From mboxrd@z Thu Jan 1 00:00:00 1970 From: lhh@sourceware.org Date: 30 Nov 2007 20:06:57 -0000 Subject: [Cluster-devel] cluster/rgmanager ChangeLog src/resources/clus ... Message-ID: <20071130200657.846.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: lhh at sourceware.org 2007-11-30 20:06:55 Modified files: rgmanager : ChangeLog rgmanager/src/resources: clusterfs.sh fs.sh ocf-shellfuncs service.sh vm.sh rgmanager/src/utils: clulog.c clustat.c clusvcadm.c Log message: Merges from RHEL5 branch - round 1. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/ChangeLog.diff?cvsroot=cluster&r1=1.59&r2=1.60 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/resources/clusterfs.sh.diff?cvsroot=cluster&r1=1.19&r2=1.20 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/resources/fs.sh.diff?cvsroot=cluster&r1=1.23&r2=1.24 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/resources/ocf-shellfuncs.diff?cvsroot=cluster&r1=1.4&r2=1.5 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/resources/service.sh.diff?cvsroot=cluster&r1=1.11&r2=1.12 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/resources/vm.sh.diff?cvsroot=cluster&r1=1.7&r2=1.8 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/utils/clulog.c.diff?cvsroot=cluster&r1=1.4&r2=1.5 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/utils/clustat.c.diff?cvsroot=cluster&r1=1.35&r2=1.36 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/utils/clusvcadm.c.diff?cvsroot=cluster&r1=1.22&r2=1.23 --- cluster/rgmanager/ChangeLog 2007/08/30 16:09:38 1.59 +++ cluster/rgmanager/ChangeLog 2007/11/30 20:06:55 1.60 @@ -1,3 +1,7 @@ +2007-11-30 Lon Hohberger + * src/resources/*: Merge from RHEL5 branch. + * src/utils/*: Merge from RHEL5 branch. + 2007-08-30 Lon Hohberger * src/daemons/restree.c, rg_state.c: Fix tree-restart bug This is another part of #229650 --- cluster/rgmanager/src/resources/clusterfs.sh 2007/05/21 15:58:04 1.19 +++ cluster/rgmanager/src/resources/clusterfs.sh 2007/11/30 20:06:55 1.20 @@ -133,6 +133,18 @@ + + + If set and unmounting the file system fails, the node will + immediately reboot. Generally, this is used in conjunction + with force-unmount support, but it is not required. + + + Seppuku Unmount + + + + File system ID for NFS exports. This can be overridden @@ -279,9 +291,6 @@ gfs) return $OCF_SUCCESS ;; - ocfs|ocfs2) - return $OCF_SUCCESS - ;; *) ocf_log err "File system type $OCF_RESKEY_fstype not supported" return $OCF_ERR_ARGS @@ -798,6 +807,15 @@ esac fi + if [ -n "$mp" ]; then + case ${OCF_RESKEY_self_fence} in + $YES_STR) self_fence=$YES ;; + 1) self_fence=$YES ;; + *) self_fence="" ;; + esac + fi + + # # Always do this hackery on clustered file systems. # @@ -873,8 +891,13 @@ done # while if [ -n "$umount_failed" ]; then - ocf_log err "'umount $dev' failed ($mp), error=$ret_val" + ocf_log err "'umount $mp' failed, error=$ret_val" + if [ "$self_fence" ]; then + ocf_log alert "umount failed - REBOOTING" + sync + reboot -fn + fi return $FAIL fi @@ -884,8 +907,20 @@ case $1 in start) - startFilesystem - exit $? + declare tries=0 + declare rv + + while [ $tries -lt 3 ]; do + startFilesystem + rv=$? + if [ rv -eq 0 ]; then + exit 0 + fi + + ((tries++)) + sleep 3 + done + exit $rv ;; stop) stopFilesystem --- cluster/rgmanager/src/resources/fs.sh 2007/05/21 15:58:04 1.23 +++ cluster/rgmanager/src/resources/fs.sh 2007/11/30 20:06:55 1.24 @@ -535,8 +535,8 @@ do #echo "spec=$1 dev=$dev tmp_dev=$tmp_dev" tmp_dev=$(real_device $tmp_dev) - tmp_mp=$(trim_trailing_slash $tmp_mp) - mp=$(trim_trailing_slash $mp) + tmp_mp=${tmp_mp/%\//} #$(trim_trailing_slash $tmp_mp) + mp=${mp/%\//} #$(trim_trailing_slash $mp) if [ -n "$tmp_dev" -a "$tmp_dev" = "$dev" ]; then # @@ -1149,6 +1149,9 @@ umount_failed= done=$YES ;; + $FAIL) + return $FAIL + ;; $YES) sync; sync; sync ocf_log info "unmounting $mp" --- cluster/rgmanager/src/resources/ocf-shellfuncs 2007/01/15 19:52:05 1.4 +++ cluster/rgmanager/src/resources/ocf-shellfuncs 2007/11/30 20:06:55 1.5 @@ -1,5 +1,5 @@ # -# $Id: ocf-shellfuncs,v 1.4 2007/01/15 19:52:05 lhh Exp $ +# $Id: ocf-shellfuncs,v 1.5 2007/11/30 20:06:55 lhh Exp $ # # Common helper functions for the OCF Resource Agents supplied by # heartbeat. @@ -174,6 +174,10 @@ esac pretty_echo $__OCF_PRIO "$__OCF_MSG" + + if [ -z "`which clulog 2> /dev/null`" ]; then + return 0 + fi clulog -p $__LOG_PID -n $__LOG_NAME \ -s $__OCF_PRIO_N "$__OCF_MSG" } --- cluster/rgmanager/src/resources/service.sh 2007/07/31 18:00:25 1.11 +++ cluster/rgmanager/src/resources/service.sh 2007/11/30 20:06:55 1.12 @@ -77,7 +77,7 @@ Automatic start after quorum formation - + @@ -92,10 +92,10 @@ Reboot if stop phase fails - + - + If set, this resource group will only relocate to nodes which have no other resource groups running in the @@ -109,7 +109,7 @@ Exclusive resource group - + @@ -125,7 +125,7 @@ Enable NFS lock workarounds - + @@ -141,7 +141,7 @@ Failure recovery policy - + @@ -154,6 +154,32 @@ + + + + Maximum restarts for this service. + + + Maximum restarts for this service. + + + + + + + Restart expiration time + + + Restart expiration time. A restart is forgotten + after this time. When combined with the max_restarts + option, this lets administrators specify a threshold + for when to fail over services. If max_restarts + is exceeded in this given expiration time, the service + is relocated instead of restarted again. + + + + @@ -229,8 +255,8 @@ exit 0 ;; reconfig) - exit 0 - ;; + exit 0 + ;; *) exit 0 ;; --- cluster/rgmanager/src/resources/vm.sh 2007/08/02 14:53:38 1.7 +++ cluster/rgmanager/src/resources/vm.sh 2007/11/30 20:06:55 1.8 @@ -77,7 +77,39 @@ Automatic start after quorum formation - + + + + + + If set to yes, the last owner will reboot if this resource + group fails to stop cleanly, thus allowing the resource + group to fail over to another node. Use with caution; a + badly-behaved resource could cause the entire cluster to + reboot. This should never be enabled if the automatic + start feature is used. + + + Reboot if stop phase fails + + + + + + + If set, this resource group will only relocate to + nodes which have no other resource groups running in the + event of a failure. If no empty nodes are available, + this resource group will not be restarted after a failure. + Additionally, resource groups will not automatically + relocate to the node running this resource group. This + option can be overridden by manual start and/or relocate + operations. + + + Exclusive resource group + + @@ -177,6 +209,51 @@ + + + Migration type live or pause, default = live. + + + Migration type live or pause, default = live. + + + + + + + Top-level service this depends on, in "service:name" format. + + + Service dependency; will not start without the specified + service running. + + + + + + + Maximum restarts for this service. + + + Maximum restarts for this service. + + + + + + + Restart expiration time + + + Restart expiration time. A restart is forgotten + after this time. When combined with the max_restarts + option, this lets administrators specify a threshold + for when to fail over services. If max_restarts + is exceeded in this given expiration time, the service + is relocated instead of restarted again. + + + @@ -202,11 +279,11 @@ - - + + EOT @@ -220,7 +297,7 @@ # controlled externally; the external monitoring app # should. # - declare cmdline="restart=\"never\"" + declare cmdline="on_shutdown=\"destroy\" on_reboot=\"destroy\" on_crash=\"destroy\"" declare varp val temp # @@ -260,6 +337,8 @@ path) cmdline="$cmdline --path=\"$val\"" ;; + migrate) + ;; *) cmdline="$cmdline $varp=\"$val\"" ;; @@ -285,7 +364,7 @@ # declare cmdline - do_status && return 0 + status && return 0 cmdline="`build_xm_cmdline`" @@ -314,7 +393,7 @@ while [ $timeout -gt 0 ]; do sleep 5 ((timeout -= 5)) - do_status || return 0 + status || return 0 while read dom state; do # # State is "stopped". Kill it. @@ -355,45 +434,12 @@ # do_status() { - declare line - - xm list $OCF_RESKEY_name &> /dev/null - if [ $? -eq 0 ]; then - return $OCF_SUCCESS - fi - xm list migrating-$OCF_RESKEY_name &> /dev/null - if [ $? -eq 1 ]; then - return $OCF_NOT_RUNNING - fi - - return $OCF_ERR_GENERIC - -### NOT REACHED ### - - # virsh doesn't handle migrating domains right now - # When this gets fixed, we need to revisit this status - # function. - - line=$(virsh domstate $OCF_RESKEY_name) - if [ "$line" = "" ]; then - return $OCF_NOT_RUNNING + xm list $OCF_RESKEY_name &> /dev/null + if [ $? -eq 0 ]; then + return 0 fi - - if [ "$line" = "blocked" ]; then - return $OCF_SUCCESS - elif [ "$line" = "running" ]; then - return $OCF_SUCCESS - elif [ "$line" = "in shutdown" ]; then - return $OCF_SUCCESS - elif [ "$line" = "shut off" ]; then - return $OCF_NOT_RUNNING - fi - - # - # Crashed or paused - # - - return $OCF_ERR_GENERIC + xm list migrating-$OCF_RESKEY_name &> /dev/null + return $? } @@ -412,9 +458,13 @@ migrate() { declare target=$1 - declare errstr rv + declare errstr rv migrate_opt + + if [ "$OCF_RESKEY_migrate" = "live" ]; then + migrate_opt="-l" + fi - err=$(xm migrate $OCF_RESKEY_name $target 2>&1 | head -1) + err=$(xm migrate $migrate_opt $OCF_RESKEY_name $target 2>&1 | head -1) rv=$? if [ $rv -ne 0 ]; then @@ -446,7 +496,7 @@ exit $? ;; kill) - do_stop destroy + stop destroy exit $? ;; recover|restart) @@ -457,7 +507,7 @@ exit $? ;; migrate) - do_migrate $2 # Send VM to this node + migrate $2 # Send VM to this node exit $? ;; reload) @@ -478,6 +528,6 @@ ;; *) echo "usage: $0 {start|stop|restart|status|reload|reconfig|meta-data|validate-all}" - exit $OCF_ERR_UNIMPLEMENTED + exit 1 ;; esac --- cluster/rgmanager/src/utils/clulog.c 2007/03/27 19:33:20 1.4 +++ cluster/rgmanager/src/utils/clulog.c 2007/11/30 20:06:55 1.5 @@ -92,9 +92,6 @@ if (argc < 4) usage(argv[0]); - /* ../daemons/log.c */ - configure_logging(-1); - while ((opt = getopt(argc, argv, "f:l:s:hp:n:")) != -1) { switch (opt) { case 'l': @@ -133,9 +130,10 @@ if (!cmdline_loglevel) { /* * Let's see what loglevel the SM is running at. - * TODO Get rgmgr log level + * If ccsd's not available, use default. */ - clu_set_loglevel(LOGLEVEL_DFLT); + if (configure_logging(-1) < 0) + clu_set_loglevel(LOGLEVEL_DFLT); } result = clulog_pid(severity, pid, progname, logmsg); free(progname); --- cluster/rgmanager/src/utils/clustat.c 2007/09/19 10:56:08 1.35 +++ cluster/rgmanager/src/utils/clustat.c 2007/11/30 20:06:55 1.36 @@ -21,6 +21,7 @@ #define FLAG_RGMGR 0x4 #define FLAG_NOCFG 0x8 /* Shouldn't happen */ #define FLAG_QDISK 0x10 +#define FLAG_RGMAST 0x20 /* for RIND */ #define RG_VERBOSE 0x1 @@ -30,6 +31,8 @@ int running = 1; +int dimx = 80, dimy = 24, stdout_is_tty = 0; +int rgmanager_master_present = 0; void term_handler(int sig) @@ -44,6 +47,28 @@ } rg_state_list_t; +int +rg_name_sort(const void *left, const void *right) +{ + return strcmp(((rg_state_t *)left)->rs_name, + ((rg_state_t *)right)->rs_name); +} + + +int +member_id_sort(const void *left, const void *right) +{ + cman_node_t *l = (cman_node_t *)left; + cman_node_t *r = (cman_node_t *)right; + + if (l->cn_nodeid < r->cn_nodeid) + return -1; + if (l->cn_nodeid > r->cn_nodeid) + return 1; + return 0; +} + + void flag_rgmanager_nodes(cluster_member_list_t *cml) { @@ -55,7 +80,7 @@ struct timeval tv; if (msg_open(MSG_SOCKET, 0, 0, &ctx, 10) < 0) { - perror("msg_open"); + //perror("msg_open"); return; } @@ -121,6 +146,10 @@ if (cml->cml_members[n].cn_nodeid != msgp->gh_arg1) continue; cml->cml_members[n].cn_member |= FLAG_RGMGR; + if (msgp->gh_arg2) { + rgmanager_master_present = 1; + cml->cml_members[n].cn_member |= FLAG_RGMAST; + } } free(msgp); @@ -147,7 +176,7 @@ struct timeval tv; if (msg_open(MSG_SOCKET, 0, 0, &ctx, 10) < 0) { - perror("msg_open"); + //perror("msg_open"); return NULL; } @@ -248,6 +277,9 @@ return NULL; } + qsort(rsl->rgl_states, rsl->rgl_count, sizeof(rg_state_t), + rg_name_sort); + return rsl; } @@ -270,9 +302,11 @@ sleep(1); x = 0; + memset(buf, 0, sizeof(buf)); + while (++x) { name = NULL; - snprintf(buf, sizeof(buf), + snprintf(buf, sizeof(buf)-1, "/cluster/clusternodes/clusternode[%d]/@name", x); if (ccs_get(desc, buf, &name) != 0) @@ -307,7 +341,7 @@ free(name); /* Add node ID */ - snprintf(buf, sizeof(buf), + snprintf(buf, sizeof(buf)-1, "/cluster/clusternodes/clusternode[%d]/@nodeid", x); if (ccs_get(desc, buf, &name) == 0) { nodes[x-1].cn_nodeid = atoi(name); @@ -320,6 +354,9 @@ ccs_disconnect(desc); ret->cml_members = nodes; + qsort(ret->cml_members, ret->cml_count, sizeof(cman_node_t), + member_id_sort); + return ret; } @@ -413,68 +450,71 @@ void -_txt_rg_state(rg_state_t *rs, cluster_member_list_t *members, int flags) +_txt_rg_state(rg_state_t *rs, cluster_member_list_t *members, int flags, + char *fmt_buf, int ns) { - char owner[31]; - char flags_string[255] = ""; + char owner[MAXHOSTNAMELEN+1]; + char owner_fmt[16]; + char *name = rs->rs_name, *ptr; + int l; + + if (stdout_is_tty) { + ptr = strchr(rs->rs_name, ':'); + if (ptr) { + l = (int)(ptr - rs->rs_name); + if ((l == 7) && /* strlen("service") == 7 */ + (strncmp(rs->rs_name, "service", l) == 0)) + name = ptr+1; + } + } + + memset(owner, 0, sizeof(owner)); + memset(owner_fmt, 0, sizeof(owner_fmt)); if (rs->rs_state == RG_STATE_STOPPED || rs->rs_state == RG_STATE_DISABLED || rs->rs_state == RG_STATE_ERROR || rs->rs_state == RG_STATE_FAILED) { - snprintf(owner, sizeof(owner), "(%-.28s)", + snprintf(owner_fmt, sizeof(owner_fmt)-1, "(%%-.%ds)", ns-2); + snprintf(owner, sizeof(owner)-1, owner_fmt, my_memb_id_to_name(members, rs->rs_last_owner)); } else { - snprintf(owner, sizeof(owner), "%-.30s", + snprintf(owner_fmt, sizeof(owner_fmt)-1, "%%-.%ds", ns); + snprintf(owner, sizeof(owner)-1, owner_fmt, my_memb_id_to_name(members, rs->rs_owner)); } - rg_flags_str(flags_string, sizeof(flags_string), rs->rs_flags, ", "); - printf(" %-20.20s %-30.30s %-16.16s ", - rs->rs_name, + + printf(fmt_buf, + name, owner, rg_state_str(rs->rs_state)); - if(strlen(flags_string)) - printf ("%-30.30s\n", flags_string); - else - printf("\n"); } void _txt_rg_state_v(rg_state_t *rs, cluster_member_list_t *members, int flags) { - char flags_string[255] = ""; - time_t transtime = rs->rs_transition; - - rg_flags_str(flags_string, sizeof(flags_string), rs->rs_flags, ", "); - printf("Service Name : %s\n", rs->rs_name); printf(" Current State : %s (%d)\n", rg_state_str(rs->rs_state), rs->rs_state); - if (rs->rs_flags) - printf(" Flags : %s (%d)\n", - flags_string, rs->rs_flags); - else - printf(" Flags : none (%d)\n", - rs->rs_flags); printf(" Owner : %s\n", my_memb_id_to_name(members, rs->rs_owner)); printf(" Last Owner : %s\n", my_memb_id_to_name(members, rs->rs_last_owner)); printf(" Last Transition : %s\n", - ctime(&transtime)); + ctime((time_t *)(&rs->rs_transition))); } void -txt_rg_state(rg_state_t *rs, cluster_member_list_t *members, int flags) +txt_rg_state(rg_state_t *rs, cluster_member_list_t *members, int flags, char *fmt_buf, int ns) { if (flags & RG_VERBOSE) _txt_rg_state_v(rs, members, flags); else - _txt_rg_state(rs, members, flags); + _txt_rg_state(rs, members, flags, fmt_buf, ns); } @@ -482,12 +522,10 @@ xml_rg_state(rg_state_t *rs, cluster_member_list_t *members, int flags) { char time_str[32]; - char flags_string[255] = ""; - time_t transtime = rs->rs_transition; int x; /* Chop off newlines */ - ctime_r((time_t *)&transtime, time_str); + ctime_r((time_t *)&rs->rs_transition, time_str); for (x = 0; time_str[x]; x++) { if (time_str[x] < 32) { time_str[x] = 0; @@ -495,15 +533,12 @@ } } - printf(" \n", rs->rs_name, rs->rs_state, rg_state_str(rs->rs_state), - rs->rs_flags, - rg_flags_str(flags_string, sizeof(flags_string), rs->rs_flags, " "), my_memb_id_to_name(members, rs->rs_owner), my_memb_id_to_name(members, rs->rs_last_owner), rs->rs_restarts, @@ -512,11 +547,37 @@ } +void +build_service_format(char *buf, int buflen, int cols, int *ns) +{ + /* Based on 80 columns */ + int svcsize = 30; + int nodesize = 30; + int statsize = 14; /* uninitialized */ + int pad = 6; /* Spaces and such; newline */ + + svcsize = (cols - (statsize + pad)) / 2; + nodesize = (cols - (statsize + pad)) / 2; + if (svcsize > MAXHOSTNAMELEN) + svcsize = MAXHOSTNAMELEN; + if (nodesize > MAXHOSTNAMELEN) + nodesize = MAXHOSTNAMELEN; + + memset(buf, 0, buflen); + snprintf(buf, buflen-1, " %%-%d.%ds %%-%d.%ds %%-%d.%ds\n", + svcsize, svcsize, nodesize, nodesize, statsize, + statsize); + + *ns = nodesize; +} + + int txt_rg_states(rg_state_list_t *rgl, cluster_member_list_t *members, char *svcname, int flags) { - int x, ret = 0; + int x, ret = 0, ns; + char fmt_buf[80]; if (!rgl || !members) return -1; @@ -524,11 +585,14 @@ if (svcname) ret = -1; + build_service_format(fmt_buf, sizeof(fmt_buf), dimx, &ns); + if (!(flags & RG_VERBOSE)) { - printf(" %-20.20s %-30.30s %-16.16s %-30.30s\n", - "Service Name", "Owner (Last)", "State", "Flags"); - printf(" %-20.20s %-30.30s %-16.16s %-30.30s\n", - "------- ----", "----- ------", "-----", "-----"); + + printf(fmt_buf, + "Service Name", "Owner (Last)", "State"); + printf(fmt_buf, + "------- ----", "----- ------", "-----"); } else { printf("Service Information\n" "------- -----------\n\n"); @@ -538,7 +602,7 @@ if (svcname && strcmp(rgl->rgl_states[x].rs_name, svcname)) continue; - txt_rg_state(&rgl->rgl_states[x], members, flags); + txt_rg_state(&rgl->rgl_states[x], members, flags, fmt_buf, ns); if (svcname) { switch (rgl->rgl_states[x].rs_state) { case RG_STATE_STARTING: @@ -551,7 +615,7 @@ } } } - + return ret; } @@ -604,6 +668,24 @@ void +txt_cluster_info(cman_cluster_t *ci) +{ + time_t now = time(NULL); + + printf("Cluster Status for %s @ %s", + ci->ci_name, ctime(&now)); +} + + +void +xml_cluster_info(cman_cluster_t *ci) +{ + printf(" \n", + ci->ci_name, ci->ci_number, ci->ci_generation); +} + + +void xml_quorum_state(int qs) { /* XXX output groupmember attr (carry over from RHCS4) */ @@ -619,15 +701,31 @@ } else { printf(" groupmember=\"0\""); } + printf("/>\n"); } +void +build_member_format(char *buf, int buflen, int cols) +{ + /* Based on 80 columns */ + int nodesize = 40; + + nodesize = (cols / 2); + if (nodesize > MAXHOSTNAMELEN) + nodesize = MAXHOSTNAMELEN; + + memset(buf, 0, buflen); + snprintf(buf, buflen-1, " %%-%d.%ds ", + nodesize, nodesize); +} + void -txt_member_state(cman_node_t *node) +txt_member_state(cman_node_t *node, char *fmt_buf) { - printf(" %-34.34s %4d ", node->cn_name, - node->cn_nodeid); + printf(fmt_buf, node->cn_name); + printf("%4d ", node->cn_nodeid); if (node->cn_member & FLAG_UP) printf("Online"); @@ -640,15 +738,21 @@ if (node->cn_member & FLAG_NOCFG) printf(", Estranged"); - if (node->cn_member & FLAG_RGMGR) - printf(", rgmanager"); + if (node->cn_member & FLAG_RGMGR) { + if (rgmanager_master_present) { + if (node->cn_member & FLAG_RGMAST) + printf(", RG-Master"); + else + printf(", RG-Worker"); + } else { + printf(", rgmanager"); + } + } if (node->cn_member & FLAG_QDISK) printf(", Quorum Disk"); printf("\n"); - - } @@ -656,12 +760,14 @@ xml_member_state(cman_node_t *node) { printf(" \n", + "estranged=\"%d\" rgmanager=\"%d\" rgmanager_master=\"%d\" " + "qdisk=\"%d\" nodeid=\"0x%08x\"/>\n", node->cn_name, !!(node->cn_member & FLAG_UP), !!(node->cn_member & FLAG_LOCAL), !!(node->cn_member & FLAG_NOCFG), !!(node->cn_member & FLAG_RGMGR), + !!(node->cn_member & FLAG_RGMAST), !!(node->cn_member & FLAG_QDISK), (uint32_t)((node->cn_nodeid )&0xffffffff)); } @@ -670,6 +776,7 @@ int txt_member_states(cluster_member_list_t *membership, char *name) { + char buf[80]; int x, ret = 0; if (!membership) { @@ -677,13 +784,17 @@ return -1; } - printf(" %-34.34s %-4.4s %s\n", "Member Name", "ID", "Status"); - printf(" %-34.34s %-4.4s %s\n", "------ ----", "----", "------"); + build_member_format(buf, sizeof(buf), dimx); + + printf(buf, "Member Name"); + printf("%-4.4s %s\n", "ID", "Status"); + printf(buf, "------ ----"); + printf("%-4.4s %s\n", "----", "------"); for (x = 0; x < membership->cml_count; x++) { if (name && strcmp(membership->cml_members[x].cn_name, name)) continue; - txt_member_state(&membership->cml_members[x]); + txt_member_state(&membership->cml_members[x], buf); ret = !(membership->cml_members[x].cn_member & FLAG_UP); } @@ -717,13 +828,15 @@ int -txt_cluster_status(int qs, cluster_member_list_t *membership, +txt_cluster_status(cman_cluster_t *ci, + int qs, cluster_member_list_t *membership, rg_state_list_t *rgs, char *name, char *svcname, int flags) { int ret; if (!svcname && !name) { + txt_cluster_info(ci); txt_quorum_state(qs); if (!membership) { /* XXX Check for rgmanager?! */ @@ -738,12 +851,14 @@ return ret; if (!name || (name && svcname)) ret = txt_rg_states(rgs, membership, svcname, flags); + return ret; } int -xml_cluster_status(int qs, cluster_member_list_t *membership, +xml_cluster_status(cman_cluster_t *ci, int qs, + cluster_member_list_t *membership, rg_state_list_t *rgs, char *name, char *svcname, int flags) { @@ -768,6 +883,8 @@ } if (!svcname && !name) + xml_cluster_info(ci); + if (!svcname && !name) xml_quorum_state(qs); if (!svcname || (name && svcname)) ret1 = xml_member_states(membership, name); @@ -862,7 +979,9 @@ int local_node_id; int fast = 0; int runtype = 0; + time_t now; cman_handle_t ch = NULL; + cman_cluster_t ci; int refresh_sec = 0, errors = 0; int opt, xml = 0, flags = 0; @@ -900,8 +1019,9 @@ case 's': rg_name = optarg; if (!strchr(rg_name,':')) { + memset(real_rg_name, 0, sizeof(real_rg_name)); snprintf(real_rg_name, - sizeof(real_rg_name), + sizeof(real_rg_name)-1, "service:%s", rg_name); rg_name = real_rg_name; } @@ -941,7 +1061,7 @@ /* Connect & grab all our info */ ch = cman_init(NULL); if (!ch) { - printf("CMAN is not running.\n"); + perror("Could not connect to CMAN"); return 1; } @@ -952,8 +1072,12 @@ ret = !(cman_is_quorate(ch)); goto cleanup; case VERSION_ONLY: +#ifdef RELEASE_VERSION printf("%s version %s\n", basename(argv[0]), RELEASE_VERSION); +#else + printf("%s version DEVEL\n", basename(argv[0])); +#endif if (!ch) break; goto cleanup; @@ -974,6 +1098,16 @@ signal(SIGINT, term_handler); signal(SIGTERM, term_handler); + if (isatty(STDOUT_FILENO)) { + stdout_is_tty = 1; + setupterm((char *) 0, STDOUT_FILENO, (int *) 0); + dimx = tigetnum("cols"); + dimy = tigetnum("lines"); + } + + memset(&ci, 0, sizeof(ci)); + cman_get_cluster(ch, &ci); + while (1) { qs = cman_is_quorate(ch); membership = build_member_list(ch, &local_node_id); @@ -985,16 +1119,16 @@ } if (refresh_sec) { - setupterm((char *) 0, STDOUT_FILENO, (int *) 0); tputs(clear_screen, lines > 0 ? lines : 1, putchar); + now = time(NULL); } if (xml) - ret = xml_cluster_status(qs, membership, rgs, + ret = xml_cluster_status(&ci, qs, membership, rgs, member_name, rg_name, flags); else - ret = txt_cluster_status(qs, membership, rgs, + ret = txt_cluster_status(&ci, qs, membership, rgs, member_name, rg_name, flags); @@ -1011,5 +1145,6 @@ cleanup: cman_finish(ch); + return ret; } --- cluster/rgmanager/src/utils/clusvcadm.c 2007/08/22 08:58:47 1.22 +++ cluster/rgmanager/src/utils/clusvcadm.c 2007/11/30 20:06:55 1.23 @@ -311,7 +311,11 @@ node_specified = 1; break; case 'v': - printf("%s\n",RELEASE_VERSION); +#ifdef RELEASE_VERSION + printf("%s\n", RELEASE_VERSION); +#else + printf("DEVEL\n"); +#endif return 0; case 'Z': actionstr = "freezing";