* [Cluster-devel] cluster/cman cman_tool/cman_tool.h cman_tool/j ...
@ 2008-01-30 15:46 pcaulfield
0 siblings, 0 replies; 2+ messages in thread
From: pcaulfield @ 2008-01-30 15:46 UTC (permalink / raw)
To: cluster-devel.redhat.com
CVSROOT: /cvs/cluster
Module name: cluster
Changes by: pcaulfield at sourceware.org 2008-01-30 15:46:41
Modified files:
cman/cman_tool : cman_tool.h join.c
cman/daemon : ais.c
cman/man : cman_tool.8
Log message:
Improve startup error checking and logging.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/cman_tool/cman_tool.h.diff?cvsroot=cluster&r1=1.14&r2=1.15
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/cman_tool/join.c.diff?cvsroot=cluster&r1=1.53&r2=1.54
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/daemon/ais.c.diff?cvsroot=cluster&r1=1.59&r2=1.60
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/cman/man/cman_tool.8.diff?cvsroot=cluster&r1=1.15&r2=1.16
--- cluster/cman/cman_tool/cman_tool.h 2007/11/29 11:19:12 1.14
+++ cluster/cman/cman_tool/cman_tool.h 2008/01/30 15:46:41 1.15
@@ -56,6 +56,8 @@
#define MAX_MCAST_NAME_LEN 256
#define MAX_PATH_LEN 256
+#define DEBUG_STARTUP_ONLY 32
+
enum format_opt
{
FMT_NONE,
--- cluster/cman/cman_tool/join.c 2008/01/10 10:39:16 1.53
+++ cluster/cman/cman_tool/join.c 2008/01/30 15:46:41 1.54
@@ -2,7 +2,7 @@
*******************************************************************************
**
** Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
-** Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
+** Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
**
** This copyrighted material is made available to anyone wishing to use,
** modify, copy, or redistribute it subject to the terms and conditions
@@ -51,22 +51,21 @@
setsid();
}
-
int join(commandline_t *comline)
{
int i;
int envptr = 0;
+ int argvptr = 0;
char scratch[1024];
cman_handle_t h;
+ int status;
pid_t aisexec_pid;
int ctree;
int p[2];
- if (!comline->noccs_opt)
- {
+ if (!comline->noccs_opt) {
ctree = ccs_force_connect(NULL, 1);
- if (ctree < 0)
- {
+ if (ctree < 0) {
die("ccsd is not running\n");
}
ccs_disconnect(ctree);
@@ -79,7 +78,6 @@
if (h)
die("Node is already active");
-
/* Set up environment variables for override */
if (comline->multicast_addr) {
snprintf(scratch, sizeof(scratch), "CMAN_MCAST_ADDR=%s", comline->multicast_addr);
@@ -117,27 +115,29 @@
snprintf(scratch, sizeof(scratch), "CMAN_2NODE=true");
envp[envptr++] = strdup(scratch);
}
- if (comline->verbose) {
+ if (comline->verbose ^ DEBUG_STARTUP_ONLY) {
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);
+ envp[envptr++] = strdup("CMAN_NOCCS=true");
+ envp[envptr++] = strdup("OPENAIS_DEFAULT_CONFIG_IFACE=cmanpreconfig");
+ }
+ else {
+ envp[envptr++] = strdup("OPENAIS_DEFAULT_CONFIG_IFACE=cmanconfig");
}
-
- /* Use cman to configure services */
- envp[envptr++] = strdup("OPENAIS_DEFAULT_CONFIG_IFACE=cmanconfig");
/* Create a pipe to monitor cman startup progress */
pipe(p);
fcntl(p[1], F_SETFD, 0); /* Don't close on exec */
snprintf(scratch, sizeof(scratch), "CMAN_PIPE=%d", p[1]);
envp[envptr++] = strdup(scratch);
-
envp[envptr++] = NULL;
argv[0] = "aisexec";
+ if (comline->verbose & ~DEBUG_STARTUP_ONLY)
+ argv[++argvptr] = "-f";
+ argv[++argvptr] = NULL;
/* Fork/exec cman */
switch ( (aisexec_pid = fork()) )
@@ -145,18 +145,28 @@
case -1:
die("fork of aisexec daemon failed: %s", strerror(errno));
- case 0: // child
+ case 0: /* child */
close(p[0]);
- be_daemon(!comline->verbose);
+ if (comline->verbose & DEBUG_STARTUP_ONLY) {
+ fprintf(stderr, "Starting %s", AISEXECBIN);
+ for (i=0; i< argvptr; i++) {
+ fprintf(stderr, " %s", argv[i]);
+ }
+ fprintf(stderr, "\n");
+ for (i=0; i<envptr-1; i++) {
+ fprintf(stderr, "%s\n", envp[i]);
+ }
+ }
+ be_daemon(!(comline->verbose & ~DEBUG_STARTUP_ONLY));
execve(AISEXECBIN, argv, envp);
- // exec failed - tell the parent process */
+ /* exec failed - tell the parent process */
sprintf(scratch, "execve of " AISEXECBIN " failed: %s", strerror(errno));
write(p[1], scratch, strlen(scratch));
exit(1);
break;
- default: //parent
+ default: /* parent */
break;
}
@@ -164,10 +174,12 @@
/* Give the daemon a chance to start up, and monitor the pipe FD for messages */
i = 0;
close(p[1]);
+
+ /* Wait for the process to start or die */
+ sleep(1);
do {
fd_set fds;
struct timeval tv={1, 0};
- int status;
char message[1024];
FD_ZERO(&fds);
@@ -177,31 +189,69 @@
/* Did we get an error? */
if (status == 1) {
- if (read(p[0], message, sizeof(message)) != 0) {
- fprintf(stderr, "cman not started: %s\n", message);
+ int len;
+ if ((len = read(p[0], message, sizeof(message)) > 0)) {
+
+ /* Success! get the new PID of double-forked aisexec */
+ if (sscanf(message, "SUCCESS: %d", &aisexec_pid) == 1) {
+ if (comline->verbose & DEBUG_STARTUP_ONLY)
+ fprintf(stderr, "aisexec running, process ID is %d\n", aisexec_pid);
+ status = 0;
+ }
+ else {
+ fprintf(stderr, "cman not started: %s\n", message);
+ }
break;
}
- else {
+ else if (len < 0 && errno == EINTR) {
+ continue;
+ }
+ else { /* Error or EOF - check the child status */
int pidstatus;
- if (waitpid(aisexec_pid, &pidstatus, WNOHANG) == 0 && pidstatus != 0)
- fprintf(stderr, "cman died with status: %d\n", WEXITSTATUS(pidstatus));
- else
+ status = waitpid(aisexec_pid, &pidstatus, WNOHANG);
+ if (status == -1 && errno == ECHILD) {
+ fprintf(stderr, "cman not started\n");
+ break;
+ }
+ if (status == 0 && pidstatus != 0) {
+ if (WIFEXITED(pidstatus))
+ fprintf(stderr, "aisexec died with status: %d\n", WEXITSTATUS(pidstatus));
+ if (WIFSIGNALED(pidstatus))
+ fprintf(stderr, "aisexec died with signal: %d\n", WTERMSIG(pidstatus));
+ status = -1;
+ break;
+ }
+ else {
status = 0; /* Try to connect */
+ }
}
}
- if (status == 0) {
- h = cman_admin_init(NULL);
- if (!h && comline->verbose)
- {
- fprintf(stderr, "waiting for aisexec to start\n");
+
+ } while (status != 0);
+ close(p[0]);
+
+ /* If aisexec has started, try to connect to cman ... if it's still there */
+ if (status == 0) {
+ do {
+ if (status == 0) {
+ if (kill(aisexec_pid, 0) < 0) {
+ die("aisexec died during startup\n");
+ }
+
+ h = cman_admin_init(NULL);
+ if (!h && comline->verbose & DEBUG_STARTUP_ONLY)
+ {
+ fprintf(stderr, "waiting for aisexec to start\n");
+ }
}
- }
- } while (!h && ++i < 100);
+ sleep (1);
+ } while (!h && ++i < 100);
+ }
if (!h)
die("aisexec daemon didn't start");
- if (comline->verbose && !cman_is_active(h))
+ if ((comline->verbose & DEBUG_STARTUP_ONLY) && !cman_is_active(h))
fprintf(stderr, "aisexec started, but not joined the cluster yet.\n");
cman_finish(h);
--- cluster/cman/daemon/ais.c 2008/01/02 16:35:44 1.59
+++ cluster/cman/daemon/ais.c 2008/01/30 15:46:41 1.60
@@ -249,6 +249,7 @@
static int cman_exec_init_fn(struct objdb_iface_ver0 *objdb)
{
unsigned int object_handle;
+ char pipe_msg[256];
/* We can only work if our config interface was run first */
if (!config_run)
@@ -273,7 +274,9 @@
/* Open local sockets and initialise I/O queues */
cman_init();
- /* Let cman_tool know we are running */
+ /* Let cman_tool know we are running and our PID */
+ sprintf(pipe_msg,"SUCCESS: %d", getpid());
+ write_cman_pipe(pipe_msg);
close(startup_pipe);
startup_pipe = 0;
--- cluster/cman/man/cman_tool.8 2007/11/29 11:19:12 1.15
+++ cluster/cman/man/cman_tool.8 2008/01/30 15:46:41 1.16
@@ -290,6 +290,8 @@
.br
16 Interaction with OpenAIS
.br
+32 Startup debugging (cman_tool join operations only)
+.br
.SH NOTES
.br
the
^ permalink raw reply [flat|nested] 2+ messages in thread* [Cluster-devel] cluster/cman cman_tool/cman_tool.h cman_tool/j ...
@ 2007-11-29 11:19 pcaulfield
0 siblings, 0 replies; 2+ messages in thread
From: pcaulfield @ 2007-11-29 11:19 UTC (permalink / raw)
To: cluster-devel.redhat.com
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 <file> 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<nodeid>. 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
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2008-01-30 15:46 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-30 15:46 [Cluster-devel] cluster/cman cman_tool/cman_tool.h cman_tool/j pcaulfield
-- strict thread matches above, loose matches on Subject: below --
2007-11-29 11:19 pcaulfield
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).