summaryrefslogtreecommitdiff
path: root/src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp
diff options
context:
space:
mode:
authorFelix Geyer <debfx-pkg@fobos.de>2011-05-17 13:57:57 +0200
committerFelix Geyer <debfx-pkg@fobos.de>2011-05-17 13:57:57 +0200
commit0056814bdb2f8a457b56803fd24c72347173250d (patch)
tree0a0f513bb8030d6bcdff405a5caab73fcb1399ce /src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp
parent3c3b014d3682252dbc133a6d2cd5dd2f8a028bbe (diff)
downloadvirtualbox-0056814bdb2f8a457b56803fd24c72347173250d.tar.gz
Imported Upstream version 4.0.8-dfsgupstream/4.0.8-dfsg
Diffstat (limited to 'src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp')
-rw-r--r--src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp85
1 files changed, 66 insertions, 19 deletions
diff --git a/src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp b/src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp
index eab255187..2a0efc06e 100644
--- a/src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp
+++ b/src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp
@@ -31,6 +31,7 @@
#include <iprt/alloc.h>
#include <iprt/assert.h>
#include <iprt/ctype.h>
+#include <iprt/dir.h>
#include <iprt/env.h>
#include <iprt/file.h>
#include <iprt/err.h>
@@ -61,10 +62,38 @@ USBProxyServiceLinux::USBProxyServiceLinux(Host *aHost)
: USBProxyService(aHost), mFile(NIL_RTFILE), mWakeupPipeR(NIL_RTFILE),
mWakeupPipeW(NIL_RTFILE), mUsingUsbfsDevices(true /* see init */),
mUdevPolls(0), mpWaiter(NULL)
+#ifdef UNIT_TEST
+ , mpcszTestUsbfsRoot(NULL), mfTestUsbfsAccessible(false),
+ mpcszTestDevicesRoot(NULL), mfTestDevicesAccessible(false),
+ mrcTestMethodInitResult(VINF_SUCCESS), mpcszTestEnvUsb(NULL),
+ mpcszTestEnvUsbRoot(NULL)
+#endif
{
LogFlowThisFunc(("aHost=%p\n", aHost));
}
+#ifdef UNIT_TEST
+/* For testing we redefine anything that accesses the outside world to
+ * return test values. */
+# define RTEnvGet(a) \
+ ( !RTStrCmp(a, "VBOX_USB") ? mpcszTestEnvUsb \
+ : !RTStrCmp(a, "VBOX_USB_ROOT") ? mpcszTestEnvUsbRoot \
+ : NULL)
+# define USBProxyLinuxCheckDeviceRoot(pcszPath, fUseNodes) \
+ ( ((fUseNodes) && mfTestDevicesAccessible \
+ && !RTStrCmp(pcszPath, mpcszTestDevicesRoot)) \
+ || (!(fUseNodes) && mfTestUsbfsAccessible \
+ && !RTStrCmp(pcszPath, mpcszTestUsbfsRoot)))
+# define RTDirExists(pcszDir) \
+ ( (pcszDir) \
+ && ( !RTStrCmp(pcszDir, mpcszTestDevicesRoot) \
+ || !RTStrCmp(pcszDir, mpcszTestUsbfsRoot)))
+# define RTFileExists(pcszFile) \
+ ( (pcszFile) \
+ && mpcszTestUsbfsRoot \
+ && !RTStrNCmp(pcszFile, mpcszTestUsbfsRoot, strlen(mpcszTestUsbfsRoot)) \
+ && !RTStrCmp(pcszFile + strlen(mpcszTestUsbfsRoot), "/devices"))
+#endif
/**
* Initializes the object (called right after construction).
@@ -81,17 +110,14 @@ HRESULT USBProxyServiceLinux::init(void)
/*
* We have two methods available for getting host USB device data - using
- * USBFS and using sysfs/hal. The default choice depends on build-time
- * settings and an environment variable; if the default is not available
- * we fall back to the second.
- * In the event of both failing, the error from the second method tried
- * will be presented to the user.
+ * USBFS and using sysfs. The default choice is sysfs; if that is not
+ * available we fall back to USBFS.
+ * In the event of both failing, an appropriate error will be returned.
+ * The user may also specify a method and root using the VBOX_USB and
+ * VBOX_USB_ROOT environment variables. In this case we don't check
+ * the root they provide for validity.
*/
-#ifdef VBOX_WITH_SYSFS_BY_DEFAULT
- bool fUseSysfs = true;
-#else
- bool fUseSysfs = false;
-#endif
+ bool fUsbfsChosen = false, fSysfsChosen = false;
const char *pcszUsbFromEnv = RTEnvGet("VBOX_USB");
const char *pcszUsbRoot = NULL;
if (pcszUsbFromEnv)
@@ -102,37 +128,49 @@ HRESULT USBProxyServiceLinux::init(void)
if (!RTStrICmp(pcszUsbFromEnv, "USBFS"))
{
LogRel(("Default USB access method set to \"usbfs\" from environment\n"));
- fUseSysfs = false;
+ fUsbfsChosen = true;
}
else if (!RTStrICmp(pcszUsbFromEnv, "SYSFS"))
{
LogRel(("Default USB method set to \"sysfs\" from environment\n"));
- fUseSysfs = true;
+ fSysfsChosen = true;
}
else
{
LogRel(("Invalid VBOX_USB environment variable setting \"%s\"\n",
pcszUsbFromEnv));
fValidVBoxUSB = false;
+ pcszUsbFromEnv = NULL;
}
if (!fValidVBoxUSB && pcszUsbRoot)
pcszUsbRoot = NULL;
}
if (!pcszUsbRoot)
{
- PCUSBDEVTREELOCATION pcLocation;
- pcLocation = USBProxyLinuxGetDeviceRoot(fUseSysfs);
- if (pcLocation)
+ if ( !fUsbfsChosen
+ && USBProxyLinuxCheckDeviceRoot("/dev/vboxusb", true))
{
- pcszUsbRoot = pcLocation->szDevicesRoot;
- fUseSysfs = pcLocation->fUseSysfs;
+ fSysfsChosen = true;
+ pcszUsbRoot = "/dev/vboxusb";
+ }
+ else if ( !fSysfsChosen
+ && USBProxyLinuxCheckDeviceRoot("/proc/bus/usb", false))
+ {
+ fUsbfsChosen = true;
+ pcszUsbRoot = "/proc/bus/usb";
}
}
+ else if (!USBProxyLinuxCheckDeviceRoot(pcszUsbRoot, fSysfsChosen))
+ pcszUsbRoot = NULL;
if (pcszUsbRoot)
{
- mUsingUsbfsDevices = !fUseSysfs;
+ mUsingUsbfsDevices = fUsbfsChosen;
mDevicesRoot = pcszUsbRoot;
+#ifndef UNIT_TEST /* Hack for now */
int rc = mUsingUsbfsDevices ? initUsbfs() : initSysfs();
+#else
+ int rc = mrcTestMethodInitResult;
+#endif
/* For the day when we have VBoxSVC release logging... */
LogRel((RT_SUCCESS(rc) ? "Successfully initialised host USB using %s\n"
: "Failed to initialise host USB using %s\n",
@@ -140,10 +178,19 @@ HRESULT USBProxyServiceLinux::init(void)
mLastError = rc;
}
else
- mLastError = VERR_NOT_FOUND;
+ mLastError = pcszUsbFromEnv ? VERR_NOT_FOUND
+ : RTDirExists("/dev/vboxusb") ? VERR_VUSB_USB_DEVICE_PERMISSION
+ : RTFileExists("/proc/bus/usb/devices") ? VERR_VUSB_USBFS_PERMISSION
+ : VERR_NOT_FOUND;
return S_OK;
}
+#ifdef UNIT_TEST
+# undef RTEnvGet
+# undef USBProxyLinuxCheckDeviceRoot
+# undef RTDirExists
+# undef RTFileExists
+#endif
/**
* Initialization routine for the usbfs based operation.