mirror of
https://github.com/NixOS/nix.git
synced 2025-12-13 12:31:04 +01:00
daemon: Add WorkerProto serialiser for GCAction
Previously the daemon didn't validate that it got a valid GCAction and did a naive C-style cast to the enum. This is certainly unintentional, albeit mostly harmless in practice.
This commit is contained in:
parent
907a5761fa
commit
f2465bccba
5 changed files with 70 additions and 22 deletions
|
|
@ -743,7 +743,7 @@ static void performOp(
|
|||
|
||||
case WorkerProto::Op::CollectGarbage: {
|
||||
GCOptions options;
|
||||
options.action = (GCOptions::GCAction) readInt(conn.from);
|
||||
options.action = WorkerProto::Serialise<GCOptions::GCAction>::read(*store, rconn);
|
||||
options.pathsToDelete = WorkerProto::Serialise<StorePathSet>::read(*store, rconn);
|
||||
conn.from >> options.ignoreLiveness >> options.maxFreed;
|
||||
// obsolete fields
|
||||
|
|
|
|||
|
|
@ -13,9 +13,7 @@ typedef boost::unordered_flat_map<
|
|||
std::hash<StorePath>>
|
||||
Roots;
|
||||
|
||||
struct GCOptions
|
||||
{
|
||||
/**
|
||||
/**
|
||||
* Garbage collector operation:
|
||||
*
|
||||
* - `gcReturnLive`: return the set of paths reachable from
|
||||
|
|
@ -29,12 +27,17 @@ struct GCOptions
|
|||
* - `gcDeleteSpecific`: delete the paths listed in
|
||||
* `pathsToDelete`, insofar as they are not reachable.
|
||||
*/
|
||||
typedef enum {
|
||||
enum class GCAction {
|
||||
gcReturnLive,
|
||||
gcReturnDead,
|
||||
gcDeleteDead,
|
||||
gcDeleteSpecific,
|
||||
} GCAction;
|
||||
};
|
||||
|
||||
struct GCOptions
|
||||
{
|
||||
using GCAction = nix::GCAction;
|
||||
using enum GCAction;
|
||||
|
||||
GCAction action{gcDeleteDead};
|
||||
|
||||
|
|
|
|||
|
|
@ -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<TrustedFlag>);
|
||||
template<>
|
||||
DECLARE_WORKER_SERIALISER(std::optional<std::chrono::microseconds>);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<BuildMode>::write(
|
|||
};
|
||||
}
|
||||
|
||||
GCAction WorkerProto::Serialise<GCAction>::read(const StoreDirConfig & store, WorkerProto::ReadConn conn)
|
||||
{
|
||||
auto temp = readNum<unsigned>(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<GCAction>::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<TrustedFlag>
|
||||
WorkerProto::Serialise<std::optional<TrustedFlag>>::read(const StoreDirConfig & store, WorkerProto::ReadConn conn)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue