]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/fstab-generator/fstab-generator.c
Merge pull request #6324 from keszybz/generator-add-symlink
[thirdparty/systemd.git] / src / fstab-generator / fstab-generator.c
index f72ca9953508c181ee2cd7f8c8ae4d4829375dfc..ea5ceb39ca600f11717fd3a96ab34a4759b38ab4 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "alloc-util.h"
 #include "fd-util.h"
+#include "fs-util.h"
 #include "fileio.h"
 #include "fstab-util.h"
 #include "generator.h"
@@ -286,6 +287,7 @@ static int add_mount(
                 const char *dest,
                 const char *what,
                 const char *where,
+                const char *original_where,
                 const char *fstype,
                 const char *opts,
                 int passno,
@@ -392,11 +394,10 @@ static int add_mount(
                         return r;
         }
 
-        fprintf(f,
-                "\n"
-                "[Mount]\n"
-                "Where=%s\n",
-                where);
+        fprintf(f, "\n[Mount]\n");
+        if (original_where)
+                fprintf(f, "# Canonicalized from %s\n", original_where);
+        fprintf(f, "Where=%s\n", where);
 
         r = write_what(f, what);
         if (r < 0)
@@ -509,7 +510,7 @@ static int parse_fstab(bool initrd) {
         }
 
         while ((me = getmntent(f))) {
-                _cleanup_free_ char *where = NULL, *what = NULL;
+                _cleanup_free_ char *where = NULL, *what = NULL, *canonical_where = NULL;
                 bool noauto, nofail;
                 int k;
 
@@ -529,8 +530,28 @@ static int parse_fstab(bool initrd) {
                 if (!where)
                         return log_oom();
 
-                if (is_path(where))
+                if (is_path(where)) {
                         path_kill_slashes(where);
+                        /* Follow symlinks here; see 5261ba901845c084de5a8fd06500ed09bfb0bd80 which makes sense for
+                         * 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.
+                         */
+                        r = chase_symlinks(where, initrd ? "/sysroot" : NULL,
+                                           CHASE_PREFIX_ROOT | CHASE_NONEXISTENT,
+                                           &canonical_where);
+                        if (r < 0)
+                                /* In this case for now we continue on as if it wasn't a symlink */
+                                log_warning_errno(r, "Failed to read symlink target for %s: %m", where);
+                        else {
+                                if (streq(canonical_where, where))
+                                        canonical_where = mfree(canonical_where);
+                                else
+                                        log_debug("Canonicalized what=%s where=%s to %s",
+                                                  what, where, canonical_where);
+                        }
+                }
 
                 noauto = fstab_test_yes_no_option(me->mnt_opts, "noauto\0" "auto\0");
                 nofail = fstab_test_yes_no_option(me->mnt_opts, "nofail\0" "fail\0");
@@ -556,7 +577,8 @@ static int parse_fstab(bool initrd) {
 
                         k = add_mount(arg_dest,
                                       what,
-                                      where,
+                                      canonical_where ?: where,
+                                      canonical_where ? where: NULL,
                                       me->mnt_type,
                                       me->mnt_opts,
                                       me->mnt_passno,
@@ -619,6 +641,7 @@ static int add_sysroot_mount(void) {
         return add_mount(arg_dest,
                          what,
                          "/sysroot",
+                         NULL,
                          arg_root_fstype,
                          opts,
                          is_device_path(what) ? 1 : 0, /* passno */
@@ -673,6 +696,7 @@ static int add_sysroot_usr_mount(void) {
         return add_mount(arg_dest,
                          what,
                          "/sysroot/usr",
+                         NULL,
                          arg_usr_fstype,
                          opts,
                          is_device_path(what) ? 1 : 0, /* passno */
@@ -713,6 +737,7 @@ static int add_volatile_var(void) {
         return add_mount(arg_dest_late,
                          "tmpfs",
                          "/var",
+                         NULL,
                          "tmpfs",
                          "mode=0755",
                          0,