[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