From 6621195e48f8e0cbbe6e19dbcde30bd8a7da0399 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludovic=20Court=C3=A8s?= Date: Mon, 1 Sep 2014 22:21:42 +0200 Subject: [PATCH] Add an 'optimiseStore' remote procedure call. --- nix/libstore/local-store.hh | 3 +++ nix/libstore/optimise-store.cc | 16 ++++++++++++++++ nix/libstore/remote-store.cc | 7 +++++++ nix/libstore/remote-store.hh | 4 +++- nix/libstore/store-api.hh | 4 ++++ nix/libstore/worker-protocol.hh | 1 + nix/nix-daemon/nix-daemon.cc | 7 +++++++ 7 files changed, 41 insertions(+), 1 deletion(-) diff --git a/nix/libstore/local-store.hh b/nix/libstore/local-store.hh index e58e6563f1..dccdba533a 100644 --- a/nix/libstore/local-store.hh +++ b/nix/libstore/local-store.hh @@ -167,6 +167,9 @@ public: files with the same contents. */ void optimiseStore(OptimiseStats & stats); + /* Generic variant of the above method. */ + void optimiseStore(); + /* Optimise a single store path. */ void optimisePath(const Path & path); diff --git a/nix/libstore/optimise-store.cc b/nix/libstore/optimise-store.cc index 67ee94a4bd..8ba9d1a263 100644 --- a/nix/libstore/optimise-store.cc +++ b/nix/libstore/optimise-store.cc @@ -225,6 +225,22 @@ void LocalStore::optimiseStore(OptimiseStats & stats) } } +static string showBytes(unsigned long long bytes) +{ + return (format("%.2f MiB") % (bytes / (1024.0 * 1024.0))).str(); +} + +void LocalStore::optimiseStore() +{ + OptimiseStats stats; + + optimiseStore(stats); + + printMsg(lvlError, + format("%1% freed by hard-linking %2% files") + % showBytes(stats.bytesFreed) + % stats.filesLinked); +} void LocalStore::optimisePath(const Path & path) { diff --git a/nix/libstore/remote-store.cc b/nix/libstore/remote-store.cc index b3967bb241..f5fd141325 100644 --- a/nix/libstore/remote-store.cc +++ b/nix/libstore/remote-store.cc @@ -577,6 +577,13 @@ void RemoteStore::clearFailedPaths(const PathSet & paths) readInt(from); } +void RemoteStore::optimiseStore() +{ + openConnection(); + writeInt(wopOptimiseStore, to); + processStderr(); + readInt(from); +} void RemoteStore::processStderr(Sink * sink, Source * source) { diff --git a/nix/libstore/remote-store.hh b/nix/libstore/remote-store.hh index b010147643..98774c10b3 100644 --- a/nix/libstore/remote-store.hh +++ b/nix/libstore/remote-store.hh @@ -82,7 +82,9 @@ public: PathSet queryFailedPaths(); void clearFailedPaths(const PathSet & paths); - + + void optimiseStore(); + private: AutoCloseFD fdSocket; FdSink to; diff --git a/nix/libstore/store-api.hh b/nix/libstore/store-api.hh index b635fee2cf..3109f100ef 100644 --- a/nix/libstore/store-api.hh +++ b/nix/libstore/store-api.hh @@ -250,6 +250,10 @@ public: `nix-store --register-validity'. */ string makeValidityRegistration(const PathSet & paths, bool showDerivers, bool showHash); + + /* Optimise the disk space usage of the Nix store by hard-linking files + with the same contents. */ + virtual void optimiseStore() = 0; }; diff --git a/nix/libstore/worker-protocol.hh b/nix/libstore/worker-protocol.hh index c7d3a726ab..4b040b77ce 100644 --- a/nix/libstore/worker-protocol.hh +++ b/nix/libstore/worker-protocol.hh @@ -42,6 +42,7 @@ typedef enum { wopQueryValidPaths = 31, wopQuerySubstitutablePaths = 32, wopQueryValidDerivers = 33, + wopOptimiseStore = 34 } WorkerOp; diff --git a/nix/nix-daemon/nix-daemon.cc b/nix/nix-daemon/nix-daemon.cc index 88edb0425d..9cfa343d63 100644 --- a/nix/nix-daemon/nix-daemon.cc +++ b/nix/nix-daemon/nix-daemon.cc @@ -640,6 +640,13 @@ static void performOp(bool trusted, unsigned int clientVersion, break; } + case wopOptimiseStore: + startWork(); + store->optimiseStore(); + stopWork(); + writeInt(1, to); + break; + default: throw Error(format("invalid operation %1%") % op); }