2014-12-17 23:00:42 +01:00
|
|
|
#include "misc.hh"
|
2025-06-29 10:21:12 +03:00
|
|
|
#include <math.h>
|
2014-12-17 23:00:42 +01:00
|
|
|
#include "store-api.hh"
|
|
|
|
|
#include "local-store.hh"
|
|
|
|
|
#include "globals.hh"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace nix {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Derivation derivationFromPath(StoreAPI & store, const Path & drvPath)
|
|
|
|
|
{
|
|
|
|
|
assertStorePath(drvPath);
|
|
|
|
|
store.ensurePath(drvPath);
|
2015-01-04 23:27:34 +01:00
|
|
|
return readDerivation(drvPath);
|
2014-12-17 23:00:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void computeFSClosure(StoreAPI & store, const Path & path,
|
|
|
|
|
PathSet & paths, bool flipDirection, bool includeOutputs, bool includeDerivers)
|
|
|
|
|
{
|
|
|
|
|
if (paths.find(path) != paths.end()) return;
|
|
|
|
|
paths.insert(path);
|
|
|
|
|
|
|
|
|
|
PathSet edges;
|
|
|
|
|
|
|
|
|
|
if (flipDirection) {
|
|
|
|
|
store.queryReferrers(path, edges);
|
|
|
|
|
|
|
|
|
|
if (includeOutputs) {
|
|
|
|
|
PathSet derivers = store.queryValidDerivers(path);
|
daemon: Remove ‘foreach’ and ‘foreach_reverse’
‘foreach_reverse’ is not used anywhere
* nix/libutil/util.hh (foreach, foreach_reverse): Remove.
* nix/libstore/build.cc (addToWeakGoals): Use ‘std::none_of’ instead of macro ‘foreach’.
(Goal::waiteeDone, Goal::amDone, UserLock::acquire, rewriteHashes,
DerivationGoal::addWantedOutputs, DerivationGoal::haveDerivation,
DerivationGoal::outputsSubstituted, DerivationGoal::repairClosure,
DerivationGoal::inputsRealised, DerivationGoal::tryToBuild,
DerivationGoal::buildDone, DerivationGoal::tryBuildHook,
DerivationGoal::startBuilder, DerivationGoal::runChild,
parseReferenceSpecifiers, DerivationGoal::registerOutputs,
DerivationGoal::checkPathValidity, SubstitutionGoal::tryNext,
SubstitutionGoal::referencesValid, Worker::removeGoal,
Worker::childTerminated, Worker::run, Worker::waitForInput): Use range-based
‘for’ instead of macro ‘foreach’.
* nix/libstore/derivations.cc (writeDerivation, unparseDerivation,
hashDerivationModulo): Likewise.
* nix/libstore/gc.cc (addAdditionalRoots, LocalStore::deletePathRecursive,
LocalStore::canReachRoot, LocalStore::collectGarbage): Likewise.
* nix/libstore/globals.cc (Settings::pack): Likewise.
* nix/libstore/local-store.cc (checkDerivationOutputs, queryValidPaths,
querySubstitutablePaths, querySubstitutablePathInfos, registerValidPaths, verifyStore,
verifyPath): Likewise.
* nix/libstore/misc.cc (computeFSClosure, dfsVisit, topoSortPaths): Likewise.
* nix/libstore/optimise-store.cc (LocalStore::optimisePath_, LocalStore::optimiseStore): Likewise.
* nix/libstore/pathlocks.cc (PathLocks::lockPaths, PathLocks::~PathLocks): Likewise.
* nix/libstore/references.cc (search, scanForReferences): Likewise.
* nix/libstore/store-api.cc (checkStoreName, computeStorePathForText,
StoreAPI::makeValidityRegistration, showPaths, readStorePaths): Likewise.
* nix/libutil/serialise.cc (writeStrings): Likewise.
* nix/libutil/util.cc (concatStringsSep): Likewise.
* nix/nix-daemon/nix-daemon.cc (performOp): Likewise.
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2025-05-29 23:46:21 +08:00
|
|
|
for (auto& i : derivers)
|
|
|
|
|
edges.insert(i);
|
2014-12-17 23:00:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (includeDerivers && isDerivation(path)) {
|
|
|
|
|
PathSet outputs = store.queryDerivationOutputs(path);
|
daemon: Remove ‘foreach’ and ‘foreach_reverse’
‘foreach_reverse’ is not used anywhere
* nix/libutil/util.hh (foreach, foreach_reverse): Remove.
* nix/libstore/build.cc (addToWeakGoals): Use ‘std::none_of’ instead of macro ‘foreach’.
(Goal::waiteeDone, Goal::amDone, UserLock::acquire, rewriteHashes,
DerivationGoal::addWantedOutputs, DerivationGoal::haveDerivation,
DerivationGoal::outputsSubstituted, DerivationGoal::repairClosure,
DerivationGoal::inputsRealised, DerivationGoal::tryToBuild,
DerivationGoal::buildDone, DerivationGoal::tryBuildHook,
DerivationGoal::startBuilder, DerivationGoal::runChild,
parseReferenceSpecifiers, DerivationGoal::registerOutputs,
DerivationGoal::checkPathValidity, SubstitutionGoal::tryNext,
SubstitutionGoal::referencesValid, Worker::removeGoal,
Worker::childTerminated, Worker::run, Worker::waitForInput): Use range-based
‘for’ instead of macro ‘foreach’.
* nix/libstore/derivations.cc (writeDerivation, unparseDerivation,
hashDerivationModulo): Likewise.
* nix/libstore/gc.cc (addAdditionalRoots, LocalStore::deletePathRecursive,
LocalStore::canReachRoot, LocalStore::collectGarbage): Likewise.
* nix/libstore/globals.cc (Settings::pack): Likewise.
* nix/libstore/local-store.cc (checkDerivationOutputs, queryValidPaths,
querySubstitutablePaths, querySubstitutablePathInfos, registerValidPaths, verifyStore,
verifyPath): Likewise.
* nix/libstore/misc.cc (computeFSClosure, dfsVisit, topoSortPaths): Likewise.
* nix/libstore/optimise-store.cc (LocalStore::optimisePath_, LocalStore::optimiseStore): Likewise.
* nix/libstore/pathlocks.cc (PathLocks::lockPaths, PathLocks::~PathLocks): Likewise.
* nix/libstore/references.cc (search, scanForReferences): Likewise.
* nix/libstore/store-api.cc (checkStoreName, computeStorePathForText,
StoreAPI::makeValidityRegistration, showPaths, readStorePaths): Likewise.
* nix/libutil/serialise.cc (writeStrings): Likewise.
* nix/libutil/util.cc (concatStringsSep): Likewise.
* nix/nix-daemon/nix-daemon.cc (performOp): Likewise.
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2025-05-29 23:46:21 +08:00
|
|
|
for (auto& i : outputs)
|
|
|
|
|
if (store.isValidPath(i) && store.queryDeriver(i) == path)
|
|
|
|
|
edges.insert(i);
|
2014-12-17 23:00:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
store.queryReferences(path, edges);
|
|
|
|
|
|
|
|
|
|
if (includeOutputs && isDerivation(path)) {
|
|
|
|
|
PathSet outputs = store.queryDerivationOutputs(path);
|
daemon: Remove ‘foreach’ and ‘foreach_reverse’
‘foreach_reverse’ is not used anywhere
* nix/libutil/util.hh (foreach, foreach_reverse): Remove.
* nix/libstore/build.cc (addToWeakGoals): Use ‘std::none_of’ instead of macro ‘foreach’.
(Goal::waiteeDone, Goal::amDone, UserLock::acquire, rewriteHashes,
DerivationGoal::addWantedOutputs, DerivationGoal::haveDerivation,
DerivationGoal::outputsSubstituted, DerivationGoal::repairClosure,
DerivationGoal::inputsRealised, DerivationGoal::tryToBuild,
DerivationGoal::buildDone, DerivationGoal::tryBuildHook,
DerivationGoal::startBuilder, DerivationGoal::runChild,
parseReferenceSpecifiers, DerivationGoal::registerOutputs,
DerivationGoal::checkPathValidity, SubstitutionGoal::tryNext,
SubstitutionGoal::referencesValid, Worker::removeGoal,
Worker::childTerminated, Worker::run, Worker::waitForInput): Use range-based
‘for’ instead of macro ‘foreach’.
* nix/libstore/derivations.cc (writeDerivation, unparseDerivation,
hashDerivationModulo): Likewise.
* nix/libstore/gc.cc (addAdditionalRoots, LocalStore::deletePathRecursive,
LocalStore::canReachRoot, LocalStore::collectGarbage): Likewise.
* nix/libstore/globals.cc (Settings::pack): Likewise.
* nix/libstore/local-store.cc (checkDerivationOutputs, queryValidPaths,
querySubstitutablePaths, querySubstitutablePathInfos, registerValidPaths, verifyStore,
verifyPath): Likewise.
* nix/libstore/misc.cc (computeFSClosure, dfsVisit, topoSortPaths): Likewise.
* nix/libstore/optimise-store.cc (LocalStore::optimisePath_, LocalStore::optimiseStore): Likewise.
* nix/libstore/pathlocks.cc (PathLocks::lockPaths, PathLocks::~PathLocks): Likewise.
* nix/libstore/references.cc (search, scanForReferences): Likewise.
* nix/libstore/store-api.cc (checkStoreName, computeStorePathForText,
StoreAPI::makeValidityRegistration, showPaths, readStorePaths): Likewise.
* nix/libutil/serialise.cc (writeStrings): Likewise.
* nix/libutil/util.cc (concatStringsSep): Likewise.
* nix/nix-daemon/nix-daemon.cc (performOp): Likewise.
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2025-05-29 23:46:21 +08:00
|
|
|
for (auto& i : outputs)
|
|
|
|
|
if (store.isValidPath(i)) edges.insert(i);
|
2014-12-17 23:00:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (includeDerivers) {
|
|
|
|
|
Path deriver = store.queryDeriver(path);
|
|
|
|
|
if (store.isValidPath(deriver)) edges.insert(deriver);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
daemon: Remove ‘foreach’ and ‘foreach_reverse’
‘foreach_reverse’ is not used anywhere
* nix/libutil/util.hh (foreach, foreach_reverse): Remove.
* nix/libstore/build.cc (addToWeakGoals): Use ‘std::none_of’ instead of macro ‘foreach’.
(Goal::waiteeDone, Goal::amDone, UserLock::acquire, rewriteHashes,
DerivationGoal::addWantedOutputs, DerivationGoal::haveDerivation,
DerivationGoal::outputsSubstituted, DerivationGoal::repairClosure,
DerivationGoal::inputsRealised, DerivationGoal::tryToBuild,
DerivationGoal::buildDone, DerivationGoal::tryBuildHook,
DerivationGoal::startBuilder, DerivationGoal::runChild,
parseReferenceSpecifiers, DerivationGoal::registerOutputs,
DerivationGoal::checkPathValidity, SubstitutionGoal::tryNext,
SubstitutionGoal::referencesValid, Worker::removeGoal,
Worker::childTerminated, Worker::run, Worker::waitForInput): Use range-based
‘for’ instead of macro ‘foreach’.
* nix/libstore/derivations.cc (writeDerivation, unparseDerivation,
hashDerivationModulo): Likewise.
* nix/libstore/gc.cc (addAdditionalRoots, LocalStore::deletePathRecursive,
LocalStore::canReachRoot, LocalStore::collectGarbage): Likewise.
* nix/libstore/globals.cc (Settings::pack): Likewise.
* nix/libstore/local-store.cc (checkDerivationOutputs, queryValidPaths,
querySubstitutablePaths, querySubstitutablePathInfos, registerValidPaths, verifyStore,
verifyPath): Likewise.
* nix/libstore/misc.cc (computeFSClosure, dfsVisit, topoSortPaths): Likewise.
* nix/libstore/optimise-store.cc (LocalStore::optimisePath_, LocalStore::optimiseStore): Likewise.
* nix/libstore/pathlocks.cc (PathLocks::lockPaths, PathLocks::~PathLocks): Likewise.
* nix/libstore/references.cc (search, scanForReferences): Likewise.
* nix/libstore/store-api.cc (checkStoreName, computeStorePathForText,
StoreAPI::makeValidityRegistration, showPaths, readStorePaths): Likewise.
* nix/libutil/serialise.cc (writeStrings): Likewise.
* nix/libutil/util.cc (concatStringsSep): Likewise.
* nix/nix-daemon/nix-daemon.cc (performOp): Likewise.
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2025-05-29 23:46:21 +08:00
|
|
|
for (auto& i : edges)
|
|
|
|
|
computeFSClosure(store, i, paths, flipDirection, includeOutputs, includeDerivers);
|
2014-12-17 23:00:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void dfsVisit(StoreAPI & store, const PathSet & paths,
|
|
|
|
|
const Path & path, PathSet & visited, Paths & sorted,
|
|
|
|
|
PathSet & parents)
|
|
|
|
|
{
|
|
|
|
|
if (parents.find(path) != parents.end())
|
|
|
|
|
throw BuildError(format("cycle detected in the references of `%1%'") % path);
|
|
|
|
|
|
|
|
|
|
if (visited.find(path) != visited.end()) return;
|
|
|
|
|
visited.insert(path);
|
|
|
|
|
parents.insert(path);
|
|
|
|
|
|
|
|
|
|
PathSet references;
|
|
|
|
|
if (store.isValidPath(path))
|
|
|
|
|
store.queryReferences(path, references);
|
|
|
|
|
|
daemon: Remove ‘foreach’ and ‘foreach_reverse’
‘foreach_reverse’ is not used anywhere
* nix/libutil/util.hh (foreach, foreach_reverse): Remove.
* nix/libstore/build.cc (addToWeakGoals): Use ‘std::none_of’ instead of macro ‘foreach’.
(Goal::waiteeDone, Goal::amDone, UserLock::acquire, rewriteHashes,
DerivationGoal::addWantedOutputs, DerivationGoal::haveDerivation,
DerivationGoal::outputsSubstituted, DerivationGoal::repairClosure,
DerivationGoal::inputsRealised, DerivationGoal::tryToBuild,
DerivationGoal::buildDone, DerivationGoal::tryBuildHook,
DerivationGoal::startBuilder, DerivationGoal::runChild,
parseReferenceSpecifiers, DerivationGoal::registerOutputs,
DerivationGoal::checkPathValidity, SubstitutionGoal::tryNext,
SubstitutionGoal::referencesValid, Worker::removeGoal,
Worker::childTerminated, Worker::run, Worker::waitForInput): Use range-based
‘for’ instead of macro ‘foreach’.
* nix/libstore/derivations.cc (writeDerivation, unparseDerivation,
hashDerivationModulo): Likewise.
* nix/libstore/gc.cc (addAdditionalRoots, LocalStore::deletePathRecursive,
LocalStore::canReachRoot, LocalStore::collectGarbage): Likewise.
* nix/libstore/globals.cc (Settings::pack): Likewise.
* nix/libstore/local-store.cc (checkDerivationOutputs, queryValidPaths,
querySubstitutablePaths, querySubstitutablePathInfos, registerValidPaths, verifyStore,
verifyPath): Likewise.
* nix/libstore/misc.cc (computeFSClosure, dfsVisit, topoSortPaths): Likewise.
* nix/libstore/optimise-store.cc (LocalStore::optimisePath_, LocalStore::optimiseStore): Likewise.
* nix/libstore/pathlocks.cc (PathLocks::lockPaths, PathLocks::~PathLocks): Likewise.
* nix/libstore/references.cc (search, scanForReferences): Likewise.
* nix/libstore/store-api.cc (checkStoreName, computeStorePathForText,
StoreAPI::makeValidityRegistration, showPaths, readStorePaths): Likewise.
* nix/libutil/serialise.cc (writeStrings): Likewise.
* nix/libutil/util.cc (concatStringsSep): Likewise.
* nix/nix-daemon/nix-daemon.cc (performOp): Likewise.
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2025-05-29 23:46:21 +08:00
|
|
|
for (auto& i : references)
|
2014-12-17 23:00:42 +01:00
|
|
|
/* Don't traverse into paths that don't exist. That can
|
|
|
|
|
happen due to substitutes for non-existent paths. */
|
daemon: Remove ‘foreach’ and ‘foreach_reverse’
‘foreach_reverse’ is not used anywhere
* nix/libutil/util.hh (foreach, foreach_reverse): Remove.
* nix/libstore/build.cc (addToWeakGoals): Use ‘std::none_of’ instead of macro ‘foreach’.
(Goal::waiteeDone, Goal::amDone, UserLock::acquire, rewriteHashes,
DerivationGoal::addWantedOutputs, DerivationGoal::haveDerivation,
DerivationGoal::outputsSubstituted, DerivationGoal::repairClosure,
DerivationGoal::inputsRealised, DerivationGoal::tryToBuild,
DerivationGoal::buildDone, DerivationGoal::tryBuildHook,
DerivationGoal::startBuilder, DerivationGoal::runChild,
parseReferenceSpecifiers, DerivationGoal::registerOutputs,
DerivationGoal::checkPathValidity, SubstitutionGoal::tryNext,
SubstitutionGoal::referencesValid, Worker::removeGoal,
Worker::childTerminated, Worker::run, Worker::waitForInput): Use range-based
‘for’ instead of macro ‘foreach’.
* nix/libstore/derivations.cc (writeDerivation, unparseDerivation,
hashDerivationModulo): Likewise.
* nix/libstore/gc.cc (addAdditionalRoots, LocalStore::deletePathRecursive,
LocalStore::canReachRoot, LocalStore::collectGarbage): Likewise.
* nix/libstore/globals.cc (Settings::pack): Likewise.
* nix/libstore/local-store.cc (checkDerivationOutputs, queryValidPaths,
querySubstitutablePaths, querySubstitutablePathInfos, registerValidPaths, verifyStore,
verifyPath): Likewise.
* nix/libstore/misc.cc (computeFSClosure, dfsVisit, topoSortPaths): Likewise.
* nix/libstore/optimise-store.cc (LocalStore::optimisePath_, LocalStore::optimiseStore): Likewise.
* nix/libstore/pathlocks.cc (PathLocks::lockPaths, PathLocks::~PathLocks): Likewise.
* nix/libstore/references.cc (search, scanForReferences): Likewise.
* nix/libstore/store-api.cc (checkStoreName, computeStorePathForText,
StoreAPI::makeValidityRegistration, showPaths, readStorePaths): Likewise.
* nix/libutil/serialise.cc (writeStrings): Likewise.
* nix/libutil/util.cc (concatStringsSep): Likewise.
* nix/nix-daemon/nix-daemon.cc (performOp): Likewise.
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2025-05-29 23:46:21 +08:00
|
|
|
if (i != path && paths.find(i) != paths.end())
|
|
|
|
|
dfsVisit(store, paths, i, visited, sorted, parents);
|
2014-12-17 23:00:42 +01:00
|
|
|
|
|
|
|
|
sorted.push_front(path);
|
|
|
|
|
parents.erase(path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Paths topoSortPaths(StoreAPI & store, const PathSet & paths)
|
|
|
|
|
{
|
|
|
|
|
Paths sorted;
|
|
|
|
|
PathSet visited, parents;
|
daemon: Remove ‘foreach’ and ‘foreach_reverse’
‘foreach_reverse’ is not used anywhere
* nix/libutil/util.hh (foreach, foreach_reverse): Remove.
* nix/libstore/build.cc (addToWeakGoals): Use ‘std::none_of’ instead of macro ‘foreach’.
(Goal::waiteeDone, Goal::amDone, UserLock::acquire, rewriteHashes,
DerivationGoal::addWantedOutputs, DerivationGoal::haveDerivation,
DerivationGoal::outputsSubstituted, DerivationGoal::repairClosure,
DerivationGoal::inputsRealised, DerivationGoal::tryToBuild,
DerivationGoal::buildDone, DerivationGoal::tryBuildHook,
DerivationGoal::startBuilder, DerivationGoal::runChild,
parseReferenceSpecifiers, DerivationGoal::registerOutputs,
DerivationGoal::checkPathValidity, SubstitutionGoal::tryNext,
SubstitutionGoal::referencesValid, Worker::removeGoal,
Worker::childTerminated, Worker::run, Worker::waitForInput): Use range-based
‘for’ instead of macro ‘foreach’.
* nix/libstore/derivations.cc (writeDerivation, unparseDerivation,
hashDerivationModulo): Likewise.
* nix/libstore/gc.cc (addAdditionalRoots, LocalStore::deletePathRecursive,
LocalStore::canReachRoot, LocalStore::collectGarbage): Likewise.
* nix/libstore/globals.cc (Settings::pack): Likewise.
* nix/libstore/local-store.cc (checkDerivationOutputs, queryValidPaths,
querySubstitutablePaths, querySubstitutablePathInfos, registerValidPaths, verifyStore,
verifyPath): Likewise.
* nix/libstore/misc.cc (computeFSClosure, dfsVisit, topoSortPaths): Likewise.
* nix/libstore/optimise-store.cc (LocalStore::optimisePath_, LocalStore::optimiseStore): Likewise.
* nix/libstore/pathlocks.cc (PathLocks::lockPaths, PathLocks::~PathLocks): Likewise.
* nix/libstore/references.cc (search, scanForReferences): Likewise.
* nix/libstore/store-api.cc (checkStoreName, computeStorePathForText,
StoreAPI::makeValidityRegistration, showPaths, readStorePaths): Likewise.
* nix/libutil/serialise.cc (writeStrings): Likewise.
* nix/libutil/util.cc (concatStringsSep): Likewise.
* nix/nix-daemon/nix-daemon.cc (performOp): Likewise.
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
2025-05-29 23:46:21 +08:00
|
|
|
for (const auto& i : paths)
|
|
|
|
|
dfsVisit(store, paths, i, visited, sorted, parents);
|
2014-12-17 23:00:42 +01:00
|
|
|
return sorted;
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-29 10:21:12 +03:00
|
|
|
/* Max of LLONG_MAX is 8 EiB */
|
|
|
|
|
string showBytes(long long bytes)
|
|
|
|
|
{
|
|
|
|
|
if (llabs(bytes > exp2l(60))) {
|
|
|
|
|
return (format("%7.2f EiB") % (bytes / exp2l(60))).str();
|
|
|
|
|
} else if (llabs(bytes > exp2l(50))) {
|
|
|
|
|
return (format("%7.2f PiB") % (bytes / exp2l(50))).str();
|
|
|
|
|
} else if (llabs(bytes > exp2l(40))) {
|
|
|
|
|
return (format("%7.2f TiB") % (bytes / exp2l(40))).str();
|
|
|
|
|
} else if (llabs(bytes > exp2l(30))) {
|
|
|
|
|
return (format("%7.2f GiB") % (bytes / exp2l(30))).str();
|
|
|
|
|
} else if (llabs(bytes > exp2l(20))) {
|
|
|
|
|
return (format("%7.2f MiB") % (bytes / exp2l(20))).str();
|
|
|
|
|
} else if (llabs(bytes > exp2l(10))) {
|
|
|
|
|
return (format("%7.2f KiB") % (bytes / exp2l(10))).str();
|
|
|
|
|
} else {
|
|
|
|
|
return (format("%4f bytes") % bytes).str();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-17 23:00:42 +01:00
|
|
|
|
|
|
|
|
}
|