From mboxrd@z Thu Jan 1 00:00:00 1970 From: pcaulfield@sourceware.org Date: 29 Nov 2007 11:19:14 -0000 Subject: [Cluster-devel] cluster/cman cman_tool/cman_tool.h cman_tool/j ... Message-ID: <20071129111914.16568.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 Changes by: pcaulfield at sourceware.org 2007-11-29 11:19:12 Modified files: cman/cman_tool : cman_tool.h join.c main.c cman/daemon : ais.c cmanccs.c commands.c cman/man : cman_tool.8 Log message: Reinstate 'cman_tool join -X', allowing people to start a cluster without the hassle of a cluster.conf file. There are some caveats to this, which are mentioned in the man page. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/cman_tool/cman_tool.h.diff?cvsroot=cluster&r1=1.13&r2=1.14 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/cman_tool/join.c.diff?cvsroot=cluster&r1=1.51&r2=1.52 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/cman_tool/main.c.diff?cvsroot=cluster&r1=1.59&r2=1.60 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/daemon/ais.c.diff?cvsroot=cluster&r1=1.54&r2=1.55 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/daemon/cmanccs.c.diff?cvsroot=cluster&r1=1.37&r2=1.38 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/daemon/commands.c.diff?cvsroot=cluster&r1=1.75&r2=1.76 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/man/cman_tool.8.diff?cvsroot=cluster&r1=1.14&r2=1.15 --- cluster/cman/cman_tool/cman_tool.h 2007/09/19 15:59:46 1.13 +++ cluster/cman/cman_tool/cman_tool.h 2007/11/29 11:19:12 1.14 @@ -98,6 +98,7 @@ int wait_quorate_opt; int fence_opt; int addresses_opt; + int noccs_opt; }; typedef struct commandline commandline_t; --- cluster/cman/cman_tool/join.c 2007/09/07 14:21:30 1.51 +++ cluster/cman/cman_tool/join.c 2007/11/29 11:19:12 1.52 @@ -62,12 +62,15 @@ int ctree; int p[2]; - ctree = ccs_force_connect(NULL, 1); - if (ctree < 0) + if (!comline->noccs_opt) { - die("ccsd is not running\n"); + ctree = ccs_force_connect(NULL, 1); + if (ctree < 0) + { + die("ccsd is not running\n"); + } + ccs_disconnect(ctree); } - ccs_disconnect(ctree); /* * If we can talk to cman then we're already joined (or joining); @@ -114,6 +117,10 @@ snprintf(scratch, sizeof(scratch), "CMAN_DEBUGLOG=%d", comline->verbose); envp[envptr++] = strdup(scratch); } + if (comline->noccs_opt) { + snprintf(scratch, sizeof(scratch), "CMAN_NOCCS=TRUE"); + envp[envptr++] = strdup(scratch); + } /* Use cman to configure services */ envp[envptr++] = strdup("OPENAIS_DEFAULT_CONFIG_IFACE=cmanconfig"); --- cluster/cman/cman_tool/main.c 2007/09/28 12:18:19 1.59 +++ cluster/cman/cman_tool/main.c 2007/11/29 11:19:12 1.60 @@ -20,7 +20,7 @@ #include "libcman.h" #include "cman_tool.h" -#define OPTION_STRING ("m:n:v:e:2p:c:r:i:N:t:o:k:F:Vwfqah?d::") +#define OPTION_STRING ("m:n:v:e:2p:c:r:i:N:t:o:k:F:Vwfqah?Xd::") #define OP_JOIN 1 #define OP_LEAVE 2 #define OP_EXPECTED 3 @@ -63,6 +63,7 @@ printf(" -q Wait until the cluster is quorate\n"); printf(" -t Maximum time (in seconds) to wait\n"); printf(" -k Private key file for AIS communications\n"); + printf(" -X Don't use CCS for configuration\n"); printf("\n"); } @@ -228,6 +229,7 @@ printf("Nodes: %d\n", einfo->ei_members); printf("Expected votes: %d\n", einfo->ei_expected_votes); printf("Total votes: %d\n", einfo->ei_total_votes); + printf("Quorum: %d %s\n", einfo->ei_quorum, quorate?" ":"Activity blocked"); printf("Active subsystems: %d\n", cman_get_subsys_count(h)); printf("Flags:"); @@ -333,21 +335,128 @@ return FMT_NONE; } + +static void print_node(commandline_t *comline, cman_handle_t h, int *format, struct cman_node *node) +{ + char member_type; + struct tm *ftime; + struct tm *jtime; + char jstring[1024]; + int i,j,k; + + if (comline->num_nodenames > 0) { + if (node_filter(comline, node->cn_name) == 0) { + return; + } + } + + switch (node->cn_member) { + case 0: + member_type = 'X'; + break; + case 1: + member_type = 'M'; + break; + case 2: + member_type = 'd'; + break; + default: + member_type = '?'; + break; + } + + jtime = localtime(&node->cn_jointime.tv_sec); + if (node->cn_jointime.tv_sec && node->cn_member) + strftime(jstring, sizeof(jstring), "%F %H:%M:%S", jtime); + else + strcpy(jstring, " "); + + if (!comline->format_opts) { + printf("%4d %c %5d %s %s\n", + node->cn_nodeid, member_type, + node->cn_incarnation, jstring, node->cn_name); + } + + if (comline->fence_opt && !comline->format_opts) { + char agent[255]; + uint64_t fence_time; + int fenced; + + if (!cman_get_fenceinfo(h, node->cn_nodeid, &fence_time, &fenced, agent)) { + if (fence_time) { + time_t fence_time_t = (time_t)fence_time; + ftime = localtime(&fence_time_t); + strftime(jstring, sizeof(jstring), "%F %H:%M:%S", ftime); + printf(" Last fenced: %-15s by %s\n", jstring, agent); + } + if (!node->cn_member && node->cn_incarnation && !fenced) { + printf(" Node has not been fenced since it went down\n"); + } + } + } + + int numaddrs; + struct cman_node_address addrs[MAX_INTERFACES]; + + if (comline->addresses_opt || comline->format_opts) { + if (!cman_get_node_addrs(h, node->cn_nodeid, MAX_INTERFACES, &numaddrs, addrs) && + numaddrs) + { + if (!comline->format_opts) { + printf(" Addresses: "); + for (i = 0; i < numaddrs; i++) + { + print_address(addrs[i].cna_address); + printf(" "); + } + printf("\n"); + } + } + } + + if (comline->format_opts) { + for (j = 0; j < MAX_FORMAT_OPTS; j++) { + switch (format[j]) { + case FMT_NONE: + break; + case FMT_ID: + printf("%d ", node->cn_nodeid); + break; + case FMT_NAME: + printf("%s ", node->cn_name); + break; + case FMT_TYPE: + printf("%c ", member_type); + break; + case FMT_ADDR: + for (k = 0; k < numaddrs; k++) { + print_address(addrs[k].cna_address); + if (k != (numaddrs - 1)) { + printf(","); + } + } + printf(" "); + break; + default: + break; + } + } + printf("\n"); + } +} + static void show_nodes(commandline_t *comline) { cman_handle_t h; int count; int i; int j; - int k; int numnodes; int dis_count; int format[MAX_FORMAT_OPTS]; cman_node_t *dis_nodes; cman_node_t *nodes; - struct tm *jtime; - struct tm *ftime; - char jstring[1024]; + cman_node_t qdev_node; h = open_cman_handle(0); @@ -399,108 +508,14 @@ printf("Node Sts Inc Joined Name\n"); } - for (i = 0; i < numnodes; i++) { - char member_type; + /* Get quorum device & print it. */ + memset(&qdev_node, 0, sizeof(qdev_node)); + if (!cman_get_node(h, CMAN_NODEID_QDISK, &qdev_node)) + print_node(comline, h, format, &qdev_node); - if (comline->num_nodenames > 0) { - if (node_filter(comline, nodes[i].cn_name) == 0) { - continue; - } - } - - switch (nodes[i].cn_member) { - case 0: - member_type = 'X'; - break; - case 1: - member_type = 'M'; - break; - case 2: - member_type = 'd'; - break; - default: - member_type = '?'; - break; - } - - jtime = localtime(&nodes[i].cn_jointime.tv_sec); - if (nodes[i].cn_jointime.tv_sec && nodes[i].cn_member) - strftime(jstring, sizeof(jstring), "%F %H:%M:%S", jtime); - else - strcpy(jstring, " "); - - if (!comline->format_opts) { - printf("%4d %c %5d %s %s\n", - nodes[i].cn_nodeid, member_type, - nodes[i].cn_incarnation, jstring, nodes[i].cn_name); - } - - if (comline->fence_opt && !comline->format_opts) { - char agent[255]; - uint64_t fence_time; - int fenced; - - if (!cman_get_fenceinfo(h, nodes[i].cn_nodeid, &fence_time, &fenced, agent)) { - if (fence_time) { - time_t fence_time_t = (time_t)fence_time; - ftime = localtime(&fence_time_t); - strftime(jstring, sizeof(jstring), "%F %H:%M:%S", ftime); - printf(" Last fenced: %-15s by %s\n", jstring, agent); - } - if (!nodes[i].cn_member && nodes[i].cn_incarnation && !fenced) { - printf(" Node has not been fenced since it went down\n"); - } - } - } - - int numaddrs; - struct cman_node_address addrs[MAX_INTERFACES]; - - if (comline->addresses_opt || comline->format_opts) { - if (!cman_get_node_addrs(h, nodes[i].cn_nodeid, MAX_INTERFACES, &numaddrs, addrs) && - numaddrs) - { - if (!comline->format_opts) { - printf(" Addresses: "); - for (i = 0; i < numaddrs; i++) - { - print_address(addrs[i].cna_address); - printf(" "); - } - printf("\n"); - } - } - } - - if (comline->format_opts) { - for (j = 0; j < MAX_FORMAT_OPTS; j++) { - switch (format[j]) { - case FMT_NONE: - break; - case FMT_ID: - printf("%d ", nodes[i].cn_nodeid); - break; - case FMT_NAME: - printf("%s ", nodes[i].cn_name); - break; - case FMT_TYPE: - printf("%c ", member_type); - break; - case FMT_ADDR: - for (k = 0; k < numaddrs; k++) { - print_address(addrs[k].cna_address); - if (k != (numaddrs - 1)) { - printf(","); - } - } - printf(" "); - break; - default: - break; - } - } - printf("\n"); - } + /* Print 'real' nodes */ + for (i = 0; i < numnodes; i++) { + print_node(comline, h, format, &nodes[i]); } free(nodes); @@ -833,6 +848,9 @@ cont = FALSE; break; + case 'X': + comline->noccs_opt = TRUE; + break; default: die("unknown option: %c", optchar); break; --- cluster/cman/daemon/ais.c 2007/11/01 14:06:01 1.54 +++ cluster/cman/daemon/ais.c 2007/11/29 11:19:12 1.55 @@ -300,11 +300,17 @@ P_AIS("Adding local address %s\n", ifaddr); - /* This will already exist as early config creates it */ global_objdb->object_find_reset(OBJECT_PARENT_HANDLE); if (global_objdb->object_find(OBJECT_PARENT_HANDLE, - "totem", strlen("totem"),&totem_object_handle) == 0) { + "totem", strlen("totem"), &totem_object_handle)) { + global_objdb->object_create(OBJECT_PARENT_HANDLE, &totem_object_handle, + "totem", strlen("totem")); + } + + global_objdb->object_find_reset(OBJECT_PARENT_HANDLE); + if (global_objdb->object_find(OBJECT_PARENT_HANDLE, + "totem", strlen("totem"), &totem_object_handle) == 0) { if (global_objdb->object_create(totem_object_handle, &interface_object_handle, "interface", strlen("interface")) == 0) { @@ -551,6 +557,13 @@ } /* Make sure mainconfig doesn't stomp on our logging options */ + if (global_objdb->object_find(OBJECT_PARENT_HANDLE, + "logging", strlen("logging"), &object_handle)) { + + global_objdb->object_create(OBJECT_PARENT_HANDLE, &object_handle, + "logging", strlen("logging")); + } + objdb->object_find_reset(OBJECT_PARENT_HANDLE); if (objdb->object_find(OBJECT_PARENT_HANDLE, "logging", strlen("logging"), --- cluster/cman/daemon/cmanccs.c 2007/11/05 16:03:58 1.37 +++ cluster/cman/daemon/cmanccs.c 2007/11/29 11:19:12 1.38 @@ -34,6 +34,8 @@ #define DEFAULT_PORT 5405 +#define DEFAULT_CLUSTER_NAME "RHCluster" +#define NOCCS_KEY_FILENAME "/etc/cluster/cman_authkey" #define CONFIG_VERSION_PATH "/cluster/@config_version" #define CLUSTER_NAME_PATH "/cluster/@name" @@ -61,6 +63,7 @@ static char *nodenames[MAX_NODENAMES]; static int portnums[MAX_NODENAMES]; static char *mcast[MAX_NODENAMES]; +static char *nodename_env; static int num_nodenames; int two_node; char *key_filename; @@ -100,6 +103,11 @@ int expected = 0; unsigned int config; + if (getenv("CMAN_NOCCS")) { + *config_version = 1; + return 0; + } + /* Open the config file */ ctree = ccs_force_connect(NULL, 1); if (ctree < 0) { @@ -425,22 +433,73 @@ return error; } +/* get any environment variable overrides */ +static int get_overrides() +{ + if (getenv("CMAN_CLUSTER_NAME")) { + strcpy(cluster_name, getenv("CMAN_CLUSTER_NAME")); + log_printf(LOG_INFO, "Using override cluster name %s\n", cluster_name); + } + + nodename_env = getenv("CMAN_NODENAME"); + if (nodename_env) { + log_printf(LOG_INFO, "Using override node name %s\n", nodename_env); + } + + expected_votes = 0; + if (getenv("CMAN_EXPECTEDVOTES")) { + expected_votes = atoi(getenv("CMAN_EXPECTEDVOTES")); + if (expected_votes < 1) { + log_printf(LOG_ERR, "CMAN_EXPECTEDVOTES environment variable is invalid, ignoring"); + expected_votes = 0; + } + else { + log_printf(LOG_INFO, "Using override expected votes %d\n", expected_votes); + } + } + + /* optional port */ + if (getenv("CMAN_IP_PORT")) { + portnums[0] = atoi(getenv("CMAN_IP_PORT")); + log_printf(LOG_INFO, "Using override IP port %d\n", portnums[0]); + } + + /* optional security key filename */ + if (getenv("CMAN_KEYFILE")) { + key_filename = strdup(getenv("CMAN_KEYFILE")); + if (key_filename == NULL) + return -ENOMEM; + } + + /* find our own number of votes */ + if (getenv("CMAN_VOTES")) { + votes = atoi(getenv("CMAN_VOTES")); + log_printf(LOG_INFO, "Using override votes %d\n", votes); + } + + /* nodeid */ + if (getenv("CMAN_NODEID")) { + nodeid = atoi(getenv("CMAN_NODEID")); + log_printf(LOG_INFO, "Using override nodeid %d\n", nodeid); + } + + if (getenv("CMAN_MCAST_ADDR")) { + mcast_name = getenv("CMAN_MCAST_ADDR"); + log_printf(LOG_INFO, "Using override multicast address %s\n", mcast_name); + } + return 0; +} static int get_ccs_join_info(void) { char path[MAX_PATH_LEN]; char nodename[MAX_CLUSTER_MEMBER_NAME_LEN+1]; - char *str, *name, *cname = NULL, *nodename_env; + char *str, *name; int cd, error, i, vote_sum = 0, node_count = 0; unsigned short port = 0; /* Connect to ccsd */ - if (getenv("CMAN_CLUSTER_NAME")) { - cname = getenv("CMAN_CLUSTER_NAME"); - log_printf(LOG_INFO, "Using override cluster name %s\n", cname); - } - - cd = ccs_force_connect(cname, 1); + cd = ccs_force_connect(cluster_name[0]?cluster_name:NULL, 1); if (cd < 0) { log_printf(LOG_ERR, "Error connecting to CCS"); write_cman_pipe("Can't connect to CCSD"); @@ -456,9 +515,9 @@ goto out; } - if (cname) { - if (strcmp(cname, str)) { - log_printf(LOG_ERR, "cluster names not equal %s %s", cname, str); + if (cluster_name[0]) { + if (strcmp(cluster_name, str)) { + log_printf(LOG_ERR, "cluster names not equal %s %s", cluster_name, str); write_cman_pipe("Cluster name in CCS does not match that passed to cman_tool"); error = -ENOENT; goto out; @@ -485,20 +544,8 @@ } /* our nodename */ - nodename_env = getenv("CMAN_NODENAME"); - if (nodename_env != NULL) { + if (nodename_env) { int ret; - - if (strlen(nodename_env) >= sizeof(nodename)) { - log_printf(LOG_ERR, "Overridden node name %s is too long", nodename); - write_cman_pipe("Overridden node name is too long"); - error = -E2BIG; - goto out; - } - - strcpy(nodename, nodename_env); - log_printf(LOG_INFO, "Using override node name %s\n", nodename); - ret = snprintf(path, sizeof(path), NODE_NAME_PATH_BYNAME, nodename); if (ret < 0 || (size_t) ret >= sizeof(path)) { log_printf(LOG_ERR, "Overridden node name %s is too long", nodename); @@ -554,18 +601,6 @@ goto out; } - expected_votes = 0; - if (getenv("CMAN_EXPECTEDVOTES")) { - expected_votes = atoi(getenv("CMAN_EXPECTEDVOTES")); - if (expected_votes < 1) { - log_printf(LOG_ERR, "CMAN_EXPECTEDVOTES environment variable is invalid, ignoring"); - expected_votes = 0; - } - else { - log_printf(LOG_INFO, "Using override expected votes %d\n", expected_votes); - } - } - /* Sum node votes for expected */ if (expected_votes == 0) { for (i = 1; ; i++) { @@ -617,13 +652,7 @@ expected_votes = vote_sum; } - /* optional port */ - if (getenv("CMAN_IP_PORT")) { - port = atoi(getenv("CMAN_IP_PORT")); - log_printf(LOG_INFO, "Using override IP port %d\n", port); - } - - if (!port) { + if (!portnums[0]) { error = ccs_get(cd, PORT_PATH, &str); if (!error) { port = atoi(str); @@ -631,28 +660,16 @@ } else port = DEFAULT_PORT; + portnums[0] = port; } - portnums[0] = port; - /* optional security key filename */ - if (getenv("CMAN_KEYFILE")) { - key_filename = strdup(getenv("CMAN_KEYFILE")); - if (key_filename == NULL) - return -ENOMEM; - } - else { + if (!key_filename) { error = ccs_get(cd, KEY_PATH, &str); if (!error) { key_filename = str; } } - /* find our own number of votes */ - if (getenv("CMAN_VOTES")) { - votes = atoi(getenv("CMAN_VOTES")); - log_printf(LOG_INFO, "Using override votes %d\n", votes); - } - if (!votes) { int ret = snprintf(path, sizeof(path), NODE_VOTES_PATH, nodename); if (ret < 0 || (size_t) ret >= sizeof(path)) { @@ -677,13 +694,6 @@ } } - - /* nodeid */ - if (getenv("CMAN_NODEID")) { - nodeid = atoi(getenv("CMAN_NODEID")); - log_printf(LOG_INFO, "Using override nodeid %d\n", nodeid); - } - if (!nodeid) { int ret = snprintf(path, sizeof(path), NODE_NODEID_PATH, nodename); @@ -702,11 +712,6 @@ return -EINVAL; } - if (getenv("CMAN_MCAST_ADDR")) { - mcast_name = getenv("CMAN_MCAST_ADDR"); - log_printf(LOG_INFO, "Using override multicast address %s\n", mcast_name); - } - /* Optional multicast name */ if (!mcast_name) { error = ccs_get(cd, MCAST_ADDR_PATH, &str); @@ -805,6 +810,78 @@ } +/* If ccs is not available then use some defaults */ +static int noccs_defaults() +{ + /* Enforce key */ + key_filename = NOCCS_KEY_FILENAME; + + if (cluster_name[0] == '\0') + strcpy(cluster_name, DEFAULT_CLUSTER_NAME); + + if (!cluster_id) + cluster_id = generate_cluster_id(cluster_name); + + if (!nodename_env) { + int error; + struct utsname utsname; + + error = uname(&utsname); + if (error) { + log_printf(LOG_ERR, "cannot get node name, uname failed"); + write_cman_pipe("Can't determine local node name"); + return -ENOENT; + } + + nodename_env = utsname.nodename; + } + nodenames[0] = strdup(nodename_env); + num_nodenames = 1; + + if (!mcast_name) { + mcast_name = default_mcast(cluster_id); + log_printf(LOG_INFO, "Using default multicast address of %s\n", mcast_name); + } + mcast[0] = mcast_name; + + /* This will increase as nodes join the cluster */ + if (!expected_votes) + expected_votes = 1; + if (!votes) + votes = 1; + + if (!portnums[0]) + portnums[0] = DEFAULT_PORT; + + /* Invent a node ID */ + if (!nodeid) { + struct addrinfo *ainfo; + struct addrinfo ahints; + int ret; + + memset(&ahints, 0, sizeof(ahints)); + ret = getaddrinfo(nodenames[0], NULL, &ahints, &ainfo); + if (ret) { + log_printf(LOG_ERR, "Can't determine address family of nodename %s\n", nodenames[0]); + write_cman_pipe("Can't determine address family of nodename"); + return -EINVAL; + } + + if (ainfo->ai_family == AF_INET) { + struct sockaddr_in *addr = (struct sockaddr_in *)ainfo->ai_addr; + memcpy(&nodeid, &addr->sin_addr, sizeof(int)); + } + if (ainfo->ai_family == AF_INET6) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *)ainfo->ai_addr; + memcpy(&nodeid, &addr->sin6_addr.in6_u.u6_addr32[3], sizeof(int)); + } + log_printf(LOG_INFO, "Our Node ID is %d\n", nodeid); + freeaddrinfo(ainfo); + } + + return 0; +} + /* Read just the stuff we need to get started. This does what 'cman_tool join' used to to */ @@ -812,9 +889,13 @@ { int error; - error = get_ccs_join_info(); + get_overrides(); + if (getenv("CMAN_NOCCS")) + error = noccs_defaults(); + else + error = get_ccs_join_info(); if (error) { - log_printf(LOG_ERR, "Error reading CCS info, cannot start"); + log_printf(LOG_ERR, "Error reading configuration info, cannot start"); return error; } @@ -822,3 +903,4 @@ return error; } + --- cluster/cman/daemon/commands.c 2007/11/20 09:02:10 1.75 +++ cluster/cman/daemon/commands.c 2007/11/29 11:19:12 1.76 @@ -382,9 +382,6 @@ if (ais_running) return -EALREADY; - if (nodeid < 0 || nodeid > 4096) - return -EINVAL; - wanted_nodeid = nodeid; return 0; } @@ -417,8 +414,8 @@ } time(&join_time); - us = add_new_node(nodename, wanted_nodeid, -1, expected_votes, - NODESTATE_MEMBER); + us = add_new_node(nodename, wanted_nodeid, 1, expected_votes, + NODESTATE_DEAD); set_port_bit(us, 0); us->us = 1; @@ -1728,6 +1725,10 @@ msg->flags &= ~NODE_FLAGS_SEESDISALLOWED; node = find_node_by_nodeid(nodeid); + if (!node) { + add_ais_node(nodeid, incarnation, num_ais_nodes); + node = find_node_by_nodeid(nodeid); + } assert(node); /* Newer nodes 6.1.0 onwards, set the DIRTY flag if they have state. If the new node has been down @@ -1969,22 +1970,11 @@ /* This really should exist!! */ if (!node) { char tempname[256]; - node = malloc(sizeof(struct cluster_node)); - if (!node) { - log_printf(LOG_ERR, "error allocating node struct for id %d, but CCS doesn't know about it anyway\n", - nodeid); - return; - } log_printf(LOG_ERR, "Got node from AIS id %d with no CCS entry\n", nodeid); - memset(node, 0, sizeof(struct cluster_node)); - node_add_ordered(node); - node->state = NODESTATE_DEAD; - node->votes = 1; - /* Emergency nodename */ - sprintf(tempname, "Node%d\n", nodeid); - node->name = strdup(tempname); + sprintf(tempname, "Node%d", nodeid); + node = add_new_node(tempname, nodeid, 1, total_members, NODESTATE_DEAD); } if (node->state == NODESTATE_DEAD) { @@ -2003,7 +1993,8 @@ P_MEMB("del_ais_node %d\n", nodeid); node = find_node_by_nodeid(nodeid); - assert(node); + if (!node) + return; /* If the node was fenced while up (ie independantly of fenced) then * don't clear the fenced flag. There is a timeout associated with --- cluster/cman/man/cman_tool.8 2007/11/08 09:36:49 1.14 +++ cluster/cman/man/cman_tool.8 2007/11/29 11:19:12 1.15 @@ -232,6 +232,29 @@ is prepared to wait. If the operation times out then a status of 2 is returned. Note that just because cman_tool has given up, does not mean that cman itself has stopped trying to join a cluster. +.TP +.I -X +Tells cman not to use CCS to get cluster information. If you use this option then cman will +apply several defaults to the cluster to get it going. The cluster name will be +"RHCluster", node IDs will default to the IP address of the node and remote node +names will show up as Node. All of these, apart from the node names can +be overridded on the cman_tool command-line if required. +.br +If you have to set up fence devices, services or anything else in cluster.conf then +this option is probably not worthwhile to you - the extra readability of sensible node +names and numbers will make it worth using CCS for the cluster too. But for a simple +failover cluster this might save you some effort. +.br +On each node using this configuration you will need to have the same authorisation key +installed. To create this key run +.br +mkdir /etc/ais +.br +ais-keygen +.br +mv /etc/ais/authkey /etc/cluster/cman_authkey +.br +then copy that file to all nodes you want to join the cluster. .br .SH "NODES" OPTIONS .TP