forked from elastic/elasticsearch
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Set LIBFFI_TMPDIR at startup (elastic#80651)
Today if `libffi` cannot allocate pages of memory which are both writeable and executable then it will attempt to write code to a temporary file. Elasticsearch configures itself a suitable temporary directory for use by JNA but by default `libffi` won't find this directory and will try various other places. In certain configurations, none of the other places that `libffi` tries are suitable. With older versions of JNA this would result in a `SIGSEGV`; since elastic#80617 the JVM will exit with an exception. With this commit we use the `LIBFFI_TMPDIR` environment variable to configure `libffi` to use the same directory as JNA for its temporary files if they are needed. Closes elastic#18272 Closes elastic#73309 Closes elastic#74545 Closes elastic#77014 Closes elastic#77053 Relates elastic#77285 Co-authored-by: Rory Hunter <roryhunter2@gmail.com>
- Loading branch information
1 parent
34b2990
commit ce59bd2
Showing
7 changed files
with
215 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
114 changes: 114 additions & 0 deletions
114
qa/os/src/test/java/org/elasticsearch/packaging/test/TemporaryDirectoryConfigTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
package org.elasticsearch.packaging.test; | ||
|
||
import org.apache.http.client.fluent.Request; | ||
import org.elasticsearch.core.CheckedConsumer; | ||
import org.elasticsearch.packaging.util.Distribution; | ||
import org.elasticsearch.packaging.util.ServerUtils; | ||
import org.elasticsearch.packaging.util.Shell; | ||
import org.elasticsearch.packaging.util.docker.DockerRun; | ||
import org.junit.After; | ||
import org.junit.Before; | ||
|
||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
|
||
import static org.elasticsearch.packaging.util.FileUtils.append; | ||
import static org.elasticsearch.packaging.util.docker.Docker.removeContainer; | ||
import static org.elasticsearch.packaging.util.docker.Docker.runContainer; | ||
import static org.elasticsearch.packaging.util.docker.Docker.runContainerExpectingFailure; | ||
import static org.elasticsearch.packaging.util.docker.Docker.waitForElasticsearch; | ||
import static org.hamcrest.Matchers.containsString; | ||
import static org.junit.Assume.assumeFalse; | ||
import static org.junit.Assume.assumeTrue; | ||
|
||
public class TemporaryDirectoryConfigTests extends PackagingTestCase { | ||
|
||
@Before | ||
public void onlyLinux() { | ||
assumeTrue("only Linux", distribution.platform == Distribution.Platform.LINUX); | ||
} | ||
|
||
@After | ||
public void cleanupContainer() { | ||
if (distribution().isDocker()) { | ||
removeContainer(); | ||
} | ||
} | ||
|
||
public void test10Install() throws Exception { | ||
install(); | ||
} | ||
|
||
public void test20AcceptsCustomPath() throws Exception { | ||
assumeFalse(distribution().isDocker()); | ||
|
||
final Path tmpDir = createTempDir("libffi"); | ||
sh.getEnv().put("LIBFFI_TMPDIR", tmpDir.toString()); | ||
withLibffiTmpdir( | ||
tmpDir.toString(), | ||
confPath -> assertWhileRunning(() -> ServerUtils.makeRequest(Request.Get("https://localhost:9200/"))) | ||
); // just checking it doesn't throw | ||
} | ||
|
||
public void test21AcceptsCustomPathInDocker() throws Exception { | ||
assumeTrue(distribution().isDocker()); | ||
|
||
final Path tmpDir = createTempDir("libffi"); | ||
|
||
installation = runContainer( | ||
distribution(), | ||
DockerRun.builder() | ||
// There's no actual need for this to be a bind-mounted dir, but it's the quickest | ||
// way to create a directory in the container before the entrypoint runs. | ||
.volume(tmpDir, tmpDir) | ||
.envVar("ELASTIC_PASSWORD", "nothunter2") | ||
.envVar("LIBFFI_TMPDIR", tmpDir.toString()) | ||
); | ||
|
||
waitForElasticsearch("green", null, installation, "elastic", "nothunter2"); | ||
} | ||
|
||
public void test30VerifiesCustomPath() throws Exception { | ||
assumeFalse(distribution().isDocker()); | ||
|
||
final Path tmpFile = createTempDir("libffi").resolve("file"); | ||
Files.createFile(tmpFile); | ||
withLibffiTmpdir( | ||
tmpFile.toString(), | ||
confPath -> assertElasticsearchFailure(runElasticsearchStartCommand(null, false, false), "LIBFFI_TMPDIR", null) | ||
); | ||
} | ||
|
||
public void test31VerifiesCustomPathInDocker() throws Exception { | ||
assumeTrue(distribution().isDocker()); | ||
|
||
final Path tmpDir = createTempDir("libffi"); | ||
final Path tmpFile = tmpDir.resolve("file"); | ||
Files.createFile(tmpFile); | ||
|
||
final Shell.Result result = runContainerExpectingFailure( | ||
distribution(), | ||
DockerRun.builder().volume(tmpDir, tmpDir).envVar("LIBFFI_TMPDIR", tmpFile.toString()) | ||
); | ||
assertThat(result.stderr, containsString("LIBFFI_TMPDIR")); | ||
} | ||
|
||
private void withLibffiTmpdir(String tmpDir, CheckedConsumer<Path, Exception> action) throws Exception { | ||
sh.getEnv().put("LIBFFI_TMPDIR", tmpDir); | ||
withCustomConfig(confPath -> { | ||
if (distribution.isPackage()) { | ||
append(installation.envFile, "LIBFFI_TMPDIR=" + tmpDir); | ||
} | ||
action.accept(confPath); | ||
}); | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters