Index: /trunk/include/iprt/linux/sysfs.h
===================================================================
--- /trunk/include/iprt/linux/sysfs.h	(revision 50782)
+++ /trunk/include/iprt/linux/sysfs.h	(revision 50783)
@@ -208,11 +208,6 @@
 
 /**
- * Find the path of a device node under /dev, given then device number.
- *
- * This function will recursively search under /dev until it finds a device node
- * matching @a devnum, and store the path into @a pszBuf.  The caller may
- * provide an expected path in pszSuggestion, which will be tried before
- * searching, but due to the variance in Linux systems it can be hard to always
- * correctly predict the path.
+ * Check the path of a device node under /dev, given the device number and a
+ * pattern and store the path into @a pszBuf.
  *
  * @returns The length of the returned string on success, -1 and errno on
@@ -224,19 +219,15 @@
  * @param   pszBuf         Where to store the path.
  * @param   cchBuf         The size of the buffer.
- * @param   pszSuggestion  The expected path format of the device node, either
- *                         absolute or relative to "/dev". (Optional)
+ * @param   pszPattern     The expected path format of the device node, either
+ *                         absolute or relative to "/dev".
  * @param   va             Format args.
  */
-RTDECL(ssize_t) RTLinuxFindDevicePathV(dev_t DevNum, RTFMODE fMode, char *pszBuf, size_t cchBuf,
-                                       const char *pszSuggestion, va_list va);
-
-/**
- * Find the path of a device node under /dev, given the device number.
- *
- * This function will recursively search under /dev until it finds a device node
- * matching @a devnum, and store the path into @a pszBuf.  The caller may
- * provide an expected path in pszSuggestion, which will be tried before
- * searching, but due to the variance in Linux systems it can be hard to always
- * correctly predict the path.
+RTDECL(ssize_t) RTLinuxCheckDevicePathV(dev_t DevNum, RTFMODE fMode,
+                                        char *pszBuf, size_t cchBuf,
+                                        const char *pszPattern, va_list va);
+
+/**
+ * Check the path of a device node under /dev, given the device number and a
+ * pattern and store the path into @a pszBuf.
  *
  * @returns The length of the returned string on success, -1 and errno on
@@ -248,10 +239,11 @@
  * @param   pszBuf          Where to store the path.
  * @param   cchBuf          The size of the buffer.
- * @param   pszSuggestion   The expected path format of the device node, either
- *                          absolute or relative to "/dev". (Optional)
+ * @param   pszPattern      The expected path format of the device node, either
+ *                          absolute or relative to "/dev".
  * @param   ...             Format args.
  */
-RTDECL(ssize_t) RTLinuxFindDevicePath(dev_t DevNum, RTFMODE fMode, char *pszBuf, size_t cchBuf,
-                                      const char *pszSuggestion, ...);
+RTDECL(ssize_t) RTLinuxCheckDevicePath(dev_t DevNum, RTFMODE fMode,
+                                       char *pszBuf, size_t cchBuf,
+                                       const char *pszPattern, ...);
 
 /** @} */
Index: /trunk/src/VBox/Main/src-server/linux/HostHardwareLinux.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/linux/HostHardwareLinux.cpp	(revision 50782)
+++ /trunk/src/VBox/Main/src-server/linux/HostHardwareLinux.cpp	(revision 50783)
@@ -86,6 +86,4 @@
 static int getDriveInfoFromEnv(const char *pcszVar, DriveInfoList *pList,
                                bool isDVD, bool *pfSuccess);
-static int getDriveInfoFromDev(DriveInfoList *pList, bool isDVD,
-                               bool *pfSuccess);
 static int getDriveInfoFromSysfs(DriveInfoList *pList, bool isDVD,
                                  bool *pfSuccess);
@@ -469,7 +467,4 @@
             rc = getDriveInfoFromSysfs(&mDVDList, true /* isDVD */, &success);
         }
-        /* Walk through the /dev subtree if nothing else has helped. */
-        if (RT_SUCCESS(rc) && (!success | testing()))
-            rc = getDriveInfoFromDev(&mDVDList, true /* isDVD */, &success);
     }
     catch(std::bad_alloc &e)
@@ -501,8 +496,4 @@
             rc = getDriveInfoFromSysfs(&mFloppyList, false /* isDVD */, &success);
         }
-        /* Walk through the /dev subtree if nothing else has helped. */
-        if (   RT_SUCCESS(rc) && (!success || testing()))
-            rc = getDriveInfoFromDev(&mFloppyList, false /* isDVD */,
-                                     &success);
     }
     catch(std::bad_alloc &e)
@@ -622,6 +613,6 @@
             return false;
         }
-        if (RTLinuxFindDevicePath(dev, RTFS_TYPE_DEV_BLOCK, mszNode,
-                                  sizeof(mszNode), "%s", mpcszName) < 0)
+        if (RTLinuxCheckDevicePath(dev, RTFS_TYPE_DEV_BLOCK, mszNode,
+                                   sizeof(mszNode), "%s", mpcszName) < 0)
             return false;
         return true;
@@ -809,168 +800,4 @@
 
 
-/** Structure for holding information about a drive we have found */
-struct deviceNodeInfo
-{
-    /** The device number */
-    dev_t Device;
-    /** The device node path */
-    char szPath[RTPATH_MAX];
-    /** The device description */
-    char szDesc[256];
-    /** The device UDI */
-    char szUdi[256];
-};
-
-/** The maximum number of devices we will search for. */
-enum { MAX_DEVICE_NODES = 8 };
-/** An array of MAX_DEVICE_NODES devices */
-typedef struct deviceNodeInfo deviceNodeArray[MAX_DEVICE_NODES];
-
-/**
- * Recursive worker function to walk the /dev tree looking for DVD or floppy
- * devices.
- * @returns true if we have already found MAX_DEVICE_NODES devices, false
- *          otherwise
- * @param   pszPath   the path to start recursing.  The function can modify
- *                    this string at and after the terminating zero
- * @param   cchPath   the size of the buffer (not the string!) in @a pszPath
- * @param   aDevices  where to fill in information about devices that we have
- *                    found
- * @param   wantDVD   are we looking for DVD devices (or floppies)?
- */
-static bool devFindDeviceRecursive(char *pszPath, size_t cchPath,
-                                   deviceNodeArray aDevices, bool wantDVD)
-{
-    /*
-     * Check assumptions made by the code below.
-     */
-    size_t const cchBasePath = strlen(pszPath);
-    AssertReturn(cchBasePath < RTPATH_MAX - 10U, false);
-    AssertReturn(pszPath[cchBasePath - 1] != '/', false);
-
-    PRTDIR  pDir;
-    if (RT_FAILURE(RTDirOpen(&pDir, pszPath)))
-        return false;
-    for (;;)
-    {
-        RTDIRENTRY Entry;
-        RTFSOBJINFO ObjInfo;
-        int rc = RTDirRead(pDir, &Entry, NULL);
-        if (RT_FAILURE(rc))
-            break;
-        if (Entry.enmType == RTDIRENTRYTYPE_UNKNOWN)
-        {
-            if (RT_FAILURE(RTPathQueryInfo(pszPath, &ObjInfo,
-                           RTFSOBJATTRADD_UNIX)))
-                continue;
-            if (RTFS_IS_SYMLINK(ObjInfo.Attr.fMode))
-                continue;
-        }
-
-        if (Entry.enmType == RTDIRENTRYTYPE_SYMLINK)
-            continue;
-        pszPath[cchBasePath] = '\0';
-        if (RT_FAILURE(RTPathAppend(pszPath, cchPath, Entry.szName)))
-            break;
-
-        /* Do the matching. */
-        dev_t DevNode;
-        char szDesc[256], szUdi[256];
-        if (!devValidateDevice(pszPath, wantDVD, &DevNode, szDesc,
-                               sizeof(szDesc), szUdi, sizeof(szUdi)))
-            continue;
-        unsigned i;
-        for (i = 0; i < MAX_DEVICE_NODES; ++i)
-            if (!aDevices[i].Device || (aDevices[i].Device == DevNode))
-                break;
-        AssertBreak(i < MAX_DEVICE_NODES);
-        if (aDevices[i].Device)
-            continue;
-        aDevices[i].Device = DevNode;
-        RTStrPrintf(aDevices[i].szPath, sizeof(aDevices[i].szPath),
-                    "%s", pszPath);
-        AssertCompile(sizeof(aDevices[i].szDesc) == sizeof(szDesc));
-        strcpy(aDevices[i].szDesc, szDesc);
-        AssertCompile(sizeof(aDevices[i].szUdi) == sizeof(szUdi));
-        strcpy(aDevices[i].szUdi, szUdi);
-        if (i == MAX_DEVICE_NODES - 1)
-            break;
-        continue;
-
-        /* Recurse into subdirectories. */
-        if (   (Entry.enmType == RTDIRENTRYTYPE_UNKNOWN)
-            && !RTFS_IS_DIRECTORY(ObjInfo.Attr.fMode))
-            continue;
-        if (Entry.enmType != RTDIRENTRYTYPE_DIRECTORY)
-            continue;
-        if (Entry.szName[0] == '.')
-            continue;
-
-        if (devFindDeviceRecursive(pszPath, cchPath, aDevices, wantDVD))
-            break;
-    }
-    RTDirClose(pDir);
-    return aDevices[MAX_DEVICE_NODES - 1].Device ? true : false;
-}
-
-
-/**
- * Recursively walk through the /dev tree and add any DVD or floppy drives we
- * find and can access to our list.  (If we can't access them we can't check
- * whether or not they are really DVD or floppy drives).
- * @note  this is rather slow (a couple of seconds) for DVD probing on
- *        systems with a static /dev tree, as the current code tries to open
- *        any device node with a major/minor combination that could belong to
- *        a CD-ROM device, and opening a non-existent device can take a non.
- *        negligible time on Linux.  If it is ever necessary to improve this
- *        (static /dev trees are no longer very fashionable these days, and
- *        sysfs looks like it will be with us for a while), we could further
- *        reduce the number of device nodes we open by checking whether the
- *        driver is actually loaded in /proc/devices, and by counting the
- *        of currently attached SCSI CD-ROM devices in /proc/scsi/scsi (yes,
- *        there is a race, but it is probably not important for us).
- * @returns iprt status code
- * @param   pList      the list to append the drives found to
- * @param   isDVD      are we looking for DVD drives or for floppies?
- * @param   pfSuccess  this will be set to true if we found at least one drive
- *                     and to false otherwise.  Optional.
- */
-/* static */
-int getDriveInfoFromDev(DriveInfoList *pList, bool isDVD, bool *pfSuccess)
-{
-    AssertPtrReturn(pList, VERR_INVALID_POINTER);
-    AssertPtrNullReturn(pfSuccess, VERR_INVALID_POINTER);
-    LogFlowFunc(("pList=%p, isDVD=%d, pfSuccess=%p\n", pList, isDVD,
-                 pfSuccess));
-    int rc = VINF_SUCCESS;
-    bool success = false;
-
-    char szPath[RTPATH_MAX] = "/dev";
-    deviceNodeArray aDevices;
-    RT_ZERO(aDevices);
-    devFindDeviceRecursive(szPath, sizeof(szPath), aDevices, isDVD);
-    try
-    {
-        for (unsigned i = 0; i < MAX_DEVICE_NODES; ++i)
-        {
-            if (aDevices[i].Device)
-            {
-                pList->push_back(DriveInfo(aDevices[i].szPath,
-                                 aDevices[i].szUdi, aDevices[i].szDesc));
-                success = true;
-            }
-        }
-        if (pfSuccess != NULL)
-            *pfSuccess = success;
-    }
-    catch(std::bad_alloc &e)
-    {
-        rc = VERR_NO_MEMORY;
-    }
-    LogFlowFunc (("rc=%Rrc, success=%d\n", rc, success));
-    return rc;
-}
-
-
 /** Helper for readFilePathsFromDir().  Adds a path to the vector if it is not
  * NULL and not a dotfile (".", "..", ".*"). */
Index: /trunk/src/VBox/Main/src-server/linux/USBGetDevices.cpp
===================================================================
--- /trunk/src/VBox/Main/src-server/linux/USBGetDevices.cpp	(revision 50782)
+++ /trunk/src/VBox/Main/src-server/linux/USBGetDevices.cpp	(revision 50783)
@@ -882,8 +882,8 @@
     char szDevPath[RTPATH_MAX];
     ssize_t cchDevPath;
-    cchDevPath = RTLinuxFindDevicePath(devnum, RTFS_TYPE_DEV_CHAR,
-                                       szDevPath, sizeof(szDevPath),
-                                       "%s/%.3d/%.3d",
-                                       pcszDevicesRoot, bus, device);
+    cchDevPath = RTLinuxCheckDevicePath(devnum, RTFS_TYPE_DEV_CHAR,
+                                        szDevPath, sizeof(szDevPath),
+                                        "%s/%.3d/%.3d",
+                                        pcszDevicesRoot, bus, device);
     if (cchDevPath < 0)
         return VINF_SUCCESS;
Index: /trunk/src/VBox/Runtime/r3/linux/sysfs.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/linux/sysfs.cpp	(revision 50782)
+++ /trunk/src/VBox/Runtime/r3/linux/sysfs.cpp	(revision 50783)
@@ -413,62 +413,7 @@
 
 
-/** Search for a device node with the number @a DevNum and the type (character
- * or block) @a fMode below the path @a pszPath.  @a pszPath MUST point to a
- * buffer of size at least RTPATH_MAX which will be modified during the function
- * execution.  On successful return it will contain the path to the device node
- * found. */
-/** @note This function previously used a local stack buffer of size RTPATH_MAX
- *    to construct the path passed to the next recursive call, which used up 4K
- *    of stack space per iteration and caused a stack overflow on a path with
- *    too many components. */
-static int rtLinuxFindDevicePathRecursive(dev_t DevNum, RTFMODE fMode,
-                                          char *pszPath)
-{
-    int rc;
-    PRTDIR  pDir;
-    size_t const cchPath = strlen(pszPath);
-
-    /*
-     * Check assumptions made by the code below.
-     */
-    AssertReturn(cchPath < RTPATH_MAX - 10U, VERR_BUFFER_OVERFLOW);
-    rc = RTDirOpen(&pDir, pszPath);
-    if (RT_SUCCESS(rc))
-    {
-        for (;;)
-        {
-            RTDIRENTRYEX Entry;
-            rc = RTDirReadEx(pDir, &Entry, NULL, RTFSOBJATTRADD_UNIX,
-                             RTPATH_F_ON_LINK);
-            if (RT_FAILURE(rc))
-                break;
-            if (RTFS_IS_SYMLINK(Entry.Info.Attr.fMode))
-                continue;
-            pszPath[cchPath] = '\0';
-            rc = RTPathAppend(pszPath, RTPATH_MAX, Entry.szName);
-            if (RT_FAILURE(rc))
-                break;
-            /* Do the matching. */
-            if (   Entry.Info.Attr.u.Unix.Device == DevNum
-                && (Entry.Info.Attr.fMode & RTFS_TYPE_MASK) == fMode)
-                break;
-            /* Recurse into subdirectories. */
-            if (!RTFS_IS_DIRECTORY(Entry.Info.Attr.fMode))
-                continue;
-            if (Entry.szName[0] == '.')
-                continue;
-            rc = rtLinuxFindDevicePathRecursive(DevNum, fMode, pszPath);
-            if (RT_SUCCESS(rc) || rc != VERR_NO_MORE_FILES)
-                break;
-        }
-        RTDirClose(pDir);
-    }
-    return rc;
-}
-
-
-RTDECL(ssize_t) RTLinuxFindDevicePathV(dev_t DevNum, RTFMODE fMode, char *pszBuf,
-                                       size_t cchBuf, const char *pszSuggestion,
-                                       va_list va)
+RTDECL(ssize_t) RTLinuxCheckDevicePathV(dev_t DevNum, RTFMODE fMode, char *pszBuf,
+                                        size_t cchBuf, const char *pszPattern,
+                                        va_list va)
 {
     char szFilename[RTPATH_MAX];
@@ -479,5 +424,5 @@
                  || fMode == RTFS_TYPE_DEV_BLOCK,
                  VERR_INVALID_PARAMETER);
-    if (pszSuggestion)
+    if (pszPattern)
     {
         /*
@@ -485,27 +430,17 @@
          */
         rc = rtLinuxConstructPathV(szFilename, sizeof(szFilename), "/dev/",
-                                   pszSuggestion, va);
+                                   pszPattern, va);
         if (rc > 0)
         {
-            /*
-             * Check whether the caller's suggestion was right.
-             */
             RTFSOBJINFO Info;
             rc = RTPathQueryInfo(szFilename, &Info, RTFSOBJATTRADD_UNIX);
-            if (   rc == VERR_PATH_NOT_FOUND 
-                || rc == VERR_FILE_NOT_FOUND
+            if (   rc == VERR_PATH_NOT_FOUND
                 || (   RT_SUCCESS(rc)
                     && (   Info.Attr.u.Unix.Device != DevNum
                         || (Info.Attr.fMode & RTFS_TYPE_MASK) != fMode)))
-            /* The suggestion was wrong, fall back on the brute force attack. */
-                rc = VINF_TRY_AGAIN;
+                rc = VERR_FILE_NOT_FOUND;
         }
     }
 
-    if (rc == VINF_TRY_AGAIN)
-    {
-        RTStrCopy(szFilename, sizeof(szFilename), "/dev/");
-        rc = rtLinuxFindDevicePathRecursive(DevNum, fMode, szFilename);
-    }
     if (RT_SUCCESS(rc))
     {
@@ -522,13 +457,14 @@
 /** @todo Do we really need to return the string length?  If the caller is
  * interested (the current ones aren't) they can check themselves. */
-RTDECL(ssize_t) RTLinuxFindDevicePath(dev_t DevNum, RTFMODE fMode, char *pszBuf,
-                                      size_t cchBuf, const char *pszSuggestion,
-                                      ...)
-{
-    va_list va;
-    va_start(va, pszSuggestion);
-    int rc = RTLinuxFindDevicePathV(DevNum, fMode, pszBuf, cchBuf, pszSuggestion, va);
-    va_end(va);
-    return rc;
-}
-
+RTDECL(ssize_t) RTLinuxCheckDevicePath(dev_t DevNum, RTFMODE fMode, char *pszBuf,
+                                       size_t cchBuf, const char *pszPattern,
+                                       ...)
+{
+    va_list va;
+    va_start(va, pszPattern);
+    int rc = RTLinuxCheckDevicePathV(DevNum, fMode, pszBuf, cchBuf,
+                                     pszPattern, va);
+    va_end(va);
+    return rc;
+}
+
