aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/gc.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2023-03-09 16:44:51 +0100
committerEelco Dolstra <edolstra@gmail.com>2023-03-09 16:44:51 +0100
commit4f3a4b732cdc8a0179b0da9cccafef0b215a4e86 (patch)
tree684d896b5d7aa15d376d8a867b57cbf98e9fce82 /src/libstore/gc.cc
parentc44750982d7a271c8444819377ab972af8946e5d (diff)
Make findRuntimeRoots() more resilient to disappearing processes
I saw this random failure in https://hydra.nixos.org/build/211811692: error: opening /proc/15307/fd: No such process while running nix-collect-garbage in a readfile-context.sh. This is because we're not handling ESRCH errors reading /proc/<pid>/fd. So just move the read inside the try/catch where we do handle it.
Diffstat (limited to 'src/libstore/gc.cc')
-rw-r--r--src/libstore/gc.cc44
1 files changed, 22 insertions, 22 deletions
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index 0aecc2d3b..0038ec802 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -371,29 +371,29 @@ void LocalStore::findRuntimeRoots(Roots & roots, bool censor)
while (errno = 0, ent = readdir(procDir.get())) {
checkInterrupt();
if (std::regex_match(ent->d_name, digitsRegex)) {
- readProcLink(fmt("/proc/%s/exe" ,ent->d_name), unchecked);
- readProcLink(fmt("/proc/%s/cwd", ent->d_name), unchecked);
-
- auto fdStr = fmt("/proc/%s/fd", ent->d_name);
- auto fdDir = AutoCloseDir(opendir(fdStr.c_str()));
- if (!fdDir) {
- if (errno == ENOENT || errno == EACCES)
- continue;
- throw SysError("opening %1%", fdStr);
- }
- struct dirent * fd_ent;
- while (errno = 0, fd_ent = readdir(fdDir.get())) {
- if (fd_ent->d_name[0] != '.')
- readProcLink(fmt("%s/%s", fdStr, fd_ent->d_name), unchecked);
- }
- if (errno) {
- if (errno == ESRCH)
- continue;
- throw SysError("iterating /proc/%1%/fd", ent->d_name);
- }
- fdDir.reset();
-
try {
+ readProcLink(fmt("/proc/%s/exe" ,ent->d_name), unchecked);
+ readProcLink(fmt("/proc/%s/cwd", ent->d_name), unchecked);
+
+ auto fdStr = fmt("/proc/%s/fd", ent->d_name);
+ auto fdDir = AutoCloseDir(opendir(fdStr.c_str()));
+ if (!fdDir) {
+ if (errno == ENOENT || errno == EACCES)
+ continue;
+ throw SysError("opening %1%", fdStr);
+ }
+ struct dirent * fd_ent;
+ while (errno = 0, fd_ent = readdir(fdDir.get())) {
+ if (fd_ent->d_name[0] != '.')
+ readProcLink(fmt("%s/%s", fdStr, fd_ent->d_name), unchecked);
+ }
+ if (errno) {
+ if (errno == ESRCH)
+ continue;
+ throw SysError("iterating /proc/%1%/fd", ent->d_name);
+ }
+ fdDir.reset();
+
auto mapFile = fmt("/proc/%s/maps", ent->d_name);
auto mapLines = tokenizeString<std::vector<std::string>>(readFile(mapFile), "\n");
for (const auto & line : mapLines) {