guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[shepherd] 02/07: Make sure ctrl-alt-del is handled by PID 1.


From: Ludovic Courtès
Subject: [shepherd] 02/07: Make sure ctrl-alt-del is handled by PID 1.
Date: Wed, 19 Sep 2018 11:44:27 -0400 (EDT)

civodul pushed a commit to branch master
in repository shepherd.

commit b8193d14a536611bd5afd4b7d013a74af65c37fb
Author: Ludovic Courtès <address@hidden>
Date:   Wed Sep 19 12:43:02 2018 +0200

    Make sure ctrl-alt-del is handled by PID 1.
    
    * configure.ac: Set RB_DISABLE_CAD to "#f" on GNU/Hurd and other OSes.
    Substitute it.
    * modules/shepherd.scm (main): Call 'disable-reboot-on-ctrl-alt-del'
    when running as PID 1.  In SIGINT handler, catch 'quit to make sure we
    reboot.
    (quit-exception-handler): New procedure.
    (process-command): Use it.
    * modules/shepherd/system.scm.in (RB_DISABLE_CAD): New variable.
    (disable-reboot-on-ctrl-alt-del): New procedure.
---
 configure.ac                   |  3 +++
 modules/shepherd.scm           | 34 ++++++++++++++++++++++------------
 modules/shepherd/system.scm.in | 11 ++++++++++-
 3 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/configure.ac b/configure.ac
index a5e2d21..0039093 100644
--- a/configure.ac
+++ b/configure.ac
@@ -64,15 +64,18 @@ case "$host_os" in
     # has a different set of features and flags.
     AC_COMPUTE_INT([RB_HALT_SYSTEM], [RB_HALT], [#include <sys/reboot.h>])
     AC_COMPUTE_INT([RB_POWER_OFF], [RB_HALT], [#include <sys/reboot.h>])
+    RB_DISABLE_CAD="#f"
     ;;
   *)
     # What is this?  GNU/kFreeBSD?
     AC_MSG_WARN([not sure how to halt the system on '$host_os'])
     AC_COMPUTE_INT([RB_HALT_SYSTEM], [RB_HALT_SYSTEM], [#include 
<sys/reboot.h>])
     AC_COMPUTE_INT([RB_POWER_OFF], [RB_HALT_SYSTEM], [#include <sys/reboot.h>])
+    RB_DISABLE_CAD="#f"
     ;;
 esac
 
+AC_SUBST([RB_DISABLE_CAD])
 AC_SUBST([RB_AUTOBOOT])
 AC_SUBST([RB_HALT_SYSTEM])
 AC_SUBST([RB_POWER_OFF])
diff --git a/modules/shepherd.scm b/modules/shepherd.scm
index 1efe4ce..b01760a 100644
--- a/modules/shepherd.scm
+++ b/modules/shepherd.scm
@@ -216,12 +216,19 @@
         (sigaction SIGALRM (lambda _ (alarm 1)))
         (alarm 1))
 
-      ;; Stop everything when we get SIGINT.  When running as PID 1, that means
-      ;; rebooting; this is what happens when pressing ctrl-alt-del, see
-      ;; ctrlaltdel(8).
+      (when (= 1 (getpid))
+        ;; When running as PID 1, disable hard reboots upon ctrl-alt-del.
+        ;; Instead, the kernel will send us SIGINT so that we can gracefully
+        ;; shut down.  See ctrlaltdel(8) and kernel/reboot.c.
+        (disable-reboot-on-ctrl-alt-del))
+
+      ;; Stop everything when we get SIGINT.
       (sigaction SIGINT
         (lambda _
-          (stop root-service)))
+          (catch 'quit
+            (lambda ()
+              (stop root-service))
+            quit-exception-handler)))
 
       ;; Stop everything when we get SIGTERM.
       (sigaction SIGTERM
@@ -284,6 +291,16 @@
       ;; Maybe we got EPIPE while writing to SOCK, or something like that.
       (false-if-exception (close sock)))))
 
+(define (quit-exception-handler key)
+  "Handle the 'quit' exception, rebooting if we're running as root."
+  ;; Most likely we're receiving 'quit' from the 'stop' method of
+  ;; ROOT-SERVICE.  So, if we're running as 'root', just reboot.
+  (if (zero? (getuid))
+      (begin
+        (local-output "Rebooting...")
+        (reboot))
+      (quit)))
+
 (define (process-command command port)
   "Interpret COMMAND, a command sent by the user, represented as a
 <shepherd-command> object.  Send the reply to PORT."
@@ -333,14 +350,7 @@
 
              (write-reply (command-reply command result #f (get-messages))
                           port))))
-       (lambda (key)
-         ;; Most likely we're receiving 'quit' from the 'stop' method of
-         ;; ROOT-SERVICE.  So, if we're running as 'root', just reboot.
-         (if (zero? (getuid))
-             (begin
-               (local-output "Rebooting...")
-               (reboot))
-             (quit)))))
+       quit-exception-handler))
     (_
      (local-output "Invalid command."))))
 
diff --git a/modules/shepherd/system.scm.in b/modules/shepherd/system.scm.in
index 7836985..769404a 100644
--- a/modules/shepherd/system.scm.in
+++ b/modules/shepherd/system.scm.in
@@ -21,7 +21,8 @@
   #:use-module (system foreign)
   #:use-module (rnrs bytevectors)
   #:use-module (srfi srfi-11)
-  #:export (reboot
+  #:export (disable-reboot-on-ctrl-alt-del
+            reboot
             halt
             power-off
             max-file-descriptors
@@ -32,6 +33,7 @@
 (define RB_AUTOBOOT @RB_AUTOBOOT@)
 (define RB_HALT_SYSTEM @RB_HALT_SYSTEM@)
 (define RB_POWER_OFF @RB_POWER_OFF@)
+(define RB_DISABLE_CAD @RB_DISABLE_CAD@)          ; integer | #f
 
 (define (syscall->procedure return-type name argument-types)
   "Return a procedure that wraps the C function NAME using the dynamic FFI,
@@ -107,6 +109,13 @@ the returned procedure is called."
             (ref bv))))
       (lambda () 0)))
 
+(define (disable-reboot-on-ctrl-alt-del)
+  "Disable hard reboot upon ctrl-alt-del.  Instead, the kernel Linux will send
+SIGINT to PID 1, which is responsible for cleaning things up gracefully.  See
+ctrlaltdel(8) and see kernel/reboot.c in Linux."
+  (when RB_DISABLE_CAD
+    (%libc-reboot RB_DISABLE_CAD)))
+
 (define (reboot)
   "Perform a hard reset of the system now.  Return #f on failure."
   (%libc-reboot RB_AUTOBOOT))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]