about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSymphorien Gibol <symphorien+git@xlumurb.eu>2018-06-11T13·59+0200
committerSymphorien Gibol <symphorien+git@xlumurb.eu>2018-06-11T14·29+0200
commit8c567afe355dff8cb86dd15c94755eb6500f48cd (patch)
tree9bc2a74c4e9b1af2b7f22d517af6d0c4449b0690
parentde71335e4d7e5e7d63149b8d832878d163d13fd4 (diff)
libstore/gc.cc: ignore ESRCH when reading /proc
If a process disappears between the time /proc/[pid]/maps is opened and
the time it is read, the read() syscall will return ESRCH. This should be ignored.
-rw-r--r--src/libstore/gc.cc23
1 files changed, 13 insertions, 10 deletions
diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc
index ba49749d830a..233a70bd2d2a 100644
--- a/src/libstore/gc.cc
+++ b/src/libstore/gc.cc
@@ -425,25 +425,28 @@ PathSet LocalStore::findRuntimeRoots()
                         readProcLink((format("%1%/%2%") % fdStr % fd_ent->d_name).str(), paths);
                     }
                 }
-                if (errno)
+                if (errno) {
+                    if (errno == ESRCH)
+                        continue;
                     throw SysError(format("iterating /proc/%1%/fd") % ent->d_name);
-                fdDir.reset();
-
-                auto mapLines =
-                    tokenizeString<std::vector<string>>(readFile((format("/proc/%1%/maps") % ent->d_name).str(), true), "\n");
-                for (const auto& line : mapLines) {
-                    auto match = std::smatch{};
-                    if (std::regex_match(line, match, mapRegex))
-                        paths.emplace(match[1]);
                 }
+                fdDir.reset();
 
                 try {
+                    auto mapLines =
+                        tokenizeString<std::vector<string>>(readFile((format("/proc/%1%/maps") % ent->d_name).str(), true), "\n");
+                    for (const auto& line : mapLines) {
+                        auto match = std::smatch{};
+                        if (std::regex_match(line, match, mapRegex))
+                            paths.emplace(match[1]);
+                    }
+
                     auto envString = readFile((format("/proc/%1%/environ") % ent->d_name).str(), true);
                     auto env_end = std::sregex_iterator{};
                     for (auto i = std::sregex_iterator{envString.begin(), envString.end(), storePathRegex}; i != env_end; ++i)
                         paths.emplace(i->str());
                 } catch (SysError & e) {
-                    if (errno == ENOENT || errno == EACCES)
+                    if (errno == ENOENT || errno == EACCES || errno == ESRCH)
                         continue;
                     throw;
                 }