Jelajahi Sumber

HDFS-9019. Adding informative message to sticky bit permission denied exception. Contributed by Xiaoyu Yao.

(cherry picked from commit 970daaa5e44d3c09afd46d1c8e923a5096708c44)
(cherry picked from commit b2465690a15ee4257b381a8d186ffa6981ddc537)
Xiaoyu Yao 10 tahun lalu
induk
melakukan
d7da70332f

+ 3 - 0
hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt

@@ -93,6 +93,9 @@ Release 2.7.3 - UNRELEASED
     HDFS-5802. NameNode does not check for inode type before traversing down a
     path. (Xiao Chen via Yongjun Zhang)
 
+    HDFS-9019. Adding informative message to sticky bit permission denied
+    exception. (xyao)
+
   OPTIMIZATIONS
 
     HDFS-8845. DiskChecker should not traverse the entire tree (Chang Li via

+ 11 - 5
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSPermissionChecker.java

@@ -227,7 +227,7 @@ class FSPermissionChecker implements AccessControlEnforcer {
     final INodeAttributes last = inodeAttrs[inodeAttrs.length - 1];
     if (parentAccess != null && parentAccess.implies(FsAction.WRITE)
         && inodeAttrs.length > 1 && last != null) {
-      checkStickyBit(inodeAttrs[inodeAttrs.length - 2], last);
+      checkStickyBit(inodeAttrs[inodeAttrs.length - 2], last, path);
     }
     if (ancestorAccess != null && inodeAttrs.length > 1) {
       check(inodeAttrs, path, ancestorIndex, ancestorAccess);
@@ -430,8 +430,8 @@ class FSPermissionChecker implements AccessControlEnforcer {
   }
 
   /** Guarded by {@link FSNamesystem#readLock()} */
-  private void checkStickyBit(INodeAttributes parent, INodeAttributes inode
-      ) throws AccessControlException {
+  private void checkStickyBit(INodeAttributes parent, INodeAttributes inode,
+      String path) throws AccessControlException {
     if (!parent.getFsPermission().getStickyBit()) {
       return;
     }
@@ -446,8 +446,14 @@ class FSPermissionChecker implements AccessControlEnforcer {
       return;
     }
 
-    throw new AccessControlException("Permission denied by sticky bit setting:" +
-      " user=" + getUser() + ", inode=" + inode);
+    throw new AccessControlException(String.format(
+        "Permission denied by sticky bit: user=%s, path=\"%s\":%s:%s:%s%s, " +
+        "parent=\"%s\":%s:%s:%s%s", user,
+        path, inode.getUserName(), inode.getGroupName(),
+        inode.isDirectory() ? "d" : "-", inode.getFsPermission().toString(),
+        path.substring(0, path.length() - inode.toString().length() - 1 ),
+        parent.getUserName(), parent.getGroupName(),
+        parent.isDirectory() ? "d" : "-", parent.getFsPermission().toString()));
   }
 
   /**

+ 3 - 0
hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/fs/permission/TestStickyBit.java

@@ -140,6 +140,9 @@ public class TestStickyBit {
     } catch (IOException ioe) {
       assertTrue(ioe instanceof AccessControlException);
       assertTrue(ioe.getMessage().contains("sticky bit"));
+      assertTrue(ioe.getMessage().contains("user="+user2.getUserName()));
+      assertTrue(ioe.getMessage().contains("path=\"" + file + "\""));
+      assertTrue(ioe.getMessage().contains("parent=\"" + file.getParent() + "\""));
     }
   }