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 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list