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.
This commit is contained in:
Symphorien Gibol 2018-06-11 15:59:32 +02:00
parent de71335e4d
commit 8c567afe35

View file

@ -425,25 +425,28 @@ PathSet LocalStore::findRuntimeRoots()
readProcLink((format("%1%/%2%") % fdStr % fd_ent->d_name).str(), paths); 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); throw SysError(format("iterating /proc/%1%/fd") % ent->d_name);
}
fdDir.reset(); 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]);
}
try { 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 envString = readFile((format("/proc/%1%/environ") % ent->d_name).str(), true);
auto env_end = std::sregex_iterator{}; auto env_end = std::sregex_iterator{};
for (auto i = std::sregex_iterator{envString.begin(), envString.end(), storePathRegex}; i != env_end; ++i) for (auto i = std::sregex_iterator{envString.begin(), envString.end(), storePathRegex}; i != env_end; ++i)
paths.emplace(i->str()); paths.emplace(i->str());
} catch (SysError & e) { } catch (SysError & e) {
if (errno == ENOENT || errno == EACCES) if (errno == ENOENT || errno == EACCES || errno == ESRCH)
continue; continue;
throw; throw;
} }