]> xenbits.xensource.com Git - libvirt.git/commitdiff
Rename hostusb.{c,h} to virusb.{c,h}
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 12 Dec 2012 17:04:51 +0000 (17:04 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Fri, 21 Dec 2012 11:17:13 +0000 (11:17 +0000)
17 files changed:
po/POTFILES.in
src/Makefile.am
src/lxc/lxc_cgroup.h
src/lxc/lxc_conf.h
src/lxc/lxc_container.c
src/qemu/qemu_cgroup.h
src/qemu/qemu_conf.h
src/qemu/qemu_driver.c
src/qemu/qemu_hostdev.c
src/security/security_apparmor.c
src/security/security_dac.c
src/security/security_selinux.c
src/security/virt-aa-helper.c
src/util/hostusb.c [deleted file]
src/util/hostusb.h [deleted file]
src/util/virusb.c [new file with mode: 0644]
src/util/virusb.h [new file with mode: 0644]

index be3f5d8b8d1c6e517b71b5ee4419463c6f9c6ab0..cc595b177911a8e048e2439bbb42b3a97339e485 100644 (file)
@@ -138,7 +138,6 @@ src/storage/storage_driver.c
 src/test/test_driver.c
 src/uml/uml_conf.c
 src/uml/uml_driver.c
-src/util/hostusb.c
 src/util/iohelper.c
 src/util/iptables.c
 src/util/json.c
@@ -182,6 +181,7 @@ src/util/virterror_internal.h
 src/util/virtime.c
 src/util/virtypedparam.c
 src/util/viruri.c
+src/util/virusb.c
 src/util/xml.c
 src/vbox/vbox_MSCOMGlue.c
 src/vbox/vbox_XPCOMCGlue.c
index 5df6fff0b8e6671e6947c45786d362fa79f552bb..322998705e93ce3223708722c7470c51cbec9351 100644 (file)
@@ -59,7 +59,6 @@ UTIL_SOURCES =                                                        \
                util/memory.c util/memory.h                     \
                util/pci.c util/pci.h                           \
                util/processinfo.c util/processinfo.h           \
-               util/hostusb.c util/hostusb.h                   \
                util/sexpr.c util/sexpr.h                       \
                util/stats_linux.c util/stats_linux.h           \
                util/storage_file.c util/storage_file.h         \
@@ -116,6 +115,7 @@ UTIL_SOURCES =                                                      \
                util/virsocketaddr.h util/virsocketaddr.c \
                util/virstring.h util/virstring.c \
                util/virtime.h util/virtime.c \
+               util/virusb.c util/virusb.h                     \
                util/viruri.h util/viruri.c
 
 EXTRA_DIST += $(srcdir)/util/virkeymaps.h $(srcdir)/util/keymaps.csv \
index c1d4551285a11b0d643e9cbc4374c9ec5676cfda..97b94e57253da9806ee423a87ffe3be399be1708 100644 (file)
@@ -24,7 +24,7 @@
 
 # include "domain_conf.h"
 # include "lxc_fuse.h"
-# include "hostusb.h"
+# include "virusb.h"
 
 int virLXCCgroupSetup(virDomainDefPtr def);
 int virLXCCgroupGetMeminfo(virLXCMeminfoPtr meminfo);
index a9c337e6aafd04855988cb7d89214b60acccfbf2..70d47a4cae770dfcc0acefe8c5f41c5ace4824fb 100644 (file)
@@ -35,7 +35,7 @@
 # include "vircgroup.h"
 # include "security/security_manager.h"
 # include "configmake.h"
-# include "hostusb.h"
+# include "virusb.h"
 
 # define LXC_DRIVER_NAME "LXC"
 
index 0c4e676ba22976fd88c7f62ac440edf1bec18610..717811f3afb24f534bbcb54bbbda3f4ec0709c7c 100644 (file)
@@ -61,7 +61,7 @@
 #include "virnetdevveth.h"
 #include "uuid.h"
 #include "virfile.h"
-#include "hostusb.h"
+#include "virusb.h"
 #include "vircommand.h"
 #include "virnetdev.h"
 #include "virprocess.h"
index e212581bb7ad089fe01c343e6d74a8e535607622..75ef514a3b84a905f5e4bbb27c5c910dda20dafd 100644 (file)
@@ -24,7 +24,7 @@
 #ifndef __QEMU_CGROUP_H__
 # define __QEMU_CGROUP_H__
 
-# include "hostusb.h"
+# include "virusb.h"
 # include "domain_conf.h"
 # include "qemu_conf.h"
 
index 5499203272771d3b4edd77ffc562902b1867881f..283251a430f252d9d3f9467842fefcf83fe9d240 100644 (file)
@@ -36,7 +36,7 @@
 # include "security/security_manager.h"
 # include "vircgroup.h"
 # include "pci.h"
-# include "hostusb.h"
+# include "virusb.h"
 # include "cpu_conf.h"
 # include "driver.h"
 # include "virbitmap.h"
index a499cb51af80f8aced49fd03b857490438734d01..477c20883444403a0d2cc1369fccce4bcfdc8fea 100644 (file)
@@ -72,7 +72,7 @@
 #include "domain_audit.h"
 #include "node_device_conf.h"
 #include "pci.h"
-#include "hostusb.h"
+#include "virusb.h"
 #include "processinfo.h"
 #include "libvirt_internal.h"
 #include "xml.h"
index 57c5a711604e323f4c85bd7d016eae92d35440bc..08094d1cdbf71a42bc05d0aed41dc0bc777cb758 100644 (file)
@@ -28,7 +28,7 @@
 #include "virterror_internal.h"
 #include "memory.h"
 #include "pci.h"
-#include "hostusb.h"
+#include "virusb.h"
 #include "virnetdev.h"
 
 #define VIR_FROM_THIS VIR_FROM_QEMU
index fff1bdcdee41b1378f48cc4e5bc1b7de3a79a52a..2b3a2e20fc5535561b3d27e4365382b85fac62f6 100644 (file)
@@ -44,7 +44,7 @@
 #include "datatypes.h"
 #include "uuid.h"
 #include "pci.h"
-#include "hostusb.h"
+#include "virusb.h"
 #include "virfile.h"
 #include "configmake.h"
 #include "vircommand.h"
index 2861725cdb7637d79f4f75652a68890174f9885b..8ad61d74a9fbcaad58a7107c79503788ed406075 100644 (file)
@@ -29,7 +29,7 @@
 #include "memory.h"
 #include "logging.h"
 #include "pci.h"
-#include "hostusb.h"
+#include "virusb.h"
 #include "storage_file.h"
 
 #define VIR_FROM_THIS VIR_FROM_SECURITY
index 4456a20c2c3cb94a3340d97f35a006ab63937f5f..8ac647309d02b01a180d0c436f7830a43ad7b5e1 100644 (file)
@@ -38,7 +38,7 @@
 #include "memory.h"
 #include "logging.h"
 #include "pci.h"
-#include "hostusb.h"
+#include "virusb.h"
 #include "storage_file.h"
 #include "virfile.h"
 #include "virhash.h"
index 00e880ea37fe1c6f8ffaedda616b756d806a13e5..cedffbd60c808830d5506d19f2ee239836b73ed5 100644 (file)
@@ -50,7 +50,7 @@
 #include "domain_conf.h"
 #include "xml.h"
 #include "uuid.h"
-#include "hostusb.h"
+#include "virusb.h"
 #include "pci.h"
 #include "virfile.h"
 #include "configmake.h"
diff --git a/src/util/hostusb.c b/src/util/hostusb.c
deleted file mode 100644 (file)
index 2eb80a0..0000000
+++ /dev/null
@@ -1,514 +0,0 @@
-/*
- * Copyright (C) 2009-2012 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * Authors:
- *     Daniel P. Berrange <berrange@redhat.com>
- */
-
-#include <config.h>
-
-#include <dirent.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "hostusb.h"
-#include "logging.h"
-#include "memory.h"
-#include "util.h"
-#include "virterror_internal.h"
-
-#define USB_SYSFS "/sys/bus/usb"
-#define USB_ID_LEN 10 /* "1234 5678" */
-#define USB_ADDR_LEN 8 /* "123:456" */
-
-/* For virReportOOMError()  and virReportSystemError() */
-#define VIR_FROM_THIS VIR_FROM_NONE
-
-struct _usbDevice {
-    unsigned int      bus;
-    unsigned int      dev;
-
-    char          name[USB_ADDR_LEN]; /* domain:bus:slot.function */
-    char          id[USB_ID_LEN];     /* product vendor */
-    char          *path;
-    const char    *used_by;           /* name of the domain using this dev */
-};
-
-struct _usbDeviceList {
-    unsigned int count;
-    usbDevice **devs;
-};
-
-typedef enum {
-    USB_DEVICE_ALL = 0,
-    USB_DEVICE_FIND_BY_VENDOR = 1 << 0,
-    USB_DEVICE_FIND_BY_BUS = 1 << 1,
-} usbDeviceFindFlags;
-
-static int usbSysReadFile(const char *f_name, const char *d_name,
-                          int base, unsigned int *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();
-        goto cleanup;
-    }
-
-    if (virFileReadAll(filename, 1024, &buf) < 0)
-        goto cleanup;
-
-    if (virStrToLong_ui(buf, &ignore, base, value) < 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Could not parse usb file %s"), filename);
-        goto cleanup;
-    }
-
-    ret = 0;
-cleanup:
-    VIR_FREE(filename);
-    VIR_FREE(buf);
-    return ret;
-}
-
-static usbDeviceList *
-usbDeviceSearch(unsigned int vendor,
-                unsigned int product,
-                unsigned int bus,
-                unsigned int devno,
-                const char *vroot,
-                unsigned int flags)
-{
-    DIR *dir = NULL;
-    bool found = false;
-    char *ignore = NULL;
-    struct dirent *de;
-    usbDeviceList *list = NULL, *ret = NULL;
-    usbDevice *usb;
-
-    if (!(list = usbDeviceListNew()))
-        goto cleanup;
-
-    dir = opendir(USB_SYSFS "/devices");
-    if (!dir) {
-        virReportSystemError(errno,
-                             _("Could not open directory %s"),
-                             USB_SYSFS "/devices");
-        goto cleanup;
-    }
-
-    while ((de = readdir(dir))) {
-        unsigned int found_prod, found_vend, found_bus, found_devno;
-        char *tmpstr = de->d_name;
-
-        if (de->d_name[0] == '.' || strchr(de->d_name, ':'))
-            continue;
-
-        if (usbSysReadFile("idVendor", de->d_name,
-                           16, &found_vend) < 0)
-            goto cleanup;
-
-        if (usbSysReadFile("idProduct", de->d_name,
-                           16, &found_prod) < 0)
-            goto cleanup;
-
-        if (STRPREFIX(de->d_name, "usb"))
-            tmpstr += 3;
-
-        if (virStrToLong_ui(tmpstr, &ignore, 10, &found_bus) < 0) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("Failed to parse dir name '%s'"),
-                           de->d_name);
-            goto cleanup;
-        }
-
-        if (usbSysReadFile("devnum", de->d_name,
-                           10, &found_devno) < 0)
-            goto cleanup;
-
-        if ((flags & USB_DEVICE_FIND_BY_VENDOR) &&
-            (found_prod != product || found_vend != vendor))
-            continue;
-
-        if (flags & USB_DEVICE_FIND_BY_BUS) {
-            if (found_bus != bus || found_devno != devno)
-                continue;
-            found = true;
-        }
-
-        usb = usbGetDevice(found_bus, found_devno, vroot);
-        if (!usb)
-            goto cleanup;
-
-        if (usbDeviceListAdd(list, usb) < 0) {
-            usbFreeDevice(usb);
-            goto cleanup;
-        }
-
-        if (found)
-            break;
-    }
-    ret = list;
-
-cleanup:
-    if (dir) {
-        int saved_errno = errno;
-        closedir(dir);
-        errno = saved_errno;
-    }
-
-    if (!ret)
-        usbDeviceListFree(list);
-    return ret;
-}
-
-int
-usbFindDeviceByVendor(unsigned int vendor,
-                      unsigned product,
-                      const char *vroot,
-                      bool mandatory,
-                      usbDeviceList **devices)
-{
-    usbDeviceList *list;
-    int count;
-
-    if (!(list = usbDeviceSearch(vendor, product, 0 , 0,
-                                 vroot,
-                                 USB_DEVICE_FIND_BY_VENDOR)))
-        return -1;
-
-    if (list->count == 0) {
-        usbDeviceListFree(list);
-        if (!mandatory) {
-            VIR_DEBUG("Did not find USB device %x:%x",
-                      vendor, product);
-            if (devices)
-                *devices = NULL;
-            return 0;
-        }
-
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Did not find USB device %x:%x"), vendor, product);
-        return -1;
-    }
-
-    count = list->count;
-    if (devices)
-        *devices = list;
-    else
-        usbDeviceListFree(list);
-
-    return count;
-}
-
-int
-usbFindDeviceByBus(unsigned int bus,
-                   unsigned devno,
-                   const char *vroot,
-                   bool mandatory,
-                   usbDevice **usb)
-{
-    usbDeviceList *list;
-
-    if (!(list = usbDeviceSearch(0, 0, bus, devno,
-                                 vroot,
-                                 USB_DEVICE_FIND_BY_BUS)))
-        return -1;
-
-    if (list->count == 0) {
-        usbDeviceListFree(list);
-        if (!mandatory) {
-            VIR_DEBUG("Did not find USB device bus:%u device:%u",
-                      bus, devno);
-            if (usb)
-                *usb = NULL;
-            return 0;
-        }
-
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Did not find USB device bus:%u device:%u"),
-                       bus, devno);
-        return -1;
-    }
-
-    if (usb) {
-        *usb = usbDeviceListGet(list, 0);
-        usbDeviceListSteal(list, *usb);
-    }
-    usbDeviceListFree(list);
-
-    return 0;
-}
-
-int
-usbFindDevice(unsigned int vendor,
-              unsigned int product,
-              unsigned int bus,
-              unsigned int devno,
-              const char *vroot,
-              bool mandatory,
-              usbDevice **usb)
-{
-    usbDeviceList *list;
-
-    unsigned int flags = USB_DEVICE_FIND_BY_VENDOR|USB_DEVICE_FIND_BY_BUS;
-    if (!(list = usbDeviceSearch(vendor, product, bus, devno,
-                                 vroot, flags)))
-        return -1;
-
-    if (list->count == 0) {
-        usbDeviceListFree(list);
-        if (!mandatory) {
-            VIR_DEBUG("Did not find USB device %x:%x bus:%u device:%u",
-                      vendor, product, bus, devno);
-            if (usb)
-                *usb = NULL;
-            return 0;
-        }
-
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Did not find USB device %x:%x bus:%u device:%u"),
-                       vendor, product, bus, devno);
-        return -1;
-    }
-
-    if (usb) {
-        *usb = usbDeviceListGet(list, 0);
-        usbDeviceListSteal(list, *usb);
-    }
-    usbDeviceListFree(list);
-
-    return 0;
-}
-
-usbDevice *
-usbGetDevice(unsigned int bus,
-             unsigned int devno,
-             const char *vroot)
-{
-    usbDevice *dev;
-
-    if (VIR_ALLOC(dev) < 0) {
-        virReportOOMError();
-        return NULL;
-    }
-
-    dev->bus     = bus;
-    dev->dev     = devno;
-
-    if (snprintf(dev->name, sizeof(dev->name), "%.3o:%.3o",
-                 dev->bus, dev->dev) >= sizeof(dev->name)) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("dev->name buffer overflow: %.3o:%.3o"),
-                       dev->bus, dev->dev);
-        usbFreeDevice(dev);
-        return NULL;
-    }
-    if (virAsprintf(&dev->path, "%s" USB_DEVFS "%03d/%03d",
-                    vroot ? vroot : "",
-                    dev->bus, dev->dev) < 0) {
-        virReportOOMError();
-        usbFreeDevice(dev);
-        return NULL;
-    }
-
-    /* XXX fixme. this should be product/vendor */
-    if (snprintf(dev->id, sizeof(dev->id), "%d %d", dev->bus,
-                 dev->dev) >= sizeof(dev->id)) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("dev->id buffer overflow: %d %d"),
-                       dev->bus, dev->dev);
-        usbFreeDevice(dev);
-        return NULL;
-    }
-
-    VIR_DEBUG("%s %s: initialized", dev->id, dev->name);
-
-    return dev;
-}
-
-void
-usbFreeDevice(usbDevice *dev)
-{
-    VIR_DEBUG("%s %s: freeing", dev->id, dev->name);
-    VIR_FREE(dev->path);
-    VIR_FREE(dev);
-}
-
-
-void usbDeviceSetUsedBy(usbDevice *dev,
-                        const char *name)
-{
-    dev->used_by = name;
-}
-
-const char * usbDeviceGetUsedBy(usbDevice *dev)
-{
-    return dev->used_by;
-}
-
-const char *usbDeviceGetName(usbDevice *dev)
-{
-    return dev->name;
-}
-
-unsigned int usbDeviceGetBus(usbDevice *dev)
-{
-    return dev->bus;
-}
-
-
-unsigned int usbDeviceGetDevno(usbDevice *dev)
-{
-    return dev->dev;
-}
-
-
-int usbDeviceFileIterate(usbDevice *dev,
-                         usbDeviceFileActor actor,
-                         void *opaque)
-{
-    return (actor)(dev, dev->path, opaque);
-}
-
-usbDeviceList *
-usbDeviceListNew(void)
-{
-    usbDeviceList *list;
-
-    if (VIR_ALLOC(list) < 0) {
-        virReportOOMError();
-        return NULL;
-    }
-
-    return list;
-}
-
-void
-usbDeviceListFree(usbDeviceList *list)
-{
-    int i;
-
-    if (!list)
-        return;
-
-    for (i = 0; i < list->count; i++)
-        usbFreeDevice(list->devs[i]);
-
-    VIR_FREE(list->devs);
-    VIR_FREE(list);
-}
-
-int
-usbDeviceListAdd(usbDeviceList *list,
-                 usbDevice *dev)
-{
-    if (usbDeviceListFind(list, dev)) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("Device %s is already in use"),
-                       dev->name);
-        return -1;
-    }
-
-    if (VIR_REALLOC_N(list->devs, list->count+1) < 0) {
-        virReportOOMError();
-        return -1;
-    }
-
-    list->devs[list->count++] = dev;
-
-    return 0;
-}
-
-usbDevice *
-usbDeviceListGet(usbDeviceList *list,
-                 int idx)
-{
-    if (idx >= list->count ||
-        idx < 0)
-        return NULL;
-
-    return list->devs[idx];
-}
-
-int
-usbDeviceListCount(usbDeviceList *list)
-{
-    return list->count;
-}
-
-usbDevice *
-usbDeviceListSteal(usbDeviceList *list,
-                   usbDevice *dev)
-{
-    usbDevice *ret = NULL;
-    int i;
-
-    for (i = 0; i < list->count; i++) {
-        if (list->devs[i]->bus != dev->bus ||
-            list->devs[i]->dev != dev->dev)
-            continue;
-
-        ret = list->devs[i];
-
-        if (i != list->count--)
-            memmove(&list->devs[i],
-                    &list->devs[i+1],
-                    sizeof(*list->devs) * (list->count - i));
-
-        if (VIR_REALLOC_N(list->devs, list->count) < 0) {
-            ; /* not fatal */
-        }
-
-        break;
-    }
-    return ret;
-}
-
-void
-usbDeviceListDel(usbDeviceList *list,
-                 usbDevice *dev)
-{
-    usbDevice *ret = usbDeviceListSteal(list, dev);
-    if (ret)
-        usbFreeDevice(ret);
-}
-
-usbDevice *
-usbDeviceListFind(usbDeviceList *list,
-                  usbDevice *dev)
-{
-    int i;
-
-    for (i = 0; i < list->count; i++) {
-        if (list->devs[i]->bus == dev->bus &&
-            list->devs[i]->dev == dev->dev)
-            return list->devs[i];
-    }
-
-    return NULL;
-}
diff --git a/src/util/hostusb.h b/src/util/hostusb.h
deleted file mode 100644 (file)
index ad2476d..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2009 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library.  If not, see
- * <http://www.gnu.org/licenses/>.
- *
- * Authors:
- *     Daniel P. Berrange <berrange@redhat.com>
- *     Michal Privoznik <mprivozn@redhat.com>
- */
-
-#ifndef __VIR_USB_H__
-# define __VIR_USB_H__
-
-# include "internal.h"
-
-# define USB_DEVFS "/dev/bus/usb/"
-
-typedef struct _usbDevice usbDevice;
-typedef struct _usbDeviceList usbDeviceList;
-
-usbDevice *usbGetDevice(unsigned int bus,
-                        unsigned int devno,
-                        const char *vroot);
-
-int usbFindDeviceByBus(unsigned int bus,
-                       unsigned int devno,
-                       const char *vroot,
-                       bool mandatory,
-                       usbDevice **usb);
-
-int usbFindDeviceByVendor(unsigned int vendor,
-                          unsigned int product,
-                          const char *vroot,
-                          bool mandatory,
-                          usbDeviceList **devices);
-
-int usbFindDevice(unsigned int vendor,
-                  unsigned int product,
-                  unsigned int bus,
-                  unsigned int devno,
-                  const char *vroot,
-                  bool mandatory,
-                  usbDevice **usb);
-
-void       usbFreeDevice (usbDevice *dev);
-void       usbDeviceSetUsedBy(usbDevice *dev, const char *name);
-const char *usbDeviceGetUsedBy(usbDevice *dev);
-const char *usbDeviceGetName(usbDevice *dev);
-
-unsigned int usbDeviceGetBus(usbDevice *dev);
-unsigned int usbDeviceGetDevno(usbDevice *dev);
-
-/*
- * Callback that will be invoked once for each file
- * associated with / used for USB host device access.
- *
- * Should return 0 if successfully processed, or
- * -1 to indicate error and abort iteration
- */
-typedef int (*usbDeviceFileActor)(usbDevice *dev,
-                                  const char *path, void *opaque);
-
-int usbDeviceFileIterate(usbDevice *dev,
-                         usbDeviceFileActor actor,
-                         void *opaque);
-
-usbDeviceList *usbDeviceListNew(void);
-void           usbDeviceListFree(usbDeviceList *list);
-int            usbDeviceListAdd(usbDeviceList *list,
-                                usbDevice *dev);
-usbDevice *    usbDeviceListGet(usbDeviceList *list,
-                                int idx);
-int            usbDeviceListCount(usbDeviceList *list);
-usbDevice *    usbDeviceListSteal(usbDeviceList *list,
-                                  usbDevice *dev);
-void           usbDeviceListDel(usbDeviceList *list,
-                                usbDevice *dev);
-usbDevice *    usbDeviceListFind(usbDeviceList *list,
-                                 usbDevice *dev);
-
-#endif /* __VIR_USB_H__ */
diff --git a/src/util/virusb.c b/src/util/virusb.c
new file mode 100644 (file)
index 0000000..c141385
--- /dev/null
@@ -0,0 +1,516 @@
+/*
+ * virusb.c: helper APIs for managing host USB devices
+ *
+ * Copyright (C) 2009-2012 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *     Daniel P. Berrange <berrange@redhat.com>
+ */
+
+#include <config.h>
+
+#include <dirent.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "virusb.h"
+#include "logging.h"
+#include "memory.h"
+#include "util.h"
+#include "virterror_internal.h"
+
+#define USB_SYSFS "/sys/bus/usb"
+#define USB_ID_LEN 10 /* "1234 5678" */
+#define USB_ADDR_LEN 8 /* "123:456" */
+
+/* For virReportOOMError()  and virReportSystemError() */
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+struct _usbDevice {
+    unsigned int      bus;
+    unsigned int      dev;
+
+    char          name[USB_ADDR_LEN]; /* domain:bus:slot.function */
+    char          id[USB_ID_LEN];     /* product vendor */
+    char          *path;
+    const char    *used_by;           /* name of the domain using this dev */
+};
+
+struct _usbDeviceList {
+    unsigned int count;
+    usbDevice **devs;
+};
+
+typedef enum {
+    USB_DEVICE_ALL = 0,
+    USB_DEVICE_FIND_BY_VENDOR = 1 << 0,
+    USB_DEVICE_FIND_BY_BUS = 1 << 1,
+} usbDeviceFindFlags;
+
+static int usbSysReadFile(const char *f_name, const char *d_name,
+                          int base, unsigned int *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();
+        goto cleanup;
+    }
+
+    if (virFileReadAll(filename, 1024, &buf) < 0)
+        goto cleanup;
+
+    if (virStrToLong_ui(buf, &ignore, base, value) < 0) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Could not parse usb file %s"), filename);
+        goto cleanup;
+    }
+
+    ret = 0;
+cleanup:
+    VIR_FREE(filename);
+    VIR_FREE(buf);
+    return ret;
+}
+
+static usbDeviceList *
+usbDeviceSearch(unsigned int vendor,
+                unsigned int product,
+                unsigned int bus,
+                unsigned int devno,
+                const char *vroot,
+                unsigned int flags)
+{
+    DIR *dir = NULL;
+    bool found = false;
+    char *ignore = NULL;
+    struct dirent *de;
+    usbDeviceList *list = NULL, *ret = NULL;
+    usbDevice *usb;
+
+    if (!(list = usbDeviceListNew()))
+        goto cleanup;
+
+    dir = opendir(USB_SYSFS "/devices");
+    if (!dir) {
+        virReportSystemError(errno,
+                             _("Could not open directory %s"),
+                             USB_SYSFS "/devices");
+        goto cleanup;
+    }
+
+    while ((de = readdir(dir))) {
+        unsigned int found_prod, found_vend, found_bus, found_devno;
+        char *tmpstr = de->d_name;
+
+        if (de->d_name[0] == '.' || strchr(de->d_name, ':'))
+            continue;
+
+        if (usbSysReadFile("idVendor", de->d_name,
+                           16, &found_vend) < 0)
+            goto cleanup;
+
+        if (usbSysReadFile("idProduct", de->d_name,
+                           16, &found_prod) < 0)
+            goto cleanup;
+
+        if (STRPREFIX(de->d_name, "usb"))
+            tmpstr += 3;
+
+        if (virStrToLong_ui(tmpstr, &ignore, 10, &found_bus) < 0) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("Failed to parse dir name '%s'"),
+                           de->d_name);
+            goto cleanup;
+        }
+
+        if (usbSysReadFile("devnum", de->d_name,
+                           10, &found_devno) < 0)
+            goto cleanup;
+
+        if ((flags & USB_DEVICE_FIND_BY_VENDOR) &&
+            (found_prod != product || found_vend != vendor))
+            continue;
+
+        if (flags & USB_DEVICE_FIND_BY_BUS) {
+            if (found_bus != bus || found_devno != devno)
+                continue;
+            found = true;
+        }
+
+        usb = usbGetDevice(found_bus, found_devno, vroot);
+        if (!usb)
+            goto cleanup;
+
+        if (usbDeviceListAdd(list, usb) < 0) {
+            usbFreeDevice(usb);
+            goto cleanup;
+        }
+
+        if (found)
+            break;
+    }
+    ret = list;
+
+cleanup:
+    if (dir) {
+        int saved_errno = errno;
+        closedir(dir);
+        errno = saved_errno;
+    }
+
+    if (!ret)
+        usbDeviceListFree(list);
+    return ret;
+}
+
+int
+usbFindDeviceByVendor(unsigned int vendor,
+                      unsigned product,
+                      const char *vroot,
+                      bool mandatory,
+                      usbDeviceList **devices)
+{
+    usbDeviceList *list;
+    int count;
+
+    if (!(list = usbDeviceSearch(vendor, product, 0 , 0,
+                                 vroot,
+                                 USB_DEVICE_FIND_BY_VENDOR)))
+        return -1;
+
+    if (list->count == 0) {
+        usbDeviceListFree(list);
+        if (!mandatory) {
+            VIR_DEBUG("Did not find USB device %x:%x",
+                      vendor, product);
+            if (devices)
+                *devices = NULL;
+            return 0;
+        }
+
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Did not find USB device %x:%x"), vendor, product);
+        return -1;
+    }
+
+    count = list->count;
+    if (devices)
+        *devices = list;
+    else
+        usbDeviceListFree(list);
+
+    return count;
+}
+
+int
+usbFindDeviceByBus(unsigned int bus,
+                   unsigned devno,
+                   const char *vroot,
+                   bool mandatory,
+                   usbDevice **usb)
+{
+    usbDeviceList *list;
+
+    if (!(list = usbDeviceSearch(0, 0, bus, devno,
+                                 vroot,
+                                 USB_DEVICE_FIND_BY_BUS)))
+        return -1;
+
+    if (list->count == 0) {
+        usbDeviceListFree(list);
+        if (!mandatory) {
+            VIR_DEBUG("Did not find USB device bus:%u device:%u",
+                      bus, devno);
+            if (usb)
+                *usb = NULL;
+            return 0;
+        }
+
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Did not find USB device bus:%u device:%u"),
+                       bus, devno);
+        return -1;
+    }
+
+    if (usb) {
+        *usb = usbDeviceListGet(list, 0);
+        usbDeviceListSteal(list, *usb);
+    }
+    usbDeviceListFree(list);
+
+    return 0;
+}
+
+int
+usbFindDevice(unsigned int vendor,
+              unsigned int product,
+              unsigned int bus,
+              unsigned int devno,
+              const char *vroot,
+              bool mandatory,
+              usbDevice **usb)
+{
+    usbDeviceList *list;
+
+    unsigned int flags = USB_DEVICE_FIND_BY_VENDOR|USB_DEVICE_FIND_BY_BUS;
+    if (!(list = usbDeviceSearch(vendor, product, bus, devno,
+                                 vroot, flags)))
+        return -1;
+
+    if (list->count == 0) {
+        usbDeviceListFree(list);
+        if (!mandatory) {
+            VIR_DEBUG("Did not find USB device %x:%x bus:%u device:%u",
+                      vendor, product, bus, devno);
+            if (usb)
+                *usb = NULL;
+            return 0;
+        }
+
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Did not find USB device %x:%x bus:%u device:%u"),
+                       vendor, product, bus, devno);
+        return -1;
+    }
+
+    if (usb) {
+        *usb = usbDeviceListGet(list, 0);
+        usbDeviceListSteal(list, *usb);
+    }
+    usbDeviceListFree(list);
+
+    return 0;
+}
+
+usbDevice *
+usbGetDevice(unsigned int bus,
+             unsigned int devno,
+             const char *vroot)
+{
+    usbDevice *dev;
+
+    if (VIR_ALLOC(dev) < 0) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    dev->bus     = bus;
+    dev->dev     = devno;
+
+    if (snprintf(dev->name, sizeof(dev->name), "%.3o:%.3o",
+                 dev->bus, dev->dev) >= sizeof(dev->name)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("dev->name buffer overflow: %.3o:%.3o"),
+                       dev->bus, dev->dev);
+        usbFreeDevice(dev);
+        return NULL;
+    }
+    if (virAsprintf(&dev->path, "%s" USB_DEVFS "%03d/%03d",
+                    vroot ? vroot : "",
+                    dev->bus, dev->dev) < 0) {
+        virReportOOMError();
+        usbFreeDevice(dev);
+        return NULL;
+    }
+
+    /* XXX fixme. this should be product/vendor */
+    if (snprintf(dev->id, sizeof(dev->id), "%d %d", dev->bus,
+                 dev->dev) >= sizeof(dev->id)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("dev->id buffer overflow: %d %d"),
+                       dev->bus, dev->dev);
+        usbFreeDevice(dev);
+        return NULL;
+    }
+
+    VIR_DEBUG("%s %s: initialized", dev->id, dev->name);
+
+    return dev;
+}
+
+void
+usbFreeDevice(usbDevice *dev)
+{
+    VIR_DEBUG("%s %s: freeing", dev->id, dev->name);
+    VIR_FREE(dev->path);
+    VIR_FREE(dev);
+}
+
+
+void usbDeviceSetUsedBy(usbDevice *dev,
+                        const char *name)
+{
+    dev->used_by = name;
+}
+
+const char * usbDeviceGetUsedBy(usbDevice *dev)
+{
+    return dev->used_by;
+}
+
+const char *usbDeviceGetName(usbDevice *dev)
+{
+    return dev->name;
+}
+
+unsigned int usbDeviceGetBus(usbDevice *dev)
+{
+    return dev->bus;
+}
+
+
+unsigned int usbDeviceGetDevno(usbDevice *dev)
+{
+    return dev->dev;
+}
+
+
+int usbDeviceFileIterate(usbDevice *dev,
+                         usbDeviceFileActor actor,
+                         void *opaque)
+{
+    return (actor)(dev, dev->path, opaque);
+}
+
+usbDeviceList *
+usbDeviceListNew(void)
+{
+    usbDeviceList *list;
+
+    if (VIR_ALLOC(list) < 0) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    return list;
+}
+
+void
+usbDeviceListFree(usbDeviceList *list)
+{
+    int i;
+
+    if (!list)
+        return;
+
+    for (i = 0; i < list->count; i++)
+        usbFreeDevice(list->devs[i]);
+
+    VIR_FREE(list->devs);
+    VIR_FREE(list);
+}
+
+int
+usbDeviceListAdd(usbDeviceList *list,
+                 usbDevice *dev)
+{
+    if (usbDeviceListFind(list, dev)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Device %s is already in use"),
+                       dev->name);
+        return -1;
+    }
+
+    if (VIR_REALLOC_N(list->devs, list->count+1) < 0) {
+        virReportOOMError();
+        return -1;
+    }
+
+    list->devs[list->count++] = dev;
+
+    return 0;
+}
+
+usbDevice *
+usbDeviceListGet(usbDeviceList *list,
+                 int idx)
+{
+    if (idx >= list->count ||
+        idx < 0)
+        return NULL;
+
+    return list->devs[idx];
+}
+
+int
+usbDeviceListCount(usbDeviceList *list)
+{
+    return list->count;
+}
+
+usbDevice *
+usbDeviceListSteal(usbDeviceList *list,
+                   usbDevice *dev)
+{
+    usbDevice *ret = NULL;
+    int i;
+
+    for (i = 0; i < list->count; i++) {
+        if (list->devs[i]->bus != dev->bus ||
+            list->devs[i]->dev != dev->dev)
+            continue;
+
+        ret = list->devs[i];
+
+        if (i != list->count--)
+            memmove(&list->devs[i],
+                    &list->devs[i+1],
+                    sizeof(*list->devs) * (list->count - i));
+
+        if (VIR_REALLOC_N(list->devs, list->count) < 0) {
+            ; /* not fatal */
+        }
+
+        break;
+    }
+    return ret;
+}
+
+void
+usbDeviceListDel(usbDeviceList *list,
+                 usbDevice *dev)
+{
+    usbDevice *ret = usbDeviceListSteal(list, dev);
+    if (ret)
+        usbFreeDevice(ret);
+}
+
+usbDevice *
+usbDeviceListFind(usbDeviceList *list,
+                  usbDevice *dev)
+{
+    int i;
+
+    for (i = 0; i < list->count; i++) {
+        if (list->devs[i]->bus == dev->bus &&
+            list->devs[i]->dev == dev->dev)
+            return list->devs[i];
+    }
+
+    return NULL;
+}
diff --git a/src/util/virusb.h b/src/util/virusb.h
new file mode 100644 (file)
index 0000000..917dd15
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * virusb.h: helper APIs for managing host USB devices
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *     Daniel P. Berrange <berrange@redhat.com>
+ *     Michal Privoznik <mprivozn@redhat.com>
+ */
+
+#ifndef __VIR_USB_H__
+# define __VIR_USB_H__
+
+# include "internal.h"
+
+# define USB_DEVFS "/dev/bus/usb/"
+
+typedef struct _usbDevice usbDevice;
+typedef struct _usbDeviceList usbDeviceList;
+
+usbDevice *usbGetDevice(unsigned int bus,
+                        unsigned int devno,
+                        const char *vroot);
+
+int usbFindDeviceByBus(unsigned int bus,
+                       unsigned int devno,
+                       const char *vroot,
+                       bool mandatory,
+                       usbDevice **usb);
+
+int usbFindDeviceByVendor(unsigned int vendor,
+                          unsigned int product,
+                          const char *vroot,
+                          bool mandatory,
+                          usbDeviceList **devices);
+
+int usbFindDevice(unsigned int vendor,
+                  unsigned int product,
+                  unsigned int bus,
+                  unsigned int devno,
+                  const char *vroot,
+                  bool mandatory,
+                  usbDevice **usb);
+
+void       usbFreeDevice (usbDevice *dev);
+void       usbDeviceSetUsedBy(usbDevice *dev, const char *name);
+const char *usbDeviceGetUsedBy(usbDevice *dev);
+const char *usbDeviceGetName(usbDevice *dev);
+
+unsigned int usbDeviceGetBus(usbDevice *dev);
+unsigned int usbDeviceGetDevno(usbDevice *dev);
+
+/*
+ * Callback that will be invoked once for each file
+ * associated with / used for USB host device access.
+ *
+ * Should return 0 if successfully processed, or
+ * -1 to indicate error and abort iteration
+ */
+typedef int (*usbDeviceFileActor)(usbDevice *dev,
+                                  const char *path, void *opaque);
+
+int usbDeviceFileIterate(usbDevice *dev,
+                         usbDeviceFileActor actor,
+                         void *opaque);
+
+usbDeviceList *usbDeviceListNew(void);
+void           usbDeviceListFree(usbDeviceList *list);
+int            usbDeviceListAdd(usbDeviceList *list,
+                                usbDevice *dev);
+usbDevice *    usbDeviceListGet(usbDeviceList *list,
+                                int idx);
+int            usbDeviceListCount(usbDeviceList *list);
+usbDevice *    usbDeviceListSteal(usbDeviceList *list,
+                                  usbDevice *dev);
+void           usbDeviceListDel(usbDeviceList *list,
+                                usbDevice *dev);
+usbDevice *    usbDeviceListFind(usbDeviceList *list,
+                                 usbDevice *dev);
+
+#endif /* __VIR_USB_H__ */