diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/localizer/ResourceLocalizationService.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/localizer/ResourceLocalizationService.java index 611fe80..944648e 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/localizer/ResourceLocalizationService.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/localizer/ResourceLocalizationService.java @@ -160,6 +160,7 @@ private LocalDirsHandlerService dirsHandler; private Context nmContext; + private long disksCheckTime = -1L; /** * Map of LocalResourceTrackers keyed by username, for private @@ -787,8 +788,7 @@ public void addResource(LocalizerResourceRequestEvent request) { // In case this is not a newly initialized nm state, ensure // initialized local/log dirs similar to LocalizerRunner - getInitializedLocalDirs(); - getInitializedLogDirs(); + initDirsIfDisksCheckTimeChanged(); // explicitly synchronize pending here to avoid future task // completing and being dequeued before pending updated @@ -1085,8 +1085,7 @@ public void run() { // 1) write credentials to private dir writeCredentials(nmPrivateCTokensPath); // 2) exec initApplication and wait - List localDirs = getInitializedLocalDirs(); - List logDirs = getInitializedLogDirs(); + initDirsIfDisksCheckTimeChanged(); if (dirsHandler.areDisksHealthy()) { exec.startLocalizer(nmPrivateCTokensPath, localizationServerAddress, context.getUser(), @@ -1358,7 +1357,8 @@ private void cleanUpFilesPerUserDir(FileContext lfs, DeletionService del, * * @return list of initialized local dirs */ - synchronized private List getInitializedLocalDirs() { + @VisibleForTesting + synchronized List getInitializedLocalDirs() { List dirs = dirsHandler.getLocalDirs(); List checkFailedDirs = new ArrayList(); for (String dir : dirs) { @@ -1441,4 +1441,15 @@ private boolean checkLocalDir(String localDir) { initializeLogDirs(lfs); return dirs; } + + synchronized private void initDirsIfDisksCheckTimeChanged() { + long lastDisksCheckTime = dirsHandler.getLastDisksCheckTime(); + if (disksCheckTime == lastDisksCheckTime) { + return; + } + disksCheckTime = lastDisksCheckTime; + + getInitializedLocalDirs(); + getInitializedLogDirs(); + } } diff --git hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/localizer/TestResourceLocalizationService.java hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/localizer/TestResourceLocalizationService.java index d3c3521..f7e2f16 100644 --- hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/localizer/TestResourceLocalizationService.java +++ hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/localizer/TestResourceLocalizationService.java @@ -1123,21 +1123,32 @@ public void testPublicResourceInitializesLocalDir() throws Exception { r.setSeed(seed); // Queue up public resource localization - final LocalResource pubResource = getPublicMockedResource(r); - final LocalResourceRequest pubReq = new LocalResourceRequest(pubResource); + final LocalResource pubResource1 = getPublicMockedResource(r); + final LocalResourceRequest pubReq1 = + new LocalResourceRequest(pubResource1); + + LocalResource pubResource2 = null; + do { + pubResource2 = getPublicMockedResource(r); + } while (pubResource2 == null || pubResource2.equals(pubResource1)); + // above call to make sure we don't get identical resources. + final LocalResourceRequest pubReq2 = + new LocalResourceRequest(pubResource2); + + Set pubRsrcs = new HashSet(); + pubRsrcs.add(pubReq1); + pubRsrcs.add(pubReq2); Map> req = new HashMap>(); - req.put(LocalResourceVisibility.PUBLIC, - Collections.singletonList(pubReq)); - - Set pubRsrcs = new HashSet(); - pubRsrcs.add(pubReq); + req.put(LocalResourceVisibility.PUBLIC, pubRsrcs); spyService.handle(new ContainerLocalizationRequestEvent(c, req)); dispatcher.await(); + verify(spyService, times(1)).getInitializedLocalDirs(); + // verify directory creation for (Path p : localDirs) { p = new Path((new URI(p.toString())).getPath());