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 | 45 +++++++++++++++++++++++++++++++++++++++++----
1 file changed, 41 insertions(+), 4 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 34dc94b..1174da9 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -15020,6 +15020,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",
@@ -15027,6 +15029,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;
@@ -15087,10 +15096,35 @@ 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 (virStorageFileGetRelativeBackingPath(disk->src->backingStore,
+ baseSource,
+ &backingPath) < 0)
+ goto endjob;
+
+
+ if (!backingPath) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("can't keep relative backing
relationship"));
+ 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;
@@ -15165,6 +15199,8 @@ qemuDomainBlockJobImpl(virDomainObjPtr vm,
}
cleanup:
+ VIR_FREE(basePath);
+ VIR_FREE(backingPath);
VIR_FREE(device);
if (vm)
virObjectUnlock(vm);
@@ -15415,7 +15451,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