diff options
14 files changed, 131 insertions, 19 deletions
diff --git a/docs/ENVIRONMENT.md b/docs/ENVIRONMENT.md index 30ef1e7e42..3e957113e7 100644 --- a/docs/ENVIRONMENT.md +++ b/docs/ENVIRONMENT.md @@ -54,6 +54,10 @@ All tools: * `$SYSTEMD_SYSROOT_FSTAB` — if set, use this path instead of `/sysroot/etc/fstab`. Only useful for debugging `systemd-fstab-generator`. +* `$SYSTEMD_SYSFS_CHECK` — takes a boolean. If set, overrides sysfs container + detection that ignores `/dev/` entries in fstab. Only useful for debugging + `systemd-fstab-generator`. + * `$SYSTEMD_CRYPTTAB` — if set, use this path instead of `/etc/crypttab`. Only useful for debugging. Currently only supported by `systemd-cryptsetup-generator`. 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 @@ <listitem><para>Configures the operating system's root filesystem to mount when running in the initrd. This accepts a device node path (usually <filename>/dev/disk/by-uuid/…</filename> or - <filename>/dev/disk/by-label/…</filename> or similar), or the special values <literal>gpt-auto</literal> - and <literal>tmpfs</literal>.</para> + <filename>/dev/disk/by-label/…</filename> or similar), or the special values <literal>gpt-auto</literal>, + <literal>fstab</literal>, and <literal>tmpfs</literal>.</para> <para>Use <literal>gpt-auto</literal> to explicitly request automatic root file system discovery via <citerefentry><refentrytitle>systemd-gpt-auto-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para> + <para>Use <literal>fstab</literal> to explicitly request automatic root file system discovery via + the initrd <filename>/etc/fstab</filename> rather than via kernel command line.</para> + <para>Use <literal>tmpfs</literal> in order to mount a <citerefentry project='man-pages'><refentrytitle>tmpfs</refentrytitle><manvolnum>5</manvolnum></citerefentry> 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 efc553b698..138321680d 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -9,6 +9,7 @@ #include "bus-locator.h" #include "chase-symlinks.h" #include "efi-loader.h" +#include "env-util.h" #include "fd-util.h" #include "fileio.h" #include "fstab-util.h" @@ -648,11 +649,24 @@ 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; struct mntent *me; - int r = 0; + int r = 0, sysfs_check = -1; if (initrd) fstab = sysroot_fstab_path(); @@ -690,7 +704,14 @@ static int parse_fstab(bool initrd) { continue; } - if (is_device_path(what)) { + if (sysfs_check < 0) { + r = getenv_bool_secure("SYSTEMD_SYSFS_CHECK"); + if (r < 0 && r != -ENXIO) + log_debug_errno(r, "Failed to parse $SYSTEMD_SYSFS_CHECK, ignoring: %m"); + sysfs_check = r != 0; + } + + if (sysfs_check && is_device_path(what)) { log_info("/sys/ is read-only (running in a container?), ignoring fstab device entry for %s.", what); continue; } @@ -751,7 +772,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, @@ -761,21 +782,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) @@ -854,6 +897,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(); @@ -974,6 +1021,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")) { @@ -1018,18 +1070,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; diff --git a/test/test-fstab-generator.sh b/test/test-fstab-generator.sh index 7c060dfac7..c86914a107 100755 --- a/test/test-fstab-generator.sh +++ b/test/test-fstab-generator.sh @@ -26,7 +26,11 @@ for f in "$src"/test-*.input; do trap "rm -rf '$out'" EXIT INT QUIT PIPE # shellcheck disable=SC2046 - SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_PROC_CMDLINE="fstab=no $(cat "$f")" $generator "$out" "$out" "$out" + if [[ "$f" == *.fstab.input ]]; then + SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_SYSFS_CHECK=no SYSTEMD_PROC_CMDLINE="fstab=yes root=fstab" SYSTEMD_FSTAB="$f" SYSTEMD_SYSROOT_FSTAB="/dev/null" $generator "$out" "$out" "$out" + else + SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD=yes SYSTEMD_PROC_CMDLINE="fstab=no $(cat "$f")" $generator "$out" "$out" "$out" + fi if [[ -f "$out"/systemd-fsck-root.service ]]; then # For split-usr system diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-fs.target.requires/sysroot-usr.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-fs.target.requires/sysroot-usr.mount new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-fs.target.requires/sysroot-usr.mount diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-device.target.d/50-root-device.conf b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-device.target.d/50-root-device.conf new file mode 100644 index 0000000000..47c4232223 --- /dev/null +++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-device.target.d/50-root-device.conf @@ -0,0 +1,5 @@ +# Automatically generated by systemd-fstab-generator + +[Unit] +Requires=dev-sdx1.device +After=dev-sdx1.device diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-fs.target.requires/sysroot.mount new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-root-fs.target.requires/sysroot.mount diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysroot.mount diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysusr-usr.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysusr-usr.mount new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/initrd-usr-fs.target.requires/sysusr-usr.mount diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/sysroot-usr.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/sysroot-usr.mount new file mode 100644 index 0000000000..69be9c17d4 --- /dev/null +++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/sysroot-usr.mount @@ -0,0 +1,11 @@ +# Automatically generated by systemd-fstab-generator + +[Unit] +Documentation=man:fstab(5) man:systemd-fstab-generator(8) +SourcePath=/etc/fstab +Before=initrd-fs.target + +[Mount] +What=/sysusr/usr +Where=/sysroot/usr +Options=bind diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/sysroot.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/sysroot.mount new file mode 100644 index 0000000000..0e8a701be9 --- /dev/null +++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/sysroot.mount @@ -0,0 +1,13 @@ +# Automatically generated by systemd-fstab-generator + +[Unit] +Documentation=man:fstab(5) man:systemd-fstab-generator(8) +SourcePath=/etc/fstab +Before=initrd-root-fs.target +Requires=systemd-fsck-root.service +After=systemd-fsck-root.service +After=blockdev@dev-sdx1.target + +[Mount] +What=/dev/sdx1 +Where=/sysroot diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service new file mode 100644 index 0000000000..7f914fdd14 --- /dev/null +++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/systemd-fsck-root.service @@ -0,0 +1,16 @@ +# Automatically generated by systemd-fstab-generator + +[Unit] +Description=File System Check on /dev/sdx1 +Documentation=man:systemd-fsck-root.service(8) +DefaultDependencies=no +BindsTo=dev-sdx1.device +Conflicts=shutdown.target +After=initrd-root-device.target local-fs-pre.target dev-sdx1.device +Before=shutdown.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/lib/systemd/systemd-fsck /dev/sdx1 +TimeoutSec=0 diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/sysusr-usr.mount b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/sysusr-usr.mount new file mode 100644 index 0000000000..63fcb10340 --- /dev/null +++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.expected/sysusr-usr.mount @@ -0,0 +1,11 @@ +# Automatically generated by systemd-fstab-generator + +[Unit] +Documentation=man:fstab(5) man:systemd-fstab-generator(8) +SourcePath=/etc/fstab +Before=initrd-usr-fs.target +After=blockdev@dev-sdx2.target + +[Mount] +What=/dev/sdx2 +Where=/sysusr/usr diff --git a/test/test-fstab-generator/test-17-initrd-sysroot.fstab.input b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.input new file mode 100644 index 0000000000..1ba9b0624e --- /dev/null +++ b/test/test-fstab-generator/test-17-initrd-sysroot.fstab.input @@ -0,0 +1,2 @@ +/dev/sdx1 /sysroot auto defaults 0 1 +/dev/sdx2 /sysroot/usr auto defaults 0 0 |