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