]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sysext: provide a cmdline kill switch for the sysext/confext merging logic 41161/head
authorVitaly Kuznetsov <vkuznets@redhat.com>
Thu, 19 Mar 2026 15:04:34 +0000 (16:04 +0100)
committerVitaly Kuznetsov <vkuznets@redhat.com>
Tue, 7 Apr 2026 07:51:03 +0000 (09:51 +0200)
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.

man/kernel-command-line.xml
man/systemd-sysext.xml
src/sysext/sysext.c
units/systemd-confext-initrd.service
units/systemd-confext-sysroot.service
units/systemd-confext.service
units/systemd-sysext-initrd.service
units/systemd-sysext-sysroot.service
units/systemd-sysext.service

index 9e24e749b3f97b9d53d6bb8259de02a4d1e0795a..0ad3c9c772f3e5e4f1641fd8a0d2986774a22c60 100644 (file)
         <xi:include href="version-info.xml" xpointer="v261"/></listitem>
       </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>
   </refsect1>
 
index 49cfee86687418fda20f64a16f56c50a8dbd880e..a0e77ad72945b2e18a79632bc02bb8037933bbb6 100644 (file)
     <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
     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
     <filename>/usr/lib/extension-release.d/extension-release.<replaceable>NAME</replaceable></filename>
index 52e6c3be666b0362b6118c9422d7d8666059dfc0..0ac35d1b56b8d78d62977e64db40df9fab532019 100644 (file)
@@ -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. */
index 67e1b1b8d3f33a764ecbc46ec999c5ad4ebca4af..9984bd7065217192ee8fc782d6f58c466123fedb 100644 (file)
@@ -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
index 2ca6da70aac21db72af7ccd606393c30a72dc507..e30193e17e4dc29a73a58fb5a7aa5bd9327851d7 100644 (file)
@@ -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
index e509036d035992ff9c876da893f2680bf02ffc2b..ffbf8345b8d6ad4623b49b5d4bfcb68d05f1dc27 100644 (file)
@@ -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
index c6e93a37195d11ab723516145530b5528fe36208..2d9fb59cf29001b803db9bcc7a5029920b9380ad 100644 (file)
@@ -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
index 11841ebdcd47e0be65e0f575c9eee2a1bfe58b87..d68c70da69127d1553eff7b1d13af038530a7788 100644 (file)
@@ -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
index f20a0761280228645b9fdd9d00f5e2699ab3b8be..3246ea7fb7b767c719fb3b27440d6e895e4a7047 100644 (file)
@@ -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