<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'/>
</redirfilter>
will be converted to:
-device usb-redir,chardev=charredir0,id=redir0,\
filter=0x08:0x1234:0xBEEF:0x2000:1|-1:-1:-1:-1:0,bus=usb.0,port=4
---
src/qemu/qemu_command.c | 45 +++++++++++++++++++++++++++++++++++++++++++--
src/qemu/qemu_command.h | 5 +++--
src/qemu/qemu_hotplug.c | 3 ++-
3 files changed, 48 insertions(+), 5 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index a83d6de..208a57c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3437,10 +3437,13 @@ qemuBuildPCIHostdevPCIDevStr(virDomainHostdevDefPtr dev)
char *
-qemuBuildRedirdevDevStr(virDomainRedirdevDefPtr dev,
+qemuBuildRedirdevDevStr(virDomainDefPtr def,
+ virDomainRedirdevDefPtr dev,
virBitmapPtr qemuCaps)
{
+ int i;
virBuffer buf = VIR_BUFFER_INITIALIZER;
+ virDomainRedirFilterDefPtr redirfilter = def->redirfilter;
if (dev->bus != VIR_DOMAIN_REDIRDEV_BUS_USB) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -3460,6 +3463,44 @@ qemuBuildRedirdevDevStr(virDomainRedirdevDefPtr dev,
dev->info.alias,
dev->info.alias);
+ if (redirfilter && redirfilter->nusbdevs) {
+ if (!qemuCapsGet(qemuCaps, QEMU_CAPS_USB_REDIR_FILTER)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("USB redirection filter is not "
+ "supported by this version of QEMU"));
+ goto error;
+ }
+
+ virBufferAsprintf(&buf, ",filter=");
+
+ for (i = 0; i < redirfilter->nusbdevs; i++) {
+ virDomainRedirFilterUsbDevDefPtr usbdev = redirfilter->usbdevs[i];
+ if (usbdev->usbClass > 0)
+ virBufferAsprintf(&buf, "0x%02X:", usbdev->usbClass);
+ else
+ virBufferAsprintf(&buf, "-1:");
+
+ if (usbdev->vendor > 0)
+ virBufferAsprintf(&buf, "0x%04X:", usbdev->vendor);
+ else
+ virBufferAsprintf(&buf, "-1:");
+
+ if (usbdev->product > 0)
+ virBufferAsprintf(&buf, "0x%04X:", usbdev->product);
+ else
+ virBufferAsprintf(&buf, "-1:");
+
+ if (usbdev->version > 0)
+ virBufferAsprintf(&buf, "0x%04X:", usbdev->version);
+ else
+ virBufferAsprintf(&buf, "-1:");
+
+ virBufferAsprintf(&buf, "%u", usbdev->allow);
+ if (i < redirfilter->nusbdevs -1)
+ virBufferAsprintf(&buf, "|");
+ }
+ }
+
if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0)
goto error;
@@ -6274,7 +6315,7 @@ qemuBuildCommandLine(virConnectPtr conn,
goto error;
virCommandAddArg(cmd, "-device");
- if (!(devstr = qemuBuildRedirdevDevStr(redirdev, qemuCaps)))
+ if (!(devstr = qemuBuildRedirdevDevStr(def, redirdev, qemuCaps)))
goto error;
virCommandAddArg(cmd, devstr);
VIR_FREE(devstr);
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index 7c5e8dd..2332431 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -139,8 +139,9 @@ char * qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev,
virBitmapPtr qemuCaps);
char * qemuBuildHubDevStr(virDomainHubDefPtr dev, virBitmapPtr qemuCaps);
-char * qemuBuildRedirdevDevStr(virDomainRedirdevDefPtr dev, virBitmapPtr qemuCaps);
-
+char * qemuBuildRedirdevDevStr(virDomainDefPtr def,
+ virDomainRedirdevDefPtr dev,
+ virBitmapPtr qemuCaps);
int qemuNetworkIfaceConnect(virDomainDefPtr def,
virConnectPtr conn,
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index a8a904c..0b2596f 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1022,12 +1022,13 @@ int qemuDomainAttachRedirdevDevice(struct qemud_driver *driver,
{
int ret;
qemuDomainObjPrivatePtr priv = vm->privateData;
+ virDomainDefPtr def = vm->def;
char *devstr = NULL;
if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
if (qemuAssignDeviceRedirdevAlias(vm->def, redirdev, -1) < 0)
goto error;
- if (!(devstr = qemuBuildRedirdevDevStr(redirdev, priv->qemuCaps)))
+ if (!(devstr = qemuBuildRedirdevDevStr(def, redirdev, priv->qemuCaps)))
goto error;
}
--
1.7.11.2