[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