瀏覽代碼

HADOOP-12718. Incorrect error message by fs -put local dir without permission. (John Zhuge via Yongjun Zhang)

Yongjun Zhang 8 年之前
父節點
當前提交
470bdaa27a

+ 2 - 0
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FSExceptionMessages.java

@@ -46,4 +46,6 @@ public class FSExceptionMessages {
 
   public static final String TOO_MANY_BYTES_FOR_DEST_BUFFER
       = "Requested more bytes than destination buffer size";
+
+  public static final String PERMISSION_DENIED = "Permission denied";
 }

+ 7 - 1
hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/FileUtil.java

@@ -29,6 +29,7 @@ import java.io.OutputStream;
 import java.net.InetAddress;
 import java.net.URI;
 import java.net.UnknownHostException;
+import java.nio.file.AccessDeniedException;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.List;
@@ -1139,9 +1140,14 @@ public class FileUtil {
    * an IOException to be thrown.
    * @param dir directory for which listing should be performed
    * @return list of file names or empty string list
-   * @exception IOException for invalid directory or for a bad disk.
+   * @exception AccessDeniedException for unreadable directory
+   * @exception IOException for invalid directory or for bad disk
    */
   public static String[] list(File dir) throws IOException {
+    if (!canRead(dir)) {
+      throw new AccessDeniedException(dir.toString(), null,
+          FSExceptionMessages.PERMISSION_DENIED);
+    }
     String[] fileNames = dir.list();
     if(fileNames == null) {
       throw new IOException("Invalid directory or I/O error occurred for dir: "

+ 51 - 0
hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestFsShellCopy.java

@@ -26,12 +26,15 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
+import java.io.PrintStream;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.permission.FsPermission;
 import org.apache.hadoop.test.GenericTestUtils;
 import org.apache.hadoop.util.StringUtils;
 import org.junit.Before;
@@ -607,4 +610,52 @@ public class TestFsShellCopy {
         shellRun("-copyFromLocal", srcPath.toString(), noDirName + "/"),
         is(not(0)));
   }
+
+  @Test
+  public void testPutSrcDirNoPerm()
+      throws Exception {
+    final Path src = new Path(testRootDir, "srcNoPerm");
+    final Path dst = new Path(testRootDir, "dst");
+    lfs.delete(src, true);
+    lfs.mkdirs(src, new FsPermission((short)0));
+    lfs.delete(dst, true);
+
+    try {
+      final ByteArrayOutputStream err = new ByteArrayOutputStream();
+      PrintStream oldErr = System.err;
+      System.setErr(new PrintStream(err));
+      shellRun(1, "-put", src.toString(), dst.toString());
+      System.setErr(oldErr);
+      System.err.print(err.toString());
+      assertTrue(err.toString().contains(
+          FSExceptionMessages.PERMISSION_DENIED));
+    } finally {
+      // Make sure the test directory can be deleted
+      lfs.setPermission(src, new FsPermission((short)0755));
+    }
+  }
+
+  @Test
+  public void testPutSrcFileNoPerm()
+      throws Exception {
+    final Path src = new Path(testRootDir, "srcNoPerm");
+    final Path dst = new Path(testRootDir, "dst");
+    lfs.delete(src, true);
+    lfs.create(src);
+    lfs.setPermission(src, new FsPermission((short)0));
+    lfs.delete(dst, true);
+
+    try {
+      final ByteArrayOutputStream err = new ByteArrayOutputStream();
+      PrintStream oldErr = System.err;
+      System.setErr(new PrintStream(err));
+      shellRun(1, "-put", src.toString(), dst.toString());
+      System.setErr(oldErr);
+      System.err.print(err.toString());
+      assertTrue(err.toString().contains("(Permission denied)"));
+    } finally {
+      // make sure the test file can be deleted
+      lfs.setPermission(src, new FsPermission((short)0755));
+    }
+  }
 }