unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
* [bug#75027] [PATCH 0/3] 'guix system reconfigure' loads system for kexec reboot
@ 2024-12-22 15:56 Ludovic Courtès
  2024-12-22 15:57 ` [bug#75027] [PATCH 1/3] syscalls: Add ‘kexec-load-file’ Ludovic Courtès
                   ` (4 more replies)
  0 siblings, 5 replies; 18+ messages in thread
From: Ludovic Courtès @ 2024-12-22 15:56 UTC (permalink / raw)
  To: 75027
  Cc: Jakob Kirsch, Ludovic Courtès, Christopher Baines,
	Josselin Poiret, Ludovic Courtès, Mathieu Othacehe,
	Simon Tournier, Tobias Geerinckx-Rice

Hello Guix,

Following work by Jakob Kirsch adding kexec support in the Shepherd
(the new ‘reboot -k’ option), here’s the Guix side of it: with these
patches, ‘guix system reconfigure’ loads the new system so that one
can run ‘reboot -k’ to quickly reboot into it.

Thoughts?

Ludo’.

PS: It took me a while to debug until I realized it was working
    very well: it’s just that I was booting a kernel with “quiet”
    on its command line, so I couldn’t see anything. 🤦

Ludovic Courtès (3):
  syscalls: Add ‘kexec-load-file’.
  system: Export ‘…-initrd-file’ and ‘…-root-file-system’.
  reconfigure: Call ‘kexec-load-file’.

 gnu/system.scm                      |  4 +-
 gnu/tests/reconfigure.scm           | 77 +++++++++++++++++++++++++++++
 guix/build/syscalls.scm             | 54 ++++++++++++++++++++
 guix/scripts/system/reconfigure.scm | 25 ++++++++++
 tests/syscalls.scm                  | 13 +++++
 5 files changed, 172 insertions(+), 1 deletion(-)


base-commit: 9f53e10235cced7a85697481c859829742b9912c
-- 
2.46.0





^ permalink raw reply	[flat|nested] 18+ messages in thread

* [bug#75027] [PATCH 1/3] syscalls: Add ‘kexec-load-file’.
  2024-12-22 15:56 [bug#75027] [PATCH 0/3] 'guix system reconfigure' loads system for kexec reboot Ludovic Courtès
@ 2024-12-22 15:57 ` Ludovic Courtès
  2024-12-22 15:57 ` [bug#75027] [PATCH 2/3] system: Export ‘…-initrd-file’ and ‘…-root-file-system’ Ludovic Courtès
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 18+ messages in thread
From: Ludovic Courtès @ 2024-12-22 15:57 UTC (permalink / raw)
  To: 75027; +Cc: Ludovic Courtès

* guix/build/syscalls.scm (string->utf-8/nul-terminated)
(kexec-load-file): New procedures.
* tests/syscalls.scm ("kexec-load-file"): New test.

Change-Id: I3724226a14ecc07f346e77519fb5b0591096c7f6
---
 guix/build/syscalls.scm | 54 +++++++++++++++++++++++++++++++++++++++++
 tests/syscalls.scm      | 13 ++++++++++
 2 files changed, 67 insertions(+)

diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm
index 2c20edf058..f8c9937f54 100644
--- a/guix/build/syscalls.scm
+++ b/guix/build/syscalls.scm
@@ -146,6 +146,12 @@ (define-module (guix build syscalls)
             clone
             setns
 
+            kexec-load-file
+            KEXEC_FILE_UNLOAD
+            KEXEC_FILE_ON_CRASH
+            KEXEC_FILE_NO_INITRAMFS
+            KEXEC_FILE_DEBUG
+
             PF_PACKET
             AF_PACKET
             all-network-interface-names
@@ -765,6 +771,54 @@ (define-as-needed load-linux-module
                  (list (strerror err))
                  (list err)))))))
 
+(define (string->utf-8/nul-terminated str)
+  "Serialize STR to UTF-8; return the resulting bytevector, including
+terminating nul character."
+  (let* ((source (string->utf8 str))
+         (bv     (make-bytevector (+ (bytevector-length source) 1) 0)))
+    (bytevector-copy! source 0 bv 0 (bytevector-length source))
+    bv))
+
+;; Constants from <linux/kexec.h>.
+(define KEXEC_FILE_UNLOAD	#x00000001)
+(define KEXEC_FILE_ON_CRASH	#x00000002)
+(define KEXEC_FILE_NO_INITRAMFS	#x00000004)
+(define KEXEC_FILE_DEBUG	#x00000008)
+
+(define kexec-load-file
+  (let* ((proc (syscall->procedure int "syscall"
+                                   (list long             ;sysno
+                                         int              ;kernel fd
+                                         int              ;initrd fd
+                                         unsigned-long    ;cmdline length
+                                         '*               ;cmdline
+                                         unsigned-long))) ;flags
+         ;; TODO: Don't do this.
+         (syscall-id (match (utsname:machine (uname))
+                       ("i686"    320)
+                       ("x86_64"  320)
+                       ("armv7l"  401)
+                       ("aarch64" 401)
+                       ;; XXX: There's apparently no support for ppc64le and
+                       ;; riscv64.
+                       (_ #f))))
+    (lambda* (kernel-fd initrd-fd command-line #:optional (flags 0))
+      "Load for eventual use of kexec(8) the Linux kernel from
+@var{kernel-fd}, its initial RAM disk from @var{initrd-fd}, with the given
+@var{command-line} (a string).  Optionally, @var{flags} can be a bitwise or of
+the KEXEC_FILE_* constants."
+      (let*-values (((command-line)
+                     (string->utf-8/nul-terminated command-line))
+                    ((ret err)
+                     (proc syscall-id kernel-fd initrd-fd
+                           (bytevector-length command-line)
+                           (bytevector->pointer command-line)
+                           flags)))
+        (when (= ret -1)
+          (throw 'system-error "kexec-load-file" "~A"
+                 (list (strerror err))
+                 (list err)))))))
+
 (define (linux-process-flags pid)                 ;copied from the Shepherd
   "Return the process flags of @var{pid} (or'd @code{PF_} constants), assuming
 the Linux /proc file system is mounted; raise a @code{system-error} exception
diff --git a/tests/syscalls.scm b/tests/syscalls.scm
index 13f4f11721..eef864d097 100644
--- a/tests/syscalls.scm
+++ b/tests/syscalls.scm
@@ -679,6 +679,19 @@ (define perform-container-tests?
         (lambda args
           (system-error-errno args))))))
 
+(when (or (zero? (getuid))
+          (not (string-contains %host-type "linux")))
+  (test-skip 1))
+(test-equal "kexec-load-file"
+  EPERM
+  (catch 'system-error
+    (lambda ()
+      (let ((fd1 (open-fdes "/dev/null" O_RDONLY))
+            (fd2 (open-fdes "/dev/null" O_RDONLY)))
+        (kexec-load-file fd1 fd2 "gnu.repl=yes")))
+    (lambda args
+      (system-error-errno args))))
+
 (test-end)
 
 (false-if-exception (delete-file temp-file))
-- 
2.46.0





^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [bug#75027] [PATCH 2/3] system: Export ‘…-initrd-file’ and ‘…-root-file-system’.
  2024-12-22 15:56 [bug#75027] [PATCH 0/3] 'guix system reconfigure' loads system for kexec reboot Ludovic Courtès
  2024-12-22 15:57 ` [bug#75027] [PATCH 1/3] syscalls: Add ‘kexec-load-file’ Ludovic Courtès
@ 2024-12-22 15:57 ` Ludovic Courtès
  2024-12-22 15:57 ` [bug#75027] [PATCH 3/3] reconfigure: Call ‘kexec-load-file’ Ludovic Courtès
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 18+ messages in thread
From: Ludovic Courtès @ 2024-12-22 15:57 UTC (permalink / raw)
  To: 75027; +Cc: Ludovic Courtès

* gnu/system.scm (operating-system-initrd-file): Fix docstring and
export.
(operating-system-root-file-system): Export.

Change-Id: I5254d82ce547e8014027ed20675b8bfe5a5847c5
---
 gnu/system.scm | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gnu/system.scm b/gnu/system.scm
index dfcb8fb279..252a26cac3 100644
--- a/gnu/system.scm
+++ b/gnu/system.scm
@@ -110,6 +110,7 @@ (define-module (gnu system)
             operating-system-default-label
             operating-system-initrd-modules
             operating-system-initrd
+            operating-system-initrd-file
             operating-system-users
             operating-system-groups
             operating-system-issue
@@ -119,6 +120,7 @@ (define-module (gnu system)
             operating-system-locale-libcs
             operating-system-mapped-devices
             operating-system-file-systems
+            operating-system-root-file-system
             operating-system-store-file-system
             operating-system-user-mapped-devices
             operating-system-boot-mapped-devices
@@ -1355,7 +1357,7 @@ (define (operating-system-root-file-system os)
                (location (operating-system-location os)))))))
 
 (define (operating-system-initrd-file os)
-  "Return a gexp denoting the initrd file of OS."
+  "Return a file-like object for the initrd file of OS."
   (define boot-file-systems
     (filter file-system-needed-for-boot?
             (operating-system-file-systems os)))
-- 
2.46.0





^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [bug#75027] [PATCH 3/3] reconfigure: Call ‘kexec-load-file’.
  2024-12-22 15:56 [bug#75027] [PATCH 0/3] 'guix system reconfigure' loads system for kexec reboot Ludovic Courtès
  2024-12-22 15:57 ` [bug#75027] [PATCH 1/3] syscalls: Add ‘kexec-load-file’ Ludovic Courtès
  2024-12-22 15:57 ` [bug#75027] [PATCH 2/3] system: Export ‘…-initrd-file’ and ‘…-root-file-system’ Ludovic Courtès
@ 2024-12-22 15:57 ` Ludovic Courtès
  2024-12-22 21:47 ` [bug#75027] [PATCH 0/3] 'guix system reconfigure' loads system for kexec reboot Jakob Kirsch via Guix-patches via
  2024-12-26 17:21 ` [bug#75027] [PATCH v2 " Ludovic Courtès
  4 siblings, 0 replies; 18+ messages in thread
From: Ludovic Courtès @ 2024-12-22 15:57 UTC (permalink / raw)
  To: 75027
  Cc: Ludovic Courtès, Christopher Baines, Josselin Poiret,
	Ludovic Courtès, Mathieu Othacehe, Simon Tournier,
	Tobias Geerinckx-Rice

This allows rebooting straight into the new system with ‘reboot -k’.

* guix/scripts/system/reconfigure.scm (kexec-loading-program): New
procedure.
(upgrade-shepherd-services): Use it.
* gnu/tests/reconfigure.scm (run-kexec-test): New procedure.
(%test-upgrade-kexec): New variable.

Change-Id: I86d11f1c348e4359bc9e73c86e5aebff60fe875c
---
 gnu/tests/reconfigure.scm           | 77 +++++++++++++++++++++++++++++
 guix/scripts/system/reconfigure.scm | 25 ++++++++++
 2 files changed, 102 insertions(+)

diff --git a/gnu/tests/reconfigure.scm b/gnu/tests/reconfigure.scm
index bcc7645fa3..8d33bdac9b 100644
--- a/gnu/tests/reconfigure.scm
+++ b/gnu/tests/reconfigure.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.org>
+;;; Copyright © 2024 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -18,9 +19,12 @@
 
 (define-module (gnu tests reconfigure)
   #:use-module (gnu bootloader)
+  #:use-module (gnu services)
+  #:use-module (gnu services base)
   #:use-module (gnu services shepherd)
   #:use-module (gnu system)
   #:use-module (gnu system accounts)
+  #:use-module (gnu system file-systems)
   #:use-module (gnu system shadow)
   #:use-module (gnu system vm)
   #:use-module (gnu tests)
@@ -31,6 +35,7 @@ (define-module (gnu tests reconfigure)
   #:use-module (guix store)
   #:export (%test-switch-to-system
             %test-upgrade-services
+            %test-upgrade-kexec
             %test-install-bootloader))
 
 ;;; Commentary:
@@ -178,6 +183,72 @@ (define* (run-upgrade-services-test)
           (disable (upgrade-services-program '() '() '(dummy) '())))
      (test enable disable))))
 
+(define* (run-kexec-test)
+  (define os
+    (marionette-operating-system
+     (operating-system
+       (inherit %simple-os)
+       (services (modify-services %base-services
+                   (syslog-service-type
+                    config => (syslog-configuration
+                               (inherit config)
+                               (config-file
+                                (plain-file
+                                 "syslog.conf"
+                                 "*.* /dev/console\n")))))))
+     #:imported-modules '((gnu services herd)
+                          (guix combinators))))
+
+  (define new-os
+    (marionette-operating-system
+     (virtualized-operating-system               ;run as with "guix system vm"
+      (operating-system
+        (inherit %simple-os)
+        (host-name "the-new-os")
+        (kernel-arguments '("console=ttyS0")))    ;be verbose
+      #:volatile? #t)                             ;mount root read-only
+     #:imported-modules '((gnu services herd)
+                          (guix combinators))))
+
+  (define vm (virtual-machine os))
+
+  (define test
+    (with-imported-modules '((gnu build marionette))
+      #~(begin
+          (use-modules (gnu build marionette)
+                       (srfi srfi-64))
+
+          (define marionette
+            (make-marionette (list #$vm)))
+
+          (test-runner-current (system-test-runner #$output))
+          (test-begin "kexec")
+
+          (test-equal "host name"
+            #$(operating-system-host-name os)
+            (marionette-eval '(gethostname) marionette))
+
+          (test-assert "kexec-loading-program"
+            (marionette-eval
+             '(primitive-load #$(kexec-loading-program new-os))
+             marionette))
+
+          (test-assert "reboot/kexec"
+            (marionette-eval
+             '(begin
+                (use-modules (gnu services herd))
+                (with-shepherd-action 'root ('kexec) result
+                  (pk 'reboot-kexec result)))
+             marionette))
+
+          (test-equal "host name of new OS"
+            #$(operating-system-host-name new-os)
+            (marionette-eval '(gethostname) marionette))
+
+          (test-end))))
+
+  (gexp->derivation "kexec-test" test))
+
 (define* (run-install-bootloader-test)
   "Run a test of an OS running INSTALL-BOOTLOADER-PROGRAM, which installs a
 bootloader's configuration file."
@@ -268,6 +339,12 @@ (define %test-upgrade-services
 loading new services.")
    (value (run-upgrade-services-test))))
 
+(define %test-upgrade-kexec
+  (system-test
+   (name "upgrade-kexec")
+   (description "FIXME")
+   (value (run-kexec-test))))
+
 (define %test-install-bootloader
   (system-test
    (name "install-bootloader")
diff --git a/guix/scripts/system/reconfigure.scm b/guix/scripts/system/reconfigure.scm
index ddb561d28c..9e08179613 100644
--- a/guix/scripts/system/reconfigure.scm
+++ b/guix/scripts/system/reconfigure.scm
@@ -31,6 +31,7 @@ (define-module (guix scripts system reconfigure)
   #:use-module (gnu services herd)
   #:use-module (gnu services shepherd)
   #:use-module (gnu system)
+  #:autoload   (gnu system file-systems) (file-system-device)
   #:use-module (guix gexp)
   #:use-module (guix modules)
   #:use-module (guix monads)
@@ -51,6 +52,7 @@ (define-module (guix scripts system reconfigure)
 
             upgrade-services-program
             upgrade-shepherd-services
+            kexec-loading-program
 
             install-bootloader-program
             install-bootloader
@@ -176,6 +178,27 @@ (define (upgrade-services-program service-files to-start to-unload to-restart)
         (for-each unload-service '#$to-unload)
         (for-each start-service '#$to-start)))))
 
+(define (kexec-loading-program os)
+  "Return a program that calls 'kexec_file_load' to allow rebooting into OS
+via 'kexec'."
+  (let ((root-device (file-system-device
+                      (operating-system-root-file-system os))))
+    (program-file
+     "kexec-load-system.scm"
+     (with-imported-modules '((guix build syscalls))
+       #~(begin
+           (use-modules (guix build syscalls))
+
+           (let ((kernel (open-fdes #$(operating-system-kernel-file os)
+                                    O_RDONLY))
+                 (initrd (open-fdes #$(operating-system-initrd-file os)
+                                    O_RDONLY)))
+             (kexec-load-file kernel initrd
+                              (string-join
+                               (list #$@(operating-system-kernel-arguments
+                                         os root-device)))
+                              KEXEC_FILE_DEBUG)))))))
+
 (define* (upgrade-shepherd-services eval os)
   "Using EVAL, a monadic procedure taking a single G-Expression as an argument,
 upgrade the Shepherd (PID 1) by unloading obsolete services and loading new
@@ -200,6 +223,8 @@ (define* (upgrade-shepherd-services eval os)
                                         running))
            (service-files (map shepherd-service-file target-services)))
       (eval #~(parameterize ((current-warning-port (%make-void-port "w")))
+                (when (string-contains %host-type "-linux")
+                  (primitive-load #$(kexec-loading-program os)))
                 (primitive-load #$(upgrade-services-program service-files
                                                             to-start
                                                             to-unload
-- 
2.46.0





^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [bug#75027] [PATCH 0/3] 'guix system reconfigure' loads system for kexec reboot
  2024-12-22 15:56 [bug#75027] [PATCH 0/3] 'guix system reconfigure' loads system for kexec reboot Ludovic Courtès
                   ` (2 preceding siblings ...)
  2024-12-22 15:57 ` [bug#75027] [PATCH 3/3] reconfigure: Call ‘kexec-load-file’ Ludovic Courtès
@ 2024-12-22 21:47 ` Jakob Kirsch via Guix-patches via
       [not found]   ` <87y106ej9v.fsf@gnu.org>
  2024-12-26 17:21 ` [bug#75027] [PATCH v2 " Ludovic Courtès
  4 siblings, 1 reply; 18+ messages in thread
From: Jakob Kirsch via Guix-patches via @ 2024-12-22 21:47 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 75027

Would it be possible to expose the output of kexec-loading-program as a file in the output directory of the operating system (e.g. as /run/current-system/kexec)?




^ permalink raw reply	[flat|nested] 18+ messages in thread

* [bug#75027] [PATCH 0/3] 'guix system reconfigure' loads system for kexec reboot
       [not found]   ` <87y106ej9v.fsf@gnu.org>
@ 2024-12-23 18:24     ` Jakob Kirsch via Guix-patches via
  2024-12-26 17:25       ` Ludovic Courtès
  0 siblings, 1 reply; 18+ messages in thread
From: Jakob Kirsch via Guix-patches via @ 2024-12-23 18:24 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 75027

On Mon, Dec 23, 2024 at 12:22:20PM +0100, Ludovic Courtès wrote:
> In addition to or instead of running it by default?

I would say in addition to but with a flag to not load it (like with "--no-bootloader" for the bootloader).

Btw I've also noticed that the framebuffer is only initialized after something graphical (gdm in my case) has been started. This usually isn't an issue for most users but my disks are encrypted so I can't see the password prompt but I can still type in my password.




^ permalink raw reply	[flat|nested] 18+ messages in thread

* [bug#75027] [PATCH v2 0/3] 'guix system reconfigure' loads system for kexec reboot
  2024-12-22 15:56 [bug#75027] [PATCH 0/3] 'guix system reconfigure' loads system for kexec reboot Ludovic Courtès
                   ` (3 preceding siblings ...)
  2024-12-22 21:47 ` [bug#75027] [PATCH 0/3] 'guix system reconfigure' loads system for kexec reboot Jakob Kirsch via Guix-patches via
@ 2024-12-26 17:21 ` Ludovic Courtès
  2024-12-26 17:21   ` [bug#75027] [PATCH v2 1/3] syscalls: Add ‘kexec-load-file’ Ludovic Courtès
                     ` (3 more replies)
  4 siblings, 4 replies; 18+ messages in thread
From: Ludovic Courtès @ 2024-12-26 17:21 UTC (permalink / raw)
  To: 75027
  Cc: Jakob Kirsch, Ludovic Courtès, Christopher Baines,
	Josselin Poiret, Ludovic Courtès, Mathieu Othacehe,
	Maxim Cournoyer, Simon Tournier, Tobias Geerinckx-Rice

Hello,

Changes compared to v1:

  • Move kexec code outside of ‘upgrade-shepherd-services’.  Now both
    (guix scripts system) and (gnu machine ssh) have to explicitly
    call ‘load-system-for-kexec’.

  • Add ‘--no-kexec’ command-line option for ‘guix system reconfigure’,
    as Jakob suggested.

  • Document kexec support under “Invoking guix system”.

The one thing I didn’t do is add a “kexec” symlink in the system; as it
turns out that’s not easily doable because of the circular dependency:
code returned by ‘kexec-loading-program’ needs to refer to the operating
system in which it would appear.

If we find a way to work around this, maybe we can add this later.

Thoughts?

Ludo’.

Ludovic Courtès (3):
  syscalls: Add ‘kexec-load-file’.
  system: Export ‘…-initrd-file’ and ‘…-root-file-system’.
  reconfigure: Support loading the system for kexec reboot.

 doc/guix.texi                       | 11 +++-
 gnu/machine/ssh.scm                 |  9 +++-
 gnu/system.scm                      |  4 +-
 gnu/tests/reconfigure.scm           | 78 +++++++++++++++++++++++++++++
 guix/build/syscalls.scm             | 54 ++++++++++++++++++++
 guix/scripts/system.scm             | 17 ++++++-
 guix/scripts/system/reconfigure.scm | 31 ++++++++++++
 tests/syscalls.scm                  | 13 +++++
 8 files changed, 213 insertions(+), 4 deletions(-)


base-commit: f96c14e3ca6b22e56621cc04a1bf06a8cac6ca23
-- 
2.46.0





^ permalink raw reply	[flat|nested] 18+ messages in thread

* [bug#75027] [PATCH v2 1/3] syscalls: Add ‘kexec-load-file’.
  2024-12-26 17:21 ` [bug#75027] [PATCH v2 " Ludovic Courtès
@ 2024-12-26 17:21   ` Ludovic Courtès
  2024-12-28  6:12     ` Maxim Cournoyer
  2024-12-26 17:21   ` [bug#75027] [PATCH v2 2/3] system: Export ‘…-initrd-file’ and ‘…-root-file-system’ Ludovic Courtès
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 18+ messages in thread
From: Ludovic Courtès @ 2024-12-26 17:21 UTC (permalink / raw)
  To: 75027; +Cc: Ludovic Courtès

* guix/build/syscalls.scm (string->utf-8/nul-terminated)
(kexec-load-file): New procedures.
* tests/syscalls.scm ("kexec-load-file"): New test.

Change-Id: I3724226a14ecc07f346e77519fb5b0591096c7f6
---
 guix/build/syscalls.scm | 54 +++++++++++++++++++++++++++++++++++++++++
 tests/syscalls.scm      | 13 ++++++++++
 2 files changed, 67 insertions(+)

diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm
index 2c20edf058..f8c9937f54 100644
--- a/guix/build/syscalls.scm
+++ b/guix/build/syscalls.scm
@@ -146,6 +146,12 @@ (define-module (guix build syscalls)
             clone
             setns
 
+            kexec-load-file
+            KEXEC_FILE_UNLOAD
+            KEXEC_FILE_ON_CRASH
+            KEXEC_FILE_NO_INITRAMFS
+            KEXEC_FILE_DEBUG
+
             PF_PACKET
             AF_PACKET
             all-network-interface-names
@@ -765,6 +771,54 @@ (define-as-needed load-linux-module
                  (list (strerror err))
                  (list err)))))))
 
+(define (string->utf-8/nul-terminated str)
+  "Serialize STR to UTF-8; return the resulting bytevector, including
+terminating nul character."
+  (let* ((source (string->utf8 str))
+         (bv     (make-bytevector (+ (bytevector-length source) 1) 0)))
+    (bytevector-copy! source 0 bv 0 (bytevector-length source))
+    bv))
+
+;; Constants from <linux/kexec.h>.
+(define KEXEC_FILE_UNLOAD	#x00000001)
+(define KEXEC_FILE_ON_CRASH	#x00000002)
+(define KEXEC_FILE_NO_INITRAMFS	#x00000004)
+(define KEXEC_FILE_DEBUG	#x00000008)
+
+(define kexec-load-file
+  (let* ((proc (syscall->procedure int "syscall"
+                                   (list long             ;sysno
+                                         int              ;kernel fd
+                                         int              ;initrd fd
+                                         unsigned-long    ;cmdline length
+                                         '*               ;cmdline
+                                         unsigned-long))) ;flags
+         ;; TODO: Don't do this.
+         (syscall-id (match (utsname:machine (uname))
+                       ("i686"    320)
+                       ("x86_64"  320)
+                       ("armv7l"  401)
+                       ("aarch64" 401)
+                       ;; XXX: There's apparently no support for ppc64le and
+                       ;; riscv64.
+                       (_ #f))))
+    (lambda* (kernel-fd initrd-fd command-line #:optional (flags 0))
+      "Load for eventual use of kexec(8) the Linux kernel from
+@var{kernel-fd}, its initial RAM disk from @var{initrd-fd}, with the given
+@var{command-line} (a string).  Optionally, @var{flags} can be a bitwise or of
+the KEXEC_FILE_* constants."
+      (let*-values (((command-line)
+                     (string->utf-8/nul-terminated command-line))
+                    ((ret err)
+                     (proc syscall-id kernel-fd initrd-fd
+                           (bytevector-length command-line)
+                           (bytevector->pointer command-line)
+                           flags)))
+        (when (= ret -1)
+          (throw 'system-error "kexec-load-file" "~A"
+                 (list (strerror err))
+                 (list err)))))))
+
 (define (linux-process-flags pid)                 ;copied from the Shepherd
   "Return the process flags of @var{pid} (or'd @code{PF_} constants), assuming
 the Linux /proc file system is mounted; raise a @code{system-error} exception
diff --git a/tests/syscalls.scm b/tests/syscalls.scm
index 13f4f11721..eef864d097 100644
--- a/tests/syscalls.scm
+++ b/tests/syscalls.scm
@@ -679,6 +679,19 @@ (define perform-container-tests?
         (lambda args
           (system-error-errno args))))))
 
+(when (or (zero? (getuid))
+          (not (string-contains %host-type "linux")))
+  (test-skip 1))
+(test-equal "kexec-load-file"
+  EPERM
+  (catch 'system-error
+    (lambda ()
+      (let ((fd1 (open-fdes "/dev/null" O_RDONLY))
+            (fd2 (open-fdes "/dev/null" O_RDONLY)))
+        (kexec-load-file fd1 fd2 "gnu.repl=yes")))
+    (lambda args
+      (system-error-errno args))))
+
 (test-end)
 
 (false-if-exception (delete-file temp-file))
-- 
2.46.0





^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [bug#75027] [PATCH v2 2/3] system: Export ‘…-initrd-file’ and ‘…-root-file-system’.
  2024-12-26 17:21 ` [bug#75027] [PATCH v2 " Ludovic Courtès
  2024-12-26 17:21   ` [bug#75027] [PATCH v2 1/3] syscalls: Add ‘kexec-load-file’ Ludovic Courtès
@ 2024-12-26 17:21   ` Ludovic Courtès
  2024-12-28  6:12     ` Maxim Cournoyer
  2024-12-26 17:21   ` [bug#75027] [PATCH v2 3/3] reconfigure: Support loading the system for kexec reboot Ludovic Courtès
  2024-12-28  7:24   ` [bug#75027] [PATCH v2 0/3] 'guix system reconfigure' loads " Maxim Cournoyer
  3 siblings, 1 reply; 18+ messages in thread
From: Ludovic Courtès @ 2024-12-26 17:21 UTC (permalink / raw)
  To: 75027; +Cc: Ludovic Courtès

* gnu/system.scm (operating-system-initrd-file): Fix docstring and
export.
(operating-system-root-file-system): Export.

Change-Id: I5254d82ce547e8014027ed20675b8bfe5a5847c5
---
 gnu/system.scm | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/gnu/system.scm b/gnu/system.scm
index dfcb8fb279..252a26cac3 100644
--- a/gnu/system.scm
+++ b/gnu/system.scm
@@ -110,6 +110,7 @@ (define-module (gnu system)
             operating-system-default-label
             operating-system-initrd-modules
             operating-system-initrd
+            operating-system-initrd-file
             operating-system-users
             operating-system-groups
             operating-system-issue
@@ -119,6 +120,7 @@ (define-module (gnu system)
             operating-system-locale-libcs
             operating-system-mapped-devices
             operating-system-file-systems
+            operating-system-root-file-system
             operating-system-store-file-system
             operating-system-user-mapped-devices
             operating-system-boot-mapped-devices
@@ -1355,7 +1357,7 @@ (define (operating-system-root-file-system os)
                (location (operating-system-location os)))))))
 
 (define (operating-system-initrd-file os)
-  "Return a gexp denoting the initrd file of OS."
+  "Return a file-like object for the initrd file of OS."
   (define boot-file-systems
     (filter file-system-needed-for-boot?
             (operating-system-file-systems os)))
-- 
2.46.0





^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [bug#75027] [PATCH v2 3/3] reconfigure: Support loading the system for kexec reboot.
  2024-12-26 17:21 ` [bug#75027] [PATCH v2 " Ludovic Courtès
  2024-12-26 17:21   ` [bug#75027] [PATCH v2 1/3] syscalls: Add ‘kexec-load-file’ Ludovic Courtès
  2024-12-26 17:21   ` [bug#75027] [PATCH v2 2/3] system: Export ‘…-initrd-file’ and ‘…-root-file-system’ Ludovic Courtès
@ 2024-12-26 17:21   ` Ludovic Courtès
  2024-12-28  7:22     ` Maxim Cournoyer
  2024-12-28  7:24   ` [bug#75027] [PATCH v2 0/3] 'guix system reconfigure' loads " Maxim Cournoyer
  3 siblings, 1 reply; 18+ messages in thread
From: Ludovic Courtès @ 2024-12-26 17:21 UTC (permalink / raw)
  To: 75027
  Cc: Ludovic Courtès, Christopher Baines, Josselin Poiret,
	Ludovic Courtès, Mathieu Othacehe, Maxim Cournoyer,
	Simon Tournier, Tobias Geerinckx-Rice

This allows rebooting straight into the new system with ‘reboot -k’.

* guix/scripts/system/reconfigure.scm (kexec-loading-program)
(load-system-for-kexec): New procedures.
* gnu/tests/reconfigure.scm (run-kexec-test): New procedure.
(%test-upgrade-kexec): New variable.
* guix/scripts/system.scm (perform-action): Add #:load-for-kexec?.
Call ‘load-system-for-kexec’.
(show-help, %options): Add ‘--no-kexec’.
(%default-options): Add ‘load-for-kexec?’.
(process-action): Honor it and pass it to ‘perform-action’.
* gnu/machine/ssh.scm (deploy-managed-host): Add call to
‘load-system-for-kexec’.
* doc/guix.texi (Invoking guix system): Document it.

Change-Id: I86d11f1c348e4359bc9e73c86e5aebff60fe875c
---
 doc/guix.texi                       | 11 +++-
 gnu/machine/ssh.scm                 |  9 +++-
 gnu/tests/reconfigure.scm           | 78 +++++++++++++++++++++++++++++
 guix/scripts/system.scm             | 17 ++++++-
 guix/scripts/system/reconfigure.scm | 31 ++++++++++++
 5 files changed, 143 insertions(+), 3 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index da4d2f5ebc..7bf14a49e9 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -43599,11 +43599,20 @@ Invoking guix system
 overwritten.  This behavior mirrors that of @command{guix package}
 (@pxref{Invoking guix package}).
 
-It also adds a bootloader menu entry for the new OS configuration,
+It adds a bootloader menu entry for the new OS configuration,
 ---unless @option{--no-bootloader} is passed.  For GRUB, it moves
 entries for older configurations to a submenu, allowing you to choose
 an older system generation at boot time should you need it.
 
+@cindex kexec, for fast reboots
+@cindex rebooting @i{via} Linux kexec
+On Linux, @command{guix system reconfigure} also loads the new system
+for fast reboot @i{via} kexec: running @command{reboot --kexec} will
+boot the new system by directly executing its kernel, thus bypassing the
+BIOS initialization phase and bootloader (@pxref{Invoking reboot,,,
+shepherd, The GNU Shepherd Manual}).  You can avoid this behavior by
+passing the @option{--no-kexec} option.
+
 @cindex provenance tracking, of the operating system
 Upon completion, the new system is deployed under
 @file{/run/current-system}.  This directory contains @dfn{provenance
diff --git a/gnu/machine/ssh.scm b/gnu/machine/ssh.scm
index 3e10d984e7..f58fcdaf4a 100644
--- a/gnu/machine/ssh.scm
+++ b/gnu/machine/ssh.scm
@@ -1,6 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.org>
-;;; Copyright © 2020-2023 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2020-2024 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2024 Ricardo <rekado@elephly.net>
 ;;;
 ;;; This file is part of GNU Guix.
@@ -552,6 +552,13 @@ (define (deploy-managed-host machine)
                                                       (inferior-exception-arguments
                                                        c)))
                                            os)
+                (load-system-for-kexec (eval/error-handling c
+                                         (warning (G_ "\
+failed to load system of '~a' for kexec reboot:~%~{~s ~}~%")
+                                                  host
+                                                  (inferior-exception-arguments
+                                                   c)))
+                                       os)
                 (install-bootloader (eval/error-handling c
                                       (raise (formatted-message
                                               (G_ "\
diff --git a/gnu/tests/reconfigure.scm b/gnu/tests/reconfigure.scm
index bcc7645fa3..a24a953e6e 100644
--- a/gnu/tests/reconfigure.scm
+++ b/gnu/tests/reconfigure.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.org>
+;;; Copyright © 2024 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -18,9 +19,12 @@
 
 (define-module (gnu tests reconfigure)
   #:use-module (gnu bootloader)
+  #:use-module (gnu services)
+  #:use-module (gnu services base)
   #:use-module (gnu services shepherd)
   #:use-module (gnu system)
   #:use-module (gnu system accounts)
+  #:use-module (gnu system file-systems)
   #:use-module (gnu system shadow)
   #:use-module (gnu system vm)
   #:use-module (gnu tests)
@@ -31,6 +35,7 @@ (define-module (gnu tests reconfigure)
   #:use-module (guix store)
   #:export (%test-switch-to-system
             %test-upgrade-services
+            %test-upgrade-kexec
             %test-install-bootloader))
 
 ;;; Commentary:
@@ -178,6 +183,73 @@ (define* (run-upgrade-services-test)
           (disable (upgrade-services-program '() '() '(dummy) '())))
      (test enable disable))))
 
+(define (run-kexec-test)
+  "Run a test aiming to reboot via Linux kexec into a new system."
+  (define os
+    (marionette-operating-system
+     (operating-system
+       (inherit %simple-os)
+       (services (modify-services %base-services
+                   (syslog-service-type
+                    config => (syslog-configuration
+                               (inherit config)
+                               (config-file
+                                (plain-file
+                                 "syslog.conf"
+                                 "*.* /dev/console\n")))))))
+     #:imported-modules '((gnu services herd)
+                          (guix combinators))))
+
+  (define new-os
+    (marionette-operating-system
+     (virtualized-operating-system               ;run as with "guix system vm"
+      (operating-system
+        (inherit %simple-os)
+        (host-name "the-new-os")
+        (kernel-arguments '("console=ttyS0")))    ;be verbose
+      #:volatile? #t)                             ;mount root read-only
+     #:imported-modules '((gnu services herd)
+                          (guix combinators))))
+
+  (define vm (virtual-machine os))
+
+  (define test
+    (with-imported-modules '((gnu build marionette))
+      #~(begin
+          (use-modules (gnu build marionette)
+                       (srfi srfi-64))
+
+          (define marionette
+            (make-marionette (list #$vm)))
+
+          (test-runner-current (system-test-runner #$output))
+          (test-begin "kexec")
+
+          (test-equal "host name"
+            #$(operating-system-host-name os)
+            (marionette-eval '(gethostname) marionette))
+
+          (test-assert "kexec-loading-program"
+            (marionette-eval
+             '(primitive-load #$(kexec-loading-program new-os))
+             marionette))
+
+          (test-assert "reboot/kexec"
+            (marionette-eval
+             '(begin
+                (use-modules (gnu services herd))
+                (with-shepherd-action 'root ('kexec) result
+                  (pk 'reboot-kexec result)))
+             marionette))
+
+          (test-equal "host name of new OS"
+            #$(operating-system-host-name new-os)
+            (marionette-eval '(gethostname) marionette))
+
+          (test-end))))
+
+  (gexp->derivation "kexec-test" test))
+
 (define* (run-install-bootloader-test)
   "Run a test of an OS running INSTALL-BOOTLOADER-PROGRAM, which installs a
 bootloader's configuration file."
@@ -268,6 +340,12 @@ (define %test-upgrade-services
 loading new services.")
    (value (run-upgrade-services-test))))
 
+(define %test-upgrade-kexec
+  (system-test
+   (name "upgrade-kexec")
+   (description "Load a system and reboot into it via Linux kexec.")
+   (value (run-kexec-test))))
+
 (define %test-install-bootloader
   (system-test
    (name "install-bootloader")
diff --git a/guix/scripts/system.scm b/guix/scripts/system.scm
index dd34f6cd15..f174c8ada1 100644
--- a/guix/scripts/system.scm
+++ b/guix/scripts/system.scm
@@ -798,6 +798,7 @@ (define* (perform-action action image
                          save-provenance?
                          skip-safety-checks?
                          install-bootloader?
+                         load-for-kexec?
                          dry-run? derivations-only?
                          use-substitutes? target
                          full-boot?
@@ -900,7 +901,13 @@ (define* (perform-action action image
 To complete the upgrade, run 'herd restart SERVICE' to stop,
 upgrade, and restart each service that was not automatically restarted.\n")))
                 (return (format #t (G_ "\
-Run 'herd status' to view the list of services on your system.\n"))))))
+Run 'herd status' to view the list of services on your system.\n"))))
+               (mwhen load-for-kexec?
+                 (mlet %store-monad ((kexec? (load-system-for-kexec local-eval
+                                                                    os)))
+                   (mwhen kexec?
+                     (return (info (G_ "system loaded for fast reboot \
+ with 'reboot --kexec'~%"))))))))
             ((init)
              (newline)
              (format #t (G_ "initializing operating system under '~a'...~%")
@@ -1025,6 +1032,8 @@ (define (show-help)
       --image-size=SIZE  for 'image', produce an image of SIZE"))
   (display (G_ "
       --no-bootloader    for 'init', do not install a bootloader"))
+  (display (G_ "
+      --no-kexec         for 'reconfigure', do not load system for kexec reboot"))
   (display (G_ "
       --volatile         for 'image', make the root file system volatile"))
   (display (G_ "
@@ -1127,6 +1136,9 @@ (define %options
          (option '("no-bootloader" "no-grub") #f #f
                  (lambda (opt name arg result)
                    (alist-cons 'install-bootloader? #f result)))
+         (option '("no-kexec") #f #f
+                 (lambda (opt name arg result)
+                   (alist-cons 'load-for-kexec? #f result)))
          (option '("volatile") #f #f
                  (lambda (opt name arg result)
                    (alist-cons 'volatile-image-root? #t result)))
@@ -1198,6 +1210,7 @@ (define %default-options
     (image-type . mbr-hybrid-raw)
     (image-size . guess)
     (install-bootloader? . #t)
+    (load-for-kexec? . #t)
     (label . #f)
     (volatile-image-root? . #f)
     (volatile-vm-root? . #t)
@@ -1275,6 +1288,7 @@ (define (process-action action args opts)
                            (leave (G_ "no configuration specified~%")))))))
          (dry?        (assoc-ref opts 'dry-run?))
          (bootloader? (assoc-ref opts 'install-bootloader?))
+         (kexec?      (assoc-ref opts 'load-for-kexec?))
          (label       (assoc-ref opts 'label))
          (image-type  (lookup-image-type-by-name
                        (assoc-ref opts 'image-type)))
@@ -1360,6 +1374,7 @@ (define (process-action action args opts)
                                                         (_ #f))
                                                       opts)
                                #:install-bootloader? bootloader?
+                               #:load-for-kexec? kexec?
                                #:target target-file
                                #:gc-root (assoc-ref opts 'gc-root)))))
           #:target target
diff --git a/guix/scripts/system/reconfigure.scm b/guix/scripts/system/reconfigure.scm
index ddb561d28c..e9e16e3422 100644
--- a/guix/scripts/system/reconfigure.scm
+++ b/guix/scripts/system/reconfigure.scm
@@ -31,6 +31,7 @@ (define-module (guix scripts system reconfigure)
   #:use-module (gnu services herd)
   #:use-module (gnu services shepherd)
   #:use-module (gnu system)
+  #:autoload   (gnu system file-systems) (file-system-device)
   #:use-module (guix gexp)
   #:use-module (guix modules)
   #:use-module (guix monads)
@@ -52,6 +53,9 @@ (define-module (guix scripts system reconfigure)
             upgrade-services-program
             upgrade-shepherd-services
 
+            kexec-loading-program
+            load-system-for-kexec
+
             install-bootloader-program
             install-bootloader
 
@@ -176,6 +180,27 @@ (define (upgrade-services-program service-files to-start to-unload to-restart)
         (for-each unload-service '#$to-unload)
         (for-each start-service '#$to-start)))))
 
+(define (kexec-loading-program os)
+  "Return a program that calls 'kexec_file_load' to allow rebooting into OS
+via 'kexec'."
+  (let ((root-device (file-system-device
+                      (operating-system-root-file-system os))))
+    (program-file
+     "kexec-load-system.scm"
+     (with-imported-modules '((guix build syscalls))
+       #~(begin
+           (use-modules (guix build syscalls))
+
+           (let ((kernel (open-fdes #$(operating-system-kernel-file os)
+                                    O_RDONLY))
+                 (initrd (open-fdes #$(operating-system-initrd-file os)
+                                    O_RDONLY)))
+             (kexec-load-file kernel initrd
+                              (string-join
+                               (list #$@(operating-system-kernel-arguments
+                                         os root-device)))
+                              KEXEC_FILE_DEBUG)))))))
+
 (define* (upgrade-shepherd-services eval os)
   "Using EVAL, a monadic procedure taking a single G-Expression as an argument,
 upgrade the Shepherd (PID 1) by unloading obsolete services and loading new
@@ -205,6 +230,12 @@ (define* (upgrade-shepherd-services eval os)
                                                             to-unload
                                                             to-restart)))))))
 
+(define (load-system-for-kexec eval os)
+  "Load OS so that it can be rebooted into via kexec, if supported.  Return
+true on success."
+  (eval #~(and (string-contains %host-type "-linux")
+               (primitive-load #$(kexec-loading-program os)))))
+
 \f
 ;;;
 ;;; Bootloader configuration.
-- 
2.46.0





^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [bug#75027] [PATCH 0/3] 'guix system reconfigure' loads system for kexec reboot
  2024-12-23 18:24     ` Jakob Kirsch via Guix-patches via
@ 2024-12-26 17:25       ` Ludovic Courtès
  0 siblings, 0 replies; 18+ messages in thread
From: Ludovic Courtès @ 2024-12-26 17:25 UTC (permalink / raw)
  To: Jakob Kirsch; +Cc: 75027

Hi,

Jakob Kirsch <jakob.kirsch@web.de> skribis:

> On Mon, Dec 23, 2024 at 12:22:20PM +0100, Ludovic Courtès wrote:
>> In addition to or instead of running it by default?
>
> I would say in addition to but with a flag to not load it (like with "--no-bootloader" for the bootloader).

I sent v2, which includes some of your suggestions, but unfortunately
not the “kexec” system entry.

> Btw I've also noticed that the framebuffer is only initialized after something graphical (gdm in my case) has been started. This usually isn't an issue for most users but my disks are encrypted so I can't see the password prompt but I can still type in my password.

Weird; for me the Linux framebuffer is initialized early on.

Perhaps report a bug with details about your hardware and OS config?

Ludo’.




^ permalink raw reply	[flat|nested] 18+ messages in thread

* [bug#75027] [PATCH v2 1/3] syscalls: Add ‘kexec-load-file’.
  2024-12-26 17:21   ` [bug#75027] [PATCH v2 1/3] syscalls: Add ‘kexec-load-file’ Ludovic Courtès
@ 2024-12-28  6:12     ` Maxim Cournoyer
  2024-12-28 21:32       ` Ludovic Courtès
  0 siblings, 1 reply; 18+ messages in thread
From: Maxim Cournoyer @ 2024-12-28  6:12 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 75027

Hi Ludovic,

Ludovic Courtès <ludo@gnu.org> writes:

> * guix/build/syscalls.scm (string->utf-8/nul-terminated)
> (kexec-load-file): New procedures.

[...]

> +;; Constants from <linux/kexec.h>.
> +(define KEXEC_FILE_UNLOAD	#x00000001)
> +(define KEXEC_FILE_ON_CRASH	#x00000002)
> +(define KEXEC_FILE_NO_INITRAMFS	#x00000004)
> +(define KEXEC_FILE_DEBUG	#x00000008)
> +
> +(define kexec-load-file
> +  (let* ((proc (syscall->procedure int "syscall"
> +                                   (list long             ;sysno
> +                                         int              ;kernel fd
> +                                         int              ;initrd fd
> +                                         unsigned-long    ;cmdline length
> +                                         '*               ;cmdline
> +                                         unsigned-long))) ;flags
> +         ;; TODO: Don't do this.

Why this TODO?  "Don't do this" is not explicit enough; what would be
preferable to do here, but can't be done now for some reason?  Could we
instead detect the error as returned by the syscall when it's not
implemented, and throw/report the error accordingly?  I see that's kind
of done below (a misc-error is raised) -- I think we can remove this
special handling already and let the error be throw if it's not
implemented -- this removes the need to remember to come back here to
edit the list of supported systems the day they gain support.

> +         (syscall-id (match (utsname:machine (uname))
> +                       ("i686"    320)
> +                       ("x86_64"  320)
> +                       ("armv7l"  401)
> +                       ("aarch64" 401)
> +                       ;; XXX: There's apparently no support for ppc64le and
> +                       ;; riscv64.
> +                       (_ #f))))
> +    (lambda* (kernel-fd initrd-fd command-line #:optional (flags 0))
> +      "Load for eventual use of kexec(8) the Linux kernel from
> +@var{kernel-fd}, its initial RAM disk from @var{initrd-fd}, with the given
> +@var{command-line} (a string).  Optionally, @var{flags} can be a bitwise or of
> +the KEXEC_FILE_* constants."
> +      (let*-values (((command-line)
> +                     (string->utf-8/nul-terminated command-line))
> +                    ((ret err)
> +                     (proc syscall-id kernel-fd initrd-fd
> +                           (bytevector-length command-line)
> +                           (bytevector->pointer command-line)
> +                           flags)))
> +        (when (= ret -1)

I checked 'man 2 kexec_file_load*' to make sure:

       On success, these system calls returns 0.  On error, -1 is returned and
       errno is set to indicate the error.

So, looks good.

-- 
Thanks,
Maxim




^ permalink raw reply	[flat|nested] 18+ messages in thread

* [bug#75027] [PATCH v2 2/3] system: Export ‘…-initrd-file’ and ‘…-root-file-system’.
  2024-12-26 17:21   ` [bug#75027] [PATCH v2 2/3] system: Export ‘…-initrd-file’ and ‘…-root-file-system’ Ludovic Courtès
@ 2024-12-28  6:12     ` Maxim Cournoyer
  0 siblings, 0 replies; 18+ messages in thread
From: Maxim Cournoyer @ 2024-12-28  6:12 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: 75027

Ludovic Courtès <ludo@gnu.org> writes:

> * gnu/system.scm (operating-system-initrd-file): Fix docstring and
> export.
> (operating-system-root-file-system): Export.
>
> Change-Id: I5254d82ce547e8014027ed20675b8bfe5a5847c5

Reviewed-by: Maxim Cournoyer <maxim.cournoyer@gmail.com>

-- 
Thanks,
Maxim




^ permalink raw reply	[flat|nested] 18+ messages in thread

* [bug#75027] [PATCH v2 3/3] reconfigure: Support loading the system for kexec reboot.
  2024-12-26 17:21   ` [bug#75027] [PATCH v2 3/3] reconfigure: Support loading the system for kexec reboot Ludovic Courtès
@ 2024-12-28  7:22     ` Maxim Cournoyer
  2024-12-28 21:46       ` Ludovic Courtès
  0 siblings, 1 reply; 18+ messages in thread
From: Maxim Cournoyer @ 2024-12-28  7:22 UTC (permalink / raw)
  To: Ludovic Courtès
  Cc: Josselin Poiret, Simon Tournier, Mathieu Othacehe,
	Tobias Geerinckx-Rice, 75027, Christopher Baines

Hi,

Ludovic Courtès <ludo@gnu.org> writes:

> This allows rebooting straight into the new system with ‘reboot -k’.
>
> * guix/scripts/system/reconfigure.scm (kexec-loading-program)
> (load-system-for-kexec): New procedures.
> * gnu/tests/reconfigure.scm (run-kexec-test): New procedure.
> (%test-upgrade-kexec): New variable.
> * guix/scripts/system.scm (perform-action): Add #:load-for-kexec?.
> Call ‘load-system-for-kexec’.
> (show-help, %options): Add ‘--no-kexec’.
> (%default-options): Add ‘load-for-kexec?’.
> (process-action): Honor it and pass it to ‘perform-action’.
> * gnu/machine/ssh.scm (deploy-managed-host): Add call to
> ‘load-system-for-kexec’.
> * doc/guix.texi (Invoking guix system): Document it.

Neat.

[...]

> +@cindex kexec, for fast reboots
> +@cindex rebooting @i{via} Linux kexec

Oh, special formatting in index entries; is that allowed/encouraged?

[...]

> --- a/gnu/machine/ssh.scm
> +++ b/gnu/machine/ssh.scm
> @@ -1,6 +1,6 @@
>  ;;; GNU Guix --- Functional package management for GNU
>  ;;; Copyright © 2019 Jakob L. Kreuze <zerodaysfordays@sdf.org>
> -;;; Copyright © 2020-2023 Ludovic Courtès <ludo@gnu.org>
> +;;; Copyright © 2020-2024 Ludovic Courtès <ludo@gnu.org>
>  ;;; Copyright © 2024 Ricardo <rekado@elephly.net>
>  ;;;
>  ;;; This file is part of GNU Guix.
> @@ -552,6 +552,13 @@ (define (deploy-managed-host machine)
>                                                        (inferior-exception-arguments
>                                                         c)))
>                                             os)
> +                (load-system-for-kexec (eval/error-handling c
> +                                         (warning (G_ "\
> +failed to load system of '~a' for kexec reboot:~%~{~s ~}~%")

Nitpick: I guess ideally you don't want a trailing space added in your
formatted list, so you should escape the space something like '~%~{~s~^
~}~%' in your (ice-9 format) format string.

-- 
Thanks,
Maxim




^ permalink raw reply	[flat|nested] 18+ messages in thread

* [bug#75027] [PATCH v2 0/3] 'guix system reconfigure' loads system for kexec reboot
  2024-12-26 17:21 ` [bug#75027] [PATCH v2 " Ludovic Courtès
                     ` (2 preceding siblings ...)
  2024-12-26 17:21   ` [bug#75027] [PATCH v2 3/3] reconfigure: Support loading the system for kexec reboot Ludovic Courtès
@ 2024-12-28  7:24   ` Maxim Cournoyer
  2024-12-28 22:18     ` Ludovic Courtès
  3 siblings, 1 reply; 18+ messages in thread
From: Maxim Cournoyer @ 2024-12-28  7:24 UTC (permalink / raw)
  To: Ludovic Courtès
  Cc: Josselin Poiret, Simon Tournier, Mathieu Othacehe,
	Tobias Geerinckx-Rice, 75027, Jakob Kirsch, Christopher Baines

Hi Ludovic,

Ludovic Courtès <ludo@gnu.org> writes:

> Hello,
>
> Changes compared to v1:
>
>   • Move kexec code outside of ‘upgrade-shepherd-services’.  Now both
>     (guix scripts system) and (gnu machine ssh) have to explicitly
>     call ‘load-system-for-kexec’.
>

I've sent a couple comments; assuming you can address them, LGTM!
Thanks for working on this interesting improvement.

Reviewed-by: Maxim Cournoyer <maxim.cournoyer@gmail.com>

-- 
Thanks,
Maxim




^ permalink raw reply	[flat|nested] 18+ messages in thread

* [bug#75027] [PATCH v2 1/3] syscalls: Add ‘kexec-load-file’.
  2024-12-28  6:12     ` Maxim Cournoyer
@ 2024-12-28 21:32       ` Ludovic Courtès
  0 siblings, 0 replies; 18+ messages in thread
From: Ludovic Courtès @ 2024-12-28 21:32 UTC (permalink / raw)
  To: Maxim Cournoyer; +Cc: 75027

[-- Attachment #1: Type: text/plain, Size: 1649 bytes --]

Hi Maxim,

Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:

>> +(define kexec-load-file
>> +  (let* ((proc (syscall->procedure int "syscall"
>> +                                   (list long             ;sysno
>> +                                         int              ;kernel fd
>> +                                         int              ;initrd fd
>> +                                         unsigned-long    ;cmdline length
>> +                                         '*               ;cmdline
>> +                                         unsigned-long))) ;flags
>> +         ;; TODO: Don't do this.
>
> Why this TODO?  "Don't do this" is not explicit enough; what would be
> preferable to do here, but can't be done now for some reason?

The TODO is actually copy/pasted for a few lines above, but I agree it’s
not very clear nor helpful.  Presumably it’s here to mean that using the
‘syscall’ function and having to record syscall numbers of each
architecture is not great.  There’s no alternative though, at this time.

> Could we instead detect the error as returned by the syscall when it's
> not implemented, and throw/report the error accordingly?  I see that's
> kind of done below (a misc-error is raised) -- I think we can remove
> this special handling already and let the error be throw if it's not
> implemented -- this removes the need to remember to come back here to
> edit the list of supported systems the day they gain support.

Yes.  Plus I got the magic numbers wrong it seems (protip: it’s easier
to grep glibc than Linux to get them), so this gives us this change:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 1541 bytes --]

diff --git a/guix/build/syscalls.scm b/guix/build/syscalls.scm
index f8c9937f54..960339e8bf 100644
--- a/guix/build/syscalls.scm
+++ b/guix/build/syscalls.scm
@@ -793,20 +793,24 @@ (define kexec-load-file
                                          unsigned-long    ;cmdline length
                                          '*               ;cmdline
                                          unsigned-long))) ;flags
-         ;; TODO: Don't do this.
          (syscall-id (match (utsname:machine (uname))
                        ("i686"    320)
                        ("x86_64"  320)
                        ("armv7l"  401)
-                       ("aarch64" 401)
-                       ;; XXX: There's apparently no support for ppc64le and
-                       ;; riscv64.
+                       ("aarch64" 294)
+                       ("ppc64le" 382)
+                       ("riscv64" 294)
                        (_ #f))))
     (lambda* (kernel-fd initrd-fd command-line #:optional (flags 0))
       "Load for eventual use of kexec(8) the Linux kernel from
 @var{kernel-fd}, its initial RAM disk from @var{initrd-fd}, with the given
 @var{command-line} (a string).  Optionally, @var{flags} can be a bitwise or of
 the KEXEC_FILE_* constants."
+      (unless syscall-id
+        (throw 'system-error "kexec-load-file" "~A"
+               (list (strerror ENOSYS))
+               (list ENOSYS)))
+
       (let*-values (((command-line)
                      (string->utf-8/nul-terminated command-line))
                     ((ret err)

[-- Attachment #3: Type: text/plain, Size: 21 bytes --]


Thanks,
Ludo’.

^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [bug#75027] [PATCH v2 3/3] reconfigure: Support loading the system for kexec reboot.
  2024-12-28  7:22     ` Maxim Cournoyer
@ 2024-12-28 21:46       ` Ludovic Courtès
  0 siblings, 0 replies; 18+ messages in thread
From: Ludovic Courtès @ 2024-12-28 21:46 UTC (permalink / raw)
  To: Maxim Cournoyer
  Cc: Josselin Poiret, Simon Tournier, Mathieu Othacehe,
	Tobias Geerinckx-Rice, 75027, Christopher Baines

Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:

>> +@cindex kexec, for fast reboots
>> +@cindex rebooting @i{via} Linux kexec
>
> Oh, special formatting in index entries; is that allowed/encouraged?

It’s definitely allowed.

>> +                (load-system-for-kexec (eval/error-handling c
>> +                                         (warning (G_ "\
>> +failed to load system of '~a' for kexec reboot:~%~{~s ~}~%")
>
> Nitpick: I guess ideally you don't want a trailing space added in your
> formatted list, so you should escape the space something like '~%~{~s~^
> ~}~%' in your (ice-9 format) format string.

Good idea.  First time I use ~^.  :-)  Thanks!

Ludo’.




^ permalink raw reply	[flat|nested] 18+ messages in thread

* [bug#75027] [PATCH v2 0/3] 'guix system reconfigure' loads system for kexec reboot
  2024-12-28  7:24   ` [bug#75027] [PATCH v2 0/3] 'guix system reconfigure' loads " Maxim Cournoyer
@ 2024-12-28 22:18     ` Ludovic Courtès
  0 siblings, 0 replies; 18+ messages in thread
From: Ludovic Courtès @ 2024-12-28 22:18 UTC (permalink / raw)
  To: Maxim Cournoyer
  Cc: Josselin Poiret, Simon Tournier, Mathieu Othacehe,
	Tobias Geerinckx-Rice, 75027, Jakob Kirsch, Christopher Baines

Maxim Cournoyer <maxim.cournoyer@gmail.com> skribis:

> I've sent a couple comments; assuming you can address them, LGTM!
> Thanks for working on this interesting improvement.

Now pushed, taking your suggestions into account, and together with a
news entry (I should have posted it here from the start but I thought
about it too late):

  4f7b58b92a * news: Add entry about kexec.
  1305f78d05 * reconfigure: Support loading the system for kexec reboot.
  ebe706a1e8 * system: Export ‘…-initrd-file’ and ‘…-root-file-system’.
  5c9029dc79 * syscalls: Add ‘kexec-load-file’.

Thanks,
Ludo’.




^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2024-12-28 22:19 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-22 15:56 [bug#75027] [PATCH 0/3] 'guix system reconfigure' loads system for kexec reboot Ludovic Courtès
2024-12-22 15:57 ` [bug#75027] [PATCH 1/3] syscalls: Add ‘kexec-load-file’ Ludovic Courtès
2024-12-22 15:57 ` [bug#75027] [PATCH 2/3] system: Export ‘…-initrd-file’ and ‘…-root-file-system’ Ludovic Courtès
2024-12-22 15:57 ` [bug#75027] [PATCH 3/3] reconfigure: Call ‘kexec-load-file’ Ludovic Courtès
2024-12-22 21:47 ` [bug#75027] [PATCH 0/3] 'guix system reconfigure' loads system for kexec reboot Jakob Kirsch via Guix-patches via
     [not found]   ` <87y106ej9v.fsf@gnu.org>
2024-12-23 18:24     ` Jakob Kirsch via Guix-patches via
2024-12-26 17:25       ` Ludovic Courtès
2024-12-26 17:21 ` [bug#75027] [PATCH v2 " Ludovic Courtès
2024-12-26 17:21   ` [bug#75027] [PATCH v2 1/3] syscalls: Add ‘kexec-load-file’ Ludovic Courtès
2024-12-28  6:12     ` Maxim Cournoyer
2024-12-28 21:32       ` Ludovic Courtès
2024-12-26 17:21   ` [bug#75027] [PATCH v2 2/3] system: Export ‘…-initrd-file’ and ‘…-root-file-system’ Ludovic Courtès
2024-12-28  6:12     ` Maxim Cournoyer
2024-12-26 17:21   ` [bug#75027] [PATCH v2 3/3] reconfigure: Support loading the system for kexec reboot Ludovic Courtès
2024-12-28  7:22     ` Maxim Cournoyer
2024-12-28 21:46       ` Ludovic Courtès
2024-12-28  7:24   ` [bug#75027] [PATCH v2 0/3] 'guix system reconfigure' loads " Maxim Cournoyer
2024-12-28 22:18     ` Ludovic Courtès

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).