internal virtual IDictionary <string, DirectoryCollection.DiskErrorInformation> TestDirs (IList <string> dirs) { Dictionary <string, DirectoryCollection.DiskErrorInformation> ret = new Dictionary <string, DirectoryCollection.DiskErrorInformation>(); foreach (string dir in dirs) { string msg; try { FilePath testDir = new FilePath(dir); DiskChecker.CheckDir(testDir); if (IsDiskUsageOverPercentageLimit(testDir)) { msg = "used space above threshold of " + diskUtilizationPercentageCutoff + "%"; ret[dir] = new DirectoryCollection.DiskErrorInformation(DirectoryCollection.DiskErrorCause .DiskFull, msg); continue; } else { if (IsDiskFreeSpaceUnderLimit(testDir)) { msg = "free space below limit of " + diskUtilizationSpaceCutoff + "MB"; ret[dir] = new DirectoryCollection.DiskErrorInformation(DirectoryCollection.DiskErrorCause .DiskFull, msg); continue; } } // create a random dir to make sure fs isn't in read-only mode VerifyDirUsingMkdir(testDir); } catch (IOException ie) { ret[dir] = new DirectoryCollection.DiskErrorInformation(DirectoryCollection.DiskErrorCause .Other, ie.Message); } } return(ret); }
/// <summary> /// Check the health of current set of local directories(good and failed), /// updating the list of valid directories if necessary. /// </summary> /// <returns> /// <em>true</em> if there is a new disk-failure identified in this /// checking or a failed directory passes the disk check <em>false</em> /// otherwise. /// </returns> internal virtual bool CheckDirs() { lock (this) { bool setChanged = false; ICollection <string> preCheckGoodDirs = new HashSet <string>(localDirs); ICollection <string> preCheckFullDirs = new HashSet <string>(fullDirs); ICollection <string> preCheckOtherErrorDirs = new HashSet <string>(errorDirs); IList <string> failedDirs = DirectoryCollection.Concat(errorDirs, fullDirs); IList <string> allLocalDirs = DirectoryCollection.Concat(localDirs, failedDirs); IDictionary <string, DirectoryCollection.DiskErrorInformation> dirsFailedCheck = TestDirs (allLocalDirs); localDirs.Clear(); errorDirs.Clear(); fullDirs.Clear(); foreach (KeyValuePair <string, DirectoryCollection.DiskErrorInformation> entry in dirsFailedCheck) { string dir = entry.Key; DirectoryCollection.DiskErrorInformation errorInformation = entry.Value; switch (entry.Value.cause) { case DirectoryCollection.DiskErrorCause.DiskFull: { fullDirs.AddItem(entry.Key); break; } case DirectoryCollection.DiskErrorCause.Other: { errorDirs.AddItem(entry.Key); break; } } if (preCheckGoodDirs.Contains(dir)) { Log.Warn("Directory " + dir + " error, " + errorInformation.message + ", removing from list of valid directories" ); setChanged = true; numFailures++; } } foreach (string dir_1 in allLocalDirs) { if (!dirsFailedCheck.Contains(dir_1)) { localDirs.AddItem(dir_1); if (preCheckFullDirs.Contains(dir_1) || preCheckOtherErrorDirs.Contains(dir_1)) { setChanged = true; Log.Info("Directory " + dir_1 + " passed disk check, adding to list of valid directories." ); } } } ICollection <string> postCheckFullDirs = new HashSet <string>(fullDirs); ICollection <string> postCheckOtherDirs = new HashSet <string>(errorDirs); foreach (string dir_2 in preCheckFullDirs) { if (postCheckOtherDirs.Contains(dir_2)) { Log.Warn("Directory " + dir_2 + " error " + dirsFailedCheck[dir_2].message); } } foreach (string dir_3 in preCheckOtherErrorDirs) { if (postCheckFullDirs.Contains(dir_3)) { Log.Warn("Directory " + dir_3 + " error " + dirsFailedCheck[dir_3].message); } } return(setChanged); } }