diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2016-06-01T12·49+0200 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2016-06-01T14·24+0200 |
commit | 7850d3d27910c30232dd09dd86ee8afdaad26b90 (patch) | |
tree | da539f14d98d815e89b6ad60ed8e1e1ab9981cbf /src | |
parent | 1b5b654fe25cf7f2219ebe96a943397d683bfa0e (diff) |
Make the store directory a member variable of Store
Diffstat (limited to 'src')
33 files changed, 312 insertions, 292 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 5a6428ca6b6f..0833603b2a9e 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -341,7 +341,7 @@ Path EvalState::checkSourcePath(const Path & path_) /* To support import-from-derivation, allow access to anything in the store. FIXME: only allow access to paths that have been constructed by this evaluation. */ - if (isInStore(path)) return path; + if (store->isInStore(path)) return path; #if 0 /* Hack to support the chroot dependencies of corepkgs (see @@ -1517,7 +1517,7 @@ string EvalState::copyPathToStore(PathSet & context, const Path & path) dstPath = srcToStore[path]; else { dstPath = settings.readOnlyMode - ? computeStorePathForPath(checkSourcePath(path)).first + ? store->computeStorePathForPath(checkSourcePath(path)).first : store->addToStore(baseNameOf(path), checkSourcePath(path), true, htSHA256, defaultPathFilter, repair); srcToStore[path] = dstPath; printMsg(lvlChatty, format("copied source ‘%1%’ -> ‘%2%’") diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index d7245fca52e1..565ed69ae77b 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -50,7 +50,7 @@ void EvalState::realiseContext(const PathSet & context) for (auto & i : context) { std::pair<string, string> decoded = decodeContext(i); Path ctx = decoded.first; - assert(isStorePath(ctx)); + assert(store->isStorePath(ctx)); if (!store->isValidPath(ctx)) throw InvalidPathError(ctx); if (!decoded.second.empty() && nix::isDerivation(ctx)) @@ -82,7 +82,7 @@ static void prim_scopedImport(EvalState & state, const Pos & pos, Value * * args path = state.checkSourcePath(path); - if (isStorePath(path) && state.store->isValidPath(path) && isDerivation(path)) { + if (state.store->isStorePath(path) && state.store->isValidPath(path) && isDerivation(path)) { Derivation drv = readDerivation(path); Value & w = *state.allocValue(); state.mkAttrs(w, 3 + drv.outputs.size()); @@ -624,7 +624,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * outputHash = printHash(h); if (outputHashRecursive) outputHashAlgo = "r:" + outputHashAlgo; - Path outPath = makeFixedOutputPath(outputHashRecursive, ht, h, drvName); + Path outPath = state.store->makeFixedOutputPath(outputHashRecursive, ht, h, drvName); drv.env["out"] = outPath; drv.outputs["out"] = DerivationOutput(outPath, outputHashAlgo, outputHash); } @@ -646,7 +646,7 @@ static void prim_derivationStrict(EvalState & state, const Pos & pos, Value * * for (auto & i : drv.outputs) if (i.second.path == "") { - Path outPath = makeOutputPath(i.first, h, drvName); + Path outPath = state.store->makeOutputPath(i.first, h, drvName); drv.env[i.first] = outPath; i.second.path = outPath; } @@ -702,10 +702,10 @@ static void prim_storePath(EvalState & state, const Pos & pos, Value * * args, V /* Resolve symlinks in ‘path’, unless ‘path’ itself is a symlink directly in the store. The latter condition is necessary so e.g. nix-push does the right thing. */ - if (!isStorePath(path)) path = canonPath(path, true); - if (!isInStore(path)) + if (!state.store->isStorePath(path)) path = canonPath(path, true); + if (!state.store->isInStore(path)) throw EvalError(format("path ‘%1%’ is not in the Nix store, at %2%") % path % pos); - Path path2 = toStorePath(path); + Path path2 = state.store->toStorePath(path); if (!settings.readOnlyMode) state.store->ensurePath(path2); context.insert(path2); @@ -897,7 +897,7 @@ static void prim_toFile(EvalState & state, const Pos & pos, Value * * args, Valu } Path storePath = settings.readOnlyMode - ? computeStorePathForText(name, contents, refs) + ? state.store->computeStorePathForText(name, contents, refs) : state.store->addTextToStore(name, contents, refs, state.repair); /* Note: we don't need to add `context' to the context of the @@ -963,7 +963,7 @@ static void prim_filterSource(EvalState & state, const Pos & pos, Value * * args path = state.checkSourcePath(path); Path dstPath = settings.readOnlyMode - ? computeStorePathForPath(path, true, htSHA256, filter).first + ? state.store->computeStorePathForPath(path, true, htSHA256, filter).first : state.store->addToStore(baseNameOf(path), path, true, htSHA256, filter, state.repair); mkString(v, dstPath, {dstPath}); @@ -1765,7 +1765,7 @@ void EvalState::createBaseEnv() mkString(v, nixVersion); addConstant("__nixVersion", v); - mkString(v, settings.nixStore); + mkString(v, store->storeDir); addConstant("__storeDir", v); /* Language version. This should be increased every time a new diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc index 1a95e01a5e26..668f1e566c01 100644 --- a/src/libstore/binary-cache-store.cc +++ b/src/libstore/binary-cache-store.cc @@ -14,8 +14,9 @@ namespace nix { -BinaryCacheStore::BinaryCacheStore(const StoreParams & params) - : compression(get(params, "compression", "xz")) +BinaryCacheStore::BinaryCacheStore(const Params & params) + : Store(params) + , compression(get(params, "compression", "xz")) { auto secretKeyFile = get(params, "secret-key", ""); if (secretKeyFile != "") @@ -32,7 +33,7 @@ void BinaryCacheStore::init() auto cacheInfo = getFile(cacheInfoFile); if (!cacheInfo) { - upsertFile(cacheInfoFile, "StoreDir: " + settings.nixStore + "\n"); + upsertFile(cacheInfoFile, "StoreDir: " + storeDir + "\n"); } else { for (auto & line : tokenizeString<Strings>(*cacheInfo, "\n")) { size_t colon = line.find(':'); @@ -40,9 +41,9 @@ void BinaryCacheStore::init() auto name = line.substr(0, colon); auto value = trim(line.substr(colon + 1, std::string::npos)); if (name == "StoreDir") { - if (value != settings.nixStore) + if (value != storeDir) throw Error(format("binary cache ‘%s’ is for Nix stores with prefix ‘%s’, not ‘%s’") - % getUri() % value % settings.nixStore); + % getUri() % value % storeDir); } else if (name == "WantMassQuery") { wantMassQuery_ = value == "1"; } else if (name == "Priority") { @@ -181,7 +182,7 @@ std::shared_ptr<ValidPathInfo> BinaryCacheStore::queryPathInfoUncached(const Pat auto data = getFile(narInfoFile); if (!data) return 0; - auto narInfo = make_ref<NarInfo>(*data, narInfoFile); + auto narInfo = make_ref<NarInfo>(*this, *data, narInfoFile); stats.narInfoRead++; @@ -249,7 +250,7 @@ struct BinaryCacheStoreAccessor : public FSAccessor { auto path = canonPath(path_); - auto storePath = toStorePath(path); + auto storePath = store->toStorePath(path); std::string restPath = std::string(path, storePath.size()); if (!store->isValidPath(storePath)) diff --git a/src/libstore/binary-cache-store.hh b/src/libstore/binary-cache-store.hh index 3f269b8cf024..2d10179f32ab 100644 --- a/src/libstore/binary-cache-store.hh +++ b/src/libstore/binary-cache-store.hh @@ -21,7 +21,7 @@ private: protected: - BinaryCacheStore(const StoreParams & params); + BinaryCacheStore(const Params & params); [[noreturn]] void notImpl(); diff --git a/src/libstore/build.cc b/src/libstore/build.cc index cca357dfb31b..7be1571cbb16 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -1442,7 +1442,7 @@ void DerivationGoal::buildDone() #if HAVE_STATVFS unsigned long long required = 8ULL * 1024 * 1024; // FIXME: make configurable struct statvfs st; - if (statvfs(settings.nixStore.c_str(), &st) == 0 && + if (statvfs(worker.store.storeDir.c_str(), &st) == 0 && (unsigned long long) st.f_bavail * st.f_bsize < required) diskFull = true; if (statvfs(tmpDir.c_str(), &st) == 0 && @@ -1701,7 +1701,7 @@ void DerivationGoal::startBuilder() shouldn't care, but this is useful for purity checking (e.g., the compiler or linker might only want to accept paths to files in the store or in the build directory). */ - env["NIX_STORE"] = settings.nixStore; + env["NIX_STORE"] = worker.store.storeDir; /* The maximum number of cores to utilize for parallel building. */ env["NIX_BUILD_CORES"] = (format("%d") % settings.buildCores).str(); @@ -1784,10 +1784,10 @@ void DerivationGoal::startBuilder() /* Check that the store path is valid. */ Path storePath = *i++; - if (!isInStore(storePath)) + if (!worker.store.isInStore(storePath)) throw BuildError(format("‘exportReferencesGraph’ contains a non-store path ‘%1%’") % storePath); - storePath = toStorePath(storePath); + storePath = worker.store.toStorePath(storePath); if (!worker.store.isValidPath(storePath)) throw BuildError(format("‘exportReferencesGraph’ contains an invalid path ‘%1%’") % storePath); @@ -1838,7 +1838,7 @@ void DerivationGoal::startBuilder() string defaultChrootDirs; #if __linux__ - if (isInStore(BASH_PATH)) + if (worker.store.isInStore(BASH_PATH)) defaultChrootDirs = "/bin/sh=" BASH_PATH; #endif @@ -1867,8 +1867,8 @@ void DerivationGoal::startBuilder() /* Add the closure of store paths to the chroot. */ PathSet closure; for (auto & i : dirsInChroot) - if (isInStore(i.second)) - worker.store.computeFSClosure(toStorePath(i.second), closure); + if (worker.store.isInStore(i.second)) + worker.store.computeFSClosure(worker.store.toStorePath(i.second), closure); for (auto & i : closure) dirsInChroot[i] = i; @@ -1953,7 +1953,7 @@ void DerivationGoal::startBuilder() can be bind-mounted). !!! As an extra security precaution, make the fake Nix store only writable by the build user. */ - Path chrootStoreDir = chrootRootDir + settings.nixStore; + Path chrootStoreDir = chrootRootDir + worker.store.storeDir; createDirs(chrootStoreDir); chmod_(chrootStoreDir, 01775); @@ -2408,7 +2408,7 @@ void DerivationGoal::runChild() /* And we want the store in there regardless of how empty dirsInChroot. We include the innermost path component this time, since it's typically /nix/store and we care about that. */ - Path cur = settings.nixStore; + Path cur = worker.store.storeDir; while (cur.compare("/") != 0) { ancestry.insert(cur); cur = dirOf(cur); @@ -2532,12 +2532,12 @@ void DerivationGoal::runChild() /* Parse a list of reference specifiers. Each element must either be a store path, or the symbolic name of the output of the derivation (such as `out'). */ -PathSet parseReferenceSpecifiers(const BasicDerivation & drv, string attr) +PathSet parseReferenceSpecifiers(Store & store, const BasicDerivation & drv, string attr) { PathSet result; Paths paths = tokenizeString<Paths>(attr); for (auto & i : paths) { - if (isStorePath(i)) + if (store.isStorePath(i)) result.insert(i); else if (drv.outputs.find(i) != drv.outputs.end()) result.insert(drv.outputs.find(i)->second.path); @@ -2660,7 +2660,7 @@ void DerivationGoal::registerOutputs() the derivation to its content-addressed location. */ Hash h2 = recursive ? hashPath(ht, actualPath).first : hashFile(ht, actualPath); if (buildMode == bmHash) { - Path dest = makeFixedOutputPath(recursive, ht, h2, drv->env["name"]); + Path dest = worker.store.makeFixedOutputPath(recursive, ht, h2, drv->env["name"]); printMsg(lvlError, format("build produced path ‘%1%’ with %2% hash ‘%3%’") % dest % printHashType(ht) % printHash16or32(h2)); if (worker.store.isValidPath(dest)) @@ -2733,7 +2733,7 @@ void DerivationGoal::registerOutputs() auto checkRefs = [&](const string & attrName, bool allowed, bool recursive) { if (drv->env.find(attrName) == drv->env.end()) return; - PathSet spec = parseReferenceSpecifiers(*drv, get(drv->env, attrName)); + PathSet spec = parseReferenceSpecifiers(worker.store, *drv, get(drv->env, attrName)); PathSet used; if (recursive) { @@ -2965,9 +2965,9 @@ PathSet DerivationGoal::checkPathValidity(bool returnValid, bool checkHash) Path DerivationGoal::addHashRewrite(const Path & path) { - string h1 = string(path, settings.nixStore.size() + 1, 32); + string h1 = string(path, worker.store.storeDir.size() + 1, 32); string h2 = string(printHash32(hashString(htSHA256, "rewrite:" + drvPath + ":" + path)), 0, 32); - Path p = settings.nixStore + "/" + h2 + string(path, settings.nixStore.size() + 33); + Path p = worker.store.storeDir + "/" + h2 + string(path, worker.store.storeDir.size() + 33); deletePath(p); assert(path.size() == p.size()); rewritesToTmp[h1] = h2; diff --git a/src/libstore/builtins.cc b/src/libstore/builtins.cc index e1ce36e922e1..c2763f1ab4d8 100644 --- a/src/libstore/builtins.cc +++ b/src/libstore/builtins.cc @@ -26,7 +26,6 @@ void builtinFetchurl(const BasicDerivation & drv) if (out == drv.env.end()) throw Error("attribute ‘url’ missing"); Path storePath = out->second; - assertStorePath(storePath); auto unpack = drv.env.find("unpack"); if (unpack != drv.env.end() && unpack->second == "1") { diff --git a/src/libstore/derivations.cc b/src/libstore/derivations.cc index becf8524546c..8067e412adf2 100644 --- a/src/libstore/derivations.cc +++ b/src/libstore/derivations.cc @@ -81,7 +81,7 @@ Path writeDerivation(ref<Store> store, string suffix = name + drvExtension; string contents = drv.unparse(); return settings.readOnlyMode - ? computeStorePathForText(suffix, contents, references) + ? store->computeStorePathForText(suffix, contents, references) : store->addTextToStore(suffix, contents, references, repair); } @@ -336,7 +336,7 @@ PathSet BasicDerivation::outputPaths() const } -Source & operator >> (Source & in, BasicDerivation & drv) +Source & readDerivation(Source & in, Store & store, BasicDerivation & drv) { drv.outputs.clear(); auto nr = readInt(in); @@ -344,11 +344,11 @@ Source & operator >> (Source & in, BasicDerivation & drv) auto name = readString(in); DerivationOutput o; in >> o.path >> o.hashAlgo >> o.hash; - assertStorePath(o.path); + store.assertStorePath(o.path); drv.outputs[name] = o; } - drv.inputSrcs = readStorePaths<PathSet>(in); + drv.inputSrcs = readStorePaths<PathSet>(store, in); in >> drv.platform >> drv.builder; drv.args = readStrings<Strings>(in); diff --git a/src/libstore/derivations.hh b/src/libstore/derivations.hh index 6f98869b0fe0..e27c937132e8 100644 --- a/src/libstore/derivations.hh +++ b/src/libstore/derivations.hh @@ -114,7 +114,7 @@ bool wantOutput(const string & output, const std::set<string> & wanted); struct Source; struct Sink; -Source & operator >> (Source & in, BasicDerivation & drv); +Source & readDerivation(Source & in, Store & store, BasicDerivation & drv); Sink & operator << (Sink & out, const BasicDerivation & drv); } diff --git a/src/libstore/export-import.cc b/src/libstore/export-import.cc index 12b194643b12..6090ee3e9f83 100644 --- a/src/libstore/export-import.cc +++ b/src/libstore/export-import.cc @@ -101,11 +101,11 @@ Paths Store::importPaths(Source & source, std::shared_ptr<FSAccessor> accessor, ValidPathInfo info; - info.path = readStorePath(source); + info.path = readStorePath(*this, source); Activity act(*logger, lvlInfo, format("importing path ‘%s’") % info.path); - info.references = readStorePaths<PathSet>(source); + info.references = readStorePaths<PathSet>(*this, source); info.deriver = readString(source); if (info.deriver != "") assertStorePath(info.deriver); diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index f4cb672cdeb9..df48e8b662e1 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -204,7 +204,7 @@ typedef std::shared_ptr<AutoCloseFD> FDPtr; typedef list<FDPtr> FDs; -static void readTempRoots(PathSet & tempRoots, FDs & fds) +static void readTempRoots(Store & store, PathSet & tempRoots, FDs & fds) { /* Read the `temproots' directory for per-process temporary root files. */ @@ -251,7 +251,7 @@ static void readTempRoots(PathSet & tempRoots, FDs & fds) while ((end = contents.find((char) 0, pos)) != string::npos) { Path root(contents, pos, end - pos); debug(format("got temporary root ‘%1%’") % root); - assertStorePath(root); + store.assertStorePath(root); tempRoots.insert(root); pos = end + 1; } @@ -304,7 +304,7 @@ void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots) } else if (type == DT_REG) { - Path storePath = settings.nixStore + "/" + baseNameOf(path); + Path storePath = storeDir + "/" + baseNameOf(path); if (isStorePath(storePath) && isValidPath(storePath)) roots[path] = storePath; } @@ -594,7 +594,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) { GCState state(results); state.options = options; - state.trashDir = settings.nixStore + "/trash"; + state.trashDir = storeDir + "/trash"; state.gcKeepOutputs = settings.gcKeepOutputs; state.gcKeepDerivations = settings.gcKeepDerivations; @@ -635,7 +635,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) 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); + readTempRoots(*this, state.tempRoots, fds); state.roots.insert(state.tempRoots.begin(), state.tempRoots.end()); /* After this point the set of roots or temporary roots cannot @@ -675,8 +675,8 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) try { - AutoCloseDir dir = opendir(settings.nixStore.c_str()); - if (!dir) throw SysError(format("opening directory ‘%1%’") % settings.nixStore); + AutoCloseDir dir = opendir(storeDir.c_str()); + if (!dir) throw SysError(format("opening directory ‘%1%’") % storeDir); /* Read the store and immediately delete all paths that aren't valid. When using --max-freed etc., deleting @@ -690,7 +690,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) checkInterrupt(); string name = dirent->d_name; if (name == "." || name == "..") continue; - Path path = settings.nixStore + "/" + name; + Path path = storeDir + "/" + name; if (isStorePath(path) && isValidPath(path)) entries.push_back(path); else diff --git a/src/libstore/http-binary-cache-store.cc b/src/libstore/http-binary-cache-store.cc index 8c8d545c6d85..9587ac5474fb 100644 --- a/src/libstore/http-binary-cache-store.cc +++ b/src/libstore/http-binary-cache-store.cc @@ -18,7 +18,7 @@ private: public: HttpBinaryCacheStore( - const StoreParams & params, const Path & _cacheUri) + const Params & params, const Path & _cacheUri) : BinaryCacheStore(params) , cacheUri(_cacheUri) , downloaders( @@ -45,7 +45,7 @@ public: } catch (UploadToHTTP &) { throw Error(format("‘%s’ does not appear to be a binary cache") % cacheUri); } - diskCache->createCache(cacheUri, wantMassQuery_, priority); + diskCache->createCache(cacheUri, storeDir, wantMassQuery_, priority); } } @@ -91,7 +91,7 @@ protected: }; static RegisterStoreImplementation regStore([]( - const std::string & uri, const StoreParams & params) + const std::string & uri, const Store::Params & params) -> std::shared_ptr<Store> { if (std::string(uri, 0, 7) != "http://" && diff --git a/src/libstore/local-binary-cache-store.cc b/src/libstore/local-binary-cache-store.cc index b418c9c04148..bdc80cf90fee 100644 --- a/src/libstore/local-binary-cache-store.cc +++ b/src/libstore/local-binary-cache-store.cc @@ -13,7 +13,7 @@ private: public: LocalBinaryCacheStore( - const StoreParams & params, const Path & binaryCacheDir) + const Params & params, const Path & binaryCacheDir) : BinaryCacheStore(params) , binaryCacheDir(binaryCacheDir) { @@ -45,7 +45,7 @@ protected: if (entry.name.size() != 40 || !hasSuffix(entry.name, ".narinfo")) continue; - paths.insert(settings.nixStore + "/" + entry.name.substr(0, entry.name.size() - 8)); + paths.insert(storeDir + "/" + entry.name.substr(0, entry.name.size() - 8)); } return paths; @@ -59,7 +59,7 @@ void LocalBinaryCacheStore::init() BinaryCacheStore::init(); if (diskCache && !diskCache->cacheExists(getUri())) - diskCache->createCache(getUri(), wantMassQuery_, priority); + diskCache->createCache(getUri(), storeDir, wantMassQuery_, priority); } static void atomicWrite(const Path & path, const std::string & s) @@ -93,7 +93,7 @@ std::shared_ptr<std::string> LocalBinaryCacheStore::getFile(const std::string & } static RegisterStoreImplementation regStore([]( - const std::string & uri, const StoreParams & params) + const std::string & uri, const Store::Params & params) -> std::shared_ptr<Store> { if (std::string(uri, 0, 7) != "file://") return 0; diff --git a/src/libstore/local-fs-store.cc b/src/libstore/local-fs-store.cc index 303c3af27b8d..ea9c6b541a1f 100644 --- a/src/libstore/local-fs-store.cc +++ b/src/libstore/local-fs-store.cc @@ -12,7 +12,7 @@ struct LocalStoreAccessor : public FSAccessor void assertStore(const Path & path) { - Path storePath = toStorePath(path); + Path storePath = store->toStorePath(path); if (!store->isValidPath(storePath)) throw Error(format("path ‘%1%’ is not a valid store path") % storePath); } diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index cd3a74d80d82..32f4e31e07e4 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -36,26 +36,9 @@ namespace nix { -void checkStoreNotSymlink() -{ - if (getEnv("NIX_IGNORE_SYMLINK_STORE") == "1") return; - Path path = settings.nixStore; - struct stat st; - while (path != "/") { - if (lstat(path.c_str(), &st)) - throw SysError(format("getting status of ‘%1%’") % path); - if (S_ISLNK(st.st_mode)) - throw Error(format( - "the path ‘%1%’ is a symlink; " - "this is not allowed for the Nix store and its parent directories") - % path); - path = dirOf(path); - } -} - - -LocalStore::LocalStore() - : linksDir(settings.nixStore + "/.links") +LocalStore::LocalStore(const Params & params) + : LocalFSStore(params) + , linksDir(storeDir + "/.links") , reservedPath(settings.nixDBPath + "/reserved") , schemaPath(settings.nixDBPath + "/schema") , requireSigs(settings.get("signed-binary-caches", std::string("")) != "") // FIXME: rename option @@ -69,7 +52,7 @@ LocalStore::LocalStore() } /* Create missing state directories if they don't already exist. */ - createDirs(settings.nixStore); + createDirs(storeDir); makeStoreWritable(); createDirs(linksDir); Path profilesDir = settings.nixStateDir + "/profiles"; @@ -99,19 +82,33 @@ LocalStore::LocalStore() % settings.buildUsersGroup); else { struct stat st; - if (stat(settings.nixStore.c_str(), &st)) - throw SysError(format("getting attributes of path ‘%1%’") % settings.nixStore); + if (stat(storeDir.c_str(), &st)) + throw SysError(format("getting attributes of path ‘%1%’") % storeDir); if (st.st_uid != 0 || st.st_gid != gr->gr_gid || (st.st_mode & ~S_IFMT) != perm) { - if (chown(settings.nixStore.c_str(), 0, gr->gr_gid) == -1) - throw SysError(format("changing ownership of path ‘%1%’") % settings.nixStore); - if (chmod(settings.nixStore.c_str(), perm) == -1) - throw SysError(format("changing permissions on path ‘%1%’") % settings.nixStore); + if (chown(storeDir.c_str(), 0, gr->gr_gid) == -1) + throw SysError(format("changing ownership of path ‘%1%’") % storeDir); + if (chmod(storeDir.c_str(), perm) == -1) + throw SysError(format("changing permissions on path ‘%1%’") % storeDir); } } } - checkStoreNotSymlink(); + /* Ensure that the store and its parents are not symlinks. */ + if (getEnv("NIX_IGNORE_SYMLINK_STORE") != "1") { + Path path = storeDir; + struct stat st; + while (path != "/") { + if (lstat(path.c_str(), &st)) + throw SysError(format("getting status of ‘%1%’") % path); + if (S_ISLNK(st.st_mode)) + throw Error(format( + "the path ‘%1%’ is a symlink; " + "this is not allowed for the Nix store and its parent directories") + % path); + path = dirOf(path); + } + } /* We can't open a SQLite database if the disk is full. Since this prevents the garbage collector from running when it's most @@ -351,15 +348,15 @@ void LocalStore::makeStoreWritable() if (getuid() != 0) return; /* Check if /nix/store is on a read-only mount. */ struct statvfs stat; - if (statvfs(settings.nixStore.c_str(), &stat) != 0) + if (statvfs(storeDir.c_str(), &stat) != 0) throw SysError("getting info about the Nix store mount point"); if (stat.f_flag & ST_RDONLY) { if (unshare(CLONE_NEWNS) == -1) throw SysError("setting up a private mount namespace"); - if (mount(0, settings.nixStore.c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1) - throw SysError(format("remounting %1% writable") % settings.nixStore); + if (mount(0, storeDir.c_str(), "none", MS_REMOUNT | MS_BIND, 0) == -1) + throw SysError(format("remounting %1% writable") % storeDir); } #endif } @@ -771,7 +768,7 @@ Path LocalStore::queryPathFromHashPart(const string & hashPart) { if (hashPart.size() != storePathHashLen) throw Error("invalid hash part"); - Path prefix = settings.nixStore + "/" + hashPart; + Path prefix = storeDir + "/" + hashPart; return retrySQLite<Path>([&]() { auto state(_state.lock()); @@ -1071,7 +1068,7 @@ Path LocalStore::createTempDirInStore() /* There is a slight possibility that `tmpDir' gets deleted by the GC between createTempDir() and addTempRoot(), so repeat until `tmpDir' exists. */ - tmpDir = createTempDir(settings.nixStore); + tmpDir = createTempDir(storeDir); addTempRoot(tmpDir); } while (!pathExists(tmpDir)); return tmpDir; @@ -1111,7 +1108,7 @@ bool LocalStore::verifyStore(bool checkContents, bool repair) AutoCloseFD fdGCLock = openGCLock(ltWrite); PathSet store; - for (auto & i : readDirectory(settings.nixStore)) store.insert(i.name); + for (auto & i : readDirectory(storeDir)) store.insert(i.name); /* Check whether all valid paths actually exist. */ printMsg(lvlInfo, "checking path existence..."); @@ -1275,7 +1272,7 @@ void LocalStore::upgradeStore7() { if (getuid() != 0) return; printMsg(lvlError, "removing immutable bits from the Nix store (this may take a while)..."); - makeMutable(settings.nixStore); + makeMutable(storeDir); } #else diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index 231ae65a31ef..eb5fcf83360b 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -85,7 +85,7 @@ public: /* Initialise the local store, upgrading the schema if necessary. */ - LocalStore(); + LocalStore(const Params & params); ~LocalStore(); diff --git a/src/libstore/nar-info-disk-cache.cc b/src/libstore/nar-info-disk-cache.cc index ae368e152866..b05f2661ea8d 100644 --- a/src/libstore/nar-info-disk-cache.cc +++ b/src/libstore/nar-info-disk-cache.cc @@ -1,7 +1,6 @@ #include "nar-info-disk-cache.hh" #include "sync.hh" #include "sqlite.hh" -#include "globals.hh" #include <sqlite3.h> @@ -54,11 +53,17 @@ public: /* How long negative lookups are valid. */ const int ttlNegative = 3600; + struct Cache + { + int id; + Path storeDir; + }; + struct State { SQLite db; SQLiteStmt insertCache, queryCache, insertNAR, queryNAR, insertNARExistence, queryNARExistence; - std::map<std::string, int> caches; + std::map<std::string, Cache> caches; }; Sync<State> _state; @@ -106,22 +111,22 @@ public: "select exist, timestamp from NARExistence where cache = ? and storePath = ?"); } - int uriToInt(State & state, const std::string & uri) + Cache & getCache(State & state, const std::string & uri) { auto i = state.caches.find(uri); if (i == state.caches.end()) abort(); return i->second; } - void createCache(const std::string & uri, bool wantMassQuery, int priority) override + void createCache(const std::string & uri, const Path & storeDir, bool wantMassQuery, int priority) override { auto state(_state.lock()); // FIXME: race - state->insertCache.use()(uri)(time(0))(settings.nixStore)(wantMassQuery)(priority).exec(); + state->insertCache.use()(uri)(time(0))(storeDir)(wantMassQuery)(priority).exec(); assert(sqlite3_changes(state->db) == 1); - state->caches[uri] = sqlite3_last_insert_rowid(state->db); + state->caches[uri] = Cache{(int) sqlite3_last_insert_rowid(state->db), storeDir}; } bool cacheExists(const std::string & uri) override @@ -134,7 +139,7 @@ public: auto queryCache(state->queryCache.use()(uri)); if (queryCache.next()) { - state->caches[uri] = queryCache.getInt(0); + state->caches[uri] = Cache{(int) queryCache.getInt(0), queryCache.getStr(1)}; return true; } @@ -146,9 +151,9 @@ public: { auto state(_state.lock()); - auto queryNAR(state->queryNAR.use() - (uriToInt(*state, uri)) - (hashPart)); + auto & cache(getCache(*state, uri)); + + auto queryNAR(state->queryNAR.use()(cache.id)(hashPart)); if (!queryNAR.next()) // FIXME: check NARExistence @@ -159,7 +164,7 @@ public: // FIXME: implement TTL. auto namePart = queryNAR.getStr(2); - narInfo->path = settings.nixStore + "/" + + narInfo->path = cache.storeDir + "/" + hashPart + (namePart.empty() ? "" : "-" + namePart); narInfo->url = queryNAR.getStr(3); narInfo->compression = queryNAR.getStr(4); @@ -169,9 +174,9 @@ public: narInfo->narHash = parseHash(queryNAR.getStr(7)); narInfo->narSize = queryNAR.getInt(8); for (auto & r : tokenizeString<Strings>(queryNAR.getStr(9), " ")) - narInfo->references.insert(settings.nixStore + "/" + r); + narInfo->references.insert(cache.storeDir + "/" + r); if (!queryNAR.isNull(10)) - narInfo->deriver = settings.nixStore + "/" + queryNAR.getStr(10); + narInfo->deriver = cache.storeDir + "/" + queryNAR.getStr(10); for (auto & sig : tokenizeString<Strings>(queryNAR.getStr(11), " ")) narInfo->sigs.insert(sig); @@ -184,6 +189,8 @@ public: { auto state(_state.lock()); + auto & cache(getCache(*state, uri)); + if (info) { auto narInfo = std::dynamic_pointer_cast<NarInfo>(info); @@ -191,7 +198,7 @@ public: assert(hashPart == storePathToHash(info->path)); state->insertNAR.use() - (uriToInt(*state, uri)) + (cache.id) (hashPart) (storePathToName(info->path)) (narInfo ? narInfo->url : "", narInfo != 0) diff --git a/src/libstore/nar-info-disk-cache.hh b/src/libstore/nar-info-disk-cache.hh index ce5da062c5e3..f86d720a9586 100644 --- a/src/libstore/nar-info-disk-cache.hh +++ b/src/libstore/nar-info-disk-cache.hh @@ -10,7 +10,8 @@ class NarInfoDiskCache public: typedef enum { oValid, oInvalid, oUnknown } Outcome; - virtual void createCache(const std::string & uri, bool wantMassQuery, int priority) = 0; + virtual void createCache(const std::string & uri, const Path & storeDir, + bool wantMassQuery, int priority) = 0; virtual bool cacheExists(const std::string & uri) = 0; diff --git a/src/libstore/nar-info.cc b/src/libstore/nar-info.cc index 4ff4c996dabd..1aacca84b800 100644 --- a/src/libstore/nar-info.cc +++ b/src/libstore/nar-info.cc @@ -3,7 +3,7 @@ namespace nix { -NarInfo::NarInfo(const std::string & s, const std::string & whence) +NarInfo::NarInfo(const Store & store, const std::string & s, const std::string & whence) { auto corrupt = [&]() { throw Error("NAR info file ‘%1%’ is corrupt"); @@ -32,7 +32,7 @@ NarInfo::NarInfo(const std::string & s, const std::string & whence) std::string value(s, colon + 2, eol - colon - 2); if (name == "StorePath") { - if (!isStorePath(value)) corrupt(); + if (!store.isStorePath(value)) corrupt(); path = value; } else if (name == "URL") @@ -53,14 +53,14 @@ NarInfo::NarInfo(const std::string & s, const std::string & whence) auto refs = tokenizeString<Strings>(value, " "); if (!references.empty()) corrupt(); for (auto & r : refs) { - auto r2 = settings.nixStore + "/" + r; - if (!isStorePath(r2)) corrupt(); + auto r2 = store.storeDir + "/" + r; + if (!store.isStorePath(r2)) corrupt(); references.insert(r2); } } else if (name == "Deriver") { - auto p = settings.nixStore + "/" + value; - if (!isStorePath(p)) corrupt(); + auto p = store.storeDir + "/" + value; + if (!store.isStorePath(p)) corrupt(); deriver = p; } else if (name == "System") diff --git a/src/libstore/nar-info.hh b/src/libstore/nar-info.hh index 6bc2f03b139b..4995061fbb6d 100644 --- a/src/libstore/nar-info.hh +++ b/src/libstore/nar-info.hh @@ -16,7 +16,7 @@ struct NarInfo : ValidPathInfo NarInfo() { } NarInfo(const ValidPathInfo & info) : ValidPathInfo(info) { } - NarInfo(const std::string & s, const std::string & whence); + NarInfo(const Store & store, const std::string & s, const std::string & whence); std::string to_string() const; }; diff --git a/src/libstore/optimise-store.cc b/src/libstore/optimise-store.cc index ad7fe0e8bebf..33f002f9dbb1 100644 --- a/src/libstore/optimise-store.cc +++ b/src/libstore/optimise-store.cc @@ -184,7 +184,7 @@ void LocalStore::optimisePath_(OptimiseStats & stats, const Path & path, InodeHa MakeReadOnly makeReadOnly(mustToggle ? dirOf(path) : ""); Path tempLink = (format("%1%/.tmp-link-%2%-%3%") - % settings.nixStore % getpid() % rand()).str(); + % storeDir % getpid() % rand()).str(); if (link(linkPath.c_str(), tempLink.c_str()) == -1) { if (errno == EMLINK) { diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 48653595f0e8..3654ffbffc44 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -21,26 +21,27 @@ namespace nix { -Path readStorePath(Source & from) +Path readStorePath(Store & store, Source & from) { Path path = readString(from); - assertStorePath(path); + store.assertStorePath(path); return path; } -template<class T> T readStorePaths(Source & from) +template<class T> T readStorePaths(Store & store, Source & from) { T paths = readStrings<T>(from); - for (auto & i : paths) assertStorePath(i); + for (auto & i : paths) store.assertStorePath(i); return paths; } -template PathSet readStorePaths(Source & from); +template PathSet readStorePaths(Store & store, Source & from); -RemoteStore::RemoteStore(size_t maxConnections) - : connections(make_ref<Pool<Connection>>( +RemoteStore::RemoteStore(const Params & params, size_t maxConnections) + : LocalFSStore(params) + , connections(make_ref<Pool<Connection>>( maxConnections, [this]() { return openConnection(); }, [](const ref<Connection> & r) { return r->to.good() && r->from.good(); } @@ -168,7 +169,7 @@ PathSet RemoteStore::queryValidPaths(const PathSet & paths) } else { conn->to << wopQueryValidPaths << paths; conn->processStderr(); - return readStorePaths<PathSet>(conn->from); + return readStorePaths<PathSet>(*this, conn->from); } } @@ -178,7 +179,7 @@ PathSet RemoteStore::queryAllValidPaths() auto conn(connections->get()); conn->to << wopQueryAllValidPaths; conn->processStderr(); - return readStorePaths<PathSet>(conn->from); + return readStorePaths<PathSet>(*this, conn->from); } @@ -196,7 +197,7 @@ PathSet RemoteStore::querySubstitutablePaths(const PathSet & paths) } else { conn->to << wopQuerySubstitutablePaths << paths; conn->processStderr(); - return readStorePaths<PathSet>(conn->from); + return readStorePaths<PathSet>(*this, conn->from); } } @@ -220,7 +221,7 @@ void RemoteStore::querySubstitutablePathInfos(const PathSet & paths, if (reply == 0) continue; info.deriver = readString(conn->from); if (info.deriver != "") assertStorePath(info.deriver); - info.references = readStorePaths<PathSet>(conn->from); + info.references = readStorePaths<PathSet>(*this, conn->from); info.downloadSize = readLongLong(conn->from); info.narSize = GET_PROTOCOL_MINOR(conn->daemonVersion) >= 7 ? readLongLong(conn->from) : 0; infos[i] = info; @@ -232,11 +233,11 @@ void RemoteStore::querySubstitutablePathInfos(const PathSet & paths, conn->processStderr(); unsigned int count = readInt(conn->from); for (unsigned int n = 0; n < count; n++) { - Path path = readStorePath(conn->from); + Path path = readStorePath(*this, conn->from); SubstitutablePathInfo & info(infos[path]); info.deriver = readString(conn->from); if (info.deriver != "") assertStorePath(info.deriver); - info.references = readStorePaths<PathSet>(conn->from); + info.references = readStorePaths<PathSet>(*this, conn->from); info.downloadSize = readLongLong(conn->from); info.narSize = readLongLong(conn->from); } @@ -266,7 +267,7 @@ std::shared_ptr<ValidPathInfo> RemoteStore::queryPathInfoUncached(const Path & p info->deriver = readString(conn->from); if (info->deriver != "") assertStorePath(info->deriver); info->narHash = parseHash(htSHA256, readString(conn->from)); - info->references = readStorePaths<PathSet>(conn->from); + info->references = readStorePaths<PathSet>(*this, conn->from); info->registrationTime = readInt(conn->from); info->narSize = readLongLong(conn->from); if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 16) { @@ -283,7 +284,7 @@ void RemoteStore::queryReferrers(const Path & path, auto conn(connections->get()); conn->to << wopQueryReferrers << path; conn->processStderr(); - PathSet referrers2 = readStorePaths<PathSet>(conn->from); + PathSet referrers2 = readStorePaths<PathSet>(*this, conn->from); referrers.insert(referrers2.begin(), referrers2.end()); } @@ -293,7 +294,7 @@ PathSet RemoteStore::queryValidDerivers(const Path & path) auto conn(connections->get()); conn->to << wopQueryValidDerivers << path; conn->processStderr(); - return readStorePaths<PathSet>(conn->from); + return readStorePaths<PathSet>(*this, conn->from); } @@ -302,7 +303,7 @@ PathSet RemoteStore::queryDerivationOutputs(const Path & path) auto conn(connections->get()); conn->to << wopQueryDerivationOutputs << path; conn->processStderr(); - return readStorePaths<PathSet>(conn->from); + return readStorePaths<PathSet>(*this, conn->from); } @@ -363,7 +364,7 @@ Path RemoteStore::addToStore(const string & name, const Path & _srcPath, throw; } - return readStorePath(conn->from); + return readStorePath(*this, conn->from); } @@ -376,7 +377,7 @@ Path RemoteStore::addTextToStore(const string & name, const string & s, conn->to << wopAddTextToStore << name << s << references; conn->processStderr(); - return readStorePath(conn->from); + return readStorePath(*this, conn->from); } @@ -465,7 +466,7 @@ Roots RemoteStore::findRoots() Roots result; while (count--) { Path link = readString(conn->from); - Path target = readStorePath(conn->from); + Path target = readStorePath(*this, conn->from); result[link] = target; } return result; diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh index 3e0fc4e04f41..e756805ea05b 100644 --- a/src/libstore/remote-store.hh +++ b/src/libstore/remote-store.hh @@ -22,7 +22,7 @@ class RemoteStore : public LocalFSStore { public: - RemoteStore(size_t maxConnections = std::numeric_limits<size_t>::max()); + RemoteStore(const Params & params, size_t maxConnections = std::numeric_limits<size_t>::max()); /* Implementations of abstract store API methods. */ diff --git a/src/libstore/s3-binary-cache-store.cc b/src/libstore/s3-binary-cache-store.cc index 371bf24fd419..33cc9659a0cd 100644 --- a/src/libstore/s3-binary-cache-store.cc +++ b/src/libstore/s3-binary-cache-store.cc @@ -47,7 +47,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore Stats stats; S3BinaryCacheStoreImpl( - const StoreParams & params, const std::string & bucketName) + const Params & params, const std::string & bucketName) : S3BinaryCacheStore(params) , bucketName(bucketName) , config(makeConfig()) @@ -95,7 +95,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore BinaryCacheStore::init(); - diskCache->createCache(getUri(), wantMassQuery_, priority); + diskCache->createCache(getUri(), storeDir, wantMassQuery_, priority); } } @@ -232,7 +232,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore for (auto object : contents) { auto & key = object.GetKey(); if (key.size() != 40 || !hasSuffix(key, ".narinfo")) continue; - paths.insert(settings.nixStore + "/" + key.substr(0, key.size() - 8)); + paths.insert(storeDir + "/" + key.substr(0, key.size() - 8)); } marker = res.GetNextMarker(); @@ -244,7 +244,7 @@ struct S3BinaryCacheStoreImpl : public S3BinaryCacheStore }; static RegisterStoreImplementation regStore([]( - const std::string & uri, const StoreParams & params) + const std::string & uri, const Store::Params & params) -> std::shared_ptr<Store> { if (std::string(uri, 0, 5) != "s3://") return 0; diff --git a/src/libstore/s3-binary-cache-store.hh b/src/libstore/s3-binary-cache-store.hh index 3f9bd891274b..79ab72e5a940 100644 --- a/src/libstore/s3-binary-cache-store.hh +++ b/src/libstore/s3-binary-cache-store.hh @@ -10,7 +10,7 @@ class S3BinaryCacheStore : public BinaryCacheStore { protected: - S3BinaryCacheStore(const StoreParams & params) + S3BinaryCacheStore(const Params & params) : BinaryCacheStore(params) { } diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index f39d6b54787c..cea4b4b6ebcb 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -8,32 +8,32 @@ namespace nix { -bool isInStore(const Path & path) +bool Store::isInStore(const Path & path) const { - return isInDir(path, settings.nixStore); + return isInDir(path, storeDir); } -bool isStorePath(const Path & path) +bool Store::isStorePath(const Path & path) const { return isInStore(path) - && path.size() >= settings.nixStore.size() + 1 + storePathHashLen - && path.find('/', settings.nixStore.size() + 1) == Path::npos; + && path.size() >= storeDir.size() + 1 + storePathHashLen + && path.find('/', storeDir.size() + 1) == Path::npos; } -void assertStorePath(const Path & path) +void Store::assertStorePath(const Path & path) const { if (!isStorePath(path)) throw Error(format("path ‘%1%’ is not in the Nix store") % path); } -Path toStorePath(const Path & path) +Path Store::toStorePath(const Path & path) const { if (!isInStore(path)) throw Error(format("path ‘%1%’ is not in the Nix store") % path); - Path::size_type slash = path.find('/', settings.nixStore.size() + 1); + Path::size_type slash = path.find('/', storeDir.size() + 1); if (slash == Path::npos) return path; else @@ -41,7 +41,7 @@ Path toStorePath(const Path & path) } -Path followLinksToStore(const Path & _path) +Path Store::followLinksToStore(const Path & _path) const { Path path = absPath(_path); while (!isInStore(path)) { @@ -55,7 +55,7 @@ Path followLinksToStore(const Path & _path) } -Path followLinksToStorePath(const Path & path) +Path Store::followLinksToStorePath(const Path & path) const { return toStorePath(followLinksToStore(path)); } @@ -63,18 +63,17 @@ Path followLinksToStorePath(const Path & path) string storePathToName(const Path & path) { - assertStorePath(path); - auto l = settings.nixStore.size() + 1 + storePathHashLen; - assert(path.size() >= l); - return path.size() == l ? "" : string(path, l + 1); + auto base = baseNameOf(path); + assert(base.size() == storePathHashLen || (base.size() > storePathHashLen && base[storePathHashLen] == '-')); + return base.size() == storePathHashLen ? "" : string(base, storePathHashLen + 1); } string storePathToHash(const Path & path) { - assertStorePath(path); - assert(path.size() >= settings.nixStore.size() + 1 + storePathHashLen); - return string(path, settings.nixStore.size() + 1, storePathHashLen); + auto base = baseNameOf(path); + assert(base.size() >= storePathHashLen); + return string(base, 0, storePathHashLen); } @@ -168,31 +167,31 @@ void checkStoreName(const string & name) */ -Path makeStorePath(const string & type, - const Hash & hash, const string & name) +Path Store::makeStorePath(const string & type, + const Hash & hash, const string & name) const { /* e.g., "source:sha256:1abc...:/nix/store:foo.tar.gz" */ string s = type + ":sha256:" + printHash(hash) + ":" - + settings.nixStore + ":" + name; + + storeDir + ":" + name; checkStoreName(name); - return settings.nixStore + "/" + return storeDir + "/" + printHash32(compressHash(hashString(htSHA256, s), 20)) + "-" + name; } -Path makeOutputPath(const string & id, - const Hash & hash, const string & name) +Path Store::makeOutputPath(const string & id, + const Hash & hash, const string & name) const { return makeStorePath("output:" + id, hash, name + (id == "out" ? "" : "-" + id)); } -Path makeFixedOutputPath(bool recursive, - HashType hashAlgo, Hash hash, string name) +Path Store::makeFixedOutputPath(bool recursive, + HashType hashAlgo, Hash hash, string name) const { return hashAlgo == htSHA256 && recursive ? makeStorePath("source", hash, name) @@ -203,8 +202,8 @@ Path makeFixedOutputPath(bool recursive, } -std::pair<Path, Hash> computeStorePathForPath(const Path & srcPath, - bool recursive, HashType hashAlgo, PathFilter & filter) +std::pair<Path, Hash> Store::computeStorePathForPath(const Path & srcPath, + bool recursive, HashType hashAlgo, PathFilter & filter) const { HashType ht(hashAlgo); Hash h = recursive ? hashPath(ht, srcPath, filter).first : hashFile(ht, srcPath); @@ -214,8 +213,8 @@ std::pair<Path, Hash> computeStorePathForPath(const Path & srcPath, } -Path computeStorePathForText(const string & name, const string & s, - const PathSet & references) +Path Store::computeStorePathForText(const string & name, const string & s, + const PathSet & references) const { Hash hash = hashString(htSHA256, s); /* Stuff the references (if any) into the type. This is a bit @@ -230,6 +229,12 @@ Path computeStorePathForText(const string & name, const string & s, } +Store::Store(const Params & params) + : storeDir(settings.nixStore) +{ +} + + std::string Store::getUri() { return ""; @@ -465,7 +470,7 @@ RegisterStoreImplementation::Implementations * RegisterStoreImplementation::impl ref<Store> openStoreAt(const std::string & uri_) { auto uri(uri_); - StoreParams params; + Store::Params params; auto q = uri.find('?'); if (q != std::string::npos) { for (auto s : tokenizeString<Strings>(uri.substr(q + 1), "&")) { @@ -492,7 +497,7 @@ ref<Store> openStore() static RegisterStoreImplementation regStore([]( - const std::string & uri, const StoreParams & params) + const std::string & uri, const Store::Params & params) -> std::shared_ptr<Store> { enum { mDaemon, mLocal, mAuto } mode; @@ -512,8 +517,8 @@ static RegisterStoreImplementation regStore([]( } return mode == mDaemon - ? std::shared_ptr<Store>(std::make_shared<RemoteStore>()) - : std::shared_ptr<Store>(std::make_shared<LocalStore>()); + ? std::shared_ptr<Store>(std::make_shared<RemoteStore>(params)) + : std::shared_ptr<Store>(std::make_shared<LocalStore>(params)); }); diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index ab7baf82d5f8..45cf7e7819a9 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -177,6 +177,12 @@ class NarInfoDiskCache; class Store : public std::enable_shared_from_this<Store> { +public: + + typedef std::map<std::string, std::string> Params; + + const Path storeDir; + protected: struct State @@ -188,12 +194,71 @@ protected: std::shared_ptr<NarInfoDiskCache> diskCache; + Store(const Params & params); + public: virtual ~Store() { } virtual std::string getUri() = 0; + /* Return true if ‘path’ is in the Nix store (but not the Nix + store itself). */ + bool isInStore(const Path & path) const; + + /* Return true if ‘path’ is a store path, i.e. a direct child of + the Nix store. */ + bool isStorePath(const Path & path) const; + + /* Throw an exception if ‘path’ is not a store path. */ + void assertStorePath(const Path & path) const; + + /* Chop off the parts after the top-level store name, e.g., + /nix/store/abcd-foo/bar => /nix/store/abcd-foo. */ + Path toStorePath(const Path & path) const; + + /* Follow symlinks until we end up with a path in the Nix store. */ + Path followLinksToStore(const Path & path) const; + + /* Same as followLinksToStore(), but apply toStorePath() to the + result. */ + Path followLinksToStorePath(const Path & path) const; + + /* Constructs a unique store path name. */ + Path makeStorePath(const string & type, + const Hash & hash, const string & name) const; + + Path makeOutputPath(const string & id, + const Hash & hash, const string & name) const; + + Path makeFixedOutputPath(bool recursive, + HashType hashAlgo, Hash hash, string name) const; + + /* This is the preparatory part of addToStore() and + addToStoreFixed(); it computes the store path to which srcPath + is to be copied. Returns the store path and the cryptographic + hash of the contents of srcPath. */ + std::pair<Path, Hash> computeStorePathForPath(const Path & srcPath, + bool recursive = true, HashType hashAlgo = htSHA256, + PathFilter & filter = defaultPathFilter) const; + + /* Preparatory part of addTextToStore(). + + !!! Computation of the path should take the references given to + addTextToStore() into account, otherwise we have a (relatively + minor) security hole: a caller can register a source file with + bogus references. If there are too many references, the path may + not be garbage collected when it has to be (not really a problem, + the caller could create a root anyway), or it may be garbage + collected when it shouldn't be (more serious). + + Hashing the references would solve this (bogus references would + simply yield a different store path, so other users wouldn't be + affected), but it has some backwards compatibility issues (the + hashing scheme changes), so I'm not doing that for now. */ + Path computeStorePathForText(const string & name, const string & s, + const PathSet & references) const; + /* Check whether a path is valid. */ bool isValidPath(const Path & path); @@ -429,80 +494,26 @@ protected: class LocalFSStore : public Store { +protected: + using Store::Store; public: void narFromPath(const Path & path, Sink & sink) override; ref<FSAccessor> getFSAccessor() override; }; -/* !!! These should be part of the store API, I guess. */ - -/* Throw an exception if `path' is not directly in the Nix store. */ -void assertStorePath(const Path & path); - -bool isInStore(const Path & path); -bool isStorePath(const Path & path); - /* Extract the name part of the given store path. */ string storePathToName(const Path & path); /* Extract the hash part of the given store path. */ string storePathToHash(const Path & path); +/* Check whether ‘name’ is a valid store path name part, i.e. contains + only the characters [a-zA-Z0-9\+\-\.\_\?\=] and doesn't start with + a dot. */ void checkStoreName(const string & name); -/* Chop off the parts after the top-level store name, e.g., - /nix/store/abcd-foo/bar => /nix/store/abcd-foo. */ -Path toStorePath(const Path & path); - - -/* Follow symlinks until we end up with a path in the Nix store. */ -Path followLinksToStore(const Path & path); - - -/* Same as followLinksToStore(), but apply toStorePath() to the - result. */ -Path followLinksToStorePath(const Path & path); - - -/* Constructs a unique store path name. */ -Path makeStorePath(const string & type, - const Hash & hash, const string & name); - -Path makeOutputPath(const string & id, - const Hash & hash, const string & name); - -Path makeFixedOutputPath(bool recursive, - HashType hashAlgo, Hash hash, string name); - - -/* This is the preparatory part of addToStore() and addToStoreFixed(); - it computes the store path to which srcPath is to be copied. - Returns the store path and the cryptographic hash of the - contents of srcPath. */ -std::pair<Path, Hash> computeStorePathForPath(const Path & srcPath, - bool recursive = true, HashType hashAlgo = htSHA256, - PathFilter & filter = defaultPathFilter); - -/* Preparatory part of addTextToStore(). - - !!! Computation of the path should take the references given to - addTextToStore() into account, otherwise we have a (relatively - minor) security hole: a caller can register a source file with - bogus references. If there are too many references, the path may - not be garbage collected when it has to be (not really a problem, - the caller could create a root anyway), or it may be garbage - collected when it shouldn't be (more serious). - - Hashing the references would solve this (bogus references would - simply yield a different store path, so other users wouldn't be - affected), but it has some backwards compatibility issues (the - hashing scheme changes), so I'm not doing that for now. */ -Path computeStorePathForText(const string & name, const string & s, - const PathSet & references); - - /* Copy a path from one store to another. */ void copyStorePath(ref<Store> srcStore, ref<Store> dstStore, const Path & storePath, bool repair = false); @@ -542,10 +553,8 @@ std::list<ref<Store>> getDefaultSubstituters(); /* Store implementation registration. */ -typedef std::map<std::string, std::string> StoreParams; - typedef std::function<std::shared_ptr<Store>( - const std::string & uri, const StoreParams & params)> OpenStore; + const std::string & uri, const Store::Params & params)> OpenStore; struct RegisterStoreImplementation { diff --git a/src/libstore/worker-protocol.hh b/src/libstore/worker-protocol.hh index 7ff0553a016c..f8cd7cc4be29 100644 --- a/src/libstore/worker-protocol.hh +++ b/src/libstore/worker-protocol.hh @@ -56,8 +56,8 @@ typedef enum { #define STDERR_ERROR 0x63787470 -Path readStorePath(Source & from); -template<class T> T readStorePaths(Source & from); +Path readStorePath(Store & store, Source & from); +template<class T> T readStorePaths(Store & store, Source & from); } diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc index 9757086c650e..6a992b95340d 100644 --- a/src/nix-daemon/nix-daemon.cc +++ b/src/nix-daemon/nix-daemon.cc @@ -176,7 +176,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe connection. */ Path path = readString(from); startWork(); - assertStorePath(path); + store->assertStorePath(path); bool result = store->isValidPath(path); stopWork(); to << result; @@ -184,7 +184,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe } case wopQueryValidPaths: { - PathSet paths = readStorePaths<PathSet>(from); + PathSet paths = readStorePaths<PathSet>(*store, from); startWork(); PathSet res = store->queryValidPaths(paths); stopWork(); @@ -193,7 +193,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe } case wopHasSubstitutes: { - Path path = readStorePath(from); + Path path = readStorePath(*store, from); startWork(); PathSet res = store->querySubstitutablePaths({path}); stopWork(); @@ -202,7 +202,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe } case wopQuerySubstitutablePaths: { - PathSet paths = readStorePaths<PathSet>(from); + PathSet paths = readStorePaths<PathSet>(*store, from); startWork(); PathSet res = store->querySubstitutablePaths(paths); stopWork(); @@ -211,7 +211,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe } case wopQueryPathHash: { - Path path = readStorePath(from); + Path path = readStorePath(*store, from); startWork(); auto hash = store->queryPathInfo(path)->narHash; stopWork(); @@ -223,7 +223,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe case wopQueryReferrers: case wopQueryValidDerivers: case wopQueryDerivationOutputs: { - Path path = readStorePath(from); + Path path = readStorePath(*store, from); startWork(); PathSet paths; if (op == wopQueryReferences) @@ -239,7 +239,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe } case wopQueryDerivationOutputNames: { - Path path = readStorePath(from); + Path path = readStorePath(*store, from); startWork(); StringSet names; names = store->queryDerivationOutputNames(path); @@ -249,7 +249,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe } case wopQueryDeriver: { - Path path = readStorePath(from); + Path path = readStorePath(*store, from); startWork(); auto deriver = store->queryPathInfo(path)->deriver; stopWork(); @@ -302,7 +302,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe case wopAddTextToStore: { string suffix = readString(from); string s = readString(from); - PathSet refs = readStorePaths<PathSet>(from); + PathSet refs = readStorePaths<PathSet>(*store, from); startWork(); Path path = store->addTextToStore(suffix, s, refs); stopWork(); @@ -311,7 +311,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe } case wopExportPath: { - Path path = readStorePath(from); + Path path = readStorePath(*store, from); readInt(from); // obsolete startWork(); TunnelSink sink(to); @@ -331,7 +331,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe } case wopBuildPaths: { - PathSet drvs = readStorePaths<PathSet>(from); + PathSet drvs = readStorePaths<PathSet>(*store, from); BuildMode mode = bmNormal; if (GET_PROTOCOL_MINOR(clientVersion) >= 15) { mode = (BuildMode)readInt(from); @@ -349,9 +349,9 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe } case wopBuildDerivation: { - Path drvPath = readStorePath(from); + Path drvPath = readStorePath(*store, from); BasicDerivation drv; - from >> drv; + readDerivation(from, *store, drv); BuildMode buildMode = (BuildMode) readInt(from); startWork(); if (!trusted) @@ -363,7 +363,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe } case wopEnsurePath: { - Path path = readStorePath(from); + Path path = readStorePath(*store, from); startWork(); store->ensurePath(path); stopWork(); @@ -372,7 +372,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe } case wopAddTempRoot: { - Path path = readStorePath(from); + Path path = readStorePath(*store, from); startWork(); store->addTempRoot(path); stopWork(); @@ -410,7 +410,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe case wopCollectGarbage: { GCOptions options; options.action = (GCOptions::GCAction) readInt(from); - options.pathsToDelete = readStorePaths<PathSet>(from); + options.pathsToDelete = readStorePaths<PathSet>(*store, from); options.ignoreLiveness = readInt(from); options.maxFreed = readLongLong(from); readInt(from); // obsolete field @@ -486,7 +486,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe } case wopQuerySubstitutablePathInfos: { - PathSet paths = readStorePaths<PathSet>(from); + PathSet paths = readStorePaths<PathSet>(*store, from); startWork(); SubstitutablePathInfos infos; store->querySubstitutablePathInfos(paths, infos); @@ -508,7 +508,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe } case wopQueryPathInfo: { - Path path = readStorePath(from); + Path path = readStorePath(*store, from); std::shared_ptr<const ValidPathInfo> info; startWork(); try { @@ -553,7 +553,7 @@ static void performOp(ref<LocalStore> store, bool trusted, unsigned int clientVe } case wopAddSignatures: { - Path path = readStorePath(from); + Path path = readStorePath(*store, from); StringSet sigs = readStrings<StringSet>(from); startWork(); if (!trusted) @@ -607,7 +607,7 @@ static void processConnection(bool trusted) #endif /* Open the store. */ - auto store = make_ref<LocalStore>(); + auto store = make_ref<LocalStore>(Store::Params()); // FIXME: get params from somewhere stopWork(); to.flush(); diff --git a/src/nix-env/nix-env.cc b/src/nix-env/nix-env.cc index 6b6c245d3637..fbb0f61a19d2 100644 --- a/src/nix-env/nix-env.cc +++ b/src/nix-env/nix-env.cc @@ -387,7 +387,7 @@ static void queryInstSources(EvalState & state, case srcStorePaths: { for (auto & i : args) { - Path path = followLinksToStorePath(i); + Path path = state.store->followLinksToStorePath(i); string name = baseNameOf(path); string::size_type dash = name.find('-'); @@ -742,7 +742,7 @@ static void uninstallDerivations(Globals & globals, Strings & selectors, for (auto & j : selectors) /* !!! the repeated calls to followLinksToStorePath() are expensive, should pre-compute them. */ - if ((isPath(j) && i.queryOutPath() == followLinksToStorePath(j)) + if ((isPath(j) && i.queryOutPath() == globals.state->store->followLinksToStorePath(j)) || DrvName(j).matches(drvName)) { printMsg(lvlInfo, format("uninstalling ‘%1%’") % i.name); diff --git a/src/nix-prefetch-url/nix-prefetch-url.cc b/src/nix-prefetch-url/nix-prefetch-url.cc index 64da10513711..44a16743d886 100644 --- a/src/nix-prefetch-url/nix-prefetch-url.cc +++ b/src/nix-prefetch-url/nix-prefetch-url.cc @@ -146,7 +146,7 @@ int main(int argc, char * * argv) Path storePath; if (args.size() == 2) { expectedHash = parseHash16or32(ht, args[1]); - storePath = makeFixedOutputPath(unpack, ht, expectedHash, name); + storePath = store->makeFixedOutputPath(unpack, ht, expectedHash, name); if (store->isValidPath(storePath)) hash = expectedHash; else @@ -197,7 +197,7 @@ int main(int argc, char * * argv) into the Nix store. */ storePath = store->addToStore(name, tmpFile, unpack, ht); - assert(storePath == makeFixedOutputPath(unpack, ht, hash, name)); + assert(storePath == store->makeFixedOutputPath(unpack, ht, hash, name)); } if (!printPath) diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index 1fd8a148e472..cd00412a8a86 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -124,7 +124,7 @@ static void opRealise(Strings opFlags, Strings opArgs) Paths paths; for (auto & i : opArgs) { DrvPathWithOutputs p = parseDrvPathWithOutputs(i); - paths.push_back(makeDrvPathWithOutputs(followLinksToStorePath(p.first), p.second)); + paths.push_back(makeDrvPathWithOutputs(store->followLinksToStorePath(p.first), p.second)); } unsigned long long downloadSize, narSize; @@ -207,7 +207,7 @@ static void opPrintFixedPath(Strings opFlags, Strings opArgs) string name = *i++; cout << format("%1%\n") % - makeFixedOutputPath(recursive, hashAlgo, + store->makeFixedOutputPath(recursive, hashAlgo, parseHash16or32(hashAlgo, hash), name); } @@ -315,7 +315,7 @@ static void opQuery(Strings opFlags, Strings opArgs) case qOutputs: { for (auto & i : opArgs) { - i = followLinksToStorePath(i); + i = store->followLinksToStorePath(i); if (forceRealise) realisePath(i); Derivation drv = store->derivationFromPath(i); for (auto & j : drv.outputs) @@ -330,7 +330,7 @@ static void opQuery(Strings opFlags, Strings opArgs) case qReferrersClosure: { PathSet paths; for (auto & i : opArgs) { - PathSet ps = maybeUseOutputs(followLinksToStorePath(i), useOutput, forceRealise); + PathSet ps = maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise); for (auto & j : ps) { if (query == qRequisites) store->computeFSClosure(j, paths, false, includeOutputs); else if (query == qReferences) { @@ -350,7 +350,7 @@ static void opQuery(Strings opFlags, Strings opArgs) case qDeriver: for (auto & i : opArgs) { - Path deriver = store->queryPathInfo(followLinksToStorePath(i))->deriver; + Path deriver = store->queryPathInfo(store->followLinksToStorePath(i))->deriver; cout << format("%1%\n") % (deriver == "" ? "unknown-deriver" : deriver); } @@ -358,7 +358,7 @@ static void opQuery(Strings opFlags, Strings opArgs) case qBinding: for (auto & i : opArgs) { - Path path = useDeriver(followLinksToStorePath(i)); + Path path = useDeriver(store->followLinksToStorePath(i)); Derivation drv = store->derivationFromPath(path); StringPairs::iterator j = drv.env.find(bindingName); if (j == drv.env.end()) @@ -371,7 +371,7 @@ static void opQuery(Strings opFlags, Strings opArgs) case qHash: case qSize: for (auto & i : opArgs) { - PathSet paths = maybeUseOutputs(followLinksToStorePath(i), useOutput, forceRealise); + PathSet paths = maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise); for (auto & j : paths) { auto info = store->queryPathInfo(j); if (query == qHash) { @@ -386,14 +386,14 @@ static void opQuery(Strings opFlags, Strings opArgs) case qTree: { PathSet done; for (auto & i : opArgs) - printTree(followLinksToStorePath(i), "", "", done); + printTree(store->followLinksToStorePath(i), "", "", done); break; } case qGraph: { PathSet roots; for (auto & i : opArgs) { - PathSet paths = maybeUseOutputs(followLinksToStorePath(i), useOutput, forceRealise); + PathSet paths = maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise); roots.insert(paths.begin(), paths.end()); } printDotGraph(ref<Store>(store), roots); @@ -403,7 +403,7 @@ static void opQuery(Strings opFlags, Strings opArgs) case qXml: { PathSet roots; for (auto & i : opArgs) { - PathSet paths = maybeUseOutputs(followLinksToStorePath(i), useOutput, forceRealise); + PathSet paths = maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise); roots.insert(paths.begin(), paths.end()); } printXmlGraph(ref<Store>(store), roots); @@ -412,14 +412,14 @@ static void opQuery(Strings opFlags, Strings opArgs) case qResolve: { for (auto & i : opArgs) - cout << format("%1%\n") % followLinksToStorePath(i); + cout << format("%1%\n") % store->followLinksToStorePath(i); break; } case qRoots: { PathSet referrers; for (auto & i : opArgs) { - PathSet paths = maybeUseOutputs(followLinksToStorePath(i), useOutput, forceRealise); + PathSet paths = maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise); for (auto & j : paths) store->computeFSClosure(j, referrers, true, settings.gcKeepOutputs, settings.gcKeepDerivations); @@ -479,7 +479,7 @@ static void opReadLog(Strings opFlags, Strings opArgs) RunPager pager; for (auto & i : opArgs) { - Path path = useDeriver(followLinksToStorePath(i)); + Path path = useDeriver(store->followLinksToStorePath(i)); string baseName = baseNameOf(path); bool found = false; @@ -599,7 +599,7 @@ static void opCheckValidity(Strings opFlags, Strings opArgs) else throw UsageError(format("unknown flag ‘%1%’") % i); for (auto & i : opArgs) { - Path path = followLinksToStorePath(i); + Path path = store->followLinksToStorePath(i); if (!store->isValidPath(path)) { if (printInvalid) cout << format("%1%\n") % path; @@ -662,7 +662,7 @@ static void opDelete(Strings opFlags, Strings opArgs) else throw UsageError(format("unknown flag ‘%1%’") % i); for (auto & i : opArgs) - options.pathsToDelete.insert(followLinksToStorePath(i)); + options.pathsToDelete.insert(store->followLinksToStorePath(i)); GCResults results; PrintFreed freed(true, results); @@ -761,7 +761,7 @@ static void opVerifyPath(Strings opFlags, Strings opArgs) int status = 0; for (auto & i : opArgs) { - Path path = followLinksToStorePath(i); + Path path = store->followLinksToStorePath(i); printMsg(lvlTalkative, format("checking path ‘%1%’...") % path); auto info = store->queryPathInfo(path); HashSink sink(info->narHash.type); @@ -787,7 +787,7 @@ static void opRepairPath(Strings opFlags, Strings opArgs) throw UsageError("no flags expected"); for (auto & i : opArgs) { - Path path = followLinksToStorePath(i); + Path path = store->followLinksToStorePath(i); ensureLocalStore()->repairPath(path); } } @@ -847,7 +847,7 @@ static void opServe(Strings opFlags, Strings opArgs) case cmdQueryValidPaths: { bool lock = readInt(in); bool substitute = readInt(in); - PathSet paths = readStorePaths<PathSet>(in); + PathSet paths = readStorePaths<PathSet>(*store, in); if (lock && writeAllowed) for (auto & path : paths) store->addTempRoot(path); @@ -879,7 +879,7 @@ static void opServe(Strings opFlags, Strings opArgs) } case cmdQueryPathInfos: { - PathSet paths = readStorePaths<PathSet>(in); + PathSet paths = readStorePaths<PathSet>(*store, in); // !!! Maybe we want a queryPathInfos? for (auto & i : paths) { try { @@ -896,7 +896,7 @@ static void opServe(Strings opFlags, Strings opArgs) } case cmdDumpStorePath: - dumpPath(readStorePath(in), out); + dumpPath(readStorePath(*store, in), out); break; case cmdImportPaths: { @@ -908,7 +908,7 @@ static void opServe(Strings opFlags, Strings opArgs) case cmdExportPaths: { readInt(in); // obsolete - Paths sorted = store->topoSortPaths(readStorePaths<PathSet>(in)); + Paths sorted = store->topoSortPaths(readStorePaths<PathSet>(*store, in)); reverse(sorted.begin(), sorted.end()); store->exportPaths(sorted, out); break; @@ -917,7 +917,7 @@ static void opServe(Strings opFlags, Strings opArgs) case cmdBuildPaths: { /* Used by build-remote.pl. */ if (!writeAllowed) throw Error("building paths is not allowed"); - PathSet paths = readStorePaths<PathSet>(in); + PathSet paths = readStorePaths<PathSet>(*store, in); getBuildSettings(); @@ -936,9 +936,9 @@ static void opServe(Strings opFlags, Strings opArgs) if (!writeAllowed) throw Error("building paths is not allowed"); - Path drvPath = readStorePath(in); // informational only + Path drvPath = readStorePath(*store, in); // informational only BasicDerivation drv; - in >> drv; + readDerivation(in, *store, drv); getBuildSettings(); @@ -952,7 +952,7 @@ static void opServe(Strings opFlags, Strings opArgs) case cmdQueryClosure: { bool includeOutputs = readInt(in); - PathSet paths = readStorePaths<PathSet>(in); + PathSet paths = readStorePaths<PathSet>(*store, in); PathSet closure; for (auto & i : paths) store->computeFSClosure(i, closure, false, includeOutputs); diff --git a/src/nix/command.cc b/src/nix/command.cc index 253c9686ba75..37534015b89f 100644 --- a/src/nix/command.cc +++ b/src/nix/command.cc @@ -102,7 +102,7 @@ void StorePathsCommand::run(ref<Store> store) else { for (auto & storePath : storePaths) - storePath = followLinksToStorePath(storePath); + storePath = store->followLinksToStorePath(storePath); if (recursive) { PathSet closure; diff --git a/src/nix/installables.cc b/src/nix/installables.cc index fb5a515825aa..6257c7679af9 100644 --- a/src/nix/installables.cc +++ b/src/nix/installables.cc @@ -17,7 +17,7 @@ UserEnvElems MixInstallables::evalInstallables(ref<Store> store) if (std::string(installable, 0, 1) == "/") { - if (isStorePath(installable)) { + if (store->isStorePath(installable)) { if (isDerivation(installable)) { UserEnvElem elem; |