Skip to content

Commit 488b630

Browse files
oquenchilcopybara-github
authored andcommitted
Fix sandbox cleanup crashing after server restart
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 PiperOrigin-RevId: 617150522 Change-Id: I82a07ac0ade66cfb1e5732a90a5f3ab4e2e8caa7
1 parent f07c26e commit 488b630

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

Lines changed: 28 additions & 19 deletions
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)