Index: /trunk/src/VBox/ValidationKit/testmanager/batch/virtual_test_sheriff.py
===================================================================
--- /trunk/src/VBox/ValidationKit/testmanager/batch/virtual_test_sheriff.py	(revision 65316)
+++ /trunk/src/VBox/ValidationKit/testmanager/batch/virtual_test_sheriff.py	(revision 65317)
@@ -328,4 +328,7 @@
         return 0;
 
+    def getFailureReason(self, tReason):
+        """ Gets the failure reason object for tReason. """
+        return self.oFailureReasonLogic.cachedLookupByNameAndCategory(tReason[1], tReason[0]);
 
     def selfCheck(self):
@@ -335,5 +338,5 @@
             if sAttr.startswith('ktReason_'):
                 tReason = getattr(self.__class__, sAttr);
-                oFailureReason = self.oFailureReasonLogic.cachedLookupByNameAndCategory(tReason[1], tReason[0]);
+                oFailureReason = self.getFailureReason(tReason);
                 if oFailureReason is None:
                     rcExit = self.eprint(u'Failed to find failure reason "%s" in category "%s" in the database!'
@@ -366,7 +369,15 @@
 
         #
+        # Generate a list of failures reasons we consider bad-testbox behavior.
+        #
+        aidFailureReasons = [
+            self.getFailureReason(self.ktReason_Host_DriverNotUnloading).idFailureReason,
+        ];
+
+        #
         # Get list of bad test boxes for given period and check them out individually.
         #
-        aidBadTestBoxes = self.oTestSetLogic.fetchBadTestBoxIds(cHoursBack = cHoursBack, tsNow = tsNow);
+        aidBadTestBoxes = self.oTestSetLogic.fetchBadTestBoxIds(cHoursBack = cHoursBack, tsNow = tsNow,
+                                                                aidFailureReasons = aidFailureReasons);
         for idTestBox in aidBadTestBoxes:
             # Skip if the testbox is already disabled or has a pending reboot command.
@@ -394,8 +405,16 @@
                     cBad += 1;
                 else:
-                    ## @todo maybe check the elapsed time here, it could still be a bad run.
-                    cOkay += 1;
-                    if iFirstOkay > iSet:
-                        iFirstOkay = iSet;
+                    # Check for bad failure reasons.
+                    oFailure = None;
+                    if oSet.enmStatus in TestSetData.kasBadTestStatuses:
+                        oFailure = self.oTestResultFailureLogic.getById(oSet.idTestResult);
+                    if oFailure is not None and oFailure.idFailureReason in aidFailureReasons:
+                        cBad += 1;
+                    else:
+                        # This is an okay test result then.
+                        ## @todo maybe check the elapsed time here, it could still be a bad run?
+                        cOkay += 1;
+                        if iFirstOkay > iSet:
+                            iFirstOkay = iSet;
                 if iSet > 10:
                     break;
@@ -522,5 +541,5 @@
         #
         for idTestResult, tReason in dReasonForResultId.items():
-            oFailureReason = self.oFailureReasonLogic.cachedLookupByNameAndCategory(tReason[1], tReason[0]);
+            oFailureReason = self.getFailureReason(tReason);
             if oFailureReason is not None:
                 sComment = 'Set by $Revision$' # Handy for reverting later.
@@ -641,4 +660,6 @@
         an uninstall first and will be seeing similar issues to the uninstall.
         """
+        _ = fInstall;
+
         atSimple = self.katSimpleInstallUninstallMainLogReasons;
         if oCaseFile.oTestBox.sOs in self.kdatSimpleInstallUninstallMainLogReasonsPerOs:
@@ -1138,5 +1159,7 @@
                 self.uidSelf = self.oLogin.uid;
 
+        #
         # Do the stuff.
+        #
         if rcExit == 0:
             rcExit  = self.selfCheck();
@@ -1146,4 +1169,7 @@
             if rcExit == 0:
                 rcExit = rcExit2;
+            # Redo the bad testbox management after failure reasons have been assigned (got timing issues).
+            if rcExit == 0:
+                rcExit = self.badTestBoxManagement();
 
         # Cleanup.
Index: /trunk/src/VBox/ValidationKit/testmanager/core/testset.py
===================================================================
--- /trunk/src/VBox/ValidationKit/testmanager/core/testset.py	(revision 65316)
+++ /trunk/src/VBox/ValidationKit/testmanager/core/testset.py	(revision 65317)
@@ -742,5 +742,5 @@
     #
 
-    def fetchBadTestBoxIds(self, cHoursBack = 2, tsNow = None):
+    def fetchBadTestBoxIds(self, cHoursBack = 2, tsNow = None, aidFailureReasons = None):
         """
         Fetches a list of test box IDs which returned bad-testbox statuses in the
@@ -749,10 +749,25 @@
         if tsNow is None:
             tsNow = self._oDb.getCurrentTimestamp();
-        self._oDb.execute('SELECT DISTINCT idTestBox\n'
-                          'FROM   TestSets\n'
-                          'WHERE  TestSets.enmStatus = \'bad-testbox\'\n'
-                          '   AND tsDone           <= %s\n'
-                          '   AND tsDone            > (%s - interval \'%s hours\')\n'
-                          , ( tsNow, tsNow, cHoursBack,));
+        if aidFailureReasons is None:
+            aidFailureReasons = [ -1, ];
+        self._oDb.execute('(SELECT idTestBox\n'
+                          ' FROM   TestSets\n'
+                          ' WHERE  TestSets.enmStatus = \'bad-testbox\'\n'
+                          '    AND tsDone           <= %s\n'
+                          '    AND tsDone            > (%s - interval \'%s hours\')\n'
+                          ') UNION (\n'
+                          ' SELECT TestSets.idTestBox\n'
+                          '   FROM TestSets,\n'
+                          '        TestResultFailures\n'
+                          '  WHERE TestSets.tsDone                   <= %s\n'
+                          '    AND TestSets.tsDone                   >  (%s - interval \'%s hours\')\n'
+                          '    AND TestSets.enmStatus                >= \'failure\'::TestStatus_T\n'
+                          '    AND TestSets.idTestSet                 = TestResultFailures.idTestSet\n'
+                          '    AND TestResultFailures.tsExpire        = \'infinity\'::TIMESTAMP\n'
+                          '    AND TestResultFailures.idFailureReason IN ('
+                          + ', '.join([str(i) for i in aidFailureReasons]) + ')\n'
+                          ')\n'
+                          , ( tsNow, tsNow, cHoursBack,
+                              tsNow, tsNow, cHoursBack, ));
         return [aoRow[0] for aoRow in self._oDb.fetchAll()];
 
