From 2739a62abe692e9ca5792fc46f03cd4618a65000 Mon Sep 17 00:00:00 2001 From: Lily Foster Date: Wed, 25 Jan 2023 19:05:08 -0500 Subject: [PATCH] fstab-generator: use correct targets when /sysroot is specificied in fstab only (cherry picked from commit dfce61dda7b7b15b910221e5ca1673b371554368) Related: #2190226 --- man/systemd-fstab-generator.xml | 7 ++- src/fstab-generator/fstab-generator.c | 63 +++++++++++++++++++++------ 2 files changed, 54 insertions(+), 16 deletions(-) diff --git a/man/systemd-fstab-generator.xml b/man/systemd-fstab-generator.xml index b7908377a4..30204f5d8a 100644 --- a/man/systemd-fstab-generator.xml +++ b/man/systemd-fstab-generator.xml @@ -81,12 +81,15 @@ Configures the operating system's root filesystem to mount when running in the initrd. This accepts a device node path (usually /dev/disk/by-uuid/… or - /dev/disk/by-label/… or similar), or the special values gpt-auto - and tmpfs. + /dev/disk/by-label/… or similar), or the special values gpt-auto, + fstab, and tmpfs. Use gpt-auto to explicitly request automatic root file system discovery via systemd-gpt-auto-generator8. + Use fstab to explicitly request automatic root file system discovery via + the initrd /etc/fstab rather than via kernel command line. + Use tmpfs in order to mount a tmpfs5 file system as root file system of the OS. This is useful in combination with diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index e76de45a0f..9bf5f04d1d 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -633,6 +633,19 @@ static const char* sysroot_fstab_path(void) { return getenv("SYSTEMD_SYSROOT_FSTAB") ?: "/sysroot/etc/fstab"; } +static int add_sysusr_sysroot_usr_bind_mount(const char *source) { + return add_mount(source, + arg_dest, + "/sysusr/usr", + "/sysroot/usr", + NULL, + NULL, + "bind", + 0, + 0, + SPECIAL_INITRD_FS_TARGET); +} + static int parse_fstab(bool initrd) { _cleanup_endmntent_ FILE *f = NULL; const char *fstab; @@ -734,7 +747,7 @@ static int parse_fstab(bool initrd) { if (streq(me->mnt_type, "swap")) k = add_swap(fstab, what, me, flags); else { - bool rw_only, automount; + bool rw_only, automount, is_sysroot, is_sysroot_usr; rw_only = fstab_test_option(me->mnt_opts, "x-systemd.rw-only\0"); automount = fstab_test_option(me->mnt_opts, @@ -744,21 +757,43 @@ static int parse_fstab(bool initrd) { flags |= rw_only * MOUNT_RW_ONLY | automount * MOUNT_AUTOMOUNT; + is_sysroot = in_initrd() && path_equal(where, "/sysroot"); + /* See comment from add_sysroot_usr_mount about the need for extra indirection + * in case /usr needs to be mounted in order for the root fs to be synthesized + * based on configuration included in /usr/, e.g. systemd-repart. */ + is_sysroot_usr = in_initrd() && path_equal(where, "/sysroot/usr"); + const char *target_unit = initrd ? SPECIAL_INITRD_FS_TARGET : + is_sysroot ? SPECIAL_INITRD_ROOT_FS_TARGET : + is_sysroot_usr ? SPECIAL_INITRD_USR_FS_TARGET : mount_is_network(me) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET; + if (is_sysroot && is_device_path(what)) { + r = generator_write_initrd_root_device_deps(arg_dest, what); + if (r < 0) + return r; + } + k = add_mount(fstab, arg_dest, what, - canonical_where ?: where, - canonical_where ? where: NULL, + is_sysroot_usr ? "/sysusr/usr" : canonical_where ?: where, + !is_sysroot_usr && canonical_where ? where : NULL, me->mnt_type, me->mnt_opts, me->mnt_passno, flags, target_unit); + + if (is_sysroot_usr && k >= 0) { + log_debug("Synthesizing fstab entry what=/sysusr/usr where=/sysroot/usr opts=bind"); + + r = add_sysusr_sysroot_usr_bind_mount(fstab); + if (r != 0) + k = r; + } } if (arg_sysroot_check && k > 0) @@ -836,6 +871,10 @@ static int add_sysroot_mount(void) { /* This is handled by gpt-auto-generator */ log_debug("Skipping root directory handling, as gpt-auto was requested."); return 0; + } else if (streq(arg_root_what, "fstab")) { + /* This is handled by parse_fstab */ + log_debug("Using initrd's fstab for /sysroot/ configuration."); + return 0; } r = sysroot_is_nfsroot(); @@ -951,6 +990,11 @@ static int add_sysroot_usr_mount(void) { log_debug("Skipping /usr/ directory handling, as gpt-auto was requested."); return 1; /* systemd-gpt-auto-generator will generate a unit for this, hence report that a * unit file is being created for the host /usr/ mount. */ + } else if (streq(arg_usr_what, "fstab")) { + /* This is handled by parse_fstab */ + log_debug("Using initrd's fstab for /sysroot/usr/ configuration."); + return 1; /* parse_fstab will generate a unit for this, hence report that a + * unit file is being created for the host /usr/ mount. */ } if (path_equal(arg_usr_what, "/dev/nfs")) { @@ -992,18 +1036,9 @@ static int add_sysroot_usr_mount(void) { if (r < 0) return r; - log_debug("Synthesizing entry what=/sysusr/usr where=/sysrootr/usr opts=bind"); + log_debug("Synthesizing entry what=/sysusr/usr where=/sysroot/usr opts=bind"); - r = add_mount("/proc/cmdline", - arg_dest, - "/sysusr/usr", - "/sysroot/usr", - NULL, - NULL, - "bind", - 0, - 0, - SPECIAL_INITRD_FS_TARGET); + r = add_sysusr_sysroot_usr_bind_mount("/proc/cmdline"); if (r < 0) return r;