[
https://issues.apache.org/jira/browse/HDFS-10948?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Karthik Palaniappan updated HDFS-10948:
---------------------------------------
Description:
The HDFS setOwner RPC takes a path, optional username, and optional groupname
(see ClientNamenodeProtocol.proto). If neither username nor groupname are set,
the RPC is a no-op. However, an entry in the edit log is still committed, and
when retrieved through getEditsFromTxid, both username and groupname are set to
the empty string.
This does not match the behavior of the setTimes RPC. There atime and mtime are
both required, and you can set "-1" to indicated "don't change the time". If
both are set to "-1", the RPC is a no-op, and appropriately no edit log
transaction is created.
Here's an example of an (untested) patch to fix the issue:
{code}
diff --git
a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirAttrOp.java
b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirAttrOp.java
index 3dc1c30..0728bc5 100644
---
a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirAttrOp.java
+++
b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirAttrOp.java
@@ -77,6 +77,7 @@ static HdfsFileStatus setOwner(
if (FSDirectory.isExactReservedName(src)) {
throw new InvalidPathException(src);
}
+ boolean changed = false;
FSPermissionChecker pc = fsd.getPermissionChecker();
INodesInPath iip;
fsd.writeLock();
@@ -92,11 +93,13 @@ static HdfsFileStatus setOwner(
throw new AccessControlException("User does not belong to " + group);
}
}
- unprotectedSetOwner(fsd, src, username, group);
+ changed = unprotectedSetOwner(fsd, src, username, group);
} finally {
fsd.writeUnlock();
}
- fsd.getEditLog().logSetOwner(src, username, group);
+ if (changed) {
+ fsd.getEditLog().logSetOwner(src, username, group);
+ }
return fsd.getAuditFileInfo(iip);
}
@@ -287,22 +290,27 @@ static void unprotectedSetPermission(
inode.setPermission(permissions, snapshotId);
}
- static void unprotectedSetOwner(
+ static boolean unprotectedSetOwner(
FSDirectory fsd, String src, String username, String groupname)
throws FileNotFoundException, UnresolvedLinkException,
QuotaExceededException, SnapshotAccessControlException {
assert fsd.hasWriteLock();
+ boolean status = false;
final INodesInPath inodesInPath = fsd.getINodesInPath4Write(src, true);
INode inode = inodesInPath.getLastINode();
if (inode == null) {
throw new FileNotFoundException("File does not exist: " + src);
}
if (username != null) {
+ status = true;
inode = inode.setUser(username, inodesInPath.getLatestSnapshotId());
}
if (groupname != null) {
+ status = true;
inode.setGroup(groupname, inodesInPath.getLatestSnapshotId());
}
+
+ return status;
}
static boolean setTimes(
{code}
was:
The HDFS setOwner RPC takes a path, optional username, and optional groupname
(see ClientNamenodeProtocol.proto). If neither username nor groupname are set,
the RPC is a no-op. However, an entry in the edit log is still committed, and
when retrieved through getEditsFromTxid, both username and groupname are set to
the empty string.
This does not match the behavior of the setTimes RPC. There atime and mtime are
both required, and you can set "-1" to indicated "don't change the time". If
both are set to "-1", the RPC is a no-op, and appropriately no edit log
transaction is created.
Here's an example of an (untested) patch to fix the issue:
```
diff --git
a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirAttrOp.java
b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirAttrOp.java
index 3dc1c30..0728bc5 100644
---
a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirAttrOp.java
+++
b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirAttrOp.java
@@ -77,6 +77,7 @@ static HdfsFileStatus setOwner(
if (FSDirectory.isExactReservedName(src)) {
throw new InvalidPathException(src);
}
+ boolean changed = false;
FSPermissionChecker pc = fsd.getPermissionChecker();
INodesInPath iip;
fsd.writeLock();
@@ -92,11 +93,13 @@ static HdfsFileStatus setOwner(
throw new AccessControlException("User does not belong to " + group);
}
}
- unprotectedSetOwner(fsd, src, username, group);
+ changed = unprotectedSetOwner(fsd, src, username, group);
} finally {
fsd.writeUnlock();
}
- fsd.getEditLog().logSetOwner(src, username, group);
+ if (changed) {
+ fsd.getEditLog().logSetOwner(src, username, group);
+ }
return fsd.getAuditFileInfo(iip);
}
@@ -287,22 +290,27 @@ static void unprotectedSetPermission(
inode.setPermission(permissions, snapshotId);
}
- static void unprotectedSetOwner(
+ static boolean unprotectedSetOwner(
FSDirectory fsd, String src, String username, String groupname)
throws FileNotFoundException, UnresolvedLinkException,
QuotaExceededException, SnapshotAccessControlException {
assert fsd.hasWriteLock();
+ boolean status = false;
final INodesInPath inodesInPath = fsd.getINodesInPath4Write(src, true);
INode inode = inodesInPath.getLastINode();
if (inode == null) {
throw new FileNotFoundException("File does not exist: " + src);
}
if (username != null) {
+ status = true;
inode = inode.setUser(username, inodesInPath.getLatestSnapshotId());
}
if (groupname != null) {
+ status = true;
inode.setGroup(groupname, inodesInPath.getLatestSnapshotId());
}
+
+ return status;
}
static boolean setTimes(
```
> HDFS setOwner no-op should not generate an edit log transaction
> ---------------------------------------------------------------
>
> Key: HDFS-10948
> URL: https://issues.apache.org/jira/browse/HDFS-10948
> Project: Hadoop HDFS
> Issue Type: Bug
> Components: hdfs
> Affects Versions: 2.7.0
> Reporter: Karthik Palaniappan
> Assignee: John Zhuge
> Priority: Minor
> Attachments: testNullUserNullGroup.patch
>
>
> The HDFS setOwner RPC takes a path, optional username, and optional groupname
> (see ClientNamenodeProtocol.proto). If neither username nor groupname are
> set, the RPC is a no-op. However, an entry in the edit log is still
> committed, and when retrieved through getEditsFromTxid, both username and
> groupname are set to the empty string.
> This does not match the behavior of the setTimes RPC. There atime and mtime
> are both required, and you can set "-1" to indicated "don't change the time".
> If both are set to "-1", the RPC is a no-op, and appropriately no edit log
> transaction is created.
> Here's an example of an (untested) patch to fix the issue:
> {code}
> diff --git
> a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirAttrOp.java
>
> b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirAttrOp.java
> index 3dc1c30..0728bc5 100644
> ---
> a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirAttrOp.java
> +++
> b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirAttrOp.java
> @@ -77,6 +77,7 @@ static HdfsFileStatus setOwner(
> if (FSDirectory.isExactReservedName(src)) {
> throw new InvalidPathException(src);
> }
> + boolean changed = false;
> FSPermissionChecker pc = fsd.getPermissionChecker();
> INodesInPath iip;
> fsd.writeLock();
> @@ -92,11 +93,13 @@ static HdfsFileStatus setOwner(
> throw new AccessControlException("User does not belong to " +
> group);
> }
> }
> - unprotectedSetOwner(fsd, src, username, group);
> + changed = unprotectedSetOwner(fsd, src, username, group);
> } finally {
> fsd.writeUnlock();
> }
> - fsd.getEditLog().logSetOwner(src, username, group);
> + if (changed) {
> + fsd.getEditLog().logSetOwner(src, username, group);
> + }
> return fsd.getAuditFileInfo(iip);
> }
>
> @@ -287,22 +290,27 @@ static void unprotectedSetPermission(
> inode.setPermission(permissions, snapshotId);
> }
>
> - static void unprotectedSetOwner(
> + static boolean unprotectedSetOwner(
> FSDirectory fsd, String src, String username, String groupname)
> throws FileNotFoundException, UnresolvedLinkException,
> QuotaExceededException, SnapshotAccessControlException {
> assert fsd.hasWriteLock();
> + boolean status = false;
> final INodesInPath inodesInPath = fsd.getINodesInPath4Write(src, true);
> INode inode = inodesInPath.getLastINode();
> if (inode == null) {
> throw new FileNotFoundException("File does not exist: " + src);
> }
> if (username != null) {
> + status = true;
> inode = inode.setUser(username, inodesInPath.getLatestSnapshotId());
> }
> if (groupname != null) {
> + status = true;
> inode.setGroup(groupname, inodesInPath.getLatestSnapshotId());
> }
> +
> + return status;
> }
>
> static boolean setTimes(
> {code}
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]