grub-devel
[Top][All Lists]
Advanced

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

[PATCH v5 0/1] Add support for grub-emu to kexec Linux menu entries


From: Robbie Harwood
Subject: [PATCH v5 0/1] Add support for grub-emu to kexec Linux menu entries
Date: Wed, 19 Oct 2022 14:49:59 -0400

Address feedback from Daniel's review (interdiff attached).  Specifically,
perform a style cleanup, add more documentation, and add three comments.

Be well,
--Robbie

Raymund Will (1):
  Add support for grub-emu to kexec Linux menu entries

 docs/grub.texi               |  28 ++++--
 grub-core/Makefile.am        |   1 +
 grub-core/Makefile.core.def  |   2 +-
 grub-core/kern/emu/main.c    |   4 +
 grub-core/kern/emu/misc.c    |  18 +++-
 grub-core/loader/emu/linux.c | 183 +++++++++++++++++++++++++++++++++++
 include/grub/emu/exec.h      |   4 +-
 include/grub/emu/hostfile.h  |   3 +-
 include/grub/emu/misc.h      |   3 +
 9 files changed, 233 insertions(+), 13 deletions(-)
 create mode 100644 grub-core/loader/emu/linux.c

Interdiff against v4:
diff --git a/docs/grub.texi b/docs/grub.texi
index af119dea3b..1463e62e6b 100644
--- a/docs/grub.texi
+++ b/docs/grub.texi
@@ -1,4 +1,4 @@
-\input texinfo
+i\input texinfo
 @c -*-texinfo-*-
 @c %**start of header
 @setfilename grub.info
@@ -923,17 +923,17 @@ magic.
 @node General boot methods
 @section How to boot operating systems
 
-GRUB has two distinct boot methods. One of the two is to load an
-operating system directly, and the other is to chain-load another boot
-loader which then will load an operating system actually. Generally
-speaking, the former is more desirable, because you don't need to
-install or maintain other boot loaders and GRUB is flexible enough to
-load an operating system from an arbitrary disk/partition. However,
-the latter is sometimes required, since GRUB doesn't support all the
-existing operating systems natively.
+GRUB has three distinct boot methods: loading an operating system
+directly, using kexec from userspace, and chainloading another
+bootloader.  Generally speaking, the first two are more desirable
+because you don't need to install or maintain other boot loaders and
+GRUB is flexible enough to load an operating system from an arbitrary
+disk/partition.  However, chainloading is sometimes required, as GRUB
+doesn't support all existing operating systems natively.
 
 @menu
 * Loading an operating system directly::
+* Kexec::
 * Chain-loading::
 @end menu
 
@@ -959,6 +959,16 @@ use more complicated instructions. @xref{DOS/Windows}, for 
more
 information.
 
 
+@node Kexec
+@subsection Kexec with grub2-emu
+
+grub2 can be run in userspace by invoking the grub2-emu tool.  It will
+read all configuration scripts as if booting directly (see @xref{Loading
+an operating system directly}).  With the @code{--kexec} flag, and
+kexec(8) support from the operating system, the @command{linux} command
+will directly boot the target image.
+
+
 @node Chain-loading
 @subsection Chain-loading an OS
 
diff --git a/grub-core/loader/emu/linux.c b/grub-core/loader/emu/linux.c
index bdcdbb0ff4..f232f195b3 100644
--- a/grub-core/loader/emu/linux.c
+++ b/grub-core/loader/emu/linux.c
@@ -1,6 +1,6 @@
 /*
  *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2008,2009,2010  Free Software Foundation, Inc.
+ *  Copyright (C) 2022  Free Software Foundation, Inc.
  *
  *  GRUB is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -38,8 +38,9 @@ grub_linux_boot (void)
 {
   grub_err_t rc = GRUB_ERR_NONE;
   char *initrd_param;
-  const char *kexec[] = { "kexec", "-la", kernel_path, boot_cmdline, NULL, 
NULL };
-  const char *systemctl[] = { "systemctl", "kexec", NULL };
+  const char *kexec[] = {"kexec", "-la", kernel_path, boot_cmdline, NULL,
+         NULL};
+  const char *systemctl[] = {"systemctl", "kexec", NULL};
   int kexecute = grub_util_get_kexecute ();
 
   if (initrd_path)
@@ -49,9 +50,7 @@ grub_linux_boot (void)
       kexec[4] = boot_cmdline;
     }
   else
-    {
-      initrd_param = grub_xasprintf ("%s", "");
-    }
+    initrd_param = grub_xasprintf ("%s", "");
 
   grub_dprintf ("linux", "%serforming 'kexec -la %s %s %s'\n",
                 (kexecute) ? "P" : "Not p",
@@ -64,30 +63,32 @@ grub_linux_boot (void)
 
   if (rc != GRUB_ERR_NONE)
     {
-      grub_error (rc, N_("Error trying to perform kexec load operation."));
+      grub_error (rc, N_("error trying to perform kexec load operation"));
       grub_sleep (3);
       return rc;
     }
 
   if (kexecute < 1)
-    grub_fatal (N_("Use '"PACKAGE"-emu --kexec' to force a system restart."));
+    grub_fatal (N_("use '"PACKAGE"-emu --kexec' to force a system restart"));
 
   grub_dprintf ("linux", "Performing 'systemctl kexec' (%s) ",
                (kexecute==1) ? "do-or-die" : "just-in-case");
   rc = grub_util_exec (systemctl);
 
   if (kexecute == 1)
-    grub_fatal (N_("Error trying to perform 'systemctl kexec'"));
+    grub_fatal (N_("error trying to perform 'systemctl kexec': %d"), rc);
 
-  /* WARNING: forcible reset should only be used in read-only environments.
-   * grub-emu cannot check for these - users beware. */
+  /*
+   * WARNING: forcible reset should only be used in read-only environments.
+   * grub-emu cannot check for these - users beware.
+   */
   grub_dprintf ("linux", "Performing 'kexec -e -x'");
   kexec[1] = "-e";
   kexec[2] = "-x";
   kexec[3] = NULL;
   rc = grub_util_exec (kexec);
   if ( rc != GRUB_ERR_NONE )
-    grub_fatal (N_("Error trying to directly perform 'kexec -e'."));
+    grub_fatal (N_("error trying to directly perform 'kexec -e': %d"), rc);
 
   return rc;
 }
@@ -95,45 +96,43 @@ grub_linux_boot (void)
 static grub_err_t
 grub_linux_unload (void)
 {
+  /* Unloading: we're no longer in use. */
   grub_dl_unref (my_mod);
-  if ( boot_cmdline != NULL )
-    grub_free (boot_cmdline);
+  grub_free (boot_cmdline);
   boot_cmdline = NULL;
   return GRUB_ERR_NONE;
 }
 
 static grub_err_t
-grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), int argc, char 
*argv[])
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), int argc,
+               char *argv[])
 {
   int i;
   char *tempstr;
 
+  /* Mark ourselves as in-use. */
   grub_dl_ref (my_mod);
 
   if (argc == 0)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
 
-  if ( !grub_util_is_regular (argv[0]) )
-    return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("Cannot find kernel file 
%s"), argv[0]);
-
-  if ( kernel_path != NULL )
-    grub_free (kernel_path);
+  if (!grub_util_is_regular (argv[0]))
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND,
+                      N_("cannot find kernel file %s"), argv[0]);
 
+  grub_free (kernel_path);
   kernel_path = grub_xasprintf ("%s", argv[0]);
 
-  if ( boot_cmdline != NULL )
-    {
-      grub_free(boot_cmdline);
-      boot_cmdline = NULL;
-    }
+  grub_free (boot_cmdline);
+  boot_cmdline = NULL;
 
-  if ( argc > 1 )
+  if (argc > 1)
     {
-      boot_cmdline = grub_xasprintf("--command-line=%s", argv[1]);
+      boot_cmdline = grub_xasprintf ("--command-line=%s", argv[1]);
       for ( i = 2; i < argc; i++ )
         {
-          tempstr = grub_xasprintf("%s %s", boot_cmdline, argv[i]);
-          grub_free(boot_cmdline);
+          tempstr = grub_xasprintf ("%s %s", boot_cmdline, argv[i]);
+          grub_free (boot_cmdline);
           boot_cmdline = tempstr;
         }
     }
@@ -144,19 +143,20 @@ grub_cmd_linux (grub_command_t cmd __attribute__ 
((unused)), int argc, char *arg
 }
 
 static grub_err_t
-grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), int argc, char 
*argv[])
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), int argc,
+                char *argv[])
 {
   if (argc == 0)
     return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
 
-  if ( !grub_util_is_regular (argv[0]) )
-    return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("Cannot find initrd file 
%s"), argv[0]);
-
-  if ( initrd_path != NULL )
-    grub_free (initrd_path);
+  if (!grub_util_is_regular (argv[0]))
+    return grub_error (GRUB_ERR_FILE_NOT_FOUND,
+                      N_("Cannot find initrd file %s"), argv[0]);
 
+  grub_free (initrd_path);
   initrd_path = grub_xasprintf("%s", argv[0]);
 
+  /* We are done - mark ourselves as on longer in use. */
   grub_dl_unref (my_mod);
 
   return GRUB_ERR_NONE;
@@ -166,8 +166,10 @@ static grub_command_t cmd_linux, cmd_initrd;
 
 GRUB_MOD_INIT (linux)
 {
-  cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0, N_("Load 
Linux."));
-  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, 0, N_("Load 
initrd."));
+  cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0,
+                                    N_("Load Linux."));
+  cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, 0,
+                                     N_("Load initrd."));
   my_mod = mod;
   kernel_path = NULL;
   initrd_path = NULL;
-- 
2.35.1




reply via email to

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