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.
This commit is contained in:
Vitaly Kuznetsov
2026-04-07 09:51:03 +02:00
parent c70b17daad
commit 2299a37e28
9 changed files with 46 additions and 1 deletions
+16
View File
@@ -829,6 +829,22 @@
<xi:include href="version-info.xml" xpointer="v261"/></listitem> <xi:include href="version-info.xml" xpointer="v261"/></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>systemd.sysext=</varname></term>
<term><varname>systemd.confext=</varname></term>
<term><varname>rd.systemd.sysext=</varname></term>
<term><varname>rd.systemd.confext=</varname></term>
<listitem><para>Take boolean arguments, default to on. Control whether system and configuration
extensions for the initrd (<varname>rd.systemd.sysext=</varname>, <varname>rd.systemd.confext=</varname>)
and for the main system (<varname>systemd.sysext=</varname>, <varname>systemd.confext=</varname>) are
merged automatically on boot. See
<citerefentry><refentrytitle>systemd-sysext</refentrytitle><manvolnum>8</manvolnum></citerefentry>
for details.</para>
<xi:include href="version-info.xml" xpointer="v261"/></listitem>
</varlistentry>
</variablelist> </variablelist>
</refsect1> </refsect1>
+7 -1
View File
@@ -150,7 +150,13 @@
<para>Note that there is no concept of enabling/disabling installed system extension images: all <para>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 installed extension images are automatically activated at boot. However, you can place an empty directory
named like the extension (no <filename>.raw</filename>) in <filename>/etc/extensions/</filename> to "mask" named like the extension (no <filename>.raw</filename>) in <filename>/etc/extensions/</filename> to "mask"
an extension with the same name in a system folder with lower precedence.</para> an extension with the same name in a system folder with lower precedence. It is also possible to disable
automatic merging altogether using the <varname>rd.systemd.sysext=</varname>, <varname>rd.systemd.confext=</varname>,
<varname>systemd.sysext=</varname>, and <varname>systemd.confext=</varname> kernel command line options.
Note that <filename>systemd-sysext-sysroot.service</filename> and
<filename>systemd-confext-sysroot.service</filename> are controlled by the <varname>systemd.sysext=</varname>
and <varname>systemd.confext=</varname> options, as these services merge system and configuration
extensions for the main system, not for the initrd.</para>
<para>A simple mechanism for version compatibility is enforced: a system extension image must carry a <para>A simple mechanism for version compatibility is enforced: a system extension image must carry a
<filename>/usr/lib/extension-release.d/extension-release.<replaceable>NAME</replaceable></filename> <filename>/usr/lib/extension-release.d/extension-release.<replaceable>NAME</replaceable></filename>
+17
View File
@@ -51,6 +51,7 @@
#include "path-util.h" #include "path-util.h"
#include "pidref.h" #include "pidref.h"
#include "pretty-print.h" #include "pretty-print.h"
#include "proc-cmdline.h"
#include "process-util.h" #include "process-util.h"
#include "rm-rf.h" #include "rm-rf.h"
#include "runtime-scope.h" #include "runtime-scope.h"
@@ -3038,6 +3039,22 @@ static int run(int argc, char *argv[]) {
if (r <= 0) if (r <= 0)
return r; 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=. /* Parse configuration file after argv because it needs --root=.
* The config entries will not overwrite values set already by * The config entries will not overwrite values set already by
* env/argv because we track initialization. */ * env/argv because we track initialization. */
+1
View File
@@ -19,6 +19,7 @@ ConditionDirectoryNotEmpty=|/usr/lib/confexts
ConditionDirectoryNotEmpty=|/.extra/confext ConditionDirectoryNotEmpty=|/.extra/confext
ConditionDirectoryNotEmpty=|/.extra/global_confext ConditionDirectoryNotEmpty=|/.extra/global_confext
ConditionPathExists=/etc/initrd-release ConditionPathExists=/etc/initrd-release
ConditionKernelCommandLine=!rd.systemd.confext=0
DefaultDependencies=no DefaultDependencies=no
Before=local-fs-pre.target cryptsetup-pre.target systemd-tmpfiles-setup.service Before=local-fs-pre.target cryptsetup-pre.target systemd-tmpfiles-setup.service
+1
View File
@@ -16,6 +16,7 @@ ConditionDirectoryNotEmpty=|/sysroot/var/lib/confexts
ConditionDirectoryNotEmpty=|/sysroot/usr/local/lib/confexts ConditionDirectoryNotEmpty=|/sysroot/usr/local/lib/confexts
ConditionDirectoryNotEmpty=|/sysroot/usr/lib/confexts ConditionDirectoryNotEmpty=|/sysroot/usr/lib/confexts
ConditionPathExists=/etc/initrd-release ConditionPathExists=/etc/initrd-release
ConditionKernelCommandLine=!systemd.confext=0
DefaultDependencies=no DefaultDependencies=no
Conflicts=shutdown.target Conflicts=shutdown.target
+1
View File
@@ -17,6 +17,7 @@ ConditionDirectoryNotEmpty=|/var/lib/confexts
ConditionDirectoryNotEmpty=|/usr/local/lib/confexts ConditionDirectoryNotEmpty=|/usr/local/lib/confexts
ConditionDirectoryNotEmpty=|/usr/lib/confexts ConditionDirectoryNotEmpty=|/usr/lib/confexts
ConditionPathExists=!/etc/initrd-release ConditionPathExists=!/etc/initrd-release
ConditionKernelCommandLine=!systemd.confext=0
DefaultDependencies=no DefaultDependencies=no
After=local-fs.target After=local-fs.target
+1
View File
@@ -18,6 +18,7 @@ ConditionDirectoryNotEmpty=|/var/lib/extensions
ConditionDirectoryNotEmpty=|/.extra/sysext ConditionDirectoryNotEmpty=|/.extra/sysext
ConditionDirectoryNotEmpty=|/.extra/global_sysext ConditionDirectoryNotEmpty=|/.extra/global_sysext
ConditionPathExists=/etc/initrd-release ConditionPathExists=/etc/initrd-release
ConditionKernelCommandLine=!rd.systemd.sysext=0
DefaultDependencies=no DefaultDependencies=no
Before=local-fs-pre.target cryptsetup-pre.target systemd-tmpfiles-setup.service Before=local-fs-pre.target cryptsetup-pre.target systemd-tmpfiles-setup.service
+1
View File
@@ -15,6 +15,7 @@ ConditionCapability=CAP_SYS_ADMIN
ConditionDirectoryNotEmpty=|/sysroot/etc/extensions ConditionDirectoryNotEmpty=|/sysroot/etc/extensions
ConditionDirectoryNotEmpty=|/sysroot/var/lib/extensions ConditionDirectoryNotEmpty=|/sysroot/var/lib/extensions
ConditionPathExists=/etc/initrd-release ConditionPathExists=/etc/initrd-release
ConditionKernelCommandLine=!systemd.sysext=0
DefaultDependencies=no DefaultDependencies=no
Conflicts=shutdown.target Conflicts=shutdown.target
+1
View File
@@ -17,6 +17,7 @@ ConditionDirectoryNotEmpty=|/run/extensions
ConditionDirectoryNotEmpty=|/var/lib/extensions ConditionDirectoryNotEmpty=|/var/lib/extensions
ConditionDirectoryNotEmpty=|/var/lib/extensions.mutable ConditionDirectoryNotEmpty=|/var/lib/extensions.mutable
ConditionPathExists=!/etc/initrd-release ConditionPathExists=!/etc/initrd-release
ConditionKernelCommandLine=!systemd.sysext=0
DefaultDependencies=no DefaultDependencies=no
After=local-fs.target After=local-fs.target