CVSROOT:        /cvs/cluster
Module name:    cluster
Branch:         RHEL5
Changes by:     [EMAIL PROTECTED]       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 via email to