From 846cf620db447d4efffc63bcd80a77e8372ddb05 Mon Sep 17 00:00:00 2001 From: Simon Willnauer Date: Fri, 21 Aug 2015 21:44:54 +0200 Subject: [PATCH] Don't check if directory is present to prevent races We do check if a directory is present and then open a dir stream on it. Yet the file can be concurrrently deleted which is OK but we fail with a hard exception. This change tries to open the dir directly (listing via stream) and catches NoSuchFileEx | FNFEx. --- .../elasticsearch/gateway/MetaDataStateFormat.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/org/elasticsearch/gateway/MetaDataStateFormat.java b/core/src/main/java/org/elasticsearch/gateway/MetaDataStateFormat.java index 523e9bc5414..23546f123ec 100644 --- a/core/src/main/java/org/elasticsearch/gateway/MetaDataStateFormat.java +++ b/core/src/main/java/org/elasticsearch/gateway/MetaDataStateFormat.java @@ -43,12 +43,10 @@ import org.elasticsearch.common.xcontent.XContentHelper; import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentType; +import java.io.FileNotFoundException; import java.io.IOException; import java.io.OutputStream; -import java.nio.file.DirectoryStream; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; +import java.nio.file.*; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; @@ -253,10 +251,9 @@ public abstract class MetaDataStateFormat { if (dataLocations != null) { // select all eligable files first for (Path dataLocation : dataLocations) { final Path stateDir = dataLocation.resolve(STATE_DIR_NAME); - if (!Files.isDirectory(stateDir)) { - continue; - } // now, iterate over the current versions, and find latest one + // we don't check if the stateDir is present since it could be deleted + // after the check. Also if there is a _state file and it's not a dir something is really wrong try (DirectoryStream paths = Files.newDirectoryStream(stateDir)) { // we don't pass a glob since we need the group part for parsing for (Path stateFile : paths) { final Matcher matcher = stateFilePattern.matcher(stateFile.getFileName().toString()); @@ -270,6 +267,8 @@ public abstract class MetaDataStateFormat { files.add(pav); } } + } catch (NoSuchFileException | FileNotFoundException ex) { + // no _state directory -- move on } } }