summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2025-04-11 23:29:51 +0200
committerLudovic Courtès <ludo@gnu.org>2025-04-14 17:33:11 +0200
commitdd947985522886f9de6fdfdde3f0601e42219da5 (patch)
tree1f32a42658a61bd212cf1c7730ccc1bed5809f5f
parentdfac0a5a9526805334bd7f72926b77b5d46f59db (diff)
daemon: Catch SIGINT, SIGTERM, and SIGHUP for proper termination.
Previously the daemon would not install handlers for these signals. It would thus terminate abruptly when receiving them, without properly closing the SQLite database. Consequently, the database’s WAL file, which is normally deleted by the last client closing the database (via ‘sqlite3_close’), would not be deleted when the guix-daemon process is terminated; instead, it would persist and possibly keep growing beyond reason. This patch fixes that. * nix/nix-daemon/nix-daemon.cc (handleSignal, setTerminationSignalHandler): New functions. (processConnection): Call it. Reported-by: Christopher Baines <mail@cbaines.net> Change-Id: I07e510a1242e92b6a629d60eb840e029c0f921be
-rw-r--r--nix/nix-daemon/nix-daemon.cc22
1 files changed, 22 insertions, 0 deletions
diff --git a/nix/nix-daemon/nix-daemon.cc b/nix/nix-daemon/nix-daemon.cc
index 4cb05c802e0..e29237e65dd 100644
--- a/nix/nix-daemon/nix-daemon.cc
+++ b/nix/nix-daemon/nix-daemon.cc
@@ -165,6 +165,24 @@ static void setSigPollAction(bool enable)
165#endif 165#endif
166} 166}
167 167
168static void handleSignal(int signum)
169{
170 string name = program_invocation_short_name;
171 auto message = name + ": PID " + std::to_string(getpid())
172 + " caught signal " + std::to_string(signum) + "\n";
173 writeFull(STDERR_FILENO, (unsigned char *) message.c_str(), message.length());
174 _isInterrupted = 1;
175 blockInt = 1;
176}
177
178static void setTerminationSignalHandler()
179{
180 auto signals = { SIGINT, SIGTERM, SIGHUP };
181 for (int signum: signals) {
182 signal(signum, handleSignal);
183 }
184}
185
168 186
169/* startWork() means that we're starting an operation for which we 187/* startWork() means that we're starting an operation for which we
170 want to send out stderr to the client. */ 188 want to send out stderr to the client. */
@@ -803,6 +821,10 @@ static void processConnection(bool trusted, uid_t userId)
803 throw Error("if you run `nix-daemon' as root, then you MUST set `build-users-group'!"); 821 throw Error("if you run `nix-daemon' as root, then you MUST set `build-users-group'!");
804#endif 822#endif
805 823
824 /* Catch SIGTERM & co. to ensure proper termination: closing the store
825 and its database, thereby deleting its WAL file. */
826 setTerminationSignalHandler();
827
806 /* Open the store. */ 828 /* Open the store. */
807 store = std::shared_ptr<StoreAPI>(new LocalStore(reserveSpace)); 829 store = std::shared_ptr<StoreAPI>(new LocalStore(reserveSpace));
808 830