From 68a906ac84700605a6a2a30ab1a9a5a4a60de513 Mon Sep 17 00:00:00 2001 From: Fabio Di Fabio Date: Tue, 23 Aug 2022 12:37:19 +0200 Subject: [PATCH] Better management of jemalloc presence/absence (#4237) Signed-off-by: Fabio Di Fabio Co-authored-by: Adrian Sutton Signed-off-by: garyschulte --- CHANGELOG.md | 8 +++++--- .../org/hyperledger/besu/cli/BesuCommand.java | 14 ++++++++++++++ besu/src/main/scripts/unixStartScript.txt | 17 ++++++++++++++--- .../hyperledger/besu/cli/BesuCommandTest.java | 18 ++++++++++++++++++ 4 files changed, 51 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42207a5d312..56627a5d4cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ ## 22.7.2 ### Additions and Improvements +- Upgrade besu-native to 0.6.0 and use Blake2bf native implementation if available by default [#4264](https://github.com/hyperledger/besu/pull/4264) +- Better management of jemalloc presence/absence in startup script [#4237](https://github.com/hyperledger/besu/pull/4237) ### Bug Fixes @@ -33,7 +35,7 @@ ### Additions and Improvements - Deprecation warning for Ropsten, Rinkeby, Kiln [#4173](https://github.com/hyperledger/besu/pull/4173) -### Bug Fixes +### Bug Fixes - Fixes previous known issue [#3890](https://github.com/hyperledger/besu/issues/3890)from RC3 requiring a restart post-merge to continue correct transaction handling. - Stop producing stack traces when a get headers response only contains the range start header [#4189](https://github.com/hyperledger/besu/pull/4189) @@ -52,8 +54,8 @@ ### Additions and Improvements - Engine API: Change expiration time for JWT tokens to 60s [#4168](https://github.com/hyperledger/besu/pull/4168) - Sepolia mergeNetSplit block [#4158](https://github.com/hyperledger/besu/pull/4158) -- Goerli TTD [#4160](https://github.com/hyperledger/besu/pull/4160) -- Several logging improvements +- Goerli TTD [#4160](https://github.com/hyperledger/besu/pull/4160) +- Several logging improvements ### Bug Fixes - Allow to set any value for baseFeePerGas in the genesis file [#4177](https://github.com/hyperledger/besu/pull/4177) diff --git a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java index d1ec8d28b15..9cb91613cb2 100644 --- a/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java +++ b/besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java @@ -185,6 +185,7 @@ import org.hyperledger.besu.util.number.Fraction; import org.hyperledger.besu.util.number.Percentage; import org.hyperledger.besu.util.number.PositiveNumber; +import org.hyperledger.besu.util.platform.PlatformDetector; import java.io.File; import java.io.IOException; @@ -1391,6 +1392,7 @@ public void parse( handleUnstableOptions(); preparePlugins(); parse(resultHandler, exceptionHandler, args); + detectJemalloc(); } @Override @@ -1492,6 +1494,18 @@ private void registerConverters() { commandLine.registerConverter(MetricCategory.class, metricCategoryConverter); } + private void detectJemalloc() { + // jemalloc is only supported on Linux at the moment + if (PlatformDetector.getOSType().equals("linux")) { + Optional.ofNullable(environment.get("BESU_USING_JEMALLOC")) + .ifPresentOrElse( + present -> logger.info("Using jemalloc"), + () -> + logger.info( + "jemalloc library not found, memory usage may be reduced by installing it")); + } + } + private void handleStableOptions() { commandLine.addMixin("Ethstats", ethstatsOptions); commandLine.addMixin("Private key file", nodePrivateKeyFileOption); diff --git a/besu/src/main/scripts/unixStartScript.txt b/besu/src/main/scripts/unixStartScript.txt index 50585f07660..3302b9c2fe1 100644 --- a/besu/src/main/scripts/unixStartScript.txt +++ b/besu/src/main/scripts/unixStartScript.txt @@ -182,8 +182,19 @@ APP_ARGS=`save "\$@"` # Collect all arguments for the java command, following the shell quoting and substitution rules eval set -- \$DEFAULT_JVM_OPTS \$JAVA_OPTS \$${optsEnvironmentVar} <% if ( appNameSystemProperty ) { %>"\"-D${appNameSystemProperty}=\$APP_BASE_NAME\"" <% } %>-classpath "\"\$CLASSPATH\"" <% if ( mainClassName.startsWith('--module ') ) { %>--module-path "\"\$MODULE_PATH\"" <% } %>${mainClassName} "\$APP_ARGS" -# limit malloc to 2 arenas, and use jemalloc if available -export MALLOC_ARENA_MAX=2 -export LD_PRELOAD=libjemalloc.so +unset BESU_USING_JEMALLOC +if [ "\$darwin" = "false" -a "\$msys" = "false" ]; then + # check if jemalloc is available + TEST_JEMALLOC=\$(LD_PRELOAD=libjemalloc.so sh -c true 2>&1) + + # if jemalloc is available the output is empty, otherwise the output has an error line + if [ -z "\$TEST_JEMALLOC" ]; then + export LD_PRELOAD=libjemalloc.so + export BESU_USING_JEMALLOC=true + else + # jemalloc not available, as fallback limit malloc to 2 arenas + export MALLOC_ARENA_MAX=2 + fi +fi exec "\$JAVACMD" "\$@" diff --git a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java index 1b64a1cdb65..9878140ccd4 100644 --- a/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java +++ b/besu/src/test/java/org/hyperledger/besu/cli/BesuCommandTest.java @@ -17,6 +17,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.startsWith; import static org.hyperledger.besu.cli.config.NetworkName.CLASSIC; import static org.hyperledger.besu.cli.config.NetworkName.DEV; @@ -94,6 +95,7 @@ import org.hyperledger.besu.plugin.services.rpc.PluginRpcRequest; import org.hyperledger.besu.util.number.Fraction; import org.hyperledger.besu.util.number.Percentage; +import org.hyperledger.besu.util.platform.PlatformDetector; import java.io.File; import java.io.IOException; @@ -5318,4 +5320,20 @@ public void pkiBlockCreationFullConfig() throws Exception { assertThat(pkiKeyStoreConfig.getTrustStorePassword()).isEqualTo("foo"); assertThat(pkiKeyStoreConfig.getCrlFilePath()).hasValue(Path.of("/tmp/crl")); } + + @Test + public void logsUsingJemallocWhenEnvVarPresent() { + assumeThat(PlatformDetector.getOSType(), is("linux")); + setEnvironmentVariable("BESU_USING_JEMALLOC", "true"); + parseCommand(); + verify(mockLogger).info("Using jemalloc"); + } + + @Test + public void logsSuggestInstallingJemallocWhenEnvVarNotPresent() { + assumeThat(PlatformDetector.getOSType(), is("linux")); + parseCommand(); + verify(mockLogger) + .info("jemalloc library not found, memory usage may be reduced by installing it"); + } }