This is an automated email from the ASF dual-hosted git repository.

stevel pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/hadoop.git


The following commit(s) were added to refs/heads/trunk by this push:
     new cd68d134989 Revert " HADOOP-19554. LocalDirAllocator still doesn't 
always recover from directory deletion (#7651)"
cd68d134989 is described below

commit cd68d1349896b391244b3764cb4050b07452683b
Author: Steve Loughran <ste...@cloudera.com>
AuthorDate: Mon May 12 17:33:09 2025 +0100

    Revert " HADOOP-19554. LocalDirAllocator still doesn't always recover from 
directory deletion (#7651)"
    
    not the final commit
    
    This reverts commit 4769febaccc3a55ca61f600db0a2eaf11459b333.
---
 .../org/apache/hadoop/fs/LocalDirAllocator.java    | 118 +++++----------------
 .../apache/hadoop/fs/TestLocalDirAllocator.java    |  44 ++------
 2 files changed, 33 insertions(+), 129 deletions(-)

diff --git 
a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/LocalDirAllocator.java
 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/LocalDirAllocator.java
index ba7a5418e61..d8ab16f41d3 100644
--- 
a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/LocalDirAllocator.java
+++ 
b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/LocalDirAllocator.java
@@ -65,10 +65,7 @@
 @InterfaceAudience.LimitedPrivate({"HDFS", "MapReduce"})
 @InterfaceStability.Unstable
 public class LocalDirAllocator {
-
-  static final String E_NO_SPACE_AVAILABLE =
-      "No space available in any of the local directories";
-
+  
   //A Map from the config item names like "mapred.local.dir"
   //to the instance of the AllocatorPerContext. This
   //is a static object to make sure there exists exactly one instance per JVM
@@ -387,24 +384,6 @@ int getCurrentDirectoryIndex() {
       return currentContext.get().dirNumLastAccessed.get();
     }
 
-    /**
-     * Format a string, log at debug and append it to the history as a new 
line.
-     *
-     * @param history history to fill in
-     * @param fmt format string
-     * @param args varags
-     */
-    private void note(StringBuilder history, String fmt, Object... args) {
-      try {
-        final String s = String.format(fmt, args);
-        history.append(s).append("\n");
-        LOG.debug(s);
-      } catch (Exception e) {
-        // some resilience in case the format string is wrong
-        LOG.debug(fmt, e);
-      }
-    }
-
     /** Get a path from the local FS. If size is known, we go
      *  round-robin over the set of disks (via the configured dirs) and return
      *  the first complete path which has enough space.
@@ -414,12 +393,6 @@ private void note(StringBuilder history, String fmt, 
Object... args) {
      */
     public Path getLocalPathForWrite(String pathStr, long size,
         Configuration conf, boolean checkWrite) throws IOException {
-
-      // history is built up and logged at error if the alloc
-      StringBuilder history = new StringBuilder();
-
-      note(history, "Searchng for a directory for file at %s, size = %,d; 
checkWrite=%s",
-          pathStr, size, checkWrite);
       Context ctx = confChanged(conf);
       int numDirs = ctx.localDirs.length;
       int numDirsSearched = 0;
@@ -433,56 +406,27 @@ public Path getLocalPathForWrite(String pathStr, long 
size,
         pathStr = pathStr.substring(1);
       }
       Path returnPath = null;
-
-      final int dirCount = ctx.dirDF.length;
-      long[] availableOnDisk = new long[dirCount];
-      long totalAvailable = 0;
-
-      StringBuilder pathNames = new StringBuilder();
-
-      //build the "roulette wheel"
-      for (int i =0; i < dirCount; ++i) {
-        final DF target = ctx.dirDF[i];
-        // attempt to recreate the dir so that getAvailable() is valid
-        // if it fails, getAvailable() will return 0, so the dir will
-        // be declared unavailable.
-        // return value is logged at debug to keep spotbugs quiet.
-        final String name = target.getDirPath();
-        pathNames.append(" ").append(name);
-        final File dirPath = new File(name);
-
-        // existence probe
-        if (!dirPath.exists()) {
-          LOG.debug("creating buffer dir {}", name);
-          if (dirPath.mkdirs()) {
-            note(history, "Created buffer dir %s", name);
-          } else {
-            note(history, "Failed to create buffer dir %s", name);
-          }
-        }
-
-        // path already existed or the mkdir call had an outcome
-        // make sure the path is present and a dir, and if so add its 
availability
-        if (dirPath.isDirectory()) {
-          final long available = target.getAvailable();
-          availableOnDisk[i] = available;
-          note(history, "%s available under path %s",  pathStr, available);
+      
+      if(size == SIZE_UNKNOWN) {  //do roulette selection: pick dir with 
probability 
+                    //proportional to available size
+        long[] availableOnDisk = new long[ctx.dirDF.length];
+        long totalAvailable = 0;
+        
+            //build the "roulette wheel"
+        for(int i =0; i < ctx.dirDF.length; ++i) {
+          final DF target = ctx.dirDF[i];
+          // attempt to recreate the dir so that getAvailable() is valid
+          // if it fails, getAvailable() will return 0, so the dir will
+          // be declared unavailable.
+          // return value is logged at debug to keep spotbugs quiet.
+          final boolean b = new File(target.getDirPath()).mkdirs();
+          LOG.debug("mkdirs of {}={}", target, b);
+          availableOnDisk[i] = target.getAvailable();
           totalAvailable += availableOnDisk[i];
-        } else {
-          note(history, "%s does not exist/is not a directory",  pathStr);
         }
-      }
-
-      note(history, "Directory count is %d; total available capacity is %,d{}",
-          dirCount, totalAvailable);
 
-      if (size == SIZE_UNKNOWN) {
-        //do roulette selection: pick dir with probability
-        // proportional to available size
-        note(history, "Size not specified, so picking at random.");
-
-        if (totalAvailable == 0) {
-          throw new DiskErrorException(E_NO_SPACE_AVAILABLE + pathNames + "; 
history=" + history);
+        if (totalAvailable == 0){
+          throw new DiskErrorException("No space available in any of the local 
directories.");
         }
 
         // Keep rolling the wheel till we get a valid path
@@ -495,19 +439,14 @@ public Path getLocalPathForWrite(String pathStr, long 
size,
             dir++;
           }
           ctx.dirNumLastAccessed.set(dir);
-          final Path localDir = ctx.localDirs[dir];
-          returnPath = createPath(localDir, pathStr, checkWrite);
+          returnPath = createPath(ctx.localDirs[dir], pathStr, checkWrite);
           if (returnPath == null) {
             totalAvailable -= availableOnDisk[dir];
             availableOnDisk[dir] = 0; // skip this disk
             numDirsSearched++;
-            note(history, "No capacity in %s", localDir);
-          } else {
-            note(history, "Allocated file %s in %s", returnPath, localDir);
           }
         }
       } else {
-        note(history, "Size is %,d; searching", size);
         // Start linear search with random increment if possible
         int randomInc = 1;
         if (numDirs > 2) {
@@ -520,22 +459,17 @@ public Path getLocalPathForWrite(String pathStr, long 
size,
             maxCapacity = capacity;
           }
           if (capacity > size) {
-            final Path localDir = ctx.localDirs[dirNum];
             try {
-              returnPath = createPath(localDir, pathStr, checkWrite);
+              returnPath = createPath(ctx.localDirs[dirNum], pathStr,
+                  checkWrite);
             } catch (IOException e) {
               errorText = e.getMessage();
               diskException = e;
-              note(history, "Exception while creating path %s: %s", localDir, 
errorText);
-              LOG.debug("DiskException caught for dir {}", localDir, e);
+              LOG.debug("DiskException caught for dir {}", 
ctx.localDirs[dirNum], e);
             }
             if (returnPath != null) {
-              // success
               ctx.getAndIncrDirNumLastAccessed(numDirsSearched);
-              note(history, "Allocated file %s in %s", returnPath, localDir);
               break;
-            } else {
-              note(history, "No capacity in %s", localDir);
             }
           }
           dirNum++;
@@ -550,14 +484,10 @@ public Path getLocalPathForWrite(String pathStr, long 
size,
       //no path found
       String newErrorText = "Could not find any valid local directory for " +
           pathStr + " with requested size " + size +
-          " as the max capacity in any directory"
-          + " (" + pathNames + " )"
-          + " is " + maxCapacity;
+          " as the max capacity in any directory is " + maxCapacity;
       if (errorText != null) {
         newErrorText = newErrorText + " due to " + errorText;
       }
-      LOG.error(newErrorText);
-      LOG.error(history.toString());
       throw new DiskErrorException(newErrorText, diskException);
     }
 
diff --git 
a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestLocalDirAllocator.java
 
b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestLocalDirAllocator.java
index 0e89e29dace..eb6d251add0 100644
--- 
a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestLocalDirAllocator.java
+++ 
b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestLocalDirAllocator.java
@@ -26,16 +26,14 @@
 import java.util.NoSuchElementException;
 
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.test.LambdaTestUtils;
 import org.apache.hadoop.util.DiskChecker.DiskErrorException;
 import org.apache.hadoop.util.Shell;
 
-import org.assertj.core.api.Assertions;
 import org.junit.jupiter.api.Timeout;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.MethodSource;
 
-import static org.apache.hadoop.fs.LocalDirAllocator.E_NO_SPACE_AVAILABLE;
-import static org.apache.hadoop.test.LambdaTestUtils.intercept;
 import static org.apache.hadoop.test.PlatformAssumptions.assumeNotWindows;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -566,8 +564,13 @@ public void testGetLocalPathForWriteForInvalidPaths(String 
paramRoot, String par
       throws Exception {
     initTestLocalDirAllocator(paramRoot, paramPrefix);
     conf.set(CONTEXT, " ");
-    intercept(IOException.class, E_NO_SPACE_AVAILABLE, () ->
-        dirAllocator.getLocalPathForWrite("/test", conf));
+    try {
+      dirAllocator.getLocalPathForWrite("/test", conf);
+      fail("not throwing the exception");
+    } catch (IOException e) {
+      assertEquals("No space available in any of the local directories.",
+          e.getMessage(), "Incorrect exception message");
+    }
   }
 
   /**
@@ -584,13 +587,10 @@ public void testGetLocalPathForWriteForLessSpace(String 
paramRoot, String paramP
     String dir0 = buildBufferDir(root, 0);
     String dir1 = buildBufferDir(root, 1);
     conf.set(CONTEXT, dir0 + "," + dir1);
-    final DiskErrorException ex = intercept(DiskErrorException.class,
+    LambdaTestUtils.intercept(DiskErrorException.class,
         String.format("Could not find any valid local directory for %s with 
requested size %s",
             "p1/x", Long.MAX_VALUE - 1), "Expect a DiskErrorException.",
         () -> dirAllocator.getLocalPathForWrite("p1/x", Long.MAX_VALUE - 1, 
conf));
-    Assertions.assertThat(ex.getMessage())
-        .contains(new File(dir0).getName())
-        .contains(new File(dir1).getName());
   }
 
   /**
@@ -614,31 +614,5 @@ public void testDirectoryRecovery(String paramRoot, String 
paramPrefix) throws T
     // and expect to get a new file back
     dirAllocator.getLocalPathForWrite("file2", -1, conf);
   }
-
-
-  /**
-   * Test for HADOOP-19554. LocalDirAllocator still doesn't always recover
-   * from directory tree deletion.
-   */
-  @Timeout(value = 30)
-  @MethodSource("params")
-  @ParameterizedTest
-  public void testDirectoryRecoveryKnownSize(String paramRoot, String 
paramPrefix) throws Throwable {
-    initTestLocalDirAllocator(paramRoot, paramPrefix);
-    String dir0 = buildBufferDir(root, 0);
-    String subdir = dir0 + "/subdir1/subdir2";
-
-    conf.set(CONTEXT, subdir);
-    // get local path and an ancestor
-    final Path pathForWrite = dirAllocator.getLocalPathForWrite("file", 512, 
conf);
-    final Path ancestor = pathForWrite.getParent().getParent();
-
-    // delete that ancestor
-    localFs.delete(ancestor, true);
-    // and expect to get a new file back
-    dirAllocator.getLocalPathForWrite("file2", -1, conf);
-  }
-
-
 }
 


---------------------------------------------------------------------
To unsubscribe, e-mail: common-commits-unsubscr...@hadoop.apache.org
For additional commands, e-mail: common-commits-h...@hadoop.apache.org

Reply via email to