HBASE-12402 ZKPermissionWatcher race condition in refreshing the cache leaving stale ACLs and causing AccessDenied
This commit is contained in:
parent
f7adec0548
commit
71f73fcd0b
|
@ -31,6 +31,7 @@ import org.apache.zookeeper.KeeperException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles synchronization of access control list entries and updates
|
* Handles synchronization of access control list entries and updates
|
||||||
|
@ -48,6 +49,7 @@ public class ZKPermissionWatcher extends ZooKeeperListener {
|
||||||
static final String ACL_NODE = "acl";
|
static final String ACL_NODE = "acl";
|
||||||
TableAuthManager authManager;
|
TableAuthManager authManager;
|
||||||
String aclZNode;
|
String aclZNode;
|
||||||
|
CountDownLatch initialized = new CountDownLatch(1);
|
||||||
|
|
||||||
public ZKPermissionWatcher(ZooKeeperWatcher watcher,
|
public ZKPermissionWatcher(ZooKeeperWatcher watcher,
|
||||||
TableAuthManager authManager, Configuration conf) {
|
TableAuthManager authManager, Configuration conf) {
|
||||||
|
@ -58,18 +60,32 @@ public class ZKPermissionWatcher extends ZooKeeperListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() throws KeeperException {
|
public void start() throws KeeperException {
|
||||||
watcher.registerListener(this);
|
try {
|
||||||
if (ZKUtil.watchAndCheckExists(watcher, aclZNode)) {
|
watcher.registerListener(this);
|
||||||
List<ZKUtil.NodeAndData> existing =
|
if (ZKUtil.watchAndCheckExists(watcher, aclZNode)) {
|
||||||
ZKUtil.getChildDataAndWatchForNewChildren(watcher, aclZNode);
|
List<ZKUtil.NodeAndData> existing =
|
||||||
if (existing != null) {
|
ZKUtil.getChildDataAndWatchForNewChildren(watcher, aclZNode);
|
||||||
refreshNodes(existing);
|
if (existing != null) {
|
||||||
|
refreshNodes(existing);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
initialized.countDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void waitUntilStarted() {
|
||||||
|
try {
|
||||||
|
initialized.await();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
LOG.warn("Interrupted while waiting", e);
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void nodeCreated(String path) {
|
public void nodeCreated(String path) {
|
||||||
|
waitUntilStarted();
|
||||||
if (path.equals(aclZNode)) {
|
if (path.equals(aclZNode)) {
|
||||||
try {
|
try {
|
||||||
List<ZKUtil.NodeAndData> nodes =
|
List<ZKUtil.NodeAndData> nodes =
|
||||||
|
@ -85,6 +101,7 @@ public class ZKPermissionWatcher extends ZooKeeperListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void nodeDeleted(String path) {
|
public void nodeDeleted(String path) {
|
||||||
|
waitUntilStarted();
|
||||||
if (aclZNode.equals(ZKUtil.getParent(path))) {
|
if (aclZNode.equals(ZKUtil.getParent(path))) {
|
||||||
String table = ZKUtil.getNodeName(path);
|
String table = ZKUtil.getNodeName(path);
|
||||||
if(AccessControlLists.isNamespaceEntry(table)) {
|
if(AccessControlLists.isNamespaceEntry(table)) {
|
||||||
|
@ -97,6 +114,7 @@ public class ZKPermissionWatcher extends ZooKeeperListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void nodeDataChanged(String path) {
|
public void nodeDataChanged(String path) {
|
||||||
|
waitUntilStarted();
|
||||||
if (aclZNode.equals(ZKUtil.getParent(path))) {
|
if (aclZNode.equals(ZKUtil.getParent(path))) {
|
||||||
// update cache on an existing table node
|
// update cache on an existing table node
|
||||||
String entry = ZKUtil.getNodeName(path);
|
String entry = ZKUtil.getNodeName(path);
|
||||||
|
@ -115,6 +133,7 @@ public class ZKPermissionWatcher extends ZooKeeperListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void nodeChildrenChanged(String path) {
|
public void nodeChildrenChanged(String path) {
|
||||||
|
waitUntilStarted();
|
||||||
if (path.equals(aclZNode)) {
|
if (path.equals(aclZNode)) {
|
||||||
// table permissions changed
|
// table permissions changed
|
||||||
try {
|
try {
|
||||||
|
|
Loading…
Reference in New Issue