Skip to content

Commit 681fb35

Browse files
virajjasanipetersomogyi
authored andcommitted
HBASE-28081 Snapshot working dir does not retain ACLs after snapshot commit phase (apache#5437)
Signed-off-by: Duo Zhang <zhangduo@apache.org> Signed-off-by: Andrew Purtell <apurtell@apache.org> Signed-off-by: Aman Poonia <aman.poonia.29@gmail.com> (cherry picked from commit 0d4c756) Change-Id: I8003de7b96ad7db6778a2187ad21557661030c9c
1 parent 9f85def commit 681fb35

3 files changed

Lines changed: 55 additions & 12 deletions

File tree

hbase-server/src/main/java/org/apache/hadoop/hbase/master/snapshot/SnapshotManager.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,13 @@
3636
import java.util.concurrent.locks.ReadWriteLock;
3737
import java.util.concurrent.locks.ReentrantReadWriteLock;
3838
import org.apache.hadoop.conf.Configuration;
39+
import org.apache.hadoop.fs.CommonPathCapabilities;
3940
import org.apache.hadoop.fs.FSDataInputStream;
4041
import org.apache.hadoop.fs.FileStatus;
4142
import org.apache.hadoop.fs.FileSystem;
4243
import org.apache.hadoop.fs.Path;
44+
import org.apache.hadoop.fs.permission.AclEntry;
45+
import org.apache.hadoop.fs.permission.AclStatus;
4346
import org.apache.hadoop.hbase.HBaseInterfaceAudience;
4447
import org.apache.hadoop.hbase.HConstants;
4548
import org.apache.hadoop.hbase.Stoppable;
@@ -486,6 +489,7 @@ private synchronized void prepareToTakeSnapshot(SnapshotDescription snapshot)
486489
"Couldn't create working directory (" + workingDir + ") for snapshot",
487490
ProtobufUtil.createSnapshotDesc(snapshot));
488491
}
492+
updateWorkingDirAclsIfRequired(workingDir, workingDirFS);
489493
} catch (HBaseSnapshotException e) {
490494
throw e;
491495
} catch (IOException e) {
@@ -495,6 +499,42 @@ private synchronized void prepareToTakeSnapshot(SnapshotDescription snapshot)
495499
}
496500
}
497501

502+
/**
503+
* If the parent dir of the snapshot working dir (e.g. /hbase/.hbase-snapshot) has non-empty ACLs,
504+
* use them for the current working dir (e.g. /hbase/.hbase-snapshot/.tmp/{snapshot-name}) so that
505+
* regardless of whether the snapshot commit phase performs atomic rename or non-atomic copy of
506+
* the working dir to new snapshot dir, the ACLs are retained.
507+
* @param workingDir working dir to build the snapshot.
508+
* @param workingDirFS working dir file system.
509+
* @throws IOException If ACL read/modify operation fails.
510+
*/
511+
private static void updateWorkingDirAclsIfRequired(Path workingDir, FileSystem workingDirFS)
512+
throws IOException {
513+
if (
514+
!workingDirFS.hasPathCapability(workingDir, CommonPathCapabilities.FS_ACLS)
515+
|| workingDir.getParent() == null || workingDir.getParent().getParent() == null
516+
) {
517+
return;
518+
}
519+
AclStatus snapshotWorkingParentDirStatus;
520+
try {
521+
snapshotWorkingParentDirStatus =
522+
workingDirFS.getAclStatus(workingDir.getParent().getParent());
523+
} catch (IOException e) {
524+
LOG.warn("Unable to retrieve ACL status for path: {}, current working dir path: {}",
525+
workingDir.getParent().getParent(), workingDir, e);
526+
return;
527+
}
528+
List<AclEntry> snapshotWorkingParentDirAclStatusEntries =
529+
snapshotWorkingParentDirStatus.getEntries();
530+
if (
531+
snapshotWorkingParentDirAclStatusEntries != null
532+
&& snapshotWorkingParentDirAclStatusEntries.size() > 0
533+
) {
534+
workingDirFS.modifyAclEntries(workingDir, snapshotWorkingParentDirAclStatusEntries);
535+
}
536+
}
537+
498538
/**
499539
* Take a snapshot of a disabled table.
500540
* @param snapshot description of the snapshot to take. Modified to be {@link Type#DISABLED}.

hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/SnapshotScannerHDFSAclHelper.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,12 @@ public boolean grantAcl(UserPermission userPermission, Set<String> skipNamespace
155155
long start = System.currentTimeMillis();
156156
handleGrantOrRevokeAcl(userPermission, HDFSAclOperation.OperationType.MODIFY, skipNamespaces,
157157
skipTables);
158-
LOG.info("Set HDFS acl when grant {}, cost {} ms", userPermission,
159-
System.currentTimeMillis() - start);
158+
LOG.info("Set HDFS acl when grant {}, skipNamespaces: {}, skipTables: {}, cost {} ms",
159+
userPermission, skipNamespaces, skipTables, System.currentTimeMillis() - start);
160160
return true;
161161
} catch (Exception e) {
162-
LOG.error("Set HDFS acl error when grant: {}", userPermission, e);
162+
LOG.error("Set HDFS acl error when grant: {}, skipNamespaces: {}, skipTables: {}",
163+
userPermission, skipNamespaces, skipTables, e);
163164
return false;
164165
}
165166
}
@@ -177,11 +178,12 @@ public boolean revokeAcl(UserPermission userPermission, Set<String> skipNamespac
177178
long start = System.currentTimeMillis();
178179
handleGrantOrRevokeAcl(userPermission, HDFSAclOperation.OperationType.REMOVE, skipNamespaces,
179180
skipTables);
180-
LOG.info("Set HDFS acl when revoke {}, cost {} ms", userPermission,
181-
System.currentTimeMillis() - start);
181+
LOG.info("Set HDFS acl when revoke {}, skipNamespaces: {}, skipTables: {}, cost {} ms",
182+
userPermission, skipNamespaces, skipTables, System.currentTimeMillis() - start);
182183
return true;
183184
} catch (Exception e) {
184-
LOG.error("Set HDFS acl error when revoke: {}", userPermission, e);
185+
LOG.error("Set HDFS acl error when revoke: {}, skipNamespaces: {}, skipTables: {}",
186+
userPermission, skipNamespaces, skipTables, e);
185187
return false;
186188
}
187189
}

hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestSnapshotScannerHDFSAclController.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,6 @@ public void testGrantGlobal1() throws Exception {
158158

159159
TestHDFSAclHelper.createTableAndPut(TEST_UTIL, table);
160160
snapshotAndWait(snapshot1, table);
161-
snapshotAndWait(snapshot2, table);
162161
// grant G(R)
163162
SecureTestUtil.grantGlobal(TEST_UTIL, grantUserName, READ);
164163
TestHDFSAclHelper.canUserScanSnapshot(TEST_UTIL, grantUser, snapshot1, 6);
@@ -175,6 +174,8 @@ public void testGrantGlobal1() throws Exception {
175174
// grant G(R)
176175
SecureTestUtil.grantGlobal(TEST_UTIL, grantUserName, READ);
177176
TestHDFSAclHelper.canUserScanSnapshot(TEST_UTIL, grantUser, snapshot1, 6);
177+
// take a snapshot and ACLs are inherited automatically
178+
snapshotAndWait(snapshot2, table);
178179
TestHDFSAclHelper.canUserScanSnapshot(TEST_UTIL, grantUser, snapshot2, 6);
179180
assertTrue(hasUserGlobalHdfsAcl(aclTable, grantUserName));
180181
deleteTable(table);
@@ -196,10 +197,10 @@ public void testGrantGlobal2() throws Exception {
196197
// create table in namespace1 and snapshot
197198
TestHDFSAclHelper.createTableAndPut(TEST_UTIL, table1);
198199
snapshotAndWait(snapshot1, table1);
199-
// grant G(W)
200-
SecureTestUtil.grantGlobal(TEST_UTIL, grantUserName, WRITE);
201200
admin.grant(new UserPermission(grantUserName,
202201
Permission.newBuilder(namespace1).withActions(READ).build()), false);
202+
// grant G(W)
203+
SecureTestUtil.grantGlobal(TEST_UTIL, grantUserName, WRITE);
203204
// create table in namespace2 and snapshot
204205
TestHDFSAclHelper.createTableAndPut(TEST_UTIL, table2);
205206
snapshotAndWait(snapshot2, table2);
@@ -230,11 +231,11 @@ public void testGrantGlobal3() throws Exception {
230231
// grant table1(R)
231232
TestHDFSAclHelper.createTableAndPut(TEST_UTIL, table1);
232233
snapshotAndWait(snapshot1, table1);
233-
TestHDFSAclHelper.createTableAndPut(TEST_UTIL, table2);
234-
snapshotAndWait(snapshot2, table2);
234+
TestHDFSAclHelper.grantOnTable(TEST_UTIL, grantUserName, table1, READ);
235235
// grant G(W)
236236
SecureTestUtil.grantGlobal(TEST_UTIL, grantUserName, WRITE);
237-
TestHDFSAclHelper.grantOnTable(TEST_UTIL, grantUserName, table1, READ);
237+
TestHDFSAclHelper.createTableAndPut(TEST_UTIL, table2);
238+
snapshotAndWait(snapshot2, table2);
238239
// check scan snapshot
239240
TestHDFSAclHelper.canUserScanSnapshot(TEST_UTIL, grantUser, snapshot1, 6);
240241
TestHDFSAclHelper.canUserScanSnapshot(TEST_UTIL, grantUser, snapshot2, -1);

0 commit comments

Comments
 (0)