From mboxrd@z Thu Jan 1 00:00:00 1970 From: pcaulfield@sourceware.org Date: 17 Sep 2007 13:22:33 -0000 Subject: [Cluster-devel] cluster/cman cman_tool/main.c daemon/cnxman-pr ... Message-ID: <20070917132233.20254.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit CVSROOT: /cvs/cluster Module name: cluster Branch: RHEL5 Changes by: pcaulfield at sourceware.org 2007-09-17 13:22:31 Modified files: cman/cman_tool : main.c cman/daemon : cnxman-private.h cnxman-socket.h commands.c cman/lib : libcman.c libcman.h cman/tests : sysmand.c Log message: Add dirty-flag to RHEL5 branch Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/cman_tool/main.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.51.2.1&r2=1.51.2.2 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/daemon/cnxman-private.h.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.26&r2=1.26.2.1 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/daemon/cnxman-socket.h.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.17&r2=1.17.2.1 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/daemon/commands.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.55.2.9&r2=1.55.2.10 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/lib/libcman.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.30.2.3&r2=1.30.2.4 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/lib/libcman.h.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.29&r2=1.29.2.1 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/tests/sysmand.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.2&r2=1.2.2.1 --- cluster/cman/cman_tool/main.c 2007/02/19 14:05:04 1.51.2.1 +++ cluster/cman/cman_tool/main.c 2007/09/17 13:22:30 1.51.2.2 @@ -235,6 +235,8 @@ printf(" Error"); if (einfo->ei_flags & CMAN_EXTRA_FLAG_DISALLOWED) printf(" DisallowedNodes"); + if (einfo->ei_flags & CMAN_EXTRA_FLAG_DIRTY) + printf(" Dirty"); printf(" \n"); printf("Ports Bound: "); --- cluster/cman/daemon/cnxman-private.h 2006/11/03 15:07:52 1.26 +++ cluster/cman/daemon/cnxman-private.h 2007/09/17 13:22:31 1.26.2.1 @@ -18,8 +18,8 @@ /* Protocol Version triplet */ #define CNXMAN_MAJOR_VERSION 6 -#define CNXMAN_MINOR_VERSION 0 -#define CNXMAN_PATCH_VERSION 1 +#define CNXMAN_MINOR_VERSION 1 +#define CNXMAN_PATCH_VERSION 0 /* How we announce ourself in console events */ #define CMAN_NAME "CMAN" @@ -147,11 +147,14 @@ NODE_FLAGS_FENCED - This node has been fenced since it last went down. NODE_FLAGS_FENCEDWHILEUP - This node was fenced manually (probably). NODE_FLAGS_SEESDISALLOWED - Only set in a transition message + NODE_FLAGS_DIRTY - This node has internal state and must not join + a cluster that also has state. */ #define NODE_FLAGS_BEENDOWN 1 #define NODE_FLAGS_FENCED 2 #define NODE_FLAGS_FENCEDWHILEUP 4 #define NODE_FLAGS_SEESDISALLOWED 8 +#define NODE_FLAGS_DIRTY 16 /* There's one of these for each node in the cluster */ struct cluster_node { --- cluster/cman/daemon/cnxman-socket.h 2006/10/05 07:48:33 1.17 +++ cluster/cman/daemon/cnxman-socket.h 2007/09/17 13:22:31 1.17.2.1 @@ -52,6 +52,7 @@ #define CMAN_CMD_GET_NODEADDRS 0x000000bf #define CMAN_CMD_START_CONFCHG 0x000000c0 #define CMAN_CMD_STOP_CONFCHG 0x000000c1 +#define CMAN_CMD_SET_DIRTY 0x800000c2 #define CMAN_CMD_DATA 0x00000100 #define CMAN_CMD_BIND 0x00000101 @@ -167,6 +168,7 @@ #define CMAN_EXTRA_FLAG_ERROR 2 #define CMAN_EXTRA_FLAG_SHUTDOWN 4 #define CMAN_EXTRA_FLAG_UNCOUNTED 8 +#define CMAN_EXTRA_FLAG_DIRTY 16 struct cl_extra_info { int node_state; --- cluster/cman/daemon/commands.c 2007/08/31 14:26:04 1.55.2.9 +++ cluster/cman/daemon/commands.c 2007/09/17 13:22:31 1.55.2.10 @@ -501,6 +501,8 @@ einfo->flags |= CMAN_EXTRA_FLAG_SHUTDOWN; if (uncounted) einfo->flags |= CMAN_EXTRA_FLAG_UNCOUNTED; + if (us->flags & NODE_FLAGS_DIRTY) + einfo->flags |= CMAN_EXTRA_FLAG_DIRTY; ptr = einfo->addresses; for (i=0; iflags |= NODE_FLAGS_DIRTY; + break; + case CMAN_CMD_START_CONFCHG: con->confchg = 1; err = 0; @@ -1705,7 +1711,27 @@ node = find_node_by_nodeid(nodeid); assert(node); - /* This is the killer. If the join_time of the node matches that already stored AND + /* Newer nodes 6.1.0 onwards, set the DIRTY flag if they have state. If the new node has been down + and has state then we mark it disallowed because we cannot merge stateful nodes */ + if (msg->flags & NODE_FLAGS_DIRTY && node->flags & NODE_FLAGS_BEENDOWN) { + /* Don't duplicate messages */ + if (node->state != NODESTATE_AISONLY) { + if (cluster_is_quorate) { + P_MEMB("Killing node %s because it has rejoined the cluster with existing state", node->name); + log_printf(LOG_CRIT, "Killing node %s because it has rejoined the cluster with existing state", node->name); + node->state = NODESTATE_AISONLY; + send_kill(nodeid, CLUSTER_KILL_REJOIN); + } + else { + P_MEMB("Node %s not joined to cman because it has existing state", node->name); + log_printf(LOG_CRIT, "Node %s not joined to cman because it has existing state", node->name); + node->state = NODESTATE_AISONLY; + } + } + return; + } + + /* This is for older nodes. If the join_time of the node matches that already stored AND the node has been down, then we kill it as this must be a rejoin */ if (msg->join_time == node->cman_join_time && node->flags & NODE_FLAGS_BEENDOWN) { /* Don't duplicate messages */ --- cluster/cman/lib/libcman.c 2007/01/05 10:31:33 1.30.2.3 +++ cluster/cman/lib/libcman.c 2007/09/17 13:22:31 1.30.2.4 @@ -1,7 +1,7 @@ /****************************************************************************** ******************************************************************************* ** -** Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. +** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public @@ -250,7 +250,7 @@ } -static int send_message(struct cman_handle *h, int msgtype, void *inbuf, int inlen) +static int send_message(struct cman_handle *h, int msgtype, const void *inbuf, int inlen) { struct sock_header header; size_t len; @@ -268,7 +268,7 @@ if (inbuf) { iov[1].iov_len = inlen; - iov[1].iov_base = inbuf; + iov[1].iov_base = (void *) inbuf; iovlen++; } @@ -279,7 +279,7 @@ } /* Does something similar to the ioctl calls */ -static int info_call(struct cman_handle *h, int msgtype, void *inbuf, int inlen, void *outbuf, int outlen) +static int info_call(struct cman_handle *h, int msgtype, const void *inbuf, int inlen, void *outbuf, int outlen) { if (send_message(h, msgtype, inbuf, inlen)) return -1; @@ -752,7 +752,7 @@ return info_call(h, CMAN_CMD_GET_VERSION, NULL, 0, version, sizeof(cman_version_t)); } -int cman_set_version(cman_handle_t handle, cman_version_t *version) +int cman_set_version(cman_handle_t handle, const cman_version_t *version) { struct cman_handle *h = (struct cman_handle *)handle; VALIDATE_HANDLE(h); @@ -841,7 +841,7 @@ return info_call(h, CMAN_CMD_GETEXTRAINFO, NULL, 0, info, maxlen); } -int cman_send_data(cman_handle_t handle, void *buf, int len, int flags, uint8_t port, int nodeid) +int cman_send_data(cman_handle_t handle, const void *buf, int len, int flags, uint8_t port, int nodeid) { struct cman_handle *h = (struct cman_handle *)handle; struct iovec iov[2]; @@ -859,7 +859,7 @@ iov[0].iov_len = sizeof(header); iov[0].iov_base = &header; iov[1].iov_len = len; - iov[1].iov_base = buf; + iov[1].iov_base = (void *) buf; return loopy_writev(h->fd, iov, 2); } @@ -892,7 +892,7 @@ } -int cman_barrier_register(cman_handle_t handle, char *name, int flags, int nodes) +int cman_barrier_register(cman_handle_t handle, const char *name, int flags, int nodes) { struct cman_handle *h = (struct cman_handle *)handle; struct cl_barrier_info binfo; @@ -913,7 +913,7 @@ } -int cman_barrier_change(cman_handle_t handle, char *name, int flags, int arg) +int cman_barrier_change(cman_handle_t handle, const char *name, int flags, int arg) { struct cman_handle *h = (struct cman_handle *)handle; struct cl_barrier_info binfo; @@ -934,7 +934,7 @@ } -int cman_barrier_wait(cman_handle_t handle, char *name) +int cman_barrier_wait(cman_handle_t handle, const char *name) { struct cman_handle *h = (struct cman_handle *)handle; struct cl_barrier_info binfo; @@ -952,7 +952,7 @@ return info_call(h, CMAN_CMD_BARRIER, &binfo, sizeof(binfo), NULL, 0); } -int cman_barrier_delete(cman_handle_t handle, char *name) +int cman_barrier_delete(cman_handle_t handle, const char *name) { struct cman_handle *h = (struct cman_handle *)handle; struct cl_barrier_info binfo; @@ -978,6 +978,14 @@ return info_call(h, CMAN_CMD_TRY_SHUTDOWN, &flags, sizeof(int), NULL, 0); } +int cman_set_dirty(cman_handle_t handle) +{ + struct cman_handle *h = (struct cman_handle *)handle; + VALIDATE_HANDLE(h); + + return info_call(h, CMAN_CMD_SET_DIRTY, NULL, 0, NULL, 0); +} + int cman_replyto_shutdown(cman_handle_t handle, int yesno) { struct cman_handle *h = (struct cman_handle *)handle; --- cluster/cman/lib/libcman.h 2006/10/05 07:48:33 1.29 +++ cluster/cman/lib/libcman.h 2007/09/17 13:22:31 1.29.2.1 @@ -1,7 +1,7 @@ /****************************************************************************** ******************************************************************************* ** -** Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. +** Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. ** ** This library is free software; you can redistribute it and/or ** modify it under the terms of the GNU Lesser General Public @@ -154,6 +154,7 @@ #define CMAN_EXTRA_FLAG_ERROR 2 #define CMAN_EXTRA_FLAG_SHUTDOWN 4 #define CMAN_EXTRA_FLAG_DISALLOWED 8 +#define CMAN_EXTRA_FLAG_DIRTY 16 typedef struct cman_extra_info { int ei_node_state; @@ -321,7 +322,7 @@ /* Change the config file version. This should be needed much less now, as cman will re-read the config file if a new node joins with a new config versoin */ -int cman_set_version(cman_handle_t handle, cman_version_t *version); +int cman_set_version(cman_handle_t handle, const cman_version_t *version); /* Deprecated in favour of cman_shutdown(). Use cman_tool anyway please. */ int cman_leave_cluster(cman_handle_t handle, int reason); @@ -363,7 +364,7 @@ * cman_start_recv_data() is like a bind(), and marks the port * as "listening". See cman_is_listening() above. */ -int cman_send_data(cman_handle_t handle, void *buf, int len, int flags, uint8_t port, int nodeid); +int cman_send_data(cman_handle_t handle, const void *buf, int len, int flags, uint8_t port, int nodeid); int cman_start_recv_data(cman_handle_t handle, cman_datacallback_t, uint8_t port); int cman_end_recv_data(cman_handle_t handle); @@ -372,10 +373,10 @@ * Here for backwards compatibility. Most of the things you would achieve * with this can now be better done using openAIS services or just messaging. */ -int cman_barrier_register(cman_handle_t handle, char *name, int flags, int nodes); -int cman_barrier_change(cman_handle_t handle, char *name, int flags, int arg); -int cman_barrier_wait(cman_handle_t handle, char *name); -int cman_barrier_delete(cman_handle_t handle, char *name); +int cman_barrier_register(cman_handle_t handle, const char *name, int flags, int nodes); +int cman_barrier_change(cman_handle_t handle, const char *name, int flags, int arg); +int cman_barrier_wait(cman_handle_t handle, const char *name); +int cman_barrier_delete(cman_handle_t handle, const char *name); /* * Add your own quorum device here, needs an admin socket @@ -388,4 +389,12 @@ int cman_unregister_quorum_device(cman_handle_t handle); int cman_poll_quorum_device(cman_handle_t handle, int isavailable); +/* + * Sets the dirty bit inside cman. This indicates that the node has + * some internal 'state' (eg in a daemon, filesystem or lock manager) + * and cannot merge with another cluster that already has state. + * This cannot be reset. + */ +int cman_set_dirty(cman_handle_t handle); + #endif --- cluster/cman/tests/sysmand.c 2006/05/11 10:35:25 1.2 +++ cluster/cman/tests/sysmand.c 2007/09/17 13:22:31 1.2.2.1 @@ -74,7 +74,8 @@ static void event_callback(cman_handle_t handle, void *private, int reason, int arg) { - get_members(); + if (reason == CMAN_REASON_STATECHANGE) + get_members(); } static void data_callback(cman_handle_t handle, void *private,