Subject: Re: bug#73992: [Shepherd PATCH] shepherd: Add support for rebooting using kexec
From: Ludovic Courtès <[email-masked]>
To: Jakob Kirsch <[email-masked]>
Cc: [email-masked]
Date: Sun, 03 Nov 2024 15:46:10 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

Hi Jakob,

Jakob Kirsch <[email-masked]> skribis:

> From 762fbee53fb890a7cf5e26abcc2dcfad03b1bab4 Mon Sep 17 00:00:00 2001
> From: Jakob Kirsch <[email-masked]>
> Date: Thu, 24 Oct 2024 19:45:31 +0200
> Subject: [PATCH v3] shepherd: Add support for rebooting using kexec
>
> ---
>  AUTHORS                             |  1 +
>  configure.ac                        |  4 ++++
>  doc/shepherd.texi                   |  9 +++++++++
>  modules/shepherd/scripts/reboot.scm | 12 ++++++++++--
>  modules/shepherd/service.scm        |  9 +++++++++
>  modules/shepherd/system.scm.in      | 10 ++++++++++
>  tests/status-sexp.sh                |  2 +-
>  7 files changed, 44 insertions(+), 3 deletions(-)

I applied it to the ‘devel’ branch after making the cosmetic changes
below (let me know if anything is amiss).  I also added a commit log
that follows the project’s conventions.

Thank you!

Ludo’.

diff --git a/doc/shepherd.texi b/doc/shepherd.texi
index faef6f1..b164fe8 100644
--- a/doc/shepherd.texi
+++ b/doc/shepherd.texi
@@ -516,12 +516,15 @@ Send commands to the socket special file @var{file}. If this option is
 not specified, @file{@var{localstatedir}/run/shepherd/socket} is taken.
 
 @item -k
-@itemx --do-kexec
-Reboot the system using kexec. The kernel that was previously loaded
-using @command{kexec -l @var{file}} is executed instead of rebooting
-into the BIOS in order to keep the down time to a minimum or to chainload
-another kernel. This feature is only available on Linux-based systems and will
-throw an exception on GNU/Hurd. This is also equivalent to running @command{herd kexec shepherd}.
+@itemx --kexec
+Reboot the system using Linux's kexec (this is equivalent to running
+@command{herd kexec root}).  The kernel that was previously loaded using
+the @command{kexec -l @var{file}} command is executed directly instead
+of rebooting into the BIOS, keeping the downtime to a minimum.  See the
+@uref{https://linux.die.net/man/8/kexec, @command{kexec} command
+documentation} for more information.
+
+This feature is only available on Linux-based systems.
 
 @end table
 
diff --git a/modules/shepherd/scripts/reboot.scm b/modules/shepherd/scripts/reboot.scm
index 4c2448e..0f3fc30 100644
--- a/modules/shepherd/scripts/reboot.scm
+++ b/modules/shepherd/scripts/reboot.scm
@@ -1,5 +1,6 @@
 ;; reboot.scm -- Reboot the system.
 ;; Copyright (C) 2013, 2014, 2015, 2016, 2018, 2023 Ludovic Courtès <[email-masked]>
+;; Copyright (C) 2024 Jakob Kirsch <[email-masked]>
 ;;
 ;; This file is part of the GNU Shepherd.
 ;;
@@ -48,11 +49,11 @@
                       #:action (lambda (file)
                                  (set! socket-file file)))
                     (option
-                      #:long-name "do-kexec" #:short-name #\k
+                      #:long-name "kexec" #:short-name #\k
                       #:takes-argument? #f
                       #:description "reboot using kexec"
-                      #:action (lambda () (set! action 'kexec))
-                    ))
+                      #:action (lambda ()
+                                 (set! action 'kexec))))
 
       (set! command-args (reverse command-args))
       (with-system-error-handling
diff --git a/modules/shepherd/service.scm b/modules/shepherd/service.scm
index 6a5e112..08a9df2 100644
--- a/modules/shepherd/service.scm
+++ b/modules/shepherd/service.scm
@@ -2709,13 +2709,14 @@ Clients such as 'herd' can read it and format it in a human-readable way."
             (power-off)))))
 
      (kexec
-       "Reboot the system and run kexec."
-       (lambda (running)
+      "Reboot the system and run kexec."
+      (lambda (running)
         (catch 'quit
-          (cut stop root-service)
+          (cut stop-service root-service)
           (lambda (key)
             (local-output (l10n "Rebooting with kexec..."))
             (reboot-kexec)))))
+
      ;; Evaluate arbitrary code.
      (load
       "Load the Scheme code from FILE into shepherd.  This is potentially
diff --git a/modules/shepherd/system.scm.in b/modules/shepherd/system.scm.in
index 1168c15..46f1848 100644
--- a/modules/shepherd/system.scm.in
+++ b/modules/shepherd/system.scm.in
@@ -2,6 +2,7 @@
 ;; Copyright (C) 2013-2014, 2016, 2018, 2020, 2022-2024 Ludovic Courtès <[email-masked]>
 ;; Copyright (C) 2018 Carlo Zancanaro <[email-masked]>
 ;; Copyright (C) 2020 Jan (janneke) Nieuwenhuizen <[email-masked]>
+;; Copyright (C) 2024 Jakob Kirsch <[email-masked]>
 ;;
 ;; This file is part of the GNU Shepherd.
 ;;
@@ -98,12 +99,13 @@ ctrlaltdel(8) and see kernel/reboot.c in Linux."
   (%libc-reboot RB_AUTOBOOT))
 
 (define (reboot-kexec)
-  "Execute kernel loaded with 'kexec -l' now. Kexec is a feature of the
+  "Execute kernel loaded with 'kexec -l' now.  Kexec is a feature of the
 Linux kernel that allows you to instantly reboot into a new kernel while skipping
 the BIOS phase.  Return #f on failure or throw an exception on non-Linux systems."
   (if RB_KEXEC
-    (%libc-reboot RB_KEXEC)
-    (throw 'system-error 'kexec  "~A" (list (strerror ENOSYS)) (list ENOSYS))))
+      (%libc-reboot RB_KEXEC)
+      (throw 'system-error 'kexec  "~A" (list (strerror ENOSYS))
+             (list ENOSYS))))
 
 (define (halt)
   "Halt the system.  Return #f on failure."