You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rm...@apache.org on 2017/09/09 06:17:15 UTC
lucene-solr:branch_7x: LUCENE-7959: Improve NativeFSLockFactory's
NoSuchFileException
Repository: lucene-solr
Updated Branches:
refs/heads/branch_7x a1c584d54 -> bcdac5fef
LUCENE-7959: Improve NativeFSLockFactory's NoSuchFileException
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/bcdac5fe
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/bcdac5fe
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/bcdac5fe
Branch: refs/heads/branch_7x
Commit: bcdac5fef3ac0a8de074ca8308206e39d81e439f
Parents: a1c584d
Author: Robert Muir <rm...@apache.org>
Authored: Sat Sep 9 02:00:47 2017 -0400
Committer: Robert Muir <rm...@apache.org>
Committed: Sat Sep 9 02:05:33 2017 -0400
----------------------------------------------------------------------
lucene/CHANGES.txt | 4 ++
.../lucene/store/NativeFSLockFactory.java | 14 ++++++-
.../lucene/store/TestNativeFSLockFactory.java | 42 ++++++++++++++++++++
3 files changed, 59 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/bcdac5fe/lucene/CHANGES.txt
----------------------------------------------------------------------
diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt
index 41c559c..4a8e247 100644
--- a/lucene/CHANGES.txt
+++ b/lucene/CHANGES.txt
@@ -47,6 +47,10 @@ Bug Fixes
* LUCENE-7891: Lucene's taxonomy facets now uses a non-buggy LRU cache
by default. (Jan-Willem van den Broek via Mike McCandless)
+* LUCENE-7959: Improve NativeFSLockFactory's exception message if it cannot create
+ write.lock for an empty index due to bad permissions/read-only filesystem/etc.
+ (Erick Erickson, Shawn Heisey, Robert Muir)
+
Build
* SOLR-11181: Switch order of maven artifact publishing procedure: deploy first
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/bcdac5fe/lucene/core/src/java/org/apache/lucene/store/NativeFSLockFactory.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/java/org/apache/lucene/store/NativeFSLockFactory.java b/lucene/core/src/java/org/apache/lucene/store/NativeFSLockFactory.java
index 4f17d95..106b02e 100644
--- a/lucene/core/src/java/org/apache/lucene/store/NativeFSLockFactory.java
+++ b/lucene/core/src/java/org/apache/lucene/store/NativeFSLockFactory.java
@@ -93,15 +93,27 @@ public final class NativeFSLockFactory extends FSLockFactory {
Path lockFile = lockDir.resolve(lockName);
+ IOException creationException = null;
try {
Files.createFile(lockFile);
} catch (IOException ignore) {
// we must create the file to have a truly canonical path.
// if it's already created, we don't care. if it cant be created, it will fail below.
+ creationException = ignore;
}
// fails if the lock file does not exist
- final Path realPath = lockFile.toRealPath();
+ final Path realPath;
+ try {
+ realPath = lockFile.toRealPath();
+ } catch (IOException e) {
+ // if we couldn't resolve the lock file, it might be because we couldn't create it.
+ // so append any exception from createFile as a suppressed exception, in case its useful
+ if (creationException != null) {
+ e.addSuppressed(creationException);
+ }
+ throw e;
+ }
// used as a best-effort check, to see if the underlying file has changed
final FileTime creationTime = Files.readAttributes(realPath, BasicFileAttributes.class).creationTime();
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/bcdac5fe/lucene/core/src/test/org/apache/lucene/store/TestNativeFSLockFactory.java
----------------------------------------------------------------------
diff --git a/lucene/core/src/test/org/apache/lucene/store/TestNativeFSLockFactory.java b/lucene/core/src/test/org/apache/lucene/store/TestNativeFSLockFactory.java
index 5d202bf..dc77178 100644
--- a/lucene/core/src/test/org/apache/lucene/store/TestNativeFSLockFactory.java
+++ b/lucene/core/src/test/org/apache/lucene/store/TestNativeFSLockFactory.java
@@ -18,9 +18,17 @@ package org.apache.lucene.store;
import java.io.IOException;
+import java.nio.channels.SeekableByteChannel;
+import java.nio.file.AccessDeniedException;
+import java.nio.file.FileSystem;
import java.nio.file.Files;
+import java.nio.file.OpenOption;
import java.nio.file.Path;
+import java.nio.file.attribute.FileAttribute;
+import java.util.Set;
+import org.apache.lucene.mockfile.FilterFileSystemProvider;
+import org.apache.lucene.mockfile.FilterPath;
import org.apache.lucene.util.IOUtils;
import org.apache.lucene.util.TestUtil;
@@ -89,4 +97,38 @@ public class TestNativeFSLockFactory extends BaseLockFactoryTestCase {
IOUtils.closeWhileHandlingException(lock);
}
}
+
+ /** MockFileSystem that throws AccessDeniedException on creating test.lock */
+ static class MockBadPermissionsFileSystem extends FilterFileSystemProvider {
+ public MockBadPermissionsFileSystem(FileSystem delegateInstance) {
+ super("mockbadpermissions://", delegateInstance);
+ }
+
+ @Override
+ public SeekableByteChannel newByteChannel(Path path, Set<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException {
+ if (path.getFileName().toString().equals("test.lock")) {
+ throw new AccessDeniedException(path.toString(), null, "fake access denied");
+ }
+ return super.newByteChannel(path, options, attrs);
+ }
+ }
+
+ public void testBadPermissions() throws IOException {
+ // create a mock filesystem that will throw exc on creating test.lock
+ Path tmpDir = createTempDir();
+ tmpDir = FilterPath.unwrap(tmpDir).toRealPath();
+ FileSystem mock = new MockBadPermissionsFileSystem(tmpDir.getFileSystem()).getFileSystem(null);
+ Path mockPath = mock.getPath(tmpDir.toString());
+
+ // we should get an IOException (typically NoSuchFileException but no guarantee) with
+ // our fake AccessDenied added as suppressed.
+ Directory dir = getDirectory(mockPath.resolve("indexDir"));
+ IOException expected = expectThrows(IOException.class, () -> {
+ dir.obtainLock("test.lock");
+ });
+ AccessDeniedException suppressed = (AccessDeniedException) expected.getSuppressed()[0];
+ assertTrue(suppressed.getMessage().contains("fake access denied"));
+
+ dir.close();
+ }
}