Package: guix-patches;
Reported by: Carlo Zancanaro <carlo <at> zancanaro.id.au>
Date: Mon, 19 Feb 2018 17:13:02 UTC
Severity: normal
Tags: fixed, patch
Done: ludo <at> gnu.org (Ludovic Courtès)
Bug is archived. No further changes may be made.
Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
From: Carlo Zancanaro <carlo <at> zancanaro.id.au> To: guix-patches <at> gnu.org Subject: [PATCH] Shepherd: Terminate all services upon SIGTERM or SIGHUP Date: Tue, 20 Feb 2018 04:11:45 +1100
[Message part 1 (text/plain, inline)]
Hey, I use Shepherd to manage my user session, and if I log out then Shepherd leaves all my services running. This patch handles SIGTERM and SIGHUP to prevent that. I hope the guix-patches mailing list was the right place to send it. From what I understand Shepherd development is done through the guix lists, so it seemed to make the most sense to me. It's also worth noting that I had to run `gettextize` to get Shepherd to build on current master, but I haven't included those changes in this commit (because I don't know what should be committed and what shouldn't). Carlo
[0001-Terminate-all-services-upon-SIGTERM-or-SIGHUP.patch (text/x-patch, inline)]
From aabb9c6b1b52189d20339531de0b8b96bcace69f Mon Sep 17 00:00:00 2001 From: Carlo Zancanaro <carlo <at> zancanaro.id.au> Date: Tue, 20 Feb 2018 02:52:47 +1100 Subject: [PATCH] Terminate all services upon SIGTERM or SIGHUP * modules/shepherd.scm (main): Add SIGTERM and SIGHUP handlers which stop root-service. * tests/sigterm.sh, tests/sighup.sh: New files. * Makefile.am (TESTS): Add tests/sigterm.sh and tests/sighup.sh. --- Makefile.am | 5 ++++- modules/shepherd.scm | 11 ++++++++++ tests/sighup.sh | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/sigterm.sh | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 tests/sighup.sh create mode 100644 tests/sigterm.sh diff --git a/Makefile.am b/Makefile.am index a30b11d..021857d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,7 @@ # Makefile.am -- How to build and install the Shepherd. # Copyright © 2002, 2003 Wolfgang Jährling <wolfgang <at> pro-linux.de> # Copyright © 2013, 2014, 2015, 2016, 2018 Ludovic Courtès <ludo <at> gnu.org> +# Copyright © 2018 Carlo Zancanaro <carlo <at> zancanaro.id.au> # # This file is part of the GNU Shepherd. # @@ -188,7 +189,9 @@ TESTS = \ tests/no-home.sh \ tests/pid-file.sh \ tests/status-sexp.sh \ - tests/sigint.sh + tests/sigint.sh \ + tests/sigterm.sh \ + tests/sighup.sh TEST_EXTENSIONS = .sh EXTRA_DIST += $(TESTS) diff --git a/modules/shepherd.scm b/modules/shepherd.scm index 5334657..650ba63 100644 --- a/modules/shepherd.scm +++ b/modules/shepherd.scm @@ -1,6 +1,7 @@ ;; shepherd.scm -- The daemon shepherd. ;; Copyright (C) 2013, 2014, 2016, 2018 Ludovic Courtès <ludo <at> gnu.org> ;; Copyright (C) 2002, 2003 Wolfgang Jährling <wolfgang <at> pro-linux.de> +;; Copyright (C) 2018 Carlo Zancanaro <carlo <at> zancanaro.id.au> ;; ;; This file is part of the GNU Shepherd. ;; @@ -182,6 +183,16 @@ (lambda _ (stop root-service))) + ;; Stop everything when we get SIGTERM. + (sigaction SIGTERM + (lambda _ + (stop root-service))) + + ;; Stop everything when we get SIGHUP. + (sigaction SIGHUP + (lambda _ + (stop root-service))) + ;; Ignore SIGPIPE so that we don't die if a client closes the connection ;; prematurely. (sigaction SIGPIPE SIG_IGN) diff --git a/tests/sighup.sh b/tests/sighup.sh new file mode 100644 index 0000000..e9ca84b --- /dev/null +++ b/tests/sighup.sh @@ -0,0 +1,58 @@ +# GNU Shepherd --- Make sure SIGHUP is correctly handled. +# Copyright © 2014, 2016 Ludovic Courtès <ludo <at> gnu.org> +# Copyright © 2018 Carlo Zancanaro <carlo <at> zancanaro.id.au> +# +# This file is part of the GNU Shepherd. +# +# The GNU Shepherd is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or (at +# your option) any later version. +# +# The GNU Shepherd is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with the GNU Shepherd. If not, see <http://www.gnu.org/licenses/>. + +shepherd --version +herd --version + +socket="t-socket-$$" +conf="t-conf-$$" +log="t-log-$$" +stamp="t-stamp-$$" +pid="t-pid-$$" + +herd="herd -s $socket" + +trap "rm -f $socket $conf $stamp $log; + test -f $pid && kill \`cat $pid\` || true; rm -f $pid" EXIT + +cat > "$conf"<<EOF +(use-modules (srfi srfi-26)) +(register-services + (make <service> + #:provides '(test) + #:start (const #t) + #:stop (lambda _ + (call-with-output-file "$stamp" + (lambda (port) + (display "stopped" port)))) + #:respawn? #f)) + (start 'test) +EOF + +rm -f "$pid" "$stamp" +shepherd -I -s "$socket" -c "$conf" --pid="$pid" --log="$log" & + +while [ ! -f "$pid" ] ; do sleep 0.5 ; done + +# Send SIGTERM to shepherd. +kill -HUP "`cat "$pid"`" +while kill -0 "`cat "$pid"`" ; do sleep 0.5 ; done + +# Make sure the service's 'stop' method was called. +test -f "$stamp" diff --git a/tests/sigterm.sh b/tests/sigterm.sh new file mode 100644 index 0000000..f6b66be --- /dev/null +++ b/tests/sigterm.sh @@ -0,0 +1,58 @@ +# GNU Shepherd --- Make sure SIGTERM is correctly handled. +# Copyright © 2014, 2016 Ludovic Courtès <ludo <at> gnu.org> +# Copyright © 2018 Carlo Zancanaro <carlo <at> zancanaro.id.au> +# +# This file is part of the GNU Shepherd. +# +# The GNU Shepherd is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or (at +# your option) any later version. +# +# The GNU Shepherd is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with the GNU Shepherd. If not, see <http://www.gnu.org/licenses/>. + +shepherd --version +herd --version + +socket="t-socket-$$" +conf="t-conf-$$" +log="t-log-$$" +stamp="t-stamp-$$" +pid="t-pid-$$" + +herd="herd -s $socket" + +trap "rm -f $socket $conf $stamp $log; + test -f $pid && kill \`cat $pid\` || true; rm -f $pid" EXIT + +cat > "$conf"<<EOF +(use-modules (srfi srfi-26)) +(register-services + (make <service> + #:provides '(test) + #:start (const #t) + #:stop (lambda _ + (call-with-output-file "$stamp" + (lambda (port) + (display "stopped" port)))) + #:respawn? #f)) + (start 'test) +EOF + +rm -f "$pid" "$stamp" +shepherd -I -s "$socket" -c "$conf" --pid="$pid" --log="$log" & + +while [ ! -f "$pid" ] ; do sleep 0.5 ; done + +# Send SIGTERM to shepherd. +kill -TERM "`cat "$pid"`" +while kill -0 "`cat "$pid"`" ; do sleep 0.5 ; done + +# Make sure the service's 'stop' method was called. +test -f "$stamp" -- 2.16.1
[signature.asc (application/pgp-signature, inline)]
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.