[libvirt] [PATCH] storage sheepdog: allow to specify redundancy level

Vasiliy Tolstov v.tolstov at selfip.ru
Wed Nov 18 13:36:00 UTC 2015


Some storage backends allows to specify per volume redundancy options.
Sheepdog use x format for specify copies, and x:y format to specify
data and parity block count.

Signed-off-by: Alexey Tyabin <aleksey.tyabin at gmail.com>
Signed-off-by: Vasiliy Tolstov <v.tolstov at selfip.ru>
---
 docs/schemas/storagevol.rng                 |   3 +
 src/conf/storage_conf.c                     |   2 +
 src/storage/storage_backend_sheepdog.c      | 141 +++++++++++++++++-----------
 src/util/virstoragefile.c                   |   4 +-
 src/util/virstoragefile.h                   |   2 +
 tests/storagebackendsheepdogtest.c          |  79 +++++++++-------
 tests/storagevolxml2xmlin/vol-sheepdog.xml  |   1 +
 tests/storagevolxml2xmlout/vol-sheepdog.xml |   1 +
 8 files changed, 141 insertions(+), 92 deletions(-)

diff --git a/docs/schemas/storagevol.rng b/docs/schemas/storagevol.rng
index 7450547..068993f 100644
--- a/docs/schemas/storagevol.rng
+++ b/docs/schemas/storagevol.rng
@@ -55,6 +55,9 @@
         <element name='allocation'>
           <ref name='scaledInteger'/>
         </element>
+        <element name='redundancy'>
+          <ref name='string'/>
+        </element>
       </optional>
     </interleave>
   </define>
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index 9b8abea..d37c93a 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -1345,6 +1345,8 @@ virStorageVolDefParseXML(virStoragePoolDefPtr pool,
         ret->target.allocation = ret->target.capacity;
     }
 
+    ret->target.redundancy = virXPathString("string(./redundancy)", ctxt);
+
     ret->target.path = virXPathString("string(./target/path)", ctxt);
     if (options->formatFromString) {
         char *format = virXPathString("string(./target/format/@type)", ctxt);
diff --git a/src/storage/storage_backend_sheepdog.c b/src/storage/storage_backend_sheepdog.c
index 1200813..b84a497 100644
--- a/src/storage/storage_backend_sheepdog.c
+++ b/src/storage/storage_backend_sheepdog.c
@@ -51,43 +51,51 @@ virStorageBackendSheepdogParseNodeInfo(virStoragePoolDefPtr pool,
      * node id/total, size, used, use%, [total vdi size]
      *
      * example output:
-     * 0 15245667872 117571104 0%
-     * Total 15245667872 117571104 0% 20972341
+     * 0 425814278144 4871131136 420943147008 1%
+     * Total 2671562256384 32160083968 2639402172416 1% 75161927680
      */
-
-    const char *p, *next;
+    char **lines = NULL;
+    char **cells = NULL;
+    size_t i;
+    int ret = -1;
 
     pool->allocation = pool->capacity = pool->available = 0;
 
-    p = output;
-    do {
-        char *end;
+    lines = virStringSplit(output, "\n", 0);
+    if (lines == NULL)
+        goto cleanup;
 
-        if ((next = strchr(p, '\n')))
-            ++next;
-        else
-            break;
+    for (i = 0; lines[i]; i++) {
+        char *line = lines[i];
+        if (line == NULL)
+            goto cleanup;
 
-        if (!STRPREFIX(p, "Total "))
+        if (!STRPREFIX(line, "Total "))
             continue;
 
-        p = p + 6;
+        virStringStripControlChars(line);
+        if ((cells = virStringSplit(line, " ", 0)) == NULL)
+            continue;
 
-        if (virStrToLong_ull(p, &end, 10, &pool->capacity) < 0)
-            break;
+        if (virStringListLength(cells) < 3) {
+            goto cleanup;
+        }
 
-        if ((p = end + 1) > next)
-            break;
+        if (virStrToLong_ull(cells[1], NULL, 10, &pool->capacity) < 0)
+            goto cleanup;
 
-        if (virStrToLong_ull(p, &end, 10, &pool->allocation) < 0)
-            break;
+        if (virStrToLong_ull(cells[2], NULL, 10, &pool->allocation) < 0)
+            goto cleanup;
 
         pool->available = pool->capacity - pool->allocation;
-        return 0;
-
-    } while ((p = next));
+        break;
+    }
+    ret = 0;
 
-    return -1;
+ cleanup:
+    virStringFreeList(lines);
+    virStringFreeList(cells);
+    return ret;
 }
 
 void
@@ -275,6 +283,10 @@ virStorageBackendSheepdogBuildVol(virConnectPtr conn ATTRIBUTE_UNUSED,
 
     cmd = virCommandNewArgList(SHEEPDOGCLI, "vdi", "create", vol->name, NULL);
     virCommandAddArgFormat(cmd, "%llu", vol->target.capacity);
+
+    if(NULL != vol->target.redundancy)
+        virCommandAddArgFormat(cmd, "-c %s", vol->target.redundancy);
+
     virStorageBackendSheepdogAddHostArg(cmd, pool);
     if (virCommandRun(cmd, NULL) < 0)
         goto cleanup;
@@ -291,60 +303,77 @@ virStorageBackendSheepdogParseVdiList(virStorageVolDefPtr vol,
                                       char *output)
 {
     /* fields:
-     * current/clone/snapshot, name, id, size, used, shared, creation time, vdi id, [tag]
+     * current/clone/snapshot, name, id, size, used, shared, creation time, vdi id, redundancy, [tag], size shift
      *
      * example output:
-     * s test 1 10 0 0 1336556634 7c2b25
-     * s test 2 10 0 0 1336557203 7c2b26
-     * = test 3 10 0 0 1336557216 7c2b27
+     * s test 1 10 0 0 1336556634 7c2b25 1 tt 22
+     * s test 2 10 0 0 1336557203 7c2b26 2 zz 22
+     * = 39865 0 21474836480 247463936 1337982976 1447516646 47d187 2  22
+     * = test 3 10 0 0 1336557216 7c2b27 3 xx 22
      */
-
-    int id;
-    const char *p, *next;
+    char **lines = NULL;
+    char **cells = NULL;
+    size_t i;
+    int ret = -1;
 
     vol->target.allocation = vol->target.capacity = 0;
+    vol->target.redundancy = NULL;
 
-    p = output;
-    do {
-        char *end;
+    lines = virStringSplit(output, "\n", 0);
+    if (lines == NULL)
+        goto cleanup;
 
-        if ((next = strchr(p, '\n')))
-            ++next;
+    for (i = 0; lines[i]; i++) {
+        char *line = lines[i];
+        if (line == NULL)
+            break;
 
-        /* ignore snapshots */
-        if (*p != '=')
+        if (!STRPREFIX(line, "= "))
             continue;
 
-        /* skip space */
-        if (p + 2 < next)
-            p += 2;
+        /* skip = and space */
+        if (*(line + 2) != '\0')
+            line += 2;
         else
-            return -1;
+            continue;
 
         /* skip name */
-        while (*p != '\0' && *p != ' ') {
-            if (*p == '\\')
-                ++p;
-            ++p;
+        while (*line != '\0' && *line != ' ') {
+            if (*line == '\\')
+                ++line;
+            ++line;
         }
 
-        if (virStrToLong_i(p, &end, 10, &id) < 0)
-            return -1;
+        /* skip space */
+        if (*(line + 1) != '\0')
+            line += 1;
+        else
+            continue;
 
-        p = end + 1;
+        virStringStripControlChars(line);
+        if ((cells = virStringSplit(line, " ", 0)) == NULL)
+            continue;
 
-        if (virStrToLong_ull(p, &end, 10, &vol->target.capacity) < 0)
-            return -1;
+        if (virStringListLength(cells) < 5)
+            continue;
 
-        p = end + 1;
+        if ((ret = virStrToLong_ull(cells[1], NULL, 10, &vol->target.capacity)) < 0)
+            goto cleanup;
 
-        if (virStrToLong_ull(p, &end, 10, &vol->target.allocation) < 0)
-            return -1;
+        if ((ret = virStrToLong_ull(cells[2], NULL, 10, &vol->target.allocation)) < 0)
+            goto cleanup;
 
-        return 0;
-    } while ((p = next));
+        if ((ret = VIR_STRDUP(vol->target.redundancy, cells[6])) < 0)
+            goto cleanup;
 
-    return -1;
+        break;
+    }
+    ret = 0;
+
+ cleanup:
+    virStringFreeList(lines);
+    virStringFreeList(cells);
+    return ret;
 }
 
 static int
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 2aa1d90..9cdc90d 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -1846,7 +1846,8 @@ virStorageSourceCopy(const virStorageSource *src,
         VIR_STRDUP(ret->backingStoreRaw, src->backingStoreRaw) < 0 ||
         VIR_STRDUP(ret->snapshot, src->snapshot) < 0 ||
         VIR_STRDUP(ret->configFile, src->configFile) < 0 ||
-        VIR_STRDUP(ret->compat, src->compat) < 0)
+        VIR_STRDUP(ret->compat, src->compat) < 0 ||
+        VIR_STRDUP(ret->redundancy, src->redundancy) < 0)
         goto error;
 
     if (src->nhosts) {
@@ -2040,6 +2041,7 @@ virStorageSourceClear(virStorageSourcePtr def)
     VIR_FREE(def->volume);
     VIR_FREE(def->snapshot);
     VIR_FREE(def->configFile);
+    VIR_FREE(def->redundancy);
     virStorageSourcePoolDefFree(def->srcpool);
     VIR_FREE(def->driverName);
     virBitmapFree(def->features);
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index b98fe25..c37cfc2 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -282,6 +282,8 @@ struct _virStorageSource {
     /* Name of the child backing store recorded in metadata of the
      * current file.  */
     char *backingStoreRaw;
+    /* redundancy level, may be used by sheepdog or ceph */
+    char *redundancy;
 };
 
 
diff --git a/tests/storagebackendsheepdogtest.c b/tests/storagebackendsheepdogtest.c
index 2b0f4db..1b32b7d 100644
--- a/tests/storagebackendsheepdogtest.c
+++ b/tests/storagebackendsheepdogtest.c
@@ -42,15 +42,23 @@ typedef struct {
     int expected_return;
     uint64_t expected_capacity;
     uint64_t expected_allocation;
-} collie_test;
+} collie_test1;
+
+typedef struct {
+    const char *output;
+    int expected_return;
+    uint64_t expected_capacity;
+    uint64_t expected_allocation;
+    const char *expected_redundancy;
+} collie_test2;
 
 struct testNodeInfoParserData {
-    collie_test data;
+    collie_test1 data;
     const char *poolxml;
 };
 
 struct testVDIListParserData {
-    collie_test data;
+    collie_test2 data;
     const char *poolxml;
     const char *volxml;
 };
@@ -60,7 +68,7 @@ static int
 test_node_info_parser(const void *opaque)
 {
     const struct testNodeInfoParserData *data = opaque;
-    collie_test test = data->data;
+    collie_test1 test = data->data;
     int ret = -1;
     char *output = NULL;
     virStoragePoolDefPtr pool = NULL;
@@ -94,7 +102,7 @@ static int
 test_vdi_list_parser(const void *opaque)
 {
     const struct testVDIListParserData *data = opaque;
-    collie_test test = data->data;
+    collie_test2 test = data->data;
     int ret = -1;
     char *output = NULL;
     virStoragePoolDefPtr pool = NULL;
@@ -119,7 +127,8 @@ test_vdi_list_parser(const void *opaque)
     }
 
     if (vol->target.capacity == test.expected_capacity &&
-        vol->target.allocation == test.expected_allocation)
+        vol->target.allocation == test.expected_allocation &&
+	!strcmp(vol->target.redundancy, test.expected_redundancy))
         ret = 0;
 
  cleanup:
@@ -137,45 +146,47 @@ mymain(void)
     char *poolxml = NULL;
     char *volxml = NULL;
 
-    collie_test node_info_tests[] = {
+    collie_test1 node_info_tests[] = {
         {"", -1, 0, 0},
-        {"Total 15245667872 117571104 0% 20972341\n", 0, 15245667872, 117571104},
+        {"Total 2671562256384 32160083968 2639402172416 1% 75161927680\n", 0, 2671562256384, 32160083968},
+        {"Total 15245667872 117571104 20972341 0%\n", 0, 15245667872, 117571104},
         {"To", -1, 0, 0},
         {"asdf\nasdf", -1, 0, 0},
         {"Total ", -1, 0, 0},
         {"Total 1", -1, 0, 0},
         {"Total 1\n", -1, 0, 0},
         {"Total 1 ", -1, 0, 0},
-        {"Total 1 2", -1, 0, 0},
-        {"Total 1 2 ", -1, 0, 0},
+        {"Total 1 2 ", 0, 1, 2},
         {"Total 1 2\n", 0, 1, 2},
         {"Total 1 2 \n", 0, 1, 2},
+        {"Total 1 2 \n", 0, 1, 2},
         {"Total a 2 \n", -1, 0, 0},
         {"Total 1 b \n", -1, 0, 0},
         {"Total a b \n", -1, 0, 0},
         {"stuff\nTotal 1 2 \n", 0, 1, 2},
-        {"0 1 2 3\nTotal 1 2 \n", 0, 1, 2},
+        {"0 1 2\nTotal 1 2 \n", 0, 1, 2},
         {NULL, 0, 0, 0}
     };
 
-    collie_test vdi_list_tests[] = {
-        {"", -1, 0, 0},
-        {"= test 3 10 20 0 1336557216 7c2b27\n", 0, 10, 20},
-        {"= test\\ with\\ spaces 3 10 20 0 1336557216 7c2b27\n", 0, 10, 20},
-        {"= backslashattheend\\\\ 3 10 20 0 1336557216 7c2b27\n", 0, 10, 20},
-        {"s test 1 10 20 0 1336556634 7c2b25\n= test 3 50 60 0 1336557216 7c2b27\n", 0, 50, 60},
-        {"=", -1, 0, 0},
-        {"= test", -1, 0, 0},
-        {"= test ", -1, 0, 0},
-        {"= test 1", -1, 0, 0},
-        {"= test 1 ", -1, 0, 0},
-        {"= test 1 2", -1, 0, 0},
-        {"= test 1 2 ", -1, 0, 0},
-        {"= test 1 2 3", -1, 0, 0},
-        {NULL, 0, 0, 0}
+    collie_test2 vdi_list_tests[] = {
+        {"", -1, 0, 0,NULL},
+        {"= test 3 10 20 1 1336557216 7c2b27 1 22\n", 0, 10, 20, "1"},
+        {"= test\\ with\\ spaces 3 10 20 0 1336557216 7c2b27 3:4 22\n", 0, 10, 20, "3:4"},
+        {"= backslashattheend\\\\ 3 10 20 0 1336557216 7c2b27 1 22\n", 0, 10, 20, "1"},
+        {"s test 1 10 20 0 1336556634 7c2b25 2\n= test 3 50 60 0 1336557216 7c2b27 2:3 22\n", 0, 50, 60, "2:3"},
+        {"=", -1, 0, 0, NULL},
+        {"= test", -1, 0, 0, NULL},
+        {"= test ", -1, 0, 0,NULL},
+        {"= test 1", -1, 0, 0,NULL},
+        {"= test 1 ", -1, 0, 0,NULL},
+        {"= test 1 2", -1, 0, 0,NULL},
+        {"= test 1 2 ", -1, 0, 0,NULL},
+        {"= test 1 2 3", -1, 0, 0,NULL},
+        {NULL, 0, 0, 0,NULL}
     };
 
-    collie_test *test = node_info_tests;
+    collie_test1 *test1 = node_info_tests;
+    collie_test2 *test2 = vdi_list_tests;
 
     if (virAsprintf(&poolxml, "%s/storagepoolxml2xmlin/pool-sheepdog.xml",
                     abs_srcdir) < 0)
@@ -196,9 +207,9 @@ mymain(void)
             ret = -1;                                                   \
     } while (0)
 
-    while (test->output != NULL) {
-        DO_TEST_NODE(*test);
-        ++test;
+    while (test1->output != NULL) {
+        DO_TEST_NODE(*test1);
+        ++test1;
     }
 
 
@@ -214,11 +225,9 @@ mymain(void)
             ret = -1;                                                   \
     } while (0)
 
-    test = vdi_list_tests;
-
-    while (test->output != NULL) {
-        DO_TEST_VDI(*test);
-        ++test;
+    while (test2->output != NULL) {
+        DO_TEST_VDI(*test2);
+        ++test2;
     }
 
  cleanup:
diff --git a/tests/storagevolxml2xmlin/vol-sheepdog.xml b/tests/storagevolxml2xmlin/vol-sheepdog.xml
index d6e920b..f88e6db 100644
--- a/tests/storagevolxml2xmlin/vol-sheepdog.xml
+++ b/tests/storagevolxml2xmlin/vol-sheepdog.xml
@@ -4,6 +4,7 @@
   </source>
   <capacity unit='bytes'>1024</capacity>
   <allocation unit='bytes'>0</allocation>
+  <redundancy unit='string'>3</redundancy>
   <target>
     <path>sheepdog:test2</path>
   </target>
diff --git a/tests/storagevolxml2xmlout/vol-sheepdog.xml b/tests/storagevolxml2xmlout/vol-sheepdog.xml
index e1d6a9e..207f5fb 100644
--- a/tests/storagevolxml2xmlout/vol-sheepdog.xml
+++ b/tests/storagevolxml2xmlout/vol-sheepdog.xml
@@ -4,6 +4,7 @@
   </source>
   <capacity unit='bytes'>1024</capacity>
   <allocation unit='bytes'>0</allocation>
+  <redundancy unit='string'>3</redundancy>
   <target>
     <path>sheepdog:test2</path>
     <format type='unknown'/>
-- 
2.5.0




More information about the libvir-list mailing list