From: Vitaly Kuznetsov Date: Thu, 19 Mar 2026 15:04:34 +0000 (+0100) Subject: sysext: provide a cmdline kill switch for the sysext/confext merging logic X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2299a37e28249edd06fc66bfda2ad36106cf69da;p=thirdparty%2Fsystemd.git sysext: provide a cmdline kill switch for the sysext/confext merging logic While it is possible to disable sysext/confext merging in the main system with 'systemctl disable', sysext/confext are always merged in the initrd, both by systemd-{sys,conf}ext-initrd.service and by systemd-{sys,conf}ext-sysroot.service and especially the latter can be unexpected. Provide kernel cmdline options systemd.{sys,conf}ext=0 and rd.systemd.{sys,conf}ext=0 covering all options. --- diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml index 9e24e749b3f..0ad3c9c772f 100644 --- a/man/kernel-command-line.xml +++ b/man/kernel-command-line.xml @@ -829,6 +829,22 @@ + + systemd.sysext= + systemd.confext= + rd.systemd.sysext= + rd.systemd.confext= + + Take boolean arguments, default to on. Control whether system and configuration + extensions for the initrd (rd.systemd.sysext=, rd.systemd.confext=) + and for the main system (systemd.sysext=, systemd.confext=) are + merged automatically on boot. See + systemd-sysext8 + for details. + + + + diff --git a/man/systemd-sysext.xml b/man/systemd-sysext.xml index 49cfee86687..a0e77ad7294 100644 --- a/man/systemd-sysext.xml +++ b/man/systemd-sysext.xml @@ -150,7 +150,13 @@ Note that there is no concept of enabling/disabling installed system extension images: all installed extension images are automatically activated at boot. However, you can place an empty directory named like the extension (no .raw) in /etc/extensions/ to "mask" - an extension with the same name in a system folder with lower precedence. + an extension with the same name in a system folder with lower precedence. It is also possible to disable + automatic merging altogether using the rd.systemd.sysext=, rd.systemd.confext=, + systemd.sysext=, and systemd.confext= kernel command line options. + Note that systemd-sysext-sysroot.service and + systemd-confext-sysroot.service are controlled by the systemd.sysext= + and systemd.confext= options, as these services merge system and configuration + extensions for the main system, not for the initrd. A simple mechanism for version compatibility is enforced: a system extension image must carry a /usr/lib/extension-release.d/extension-release.NAME diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c index 52e6c3be666..0ac35d1b56b 100644 --- a/src/sysext/sysext.c +++ b/src/sysext/sysext.c @@ -51,6 +51,7 @@ #include "path-util.h" #include "pidref.h" #include "pretty-print.h" +#include "proc-cmdline.h" #include "process-util.h" #include "rm-rf.h" #include "runtime-scope.h" @@ -3038,6 +3039,22 @@ static int run(int argc, char *argv[]) { if (r <= 0) return r; + /* PROC_CMDLINE_STRIP_RD_PREFIX cannot be used here as we need to be able to distinguish between + * rd.systemd.{sysext,confext} and systemd.{sysext,confext} in the initrd where they are both used + * and have different meaning. */ + const char *string_class = image_class_to_string(arg_image_class); + const char *cmdline_opt = strjoina(in_initrd() && !arg_root ? "rd." : "", "systemd.", string_class); + + bool enabled; + r = proc_cmdline_get_bool(cmdline_opt, PROC_CMDLINE_TRUE_WHEN_MISSING, &enabled); + if (r < 0) + log_debug_errno(r, "Failed to check '%s=' kernel command line option, proceeding: %m", cmdline_opt); + else if (!enabled && invoked_by_systemd()) { + /* Kernel command line option should not affect manual invocation. */ + log_notice("Disabled by the kernel command line option '%s=', skipping execution.", cmdline_opt); + return 0; + } + /* Parse configuration file after argv because it needs --root=. * The config entries will not overwrite values set already by * env/argv because we track initialization. */ diff --git a/units/systemd-confext-initrd.service b/units/systemd-confext-initrd.service index 67e1b1b8d3f..9984bd70652 100644 --- a/units/systemd-confext-initrd.service +++ b/units/systemd-confext-initrd.service @@ -19,6 +19,7 @@ ConditionDirectoryNotEmpty=|/usr/lib/confexts ConditionDirectoryNotEmpty=|/.extra/confext ConditionDirectoryNotEmpty=|/.extra/global_confext ConditionPathExists=/etc/initrd-release +ConditionKernelCommandLine=!rd.systemd.confext=0 DefaultDependencies=no Before=local-fs-pre.target cryptsetup-pre.target systemd-tmpfiles-setup.service diff --git a/units/systemd-confext-sysroot.service b/units/systemd-confext-sysroot.service index 2ca6da70aac..e30193e17e4 100644 --- a/units/systemd-confext-sysroot.service +++ b/units/systemd-confext-sysroot.service @@ -16,6 +16,7 @@ ConditionDirectoryNotEmpty=|/sysroot/var/lib/confexts ConditionDirectoryNotEmpty=|/sysroot/usr/local/lib/confexts ConditionDirectoryNotEmpty=|/sysroot/usr/lib/confexts ConditionPathExists=/etc/initrd-release +ConditionKernelCommandLine=!systemd.confext=0 DefaultDependencies=no Conflicts=shutdown.target diff --git a/units/systemd-confext.service b/units/systemd-confext.service index e509036d035..ffbf8345b8d 100644 --- a/units/systemd-confext.service +++ b/units/systemd-confext.service @@ -17,6 +17,7 @@ ConditionDirectoryNotEmpty=|/var/lib/confexts ConditionDirectoryNotEmpty=|/usr/local/lib/confexts ConditionDirectoryNotEmpty=|/usr/lib/confexts ConditionPathExists=!/etc/initrd-release +ConditionKernelCommandLine=!systemd.confext=0 DefaultDependencies=no After=local-fs.target diff --git a/units/systemd-sysext-initrd.service b/units/systemd-sysext-initrd.service index c6e93a37195..2d9fb59cf29 100644 --- a/units/systemd-sysext-initrd.service +++ b/units/systemd-sysext-initrd.service @@ -18,6 +18,7 @@ ConditionDirectoryNotEmpty=|/var/lib/extensions ConditionDirectoryNotEmpty=|/.extra/sysext ConditionDirectoryNotEmpty=|/.extra/global_sysext ConditionPathExists=/etc/initrd-release +ConditionKernelCommandLine=!rd.systemd.sysext=0 DefaultDependencies=no Before=local-fs-pre.target cryptsetup-pre.target systemd-tmpfiles-setup.service diff --git a/units/systemd-sysext-sysroot.service b/units/systemd-sysext-sysroot.service index 11841ebdcd4..d68c70da691 100644 --- a/units/systemd-sysext-sysroot.service +++ b/units/systemd-sysext-sysroot.service @@ -15,6 +15,7 @@ ConditionCapability=CAP_SYS_ADMIN ConditionDirectoryNotEmpty=|/sysroot/etc/extensions ConditionDirectoryNotEmpty=|/sysroot/var/lib/extensions ConditionPathExists=/etc/initrd-release +ConditionKernelCommandLine=!systemd.sysext=0 DefaultDependencies=no Conflicts=shutdown.target diff --git a/units/systemd-sysext.service b/units/systemd-sysext.service index f20a0761280..3246ea7fb7b 100644 --- a/units/systemd-sysext.service +++ b/units/systemd-sysext.service @@ -17,6 +17,7 @@ ConditionDirectoryNotEmpty=|/run/extensions ConditionDirectoryNotEmpty=|/var/lib/extensions ConditionDirectoryNotEmpty=|/var/lib/extensions.mutable ConditionPathExists=!/etc/initrd-release +ConditionKernelCommandLine=!systemd.sysext=0 DefaultDependencies=no After=local-fs.target