[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