]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: fix is-mounted check for btrfs
authorKarel Zak <kzak@redhat.com>
Wed, 2 Dec 2015 12:38:51 +0000 (13:38 +0100)
committerKarel Zak <kzak@redhat.com>
Wed, 2 Dec 2015 12:38:51 +0000 (13:38 +0100)
fstab:
  /dev/sdc        /mnt/test       btrfs   subvol=/anydir
  /mnt/test       /mnt/test2      auto    bind

and "mount -a" does not detect that /mnt/test2 is already mounted.

Reported-by: Stanislav Brabec <sbrabec@suse.cz>
Signed-off-by: Karel Zak <kzak@redhat.com>
libmount/src/tab.c

index 0df8d496d0373b6a46c6d9597dfc507d8b489824..951fe8c402ca5d784834d0083a95de16730a1cf2 100644 (file)
@@ -1240,21 +1240,33 @@ struct libmnt_fs *mnt_table_get_fs_root(struct libmnt_table *tb,
                        goto dflt;
                }
 
-               /* on btrfs the subvolume is used as fs-root in
-                * /proc/self/mountinfo, so we have to get the original subvolume
-                * name from src_fs and prepend the subvolume name to the
-                * fs-root path
+               /* It's possible that fstab_fs source is subdirectory on btrfs
+                * subvolume or anothe bind mount. For example:
+                *
+                * /dev/sdc        /mnt/test       btrfs   subvol=/anydir
+                * /mnt/test/foo   /mnt/test2      auto    bind
+                *
+                * in this case, the root for /mnt/test2 will be /anydir/foo on
+                * /dev/sdc. It means we have to compose the final root from
+                * root and src_root.
                 */
                src_root = mnt_fs_get_root(src_fs);
+
+               DBG(FS, ul_debugobj(fs, "source root: %s, source FS root: %s", root, src_root));
+
                if (src_root && !startswith(root, src_root)) {
-                       size_t sz = strlen(root) + strlen(src_root) + 1;
-                       char *tmp = malloc(sz);
-
-                       if (!tmp)
-                               goto err;
-                       snprintf(tmp, sz, "%s%s", src_root, root);
-                       free(root);
-                       root = tmp;
+                       if (strcmp(root, "/") == 0) {
+                               free(root);
+                               root = strdup(src_root);
+                               if (!root)
+                                       goto err;
+                       } else {
+                               char *tmp;
+                               if (asprintf(&tmp, "%s%s", src_root, root) < 0)
+                                       goto err;
+                               free(root);
+                               root = tmp;
+                       }
                }
        }
 
@@ -1372,6 +1384,8 @@ int mnt_table_is_fs_mounted(struct libmnt_table *tb, struct libmnt_fs *fstab_fs)
        }
        mnt_reset_iter(&itr, MNT_ITER_FORWARD);
 
+       DBG(FS, ul_debugobj(fstab_fs, "is mounted: src=%s, tgt=%s, root=%s", src, tgt, root));
+
        while (mnt_table_next_fs(tb, &itr, &fs) == 0) {
 
                int eq = mnt_fs_streq_srcpath(fs, src);