diff options
-rw-r--r-- | libmount/src/context.c | 2 | ||||
-rw-r--r-- | libmount/src/tab.c | 74 |
2 files changed, 52 insertions, 24 deletions
diff --git a/libmount/src/context.c b/libmount/src/context.c index bfc418cd8..d6f905039 100644 --- a/libmount/src/context.c +++ b/libmount/src/context.c @@ -1963,6 +1963,8 @@ int mnt_context_helper_setopt(struct libmnt_context *cxt, int c, char *arg) * @fs: filesystem * @mounted: returns 1 for mounted and 0 for non-mounted filesystems * + * Please, read mnt_table_is_fs_mounted() description! + * * Returns: 0 on success and negative number in case of error. */ int mnt_context_is_fs_mounted(struct libmnt_context *cxt, diff --git a/libmount/src/tab.c b/libmount/src/tab.c index 927e0f8da..1c159b56f 100644 --- a/libmount/src/tab.c +++ b/libmount/src/tab.c @@ -876,8 +876,18 @@ static int is_mountinfo(struct libmnt_table *tb) * @tb: /proc/self/mountinfo file * @fstab_fs: /etc/fstab entry * - * Checks if the @fstab_fs entry is already in the @tb table. The "swap" - * is ignored. + * Checks if the @fstab_fs entry is already in the @tb table. The "swap" is + * ignored. This function explicitly compares source, target and root of the + * filesystems. + * + * Note that source and target are canonicalized only if a cache for @tb is + * defined (see mnt_table_set_cache()). The target canonicalization may + * triggers automount on autofs mountpoints! + * + * Don't use it if you want to know if a device is mounted, just use + * mnt_table_find_source() for the device. + * + * This function is designed mostly for "mount -a". * * TODO: check for loopdev (see mount/mount.c is_fstab_entry_mounted(). * @@ -886,8 +896,8 @@ static int is_mountinfo(struct libmnt_table *tb) int mnt_table_is_fs_mounted(struct libmnt_table *tb, struct libmnt_fs *fstab_fs) { char *root = NULL; - const char *src = NULL; - char *xsrc = NULL, *tgt; + const char *src = NULL, *tgt = NULL; + char *xtgt = NULL; int rc = 0; assert(tb); @@ -909,15 +919,13 @@ int mnt_table_is_fs_mounted(struct libmnt_table *tb, struct libmnt_fs *fstab_fs) src = mnt_fs_get_srcpath(fs); } - if (src) - src = xsrc = mnt_resolve_spec(src, tb->cache); - else if (mnt_fs_is_pseudofs(fstab_fs)) + if (!src) src = mnt_fs_get_source(fstab_fs); - else - src = xsrc = mnt_resolve_spec(mnt_fs_get_source(fstab_fs), - tb->cache); - tgt = mnt_resolve_path(mnt_fs_get_target(fstab_fs), tb->cache); + if (src && tb->cache && !mnt_fs_is_pseudofs(fstab_fs)) + src = mnt_resolve_spec(src, tb->cache); + + tgt = mnt_fs_get_target(fstab_fs); if (tgt && src) { struct libmnt_iter itr; @@ -925,31 +933,36 @@ int mnt_table_is_fs_mounted(struct libmnt_table *tb, struct libmnt_fs *fstab_fs) mnt_reset_iter(&itr, MNT_ITER_FORWARD); - while(mnt_table_next_fs(tb, &itr, &fs) == 0) { + while (mnt_table_next_fs(tb, &itr, &fs) == 0) { + + if (!mnt_fs_streq_srcpath(fs, src)) + continue; if (root) { - /* mountinfo: compare root, source and target */ const char *r = mnt_fs_get_root(fs); + if (!r || strcmp(r, root) != 0) + continue; + } - if (r && strcmp(r, root) == 0 && - mnt_fs_streq_srcpath(fs, src) && - mnt_fs_streq_target(fs, tgt)) + /* + * Compare target, try to minimize number of situations + * when we need to canonicalize the path to avoid + * readlink() on mountpoints. + */ + if (!xtgt) { + if (mnt_fs_streq_target(fs, tgt)) break; + if (tb->cache) + xtgt = mnt_resolve_path(tgt, tb->cache); } - /* mtab: compare source and target */ - else if (mnt_fs_streq_srcpath(fs, src) && - mnt_fs_streq_target(fs, tgt)) + if (xtgt && mnt_fs_streq_target(fs, xtgt)) break; + } if (fs) rc = 1; /* success */ } - if (xsrc && !tb->cache) - free(xsrc); - if (!tb->cache) - free(tgt); - free(root); return rc; } @@ -1094,11 +1107,16 @@ int test_find_pair(struct libmnt_test *ts, int argc, char *argv[]) { struct libmnt_table *tb; struct libmnt_fs *fs; + struct libmnt_cache *mpc = NULL; int rc = -1; tb = create_table(argv[1]); if (!tb) return -1; + mpc = mnt_new_cache(); + if (!mpc) + goto done; + mnt_table_set_cache(tb, mpc); fs = mnt_table_find_pair(tb, argv[2], argv[3], MNT_ITER_FORWARD); if (!fs) @@ -1108,6 +1126,7 @@ int test_find_pair(struct libmnt_test *ts, int argc, char *argv[]) rc = 0; done: mnt_free_table(tb); + mnt_free_cache(mpc); return rc; } @@ -1116,6 +1135,7 @@ static int test_is_mounted(struct libmnt_test *ts, int argc, char *argv[]) struct libmnt_table *tb = NULL, *fstab = NULL; struct libmnt_fs *fs; struct libmnt_iter *itr = NULL; + struct libmnt_cache *mpc = NULL; int rc; tb = mnt_new_table_from_file("/proc/self/mountinfo"); @@ -1132,6 +1152,11 @@ static int test_is_mounted(struct libmnt_test *ts, int argc, char *argv[]) if (!itr) goto done; + mpc = mnt_new_cache(); + if (!mpc) + goto done; + mnt_table_set_cache(tb, mpc); + while(mnt_table_next_fs(fstab, itr, &fs) == 0) { if (mnt_table_is_fs_mounted(tb, fs)) printf("%s already mounted on %s\n", @@ -1147,6 +1172,7 @@ static int test_is_mounted(struct libmnt_test *ts, int argc, char *argv[]) done: mnt_free_table(tb); mnt_free_table(fstab); + mnt_free_cache(mpc); mnt_free_iter(itr); return rc; } |