From ff52ff2565a3034a0ad063454a58d0c5649adc00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 14 Jul 2022 17:33:13 +0200 Subject: fstab-generator: do not skip /sysroot prefix if the mount point is missing When chase_symlinks() is called on something on a doesn't exist, it immediately returns an error. But we were relying on it to prepend "/sysroot/". If it fails, we need to do that ourselves. For example, with /sysroot/etc/fstab containing a line for /foo, if /sysroot/foo doesn't exist, we'd generate a mount point for /foo. --- src/fstab-generator/fstab-generator.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'src/fstab-generator') diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 8bd6022175..da7ea627f1 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -631,13 +631,25 @@ static int parse_fstab(bool initrd) { * mount units, but causes problems since it historically worked to have symlinks in e.g. * /etc/fstab. So we canonicalize here. Note that we use CHASE_NONEXISTENT to handle the case * where a symlink refers to another mount target; this works assuming the sub-mountpoint - * target is the final directory. */ + * target is the final directory. + * + * FIXME: when chase_symlinks() learns to chase non-existent paths, use this here and + * drop the prefixing with /sysroot on error below. + */ k = chase_symlinks(where, initrd ? "/sysroot" : NULL, CHASE_PREFIX_ROOT | CHASE_NONEXISTENT, &canonical_where, NULL); - if (k < 0) /* If we can't canonicalize, continue as if it wasn't a symlink */ - log_debug_errno(k, "Failed to read symlink target for %s, ignoring: %m", where); - else if (streq(canonical_where, where)) /* If it was fully canonicalized, suppress the change */ + if (k < 0) { + /* If we can't canonicalize, continue as if it wasn't a symlink */ + log_debug_errno(k, "Failed to read symlink target for %s, using as-is: %m", where); + + if (initrd) { + canonical_where = path_join("/sysroot", where); + if (!canonical_where) + return log_oom(); + } + + } else if (streq(canonical_where, where)) /* If it was fully canonicalized, suppress the change */ canonical_where = mfree(canonical_where); else log_debug("Canonicalized what=%s where=%s to %s", what, where, canonical_where); -- cgit v1.2.1