[PATCH v2 2/3] conf: Parse/format XML input type 'evdev'

Michal Prívozník mprivozn at redhat.com
Wed May 19 14:11:01 UTC 2021


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




More information about the libvir-list mailing list