[Cluster-devel] cluster/rgmanager/src/utils clustat.c

lhh at sourceware.org lhh at sourceware.org
Fri Nov 30 19:47:15 UTC 2007


CVSROOT:	/cvs/cluster
Module name:	cluster
Branch: 	RHEL5
Changes by:	lhh at sourceware.org	2007-11-30 19:47:15

Modified files:
	rgmanager/src/utils: clustat.c 

Log message:
	Make clustat terminal-width dependent, but don't break scripts.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/utils/clustat.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.25.2.6&r2=1.25.2.7

--- cluster/rgmanager/src/utils/clustat.c	2007/08/15 18:41:12	1.25.2.6
+++ cluster/rgmanager/src/utils/clustat.c	2007/11/30 19:47:15	1.25.2.7
@@ -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,25 +450,44 @@
 
 
 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 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));
 	}
-	printf("  %-20.20s %-30.30s %-16.16s\n",
-	       rs->rs_name,
+	
+	printf(fmt_buf,
+	       name,
 	       owner,
 	       rg_state_str(rs->rs_state));
 }
@@ -453,12 +509,12 @@
 
 
 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);
 }
 
 
@@ -491,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;
@@ -503,10 +585,13 @@
 	if (svcname)
 		ret = -1;
 
+	build_service_format(fmt_buf, sizeof(fmt_buf), dimx, &ns);
+
 	if (!(flags & RG_VERBOSE)) {
-		printf("  %-20.20s %-30.30s %-14.14s\n",
+
+		printf(fmt_buf,
 		       "Service Name", "Owner (Last)", "State");
-		printf("  %-20.20s %-30.30s %-14.14s\n",
+		printf(fmt_buf,
 		       "------- ----", "----- ------", "-----");
 	} else {
 		printf("Service Information\n"
@@ -517,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:
@@ -530,7 +615,7 @@
 			}
 		}
 	}
-	
+
 	return ret;
 }
 
@@ -583,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) */
@@ -598,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");
@@ -619,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");
-		
-
 }
 
 
@@ -635,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));
 }
@@ -649,6 +776,7 @@
 int
 txt_member_states(cluster_member_list_t *membership, char *name)
 {
+	char buf[80];
 	int x, ret = 0;
 
   	if (!membership) {
@@ -656,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);
 	}
 
@@ -696,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?! */
@@ -717,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)
 {
@@ -747,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);
@@ -841,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;
@@ -879,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;
 			}
@@ -920,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;
 	}
 
@@ -953,6 +1094,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);
@@ -964,16 +1115,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);
 
@@ -990,5 +1141,6 @@
 
 cleanup:
 	cman_finish(ch);
+
 	return ret;
 }




More information about the Cluster-devel mailing list