mirror of
https://github.com/NixOS/nix.git
synced 2025-12-13 20:41: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: {
|
case WorkerProto::Op::CollectGarbage: {
|
||||||
GCOptions options;
|
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);
|
options.pathsToDelete = WorkerProto::Serialise<StorePathSet>::read(*store, rconn);
|
||||||
conn.from >> options.ignoreLiveness >> options.maxFreed;
|
conn.from >> options.ignoreLiveness >> options.maxFreed;
|
||||||
// obsolete fields
|
// obsolete fields
|
||||||
|
|
|
||||||
|
|
@ -13,28 +13,31 @@ typedef boost::unordered_flat_map<
|
||||||
std::hash<StorePath>>
|
std::hash<StorePath>>
|
||||||
Roots;
|
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
|
struct GCOptions
|
||||||
{
|
{
|
||||||
/**
|
using GCAction = nix::GCAction;
|
||||||
* Garbage collector operation:
|
using enum GCAction;
|
||||||
*
|
|
||||||
* - `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};
|
GCAction action{gcDeleteDead};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ struct ValidPathInfo;
|
||||||
struct UnkeyedValidPathInfo;
|
struct UnkeyedValidPathInfo;
|
||||||
enum BuildMode : uint8_t;
|
enum BuildMode : uint8_t;
|
||||||
enum TrustedFlag : bool;
|
enum TrustedFlag : bool;
|
||||||
|
enum class GCAction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The "worker protocol", used by unix:// and ssh-ng:// stores.
|
* The "worker protocol", used by unix:// and ssh-ng:// stores.
|
||||||
|
|
@ -263,6 +264,8 @@ DECLARE_WORKER_SERIALISER(UnkeyedValidPathInfo);
|
||||||
template<>
|
template<>
|
||||||
DECLARE_WORKER_SERIALISER(BuildMode);
|
DECLARE_WORKER_SERIALISER(BuildMode);
|
||||||
template<>
|
template<>
|
||||||
|
DECLARE_WORKER_SERIALISER(GCAction);
|
||||||
|
template<>
|
||||||
DECLARE_WORKER_SERIALISER(std::optional<TrustedFlag>);
|
DECLARE_WORKER_SERIALISER(std::optional<TrustedFlag>);
|
||||||
template<>
|
template<>
|
||||||
DECLARE_WORKER_SERIALISER(std::optional<std::chrono::microseconds>);
|
DECLARE_WORKER_SERIALISER(std::optional<std::chrono::microseconds>);
|
||||||
|
|
|
||||||
|
|
@ -694,7 +694,8 @@ void RemoteStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||||
{
|
{
|
||||||
auto conn(getConnection());
|
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);
|
WorkerProto::write(*this, *conn, options.pathsToDelete);
|
||||||
conn->to << options.ignoreLiveness
|
conn->to << options.ignoreLiveness
|
||||||
<< options.maxFreed
|
<< options.maxFreed
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#include "nix/util/serialise.hh"
|
#include "nix/util/serialise.hh"
|
||||||
#include "nix/store/path-with-outputs.hh"
|
#include "nix/store/path-with-outputs.hh"
|
||||||
#include "nix/store/store-api.hh"
|
#include "nix/store/store-api.hh"
|
||||||
|
#include "nix/store/gc-store.hh"
|
||||||
#include "nix/store/build-result.hh"
|
#include "nix/store/build-result.hh"
|
||||||
#include "nix/store/worker-protocol.hh"
|
#include "nix/store/worker-protocol.hh"
|
||||||
#include "nix/store/worker-protocol-impl.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>
|
std::optional<TrustedFlag>
|
||||||
WorkerProto::Serialise<std::optional<TrustedFlag>>::read(const StoreDirConfig & store, WorkerProto::ReadConn conn)
|
WorkerProto::Serialise<std::optional<TrustedFlag>>::read(const StoreDirConfig & store, WorkerProto::ReadConn conn)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue