QEMU uses the qcow2 driver for qcow3, which is why virStorageFileFormatToStringQemu is added. TODO: make snapshots work. --- src/libvirt_private.syms | 1 + src/qemu/qemu_command.c | 2 +- src/qemu/qemu_hotplug.c | 4 ++-- src/storage/storage_backend.c | 29 +++++++++++++++++++++++------ src/util/virstoragefile.c | 8 ++++++++ src/util/virstoragefile.h | 1 + 6 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 699cec6..9193342 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1165,6 +1165,7 @@ virStorageGenerateQcowPassphrase; # storage_file.h virStorageFileChainLookup; +virStorageFileFormatToStringQemu; virStorageFileFormatTypeFromString; virStorageFileFormatTypeToString; virStorageFileFreeMetadata; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 3e3b588..4c7451b 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -2417,7 +2417,7 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED, disk->type != VIR_DOMAIN_DISK_TYPE_DIR && qemuCapsGet(caps, QEMU_CAPS_DRIVE_FORMAT)) virBufferAsprintf(&opt, ",format=%s", - virStorageFileFormatTypeToString(disk->format)); + virStorageFileFormatToStringQemu(disk->format)); /* generate geometry command string */ if (disk->geometry.cylinders > 0 && diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 19172e1..305271b 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -109,9 +109,9 @@ int qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver, const char *format = NULL; if (disk->type != VIR_DOMAIN_DISK_TYPE_DIR) { if (disk->format > 0) - format = virStorageFileFormatTypeToString(disk->format); + format = virStorageFileFormatToStringQemu(disk->format); else if (origdisk->format > 0) - format = virStorageFileFormatTypeToString(origdisk->format); + format = virStorageFileFormatToStringQemu(origdisk->format); } ret = qemuMonitorChangeMedia(priv->mon, driveAlias, diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c index a7e9493..192c085 100644 --- a/src/storage/storage_backend.c +++ b/src/storage/storage_backend.c @@ -670,22 +670,23 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, unsigned long long int size_arg; bool preallocate = false; char *options; + bool tmp; virBuffer buf = VIR_BUFFER_INITIALIZER; virCheckFlags(VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA, -1); preallocate = !!(flags & VIR_STORAGE_VOL_CREATE_PREALLOC_METADATA); - const char *type = virStorageFileFormatTypeToString(vol->target.format); + const char *type = virStorageFileFormatToStringQemu(vol->target.format); const char *backingType = vol->backingStore.path ? - virStorageFileFormatTypeToString(vol->backingStore.format) : NULL; + virStorageFileFormatToStringQemu(vol->backingStore.format) : NULL; const char *inputBackingPath = (inputvol ? inputvol->backingStore.path : NULL); const char *inputPath = inputvol ? inputvol->target.path : NULL; /* Treat input block devices as 'raw' format */ const char *inputType = inputPath ? - virStorageFileFormatTypeToString(inputvol->type == VIR_STORAGE_VOL_BLOCK ? + virStorageFileFormatToStringQemu(inputvol->type == VIR_STORAGE_VOL_BLOCK ? VIR_STORAGE_FILE_RAW : inputvol->target.format) : NULL; @@ -702,9 +703,11 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, inputvol->target.format); return -1; } - if (preallocate && vol->target.format != VIR_STORAGE_FILE_QCOW2) { + if (preallocate && vol->target.format != VIR_STORAGE_FILE_QCOW2 + && vol->target.format != VIR_STORAGE_FILE_QCOW3) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("metadata preallocation only available with qcow2")); + _("metadata preallocation only available with qcow2" + " or qcow3")); return -1; } @@ -763,7 +766,8 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, virStorageEncryptionPtr enc; if (vol->target.format != VIR_STORAGE_FILE_QCOW && - vol->target.format != VIR_STORAGE_FILE_QCOW2) { + vol->target.format != VIR_STORAGE_FILE_QCOW2 && + vol->target.format != VIR_STORAGE_FILE_QCOW3) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("qcow volume encryption unsupported with " "volume format %s"), type); @@ -831,6 +835,19 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, else if (preallocate) virBufferAddLit(&buf, ",preallocation=metadata"); + if (vol->target.format == VIR_STORAGE_FILE_QCOW3) { + virBufferAddLit(&buf, ",compat=1.1"); + if (virBitmapGetBit(vol->target.features.compatible, + VIR_STORAGE_FILE_QCOW3_COMP_LAZY_REFCOUNT, + &tmp) < 0) { + virReportOOMError(); + virBufferFreeAndReset(&buf); + goto cleanup; + } + if (tmp) + virBufferAddLit(&buf, ",lazy_refcounts=on"); + } + if (virBufferError(&buf) > 0) { virReportOOMError(); goto cleanup; diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index e9ecff1..75518ab 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -1493,3 +1493,11 @@ error: *meta = NULL; return NULL; } + +const char *virStorageFileFormatToStringQemu(enum virStorageFileFormat format) +{ + if (format == VIR_STORAGE_FILE_QCOW3) + return virStorageFileFormatTypeToString(VIR_STORAGE_FILE_QCOW2); + else + return virStorageFileFormatTypeToString(format); +} diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h index 3249e8f..8a010fa 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -131,5 +131,6 @@ int virStorageFileGetLVMKey(const char *path, char **key); int virStorageFileGetSCSIKey(const char *path, char **key); +const char *virStorageFileFormatToStringQemu(enum virStorageFileFormat format); #endif /* __VIR_STORAGE_FILE_H__ */ -- 1.7.8.6 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list