aboutsummaryrefslogtreecommitdiff
path: root/src/libstore
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore')
-rw-r--r--src/libstore/build/local-derivation-goal.cc3
-rw-r--r--src/libstore/daemon.cc12
-rw-r--r--src/libstore/gc-store.cc13
-rw-r--r--src/libstore/gc-store.hh84
-rw-r--r--src/libstore/local-fs-store.hh3
-rw-r--r--src/libstore/local-store.hh3
-rw-r--r--src/libstore/path-with-outputs.cc6
-rw-r--r--src/libstore/remote-store.cc1
-rw-r--r--src/libstore/remote-store.hh3
-rw-r--r--src/libstore/store-api.hh73
10 files changed, 118 insertions, 83 deletions
diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc
index 7e69d4145..581d63d0e 100644
--- a/src/libstore/build/local-derivation-goal.cc
+++ b/src/libstore/build/local-derivation-goal.cc
@@ -1,4 +1,5 @@
#include "local-derivation-goal.hh"
+#include "gc-store.hh"
#include "hook-instance.hh"
#include "worker.hh"
#include "builtins.hh"
@@ -1127,7 +1128,7 @@ struct RestrictedStoreConfig : virtual LocalFSStoreConfig
/* A wrapper around LocalStore that only allows building/querying of
paths that are in the input closures of the build or were added via
recursive Nix calls. */
-struct RestrictedStore : public virtual RestrictedStoreConfig, public virtual LocalFSStore
+struct RestrictedStore : public virtual RestrictedStoreConfig, public virtual LocalFSStore, public virtual GcStore
{
ref<LocalStore> next;
diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc
index 9d4f6b4a4..89d9487da 100644
--- a/src/libstore/daemon.cc
+++ b/src/libstore/daemon.cc
@@ -3,6 +3,7 @@
#include "worker-protocol.hh"
#include "build-result.hh"
#include "store-api.hh"
+#include "gc-store.hh"
#include "path-with-outputs.hh"
#include "finally.hh"
#include "archive.hh"
@@ -623,9 +624,12 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
case wopAddIndirectRoot: {
Path path = absPath(readString(from));
+
logger->startWork();
- store->addIndirectRoot(path);
+ auto & gcStore = requireGcStore(*store);
+ gcStore.addIndirectRoot(path);
logger->stopWork();
+
to << 1;
break;
}
@@ -640,7 +644,8 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
case wopFindRoots: {
logger->startWork();
- Roots roots = store->findRoots(!trusted);
+ auto & gcStore = requireGcStore(*store);
+ Roots roots = gcStore.findRoots(!trusted);
logger->stopWork();
size_t size = 0;
@@ -671,7 +676,8 @@ static void performOp(TunnelLogger * logger, ref<Store> store,
logger->startWork();
if (options.ignoreLiveness)
throw Error("you are not allowed to ignore liveness");
- store->collectGarbage(options, results);
+ auto & gcStore = requireGcStore(*store);
+ gcStore.collectGarbage(options, results);
logger->stopWork();
to << results.paths << results.bytesFreed << 0 /* obsolete */;
diff --git a/src/libstore/gc-store.cc b/src/libstore/gc-store.cc
new file mode 100644
index 000000000..3dbdec53b
--- /dev/null
+++ b/src/libstore/gc-store.cc
@@ -0,0 +1,13 @@
+#include "gc-store.hh"
+
+namespace nix {
+
+GcStore & requireGcStore(Store & store)
+{
+ auto * gcStore = dynamic_cast<GcStore *>(&store);
+ if (!gcStore)
+ throw UsageError("Garbage collection not supported by this store");
+ return *gcStore;
+}
+
+}
diff --git a/src/libstore/gc-store.hh b/src/libstore/gc-store.hh
new file mode 100644
index 000000000..829f70dc4
--- /dev/null
+++ b/src/libstore/gc-store.hh
@@ -0,0 +1,84 @@
+#pragma once
+
+#include "store-api.hh"
+
+
+namespace nix {
+
+
+typedef std::unordered_map<StorePath, std::unordered_set<std::string>> Roots;
+
+
+struct GCOptions
+{
+ /* Garbage collector operation:
+
+ - `gcReturnLive': return the set of paths reachable from
+ (i.e. in the closure of) the roots.
+
+ - `gcReturnDead': return the set of paths not reachable from
+ the roots.
+
+ - `gcDeleteDead': actually delete the latter set.
+
+ - `gcDeleteSpecific': delete the paths listed in
+ `pathsToDelete', insofar as they are not reachable.
+ */
+ typedef enum {
+ gcReturnLive,
+ gcReturnDead,
+ gcDeleteDead,
+ gcDeleteSpecific,
+ } GCAction;
+
+ GCAction action{gcDeleteDead};
+
+ /* If `ignoreLiveness' is set, then reachability from the roots is
+ ignored (dangerous!). However, the paths must still be
+ unreferenced *within* the store (i.e., there can be no other
+ store paths that depend on them). */
+ bool ignoreLiveness{false};
+
+ /* For `gcDeleteSpecific', the paths to delete. */
+ StorePathSet pathsToDelete;
+
+ /* Stop after at least `maxFreed' bytes have been freed. */
+ uint64_t maxFreed{std::numeric_limits<uint64_t>::max()};
+};
+
+
+struct GCResults
+{
+ /* Depending on the action, the GC roots, or the paths that would
+ be or have been deleted. */
+ PathSet paths;
+
+ /* For `gcReturnDead', `gcDeleteDead' and `gcDeleteSpecific', the
+ number of bytes that would be or was freed. */
+ uint64_t bytesFreed = 0;
+};
+
+
+struct GcStore : public virtual Store
+{
+ /* Add an indirect root, which is merely a symlink to `path' from
+ /nix/var/nix/gcroots/auto/<hash of `path'>. `path' is supposed
+ to be a symlink to a store path. The garbage collector will
+ automatically remove the indirect root when it finds that
+ `path' has disappeared. */
+ virtual void addIndirectRoot(const Path & path) = 0;
+
+ /* Find the roots of the garbage collector. Each root is a pair
+ (link, storepath) where `link' is the path of the symlink
+ outside of the Nix store that point to `storePath'. If
+ 'censor' is true, privacy-sensitive information about roots
+ found in /proc is censored. */
+ virtual Roots findRoots(bool censor) = 0;
+
+ /* Perform a garbage collection. */
+ virtual void collectGarbage(const GCOptions & options, GCResults & results) = 0;
+};
+
+GcStore & requireGcStore(Store & store);
+
+}
diff --git a/src/libstore/local-fs-store.hh b/src/libstore/local-fs-store.hh
index d34f0cb62..fbd49dc2c 100644
--- a/src/libstore/local-fs-store.hh
+++ b/src/libstore/local-fs-store.hh
@@ -1,6 +1,7 @@
#pragma once
#include "store-api.hh"
+#include "gc-store.hh"
namespace nix {
@@ -23,7 +24,7 @@ struct LocalFSStoreConfig : virtual StoreConfig
"physical path to the Nix store"};
};
-class LocalFSStore : public virtual LocalFSStoreConfig, public virtual Store
+class LocalFSStore : public virtual LocalFSStoreConfig, public virtual Store, virtual GcStore
{
public:
diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh
index 1a278c9a8..70d225be3 100644
--- a/src/libstore/local-store.hh
+++ b/src/libstore/local-store.hh
@@ -5,6 +5,7 @@
#include "pathlocks.hh"
#include "store-api.hh"
#include "local-fs-store.hh"
+#include "gc-store.hh"
#include "sync.hh"
#include "util.hh"
@@ -43,7 +44,7 @@ struct LocalStoreConfig : virtual LocalFSStoreConfig
};
-class LocalStore : public virtual LocalStoreConfig, public virtual LocalFSStore
+class LocalStore : public virtual LocalStoreConfig, public virtual LocalFSStore, public virtual GcStore
{
private:
diff --git a/src/libstore/path-with-outputs.cc b/src/libstore/path-with-outputs.cc
index 97aa01b57..078c117bd 100644
--- a/src/libstore/path-with-outputs.cc
+++ b/src/libstore/path-with-outputs.cc
@@ -22,9 +22,9 @@ DerivedPath StorePathWithOutputs::toDerivedPath() const
std::vector<DerivedPath> toDerivedPaths(const std::vector<StorePathWithOutputs> ss)
{
- std::vector<DerivedPath> reqs;
- for (auto & s : ss) reqs.push_back(s.toDerivedPath());
- return reqs;
+ std::vector<DerivedPath> reqs;
+ for (auto & s : ss) reqs.push_back(s.toDerivedPath());
+ return reqs;
}
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index cbcb75c00..a25398ef2 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -1,6 +1,7 @@
#include "serialise.hh"
#include "util.hh"
#include "path-with-outputs.hh"
+#include "gc-store.hh"
#include "remote-fs-accessor.hh"
#include "build-result.hh"
#include "remote-store.hh"
diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh
index b94216d31..2628206b1 100644
--- a/src/libstore/remote-store.hh
+++ b/src/libstore/remote-store.hh
@@ -4,6 +4,7 @@
#include <string>
#include "store-api.hh"
+#include "gc-store.hh"
namespace nix {
@@ -29,7 +30,7 @@ struct RemoteStoreConfig : virtual StoreConfig
/* FIXME: RemoteStore is a misnomer - should be something like
DaemonStore. */
-class RemoteStore : public virtual RemoteStoreConfig, public virtual Store
+class RemoteStore : public virtual RemoteStoreConfig, public virtual Store, public virtual GcStore
{
public:
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index 8c57596d0..7bd21519c 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -76,59 +76,6 @@ enum AllowInvalidFlag : bool { DisallowInvalid = false, AllowInvalid = true };
const uint32_t exportMagic = 0x4558494e;
-typedef std::unordered_map<StorePath, std::unordered_set<std::string>> Roots;
-
-
-struct GCOptions
-{
- /* Garbage collector operation:
-
- - `gcReturnLive': return the set of paths reachable from
- (i.e. in the closure of) the roots.
-
- - `gcReturnDead': return the set of paths not reachable from
- the roots.
-
- - `gcDeleteDead': actually delete the latter set.
-
- - `gcDeleteSpecific': delete the paths listed in
- `pathsToDelete', insofar as they are not reachable.
- */
- typedef enum {
- gcReturnLive,
- gcReturnDead,
- gcDeleteDead,
- gcDeleteSpecific,
- } GCAction;
-
- GCAction action{gcDeleteDead};
-
- /* If `ignoreLiveness' is set, then reachability from the roots is
- ignored (dangerous!). However, the paths must still be
- unreferenced *within* the store (i.e., there can be no other
- store paths that depend on them). */
- bool ignoreLiveness{false};
-
- /* For `gcDeleteSpecific', the paths to delete. */
- StorePathSet pathsToDelete;
-
- /* Stop after at least `maxFreed' bytes have been freed. */
- uint64_t maxFreed{std::numeric_limits<uint64_t>::max()};
-};
-
-
-struct GCResults
-{
- /* Depending on the action, the GC roots, or the paths that would
- be or have been deleted. */
- PathSet paths;
-
- /* For `gcReturnDead', `gcDeleteDead' and `gcDeleteSpecific', the
- number of bytes that would be or was freed. */
- uint64_t bytesFreed = 0;
-};
-
-
enum BuildMode { bmNormal, bmRepair, bmCheck };
struct BuildResult;
@@ -531,26 +478,6 @@ public:
virtual void addTempRoot(const StorePath & path)
{ debug("not creating temporary root, store doesn't support GC"); }
- /* Add an indirect root, which is merely a symlink to `path' from
- /nix/var/nix/gcroots/auto/<hash of `path'>. `path' is supposed
- to be a symlink to a store path. The garbage collector will
- automatically remove the indirect root when it finds that
- `path' has disappeared. */
- virtual void addIndirectRoot(const Path & path)
- { unsupported("addIndirectRoot"); }
-
- /* Find the roots of the garbage collector. Each root is a pair
- (link, storepath) where `link' is the path of the symlink
- outside of the Nix store that point to `storePath'. If
- 'censor' is true, privacy-sensitive information about roots
- found in /proc is censored. */
- virtual Roots findRoots(bool censor)
- { unsupported("findRoots"); }
-
- /* Perform a garbage collection. */
- virtual void collectGarbage(const GCOptions & options, GCResults & results)
- { unsupported("collectGarbage"); }
-
/* Return a string representing information about the path that
can be loaded into the database using `nix-store --load-db' or
`nix-store --register-validity'. */