findRuntimeRoots: Simplify/fix handling of /proc files
Scanning of /proc/<pid>/{exe,cwd} was broken because '{memory:' was prepended twice. Also, get rid of the whole '{memory:...}' thing because it's unnecessary, we can just list the file in /proc directly.
This commit is contained in:
parent
115e2c8c67
commit
a3f37d87ea
2 changed files with 14 additions and 15 deletions
|
@ -362,8 +362,7 @@ try_again:
|
||||||
}
|
}
|
||||||
if (res > 0 && buf[0] == '/')
|
if (res > 0 && buf[0] == '/')
|
||||||
roots[std::string(static_cast<char *>(buf), res)]
|
roots[std::string(static_cast<char *>(buf), res)]
|
||||||
.emplace((format("{memory:%1%") % file).str());
|
.emplace(file);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static string quoteRegexChars(const string & raw)
|
static string quoteRegexChars(const string & raw)
|
||||||
|
@ -395,10 +394,10 @@ void LocalStore::findRuntimeRoots(Roots & roots)
|
||||||
while (errno = 0, ent = readdir(procDir.get())) {
|
while (errno = 0, ent = readdir(procDir.get())) {
|
||||||
checkInterrupt();
|
checkInterrupt();
|
||||||
if (std::regex_match(ent->d_name, digitsRegex)) {
|
if (std::regex_match(ent->d_name, digitsRegex)) {
|
||||||
readProcLink((format("{memory:/proc/%1%/exe}") % ent->d_name).str(), unchecked);
|
readProcLink(fmt("/proc/%s/exe" ,ent->d_name), unchecked);
|
||||||
readProcLink((format("{memory:/proc/%1%/cwd}") % ent->d_name).str(), unchecked);
|
readProcLink(fmt("/proc/%s/cwd", ent->d_name), unchecked);
|
||||||
|
|
||||||
auto fdStr = (format("/proc/%1%/fd") % ent->d_name).str();
|
auto fdStr = fmt("/proc/%s/fd", ent->d_name);
|
||||||
auto fdDir = AutoCloseDir(opendir(fdStr.c_str()));
|
auto fdDir = AutoCloseDir(opendir(fdStr.c_str()));
|
||||||
if (!fdDir) {
|
if (!fdDir) {
|
||||||
if (errno == ENOENT || errno == EACCES)
|
if (errno == ENOENT || errno == EACCES)
|
||||||
|
@ -407,9 +406,8 @@ void LocalStore::findRuntimeRoots(Roots & roots)
|
||||||
}
|
}
|
||||||
struct dirent * fd_ent;
|
struct dirent * fd_ent;
|
||||||
while (errno = 0, fd_ent = readdir(fdDir.get())) {
|
while (errno = 0, fd_ent = readdir(fdDir.get())) {
|
||||||
if (fd_ent->d_name[0] != '.') {
|
if (fd_ent->d_name[0] != '.')
|
||||||
readProcLink((format("%1%/%2%") % fdStr % fd_ent->d_name).str(), unchecked);
|
readProcLink(fmt("%s/%s", fdStr, fd_ent->d_name), unchecked);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (errno) {
|
if (errno) {
|
||||||
if (errno == ESRCH)
|
if (errno == ESRCH)
|
||||||
|
@ -419,19 +417,19 @@ void LocalStore::findRuntimeRoots(Roots & roots)
|
||||||
fdDir.reset();
|
fdDir.reset();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto mapFile = (format("/proc/%1%/maps") % ent->d_name).str();
|
auto mapFile = fmt("/proc/%s/maps", ent->d_name);
|
||||||
auto mapLines = tokenizeString<std::vector<string>>(readFile(mapFile, true), "\n");
|
auto mapLines = tokenizeString<std::vector<string>>(readFile(mapFile, true), "\n");
|
||||||
for (const auto & line : mapLines) {
|
for (const auto & line : mapLines) {
|
||||||
auto match = std::smatch{};
|
auto match = std::smatch{};
|
||||||
if (std::regex_match(line, match, mapRegex))
|
if (std::regex_match(line, match, mapRegex))
|
||||||
unchecked[match[1]].emplace((format("{memory:%1%}") % mapFile).str());
|
unchecked[match[1]].emplace(mapFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto envFile = (format("/proc/%1%/environ") % ent->d_name).str();
|
auto envFile = fmt("/proc/%s/environ", ent->d_name);
|
||||||
auto envString = readFile(envFile, true);
|
auto envString = readFile(envFile, 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)
|
||||||
unchecked[i->str()].emplace((format("{memory:%1%}") % envFile).str());
|
unchecked[i->str()].emplace(envFile);
|
||||||
} catch (SysError & e) {
|
} catch (SysError & e) {
|
||||||
if (errno == ENOENT || errno == EACCES || errno == ESRCH)
|
if (errno == ENOENT || errno == EACCES || errno == ESRCH)
|
||||||
continue;
|
continue;
|
||||||
|
@ -451,7 +449,7 @@ void LocalStore::findRuntimeRoots(Roots & roots)
|
||||||
for (const auto & line : lsofLines) {
|
for (const auto & line : lsofLines) {
|
||||||
std::smatch match;
|
std::smatch match;
|
||||||
if (std::regex_match(line, match, lsofRegex))
|
if (std::regex_match(line, match, lsofRegex))
|
||||||
unchecked[match[1]].emplace((format("{memory:%1%}" % LSOF).str());
|
unchecked[match[1]].emplace("{lsof}");
|
||||||
}
|
}
|
||||||
} catch (ExecError & e) {
|
} catch (ExecError & e) {
|
||||||
/* lsof not installed, lsof failed */
|
/* lsof not installed, lsof failed */
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <unordered_set>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
@ -47,7 +48,7 @@ const size_t storePathHashLen = 32; // i.e. 160 bits
|
||||||
const uint32_t exportMagic = 0x4558494e;
|
const uint32_t exportMagic = 0x4558494e;
|
||||||
|
|
||||||
|
|
||||||
typedef std::map<Path, std::set<std::string>> Roots;
|
typedef std::unordered_map<Path, std::unordered_set<std::string>> Roots;
|
||||||
|
|
||||||
|
|
||||||
struct GCOptions
|
struct GCOptions
|
||||||
|
|
Loading…
Reference in a new issue