Now that we support blockdev for qemuDomainBlockCopy we can allow
copying to remote destinations as well.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/qemu/qemu_driver.c | 47 ++++++++++++++++++++++++++++--------------
1 file changed, 32 insertions(+), 15 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 261a4167b5..b4eecdd8be 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -18195,6 +18195,9 @@ qemuDomainBlockCopyValidateMirror(virStorageSourcePtr mirror,
int desttype = virStorageSourceGetActualType(mirror);
struct stat st;
+ if (!virStorageSourceIsLocalStorage(mirror))
+ return 0;
+
if (virStorageFileAccess(mirror, F_OK) < 0) {
if (errno != ENOENT) {
virReportSystemError(errno, "%s",
@@ -18321,6 +18324,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
qemuBlockJobDataPtr job = NULL;
VIR_AUTOUNREF(virStorageSourcePtr) mirror = mirrorsrc;
bool blockdev = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BLOCKDEV);
+ bool mirror_initialized = false;
VIR_AUTOPTR(qemuBlockStorageSourceChainData) data = NULL;
VIR_AUTOPTR(qemuBlockStorageSourceChainData) crdata = NULL;
virStorageSourcePtr n;
@@ -18393,15 +18397,19 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
}
/* Prepare the destination file. */
- /* XXX Allow non-file mirror destinations */
- if (!virStorageSourceIsLocalStorage(mirror)) {
+ if (!blockdev &&
+ !virStorageSourceIsLocalStorage(mirror)) {
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
_("non-file destination not supported yet"));
goto endjob;
}
- if (qemuDomainStorageFileInit(driver, vm, mirror, NULL) < 0)
- goto endjob;
+ if (virStorageFileSupportsCreate(mirror) == 1) {
+ if (qemuDomainStorageFileInit(driver, vm, mirror, NULL) < 0)
+ goto endjob;
+
+ mirror_initialized = true;
+ }
if (qemuDomainBlockCopyValidateMirror(mirror, disk->dst, &existing) < 0)
goto endjob;
@@ -18410,12 +18418,19 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
if (!mirror_reuse) {
mirror->format = disk->src->format;
} else {
- /* If the user passed the REUSE_EXT flag, then either they
- * can also pass the RAW flag or use XML to tell us the format.
- * So if we get here, we assume it is safe for us to probe the
- * format from the file that we will be using. */
- mirror->format = virStorageFileProbeFormat(mirror->path, cfg->user,
- cfg->group);
+ if (mirror_initialized &&
+ virStorageSourceIsLocalStorage(mirror)) {
+ /* If the user passed the REUSE_EXT flag, then either they
+ * can also pass the RAW flag or use XML to tell us the format.
+ * So if we get here, we assume it is safe for us to probe the
+ * format from the file that we will be using. */
+ mirror->format = virStorageFileProbeFormat(mirror->path,
cfg->user,
+ cfg->group);
+ } else {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("reused mirror destination format must be
specified"));
+ goto endjob;
+ }
}
}
@@ -18432,12 +18447,14 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
/* pre-create the image file. In case when 'blockdev' is used this is
* required so that libvirt can properly label the image for access by qemu */
if (!existing) {
- if (virStorageFileCreate(mirror) < 0) {
- virReportSystemError(errno, "%s", _("failed to create copy
target"));
- goto endjob;
- }
+ if (mirror_initialized) {
+ if (virStorageFileCreate(mirror) < 0) {
+ virReportSystemError(errno, "%s", _("failed to create copy
target"));
+ goto endjob;
+ }
- need_unlink = true;
+ need_unlink = true;
+ }
}
if (mirror->format > 0)
--
2.21.0