[Pkg-libvirt-commits] [SCM] Libvirt Debian packaging branch, master, updated. debian/0.7.5-4

Guido Günther agx at sigxcpu.org
Wed Jan 13 23:12:15 UTC 2010


The following commit has been merged in the master branch:
commit 49c357cf5b681e0b7723e142e6bcfe2643915397
Author: Guido Günther <agx at sigxcpu.org>
Date:   Wed Jan 13 23:41:21 2010 +0100

    Implement path lookup for USB by vendor:product
    
    Thanks: Cole Robinson
    Closes: #563502

diff --git a/debian/patches/0007-Implement-path-lookup-for-USB-by-vendor-product.patch b/debian/patches/0007-Implement-path-lookup-for-USB-by-vendor-product.patch
new file mode 100644
index 0000000..957ff81
--- /dev/null
+++ b/debian/patches/0007-Implement-path-lookup-for-USB-by-vendor-product.patch
@@ -0,0 +1,307 @@
+From: Cole Robinson <crobinso at redhat.com>
+Date: Wed, 13 Jan 2010 15:50:05 -0500
+Subject: [PATCH] Implement path lookup for USB by vendor:product
+
+Based off how QEMU does it, look through /sys/bus/usb/devices/* for
+matching vendor:product info, and if found, use info from the surrounding
+files to build the device's /dev/bus/usb path.
+
+This fixes USB device assignment by vendor:product when running qemu
+as non-root (well, it should, but for some reason I couldn't reproduce
+the failure people are seeing in [1], but it appears to work properly)
+
+[1] https://bugzilla.redhat.com/show_bug.cgi?id=542450
+
+v2:
+    Drop 'bus.addr only' checks in security drivers
+    Use various util helpers
+
+Signed-off-by: Cole Robinson <crobinso at redhat.com>
+---
+ po/POTFILES.in                  |    1 +
+ src/qemu/qemu_driver.c          |    9 +--
+ src/security/security_selinux.c |   25 ++++-----
+ src/security/virt-aa-helper.c   |   32 +++++------
+ src/util/hostusb.c              |  110 +++++++++++++++++++++++++++++++++++++-
+ src/util/hostusb.h              |    4 +-
+ 6 files changed, 141 insertions(+), 40 deletions(-)
+
+diff --git a/po/POTFILES.in b/po/POTFILES.in
+index 1ab0859..22e9c3c 100644
+--- a/po/POTFILES.in
++++ b/po/POTFILES.in
+@@ -54,6 +54,7 @@ src/uml/uml_conf.c
+ src/uml/uml_driver.c
+ src/util/bridge.c
+ src/util/conf.c
++src/util/hostusb.c
+ src/util/json.c
+ src/util/logging.c
+ src/util/pci.c
+diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
+index a6a1a5a..7dfa78f 100644
+--- a/src/qemu/qemu_driver.c
++++ b/src/qemu/qemu_driver.c
+@@ -2099,14 +2099,11 @@ static int qemuDomainSetHostdevUSBOwnership(virConnectPtr conn,
+     struct qemuFileOwner owner = { uid, gid };
+     int ret = -1;
+ 
+-    /* XXX what todo for USB devs assigned based on product/vendor ? Doom :-( */
+-    if (!def->source.subsys.u.usb.bus ||
+-        !def->source.subsys.u.usb.device)
+-        return 0;
+-
+     usbDevice *dev = usbGetDevice(conn,
+                                   def->source.subsys.u.usb.bus,
+-                                  def->source.subsys.u.usb.device);
++                                  def->source.subsys.u.usb.device,
++                                  def->source.subsys.u.usb.vendor,
++                                  def->source.subsys.u.usb.product);
+ 
+     if (!dev)
+         goto cleanup;
+diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
+index 000bc8a..cb585ed 100644
+--- a/src/security/security_selinux.c
++++ b/src/security/security_selinux.c
+@@ -481,20 +481,17 @@ SELinuxSetSecurityHostdevLabel(virConnectPtr conn,
+ 
+     switch (dev->source.subsys.type) {
+     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
+-        if (dev->source.subsys.u.usb.bus && dev->source.subsys.u.usb.device) {
+-            usbDevice *usb = usbGetDevice(conn,
+-                                          dev->source.subsys.u.usb.bus,
+-                                          dev->source.subsys.u.usb.device);
++        usbDevice *usb = usbGetDevice(conn,
++                                      dev->source.subsys.u.usb.bus,
++                                      dev->source.subsys.u.usb.device,
++                                      dev->source.subsys.u.usb.vendor,
++                                      dev->source.subsys.u.usb.product);
+ 
+-            if (!usb)
+-                goto done;
++        if (!usb)
++            goto done;
+ 
+-            ret = usbDeviceFileIterate(conn, usb, SELinuxSetSecurityUSBLabel, vm);
+-            usbFreeDevice(conn, usb);
+-        } else {
+-            /* XXX deal with product/vendor better */
+-            ret = 0;
+-        }
++        ret = usbDeviceFileIterate(conn, usb, SELinuxSetSecurityUSBLabel, vm);
++        usbFreeDevice(conn, usb);
+         break;
+     }
+ 
+@@ -556,7 +553,9 @@ SELinuxRestoreSecurityHostdevLabel(virConnectPtr conn,
+     case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
+         usbDevice *usb = usbGetDevice(conn,
+                                       dev->source.subsys.u.usb.bus,
+-                                      dev->source.subsys.u.usb.device);
++                                      dev->source.subsys.u.usb.device,
++                                      dev->source.subsys.u.usb.vendor,
++                                      dev->source.subsys.u.usb.product);
+ 
+         if (!usb)
+             goto done;
+diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c
+index 35b29ad..3c8b49a 100644
+--- a/src/security/virt-aa-helper.c
++++ b/src/security/virt-aa-helper.c
+@@ -836,24 +836,22 @@ get_files(vahControl * ctl)
+             virDomainHostdevDefPtr dev = ctl->def->hostdevs[i];
+             switch (dev->source.subsys.type) {
+             case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB: {
+-                if (dev->source.subsys.u.usb.bus &&
+-                    dev->source.subsys.u.usb.device) {
+-                    usbDevice *usb = usbGetDevice(NULL,
+-                               dev->source.subsys.u.usb.bus,
+-                               dev->source.subsys.u.usb.device);
+-                    if (usb == NULL)
+-                        continue;
+-                    rc = usbDeviceFileIterate(NULL, usb,
+-                                              file_iterate_cb, &buf);
+-                    usbFreeDevice(NULL, usb);
+-                    if (rc != 0)
+-                        goto clean;
+-                    else {
+-                        /* TODO: deal with product/vendor better */
+-                        rc = 0;
+-                    }
+-                }
++                usbDevice *usb = usbGetDevice(NULL,
++                                          dev->source.subsys.u.usb.bus,
++                                          dev->source.subsys.u.usb.device,
++                                          dev->source.subsys.u.usb.vendor,
++                                          dev->source.subsys.u.usb.product);
++
++                if (usb == NULL)
++                    continue;
++
++                rc = usbDeviceFileIterate(NULL, usb,
++                                          file_iterate_cb, &buf);
++                usbFreeDevice(NULL, usb);
++                if (rc != 0)
++                    goto clean;
+                 break;
++                }
+             }
+ /* TODO: update so files in /sys are readonly
+             case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: {
+diff --git a/src/util/hostusb.c b/src/util/hostusb.c
+index 07e10b1..8fbb486 100644
+--- a/src/util/hostusb.c
++++ b/src/util/hostusb.c
+@@ -37,9 +37,10 @@
+ #include "util.h"
+ #include "virterror_internal.h"
+ 
++#define USB_SYSFS "/sys/bus/usb"
+ #define USB_DEVFS "/dev/bus/usb/"
+-#define USB_ID_LEN 10 /* "XXXX XXXX" */
+-#define USB_ADDR_LEN 8 /* "XXX:XXX" */
++#define USB_ID_LEN 10 /* "1234 5678" */
++#define USB_ADDR_LEN 8 /* "123:456" */
+ 
+ struct _usbDevice {
+     unsigned      bus;
+@@ -57,11 +58,108 @@ struct _usbDevice {
+     virReportErrorHelper(conn, VIR_FROM_NONE, code, __FILE__,  \
+                          __FUNCTION__, __LINE__, fmt)
+ 
++static int usbSysReadFile(virConnectPtr conn,
++                          const char *f_name, const char *d_name,
++                          int base, unsigned *value)
++{
++    int ret = -1, tmp;
++    char *buf = NULL;
++    char *filename = NULL;
++    char *ignore = NULL;
++
++    tmp = virAsprintf(&filename, USB_SYSFS "/devices/%s/%s", d_name, f_name);
++    if (tmp < 0) {
++        virReportOOMError(conn);
++        goto error;
++    }
++
++    if (virFileReadAll(filename, 1024, &buf) < 0)
++        goto error;
++
++    if (virStrToLong_ui(buf, &ignore, base, value) < 0) {
++        usbReportError(conn, VIR_ERR_INTERNAL_ERROR,
++                       _("Could not parse usb file %s"), filename);
++        goto error;
++    }
++
++    ret = 0;
++error:
++    VIR_FREE(filename);
++    VIR_FREE(buf);
++    return ret;
++}
++
++static int usbFindBusByVendor(virConnectPtr conn,
++                              unsigned vendor, unsigned product,
++                              unsigned *bus, unsigned *devno)
++{
++    DIR *dir = NULL;
++    int ret = -1, found = 0;
++    char *ignore = NULL;
++    struct dirent *de;
++
++    dir = opendir(USB_SYSFS "/devices");
++    if (!dir) {
++        virReportSystemError(conn, errno,
++                             _("Could not open directory %s"),
++                             USB_SYSFS "/devices");
++        goto error;
++    }
++
++    while ((de = readdir(dir))) {
++        unsigned found_prod, found_vend;
++        if (de->d_name[0] == '.' || strchr(de->d_name, ':'))
++            continue;
++
++        if (usbSysReadFile(conn, "idVendor", de->d_name,
++                           16, &found_vend) < 0)
++            goto error;
++        if (usbSysReadFile(conn, "idProduct", de->d_name,
++                           16, &found_prod) < 0)
++            goto error;
++
++        if (found_prod == product && found_vend == vendor) {
++            /* Lookup bus.addr info */
++            char *tmpstr = de->d_name;
++            unsigned found_bus, found_addr;
++
++            if (STREQ(de->d_name, "usb"))
++                tmpstr += 3;
++
++            if (virStrToLong_ui(tmpstr, &ignore, 10, &found_bus) < 0) {
++                usbReportError(conn, VIR_ERR_INTERNAL_ERROR,
++                               _("Failed to parse dir name '%s'"),
++                               de->d_name);
++                goto error;
++            }
++
++            if (usbSysReadFile(conn, "devnum", de->d_name,
++                               10, &found_addr) < 0)
++                goto error;
++
++            *bus = found_bus;
++            *devno = found_addr;
++            found = 1;
++            break;
++        }
++    }
++
++    if (!found)
++        usbReportError(conn, VIR_ERR_INTERNAL_ERROR,
++                       _("Did not find USB device %x:%x"), vendor, product);
++    else
++        ret = 0;
++
++error:
++    return ret;
++}
+ 
+ usbDevice *
+ usbGetDevice(virConnectPtr conn,
+              unsigned bus,
+-             unsigned devno)
++             unsigned devno,
++             unsigned vendor,
++             unsigned product)
+ {
+     usbDevice *dev;
+ 
+@@ -70,6 +168,12 @@ usbGetDevice(virConnectPtr conn,
+         return NULL;
+     }
+ 
++    if (vendor) {
++        /* Look up bus.dev by vendor:product */
++        if (usbFindBusByVendor(conn, vendor, product, &bus, &devno) < 0)
++            return NULL;
++    }
++
+     dev->bus     = bus;
+     dev->dev     = devno;
+ 
+diff --git a/src/util/hostusb.h b/src/util/hostusb.h
+index 7f75c8b..739a4aa 100644
+--- a/src/util/hostusb.h
++++ b/src/util/hostusb.h
+@@ -28,7 +28,9 @@ typedef struct _usbDevice usbDevice;
+ 
+ usbDevice *usbGetDevice      (virConnectPtr  conn,
+                               unsigned       bus,
+-                              unsigned       devno);
++                              unsigned       devno,
++                              unsigned       vendor,
++                              unsigned       product);
+ void       usbFreeDevice     (virConnectPtr  conn,
+                               usbDevice     *dev);
+ 
+-- 
diff --git a/debian/patches/series b/debian/patches/series
index aa4a9bd..54150d1 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -4,3 +4,4 @@
 0004-fix-Debian-specific-path-to-hvm-loader.patch
 0005-Also-look-for-dmi-information-in-sys-class.patch
 0006-Terminate-nc-on-EOF.patch
+0007-Implement-path-lookup-for-USB-by-vendor-product.patch

-- 
Libvirt Debian packaging



More information about the Pkg-libvirt-commits mailing list