Переглянути джерело

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

git-svn-id: https://svn.apache.org/repos/asf/lucene/hadoop/branches/branch-0.13@558141 13f79535-47bb-0310-9956-ffa450edef68
Doug Cutting 18 роки тому
батько
коміт
3afac1a6bb

+ 6 - 0
CHANGES.txt

@@ -1,6 +1,12 @@
 Hadoop Change Log
 Hadoop Change Log
 
 
 
 
+Branch 0.13 (unreleased changes)
+
+ 1. HADOOP-1623.  Fix an infinite loop when copying directories into
+    themselves.  (Dhruba Borthakur via cutting)
+
+
 Release 0.13.0 - 2007-06-08
 Release 0.13.0 - 2007-06-08
 
 
  1. HADOOP-1047.  Fix TestReplication to succeed more reliably.
  1. HADOOP-1047.  Fix TestReplication to succeed more reliably.

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

@@ -85,6 +85,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, 
@@ -93,6 +116,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

@@ -175,6 +175,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 {