From 812c0dfbe24c8fe93992f77abbf1e5a975ea42f4 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 2 Jun 2016 13:33:49 +0200 Subject: Allow setting the state directory as a store parameter E.g. "local?store=/tmp/store&state=/tmp/var". --- src/libstore/gc.cc | 34 +++++++++++++++------------------- src/libstore/local-fs-store.cc | 7 +++++++ src/libstore/local-store.cc | 27 +++++++++++---------------- src/libstore/local-store.hh | 12 ++++++++++-- src/libstore/profiles.cc | 2 +- src/libstore/profiles.hh | 4 ++-- src/libstore/store-api.cc | 5 +++-- src/libstore/store-api.hh | 14 ++++++++------ 8 files changed, 57 insertions(+), 48 deletions(-) (limited to 'src/libstore') diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index df48e8b662e1..e5be048d8d81 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -29,7 +29,7 @@ static string gcRootsDir = "gcroots"; int LocalStore::openGCLock(LockType lockType) { Path fnGCLock = (format("%1%/%2%") - % settings.nixStateDir % gcLockName).str(); + % stateDir % gcLockName).str(); debug(format("acquiring global GC lock ‘%1%’") % fnGCLock); @@ -78,12 +78,12 @@ void LocalStore::addIndirectRoot(const Path & path) { string hash = printHash32(hashString(htSHA1, path)); Path realRoot = canonPath((format("%1%/%2%/auto/%3%") - % settings.nixStateDir % gcRootsDir % hash).str()); + % stateDir % gcRootsDir % hash).str()); makeSymlink(realRoot, path); } -Path Store::addPermRoot(const Path & _storePath, +Path LocalFSStore::addPermRoot(const Path & _storePath, const Path & _gcRoot, bool indirect, bool allowOutsideRootsDir) { Path storePath(canonPath(_storePath)); @@ -106,7 +106,7 @@ Path Store::addPermRoot(const Path & _storePath, else { if (!allowOutsideRootsDir) { - Path rootsDir = canonPath((format("%1%/%2%") % settings.nixStateDir % gcRootsDir).str()); + Path rootsDir = canonPath((format("%1%/%2%") % stateDir % gcRootsDir).str()); if (string(gcRoot, 0, rootsDir.size() + 1) != rootsDir + "/") throw Error(format( @@ -153,7 +153,7 @@ void LocalStore::addTempRoot(const Path & path) if (state->fdTempRoots == -1) { while (1) { - Path dir = (format("%1%/%2%") % settings.nixStateDir % tempRootsDir).str(); + Path dir = (format("%1%/%2%") % stateDir % tempRootsDir).str(); createDirs(dir); state->fnTempRoots = (format("%1%/%2%") % dir % getpid()).str(); @@ -200,19 +200,15 @@ void LocalStore::addTempRoot(const Path & path) } -typedef std::shared_ptr FDPtr; -typedef list FDs; - - -static void readTempRoots(Store & store, PathSet & tempRoots, FDs & fds) +void LocalStore::readTempRoots(PathSet & tempRoots, FDs & fds) { /* Read the `temproots' directory for per-process temporary root files. */ DirEntries tempRootFiles = readDirectory( - (format("%1%/%2%") % settings.nixStateDir % tempRootsDir).str()); + (format("%1%/%2%") % stateDir % tempRootsDir).str()); for (auto & i : tempRootFiles) { - Path path = (format("%1%/%2%/%3%") % settings.nixStateDir % tempRootsDir % i.name).str(); + Path path = (format("%1%/%2%/%3%") % stateDir % tempRootsDir % i.name).str(); debug(format("reading temporary root file ‘%1%’") % path); FDPtr fd(new AutoCloseFD(open(path.c_str(), O_RDWR, 0666))); @@ -251,7 +247,7 @@ static void readTempRoots(Store & store, 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); - store.assertStorePath(root); + assertStorePath(root); tempRoots.insert(root); pos = end + 1; } @@ -290,7 +286,7 @@ void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots) else { target = absPath(target, dirOf(path)); if (!pathExists(target)) { - if (isInDir(path, settings.nixStateDir + "/" + gcRootsDir + "/auto")) { + if (isInDir(path, stateDir + "/" + gcRootsDir + "/auto")) { printMsg(lvlInfo, format("removing stale link from ‘%1%’ to ‘%2%’") % path % target); unlink(path.c_str()); } @@ -326,10 +322,10 @@ Roots LocalStore::findRoots() Roots roots; /* Process direct roots in {gcroots,manifests,profiles}. */ - findRoots(settings.nixStateDir + "/" + gcRootsDir, DT_UNKNOWN, roots); - if (pathExists(settings.nixStateDir + "/manifests")) - findRoots(settings.nixStateDir + "/manifests", DT_UNKNOWN, roots); - findRoots(settings.nixStateDir + "/profiles", DT_UNKNOWN, roots); + findRoots(stateDir + "/" + gcRootsDir, DT_UNKNOWN, roots); + if (pathExists(stateDir + "/manifests")) + findRoots(stateDir + "/manifests", DT_UNKNOWN, roots); + findRoots(stateDir + "/profiles", DT_UNKNOWN, roots); return roots; } @@ -635,7 +631,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(*this, state.tempRoots, fds); + readTempRoots(state.tempRoots, fds); state.roots.insert(state.tempRoots.begin(), state.tempRoots.end()); /* After this point the set of roots or temporary roots cannot diff --git a/src/libstore/local-fs-store.cc b/src/libstore/local-fs-store.cc index ea9c6b541a1f..a19e4ce5dbc9 100644 --- a/src/libstore/local-fs-store.cc +++ b/src/libstore/local-fs-store.cc @@ -1,9 +1,16 @@ #include "archive.hh" #include "fs-accessor.hh" #include "store-api.hh" +#include "globals.hh" namespace nix { +LocalFSStore::LocalFSStore(const Params & params) + : Store(params) + , stateDir(get(params, "state", settings.nixStateDir)) +{ +} + struct LocalStoreAccessor : public FSAccessor { ref store; diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 7588d4b073a9..e1ff94d2ce75 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -38,9 +38,10 @@ namespace nix { LocalStore::LocalStore(const Params & params) : LocalFSStore(params) + , dbDir(get(params, "state", "") != "" ? get(params, "state", "") + "/db" : settings.nixDBPath) , linksDir(storeDir + "/.links") - , reservedPath(settings.nixDBPath + "/reserved") - , schemaPath(settings.nixDBPath + "/schema") + , reservedPath(dbDir + "/reserved") + , schemaPath(dbDir + "/schema") , requireSigs(settings.get("signed-binary-caches", std::string("")) != "") // FIXME: rename option , publicKeys(getDefaultPublicKeys()) { @@ -55,11 +56,11 @@ LocalStore::LocalStore(const Params & params) createDirs(storeDir); makeStoreWritable(); createDirs(linksDir); - Path profilesDir = settings.nixStateDir + "/profiles"; + Path profilesDir = stateDir + "/profiles"; createDirs(profilesDir); - createDirs(settings.nixStateDir + "/temproots"); - createDirs(settings.nixDBPath); - Path gcRootsDir = settings.nixStateDir + "/gcroots"; + createDirs(stateDir + "/temproots"); + createDirs(dbDir); + Path gcRootsDir = stateDir + "/gcroots"; if (!pathExists(gcRootsDir)) { createDirs(gcRootsDir); createSymlink(profilesDir, gcRootsDir + "/profiles"); @@ -135,7 +136,7 @@ LocalStore::LocalStore(const Params & params) /* Acquire the big fat lock in shared mode to make sure that no schema upgrade is in progress. */ try { - Path globalLockPath = settings.nixDBPath + "/big-lock"; + Path globalLockPath = dbDir + "/big-lock"; globalLock = openLockFile(globalLockPath.c_str(), true); } catch (SysError & e) { if (e.errNo != EACCES) throw; @@ -246,19 +247,13 @@ int LocalStore::getSchema() } -bool LocalStore::haveWriteAccess() -{ - return access(settings.nixDBPath.c_str(), R_OK | W_OK) == 0; -} - - void LocalStore::openDB(State & state, bool create) { - if (!haveWriteAccess()) - throw SysError(format("Nix database directory ‘%1%’ is not writable") % settings.nixDBPath); + if (access(dbDir.c_str(), R_OK | W_OK)) + throw SysError(format("Nix database directory ‘%1%’ is not writable") % dbDir); /* Open the Nix database. */ - string dbPath = settings.nixDBPath + "/db.sqlite"; + string dbPath = dbDir + "/db.sqlite"; auto & db(state.db); if (sqlite3_open_v2(dbPath.c_str(), &db.db, SQLITE_OPEN_READWRITE | (create ? SQLITE_OPEN_CREATE : 0), 0) != SQLITE_OK) diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index eb5fcf83360b..5166c04e5319 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -73,6 +73,7 @@ private: Sync _state; + const Path dbDir; const Path linksDir; const Path reservedPath; const Path schemaPath; @@ -146,6 +147,15 @@ public: void syncWithGC() override; +private: + + typedef std::shared_ptr FDPtr; + typedef list FDs; + + void readTempRoots(PathSet & tempRoots, FDs & fds); + +public: + Roots findRoots() override; void collectGarbage(const GCOptions & options, GCResults & results) override; @@ -179,8 +189,6 @@ public: void addSignatures(const Path & storePath, const StringSet & sigs) override; - static bool haveWriteAccess(); - private: int getSchema(); diff --git a/src/libstore/profiles.cc b/src/libstore/profiles.cc index 18e3bcbec4a3..449c88b576b6 100644 --- a/src/libstore/profiles.cc +++ b/src/libstore/profiles.cc @@ -74,7 +74,7 @@ static void makeName(const Path & profile, unsigned int num, } -Path createGeneration(ref store, Path profile, Path outPath) +Path createGeneration(ref store, Path profile, Path outPath) { /* The new generation number should be higher than old the previous ones. */ diff --git a/src/libstore/profiles.hh b/src/libstore/profiles.hh index d758d94b603c..1d4e6d3037db 100644 --- a/src/libstore/profiles.hh +++ b/src/libstore/profiles.hh @@ -31,9 +31,9 @@ typedef list Generations; profile, sorted by generation number. */ Generations findGenerations(Path profile, int & curGen); -class Store; +class LocalFSStore; -Path createGeneration(ref store, Path profile, Path outPath); +Path createGeneration(ref store, Path profile, Path outPath); void deleteGeneration(const Path & profile, unsigned int gen); diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index cea4b4b6ebcb..c6616a43d708 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -230,7 +230,7 @@ Path Store::computeStorePathForText(const string & name, const string & s, Store::Store(const Params & params) - : storeDir(settings.nixStore) + : storeDir(get(params, "store", settings.nixStore)) { } @@ -508,7 +508,8 @@ static RegisterStoreImplementation regStore([]( else return 0; if (mode == mAuto) { - if (LocalStore::haveWriteAccess()) + auto stateDir = get(params, "state", settings.nixStateDir); + if (access(stateDir.c_str(), R_OK | W_OK) == 0) mode = mLocal; else if (pathExists(settings.nixDaemonSocketFile)) mode = mDaemon; diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index 45cf7e7819a9..b665babc082c 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -372,10 +372,6 @@ public: `path' has disappeared. */ virtual void addIndirectRoot(const Path & path) = 0; - /* Register a permanent GC root. */ - Path addPermRoot(const Path & storePath, - const Path & gcRoot, bool indirect, bool allowOutsideRootsDir = false); - /* Acquire the global GC lock, then immediately release it. This function must be called after registering a new permanent root, but before exiting. Otherwise, it is possible that a running @@ -494,11 +490,17 @@ protected: class LocalFSStore : public Store { -protected: - using Store::Store; public: + const Path stateDir; + + LocalFSStore(const Params & params); + void narFromPath(const Path & path, Sink & sink) override; ref getFSAccessor() override; + + /* Register a permanent GC root. */ + Path addPermRoot(const Path & storePath, + const Path & gcRoot, bool indirect, bool allowOutsideRootsDir = false); }; -- cgit 1.4.1