Now that we are able to select images from the backing chain via indexed
access we should also convert possible network sources to
qemu-compatible strings before passing them to qemu.
---
src/qemu/qemu_driver.c | 43 +++++++++++++++++++++++++++++++++++++++----
1 file changed, 39 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 424be4a..feef9fa 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -14980,6 +14980,8 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
virDomainDiskDefPtr disk;
virStorageSourcePtr baseSource = NULL;
unsigned int baseIndex = 0;
+ char *basePath = NULL;
+ char *backingPath = NULL;
if (!virDomainObjIsActive(vm)) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
@@ -14987,6 +14989,13 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
goto cleanup;
}
+ if (flags & VIR_DOMAIN_BLOCK_REBASE_RELATIVE && !base) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("flag VIR_DOMAIN_BLOCK_REBASE_RELATIVE is valid only
"
+ " with non-null base "));
+ goto cleanup;
+ }
+
priv = vm->privateData;
if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKJOB_ASYNC)) {
async = true;
@@ -15048,10 +15057,33 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
base, baseIndex, NULL))))
goto endjob;
+ if (baseSource) {
+ if (qemuGetDriveSourceString(baseSource, NULL, &basePath) < 0)
+ goto endjob;
+
+ if (flags & VIR_DOMAIN_BLOCK_REBASE_RELATIVE) {
+ if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_CHANGE_BACKING_FILE)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("this QEMU binary doesn't support relative
"
+ "block pull/rebase"));
+ goto endjob;
+ }
+
+ if (disk->src.backingStore == baseSource) {
+ if (VIR_STRDUP(backingPath, baseSource->relPath) < 0)
+ goto endjob;
+ } else {
+ if (virStorageFileGetRelativeBackingPath(disk->src.backingStore,
+ baseSource,
+ &backingPath) < 0)
+ goto endjob;
+ }
+ }
+ }
+
qemuDomainObjEnterMonitor(driver, vm);
- ret = qemuMonitorBlockJob(priv->mon, device,
- baseIndex ? baseSource->path : base,
- NULL, bandwidth, info, mode, async);
+ ret = qemuMonitorBlockJob(priv->mon, device, basePath, backingPath,
+ bandwidth, info, mode, async);
qemuDomainObjExitMonitor(driver, vm);
if (ret < 0)
goto endjob;
@@ -15121,6 +15153,8 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
}
cleanup:
+ VIR_FREE(basePath);
+ VIR_FREE(backingPath);
VIR_FREE(device);
if (vm)
virObjectUnlock(vm);
@@ -15361,7 +15395,8 @@ qemuDomainBlockRebase(virDomainPtr dom, const char *path, const
char *base,
virCheckFlags(VIR_DOMAIN_BLOCK_REBASE_SHALLOW |
VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT |
VIR_DOMAIN_BLOCK_REBASE_COPY |
- VIR_DOMAIN_BLOCK_REBASE_COPY_RAW, -1);
+ VIR_DOMAIN_BLOCK_REBASE_COPY_RAW |
+ VIR_DOMAIN_BLOCK_REBASE_RELATIVE, -1);
if (!(vm = qemuDomObjFromDomain(dom)))
return -1;
--
1.9.3