If the connection is not local, paths of disks will refer to the remote
host, which were mistakenly handled as local paths (in the best case
failing to open a non-existing disk, and in the worst case opening a
different disk!).
In case the disks are remote resources like ssh or ceph, nothing
guarantees that the hostname can be reached from the local machine, or
even that it is actually the same on both machines.
For these reasons, just forbit outright the addition of disks from
non-local libvirt connections for now.
---
lib/libvirt-domain.c | 38 ++++++++++++++++++++++++++++++++++++--
1 file changed, 36 insertions(+), 2 deletions(-)
diff --git a/lib/libvirt-domain.c b/lib/libvirt-domain.c
index 37c0b49..6b9467b 100644
--- a/lib/libvirt-domain.c
+++ b/lib/libvirt-domain.c
@@ -32,6 +32,7 @@
#include <libxml/xpath.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
+#include <libxml/uri.h>
#include "base64.h"
@@ -203,7 +204,9 @@ guestfs_impl_add_libvirt_dom (guestfs_h *g, void *domvp,
size_t ckp;
struct add_disk_data data;
CLEANUP_XMLFREEDOC xmlDocPtr doc = NULL;
- CLEANUP_FREE char *label = NULL, *imagelabel = NULL;
+ CLEANUP_FREE char *label = NULL, *imagelabel = NULL, *uristr = NULL;
+ virConnectPtr conn;
+ CLEANUP_XMLFREEURI xmlURIPtr uri = NULL;
readonly =
optargs->bitmask & GUESTFS_ADD_LIBVIRT_DOM_READONLY_BITMASK
@@ -247,6 +250,37 @@ guestfs_impl_add_libvirt_dom (guestfs_h *g, void *domvp,
return -1;
}
+ conn = virDomainGetConnect (dom);
+ if (conn == NULL) {
+ virErrorPtr err;
+ err = virGetLastError ();
+ error (g, _("cannot get the libvirt connection of the domain ā%sā: %s"),
+ virDomainGetName (dom), err ? err->message : "");
+ return -1;
+ }
+
+ uristr = virConnectGetURI (conn);
+ if (uristr == NULL) {
+ virErrorPtr err;
+ err = virGetLastError ();
+ error (g, _("cannot get the URI of the libvirt connection: %s"),
+ err ? err->message : "");
+ return -1;
+ }
+
+ uri = xmlParseURI (uristr);
+ if (uri == NULL) {
+ error (g, _("cannot parse the URI of the libvirt connection: %s"),
+ uristr);
+ return -1;
+ }
+
+ if (uri->server && uri->server[0] != '\0') {
+ error (g, _("cannot add a non-local libvirt connection: %s"),
+ uristr);
+ return -1;
+ }
+
if (!readonly) {
virDomainInfo info;
virErrorPtr err;
@@ -320,7 +354,7 @@ guestfs_impl_add_libvirt_dom (guestfs_h *g, void *domvp,
* all disks are added or none are added.
*/
ckp = guestfs_int_checkpoint_drives (g);
- r = for_each_disk (g, virDomainGetConnect (dom), doc, add_disk, &data);
+ r = for_each_disk (g, conn, doc, add_disk, &data);
if (r == -1)
guestfs_int_rollback_drives (g, ckp);
--
2.9.4