[sheepdog] [PATCH 4/5] dog: upgrade command for print location under the latest placement strategy

Hitoshi Mitake mitake.hitoshi at lab.ntt.co.jp
Sun Jul 12 07:54:31 CEST 2015


This patch adds a new upgrade command for printing location of objects
under latest sheepdog.

How to use:
$ dog upgrade object-location <converted new epoch file> <oid>

Cc: Masahiro Tsuji <tuji at atworks.co.jp>
Signed-off-by: Hitoshi Mitake <mitake.hitoshi at lab.ntt.co.jp>
---
 dog/upgrade.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 126 insertions(+)

diff --git a/dog/upgrade.c b/dog/upgrade.c
index 15551a9..3e7a2d3 100644
--- a/dog/upgrade.c
+++ b/dog/upgrade.c
@@ -32,6 +32,129 @@ static struct upgrade_cmd_data {
 	enum orig_version orig;
 } upgrade_cmd_data = { ~0, };
 
+/* FIXME: this is a ugly copy from group.c, unify is todo */
+static int get_zones_nr_from(struct rb_root *nroot)
+{
+	int nr_zones = 0, j;
+	uint32_t zones[SD_MAX_COPIES];
+	struct sd_node *n;
+
+	rb_for_each_entry(n, nroot, rb) {
+		/*
+		 * Only count zones that actually store data, pure gateways
+		 * don't contribute to the redundancy level.
+		 */
+		if (!n->nr_vnodes)
+			continue;
+
+		for (j = 0; j < nr_zones; j++) {
+			if (n->zone == zones[j])
+				break;
+		}
+
+		if (j == nr_zones) {
+			zones[nr_zones] = n->zone;
+			if (++nr_zones == ARRAY_SIZE(zones))
+				break;
+		}
+	}
+
+	return nr_zones;
+}
+
+static struct vnode_info *alloc_vnode_info_from_epoch_file(const char *epoch_file)
+{
+	int fd, buf_len, ret, nr_nodes;
+	struct stat epoch_stat;
+	struct vnode_info *vinfo = NULL;
+	struct sd_node *nodes;
+
+	fd = open(epoch_file, O_RDONLY);
+	if (fd < 0) {
+		sd_err("failed to read epoch file %s: %m", epoch_file);
+		return NULL;
+	}
+
+	memset(&epoch_stat, 0, sizeof(epoch_stat));
+	ret = fstat(fd, &epoch_stat);
+	if (ret < 0) {
+		sd_err("failed to stat epoch log file: %m");
+		goto close_fd;
+	}
+
+	buf_len = epoch_stat.st_size - sizeof(time_t);
+	if (buf_len < 0) {
+		sd_err("invalid epoch log file: %m");
+		goto close_fd;
+	}
+
+	sd_assert(buf_len % sizeof(struct sd_node) == 0);
+	nr_nodes = buf_len / sizeof(struct sd_node);
+
+	nodes = xzalloc(buf_len);
+
+	ret = xread(fd, nodes, buf_len);
+	if (ret != buf_len) {
+		sd_err("failed to read from epoch file: %m");
+		goto free_nodes;
+	}
+
+	vinfo = xzalloc(sizeof(*vinfo));
+
+	INIT_RB_ROOT(&vinfo->vroot);
+	INIT_RB_ROOT(&vinfo->nroot);
+
+	for (int i = 0; i < nr_nodes; i++) {
+		rb_insert(&vinfo->nroot, &nodes[i], rb, node_cmp);
+		vinfo->nr_nodes++;
+	}
+
+	nodes_to_vnodes(&vinfo->nroot, &vinfo->vroot);
+	vinfo->nr_zones = get_zones_nr_from(&vinfo->nroot);
+
+	return vinfo;
+
+free_nodes:
+	free(nodes);
+
+close_fd:
+	close(fd);
+
+	return vinfo;
+}
+
+/*
+ * caution: currently upgrade_object_location() doesn't assume disk vnodes mode
+ */
+static int upgrade_object_location(int argc, char **argv)
+{
+	const char *epoch_file = argv[optind++], *oid_string = NULL;
+	uint64_t oid;
+	struct vnode_info *vinfo;
+
+	if (optind < argc)
+		oid_string = argv[optind++];
+	else {
+		sd_info("please specify object id in hex format");
+		return EXIT_USAGE;
+	}
+
+	oid = strtoull(oid_string, NULL, 16);
+
+	vinfo = alloc_vnode_info_from_epoch_file(epoch_file);
+	if (!vinfo) {
+		sd_err("failed to construct vnode info from epoch file %s",
+		       epoch_file);
+		return EXIT_SYSFAIL;
+	}
+
+
+	/* TODO: erasure coded objects */
+	sd_info("%s", node_to_str(oid_to_node(oid, &vinfo->vroot, 0)));
+
+	return EXIT_SUCCESS;
+}
+
 static int upgrade_config_convert(int argc, char **argv)
 {
 	const char *orig_file = argv[optind++], *dst_file = NULL;
@@ -334,6 +457,9 @@ static struct subcommand upgrade_cmd[] = {
 	 " <path of new config file>",
 	 "hT", "upgrade config file",
 	 NULL, CMD_NEED_ARG, upgrade_config_convert, upgrade_options},
+	{"object-location", "<path of latest epoch file> <oid>",
+	 "hT", "print object location",
+	 NULL, CMD_NEED_ARG, upgrade_object_location, upgrade_options},
 	{NULL,},
 };
 
-- 
1.9.1



More information about the sheepdog mailing list