diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/ZKRMStateStore.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/ZKRMStateStore.java index f3da21e..744d2ce 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/ZKRMStateStore.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/ZKRMStateStore.java @@ -30,6 +30,7 @@ import java.util.Collections; import java.util.List; +import com.google.common.base.Preconditions; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.classification.InterfaceAudience.Private; @@ -275,7 +276,7 @@ public synchronized void startInternal() throws Exception { createConnection(); // ensure root dirs exist - createRootDir(znodeWorkingPath); + createRootDirRecursively(znodeWorkingPath); createRootDir(zkRootNodePath); if (HAUtil.isHAEnabled(getConfig())){ fence(); @@ -1143,4 +1144,19 @@ public synchronized void storeOrUpdateAMRMTokenSecretManagerState( setDataWithRetries(amrmTokenSecretManagerRoot, stateData, -1); } + /** + * Utility function to ensure that the configured base znode exists. + * This recursively creates the znode as well as all of its parents. + */ + @VisibleForTesting + public void createRootDirRecursively(String path) throws Exception { + String pathParts[] = path.split("/"); + Preconditions.checkArgument(pathParts.length >= 1 && pathParts[0].isEmpty(), + "Invalid path: %s", path); + StringBuilder sb = new StringBuilder(); + for (int i = 1; i < pathParts.length; i++) { + sb.append("/").append(pathParts[i]); + createRootDir(sb.toString()); + } + } } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/TestZKRMStateStore.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/TestZKRMStateStore.java index 87df3d6..76595c6 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/TestZKRMStateStore.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/test/java/org/apache/hadoop/yarn/server/resourcemanager/recovery/TestZKRMStateStore.java @@ -139,6 +139,7 @@ public boolean appExists(RMApp app) throws Exception { @Test (timeout = 60000) public void testZKRMStateStoreRealZK() throws Exception { TestZKRMStateStoreTester zkTester = new TestZKRMStateStoreTester(); + testCreatePathRecursively(zkTester); testRMAppStateStore(zkTester); testRMDTSecretManagerStateStore(zkTester); testCheckVersion(zkTester); @@ -370,4 +371,11 @@ public void testFencedState() throws Exception { store.close(); } + + public void testCreatePathRecursively(TestZKRMStateStoreTester zkTester) + throws Exception { + ZKRMStateStore rmStateStore = (ZKRMStateStore) zkTester.getRMStateStore(); + rmStateStore.createRootDirRecursively("/foo/bar"); + rmStateStore.getDataWithRetries("/foo/bar", false); + } }