1
0
mirror of https://github.com/systemd/systemd.git synced 2025-02-28 05:57:33 +03:00

Merge pull request #26038 from lilyinstarlight/fix/fstab-generator-sysroot-without-cmdline

fstab-generator: use correct targets when /sysroot is specificied in fstab only
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2023-03-09 08:51:31 +01:00 committed by GitHub
commit ba0e70673c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 131 additions and 19 deletions

View File

@ -54,6 +54,10 @@ All tools:
* `$SYSTEMD_SYSROOT_FSTAB` — if set, use this path instead of * `$SYSTEMD_SYSROOT_FSTAB` — if set, use this path instead of
`/sysroot/etc/fstab`. Only useful for debugging `systemd-fstab-generator`. `/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 * `$SYSTEMD_CRYPTTAB` — if set, use this path instead of `/etc/crypttab`. Only
useful for debugging. Currently only supported by useful for debugging. Currently only supported by
`systemd-cryptsetup-generator`. `systemd-cryptsetup-generator`.

View File

@ -81,12 +81,15 @@
<listitem><para>Configures the operating system's root filesystem to mount when running in the <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 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> <filename>/dev/disk/by-label/…</filename> or similar), or the special values <literal>gpt-auto</literal>,
and <literal>tmpfs</literal>.</para> <literal>fstab</literal>, and <literal>tmpfs</literal>.</para>
<para>Use <literal>gpt-auto</literal> to explicitly request automatic root file system discovery via <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> <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 <para>Use <literal>tmpfs</literal> in order to mount a <citerefentry
project='man-pages'><refentrytitle>tmpfs</refentrytitle><manvolnum>5</manvolnum></citerefentry> file 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 system as root file system of the OS. This is useful in combination with

View File

@ -9,6 +9,7 @@
#include "bus-locator.h" #include "bus-locator.h"
#include "chase-symlinks.h" #include "chase-symlinks.h"
#include "efi-loader.h" #include "efi-loader.h"
#include "env-util.h"
#include "fd-util.h" #include "fd-util.h"
#include "fileio.h" #include "fileio.h"
#include "fstab-util.h" #include "fstab-util.h"
@ -648,11 +649,24 @@ static const char* sysroot_fstab_path(void) {
return getenv("SYSTEMD_SYSROOT_FSTAB") ?: "/sysroot/etc/fstab"; 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) { static int parse_fstab(bool initrd) {
_cleanup_endmntent_ FILE *f = NULL; _cleanup_endmntent_ FILE *f = NULL;
const char *fstab; const char *fstab;
struct mntent *me; struct mntent *me;
int r = 0; int r = 0, sysfs_check = -1;
if (initrd) if (initrd)
fstab = sysroot_fstab_path(); fstab = sysroot_fstab_path();
@ -690,7 +704,14 @@ static int parse_fstab(bool initrd) {
continue; 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); log_info("/sys/ is read-only (running in a container?), ignoring fstab device entry for %s.", what);
continue; continue;
} }
@ -751,7 +772,7 @@ static int parse_fstab(bool initrd) {
if (streq(me->mnt_type, "swap")) if (streq(me->mnt_type, "swap"))
k = add_swap(fstab, what, me, flags); k = add_swap(fstab, what, me, flags);
else { 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"); rw_only = fstab_test_option(me->mnt_opts, "x-systemd.rw-only\0");
automount = fstab_test_option(me->mnt_opts, automount = fstab_test_option(me->mnt_opts,
@ -761,21 +782,43 @@ static int parse_fstab(bool initrd) {
flags |= rw_only * MOUNT_RW_ONLY | flags |= rw_only * MOUNT_RW_ONLY |
automount * MOUNT_AUTOMOUNT; 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 = const char *target_unit =
initrd ? SPECIAL_INITRD_FS_TARGET : 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 : mount_is_network(me) ? SPECIAL_REMOTE_FS_TARGET :
SPECIAL_LOCAL_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, k = add_mount(fstab,
arg_dest, arg_dest,
what, what,
canonical_where ?: where, is_sysroot_usr ? "/sysusr/usr" : canonical_where ?: where,
canonical_where ? where: NULL, !is_sysroot_usr && canonical_where ? where : NULL,
me->mnt_type, me->mnt_type,
me->mnt_opts, me->mnt_opts,
me->mnt_passno, me->mnt_passno,
flags, flags,
target_unit); 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) if (arg_sysroot_check && k > 0)
@ -854,6 +897,10 @@ static int add_sysroot_mount(void) {
/* This is handled by gpt-auto-generator */ /* This is handled by gpt-auto-generator */
log_debug("Skipping root directory handling, as gpt-auto was requested."); log_debug("Skipping root directory handling, as gpt-auto was requested.");
return 0; 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(); 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."); 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 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. */ * 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")) { if (path_equal(arg_usr_what, "/dev/nfs")) {
@ -1018,18 +1070,9 @@ static int add_sysroot_usr_mount(void) {
if (r < 0) if (r < 0)
return r; 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", r = add_sysusr_sysroot_usr_bind_mount("/proc/cmdline");
arg_dest,
"/sysusr/usr",
"/sysroot/usr",
NULL,
NULL,
"bind",
0,
0,
SPECIAL_INITRD_FS_TARGET);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -26,7 +26,11 @@ for f in "$src"/test-*.input; do
trap "rm -rf '$out'" EXIT INT QUIT PIPE trap "rm -rf '$out'" EXIT INT QUIT PIPE
# shellcheck disable=SC2046 # 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 if [[ -f "$out"/systemd-fsck-root.service ]]; then
# For split-usr system # For split-usr system

View File

@ -0,0 +1,5 @@
# Automatically generated by systemd-fstab-generator
[Unit]
Requires=dev-sdx1.device
After=dev-sdx1.device

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,2 @@
/dev/sdx1 /sysroot auto defaults 0 1
/dev/sdx2 /sysroot/usr auto defaults 0 0