diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc index 1bf3b917d..4d1c9078f 100644 --- a/src/libstore/daemon.cc +++ b/src/libstore/daemon.cc @@ -743,7 +743,7 @@ static void performOp( case WorkerProto::Op::CollectGarbage: { GCOptions options; - options.action = (GCOptions::GCAction) readInt(conn.from); + options.action = WorkerProto::Serialise::read(*store, rconn); options.pathsToDelete = WorkerProto::Serialise::read(*store, rconn); conn.from >> options.ignoreLiveness >> options.maxFreed; // obsolete fields diff --git a/src/libstore/include/nix/store/gc-store.hh b/src/libstore/include/nix/store/gc-store.hh index 5a4a6db14..7f04ed5a2 100644 --- a/src/libstore/include/nix/store/gc-store.hh +++ b/src/libstore/include/nix/store/gc-store.hh @@ -13,28 +13,31 @@ typedef boost::unordered_flat_map< std::hash> Roots; +/** + * 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. + */ +enum class GCAction { + gcReturnLive, + gcReturnDead, + gcDeleteDead, + gcDeleteSpecific, +}; + 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; + using GCAction = nix::GCAction; + using enum GCAction; GCAction action{gcDeleteDead}; diff --git a/src/libstore/include/nix/store/worker-protocol.hh b/src/libstore/include/nix/store/worker-protocol.hh index 6ae5fdcbc..87ef2a399 100644 --- a/src/libstore/include/nix/store/worker-protocol.hh +++ b/src/libstore/include/nix/store/worker-protocol.hh @@ -37,6 +37,7 @@ struct ValidPathInfo; struct UnkeyedValidPathInfo; enum BuildMode : uint8_t; enum TrustedFlag : bool; +enum class GCAction; /** * The "worker protocol", used by unix:// and ssh-ng:// stores. @@ -263,6 +264,8 @@ DECLARE_WORKER_SERIALISER(UnkeyedValidPathInfo); template<> DECLARE_WORKER_SERIALISER(BuildMode); template<> +DECLARE_WORKER_SERIALISER(GCAction); +template<> DECLARE_WORKER_SERIALISER(std::optional); template<> DECLARE_WORKER_SERIALISER(std::optional); diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index b07efc024..6d1204570 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -694,7 +694,8 @@ void RemoteStore::collectGarbage(const GCOptions & options, GCResults & results) { auto conn(getConnection()); - conn->to << WorkerProto::Op::CollectGarbage << options.action; + conn->to << WorkerProto::Op::CollectGarbage; + WorkerProto::write(*this, *conn, options.action); WorkerProto::write(*this, *conn, options.pathsToDelete); conn->to << options.ignoreLiveness << options.maxFreed diff --git a/src/libstore/worker-protocol.cc b/src/libstore/worker-protocol.cc index d13f8f3f6..2788222c0 100644 --- a/src/libstore/worker-protocol.cc +++ b/src/libstore/worker-protocol.cc @@ -1,6 +1,7 @@ #include "nix/util/serialise.hh" #include "nix/store/path-with-outputs.hh" #include "nix/store/store-api.hh" +#include "nix/store/gc-store.hh" #include "nix/store/build-result.hh" #include "nix/store/worker-protocol.hh" #include "nix/store/worker-protocol-impl.hh" @@ -47,6 +48,46 @@ void WorkerProto::Serialise::write( }; } +GCAction WorkerProto::Serialise::read(const StoreDirConfig & store, WorkerProto::ReadConn conn) +{ + auto temp = readNum(conn.from); + using enum GCAction; + switch (temp) { + case 0: + return gcReturnLive; + case 1: + return gcReturnDead; + case 2: + return gcDeleteDead; + case 3: + return gcDeleteSpecific; + default: + throw Error("Invalid GC action"); + } +} + +void WorkerProto::Serialise::write( + const StoreDirConfig & store, WorkerProto::WriteConn conn, const GCAction & action) +{ + using enum GCAction; + switch (action) { + case gcReturnLive: + conn.to << unsigned{0}; + break; + case gcReturnDead: + conn.to << unsigned{1}; + break; + case gcDeleteDead: + conn.to << unsigned{2}; + break; + case gcDeleteSpecific: + conn.to << unsigned{3}; + break; + default: + assert(false); + } +} + std::optional WorkerProto::Serialise>::read(const StoreDirConfig & store, WorkerProto::ReadConn conn) {