Add mlockall bootstrap check

This commit adds a boostrap check for the situation bootstrap.mlockall
is enabled, but memory was not able to be locked.

Closes #16909
This commit is contained in:
Jason Tedor 2016-03-02 09:36:02 -05:00
parent 6caec9bc25
commit f2220c9786
2 changed files with 80 additions and 4 deletions

View File

@ -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<Check> checks() {
private static List<Check> checks(Settings settings) {
List<Check> 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();
}
}
}

View File

@ -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<MlockallCheckTestCase> 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<Setting> enforceSettings = BootstrapCheck.enforceSettings();
final Setting setting = randomFrom(Arrays.asList(enforceSettings.toArray(new Setting[enforceSettings.size()])));