]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Xen: Add support for qemu command-line passthrough
authorJim Fehlig <jfehlig@suse.com>
Thu, 30 Jul 2020 19:25:20 +0000 (13:25 -0600)
committerJim Fehlig <jfehlig@suse.com>
Tue, 25 Aug 2020 16:11:08 +0000 (10:11 -0600)
Xen supports passing arbitrary arguments to the QEMU device model via
the 'extra' member of the public libxl_domain_build_info structure.
This patch adds a 'xen' namespace extension, similar to the QEMU and
bhyve drivers, to map arbitrary arguments to the 'extra' member. Only
passthrough of arguments is supported. Passthrough of environment
variables or capabilities adjustments is not supported.

Signed-off-by: Jim Fehlig <jfehlig@suse.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
docs/drvxen.html.in
docs/schemas/domaincommon.rng
src/libxl/libxl_conf.c
src/libxl/libxl_conf.h
src/libxl/libxl_domain.c
src/libxl/libxl_domain.h

index b2f41c17632e2e424a0ff9a6908084528dd04180..45a9329fcfaf91cbd11c5dae5d628235cdeedb62 100644 (file)
@@ -141,6 +141,35 @@ vnclisten = "0.0.0.0"
 disk = [ "tap:aio:/var/lib/xen/images/rhel5pv.img,xvda,w", "tap:qcow:/root/qcow1-xen.img,xvdd,w" ]
 vif = [ "mac=00:16:3e:60:36:ba,bridge=virbr0,script=vif-bridge,vifname=vif5.0" ]</pre>
 
+    <h2><a id="xencommand">Pass-through of arbitrary command-line arguments
+    to the qemu device model</a></h2>
+
+    <p><span class="since">Since 6.7.0</span>, the Xen driver supports passing
+      arbitrary command-line arguments to the qemu device model used by Xen with
+      the <code>&lt;xen:commandline&gt;</code> element under <code>domain</code>.
+      In order to use command-line pass-through, an XML namespace request must be
+      issued that pulls in <code>http://libvirt.org/schemas/domain/xen/1.0</code>.
+      With the namespace in place, it is then possible to add
+      <code>&lt;xen:arg&gt;</code>sub-elements to
+      <code>&lt;xen:commandline&gt;</code> describing each argument passed to
+      the device model when starting the domain.
+    </p>
+    <p>The following example illustrates passing agruments to the QEMU device
+      model that define a floppy drive, which Xen does not support through its
+      public APIs:
+    </p>
+    <pre>
+&lt;domain type="xen" xmlns:xen="http://libvirt.org/schemas/domain/xen/1.0"&gt;
+  ...
+  &lt;xen:commandline&gt;
+    &lt;xen:arg value='-drive'/&gt;
+    &lt;xen:arg value='file=/path/to/image,format=raw,if=none,id=drive-fdc0-0-0'/&gt;
+    &lt;xen:arg value='-global'/&gt;
+    &lt;xen:arg value='isa-fdc.driveA=drive-fdc0-0-0'/&gt;
+  &lt;/xen:commandline&gt;
+&lt;/domain&gt;
+    </pre>
+
     <h2><a id="xmlconfig">Example domain XML config</a></h2>
 
     <p>
index c933c71035d09313d8c71adae2067e1a0f7b3872..0d8a0caaf62118f658f3fce606278180224d899b 100644 (file)
@@ -87,6 +87,9 @@
         <optional>
           <ref name='bhyvecmdline'/>
         </optional>
+        <optional>
+          <ref name='xencmdline'/>
+        </optional>
       </interleave>
     </element>
   </define>
     </element>
   </define>
 
+  <!--
+       Optional hypervisor extensions in their own namespace:
+         Xen
+    -->
+  <define name="xencmdline">
+    <element name="commandline" ns="http://libvirt.org/schemas/domain/xen/1.0">
+      <zeroOrMore>
+        <element name="arg">
+          <attribute name='value'/>
+        </element>
+      </zeroOrMore>
+    </element>
+  </define>
+
   <!--
        Type library
     -->
index 7c2c0150152fd7f5d024503e4fcc0d9cd7b0b8ec..e7c7022b690323f35ac21331cc54b5ef503236c5 100644 (file)
@@ -760,6 +760,13 @@ libxlMakeDomBuildInfo(virDomainDefPtr def,
         libxl_get_required_shadow_memory(b_info->max_memkb,
                                          b_info->max_vcpus);
 
+    if (def->namespaceData) {
+        libxlDomainXmlNsDefPtr nsdata = def->namespaceData;
+
+        if (nsdata->num_args > 0)
+            b_info->extra = g_strdupv(nsdata->args);
+    }
+
     return 0;
 }
 
@@ -2513,5 +2520,6 @@ libxlCreateXMLConf(libxlDriverPrivatePtr driver)
     libxlDomainDefParserConfig.priv = driver;
     return virDomainXMLOptionNew(&libxlDomainDefParserConfig,
                                  &libxlDomainXMLPrivateDataCallbacks,
-                                 NULL, NULL, NULL);
+                                 &libxlDriverDomainXMLNamespace,
+                                 NULL, NULL);
 }
index b057a9e4ba9bd6095649ed5b01f7979b849289ca..fc652df61e6d073e24475caca54c55e2337fa0d9 100644 (file)
@@ -168,6 +168,14 @@ struct _libxlSavefileHeader {
     uint32_t unused[10];
 };
 
+
+typedef struct _libxlDomainXmlNsDef libxlDomainXmlNsDef;
+typedef libxlDomainXmlNsDef *libxlDomainXmlNsDefPtr;
+struct _libxlDomainXmlNsDef {
+    size_t num_args;
+    char **args;
+};
+
 libxlDriverConfigPtr
 libxlDriverConfigNew(void);
 int
index d9fcde436418a47fb90d0e28da30e18a4153eb9e..de2059fa249da0ff10fe4601199480a4ad8e27f5 100644 (file)
@@ -1573,3 +1573,85 @@ libxlDomainDefCheckABIStability(libxlDriverPrivatePtr driver,
     virDomainDefFree(migratableDefDst);
     return ret;
 }
+
+
+static void
+libxlDomainDefNamespaceFree(void *nsdata)
+{
+    libxlDomainXmlNsDefPtr def = nsdata;
+
+    if (!def)
+        return;
+
+    g_strfreev(def->args);
+    g_free(def);
+}
+
+
+static int
+libxlDomainDefNamespaceParse(xmlXPathContextPtr ctxt,
+                             void **data)
+{
+    libxlDomainXmlNsDefPtr nsdata = NULL;
+    g_autofree xmlNodePtr *nodes = NULL;
+    ssize_t nnodes;
+    size_t i;
+    int ret = -1;
+
+    if ((nnodes = virXPathNodeSet("./xen:commandline/xen:arg", ctxt, &nodes)) < 0)
+        return -1;
+
+    if (nnodes == 0)
+        return 0;
+
+    nsdata = g_new0(libxlDomainXmlNsDef, 1);
+    nsdata->args = g_new0(char *, nnodes + 1);
+
+    for (i = 0; i < nnodes; i++) {
+        if (!(nsdata->args[nsdata->num_args++] = virXMLPropString(nodes[i], "value"))) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("No device model command-line argument specified"));
+            goto cleanup;
+        }
+    }
+
+    *data = g_steal_pointer(&nsdata);
+    ret = 0;
+
+ cleanup:
+    libxlDomainDefNamespaceFree(nsdata);
+    return ret;
+}
+
+
+static int
+libxlDomainDefNamespaceFormatXML(virBufferPtr buf,
+                                 void *nsdata)
+{
+    libxlDomainXmlNsDefPtr cmd = nsdata;
+    size_t i;
+
+    if (!cmd->num_args)
+        return 0;
+
+    virBufferAddLit(buf, "<xen:commandline>\n");
+    virBufferAdjustIndent(buf, 2);
+
+    for (i = 0; i < cmd->num_args; i++)
+        virBufferEscapeString(buf, "<xen:arg value='%s'/>\n",
+                              cmd->args[i]);
+
+    virBufferAdjustIndent(buf, -2);
+    virBufferAddLit(buf, "</xen:commandline>\n");
+
+    return 0;
+}
+
+
+virXMLNamespace libxlDriverDomainXMLNamespace = {
+    .parse = libxlDomainDefNamespaceParse,
+    .free = libxlDomainDefNamespaceFree,
+    .format = libxlDomainDefNamespaceFormatXML,
+    .prefix = "xen",
+    .uri = "http://libvirt.org/schemas/domain/xen/1.0",
+};
index 7e280937221fdd1a602bd1229ce49c32b7e883dc..00682546e01060abfc16cbebe9a56240212cfae0 100644 (file)
@@ -77,6 +77,7 @@ struct _libxlDomainObjPrivate {
 
 extern virDomainXMLPrivateDataCallbacks libxlDomainXMLPrivateDataCallbacks;
 extern virDomainDefParserConfig libxlDomainDefParserConfig;
+extern virXMLNamespace libxlDriverDomainXMLNamespace;
 extern const struct libxl_event_hooks ev_hooks;
 
 int