[Sheepdog] [PATCH 3/5] sheepdog: support backing_fmt and tag options for image creation

MORITA Kazutaka morita.kazutaka at lab.ntt.co.jp
Sat Jan 9 15:03:33 CET 2010


To clone images, run

 $ qemu-img create -f sheepdog -F sheepdog -b [base vdiname] -o tag=[base tag] [vdiname]
or
 $ qemu-img create -f sheepdog -o backing_fmt=sheepdog,backing_file=[base vdi],tag=[base tag] [vdiname]

Using sheepdog images as a backing image of other formats may also be
possible though it is not well tested.
For example,

 $ qemu-img create -f qcow2 -F sheepdog -b [base vdiname] -o tag=[base tag] [filename]

Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
 block/sheepdog.c |   84 ++++++++++++++++++++++++-----------------------------
 1 files changed, 38 insertions(+), 46 deletions(-)

diff --git a/block/sheepdog.c b/block/sheepdog.c
index ad3a759..72c1ee4 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -103,6 +103,8 @@ do {									\
 	type __min2 = (y);			\
 	__min1 < __min2 ? __min1: __min2; })
 
+#define BLOCK_OPT_TAG   "tag"
+
 struct sd_req {
 	uint8_t		proto_ver;
 	uint8_t		opcode;
@@ -984,35 +986,8 @@ static int get_sheep_fd(struct bdrv_sd_state *s, uint16_t idx, int *cached)
 	return fd;
 }
 
-static int parse_vdiname(const char *filename, char *vdi, int vdi_len,
-			 uint64_t *tag)
-{
-	char *p, *q;
-
-	p = q = strdup(filename);
-
-	if (!p)
-		return 1;
-
-	strstart(p, "sheepdog:", (const char **)&p);
-
-	strncpy(vdi, p, vdi_len);
-
-	p = strchr(vdi, ':');
-	if (p) {
-		*p++ = '\0';
-		*tag = strtol(p, NULL, 16);
-	} else
-		*tag = -1; /* search current vdi */
-
-	free(q);
-
-	return 0;
-}
-
 static int find_vdi_name(struct bdrv_sd_state *s, char *filename, uint64_t tag,
-			 uint64_t *oid, int for_snapshot, int *current,
-			 unsigned int *epoch)
+			 uint64_t *oid, int *current, unsigned int *epoch)
 {
 	int ret, fd;
 	struct sd_vdi_req hdr;
@@ -1310,9 +1285,8 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags)
 	int nr, ret, i, j;
 	uint64_t oid = 0;
 	struct bdrv_sd_state *s = bs->opaque;
-	char vdi[256];
 	uint64_t tag;
-	int for_snapshot = 0, dummy;
+	int dummy;
 	unsigned int epoch;
 	char *buf;
 
@@ -1333,22 +1307,16 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags)
 		aio_state->nr_aio_req_free = MAX_AIO_REQS;
 	}
 
-	if (strstart(filename, "sheepdog:", NULL))
-		for_snapshot = 1;
-
 	nr = update_node_list(s);
 	if (nr < 0 || !nr)
 		goto out;
 
-	memset(vdi, 0, sizeof(vdi));
-	if (parse_vdiname(filename, vdi, sizeof(vdi), &tag) < 0)
-		goto out;
-
 	tag = strtoull(bs->tag, NULL, 16);
 	if (tag == 0)
 		tag = -1; /* search current vdi */
 
-	ret = find_vdi_name(s, vdi, tag, &oid, for_snapshot, &s->is_current, &epoch);
+	s->name = strdup(filename);
+	ret = find_vdi_name(s, s->name, tag, &oid, &s->is_current, &epoch);
 	if (ret)
 		goto out;
 
@@ -1370,7 +1338,6 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags)
 	       sizeof(s->obj_epoch_array));
 
 	bs->total_sectors = s->inode.vdi_size >> 9;
-	s->name = strdup(vdi);
 	free(buf);
 
 	return 0;
@@ -1432,6 +1399,8 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
 	uint64_t oid = 0;
 	int64_t total_sectors = 0;
 	char *backing_file = NULL;
+	char *backing_fmt = NULL;
+	char *tag = 0;
 	struct timeval tv;
 
 	while (options && options->name) {
@@ -1439,6 +1408,10 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
 			total_sectors = options->value.n / 512;
 		} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
 			backing_file = options->value.s;
+		} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FMT)) {
+			backing_fmt = options->value.s;
+		} else if (!strcmp(options->name, BLOCK_OPT_TAG)) {
+			tag = options->value.s;
 		}
 		options++;
 	}
@@ -1450,12 +1423,22 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
 
 	if (backing_file) {
 		BlockDriverState bs;
-		char vdi[256];
-		uint64_t tag;
 		unsigned int dummy;
+		uint64_t tag_id;
+
+		if (!backing_fmt || strcmp(backing_fmt, "sheepdog") != 0) {
+			eprintf("cloning from other formats is not supported\n");
+			return -1;
+		}
+
+		if (!tag) {
+			eprintf("tag name is required to specify a base image\n");
+			return -1;
+		}
 
 		memset(&bs, 0, sizeof(bs));
 
+		pstrcpy(bs.tag, sizeof(bs.tag), tag);
 		bs.opaque = malloc(sizeof(struct bdrv_sd_state));
 		if (!bs.opaque)
 			return -1;
@@ -1464,14 +1447,13 @@ static int sd_create(const char *filename, QEMUOptionParameter *options)
 		if (ret < 0)
 			return -1;
 
-		if (parse_vdiname(backing_file, vdi, sizeof(vdi), &tag) < 0)
-			return -1;
-
+		tag_id = strtoull(tag, NULL, 16);
 		/* cannot clone from a current inode */
-		if (tag == -1)
+		if (tag_id == 0)
 			return -1;
 
-		ret = find_vdi_name(bs.opaque, vdi, tag, &oid, 1, NULL, &dummy);
+		ret = find_vdi_name(bs.opaque, backing_file, tag_id, &oid, NULL,
+				    &dummy);
 		struct bdrv_sd_state *s = bs.opaque;
 		if (ret || s->is_current)
 			return -1;
@@ -1997,6 +1979,16 @@ static QEMUOptionParameter sd_create_options[] = {
 		.type = OPT_STRING,
 		.help = "File name of a base image"
 	},
+	{
+		.name = BLOCK_OPT_BACKING_FMT,
+		.type = OPT_STRING,
+		.help = "Image format of the base image"
+	},
+	{
+		.name = BLOCK_OPT_TAG,
+		.type = OPT_STRING,
+		.help = "Tag of the base image"
+	},
 	{ NULL }
 };
 
-- 
1.5.6.5




More information about the sheepdog mailing list