Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions core/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,9 @@ public void run() {
node = new Node(environment) {
@Override
protected void validateNodeBeforeAcceptingRequests(
final Settings settings,
final BootstrapContext context,
final BoundTransportAddress boundTransportAddress, List<BootstrapCheck> checks) throws NodeValidationException {
BootstrapChecks.check(settings, boundTransportAddress, checks);
BootstrapChecks.check(context, boundTransportAddress, checks);
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ public interface BootstrapCheck {
/**
* Test if the node fails the check.
*
* @param context the bootstrap context for more sophisticated checks
* @return {@code true} if the node failed the check
*/
boolean check();
boolean check(BootstrapContext context);

/**
* The error message for a failed check.
Expand All @@ -41,5 +42,4 @@ public interface BootstrapCheck {
default boolean alwaysEnforce() {
return false;
}

}
71 changes: 31 additions & 40 deletions core/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.common.io.PathUtils;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.BoundTransportAddress;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.discovery.DiscoveryModule;
Expand Down Expand Up @@ -65,46 +64,50 @@ private BootstrapChecks() {
* {@code es.enforce.bootstrap.checks} is set to {@code true} then the bootstrap checks will be enforced regardless of whether or not
* the transport protocol is bound to a non-loopback interface.
*
* @param settings the current node settings
* @param context the current node bootstrap context
* @param boundTransportAddress the node network bindings
*/
static void check(final Settings settings, final BoundTransportAddress boundTransportAddress, List<BootstrapCheck> additionalChecks)
throws NodeValidationException {
final List<BootstrapCheck> builtInChecks = checks(settings);
static void check(final BootstrapContext context, final BoundTransportAddress boundTransportAddress,
List<BootstrapCheck> additionalChecks) throws NodeValidationException {
final List<BootstrapCheck> builtInChecks = checks();
final List<BootstrapCheck> combinedChecks = new ArrayList<>(builtInChecks);
combinedChecks.addAll(additionalChecks);
check(
enforceLimits(boundTransportAddress, DiscoveryModule.DISCOVERY_TYPE_SETTING.get(settings)),
check( context,
enforceLimits(boundTransportAddress, DiscoveryModule.DISCOVERY_TYPE_SETTING.get(context.settings)),
Collections.unmodifiableList(combinedChecks),
Node.NODE_NAME_SETTING.get(settings));
Node.NODE_NAME_SETTING.get(context.settings));
}

/**
* Executes the provided checks and fails the node if {@code enforceLimits} is {@code true}, otherwise logs warnings. If the system
* property {@code es.enforce.bootstrap.checks} is set to {@code true} then the bootstrap checks will be enforced regardless of whether
* or not the transport protocol is bound to a non-loopback interface.
*
* @param context the current node boostrap context
* @param enforceLimits {@code true} if the checks should be enforced or otherwise warned
* @param checks the checks to execute
* @param nodeName the node name to be used as a logging prefix
*/
static void check(
final BootstrapContext context,
final boolean enforceLimits,
final List<BootstrapCheck> checks,
final String nodeName) throws NodeValidationException {
check(enforceLimits, checks, Loggers.getLogger(BootstrapChecks.class, nodeName));
check(context, enforceLimits, checks, Loggers.getLogger(BootstrapChecks.class, nodeName));
}

/**
* Executes the provided checks and fails the node if {@code enforceLimits} is {@code true}, otherwise logs warnings. If the system
* property {@code es.enforce.bootstrap.checks }is set to {@code true} then the bootstrap checks will be enforced regardless of whether
* or not the transport protocol is bound to a non-loopback interface.
*
* @param context the current node boostrap context
* @param enforceLimits {@code true} if the checks should be enforced or otherwise warned
* @param checks the checks to execute
* @param logger the logger to
*/
static void check(
final BootstrapContext context,
final boolean enforceLimits,
final List<BootstrapCheck> checks,
final Logger logger) throws NodeValidationException {
Expand Down Expand Up @@ -134,7 +137,7 @@ static void check(
}

for (final BootstrapCheck check : checks) {
if (check.check()) {
if (check.check(context)) {
if (!(enforceLimits || enforceBootstrapChecks) && !check.alwaysEnforce()) {
ignoredErrors.add(check.errorMessage());
} else {
Expand Down Expand Up @@ -180,13 +183,13 @@ static boolean enforceLimits(final BoundTransportAddress boundTransportAddress,
}

// the list of checks to execute
static List<BootstrapCheck> checks(final Settings settings) {
static List<BootstrapCheck> checks() {
final List<BootstrapCheck> checks = new ArrayList<>();
checks.add(new HeapSizeCheck());
final FileDescriptorCheck fileDescriptorCheck
= Constants.MAC_OS_X ? new OsXFileDescriptorCheck() : new FileDescriptorCheck();
checks.add(fileDescriptorCheck);
checks.add(new MlockallCheck(BootstrapSettings.MEMORY_LOCK_SETTING.get(settings)));
checks.add(new MlockallCheck());
if (Constants.LINUX) {
checks.add(new MaxNumberOfThreadsCheck());
}
Expand All @@ -201,7 +204,7 @@ static List<BootstrapCheck> checks(final Settings settings) {
}
checks.add(new ClientJvmCheck());
checks.add(new UseSerialGCCheck());
checks.add(new SystemCallFilterCheck(BootstrapSettings.SYSTEM_CALL_FILTER_SETTING.get(settings)));
checks.add(new SystemCallFilterCheck());
checks.add(new OnErrorCheck());
checks.add(new OnOutOfMemoryErrorCheck());
checks.add(new EarlyAccessCheck());
Expand All @@ -212,7 +215,7 @@ static List<BootstrapCheck> checks(final Settings settings) {
static class HeapSizeCheck implements BootstrapCheck {

@Override
public boolean check() {
public boolean check(BootstrapContext context) {
final long initialHeapSize = getInitialHeapSize();
final long maxHeapSize = getMaxHeapSize();
return initialHeapSize != 0 && maxHeapSize != 0 && initialHeapSize != maxHeapSize;
Expand Down Expand Up @@ -268,7 +271,7 @@ protected FileDescriptorCheck(final int limit) {
this.limit = limit;
}

public final boolean check() {
public final boolean check(BootstrapContext context) {
final long maxFileDescriptorCount = getMaxFileDescriptorCount();
return maxFileDescriptorCount != -1 && maxFileDescriptorCount < limit;
}
Expand All @@ -292,15 +295,9 @@ long getMaxFileDescriptorCount() {

static class MlockallCheck implements BootstrapCheck {

private final boolean mlockallSet;

MlockallCheck(final boolean mlockAllSet) {
this.mlockallSet = mlockAllSet;
}

@Override
public boolean check() {
return mlockallSet && !isMemoryLocked();
public boolean check(BootstrapContext context) {
return BootstrapSettings.MEMORY_LOCK_SETTING.get(context.settings) && !isMemoryLocked();
}

@Override
Expand All @@ -321,7 +318,7 @@ static class MaxNumberOfThreadsCheck implements BootstrapCheck {
private static final long MAX_NUMBER_OF_THREADS_THRESHOLD = 1 << 12;

@Override
public boolean check() {
public boolean check(BootstrapContext context) {
return getMaxNumberOfThreads() != -1 && getMaxNumberOfThreads() < MAX_NUMBER_OF_THREADS_THRESHOLD;
}

Expand All @@ -345,7 +342,7 @@ long getMaxNumberOfThreads() {
static class MaxSizeVirtualMemoryCheck implements BootstrapCheck {

@Override
public boolean check() {
public boolean check(BootstrapContext context) {
return getMaxSizeVirtualMemory() != Long.MIN_VALUE && getMaxSizeVirtualMemory() != getRlimInfinity();
}

Expand Down Expand Up @@ -376,7 +373,7 @@ long getMaxSizeVirtualMemory() {
static class MaxFileSizeCheck implements BootstrapCheck {

@Override
public boolean check() {
public boolean check(BootstrapContext context) {
final long maxFileSize = getMaxFileSize();
return maxFileSize != Long.MIN_VALUE && maxFileSize != getRlimInfinity();
}
Expand Down Expand Up @@ -405,7 +402,7 @@ static class MaxMapCountCheck implements BootstrapCheck {
private static final long LIMIT = 1 << 18;

@Override
public boolean check() {
public boolean check(BootstrapContext context) {
return getMaxMapCount() != -1 && getMaxMapCount() < LIMIT;
}

Expand Down Expand Up @@ -470,7 +467,7 @@ long parseProcSysVmMaxMapCount(final String procSysVmMaxMapCount) throws NumberF
static class ClientJvmCheck implements BootstrapCheck {

@Override
public boolean check() {
public boolean check(BootstrapContext context) {
return getVmName().toLowerCase(Locale.ROOT).contains("client");
}

Expand All @@ -496,7 +493,7 @@ public String errorMessage() {
static class UseSerialGCCheck implements BootstrapCheck {

@Override
public boolean check() {
public boolean check(BootstrapContext context) {
return getUseSerialGC().equals("true");
}

Expand All @@ -521,15 +518,9 @@ public String errorMessage() {
*/
static class SystemCallFilterCheck implements BootstrapCheck {

private final boolean areSystemCallFiltersEnabled;

SystemCallFilterCheck(final boolean areSystemCallFiltersEnabled) {
this.areSystemCallFiltersEnabled = areSystemCallFiltersEnabled;
}

@Override
public boolean check() {
return areSystemCallFiltersEnabled && !isSystemCallFilterInstalled();
public boolean check(BootstrapContext context) {
return BootstrapSettings.SYSTEM_CALL_FILTER_SETTING.get(context.settings) && !isSystemCallFilterInstalled();
}

// visible for testing
Expand All @@ -548,7 +539,7 @@ public String errorMessage() {
abstract static class MightForkCheck implements BootstrapCheck {

@Override
public boolean check() {
public boolean check(BootstrapContext context) {
return isSystemCallFilterInstalled() && mightFork();
}

Expand Down Expand Up @@ -623,7 +614,7 @@ public String errorMessage() {
static class EarlyAccessCheck implements BootstrapCheck {

@Override
public boolean check() {
public boolean check(BootstrapContext context) {
return "Oracle Corporation".equals(jvmVendor()) && javaVersion().endsWith("-ea");
}

Expand Down Expand Up @@ -651,7 +642,7 @@ public String errorMessage() {
static class G1GCCheck implements BootstrapCheck {

@Override
public boolean check() {
public boolean check(BootstrapContext context) {
if ("Oracle Corporation".equals(jvmVendor()) && isJava8() && isG1GCEnabled()) {
final String jvmVersion = jvmVersion();
// HotSpot versions on Java 8 match this regular expression; note that this changes with Java 9 after JEP-223
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.bootstrap;

import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.common.settings.Settings;

/**
* Context that is passed to every bootstrap check to make decisions on.
*/
public class BootstrapContext {
/**
* The nodes settings
*/
public final Settings settings;
/**
* The nodes local state metadata loaded on startup
*/
public final MetaData metaData;

public BootstrapContext(Settings settings, MetaData metaData) {
this.settings = settings;
this.metaData = metaData;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.elasticsearch.index.Index;
import org.elasticsearch.plugins.MetaDataUpgrader;

import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -114,7 +115,7 @@ public GatewayMetaState(Settings settings, NodeEnvironment nodeEnv, MetaStateSer
}
}

public MetaData loadMetaState() throws Exception {
public MetaData loadMetaState() throws IOException {
return metaStateService.loadFullState();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public MetaStateService(Settings settings, NodeEnvironment nodeEnv, NamedXConten
* Loads the full state, which includes both the global state and all the indices
* meta state.
*/
MetaData loadFullState() throws Exception {
MetaData loadFullState() throws IOException {
MetaData globalMetaData = loadGlobalState();
MetaData.Builder metaDataBuilder;
if (globalMetaData != null) {
Expand Down
25 changes: 22 additions & 3 deletions core/src/main/java/org/elasticsearch/node/Node.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import org.elasticsearch.action.support.TransportAction;
import org.elasticsearch.action.update.UpdateHelper;
import org.elasticsearch.bootstrap.BootstrapCheck;
import org.elasticsearch.bootstrap.BootstrapContext;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.node.NodeClient;
import org.elasticsearch.cluster.ClusterInfo;
Expand Down Expand Up @@ -86,6 +87,7 @@
import org.elasticsearch.env.Environment;
import org.elasticsearch.env.NodeEnvironment;
import org.elasticsearch.gateway.GatewayAllocator;
import org.elasticsearch.gateway.GatewayMetaState;
import org.elasticsearch.gateway.GatewayModule;
import org.elasticsearch.gateway.GatewayService;
import org.elasticsearch.gateway.MetaStateService;
Expand Down Expand Up @@ -139,6 +141,7 @@
import java.io.BufferedWriter;
import java.io.Closeable;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
Expand Down Expand Up @@ -604,7 +607,23 @@ public Node start() throws NodeValidationException {
assert localNodeFactory.getNode() != null;
assert transportService.getLocalNode().equals(localNodeFactory.getNode())
: "transportService has a different local node than the factory provided";
validateNodeBeforeAcceptingRequests(settings, transportService.boundAddress(), pluginsService.filterPlugins(Plugin.class).stream()
final MetaData onDiskMetadata;
try {
// we load the global state here (the persistent part of the cluster state stored on disk) to
// pass it to the bootstrap checks to allow plugins to enforce certain preconditions based on the recovered state.
if (DiscoveryNode.isMasterNode(settings) || DiscoveryNode.isDataNode(settings)) {
onDiskMetadata = injector.getInstance(GatewayMetaState.class).loadMetaState();
} else {
onDiskMetadata = MetaData.EMPTY_META_DATA;
}
assert onDiskMetadata != null : "metadata is null but shouldn't"; // this is never null
} catch (IOException e) {
throw new UncheckedIOException(e);
}
validateNodeBeforeAcceptingRequests(new BootstrapContext(settings, onDiskMetadata), transportService.boundAddress(), pluginsService
.filterPlugins(Plugin
.class)
.stream()
.flatMap(p -> p.getBootstrapChecks().stream()).collect(Collectors.toList()));

clusterService.addStateApplier(transportService.getTaskManager());
Expand Down Expand Up @@ -811,13 +830,13 @@ public Injector injector() {
* and before the network service starts accepting incoming network
* requests.
*
* @param settings the fully-resolved settings
* @param context the bootstrap context for this node
* @param boundTransportAddress the network addresses the node is
* bound and publishing to
*/
@SuppressWarnings("unused")
protected void validateNodeBeforeAcceptingRequests(
final Settings settings,
final BootstrapContext context,
final BoundTransportAddress boundTransportAddress, List<BootstrapCheck> bootstrapChecks) throws NodeValidationException {
}

Expand Down
Loading