[libvirt] [PATCH 9/9] Allow creating volumes with a backing store but no capacity

Ján Tomko jtomko at redhat.com
Thu Feb 19 14:59:17 UTC 2015


The tool creating the image can get the capacity from the backing
storage. Just refresh the volume afterwards.

https://bugzilla.redhat.com/show_bug.cgi?id=958510
---
 src/storage/storage_backend.c                      |  6 ++++++
 src/storage/storage_backend_fs.c                   |  7 +++++++
 src/storage/storage_backend_rbd.c                  |  6 ++++++
 src/storage/storage_backend_sheepdog.c             |  6 ++++++
 src/storage/storage_driver.c                       | 14 ++++++++++++-
 tests/storagevolxml2argvdata/qcow2-nocapacity.argv |  5 +++++
 tests/storagevolxml2argvtest.c                     | 20 +++++++++++--------
 .../vol-qcow2-nocapacity-backing.xml               | 23 ++++++++++++++++++++++
 8 files changed, 78 insertions(+), 9 deletions(-)
 create mode 100644 tests/storagevolxml2argvdata/qcow2-nocapacity.argv
 create mode 100644 tests/storagevolxml2xmlin/vol-qcow2-nocapacity-backing.xml

diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index ea5cabe..a4e75f5a5 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -487,6 +487,12 @@ virStorageBackendCreateRaw(virConnectPtr conn ATTRIBUTE_UNUSED,
         goto cleanup;
     }
 
+    if (vol->target.backingStore) {
+        virReportError(VIR_ERR_NO_SUPPORT, "%s",
+                       _("backing storage not supported for raw volumes"));
+        goto cleanup;
+    }
+
     if (flags & VIR_STORAGE_VOL_CREATE_REFLINK)
         reflink_copy = true;
 
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index 77d894c..35385db 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -1037,6 +1037,13 @@ static int createFileDir(virConnectPtr conn ATTRIBUTE_UNUSED,
         return -1;
     }
 
+    if (vol->target.backingStore) {
+        virReportError(VIR_ERR_NO_SUPPORT, "%s",
+                       _("backing storage not supported for directories volumes"));
+        return -1;
+    }
+
+
     if ((err = virDirCreate(vol->target.path, vol->target.perms->mode,
                             vol->target.perms->uid,
                             vol->target.perms->gid,
diff --git a/src/storage/storage_backend_rbd.c b/src/storage/storage_backend_rbd.c
index 57182de..ae4bcb3 100644
--- a/src/storage/storage_backend_rbd.c
+++ b/src/storage/storage_backend_rbd.c
@@ -509,6 +509,12 @@ virStorageBackendRBDBuildVol(virConnectPtr conn,
 
     virCheckFlags(0, -1);
 
+    if (!vol->target.capacity) {
+        virReportError(VIR_ERR_NO_SUPPORT, "%s",
+                       _("volume capacity required for this storage pool"));
+        goto cleanup;
+    }
+
     if (virStorageBackendRBDOpenRADOSConn(&ptr, conn, &pool->def->source) < 0)
         goto cleanup;
 
diff --git a/src/storage/storage_backend_sheepdog.c b/src/storage/storage_backend_sheepdog.c
index 9419859..f389d9b 100644
--- a/src/storage/storage_backend_sheepdog.c
+++ b/src/storage/storage_backend_sheepdog.c
@@ -266,6 +266,12 @@ virStorageBackendSheepdogBuildVol(virConnectPtr conn,
 
     virCheckFlags(0, -1);
 
+    if (!vol->target.capacity) {
+        virReportError(VIR_ERR_NO_SUPPORT, "%s",
+                       _("volume capacity required for this pool"));
+        goto cleanup;
+    }
+
     virCommandPtr cmd = virCommandNewArgList(COLLIE, "vdi", "create", vol->name, NULL);
     virCommandAddArgFormat(cmd, "%llu", vol->target.capacity);
     virStorageBackendSheepdogAddHostArg(cmd, pool);
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index 409b486..e8af90f 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -1649,10 +1649,18 @@ storageVolCreateXML(virStoragePoolPtr obj,
     if ((backend = virStorageBackendForType(pool->def->type)) == NULL)
         goto cleanup;
 
-    voldef = virStorageVolDefParseString(pool->def, xmldesc, 0);
+    voldef = virStorageVolDefParseString(pool->def, xmldesc,
+                                         VIR_VOL_XML_PARSE_OPT_CAPACITY);
     if (voldef == NULL)
         goto cleanup;
 
+    if (!voldef->target.capacity && !backend->buildVol) {
+        virReportError(VIR_ERR_NO_SUPPORT,
+                       "%s", _("volume capacity required for this "
+                               "storage pool"));
+        goto cleanup;
+    }
+
     if (virStorageVolCreateXMLEnsureACL(obj->conn, pool->def, voldef) < 0)
         goto cleanup;
 
@@ -1725,6 +1733,10 @@ storageVolCreateXML(virStoragePoolPtr obj,
 
     }
 
+    if (backend->refreshVol &&
+        backend->refreshVol(obj->conn, pool, voldef) < 0)
+        goto cleanup;
+
     /* Update pool metadata */
     pool->def->allocation += buildvoldef->target.allocation;
     pool->def->available -= buildvoldef->target.allocation;
diff --git a/tests/storagevolxml2argvdata/qcow2-nocapacity.argv b/tests/storagevolxml2argvdata/qcow2-nocapacity.argv
new file mode 100644
index 0000000..1198cba
--- /dev/null
+++ b/tests/storagevolxml2argvdata/qcow2-nocapacity.argv
@@ -0,0 +1,5 @@
+qemu-img create \
+-f qcow2 \
+-b /dev/null \
+-o backing_fmt=raw,encryption=on \
+/var/lib/libvirt/images/OtherDemo.img
diff --git a/tests/storagevolxml2argvtest.c b/tests/storagevolxml2argvtest.c
index 52bb856..696659c 100644
--- a/tests/storagevolxml2argvtest.c
+++ b/tests/storagevolxml2argvtest.c
@@ -40,7 +40,8 @@ testCompareXMLToArgvFiles(bool shouldFail,
                           const char *inputvolxml,
                           const char *cmdline,
                           unsigned int flags,
-                          int imgformat)
+                          int imgformat,
+                          unsigned long parse_flags)
 {
     char *volXmlData = NULL;
     char *poolXmlData = NULL;
@@ -49,7 +50,6 @@ testCompareXMLToArgvFiles(bool shouldFail,
     char *expectedCmdline = NULL;
     char *actualCmdline = NULL;
     int ret = -1;
-    unsigned long parse_flags = 0;
 
     int len;
 
@@ -149,6 +149,7 @@ struct testInfo {
     const char *cmdline;
     unsigned int flags;
     int imgformat;
+    unsigned long parseflags;
 };
 
 static int
@@ -183,7 +184,7 @@ testCompareXMLToArgvHelper(const void *data)
     result = testCompareXMLToArgvFiles(info->shouldFail, poolxml, volxml,
                                        inputpoolxml, inputvolxml,
                                        cmdline, info->flags,
-                                       info->imgformat);
+                                       info->imgformat, info->parseflags);
 
  cleanup:
     VIR_FREE(poolxml);
@@ -210,11 +211,11 @@ mymain(void)
     int ret = 0;
     unsigned int flags = VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA;
 
-#define DO_TEST_FULL(shouldFail, pool, vol, inputpool, inputvol, cmdline,    \
-                     flags, imgformat)                                       \
+#define DO_TEST_FULL(shouldFail, parseflags, pool, vol, inputpool, inputvol, \
+                     cmdline, flags, imgformat)                              \
     do {                                                                     \
         struct testInfo info = { shouldFail, pool, vol, inputpool, inputvol, \
-                                 cmdline, flags, imgformat };                \
+                                 cmdline, flags, imgformat, parseflags };    \
         if (virtTestRun("Storage Vol XML-2-argv " cmdline,                   \
                         testCompareXMLToArgvHelper, &info) < 0)              \
             ret = -1;                                                        \
@@ -222,10 +223,10 @@ mymain(void)
     while (0);
 
 #define DO_TEST(pool, ...)                                                 \
-    DO_TEST_FULL(false, pool, __VA_ARGS__)
+    DO_TEST_FULL(false, 0, pool, __VA_ARGS__)
 
 #define DO_TEST_FAIL(pool, ...)                                            \
-    DO_TEST_FULL(true, pool, __VA_ARGS__)
+    DO_TEST_FULL(true, 0, pool, __VA_ARGS__)
 
     DO_TEST("pool-dir", "vol-qcow2",
             NULL, NULL,
@@ -312,6 +313,9 @@ mymain(void)
     DO_TEST("pool-dir", "vol-qcow2-nocapacity",
             "pool-dir", "vol-file",
             "qcow2-nocapacity-convert-prealloc", flags, FMT_OPTIONS);
+    DO_TEST_FULL(false, VIR_VOL_XML_PARSE_OPT_CAPACITY,
+                 "pool-dir", "vol-qcow2-nocapacity-backing", NULL, NULL,
+                 "qcow2-nocapacity", 0, FMT_OPTIONS);
 
     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }
diff --git a/tests/storagevolxml2xmlin/vol-qcow2-nocapacity-backing.xml b/tests/storagevolxml2xmlin/vol-qcow2-nocapacity-backing.xml
new file mode 100644
index 0000000..f8e439b
--- /dev/null
+++ b/tests/storagevolxml2xmlin/vol-qcow2-nocapacity-backing.xml
@@ -0,0 +1,23 @@
+<volume>
+  <name>OtherDemo.img</name>
+  <key>/var/lib/libvirt/images/OtherDemo.img</key>
+  <source>
+  </source>
+  <target>
+    <path>/var/lib/libvirt/images/OtherDemo.img</path>
+    <format type='qcow2'/>
+    <permissions>
+      <mode>0644</mode>
+      <owner>0</owner>
+      <group>0</group>
+      <label>unconfined_u:object_r:virt_image_t:s0</label>
+    </permissions>
+    <encryption format='qcow'>
+      <secret type='passphrase' uuid='e78d4b51-a2af-485f-b0f5-afca709a80f4'/>
+    </encryption>
+  </target>
+  <backingStore>
+    <path>/dev/null</path>
+    <format type='raw'/>
+  </backingStore>
+</volume>
-- 
2.0.5




More information about the libvir-list mailing list