Fix Data Node system parameters pre-flight check (#17497)

- Read the "max_map_count" from the /proc system instead of calling the
  /sbin/sysctl command
- Only run check on Linux operating systems (avoids warning on FreeBSD)
- Throw "PreflightCheckException" instead of "RuntimeException"
- Don't use "System.out.println()" for logging
- Enhance changelog entry to help users to understand the fix

Refs https://github.com/Graylog2/graylog2-server/pull/17436
This commit is contained in:
Bernd Ahlers
2023-11-29 11:34:15 +01:00
committed by GitHub
parent af4c9085b1
commit 28f59c326f
2 changed files with 19 additions and 30 deletions

View File

@@ -16,51 +16,40 @@
*/
package org.graylog.datanode.bootstrap.preflight;
import org.apache.commons.exec.OS;
import com.sun.jna.Platform;
import org.graylog2.bootstrap.preflight.PreflightCheck;
import org.graylog2.bootstrap.preflight.PreflightCheckException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import oshi.PlatformEnum;
import oshi.util.FileUtil;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import static org.graylog2.shared.utilities.StringUtils.f;
/**
* Check required system parameters
* Check required system parameters.
*/
public class OpenSearchPreconditionsCheck implements PreflightCheck {
private static final Logger LOG = LoggerFactory.getLogger(OpenSearchPreconditionsCheck.class);
// See: https://opensearch.org/docs/2.11/install-and-configure/install-opensearch/index/#important-settings
private static final long MAX_MAP_COUNT_MIN = 262144L;
private static final String PROC_SYS_VM_MAX_MAP_COUNT_PATH = "/proc/sys/vm/max_map_count";
@Override
public void runCheck() throws PreflightCheckException {
if (OS.isFamilyMac()) {
return; // don't throw an exception on Mac dev machines
if (PlatformEnum.getValue(Platform.getOSType()) != PlatformEnum.LINUX) {
LOG.debug("Check only supports Linux operating systems");
return;
}
ProcessBuilder builder = new ProcessBuilder().redirectErrorStream(true);
builder.command("/sbin/sysctl", "-n", "vm.max_map_count");
try {
final Process process = builder.start();
final BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream(), Charset.defaultCharset()));
String line = reader.readLine();
reader.close();
int exitVal = process.waitFor();
if (exitVal != 0) {
System.out.println("Sysctl failed with error return " + exitVal);
return;
}
if (line != null) {
long count = Long.valueOf(line);
if (count < MAX_MAP_COUNT_MIN) {
throw new RuntimeException("vm.max_map_count = " + count + " but should be at least " + MAX_MAP_COUNT_MIN);
}
}
} catch (IOException | InterruptedException e) {
LOG.warn("Failed to run sysctl check: {}", e.getMessage(), e);
final var vmMaxMapCount = FileUtil.getLongFromFile(PROC_SYS_VM_MAX_MAP_COUNT_PATH);
if (vmMaxMapCount == 0) {
LOG.warn("Couldn't read value from {}", PROC_SYS_VM_MAX_MAP_COUNT_PATH);
} else if (vmMaxMapCount < MAX_MAP_COUNT_MIN) {
throw new PreflightCheckException(f("%s value should be at least %d but is %d (set via \"vm.max_map_count\" sysctl)",
PROC_SYS_VM_MAX_MAP_COUNT_PATH, MAX_MAP_COUNT_MIN, vmMaxMapCount));
}
}
}