[Sheepdog] [PATCH 2/2] shepherd: sort the output of vdi list

MORITA Kazutaka morita.kazutaka at lab.ntt.co.jp
Sat Jan 9 14:58:30 CET 2010


Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
 collie/store.c      |   13 ++++++++++-
 include/meta.h      |   14 ++---------
 shepherd/shepherd.c |   59 ++++++++++++++++++++++++++++++++++++++------------
 3 files changed, 60 insertions(+), 26 deletions(-)

diff --git a/collie/store.c b/collie/store.c
index fce71ff..aa785b4 100644
--- a/collie/store.c
+++ b/collie/store.c
@@ -60,6 +60,8 @@ static int stat_sheep(uint64_t *store_size, uint64_t *store_free)
 		used += s.st_size;
 	}
 
+	closedir(dir);
+
 	*store_size = vs.f_frsize * vs.f_bfree;
 	*store_free = vs.f_frsize * vs.f_bfree - used;
 
@@ -325,6 +327,7 @@ out:
 
 static int so_read_vdis(struct request *req)
 {
+	struct sd_so_req *hdr = (struct sd_so_req *)&req->rq;
 	struct sd_so_rsp *rsp = (struct sd_so_rsp *)&req->rp;
 	DIR *dir, *vdir;
 	struct dirent *dent, *vdent;
@@ -373,6 +376,11 @@ static int so_read_vdis(struct request *req)
 			return SD_RES_NO_VDI;
 
 		while ((vdent = readdir(vdir))) {
+			if ((char *)sde - (char *)req->data >= hdr->data_length) {
+				closedir(vdir);
+				goto out;
+			}
+
 			if (!strcmp(vdent->d_name, ".") ||
 			    !strcmp(vdent->d_name, ".."))
 				continue;
@@ -395,9 +403,12 @@ static int so_read_vdis(struct request *req)
 
 			sde->name_len = strlen(dent->d_name);
 			strcpy(sde->name, dent->d_name);
-			sde = next_entry(sde);
+			sde++;
 		}
+		closedir(vdir);
 	}
+out:
+	closedir(dir);
 
 	rsp->data_length = (char *)sde - (char *)req->data;
 	dprintf("%d\n", rsp->data_length);
diff --git a/include/meta.h b/include/meta.h
index 801f31e..31568d0 100644
--- a/include/meta.h
+++ b/include/meta.h
@@ -51,6 +51,8 @@ static inline int is_data_obj(uint64_t oid)
 
 #define FLAG_CURRENT 1
 
+#define MAX_VDINAME_LEN 1024
+
 struct sheepdog_dir_entry {
 	uint64_t oid;
 	uint32_t tag;
@@ -59,19 +61,9 @@ struct sheepdog_dir_entry {
 	uint8_t flags;
 	uint32_t epoch;
 	uint32_t pad;
-	char name[0];
+	char name[MAX_VDINAME_LEN];
 };
 
-#define SD_DIR_ALIGN 8
-
-static inline struct sheepdog_dir_entry *next_entry(struct sheepdog_dir_entry *ent)
-{
-	int len = offsetof(struct sheepdog_dir_entry, name)
-		+ roundup(ent->name_len, SD_DIR_ALIGN);
-
-	return (struct sheepdog_dir_entry *)((char *)ent + len);
-}
-
 #define MAX_DATA_OBJS (1 << 18)
 #define MAX_CHILDREN 1024
 
diff --git a/shepherd/shepherd.c b/shepherd/shepherd.c
index e66c7e7..8c4aa9e 100644
--- a/shepherd/shepherd.c
+++ b/shepherd/shepherd.c
@@ -393,15 +393,44 @@ static int shutdown_sheepdog(void)
 
 typedef void (*vdi_parser_func_t)(uint64_t oid, char *name, uint32_t tag, uint32_t flags,
 				  struct sheepdog_inode *i, void *data);
+typedef int (*vdi_comp_func_t)(const void *p1, const void *p2);
+
+static int vdicomp_ctime(const void *p1, const void *p2)
+{
+	struct sheepdog_dir_entry *ent1 = (struct sheepdog_dir_entry *) p1;
+	struct sheepdog_dir_entry *ent2 = (struct sheepdog_dir_entry *) p2;
+
+	/* TODO: make a ctime field in struct sheepdog_dir_entry */
+	if (ent1->tag < ent2->tag)
+		return -1;
+
+	if (ent1->tag > ent2->tag)
+		return 1;
+
+	return 0;
+}
+
+static int vdicomp_name(const void *p1, const void *p2)
+{
+	struct sheepdog_dir_entry *ent1 = (struct sheepdog_dir_entry *) p1;
+	struct sheepdog_dir_entry *ent2 = (struct sheepdog_dir_entry *) p2;
+	int ret;
+
+	ret = strcmp(ent1->name, ent2->name);
+	if (ret)
+		return ret;
+
+	return -vdicomp_ctime(p1, p2);
+}
 
 /*
  * TODO: handle larger buffer
  */
-int parse_vdi(vdi_parser_func_t func, void *data)
+int parse_vdi(vdi_parser_func_t func, vdi_comp_func_t compare, void *data)
 {
-	struct sheepdog_dir_entry *prv, *ent;
+	struct sheepdog_dir_entry *ent, *endp;
 	char *buf;
-	int rest, ret;
+	int nr_ent, ret;
 	struct sheepdog_inode i;
 	struct sd_so_req req;
 
@@ -422,9 +451,13 @@ int parse_vdi(vdi_parser_func_t func, void *data)
 		goto out;
 	}
 
+	nr_ent = ret / sizeof(struct sheepdog_dir_entry);
+	if (compare)
+		qsort(buf, nr_ent, sizeof(struct sheepdog_dir_entry), compare);
+
 	ent = (struct sheepdog_dir_entry *) buf;
-	rest = ret;
-	while (rest > 0) {
+	endp = ent + nr_ent;
+	while (ent < endp) {
 		if (!ent->name_len)
 			break;
 
@@ -434,9 +467,7 @@ int parse_vdi(vdi_parser_func_t func, void *data)
 		if (ret == sizeof(i))
 			func(ent->oid, ent->name, ent->tag, ent->flags, &i, data);
 
-		prv = ent;
-		ent = next_entry(prv);
-		rest -= ((char *)ent - (char *)prv);
+		ent++;
 	}
 
 out:
@@ -504,7 +535,7 @@ static int graphview_vdi(char *vdiname, int highlight)
 	/* print a header */
 	printf("digraph G \{\n");
 
-	parse_vdi(print_graph_tree, &i);
+	parse_vdi(print_graph_tree, vdicomp_ctime, &i);
 
 	if (i.root == 0)
 		printf("  \"0\" [shape = \"ellipse\", label = \"root\"];\n");
@@ -559,7 +590,7 @@ static int treeview_vdi(char *vdiname, int highlight)
 	init_tree();
 	add_proc("", "root", 1, 1, 0);
 
-	parse_vdi(print_vdi_tree, &i);
+	parse_vdi(print_vdi_tree, vdicomp_ctime, &i);
 
 	dump_tree();
 
@@ -802,7 +833,7 @@ static void print_obj(char *vdiname, unsigned index)
 	info.name = vdiname;
 	info.oid = 0;
 
-	ret = parse_vdi(get_oid, &info);
+	ret = parse_vdi(get_oid, NULL, &info);
 
 	oid = info.oid;
 
@@ -863,7 +894,7 @@ rerun:
 		case FORMAT_LIST:
 			printf("  name     tag         size    used  shared    creation time  object id\n");
 			printf("-----------------------------------------------------------------------\n");
-			ret = parse_vdi(print_vdi_list, name);
+			ret = parse_vdi(print_vdi_list, vdicomp_name, name);
 			break;
 		case FORMAT_TREE:
 			ret = treeview_vdi(name, highlight);
@@ -939,7 +970,7 @@ rerun:
 
 		printf("\n");
 
-		parse_vdi(cal_total_vdi_size, &total_vdi_size);
+		parse_vdi(cal_total_vdi_size, NULL, &total_vdi_size);
 
 		printf("Total\t%" PRIu64 "G\t%" PRIu64 "G\t%3d%%, total virtual VDI Size\t%" PRIu64 "G\n",
 		       total_size / 1024 / 1024 / 1024,
@@ -985,7 +1016,7 @@ rerun:
 
 		printf("Name            |Vdi size |Allocated| Shared  | Status\n");
 		printf("----------------+---------+---------+---------+------------\n");
-		ret = parse_vdi(print_vm_list, &vli);
+		ret = parse_vdi(print_vm_list, vdicomp_name, &vli);
 		break;
 	}
 	default:
-- 
1.5.6.5




More information about the sheepdog mailing list