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 | 72 +++++++++++++++++++++++++++++++++++---------- 2 files changed, 62 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 b1630f8..b3e2683 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -10873,6 +10873,44 @@ 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) { + if (!compat) + virBufferAddLit(&buf, "compat=1.1,"); + for (i = 0; i < VIR_STORAGE_FILE_FEATURE_LAST; i++) { + ignore_value(virBitmapGetBit(features, i, &b)); + if (b) + virBufferAsprintf(&buf, "%s,", + virStorageFileFeatureTypeToString(i)); + } + } + + virBufferTrim(&buf, ",", -1); + + if (virBufferError(&buf)) { + virBufferFreeAndReset(&buf); + virReportOOMError(); + return -1; + } + + *opts = virBufferContentAndReset(&buf); + return 0; +} + /* The domain is expected to be locked and inactive. */ static int qemuDomainSnapshotCreateInactiveExternal(virQEMUDriverPtr driver, @@ -10888,6 +10926,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; @@ -10918,23 +10958,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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list