Below is a patch that will add the ability to filter the output of
'cman_tool nodes' by nodename, as well as specify the format of the output.
Filtering by nodename is done via the -n <nodename> option. Multiple
nodes can be specified per usual.
Formatting can be done via the -F <opt1,opt2,...> option, where opt1,
opt2, etc. can be one of four things: id, name, type, and addr. These
will output the node id, node name, type, and address(es) for the
node(s) respectively. Note that this is not a complete set of options as
they correspond to information available from cman_tool, but it does
achieve the goal.
This is intended to give users a way to extract specific information
about a node (or node), which might be useful for scripts, etc.
Comments welcome.
-Ryan
Index: cluster/cman/cman_tool/cman_tool.h
===================================================================
RCS file: /cvs/cluster/cluster/cman/cman_tool/cman_tool.h,v
retrieving revision 1.12
diff -u -p -r1.12 cman_tool.h
--- cluster/cman/cman_tool/cman_tool.h 10 May 2006 14:20:06 -0000 1.12
+++ cluster/cman/cman_tool/cman_tool.h 17 Sep 2007 16:17:55 -0000
@@ -35,7 +35,6 @@
#include <limits.h>
#include <unistd.h>
-
extern char *prog_name;
#ifndef TRUE
@@ -50,13 +49,21 @@ do { \
exit(EXIT_FAILURE); \
} while (0)
-
#define DEFAULT_VOTES 1
#define MAX_INTERFACES 10
+#define MAX_FORMAT_OPTS 10
#define MAX_NODE_NAME_LEN 65
#define MAX_MCAST_NAME_LEN 256
#define MAX_PATH_LEN 256
+enum format_opt
+{
+ FMT_NONE,
+ FMT_ID,
+ FMT_NAME,
+ FMT_TYPE,
+ FMT_ADDR,
+};
struct commandline
{
@@ -67,6 +74,7 @@ struct commandline
char *interfaces[MAX_INTERFACES];
char *override_nodename;
char *key_filename;
+ char *format_opts;
int votes;
int expected_votes;
int two_node;
Index: cluster/cman/cman_tool/main.c
===================================================================
RCS file: /cvs/cluster/cluster/cman/cman_tool/main.c,v
retrieving revision 1.56
diff -u -p -r1.56 main.c
--- cluster/cman/cman_tool/main.c 28 Aug 2007 13:14:06 -0000 1.56
+++ cluster/cman/cman_tool/main.c 17 Sep 2007 16:17:55 -0000
@@ -20,7 +20,7 @@
#include "libcman.h"
#include "cman_tool.h"
-#define OPTION_STRING ("m:n:v:e:2p:c:r:i:N:t:o:k:Vwfqah?d::")
+#define OPTION_STRING ("m:n:v:e:2p:c:r:i:N:t:o:k:F:Vwfqah?d::")
#define OP_JOIN 1
#define OP_LEAVE 2
#define OP_EXPECTED 3
@@ -199,7 +199,8 @@ static void show_status(void)
char tmpbuf[1024];
cman_extra_info_t *einfo = (cman_extra_info_t *)info_buf;
int quorate;
- int i,j;
+ int i;
+ int j;
int portnum;
char *addrptr;
@@ -300,13 +301,46 @@ static int node_compare(const void *va,
return a->cn_nodeid - b->cn_nodeid;
}
+static int node_filter(commandline_t *comline, const char *node)
+{
+ int i;
+
+ for (i = 0; i < comline->num_nodenames; i++) {
+ if (strcmp(comline->nodenames[i], node) == 0) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static int get_format_opt(const char *opt)
+{
+ if (!opt)
+ return FMT_NONE;
+
+ if (!strcmp(opt, "id"))
+ return FMT_ID;
+ if (!strcmp(opt, "name"))
+ return FMT_NAME;
+ if (!strcmp(opt, "type"))
+ return FMT_TYPE;
+ if (!strcmp(opt, "addr"))
+ return FMT_ADDR;
+
+ return FMT_NONE;
+}
+
static void show_nodes(commandline_t *comline)
{
cman_handle_t h;
int count;
int i;
+ int j;
+ int k;
int numnodes;
int dis_count;
+ int format[MAX_FORMAT_OPTS];
cman_node_t *dis_nodes;
cman_node_t *nodes;
struct tm *jtime;
@@ -325,6 +359,16 @@ static void show_nodes(commandline_t *co
if (!nodes)
die("cannot allocate memory for nodes list\n");
+ if (comline->format_opts != NULL) {
+ char *format_str = comline->format_opts;
+ char *format_tmp;
+ for (i = 0; i < MAX_FORMAT_OPTS; i++) {
+ format_tmp = strtok(format_str, ",");
+ format_str = NULL;
+ format[i] = get_format_opt(format_tmp);
+ }
+ }
+
if (cman_get_nodes(h, count, &numnodes, nodes) < 0)
die("cman_get_nodes failed: %s", cman_error(errno));
@@ -333,9 +377,8 @@ static void show_nodes(commandline_t *co
dis_nodes = malloc(sizeof(cman_node_t) * count);
if (cman_get_disallowed_nodes(h, count, &dis_count, dis_nodes) == 0) {
- int i,j;
- for (i=0; i<numnodes; i++) {
- for (j=0; j<dis_count; j++) {
+ for (i = 0; i < numnodes; i++) {
+ for (j = 0; j < dis_count; j++) {
if (dis_nodes[j].cn_nodeid == nodes[i].cn_nodeid)
nodes[i].cn_member = 2;
}
@@ -350,10 +393,19 @@ static void show_nodes(commandline_t *co
printf(" members list may seem inconsistent across the cluster\n");
}
- printf("Node Sts Inc Joined Name\n");
- for (i=0; i<numnodes; i++) {
+ if (!comline->format_opts) {
+ printf("Node Sts Inc Joined Name\n");
+ }
+
+ for (i = 0; i < numnodes; i++) {
char member_type;
+ if (comline->num_nodenames > 0) {
+ if (node_filter(comline, nodes[i].cn_name) == 0) {
+ continue;
+ }
+ }
+
switch (nodes[i].cn_member) {
case 0:
member_type = 'X';
@@ -375,11 +427,13 @@ static void show_nodes(commandline_t *co
else
strcpy(jstring, " ");
- printf("%4d %c %5d %s %s\n",
- nodes[i].cn_nodeid, member_type,
- nodes[i].cn_incarnation, jstring, nodes[i].cn_name);
+ if (!comline->format_opts) {
+ printf("%4d %c %5d %s %s\n",
+ nodes[i].cn_nodeid, member_type,
+ nodes[i].cn_incarnation, jstring, nodes[i].cn_name);
+ }
- if (comline->fence_opt) {
+ if (comline->fence_opt && !comline->format_opts) {
char agent[255];
uint64_t fence_time;
int fenced;
@@ -396,25 +450,57 @@ static void show_nodes(commandline_t *co
}
}
}
+
+ int numaddrs;
+ struct cman_node_address addrs[MAX_INTERFACES];
- if (comline->addresses_opt)
- {
- int numaddrs;
- struct cman_node_address addrs[MAX_INTERFACES];
+ if (comline->addresses_opt || comline->format_opts) {
if (!cman_get_node_addrs(h, nodes[i].cn_nodeid, MAX_INTERFACES, &numaddrs, addrs) &&
numaddrs)
{
- int i;
- printf(" Addresses: ");
- for (i=0; i<numaddrs; i++)
- {
- print_address(addrs[i].cna_address);
+ if (!comline->format_opts) {
+ printf(" Addresses: ");
+ for (i = 0; i < numaddrs; i++)
+ {
+ print_address(addrs[i].cna_address);
+ printf(" ");
+ }
+ printf("\n");
+ }
+ }
+ }
+
+ if (comline->format_opts) {
+ for (j = 0; j < MAX_FORMAT_OPTS; j++) {
+ switch (format[j]) {
+ case FMT_NONE:
+ break;
+ case FMT_ID:
+ printf("%d ", nodes[i].cn_nodeid);
+ break;
+ case FMT_NAME:
+ printf("%s ", nodes[i].cn_name);
+ break;
+ case FMT_TYPE:
+ printf("%c ", member_type);
+ break;
+ case FMT_ADDR:
+ for (k = 0; k < numaddrs; k++) {
+ print_address(addrs[k].cna_address);
+ if (k != (numaddrs - 1)) {
+ printf(",");
+ }
+ }
printf(" ");
+ break;
+ default:
+ break;
}
- printf("\n");
}
+ printf("\n");
}
}
+
free(nodes);
free(dis_nodes);
cman_finish(h);
@@ -701,6 +787,10 @@ static void decode_arguments(int argc, c
comline->clustername_opt = TRUE;
break;
+ case 'F':
+ comline->format_opts = strdup(optarg);
+ break;
+
case 'V':
printf("cman_tool %s (built %s %s)\n",
RELEASE_VERSION, __DATE__, __TIME__);