[Sheepdog] [PATCH, RFC] collie: extend vdi list to allow listing a single VDI by name

Chris Webb chris at arachsys.com
Sat Jun 18 18:26:48 CEST 2011


On a test cluster with three nodes and five hundred VDIs, the early exit
optimisation introduced here reduces the time to find the size, used, and
shared values from a specific VDI from around 3.4s (for naive grep of collie
vdi list output) to around 2s, similar to a 'collie vdi object' command.

However, is it possible to make this and other VDI operations properly
constant- or log-time in the number of VDIs instead of linear?

Signed-off-by: Chris Webb <chris at arachsys.com>
---
 collie/collie.c |   58 +++++++++++++++++++++++++++++++++---------------------
 1 files changed, 35 insertions(+), 23 deletions(-)

diff --git a/collie/collie.c b/collie/collie.c
index 759d4c0..55fb5d6 100644
--- a/collie/collie.c
+++ b/collie/collie.c
@@ -365,6 +365,13 @@ static int parse_vdi(vdi_parser_func_t func, size_t size, void *data)
 	return 0;
 }
 
+struct get_vid_info {
+	char *name;
+	char *tag;
+	uint32_t vid;
+	uint32_t snapid;
+};
+
 static void print_vdi_list(uint32_t vid, char *name, char *tag, uint32_t snapid,
 			   uint32_t flags, struct sheepdog_inode *i, void *data)
 {
@@ -374,6 +381,10 @@ static void print_vdi_list(uint32_t vid, char *name, char *tag, uint32_t snapid,
 	time_t ti;
 	struct tm tm;
 	char dbuf[128];
+	struct get_vid_info *info = data;
+
+	if (info && strcmp(name, info->name) != 0)
+		return;
 
 	ti = i->ctime >> 32;
 	if (raw_output) {
@@ -399,21 +410,19 @@ static void print_vdi_list(uint32_t vid, char *name, char *tag, uint32_t snapid,
 	size_to_str(my_objs * SD_DATA_OBJ_SIZE, my_objs_str, sizeof(my_objs_str));
 	size_to_str(cow_objs * SD_DATA_OBJ_SIZE, cow_objs_str, sizeof(cow_objs_str));
 
-	if (!data || strcmp(name, data) == 0) {
-		if (raw_output) {
-			printf("%c ", is_current(i) ? '=' : 's');
-			while (*name) {
-				if (isspace(*name) || *name == '\\')
-					putchar('\\');
-				putchar(*name++);
-			}
-			printf(" %d %s %s %s %s %" PRIx32 "\n", snapid,
-			       vdi_size_str, my_objs_str, cow_objs_str, dbuf, vid);
-		} else {
-			printf("%c %-8s %5d %7s %7s %7s %s  %7" PRIx32 "\n",
-			       is_current(i) ? ' ' : 's', name, snapid,
-			       vdi_size_str, my_objs_str, cow_objs_str, dbuf, vid);
+	if (raw_output) {
+		printf("%c ", is_current(i) ? '=' : 's');
+		while (*name) {
+			if (isspace(*name) || *name == '\\')
+				putchar('\\');
+			putchar(*name++);
 		}
+		printf(" %d %s %s %s %s %" PRIx32 "\n", snapid,
+				vdi_size_str, my_objs_str, cow_objs_str, dbuf, vid);
+	} else {
+		printf("%c %-8s %5d %7s %7s %7s %s  %7" PRIx32 "\n",
+				is_current(i) ? ' ' : 's', name, snapid,
+				vdi_size_str, my_objs_str, cow_objs_str, dbuf, vid);
 	}
 }
 
@@ -480,13 +489,6 @@ static void cal_total_vdi_size(uint32_t vid, char *name, char * tag,
 		*size += i->vdi_size;
 }
 
-struct get_vid_info {
-	char *name;
-	char *tag;
-	uint32_t vid;
-	uint32_t snapid;
-};
-
 static void get_oid(uint32_t vid, char *name, char *tag, uint32_t snapid,
 		    uint32_t flags, struct sheepdog_inode *i, void *data)
 {
@@ -721,13 +723,23 @@ static struct subcommand node_cmd[] = {
 
 static int vdi_list(int argc, char **argv)
 {
+	char *vdiname = argv[optind];
+
 	if (!raw_output) {
 		printf("  name        id    size    used  shared    creation time   vdi id\n");
 		printf("------------------------------------------------------------------\n");
 	}
 
-	parse_vdi(print_vdi_list, SD_INODE_SIZE, NULL);
-	return EXIT_SUCCESS;
+	if (vdiname) {
+		struct get_vid_info info;
+		memset(&info, 0, sizeof(info));
+		info.name = vdiname;
+		parse_vdi(print_vdi_list, SD_INODE_SIZE, &info);
+		return EXIT_SUCCESS;
+	} else {
+		parse_vdi(print_vdi_list, SD_INODE_SIZE, NULL);
+		return EXIT_SUCCESS;
+	}
 }
 
 static int vdi_tree(int argc, char **argv)
-- 
1.7.4.1




More information about the sheepdog mailing list