[libvirt] [PATCH v5 5/5] qemu: add qcow2 extension support to inactive external snapshots

Ján Tomko jtomko at redhat.com
Wed Jun 19 15:24:14 UTC 2013


For live external snapshots, the image creation is done by QEMU
and we can't pass the needed options.
---
 docs/formatsnapshot.html.in |  5 +++
 src/qemu/qemu_driver.c      | 88 +++++++++++++++++++++++++++++++++++++--------
 2 files changed, 78 insertions(+), 15 deletions(-)

diff --git a/docs/formatsnapshot.html.in b/docs/formatsnapshot.html.in
index 76689cb..e160455 100644
--- a/docs/formatsnapshot.html.in
+++ b/docs/formatsnapshot.html.in
@@ -170,6 +170,11 @@
             snapshots, the original file name becomes the read-only
             snapshot, and the new file name contains the read-write
             delta of all disk changes since the snapshot.
+
+            An optional <code>compat</code> and <code>features</code>
+            elements may be specified to control format-specific
+            features. So far only for qcow2 and only for non-live
+            external snapshots.
           </dd>
         </dl>
       </dd>
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 9b738e0..58e0f51 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -11011,6 +11011,60 @@ qemuDomainSnapshotCreateInactiveInternal(virQEMUDriverPtr driver,
     return qemuDomainSnapshotForEachQcow2(driver, vm, snap, "-c", false);
 }
 
+static int
+qemuDomainSnapshotCreateQemuImgOpts(char **opts,
+                                    const char *backing_file,
+                                    const char *backing_fmt,
+                                    const char *compat,
+                                    int format,
+                                    virBitmapPtr features)
+{
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    bool b;
+    int i;
+
+    virBufferEscapeString(&buf, "backing_file=%s,", backing_file);
+    virBufferEscapeString(&buf, "backing_fmt=%s,", backing_fmt);
+    virBufferEscapeString(&buf, "compat=%s,", compat);
+    if (features && format == VIR_STORAGE_FILE_QCOW2) {
+        for (i = 0; i < VIR_STORAGE_FILE_FEATURE_LAST; i++) {
+            ignore_value(virBitmapGetBit(features, i, &b));
+            if (b) {
+                switch (i) {
+                case VIR_STORAGE_FILE_FEATURE_LAZY_REFCOUNTS:
+                    if (STREQ(compat, "0.10")) {
+                        virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                                       _("Feature %s not supported with compat"
+                                         " level %s"),
+                                       virStorageFileFeatureTypeToString(i),
+                                       compat);
+                        goto error;
+                    }
+                    break;
+                case VIR_STORAGE_FILE_FEATURE_LAST:
+                    ;
+                }
+                virBufferAsprintf(&buf, "%s,",
+                                  virStorageFileFeatureTypeToString(i));
+            }
+        }
+    }
+
+    virBufferTrim(&buf, ",", -1);
+
+    if (virBufferError(&buf))
+        goto no_memory;
+
+    *opts = virBufferContentAndReset(&buf);
+    return 0;
+
+no_memory:
+    virReportOOMError();
+error:
+    virBufferFreeAndReset(&buf);
+    return -1;
+}
+
 /* The domain is expected to be locked and inactive. */
 static int
 qemuDomainSnapshotCreateInactiveExternal(virQEMUDriverPtr driver,
@@ -11026,6 +11080,8 @@ qemuDomainSnapshotCreateInactiveExternal(virQEMUDriverPtr driver,
     virBitmapPtr created = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     int ret = -1;
+    char *opts = NULL;
+    const char *backing_fmt = NULL;
 
     if (!(qemuImgPath = qemuFindQemuImgBinary(driver)))
         goto cleanup;
@@ -11056,23 +11112,25 @@ qemuDomainSnapshotCreateInactiveExternal(virQEMUDriverPtr driver,
                                          NULL)))
             goto cleanup;
 
-        if (defdisk->format > 0) {
-            /* adds cmd line arg: backing_file=/path/to/backing/file,backing_fmd=format */
-            virCommandAddArgFormat(cmd, "backing_file=%s,backing_fmt=%s",
-                                   defdisk->src,
-                                   virStorageFileFormatTypeToString(defdisk->format));
-        } else {
-            if (!cfg->allowDiskFormatProbing) {
-                virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-                               _("unknown image format of '%s' and "
-                                 "format probing is disabled"),
-                               defdisk->src);
-                goto cleanup;
-            }
 
-            /* adds cmd line arg: backing_file=/path/to/backing/file */
-            virCommandAddArgFormat(cmd, "backing_file=%s", defdisk->src);
+        if (defdisk->format > 0) {
+            backing_fmt = virStorageFileFormatTypeToString(defdisk->format);
+        } else if (!cfg->allowDiskFormatProbing) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("unknown image format of '%s' and "
+                             "format probing is disabled"),
+                           defdisk->src);
+            goto cleanup;
         }
+        if (qemuDomainSnapshotCreateQemuImgOpts(&opts, defdisk->src,
+                                                backing_fmt,
+                                                snapdisk->compat,
+                                                snapdisk->format,
+                                                snapdisk->features) < 0)
+            goto cleanup;
+
+        virCommandAddArg(cmd, opts);
+        VIR_FREE(opts);
 
         /* adds cmd line args: /path/to/target/file */
         virCommandAddArg(cmd, snapdisk->file);
-- 
1.8.1.5




More information about the libvir-list mailing list