diff --git a/NEWS b/NEWS
index 71ad345523..dc205e6a47 100644
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,15 @@ CHANGES WITH 261 in spe:
require direct IMDS access. The new meson option "-Dimds-network="
can be used to change the default mode to "locked" at build-time.
+ Changes in systemd-sysext/systemd-confext:
+
+ * New initrd services systemd-sysext-sysroot.service and
+ systemd-confext-sysroot.service are provided. These services are
+ used to merge system and configuration extensions for the main system
+ from the initrd. This overcomes the limitation that system and
+ configuration extensions merged from the main system itself cannot be
+ used to modify the resources which are used in the early boot.
+
CHANGES WITH 260:
Feature Removals and Incompatible Changes:
@@ -689,9 +698,9 @@ CHANGES WITH 259:
systemd-sysext/systemd-confext:
* systemd-sysext and systemd-confext now support configuration files
- /etc/systemd/systemd-sysext.conf and /etc/systemd/systemd-confext.conf,
- which can be used to configure mutability or the image policy to
- apply to DDI images.
+ /etc/systemd/sysext.conf and /etc/systemd/confext.conf, which can be
+ used to configure mutability or the image policy to apply to DDI
+ images.
* systemd-sysext's and systemd-confext's --mutable= switch now accepts
a new value "help" for listing available mutability modes.
diff --git a/TODO b/TODO
index 378d318122..aca06755c0 100644
--- a/TODO
+++ b/TODO
@@ -119,6 +119,8 @@ Deprecations and removals:
similar "devices"
Features:
+* sysext: make systemd-{sys,conf}ext-sysroot.service work in the split '/var'
+ configuration.
* sd-varlink: add fully async modes of the protocol upgrade stuff
@@ -1769,9 +1771,6 @@ Features:
* in sd-id128: also parse UUIDs in RFC4122 URN syntax (i.e. chop off urn:uuid: prefix)
-* systemd-sysext: optionally, run it in initrd already, before transitioning
- into host, to open up possibility for services shipped like that.
-
* whenever we receive fds via SCM_RIGHTS make sure none got dropped due to the
reception limit the kernel silently enforces.
diff --git a/man/kernel-command-line.xml b/man/kernel-command-line.xml
index 9e24e749b3..0ad3c9c772 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/rules/meson.build b/man/rules/meson.build
index 911a68543e..aa2653ce0d 100644
--- a/man/rules/meson.build
+++ b/man/rules/meson.build
@@ -1197,8 +1197,10 @@ manpages = [
'8',
['systemd-confext',
'systemd-confext-initrd.service',
+ 'systemd-confext-sysroot.service',
'systemd-confext.service',
'systemd-sysext-initrd.service',
+ 'systemd-sysext-sysroot.service',
'systemd-sysext.service'],
'ENABLE_SYSEXT'],
['systemd-system-update-generator', '8', [], ''],
diff --git a/man/systemd-sysext.xml b/man/systemd-sysext.xml
index c9a8f1ed01..a0e77ad729 100644
--- a/man/systemd-sysext.xml
+++ b/man/systemd-sysext.xml
@@ -20,9 +20,11 @@
systemd-sysext
systemd-sysext.service
systemd-sysext-initrd.service
+ systemd-sysext-sysroot.service
systemd-confext
systemd-confext.service
systemd-confext-initrd.service
+ systemd-confext-sysroot.service
Activates System Extension Images
@@ -114,27 +116,47 @@
systemd-stub7 with
extension images found in the system's EFI System Partition.
- During boot OS extension images are activated automatically, if the
- systemd-sysext.service is enabled. Note that this service runs only after the
- underlying file systems where system extensions may be located have been mounted. This means they are not
- suitable for shipping resources that are processed by subsystems running in earliest boot. Specifically,
- OS extension images are not suitable for shipping system services or
+ During boot, system and configuration extension images are activated automatically if the
+ systemd-sysext.service and systemd-confext.service services are
+ enabled. Note that these services run only after the underlying file systems where system and configuration
+ extensions may be located have been mounted. To make it possible to ship resources that are processed by
+ subsystems running in the earliest boot stages (for example, system services or
systemd-sysusers8
- definitions. See the Portable Services page
- for a simple mechanism for shipping system services in disk images, in a similar fashion to OS
- extensions. Note the different isolation on these two mechanisms: while system extension directly extend
- the underlying OS image with additional files that appear in a way very similar to as if they were
- shipped in the OS image itself and thus imply no security isolation, portable services imply service
- level sandboxing in one way or another. The systemd-sysext.service service is
- guaranteed to finish start-up before basic.target is reached; i.e. at the time
+ definitions), the systemd-sysext-sysroot.service and
+ systemd-confext-sysroot.service initrd services are provided. Currently, these
+ services cannot be used to merge system extensions from /sysroot/var/lib/extensions/
+ and configuration extensions from /sysroot/var/lib/confexts/ when the
+ /var/ partition is split off. These extensions are later merged by the
+ systemd-sysext.service and systemd-confext.service services
+ during the main OS boot process.
+
+ Also, see the Portable Services
+ page for a simple mechanism for shipping system services in disk images, in a similar fashion to OS
+ extensions. Note the differences in isolation between these two mechanisms: while system extensions directly extend
+ the underlying OS image with additional files that appear as if they were shipped in the OS image itself
+ and thus imply no security isolation, portable services imply service-level sandboxing in one way or another.
+
+ The systemd-sysext.service and systemd-confext.service
+ services are guaranteed to finish start-up before basic.target is reached; i.e., by the time
regular services initialize (those which do not use DefaultDependencies=no), the files
- and directories system extensions provide are available in /usr/ and
- /opt/ and may be accessed.
+ and directories provided by system and configuration extensions are available in /usr/,
+ /opt/, and /etc/ and may be accessed.
+
+ System and configuration extensions can also be used to extend the initrd, and the
+ systemd-sysext-initrd.service and systemd-confext-initrd.service
+ initrd services are provided. Note that some limitations apply: resources that are used in the earliest boot
+ stages of the initrd (e.g. system services) cannot be updated.
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/presets/90-systemd-initrd.preset b/presets/90-systemd-initrd.preset
index e966a182f1..b7b966daca 100644
--- a/presets/90-systemd-initrd.preset
+++ b/presets/90-systemd-initrd.preset
@@ -9,12 +9,14 @@
# Settings for systemd units distributed with systemd itself, specific to initrds.
+enable systemd-confext-sysroot.service
enable systemd-journald-audit.socket
enable systemd-network-generator.service
enable systemd-networkd.service
enable systemd-networkd-wait-online.service
enable systemd-pstore.service
enable systemd-resolved.service
+enable systemd-sysext-sysroot.service
enable systemd-tpm2-clear.service
disable console-getty.service
diff --git a/presets/90-systemd.preset b/presets/90-systemd.preset
index 56f9e93706..cd7afb5df2 100644
--- a/presets/90-systemd.preset
+++ b/presets/90-systemd.preset
@@ -52,7 +52,9 @@ disable proc-sys-fs-binfmt_misc.mount
disable syslog.socket
disable systemd-boot-check-no-failures.service
+disable systemd-confext-sysroot.service
disable systemd-journal-gatewayd.*
disable systemd-journal-remote.*
disable systemd-journal-upload.*
+disable systemd-sysext-sysroot.service
disable systemd-time-wait-sync.service
diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c
index 52e6c3be66..0ac35d1b56 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/meson.build b/units/meson.build
index 02c2db074c..16c082a623 100644
--- a/units/meson.build
+++ b/units/meson.build
@@ -311,6 +311,10 @@ units = [
'conditions' : ['ENABLE_INITRD', 'ENABLE_SYSEXT'],
'symlinks' : ['initrd.target.wants/'],
},
+ {
+ 'file' : 'systemd-confext-sysroot.service',
+ 'conditions' : ['ENABLE_INITRD', 'ENABLE_SYSEXT'],
+ },
{
'file' : 'systemd-coredump.socket',
'conditions' : ['ENABLE_COREDUMP'],
@@ -759,6 +763,10 @@ units = [
'conditions' : ['ENABLE_INITRD', 'ENABLE_SYSEXT'],
'symlinks' : ['initrd.target.wants/'],
},
+ {
+ 'file' : 'systemd-sysext-sysroot.service',
+ 'conditions' : ['ENABLE_INITRD', 'ENABLE_SYSEXT'],
+ },
{
'file' : 'systemd-sysext.socket',
'conditions' : ['ENABLE_SYSEXT'],
diff --git a/units/systemd-confext-initrd.service b/units/systemd-confext-initrd.service
index 073307edcc..9984bd7065 100644
--- a/units/systemd-confext-initrd.service
+++ b/units/systemd-confext-initrd.service
@@ -8,7 +8,7 @@
# (at your option) any later version.
[Unit]
-Description=Merge System Configuration Images into /etc/
+Description=Merge System Configuration Images into /etc/ of the initrd
Documentation=man:systemd-confext-initrd.service(8)
ConditionCapability=CAP_SYS_ADMIN
@@ -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
new file mode 100644
index 0000000000..e30193e17e
--- /dev/null
+++ b/units/systemd-confext-sysroot.service
@@ -0,0 +1,33 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=Merge System Configuration Images into /sysroot/etc/
+Documentation=man:systemd-confext-sysroot.service(8)
+
+ConditionCapability=CAP_SYS_ADMIN
+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
+Before=initrd-root-fs.target shutdown.target
+Wants=modprobe@loop.service modprobe@dm_mod.service
+After=modprobe@loop.service modprobe@dm_mod.service sysroot.mount sysroot-usr.mount systemd-volatile-root.service
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=systemd-confext --root=/sysroot refresh
+
+[Install]
+WantedBy=initrd.target
diff --git a/units/systemd-confext.service b/units/systemd-confext.service
index e509036d03..ffbf8345b8 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 4a411bb65e..2d9fb59cf2 100644
--- a/units/systemd-sysext-initrd.service
+++ b/units/systemd-sysext-initrd.service
@@ -8,7 +8,7 @@
# (at your option) any later version.
[Unit]
-Description=Merge System Extension Images into /usr/ and /opt/
+Description=Merge System Extension Images into /usr/ and /opt/ of the initrd
Documentation=man:systemd-sysext-initrd.service(8)
ConditionCapability=CAP_SYS_ADMIN
@@ -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
new file mode 100644
index 0000000000..d68c70da69
--- /dev/null
+++ b/units/systemd-sysext-sysroot.service
@@ -0,0 +1,32 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=Merge System Extension Images into /sysroot/usr/ and /sysroot/opt/
+Documentation=man:systemd-sysext-sysroot.service(8)
+
+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
+Before=initrd-root-fs.target shutdown.target
+Wants=modprobe@loop.service modprobe@dm_mod.service
+After=modprobe@loop.service modprobe@dm_mod.service sysroot.mount sysroot-usr.mount systemd-volatile-root.service
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=systemd-sysext --root=/sysroot refresh
+
+[Install]
+WantedBy=initrd.target
diff --git a/units/systemd-sysext.service b/units/systemd-sysext.service
index f20a076128..3246ea7fb7 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