All of lore.kernel.org
 help / color / mirror / Atom feed
From: lhh@sourceware.org <lhh@sourceware.org>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] cluster/rgmanager ChangeLog src/resources/clus ...
Date: 30 Nov 2007 20:06:57 -0000	[thread overview]
Message-ID: <20071130200657.846.qmail@sourceware.org> (raw)

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 <lhh@redhat.com>
+	* src/resources/*: Merge from RHEL5 branch.
+	* src/utils/*: Merge from RHEL5 branch.
+
 2007-08-30 Lon Hohberger <lhh@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\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("    <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\"/>\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("  <cluster name=\"%s\" id=\"%d\" generation=\"%d\"/>\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("    <node name=\"%s\" state=\"%d\" local=\"%d\" "
-	       "estranged=\"%d\" rgmanager=\"%d\" qdisk=\"%d\" nodeid=\"0x%08x\"/>\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";



             reply	other threads:[~2007-11-30 20:06 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-11-30 20:06 lhh [this message]
  -- strict thread matches above, loose matches on Subject: below --
2007-09-25 13:23 [Cluster-devel] cluster/rgmanager ChangeLog src/resources/clus lhh
2007-04-19 19:54 lhh
2007-04-19 19:53 lhh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20071130200657.846.qmail@sourceware.org \
    --to=lhh@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.