1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-13 14:02:42 +01:00

gc: Also track the original roots

Will be required by `--print-roots` and friends
This commit is contained in:
Théophane Hufschmitt 2022-04-11 10:20:36 +02:00
parent c788718de1
commit 2e7f1d24a1

View file

@ -75,11 +75,20 @@ GlobalOpts parseCmdLine(int argc, char** argv)
return res; return res;
} }
/*
* A value of type `Roots` is a mapping from a store path to the set of roots that keep it alive
*/
typedef std::map<fs::path, std::set<fs::path>> Roots;
struct TraceResult { struct TraceResult {
set<fs::path> storeRoots; Roots storeRoots;
set<fs::path> deadLinks; set<fs::path> deadLinks;
}; };
bool isInStore(fs::path storeDir, fs::path dir)
{
return (std::search(dir.begin(), dir.end(), storeDir.begin(), storeDir.end()) == dir.begin());
}
void followPathToStore( void followPathToStore(
const GlobalOpts & opts, const GlobalOpts & opts,
int recursionsLeft, int recursionsLeft,
@ -92,11 +101,6 @@ void followPathToStore(
if (recursionsLeft < 0) if (recursionsLeft < 0)
return; return;
if (std::search(root.begin(), root.end(), opts.storeDir.begin(), opts.storeDir.end()) == root.begin()) {
res.storeRoots.insert(root);
return;
}
switch (status.type()) { switch (status.type()) {
case fs::file_type::directory: case fs::file_type::directory:
{ {
@ -117,7 +121,13 @@ void followPathToStore(
auto target_status = fs::symlink_status(target); auto target_status = fs::symlink_status(target);
if (target_status.type() == fs::file_type::not_found) if (target_status.type() == fs::file_type::not_found)
not_found("Not found"); not_found("Not found");
followPathToStore(opts, recursionsLeft - 1, res, target, target_status);
if (isInStore(opts.storeDir, target)) {
res.storeRoots[target].insert(root);
return;
} else {
followPathToStore(opts, recursionsLeft - 1, res, target, target_status);
}
} catch (fs::filesystem_error & e) { } catch (fs::filesystem_error & e) {
not_found(e.what()); not_found(e.what());
@ -127,7 +137,7 @@ void followPathToStore(
{ {
auto possibleStorePath = opts.storeDir / root.filename(); auto possibleStorePath = opts.storeDir / root.filename();
if (fs::exists(possibleStorePath)) if (fs::exists(possibleStorePath))
res.storeRoots.insert(possibleStorePath); res.storeRoots[possibleStorePath].insert(root);
} }
default: default:
break; break;
@ -176,8 +186,9 @@ int main(int argc, char * * argv)
opts.stateDir / fs::path("gcroots"), opts.stateDir / fs::path("gcroots"),
}; };
auto traceResult = followPathsToStore(opts, standardRoots); auto traceResult = followPathsToStore(opts, standardRoots);
for (auto & rootInStore : traceResult.storeRoots) { for (auto & [rootInStore, externalRoots] : traceResult.storeRoots) {
std::cout << rootInStore.string() << std::endl; for (auto & externalRoot : externalRoots)
std::cout << rootInStore.string() << '\t' << externalRoot.string() << std::endl;
} }
std::cout << std::endl; std::cout << std::endl;
for (auto & deadLink : traceResult.deadLinks) { for (auto & deadLink : traceResult.deadLinks) {