[Pkg-libvirt-commits] [libguestfs] 187/266: v2v: Work around buggy `virsh dumpxml'.

Hilko Bengen bengen at moszumanska.debian.org
Fri Oct 3 14:42:00 UTC 2014


This is an automated email from the git hooks/post-receive script.

bengen pushed a commit to annotated tag debian/1%1.27.35-1
in repository libguestfs.

commit 8dc45325a6b7790896a43f41db5aca376aee2bfc
Author: Richard W.M. Jones <rjones at redhat.com>
Date:   Tue Aug 26 17:31:08 2014 +0100

    v2v: Work around buggy `virsh dumpxml'.
    
    The `virsh dumpxml' command doesn't work properly when the libvirt
    source requires authentication.  This is because the authentication
    prompts are sent to stdout, but stdout is also the place where we are
    reading the output XML from.
    
    Add a mini-binding to libvirt virDomainGetXMLDesc which avoids this,
    getting the XML directly using the libvirt API.  Change existing
    external calls to `virsh dumpxml' to use this API instead.
---
 po/POTFILES          |   1 +
 po/POTFILES-ml       |   1 +
 v2v/Makefile.am      |   8 +++-
 v2v/domainxml-c.c    | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++
 v2v/domainxml.ml     |  21 +++++++++
 v2v/domainxml.mli    |  28 ++++++++++++
 v2v/input_libvirt.ml |   7 +--
 v2v/link.sh.in       |   2 +-
 8 files changed, 184 insertions(+), 9 deletions(-)

diff --git a/po/POTFILES b/po/POTFILES
index 254f419..3d208d5 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -331,5 +331,6 @@ src/test-utils.c
 src/tmpdirs.c
 src/utils.c
 test-tool/test-tool.c
+v2v/domainxml-c.c
 v2v/utils-c.c
 v2v/xml-c.c
diff --git a/po/POTFILES-ml b/po/POTFILES-ml
index 2001f47..7786569 100644
--- a/po/POTFILES-ml
+++ b/po/POTFILES-ml
@@ -86,6 +86,7 @@ v2v/DOM.ml
 v2v/cmdline.ml
 v2v/convert_linux.ml
 v2v/convert_windows.ml
+v2v/domainxml.ml
 v2v/input_disk.ml
 v2v/input_libvirt.ml
 v2v/lib_esx.ml
diff --git a/v2v/Makefile.am b/v2v/Makefile.am
index a336ee8..049d9df 100644
--- a/v2v/Makefile.am
+++ b/v2v/Makefile.am
@@ -30,6 +30,7 @@ SOURCES_MLI = \
 	convert_linux.mli \
 	convert_windows.mli \
 	DOM.mli \
+	domainxml.mli \
 	lib_esx.mli \
 	lib_linux.mli \
 	input_disk.mli \
@@ -45,6 +46,7 @@ SOURCES_ML = \
 	types.ml \
 	utils.ml \
 	xml.ml \
+	domainxml.ml \
 	DOM.ml \
 	lib_esx.ml \
 	lib_linux.ml \
@@ -65,7 +67,8 @@ SOURCES_C = \
 	$(top_builddir)/mllib/mkdtemp-c.c \
 	$(top_builddir)/customize/crypt-c.c \
 	utils-c.c \
-	xml-c.c
+	xml-c.c \
+	domainxml-c.c
 
 if HAVE_OCAML
 
@@ -80,7 +83,8 @@ virt_v2v_CPPFLAGS = \
 	-I$(top_srcdir)/fish
 virt_v2v_CFLAGS = \
 	$(WARN_CFLAGS) $(WERROR_CFLAGS) \
-	$(LIBXML2_CFLAGS)
+	$(LIBXML2_CFLAGS) \
+	$(LIBVIRT_CFLAGS)
 
 BOBJECTS = \
 	$(top_builddir)/mllib/common_gettext.cmo \
diff --git a/v2v/domainxml-c.c b/v2v/domainxml-c.c
new file mode 100644
index 0000000..fc2993d
--- /dev/null
+++ b/v2v/domainxml-c.c
@@ -0,0 +1,125 @@
+/* virt-v2v
+ * Copyright (C) 2009-2014 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+/* [virsh dumpxml] but with non-broken authentication handling. */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <errno.h>
+
+#include <caml/alloc.h>
+#include <caml/fail.h>
+#include <caml/memory.h>
+#include <caml/mlvalues.h>
+
+#ifdef HAVE_LIBVIRT
+#include <libvirt/libvirt.h>
+#endif
+
+#include "guestfs.h"
+#include "guestfs-internal-frontend.h"
+
+#pragma GCC diagnostic ignored "-Wmissing-prototypes"
+
+#ifdef HAVE_LIBVIRT
+
+static void raise_error (const char *fs, ...)
+  __attribute__((noreturn))
+  __attribute__((format (printf,1,2)));
+
+/* Note we rely on libvirt printing errors to stderr, so the exception
+ * doesn't need to contain the actual error from libvirt.
+ */
+static void
+raise_error (const char *fs, ...)
+{
+  va_list args;
+  /* We have to assemble the error on the stack because a dynamic
+   * string couldn't be freed.
+   */
+  char msg[256];
+  int len;
+
+  va_start (args, fs);
+  len = vsnprintf (msg, sizeof msg, fs , args);
+  va_end (args);
+
+  if (len < 0) caml_failwith (fs);
+
+  caml_invalid_argument (msg);
+}
+
+value
+v2v_dumpxml (value connv, value domnamev)
+{
+  CAMLparam2 (connv, domnamev);
+  CAMLlocal1 (retv);
+  const char *conn_uri = NULL;
+  const char *domname;
+  virConnectPtr conn;
+  virDomainPtr dom;
+  char *xml;
+
+  if (connv != Val_int (0))
+    conn_uri = String_val (Field (connv, 0)); /* Some conn */
+
+  /* We have to call the default authentication handler, not least
+   * since it handles all the PolicyKit crap.  However it also makes
+   * coding this simpler.
+   */
+  conn = virConnectOpenAuth (conn_uri, virConnectAuthPtrDefault, VIR_CONNECT_RO);
+  if (conn == NULL) {
+    if (conn_uri)
+      raise_error ("cannot open libvirt connection '%s'", conn_uri);
+    else
+      raise_error ("cannot open libvirt connection");
+  }
+
+  /* Look up the domain. */
+  domname = String_val (domnamev);
+
+  dom = virDomainLookupByName (conn, domname);
+  if (!dom) {
+    virConnectClose (conn);
+    raise_error ("cannot find libvirt domain '%s'", domname);
+  }
+
+  xml = virDomainGetXMLDesc (dom, 0);
+  virDomainFree (dom);
+  virConnectClose (conn);
+  if (xml == NULL)
+    raise_error ("cannot fetch XML description of guest '%s'", domname);
+
+  retv = caml_copy_string (xml);
+  free (xml);
+
+  CAMLreturn (retv);
+}
+
+#else /* !HAVE_LIBVIRT */
+
+value
+v2v_dumpxml (value connv, value domv)
+{
+  caml_invalid_argument ("virt-v2v was compiled without libvirt support");
+}
+
+#endif /* !HAVE_LIBVIRT */
diff --git a/v2v/domainxml.ml b/v2v/domainxml.ml
new file mode 100644
index 0000000..03994f9
--- /dev/null
+++ b/v2v/domainxml.ml
@@ -0,0 +1,21 @@
+(* virt-v2v
+ * Copyright (C) 2009-2014 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+(* [virsh dumpxml] but with non-broken authentication handling. *)
+
+external dumpxml : ?conn:string -> string -> string = "v2v_dumpxml"
diff --git a/v2v/domainxml.mli b/v2v/domainxml.mli
new file mode 100644
index 0000000..6d58981
--- /dev/null
+++ b/v2v/domainxml.mli
@@ -0,0 +1,28 @@
+(* virt-v2v
+ * Copyright (C) 2009-2014 Red Hat Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *)
+
+(** [virsh dumpxml] but with non-broken authentication handling.
+
+    If you do [virsh dumpxml foo] and if the libvirt source (eg. ESX)
+    requires an interactive password, then virsh unhelpfully sends the
+    password prompt to stdout, which is the same place we would be
+    reading the XML from.  This file works around this brokenness. *)
+
+val dumpxml : ?conn:string -> string -> string
+(** [dumpxml ?conn dom] returns the libvirt XML of domain [dom].
+    The optional [?conn] parameter is the libvirt connection URI. *)
diff --git a/v2v/input_libvirt.ml b/v2v/input_libvirt.ml
index ffe0c7c..d409cd9 100644
--- a/v2v/input_libvirt.ml
+++ b/v2v/input_libvirt.ml
@@ -311,11 +311,6 @@ let input_libvirt verbose libvirt_uri guest =
         None, None in
 
   (* Get the libvirt XML. *)
-  let cmd =
-    match libvirt_uri with
-    | None -> sprintf "virsh dumpxml %s" (quote guest)
-    | Some uri -> sprintf "virsh -c %s dumpxml %s" (quote uri) (quote guest) in
-  let lines = external_command ~prog cmd in
-  let xml = String.concat "\n" lines in
+  let xml = Domainxml.dumpxml ?conn:libvirt_uri guest in
 
   new input_libvirt verbose options ?map_source_file ?map_source_dev xml
diff --git a/v2v/link.sh.in b/v2v/link.sh.in
index f909015..a226947 100644
--- a/v2v/link.sh.in
+++ b/v2v/link.sh.in
@@ -19,4 +19,4 @@
 # Hack automake to link binary properly.  There is no other way to add
 # the -cclib parameter to the end of the command line.
 
-exec "$@" -linkpkg -cclib '-lutils -lncurses -lcrypt @LIBXML2_LIBS@ -lgnu'
+exec "$@" -linkpkg -cclib '-lutils -lncurses -lcrypt @LIBVIRT_LIBS@ @LIBXML2_LIBS@ -lgnu'

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-libvirt/libguestfs.git



More information about the Pkg-libvirt-commits mailing list