[libvirt] [PATCH 2/5] qemu: define and parse USB redirection filter XML
Daniel P. Berrange
berrange at redhat.com
Wed Sep 12 15:26:46 UTC 2012
On Wed, Sep 12, 2012 at 04:35:47PM +0800, Guannan Ren wrote:
> https://bugzilla.redhat.com/show_bug.cgi?id=795929
> http://git.qemu.org/?p=qemu.git;a=commitdiff;h=6af165892cf900291046f1d25f95416f379504c2
>
> This patch define and parse the XML of USB redirection filter.
> <devices>
> ...
> <redirdev bus='usb' type='spicevmc'>
> <address type='usb' bus='0' port='4'/>
> </redirdev>
> <redirfilter>
> <usbdev class='0x08' vendor='0x1234' product='0xbeef' \
> version='2.00' allow='yes'/>
> <usbdev class='-1' vendor='-1' product='-1' version='-1' allow='no'/>
I find it a little odd to output XML which uses both hex
and decimal. If the value is '-1', then can't we just omit
the attribute entirely.
> </redirfilter>
> ...
> </devices>
>
> There is no 1:1 mapping between ports and redirected devices and
> qemu and spicy client couldn't decide into which usbredir ports
> the client can 'plug' redirected devices. So it make sense to apply
> all of filter rules global to all existing usb redirection devices.
> class attribute is USB Class codes. version is bcdDevice value
> of USB device. vendor and product is USB vendorId and productId.
> -1 can be used to allow any value for a field. Except allow attribute
> the other four are optional, default value is -1.
> ---
> src/conf/domain_conf.c | 346 +++++++++++++++++++++++++++++++++++++++++++++++++
> src/conf/domain_conf.h | 21 +++
> 2 files changed, 367 insertions(+)
>
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 8952b69..dc89eae 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -1438,6 +1438,20 @@ void virDomainRedirdevDefFree(virDomainRedirdevDefPtr def)
> VIR_FREE(def);
> }
>
> +void virDomainRedirFilterDefFree(virDomainRedirFilterDefPtr def)
> +{
> + int i;
s/int/size_t/;
> +
> + if (!def)
> + return;
> +
> + for (i = 0; i < def->nusbdevs; i++)
> + VIR_FREE(def->usbdevs[i]);
> +
> + VIR_FREE(def->usbdevs);
> + VIR_FREE(def);
> +}
> +
> void virDomainDeviceDefFree(virDomainDeviceDefPtr def)
> {
> if (!def)
> @@ -1674,6 +1688,8 @@ void virDomainDefFree(virDomainDefPtr def)
>
> virSysinfoDefFree(def->sysinfo);
>
> + virDomainRedirFilterDefFree(def->redirfilter);
> +
> if (def->namespaceData && def->ns.free)
> (def->ns.free)(def->namespaceData);
>
> +static virDomainRedirFilterDefPtr
> +virDomainRedirFilterDefParseXML(const xmlNodePtr node,
> + xmlXPathContextPtr ctxt)
> +{
> + int i, n;
i can be size_t, while n must remain signed.
> + xmlNodePtr *nodes = NULL;
> + xmlNodePtr save = ctxt->node;
> + virDomainRedirFilterDefPtr def = NULL;
> +
> + if (VIR_ALLOC(def) < 0)
> + goto no_memory;
> +
> + ctxt->node = node;
> + if ((n = virXPathNodeSet("./usbdev", ctxt, &nodes)) < 0) {
> + goto error;
> + }
> +
> + if (n && VIR_ALLOC_N(def->usbdevs, n) < 0)
> + goto no_memory;
> +
> + for (i = 0; i < n; i++) {
> + virDomainRedirFilterUsbDevDefPtr usbdev =
> + virDomainRedirFilterUsbDevDefParseXML(nodes[i]);
> +
> + if (!usbdev)
> + goto error;
> + def->usbdevs[def->nusbdevs++] = usbdev;
> + }
> + VIR_FREE(nodes);
> +
> + ctxt->node = save;
> + return def;
> +
> +no_memory:
> + virReportOOMError();
> +
> +error:
> + VIR_FREE(nodes);
> + virDomainRedirFilterDefFree(def);
> + return NULL;
> +}
> +
> static int virDomainLifecycleParseXML(xmlXPathContextPtr ctxt,
> const char *xpath,
> int *val,
> @@ -13019,6 +13321,47 @@ virDomainRedirdevDefFormat(virBufferPtr buf,
> }
>
> static int
> +virDomainRedirFilterDefFormat(virBufferPtr buf,
> + virDomainRedirFilterDefPtr filter)
> +{
> + int i;
size_t
> +
> + virBufferAddLit(buf, " <redirfilter>\n");
> + for (i = 0; i < filter->nusbdevs; i++) {
> + virDomainRedirFilterUsbDevDefPtr usbdev = filter->usbdevs[i];
> + virBufferAddLit(buf, " <usbdev");
> + if (usbdev->usbClass > 0)
> + virBufferAsprintf(buf, " class='0x%02X'", usbdev->usbClass);
> + else
> + virBufferAddLit(buf, " class='-1'");
> +
> + if (usbdev->vendor > 0)
> + virBufferAsprintf(buf, " vendor='0x%04X'", usbdev->vendor);
> + else
> + virBufferAddLit(buf, " vendor='-1'");
> +
> + if (usbdev->product > 0)
> + virBufferAsprintf(buf, " product='0x%04X'", usbdev->product);
> + else
> + virBufferAddLit(buf, " product='-1'");
> +
> + if (usbdev->version > 0)
> + virBufferAsprintf(buf, " version='%d.%d'",
> + ((usbdev->version & 0xf000) >> 12) * 10 +
> + ((usbdev->version & 0x0f00) >> 8),
> + ((usbdev->version & 0x00f0) >> 4) * 10 +
> + ((usbdev->version & 0x000f) >> 0));
> + else
> + virBufferAddLit(buf, " version='-1'");
> +
> + virBufferAsprintf(buf, " allow='%s'/>\n", usbdev->allow ? "yes" : "no");
> +
> + }
> + virBufferAddLit(buf, " </redirfilter>\n");
> + return 0;
> +}
> +
> +static int
> virDomainHubDefFormat(virBufferPtr buf,
> virDomainHubDefPtr def,
> unsigned int flags)
> @@ -13587,6 +13930,9 @@ virDomainDefFormatInternal(virDomainDefPtr def,
> +struct _virDomainRedirFilterUsbDevDef {
> + int usbClass;
> + int vendor;
> + int product;
> + int version;
> + unsigned int allow :1;
> +};
> +
> +struct _virDomainRedirFilterDef {
> + int nusbdevs;
size_t
> + virDomainRedirFilterUsbDevDefPtr *usbdevs;
> +};
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
More information about the libvir-list
mailing list