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

Reply via email to