[Libguestfs] [PATCH 1/2] launch: libvirt: get default QEMU from domcapabilities

Pino Toscano ptoscano at redhat.com
Fri May 24 10:48:48 UTC 2019


Parse the libvirt domain capabilities for the default emulator
capabilities, and get the path to the default QEMU executable.
---
 lib/launch-libvirt.c | 56 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/lib/launch-libvirt.c b/lib/launch-libvirt.c
index bc5978cc4..8ab1211c4 100644
--- a/lib/launch-libvirt.c
+++ b/lib/launch-libvirt.c
@@ -134,6 +134,7 @@ struct backend_libvirt_data {
   size_t nr_secrets;
   char *uefi_code;		/* UEFI (firmware) code and variables. */
   char *uefi_vars;
+  char *default_qemu;           /* default qemu (from domcapabilities) */
   char guestfsd_path[UNIX_PATH_MAX]; /* paths to sockets */
   char console_path[UNIX_PATH_MAX];
 };
@@ -153,6 +154,7 @@ struct libvirt_xml_params {
 };
 
 static int parse_capabilities (guestfs_h *g, const char *capabilities_xml, struct backend_libvirt_data *data);
+static int parse_domcapabilities (guestfs_h *g, const char *domcapabilities_xml, struct backend_libvirt_data *data);
 static int add_secret (guestfs_h *g, virConnectPtr conn, struct backend_libvirt_data *data, const struct drive *drv);
 static int find_secret (guestfs_h *g, const struct backend_libvirt_data *data, const struct drive *drv, const char **type, const char **uuid);
 static int have_secret (guestfs_h *g, const struct backend_libvirt_data *data, const struct drive *drv);
@@ -324,6 +326,7 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri)
   CLEANUP_FREE void *buf = NULL;
   unsigned long version_number;
   int uefi_flags;
+  CLEANUP_FREE char *domcapabilities_xml = NULL;
 
   params.current_proc_is_root = geteuid () == 0;
 
@@ -419,6 +422,20 @@ launch_libvirt (guestfs_h *g, void *datav, const char *libvirt_uri)
   if (parse_capabilities (g, capabilities_xml, data) == -1)
     goto cleanup;
 
+  domcapabilities_xml = virConnectGetDomainCapabilities (conn, NULL, NULL, NULL,
+                                                         NULL, 0);
+  if (!domcapabilities_xml) {
+    libvirt_error (g, _("could not get libvirt domain capabilities"));
+    goto cleanup;
+  }
+
+  /* Parse domcapabilities XML.
+   */
+  debug (g, "parsing domcapabilities XML");
+
+  if (parse_domcapabilities (g, domcapabilities_xml, data) == -1)
+    goto cleanup;
+
   /* UEFI code and variables, on architectures where that is required. */
   if (guestfs_int_get_uefi (g, &data->uefi_code, &data->uefi_vars,
                             &uefi_flags) == -1)
@@ -819,6 +836,42 @@ parse_capabilities (guestfs_h *g, const char *capabilities_xml,
   return 0;
 }
 
+static int
+parse_domcapabilities (guestfs_h *g, const char *domcapabilities_xml,
+                       struct backend_libvirt_data *data)
+{
+  CLEANUP_XMLFREEDOC xmlDocPtr doc = NULL;
+  CLEANUP_XMLXPATHFREECONTEXT xmlXPathContextPtr xpathCtx = NULL;
+  CLEANUP_XMLXPATHFREEOBJECT xmlXPathObjectPtr xpathObj = NULL;
+
+  doc = xmlReadMemory (domcapabilities_xml, strlen (domcapabilities_xml),
+                       NULL, NULL, XML_PARSE_NONET);
+  if (doc == NULL) {
+    error (g, _("unable to parse domain capabilities XML returned by libvirt"));
+    return -1;
+  }
+
+  xpathCtx = xmlXPathNewContext (doc);
+  if (xpathCtx == NULL) {
+    error (g, _("unable to create new XPath context"));
+    return -1;
+  }
+
+  /* This gives us the default QEMU. */
+#define XPATH_EXPR "string(/domainCapabilities/path/text())"
+  xpathObj = xmlXPathEvalExpression (BAD_CAST XPATH_EXPR, xpathCtx);
+  if (xpathObj == NULL) {
+    error (g, _("unable to evaluate XPath expression: %s"), XPATH_EXPR);
+    return -1;
+  }
+#undef XPATH_EXPR
+
+  assert (xpathObj->type == XPATH_STRING);
+  data->default_qemu = safe_strdup (g, (char *) xpathObj->stringval);
+
+  return 0;
+}
+
 static int
 is_custom_hv (guestfs_h *g)
 {
@@ -2014,6 +2067,9 @@ shutdown_libvirt (guestfs_h *g, void *datav, int check_for_errors)
   free (data->uefi_vars);
   data->uefi_vars = NULL;
 
+  free (data->default_qemu);
+  data->default_qemu = NULL;
+
   return ret;
 }
 
-- 
2.21.0




More information about the Libguestfs mailing list