[libvirt] [PATCH 1/2] Allow supplying a node device name as hostdev source

Mark McLoughlin markmc at redhat.com
Tue Feb 24 22:35:38 UTC 2009


Rather than requiring that hostdev sources be specified
using the PCI/USB addresses, allow them to be specified
using the node device name.

The patch includes documentation and test updates, but
does not implement support in any driver.

Signed-off-by: Mark McLoughlin <markmc at redhat.com>
---
 ChangeLog                                          |   12 +++++
 docs/formatdomain.html                             |   26 +++++++---
 docs/formatdomain.html.in                          |   29 +++++++---
 docs/schemas/domain.rng                            |   10 ++++
 src/domain_conf.c                                  |   53 +++++++++++++++++++-
 src/domain_conf.h                                  |    2 +
 .../qemuxml2argv-hostdev-nodedev-name.xml          |   27 ++++++++++
 tests/qemuxml2argvtest.c                           |    5 ++
 tests/qemuxml2xmltest.c                            |    1 +
 9 files changed, 146 insertions(+), 19 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-nodedev-name.xml

diff --git a/ChangeLog b/ChangeLog
index 4f2c125..4bd87a2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+Tue Feb 24 22:27:12 GMT 2009 Mark McLoughlin <markmc at redhat.com>
+
+	* src/domain_conf.[ch]: Allow supplying a node
+	device name as hostdev source
+
+	* docs/formatdomain.html, docs/schemas/domain.rng:
+	documentation updates
+
+	* tests/qemuxml2argvdata/qemuxml2argv-hostdev-nodedev-name.xml,
+	  tests/qemuxml2argvtest.c, tests/qemuxml2xmltest.c: test
+	updates
+
 Tue Feb 24 22:09:40 GMT 2009 Mark McLoughlin <markmc at redhat.com>
 
 	* src/virsh.c: add new commands for each of the new
diff --git a/docs/formatdomain.html b/docs/formatdomain.html
index 17dc0cd..11ea697 100644
--- a/docs/formatdomain.html
+++ b/docs/formatdomain.html
@@ -473,6 +473,15 @@
     </p>
         <pre>
           ...
+	  <hostdev mode='subsystem' type='nodedev'>
+	    <source>
+	      <nodedev name='pci_8086_109a'/>
+	    </source>
+	  </hostdev>
+	  ...</pre>
+        <p>or:</p>
+        <pre>
+          ...
 	  <hostdev mode='subsystem' type='usb'>
 	    <source>
 	      <vendor id='0x1234'/>
@@ -490,15 +499,16 @@
 	  </hostdev>
 	  ...</pre>
         <dl><dt><code>hostdev</code></dt><dd>The <code>hostdev</code> element is the main container for describing
-      host devices. For usb device passthrough <code>mode</code> is always
-      "subsystem" and <code>type</code> is "usb" for an USB device and "pci"
-      for a PCI device..
+      host devices. For USB or PCI device passthrough <code>mode</code> is always
+      "subsystem" and <code>type</code> is either "usb", "pci" or "nodedev".
       </dd><dt><code>source</code></dt><dd>The source element describes the device as seen from the host.
-      The USB device can either be addressed by vendor / product id using the
-      <code>vendor</code> and <code>product</code> elements or by the device's
-      address on the hosts using the <code>address</code> element.
-      PCI devices on the other hand can only be described by their
-      <code>address</code></dd><dt><code>vendor</code>, <code>product</code></dt><dd>The <code>vendor</code> and <code>product</code> elements each have an
+      With <code>type</code> "nodedev", USB and PCI devices can be described
+      using their node device name as listed by <code>virsh nodedev-list</code>.
+      Alternatively, USB devices can either be addressed by vendor / product id
+      using the <code>vendor</code> and <code>product</code> elements or by the
+      device's address on the hosts using the <code>address</code> element.
+      PCI devices can be described by their <code>address</code>.</dd><dt><code>nodedev</code></dt><dd>The <code>nodedev</code> element describes a USB or PCI device using
+      its node device name as listed by <code>virsh nodedev-list</code>.</dd><dt><code>vendor</code>, <code>product</code></dt><dd>The <code>vendor</code> and <code>product</code> elements each have an
       <code>id</code> attribute that specifies the USB vendor and product id.
       The ids can be given in decimal, hexadecimal (starting with 0x) or
       octal (starting with 0) form.</dd><dt><code>address</code></dt><dd>The <code>address</code> element for USB devices has a
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index ee32354..a661b02 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -385,6 +385,15 @@
 
     <pre>
           ...
+	  <hostdev mode='subsystem' type='nodedev'>
+	    <source>
+	      <nodedev name='pci_8086_109a'/>
+	    </source>
+	  </hostdev>
+	  ...</pre>
+    <p>or:</p>
+    <pre>
+          ...
 	  <hostdev mode='subsystem' type='usb'>
 	    <source>
 	      <vendor id='0x1234'/>
@@ -401,20 +410,22 @@
 	    </source>
 	  </hostdev>
 	  ...</pre>
-
     <dl>
       <dt><code>hostdev</code></dt>
       <dd>The <code>hostdev</code> element is the main container for describing
-      host devices. For usb device passthrough <code>mode</code> is always
-      "subsystem" and <code>type</code> is "usb" for an USB device and "pci"
-      for a PCI device..
+      host devices. For USB or PCI device passthrough <code>mode</code> is always
+      "subsystem" and <code>type</code> is either "usb", "pci" or "nodedev".
       <dt><code>source</code></dt>
       <dd>The source element describes the device as seen from the host.
-      The USB device can either be addressed by vendor / product id using the
-      <code>vendor</code> and <code>product</code> elements or by the device's
-      address on the hosts using the <code>address</code> element.
-      PCI devices on the other hand can only be described by their
-      <code>address</code></dd>
+      With <code>type</code> "nodedev", USB and PCI devices can be described
+      using their node device name as listed by <code>virsh nodedev-list</code>.
+      Alternatively, USB devices can either be addressed by vendor / product id
+      using the <code>vendor</code> and <code>product</code> elements or by the
+      device's address on the hosts using the <code>address</code> element.
+      PCI devices can be described by their <code>address</code>.</dd>
+      <dt><code>nodedev</code></dt>
+      <dd>The <code>nodedev</code> element describes a USB or PCI device using
+      its node device name as listed by <code>virsh nodedev-list</code>.</dd>
       <dt><code>vendor</code>, <code>product</code></dt>
       <dd>The <code>vendor</code> and <code>product</code> elements each have an
       <code>id</code> attribute that specifies the USB vendor and product id.
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index 04f6e78..3dfbddb 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -909,6 +909,7 @@
           <choice>
 	    <value>usb</value>
 	    <value>pci</value>
+	    <value>nodedev</value>
           </choice>
         </attribute>
       </optional>
@@ -918,6 +919,7 @@
               <ref name="usbproduct"/>
               <ref name="usbaddress"/>
               <ref name="pciaddress"/>
+              <ref name="nodedev"/>
             </choice>
           </element>
       </group>
@@ -966,6 +968,14 @@
       </attribute>
     </element>
   </define>
+
+  <define name="nodedev">
+    <element name="nodedev">
+      <attribute name="name">
+        <ref name="genericName"/>
+      </attribute>
+    </element>
+  </define>
   <!--
       Devices attached to a domain.
     -->
diff --git a/src/domain_conf.c b/src/domain_conf.c
index 622665c..1ad52f1 100644
--- a/src/domain_conf.c
+++ b/src/domain_conf.c
@@ -149,7 +149,8 @@ VIR_ENUM_IMPL(virDomainHostdevMode, VIR_DOMAIN_HOSTDEV_MODE_LAST,
 
 VIR_ENUM_IMPL(virDomainHostdevSubsys, VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST,
               "usb",
-              "pci")
+              "pci",
+              "nodedev")
 
 VIR_ENUM_IMPL(virDomainState, VIR_DOMAIN_CRASHED+1,
               "nostate",
@@ -349,6 +350,10 @@ void virDomainHostdevDefFree(virDomainHostdevDefPtr def)
     if (!def)
         return;
 
+    if (def->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+        def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_NODEDEV)
+        VIR_FREE(def->source.subsys.u.nodedev_name);
+
     VIR_FREE(def->target);
     VIR_FREE(def);
 }
@@ -1721,6 +1726,38 @@ out:
     return ret;
 }
 
+static int
+virDomainHostdevSubsysNodedevDefParseXML(virConnectPtr conn,
+                                         const xmlNodePtr node,
+                                         virDomainHostdevDefPtr def) {
+
+    int ret = -1;
+    xmlNodePtr cur;
+
+    cur = node->children;
+    while (cur != NULL) {
+        if (cur->type == XML_ELEMENT_NODE) {
+            if (xmlStrEqual(cur->name, BAD_CAST "nodedev")) {
+                def->source.subsys.u.nodedev_name = virXMLPropString(cur, "name");
+                if (!def->source.subsys.u.nodedev_name) {
+                    virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+                                         _("missing node device name"));
+                    goto out;
+                }
+            } else {
+                virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+                                     _("unknown nodedev source type '%s'"),
+                                     cur->name);
+                goto out;
+            }
+        }
+        cur = cur->next;
+    }
+
+    ret = 0;
+out:
+    return ret;
+}
 
 static virDomainHostdevDefPtr
 virDomainHostdevDefParseXML(virConnectPtr conn,
@@ -1776,6 +1813,11 @@ virDomainHostdevDefParseXML(virConnectPtr conn,
                         if (virDomainHostdevSubsysPciDefParseXML(conn, cur, def) < 0)
                             goto error;
                 }
+                if (def->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+                    def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_NODEDEV) {
+                        if (virDomainHostdevSubsysNodedevDefParseXML(conn, cur, def) < 0)
+                            goto error;
+                }
             } else {
                 virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
                                      _("unknown node %s"), cur->name);
@@ -3178,7 +3220,10 @@ virDomainHostdevDefFormat(virConnectPtr conn,
     }
 
     type = virDomainHostdevSubsysTypeToString(def->source.subsys.type);
-    if (!type || (def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB && def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) ) {
+    if (!type ||
+        (def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB &&
+         def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
+         def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_NODEDEV) ) {
         virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
                              _("unexpected hostdev type %d"),
                              def->source.subsys.type);
@@ -3207,6 +3252,10 @@ virDomainHostdevDefFormat(virConnectPtr conn,
                           def->source.subsys.u.pci.slot,
                           def->source.subsys.u.pci.function);
     }
+    if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_NODEDEV) {
+        virBufferVSprintf(buf, "        <nodedev name='%s'/>\n",
+                          def->source.subsys.u.nodedev_name);
+    }
 
     virBufferAddLit(buf, "      </source>\n");
     virBufferAddLit(buf, "    </hostdev>\n");
diff --git a/src/domain_conf.h b/src/domain_conf.h
index b6f6b43..bde3417 100644
--- a/src/domain_conf.h
+++ b/src/domain_conf.h
@@ -297,6 +297,7 @@ enum virDomainHostdevMode {
 enum virDomainHostdevSubsysType {
     VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB,
     VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI,
+    VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_NODEDEV,
 
     VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST
 };
@@ -322,6 +323,7 @@ struct _virDomainHostdevDef {
                      unsigned slot;
                      unsigned function;
                 } pci;
+                char *nodedev_name;
             } u;
         } subsys;
         struct {
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-nodedev-name.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-nodedev-name.xml
new file mode 100644
index 0000000..96c6112
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-nodedev-name.xml
@@ -0,0 +1,27 @@
+<domain type='qemu'>
+  <name>QEMUGuest2</name>
+  <uuid>c7a5fdbd-edaf-9466-926a-d65c16db1809</uuid>
+  <memory>219200</memory>
+  <currentMemory>219200</currentMemory>
+  <vcpu>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest2'/>
+      <target dev='hda' bus='ide'/>
+    </disk>
+    <hostdev mode='subsystem' type='nodedev'>
+      <source>
+        <nodedev name='pci_8086_109a'/>
+      </source>
+    </hostdev>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 90b4740..9490d0b 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -245,6 +245,11 @@ mymain(int argc, char **argv)
 
     DO_TEST("hostdev-pci-address", 0);
 
+    /* Cannot resolve node device names here
+     *
+     *     DO_TEST("hostdev-nodedev-name", 0);
+     */
+
     DO_TEST_FULL("restore-v1", QEMUD_CMD_FLAG_MIGRATE_KVM_STDIO, "stdio");
     DO_TEST_FULL("restore-v2", QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC, "stdio");
     DO_TEST_FULL("restore-v2", QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC, "exec:cat");
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index ab9943d..5ccace8 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -130,6 +130,7 @@ mymain(int argc, char **argv)
     DO_TEST("hostdev-usb-product");
     DO_TEST("hostdev-usb-address");
     DO_TEST("hostdev-pci-address");
+    DO_TEST("hostdev-nodedev-name");
 
     virCapabilitiesFree(driver.caps);
 
-- 
1.6.0.6




More information about the libvir-list mailing list