소스 검색

Merge -r 558133:558134 from trunk to 0.14 branch. Fixes: HADOOP-1623.

git-svn-id: https://svn.apache.org/repos/asf/lucene/hadoop/branches/branch-0.14@558135 13f79535-47bb-0310-9956-ffa450edef68
Doug Cutting 18 년 전
부모
커밋
864a0d70e3
3개의 변경된 파일69개의 추가작업 그리고 0개의 파일을 삭제
  1. 3 0
      CHANGES.txt
  2. 24 0
      src/java/org/apache/hadoop/fs/FileUtil.java
  3. 42 0
      src/test/org/apache/hadoop/dfs/TestDFSShell.java

+ 3 - 0
CHANGES.txt

@@ -385,6 +385,9 @@ Branch 0.14 (unreleased changes)
      time instead of checksum to detect file changes, as checksums are
      time instead of checksum to detect file changes, as checksums are
      no longer easily accessed.  (Arun C Murthy via cutting)
      no longer easily accessed.  (Arun C Murthy via cutting)
 
 
+130. HADOOP-1623.  Fix an infinite loop when copying directories.
+     (Dhruba Borthakur via cutting)
+
 
 
 Release 0.13.0 - 2007-06-08
 Release 0.13.0 - 2007-06-08
 
 

+ 24 - 0
src/java/org/apache/hadoop/fs/FileUtil.java

@@ -86,6 +86,29 @@ public class FileUtil {
     fs.delete(dir);
     fs.delete(dir);
   }
   }
 
 
+  //
+  // If the destination is a subdirectory of the source, then
+  // generate exception
+  //
+  private static void checkDependencies(FileSystem srcFS, 
+                                        Path src, 
+                                        FileSystem dstFS, 
+                                        Path dst)
+                                        throws IOException {
+    if (srcFS == dstFS) {
+      String srcq = src.makeQualified(srcFS).toString() + Path.SEPARATOR;
+      String dstq = dst.makeQualified(dstFS).toString() + Path.SEPARATOR;
+      if (dstq.startsWith(srcq)) {
+        if (srcq.length() == dstq.length()) {
+          throw new IOException("Cannot copy " + src + " to itself.");
+        } else {
+          throw new IOException("Cannot copy " + src + " to its subdirectory " +
+                                dst);
+        }
+      }
+    }
+  }
+
   /** Copy files between FileSystems. */
   /** Copy files between FileSystems. */
   public static boolean copy(FileSystem srcFS, Path src, 
   public static boolean copy(FileSystem srcFS, Path src, 
                              FileSystem dstFS, Path dst, 
                              FileSystem dstFS, Path dst, 
@@ -94,6 +117,7 @@ public class FileUtil {
     dst = checkDest(src.getName(), dstFS, dst);
     dst = checkDest(src.getName(), dstFS, dst);
 
 
     if (srcFS.isDirectory(src)) {
     if (srcFS.isDirectory(src)) {
+      checkDependencies(srcFS, src, dstFS, dst);
       if (!dstFS.mkdirs(dst)) {
       if (!dstFS.mkdirs(dst)) {
         return false;
         return false;
       }
       }

+ 42 - 0
src/test/org/apache/hadoop/dfs/TestDFSShell.java

@@ -293,6 +293,48 @@ public class TestDFSShell extends TestCase {
         }
         }
         assertTrue(val == 0);
         assertTrue(val == 0);
       }
       }
+
+      // Verify that cp from a directory to a subdirectory fails
+      {
+        String[] args = new String[2];
+        args[0] = "-mkdir";
+        args[1] = "/test/dir1";
+        int val = -1;
+        try {
+          val = shell.run(args);
+        } catch (Exception e) {
+          System.err.println("Exception raised from DFSShell.run " +
+                             e.getLocalizedMessage());
+        }
+        assertTrue(val == 0);
+
+        // this should fail
+        String[] args1 = new String[3];
+        args1[0] = "-cp";
+        args1[1] = "/test/dir1";
+        args1[2] = "/test/dir1/dir2";
+        val = 0;
+        try {
+          val = shell.run(args1);
+        } catch (Exception e) {
+          System.err.println("Exception raised from DFSShell.run " +
+                             e.getLocalizedMessage());
+        }
+        assertTrue(val == -1);
+
+        // this should succeed
+        args1[0] = "-cp";
+        args1[1] = "/test/dir1";
+        args1[2] = "/test/dir1foo";
+        val = -1;
+        try {
+          val = shell.run(args1);
+        } catch (Exception e) {
+          System.err.println("Exception raised from DFSShell.run " +
+                             e.getLocalizedMessage());
+        }
+        assertTrue(val == 0);
+      }
         
         
     } finally {
     } finally {
       try {
       try {