]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
systemctl: add --kernel-cmdline= argument
authorLuca Boccassi <luca.boccassi@gmail.com>
Thu, 16 Apr 2026 22:50:07 +0000 (23:50 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Fri, 17 Apr 2026 12:58:05 +0000 (13:58 +0100)
Allows appending kernel command line arguments, like
kexec-tool does. This is especially needed for the integration
tests, as mkosi adds a bunch of options that are needed for the
test suite to work, and it breaks without them.

man/systemctl.xml
shell-completion/bash/systemctl.in
src/systemctl/systemctl-start-special.c
src/systemctl/systemctl.c
src/systemctl/systemctl.h

index 2a542ba466a0da5cdaf73bd1c24edd8ff511097f..8b8d1065556f2ea386e268c793e6899733546e77 100644 (file)
@@ -2795,6 +2795,21 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>--kernel-cmdline=</option></term>
+
+        <listitem>
+          <para>When used with <command>kexec</command>, append the specified string to the kernel command
+          line options of the kexec kernel. The kernel command line is taken from the boot loader entry of
+          the currently booted kernel (as selected automatically when no kexec kernel is preloaded, see
+          <command>kexec</command> above). This string is appended verbatim, separated from the existing
+          options by a single space. <command>systemctl kexec</command> will fail if this option is specified
+          when a kexec kernel is already loaded.</para>
+
+          <xi:include href="version-info.xml" xpointer="v261"/>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><option>--plain</option></term>
 
index c34c7fb10ebc23b96918dc71ac69250ebaac29a9..9f52115b7328ad438e32aa173db3d7cab122505a 100644 (file)
@@ -137,7 +137,7 @@ _systemctl () {
                       --show-transaction -T --mkdir --read-only'
         [ARG]='--host -H --kill-whom --property -p -P --signal -s --type -t --state --job-mode --root
                --preset-mode -n --lines -o --output -M --machine --message --timestamp --check-inhibitors --what
-               --image --boot-loader-menu --boot-loader-entry --reboot-argument --drop-in'
+               --image --boot-loader-menu --boot-loader-entry --reboot-argument --kernel-cmdline --drop-in'
     )
 
     if __contains_word "--user" ${COMP_WORDS[*]}; then
index b7d10eb891d6cc74b58d24f7abeb82d679dd67eb..fd38c678ea69a564d0d041e9a404c0ad0fc36382 100644 (file)
@@ -28,6 +28,9 @@ static int load_kexec_kernel(void) {
         int r;
 
         if (kexec_loaded()) {
+                if (arg_kernel_cmdline)
+                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                               "--kernel-cmdline= specified but kexec kernel already loaded");
                 log_debug("Kexec kernel already loaded.");
                 return 0;
         }
@@ -78,6 +81,9 @@ static int load_kexec_kernel(void) {
         if (!options)
                 return log_oom();
 
+        if (!isempty(arg_kernel_cmdline) && !strextend_with_separator(&options, " ", arg_kernel_cmdline))
+                return log_oom();
+
         log_full(arg_quiet ? LOG_DEBUG : LOG_INFO,
                  "%s %s kernel=\"%s\" cmdline=\"%s\"%s%s%s",
                  arg_dry_run ? "Would call" : "Calling",
index 3d3ed98fcd2ed088404877d69b2ef82101662a12..5c9a24b119aded7e93037f81b21203d3eb84e399 100644 (file)
@@ -27,6 +27,7 @@
 #include "systemctl-compat-shutdown.h"
 #include "systemctl-logind.h"
 #include "time-util.h"
+#include "utf8.h"
 
 char **arg_types = NULL;
 char **arg_states = NULL;
@@ -68,6 +69,7 @@ char *arg_image = NULL;
 usec_t arg_when = 0;
 bool arg_stdin = false;
 const char *arg_reboot_argument = NULL;
+char *arg_kernel_cmdline = NULL;
 enum action arg_action = ACTION_SYSTEMCTL;
 BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
 const char *arg_host = NULL;
@@ -98,6 +100,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_kill_whom, unsetp);
 STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_reboot_argument, unsetp);
+STATIC_DESTRUCTOR_REGISTER(arg_kernel_cmdline, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_host, unsetp);
 STATIC_DESTRUCTOR_REGISTER(arg_boot_loader_entry, unsetp);
 STATIC_DESTRUCTOR_REGISTER(arg_clean_what, strv_freep);
@@ -305,6 +308,9 @@ static int systemctl_help(void) {
                "                         Boot into a specific boot loader entry on next boot\n"
                "     --reboot-argument=ARG\n"
                "                         Specify argument string to pass to reboot()\n"
+               "     --kernel-cmdline=CMDLINE\n"
+               "                         Append to the kernel command line when loading the\n"
+               "                         kernel from the booted boot loader entry\n"
                "     --plain             Print unit dependencies as a list instead of a tree\n"
                "     --timestamp=FORMAT  Change format of printed timestamps (pretty, unix,\n"
                "                             us, utc, us+utc)\n"
@@ -434,6 +440,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                 ARG_WAIT,
                 ARG_WHAT,
                 ARG_REBOOT_ARG,
+                ARG_KERNEL_CMDLINE,
                 ARG_TIMESTAMP_STYLE,
                 ARG_READ_ONLY,
                 ARG_MKDIR,
@@ -505,6 +512,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                 { "show-transaction",    no_argument,       NULL, 'T'                     },
                 { "what",                required_argument, NULL, ARG_WHAT                },
                 { "reboot-argument",     required_argument, NULL, ARG_REBOOT_ARG          },
+                { "kernel-cmdline",      required_argument, NULL, ARG_KERNEL_CMDLINE      },
                 { "timestamp",           required_argument, NULL, ARG_TIMESTAMP_STYLE     },
                 { "read-only",           no_argument,       NULL, ARG_READ_ONLY           },
                 { "mkdir",               no_argument,       NULL, ARG_MKDIR               },
@@ -960,6 +968,19 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                         arg_reboot_argument = optarg;
                         break;
 
+                case ARG_KERNEL_CMDLINE:
+                        if (!utf8_is_valid(optarg))
+                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                                       "--kernel-cmdline= argument is not valid UTF-8: %s", optarg);
+                        if (string_has_cc(optarg, NULL))
+                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                                       "--kernel-cmdline= argument contains control characters: %s", optarg);
+
+                        r = free_and_strdup_warn(&arg_kernel_cmdline, optarg);
+                        if (r < 0)
+                                 return r;
+                        break;
+
                 case ARG_TIMESTAMP_STYLE:
                         if (streq(optarg, "help"))
                                 return DUMP_STRING_TABLE(timestamp_style, TimestampStyle, _TIMESTAMP_STYLE_MAX);
index 8d4b1a614da285c7d8e1488b3d86d58f0a866211..bc52e96fe3bfd8a8a1615152fbf8d33341d2493a 100644 (file)
@@ -76,6 +76,7 @@ extern char *arg_image;
 extern usec_t arg_when;
 extern bool arg_stdin;
 extern const char *arg_reboot_argument;
+extern char *arg_kernel_cmdline;
 extern enum action arg_action;
 extern BusTransport arg_transport;
 extern const char *arg_host;