QEMU_IMG_BACKING_FORMAT_NONE = 0,
QEMU_IMG_BACKING_FORMAT_FLAG,
QEMU_IMG_BACKING_FORMAT_OPTIONS,
+ QEMU_IMG_BACKING_FORMAT_OPTIONS_COMPAT,
};
+static bool
+virStorageBackendQemuImgSupportsCompat(const char *qemuimg)
+{
+ bool ret = false;
+ char *output;
+ virCommandPtr cmd = NULL;
+
+ cmd = virCommandNewArgList(qemuimg, "create", "-o", "?", "-f", "qcow2",
+ "/dev/null", NULL);
+
+ virCommandAddEnvString(cmd, "LC_ALL=C");
+ virCommandSetOutputBuffer(cmd, &output);
+
+ if (virCommandRun(cmd, NULL) < 0)
+ goto cleanup;
+
+ if (strstr(output, "\ncompat "))
+ ret = true;
+
+cleanup:
+ virCommandFree(cmd);
+ VIR_FREE(output);
+ return ret;
+}
+
static int
virStorageBackendQEMUImgBackingFormat(const char *qemuimg)
{
goto cleanup;
}
if (((tmp = strstr(start, "-F fmt")) && tmp < end) ||
- ((tmp = strstr(start, "-F backing_fmt")) && tmp < end))
+ ((tmp = strstr(start, "-F backing_fmt")) && tmp < end)) {
ret = QEMU_IMG_BACKING_FORMAT_FLAG;
- else if ((tmp = strstr(start, "[-o options]")) && tmp < end)
- ret = QEMU_IMG_BACKING_FORMAT_OPTIONS;
- else
+ } else if ((tmp = strstr(start, "[-o options]")) && tmp < end) {
+ if (virStorageBackendQemuImgSupportsCompat(qemuimg))
+ ret = QEMU_IMG_BACKING_FORMAT_OPTIONS_COMPAT;
+ else
+ ret = QEMU_IMG_BACKING_FORMAT_OPTIONS;
+ } else {
ret = QEMU_IMG_BACKING_FORMAT_NONE;
+ }
cleanup:
virCommandFree(cmd);
const char *backingType = NULL;
const char *inputPath = NULL;
const char *inputType = NULL;
+ const char *compat = vol->target.compat;
char *opts = NULL;
bool convert = false;
bool backing = false;
if (backing)
virCommandAddArgList(cmd, "-b", vol->backingStore.path, NULL);
- if (imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS) {
+ if (imgformat >= QEMU_IMG_BACKING_FORMAT_OPTIONS) {
+ if (vol->target.format == VIR_STORAGE_FILE_QCOW2 && !compat &&
+ imgformat == QEMU_IMG_BACKING_FORMAT_OPTIONS_COMPAT)
+ compat = "0.10";
+
if (virStorageBackendCreateQemuImgOpts(&opts,
backing ? backingType : NULL,
do_encryption, preallocate,
vol->target.format,
- vol->target.compat,
+ compat,
vol->target.features) < 0) {
virCommandFree(cmd);
return NULL;
--- /dev/null
+qemu-img create -f qcow2 -b /dev/null \
+-o backing_fmt=raw,encryption=on,compat=0.10 \
+/var/lib/libvirt/images/OtherDemo.img 5242880K
--- /dev/null
+qemu-img convert -f raw -O qcow2 \
+-o encryption=on,compat=0.10 \
+/dev/HostVG/Swap /var/lib/libvirt/images/OtherDemo.img
--- /dev/null
+qemu-img convert -f raw -O qcow2 \
+-o encryption=on,preallocation=metadata,compat=0.10 \
+/var/lib/libvirt/images/sparse.img /var/lib/libvirt/images/OtherDemo.img
--- /dev/null
+qemu-img create -f qcow2 \
+-o encryption=on,preallocation=metadata,compat=0.10 \
+/var/lib/libvirt/images/OtherDemo.img 5242880K
FMT_NONE = 0,
FMT_FLAG,
FMT_OPTIONS,
+ FMT_COMPAT,
};
"pool-dir", "vol-qcow2-nobacking",
"logical-from-qcow2", 0, FMT_OPTIONS);
+ DO_TEST("pool-dir", "vol-qcow2",
+ NULL, NULL,
+ "qcow2-compat", 0, FMT_COMPAT);
+ DO_TEST("pool-dir", "vol-qcow2-nobacking",
+ NULL, NULL,
+ "qcow2-nobacking-prealloc-compat", flags, FMT_COMPAT);
+ DO_TEST("pool-dir", "vol-qcow2-nobacking",
+ "pool-dir", "vol-file",
+ "qcow2-nobacking-convert-prealloc-compat", flags, FMT_COMPAT);
+ DO_TEST("pool-dir", "vol-qcow2-lazy",
+ NULL, NULL,
+ "qcow2-lazy", 0, FMT_COMPAT);
+ DO_TEST("pool-dir", "vol-qcow2-1.1",
+ NULL, NULL,
+ "qcow2-1.1", 0, FMT_COMPAT);
+ DO_TEST_FAIL("pool-dir", "vol-qcow2-0.10-lazy",
+ NULL, NULL,
+ "qcow2-0.10-lazy", 0, FMT_COMPAT);
+ DO_TEST("pool-dir", "vol-qcow2-nobacking",
+ "pool-logical", "vol-logical",
+ "qcow2-from-logical-compat", 0, FMT_COMPAT);
+ DO_TEST("pool-logical", "vol-logical",
+ "pool-dir", "vol-qcow2-nobacking",
+ "logical-from-qcow2", 0, FMT_COMPAT);
+
return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
}