discovery based on the boot loader reported ESP which is also enabled if no <literal>root=</literal>
parameter is specified at all. (The latter relies on <command>systemd-udevd.service</command>'s
<filename>/dev/gpt-auto-root</filename> block device symlink generation).</para></listitem>
+
+ <listitem><para>It will also generate a unit file mounting the EFI System Partition (ESP) to
+ <filename>/sysefi/</filename>, if applicable. Unlike the file systems mentioned above this mount is not
+ activated by default however, but can be pulled in by services requiring ESP access from within the
+ initrd. Note that this mount point is initrd-specific and does not make use of autofs. The ESP is
+ typically mounted at a different place and via autofs once the system transitions out of the
+ initrd.</para></listitem>
</itemizedlist>
</para>
<entry><constant>SD_GPT_ESP</constant></entry>
<entry><constant>c12a7328-f81f-11d2-ba4b-00a0c93ec93b</constant></entry>
<entry>EFI System Partition (ESP)</entry>
- <entry><filename>/efi/</filename> or <filename>/boot/</filename></entry>
+ <entry><filename>/efi/</filename> or <filename>/boot/</filename> once the system transitioned out of the initrd, <filename>/sysefi/</filename> before</entry>
<entry>The first partition with this type UUID located on the same disk as the root partition is mounted to <filename>/boot/</filename> or <filename>/efi/</filename>, see below.</entry>
</row>
<row>
<para>The ESP is mounted to <filename>/boot/</filename> if that directory exists and is not used for
XBOOTLDR, and otherwise to <filename>/efi/</filename>. Same as for <filename>/boot/</filename>, an
- automount unit is used. The mount point will be created if necessary.</para>
+ automount unit is used. The mount point will be created if necessary. These apply once the system
+ transitioned out of the initrd phase. Before that, if components in the initrd require ESP access, it
+ will be mounted to <filename>/sysefi/</filename>.</para>
<para>No configuration is created for mount points that are configured in <citerefentry
project='man-pages'><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry> or when
MountPointFlags flags,
const char *options,
const char *description,
- const char *post) {
+ const char *post,
+ const char *conflicts) {
_cleanup_free_ char *unit = NULL, *crypto_what = NULL, *opts_filtered = NULL;
_cleanup_fclose_ FILE *f = NULL;
if (r < 0)
return r;
+ if (conflicts)
+ fprintf(f,
+ "Conflicts=%1$s\n"
+ "Before=%1$s\n",
+ conflicts);
+
fprintf(f,
"\n"
"[Mount]\n"
(STR_IN_SET(id, "root", "var") ? MOUNT_MEASURE : 0), /* by default measure rootfs and /var, since they contain the "identity" of the system */
options,
description,
- SPECIAL_LOCAL_FS_TARGET);
+ SPECIAL_LOCAL_FS_TARGET,
+ /* conflicts= */ NULL);
}
static int add_partition_swap(DissectedPartition *p) {
flags,
options,
description,
- /* post= */ NULL);
+ /* post= */ NULL,
+ /* conflicts= */ NULL);
if (r < 0)
return r;
MOUNT_MEASURE,
options,
"Root Partition",
- in_initrd() ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_LOCAL_FS_TARGET);
+ in_initrd() ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_LOCAL_FS_TARGET,
+ /* conflicts= */ NULL);
#else
return 0;
#endif
/* flags= */ 0,
options,
"/usr/ Partition",
- in_initrd() ? SPECIAL_INITRD_USR_FS_TARGET : SPECIAL_LOCAL_FS_TARGET);
+ in_initrd() ? SPECIAL_INITRD_USR_FS_TARGET : SPECIAL_LOCAL_FS_TARGET,
+ /* conflicts= */ NULL);
if (r < 0)
return r;
MOUNT_VALIDATEFS,
"bind",
"/usr/ Partition (Final)",
- SPECIAL_INITRD_FS_TARGET);
+ SPECIAL_INITRD_FS_TARGET,
+ /* conflicts= */ NULL);
if (r < 0)
return r;
}
return 0;
}
+static int add_early_esp_mount(void) {
+ int r;
+
+ /* Early ESP discovery is a bit different than the other mounts here: it's purely about the initrd,
+ * and goes away during the transition to the host (where it might likely be mounted again, but then
+ * via autofs, hence lazily). Moreover, the location is fixed → /sysefi/, i.e. we do not bother with
+ * XBOOTLDR vs. ESP for this. Also, the mount is not pulled in by default, but is expected to be
+ * pulled in by the component that uses it.
+ *
+ * The initial usecase for this is software TPM that needs a place to store its state before the root
+ * file system can be mounted.
+ *
+ * Or in other words: this is much simpler, more focussed on a short-lived boot-time operation than
+ * the regular logic during later boot. */
+
+ if (!in_initrd())
+ return 0;
+
+ if (!is_efi_boot())
+ return 0;
+
+ _cleanup_free_ char *options = NULL;
+ r = partition_pick_mount_options(
+ PARTITION_ESP,
+ "vfat",
+ /* rw= */ true,
+ /* discard= */ false,
+ &options,
+ /* ret_ms_flags= */ NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to pick ESP mount options: %m");
+
+ return add_mount("esp",
+ "/dev/disk/by-designator/esp",
+ "/sysefi/",
+ "vfat",
+ MOUNT_RW,
+ options,
+ "EFI System Partition (Early)",
+ /* post= */ NULL,
+ /* conflicts= */ "initrd-switch-root.target");
+}
+
static int process_loader_partitions(DissectedPartition *esp, DissectedPartition *xbootldr) {
sd_id128_t loader_uuid;
int r;
return 0;
/* Disable root disk logic if there's a root= value specified (unless it happens to be
- * "gpt-auto" or "gpt-auto-force") */
+ * "gpt-auto", "gpt-auto-force", "dissect", "dissect-force") */
arg_auto_root = parse_gpt_auto_root("root=", value);
assert(arg_auto_root >= 0);
if (proc_cmdline_value_missing(key, value))
return 0;
- /* Disable root disk logic if there's a root= value specified (unless it happens to be
- * "gpt-auto" or "gpt-auto-force") */
-
arg_auto_usr = parse_gpt_auto_root("mount.usr=", value);
assert(arg_auto_usr >= 0);
r = 0;
RET_GATHER(r, add_root_mount());
RET_GATHER(r, add_usr_mount());
+ RET_GATHER(r, add_early_esp_mount());
RET_GATHER(r, add_mounts());
return r;