Author: omalley Date: Mon Jul 2 10:36:56 2007 New Revision: 552548 URL: http://svn.apache.org/viewvc?view=rev&rev=552548 Log: Fix HADOOP-1513, which is a race condition in directory creation. Thanks Devaraj.
Modified: lucene/hadoop/trunk/CHANGES.txt lucene/hadoop/trunk/src/java/org/apache/hadoop/util/DiskChecker.java Modified: lucene/hadoop/trunk/CHANGES.txt URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/CHANGES.txt?view=diff&rev=552548&r1=552547&r2=552548 ============================================================================== --- lucene/hadoop/trunk/CHANGES.txt (original) +++ lucene/hadoop/trunk/CHANGES.txt Mon Jul 2 10:36:56 2007 @@ -271,6 +271,8 @@ 83. HADOOP-1520. Add appropriate synchronization to FSEditsLog. (Dhruba Borthakur via nigel) + 84. HADOOP-1513. Fix a race condition in directory creation. + (Devaraj via omalley) Release 0.13.0 - 2007-06-08 Modified: lucene/hadoop/trunk/src/java/org/apache/hadoop/util/DiskChecker.java URL: http://svn.apache.org/viewvc/lucene/hadoop/trunk/src/java/org/apache/hadoop/util/DiskChecker.java?view=diff&rev=552548&r1=552547&r2=552548 ============================================================================== --- lucene/hadoop/trunk/src/java/org/apache/hadoop/util/DiskChecker.java (original) +++ lucene/hadoop/trunk/src/java/org/apache/hadoop/util/DiskChecker.java Mon Jul 2 10:36:56 2007 @@ -21,8 +21,37 @@ } } + /** + * The semantics of mkdirsWithExistsCheck method is different from the mkdirs + * method provided in the Sun's java.io.File class in the following way: + * While creating the non-existent parent directories, this method checks for + * the existence of those directories if the mkdir fails at any point (since + * that directory might have just been created by some other process). + * If both mkdir() and the exists() check fails for any seemingly + * non-existent directory, then we signal an error; Sun's mkdir would signal + * an error (return false) if a directory it is attempting to create already + * exists or the mkdir fails. + * @param dir + * @return true on success, false on failure + */ + public static boolean mkdirsWithExistsCheck(File dir) { + if (dir.mkdir() || dir.exists()) { + return true; + } + File canonDir = null; + try { + canonDir = dir.getCanonicalFile(); + } catch (IOException e) { + return false; + } + String parent = canonDir.getParent(); + return (parent != null) && + (mkdirsWithExistsCheck(new File(parent)) && + (canonDir.mkdir() || canonDir.exists())); + } + public static void checkDir(File dir) throws DiskErrorException { - if (!dir.exists() && !dir.mkdirs()) + if (!mkdirsWithExistsCheck(dir)) throw new DiskErrorException("can not create directory: " + dir.toString());