All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/2] sheepdog: add user-defined redundancy option
@ 2013-10-29  8:17 Liu Yuan
  2013-10-29  8:17 ` [Qemu-devel] [PATCH 1/2] sheepdog: refactor do_sd_create() Liu Yuan
  2013-10-29  8:17 ` [Qemu-devel] [PATCH] sheepdog: support user-defined redundancy option Liu Yuan
  0 siblings, 2 replies; 4+ messages in thread
From: Liu Yuan @ 2013-10-29  8:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: sheepdog

This patch set add one sheepdog specific option for qemu-img to control
redundancy.

This patch set is on top of Kevin's block tree.

Liu Yuan (2):
  sheepdog: refactor do_sd_create()
  sheepdog: support user-defined redundancy option

 block/sheepdog.c          |  110 +++++++++++++++++++++++++++++++++++----------
 include/block/block_int.h |    1 +
 2 files changed, 88 insertions(+), 23 deletions(-)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Qemu-devel] [PATCH 1/2] sheepdog: refactor do_sd_create()
  2013-10-29  8:17 [Qemu-devel] [PATCH 0/2] sheepdog: add user-defined redundancy option Liu Yuan
@ 2013-10-29  8:17 ` Liu Yuan
  2013-10-29 20:32   ` Benoît Canet
  2013-10-29  8:17 ` [Qemu-devel] [PATCH] sheepdog: support user-defined redundancy option Liu Yuan
  1 sibling, 1 reply; 4+ messages in thread
From: Liu Yuan @ 2013-10-29  8:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, sheepdog, Stefan Hajnoczi

We can actually use BDRVSheepdogState *s to pass most of the parameters.

Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Liu Yuan <namei.unix@gmail.com>
---
 block/sheepdog.c |   37 +++++++++++++++----------------------
 1 file changed, 15 insertions(+), 22 deletions(-)

diff --git a/block/sheepdog.c b/block/sheepdog.c
index 9f0757b..e66d2f8 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -1348,9 +1348,7 @@ out:
     return ret;
 }
 
-static int do_sd_create(BDRVSheepdogState *s, char *filename, int64_t vdi_size,
-                        uint32_t base_vid, uint32_t *vdi_id, int snapshot,
-                        uint8_t copy_policy)
+static int do_sd_create(BDRVSheepdogState *s, uint32_t *vdi_id, int snapshot)
 {
     SheepdogVdiReq hdr;
     SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr;
@@ -1367,11 +1365,11 @@ static int do_sd_create(BDRVSheepdogState *s, char *filename, int64_t vdi_size,
      * does not fit in buf?  For now, just truncate and avoid buffer overrun.
      */
     memset(buf, 0, sizeof(buf));
-    pstrcpy(buf, sizeof(buf), filename);
+    pstrcpy(buf, sizeof(buf), s->name);
 
     memset(&hdr, 0, sizeof(hdr));
     hdr.opcode = SD_OP_NEW_VDI;
-    hdr.vdi_id = base_vid;
+    hdr.vdi_id = s->inode.vdi_id;
 
     wlen = SD_MAX_VDI_LEN;
 
@@ -1379,8 +1377,8 @@ static int do_sd_create(BDRVSheepdogState *s, char *filename, int64_t vdi_size,
     hdr.snapid = snapshot;
 
     hdr.data_length = wlen;
-    hdr.vdi_size = vdi_size;
-    hdr.copy_policy = copy_policy;
+    hdr.vdi_size = s->inode.vdi_size;
+    hdr.copy_policy = s->inode.copy_policy;
 
     ret = do_req(fd, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
 
@@ -1391,7 +1389,7 @@ static int do_sd_create(BDRVSheepdogState *s, char *filename, int64_t vdi_size,
     }
 
     if (rsp->result != SD_RES_SUCCESS) {
-        error_report("%s, %s", sd_strerror(rsp->result), filename);
+        error_report("%s, %s", sd_strerror(rsp->result), s->inode.name);
         return -EIO;
     }
 
@@ -1452,23 +1450,21 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
                      Error **errp)
 {
     int ret = 0;
-    uint32_t vid = 0, base_vid = 0;
-    int64_t vdi_size = 0;
+    uint32_t vid = 0;
     char *backing_file = NULL;
     BDRVSheepdogState *s;
-    char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN];
+    char tag[SD_MAX_VDI_TAG_LEN];
     uint32_t snapid;
     bool prealloc = false;
     Error *local_err = NULL;
 
     s = g_malloc0(sizeof(BDRVSheepdogState));
 
-    memset(vdi, 0, sizeof(vdi));
     memset(tag, 0, sizeof(tag));
     if (strstr(filename, "://")) {
-        ret = sd_parse_uri(s, filename, vdi, &snapid, tag);
+        ret = sd_parse_uri(s, filename, s->name, &snapid, tag);
     } else {
-        ret = parse_vdiname(s, filename, vdi, &snapid, tag);
+        ret = parse_vdiname(s, filename, s->name, &snapid, tag);
     }
     if (ret < 0) {
         goto out;
@@ -1476,7 +1472,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
 
     while (options && options->name) {
         if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
-            vdi_size = options->value.n;
+            s->inode.vdi_size = options->value.n;
         } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
             backing_file = options->value.s;
         } else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
@@ -1494,7 +1490,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
         options++;
     }
 
-    if (vdi_size > SD_MAX_VDI_SIZE) {
+    if (s->inode.vdi_size > SD_MAX_VDI_SIZE) {
         error_report("too big image size");
         ret = -EINVAL;
         goto out;
@@ -1529,12 +1525,11 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
             goto out;
         }
 
-        base_vid = s->inode.vdi_id;
         bdrv_unref(bs);
     }
 
     /* TODO: allow users to specify copy number */
-    ret = do_sd_create(s, vdi, vdi_size, base_vid, &vid, 0, 0);
+    ret = do_sd_create(s, &vid, 0);
     if (!prealloc || ret) {
         goto out;
     }
@@ -1723,8 +1718,7 @@ static int sd_create_branch(BDRVSheepdogState *s)
      * false bail out.
      */
     deleted = sd_delete(s);
-    ret = do_sd_create(s, s->name, s->inode.vdi_size, s->inode.vdi_id, &vid,
-                       !deleted, s->inode.copy_policy);
+    ret = do_sd_create(s, &vid, !deleted);
     if (ret) {
         goto out;
     }
@@ -2013,8 +2007,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
         goto cleanup;
     }
 
-    ret = do_sd_create(s, s->name, s->inode.vdi_size, s->inode.vdi_id, &new_vid,
-                       1, s->inode.copy_policy);
+    ret = do_sd_create(s, &new_vid, 1);
     if (ret < 0) {
         error_report("failed to create inode for snapshot. %s",
                      strerror(errno));
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [Qemu-devel] [PATCH] sheepdog: support user-defined redundancy option
  2013-10-29  8:17 [Qemu-devel] [PATCH 0/2] sheepdog: add user-defined redundancy option Liu Yuan
  2013-10-29  8:17 ` [Qemu-devel] [PATCH 1/2] sheepdog: refactor do_sd_create() Liu Yuan
@ 2013-10-29  8:17 ` Liu Yuan
  1 sibling, 0 replies; 4+ messages in thread
From: Liu Yuan @ 2013-10-29  8:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Kevin Wolf, sheepdog, Stefan Hajnoczi

Sheepdog support two kinds od redundancy, full replication and erasure coding.

# create a fully replicated vdi with x copies
 -o redundancy=x (1 <= x <= SD_MAX_COPIES)

# create a erasure coded vdi with x data strips and y parity strips
 -o redundancy=x:y (x must be one of {2,4,8,16} and 1 <= y < SD_EC_MAX_STRIP)

E.g, to convert a vdi into sheepdog vdi 'test' with 8:3 erasure coding scheme

$ qemu-img convert -o redundancy=8:3 linux-0.2.img sheepdog:test

Cc: Kevin Wolf <kwolf@redhat.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Liu Yuan <namei.unix@gmail.com>
---
 block/sheepdog.c          |   78 ++++++++++++++++++++++++++++++++++++++++++++-
 include/block/block_int.h |    1 +
 2 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/block/sheepdog.c b/block/sheepdog.c
index e66d2f8..c7ea517 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -91,6 +91,14 @@
 #define SD_NR_VDIS   (1U << 24)
 #define SD_DATA_OBJ_SIZE (UINT64_C(1) << 22)
 #define SD_MAX_VDI_SIZE (SD_DATA_OBJ_SIZE * MAX_DATA_OBJS)
+/*
+ * For erasure coding, we use at most SD_EC_MAX_STRIP for data strips and
+ * (SD_EC_MAX_STRIP - 1) for parity strips
+ *
+ * SD_MAX_COPIES is sum of number of dats trips and parity strips.
+ */
+#define SD_EC_MAX_STRIP 16
+#define SD_MAX_COPIES (SD_EC_MAX_STRIP * 2 - 1)
 
 #define SD_INODE_SIZE (sizeof(SheepdogInode))
 #define CURRENT_VDI_ID 0
@@ -1446,6 +1454,65 @@ out:
     return ret;
 }
 
+static int64_t is_numeric(const char *s)
+{
+    char *end;
+    return strtosz_suffix(s, &end, STRTOSZ_DEFSUFFIX_B);
+}
+
+/*
+ * Sheepdog support two kinds od redundancy, full replication and erasure
+ * coding.
+ *
+ * # create a fully replicated vdi with x copies
+ * -o redundancy=x (1 <= x <= SD_MAX_COPIES)
+ *
+ * # create a erasure coded vdi with x data strips and y parity strips
+ * -o redundancy=x:y (x must be one of {2,4,8,16} and 1 <= y < SD_EC_MAX_STRIP)
+ */
+static int parse_redundancy(BDRVSheepdogState *s, const char *opt)
+{
+    struct SheepdogInode *inode = &s->inode;
+    const char *n1, *n2;
+    uint8_t copy, parity;
+    char p[10];
+
+    strncpy(p, opt, sizeof(p));
+    n1 = strtok(p, ":");
+    n2 = strtok(NULL, ":");
+
+    if ((n1 && !is_numeric(n1)) || (n2 && !is_numeric(n2))) {
+        return -EINVAL;
+    }
+
+    copy = strtol(n1, NULL, 10);
+    if (copy > SD_MAX_COPIES) {
+        return -EINVAL;
+    }
+    if (!n2) {
+        inode->copy_policy = 0;
+        inode->nr_copies = copy;
+    }
+
+    if (copy != 2 && copy != 4 && copy != 8 && copy != 16) {
+        return -EINVAL;
+    }
+
+    parity = strtol(n2, NULL, 10);
+    if (parity >= SD_EC_MAX_STRIP || parity == 0) {
+        return -EINVAL;
+    }
+
+    /*
+     * 4 bits for parity and 4 bits for data.
+     * We have to compress upper data bits because it can't represent 16
+     */
+    inode->copy_policy = ((copy / 2) << 4) + parity;
+    inode->nr_copies = copy + parity;
+
+    return 0;
+}
+
 static int sd_create(const char *filename, QEMUOptionParameter *options,
                      Error **errp)
 {
@@ -1486,6 +1553,11 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
                 ret = -EINVAL;
                 goto out;
             }
+        } else if (!strcmp(options->name, BLOCK_OPT_REDUNDANCY)) {
+            ret = parse_redundancy(s, options->value.s);
+            if (ret < 0) {
+                goto out;
+            }
         }
         options++;
     }
@@ -1528,7 +1600,6 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
         bdrv_unref(bs);
     }
 
-    /* TODO: allow users to specify copy number */
     ret = do_sd_create(s, &vid, 0);
     if (!prealloc || ret) {
         goto out;
@@ -2332,6 +2403,11 @@ static QEMUOptionParameter sd_create_options[] = {
         .type = OPT_STRING,
         .help = "Preallocation mode (allowed values: off, full)"
     },
+    {
+        .name = BLOCK_OPT_REDUNDANCY,
+        .type = OPT_STRING,
+        .help = "Redundancy of the image"
+    },
     { NULL }
 };
 
diff --git a/include/block/block_int.h b/include/block/block_int.h
index a48731d..b90862f 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -53,6 +53,7 @@
 #define BLOCK_OPT_COMPAT_LEVEL      "compat"
 #define BLOCK_OPT_LAZY_REFCOUNTS    "lazy_refcounts"
 #define BLOCK_OPT_ADAPTER_TYPE      "adapter_type"
+#define BLOCK_OPT_REDUNDANCY        "redundancy"
 
 typedef struct BdrvTrackedRequest {
     BlockDriverState *bs;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [Qemu-devel] [PATCH 1/2] sheepdog: refactor do_sd_create()
  2013-10-29  8:17 ` [Qemu-devel] [PATCH 1/2] sheepdog: refactor do_sd_create() Liu Yuan
@ 2013-10-29 20:32   ` Benoît Canet
  0 siblings, 0 replies; 4+ messages in thread
From: Benoît Canet @ 2013-10-29 20:32 UTC (permalink / raw)
  To: Liu Yuan; +Cc: Kevin Wolf, sheepdog, qemu-devel, Stefan Hajnoczi

>Le Tuesday 29 Oct 2013 à 16:17:34 (+0800), Liu Yuan a écrit :
> We can actually use BDRVSheepdogState *s to pass most of the parameters.
> 
> Cc: Kevin Wolf <kwolf@redhat.com>
> Cc: Stefan Hajnoczi <stefanha@redhat.com>
> Signed-off-by: Liu Yuan <namei.unix@gmail.com>
> ---
>  block/sheepdog.c |   37 +++++++++++++++----------------------
>  1 file changed, 15 insertions(+), 22 deletions(-)
> 
> diff --git a/block/sheepdog.c b/block/sheepdog.c
> index 9f0757b..e66d2f8 100644
> --- a/block/sheepdog.c
> +++ b/block/sheepdog.c
> @@ -1348,9 +1348,7 @@ out:
>      return ret;
>  }
>  
> -static int do_sd_create(BDRVSheepdogState *s, char *filename, int64_t vdi_size,
> -                        uint32_t base_vid, uint32_t *vdi_id, int snapshot,
> -                        uint8_t copy_policy)
> +static int do_sd_create(BDRVSheepdogState *s, uint32_t *vdi_id, int snapshot)
>  {
>      SheepdogVdiReq hdr;
>      SheepdogVdiRsp *rsp = (SheepdogVdiRsp *)&hdr;
> @@ -1367,11 +1365,11 @@ static int do_sd_create(BDRVSheepdogState *s, char *filename, int64_t vdi_size,
>       * does not fit in buf?  For now, just truncate and avoid buffer overrun.
>       */
>      memset(buf, 0, sizeof(buf));
> -    pstrcpy(buf, sizeof(buf), filename);
> +    pstrcpy(buf, sizeof(buf), s->name);
>  
>      memset(&hdr, 0, sizeof(hdr));
>      hdr.opcode = SD_OP_NEW_VDI;
> -    hdr.vdi_id = base_vid;
> +    hdr.vdi_id = s->inode.vdi_id;
>  
>      wlen = SD_MAX_VDI_LEN;
>  
> @@ -1379,8 +1377,8 @@ static int do_sd_create(BDRVSheepdogState *s, char *filename, int64_t vdi_size,
>      hdr.snapid = snapshot;
>  
>      hdr.data_length = wlen;
> -    hdr.vdi_size = vdi_size;
> -    hdr.copy_policy = copy_policy;
> +    hdr.vdi_size = s->inode.vdi_size;
> +    hdr.copy_policy = s->inode.copy_policy;
>  
>      ret = do_req(fd, (SheepdogReq *)&hdr, buf, &wlen, &rlen);
>  
> @@ -1391,7 +1389,7 @@ static int do_sd_create(BDRVSheepdogState *s, char *filename, int64_t vdi_size,
>      }
>  
>      if (rsp->result != SD_RES_SUCCESS) {
> -        error_report("%s, %s", sd_strerror(rsp->result), filename);
> +        error_report("%s, %s", sd_strerror(rsp->result), s->inode.name);
>          return -EIO;
>      }
>  
> @@ -1452,23 +1450,21 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
>                       Error **errp)
>  {
>      int ret = 0;
> -    uint32_t vid = 0, base_vid = 0;
> -    int64_t vdi_size = 0;
> +    uint32_t vid = 0;
>      char *backing_file = NULL;
>      BDRVSheepdogState *s;
> -    char vdi[SD_MAX_VDI_LEN], tag[SD_MAX_VDI_TAG_LEN];
> +    char tag[SD_MAX_VDI_TAG_LEN];
>      uint32_t snapid;
>      bool prealloc = false;
>      Error *local_err = NULL;
>  
>      s = g_malloc0(sizeof(BDRVSheepdogState));
>  
> -    memset(vdi, 0, sizeof(vdi));
>      memset(tag, 0, sizeof(tag));
>      if (strstr(filename, "://")) {
> -        ret = sd_parse_uri(s, filename, vdi, &snapid, tag);
> +        ret = sd_parse_uri(s, filename, s->name, &snapid, tag);
>      } else {
> -        ret = parse_vdiname(s, filename, vdi, &snapid, tag);
> +        ret = parse_vdiname(s, filename, s->name, &snapid, tag);
>      }
>      if (ret < 0) {
>          goto out;
> @@ -1476,7 +1472,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
>  
>      while (options && options->name) {
>          if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
> -            vdi_size = options->value.n;
> +            s->inode.vdi_size = options->value.n;
>          } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
>              backing_file = options->value.s;
>          } else if (!strcmp(options->name, BLOCK_OPT_PREALLOC)) {
> @@ -1494,7 +1490,7 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
>          options++;
>      }
>  
> -    if (vdi_size > SD_MAX_VDI_SIZE) {
> +    if (s->inode.vdi_size > SD_MAX_VDI_SIZE) {
>          error_report("too big image size");
>          ret = -EINVAL;
>          goto out;
> @@ -1529,12 +1525,11 @@ static int sd_create(const char *filename, QEMUOptionParameter *options,
>              goto out;
>          }
>  
> -        base_vid = s->inode.vdi_id;
>          bdrv_unref(bs);
>      }
>  
>      /* TODO: allow users to specify copy number */
> -    ret = do_sd_create(s, vdi, vdi_size, base_vid, &vid, 0, 0);
> +    ret = do_sd_create(s, &vid, 0);
>      if (!prealloc || ret) {
>          goto out;
>      }
> @@ -1723,8 +1718,7 @@ static int sd_create_branch(BDRVSheepdogState *s)
>       * false bail out.
>       */
>      deleted = sd_delete(s);
> -    ret = do_sd_create(s, s->name, s->inode.vdi_size, s->inode.vdi_id, &vid,
> -                       !deleted, s->inode.copy_policy);
> +    ret = do_sd_create(s, &vid, !deleted);
>      if (ret) {
>          goto out;
>      }
> @@ -2013,8 +2007,7 @@ static int sd_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
>          goto cleanup;
>      }
>  
> -    ret = do_sd_create(s, s->name, s->inode.vdi_size, s->inode.vdi_id, &new_vid,
> -                       1, s->inode.copy_policy);
> +    ret = do_sd_create(s, &new_vid, 1);
>      if (ret < 0) {
>          error_report("failed to create inode for snapshot. %s",
>                       strerror(errno));
> -- 
> 1.7.9.5
> 
> 
Reviewed-by: Benoit Canet <benoit@irqsave.net>

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2013-10-29 20:33 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-10-29  8:17 [Qemu-devel] [PATCH 0/2] sheepdog: add user-defined redundancy option Liu Yuan
2013-10-29  8:17 ` [Qemu-devel] [PATCH 1/2] sheepdog: refactor do_sd_create() Liu Yuan
2013-10-29 20:32   ` Benoît Canet
2013-10-29  8:17 ` [Qemu-devel] [PATCH] sheepdog: support user-defined redundancy option Liu Yuan

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.