diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c index 862c2ec00e..5daa8d11a7 100644 --- a/src/conf/snapshot_conf.c +++ b/src/conf/snapshot_conf.c @@ -170,9 +170,7 @@ virDomainSnapshotDiskDefParseXML(xmlNodePtr node, } /* validate that the passed path is absolute */ - if (virStorageSourceIsLocalStorage(def->src) && - def->src->path && - def->src->path[0] != '/') { + if (virStorageSourceIsRelative(def->src)) { virReportError(VIR_ERR_XML_ERROR, _("disk snapshot image path '%s' must be absolute"), def->src->path); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 7beebbf27b..5c82e4a0e6 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2455,6 +2455,7 @@ virStorageSourceInitChainElement; virStorageSourceIsBlockLocal; virStorageSourceIsEmpty; virStorageSourceIsLocalStorage; +virStorageSourceIsRelative; virStorageSourceNewFromBacking; virStorageSourceNewFromBackingAbsolute; virStorageSourceParseRBDColonString; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 0bf1856446..1a464337e8 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -16665,6 +16665,12 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm, priv = vm->privateData; cfg = virQEMUDriverGetConfig(driver); + if (virStorageSourceIsRelative(mirror)) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("absolute path must be used as block copy target")); + goto cleanup; + } + if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) goto cleanup; diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index 9ec005d500..ce6d21388a 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -3672,3 +3672,34 @@ virStorageFileCheckCompat(const char *compat) virStringListFree(version); return ret; } + + +/** + * virStorageSourceIsRelative: + * @src: storage source to check + * + * Returns true if given storage source definition is a relative path. + */ +bool +virStorageSourceIsRelative(virStorageSourcePtr src) +{ + virStorageType actual_type = virStorageSourceGetActualType(src); + + if (!src->path) + return false; + + switch (actual_type) { + case VIR_STORAGE_TYPE_FILE: + case VIR_STORAGE_TYPE_BLOCK: + case VIR_STORAGE_TYPE_DIR: + return src->path[0] != '/'; + + case VIR_STORAGE_TYPE_NETWORK: + case VIR_STORAGE_TYPE_VOLUME: + case VIR_STORAGE_TYPE_NONE: + case VIR_STORAGE_TYPE_LAST: + return false; + } + + return false; +} diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h index 6d1aac78df..1f62244dbc 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -388,4 +388,6 @@ int virStorageFileCheckCompat(const char *compat); virStorageSourcePtr virStorageSourceNewFromBackingAbsolute(const char *path); +bool virStorageSourceIsRelative(virStorageSourcePtr src); + #endif /* __VIR_STORAGE_FILE_H__ */