[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