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
 | 
			
		||||
       files. */
 | 
			
		||||
    DirEntries tempRootFiles = readDirectory(tempRootsDir);
 | 
			
		||||
| 
						 | 
				
			
			@ -253,6 +255,8 @@ void LocalStore::readTempRoots(PathSet & tempRoots, FDs & fds)
 | 
			
		|||
 | 
			
		||||
        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;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -326,6 +330,27 @@ Roots LocalStore::findRoots()
 | 
			
		|||
        findRoots(stateDir + "/manifests", 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -369,8 +394,9 @@ static void readFileRoots(const char * path, StringSet & paths)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LocalStore::findRuntimeRoots(PathSet & roots)
 | 
			
		||||
PathSet LocalStore::findRuntimeRoots()
 | 
			
		||||
{
 | 
			
		||||
    PathSet roots;
 | 
			
		||||
    StringSet paths;
 | 
			
		||||
    auto procDir = AutoCloseDir{opendir("/proc")};
 | 
			
		||||
    if (procDir) {
 | 
			
		||||
| 
						 | 
				
			
			@ -454,6 +480,8 @@ void LocalStore::findRuntimeRoots(PathSet & roots)
 | 
			
		|||
                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)
 | 
			
		||||
{
 | 
			
		||||
    if (visited.find(path) != visited.end()) return false;
 | 
			
		||||
    if (visited.count(path)) return false;
 | 
			
		||||
 | 
			
		||||
    if (state.alive.find(path) != state.alive.end()) {
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
    if (state.alive.count(path)) return true;
 | 
			
		||||
 | 
			
		||||
    if (state.dead.find(path) != state.dead.end()) {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    if (state.dead.count(path)) 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);
 | 
			
		||||
        state.alive.insert(path);
 | 
			
		||||
        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
 | 
			
		||||
       permanent roots cannot increase now. */
 | 
			
		||||
    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);
 | 
			
		||||
 | 
			
		||||
    /* 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
 | 
			
		||||
       per-process temporary root files.  So after this point no paths
 | 
			
		||||
       can be added to the set of temporary roots. */
 | 
			
		||||
    FDs fds;
 | 
			
		||||
    readTempRoots(state.tempRoots, fds);
 | 
			
		||||
    state.tempRoots = readTempRoots(fds);
 | 
			
		||||
    state.roots.insert(state.tempRoots.begin(), state.tempRoots.end());
 | 
			
		||||
 | 
			
		||||
    /* After this point the set of roots or temporary roots cannot
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -176,7 +176,7 @@ private:
 | 
			
		|||
    typedef std::shared_ptr<AutoCloseFD> FDPtr;
 | 
			
		||||
    typedef list<FDPtr> FDs;
 | 
			
		||||
 | 
			
		||||
    void readTempRoots(PathSet & tempRoots, FDs & fds);
 | 
			
		||||
    PathSet readTempRoots(FDs & fds);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -261,7 +261,9 @@ private:
 | 
			
		|||
 | 
			
		||||
    void findRoots(const Path & path, unsigned char type, Roots & roots);
 | 
			
		||||
 | 
			
		||||
    void findRuntimeRoots(PathSet & roots);
 | 
			
		||||
    Roots findRootsNoTemp();
 | 
			
		||||
 | 
			
		||||
    PathSet findRuntimeRoots();
 | 
			
		||||
 | 
			
		||||
    void removeUnusedLinks(const GCState & state);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue