[sheepdog] [PATCH] add -d option for dog cluster info

Meng Lingkun starmlk at 163.com
Thu Aug 27 06:06:15 CEST 2015


From: Meng Lingkun <menglingkun at cmss.chinamobile.com>

Dog cluster info with option -d just outputs the changed nodes
between the two adjacent epoches. It's useful in a cluster with
a large amount of nodes. And it would be a way easier to create
a nagios/icinga script that advertises you when something changes
in the cluster and what has changed.

Signed-off-by: Meng Lingkun <menglingkun at cmss.chinamobile.com>
---
 dog/cluster.c |   77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 74 insertions(+), 3 deletions(-)

diff --git a/dog/cluster.c b/dog/cluster.c
index 0cc0edb..336a002 100644
--- a/dog/cluster.c
+++ b/dog/cluster.c
@@ -31,6 +31,9 @@ static struct sd_option cluster_options[] = {
 	{'z', "block_size_shift", true, "specify the shift num of default"
 	      " data object size"},
 	{'V', "fixedvnodes", false, "disable automatic vnodes calculation"},
+	{'d', "diff", false,
+	 "just output the changes between the two adjacent epoches"
+		"for cluster info"},
 	{ 0, NULL, false, NULL },
 };
 
@@ -41,6 +44,7 @@ static struct cluster_cmd_data {
 	uint8_t block_size_shift;
 	bool force;
 	bool strict;
+	bool diff;
 	char name[STORE_LEN];
 	bool fixed_vnodes;
 	bool use_lock;
@@ -223,12 +227,68 @@ static void print_nodes(const struct epoch_log *logs, uint16_t flags)
 	}
 }
 
+static void do_print_nodes_diff(const struct epoch_log *log1,
+				const struct epoch_log *log2, uint16_t flags,
+				char act)
+{
+	int i, j, nr_disk1 = 0, nr_disk2 = 0;
+	const struct sd_node *entry1, *entry2;
+	bool first = true;
+
+	for (i = 0; i < log1->nr_nodes; i++) {
+		entry1 = log1->nodes + i;
+		if (flags & SD_CLUSTER_FLAG_DISKMODE) {
+			for (nr_disk1 = 0; nr_disk1 < DISK_MAX; nr_disk1++) {
+				if (entry1->disks[nr_disk1].disk_id == 0)
+					break;
+			}
+		}
+		for (j = 0; j < log2->nr_nodes; j++) {
+			entry2 = log2->nodes + j;
+			if (flags & SD_CLUSTER_FLAG_DISKMODE) {
+				for (nr_disk2 = 0; nr_disk2 < DISK_MAX;
+						nr_disk2++) {
+					if (entry2->disks[nr_disk2].disk_id
+							== 0)
+						break;
+				}
+			}
+			if (node_cmp(entry1, entry2) == 0
+					&& nr_disk1 == nr_disk2)
+				break;
+		}
+
+		if (j == log2->nr_nodes) {
+			if (flags & SD_CLUSTER_FLAG_DISKMODE)
+				printf("%s%c%s(%d)", first ? "" : ", ",
+					act,
+					addr_to_str(entry1->nid.addr,
+						entry1->nid.port),
+					nr_disk1);
+			else
+				printf("%s%c%s",
+					first ? "" : ", ",
+					act,
+					addr_to_str(entry1->nid.addr,
+						entry1->nid.port));
+			first = false;
+		}
+	}
+}
+
+static void print_nodes_diff(const struct epoch_log *log,
+			const struct epoch_log *last_log, uint16_t flags)
+{
+	do_print_nodes_diff(log, last_log, flags, '+');
+	do_print_nodes_diff(last_log, log, flags, '-');
+}
+
 static int cluster_info(int argc, char **argv)
 {
 	int i, ret;
 	struct sd_req hdr;
 	struct sd_rsp *rsp = (struct sd_rsp *)&hdr;
-	struct epoch_log *logs, *log;
+	struct epoch_log *logs, *log, *last_log = NULL;
 	char *next_log;
 	int nr_logs, log_length;
 	time_t ti, ct;
@@ -318,6 +378,8 @@ retry:
 	next_log = (char *)logs;
 	for (i = 0; i < nr_logs; i++) {
 		log = (struct epoch_log *)next_log;
+		last_log = (struct epoch_log *)((char *)log->nodes
+				+ nodes_nr * sizeof(struct sd_node));
 		ti = log->time;
 		if (raw_output) {
 			snprintf(time_str, sizeof(time_str), "%" PRIu64, (uint64_t) ti);
@@ -328,7 +390,13 @@ retry:
 
 		printf(raw_output ? "%s %d" : "%s %6d", time_str, log->epoch);
 		printf(" [");
-		print_nodes(log, logs->flags);
+		if (cluster_cmd_data.diff) {
+			if (i == nr_logs - 1)
+				printf("formated");
+			else
+				print_nodes_diff(log, last_log, logs->flags);
+		} else
+			print_nodes(log, logs->flags);
 		printf("]\n");
 		next_log = (char *)log->nodes
 				+ nodes_nr * sizeof(struct sd_node);
@@ -822,7 +890,7 @@ failure:
 }
 
 static struct subcommand cluster_cmd[] = {
-	{"info", NULL, "aprhvT", "show cluster information",
+	{"info", NULL, "aprhvTd", "show cluster information",
 	 NULL, CMD_NEED_NODELIST, cluster_info, cluster_options},
 	{"format", NULL, "bcltaphzTVRf", "create a Sheepdog store",
 	 NULL, CMD_NEED_ROOT|CMD_NEED_NODELIST, cluster_format, cluster_options},
@@ -897,6 +965,9 @@ static int cluster_parser(int ch, const char *opt)
 	case 'R':
 		cluster_cmd_data.recycle_vid = true;
 		break;
+	case 'd':
+		cluster_cmd_data.diff = true;
+		break;
 	}
 
 	return 0;
-- 
1.7.1




More information about the sheepdog mailing list