nix-store -q --roots / --gc --print-roots: Print temporary / in-memory roots
For example, $ nix-store -q --roots /nix/store/7phd2sav7068nivgvmj2vpm3v47fd27l-patchelf-0.8pre845_0315148 {temp:1} denotes that the path is only being kept alive by a temporary root (i.e. /nix/var/nix/temproots/). Similarly, $ nix-store --gc --print-roots ... {memory:9} -> /nix/store/094gpjn9f15ip17wzxhma4r51nvsj17p-curl-7.53.1 shows that curl is being used by some process.
This commit is contained in:
parent
970366266b
commit
da1e4fdfb5
2 changed files with 41 additions and 22 deletions
|
@ -196,8 +196,10 @@ void LocalStore::addTempRoot(const Path & path)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LocalStore::readTempRoots(PathSet & tempRoots, FDs & fds)
|
PathSet LocalStore::readTempRoots(FDs & fds)
|
||||||
{
|
{
|
||||||
|
PathSet tempRoots;
|
||||||
|
|
||||||
/* Read the `temproots' directory for per-process temporary root
|
/* Read the `temproots' directory for per-process temporary root
|
||||||
files. */
|
files. */
|
||||||
DirEntries tempRootFiles = readDirectory(tempRootsDir);
|
DirEntries tempRootFiles = readDirectory(tempRootsDir);
|
||||||
|
@ -253,6 +255,8 @@ void LocalStore::readTempRoots(PathSet & tempRoots, FDs & fds)
|
||||||
|
|
||||||
fds.push_back(fd); /* keep open */
|
fds.push_back(fd); /* keep open */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return tempRoots;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -316,7 +320,7 @@ void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Roots LocalStore::findRoots()
|
Roots LocalStore::findRootsNoTemp()
|
||||||
{
|
{
|
||||||
Roots roots;
|
Roots roots;
|
||||||
|
|
||||||
|
@ -326,6 +330,27 @@ Roots LocalStore::findRoots()
|
||||||
findRoots(stateDir + "/manifests", DT_UNKNOWN, roots);
|
findRoots(stateDir + "/manifests", DT_UNKNOWN, roots);
|
||||||
findRoots(stateDir + "/profiles", DT_UNKNOWN, roots);
|
findRoots(stateDir + "/profiles", DT_UNKNOWN, roots);
|
||||||
|
|
||||||
|
/* Add additional roots returned by the program specified by the
|
||||||
|
NIX_ROOT_FINDER environment variable. This is typically used
|
||||||
|
to add running programs to the set of roots (to prevent them
|
||||||
|
from being garbage collected). */
|
||||||
|
size_t n = 0;
|
||||||
|
for (auto & root : findRuntimeRoots())
|
||||||
|
roots[fmt("{memory:%d}", n++)] = root;
|
||||||
|
|
||||||
|
return roots;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Roots LocalStore::findRoots()
|
||||||
|
{
|
||||||
|
Roots roots = findRootsNoTemp();
|
||||||
|
|
||||||
|
FDs fds;
|
||||||
|
size_t n = 0;
|
||||||
|
for (auto & root : readTempRoots(fds))
|
||||||
|
roots[fmt("{temp:%d}", n++)] = root;
|
||||||
|
|
||||||
return roots;
|
return roots;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,8 +394,9 @@ static void readFileRoots(const char * path, StringSet & paths)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocalStore::findRuntimeRoots(PathSet & roots)
|
PathSet LocalStore::findRuntimeRoots()
|
||||||
{
|
{
|
||||||
|
PathSet roots;
|
||||||
StringSet paths;
|
StringSet paths;
|
||||||
auto procDir = AutoCloseDir{opendir("/proc")};
|
auto procDir = AutoCloseDir{opendir("/proc")};
|
||||||
if (procDir) {
|
if (procDir) {
|
||||||
|
@ -454,6 +480,8 @@ void LocalStore::findRuntimeRoots(PathSet & roots)
|
||||||
roots.insert(path);
|
roots.insert(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return roots;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -554,17 +582,13 @@ void LocalStore::deletePathRecursive(GCState & state, const Path & path)
|
||||||
|
|
||||||
bool LocalStore::canReachRoot(GCState & state, PathSet & visited, const Path & path)
|
bool LocalStore::canReachRoot(GCState & state, PathSet & visited, const Path & path)
|
||||||
{
|
{
|
||||||
if (visited.find(path) != visited.end()) return false;
|
if (visited.count(path)) return false;
|
||||||
|
|
||||||
if (state.alive.find(path) != state.alive.end()) {
|
if (state.alive.count(path)) return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.dead.find(path) != state.dead.end()) {
|
if (state.dead.count(path)) return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.roots.find(path) != state.roots.end()) {
|
if (state.roots.count(path)) {
|
||||||
debug(format("cannot delete '%1%' because it's a root") % path);
|
debug(format("cannot delete '%1%' because it's a root") % path);
|
||||||
state.alive.insert(path);
|
state.alive.insert(path);
|
||||||
return true;
|
return true;
|
||||||
|
@ -724,22 +748,15 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||||
/* Find the roots. Since we've grabbed the GC lock, the set of
|
/* Find the roots. Since we've grabbed the GC lock, the set of
|
||||||
permanent roots cannot increase now. */
|
permanent roots cannot increase now. */
|
||||||
printError(format("finding garbage collector roots..."));
|
printError(format("finding garbage collector roots..."));
|
||||||
Roots rootMap = options.ignoreLiveness ? Roots() : findRoots();
|
Roots rootMap = options.ignoreLiveness ? Roots() : findRootsNoTemp();
|
||||||
|
|
||||||
for (auto & i : rootMap) state.roots.insert(i.second);
|
for (auto & i : rootMap) state.roots.insert(i.second);
|
||||||
|
|
||||||
/* Add additional roots returned by the program specified by the
|
|
||||||
NIX_ROOT_FINDER environment variable. This is typically used
|
|
||||||
to add running programs to the set of roots (to prevent them
|
|
||||||
from being garbage collected). */
|
|
||||||
if (!options.ignoreLiveness)
|
|
||||||
findRuntimeRoots(state.roots);
|
|
||||||
|
|
||||||
/* Read the temporary roots. This acquires read locks on all
|
/* Read the temporary roots. This acquires read locks on all
|
||||||
per-process temporary root files. So after this point no paths
|
per-process temporary root files. So after this point no paths
|
||||||
can be added to the set of temporary roots. */
|
can be added to the set of temporary roots. */
|
||||||
FDs fds;
|
FDs fds;
|
||||||
readTempRoots(state.tempRoots, fds);
|
state.tempRoots = readTempRoots(fds);
|
||||||
state.roots.insert(state.tempRoots.begin(), state.tempRoots.end());
|
state.roots.insert(state.tempRoots.begin(), state.tempRoots.end());
|
||||||
|
|
||||||
/* After this point the set of roots or temporary roots cannot
|
/* After this point the set of roots or temporary roots cannot
|
||||||
|
|
|
@ -176,7 +176,7 @@ private:
|
||||||
typedef std::shared_ptr<AutoCloseFD> FDPtr;
|
typedef std::shared_ptr<AutoCloseFD> FDPtr;
|
||||||
typedef list<FDPtr> FDs;
|
typedef list<FDPtr> FDs;
|
||||||
|
|
||||||
void readTempRoots(PathSet & tempRoots, FDs & fds);
|
PathSet readTempRoots(FDs & fds);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -261,7 +261,9 @@ private:
|
||||||
|
|
||||||
void findRoots(const Path & path, unsigned char type, Roots & roots);
|
void findRoots(const Path & path, unsigned char type, Roots & roots);
|
||||||
|
|
||||||
void findRuntimeRoots(PathSet & roots);
|
Roots findRootsNoTemp();
|
||||||
|
|
||||||
|
PathSet findRuntimeRoots();
|
||||||
|
|
||||||
void removeUnusedLinks(const GCState & state);
|
void removeUnusedLinks(const GCState & state);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue