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