[libvirt] [PATCH libvirt] storage: learn to create qcow2 with preallocation

Marc-André Lureau marcandre.lureau at gmail.com
Wed May 16 11:21:33 UTC 2012


Use preallocation mode specified in volume XML format when running
qemu-img.
---
 src/storage/storage_backend.c |   70 +++++++++++++++++++++++++++++++++++------
 1 file changed, 60 insertions(+), 10 deletions(-)

diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index caac2f8..523b6e2 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -645,6 +645,38 @@ cleanup:
     return ret;
 }
 
+static char *
+virStorageQemuImgOptionsStr(virStorageVolDefPtr vol)
+{
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    bool do_encryption = (vol->target.encryption != NULL);
+    const char *backingType = vol->backingStore.path ?
+        virStorageFileFormatTypeToString(vol->backingStore.format) : NULL;
+    bool comma = false;
+    const char *preallocation = vol->preallocation != VIR_STORAGE_PREALLOCATION_NONE ?
+        virStoragePreallocationModeTypeToString(vol->preallocation) : NULL;
+
+    if (backingType) {
+        virBufferAddLit(&buf, "backing_fmt=");
+        virBufferAdd(&buf, backingType, -1);
+        comma = true;
+    }
+
+    if (do_encryption) {
+        virBufferAdd(&buf, comma ? "," : "", -1);
+        virBufferAddLit(&buf, "encryption=on");
+        comma = true;
+    }
+
+    if (preallocation) {
+        virBufferAdd(&buf, comma ? "," : "", -1);
+        virBufferAddLit(&buf, "preallocation=");
+        virBufferAdd(&buf, preallocation, -1);
+        comma = true;
+    }
+
+    return virBufferContentAndReset(&buf);
+}
 
 static int
 virStorageBackendCreateQemuImg(virConnectPtr conn,
@@ -658,7 +690,9 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
     int imgformat = -1;
     virCommandPtr cmd = NULL;
     bool do_encryption = (vol->target.encryption != NULL);
+    bool with_preallocation = (vol->preallocation != VIR_STORAGE_PREALLOCATION_NONE);
     unsigned long long int size_arg;
+    char *options;
 
     virCheckFlags(0, -1);
 
@@ -689,6 +723,12 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
         return -1;
     }
 
+    if (vol->target.format != VIR_STORAGE_FILE_QCOW2 && with_preallocation) {
+        virStorageReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                              _("Preallocation is only available with qcow2"));
+        return -1;
+    }
+
     if (vol->backingStore.path) {
         int accessRetCode = -1;
         char *absolutePath = NULL;
@@ -781,16 +821,22 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
     if (imgformat < 0)
         goto cleanup;
 
+    if (imgformat != QEMU_IMG_BACKING_FORMAT_OPTIONS && with_preallocation)
+        VIR_INFO("Preallocation not supported with this version of qemu-img");
+
     cmd = virCommandNew(create_tool);
 
     if (inputvol) {
         virCommandAddArgList(cmd, "convert", "-f", inputType, "-O", type,
                              inputPath, vol->target.path, NULL);
 
-        if (do_encryption) {
-            if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS) {
-                virCommandAddArgList(cmd, "-o", "encryption=on", NULL);
-            } else {
+        if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS) {
+            virCommandAddArg(cmd, "-o");
+            options = virStorageQemuImgOptionsStr(vol);
+            virCommandAddArg(cmd, options);
+            VIR_FREE(options);
+        } else {
+            if (do_encryption) {
                 virCommandAddArg(cmd, "-e");
             }
         }
@@ -811,10 +857,11 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
 
         case QEMU_IMG_BACKING_FORMAT_OPTIONS:
             virCommandAddArg(cmd, "-o");
-            virCommandAddArgFormat(cmd, "backing_fmt=%s%s", backingType,
-                                   do_encryption ? ",encryption=on" : "");
+            options = virStorageQemuImgOptionsStr(vol);
+            virCommandAddArg(cmd, options);
             virCommandAddArg(cmd, vol->target.path);
             virCommandAddArgFormat(cmd, "%lluK", size_arg);
+            VIR_FREE(options);
             break;
 
         default:
@@ -831,10 +878,13 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
                              vol->target.path, NULL);
         virCommandAddArgFormat(cmd, "%lluK", size_arg);
 
-        if (do_encryption) {
-            if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS) {
-                virCommandAddArgList(cmd, "-o", "encryption=on", NULL);
-            } else {
+        if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS) {
+            virCommandAddArg(cmd, "-o");
+            options = virStorageQemuImgOptionsStr(vol);
+            virCommandAddArg(cmd, options);
+            VIR_FREE(options);
+        } else {
+            if (do_encryption) {
                 virCommandAddArg(cmd, "-e");
             }
         }
-- 
1.7.10.1




More information about the libvir-list mailing list