diff --git a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCheck.java b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCheck.java index 8e88f531360..c06c8d12fdc 100644 --- a/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCheck.java +++ b/core/src/main/java/org/elasticsearch/bootstrap/BootstrapCheck.java @@ -28,6 +28,7 @@ import org.elasticsearch.common.settings.Settings; import org.elasticsearch.monitor.process.ProcessProbe; import org.elasticsearch.transport.TransportSettings; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; @@ -41,7 +42,6 @@ import java.util.Set; * - discovery.zen.minimum_master_nodes * - discovery.zen.ping.unicast.hosts is set if we use zen disco * - ensure we can write in all data directories - * - fail if mlockall failed and was configured * - fail if vm.max_map_count is under a certain limit (not sure if this works cross platform) * - fail if the default cluster.name is used, if this is setup on network a real clustername should be used? */ @@ -57,7 +57,7 @@ final class BootstrapCheck { * @param settings the current node settings */ public static void check(final Settings settings) { - check(enforceLimits(settings), checks()); + check(enforceLimits(settings), checks(settings)); } /** @@ -114,10 +114,13 @@ final class BootstrapCheck { } // the list of checks to execute - private static List checks() { + private static List checks(Settings settings) { + List checks = new ArrayList<>(); FileDescriptorCheck fileDescriptorCheck = Constants.MAC_OS_X ? new OsXFileDescriptorCheck() : new FileDescriptorCheck(); - return Collections.singletonList(fileDescriptorCheck); + checks.add(fileDescriptorCheck); + checks.add(new MlockallCheck(BootstrapSettings.MLOCKALL_SETTING.get(settings))); + return Collections.unmodifiableList(checks); } /** @@ -191,4 +194,30 @@ final class BootstrapCheck { } + // visible for testing + static class MlockallCheck implements Check { + + private final boolean mlockallSet; + + public MlockallCheck(boolean mlockAllSet) { + this.mlockallSet = mlockAllSet; + } + + @Override + public boolean check() { + return mlockallSet && !isMemoryLocked(); + } + + @Override + public String errorMessage() { + return "Memory locking requested for elasticsearch process but memory is not locked"; + } + + // visible for testing + boolean isMemoryLocked() { + return Natives.isMemoryLocked(); + } + + } + } diff --git a/core/src/test/java/org/elasticsearch/bootstrap/BootstrapCheckTests.java b/core/src/test/java/org/elasticsearch/bootstrap/BootstrapCheckTests.java index 23b409cac8b..000ae7b068f 100644 --- a/core/src/test/java/org/elasticsearch/bootstrap/BootstrapCheckTests.java +++ b/core/src/test/java/org/elasticsearch/bootstrap/BootstrapCheckTests.java @@ -23,8 +23,10 @@ import org.elasticsearch.common.settings.Setting; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.test.ESTestCase; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.List; import java.util.Set; import java.util.concurrent.atomic.AtomicLong; @@ -83,6 +85,51 @@ public class BootstrapCheckTests extends ESTestCase { assertThat(e.getMessage(), containsString("limit must be positive but was")); } + public void testMlockallCheck() { + class MlockallCheckTestCase { + + private final boolean mlockallSet; + private final boolean isMemoryLocked; + private final boolean shouldFail; + + public MlockallCheckTestCase(boolean mlockallSet, boolean isMemoryLocked, boolean shouldFail) { + this.mlockallSet = mlockallSet; + this.isMemoryLocked = isMemoryLocked; + this.shouldFail = shouldFail; + } + + } + + final List testCases = new ArrayList<>(); + testCases.add(new MlockallCheckTestCase(true, true, false)); + testCases.add(new MlockallCheckTestCase(true, false, true)); + testCases.add(new MlockallCheckTestCase(false, true, false)); + testCases.add(new MlockallCheckTestCase(false, false, false)); + + for (final MlockallCheckTestCase testCase : testCases) { + final BootstrapCheck.MlockallCheck check = new BootstrapCheck.MlockallCheck(testCase.mlockallSet) { + @Override + boolean isMemoryLocked() { + return testCase.isMemoryLocked; + } + }; + + if (testCase.shouldFail) { + try { + BootstrapCheck.check(true, Collections.singletonList(check)); + fail("should have failed due to memory not being locked"); + } catch (RuntimeException e) { + assertThat( + e.getMessage(), + containsString("Memory locking requested for elasticsearch process but memory is not locked")); + } + } else { + // nothing should happen + BootstrapCheck.check(true, Collections.singletonList(check)); + } + } + } + public void testEnforceLimits() { final Set enforceSettings = BootstrapCheck.enforceSettings(); final Setting setting = randomFrom(Arrays.asList(enforceSettings.toArray(new Setting[enforceSettings.size()])));