Add support for sandboxfs-based sandboxing to Linux.
This is essentially the same as https://github.com/bazelbuild/bazel/commit/3a7b8bc2abeaf8b8647c037bed1dd5fd73b8392b.
RELNOTES: none.
PiperOrigin-RevId: 192342039
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java
index e4c5ba6..5e0a8d8 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedSpawnRunner.java
@@ -41,6 +41,7 @@
import java.time.Duration;
import java.util.Map;
import java.util.SortedMap;
+import javax.annotation.Nullable;
/** Spawn runner that uses linux sandboxing APIs to execute a local subprocess. */
final class LinuxSandboxedSpawnRunner extends AbstractSandboxSpawnRunner {
@@ -80,6 +81,7 @@
private final Path inaccessibleHelperDir;
private final LocalEnvProvider localEnvProvider;
private final Duration timeoutKillDelay;
+ private final @Nullable SandboxfsProcess sandboxfsProcess;
/**
* Creates a sandboxed spawn runner that uses the {@code linux-sandbox} tool.
@@ -89,13 +91,16 @@
* @param inaccessibleHelperFile path to a file that is (already) inaccessible
* @param inaccessibleHelperDir path to a directory that is (already) inaccessible
* @param timeoutKillDelay an additional grace period before killing timing out commands
+ * @param sandboxfsProcess instance of the sandboxfs process to use; may be null for none, in
+ * which case the runner uses a symlinked sandbox
*/
LinuxSandboxedSpawnRunner(
CommandEnvironment cmdEnv,
Path sandboxBase,
Path inaccessibleHelperFile,
Path inaccessibleHelperDir,
- Duration timeoutKillDelay) {
+ Duration timeoutKillDelay,
+ @Nullable SandboxfsProcess sandboxfsProcess) {
super(cmdEnv, sandboxBase);
this.fileSystem = cmdEnv.getRuntime().getFileSystem();
this.blazeDirs = cmdEnv.getDirectories();
@@ -105,6 +110,7 @@
this.inaccessibleHelperFile = inaccessibleHelperFile;
this.inaccessibleHelperDir = inaccessibleHelperDir;
this.timeoutKillDelay = timeoutKillDelay;
+ this.sandboxfsProcess = sandboxfsProcess;
this.localEnvProvider = new PosixLocalEnvProvider(cmdEnv.getClientEnv());
}
@@ -114,10 +120,15 @@
// Each invocation of "exec" gets its own sandbox.
Path sandboxPath = getSandboxRoot();
Path sandboxExecRoot = sandboxPath.getRelative("execroot").getRelative(execRoot.getBaseName());
+ sandboxExecRoot.createDirectoryAndParents();
- // Each sandboxed action runs in its own execroot, so we don't need to make the temp directory's
+ // Each sandboxed action runs in its own directory so we don't need to make the temp directory's
// name unique (like we have to with standalone execution strategy).
- Path tmpDir = sandboxExecRoot.getRelative("tmp");
+ //
+ // Note that, for sandboxfs-based executions, this temp directory lives outside of the sandboxfs
+ // instance. This is perfectly fine (because linux-sandbox controls accesses to this directory)
+ // and is actually desirable for performance reasons.
+ Path tmpDir = sandboxPath.getRelative("tmp");
Map<String, String> environment =
localEnvProvider.rewriteLocalEnv(spawn.getEnvironment(), execRoot, tmpDir.getPathString());
@@ -151,15 +162,28 @@
commandLineBuilder.setStatisticsPath(statisticsPath);
}
- SandboxedSpawn sandbox =
- new SymlinkedSandboxedSpawn(
- sandboxPath,
- sandboxExecRoot,
- commandLineBuilder.build(),
- environment,
- SandboxHelpers.getInputFiles(spawn, policy, execRoot),
- outputs,
- writableDirs);
+ SandboxedSpawn sandbox;
+ if (sandboxfsProcess != null) {
+ sandbox =
+ new SandboxfsSandboxedSpawn(
+ sandboxfsProcess,
+ sandboxPath,
+ commandLineBuilder.build(),
+ environment,
+ SandboxHelpers.getInputFiles(spawn, policy, execRoot),
+ outputs,
+ ImmutableSet.of());
+ } else {
+ sandbox =
+ new SymlinkedSandboxedSpawn(
+ sandboxPath,
+ sandboxExecRoot,
+ commandLineBuilder.build(),
+ environment,
+ SandboxHelpers.getInputFiles(spawn, policy, execRoot),
+ outputs,
+ writableDirs);
+ }
return runSpawn(spawn, sandbox, policy, execRoot, tmpDir, timeout, statisticsPath);
}
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategy.java b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategy.java
index bbebefa..7aac514 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategy.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/LinuxSandboxedStrategy.java
@@ -23,6 +23,7 @@
import com.google.devtools.build.lib.vfs.Path;
import java.io.IOException;
import java.time.Duration;
+import javax.annotation.Nullable;
/** Strategy that uses sandboxing to execute a process. */
// TODO(ulfjack): This class only exists for this annotation. Find a better way to handle this!
@@ -46,9 +47,12 @@
* @param cmdEnv the command environment to use
* @param sandboxBase path to the sandbox base directory
* @param timeoutKillDelay additional grace period before killing timing out commands
+ * @param sandboxfsProcess instance of the sandboxfs process to use; may be null for none, in
+ * which case the runner uses a symlinked sandbox
*/
static LinuxSandboxedSpawnRunner create(
- CommandEnvironment cmdEnv, Path sandboxBase, Duration timeoutKillDelay) throws IOException {
+ CommandEnvironment cmdEnv, Path sandboxBase, Duration timeoutKillDelay,
+ @Nullable SandboxfsProcess sandboxfsProcess) throws IOException {
Path inaccessibleHelperFile = sandboxBase.getRelative("inaccessibleHelperFile");
FileSystemUtils.touchFile(inaccessibleHelperFile);
inaccessibleHelperFile.setReadable(false);
@@ -66,6 +70,7 @@
sandboxBase,
inaccessibleHelperFile,
inaccessibleHelperDir,
- timeoutKillDelay);
+ timeoutKillDelay,
+ sandboxfsProcess);
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxActionContextProvider.java b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxActionContextProvider.java
index a7f7a5b..cee91ce 100644
--- a/src/main/java/com/google/devtools/build/lib/sandbox/SandboxActionContextProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/sandbox/SandboxActionContextProvider.java
@@ -69,11 +69,10 @@
// This is the preferred sandboxing strategy on Linux.
if (LinuxSandboxedSpawnRunner.isSupported(cmdEnv)) {
- // TODO(jmmv): Inject process into spawn runner.
SpawnRunner spawnRunner =
withFallback(
cmdEnv,
- LinuxSandboxedStrategy.create(cmdEnv, sandboxBase, timeoutKillDelay));
+ LinuxSandboxedStrategy.create(cmdEnv, sandboxBase, timeoutKillDelay, process));
contexts.add(new LinuxSandboxedStrategy(cmdEnv.getExecRoot(), spawnRunner));
}