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/src/utils clustat.c
Date: 30 Nov 2007 19:47:15 -0000	[thread overview]
Message-ID: <20071130194715.23900.qmail@sourceware.org> (raw)

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;
 }



             reply	other threads:[~2007-11-30 19:47 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-11-30 19:47 lhh [this message]
  -- strict thread matches above, loose matches on Subject: below --
2007-12-10 18:24 [Cluster-devel] cluster/rgmanager/src/utils clustat.c lhh
2007-12-10 18:11 lhh
2007-12-06 17:52 lhh
2007-12-06 17:47 lhh
2007-09-19 10:56 pcaulfield
2007-02-06 20:22 lhh
2007-02-06 20:21 lhh
2007-02-06 20:20 lhh
2007-02-06 20:18 lhh
2007-02-06 19:54 lhh
2007-01-29 19:42 lhh
2007-01-29 19:41 lhh
2007-01-29 19:40 lhh
2007-01-29 19:40 lhh
2007-01-26 21:38 lhh
2007-01-17 16:21 lhh
2007-01-17 16:20 lhh
2007-01-17 16:19 lhh
2006-12-13 18:36 lhh
2006-12-13 17:12 lhh
2006-10-12 22:07 lhh
2006-09-27 16:43 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=20071130194715.23900.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.