QEMU blockdev allows to configure cachemode, discard and detect-zeroes for blockdev-add. The benefit of allowing to change cachemode is copying a shared storage (RBD, writeback) to a local device mapping (SAN, none cache) and still allows live migration. Allowing changing detect-zeroes could be beneficial while copying from SAN to RBD without taking too much space. Signed-off-by: jshen28 <yshxxsjt715@xxxxxxx> --- src/conf/domain_conf.c | 11 +++++++++++ src/conf/storage_source_conf.h | 6 +++--- src/qemu/qemu_blockjob.c | 13 +++++++++++++ src/qemu/qemu_driver.c | 14 ++++++++++++++ 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index ff1c78ecd1..0533a770c3 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -13962,6 +13962,17 @@ virDomainDiskDefParseSource(const char *xmlStr, if ((driverNode = virXPathNode("./driver", ctxt))) { if (virDomainDiskDefDriverSourceParseXML(src, driverNode, ctxt) < 0) return NULL; + if (virXMLPropEnum(driverNode, "cache", virDomainDiskCacheTypeFromString, + VIR_XML_PROP_NONE, &src->cachemode) < 0) + return NULL; + if (virXMLPropEnum(driverNode, "detect_zeroes", + virDomainDiskDetectZeroesTypeFromString, + VIR_XML_PROP_NONE, &src->detect_zeroes) < 0) + return NULL; + if (virXMLPropEnum(driverNode, "discard", + virDomainDiskDiscardTypeFromString, + VIR_XML_PROP_NONE, &src->discard) < 0) + return NULL; } if (virStorageSourceIsEmpty(src)) { diff --git a/src/conf/storage_source_conf.h b/src/conf/storage_source_conf.h index 14a6825d54..bed3b6570d 100644 --- a/src/conf/storage_source_conf.h +++ b/src/conf/storage_source_conf.h @@ -392,9 +392,9 @@ struct _virStorageSource { * These instances are currently just copies from the parent definition and * are not mapped back to the XML */ int iomode; /* enum virDomainDiskIo */ - int cachemode; /* enum virDomainDiskCache */ - int discard; /* enum virDomainDiskDiscard */ - int detect_zeroes; /* enum virDomainDiskDetectZeroes */ + unsigned int cachemode; /* enum virDomainDiskCache */ + unsigned int discard; /* enum virDomainDiskDiscard */ + unsigned int detect_zeroes; /* enum virDomainDiskDetectZeroes */ bool floppyimg; /* set to true if the storage source is going to be used as a source for floppy drive */ diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c index cb2d05d71d..f6b85772be 100644 --- a/src/qemu/qemu_blockjob.c +++ b/src/qemu/qemu_blockjob.c @@ -1240,6 +1240,19 @@ qemuBlockJobProcessEventConcludedCopyPivot(virQEMUDriver *driver, qemuBlockJobEventProcessConcludedRemoveChain(driver, vm, asyncJob, job->disk->src); virObjectUnref(job->disk->src); job->disk->src = g_steal_pointer(&job->disk->mirror); + + /* reset cachemode, discard, detect_zeroes to reflect the enforced setting */ + if (job->disk->src->cachemode) { + job->disk->cachemode = job->disk->src->cachemode; + } + + if (job->disk->src->discard) { + job->disk->discard = job->disk->src->discard; + } + + if (job->disk->src->detect_zeroes) { + job->disk->detect_zeroes = job->disk->src->detect_zeroes; + } } diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 6154fe9bfe..4058cdfafe 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -14552,6 +14552,7 @@ qemuDomainBlockCopyCommon(virDomainObj *vm, bool existing = mirror_reuse; qemuBlockJobData *job = NULL; g_autoptr(virStorageSource) mirror = mirrorsrc; + g_autoptr(virStorageSource) mirror_cpy = virStorageSourceCopy(mirror, false); bool supports_create = false; bool supports_access = false; bool supports_detect = false; @@ -14725,6 +14726,19 @@ qemuDomainBlockCopyCommon(virDomainObj *vm, * to modify all callers of 'qemuDomainPrepareStorageSourceBlockdev' */ mirror->detect_zeroes = disk->detect_zeroes; + /* respect input disk configuration */ + if (mirror_cpy->detect_zeroes) { + mirror->detect_zeroes = mirror_cpy->detect_zeroes; + } + + if (mirror_cpy->cachemode) { + mirror->cachemode = mirror_cpy->cachemode; + } + + if (mirror_cpy->discard) { + mirror->discard = mirror_cpy->discard; + } + /* If reusing an external image that includes a backing file but the user * did not enumerate the chain in the XML we need to detect the chain */ if (mirror_reuse && -- 2.17.1