All of lore.kernel.org
 help / color / mirror / Atom feed
From: pcaulfield@sourceware.org <pcaulfield@sourceware.org>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] cluster/cman daemon/ais.c daemon/cnxman-privat ...
Date: 17 Aug 2006 13:22:41 -0000	[thread overview]
Message-ID: <20060817132241.19115.qmail@sourceware.org> (raw)

CVSROOT:	/cvs/cluster
Module name:	cluster
Changes by:	pcaulfield at sourceware.org	2006-08-17 13:22:40

Modified files:
	cman/daemon    : ais.c cnxman-private.h cnxman-socket.h 
	                 commands.c commands.h daemon.c daemon.h 
	cman/lib       : libcman.c libcman.h 
	cman/tests     : libtest.c 

Log message:
	Add a confchg callback to libcman, similar to the openAIS ones.
	this gives a race-free notification of cluster change deltas and will
	probably simplify client code hugely.
	(or it would if most of it hadn't already been written!)

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/daemon/ais.c.diff?cvsroot=cluster&r1=1.38&r2=1.39
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/daemon/cnxman-private.h.diff?cvsroot=cluster&r1=1.22&r2=1.23
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/daemon/cnxman-socket.h.diff?cvsroot=cluster&r1=1.15&r2=1.16
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/daemon/commands.c.diff?cvsroot=cluster&r1=1.47&r2=1.48
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/daemon/commands.h.diff?cvsroot=cluster&r1=1.12&r2=1.13
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/daemon/daemon.c.diff?cvsroot=cluster&r1=1.30&r2=1.31
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/daemon/daemon.h.diff?cvsroot=cluster&r1=1.5&r2=1.6
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/lib/libcman.c.diff?cvsroot=cluster&r1=1.25&r2=1.26
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/lib/libcman.h.diff?cvsroot=cluster&r1=1.26&r2=1.27
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/tests/libtest.c.diff?cvsroot=cluster&r1=1.4&r2=1.5

--- cluster/cman/daemon/ais.c	2006/08/11 12:34:18	1.38
+++ cluster/cman/daemon/ais.c	2006/08/17 13:22:39	1.39
@@ -34,6 +34,7 @@
 #include <openais/service/config.h>
 #include <openais/lcr/lcr_comp.h>
 #include <openais/service/swab.h>
+#include <openais/service/print.h>
 
 #include "cnxman-socket.h"
 #include "commands.h"
@@ -60,6 +61,7 @@
 static char errorstring[512];
 static int startup_pipe;
 static unsigned int debug_mask;
+static int first_trans = 1;
 static struct objdb_iface_ver0 *global_objdb;
 static totempg_groups_handle group_handle;
 static struct totempg_group cman_group[1] = {
@@ -390,6 +392,9 @@
 {
 	int i;
 	static int last_memb_count = 0;
+	static int saved_left_list_entries;
+	static int saved_left_list_size;
+	static unsigned int *saved_left_list = NULL;
 
 	P_AIS("confchg_fn called type = %d, seq=%lld\n", configuration_type, ring_id->seq);
 
@@ -401,10 +406,37 @@
 	for (i=0; i<joined_list_entries; i++)
 		add_ais_node(joined_list[i], incarnation, member_list_entries);
 
+	/* Save the left list for later so we can do a consolidated confchg message */
+	if (configuration_type == TOTEM_CONFIGURATION_TRANSITIONAL) {
+		if (saved_left_list == NULL) {
+			saved_left_list_size = left_list_entries*2;
+			saved_left_list = malloc(sizeof(int) * saved_left_list_size);
+			if (!saved_left_list) {
+				log_printf(LOG_LEVEL_CRIT, "cannot allocate memory for confchg message");
+				exit(3);
+			}
+		}
+		if (saved_left_list_size < left_list_entries) {
+			saved_left_list_size = left_list_entries*2;
+			saved_left_list = realloc(saved_left_list, sizeof(int) * saved_left_list_size);
+			if (!saved_left_list) {
+				log_printf(LOG_LEVEL_CRIT, "cannot reallocate memory for confchg message");
+				exit(3);
+			}
+		}
+		saved_left_list_entries = left_list_entries;
+		memcpy(saved_left_list, left_list, left_list_entries * sizeof(int));
+	}
+
 	if (configuration_type == TOTEM_CONFIGURATION_REGULAR) {
 		P_AIS("last memb_count = %d, current = %d\n", last_memb_count, member_list_entries);
-		send_transition_msg(last_memb_count);
+		send_transition_msg(last_memb_count, first_trans);
 		last_memb_count = member_list_entries;
+		first_trans = 0;
+
+		cman_send_confchg(member_list,  member_list_entries,
+				  saved_left_list, saved_left_list_entries,
+				  joined_list, joined_list_entries);
 	}
 }
 
--- cluster/cman/daemon/cnxman-private.h	2006/06/30 13:00:27	1.22
+++ cluster/cman/daemon/cnxman-private.h	2006/08/17 13:22:39	1.23
@@ -70,7 +70,7 @@
 
 struct cl_transmsg {
 	unsigned char cmd;
-	unsigned char pad;
+	unsigned char first_trans;
 	uint16_t cluster_id;
 	int high_nodeid;
 	int expected_votes;
@@ -129,6 +129,7 @@
 	uint32_t   port;        /* If bound client */
 	enum {SHUTDOWN_REPLY_UNK=0, SHUTDOWN_REPLY_YES, SHUTDOWN_REPLY_NO} shutdown_reply;
 	uint32_t   events;      /* Registered for events */
+	uint32_t   confchg;     /* Registered for confchg */
 	struct list write_msgs; /* Queued messages to go to data clients */
 	struct cl_comms_socket *clsock;
 	struct connection *next;
--- cluster/cman/daemon/cnxman-socket.h	2006/05/15 14:30:16	1.15
+++ cluster/cman/daemon/cnxman-socket.h	2006/08/17 13:22:39	1.16
@@ -50,10 +50,13 @@
 #define CMAN_CMD_UPDATE_FENCE_INFO  0x800000bd
 #define CMAN_CMD_GET_FENCE_INFO     0x000000be
 #define CMAN_CMD_GET_NODEADDRS      0x000000bf
+#define CMAN_CMD_START_CONFCHG      0x000000c0
+#define CMAN_CMD_STOP_CONFCHG       0x000000c1
 
 #define CMAN_CMD_DATA               0x00000100
 #define CMAN_CMD_BIND               0x00000101
 #define CMAN_CMD_EVENT              0x00000102
+#define CMAN_CMD_CONFCHG            0x00000103
 
 #define CMAN_CMDFLAG_PRIV           0x80000000
 #define CMAN_CMDFLAG_REPLY          0x40000000
@@ -150,6 +153,15 @@
 	int arg;
 };
 
+/* confchg message */
+struct sock_confchg_message {
+	struct sock_header header;
+	int member_entries;
+	int left_entries;
+	int joined_entries;
+	unsigned int entries[]; // In above order.
+};
+
 /* Flags */
 #define CMAN_EXTRA_FLAG_2NODE    1
 #define CMAN_EXTRA_FLAG_ERROR    2
--- cluster/cman/daemon/commands.c	2006/08/15 10:27:13	1.47
+++ cluster/cman/daemon/commands.c	2006/08/17 13:22:39	1.48
@@ -1157,6 +1157,16 @@
 		err = 0;
 		break;
 
+	case CMAN_CMD_START_CONFCHG:
+		con->confchg = 1;
+		err = 0;
+		break;
+
+	case CMAN_CMD_STOP_CONFCHG:
+		con->confchg = 0;
+		err = 0;
+		break;
+
 		/* Return the cnxman version number */
 	case CMAN_CMD_GET_VERSION:
 		err = 0;
@@ -1297,6 +1307,31 @@
 	return ret;
 }
 
+void cman_send_confchg(unsigned int *member_list, int member_list_entries,
+		       unsigned int *left_list, int left_list_entries,
+		       unsigned int *joined_list, int joined_list_entries)
+{
+	char buf[sizeof(struct sock_confchg_message) +
+		 (member_list_entries+left_list_entries+joined_list_entries) * sizeof(int)];
+	struct sock_confchg_message *msg = (struct sock_confchg_message *)buf;
+
+	msg->header.magic = CMAN_MAGIC;
+	msg->header.command = CMAN_CMD_CONFCHG;
+	msg->header.length = sizeof(buf);
+	msg->header.flags = 0;
+
+	msg->member_entries = member_list_entries;
+	msg->joined_entries = joined_list_entries;
+	msg->left_entries = left_list_entries;
+
+	memcpy(msg->entries, member_list, sizeof(int)*member_list_entries);
+	memcpy(msg->entries+member_list_entries, left_list, sizeof(int)*left_list_entries);
+	memcpy(msg->entries+member_list_entries+left_list_entries, joined_list, sizeof(int)*joined_list_entries);
+
+	notify_confchg((struct sock_header *)msg);
+}
+
+
 /* Send a port closedown message to all cluster nodes - this tells them that a
  * port listener has gone away */
 static int send_port_close_msg(unsigned char port)
@@ -1428,7 +1463,7 @@
 }
 
 
-void send_transition_msg(int last_memb_count)
+void send_transition_msg(int last_memb_count, int first_trans)
 {
 	char buf[sizeof(struct cl_transmsg)+1024];
 	struct cl_transmsg *msg = (struct cl_transmsg *)buf;
@@ -1438,6 +1473,7 @@
 
 	P_MEMB("sending TRANSITION message. cluster_name = %s\n", cluster_name);
 	msg->cmd = CLUSTER_MSG_TRANSITION;
+	msg->first_trans = first_trans;
 	msg->high_nodeid = get_highest_nodeid();
 	msg->expected_votes = us->expected_votes;
 	msg->cluster_id = cluster_id;
@@ -1601,6 +1637,9 @@
 	node = find_node_by_nodeid(nodeid);
 	assert(node);
 
+	if (node->flags & NODE_FLAGS_GOTTRANSITION) {
+
+	}
 	node->flags = msg->flags;
 	if (node->fence_agent && msg->fence_agent[0] && strcmp(node->fence_agent, msg->fence_agent))
 	{
--- cluster/cman/daemon/commands.h	2006/05/22 09:08:48	1.12
+++ cluster/cman/daemon/commands.h	2006/08/17 13:22:39	1.13
@@ -24,12 +24,17 @@
 extern void commands_init(void);
 extern int process_command(struct connection *con, int cmd, char *cmdbuf,
 			   char **retbuf, int *retlen, int retsize, int offset);
-extern void send_transition_msg(int last_memb_count);
+extern void send_transition_msg(int last_memb_count, int first_trans);
 
 extern void add_ais_node(int nodeid, uint64_t incarnation, int total_members);
 extern void del_ais_node(int nodeid);
 extern void add_ccs_node(char *name, int nodeid, int votes, int expected_votes);
 extern void override_expected(int expected);
+extern void cman_send_confchg(unsigned int *member_list, int member_list_entries,
+			      unsigned int *left_list, int left_list_entries,
+			      unsigned int *joined_list, int joined_list_entries);
+
+
 
 /* Startup stuff called from cmanccs: */
 extern int cman_set_nodename(char *name);
--- cluster/cman/daemon/daemon.c	2006/08/11 12:34:18	1.30
+++ cluster/cman/daemon/daemon.c	2006/08/17 13:22:39	1.31
@@ -412,6 +412,16 @@
 	}
 }
 
+void notify_confchg(struct sock_header *message)
+{
+	struct connection *thiscon;
+
+	list_iterate_items(thiscon, &client_list) {
+		if (thiscon->confchg)
+			send_reply_message(thiscon, message);
+	}
+}
+
 void wake_daemon(void)
 {
 	P_DAEMON("Wake daemon called\n");
--- cluster/cman/daemon/daemon.h	2006/03/15 15:15:20	1.5
+++ cluster/cman/daemon/daemon.h	2006/08/17 13:22:39	1.6
@@ -18,7 +18,7 @@
 extern void cman_set_realtime(void);
 extern int cman_init(void);
 extern int cman_finish(void);
-
+extern void notify_confchg(struct sock_header *message);
 
 extern volatile sig_atomic_t quit_threads;
 extern int num_connections;
--- cluster/cman/lib/libcman.c	2006/07/11 08:13:18	1.25
+++ cluster/cman/lib/libcman.c	2006/08/17 13:22:39	1.26
@@ -49,6 +49,7 @@
 	int want_reply;
 	cman_callback_t event_callback;
 	cman_datacallback_t data_callback;
+	cman_confchgcallback_t confchg_callback;
 
 	void *reply_buffer;
 	int reply_buflen;
@@ -192,18 +193,28 @@
 	}
 
 	/* OOB event */
-	if (msg->command == CMAN_CMD_EVENT)
+	if (msg->command == CMAN_CMD_EVENT || msg->command == CMAN_CMD_CONFCHG)
 	{
-		struct sock_event_message *emsg = (struct sock_event_message *)msg;
-
 		if (flags & CMAN_DISPATCH_IGNORE_EVENT)
 		{
 			add_to_waitlist(&h->saved_event_msg, msg);
 		}
 		else
 		{
-			if (h->event_callback)
+			if (msg->command == CMAN_CMD_EVENT && h->event_callback) {
+				struct sock_event_message *emsg = (struct sock_event_message *)msg;
 				h->event_callback(h, h->private, emsg->reason, emsg->arg);
+			}
+
+			if (msg->command == CMAN_CMD_CONFCHG && h->confchg_callback)
+			{
+				struct sock_confchg_message *cmsg = (struct sock_confchg_message *)msg;
+
+				h->confchg_callback(h, h->private,
+						    cmsg->entries,cmsg->member_entries, 
+						    &cmsg->entries[cmsg->member_entries], cmsg->left_entries, 
+						    &cmsg->entries[cmsg->member_entries+cmsg->left_entries], cmsg->joined_entries);
+			}
 		}
 	}
 
@@ -404,6 +415,35 @@
 	return 0;
 }
 
+int cman_start_confchg(cman_handle_t handle, cman_confchgcallback_t callback)
+{
+	struct cman_handle *h = (struct cman_handle *)handle;
+	VALIDATE_HANDLE(h);
+
+	if (!callback)
+	{
+		errno = EINVAL;
+		return -1;
+	}
+	if (info_call(h, CMAN_CMD_START_CONFCHG, NULL, 0, NULL, 0))
+		return -1;
+	h->confchg_callback = callback;
+
+	return 0;
+}
+
+int cman_stop_confchg(cman_handle_t handle)
+{
+	struct cman_handle *h = (struct cman_handle *)handle;
+	VALIDATE_HANDLE(h);
+
+	if (info_call(h, CMAN_CMD_STOP_CONFCHG, NULL, 0, NULL, 0))
+		return -1;
+	h->confchg_callback = NULL;
+
+	return 0;
+}
+
 
 int cman_get_fd(cman_handle_t handle)
 {
--- cluster/cman/lib/libcman.h	2006/07/11 08:13:18	1.26
+++ cluster/cman/lib/libcman.h	2006/08/17 13:22:39	1.27
@@ -181,6 +181,11 @@
 				    char *buf, int len, uint8_t port, int nodeid);
 
 
+typedef void (*cman_confchgcallback_t)(cman_handle_t handle, void *private,
+				       unsigned int *member_list, int member_list_entries,
+				       unsigned int *left_list, int left_list_entries,
+				       unsigned int *joined_list, int joined_list_entries);
+
 /*
  * cman_init        returns the handle you need to pass to the other API calls.
  * cman_admin_init  opens admin socket for privileged operations.
@@ -203,6 +208,15 @@
 int cman_start_notification(cman_handle_t handle, cman_callback_t callback);
 int cman_stop_notification(cman_handle_t handle);
 
+/*
+ * Start/stop AIS-style confchg callbacks. These are less racy than the
+ * old cman callbacks in that the caller will get one for each AIS
+ * confchg message and it will contain all of the nodes that joined &
+ * left in that transition.
+ */
+int cman_start_confchg(cman_handle_t handle, cman_confchgcallback_t callback);
+int cman_stop_confchg(cman_handle_t handle);
+
 /* Call this if you get a TRY_SHUTDOWN event to signal whether you
  * will let cman shutdown or not.
  */
--- cluster/cman/tests/libtest.c	2006/08/11 10:53:48	1.4
+++ cluster/cman/tests/libtest.c	2006/08/17 13:22:39	1.5
@@ -10,6 +10,24 @@
 	printf("callback called reason = %d, arg=%d\n", reason, arg);
 }
 
+static void confchg_callback(cman_handle_t handle, void *private,
+			     unsigned int *member_list, int member_list_entries,
+			     unsigned int *left_list, int left_list_entries,
+			     unsigned int *joined_list, int joined_list_entries)
+{
+	int i;
+	printf("Confchg callback\n");
+	printf("member_list: %d entries:\n", member_list_entries);
+	for (i=0; i<member_list_entries; i++)
+		printf("  %d\n", member_list[i]);
+	printf("left_list: %d entries:\n", left_list_entries);
+	for (i=0; i<left_list_entries; i++)
+		printf("  %d\n", left_list[i]);
+	printf("joined_list: %d entries:\n", joined_list_entries);
+	for (i=0; i<joined_list_entries; i++)
+		printf("  %d\n", joined_list[i]);
+}
+
 static void print_node(cman_node_t *node)
 {
 	printf("  node id     %d\n", node->cn_nodeid);
@@ -87,10 +105,17 @@
 		perror("get_node failed");
 	}
 
-	if (!cman_start_notification(h, cman_callback))
+	if (cman_start_notification(h, cman_callback))
 	{
 		perror("start_notification");
 	}
+
+	if (cman_start_confchg(h, confchg_callback))
+	{
+		perror("start_confchg");
+	}
+
+
 	while (1) {
 	  int ret = cman_dispatch(h, CMAN_DISPATCH_BLOCKING | CMAN_DISPATCH_ALL);
 	  if (ret == -1) {



                 reply	other threads:[~2006-08-17 13:22 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20060817132241.19115.qmail@sourceware.org \
    --to=pcaulfield@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.