[Ocfs2-tools-devel] [PATCH 13/39] ocfs2_controld: Add cman membership code.

Joel Becker joel.becker at oracle.com
Fri Mar 14 16:52:36 PDT 2008


Bring in the member_cman.c file.  It just connects to cman and loads the
node information.

Signed-off-by: Joel Becker <joel.becker at oracle.com>
---
 ocfs2_controld/Makefile         |    7 +-
 ocfs2_controld/main.c           |   12 ++-
 ocfs2_controld/member_cman.c    |  220 +++++++++++++++++++++++++++++++++++++++
 ocfs2_controld/ocfs2_controld.h |    5 +
 4 files changed, 237 insertions(+), 7 deletions(-)
 create mode 100644 ocfs2_controld/member_cman.c

diff --git a/ocfs2_controld/Makefile b/ocfs2_controld/Makefile
index 0fb9cee..ec7bb41 100644
--- a/ocfs2_controld/Makefile
+++ b/ocfs2_controld/Makefile
@@ -27,7 +27,9 @@ CFLAGS := $(OPTS) -Wall -Wstrict-prototypes -Wmissing-prototypes \
 DEFINES = -DOCFS2_FLAT_INCLUDES -DO2DLM_FLAT_INCLUDES \
 	  -DO2CB_FLAT_INCLUDES -DHAVE_CMAN -DVERSION=\"$(VERSION)\"
 
-DAEMON_CFILES = main.c
+UNINST_HFILES = ocfs2_controld.h
+
+DAEMON_CFILES = main.c member_cman.c
 TEST_CFILES = test_client.c
 
 DAEMON_OBJS = $(subst .c,.o,$(DAEMON_CFILES))
@@ -37,10 +39,11 @@ MANS =
 DIST_FILES =				\
 	$(DAEMON_CFILES)		\
 	$(TEST_CFILES)			\
+	$(UNINST_HFILES)		\
 	$(addsuffix .in,$(MANS))
 
 ocfs2_controld.cman: $(DAEMON_OBJS) $(LIBO2CB_DEPS)
-	$(LINK) $(LIBO2CB_LIBS) $(COM_ERR_LIBS)
+	$(LINK) $(LIBO2CB_LIBS) $(COM_ERR_LIBS) -lcman
 
 test_client: $(TEST_OBJS) $(LIBO2CB_DEPS) $(LIBOCFS2_DEPS)
 	$(LINK) $(LIBOCFS2_LIBS) $(LIBO2CB_LIBS) $(COM_ERR_LIBS)
diff --git a/ocfs2_controld/main.c b/ocfs2_controld/main.c
index af29916..2136534 100644
--- a/ocfs2_controld/main.c
+++ b/ocfs2_controld/main.c
@@ -411,12 +411,12 @@ static int loop(void)
 		goto out;
 	client_add(sigpipe_fd);
 
-#if 0
 	rv = cman_fd = setup_cman();
 	if (rv < 0)
 		goto out;
 	client_add(cman_fd);
 
+#if 0
 	rv = groupd_fd = setup_groupd();
 	if (rv < 0)
 		goto out;
@@ -450,14 +450,14 @@ static int loop(void)
 				if (pollfd[i].fd == groupd_fd)
 					process_groupd();
 				else if (pollfd[i].fd == cman_fd) {
+#endif
+				if (pollfd[i].fd == cman_fd) {
 					rv = process_cman();
 					if (rv) {
 						log_error("cman connection died");
 						goto stop;
 					}
 				} else if (pollfd[i].fd == sigpipe_fd) {
-#endif
-				if (pollfd[i].fd == sigpipe_fd) {
 					rv = handle_signal();
 					if (rv)
 						goto stop;
@@ -466,23 +466,25 @@ static int loop(void)
 			}
 
 			if (pollfd[i].revents & POLLHUP) {
-#if 0
 				if (pollfd[i].fd == cman_fd) {
 					log_error("cman connection died");
 					goto stop;
+#if 0
 				} else if (pollfd[i].fd == groupd_fd) {
 					log_error("groupd connection died");
 					goto stop;
-				}
 #endif
+				}
 				client_dead(i);
 			}
 		}
 	}
 
 stop:
+#if 0
 	if (!rv && !list_empty(&mounts))
 		rv = 1;
+#endif
 
 #if 0
 	bail_on_mounts();
diff --git a/ocfs2_controld/member_cman.c b/ocfs2_controld/member_cman.c
new file mode 100644
index 0000000..d5829ac
--- /dev/null
+++ b/ocfs2_controld/member_cman.c
@@ -0,0 +1,220 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ */
+
+/******************************************************************************
+*******************************************************************************
+**
+**  Copyright (C) 2005 Red Hat, Inc.  All rights reserved.
+**
+**  This copyrighted material is made available to anyone wishing to use,
+**  modify, copy, or redistribute it subject to the terms and conditions
+**  of the GNU General Public License v.2.
+**
+*******************************************************************************
+******************************************************************************/
+
+/*
+ * Copyright (C) 2007 Oracle.  All rights reserved.
+ *
+ *  This copyrighted material is made available to anyone wishing to use,
+ *  modify, copy, or redistribute it subject to the terms and conditions
+ *  of the GNU General Public License v.2.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+#include <errno.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <libcman.h>
+
+#include "ocfs2-kernel/kernel-list.h"
+#include "o2cb/o2cb.h"
+
+#include "ocfs2_controld.h"
+
+int			our_nodeid;
+char *			clustername;
+cman_cluster_t		cluster;
+static cman_handle_t	ch;
+extern struct list_head mounts;
+static cman_node_t      old_nodes[O2NM_MAX_NODES];
+static int              old_node_count;
+static cman_node_t      cman_nodes[O2NM_MAX_NODES];
+static int              cman_node_count;
+
+
+static int is_member(cman_node_t *node_list, int count, int nodeid)
+{
+	int i;
+
+	for (i = 0; i < count; i++) {
+		if (node_list[i].cn_nodeid == nodeid)
+			return node_list[i].cn_member;
+	}
+	return 0;
+}
+
+static int is_old_member(int nodeid)
+{
+	return is_member(old_nodes, old_node_count, nodeid);
+}
+
+static int is_cman_member(int nodeid)
+{
+	return is_member(cman_nodes, cman_node_count, nodeid);
+}
+
+static cman_node_t *find_cman_node(int nodeid)
+{
+	int i;
+
+	for (i = 0; i < cman_node_count; i++) {
+		if (cman_nodes[i].cn_nodeid == nodeid)
+			return &cman_nodes[i];
+	}
+	return NULL;
+}
+
+char *nodeid2name(int nodeid)
+{
+	cman_node_t *cn;
+
+	cn = find_cman_node(nodeid);
+	if (!cn)
+		return NULL;
+	return cn->cn_name;
+}
+
+/* keep track of the nodes */
+static void statechange(void)
+{
+	int i, rv;
+
+	old_node_count = cman_node_count;
+	memcpy(&old_nodes, &cman_nodes, sizeof(old_nodes));
+
+	cman_node_count = 0;
+	memset(&cman_nodes, 0, sizeof(cman_nodes));
+	rv = cman_get_nodes(ch, O2NM_MAX_NODES, &cman_node_count,
+			    cman_nodes);
+	if (rv < 0) {
+		log_debug("cman_get_nodes error %d %d", rv, errno);
+		return;
+	}
+
+	for (i = 0; i < old_node_count; i++) {
+		if (old_nodes[i].cn_member &&
+		    !is_cman_member(old_nodes[i].cn_nodeid)) {
+
+			log_debug("cman: node %d removed",
+				   old_nodes[i].cn_nodeid);
+		}
+	}
+
+	for (i = 0; i < cman_node_count; i++) {
+		if (cman_nodes[i].cn_member &&
+		    !is_old_member(cman_nodes[i].cn_nodeid)) {
+
+			log_debug("cman: node %d added",
+				  cman_nodes[i].cn_nodeid);
+		}
+	}
+}
+
+static void cman_callback(cman_handle_t h, void *private, int reason, int arg)
+{
+	switch (reason) {
+		case CMAN_REASON_TRY_SHUTDOWN:
+#if 0
+			if (list_empty(&mounts))
+#endif
+				cman_replyto_shutdown(ch, 1);
+#if 0
+			else {
+				log_debug("no to cman shutdown");
+				cman_replyto_shutdown(ch, 0);
+			}
+#endif
+			break;
+
+		case CMAN_REASON_STATECHANGE:
+			statechange();
+			break;
+	}
+}
+
+void exit_cman(void)
+{
+	log_error("cluster is down, exiting");
+	exit(1);
+}
+
+int process_cman(void)
+{
+	int rv;
+
+	rv = cman_dispatch(ch, CMAN_DISPATCH_ALL);
+
+	if (rv == -1 && errno == EHOSTDOWN)
+		return 1;
+
+	return 0;
+}
+
+int setup_cman(void)
+{
+	cman_node_t node;
+	int rv, fd;
+
+	ch = cman_init(NULL);
+	if (!ch) {
+		log_error("cman_init error %d", errno);
+		return -ENOTCONN;
+	}
+
+	rv = cman_start_notification(ch, cman_callback);
+	if (rv < 0) {
+		log_error("cman_start_notification error %d %d", rv, errno);
+		goto fail_finish;
+	}
+
+	/* FIXME: wait here for us to be a member of the cluster */
+
+	memset(&cluster, 0, sizeof(cluster));
+	rv = cman_get_cluster(ch, &cluster);
+	if (rv < 0) {
+		log_error("cman_get_cluster error %d %d", rv, errno);
+		goto fail_stop;
+	}
+	clustername = cluster.ci_name;
+
+	memset(&node, 0, sizeof(node));
+	rv = cman_get_node(ch, CMAN_NODEID_US, &node);
+	if (rv < 0) {
+		log_error("cman_get_node error %d %d", rv, errno);
+		goto fail_stop;
+	}
+	our_nodeid = node.cn_nodeid;
+
+	fd = cman_get_fd(ch);
+
+	old_node_count = 0;
+	memset(&old_nodes, 0, sizeof(old_nodes));
+	cman_node_count = 0;
+	memset(&cman_nodes, 0, sizeof(cman_nodes));
+
+	/* Fill the node list */
+	statechange();
+
+	return fd;
+
+ fail_stop:
+	cman_stop_notification(ch);
+ fail_finish:
+	cman_finish(ch);
+	return rv;
+}
+
diff --git a/ocfs2_controld/ocfs2_controld.h b/ocfs2_controld/ocfs2_controld.h
index 65571d9..a3e4068 100644
--- a/ocfs2_controld/ocfs2_controld.h
+++ b/ocfs2_controld/ocfs2_controld.h
@@ -61,4 +61,9 @@ do { \
 } while (0)
 
 
+int setup_cman(void);
+int process_cman(void);
+char *nodeid2name(int nodeid);
+void exit_cman(void);
+
 #endif
-- 
1.5.3.8




More information about the Ocfs2-tools-devel mailing list