This is the mail archive of the
cluster-cvs@sourceware.org
mailing list for the cluster.
cluster: master - groupd/libgroup: remove them
- From: David Teigland <teigland at fedoraproject dot org>
- To: cluster-cvs-relay at redhat dot com
- Date: Fri, 9 Jan 2009 20:03:38 +0000 (UTC)
- Subject: cluster: master - groupd/libgroup: remove them
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=f723d9c72f60af142ab4d9c49d762ebf7a45f0e5
Commit: f723d9c72f60af142ab4d9c49d762ebf7a45f0e5
Parent: 3a4eab96426ad3312a4616488a58071ed6b460a4
Author: David Teigland <teigland@redhat.com>
AuthorDate: Fri Jan 9 14:47:40 2009 -0600
Committer: David Teigland <teigland@redhat.com>
CommitterDate: Fri Jan 9 14:47:40 2009 -0600
groupd/libgroup: remove them
and make group_tool a simple wrapper around fence_tool,
dlm_tool and gfs_control.
Signed-off-by: David Teigland <teigland@redhat.com>
---
group/Makefile | 2 +-
group/daemon/Makefile | 35 -
group/daemon/app.c | 1842 --------------------------------------------
group/daemon/cman.c | 206 -----
group/daemon/cpg.c | 1072 --------------------------
group/daemon/gd_internal.h | 323 --------
group/daemon/groupd.h | 13 -
group/daemon/joinleave.c | 165 ----
group/daemon/logging.c | 60 --
group/daemon/main.c | 1082 --------------------------
group/lib/Makefile | 17 -
group/lib/libgroup.c | 524 -------------
group/lib/libgroup.h | 81 --
group/man/groupd.8 | 43 -
group/test/Makefile | 16 -
group/test/client.c | 45 --
group/test/clientd.c | 179 -----
group/tool/Makefile | 21 +-
group/tool/main.c | 635 +---------------
19 files changed, 21 insertions(+), 6340 deletions(-)
diff --git a/group/Makefile b/group/Makefile
index eab99ca..792c2e5 100644
--- a/group/Makefile
+++ b/group/Makefile
@@ -1,4 +1,4 @@
include ../make/defines.mk
include $(OBJDIR)/make/passthrough.mk
-SUBDIRS = lib daemon man
+SUBDIRS = man tool
diff --git a/group/daemon/Makefile b/group/daemon/Makefile
deleted file mode 100644
index 36268db..0000000
--- a/group/daemon/Makefile
+++ /dev/null
@@ -1,35 +0,0 @@
-TARGET= groupd
-
-SBINDIRT=$(TARGET)
-
-all: ${TARGET}
-
-include ../../make/defines.mk
-include $(OBJDIR)/make/cobj.mk
-include $(OBJDIR)/make/clean.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-OBJS= app.o \
- cpg.o \
- cman.o \
- joinleave.o \
- main.o \
- logging.o
-
-CFLAGS += -I${ccsincdir} -I${cmanincdir} -I${logtincdir} -I${corosyncincdir}
-CFLAGS += -I$(S) -I$(S)/../include/ -I$(S)/../lib/
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${ccslibdir} -lccs
-LDFLAGS += -L${cmanlibdir} -lcman
-LDFLAGS += -L${logtlibdir} -llogthread
-LDFLAGS += -L${corosynclibdir} -lcpg -lpthread
-LDFLAGS += -L${libdir}
-
-${TARGET}: ${OBJS}
- $(CC) -o $@ $^ $(LDFLAGS)
-
-clean: generalclean
-
--include $(OBJS:.o=.d)
diff --git a/group/daemon/app.c b/group/daemon/app.c
deleted file mode 100644
index 9ca2801..0000000
--- a/group/daemon/app.c
+++ /dev/null
@@ -1,1842 +0,0 @@
-
-/* Apply queued events to apps */
-
-#include "gd_internal.h"
-
-struct list_head recovery_sets;
-
-struct nodeid {
- struct list_head list;
- int nodeid;
-};
-
-char *msg_type(int type)
-{
- switch (type) {
- case MSG_APP_STOPPED:
- return "stopped";
- case MSG_APP_STARTED:
- return "started";
- case MSG_APP_RECOVER:
- return "recover";
- case MSG_APP_INTERNAL:
- return "internal";
- case MSG_GLOBAL_ID:
- return "global_id";
- }
- return "unknown";
-}
-
-void msg_bswap_out(msg_t *msg)
-{
- msg->ms_version[0] = cpu_to_le32(MSG_VER_MAJOR);
- msg->ms_version[1] = cpu_to_le32(MSG_VER_MINOR);
- msg->ms_version[2] = cpu_to_le32(MSG_VER_PATCH);
- msg->ms_type = cpu_to_le16(msg->ms_type);
- msg->ms_level = cpu_to_le16(msg->ms_level);
- msg->ms_length = cpu_to_le32(msg->ms_length);
- msg->ms_global_id = cpu_to_le32(msg->ms_global_id);
- msg->ms_event_id = cpu_to_le64(msg->ms_event_id);
-}
-
-void msg_bswap_in(msg_t *msg)
-{
- msg->ms_version[0] = le32_to_cpu(MSG_VER_MAJOR);
- msg->ms_version[1] = le32_to_cpu(MSG_VER_MINOR);
- msg->ms_version[2] = le32_to_cpu(MSG_VER_PATCH);
- msg->ms_type = le16_to_cpu(msg->ms_type);
- msg->ms_level = le16_to_cpu(msg->ms_level);
- msg->ms_length = le32_to_cpu(msg->ms_length);
- msg->ms_global_id = le32_to_cpu(msg->ms_global_id);
- msg->ms_event_id = le64_to_cpu(msg->ms_event_id);
-}
-
-uint64_t make_event_id(group_t *g, int state, int nodeid)
-{
- uint64_t id;
- uint32_t n = nodeid;
- uint32_t memb_count = g->memb_count;
- uint16_t type = 0;
-
- if (state == EST_JOIN_BEGIN)
- type = 1;
- else if (state == EST_LEAVE_BEGIN)
- type = 2;
- else if (state == EST_FAIL_BEGIN)
- type = 3;
- else
- log_error(g, "make_event_id invalid state %d", state);
-
- id = n;
- id = id << 32;
- memb_count = memb_count << 16;
- id = id | memb_count;
- id = id | type;
-
- log_group(g, "make_event_id %llx nodeid %d memb_count %d type %u",
- (unsigned long long)id, nodeid, g->memb_count, type);
-
- return id;
-}
-
-void free_event(event_t *ev)
-{
- struct nodeid *id, *id_safe;
-
- list_for_each_entry_safe(id, id_safe, &ev->extended, list) {
- list_del(&id->list);
- free(id);
- }
- free(ev);
-}
-
-int event_id_to_nodeid(uint64_t id)
-{
- int nodeid;
- uint64_t n = id >> 32;
- nodeid = n & 0xFFFFFFFF;
- return nodeid;
-}
-
-int event_id_to_type(uint64_t id)
-{
- uint64_t n;
- n = id & 0x000000000000FFFF;
- return ((int) n);
-}
-
-/*
- * Free queued message if:
- * - the id indicates a join for node X and X is a member
- * - the id indicates a leave for node X and X is not a member
- *
- * Note sure if all these cases are relevant, currently we only
- * purge messages after we join.
- */
-
-static void purge_messages(group_t *g)
-{
- struct save_msg *save, *tmp;
- node_t *node;
- int nodeid, type;
- char *state_str;
-
- list_for_each_entry_safe(save, tmp, &g->messages, list) {
- if (save->msg.ms_type == MSG_APP_INTERNAL)
- continue;
-
- nodeid = event_id_to_nodeid(save->msg.ms_event_id);
- type = event_id_to_type(save->msg.ms_event_id);
- node = find_app_node(g->app, nodeid);
-
- if ((type == 1 && node) || (type != 1 && !node) ||
- (save->msg.ms_type == MSG_APP_RECOVER)) {
-
- if (save->msg.ms_type == MSG_APP_RECOVER)
- state_str = "MSG_APP_RECOVER";
- else if (type == 1)
- state_str = "EST_JOIN_BEGIN";
- else if (type == 2)
- state_str = "EST_LEAVE_BEGIN";
- else if (type == 3)
- state_str = "EST_FAIL_BEGIN";
- else
- state_str = "error";
-
- log_group(g, "purge msg %llx from %d %s",
- (unsigned long long)save->msg.ms_event_id,
- nodeid, state_str);
-
- list_del(&save->list);
- if (save->msg_long)
- free(save->msg_long);
- free(save);
- }
- }
-}
-
-/* For a recovery event where multiple nodes have failed, the event id
- is based on the lowest nodeid of all the failed nodes. The event
- id is also based on the number of remaining group members which
- changes as failed nodes are added to the recovery event. */
-
-void extend_recover_event(group_t *g, event_t *ev, int nodeid)
-{
- struct nodeid *id;
- int new_id_nodeid = nodeid;
-
- log_group(g, "extend_recover_event for %d with node %d",
- ev->nodeid, nodeid);
-
- /* the lowest nodeid in a recovery event is kept in ev->nodeid,
- the other nodeid's are kept in the extended list */
-
- if (nodeid < ev->nodeid) {
- new_id_nodeid = ev->nodeid;
- ev->nodeid = nodeid;
- ev->id = make_event_id(g, EST_FAIL_BEGIN, nodeid);
- }
-
- id = malloc(sizeof(struct nodeid));
- // FIXME: handle failed malloc
- id->nodeid = new_id_nodeid;
- list_add(&id->list, &ev->extended);
-}
-
-struct recovery_set *get_recovery_set(int nodeid)
-{
- struct recovery_set *rs;
-
- list_for_each_entry(rs, &recovery_sets, list) {
- if (rs->nodeid == nodeid)
- return rs;
- }
-
- rs = malloc(sizeof(*rs));
- ASSERT(rs);
- memset(rs, 0, sizeof(struct recovery_set));
- rs->nodeid = nodeid;
- rs->cman_update = 0;
- rs->cpg_update = 0;
- INIT_LIST_HEAD(&rs->entries);
-
- list_add_tail(&rs->list, &recovery_sets);
-
- return rs;
-}
-
-/* When a node fails, all the groups that that node was in are tracked by
- one of these recovery_sets. These are the groups that will need layered
- recovery, i.e. all effected groups must be completely stopped (the app
- stopped on all nodes) before any are restarted. When restarted, the groups
- must be restarted in order from lowest level first. All groups on each
- level must complete recovery (on all nodes) before recovery can begin for
- the next level. */
-
-/* FIXME: do we need to worry about the case where we get an
- add_recovery_set_cman() that finds an old rs, the old rs completes
- and goes away, and then we get the add_recovery_set_cpg() matching
- the _cman() variant that we ignored? */
-
-void add_recovery_set_cman(int nodeid)
-{
- struct recovery_set *rs;
-
- log_debug("add_recovery_set_cman nodeid %d", nodeid);
-
- rs = get_recovery_set(nodeid);
- if (rs->cman_update) {
- log_debug("old recovery for %d still in progress", nodeid);
- return;
- }
- rs->cman_update = 1;
-
- if (!rs->cpg_update && !in_groupd_cpg(nodeid)) {
- log_debug("free recovery set %d not running groupd", nodeid);
- list_del(&rs->list);
- free(rs);
- return;
- }
-
- if (list_empty(&rs->entries) && rs->cpg_update) {
- log_debug("free unused recovery set %d cman", nodeid);
- list_del(&rs->list);
- free(rs);
- }
-}
-
-/* procdown of 1 means the groupd daemon process exited, but the node didn't
- fail. when only the process fails, we won't get a cman callback which is
- only for nodedown. if the node wasn't in any groups we don't add a recovery
- set and don't care about the exited groupd; if the node with the failed
- groupd _was_ in any groups, we add a rs and process_groupd_confchg() will do
- cman_kill_node() to make the node really fail (and we'll get an
- add_recovery_set_cman()). */
-
-struct recovery_set *add_recovery_set_cpg(int nodeid, int procdown)
-{
- struct recovery_set *rs;
- struct recovery_entry *re;
- group_t *g;
- node_t *node;
-
- log_debug("add_recovery_set_cpg nodeid %d procdown %d",
- nodeid, procdown);
-
- rs = get_recovery_set(nodeid);
- if (rs->cpg_update) {
- log_debug("old recovery for %d still in progress", nodeid);
- return rs;
- }
- rs->cpg_update = 1;
-
- list_for_each_entry(g, &gd_groups, list) {
- list_for_each_entry(node, &g->app->nodes, list) {
- if (node->nodeid == nodeid) {
- log_group(g, "add to recovery set %d", nodeid);
- re = malloc(sizeof(*re));
- // FIXME: handle failed malloc
- memset(re, 0, sizeof(struct recovery_entry));
- re->group = g;
- list_add_tail(&re->list, &rs->entries);
- break;
- }
- }
- }
-
- if (list_empty(&rs->entries)) {
- if (rs->cman_update || procdown) {
- log_debug("free unused recovery set %d cpg", nodeid);
- list_del(&rs->list);
- free(rs);
- return NULL;
- }
- }
-
- return rs;
-}
-
-void _del_recovery_set(group_t *g, int nodeid, int purge)
-{
- struct recovery_set *rs, *rs2;
- struct recovery_entry *re, *re2;
- int found = 0, entries_not_recovered;
-
- list_for_each_entry_safe(rs, rs2, &recovery_sets, list) {
- if (rs->nodeid != nodeid)
- continue;
-
- entries_not_recovered = 0;
-
- list_for_each_entry_safe(re, re2, &rs->entries, list) {
- if (re->group == g) {
- if (purge) {
- list_del(&re->list);
- free(re);
- log_group(g, "purged from rs %d",
- rs->nodeid);
- } else {
- re->recovered = 1;
- log_group(g, "done in recovery set %d",
- rs->nodeid);
- found++;
- }
- } else {
- if (re->recovered == 0)
- entries_not_recovered++;
- }
- }
-
- if (entries_not_recovered) {
- log_debug("recovery set %d has %d entries not done",
- rs->nodeid, entries_not_recovered);
- continue;
- }
-
- /* all entries in this rs are recovered, free it */
- log_debug("recovery set %d is all done", rs->nodeid);
-
- list_for_each_entry_safe(re, re2, &rs->entries, list) {
- list_del(&re->list);
- free(re);
- }
- list_del(&rs->list);
- free(rs);
- }
-
- if (!found)
- log_group(g, "not found in any recovery sets for %d", nodeid);
-}
-
-/* A group has finished recovery for given event (which can encompass more than
- one failed nodeid). Remove this group from recovery sets for those nodeids
- and free any recovery sets that are now completed. */
-
-void del_recovery_set(group_t *g, event_t *ev, int purge)
-{
- struct nodeid *id;
-
- log_group(g, "rev %llx done, remove group from rs %d",
- (unsigned long long)ev->id, ev->nodeid);
- _del_recovery_set(g, ev->nodeid, purge);
-
- list_for_each_entry(id, &ev->extended, list) {
- log_group(g, "rev %llx done, remove group from rs %d",
- (unsigned long long)ev->id, id->nodeid);
- _del_recovery_set(g, id->nodeid, purge);
- }
-}
-
-/* go through all recovery sets and check that all failed nodes have
- been removed by cman callbacks; if they haven't then cman may be
- inquorate and we just haven't gotten the cman callback yet that
- will set cman_quorate = 0 [group recoveries are driven by cpg
- callbacks, not cman callbacks, so that's why we might be trying
- to do recovery without having heard from cman yet.] */
-
-int cman_quorum_updated(void)
-{
- struct recovery_set *rs;
-
- list_for_each_entry(rs, &recovery_sets, list) {
- if (rs->cman_update)
- continue;
- log_debug("no cman update for recovery_set %d quorate %d",
- rs->nodeid, cman_quorate);
- return 0;
- }
- return 1;
-}
-
-int is_recovery_event(event_t *ev)
-{
- if (event_id_to_type(ev->id) == 3)
- return 1;
- return 0;
-}
-
-/* all groups referenced by a recovery set are stopped on all nodes,
- and stopped for recovery */
-
-static int set_is_all_stopped(struct recovery_set *rs, event_t *rev)
-{
- struct recovery_entry *re;
- event_t *ev;
-
- list_for_each_entry(re, &rs->entries, list) {
- ev = re->group->app->current_event;
-
- /* we need to use ev->fail_all_stopped instead of checking
- ev->state == FAIL_ALL_STOPPED because if two groups are at
- the low level, one will detect all_levels_all_stopped first
- and then immediately move on to starting before the other,
- also checking all_levels_all_stopped, can see it's in
- FAIL_ALL_STOPPED */
-
- if (ev && is_recovery_event(ev) && ev->fail_all_stopped)
- continue;
- else
- return 0;
- }
- return 1;
-}
-
-/* for every recovery set that this group is in, are all other groups in
- each of those sets in the "all stopped" state for recovery? */
-
-static int all_levels_all_stopped(group_t *g, event_t *rev)
-{
- struct recovery_set *rs;
- struct recovery_entry *re;
- int found = 0;
-
- list_for_each_entry(rs, &recovery_sets, list) {
- list_for_each_entry(re, &rs->entries, list) {
- if (re->group == g) {
- found = 1;
- if (set_is_all_stopped(rs, rev))
- break;
- else
- return 0;
- }
- }
- }
-
- if (!found)
- return 0;
- return 1;
-}
-
-void dump_recovery_sets(void)
-{
- struct recovery_set *rs;
- struct recovery_entry *re;
-
- list_for_each_entry(rs, &recovery_sets, list) {
- log_debug("recovery_set %d", rs->nodeid);
- list_for_each_entry(re, &rs->entries, list) {
- log_debug(" recovery_entry %d:%s recovered %d",
- re->group->level, re->group->name,
- re->recovered);
- }
- }
-}
-
-static int group_in_recovery_set(struct recovery_set *rs, group_t *g)
-{
- struct recovery_entry *re;
-
- list_for_each_entry(rs, &recovery_sets, list) {
- list_for_each_entry(re, &rs->entries, list) {
- if (re->group == g)
- return 1;
- }
- }
- return 0;
-}
-
-static int rs_lower_levels_recovered(struct recovery_set *rs, int level)
-{
- struct recovery_entry *re;
-
- list_for_each_entry(re, &rs->entries, list) {
- if (re->group->level < level && !re->recovered)
- return 0;
- }
- return 1;
-}
-
-/* lower level groups should be recovered in each rs this group is in */
-
-static int lower_levels_recovered(group_t *g)
-{
- struct recovery_set *rs;
-
- list_for_each_entry(rs, &recovery_sets, list) {
- if (!group_in_recovery_set(rs, g))
- continue;
-
- if (rs_lower_levels_recovered(rs, g->level))
- continue;
-
- log_group(g, "lower levels not recovered in rs %d", rs->nodeid);
- return 0;
- }
- return 1;
-}
-
-/* We're interested in any unrecovered group at a lower level than g, not
- just lower groups in the same recovery set. */
-
-static int lower_groups_need_recovery(group_t *g)
-{
- struct recovery_set *rs;
-
- list_for_each_entry(rs, &recovery_sets, list) {
- if (rs_lower_levels_recovered(rs, g->level))
- continue;
- log_group(g, "lower group not recovered in rs %d", rs->nodeid);
- return 1;
- }
- return 0;
-}
-
-static int level_is_lowest(struct recovery_set *rs, int level)
-{
- struct recovery_entry *re;
-
- list_for_each_entry(re, &rs->entries, list) {
- if (re->group->level < level)
- return 0;
- }
- return 1;
-}
-
-/* this group is at the lowest level in any recovery sets it's in */
-
-static int lowest_level(group_t *g)
-{
- struct recovery_set *rs;
-
- list_for_each_entry(rs, &recovery_sets, list) {
- if (!group_in_recovery_set(rs, g))
- continue;
- if (level_is_lowest(rs, g->level))
- continue;
- return 0;
- }
- return 1;
-}
-
-static event_t *create_event(group_t *g)
-{
- event_t *ev;
-
- ev = malloc(sizeof(event_t));
- ASSERT(ev);
-
- memset(ev, 0, sizeof(event_t));
-
- INIT_LIST_HEAD(&ev->memb);
- INIT_LIST_HEAD(&ev->extended);
- ev->event_nr = ++gd_event_nr;
-
- return ev;
-}
-
-int queue_app_recover(group_t *g, int nodeid)
-{
- event_t *ev;
-
- ev = create_event(g);
- ev->nodeid = nodeid;
- ev->state = EST_FAIL_BEGIN;
- ev->fail_all_stopped = 0;
- ev->id = make_event_id(g, EST_FAIL_BEGIN, nodeid);
-
- log_group(g, "queue recover event for nodeid %d", nodeid);
-
- list_add_tail(&ev->list, &g->app->events);
- return 0;
-}
-
-void del_event_nodes(event_t *ev)
-{
- node_t *node, *n;
-
- list_for_each_entry_safe(node, n, &ev->memb, list) {
- list_del(&node->list);
- free(node);
- }
-}
-
-static void add_event_nodes(group_t *g, event_t *ev)
-{
- node_t *node, *n;
-
- list_for_each_entry(node, &g->memb, list) {
- n = new_node(node->nodeid);
- list_add(&n->list, &ev->memb);
- }
-}
-
-event_t *search_event(group_t *g, int nodeid)
-{
- event_t *ev;
-
- list_for_each_entry(ev, &g->app->events, list) {
- if (ev->nodeid == nodeid)
- return ev;
- }
- return NULL;
-}
-
-void dump_queued_events(group_t *g)
-{
- event_t *ev;
-
- list_for_each_entry(ev, &g->app->events, list) {
- log_group(g, " queued ev %d %llx %s",
- ev->nodeid, (unsigned long long)ev->id,
- ev_state_str(ev));
- }
-}
-
-int queue_app_join(group_t *g, int nodeid)
-{
- event_t *ev;
-
- /* sanity check */
- ev = g->app->current_event;
- if (ev && ev->nodeid == nodeid) {
- log_group(g, "queue_app_join: current event %d %llx %s",
- nodeid, (unsigned long long)ev->id, ev_state_str(ev));
- }
-
- /* sanity check */
- ev = search_event(g, nodeid);
- if (ev) {
- log_group(g, "queue_app_join: queued event %d %llx %s",
- nodeid, (unsigned long long)ev->id, ev_state_str(ev));
- }
-
- ev = create_event(g);
- ev->nodeid = nodeid;
- ev->state = EST_JOIN_BEGIN;
- ev->id = make_event_id(g, EST_JOIN_BEGIN, nodeid);
-
- log_group(g, "queue join event for nodeid %d", nodeid);
- dump_queued_events(g);
-
- if (nodeid == our_nodeid)
- add_event_nodes(g, ev);
-
- list_add_tail(&ev->list, &g->app->events);
- return 0;
-}
-
-int queue_app_leave(group_t *g, int nodeid)
-{
- event_t *ev;
-
- /* sanity check */
- ev = g->app->current_event;
- if (ev && ev->nodeid == nodeid) {
- log_group(g, "queue_app_leave: current event %d %llx %s",
- nodeid, (unsigned long long)ev->id, ev_state_str(ev));
- }
-
- /* sanity check */
- ev = search_event(g, nodeid);
- if (ev) {
- log_group(g, "queue_app_leave: queued event %d %llx %s",
- nodeid, (unsigned long long)ev->id, ev_state_str(ev));
- }
-
- ev = create_event(g);
- ev->nodeid = nodeid;
- ev->state = EST_LEAVE_BEGIN;
- ev->id = make_event_id(g, EST_LEAVE_BEGIN, nodeid);
-
- log_group(g, "queue leave event for nodeid %d", nodeid);
- dump_queued_events(g);
-
- list_add_tail(&ev->list, &g->app->events);
- return 0;
-}
-
-int queue_app_message(group_t *g, struct save_msg *save)
-{
- /* log_group(g, "queue message %s from %d",
- msg_type(save->msg.ms_type), save->nodeid); */
- list_add_tail(&save->list, &g->messages);
- return 0;
-}
-
-/* This is called when we get the nodedown for the per-group cpg; we know
- that after the cpg nodedown we won't get any further messages. bz 436984
- It's conceivable but unlikely that the nodedown processing (initiated by
- the groupd cpg nodedown) could begin before the per-group cpg nodedown
- is received where this purging occurs. If it does, then we may need to
- add code to wait for the nodedown to happen in both the groupd cpg and the
- per-group cpg before processing the nodedown. */
-
-void purge_node_messages(group_t *g, int nodeid)
-{
- struct save_msg *save, *tmp;
-
- list_for_each_entry_safe(save, tmp, &g->messages, list) {
- if (save->nodeid != nodeid)
- continue;
-
- log_group(g, "purge msg from dead node %d", nodeid);
-
- list_del(&save->list);
- if (save->msg_long)
- free(save->msg_long);
- free(save);
- }
-}
-
-static void del_app_nodes(app_t *a)
-{
- node_t *node, *tmp;
-
- list_for_each_entry_safe(node, tmp, &a->nodes, list) {
- list_del(&node->list);
- free(node);
- }
-}
-
-node_t *find_app_node(app_t *a, int nodeid)
-{
- node_t *node;
-
- list_for_each_entry(node, &a->nodes, list) {
- if (node->nodeid == nodeid)
- return node;
- }
- return NULL;
-}
-
-int is_our_join(event_t *ev)
-{
- return (ev->nodeid == our_nodeid);
-}
-
-static int is_our_leave(event_t *ev)
-{
- return (ev->nodeid == our_nodeid);
-}
-
-/* Called after all nodes have acked that they're stopped for our
- leave. We get their stopped messages even though we've left the
- cpg because the messages are sent through the groupd cpg.
- groupd_down() will fill in stops for us for nodes that fail before
- sending stopped for our leave. */
-
-void finalize_our_leave(group_t *g)
-{
- struct recovery_set *rs;
- struct recovery_entry *re, *re2;
- app_t *a = g->app;
-
- log_group(g, "finalize_our_leave");
-
- app_terminate(a);
- cpg_finalize(g->cpg_handle);
- client_dead(g->cpg_client);
- g->app = NULL;
- del_app_nodes(a);
- free(a);
-
- /* this group shouldn't be in any recovery sets... sanity check
- and avoid future segfault by removing re's referencing this g */
-
- list_for_each_entry(rs, &recovery_sets, list) {
- list_for_each_entry_safe(re, re2, &rs->entries, list) {
- if (re->group == g) {
- log_error(g, "finalize: still in recovery "
- "set %d", rs->nodeid);
- list_del(&re->list);
- free(re);
- }
- }
- }
-
- remove_group(g);
-}
-
-static int send_stopped(group_t *g)
-{
- msg_t msg;
- event_t *ev = g->app->current_event;
-
- memset(&msg, 0, sizeof(msg));
- msg.ms_type = MSG_APP_STOPPED;
- msg.ms_global_id = g->global_id;
- msg.ms_event_id = ev->id;
- msg.ms_level = g->level;
- memcpy(&msg.ms_name, &g->name, MAX_NAMELEN);
-
- msg_bswap_out(&msg);
-
- log_group(g, "send stopped");
- return send_message_groupd(g, &msg, sizeof(msg), MSG_APP_STOPPED);
-}
-
-static int send_started(group_t *g)
-{
- msg_t msg;
- event_t *ev = g->app->current_event;
-
- memset(&msg, 0, sizeof(msg));
- msg.ms_type = MSG_APP_STARTED;
- msg.ms_global_id = g->global_id;
- msg.ms_event_id = ev->id;
- msg.ms_level = g->level;
- memcpy(&msg.ms_name, &g->name, MAX_NAMELEN);
-
- msg_bswap_out(&msg);
-
- log_group(g, "send started");
- return send_message_groupd(g, &msg, sizeof(msg), MSG_APP_STARTED);
-}
-
-static int send_recover(group_t *g, event_t *rev)
-{
- msg_t msg;
-
- memset(&msg, 0, sizeof(msg));
- msg.ms_type = MSG_APP_RECOVER;
- msg.ms_global_id = g->global_id;
- msg.ms_event_id = rev->id;
- msg.ms_level = g->level;
- memcpy(&msg.ms_name, &g->name, MAX_NAMELEN);
-
- msg_bswap_out(&msg);
-
- log_group(g, "send recover");
- return send_message_groupd(g, &msg, sizeof(msg), MSG_APP_RECOVER);
-}
-
-int do_stopdone(char *name, int level)
-{
- group_t *g;
- g = find_group_level(name, level);
- return send_stopped(g);
-}
-
-int do_startdone(char *name, int level, int event_nr)
-{
- group_t *g;
- event_t *ev;
- char *state;
-
- g = find_group_level(name, level);
- if (!g) {
- log_print("do_startdone: no group level %d name %s",
- level, name);
- return -1;
- }
-
- ev = g->app->current_event;
-
- state = ev ? ev_state_str(ev) : "no-event";
-
- if (!ev || ev->event_nr != event_nr) {
- log_group(g, "ignore startdone %d state %s", event_nr, state);
- return 0;
- }
-
- if (!event_state_starting(g->app)) {
- log_error(g, "IGNORE startdone %d state %s", event_nr, state);
- return 0;
- }
-
- return send_started(g);
-}
-
-char *ev_state_str(event_t *ev)
-{
- switch (ev->state) {
- case EST_JOIN_BEGIN:
- return "JOIN_BEGIN";
- case EST_JOIN_STOP_WAIT:
- return "JOIN_STOP_WAIT";
- case EST_JOIN_ALL_STOPPED:
- return "JOIN_ALL_STOPPED";
- case EST_JOIN_START_WAIT:
- return "JOIN_START_WAIT";
- case EST_JOIN_ALL_STARTED:
- return "JOIN_ALL_STARTED";
- case EST_LEAVE_BEGIN:
- return "LEAVE_BEGIN";
- case EST_LEAVE_STOP_WAIT:
- return "LEAVE_STOP_WAIT";
- case EST_LEAVE_ALL_STOPPED:
- return "LEAVE_ALL_STOPPED";
- case EST_LEAVE_START_WAIT:
- return "LEAVE_START_WAIT";
- case EST_LEAVE_ALL_STARTED:
- return "LEAVE_ALL_STARTED";
- case EST_FAIL_BEGIN:
- return "FAIL_BEGIN";
- case EST_FAIL_STOP_WAIT:
- return "FAIL_STOP_WAIT";
- case EST_FAIL_ALL_STOPPED:
- return "FAIL_ALL_STOPPED";
- case EST_FAIL_START_WAIT:
- return "FAIL_START_WAIT";
- case EST_FAIL_ALL_STARTED:
- return "FAIL_ALL_STARTED";
- default:
- return "unknown";
- }
-}
-
-static int count_nodes_not_stopped(app_t *a)
-{
- node_t *node;
- int i = 0;
-
- list_for_each_entry(node, &a->nodes, list) {
- if (!node->stopped)
- i++;
- }
- return i;
-}
-
-int event_state_begin(app_t *a)
-{
- if (a->current_event->state == EST_JOIN_BEGIN ||
- a->current_event->state == EST_LEAVE_BEGIN ||
- a->current_event->state == EST_FAIL_BEGIN)
- return TRUE;
- return FALSE;
-}
-
-int event_state_stopping(app_t *a)
-{
- if (a->current_event->state == EST_JOIN_STOP_WAIT ||
- a->current_event->state == EST_LEAVE_STOP_WAIT ||
- a->current_event->state == EST_FAIL_STOP_WAIT)
- return TRUE;
- return FALSE;
-}
-
-int event_state_starting(app_t *a)
-{
- if (a->current_event->state == EST_JOIN_START_WAIT ||
- a->current_event->state == EST_LEAVE_START_WAIT ||
- a->current_event->state == EST_FAIL_START_WAIT)
- return TRUE;
- return FALSE;
-}
-
-int event_state_all_stopped(app_t *a)
-{
- if (a->current_event->state == EST_JOIN_ALL_STOPPED ||
- a->current_event->state == EST_LEAVE_ALL_STOPPED ||
- a->current_event->state == EST_FAIL_ALL_STOPPED)
- return TRUE;
- return FALSE;
-}
-
-int event_state_all_started(app_t *a)
-{
- if (a->current_event->state == EST_JOIN_ALL_STARTED ||
- a->current_event->state == EST_LEAVE_ALL_STARTED ||
- a->current_event->state == EST_FAIL_ALL_STARTED)
- return TRUE;
- return FALSE;
-}
-
-static int process_current_event(group_t *g)
-{
- app_t *a = g->app;
- event_t *ev = a->current_event;
- node_t *node, *n;
- struct nodeid *id;
- int rv = 0, do_start = 0, count;
-
- if (!(event_state_stopping(a) || event_state_starting(a)))
- log_group(g, "process_current_event %llx %d %s",
- (unsigned long long)ev->id, ev->nodeid,
- ev_state_str(ev));
-
- switch (ev->state) {
-
- case EST_JOIN_BEGIN:
- ev->state = EST_JOIN_STOP_WAIT;
-
- if (is_our_join(ev)) {
- /* the initial set of members that we've joined,
- includes us */
-
- list_for_each_entry_safe(node, n, &ev->memb, list) {
- list_move(&node->list, &a->nodes);
- a->node_count++;
- log_group(g, "app node init: add %d total %d",
- node->nodeid, a->node_count);
- }
-
- /* we could have the joining node send out a stopped
- message here for all to receive and count but
- that's unnecessary, we just have everyone
- set the joining node as stopped initially */
-
- node = find_app_node(a, our_nodeid);
- ASSERT(node);
- node->stopped = 1;
-
- /* if we're the first node to be joining, move
- ahead to the JOIN_ALL_STOPPED state */
-
- if (a->node_count == 1)
- ev->state++;
-
- rv = 1;
- } else {
- app_stop(a);
-
- node = new_node(ev->nodeid);
- list_add(&node->list, &a->nodes);
- a->node_count++;
- log_group(g, "app node join: add %d total %d",
- node->nodeid, a->node_count);
- node->stopped = 1;
- }
- break;
-
- case EST_JOIN_STOP_WAIT:
- count = count_nodes_not_stopped(a);
- log_group(g, "waiting for %d more stopped messages "
- "before JOIN_ALL_STOPPED %d", count, ev->nodeid);
- break;
-
- case EST_JOIN_ALL_STOPPED:
- if (!cman_quorate) {
- log_group(g, "wait for quorum before starting app");
- break;
- }
-
- /* We want to move ahead to start here if this ev is to be
- started before a pending rev that will abort it. Once
- started, the rev becomes current and stops the app
- immediately. */
-
- if (lower_groups_need_recovery(g) &&
- !ev->start_app_before_pending_rev) {
- log_group(g, "wait for lower_groups_need_recovery "
- "before starting app");
- break;
- }
- ev->start_app_before_pending_rev = 0;
-
- ev->state = EST_JOIN_START_WAIT;
-
- if (!g->have_set_id) {
- g->have_set_id = 1;
- app_setid(a);
- }
-
- app_start(a);
- break;
-
- case EST_JOIN_ALL_STARTED:
- app_finish(a);
-
- if (is_our_join(ev)) {
- purge_messages(g);
- g->joining = 0;
- }
- free_event(ev);
- a->current_event = NULL;
- rv = 1;
- break;
-
- case EST_LEAVE_BEGIN:
- ev->state = EST_LEAVE_STOP_WAIT;
- app_stop(a);
- break;
-
- case EST_LEAVE_STOP_WAIT:
- count = count_nodes_not_stopped(a);
- log_group(g, "waiting for %d more stopped messages "
- "before LEAVE_ALL_STOPPED %d", count, ev->nodeid);
- break;
-
- case EST_LEAVE_ALL_STOPPED:
- if (is_our_leave(ev)) {
- /* frees group structure */
- finalize_our_leave(g);
- rv = -1;
- break;
- }
- ev->state = EST_LEAVE_START_WAIT;
-
- node = find_app_node(a, ev->nodeid);
- list_del(&node->list);
- a->node_count--;
- log_group(g, "app node leave: del %d total %d",
- node->nodeid, a->node_count);
- free(node);
- app_start(a);
- break;
-
- case EST_LEAVE_ALL_STARTED:
- app_finish(a);
- free_event(ev);
- a->current_event = NULL;
- rv = 1;
- break;
-
- case EST_FAIL_BEGIN:
- ev->state = EST_FAIL_STOP_WAIT;
- app_stop(a);
-
- /* set the failed nodes as stopped since we won't
- be getting a "stopped" message from them. the node
- may already have been removed in the case where one
- rev interrupts another */
-
- node = find_app_node(a, ev->nodeid);
- if (node)
- node->stopped = 1;
-
- /* multiple nodes failed together making an extended event */
- list_for_each_entry(id, &ev->extended, list) {
- node = find_app_node(a, id->nodeid);
- if (node)
- node->stopped = 1;
- }
-
- break;
-
- case EST_FAIL_STOP_WAIT:
- count = count_nodes_not_stopped(a);
- log_group(g, "waiting for %d more stopped messages "
- "before FAIL_ALL_STOPPED %d", count, ev->nodeid);
- break;
-
- case EST_FAIL_ALL_STOPPED:
- ev->fail_all_stopped = 1;
-
- /* when recovering for failed nodes, we immediately stop all
- apps the node was involved with but wait for quorum before
- starting them again */
-
- /* we make sure that cman has updated our quorum status since
- the last node failure */
-
- if (!cman_quorum_updated())
- break;
-
- if (!cman_quorate)
- break;
-
- if (lowest_level(g)) {
- if (all_levels_all_stopped(g, ev)) {
- ev->state = EST_FAIL_START_WAIT;
- do_start = 1;
- } else
- log_group(g, "wait for all_levels_all_stopped");
- } else {
- if (lower_levels_recovered(g)) {
- ev->state = EST_FAIL_START_WAIT;
- do_start = 1;
- } else
- log_group(g, "wait for lower_levels_recovered");
- }
-
- if (!do_start)
- break;
-
- node = find_app_node(a, ev->nodeid);
- if (node) {
- a->node_count--;
- log_group(g, "app node fail: del node %d total %d",
- node->nodeid, a->node_count);
- list_del(&node->list);
- free(node);
- } else
- log_group(g, "app node fail: %d prev removed",
- ev->nodeid);
-
- list_for_each_entry(id, &ev->extended, list) {
- node = find_app_node(a, id->nodeid);
- if (node) {
- a->node_count--;
- log_group(g, "app node fail: del node %d "
- "total %d, ext", node->nodeid,
- a->node_count);
- list_del(&node->list);
- free(node);
- } else
- log_group(g, "app node fail: %d prev removed",
- id->nodeid);
- }
-
- app_start(a);
- break;
-
- case EST_FAIL_ALL_STARTED:
- app_finish(a);
- del_recovery_set(g, ev, 0);
- free_event(ev);
- a->current_event = NULL;
- rv = 1;
- break;
-
- default:
- /*
- log_group(g, "nothing to do: %llx %d %s",
- (unsigned long long)ev->id, ev->nodeid,
- ev_state_str(ev));
- */
- break;
- }
-
- return rv;
-}
-
-static void clear_all_nodes_stopped(app_t *a)
-{
- node_t *node;
- log_group(a->g, "clear_all_nodes_stopped");
- list_for_each_entry(node, &a->nodes, list)
- node->stopped = 0;
-}
-
-static int mark_node_stopped(app_t *a, int nodeid)
-{
- node_t *node;
-
- /* we might get a stopped message from another node who's going
- through X_BEGIN before we get to X_BEGIN ourselves, so we need
- to accept their message if we're in X_BEGIN, too */
-
- if (!event_state_stopping(a) && !event_state_begin(a)) {
- log_error(a->g, "mark_node_stopped: event not stopping/begin: "
- "state %s from %d",
- ev_state_str(a->current_event), nodeid);
- return -1;
- }
-
- node = find_app_node(a, nodeid);
- if (!node) {
- log_error(a->g, "mark_node_stopped: no nodeid %d", nodeid);
- return -1;
- }
-
- log_group(a->g, "mark node %d stopped", nodeid);
-
- node->stopped = 1;
- node->started = 0;
-
- return 0;
-}
-
-static int mark_node_started(app_t *a, int nodeid)
-{
- node_t *node;
-
- if (!event_state_starting(a))
- log_group(a->g, "mark_node_started: event not starting %d "
- "from %d", a->current_event->state, nodeid);
-
- node = find_app_node(a, nodeid);
- if (!node) {
- log_error(a->g, "mark_node_started: no nodeid %d", nodeid);
- return -1;
- }
-
- log_group(a->g, "mark node %d started", nodeid);
-
- node->stopped = 0;
- node->started = 1;
-
- return 0;
-}
-
-static int all_nodes_stopped(app_t *a)
-{
- node_t *node;
-
- list_for_each_entry(node, &a->nodes, list) {
- if (!node->stopped) {
- /* ASSERT(node->started); */
- return FALSE;
- }
- }
- return TRUE;
-}
-
-static int all_nodes_started(app_t *a)
-{
- node_t *node;
-
- list_for_each_entry(node, &a->nodes, list) {
- if (!node->started) {
- /* ASSERT(node->stopped); */
- return FALSE;
- }
- }
- return TRUE;
-}
-
-static int process_app_messages(group_t *g)
-{
- app_t *a = g->app;
- struct save_msg *save, *tmp;
- event_t *ev;
- int rv = 0;
-
- list_for_each_entry_safe(save, tmp, &g->messages, list) {
-
- /* internal messages, sent not by groupd but by apps
- to each other, are delivered to the apps in
- deliver_app_messages() */
-
- if (save->msg.ms_type == MSG_APP_INTERNAL)
- continue;
-
- ev = a->current_event;
-
- if (save->msg.ms_type == MSG_APP_RECOVER) {
- if (ev && ev->state == EST_JOIN_STOP_WAIT &&
- is_our_join(ev)) {
- /* keep this msg around for
- recover_current_event() to see, it will
- be purged later */
- if (!save->print_ignore) {
- log_group(g, "rev %llx taken on node %d",
- (unsigned long long)save->msg.ms_event_id,
- save->nodeid);
- save->print_ignore = 1;
- }
- continue;
- } else {
- goto free_save;
- }
- }
-
-
- if (!ev || ev->id != save->msg.ms_event_id) {
- if (!save->print_ignore) {
- log_group(g, "ignore msg from %d id %llx %s",
- save->nodeid,
- (unsigned long long)save->msg.ms_event_id,
- msg_type(save->msg.ms_type));
- save->print_ignore = 1;
- }
- continue;
- }
-
- switch (save->msg.ms_type) {
-
- case MSG_APP_STOPPED:
- mark_node_stopped(a, save->nodeid);
- break;
-
- case MSG_APP_STARTED:
- mark_node_started(a, save->nodeid);
- break;
-
- default:
- log_error(g, "process_app_messages: invalid type %d "
- "from %d", save->msg.ms_type, save->nodeid);
- }
-
- if (g->global_id == 0 && save->msg.ms_global_id != 0) {
- g->global_id = save->msg.ms_global_id;
- log_group(g, "set global_id %x from %d",
- g->global_id, save->nodeid);
- }
- free_save:
- list_del(&save->list);
- if (save->msg_long)
- free(save->msg_long);
- free(save);
- rv = 1;
- }
-
- /* state changes to X_ALL_STOPPED or X_ALL_STARTED */
-
- if (event_state_stopping(a) && all_nodes_stopped(a))
- a->current_event->state++;
-
- if (event_state_starting(a) && all_nodes_started(a))
- a->current_event->state++;
-
- return rv;
-}
-
-static void deliver_app_messages(group_t *g)
-{
- app_t *a = g->app;
- struct save_msg *save, *tmp;
-
- list_for_each_entry_safe(save, tmp, &g->messages, list) {
- switch (save->msg.ms_type) {
- case MSG_APP_INTERNAL:
- app_deliver(a, save);
- break;
- default:
- continue;
- }
-
- list_del(&save->list);
- if (save->msg_long)
- free(save->msg_long);
- free(save);
- }
-}
-
-event_t *find_queued_recover_event(group_t *g)
-{
- event_t *ev;
-
- list_for_each_entry(ev, &g->app->events, list) {
- if (ev->state == EST_FAIL_BEGIN)
- return ev;
- }
- return NULL;
-}
-
-#if 0
-static int group_started(event_t *ev)
-{
- switch (ev->state) {
- case EST_JOIN_BEGIN:
- case EST_JOIN_STOP_WAIT:
- case EST_JOIN_ALL_STOPPED:
- case EST_LEAVE_BEGIN:
- case EST_LEAVE_STOP_WAIT:
- case EST_LEAVE_ALL_STOPPED:
- case EST_FAIL_BEGIN:
- case EST_FAIL_STOP_WAIT:
- case EST_FAIL_ALL_STOPPED:
- return 0;
- default:
- return 1;
- };
-}
-#endif
-
-void dump_group(group_t *g)
-{
- app_t *a = g->app;
- node_t *node;
- struct save_msg *save;
- event_t *ev;
-
- printf("---\n");
- printf("name: %s\n", g->name);
- printf("level: %d\n", g->level);
- printf("global_id: %u\n", g->global_id);
- printf("cpg handle: %llx\n", (unsigned long long)g->cpg_handle);
- printf("cpg client: %d\n", g->cpg_client);
- printf("app client: %d\n", g->app->client);
-
- printf("memb count: %u\n", g->memb_count);
- printf("memb list: ");
- list_for_each_entry(node, &g->memb, list)
- printf("%d ", node->nodeid);
- printf("\n");
-
- printf("app node count: %u\n", g->app->node_count);
- printf("app node list: ");
- list_for_each_entry(node, &g->app->nodes, list)
- printf("%d ", node->nodeid);
- printf("\n");
-
- printf("saved messages: ");
- list_for_each_entry(save, &g->messages, list)
- printf("%d/%d ", save->nodeid, save->msg.ms_type);
- printf("\n");
-
- if (a->current_event)
- printf("current_event %d-%d\n", a->current_event->nodeid, a->current_event->state);
-
- printf("events: ");
- list_for_each_entry(ev, &a->events, list)
- printf("%d-%d ", ev->nodeid, ev->state);
- printf("\n");
-
- printf("---\n");
-}
-
-void dump_all_groups(void)
-{
- group_t *g;
- list_for_each_entry(g, &gd_groups, list)
- dump_group(g);
-}
-
-/* handle a node failure while processing an event. returning > 0 means
- we want process_current_event() to be called for the group */
-
-int recover_current_event(group_t *g)
-{
- app_t *a = g->app;
- event_t *ev, *rev;
- node_t *node, *us;
- struct save_msg *save;
- struct nodeid *id, *safe;
- int rv = 0;
-
- ev = a->current_event;
- if (!ev)
- return 0;
-
- rev = find_queued_recover_event(g);
- if (!rev)
- return 0;
-
- /* if the current ev is for recovery, we merge the new rev into it;
- if the current ev is still stopping (or all stopped), it just
- continues as usual; if the current ev is starting, the state is
- reset back to FAIL_BEGIN so it goes through a stopping cycle for
- the new node failure that's been added to it */
-
- if (is_recovery_event(ev)) {
- log_group(g, "merge new rev %d into current rev %d %s",
- rev->nodeid, ev->nodeid, ev_state_str(ev));
-
- if (ev->state > EST_FAIL_ALL_STOPPED) {
- ev->state = EST_FAIL_BEGIN;
- ev->fail_all_stopped = 0;
- clear_all_nodes_stopped(a);
- } else if (event_state_stopping(a)) {
- mark_node_stopped(a, rev->nodeid);
- list_for_each_entry(id, &rev->extended, list)
- mark_node_stopped(a, id->nodeid);
- }
-
- id = malloc(sizeof(struct nodeid));
- // FIXME: handle failed malloc
- id->nodeid = rev->nodeid;
- list_add(&id->list, &ev->extended);
- log_group(g, "extend active rev %d with failed node %d",
- ev->nodeid, rev->nodeid);
- list_for_each_entry_safe(id, safe, &rev->extended, list) {
- list_del(&id->list);
- list_add(&id->list, &ev->extended);
- log_group(g, "extend active rev %d with failed node %d",
- ev->nodeid, id->nodeid);
- }
-
- send_recover(g, rev);
- list_del(&rev->list);
- free_event(rev);
- return 1;
- }
-
- /* This is a really gross situation, wish I could find a better way
- to deal with it... (rev's skip ahead of other queued ev's, I think
- that's the root of the difficulties here, we don't know if the
- rev has skipped ahead of our join on remote nodes or not).
-
- If our own join event is current on other nodes, then we want a
- rev (which will replace our join ev once it's starting). If our
- join event isn't current on other nodes, then recovery will occur
- before we're added to the app group and the rev doesn't apply to us
- (apart from needing to remove the failed node from the memb list).
-
- We won't know if our join ev is current on other nodes, though,
- until we see a message -- if the message event id is for our join,
- then our ev is current and we'll process the rev after our ev, if
- the message event id is for the rev, then the rev is being done
- by the current members without us and our ev will be done later;
- the rev doesn't apply to us.
-
- Do nothing until we see a message indicating whether other nodes
- are on our join ev (in which case go to "rev will abort curr" code),
- or whether they're processing this rev (before our join ev comes
- up) in which case we can drop the rev (NB attend to rs, too). */
-
- if (ev->state == EST_JOIN_STOP_WAIT && is_our_join(ev)) {
-
- log_group(g, "rev %d is for group we're waiting to join",
- rev->nodeid);
-
- /* If the failed node is the only other app member apart
- from us in the pending membership list, then we must go
- ahead with our own join event, there will be no remote nodes
- processing a rev or an ev for this group. We send a recover
- message so other nodes waiting to join after us will purge
- their rev on the group. */
-
- if (a->node_count == 2) {
- node = find_app_node(a, rev->nodeid);
- us = find_app_node(a, our_nodeid);
-
- if (node && us) {
- log_group(g, "joining group with one other node"
- " now dead rev %d", rev->nodeid);
- a->node_count--;
- list_del(&node->list);
- free(node);
- send_recover(g, rev);
- del_recovery_set(g, rev, 1);
- list_del(&rev->list);
- free_event(rev);
- return 0;
- }
- }
-
- /* Look for a remote node with stopped of 1, if we find one,
- then fall through to the 'else if (event_state_stopping)'
- below. A remote node with stopped of 1 means we've received
- a stopped message with an event_id of our join event. */
-
- list_for_each_entry(node, &a->nodes, list) {
- if (node->nodeid == our_nodeid)
- continue;
- if (node->stopped) {
- log_group(g, "our join is current on %d",
- node->nodeid);
- log_group(g, "rev %d behind our join ev %llx",
- rev->nodeid,
- (unsigned long long)ev->id);
- goto next;
- }
- }
-
- /* Look through saved messages for one with an event_id
- matching the rev, if we find one, then we get rid of this
- rev and clear this group (that we're joining) from any
- recovery sets that are sequencing recovery of groups the
- failed node was in. The other nodes are processing the
- rev before processing our join ev. */
-
- list_for_each_entry(save, &g->messages, list) {
- if (save->msg.ms_type == MSG_APP_INTERNAL)
- continue;
- if (save->msg.ms_event_id != rev->id)
- continue;
-
- log_group(g, "rev %d %llx ahead of our join ev %llx",
- rev->nodeid,
- (unsigned long long)rev->id,
- (unsigned long long)ev->id);
-
- node = find_app_node(a, rev->nodeid);
- if (node) {
- a->node_count--;
- log_group(g, "not joined, remove %d rev %d",
- node->nodeid, rev->nodeid);
- list_del(&node->list);
- free(node);
- }
- list_for_each_entry(id, &rev->extended, list) {
- node = find_app_node(a, id->nodeid);
- if (node) {
- a->node_count--;
- log_group(g, "not joined, remove %d "
- "rev %d", id->nodeid,
- rev->nodeid);
- list_del(&node->list);
- free(node);
- }
- }
-
- del_recovery_set(g, rev, 1);
- list_del(&rev->list);
- log_group(g, "got rid of rev %d for unjoined group",
- rev->nodeid);
- free_event(rev);
- return 0;
- }
-
- log_group(g, "no messages indicating remote state of group");
- return 0;
- }
-
- next:
- /* Before starting the rev we need to apply the node addition/removal
- * of the current ev to the app. This means processing the current ev
- * up through the starting stage. So, we're sending the app the start
- * to inform it of the ev node change, knowing that the start won't
- * complete due to the node failure (pending rev), and knowing that
- * we'll shortly be sending it a stop and new start for the rev.
- *
- * If the current event is waiting for a "stopped" message from failed
- * node(s), fill in those stopped messages so we move along to the
- * starting state so the recovery event can then take over. */
-
- if (event_state_starting(a) || event_state_all_started(a)) {
- log_group(g, "rev %d replaces current ev %d %s",
- rev->nodeid, ev->nodeid, ev_state_str(ev));
-
- /* what we do for our own join when reaching JOIN_ALL_STARTED */
- if (is_our_join(ev)) {
- purge_messages(g);
- g->joining = 0;
- }
- clear_all_nodes_stopped(a);
- list_del(&rev->list);
- a->current_event = rev;
- free_event(ev);
- send_recover(g, rev);
- rv = 1;
- } else if (event_state_stopping(a)) {
- /* We'll come back through here multiple times until all the
- stopped messages are received; we need to continue to
- process this event that's stopping so it will get to the
- starting state at which point the rev can replace it. */
-
- log_group(g, "rev %d will abort current ev %d %s",
- rev->nodeid, ev->nodeid, ev_state_str(ev));
-
- ev->start_app_before_pending_rev = 1;
-
- mark_node_stopped(a, rev->nodeid);
- list_for_each_entry(id, &rev->extended, list)
- mark_node_stopped(a, id->nodeid);
- rv = 1;
- } else {
- log_group(g, "rev %d delayed for ev %d %s",
- rev->nodeid, ev->nodeid, ev_state_str(ev));
- }
-
- /* FIXME: does the code above work ok if ev->nodeid == rev->noded
- (joining node failed) */
-
- /* FIXME: if the current event is a leave and the leaving node has
- failed, then replace the current event with the rev */
-
- return rv;
-}
-
-int process_app(group_t *g)
-{
- app_t *a = g->app;
- event_t *ev = NULL;
- int rv = 0, ret;
-
- if (a->current_event) {
- rv += process_app_messages(g);
-
- ret = process_current_event(g);
- if (ret < 0)
- goto out;
- rv += ret;
-
- ret = recover_current_event(g);
- if (ret <= 0)
- goto out;
-
- ret = process_current_event(g);
- if (ret < 0)
- goto out;
- rv += ret;
- } else {
-
- /* We only take on a new non-recovery event if there are
- no recovery sets outstanding. The new event may be
- to mount gfs X where there are no living mounters of X,
- and the pending recovery set is to fence a node that
- had X mounted. update: relax this so events are taken
- if there are unrecovered groups _at a lower level_. */
-
- ev = find_queued_recover_event(g);
- if (ev) {
- log_group(g, "set current event to recovery for %d",
- ev->nodeid);
- list_del(&ev->list);
- } else if (!list_empty(&a->events)) {
-#if 0
- if (!cman_quorate) {
- log_group(g, "no new event while inquorate");
- } else if (lower_groups_need_recovery(g)) {
- log_group(g, "no new event while lower level "
- "groups need recovery");
- } else {
- ev = list_entry(a->events.next, event_t, list);
- list_del(&ev->list);
- }
-#endif
- ev = list_entry(a->events.next, event_t, list);
- list_del(&ev->list);
- }
-
- if (ev) {
- a->need_first_event = 0;
- a->current_event = ev;
- rv = process_current_event(g);
- } else if (a->need_first_event) {
- log_group(g, "waiting for first cpg event");
- }
- }
- out:
- return rv;
-}
-
-/* process_apps() will be called again immediately if it returns > 0 */
-
-int process_apps(void)
-{
- group_t *g, *safe;
- int rv = 0;
-
- if (group_mode != GROUP_LIBGROUP)
- return 0;
-
- list_for_each_entry_safe(g, safe, &gd_groups, list) {
- rv += process_app(g);
- deliver_app_messages(g);
- }
-
- return rv;
-}
-
-/* This is a bit of a hack that may not be entirely necessary. The problem
- we're solving with this function is when a node leaves a group and is
- collecting all the "stopped" messages from the remaining members, some
- of those members may fail, so we wouldn't get a stopped message from
- them and never finalize_our_leave (terminate the group). I'm not entirely
- sure that we _need_ to wait for stopped messages from remaining members
- before we do the finalize_our_leave/terminate... The reasoning at this
- point is that when gfs is withdrawing, we want to be sure gfs is
- suspended everywhere before we leave the lockspace (which happens at
- terminate for the withdraw/leave) */
-
-void groupd_down(int nodeid)
-{
- group_t *g;
-
- list_for_each_entry(g, &gd_groups, list) {
- if (g->app &&
- g->app->current_event &&
- g->app->current_event->state == EST_LEAVE_STOP_WAIT &&
- is_our_leave(g->app->current_event)) {
- log_group(g, "groupd down on %d, push our leave",
- nodeid);
- mark_node_stopped(g->app, nodeid);
- }
- }
-}
-
diff --git a/group/daemon/cman.c b/group/daemon/cman.c
deleted file mode 100644
index 0c0bbfa..0000000
--- a/group/daemon/cman.c
+++ /dev/null
@@ -1,206 +0,0 @@
-
-/* Interface with corosync's cman API */
-
-#include <libcman.h>
-#include "gd_internal.h"
-
-static cman_handle_t ch;
-static cman_handle_t ch_admin;
-static int old_quorate;
-static cman_node_t old_nodes[MAX_NODES];
-static int old_node_count;
-static cman_node_t cman_nodes[MAX_NODES];
-static int cman_node_count;
-static char name_buf[CMAN_MAX_NODENAME_LEN+1];
-
-
-int kill_cman(int nodeid)
-{
- return cman_kill_node(ch_admin, nodeid);
-}
-
-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 void statechange(void)
-{
- int i, rv;
-
- old_quorate = cman_quorate;
- old_node_count = cman_node_count;
- memcpy(&old_nodes, &cman_nodes, sizeof(old_nodes));
-
- cman_quorate = cman_is_quorate(ch);
-
- cman_node_count = 0;
- memset(&cman_nodes, 0, sizeof(cman_nodes));
- rv = cman_get_nodes(ch, MAX_NODES, &cman_node_count, cman_nodes);
- if (rv < 0) {
- log_print("cman_get_nodes error %d %d", rv, errno);
- return;
- }
-
- /*
- printf("cman: %d old nodes:\n", old_node_count);
- for (i = 0; i < old_node_count; i++)
- printf("%d:%d ", old_nodes[i].cn_nodeid,
- old_nodes[i].cn_member);
- printf("\n");
-
- printf("cman: %d new nodes:\n", cman_node_count);
- for (i = 0; i < cman_node_count; i++)
- printf("%d:%d ", cman_nodes[i].cn_nodeid,
- cman_nodes[i].cn_member);
- printf("\n");
- */
-
- if (old_quorate && !cman_quorate)
- log_debug("cman: lost quorum");
- if (!old_quorate && cman_quorate)
- log_debug("cman: have quorum");
-
- 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);
- add_recovery_set_cman(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:
- cman_replyto_shutdown(ch, 1);
- break;
- case CMAN_REASON_STATECHANGE:
- statechange();
- break;
- case CMAN_REASON_CONFIG_UPDATE:
- setup_logging();
- break;
- }
-}
-
-void process_cman(int ci)
-{
- int rv;
-
- rv = cman_dispatch(ch, CMAN_DISPATCH_ALL);
- if (rv == -1 && errno == EHOSTDOWN)
- cluster_dead(0);
-}
-
-int setup_cman(void)
-{
- cman_node_t node;
- int rv, fd;
- int init = 0, active = 0;
-
- retry_init:
- ch = cman_init(NULL);
- if (!ch) {
- if (init++ < 2) {
- sleep(1);
- goto retry_init;
- }
- log_print("cman_init error %d", errno);
- return -ENOTCONN;
- }
-
- retry_active:
- rv = cman_is_active(ch);
- if (!rv) {
- if (active++ < 2) {
- sleep(1);
- goto retry_active;
- }
- log_print("cman_is_active error %d", errno);
- cman_finish(ch);
- return -ENOTCONN;
- }
-
- ch_admin = cman_admin_init(NULL);
- if (!ch_admin) {
- log_print("cman_admin_init error %d", errno);
- cman_finish(ch);
- return -ENOTCONN;
- }
-
- rv = cman_start_notification(ch, cman_callback);
- if (rv < 0) {
- log_print("cman_start_notification error %d %d", rv, errno);
- cman_finish(ch);
- cman_finish(ch_admin);
- return rv;
- }
-
- memset(&node, 0, sizeof(node));
- rv = cman_get_node(ch, CMAN_NODEID_US, &node);
- if (rv < 0) {
- log_print("cman_get_node us error %d %d", rv, errno);
- cman_stop_notification(ch);
- cman_finish(ch);
- cman_finish(ch_admin);
- return rv;
- }
-
- cman_node_count = 0;
- memset(&cman_nodes, 0, sizeof(cman_nodes));
- rv = cman_get_nodes(ch, MAX_NODES, &cman_node_count, cman_nodes);
- if (rv < 0) {
- log_print("cman_get_nodes error %d %d", rv, errno);
- cman_stop_notification(ch);
- cman_finish(ch);
- cman_finish(ch_admin);
- return rv;
- }
-
- cman_quorate = cman_is_quorate(ch);
-
- memset(name_buf, 0, sizeof(name_buf));
- strncpy(name_buf, node.cn_name, CMAN_MAX_NODENAME_LEN);
- our_name = name_buf;
- our_nodeid = node.cn_nodeid;
- log_debug("cman: our nodeid %d name %s quorum %d",
- our_nodeid, our_name, cman_quorate);
-
- fd = cman_get_fd(ch);
-
- return fd;
-}
-
-void close_cman(void)
-{
- cman_finish(ch);
- cman_finish(ch_admin);
-}
-
diff --git a/group/daemon/cpg.c b/group/daemon/cpg.c
deleted file mode 100644
index 6195d49..0000000
--- a/group/daemon/cpg.c
+++ /dev/null
@@ -1,1072 +0,0 @@
-
-/* Interface with corosync's closed-process-group (cpg) API */
-
-#include "gd_internal.h"
-
-static cpg_handle_t groupd_handle;
-static struct cpg_name groupd_name;
-static int global_id_counter = 0;
-static int groupd_joined = 0;
-static int groupd_ci;
-
-static int got_confchg;
-static struct cpg_address groupd_cpg_member[MAX_GROUP_MEMBERS];
-static int groupd_cpg_member_count;
-static struct cpg_address saved_member[MAX_GROUP_MEMBERS];
-static struct cpg_address saved_joined[MAX_GROUP_MEMBERS];
-static struct cpg_address saved_left[MAX_GROUP_MEMBERS];
-static int saved_member_count;
-static int saved_joined_count;
-static int saved_left_count;
-static cpg_handle_t saved_handle;
-static struct cpg_name saved_name;
-static int message_flow_control_on;
-static struct list_head group_nodes;
-static uint64_t send_version_first;
-
-#define CLUSTER2 2
-#define CLUSTER3 3
-
-struct group_version {
- uint32_t nodeid;
- uint16_t cluster;
- uint16_t group_mode;
- uint16_t groupd_compat;
- uint16_t groupd_count;
- uint32_t unused;
-};
-
-struct group_node {
- uint32_t nodeid;
- uint32_t got_from;
- int got_version;
- uint64_t add_time;
- struct group_version ver;
- struct list_head list;
-};
-
-static void block_old_nodes(void);
-
-static char *mode_str(int m)
-{
- switch (m) {
- case GROUP_PENDING:
- return "PENDING";
- case GROUP_LIBGROUP:
- return "LIBGROUP";
- case GROUP_LIBCPG:
- return "LIBCPG";
- default:
- return "UNKNOWN";
- }
-}
-
-static struct group_node *get_group_node(int nodeid)
-{
- struct group_node *node;
-
- list_for_each_entry(node, &group_nodes, list) {
- if (node->nodeid == nodeid)
- return node;
- }
- return NULL;
-}
-
-static void group_node_add(int nodeid)
-{
- struct group_node *node;
-
- node = get_group_node(nodeid);
- if (node)
- return;
-
- node = malloc(sizeof(struct group_node));
- if (!node)
- return;
- memset(node, 0, sizeof(struct group_node));
-
- node->nodeid = nodeid;
- node->add_time = time(NULL);
- list_add_tail(&node->list, &group_nodes);
-}
-
-static void group_node_del(int nodeid)
-{
- struct group_node *node;
-
- node = get_group_node(nodeid);
- if (!node) {
- log_print("group_node_del %d no node", nodeid);
- return;
- }
-
- list_del(&node->list);
- free(node);
-}
-
-static void version_copy_in(struct group_version *ver)
-{
- ver->nodeid = le32_to_cpu(ver->nodeid);
- ver->cluster = le16_to_cpu(ver->cluster);
- ver->group_mode = le16_to_cpu(ver->group_mode);
- ver->groupd_compat = le16_to_cpu(ver->groupd_compat);
- ver->groupd_count = le16_to_cpu(ver->groupd_count);
-}
-
-static void _send_version(int nodeid, int cluster, int mode, int compat)
-{
- group_t g, *gp;
- char *buf;
- msg_t *msg;
- int len;
- int count = 0;
- struct group_version *ver;
-
- list_for_each_entry(gp, &gd_groups, list)
- count++;
-
- /* just so log_group will work */
- memset(&g, 0, sizeof(group_t));
- strcpy(g.name, "groupd");
-
- len = sizeof(msg_t) + sizeof(struct group_version);
-
- buf = malloc(len);
- if (!buf)
- return;
- memset(buf, 0, len);
-
- msg = (msg_t *)buf;
- ver = (struct group_version *)(buf + sizeof(msg_t));
-
- msg->ms_type = MSG_GROUP_VERSION;
- msg_bswap_out(msg);
-
- log_debug("send_version nodeid %d cluster %d mode %s compat %d",
- nodeid, cluster, mode_str(mode), compat);
-
- ver->nodeid = cpu_to_le32(nodeid);
- ver->cluster = cpu_to_le16(cluster);
- ver->group_mode = cpu_to_le16(mode);
- ver->groupd_compat = cpu_to_le16(compat);
- ver->groupd_count = cpu_to_le16(count);
-
- send_message_groupd(&g, buf, len, MSG_GROUP_VERSION);
-}
-
-static void send_version(void)
-{
- _send_version(our_nodeid, CLUSTER3, group_mode, cfgd_groupd_compat);
-}
-
-static void set_group_mode(void)
-{
- struct group_node *node;
- int need_version, pending_count;
-
- need_version = 0;
- pending_count = 0;
-
- list_for_each_entry(node, &group_nodes, list) {
- if (!node->got_version) {
- need_version++;
- continue;
- }
- if (node->ver.group_mode == GROUP_PENDING) {
- pending_count++;
- continue;
- }
-
- /* If we receive any non-pending group mode, adopt it
- immediately. */
-
- group_mode = node->ver.group_mode;
-
- switch (group_mode) {
- case GROUP_PENDING:
- /* shouldn't happen */
- log_level(LOG_INFO, "groupd compatibility mode 2 ver");
- break;
- case GROUP_LIBGROUP:
- log_level(LOG_INFO, "groupd compatibility mode 1 ver");
- break;
- case GROUP_LIBCPG:
- log_level(LOG_INFO, "groupd compatibility mode 0 ver");
- break;
- default:
- log_level(LOG_INFO, "groupd compatibility mode %d ver",
- group_mode);
- break;
- }
-
- log_debug("set_group_mode %s matching nodeid %d got_from %d",
- mode_str(group_mode), node->nodeid, node->got_from);
- break;
- }
-
- if (group_mode == GROUP_LIBCPG)
- block_old_nodes();
-}
-
-static void receive_version(int from, msg_t *msg, int len)
-{
- struct group_node *node;
- struct group_version *ver;
-
- if (group_mode != GROUP_PENDING)
- return;
-
- ver = (struct group_version *)((char *)msg + sizeof(msg_t));
-
- version_copy_in(ver);
-
- node = get_group_node(ver->nodeid);
- if (!node) {
- log_print("receive_version from %d nodeid %d not found",
- from, ver->nodeid);
- return;
- }
-
- /* ignore a repeat of what we've seen before */
-
- if (node->got_version && from == node->got_from &&
- node->ver.group_mode == ver->group_mode)
- return;
-
- log_debug("receive_version from %d nodeid %d cluster %d mode %s "
- "compat %d", from, ver->nodeid, ver->cluster,
- mode_str(ver->group_mode), ver->groupd_compat);
-
- node->got_version = 1;
- node->got_from = from;
- memcpy(&node->ver, ver, sizeof(struct group_version));
-
- set_group_mode();
-}
-
-void group_mode_check_timeout(void)
-{
- struct group_node *node;
- int need_version, pending_count;
- uint64_t now;
-
- if (group_mode != GROUP_PENDING)
- return;
-
- if (!send_version_first)
- return;
-
- /* Wait for cfgd_groupd_wait seconds to receive a version message from
- an added node, after which we'll send a version message for it,
- calling it a cluster2 node; receiving this will cause everyone to
- immediately set mode to LIBGROUP. */
-
- need_version = 0;
- pending_count = 0;
- now = time(NULL);
-
- list_for_each_entry(node, &group_nodes, list) {
- if (node->got_version) {
- pending_count++;
- continue;
- }
- need_version++;
-
- if (now - node->add_time >= cfgd_groupd_wait) {
- log_print("send version for nodeid %d times %llu %llu",
- node->nodeid,
- (unsigned long long)node->add_time,
- (unsigned long long)now);
- _send_version(node->nodeid, CLUSTER2, GROUP_LIBGROUP,1);
- }
- }
-
- if (need_version) {
- log_debug("group_mode_check_timeout need %d pending %d",
- need_version, pending_count);
- return;
- }
-
- /* we have a version from everyone, and they all are pending;
- wait for cfgd_groupd_mode_delay to give any old cluster2 nodes
- a chance to join and cause us to use LIBGROUP */
-
- if (now - send_version_first < cfgd_groupd_mode_delay) {
- log_debug("group_mode_check_timeout delay times %llu %llu",
- (unsigned long long)send_version_first,
- (unsigned long long)now);
- return;
- }
-
- /* everyone is cluster3/pending so we can use LIBCPG; receiving
- this will cause everyone to immediately set mode to LIBCPG */
-
- log_debug("send version LIBCPG all %d pending", pending_count);
-
- _send_version(our_nodeid, CLUSTER3, GROUP_LIBCPG, cfgd_groupd_compat);
-}
-
-static node_t *find_group_node(group_t *g, int nodeid)
-{
- node_t *node;
-
- list_for_each_entry(node, &g->memb, list) {
- if (node->nodeid == nodeid)
- return node;
- }
- return NULL;
-}
-
-static void process_node_down(group_t *g, int nodeid)
-{
- node_t *node;
- event_t *ev, *ev_safe;
- int no_rev = 0;
-
- node = find_group_node(g, nodeid);
- if (!node)
- return;
-
- log_group(g, "process_node_down %d", nodeid);
-
- list_del(&node->list);
- g->memb_count--;
- free(node);
-
- log_group(g, "cpg del node %d total %d - down",
- nodeid, g->memb_count);
-
- /* purge any queued join/leave events from the dead node */
-
- list_for_each_entry_safe(ev, ev_safe, &g->app->events, list) {
- if (ev->nodeid != nodeid)
- continue;
-
- if (ev->state == EST_JOIN_BEGIN ||
- ev->state == EST_LEAVE_BEGIN) {
- if (ev->state == EST_JOIN_BEGIN)
- no_rev = 1;
-
- log_group(g, "purge event %s from %d", ev_state_str(ev),
- nodeid);
- del_event_nodes(ev);
- list_del(&ev->list);
- free(ev);
- }
- }
-
- /* the failed node was never added to the app, so the app
- doesn't need to be recovered for it */
- if (no_rev)
- return;
-
- ev = find_queued_recover_event(g);
- if (ev)
- extend_recover_event(g, ev, nodeid);
- else
- queue_app_recover(g, nodeid);
-}
-
-static void process_node_join(group_t *g, int nodeid)
-{
- node_t *node;
- int i;
-
- log_group(g, "process_node_join %d", nodeid);
-
- if (nodeid == our_nodeid) {
- for (i = 0; i < saved_member_count; i++) {
- node = new_node(saved_member[i].nodeid);
- list_add_tail(&node->list, &g->memb);
- g->memb_count++;
- log_group(g, "cpg add node %d total %d",
- node->nodeid, g->memb_count);
- }
-
- /* if we're the first one to join (create) the group,
- then set its global_id */
-
- if (saved_member_count == 1) {
- g->global_id = (++global_id_counter << 16) |
- (0x0000FFFF & our_nodeid);
- log_group(g, "create group id %x our_nodeid %d",
- g->global_id, our_nodeid);
- }
- } else {
- node = new_node(nodeid);
- list_add_tail(&node->list, &g->memb);
- g->memb_count++;
- log_group(g, "cpg add node %d total %d",
- node->nodeid, g->memb_count);
- }
-
- queue_app_join(g, nodeid);
-
- /* if this is for our own join, then make it current immediately;
- other code gets confused if we're not joined and have no current
- event */
- if (nodeid == our_nodeid)
- process_app(g);
-}
-
-static void process_node_leave(group_t *g, int nodeid)
-{
- node_t *node;
-
- log_group(g, "process_node_leave %d", nodeid);
-
- node = find_group_node(g, nodeid);
- if (!node) {
- log_error(g, "process_node_leave: no member %d", nodeid);
- return;
- }
-
- list_del(&node->list);
- g->memb_count--;
- free(node);
-
- log_group(g, "cpg del node %d total %d", nodeid, g->memb_count);
-
- queue_app_leave(g, nodeid);
-}
-
-static uint32_t max_global_id(uint32_t add_nodeid)
-{
- group_t *g;
- uint32_t nodeid, counter, max_counter = 0, max_gid = 0;
-
- list_for_each_entry(g, &gd_groups, list) {
- nodeid = g->global_id & 0x0000FFFF;
- counter = (g->global_id >> 16) & 0x0000FFFF;
- if (nodeid != add_nodeid)
- continue;
- if (!max_counter || counter > max_counter) {
- max_counter = counter;
- max_gid = g->global_id;
- }
- }
- return max_gid;
-}
-
-static int send_gid(uint32_t gid)
-{
- group_t g;
- msg_t msg;
-
- /* just so log_group will work */
- memset(&g, 0, sizeof(group_t));
- strcpy(g.name, "groupd");
-
- memset(&msg, 0, sizeof(msg));
- msg.ms_type = MSG_GLOBAL_ID;
- msg.ms_global_id = gid;
-
- msg_bswap_out(&msg);
-
- return send_message_groupd(&g, &msg, sizeof(msg), MSG_GLOBAL_ID);
-}
-
-void process_groupd_confchg(void)
-{
- group_t *g;
- struct recovery_set *rs;
- int i, found = 0;
- uint32_t gid;
-
- log_debug("groupd confchg total %d left %d joined %d",
- saved_member_count, saved_left_count, saved_joined_count);
-
- if (!send_version_first) {
- for (i = 0; i < saved_member_count; i++) {
- group_node_add(saved_member[i].nodeid);
- log_debug("groupd init %d", saved_member[i].nodeid);
- }
-
- send_version_first = time(NULL);
- } else {
- for (i = 0; i < saved_left_count; i++) {
- group_node_del(saved_left[i].nodeid);
- log_debug("groupd del %d", saved_left[i].nodeid);
- }
- for (i = 0; i < saved_joined_count; i++) {
- group_node_add(saved_joined[i].nodeid);
- log_debug("groupd add %d", saved_joined[i].nodeid);
- }
- }
-
- if (saved_joined_count)
- send_version();
-
- memcpy(&groupd_cpg_member, &saved_member, sizeof(saved_member));
- groupd_cpg_member_count = saved_member_count;
-
- if (group_mode != GROUP_LIBGROUP)
- return;
-
- for (i = 0; i < saved_member_count; i++) {
- if (saved_member[i].nodeid == our_nodeid &&
- saved_member[i].pid == (uint32_t) getpid()) {
- found = 1;
- }
- }
-
- if (!groupd_joined)
- goto next;
-
- /* find any groups that were created in the past by a new node
- and send it the id it used so it can initialize global_id_counter
- to avoid creating a new group with a duplicate id */
-
- for (i = 0; i < saved_joined_count; i++) {
- gid = max_global_id(saved_joined[i].nodeid);
- if (!gid)
- continue;
- log_debug("joined node %d had old max gid %x",
- saved_joined[i].nodeid, gid);
- send_gid(gid);
- }
-
- next:
- if (found)
- groupd_joined = 1;
- else
- log_print("we are not in groupd confchg: %u %u",
- our_nodeid, (uint32_t) getpid());
-
- for (i = 0; i < saved_left_count; i++) {
- if (saved_left[i].reason == CPG_REASON_LEAVE)
- continue;
-
- if (saved_left[i].reason == CPG_REASON_NODEDOWN) {
- /* a nice clean failure */
- add_recovery_set_cpg(saved_left[i].nodeid, 0);
- } else if (saved_left[i].reason == CPG_REASON_PROCDOWN) {
- /* groupd failed, but the node is still up; if
- the node was in any groups (non-NULL rs is
- returned), then kill the node so it'll be a
- real nodedown */
- rs = add_recovery_set_cpg(saved_left[i].nodeid, 1);
- if (rs) {
- log_print("kill node %d - groupd PROCDOWN",
- saved_left[i].nodeid);
- kill_cman(saved_left[i].nodeid);
- }
- }
- groupd_down(saved_left[i].nodeid);
- }
-
- /* we call process_node_down from here, instead of from the other cpg
- confchg's because we want everyone to see the same order of
- confchg's with respect to messages. see bz 258121 */
-
- for (i = 0; i < saved_left_count; i++) {
- if (saved_left[i].reason == CPG_REASON_NODEDOWN ||
- saved_left[i].reason == CPG_REASON_PROCDOWN) {
- list_for_each_entry(g, &gd_groups, list)
- process_node_down(g, saved_left[i].nodeid);
- }
- }
-}
-
-void copy_groupd_data(group_data_t *data)
-{
- int i;
-
- data->level = -1;
- data->member_count = groupd_cpg_member_count;
- for (i = 0; i < groupd_cpg_member_count; i++)
- data->members[i] = groupd_cpg_member[i].nodeid;
-}
-
-int in_groupd_cpg(int nodeid)
-{
- int i;
- for (i = 0; i < groupd_cpg_member_count; i++) {
- if (nodeid == groupd_cpg_member[i].nodeid)
- return 1;
- }
- return 0;
-}
-
-group_t *find_group_by_handle(cpg_handle_t h)
-{
- group_t *g;
-
- list_for_each_entry(g, &gd_groups, list) {
- if (g->cpg_handle == h)
- return g;
- }
- return NULL;
-}
-
-void deliver_cb(cpg_handle_t handle, struct cpg_name *group_name,
- uint32_t nodeid, uint32_t pid, void *data, int data_len)
-{
- group_t *g;
- struct save_msg *save;
- msg_t *msg = (msg_t *) data;
- char *buf;
- char name[MAX_NAMELEN+1];
- uint32_t to_nodeid, counter;
- int len;
-
- memset(&name, 0, sizeof(name));
-
- msg_bswap_in(msg);
-
- if (msg->ms_type == MSG_GROUP_VERSION) {
- receive_version(nodeid, msg, data_len);
- return;
- }
-
- if (msg->ms_type == MSG_GLOBAL_ID) {
- to_nodeid = msg->ms_global_id & 0x0000FFFF;
- counter = (msg->ms_global_id >> 16) & 0x0000FFFF;
-
- if (to_nodeid == our_nodeid) {
- log_debug("recv global_id %x from %u cur counter %u",
- msg->ms_global_id, nodeid, global_id_counter);
- if (counter > global_id_counter)
- global_id_counter = counter;
- }
- return;
- }
-
- if (handle == groupd_handle) {
- memcpy(&name, &msg->ms_name, MAX_NAMELEN);
-
- g = find_group_level(name, msg->ms_level);
- if (!g) {
- if (daemon_debug_verbose > 1) {
- log_print("%d:%s RECV len %d %s from %d, "
- "no group",
- msg->ms_level, name, data_len,
- msg_type(msg->ms_type), nodeid);
- }
- return;
- }
- } else {
- if (group_mode != GROUP_LIBGROUP)
- return;
-
- g = find_group_by_handle(handle);
- if (!g) {
- len = group_name->length;
- if (len > MAX_NAMELEN)
- len = MAX_NAMELEN;
- memcpy(&name, &group_name->value, len);
-
- log_print("deliver_cb no group handle %llx name %s",
- (unsigned long long)handle, name);
- return;
- }
- }
-
- if (daemon_debug_verbose > 1)
- log_group(g, "RECV len %d %s from %d", data_len,
- msg_type(msg->ms_type), nodeid);
-
- save = malloc(sizeof(struct save_msg));
- // FIXME: handle failed malloc
- memset(save, 0, sizeof(struct save_msg));
- save->nodeid = nodeid;
- save->msg_len = data_len;
-
- if (data_len > sizeof(msg_t)) {
- buf = malloc(data_len);
- // FIXME: handle failed malloc
- memcpy(buf, data, data_len);
- save->msg_long = buf;
- memcpy(&save->msg, data, sizeof(msg_t));
- } else
- memcpy(&save->msg, data, sizeof(msg_t));
-
- queue_app_message(g, save);
-}
-
-void process_confchg(void)
-{
- group_t *g;
- int i;
-
- if (saved_handle == groupd_handle) {
- process_groupd_confchg();
- return;
- }
-
- if (group_mode != GROUP_LIBGROUP)
- return;
-
- g = find_group_by_handle(saved_handle);
- if (!g) {
- log_debug("confchg: no group for handle %llx name %s",
- (unsigned long long)saved_handle,
- saved_name.value);
- return;
- }
-
- log_group(g, "confchg left %d joined %d total %d",
- saved_left_count, saved_joined_count, saved_member_count);
-
- for (i = 0; i < saved_joined_count; i++)
- process_node_join(g, saved_joined[i].nodeid);
-
- for (i = 0; i < saved_left_count; i++) {
- log_group(g, "confchg removed node %d reason %d",
- saved_left[i].nodeid, saved_left[i].reason);
-
- switch (saved_left[i].reason) {
- case CPG_REASON_LEAVE:
- process_node_leave(g, saved_left[i].nodeid);
- break;
- case CPG_REASON_NODEDOWN:
- case CPG_REASON_PROCDOWN:
- /* process_node_down(g, saved_left[i].nodeid); */
- purge_node_messages(g, saved_left[i].nodeid);
- break;
- default:
- log_error(g, "unknown leave reason %d node %d",
- saved_left[i].reason,
- saved_joined[i].nodeid);
- }
- }
-}
-
-void confchg_cb(cpg_handle_t handle, struct cpg_name *group_name,
- struct cpg_address *member_list, int member_list_entries,
- struct cpg_address *left_list, int left_list_entries,
- struct cpg_address *joined_list, int joined_list_entries)
-{
- group_t *g;
- char *name = "unknown";
- int i, level = -1;
-
- if (handle == groupd_handle)
- name = "groupd";
- else {
- g = find_group_by_handle(handle);
- if (g) {
- name = g->name;
- level = g->level;
- }
- }
-
- /*
- log_debug("%d:%s confchg_cb total %d left %d joined %d", level, name,
- member_list_entries, left_list_entries, joined_list_entries);
- */
-
- saved_handle = handle;
-
- if (left_list_entries > MAX_GROUP_MEMBERS) {
- log_debug("left_list_entries %d", left_list_entries);
- left_list_entries = MAX_GROUP_MEMBERS;
- }
- if (joined_list_entries > MAX_GROUP_MEMBERS) {
- log_debug("joined_list_entries %d", joined_list_entries);
- joined_list_entries = MAX_GROUP_MEMBERS;
- }
- if (member_list_entries > MAX_GROUP_MEMBERS) {
- log_debug("member_list_entries %d", joined_list_entries);
- member_list_entries = MAX_GROUP_MEMBERS;
- }
-
- saved_left_count = left_list_entries;
- saved_joined_count = joined_list_entries;
- saved_member_count = member_list_entries;
-
- memset(&saved_name, 0, sizeof(saved_name));
- saved_name.length = group_name->length;
- memcpy(&saved_name.value, &group_name->value, group_name->length);
-
- for (i = 0; i < left_list_entries; i++)
- saved_left[i] = left_list[i];
-
- for (i = 0; i < joined_list_entries; i++)
- saved_joined[i] = joined_list[i];
-
- for (i = 0; i < member_list_entries; i++)
- saved_member[i] = member_list[i];
-
- got_confchg = 1;
-}
-
-cpg_callbacks_t callbacks = {
- .cpg_deliver_fn = deliver_cb,
- .cpg_confchg_fn = confchg_cb,
-};
-
-void process_cpg(int ci)
-{
- group_t *g = NULL;
- cpg_error_t error;
- cpg_handle_t handle;
- int found = 0;
- cpg_flow_control_state_t flow_control_state;
-
- if (ci == groupd_ci) {
- handle = groupd_handle;
- goto dispatch;
- }
-
- list_for_each_entry(g, &gd_groups, list) {
- if (g->cpg_client == ci) {
- handle = g->cpg_handle;
- found = 1;
- break;
- }
- }
-
- if (!found) {
- log_print("process_cpg: no group found for ci %d", ci);
- sleep(1);
- return;
- }
-
- dispatch:
- got_confchg = 0;
-
- error = cpg_dispatch(handle, CPG_DISPATCH_ONE);
- if (error != CPG_OK) {
- log_print("cpg_dispatch error %d", error);
- return;
- }
-
- error = cpg_flow_control_state_get(handle, &flow_control_state);
- if (error != CPG_OK)
- log_error(g, "cpg_flow_control_state_get %d", error);
- else if (flow_control_state == CPG_FLOW_CONTROL_ENABLED) {
- message_flow_control_on = 1;
- log_debug("flow control on");
- } else {
- if (message_flow_control_on)
- log_debug("flow control off");
- message_flow_control_on = 0;
- }
-
- if (got_confchg)
- process_confchg();
-}
-
-int setup_cpg(void)
-{
- cpg_error_t error;
- int fd;
-
- INIT_LIST_HEAD(&group_nodes);
-
- error = cpg_initialize(&groupd_handle, &callbacks);
- if (error != CPG_OK) {
- log_print("cpg_initialize error %d", error);
- return error;
- }
-
- cpg_fd_get(groupd_handle, &fd);
-
- groupd_ci = client_add(fd, process_cpg, NULL);
-
- memset(&groupd_name, 0, sizeof(groupd_name));
- strcpy(groupd_name.value, "groupd");
- groupd_name.length = 7;
-
- retry:
- error = cpg_join(groupd_handle, &groupd_name);
- if (error == CPG_ERR_TRY_AGAIN) {
- log_debug("setup_cpg cpg_join retry");
- sleep(1);
- goto retry;
- }
- if (error != CPG_OK) {
- log_print("cpg_join error %d", error);
- cpg_finalize(groupd_handle);
- return error;
- }
-
- log_debug("setup_cpg groupd_handle %llx",
- (unsigned long long)groupd_handle);
-
- return 0;
-}
-
-int do_cpg_join(group_t *g)
-{
- cpg_error_t error;
- cpg_handle_t h;
- struct cpg_name name;
- int fd, ci, i = 0;
-
- error = cpg_initialize(&h, &callbacks);
- if (error != CPG_OK) {
- log_group(g, "cpg_initialize error %d", error);
- return error;
- }
-
- cpg_fd_get(h, &fd);
-
- ci = client_add(fd, process_cpg, NULL);
-
- g->cpg_client = ci;
- g->cpg_handle = h;
- g->cpg_fd = fd;
-
- memset(&name, 0, sizeof(name));
- sprintf(name.value, "%d_%s", g->level, g->name);
- name.length = strlen(name.value) + 1;
-
- log_group(g, "is cpg client %d name %s handle %llx", ci, name.value,
- (unsigned long long)h);
-
- retry:
- error = cpg_join(h, &name);
- if (error == CPG_ERR_TRY_AGAIN) {
- log_debug("cpg_join error retry");
- sleep(1);
- if (!(++i % 10))
- log_error(g, "cpg_join error retrying");
- goto retry;
- }
- if (error != CPG_OK) {
- log_group(g, "cpg_join error %d", error);
- cpg_finalize(h);
- return error;
- }
-
- log_group(g, "cpg_join ok");
- return 0;
-}
-
-int do_cpg_leave(group_t *g)
-{
- cpg_error_t error;
- struct cpg_name name;
- int i = 0;
-
- memset(&name, 0, sizeof(name));
- sprintf(name.value, "%d_%s", g->level, g->name);
- name.length = strlen(name.value) + 1;
-
- retry:
- error = cpg_leave(g->cpg_handle, &name);
- if (error == CPG_ERR_TRY_AGAIN) {
- log_debug("cpg_leave error retry");
- sleep(1);
- if (!(++i % 10))
- log_error(g, "cpg_leave error retrying");
- goto retry;
- }
- if (error != CPG_OK) {
- log_group(g, "cpg_leave error %d", error);
- return error;
- }
-
- log_group(g, "cpg_leave ok");
- return 0;
-}
-
-static int _send_message(cpg_handle_t h, group_t *g, void *buf, int len)
-{
- struct iovec iov;
- cpg_error_t error;
- int retries = 0;
-
- iov.iov_base = buf;
- iov.iov_len = len;
-
- retry:
- error = cpg_mcast_joined(h, CPG_TYPE_AGREED, &iov, 1);
- if (error == CPG_ERR_TRY_AGAIN) {
- retries++;
- usleep(1000);
- if (!(retries % 100))
- log_error(g, "cpg_mcast_joined retry %d", retries);
- goto retry;
- } else if (error != CPG_OK)
- log_error(g, "cpg_mcast_joined error %d handle %llx", error,
- (unsigned long long)h);
-
- if (retries)
- log_group(g, "cpg_mcast_joined retried %d", retries);
-
- return 0;
-}
-
-int send_message_groupd(group_t *g, void *buf, int len, int type)
-{
- if (daemon_debug_verbose > 1)
- log_group(g, "SEND len %d %s", len, msg_type(type));
-
- return _send_message(groupd_handle, g, buf, len);
-}
-
-int send_message(group_t *g, void *buf, int len)
-{
- return _send_message(g->cpg_handle, g, buf, len);
-}
-
-static void block_old_group(char *name, int level)
-{
- group_t *g;
- app_t *a;
- cpg_error_t error;
- cpg_handle_t h;
- struct cpg_name cpgname;
- int rv, fd, ci, i = 0;
-
- rv = create_group(name, level, &g);
- if (rv)
- return;
- a = create_app(g);
- if (!a)
- return;
-
- error = cpg_initialize(&h, &callbacks);
- if (error != CPG_OK) {
- log_print("cpg_initialize error %d", error);
- return;
- }
-
- cpg_fd_get(h, &fd);
-
- ci = client_add(fd, process_cpg, NULL);
-
- g->cpg_client = ci;
- g->cpg_handle = h;
- g->cpg_fd = fd;
- g->joining = 1;
- a->client = ci;
-
- memset(&cpgname, 0, sizeof(cpgname));
- sprintf(cpgname.value, "%d_%s", level, name);
- cpgname.length = strlen(cpgname.value) + 1;
-
- retry:
- error = cpg_join(h, &cpgname);
- if (error == CPG_ERR_TRY_AGAIN) {
- log_debug("cpg_join error retry");
- sleep(1);
- if (!(++i % 10))
- log_print("cpg_join error retrying");
- goto retry;
- }
- if (error != CPG_OK) {
- log_print("cpg_join error %d", error);
- cpg_finalize(h);
- return;
- }
-}
-
-/* Problem: GROUP_LIBCPG is selected during version detection, then
- an old cluster2 node starts (people aren't supposed to do this, but it may
- happen, so it's nice to do what we can to address it). groupd on the old
- cluster2 node, using libgroup, will allow new groups to be formed on it.
- Solution is a hack: when the cluster3 nodes select LIBCPG mode, they also
- create unused/placeholder cpg's with the names of old known cluster2 groups,
- which blocks them being fully joined by old groupd's that may come along. */
-
-static void block_old_nodes(void)
-{
- block_old_group("default", 0);
- block_old_group("clvmd", 1);
- block_old_group("rgmanager", 1);
-}
-
diff --git a/group/daemon/gd_internal.h b/group/daemon/gd_internal.h
deleted file mode 100644
index 1927104..0000000
--- a/group/daemon/gd_internal.h
+++ /dev/null
@@ -1,323 +0,0 @@
-#ifndef __GD_INTERNAL_DOT_H__
-#define __GD_INTERNAL_DOT_H__
-
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stddef.h>
-#include <fcntl.h>
-#include <string.h>
-#include <strings.h>
-#include <ctype.h>
-#include <dirent.h>
-#include <syslog.h>
-#include <time.h>
-#include <sched.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/types.h>
-#include <sys/errno.h>
-#include <sys/poll.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <corosync/cpg.h>
-#include <liblogthread.h>
-
-#include "list.h"
-#include "linux_endian.h"
-#include "groupd.h"
-#include "libgroup.h"
-
-#define MAX_NAMELEN 32 /* should match libgroup.h */
-#define MAX_LEVELS 4
-#define MAX_NODES 128
-
-extern int daemon_debug_opt;
-extern int daemon_debug_verbose;
-extern int daemon_quit;
-extern int cman_quorate;
-extern int our_nodeid;
-extern char *our_name;
-extern char daemon_debug_buf[256];
-extern char dump_buf[GROUPD_DUMP_SIZE];
-extern int dump_point;
-extern int dump_wrap;
-extern struct list_head gd_groups;
-extern struct list_head gd_levels[MAX_LEVELS];
-extern uint32_t gd_event_nr;
-
-#define GROUP_PENDING 1
-#define GROUP_LIBGROUP 2
-#define GROUP_LIBCPG 3
-
-extern int group_mode;
-
-#define DEFAULT_GROUPD_COMPAT 2
-#define DEFAULT_GROUPD_WAIT 5
-#define DEFAULT_GROUPD_MODE_DELAY 2
-#define DEFAULT_DEBUG_LOGFILE 0
-
-extern int optd_groupd_compat;
-extern int optd_groupd_wait;
-extern int optd_groupd_mode_delay;
-extern int optd_debug_logfile;
-
-extern int cfgd_groupd_compat;
-extern int cfgd_groupd_wait;
-extern int cfgd_groupd_mode_delay;
-extern int cfgd_debug_logfile;
-
-void daemon_dump_save(void);
-
-#define log_level(lvl, fmt, args...) \
-do { \
- snprintf(daemon_debug_buf, 255, "%ld " fmt "\n", time(NULL), ##args); \
- daemon_dump_save(); \
- logt_print(lvl, fmt "\n", ##args); \
- if (daemon_debug_opt) \
- fprintf(stderr, "%s", daemon_debug_buf); \
-} while (0)
-
-#define log_debug(fmt, args...) log_level(LOG_DEBUG, fmt, ##args)
-#define log_print(fmt, args...) log_level(LOG_ERR, fmt, ##args)
-
-#define log_group(g, fmt, args...) \
-do { \
- snprintf(daemon_debug_buf, 255, "%ld %d:%s " fmt "\n", time(NULL), \
- (g)->level, (g)->name, ##args); \
- daemon_dump_save(); \
- logt_print(LOG_DEBUG, fmt "\n", ##args); \
- if (daemon_debug_opt) \
- fprintf(stderr, "%s", daemon_debug_buf); \
-} while (0)
-
-#define log_error(g, fmt, args...) \
-do { \
- snprintf(daemon_debug_buf, 255, "%ld %d:%s " fmt "\n", time(NULL), \
- (g)->level, (g)->name, ##args); \
- daemon_dump_save(); \
- logt_print(LOG_ERR, fmt "\n", ##args); \
- if (daemon_debug_opt) \
- fprintf(stderr, "%s", daemon_debug_buf); \
-} while (0)
-
-#define ASSERT(x) \
-do { \
- if (!(x)) { \
- log_print("Assertion failed on line %d of file %s\n" \
- "Assertion: \"%s\"\n", __LINE__, __FILE__, #x); \
- } \
-} while (0)
-
-#ifndef TRUE
-#define TRUE (1)
-#endif
-#ifndef FALSE
-#define FALSE (0)
-#endif
-
-struct group;
-struct app;
-struct event;
-struct node;
-struct msg;
-typedef struct group group_t;
-typedef struct app app_t;
-typedef struct event event_t;
-typedef struct node node_t;
-typedef struct msg msg_t;
-
-
-/*
- * Event - manages nodes joining/leaving/failing
- */
-
-#define EST_JOIN_BEGIN 1
-#define EST_JOIN_STOP_WAIT 2
-#define EST_JOIN_ALL_STOPPED 3
-#define EST_JOIN_START_WAIT 4
-#define EST_JOIN_ALL_STARTED 5
-#define EST_LEAVE_BEGIN 6
-#define EST_LEAVE_STOP_WAIT 7
-#define EST_LEAVE_ALL_STOPPED 8
-#define EST_LEAVE_START_WAIT 9
-#define EST_LEAVE_ALL_STARTED 10
-#define EST_FAIL_BEGIN 11
-#define EST_FAIL_STOP_WAIT 12
-#define EST_FAIL_ALL_STOPPED 13
-#define EST_FAIL_START_WAIT 14
-#define EST_FAIL_ALL_STARTED 15
-
-struct event {
- struct list_head list;
- struct list_head memb;
- int event_nr;
- int state;
- int nodeid;
- uint64_t id;
- struct list_head extended;
- int start_app_before_pending_rev;
- int fail_all_stopped;
-};
-
-/*
- * Group
- */
-
-struct group {
- struct list_head list; /* list of groups */
- struct list_head level_list;
- uint16_t level;
- uint32_t global_id;
- struct list_head memb;
- int memb_count;
- int namelen;
- char name[MAX_NAMELEN+1];
- app_t *app;
- struct list_head messages;
- cpg_handle_t cpg_handle;
- int cpg_fd;
- int cpg_client;
- int have_set_id;
- int joining;
- int leaving;
-};
-
-struct app {
- int client;
- int node_count;
- struct list_head nodes;
- struct list_head events;
- event_t *current_event;
- group_t *g;
- int need_first_event; /* for debugging */
-};
-
-#define MSG_APP_STOPPED 1
-#define MSG_APP_STARTED 2
-#define MSG_APP_RECOVER 3
-#define MSG_APP_INTERNAL 4
-#define MSG_GLOBAL_ID 5
-#define MSG_GROUP_VERSION 6
-
-#define MSG_VER_MAJOR 1
-#define MSG_VER_MINOR 1
-#define MSG_VER_PATCH 0
-
-struct msg {
- uint32_t ms_version[3];
- uint16_t ms_type;
- uint16_t ms_level;
- uint32_t ms_length;
- uint32_t ms_global_id;
- uint64_t ms_event_id;
- char ms_name[MAX_NAMELEN];
-};
-
-struct save_msg {
- struct list_head list;
- int nodeid;
- int print_ignore;
- int msg_len;
- msg_t msg;
- char *msg_long;
-};
-
-struct node {
- struct list_head list;
- int nodeid;
- int stopped;
- int started;
-};
-
-struct recovery_set {
- struct list_head list;
- struct list_head entries;
- int nodeid;
- int cman_update;
- int cpg_update;
-};
-
-struct recovery_entry {
- struct list_head list;
- group_t *group;
- int recovered;
-};
-
-
-/* app.c */
-void add_recovery_set_cman(int nodeid);
-struct recovery_set *add_recovery_set_cpg(int nodeid, int procdown);
-int queue_app_recover(group_t *g, int nodeid);
-int queue_app_join(group_t *g, int nodeid);
-int queue_app_leave(group_t *g, int nodeid);
-int queue_app_message(group_t *g, struct save_msg *save);
-int do_stopdone(char *name, int level);
-int do_startdone(char *name, int level, int event_nr);
-char *ev_state_str(event_t *ev);
-event_t *find_queued_recover_event(group_t *g);
-void extend_recover_event(group_t *g, event_t *ev, int nodeid);
-int process_apps(void);
-void del_event_nodes(event_t *ev);
-void dump_group(group_t *g);
-void dump_all_groups(void);
-node_t *find_app_node(app_t *a, int nodeid);
-int event_state_stopping(app_t *a);
-int event_state_starting(app_t *a);
-void msg_bswap_out(msg_t *msg);
-void msg_bswap_in(msg_t *msg);
-struct recovery_set *get_recovery_set(int nodeid);
-void groupd_down(int nodeid);
-char *msg_type(int type);
-int process_app(group_t *g);
-int is_our_join(event_t *ev);
-void purge_node_messages(group_t *g, int nodeid);
-
-/* main.c */
-void read_ccs_name(char *path, char *name);
-void read_ccs_yesno(char *path, int *yes, int *no);
-void read_ccs_int(char *path, int *config_val);
-void app_stop(app_t *a);
-void app_setid(app_t *a);
-void app_start(app_t *a);
-void app_finish(app_t *a);
-void app_terminate(app_t *a);
-void app_deliver(app_t *a, struct save_msg *save);
-int client_add(int fd, void (*workfn)(int ci), void (*deadfn)(int ci));
-void client_dead(int ci);
-void cluster_dead(int ci);
-
-/* cman.c */
-int setup_cman(void);
-void close_cman(void);
-void process_cman(int ci);
-int kill_cman(int nodeid);
-
-/* cpg.c */
-int setup_cpg(void);
-int do_cpg_join(group_t *g);
-int do_cpg_leave(group_t *g);
-int send_message(group_t *g, void *buf, int len);
-int send_message_groupd(group_t *g, void *buf, int len, int type);
-void copy_groupd_data(group_data_t *data);
-int in_groupd_cpg(int nodeid);
-void group_mode_check_timeout(void);
-
-/* joinleave.c */
-void remove_group(group_t *g);
-int do_join(char *name, int level, int ci);
-int do_leave(char *name, int level);
-node_t *new_node(int nodeid);
-group_t *find_group_level(char *name, int level);
-int create_group(char *name, int level, group_t **g_out);
-app_t *create_app(group_t *g);
-
-/* logging.c */
-
-void init_logging(void);
-void setup_logging();
-void close_logging(void);
-
-#endif /* __GD_INTERNAL_DOT_H__ */
-
diff --git a/group/daemon/groupd.h b/group/daemon/groupd.h
deleted file mode 100644
index 69bd1fc..0000000
--- a/group/daemon/groupd.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __GROUPD_DOT_H__
-#define __GROUPD_DOT_H__
-
-#define GROUPD_SOCK_PATH ("groupd_socket")
-#define NODE_FAILED (1)
-#define NODE_JOIN (2)
-#define NODE_LEAVE (3)
-#define GROUPD_MSGLEN (2200) /* should be enough to permit
- group_send() of up to 2048 bytes
- of data plus header info */
-#define GROUPD_DUMP_SIZE (1024 * 1024)
-
-#endif
diff --git a/group/daemon/joinleave.c b/group/daemon/joinleave.c
deleted file mode 100644
index 95cc444..0000000
--- a/group/daemon/joinleave.c
+++ /dev/null
@@ -1,165 +0,0 @@
-
-/* Initiate join/leave requests from apps */
-
-#include "gd_internal.h"
-
-
-group_t *find_group_level(char *name, int level)
-{
- group_t *g;
-
- list_for_each_entry(g, &gd_levels[level], level_list) {
- if (!strcmp(g->name, name))
- return g;
- }
- return NULL;
-}
-
-int create_group(char *name, int level, group_t **g_out)
-{
- group_t *g;
-
- g = malloc(sizeof(*g));
- if (!g)
- return -ENOMEM;
-
- memset(g, 0, sizeof(*g));
-
- strcpy(g->name, name);
- g->namelen = strlen(name);
- g->level = level;
- INIT_LIST_HEAD(&g->memb);
- INIT_LIST_HEAD(&g->messages);
-
- list_add_tail(&g->list, &gd_groups);
- list_add_tail(&g->level_list, &gd_levels[level]);
-
- *g_out = g;
- return 0;
-}
-
-void free_group_memb(group_t *g)
-{
- node_t *node, *n;
-
- list_for_each_entry_safe(node, n, &g->memb, list) {
- list_del(&node->list);
- free(node);
- }
-}
-
-void remove_group(group_t *g)
-{
- list_del(&g->list);
- list_del(&g->level_list);
- free_group_memb(g);
- free(g);
-}
-
-app_t *create_app(group_t *g)
-{
- app_t *a;
-
- a = malloc(sizeof(app_t));
- if (!a)
- return NULL;
- memset(a, 0, sizeof(app_t));
-
- a->need_first_event = 1;
- INIT_LIST_HEAD(&a->nodes);
- INIT_LIST_HEAD(&a->events);
- a->g = g;
- g->app = a;
-
- return a;
-}
-
-int do_join(char *name, int level, int ci)
-{
- group_t *g;
- app_t *a;
- int rv;
-
- g = find_group_level(name, level);
- if (g) {
- log_group(g, "%d:%s can't join existing group", level, name);
- rv = -EEXIST;
- goto out;
- }
-
- rv = create_group(name, level, &g);
- if (rv)
- goto out;
-
- a = create_app(g);
- if (!a) {
- rv = -ENOMEM;
- goto out;
- }
-
- a->client = ci;
-
- log_debug("%d:%s got join", level, name);
- g->joining = 1;
- rv = do_cpg_join(g);
- out:
- return rv;
-}
-
-int do_leave(char *name, int level)
-{
- group_t *g;
- event_t *ev;
- int rv;
-
- g = find_group_level(name, level);
- if (!g)
- return -ENOENT;
-
- if (!g->app) {
- log_group(g, "leave: no app");
- return -EINVAL;
- }
-
- if (g->joining) {
- log_error(g, "leave: still joining");
- return -EAGAIN;
- }
-
- if (g->leaving) {
- log_error(g, "leave: already leaving");
- return -EBUSY;
- }
-
- ev = g->app->current_event;
-
- if (ev && ev->nodeid == our_nodeid) {
- log_error(g, "leave: busy event %llx state %s",
- (unsigned long long)ev->id,
- ev_state_str(ev));
- return -EAGAIN;
- }
-
- list_for_each_entry(ev, &g->app->events, list) {
- ASSERT(ev->nodeid != our_nodeid);
- log_group(g, "do_leave: found queued event id %llx",
- (unsigned long long)ev->id);
- }
-
- log_debug("%d:%s got leave", level, name);
- g->leaving = 1;
- rv = do_cpg_leave(g);
- return rv;
-}
-
-node_t *new_node(int nodeid)
-{
- node_t *node;
-
- node = malloc(sizeof(*node));
- // FIXME: handle failed malloc
- memset(node, 0, sizeof(*node));
- node->nodeid = nodeid;
- return node;
-}
-
diff --git a/group/daemon/logging.c b/group/daemon/logging.c
deleted file mode 100644
index e3cd636..0000000
--- a/group/daemon/logging.c
+++ /dev/null
@@ -1,60 +0,0 @@
-#include "gd_internal.h"
-#include "ccs.h"
-
-extern int ccs_handle;
-
-#define DAEMON_NAME "groupd"
-#define DEFAULT_LOG_MODE LOG_MODE_OUTPUT_FILE|LOG_MODE_OUTPUT_SYSLOG
-#define DEFAULT_SYSLOG_FACILITY SYSLOGFACILITY
-#define DEFAULT_SYSLOG_PRIORITY SYSLOGLEVEL
-#define DEFAULT_LOGFILE_PRIORITY LOG_INFO /* ? */
-#define DEFAULT_LOGFILE LOGDIR "/" DAEMON_NAME ".log"
-
-static int log_mode;
-static int syslog_facility;
-static int syslog_priority;
-static int logfile_priority;
-static char logfile[PATH_MAX];
-
-void init_logging(void)
-{
- log_mode = DEFAULT_LOG_MODE;
- syslog_facility = DEFAULT_SYSLOG_FACILITY;
- syslog_priority = DEFAULT_SYSLOG_PRIORITY;
- logfile_priority = DEFAULT_LOGFILE_PRIORITY;
- strcpy(logfile, DEFAULT_LOGFILE);
-
- /* logfile_priority is the only one of these options that
- can be controlled from command line or environment variable */
-
- if (cfgd_debug_logfile)
- logfile_priority = LOG_DEBUG;
-
- log_debug("logging mode %d syslog f %d p %d logfile p %d %s",
- log_mode, syslog_facility, syslog_priority,
- logfile_priority, logfile);
-
- logt_init(DAEMON_NAME, log_mode, syslog_facility, syslog_priority,
- logfile_priority, logfile);
-}
-
-void setup_logging(void)
-{
- ccs_read_logging(ccs_handle, DAEMON_NAME,
- &cfgd_debug_logfile, &log_mode,
- &syslog_facility, &syslog_priority,
- &logfile_priority, logfile);
-
- log_debug("logging mode %d syslog f %d p %d logfile p %d %s",
- log_mode, syslog_facility, syslog_priority,
- logfile_priority, logfile);
-
- logt_conf(DAEMON_NAME, log_mode, syslog_facility, syslog_priority,
- logfile_priority, logfile);
-}
-
-void close_logging(void)
-{
- logt_exit();
-}
-
diff --git a/group/daemon/main.c b/group/daemon/main.c
deleted file mode 100644
index 5b07505..0000000
--- a/group/daemon/main.c
+++ /dev/null
@@ -1,1082 +0,0 @@
-#include <signal.h>
-#include <time.h>
-
-#include "gd_internal.h"
-#include "ccs.h"
-#include "copyright.cf"
-
-#define LOCKFILE_NAME "/var/run/groupd.pid"
-#define CLIENT_NALLOC 32
-
-extern struct list_head recovery_sets;
-
-static int client_maxi;
-static int client_size = 0;
-static struct client *client = NULL;
-static struct pollfd *pollfd = NULL;
-static char last_action[16];
-int ccs_handle;
-
-struct client {
- int fd;
- int level;
- char type[32];
- void *workfn;
- void *deadfn;
-};
-
-static int do_read(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- while (off < count) {
- rv = read(fd, buf + off, count - off);
- if (rv == 0)
- return -1;
- if (rv == -1 && errno == EINTR)
- continue;
- if (rv == -1)
- return -1;
- off += rv;
- }
- return 0;
-}
-
-static int do_write(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- retry:
- rv = write(fd, buf + off, count);
- if (rv == -1 && errno == EINTR)
- goto retry;
- if (rv < 0) {
- log_print("write fd %d errno %d", fd, errno);
- return rv;
- }
-
- if (rv != count) {
- count -= rv;
- off += rv;
- goto retry;
- }
- return 0;
-}
-
-void read_ccs_name(char *path, char *name)
-{
- char *str;
- int error;
-
- error = ccs_get(ccs_handle, path, &str);
- if (error || !str)
- return;
-
- strcpy(name, str);
-
- free(str);
-}
-
-void read_ccs_yesno(char *path, int *yes, int *no)
-{
- char *str;
- int error;
-
- *yes = 0;
- *no = 0;
-
- error = ccs_get(ccs_handle, path, &str);
- if (error || !str)
- return;
-
- if (!strcmp(str, "yes"))
- *yes = 1;
-
- else if (!strcmp(str, "no"))
- *no = 1;
-
- free(str);
-}
-
-void read_ccs_int(char *path, int *config_val)
-{
- char *str;
- int val;
- int error;
-
- error = ccs_get(ccs_handle, path, &str);
- if (error || !str)
- return;
-
- val = atoi(str);
-
- if (val < 0) {
- log_print("ignore invalid value %d for %s", val, path);
- return;
- }
-
- *config_val = val;
- log_debug("%s is %u", path, val);
- free(str);
-}
-
-#define GROUPD_COMPAT_PATH "/cluster/group/@groupd_compat"
-#define GROUPD_WAIT_PATH "/cluster/group/@groupd_wait"
-#define GROUPD_MODE_DELAY_PATH "/cluster/group/@groupd_mode_delay"
-
-int setup_ccs(void)
-{
- int cd;
-
- cd = ccs_connect();
- if (cd < 0) {
- log_print("ccs_connect error %d %d", cd, errno);
- return -1;
- }
- ccs_handle = cd;
-
- /* These config values are set from cluster.conf only if they haven't
- already been set on the command line. */
-
- if (!optd_groupd_compat)
- read_ccs_int(GROUPD_COMPAT_PATH, &cfgd_groupd_compat);
-
- if (!optd_groupd_wait)
- read_ccs_int(GROUPD_WAIT_PATH, &cfgd_groupd_wait);
-
- if (!optd_groupd_mode_delay)
- read_ccs_int(GROUPD_MODE_DELAY_PATH, &cfgd_groupd_mode_delay);
-
- return 0;
-}
-
-void close_ccs(void)
-{
- ccs_disconnect(ccs_handle);
-}
-
-static void app_action(app_t *a, char *buf)
-{
- int rv;
-
- log_group(a->g, "action for app: %s", buf);
-
- rv = do_write(client[a->client].fd, buf, GROUPD_MSGLEN);
- if (rv < 0)
- log_error(a->g, "app_action write error");
-}
-
-void app_deliver(app_t *a, struct save_msg *save)
-{
- char buf[GROUPD_MSGLEN];
- int rv;
-
- rv = snprintf(buf, sizeof(buf), "deliver %s %d %d",
- a->g->name, save->nodeid,
- (int)(save->msg_len - sizeof(msg_t)));
-
- log_group(a->g, "deliver to app: %s", buf);
-
- memcpy(buf + rv + 1, save->msg_long + sizeof(msg_t),
- save->msg_len - sizeof(msg_t));
-
- /*
- log_group(a->g, "app_deliver body len %d \"%s\"",
- save->msg_len - sizeof(msg_t),
- save->msg_long + sizeof(msg_t));
- */
-
- rv = do_write(client[a->client].fd, buf, GROUPD_MSGLEN);
- if (rv < 0)
- log_error(a->g, "app_deliver write error");
-}
-
-void app_terminate(app_t *a)
-{
- char buf[GROUPD_MSGLEN];
- snprintf(buf, sizeof(buf), "terminate %s", a->g->name);
- app_action(a, buf);
-}
-
-void app_stop(app_t *a)
-{
- char buf[GROUPD_MSGLEN];
- snprintf(buf, sizeof(buf), "stop %s", a->g->name);
- app_action(a, buf);
-}
-
-void app_setid(app_t *a)
-{
- char buf[GROUPD_MSGLEN];
- snprintf(buf, sizeof(buf), "setid %s %u", a->g->name, a->g->global_id);
- app_action(a, buf);
-}
-
-void app_start(app_t *a)
-{
- char buf[GROUPD_MSGLEN];
- int len = 0, type, count = 0;
- node_t *node;
-
- if (a->current_event->state == EST_JOIN_START_WAIT)
- type = NODE_JOIN;
- else if (a->current_event->state == EST_LEAVE_START_WAIT)
- type = NODE_LEAVE;
- else if (a->current_event->state == EST_FAIL_START_WAIT)
- type = NODE_FAILED;
- else {
- /* report error */
- type = -1;
- }
-
- /* start <name> <event_nr> <type> <count> <memb0> <memb1>... */
-
- list_for_each_entry(node, &a->nodes, list)
- count++;
-
- len = snprintf(buf, sizeof(buf), "start %s %d %d %d",
- a->g->name, a->current_event->event_nr, type, count);
-
- list_for_each_entry(node, &a->nodes, list)
- len += sprintf(buf+len, " %d", node->nodeid);
-
- app_action(a, buf);
-}
-
-void app_finish(app_t *a)
-{
- char buf[GROUPD_MSGLEN];
- snprintf(buf, sizeof(buf), "finish %s %d",
- a->g->name, a->current_event->event_nr);
- app_action(a, buf);
-}
-
-#define MAXARGS 16
-
-static char *get_args(char *buf, int *argc, char **argv, char sep, int want)
-{
- char *p = buf, *rp = NULL;
- int i;
-
- argv[0] = p;
-
- for (i = 1; i < MAXARGS; i++) {
- p = strchr(buf, sep);
- if (!p)
- break;
- *p = '\0';
-
- if (want == i) {
- rp = p + 1;
- break;
- }
-
- argv[i] = p + 1;
- buf = p + 1;
- }
- *argc = i;
-
- /* we ended by hitting \0, return the point following that */
- if (!rp)
- rp = strchr(buf, '\0') + 1;
-
- return rp;
-}
-
-enum {
- DO_SETUP = 1,
- DO_JOIN,
- DO_LEAVE,
- DO_STOP_DONE,
- DO_START_DONE,
- DO_SEND,
- DO_GET_GROUPS,
- DO_GET_GROUP,
- DO_DUMP,
- DO_LOG,
- DO_GET_VERSION,
-};
-
-int get_action(char *buf)
-{
- char act[16];
- int i;
-
- memset(act, 0, 16);
-
- for (i = 0; i < 16; i++) {
- if (isalnum(buf[i]) || ispunct(buf[i]))
- act[i] = buf[i];
- else
- break;
- }
-
- /* for debug message */
- memset(&last_action, 0, 16);
- memcpy(last_action, act, 16);
-
- if (!strncmp(act, "setup", 16))
- return DO_SETUP;
-
- if (!strncmp(act, "join", 16))
- return DO_JOIN;
-
- if (!strncmp(act, "leave", 16))
- return DO_LEAVE;
-
- if (!strncmp(act, "stop_done", 16))
- return DO_STOP_DONE;
-
- if (!strncmp(act, "start_done", 16))
- return DO_START_DONE;
-
- if (!strncmp(act, "send", 16))
- return DO_SEND;
-
- if (!strncmp(act, "get_groups", 16))
- return DO_GET_GROUPS;
-
- if (!strncmp(act, "get_group", 16))
- return DO_GET_GROUP;
-
- if (!strncmp(act, "get_version", 16))
- return DO_GET_VERSION;
-
- if (!strncmp(act, "dump", 16))
- return DO_DUMP;
-
- if (!strncmp(act, "log", 16))
- return DO_LOG;
-
- return -1;
-}
-
-static void client_alloc(void)
-{
- int i;
-
- if (!client) {
- client = malloc(CLIENT_NALLOC * sizeof(struct client));
- pollfd = malloc(CLIENT_NALLOC * sizeof(struct pollfd));
- } else {
- client = realloc(client, (client_size + CLIENT_NALLOC) *
- sizeof(struct client));
- pollfd = realloc(pollfd, (client_size + CLIENT_NALLOC) *
- sizeof(struct pollfd));
- if (!pollfd)
- log_print("can't alloc for pollfd");
- }
- if (!client || !pollfd)
- log_print("can't alloc for client array");
-
- for (i = client_size; i < client_size + CLIENT_NALLOC; i++) {
- client[i].workfn = NULL;
- client[i].deadfn = NULL;
- client[i].fd = -1;
- client[i].level = -1;
- memset(client[i].type, 0, sizeof(client[i].type));
- pollfd[i].fd = -1;
- pollfd[i].revents = 0;
- }
- client_size += CLIENT_NALLOC;
-}
-
-void client_dead(int ci)
-{
- close(client[ci].fd);
- client[ci].workfn = NULL;
- client[ci].fd = -1;
- pollfd[ci].fd = -1;
-}
-
-int client_add(int fd, void (*workfn)(int ci), void (*deadfn)(int ci))
-{
- int i;
-
- if (!client)
- client_alloc();
- again:
- for (i = 0; i < client_size; i++) {
- if (client[i].fd == -1) {
- client[i].workfn = workfn;
- if (deadfn)
- client[i].deadfn = deadfn;
- else
- client[i].deadfn = client_dead;
- client[i].fd = fd;
- pollfd[i].fd = fd;
- pollfd[i].events = POLLIN;
- if (i > client_maxi)
- client_maxi = i;
- return i;
- }
- }
-
- client_alloc();
- goto again;
-}
-
-static void sigterm_handler(int sig)
-{
- daemon_quit = 1;
-}
-
-static void do_setup(int ci, int argc, char **argv)
-{
- log_debug("setup %s %s", argv[1], argv[2]);
-
- strcpy(client[ci].type, argv[1]);
- client[ci].level = atoi(argv[2]);
-}
-
-static void copy_group_data(group_t *g, group_data_t *data)
-{
- node_t *node;
- event_t *ev;
- int i = 0;
-
- strncpy(data->client_name, client[g->app->client].type, 32);
- strncpy(data->name, g->name, MAX_GROUP_NAME_LEN);
- data->level = g->level;
- data->id = g->global_id;
-
- if (g->app && g->app->current_event) {
- event_t *ev = g->app->current_event;
- data->event_state = ev->state;
- data->event_nodeid = ev->nodeid;
- data->event_id = ev->id;
- data->event_local_status = -2;
-
- node = find_app_node(g->app, our_nodeid);
- if (node) {
- if (event_state_stopping(g->app))
- data->event_local_status = node->stopped;
- else if (event_state_starting(g->app))
- data->event_local_status = node->started;
- else
- data->event_local_status = -1;
- }
- }
-
- data->member_count = g->app->node_count;
- list_for_each_entry(node, &g->app->nodes, list) {
- data->members[i] = node->nodeid;
- i++;
-
- if (node->nodeid == our_nodeid)
- data->member = 1;
- }
-
- /* we're in the member list but are still joining */
- if (data->member) {
- ev = g->app->current_event;
- if (ev && is_our_join(ev) &&
- (ev->state <= EST_JOIN_ALL_STARTED))
- data->member = 0;
- }
-}
-
-static int do_get_groups(int ci, int argc, char **argv)
-{
- group_t *g;
- group_data_t *data;
- int rv, count = 0, max = atoi(argv[1]);
-
- data = malloc(sizeof(group_data_t));
- // FIXME: handle failed malloc
- count = 0;
-
- list_for_each_entry(g, &gd_groups, list) {
- memset(data, 0, sizeof(group_data_t));
- copy_group_data(g, data);
- rv = do_write(client[ci].fd, data, sizeof(group_data_t));
- if (rv < 0) {
- log_print("do_get_groups write error");
- break;
- }
- count++;
- if (count >= max)
- break;
- }
- /* Now write an empty one indicating there aren't anymore: */
- memset(data, 0, sizeof(group_data_t));
- rv = do_write(client[ci].fd, data, sizeof(group_data_t));
- free(data);
- return 0;
-}
-
-static int do_get_group(int ci, int argc, char **argv)
-{
- group_t *g;
- group_data_t data;
- int rv;
-
- memset(&data, 0, sizeof(data));
-
- /* special case to get members of groupd cpg */
- if (atoi(argv[1]) == -1 && !strncmp(argv[2], "groupd", 6)) {
- copy_groupd_data(&data);
- goto out;
- }
-
- g = find_group_level(argv[2], atoi(argv[1]));
- if (!g)
- goto out;
-
- copy_group_data(g, &data);
- out:
- rv = do_write(client[ci].fd, &data, sizeof(data));
- if (rv < 0)
- log_print("do_get_group write error");
-
- return 0;
-}
-
-static int do_get_version(int ci)
-{
- int mode;
- int rv;
-
- if (group_mode == GROUP_PENDING)
- mode = -EAGAIN;
- else
- mode = group_mode;
-
- rv = do_write(client[ci].fd, &mode, sizeof(mode));
- if (rv < 0)
- log_print("do_get_version write error");
-
- return 0;
-}
-
-static int do_dump(int fd)
-{
- int len;
-
- if (dump_wrap) {
- len = GROUPD_DUMP_SIZE - dump_point;
- do_write(fd, dump_buf + dump_point, len);
- len = dump_point;
- } else
- len = dump_point;
-
- /* NUL terminate the debug string */
- dump_buf[dump_point] = '\0';
-
- do_write(fd, dump_buf, len);
-
- return 0;
-}
-
-static int do_log(int fd, const char *comment)
-{
- log_print("%s", comment);
- return 0;
-}
-
-static void do_send(char *name, int level, int len, char *data)
-{
- group_t *g;
- msg_t *msg;
- char *buf;
- int total;
-
- g = find_group_level(name, level);
- if (!g)
- return;
-
- total = sizeof(msg_t) + len;
- buf = malloc(total);
- // FIXME: handle failed malloc
- memset(buf, 0, total);
-
- memcpy(buf + sizeof(msg_t), data, len);
-
- msg = (msg_t *) buf;
- msg->ms_type = MSG_APP_INTERNAL;
- msg->ms_global_id = g->global_id;
-
- log_debug("%d:%s do_send %d bytes", level, name, total);
-
- send_message(g, msg, total);
-
- free(buf);
-}
-
-static void process_connection(int ci)
-{
- char buf[GROUPD_MSGLEN], *argv[MAXARGS], *p;
- int argc = 0, rv, act;
-
- memset(buf, 0, sizeof(buf));
- memset(argv, 0, sizeof(char *) * MAXARGS);
-
- rv = do_read(client[ci].fd, buf, GROUPD_MSGLEN);
- if (rv < 0) {
- client_dead(ci);
- return;
- }
-
- act = get_action(buf);
-
- log_debug("got client %d %s", ci, last_action);
-
- switch (act) {
-
- case DO_SETUP:
- get_args(buf, &argc, argv, ' ', 3);
- do_setup(ci, argc, argv);
- break;
-
- case DO_JOIN:
- get_args(buf, &argc, argv, ' ', 2);
- do_join(argv[1], client[ci].level, ci);
- break;
-
- case DO_LEAVE:
- get_args(buf, &argc, argv, ' ', 2);
- do_leave(argv[1], client[ci].level);
- break;
-
- case DO_STOP_DONE:
- get_args(buf, &argc, argv, ' ', 2);
- do_stopdone(argv[1], client[ci].level);
- break;
-
- case DO_START_DONE:
- get_args(buf, &argc, argv, ' ', 3);
- do_startdone(argv[1], client[ci].level, atoi(argv[2]));
- break;
-
- case DO_SEND:
- p = get_args(buf, &argc, argv, ' ', 3);
- do_send(argv[1], client[ci].level, atoi(argv[2]), p);
- break;
-
- case DO_GET_GROUPS:
- get_args(buf, &argc, argv, ' ', 2);
- do_get_groups(ci, argc, argv);
- break;
-
- case DO_GET_GROUP:
- get_args(buf, &argc, argv, ' ', 3);
- do_get_group(ci, argc, argv);
- break;
-
- case DO_GET_VERSION:
- do_get_version(ci);
- break;
-
- case DO_DUMP:
- do_dump(client[ci].fd);
- close(client[ci].fd);
- break;
-
- case DO_LOG:
- do_log(client[ci].fd, &buf[4]);
- break;
-
- default:
- log_print("unknown action %d client %d", act, ci);
- log_print("invalid message: \"%s\"", buf);
- }
-}
-
-static void process_listener(int ci)
-{
- int fd, i;
-
- fd = accept(client[ci].fd, NULL, NULL);
- if (fd < 0) {
- log_print("process_listener: accept error %d %d", fd, errno);
- return;
- }
-
- i = client_add(fd, process_connection, NULL);
-
- log_debug("client connection %d fd %d", i, fd);
-}
-
-static int setup_listener(char *sock_path)
-{
- struct sockaddr_un addr;
- socklen_t addrlen;
- int rv, s;
-
- /* we listen for new client connections on socket s */
-
- s = socket(AF_LOCAL, SOCK_STREAM, 0);
- if (s < 0) {
- log_print("socket error %d %d", s, errno);
- return s;
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_LOCAL;
- strcpy(&addr.sun_path[1], sock_path);
- addrlen = sizeof(sa_family_t) + strlen(addr.sun_path+1) + 1;
-
- rv = bind(s, (struct sockaddr *) &addr, addrlen);
- if (rv < 0) {
- log_print("bind error %d %d", rv, errno);
- close(s);
- return rv;
- }
-
- rv = listen(s, 5);
- if (rv < 0) {
- log_print("listen error %d %d", rv, errno);
- close(s);
- return rv;
- }
- return s;
-}
-
-void cluster_dead(int ci)
-{
- log_print("cluster is down, exiting");
- daemon_quit = 1;
-}
-
-#define min(x, y) ({ \
- typeof(x) _min1 = (x); \
- typeof(y) _min2 = (y); \
- (void) (&_min1 == &_min2); \
- _min1 < _min2 ? _min1 : _min2; })
-
-static void loop(void)
-{
- int poll_timeout = -1;
- int rv, i;
- void (*workfn) (int ci);
- void (*deadfn) (int ci);
-
- rv = setup_listener(GROUPD_SOCK_PATH);
- if (rv < 0)
- goto out;
- client_add(rv, process_listener, NULL);
-
- rv = setup_cman();
- if (rv < 0)
- goto out;
- client_add(rv, process_cman, cluster_dead);
-
- rv = setup_ccs();
- if (rv < 0)
- goto out;
-
- setup_logging();
-
- if (cfgd_groupd_compat == 0) {
- group_mode = GROUP_LIBCPG;
- log_level(LOG_INFO, "groupd compatibility mode 0 cfg");
- } else if (cfgd_groupd_compat == 1) {
- group_mode = GROUP_LIBGROUP;
- log_level(LOG_INFO, "groupd compatibility mode 1 cfg");
- } else if (cfgd_groupd_compat == 2) {
- group_mode = GROUP_PENDING;
- /* report the mode in set_group_mode() */
- }
-
- rv = setup_cpg();
- if (rv < 0)
- goto out;
-
- for (;;) {
- rv = poll(pollfd, client_maxi + 1, poll_timeout);
- if (rv == -1 && errno == EINTR) {
- if (daemon_quit && (group_mode == GROUP_LIBCPG ||
- list_empty(&gd_groups)))
- goto out;
- daemon_quit = 0;
- continue;
- }
- if (rv < 0) {
- log_print("poll errno %d", errno);
- goto out;
- }
-
- for (i = 0; i <= client_maxi; i++) {
- if (client[i].fd < 0)
- continue;
- if (pollfd[i].revents & POLLIN) {
- workfn = client[i].workfn;
- workfn(i);
- }
- if (pollfd[i].revents & (POLLERR | POLLHUP | POLLNVAL)) {
- deadfn = client[i].deadfn;
- deadfn(i);
- }
- }
-
- if (daemon_quit)
- break;
-
- /* process_apps() returns non-zero if there may be
- more work to do */
-
- do {
- rv = 0;
- rv += process_apps();
- } while (rv);
-
- poll_timeout = -1;
-
- if (group_mode == GROUP_PENDING) {
- group_mode_check_timeout();
- poll_timeout = 1000 * min(cfgd_groupd_wait, cfgd_groupd_mode_delay);
- }
- }
- out:
- close_ccs();
- close_cman();
-
- /* in LIBCPG mode, gd_groups is not empty because of the groups we
- add to "block" old versions of groupd */
- if ((group_mode == GROUP_LIBGROUP) && !list_empty(&gd_groups))
- log_print("groups abandoned");
-}
-
-static void lockfile(void)
-{
- int fd, error;
- struct flock lock;
- char buf[33];
-
- memset(buf, 0, 33);
-
- fd = open(LOCKFILE_NAME, O_CREAT|O_WRONLY,
- S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
- if (fd < 0) {
- fprintf(stderr, "cannot open/create lock file %s\n",
- LOCKFILE_NAME);
- exit(EXIT_FAILURE);
- }
-
- lock.l_type = F_WRLCK;
- lock.l_start = 0;
- lock.l_whence = SEEK_SET;
- lock.l_len = 0;
-
- error = fcntl(fd, F_SETLK, &lock);
- if (error) {
- fprintf(stderr, "groupd is already running\n");
- exit(EXIT_FAILURE);
- }
-
- error = ftruncate(fd, 0);
- if (error) {
- fprintf(stderr, "cannot clear lock file %s\n", LOCKFILE_NAME);
- exit(EXIT_FAILURE);
- }
-
- sprintf(buf, "%d\n", getpid());
-
- error = write(fd, buf, strlen(buf));
- if (error <= 0) {
- fprintf(stderr, "cannot write lock file %s\n", LOCKFILE_NAME);
- exit(EXIT_FAILURE);
- }
-}
-
-static void print_usage(void)
-{
- printf("Usage:\n");
- printf("\n");
- printf("groupd [options]\n");
- printf("\n");
- printf("Options:\n");
- printf("\n");
- printf(" -D Enable debugging to stderr and don't fork\n");
- printf(" -L Enable debugging to log file\n");
- printf(" -g <num> group compatibility mode, 0 off, 1 on, 2 detect\n");
- printf(" 0: use libcpg, no backward compat, best performance\n");
- printf(" 1: use libgroup for compat with cluster2/rhel5\n");
- printf(" 2: detect old, or mode 1, nodes that require compat,\n"
- " use libcpg if none found\n");
- printf(" Default is %d\n", DEFAULT_GROUPD_COMPAT);
- printf(" -w <secs> seconds to wait for a node's version message before\n"
- " assuming an old version requiring compat mode\n");
- printf(" Default is %d\n", DEFAULT_GROUPD_WAIT);
- printf(" -d <secs> seconds to delay the mode selection to give time\n"
- " for an old version to join and force compat mode\n");
- printf(" Default is %d\n", DEFAULT_GROUPD_MODE_DELAY);
- printf(" -h Print this help, then exit\n");
- printf(" -V Print program version information, then exit\n");
-}
-
-#define OPTION_STRING "LDg:w:d:hVv"
-
-static void read_arguments(int argc, char **argv)
-{
- int cont = 1;
- int optchar;
-
- while (cont) {
- optchar = getopt(argc, argv, OPTION_STRING);
-
- switch (optchar) {
-
- case 'D':
- daemon_debug_opt = 1;
- break;
-
- case 'L':
- optd_debug_logfile = 1;
- cfgd_debug_logfile = 1;
- break;
-
- case 'g':
- optd_groupd_compat = 1;
- cfgd_groupd_compat = atoi(optarg);
- break;
-
- case 'w':
- optd_groupd_wait = 1;
- cfgd_groupd_wait = atoi(optarg);
- break;
-
- case 'd':
- optd_groupd_mode_delay = 1;
- cfgd_groupd_mode_delay = atoi(optarg);
- break;
-
- case 'h':
- print_usage();
- exit(EXIT_SUCCESS);
- break;
-
- case 'v':
- daemon_debug_verbose++;
- break;
-
- case 'V':
- printf("groupd %s (built %s %s)\n",
- RELEASE_VERSION, __DATE__, __TIME__);
- printf("%s\n", REDHAT_COPYRIGHT);
- exit(EXIT_SUCCESS);
- break;
-
- case ':':
- case '?':
- fprintf(stderr, "Please use '-h' for usage.\n");
- exit(EXIT_FAILURE);
- break;
-
- case EOF:
- cont = FALSE;
- break;
-
- default:
- fprintf(stderr, "unknown option: %c\n", optchar);
- exit(EXIT_FAILURE);
- break;
- };
- }
-
- if (getenv("GROUPD_DEBUG")) {
- optd_debug_logfile = 1;
- cfgd_debug_logfile = 1;
- }
-}
-
-static void set_oom_adj(int val)
-{
- FILE *fp;
-
- fp = fopen("/proc/self/oom_adj", "w");
- if (!fp)
- return;
-
- fprintf(fp, "%i", val);
- fclose(fp);
-}
-
-static void set_scheduler(void)
-{
- struct sched_param sched_param;
- int rv;
-
- rv = sched_get_priority_max(SCHED_RR);
- if (rv != -1) {
- sched_param.sched_priority = rv;
- rv = sched_setscheduler(0, SCHED_RR, &sched_param);
- if (rv == -1)
- log_print("could not set SCHED_RR priority %d err %d",
- sched_param.sched_priority, errno);
- } else {
- log_print("could not get maximum scheduler priority err %d",
- errno);
- }
-}
-
-int main(int argc, char *argv[])
-{
- int i;
-
- INIT_LIST_HEAD(&recovery_sets);
- INIT_LIST_HEAD(&gd_groups);
- for (i = 0; i < MAX_LEVELS; i++)
- INIT_LIST_HEAD(&gd_levels[i]);
-
- read_arguments(argc, argv);
- lockfile();
-
- if (!daemon_debug_opt) {
- if (daemon(0, 0) < 0) {
- perror("daemon error");
- exit(EXIT_FAILURE);
- }
- }
- init_logging();
- log_level(LOG_INFO, "groupd %s", RELEASE_VERSION);
- signal(SIGTERM, sigterm_handler);
- set_scheduler();
- set_oom_adj(-16);
-
- loop();
-
- return 0;
-}
-
-void daemon_dump_save(void)
-{
- int len, i;
-
- len = strlen(daemon_debug_buf);
-
- for (i = 0; i < len; i++) {
- dump_buf[dump_point++] = daemon_debug_buf[i];
-
- if (dump_point == GROUPD_DUMP_SIZE) {
- dump_point = 0;
- dump_wrap = 1;
- }
- }
-}
-
-int daemon_debug_opt;
-int daemon_debug_verbose;
-int daemon_quit;
-int cman_quorate;
-int our_nodeid;
-char *our_name;
-char daemon_debug_buf[256];
-char dump_buf[GROUPD_DUMP_SIZE];
-int dump_point;
-int dump_wrap;
-struct list_head gd_groups;
-struct list_head gd_levels[MAX_LEVELS];
-uint32_t gd_event_nr;
-int group_mode;
-
-int optd_groupd_compat;
-int optd_groupd_wait;
-int optd_groupd_mode_delay;
-int optd_debug_logfile;
-
-int cfgd_groupd_compat = DEFAULT_GROUPD_COMPAT;
-int cfgd_groupd_wait = DEFAULT_GROUPD_WAIT;
-int cfgd_groupd_mode_delay = DEFAULT_GROUPD_MODE_DELAY;
-int cfgd_debug_logfile = DEFAULT_DEBUG_LOGFILE;
-
diff --git a/group/lib/Makefile b/group/lib/Makefile
deleted file mode 100644
index abd4336..0000000
--- a/group/lib/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-TARGET=libgroup
-
-MAKESTATICLIB = 1
-
-LIBDIRT=$(TARGET).a
-INCDIRT=$(TARGET).h
-
-include ../../make/defines.mk
-include $(OBJDIR)/make/libs.mk
-include $(OBJDIR)/make/cobj.mk
-include $(OBJDIR)/make/clean.mk
-include $(OBJDIR)/make/install.mk
-include $(OBJDIR)/make/uninstall.mk
-
-CFLAGS += -fPIC
-CFLAGS += -I$(S) -I$(S)/../daemon
-CFLAGS += -I${incdir}
diff --git a/group/lib/libgroup.c b/group/lib/libgroup.c
deleted file mode 100644
index c86ac25..0000000
--- a/group/lib/libgroup.c
+++ /dev/null
@@ -1,524 +0,0 @@
-#include <sys/types.h>
-#include <sys/un.h>
-#include <inttypes.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-
-#include "groupd.h"
-#include "libgroup.h"
-
-#define LIBGROUP_MAGIC 0x67727570
-#define MAXARGS 100 /* FIXME */
-
-#define VALIDATE_HANDLE(h) \
-do { \
- if (!(h) || (h)->magic != LIBGROUP_MAGIC) { \
- errno = EINVAL; \
- return -1; \
- } \
-} while (0)
-
-enum {
- DO_STOP = 1,
- DO_START = 2,
- DO_FINISH = 3,
- DO_TERMINATE = 4,
- DO_SET_ID = 5,
- DO_DELIVER = 6,
-};
-
-
-/* if there's more data beyond the number of args we want, the return value
- points to it */
-
-static char *get_args(char *buf, int *argc, char **argv, char sep, int want)
-{
- char *p = buf, *rp = NULL;
- int i;
-
- argv[0] = p;
-
- for (i = 1; i < MAXARGS; i++) {
- p = strchr(buf, sep);
- if (!p)
- break;
- *p = '\0';
-
- if (want == i) {
- rp = p + 1;
- break;
- }
-
- argv[i] = p + 1;
- buf = p + 1;
- }
- *argc = i;
-
- /* we ended by hitting \0, return the point following that */
- if (!rp)
- rp = strchr(buf, '\0') + 1;
-
- return rp;
-}
-
-static void get_nodeids(char *buf, int memb_count, int *nodeids)
-{
- char *p;
- int i, count = 0;
-
- for (i = 0; ; i++) {
- if (isdigit(buf[i]))
- break;
- }
-
- buf = &buf[i];
-
- for (i = 0; i < memb_count; i++) {
-
- nodeids[count++] = atoi(buf);
-
- p = strchr(buf, ' ');
- if (!p)
- break;
-
- buf = p + 1;
- }
-}
-
-static int get_action(char *buf)
-{
- char act[16];
- int i;
-
- memset(act, 0, 16);
-
- for (i = 0; i < 16; i++) {
- if (isalnum(buf[i]))
- act[i] = buf[i];
- else
- break;
- }
-
- if (!strncmp(act, "stop", 16))
- return DO_STOP;
-
- if (!strncmp(act, "start", 16))
- return DO_START;
-
- if (!strncmp(act, "finish", 16))
- return DO_FINISH;
-
- if (!strncmp(act, "terminate", 16))
- return DO_TERMINATE;
-
- if (!strncmp(act, "setid", 16))
- return DO_SET_ID;
-
- if (!strncmp(act, "deliver", 16))
- return DO_DELIVER;
-
- return -1;
-}
-
-static int do_write(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- retry:
- rv = write(fd, buf + off, count);
- if (rv == -1 && errno == EINTR)
- goto retry;
- if (rv < 0)
- return rv;
-
- if (rv != count) {
- count -= rv;
- off += rv;
- goto retry;
- }
- return 0;
-}
-
-static int do_read(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- while (off < count) {
- rv = read(fd, buf + off, count - off);
- if (rv == 0)
- return -1;
- if (rv == -1 && errno == EINTR)
- continue;
- if (rv == -1)
- return -1;
- off += rv;
- }
- return 0;
-}
-
-struct group_handle
-{
- int magic;
- int fd;
- int level;
- void *private;
- group_callbacks_t cbs;
- char prog_name[32];
-};
-
-static int _joinleave(group_handle_t handle, char *name, char *cmd)
-{
- char buf[GROUPD_MSGLEN];
- struct group_handle *h = (struct group_handle *) handle;
- VALIDATE_HANDLE(h);
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "%s %s", cmd, name);
-
- return do_write(h->fd, buf, GROUPD_MSGLEN);
-}
-
-int group_join(group_handle_t handle, char *name)
-{
- return _joinleave(handle, name, "join");
-}
-
-int group_leave(group_handle_t handle, char *name)
-{
- return _joinleave(handle, name, "leave");
-}
-
-int group_stop_done(group_handle_t handle, char *name)
-{
- char buf[GROUPD_MSGLEN];
- struct group_handle *h = (struct group_handle *) handle;
- VALIDATE_HANDLE(h);
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "stop_done %s", name);
-
- return do_write(h->fd, buf, GROUPD_MSGLEN);
-}
-
-int group_start_done(group_handle_t handle, char *name, int event_nr)
-{
- char buf[GROUPD_MSGLEN];
- struct group_handle *h = (struct group_handle *) handle;
- VALIDATE_HANDLE(h);
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "start_done %s %d", name, event_nr);
-
- return do_write(h->fd, buf, GROUPD_MSGLEN);
-}
-
-int group_send(group_handle_t handle, char *name, int len, char *data)
-{
- char buf[GROUPD_MSGLEN];
- int rv;
- struct group_handle *h = (struct group_handle *) handle;
- VALIDATE_HANDLE(h);
-
- if (len > 2048 || len <= 0)
- return -EINVAL;
-
- memset(buf, 0, sizeof(buf));
- rv = snprintf(buf, sizeof(buf), "send %s %d", name, len);
- memcpy(buf + rv + 1, data, len);
-
- return do_write(h->fd, buf, GROUPD_MSGLEN);
-}
-
-static int connect_groupd(void)
-{
- struct sockaddr_un sun;
- socklen_t addrlen;
- int rv, fd;
-
- fd = socket(PF_UNIX, SOCK_STREAM, 0);
- if (fd < 0)
- goto out;
-
- memset(&sun, 0, sizeof(sun));
- sun.sun_family = AF_UNIX;
- strcpy(&sun.sun_path[1], GROUPD_SOCK_PATH);
- addrlen = sizeof(sa_family_t) + strlen(sun.sun_path+1) + 1;
-
- rv = connect(fd, (struct sockaddr *) &sun, addrlen);
- if (rv < 0) {
- close(fd);
- fd = rv;
- }
- out:
- return fd;
-}
-
-group_handle_t group_init(void *private, char *prog_name, int level,
- group_callbacks_t *cbs, int timeout)
-{
- struct group_handle *h;
- char buf[GROUPD_MSGLEN];
- int rv, saved_errno, i;
-
- h = malloc(sizeof(struct group_handle));
- if (!h)
- return NULL;
-
- h->magic = LIBGROUP_MAGIC;
- h->private = private;
- h->cbs = *cbs;
- h->level = level;
- strncpy(h->prog_name, prog_name, 32);
-
- for (i = 0; !timeout || i < timeout * 2; i++) {
- h->fd = connect_groupd();
- if (h->fd > 0 || !timeout)
- break;
- usleep(500000);
- }
-
- if (h->fd <= 0)
- goto fail;
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "setup %s %d", prog_name, level);
-
- rv = do_write(h->fd, &buf, GROUPD_MSGLEN);
- if (rv < 0)
- goto fail;
-
- return (group_handle_t) h;
-
- fail:
- saved_errno = errno;
- close(h->fd);
- free(h);
- h = NULL;
- errno = saved_errno;
- return NULL;
-}
-
-int group_exit(group_handle_t handle)
-{
- struct group_handle *h = (struct group_handle *) handle;
- VALIDATE_HANDLE(h);
- h->magic = 0;
- close(h->fd);
- free(h);
- return 0;
-}
-
-int group_get_fd(group_handle_t handle)
-{
- struct group_handle *h = (struct group_handle *) handle;
- VALIDATE_HANDLE(h);
- return h->fd;
-}
-
-/* Format of string messages we receive from groupd:
-
- "stop <name>"
-
- name = the name of the group (same for rest)
-
- "start <name> <event_nr> <type> <memb_count> <memb0> <memb1>..."
-
- event_nr = used to later match finish/terminate
- type = 1/GROUP_NODE_FAILED, 2/GROUP_NODE_JOIN, 3/GROUP_NODE_LEAVE
- memb_count = the number of group members
- memb0... = the nodeids of the group members
-
- "finish <name> <event_nr>"
-
- event_nr = matches the start event that's finishing
-
- "terminate <name> <event_nr>"
-
- event_nr = matches the start event that's being canceled
-
- "setid <name> <id>"
-
- id = the global id of the group
-
- "deliver <name> <nodeid> <len>"<data>
-
- nodeid = who sent the message
- len = length of the message
- data = the message
-*/
-
-int group_dispatch(group_handle_t handle)
-{
- char buf[GROUPD_MSGLEN], *argv[MAXARGS];
- char *p;
- int act, argc, rv, count, *nodeids;
- struct group_handle *h = (struct group_handle *) handle;
- VALIDATE_HANDLE(h);
-
- memset(buf, 0, sizeof(buf));
-
- rv = do_read(h->fd, &buf, GROUPD_MSGLEN);
- if (rv < 0)
- goto out;
-
- act = get_action(buf);
-
- switch (act) {
-
- case DO_STOP:
- get_args(buf, &argc, argv, ' ', 2);
-
- h->cbs.stop(h, h->private, argv[1]);
- break;
-
- case DO_START:
- p = get_args(buf, &argc, argv, ' ', 5);
-
- count = atoi(argv[4]);
- nodeids = malloc(count * sizeof(int));
- if (!nodeids) {
- rv = -ENOMEM;
- goto out;
- }
- get_nodeids(p, count, nodeids);
-
- h->cbs.start(h, h->private, argv[1], atoi(argv[2]),
- atoi(argv[3]), count, nodeids);
-
- free(nodeids);
- break;
-
- case DO_FINISH:
- get_args(buf, &argc, argv, ' ', 3);
-
- h->cbs.finish(h, h->private, argv[1], atoi(argv[2]));
- break;
-
- case DO_TERMINATE:
- get_args(buf, &argc, argv, ' ', 3);
-
- /* FIXME: why aren't we passing event_nr, argv[2], through? */
-
- h->cbs.terminate(h, h->private, argv[1]);
- break;
-
- case DO_SET_ID:
- get_args(buf, &argc, argv, ' ', 3);
-
- h->cbs.set_id(h, h->private, argv[1],
- (unsigned int) strtoul(argv[2], NULL, 10));
- break;
-
- case DO_DELIVER:
- p = get_args(buf, &argc, argv, ' ', 4);
-
- h->cbs.deliver(h, h->private, argv[1], atoi(argv[2]),
- atoi(argv[3]), p);
- break;
- }
-
- rv = 0;
- out:
- return rv;
-}
-
-int group_get_groups(int max, int *count, group_data_t *data)
-{
- char buf[GROUPD_MSGLEN];
- group_data_t dbuf, empty;
- int fd, rv;
-
- *count = 0;
-
- fd = connect_groupd();
- if (fd < 0)
- return fd;
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "get_groups %d", max);
-
- rv = do_write(fd, &buf, GROUPD_MSGLEN);
- if (rv < 0)
- goto out;
-
- memset(&empty, 0, sizeof(empty));
-
- while (1) {
- memset(&dbuf, 0, sizeof(dbuf));
-
- rv = do_read(fd, &dbuf, sizeof(group_data_t));
- if (rv < 0)
- break;
-
- if (!memcmp(&dbuf, &empty, sizeof(group_data_t))) {
- rv = 0;
- break;
- } else {
- memcpy(&data[*count], &dbuf, sizeof(group_data_t));
- (*count)++;
- }
- }
- out:
- close(fd);
- return rv;
-}
-
-int group_get_group(int level, const char *name, group_data_t *data)
-{
- char buf[GROUPD_MSGLEN];
- char data_buf[sizeof(group_data_t)];
- int fd, rv;
-
- fd = connect_groupd();
- if (fd < 0)
- return fd;
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "get_group %d %s", level, name);
-
- rv = do_write(fd, &buf, GROUPD_MSGLEN);
- if (rv < 0)
- goto out;
-
- rv = do_read(fd, &data_buf, sizeof(data_buf));
- if (rv < 0)
- goto out;
-
- memcpy(data, data_buf, sizeof(group_data_t));
- rv = 0;
- out:
- close(fd);
- return rv;
-}
-
-int group_get_version(int *version)
-{
- char buf[GROUPD_MSGLEN];
- int fd, rv;
-
- fd = connect_groupd();
- if (fd < 0)
- return fd;
-
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "get_version");
-
- rv = do_write(fd, &buf, GROUPD_MSGLEN);
- if (rv < 0)
- goto out;
-
- rv = do_read(fd, version, sizeof(int));
- if (rv < 0)
- goto out;
- rv = 0;
- out:
- close(fd);
- return rv;
-}
-
diff --git a/group/lib/libgroup.h b/group/lib/libgroup.h
deleted file mode 100644
index 82ef7e1..0000000
--- a/group/lib/libgroup.h
+++ /dev/null
@@ -1,81 +0,0 @@
-#ifndef _LIBGROUP_H_
-#define _LIBGROUP_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define MAX_GROUP_MEMBERS 256
-#define MAX_GROUP_NAME_LEN 32
-
-/* these need to match what's in groupd.h */
-#define GROUP_NODE_FAILED 1
-#define GROUP_NODE_JOIN 2
-#define GROUP_NODE_LEAVE 3
-
-typedef void *group_handle_t;
-
-typedef void (*group_stop_t)(group_handle_t h, void *priv, char *name);
-typedef void (*group_start_t)(group_handle_t h, void *priv, char *name,
- int event_nr, int type, int member_count,
- int *members);
-typedef void (*group_finish_t)(group_handle_t h, void *priv, char *name,
- int event_nr);
-typedef void (*group_terminate_t)(group_handle_t h, void *priv, char *name);
-typedef void (*group_set_id_t)(group_handle_t h, void *priv, char *name,
- unsigned int id);
-typedef void (*group_deliver_t)(group_handle_t h, void *priv, char *name,
- int nodeid, int len, char *buf);
-
-typedef struct {
- group_stop_t stop;
- group_start_t start;
- group_finish_t finish;
- group_terminate_t terminate;
- group_set_id_t set_id;
- group_deliver_t deliver;
-} group_callbacks_t;
-
-group_handle_t group_init(void *priv, char *prog_name, int level, group_callbacks_t *cbs, int timeout);
-int group_exit(group_handle_t handle);
-
-int group_join(group_handle_t handle, char *name);
-int group_leave(group_handle_t handle, char *name);
-int group_stop_done(group_handle_t handle, char *name);
-int group_start_done(group_handle_t handle, char *name, int event_nr);
-int group_get_fd(group_handle_t handle);
-int group_dispatch(group_handle_t handle);
-int group_send(group_handle_t handle, char *name, int len, char *buf);
-
-
-/*
- * Querying for group information
- */
-
-typedef struct group_data {
- char client_name[32+1];
- char name[MAX_GROUP_NAME_LEN+1];
- int level;
- unsigned int id;
- int member;
- int member_count;
- int members[MAX_GROUP_MEMBERS];
- int event_state;
- int event_nodeid;
- int event_local_status;
- uint64_t event_id;
-} group_data_t;
-
-/* These routines create their own temporary connection to groupd so they
- don't interfere with dispatchable callback messages. */
-
-int group_get_groups(int max, int *count, group_data_t *data);
-int group_get_group(int level, const char *name, group_data_t *data);
-
-int group_get_version(int *version);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/group/man/groupd.8 b/group/man/groupd.8
deleted file mode 100644
index 634d0a0..0000000
--- a/group/man/groupd.8
+++ /dev/null
@@ -1,43 +0,0 @@
-.TH groupd 8
-
-.SH NAME
-groupd - the group manager for fenced, dlm_controld and gfs_controld
-
-.SH SYNOPSIS
-.B
-groupd
-[\fIOPTION\fR]...
-
-.SH DESCRIPTION
-
-The group daemon, groupd, provides a compatibility layer between the
-openais closed process group (CPG) service and the fenced, dlm_controld
-and gfs_controld daemons. groupd and its associated libgroup interface
-will go away in the future as the fencing, dlm and gfs daemons are ported
-to use the libcpg interfaces directly. groupd translates and buffers cpg
-events between openais's cpg service and the fence/dlm/gfs systems that
-use it. CPG's are used to represent the membership of the fence domain,
-dlm lockspaces and gfs mount groups.
-
-groupd is also a convenient place to query the status of the fence, dlm
-and gfs groups. This is done by the group_tool program.
-
-
-.SH OPTIONS
-.TP
-\fB-D\fP
-Run the daemon in the foreground and print debug statements to stdout.
-.TP
-\fB-V\fP
-Print the version information and exit.
-.TP
-\fB-h\fP
-Print out a help message describing available options, then exit.
-
-.SH DEBUGGING
-The groupd daemon keeps a circular buffer of debug messages that can be
-dumped with the 'group_tool dump' command.
-
-.SH SEE ALSO
-group_tool(8)
-
diff --git a/group/test/Makefile b/group/test/Makefile
deleted file mode 100644
index 3a91013..0000000
--- a/group/test/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-TARGETS= client clientd
-
-all: $(TARGETS)
-
-include ../../make/defines.mk
-include $(OBJDIR)/make/cobj.mk
-include $(OBJDIR)/make/clean.mk
-
-CFLAGS += -I${incdir}
-
-LDFLAGS += -L${libdir}
-
-%: %.o
- $(CC) -o $@ $^ $(LDFLAGS)
-
-clean: generalclean
diff --git a/group/test/client.c b/group/test/client.c
deleted file mode 100644
index a9a3930..0000000
--- a/group/test/client.c
+++ /dev/null
@@ -1,45 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <sys/types.h>
-#include <sys/errno.h>
-
-
-#define COMMAND_SOCK_PATH "command_socket"
-
-
-int main(int argc, char *argv[])
-{
- int s, i, rv;
- struct sockaddr_un addr;
- socklen_t addrlen;
- char buf[256];
-
- s = socket(AF_LOCAL, SOCK_DGRAM, 0);
- if (s < 0) {
- printf("socket error %d errno %d\n", s, errno);
- exit(-1);
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_LOCAL;
- strcpy(&addr.sun_path[1], COMMAND_SOCK_PATH);
- addrlen = sizeof(sa_family_t) + strlen(addr.sun_path+1) + 1;
-
- memset(buf, 0, 256);
-
- for (i = 1; i < argc; i++) {
- if (i != 1)
- strcat(buf, " ");
- strcat(buf, argv[i]);
- }
-
-
- rv = sendto(s, buf, strlen(buf), 0, (struct sockaddr *)&addr, addrlen);
-
- printf("send %d \"%s\"\n", rv, buf);
- return 0;
-}
-
diff --git a/group/test/clientd.c b/group/test/clientd.c
deleted file mode 100644
index 9f344f4..0000000
--- a/group/test/clientd.c
+++ /dev/null
@@ -1,179 +0,0 @@
-#include <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <asm/types.h>
-#include <sys/socket.h>
-#include <sys/poll.h>
-#include <sys/un.h>
-#include <linux/netlink.h>
-
-#define GROUPD_SOCK_PATH "groupd_socket"
-#define COMMAND_SOCK_PATH "command_socket"
-
-#define MAXLINE 256
-#define MAXCON 4
-
-#define log_error(fmt, args...) fprintf(stderr, fmt "\n", ##args)
-
-int groupd_fd;
-int command_fd;
-struct sockaddr_un sun;
-struct sockaddr_un addr;
-socklen_t addrlen;
-
-
-void process_groupd(void)
-{
- char buf[MAXLINE];
- int rv;
-
- memset(buf, 0, sizeof(buf));
-
- rv = read(groupd_fd, &buf, sizeof(buf));
- if (rv < 0) {
- log_error("read error %d errno %d", rv, errno);
- return;
- }
-
- printf("I: groupd read: %s\n", buf);
-}
-
-void process_command(void)
-{
- char buf[MAXLINE];
- int rv;
-
- memset(buf, 0, sizeof(buf));
-
- rv = recvfrom(command_fd, buf, MAXLINE, 0, (struct sockaddr *) &addr,
- &addrlen);
-
- printf("I: command recv: %s\n", buf);
-
- rv = write(groupd_fd, buf, strlen(buf));
- if (rv < 0)
- log_error("groupd write error");
-
- printf("O: command write: %s\n", buf);
-}
-
-void process_input(int fd)
-{
- if (fd == groupd_fd)
- process_groupd();
- else if (fd == command_fd)
- process_command();
-}
-
-void process_hup(int fd)
-{
- if (fd == groupd_fd)
- close(groupd_fd);
- else if (fd == command_fd)
- close(command_fd);
-}
-
-int setup_groupd(void)
-{
- char buf[] = "setup test 1";
- int rv;
-
- rv = write(groupd_fd, &buf, strlen(buf));
- if (rv < 0) {
- log_error("write error %d errno %d %s", rv, errno, buf);
- return -1;
- }
- return 0;
-}
-
-int loop(void)
-{
- struct pollfd *pollfd;
- int s, rv, i, maxi;
-
-
- pollfd = malloc(MAXCON * sizeof(struct pollfd));
- if (!pollfd)
- return -1;
-
-
- /* connect to the groupd server */
-
- s = socket(AF_LOCAL, SOCK_STREAM, 0);
- if (s < 0) {
- log_error("socket");
- exit(1);
- }
-
- memset(&sun, 0, sizeof(sun));
- sun.sun_family = AF_LOCAL;
- strcpy(&sun.sun_path[1], GROUPD_SOCK_PATH);
- addrlen = sizeof(sa_family_t) + strlen(sun.sun_path+1) + 1;
-
- rv = connect(s, (struct sockaddr *) &sun, addrlen);
- if (rv < 0) {
- log_error("groupd connect error %d errno %d", rv, errno);
- exit(1);
- }
-
- groupd_fd = s;
- pollfd[0].fd = s;
- pollfd[0].events = POLLIN;
-
-
- /* get commands via another local socket */
-
- s = socket(AF_LOCAL, SOCK_DGRAM, 0);
- if (s < 0) {
- log_error("socket");
- exit(1);
- }
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_LOCAL;
- strcpy(&addr.sun_path[1], COMMAND_SOCK_PATH);
- addrlen = sizeof(sa_family_t) + strlen(addr.sun_path+1) + 1;
-
- rv = bind(s, (struct sockaddr *) &addr, addrlen);
- if (rv < 0) {
- log_error("bind error");
- exit(1);
- }
-
- command_fd = s;
- pollfd[1].fd = s;
- pollfd[1].events = POLLIN;
-
- maxi = 1;
-
- rv = setup_groupd();
- if (rv < 0) {
- log_error("setup_groupd");
- exit(1);
- }
-
- for (;;) {
- rv = poll(pollfd, maxi + 1, -1);
- if (rv < 0)
- log_error("poll");
-
- for (i = 0; i <= maxi; i++) {
- if (pollfd[i].revents & (POLLHUP | POLLERR | POLLNVAL)) {
- process_hup(pollfd[i].fd);
- } else if (pollfd[i].revents & POLLIN) {
- process_input(pollfd[i].fd);
- }
- }
- }
-
- free(pollfd);
- return 0;
-}
-
-int main(int argc, char **argv)
-{
- return loop();
-}
-
diff --git a/group/tool/Makefile b/group/tool/Makefile
index ba5d960..191e4cc 100644
--- a/group/tool/Makefile
+++ b/group/tool/Makefile
@@ -2,7 +2,7 @@ TARGET= group_tool
SBINDIRT=$(TARGET)
-all: depends ${TARGET}
+all: ${TARGET}
include ../../make/defines.mk
include $(OBJDIR)/make/cobj.mk
@@ -12,27 +12,12 @@ include $(OBJDIR)/make/uninstall.mk
OBJS= main.o
-CFLAGS += -I$(S) -I$(S)/../daemon/ -I$(S)/../lib/
-CFLAGS += -I${dlmcontrolincdir}
-CFLAGS += -I$(S)/../../fence/libfenced
-CFLAGS += -I$(S)/../libgfscontrol
+CFLAGS += -I$(S)
CFLAGS += -I${incdir}
-CFLAGS += -I${KERNEL_SRC}/include/
-LDFLAGS += -L${dlmcontrollibdir} -ldlmcontrol
-LDFLAGS += -L../lib -lgroup
-LDFLAGS += -L../../fence/libfenced -lfenced
-LDFLAGS += -L../libgfscontrol -lgfscontrol
LDFLAGS += -L${libdir}
-LDDEPS += ../lib/libgroup.a
-LDDEPS += ../libgfscontrol/libgfscontrol.a
-LDDEPS += ../../fence/libfenced/libfenced.a
-
-${TARGET}: ${OBJS} ${LDDEPS}
+${TARGET}: ${OBJS}
$(CC) -o $@ $^ $(LDFLAGS)
-depends:
- $(MAKE) -C ../lib all
-
clean: generalclean
diff --git a/group/tool/main.c b/group/tool/main.c
index e1d911c..351e1b6 100644
--- a/group/tool/main.c
+++ b/group/tool/main.c
@@ -11,71 +11,17 @@
#include <errno.h>
#include <limits.h>
#include <netinet/in.h>
-#include <linux/dlmconstants.h>
-#include "libgroup.h"
-#include "groupd.h"
-#include "libfenced.h"
-#include "libdlmcontrol.h"
-#include "libgfscontrol.h"
#include "copyright.cf"
-#define GROUP_LIBGROUP 2
-#define GROUP_LIBCPG 3
-
-#define MAX_NODES 128
-#define MAX_LS 128
-#define MAX_MG 128
-#define MAX_GROUPS 128
-
#define OP_LIST 1
#define OP_DUMP 2
-#define OP_LOG 3
static char *prog_name;
static int operation;
static int opt_ind;
static int verbose;
-static int all_daemons;
static int ls_all_nodes;
-static int print_header_done;
-
-
-static int do_write(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- retry:
- rv = write(fd, buf + off, count);
- if (rv == -1 && errno == EINTR)
- goto retry;
- if (rv < 0)
- return rv;
-
- if (rv != count) {
- count -= rv;
- off += rv;
- goto retry;
- }
- return 0;
-}
-
-static int do_read(int fd, void *buf, size_t count)
-{
- int rv, off = 0;
-
- while (off < count) {
- rv = read(fd, buf + off, count - off);
- if (rv == 0)
- return -1;
- if (rv == -1 && errno == EINTR)
- continue;
- if (rv == -1)
- return -1;
- off += rv;
- }
- return 0;
-}
static void print_usage(void)
{
@@ -84,29 +30,19 @@ static void print_usage(void)
printf("%s [options] [ls|dump]\n", prog_name);
printf("\n");
printf("Options:\n");
- printf(" -v Verbose output, extra event information\n");
- printf(" -a fence_tool ls; dlm_tool ls; gfs_control ls\n");
- printf(" -n Show all node information with -a\n");
+ printf(" -v Verbose output, extra information\n");
+ printf(" -n Show all node information\n");
printf(" -h Print this help, then exit\n");
printf(" -V Print program version information, then exit\n");
printf("\n");
- printf("Display group information from groupd\n");
- printf("ls Show information for all groups\n");
- printf("ls <level> <name> Show information one group. If\n");
- printf(" we are not a member of the group,\n");
- printf(" return 1.\n");
- printf("\n");
printf("Display debugging information\n");
- printf("dump Show debug log from groupd\n");
printf("dump fence Show debug log from fenced\n");
+ printf("dump dlm Show debug log from dlm_controld\n");
printf("dump gfs Show debug log from gfs_controld\n");
- printf("dump plocks <name> Show posix locks for gfs with given name\n");
- printf("\n");
- printf("log <comments> Add information to the groupd log.\n");
printf("\n");
}
-#define OPTION_STRING "ahVvn"
+#define OPTION_STRING "hVvn"
static void decode_arguments(int argc, char **argv)
{
@@ -117,10 +53,6 @@ static void decode_arguments(int argc, char **argv)
optchar = getopt(argc, argv, OPTION_STRING);
switch (optchar) {
- case 'a':
- all_daemons = 1;
- break;
-
case 'n':
ls_all_nodes = 1;
break;
@@ -168,10 +100,6 @@ static void decode_arguments(int argc, char **argv)
operation = OP_LIST;
opt_ind = optind + 1;
break;
- } else if (strcmp(argv[optind], "log") == 0) {
- operation = OP_LOG;
- opt_ind = optind + 1;
- break;
}
optind++;
}
@@ -180,565 +108,36 @@ static void decode_arguments(int argc, char **argv)
operation = OP_LIST;
}
-/* copied from grouip/daemon/gd_internal.h, must keep in sync */
-
-#define EST_JOIN_BEGIN 1
-#define EST_JOIN_STOP_WAIT 2
-#define EST_JOIN_ALL_STOPPED 3
-#define EST_JOIN_START_WAIT 4
-#define EST_JOIN_ALL_STARTED 5
-#define EST_LEAVE_BEGIN 6
-#define EST_LEAVE_STOP_WAIT 7
-#define EST_LEAVE_ALL_STOPPED 8
-#define EST_LEAVE_START_WAIT 9
-#define EST_LEAVE_ALL_STARTED 10
-#define EST_FAIL_BEGIN 11
-#define EST_FAIL_STOP_WAIT 12
-#define EST_FAIL_ALL_STOPPED 13
-#define EST_FAIL_START_WAIT 14
-#define EST_FAIL_ALL_STARTED 15
-
-char *ev_state_str(state)
-{
- switch (state) {
- case EST_JOIN_BEGIN:
- return "JOIN_BEGIN";
- case EST_JOIN_STOP_WAIT:
- return "JOIN_STOP_WAIT";
- case EST_JOIN_ALL_STOPPED:
- return "JOIN_ALL_STOPPED";
- case EST_JOIN_START_WAIT:
- return "JOIN_START_WAIT";
- case EST_JOIN_ALL_STARTED:
- return "JOIN_ALL_STARTED";
- case EST_LEAVE_BEGIN:
- return "LEAVE_BEGIN";
- case EST_LEAVE_STOP_WAIT:
- return "LEAVE_STOP_WAIT";
- case EST_LEAVE_ALL_STOPPED:
- return "LEAVE_ALL_STOPPED";
- case EST_LEAVE_START_WAIT:
- return "LEAVE_START_WAIT";
- case EST_LEAVE_ALL_STARTED:
- return "LEAVE_ALL_STARTED";
- case EST_FAIL_BEGIN:
- return "FAIL_BEGIN";
- case EST_FAIL_STOP_WAIT:
- return "FAIL_STOP_WAIT";
- case EST_FAIL_ALL_STOPPED:
- return "FAIL_ALL_STOPPED";
- case EST_FAIL_START_WAIT:
- return "FAIL_START_WAIT";
- case EST_FAIL_ALL_STARTED:
- return "FAIL_ALL_STARTED";
- default:
- return "unknown";
- }
-}
-
-char *state_str(group_data_t *data)
-{
- static char buf[128];
-
- memset(buf, 0, sizeof(buf));
-
- if (!data->event_state && !data->event_nodeid)
- sprintf(buf, "none");
- else if (verbose)
- snprintf(buf, 127, "%s %d %llx %d",
- ev_state_str(data->event_state),
- data->event_nodeid,
- (unsigned long long)data->event_id,
- data->event_local_status);
- else
- snprintf(buf, 127, "%s", ev_state_str(data->event_state));
-
- return buf;
-}
-
-static int data_compare(const void *va, const void *vb)
-{
- const group_data_t *a = va;
- const group_data_t *b = vb;
- return a->level - b->level;
-}
-
-static int member_compare(const void *va, const void *vb)
-{
- const int *a = va;
- const int *b = vb;
- return *a - *b;
-}
-
-static int groupd_list(int argc, char **argv)
-{
- group_data_t data[MAX_GROUPS];
- int i, j, rv, count = 0, level, ret = 0;
- char *name, *state_header;
- int type_width = 16;
- int level_width = 5;
- int name_width = 32;
- int id_width = 8;
- int state_width = 12;
- int len, max_name = 4;
-
- memset(&data, 0, sizeof(data));
-
- if (opt_ind && opt_ind < argc) {
- level = atoi(argv[opt_ind++]);
- name = argv[opt_ind];
-
- rv = group_get_group(level, name, data);
- count = 1;
-
- /* don't output if there's no group at all */
- if (data[0].id == 0) {
- fprintf(stderr, "groupd has no information about "
- "the specified group\n");
- return 1;
- }
- /* If we wanted a specific group but we are not
- joined, print it out - but return failure to
- the caller */
- if (data[0].member != 1)
- ret = 1;
- } else
- rv = group_get_groups(MAX_GROUPS, &count, data);
-
- if (rv < 0)
- return rv;
-
- if (!count)
- return 0;
-
- for (i = 0; i < count; i++) {
- len = strlen(data[i].name);
- if (len > max_name)
- max_name = len;
- }
- name_width = max_name + 1;
-
- if (verbose)
- state_header = "state node id local_done";
- else
- state_header = "state";
-
- qsort(&data, count, sizeof(group_data_t), data_compare);
-
- for (i = 0; i < count; i++) {
- if (!i)
- printf("%-*s %-*s %-*s %-*s %-*s\n",
- type_width, "type",
- level_width, "level",
- name_width, "name",
- id_width, "id",
- state_width, state_header);
-
- printf("%-*s %-*d %-*s %0*x %-*s\n",
- type_width, data[i].client_name,
- level_width, data[i].level,
- name_width, data[i].name,
- id_width, data[i].id,
- state_width, state_str(&data[i]));
-
- qsort(&data[i].members, data[i].member_count,
- sizeof(int), member_compare);
-
- printf("[");
- for (j = 0; j < data[i].member_count; j++) {
- if (j != 0)
- printf(" ");
- printf("%d", data[i].members[j]);
- }
- printf("]\n");
- }
- return ret;
-}
-
-static int fenced_node_compare(const void *va, const void *vb)
-{
- const struct fenced_node *a = va;
- const struct fenced_node *b = vb;
-
- return a->nodeid - b->nodeid;
-}
-
-static void print_header(void)
-{
- if (print_header_done)
- return;
- print_header_done = 1;
-
- printf("type level name id state\n");
-}
-
-static void fenced_list(void)
-{
- struct fenced_domain d;
- struct fenced_node nodes[MAX_NODES];
- struct fenced_node *np;
- int node_count;
- int rv, j;
-
- rv = fenced_domain_info(&d);
- if (rv < 0)
- return;
-
- print_header();
-
- printf("fence 0 %-*s %08x %d\n",
- 16, "default", 0, d.state);
-
- node_count = 0;
- memset(&nodes, 0, sizeof(nodes));
-
- rv = fenced_domain_nodes(FENCED_NODES_MEMBERS, MAX_NODES,
- &node_count, nodes);
- if (rv < 0 || !node_count)
- goto do_nodeids;
-
- qsort(&nodes, node_count, sizeof(struct fenced_node),
- fenced_node_compare);
-
- do_nodeids:
- printf("[");
- np = nodes;
- for (j = 0; j < node_count; j++) {
- if (j)
- printf(" ");
- printf("%d", np->nodeid);
- np++;
- }
- printf("]\n");
-}
-
-static int dlmc_node_compare(const void *va, const void *vb)
-{
- const struct dlmc_node *a = va;
- const struct dlmc_node *b = vb;
-
- return a->nodeid - b->nodeid;
-}
-
-static void dlm_controld_list(void)
-{
- struct dlmc_lockspace lss[MAX_LS];
- struct dlmc_node nodes[MAX_NODES];
- struct dlmc_node *np;
- struct dlmc_lockspace *ls;
- char *name = NULL;
- int node_count;
- int ls_count;
- int rv;
- int i, j;
-
- memset(lss, 0, sizeof(lss));
-
- if (name) {
- rv = dlmc_lockspace_info(name, lss);
- if (rv < 0)
- return;
- ls_count = 1;
- } else {
- rv = dlmc_lockspaces(MAX_LS, &ls_count, lss);
- if (rv < 0)
- return;
- }
-
- for (i = 0; i < ls_count; i++) {
- ls = &lss[i];
-
- if (!i)
- print_header();
-
- printf("dlm 1 %-*s %08x %x\n",
- 16, ls->name, ls->global_id, ls->flags);
-
- node_count = 0;
- memset(&nodes, 0, sizeof(nodes));
-
- rv = dlmc_lockspace_nodes(ls->name, DLMC_NODES_MEMBERS,
- MAX_NODES, &node_count, nodes);
- if (rv < 0 || !node_count)
- goto do_nodeids;
-
- qsort(nodes, node_count, sizeof(struct dlmc_node),
- dlmc_node_compare);
-
- do_nodeids:
- printf("[");
- np = nodes;
- for (j = 0; j < node_count; j++) {
- if (j)
- printf(" ");
- printf("%d", np->nodeid);
- np++;
- }
- printf("]\n");
- }
-}
-
-static int gfsc_node_compare(const void *va, const void *vb)
-{
- const struct gfsc_node *a = va;
- const struct gfsc_node *b = vb;
-
- return a->nodeid - b->nodeid;
-}
-
-static void gfs_controld_list(void)
-{
- struct gfsc_mountgroup mgs[MAX_MG];
- struct gfsc_node nodes[MAX_NODES];
- struct gfsc_node *np;
- struct gfsc_mountgroup *mg;
- char *name = NULL;
- int node_count;
- int mg_count;
- int rv;
- int i, j;
-
- memset(mgs, 0, sizeof(mgs));
-
- if (name) {
- rv = gfsc_mountgroup_info(name, mgs);
- if (rv < 0)
- return;
- mg_count = 1;
- } else {
- rv = gfsc_mountgroups(MAX_MG, &mg_count, mgs);
- if (rv < 0)
- return;
- }
-
- for (i = 0; i < mg_count; i++) {
- mg = &mgs[i];
-
- if (!i)
- print_header();
-
- printf("gfs 2 %-*s %08x %x\n",
- 16, mg->name, mg->global_id, mg->flags);
-
- node_count = 0;
- memset(&nodes, 0, sizeof(nodes));
-
- rv = gfsc_mountgroup_nodes(mg->name, GFSC_NODES_MEMBERS,
- MAX_NODES, &node_count, nodes);
- if (rv < 0 || !node_count)
- goto do_nodeids;
-
- qsort(nodes, node_count, sizeof(struct gfsc_node),
- gfsc_node_compare);
-
- do_nodeids:
- printf("[");
- np = nodes;
- for (j = 0; j < node_count; j++) {
- if (j)
- printf(" ");
- printf("%d", np->nodeid);
- np++;
- }
- printf("]\n");
- }
-}
-
-static int connect_daemon(char *path)
-{
- struct sockaddr_un sun;
- socklen_t addrlen;
- int rv, fd;
-
- fd = socket(PF_UNIX, SOCK_STREAM, 0);
- if (fd < 0)
- goto out;
-
- memset(&sun, 0, sizeof(sun));
- sun.sun_family = AF_UNIX;
- strcpy(&sun.sun_path[1], path);
- addrlen = sizeof(sa_family_t) + strlen(sun.sun_path+1) + 1;
-
- rv = connect(fd, (struct sockaddr *) &sun, addrlen);
- if (rv < 0) {
- close(fd);
- fd = rv;
- }
- out:
- return fd;
-}
-
-static void groupd_dump_debug(int argc, char **argv, char *inbuf)
-{
- char outbuf[GROUPD_MSGLEN];
- int rv, fd;
-
- fd = connect_daemon(GROUPD_SOCK_PATH);
- if (fd < 0)
- return;
-
- memset(outbuf, 0, sizeof(outbuf));
- sprintf(outbuf, "dump");
-
- rv = do_write(fd, outbuf, sizeof(outbuf));
- if (rv < 0) {
- printf("dump write error %d errno %d\n", rv, errno);
- return;
- }
-
- do_read(fd, inbuf, GROUPD_DUMP_SIZE);
-
- close(fd);
-}
-
-static int do_log(char *comment)
-{
- char buf[GROUPD_MSGLEN];
- int fd, rv;
-
- fd = connect_daemon(GROUPD_SOCK_PATH);
- if (fd < 0)
- return fd;
- memset(buf, 0, sizeof(buf));
- snprintf(buf, sizeof(buf), "log %s", comment);
- rv = write(fd, &buf, GROUPD_MSGLEN);
- close(fd);
- return rv;
-}
-
int main(int argc, char **argv)
{
- int rv, version = 0;
-
prog_name = argv[0];
decode_arguments(argc, argv);
switch (operation) {
case OP_LIST:
-
- rv = group_get_version(&version);
- if (rv < 0)
- version = -1;
-
- switch (version) {
- case -1:
- printf("groupd not running\n");
- break;
- case -EAGAIN:
- printf("groupd compatibility mode 2 (pending)\n");
- break;
- case GROUP_LIBGROUP:
- printf("groupd compatibility mode 1\n");
- break;
- case GROUP_LIBCPG:
- printf("groupd compatibility mode 0\n");
- break;
- default:
- printf("groupd compatibility mode %d\n", version);
- break;
- }
-
- if (all_daemons) {
- /* show the new cluster3 data (from daemons) in
- the new daemon-specific format */
-
- if (verbose || ls_all_nodes) {
- system("fence_tool ls -n");
- system("dlm_tool ls -n");
- system("gfs_control ls -n");
- } else {
- system("fence_tool ls");
- system("dlm_tool ls");
- system("gfs_control ls");
- }
-
- if (version == GROUP_LIBGROUP)
- printf("Run 'group_tool ls' for groupd information.\n");
-
+ if (verbose || ls_all_nodes) {
+ system("fence_tool ls -n");
+ system("dlm_tool ls -n");
+ system("gfs_control ls -n");
} else {
- if (version == GROUP_LIBGROUP) {
- /* show the same old cluster2 data (from groupd)
- in the same old format as cluster2 */
-
- groupd_list(argc, argv);
-
- } else if (version == GROUP_LIBCPG || version == -1) {
- /* show the new cluster3 data (from daemons)
- in the (nearly) same old format as cluster2 */
-
- fenced_list();
- dlm_controld_list();
- gfs_controld_list();
-
- printf("Run 'group_tool ls -a' for daemon information.\n");
- }
+ system("fence_tool ls");
+ system("dlm_tool ls");
+ system("gfs_control ls");
}
break;
case OP_DUMP:
if (opt_ind && opt_ind < argc) {
- if (!strncmp(argv[opt_ind], "gfs", 3)) {
- char gbuf[GFSC_DUMP_SIZE];
-
- memset(gbuf, 0, sizeof(gbuf));
+ if (!strncmp(argv[opt_ind], "gfs", 3))
+ system("gfs_control dump");
- printf("dump gfs\n");
- gfsc_dump_debug(gbuf);
+ if (!strncmp(argv[opt_ind], "dlm", 3))
+ system("dlm_tool dump");
- do_write(STDOUT_FILENO, gbuf, strlen(gbuf));
- }
-
- if (!strncmp(argv[opt_ind], "dlm", 3)) {
- char dbuf[DLMC_DUMP_SIZE];
-
- memset(dbuf, 0, sizeof(dbuf));
-
- printf("dump dlm\n");
- dlmc_dump_debug(dbuf);
-
- do_write(STDOUT_FILENO, dbuf, strlen(dbuf));
- }
-
- if (!strncmp(argv[opt_ind], "fence", 5)) {
- char fbuf[FENCED_DUMP_SIZE];
-
- memset(fbuf, 0, sizeof(fbuf));
-
- fenced_dump_debug(fbuf);
-
- do_write(STDOUT_FILENO, fbuf, strlen(fbuf));
- }
-
- if (!strncmp(argv[opt_ind], "plocks", 6)) {
- char pbuf[DLMC_DUMP_SIZE];
-
- if (opt_ind + 1 >= argc) {
- printf("plock dump requires name\n");
- return -1;
- }
-
- memset(pbuf, 0, sizeof(pbuf));
-
- dlmc_dump_plocks(argv[opt_ind + 1], pbuf);
-
- do_write(STDOUT_FILENO, pbuf, strlen(pbuf));
- }
- } else {
- char rbuf[GROUPD_DUMP_SIZE];
-
- memset(rbuf, 0, sizeof(rbuf));
-
- groupd_dump_debug(argc, argv, rbuf);
-
- do_write(STDOUT_FILENO, rbuf, strlen(rbuf));
+ if (!strncmp(argv[opt_ind], "fence", 5))
+ system("fence_tool dump");
}
-
break;
-
- case OP_LOG:
- if (opt_ind && opt_ind < argc) {
- return do_log(argv[opt_ind]);
- }
}
return 0;