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=6af165892cf900291046f1d25f...
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 :|