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 <[email protected]> --- 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 -- sheepdog mailing list [email protected] http://lists.wpkg.org/mailman/listinfo/sheepdog
