Skip to content

Commit 4e194ef

Browse files
bazel-iooquenchil
andauthored
[7.1.1] Fix sandbox cleanup crashing after server restart (#21733)
We try to clean up the sandbox base from previous server instances asynchronously, however sometimes this is not possible due to the old directories being in a different filesystem. This can happen with overlays on Docker after running bazel in different RUN commands. See #21719 This change fixes the crash by catching the IOException and falling back to synchronous deletion. Fixes #21719. RELNOTES:none Commit 488b630 PiperOrigin-RevId: 617150522 Change-Id: I82a07ac0ade66cfb1e5732a90a5f3ab4e2e8caa7 Co-authored-by: Googler <[email protected]>
1 parent 8aea621 commit 4e194ef

File tree

1 file changed

+28
-19
lines changed

1 file changed

+28
-19
lines changed

src/main/java/com/google/devtools/build/lib/sandbox/SandboxModule.java

+28-19
Original file line numberDiff line numberDiff line change
@@ -227,27 +227,36 @@ private void setup(CommandEnvironment cmdEnv, SpawnStrategyRegistry.Builder buil
227227
// previous builds. However, on the very first build of an instance of the server, we must
228228
// wipe old contents to avoid reusing stale directories.
229229
if (firstBuild && sandboxBase.exists()) {
230-
if (trashBase.exists()) {
231-
// Delete stale trash from a previous server instance.
232-
Path staleTrash = getStaleTrashDir(trashBase);
233-
trashBase.renameTo(staleTrash);
234-
trashBase.createDirectory();
235-
treeDeleter.deleteTree(staleTrash);
236-
} else {
237-
trashBase.createDirectory();
238-
}
239-
// We can delete other dirs asynchronously (if the flag is on).
240-
for (Path entry : sandboxBase.getDirectoryEntries()) {
241-
if (entry.getBaseName().equals(AsynchronousTreeDeleter.MOVED_TRASH_DIR)) {
242-
continue;
243-
}
244-
if (entry.getBaseName().equals(SandboxHelpers.INACCESSIBLE_HELPER_DIR)) {
245-
entry.deleteTree();
246-
} else if (entry.isDirectory()) {
247-
treeDeleter.deleteTree(entry);
230+
try {
231+
if (trashBase.exists()) {
232+
// Delete stale trash from a previous server instance.
233+
Path staleTrash = getStaleTrashDir(trashBase);
234+
trashBase.renameTo(staleTrash);
235+
trashBase.createDirectory();
236+
treeDeleter.deleteTree(staleTrash);
248237
} else {
249-
entry.delete();
238+
trashBase.createDirectory();
250239
}
240+
// We can delete other dirs asynchronously (if the flag is on).
241+
for (Path entry : sandboxBase.getDirectoryEntries()) {
242+
if (entry.getBaseName().equals(AsynchronousTreeDeleter.MOVED_TRASH_DIR)) {
243+
continue;
244+
}
245+
if (entry.getBaseName().equals(SandboxHelpers.INACCESSIBLE_HELPER_DIR)) {
246+
entry.deleteTree();
247+
} else if (entry.isDirectory()) {
248+
treeDeleter.deleteTree(entry);
249+
} else {
250+
entry.delete();
251+
}
252+
}
253+
} catch (IOException e) {
254+
// We have observed asynchronous deletion failing when running Bazel under Docker, see
255+
// #21719. Different RUN commands with `bazel build` will write to different layers in the
256+
// docker image. The overlay filesystem is different and the renaming of the directories
257+
// that we need to do for asynchronous deletion will fail. When that happens we fall back to
258+
// synchronous deletion here.
259+
sandboxBase.deleteTree();
251260
}
252261
}
253262
firstBuild = false;

0 commit comments

Comments
 (0)