diff options
author | Daiderd Jordan <daiderd@gmail.com> | 2018-09-26T20·59+0200 |
---|---|---|
committer | Daiderd Jordan <daiderd@gmail.com> | 2018-09-26T21·13+0200 |
commit | ed25753501a7a3f77c097df01db299bdb60ede96 (patch) | |
tree | 7dc75e29ea282760aa4aa1e6c2204a485852db26 /src/nix/doctor.cc | |
parent | 80a4b44d3d1bd35ab13d6b534f1015d15fdb08fd (diff) |
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.
Diffstat (limited to 'src/nix/doctor.cc')
-rw-r--r-- | src/nix/doctor.cc | 39 |
1 files changed, 19 insertions, 20 deletions
diff --git a/src/nix/doctor.cc b/src/nix/doctor.cc index 6112b1f650a0..b608b9d59efa 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<Strings>(getEnv("PATH"), ":")) @@ -58,32 +59,29 @@ struct CmdDoctor : StoreCommand } } - void checkProfileRoots(ref<Store> store) { + void checkProfileRoots(ref<Store> store) + { PathSet dirs; - Roots roots = store->findRoots(); - for (auto & dir : tokenizeString<Strings>(getEnv("PATH"), ":")) + for (auto & dir : tokenizeString<Strings>(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; |