diff options
author | Ludovic Courtès <ludo@gnu.org> | 2025-04-11 23:29:51 +0200 |
---|---|---|
committer | Ludovic Courtès <ludo@gnu.org> | 2025-04-14 17:33:11 +0200 |
commit | dd947985522886f9de6fdfdde3f0601e42219da5 (patch) | |
tree | 1f32a42658a61bd212cf1c7730ccc1bed5809f5f | |
parent | dfac0a5a9526805334bd7f72926b77b5d46f59db (diff) | |
download | guix-dd947985522886f9de6fdfdde3f0601e42219da5.tar.gz guix-dd947985522886f9de6fdfdde3f0601e42219da5.zip |
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.cc | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/nix/nix-daemon/nix-daemon.cc b/nix/nix-daemon/nix-daemon.cc index 4cb05c802e..e29237e65d 100644 --- a/nix/nix-daemon/nix-daemon.cc +++ b/nix/nix-daemon/nix-daemon.cc @@ -165,6 +165,24 @@ static void setSigPollAction(bool enable) #endif } +static void handleSignal(int signum) +{ + string name = program_invocation_short_name; + auto message = name + ": PID " + std::to_string(getpid()) + + " caught signal " + std::to_string(signum) + "\n"; + writeFull(STDERR_FILENO, (unsigned char *) message.c_str(), message.length()); + _isInterrupted = 1; + blockInt = 1; +} + +static void setTerminationSignalHandler() +{ + auto signals = { SIGINT, SIGTERM, SIGHUP }; + for (int signum: signals) { + signal(signum, handleSignal); + } +} + /* startWork() means that we're starting an operation for which we want to send out stderr to the client. */ @@ -803,6 +821,10 @@ static void processConnection(bool trusted, uid_t userId) throw Error("if you run `nix-daemon' as root, then you MUST set `build-users-group'!"); #endif + /* Catch SIGTERM & co. to ensure proper termination: closing the store + and its database, thereby deleting its WAL file. */ + setTerminationSignalHandler(); + /* Open the store. */ store = std::shared_ptr<StoreAPI>(new LocalStore(reserveSpace)); |