- Timestamp:
- Jun 23, 2011 5:16:39 PM (13 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/USBGetDevices.h
r36993 r37618 85 85 86 86 #ifdef UNIT_TEST 87 void TestUSBSetupInit(const char *pcszUsbfsRoot, bool fUsbfsAccessible, 88 const char *pcszDevicesRoot, bool fDevicesAccessible, 89 int rcMethodInitResult); 90 void TestUSBSetEnv(const char *pcszEnvUsb, const char *pcszEnvUsbRoot); 91 #endif 92 93 /** 94 * Selects the access method that will be used to access USB devices based on 95 * what is available on the host and what if anything the user has specified 96 * in the environment. 97 * @returns iprt status value 98 * @param pfUsingUsbfsDevices on success this will be set to true if 99 * the prefered access method is USBFS-like and to 100 * false if it is sysfs/device node-like 101 * @param ppcszDevicesRoot on success the root of the tree of USBFS-like 102 * device nodes will be stored here 103 */ 104 extern int USBProxyLinuxChooseMethod(bool *pfUsingUsbfsDevices, 105 const char **ppcszDevicesRoot); 106 #ifdef UNIT_TEST 87 107 /** 88 108 * Specify the list of devices that will appear to be available through -
trunk/src/VBox/Main/include/USBProxyService.h
r37617 r37618 197 197 # endif 198 198 199 #ifdef UNIT_TEST200 void TestUSBSetupInit(const char *pcszUsbfsRoot, bool fUsbfsAccessible,201 const char *pcszDevicesRoot, bool fDevicesAccessible,202 int rcMethodInitResult);203 void TestUSBSetEnv(const char *pcszEnvUsb, const char *pcszEnvUsbRoot);204 #endif205 206 199 /** 207 200 * The Linux hosted USB Proxy Service. … … 217 210 virtual int captureDevice(HostUSBDevice *aDevice); 218 211 virtual int releaseDevice(HostUSBDevice *aDevice); 219 220 # ifdef UNIT_TEST221 /* Test getters for querying internal state. This will go away. */222 bool testGetUsingUsbfs(void) { return mUsingUsbfsDevices; }223 const char *testGetDevicesRoot(void) { return mDevicesRoot.c_str(); }224 # endif225 212 226 213 protected: -
trunk/src/VBox/Main/src-server/linux/USBGetDevices.cpp
r37390 r37618 23 23 #include "USBGetDevices.h" 24 24 25 #include <VBox/err.h> 25 26 #include <VBox/usb.h> 26 27 #include <VBox/usblib.h> … … 29 30 #include <iprt/cdefs.h> 30 31 #include <iprt/ctype.h> 31 #include <iprt/err.h> 32 #include <iprt/dir.h> 33 #include <iprt/env.h> 34 #include <iprt/file.h> 32 35 #include <iprt/fs.h> 33 36 #include <iprt/log.h> … … 1503 1506 #endif 1504 1507 1508 #ifdef UNIT_TEST 1509 # ifdef UNIT_TEST 1510 /** The path we pretend the usbfs root is located at, or NULL. */ 1511 const char *s_pcszTestUsbfsRoot; 1512 /** Should usbfs be accessible to the current user? */ 1513 bool s_fTestUsbfsAccessible; 1514 /** The path we pretend the device node tree root is located at, or NULL. */ 1515 const char *s_pcszTestDevicesRoot; 1516 /** Should the device node tree be accessible to the current user? */ 1517 bool s_fTestDevicesAccessible; 1518 /** The result of the usbfs/inotify-specific init */ 1519 int s_rcTestMethodInitResult; 1520 /** The value of the VBOX_USB environment variable. */ 1521 const char *s_pcszTestEnvUsb; 1522 /** The value of the VBOX_USB_ROOT environment variable. */ 1523 const char *s_pcszTestEnvUsbRoot; 1524 # endif 1525 1526 /** Select which access methods will be available to the @a init method 1527 * during unit testing, and (hack!) what return code it will see from 1528 * the access method-specific initialisation. */ 1529 void TestUSBSetupInit(const char *pcszUsbfsRoot, bool fUsbfsAccessible, 1530 const char *pcszDevicesRoot, bool fDevicesAccessible, 1531 int rcMethodInitResult) 1532 { 1533 s_pcszTestUsbfsRoot = pcszUsbfsRoot; 1534 s_fTestUsbfsAccessible = fUsbfsAccessible; 1535 s_pcszTestDevicesRoot = pcszDevicesRoot; 1536 s_fTestDevicesAccessible = fDevicesAccessible; 1537 s_rcTestMethodInitResult = rcMethodInitResult; 1538 } 1539 1540 /** Specify the environment that the @a init method will see during unit 1541 * testing. */ 1542 void TestUSBSetEnv(const char *pcszEnvUsb, const char *pcszEnvUsbRoot) 1543 { 1544 s_pcszTestEnvUsb = pcszEnvUsb; 1545 s_pcszTestEnvUsbRoot = pcszEnvUsbRoot; 1546 } 1547 1548 /* For testing we redefine anything that accesses the outside world to 1549 * return test values. */ 1550 # define RTEnvGet(a) \ 1551 ( !RTStrCmp(a, "VBOX_USB") ? s_pcszTestEnvUsb \ 1552 : !RTStrCmp(a, "VBOX_USB_ROOT") ? s_pcszTestEnvUsbRoot \ 1553 : NULL) 1554 # define USBProxyLinuxCheckDeviceRoot(pcszPath, fUseNodes) \ 1555 ( ((fUseNodes) && s_fTestDevicesAccessible \ 1556 && !RTStrCmp(pcszPath, s_pcszTestDevicesRoot)) \ 1557 || (!(fUseNodes) && s_fTestUsbfsAccessible \ 1558 && !RTStrCmp(pcszPath, s_pcszTestUsbfsRoot))) 1559 # define RTDirExists(pcszDir) \ 1560 ( (pcszDir) \ 1561 && ( !RTStrCmp(pcszDir, s_pcszTestDevicesRoot) \ 1562 || !RTStrCmp(pcszDir, s_pcszTestUsbfsRoot))) 1563 # define RTFileExists(pcszFile) \ 1564 ( (pcszFile) \ 1565 && s_pcszTestUsbfsRoot \ 1566 && !RTStrNCmp(pcszFile, s_pcszTestUsbfsRoot, strlen(s_pcszTestUsbfsRoot)) \ 1567 && !RTStrCmp(pcszFile + strlen(s_pcszTestUsbfsRoot), "/devices")) 1568 #endif 1569 1570 /** 1571 * Selects the access method that will be used to access USB devices based on 1572 * what is available on the host and what if anything the user has specified 1573 * in the environment. 1574 * @returns iprt status value 1575 * @param pfUsingUsbfsDevices on success this will be set to true if 1576 * the prefered access method is USBFS-like and to 1577 * false if it is sysfs/device node-like 1578 * @param ppcszDevicesRoot on success the root of the tree of USBFS-like 1579 * device nodes will be stored here 1580 */ 1581 int USBProxyLinuxChooseMethod(bool *pfUsingUsbfsDevices, 1582 const char **ppcszDevicesRoot) 1583 { 1584 /* 1585 * We have two methods available for getting host USB device data - using 1586 * USBFS and using sysfs. The default choice is sysfs; if that is not 1587 * available we fall back to USBFS. 1588 * In the event of both failing, an appropriate error will be returned. 1589 * The user may also specify a method and root using the VBOX_USB and 1590 * VBOX_USB_ROOT environment variables. In this case we don't check 1591 * the root they provide for validity. 1592 */ 1593 bool fUsbfsChosen = false, fSysfsChosen = false; 1594 const char *pcszUsbFromEnv = RTEnvGet("VBOX_USB"); 1595 const char *pcszUsbRoot = NULL; 1596 if (pcszUsbFromEnv) 1597 { 1598 bool fValidVBoxUSB = true; 1599 1600 pcszUsbRoot = RTEnvGet("VBOX_USB_ROOT"); 1601 if (!RTStrICmp(pcszUsbFromEnv, "USBFS")) 1602 { 1603 LogRel(("Default USB access method set to \"usbfs\" from environment\n")); 1604 fUsbfsChosen = true; 1605 } 1606 else if (!RTStrICmp(pcszUsbFromEnv, "SYSFS")) 1607 { 1608 LogRel(("Default USB method set to \"sysfs\" from environment\n")); 1609 fSysfsChosen = true; 1610 } 1611 else 1612 { 1613 LogRel(("Invalid VBOX_USB environment variable setting \"%s\"\n", 1614 pcszUsbFromEnv)); 1615 fValidVBoxUSB = false; 1616 pcszUsbFromEnv = NULL; 1617 } 1618 if (!fValidVBoxUSB && pcszUsbRoot) 1619 pcszUsbRoot = NULL; 1620 } 1621 if (!pcszUsbRoot) 1622 { 1623 if ( !fUsbfsChosen 1624 && USBProxyLinuxCheckDeviceRoot("/dev/vboxusb", true)) 1625 { 1626 fSysfsChosen = true; 1627 pcszUsbRoot = "/dev/vboxusb"; 1628 } 1629 else if ( !fSysfsChosen 1630 && USBProxyLinuxCheckDeviceRoot("/proc/bus/usb", false)) 1631 { 1632 fUsbfsChosen = true; 1633 pcszUsbRoot = "/proc/bus/usb"; 1634 } 1635 } 1636 else if (!USBProxyLinuxCheckDeviceRoot(pcszUsbRoot, fSysfsChosen)) 1637 pcszUsbRoot = NULL; 1638 if (pcszUsbRoot) 1639 { 1640 *pfUsingUsbfsDevices = fUsbfsChosen; 1641 *ppcszDevicesRoot = pcszUsbRoot; 1642 return VINF_SUCCESS; 1643 } 1644 /* else */ 1645 return pcszUsbFromEnv ? VERR_NOT_FOUND 1646 : RTDirExists("/dev/vboxusb") ? VERR_VUSB_USB_DEVICE_PERMISSION 1647 : RTFileExists("/proc/bus/usb/devices") ? VERR_VUSB_USBFS_PERMISSION 1648 : VERR_NOT_FOUND; 1649 } 1650 1651 #ifdef UNIT_TEST 1652 # undef RTEnvGet 1653 # undef USBProxyLinuxCheckDeviceRoot 1654 # undef RTDirExists 1655 # undef RTFileExists 1656 #endif 1657 1505 1658 bool USBProxyLinuxCheckDeviceRoot(const char *pcszRoot, bool fIsDeviceNodes) 1506 1659 { -
trunk/src/VBox/Main/src-server/linux/USBProxyServiceLinux.cpp
r37617 r37618 68 68 } 69 69 70 #ifdef UNIT_TEST71 # ifdef UNIT_TEST72 /** The path we pretend the usbfs root is located at, or NULL. */73 const char *s_pcszTestUsbfsRoot;74 /** Should usbfs be accessible to the current user? */75 bool s_fTestUsbfsAccessible;76 /** The path we pretend the device node tree root is located at, or NULL. */77 const char *s_pcszTestDevicesRoot;78 /** Should the device node tree be accessible to the current user? */79 bool s_fTestDevicesAccessible;80 /** The result of the usbfs/inotify-specific init */81 int s_rcTestMethodInitResult;82 /** The value of the VBOX_USB environment variable. */83 const char *s_pcszTestEnvUsb;84 /** The value of the VBOX_USB_ROOT environment variable. */85 const char *s_pcszTestEnvUsbRoot;86 # endif87 88 /** Select which access methods will be available to the @a init method89 * during unit testing, and (hack!) what return code it will see from90 * the access method-specific initialisation. */91 void TestUSBSetupInit(const char *pcszUsbfsRoot, bool fUsbfsAccessible,92 const char *pcszDevicesRoot, bool fDevicesAccessible,93 int rcMethodInitResult)94 {95 s_pcszTestUsbfsRoot = pcszUsbfsRoot;96 s_fTestUsbfsAccessible = fUsbfsAccessible;97 s_pcszTestDevicesRoot = pcszDevicesRoot;98 s_fTestDevicesAccessible = fDevicesAccessible;99 s_rcTestMethodInitResult = rcMethodInitResult;100 }101 102 /** Specify the environment that the @a init method will see during unit103 * testing. */104 void TestUSBSetEnv(const char *pcszEnvUsb, const char *pcszEnvUsbRoot)105 {106 s_pcszTestEnvUsb = pcszEnvUsb;107 s_pcszTestEnvUsbRoot = pcszEnvUsbRoot;108 }109 110 /* For testing we redefine anything that accesses the outside world to111 * return test values. */112 # define RTEnvGet(a) \113 ( !RTStrCmp(a, "VBOX_USB") ? s_pcszTestEnvUsb \114 : !RTStrCmp(a, "VBOX_USB_ROOT") ? s_pcszTestEnvUsbRoot \115 : NULL)116 # define USBProxyLinuxCheckDeviceRoot(pcszPath, fUseNodes) \117 ( ((fUseNodes) && s_fTestDevicesAccessible \118 && !RTStrCmp(pcszPath, s_pcszTestDevicesRoot)) \119 || (!(fUseNodes) && s_fTestUsbfsAccessible \120 && !RTStrCmp(pcszPath, s_pcszTestUsbfsRoot)))121 # define RTDirExists(pcszDir) \122 ( (pcszDir) \123 && ( !RTStrCmp(pcszDir, s_pcszTestDevicesRoot) \124 || !RTStrCmp(pcszDir, s_pcszTestUsbfsRoot)))125 # define RTFileExists(pcszFile) \126 ( (pcszFile) \127 && s_pcszTestUsbfsRoot \128 && !RTStrNCmp(pcszFile, s_pcszTestUsbfsRoot, strlen(s_pcszTestUsbfsRoot)) \129 && !RTStrCmp(pcszFile + strlen(s_pcszTestUsbfsRoot), "/devices"))130 #endif131 132 /**133 * Selects the access method that will be used to access USB devices based on134 * what is available on the host and what if anything the user has specified135 * in the environment.136 * @returns iprt status value137 * @param pfUsingUsbfsDevices on success this will be set to true if138 * the prefered access method is USBFS-like and to139 * false if it is sysfs/device node-like140 * @param ppcszDevicesRoot on success the root of the tree of USBFS-like141 * device nodes will be stored here142 */143 int USBProxyLinuxChooseMethod(bool *pfUsingUsbfsDevices,144 const char **ppcszDevicesRoot)145 {146 /*147 * We have two methods available for getting host USB device data - using148 * USBFS and using sysfs. The default choice is sysfs; if that is not149 * available we fall back to USBFS.150 * In the event of both failing, an appropriate error will be returned.151 * The user may also specify a method and root using the VBOX_USB and152 * VBOX_USB_ROOT environment variables. In this case we don't check153 * the root they provide for validity.154 */155 bool fUsbfsChosen = false, fSysfsChosen = false;156 const char *pcszUsbFromEnv = RTEnvGet("VBOX_USB");157 const char *pcszUsbRoot = NULL;158 if (pcszUsbFromEnv)159 {160 bool fValidVBoxUSB = true;161 162 pcszUsbRoot = RTEnvGet("VBOX_USB_ROOT");163 if (!RTStrICmp(pcszUsbFromEnv, "USBFS"))164 {165 LogRel(("Default USB access method set to \"usbfs\" from environment\n"));166 fUsbfsChosen = true;167 }168 else if (!RTStrICmp(pcszUsbFromEnv, "SYSFS"))169 {170 LogRel(("Default USB method set to \"sysfs\" from environment\n"));171 fSysfsChosen = true;172 }173 else174 {175 LogRel(("Invalid VBOX_USB environment variable setting \"%s\"\n",176 pcszUsbFromEnv));177 fValidVBoxUSB = false;178 pcszUsbFromEnv = NULL;179 }180 if (!fValidVBoxUSB && pcszUsbRoot)181 pcszUsbRoot = NULL;182 }183 if (!pcszUsbRoot)184 {185 if ( !fUsbfsChosen186 && USBProxyLinuxCheckDeviceRoot("/dev/vboxusb", true))187 {188 fSysfsChosen = true;189 pcszUsbRoot = "/dev/vboxusb";190 }191 else if ( !fSysfsChosen192 && USBProxyLinuxCheckDeviceRoot("/proc/bus/usb", false))193 {194 fUsbfsChosen = true;195 pcszUsbRoot = "/proc/bus/usb";196 }197 }198 else if (!USBProxyLinuxCheckDeviceRoot(pcszUsbRoot, fSysfsChosen))199 pcszUsbRoot = NULL;200 if (pcszUsbRoot)201 {202 *pfUsingUsbfsDevices = fUsbfsChosen;203 *ppcszDevicesRoot = pcszUsbRoot;204 return VINF_SUCCESS;205 }206 /* else */207 return pcszUsbFromEnv ? VERR_NOT_FOUND208 : RTDirExists("/dev/vboxusb") ? VERR_VUSB_USB_DEVICE_PERMISSION209 : RTFileExists("/proc/bus/usb/devices") ? VERR_VUSB_USBFS_PERMISSION210 : VERR_NOT_FOUND;211 }212 213 70 /** 214 71 * Initializes the object (called right after construction). … … 223 80 { 224 81 mDevicesRoot = pcszDevicesRoot; 225 #ifndef UNIT_TEST /* Hack for now */226 82 rc = mUsingUsbfsDevices ? initUsbfs() : initSysfs(); 227 #else228 rc = s_rcTestMethodInitResult;229 #endif230 83 /* For the day when we have VBoxSVC release logging... */ 231 84 LogRel((RT_SUCCESS(rc) ? "Successfully initialised host USB using %s\n" … … 236 89 return S_OK; 237 90 } 238 239 #ifdef UNIT_TEST240 # undef RTEnvGet241 # undef USBProxyLinuxCheckDeviceRoot242 # undef RTDirExists243 # undef RTFileExists244 #endif245 91 246 92 /** -
trunk/src/VBox/Main/testcase/tstUSBProxyLinux.cpp
r37617 r37618 89 89 /* "sysfs" and valid root in the environment */ 90 90 { "sysfs", "/dev/bus/usb", "/dev/bus/usb", true, NULL, false, VINF_SUCCESS, "/dev/bus/usb", false, VINF_SUCCESS }, 91 /* "sysfs" and valid root in the environment, method-specific init failed */92 { "sysfs", "/dev/bus/usb", "/dev/bus/usb", true, NULL, false, VERR_NO_MEMORY, "/dev/bus/usb", false, VERR_NO_MEMORY },93 91 /* "sysfs" and bad root in the environment */ 94 92 { "sysfs", "/dev/bus/usb", "/dev/vboxusb", false, "/proc/usb/bus", false, VINF_SUCCESS, "", true, VERR_NOT_FOUND }, … … 97 95 /* "usbfs" and valid root in the environment */ 98 96 { "usbfs", "/dev/bus/usb", NULL, false, "/dev/bus/usb", true, VINF_SUCCESS, "/dev/bus/usb", true, VINF_SUCCESS }, 99 /* "usbfs" and valid root in the environment, method-specific init failed */100 { "usbfs", "/dev/bus/usb", NULL, false, "/dev/bus/usb", true, VERR_NO_MEMORY, "/dev/bus/usb", true, VERR_NO_MEMORY },101 97 /* "usbfs" and bad root in the environment */ 102 98 { "usbfs", "/dev/bus/usb", "/dev/vboxusb", false, "/proc/usb/bus", false, VINF_SUCCESS, "", true, VERR_NOT_FOUND }, … … 119 115 /* No environment, sysfs available but without access permissions. */ 120 116 { NULL, NULL, "/dev/vboxusb", false, NULL, false, VERR_NO_MEMORY, "", true, VERR_VUSB_USB_DEVICE_PERMISSION }, 121 /* No environment, sysfs available with access permissions, method-specific init failed. */122 { NULL, NULL, "/dev/vboxusb", true, NULL, false, VERR_NO_MEMORY, "/dev/vboxusb", false, VERR_NO_MEMORY },123 117 /* No environment, usbfs available but without access permissions. */ 124 118 { NULL, NULL, NULL, false, "/proc/bus/usb", false, VERR_NO_MEMORY, "", true, VERR_VUSB_USBFS_PERMISSION }, 125 /* No environment, usbfs available with access permissions, method-specific126 * init failed. */127 { NULL, NULL, NULL, false, "/proc/bus/usb", true, VERR_NO_MEMORY, "/proc/bus/usb", true, VERR_NO_MEMORY }128 119 }; 129 120 130 121 static void testInit(RTTEST hTest) 131 122 { 132 RTTestSub(hTest, "Testing USBProxy ServiceLinux initialisation");123 RTTestSub(hTest, "Testing USBProxyLinuxChooseMethod"); 133 124 for (unsigned i = 0; i < RT_ELEMENTS(s_testEnvironment); ++i) 134 125 { 135 USBProxyServiceLinux test(NULL); 126 bool fUsingUsbfs = true; 127 const char *pcszDevicesRoot = ""; 128 136 129 TestUSBSetEnv(s_testEnvironment[i].pcszEnvUsb, 137 130 s_testEnvironment[i].pcszEnvUsbRoot); 138 131 TestUSBSetupInit(s_testEnvironment[i].pcszUsbfsRoot, 139 s_testEnvironment[i].fUsbfsAccessible, 140 s_testEnvironment[i].pcszDevicesRoot, 141 s_testEnvironment[i].fDevicesAccessible, 142 s_testEnvironment[i].rcMethodInit); 143 HRESULT hrc = test.init(); 144 RTTESTI_CHECK_MSG(hrc == S_OK, 145 ("init() returned 0x%x (test index %i)!\n", hrc, i)); 146 int rc = test.getLastError(); 132 s_testEnvironment[i].fUsbfsAccessible, 133 s_testEnvironment[i].pcszDevicesRoot, 134 s_testEnvironment[i].fDevicesAccessible, 135 s_testEnvironment[i].rcMethodInit); 136 int rc = USBProxyLinuxChooseMethod(&fUsingUsbfs, &pcszDevicesRoot); 147 137 RTTESTI_CHECK_MSG(rc == s_testEnvironment[i].rcExpected, 148 (" getLastError() returned%Rrc (test index %i) instead of %Rrc!\n",138 ("rc=%Rrc (test index %i) instead of %Rrc!\n", 149 139 rc, i, s_testEnvironment[i].rcExpected)); 150 const char *pcszDevicesRoot = test.testGetDevicesRoot();151 140 RTTESTI_CHECK_MSG(!RTStrCmp(pcszDevicesRoot, 152 141 s_testEnvironment[i].pcszDevicesRootExpected), … … 154 143 pcszDevicesRoot, i, 155 144 s_testEnvironment[i].pcszDevicesRootExpected)); 156 bool fUsingUsbfs = test.testGetUsingUsbfs();157 145 RTTESTI_CHECK_MSG( fUsingUsbfs 158 146 == s_testEnvironment[i].fUsingUsbfsExpected,
Note:
See TracChangeset
for help on using the changeset viewer.