From ed25753501a7a3f77c097df01db299bdb60ede96 Mon Sep 17 00:00:00 2001 From: Daiderd Jordan Date: Wed, 26 Sep 2018 22:59:41 +0200 Subject: [PATCH] nix doctor: reimplement profile warning without gcroot check Calculating roots seems significantly slower on darwin compared to linux. Checking for /profile/ links could show some false positives but should still catch most issues. --- src/nix/doctor.cc | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/src/nix/doctor.cc b/src/nix/doctor.cc index 6112b1f65..b608b9d59 100644 --- a/src/nix/doctor.cc +++ b/src/nix/doctor.cc @@ -42,7 +42,8 @@ struct CmdDoctor : StoreCommand checkStoreProtocol(store->getProtocol()); } - void checkNixInPath() { + void checkNixInPath() + { PathSet dirs; for (auto & dir : tokenizeString(getEnv("PATH"), ":")) @@ -58,32 +59,29 @@ struct CmdDoctor : StoreCommand } } - void checkProfileRoots(ref store) { + void checkProfileRoots(ref store) + { PathSet dirs; - Roots roots = store->findRoots(); - for (auto & dir : tokenizeString(getEnv("PATH"), ":")) + for (auto & dir : tokenizeString(getEnv("PATH"), ":")) { + Path profileDir = dirOf(dir); try { - auto profileDir = canonPath(dirOf(dir), true); - if (hasSuffix(profileDir, "user-environment") && - store->isValidPath(profileDir)) { - PathSet referrers; - store->computeFSClosure({profileDir}, referrers, true, - settings.gcKeepOutputs, settings.gcKeepDerivations); - bool found = false; - for (auto & i : roots) - if (referrers.find(i.second) != referrers.end()) - found = true; - if (!found) - dirs.insert(dir); + Path userEnv = canonPath(profileDir, true); + if (store->isStorePath(userEnv) && hasSuffix(userEnv, "user-environment")) { + while (profileDir.find("/profiles/") == std::string::npos && isLink(profileDir)) + profileDir = absPath(readLink(profileDir), dirOf(profileDir)); + + if (profileDir.find("/profiles/") == std::string::npos) + dirs.insert(dir); } } catch (SysError &) {} + } if (!dirs.empty()) { - std::cout << "Warning: found profiles without a gcroot." << std::endl; - std::cout << "The generation this profile points to will be deleted with the next gc, resulting" << std::endl; - std::cout << "in broken symlinks. Make sure your profiles are in " << settings.nixStateDir << "/profiles." << std::endl; + std::cout << "Warning: found profiles outside of " << settings.nixStateDir << "/profiles." << std::endl; + std::cout << "The generation this profile points to might not have a gcroot and could be" << std::endl; + std::cout << "garbage collected, resulting in broken symlinks." << std::endl; std::cout << std::endl; for (auto & dir : dirs) std::cout << " " << dir << std::endl; @@ -91,7 +89,8 @@ struct CmdDoctor : StoreCommand } } - void checkStoreProtocol(unsigned int storeProto) { + void checkStoreProtocol(unsigned int storeProto) + { auto clientProto = GET_PROTOCOL_MAJOR(SERVE_PROTOCOL_VERSION) == GET_PROTOCOL_MAJOR(storeProto) ? SERVE_PROTOCOL_VERSION : PROTOCOL_VERSION;