cluster/rgmanager ChangeLog src/resources/clus ...
CVSROOT: /cvs/cluster
Module name: cluster Changes by: lhh@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 <lhh at redhat.com> + * src/resources/*: Merge from RHEL5 branch. + * src/utils/*: Merge from RHEL5 branch. + 2007-08-30 Lon Hohberger <lhh at redhat.com> * 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 @@ <content type="string"/> </parameter> + <parameter name="self_fence"> + <longdesc lang="en"> + 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. + </longdesc> + <shortdesc lang="en"> + Seppuku Unmount + </shortdesc> + <content type="boolean"/> + </parameter> + <parameter name="fsid"> <longdesc lang="en"> 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 @@ <shortdesc lang="en"> Automatic start after quorum formation </shortdesc> - <content type="boolean"/> + <content type="boolean" default="1"/> </parameter> <parameter name="hardrecovery" reconfig="1"> @@ -92,10 +92,10 @@ <shortdesc lang="en"> Reboot if stop phase fails </shortdesc> - <content type="boolean"/> + <content type="boolean" default="0"/> </parameter> - <parameter name="exclusive"> + <parameter name="exclusive" reconfig="1"> <longdesc lang="en"> If set, this resource group will only relocate to nodes which have no other resource groups running in the @@ -109,7 +109,7 @@ <shortdesc lang="en"> Exclusive resource group </shortdesc> - <content type="boolean"/> + <content type="boolean" default="0"/> </parameter> <parameter name="nfslock"> @@ -125,7 +125,7 @@ <shortdesc lang="en"> Enable NFS lock workarounds </shortdesc> - <content type="boolean"/> + <content type="boolean" default="0"/> </parameter> <parameter name="recovery" reconfig="1"> @@ -141,7 +141,7 @@ <shortdesc lang="en"> Failure recovery policy </shortdesc> - <content type="string"/> + <content type="string" default="restart"/> </parameter> <parameter name="depend"> @@ -154,6 +154,32 @@ </shortdesc> <content type="string"/> </parameter> + + <parameter name="max_restarts"> + <longdesc lang="en"> + Maximum restarts for this service. + </longdesc> + <shortdesc lang="en"> + Maximum restarts for this service. + </shortdesc> + <content type="string" default="0"/> + </parameter> + + <parameter name="restart_expire_time"> + <longdesc lang="en"> + Restart expiration time + </longdesc> + <shortdesc lang="en"> + 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. + </shortdesc> + <content type="string" default="0"/> + </parameter> + </parameters> <actions> @@ -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 @@ <shortdesc lang="en"> Automatic start after quorum formation </shortdesc> - <content type="boolean"/> + <content type="boolean" default="1"/> + </parameter> + + <parameter name="hardrecovery" reconfig="1"> + <longdesc lang="en"> + 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. + </longdesc> + <shortdesc lang="en"> + Reboot if stop phase fails + </shortdesc> + <content type="boolean" default="0"/> + </parameter> + + <parameter name="exclusive" reconfig="1"> + <longdesc lang="en"> + 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. + </longdesc> + <shortdesc lang="en"> + Exclusive resource group + </shortdesc> + <content type="boolean" default="0"/> </parameter> <parameter name="recovery" reconfig="1"> @@ -177,6 +209,51 @@ <content type="string"/> </parameter> + <parameter name="migrate"> + <longdesc lang="en"> + Migration type live or pause, default = live. + </longdesc> + <shortdesc lang="en"> + Migration type live or pause, default = live. + </shortdesc> + <content type="string" default="live"/> + </parameter> + + <parameter name="depend"> + <longdesc lang="en"> + Top-level service this depends on, in "service:name" format. + </longdesc> + <shortdesc lang="en"> + Service dependency; will not start without the specified + service running. + </shortdesc> + <content type="string"/> + </parameter> + + <parameter name="max_restarts" reconfig="1"> + <longdesc lang="en"> + Maximum restarts for this service. + </longdesc> + <shortdesc lang="en"> + Maximum restarts for this service. + </shortdesc> + <content type="string" default="0"/> + </parameter> + + <parameter name="restart_expire_time" reconfig="1"> + <longdesc lang="en"> + Restart expiration time + </longdesc> + <shortdesc lang="en"> + 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. + </shortdesc> + <content type="string" default="0"/> + </parameter> </parameters> @@ -202,11 +279,11 @@ </actions> <special tag="rgmanager"> - <!-- Destroy_on_delete / init_on_add are currently only - supported for migratory resources (no children - and the 'migrate' action; see above. Do not try this - with normal services --> - <attributes maxinstances="1" destroy_on_delete="0" init_on_add="0"/> + <!-- Destroy_on_delete / init_on_add are currently only + supported for migratory resources (no children + and the 'migrate' action; see above. Do not try this + with normal services --> + <attributes maxinstances="1" destroy_on_delete="0" init_on_add="0"/> </special> </resource-agent> 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 ", flags_string); - else - printf(" "); } 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 ", rs->rs_name); printf(" Current State : %s (%d) ", rg_state_str(rs->rs_state), rs->rs_state); - if (rs->rs_flags) - printf(" Flags : %s (%d) ", - flags_string, rs->rs_flags); - else - printf(" Flags : none (%d) ", - rs->rs_flags); printf(" Owner : %s ", my_memb_id_to_name(members, rs->rs_owner)); printf(" Last Owner : %s ", my_memb_id_to_name(members, rs->rs_last_owner)); printf(" Last Transition : %s ", - 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(" <group name="%s" state="%d" state_str="%s"" - " flags="%d" flags_str="%s"" + printf(" <group name="%s" state="%d" state_str="%s" " " owner="%s" last_owner="%s" restarts="%d"" " last_transition="%llu" last_transition_str="%s"/> ", 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 ", + 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 ", - "Service Name", "Owner (Last)", "State", "Flags"); - printf(" %-20.20s %-30.30s %-16.16s %-30.30s ", - "------- ----", "----- ------", "-----", "-----"); + + printf(fmt_buf, + "Service Name", "Owner (Last)", "State"); + printf(fmt_buf, + "------- ----", "----- ------", "-----"); } else { printf("Service Information " "------- ----------- "); @@ -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(" <cluster name="%s" id="%d" generation="%d"/> ", + 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("/> "); } +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(" "); - - } @@ -656,12 +760,14 @@ xml_member_state(cman_node_t *node) { printf(" <node name="%s" state="%d" local="%d" " - "estranged="%d" rgmanager="%d" qdisk="%d" nodeid="0x%08x"/> ", + "estranged="%d" rgmanager="%d" rgmanager_master="%d" " + "qdisk="%d" nodeid="0x%08x"/> ", 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 ", "Member Name", "ID", "Status"); - printf(" %-34.34s %-4.4s %s ", "------ ----", "----", "------"); + build_member_format(buf, sizeof(buf), dimx); + + printf(buf, "Member Name"); + printf("%-4.4s %s ", "ID", "Status"); + printf(buf, "------ ----"); + printf("%-4.4s %s ", "----", "------"); 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. "); + 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 ", basename(argv[0]), RELEASE_VERSION); +#else + printf("%s version DEVEL ", 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 ",RELEASE_VERSION); +#ifdef RELEASE_VERSION + printf("%s ", RELEASE_VERSION); +#else + printf("DEVEL "); +#endif return 0; case 'Z': actionstr = "freezing"; |
| All times are GMT. The time now is 12:36 AM. |
VBulletin, Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.