
On 5/11/21 12:16 PM, Kristina Hanicova wrote:
Signed-off-by: Kristina Hanicova <khanicov@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