On 5/11/21 12:16 PM, Kristina Hanicova wrote:
Signed-off-by: Kristina Hanicova <khanicov(a)redhat.com>
---
docs/formatdomain.rst | 37 ++++++++-----
docs/schemas/domaincommon.rng | 20 +++++++
src/conf/domain_audit.c | 1 +
src/conf/domain_conf.c | 66 ++++++++++++++++++++----
src/conf/domain_conf.h | 12 +++++
src/conf/domain_validate.c | 8 +++
src/libvirt_private.syms | 2 +
src/qemu/qemu_cgroup.c | 2 +
src/qemu/qemu_command.c | 1 +
src/qemu/qemu_domain_address.c | 1 +
src/qemu/qemu_hotplug.c | 1 +
src/qemu/qemu_validate.c | 6 +++
src/security/security_apparmor.c | 1 +
src/security/security_dac.c | 2 +
src/security/security_selinux.c | 2 +
src/security/virt-aa-helper.c | 3 +-
tests/qemuxml2argvdata/input-linux.xml | 24 +++++++++
tests/qemuxml2xmloutdata/input-linux.xml | 1 +
18 files changed, 167 insertions(+), 23 deletions(-)
create mode 100644 tests/qemuxml2argvdata/input-linux.xml
create mode 120000 tests/qemuxml2xmloutdata/input-linux.xml
index e8632e4d73..299b600e24 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -12021,12 +12032,36 @@
virDomainInputDefParseXML(virDomainXMLOption *xmlopt,
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;
+ if ((source = virXPathNode("./source", ctxt))) {
+ g_autofree char *evdev = NULL;
+
+ if (def->type == VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH)
+ evdev = virXMLPropString(source, "evdev");
+ else if (def->type == VIR_DOMAIN_INPUT_TYPE_EVDEV)
+ evdev = virXMLPropString(source, "dev");
So here you parse <source dev=... />
+
+ if (evdev)
+ def->source.evdev = virFileSanitizePath(evdev);
+
+ if (def->type == VIR_DOMAIN_INPUT_TYPE_PASSTHROUGH ||
+ def->type == VIR_DOMAIN_INPUT_TYPE_EVDEV) {
+ if (!def->source.evdev) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("Missing evdev path for input device"));
+ goto error;
+ }
+ }
+
+ if (def->type == VIR_DOMAIN_INPUT_TYPE_EVDEV) {
+ if (virXMLPropEnum(source, "grab",
+ virDomainInputSourceGrabTypeFromString,
+ VIR_XML_PROP_NONZERO, &def->source.grab) < 0)
+ goto error;
+
+ if (virXMLPropTristateSwitch(source, "repeat",
+ VIR_XML_PROP_NONE, &def->source.repeat)
< 0)
+ goto error;
+ }
}
if (virDomainVirtioOptionsParseXML(virXPathNode("./driver", ctxt),
@@ -26076,9 +26111,12 @@ virDomainInputDefFormat(virBuffer *buf,
{
const char *type = virDomainInputTypeToString(def->type);
const char *bus = virDomainInputBusTypeToString(def->bus);
+ const char *grab = virDomainInputSourceGrabTypeToString(def->source.grab);
+ const char *repeat = virTristateSwitchTypeToString(def->source.repeat);
g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER;
g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf);
g_auto(virBuffer) driverAttrBuf = VIR_BUFFER_INITIALIZER;
+ g_auto(virBuffer) sourceAttrBuf = VIR_BUFFER_INITIALIZER;
/* don't format keyboard into migratable XML for backward compatibility */
if (flags & VIR_DOMAIN_DEF_FORMAT_MIGRATABLE &&
@@ -26098,7 +26136,9 @@ virDomainInputDefFormat(virBuffer *buf,
return -1;
}
- virBufferAsprintf(&attrBuf, " type='%s' bus='%s'",
type, bus);
+ virBufferAsprintf(&attrBuf, " type='%s'", type);
+ if (def->bus != VIR_DOMAIN_INPUT_BUS_NONE)
+ virBufferAsprintf(&attrBuf, " bus='%s'", bus);
if (def->model) {
const char *model = virDomainInputModelTypeToString(def->model);
@@ -26116,7 +26156,15 @@ virDomainInputDefFormat(virBuffer *buf,
virXMLFormatElement(&childBuf, "driver", &driverAttrBuf, NULL);
- virBufferEscapeString(&childBuf, "<source
evdev='%s'/>\n", def->source.evdev);
+ virBufferEscapeString(&sourceAttrBuf, " evdev='%s'",
def->source.evdev);
But here you format <source evdev=... />. What you can do is to format
dev=... here if def->type == VIR_DOMAIN_INPUT_TYPE_EVDEV, and format
evdev=... otherwise. Alternatively, you can stick with 'evdev' name even
for _TYPE_EVDEV (will require slightly more changes - to docs, RNG, XML,
...). Your call.
+
+ if (def->source.grab)
+ virBufferAsprintf(&sourceAttrBuf, " grab='%s'", grab);
+ if (def->source.repeat)
+ virBufferAsprintf(&sourceAttrBuf, " repeat='%s'",
repeat);
+
+ virXMLFormatElement(&childBuf, "source", &sourceAttrBuf, NULL);
+
virDomainDeviceInfoFormat(&childBuf, &def->info, flags);
virXMLFormatElement(buf, "input", &attrBuf, &childBuf);
Also, you are introducing qemuxml2xml test case file but not modifying
qemuxml2xmltest.c itself.
Michal