[libvirt] [PATCH 5/8] conf: add XML for input device passthrough

Ján Tomko jtomko at redhat.com
Fri Nov 20 08:59:40 UTC 2015


Add xml for the new virtio-input-host-pci device:
<input type='passthrough' bus='virtio'>
  <source evdev='/dev/input/event1234'/>
</input>

https://bugzilla.redhat.com/show_bug.cgi?id=1231114
---
 docs/formatdomain.html.in                          | 12 +++++-
 docs/schemas/domaincommon.rng                      | 49 +++++++++++++++-------
 src/conf/domain_conf.c                             | 28 +++++++++++--
 src/conf/domain_conf.h                             |  4 ++
 src/qemu/qemu_command.c                            |  2 +
 .../qemuxml2argv-virtio-input-passthrough.xml      | 24 +++++++++++
 tests/qemuxml2xmltest.c                            |  1 +
 7 files changed, 98 insertions(+), 22 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-virtio-input-passthrough.xml

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index d334071..241ed2d 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -4804,14 +4804,18 @@ qemu-kvm -net nic,model=? /dev/null
     <input type='mouse' bus='virtio'/>
     <input type='keyboard' bus='virtio'/>
     <input type='tablet' bus='virtio'/>
+    <input type='passthrough' bus='virtio'>
+      <source evdev='/dev/input/event1/>
+    </input>
   </devices>
   ...</pre>
 
     <dl>
       <dt><code>input</code></dt>
       <dd>The <code>input</code> element has one mandatory attribute,
-        the <code>type</code> whose value can be 'mouse', 'tablet' or
-        (<span class="since">since 1.2.2</span>) 'keyboard'.
+        the <code>type</code> whose value can be 'mouse', 'tablet',
+        (<span class="since">since 1.2.2</span>) 'keyboard' or
+        (<span class="since">since 1.3.0</span>) 'passthrough'.
         The tablet provides absolute cursor movement,
         while the mouse uses relative movement. The optional
         <code>bus</code> attribute can be used to refine the exact device type.
@@ -4824,6 +4828,10 @@ qemu-kvm -net nic,model=? /dev/null
       sub-element <code><address></code> which can tie the
       device to a particular PCI
       slot, <a href="#elementsAddress">documented above</a>.
+
+      For type <code>passthrough</code>, the mandatory sub-element <code>source</code>
+      must have an <code>evdev</code> attribute containing the absolute path to the
+      event device passed through to guests. (KVM only)
     </p>
 
     <h4><a name="elementsHub">Hub devices</a></h4>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index b740db8..2fb4d3f 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -3578,23 +3578,40 @@
 
   <define name="input">
     <element name="input">
-      <attribute name="type">
-        <choice>
-          <value>tablet</value>
-          <value>mouse</value>
-          <value>keyboard</value>
-        </choice>
-      </attribute>
-      <optional>
-        <attribute name="bus">
-          <choice>
-            <value>ps2</value>
-            <value>usb</value>
-            <value>xen</value>
+      <choice>
+        <group>
+          <attribute name="type">
+            <choice>
+              <value>tablet</value>
+              <value>mouse</value>
+              <value>keyboard</value>
+            </choice>
+          </attribute>
+          <optional>
+            <attribute name="bus">
+              <choice>
+                <value>ps2</value>
+                <value>usb</value>
+                <value>xen</value>
+                <value>virtio</value>
+              </choice>
+            </attribute>
+          </optional>
+        </group>
+        <group>
+          <attribute name="type">
+            <value>passthrough</value>
+          </attribute>
+          <attribute name="bus">
             <value>virtio</value>
-          </choice>
-        </attribute>
-      </optional>
+          </attribute>
+          <element name="source">
+            <attribute name="evdev">
+              <ref name="absFilePath"/>
+            </attribute>
+          </element>
+        </group>
+      </choice>
       <optional>
         <ref name="alias"/>
       </optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 419bfb9..d8ac349 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -537,7 +537,8 @@ VIR_ENUM_IMPL(virDomainVideo, VIR_DOMAIN_VIDEO_TYPE_LAST,
 VIR_ENUM_IMPL(virDomainInput, VIR_DOMAIN_INPUT_TYPE_LAST,
               "mouse",
               "tablet",
-              "keyboard")
+              "keyboard",
+              "passthrough")
 
 VIR_ENUM_IMPL(virDomainInputBus, VIR_DOMAIN_INPUT_BUS_LAST,
               "ps2",
@@ -1409,6 +1410,7 @@ void virDomainInputDefFree(virDomainInputDefPtr def)
         return;
 
     virDomainDeviceInfoClear(&def->info);
+    VIR_FREE(def->source.evdev);
     VIR_FREE(def);
 }
 
@@ -10215,15 +10217,20 @@ virDomainPanicDefParseXML(xmlNodePtr node)
 static virDomainInputDefPtr
 virDomainInputDefParseXML(const virDomainDef *dom,
                           xmlNodePtr node,
+                          xmlXPathContextPtr ctxt,
                           unsigned int flags)
 {
+    xmlNodePtr save = ctxt->node;
     virDomainInputDefPtr def;
+    char *evdev = NULL;
     char *type = NULL;
     char *bus = NULL;
 
     if (VIR_ALLOC(def) < 0)
         return NULL;
 
+    ctxt->node = node;
+
     type = virXMLPropString(node, "type");
     bus = virXMLPropString(node, "bus");
 
@@ -10330,10 +10337,20 @@ virDomainInputDefParseXML(const virDomainDef *dom,
         goto error;
     }
 
+    if ((evdev = virXPathString("string(./source/@evdev)", ctxt)))
+        def->source.evdev = virFileSanitizePath(evdev);
+    if (def->type == VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH && !def->source.evdev) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("Missing evdev path for input device passthrough"));
+        goto error;
+    }
+
  cleanup:
+    VIR_FREE(evdev);
     VIR_FREE(type);
     VIR_FREE(bus);
 
+    ctxt->node = save;
     return def;
 
  error:
@@ -12684,8 +12701,8 @@ virDomainDeviceDefParse(const char *xmlStr,
             goto error;
         break;
     case VIR_DOMAIN_DEVICE_INPUT:
-        if (!(dev->data.input = virDomainInputDefParseXML(def,
-                                                          node, flags)))
+        if (!(dev->data.input = virDomainInputDefParseXML(def, node,
+                                                          ctxt, flags)))
             goto error;
         break;
     case VIR_DOMAIN_DEVICE_SOUND:
@@ -16068,6 +16085,7 @@ virDomainDefParseXML(xmlDocPtr xml,
     for (i = 0; i < n; i++) {
         virDomainInputDefPtr input = virDomainInputDefParseXML(def,
                                                                nodes[i],
+                                                               ctxt,
                                                                flags);
         if (!input)
             goto error;
@@ -20919,9 +20937,11 @@ virDomainInputDefFormat(virBufferPtr buf,
     virBufferAsprintf(buf, "<input type='%s' bus='%s'",
                       type, bus);
 
-    if (virDomainDeviceInfoNeedsFormat(&def->info, flags)) {
+    if (virDomainDeviceInfoNeedsFormat(&def->info, flags) ||
+        def->type == VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH) {
         virBufferAddLit(buf, ">\n");
         virBufferAdjustIndent(buf, 2);
+        virBufferEscapeString(buf, "<source evdev='%s'/>\n", def->source.evdev);
         if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
             return -1;
         virBufferAdjustIndent(buf, -2);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 81c546d..4ad41e6 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1288,6 +1288,7 @@ typedef enum {
     VIR_DOMAIN_INPUT_TYPE_MOUSE,
     VIR_DOMAIN_INPUT_TYPE_TABLET,
     VIR_DOMAIN_INPUT_TYPE_KBD,
+    VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH,
 
     VIR_DOMAIN_INPUT_TYPE_LAST
 } virDomainInputType;
@@ -1305,6 +1306,9 @@ typedef enum {
 struct _virDomainInputDef {
     int type;
     int bus;
+    struct {
+        char *evdev;
+    } source;
     virDomainDeviceInfo info;
 };
 
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 570904a..5815734 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5773,6 +5773,8 @@ qemuBuildVirtioInputDevStr(virDomainDefPtr def,
         }
         virBufferAsprintf(&buf, "virtio-keyboard%s,id=%s", suffix, dev->info.alias);
         break;
+    case VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH:
+        /* TBD */
     case VIR_DOMAIN_INPUT_TYPE_LAST:
         break;
     }
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-virtio-input-passthrough.xml b/tests/qemuxml2argvdata/qemuxml2argv-virtio-input-passthrough.xml
new file mode 100644
index 0000000..e2bf063
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-virtio-input-passthrough.xml
@@ -0,0 +1,24 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>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>
+    <controller type='usb' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <input type='passthrough' bus='virtio'>
+      <source evdev='/dev/input/event1234'/>
+    </input>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 535dfb8..9b47ce0 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -627,6 +627,7 @@ mymain(void)
     DO_TEST("net-udp");
 
     DO_TEST("virtio-input");
+    DO_TEST("virtio-input-passthrough");
 
     qemuTestDriverFree(&driver);
 
-- 
2.4.6




More information about the libvir-list mailing list