fstab-generator: use correct targets when /sysroot is specificied in fstab only

This commit is contained in:
Lily Foster 2023-01-25 19:05:08 -05:00
parent c78d18215b
commit dfce61dda7
No known key found for this signature in database
GPG key ID: 49340081E484C893
2 changed files with 54 additions and 16 deletions

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

@ -650,6 +650,19 @@ 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;
@ -753,7 +766,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,
@ -763,21 +776,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)
@ -856,6 +891,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();
@ -976,6 +1015,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")) {
@ -1020,18 +1064,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;