]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: add mnt_table_find_mountpoint()
authorKarel Zak <kzak@redhat.com>
Mon, 25 Mar 2013 12:56:31 +0000 (13:56 +0100)
committerKarel Zak <kzak@redhat.com>
Mon, 25 Mar 2013 12:56:31 +0000 (13:56 +0100)
This is more robust implementation of mnt_get_mountpoint() that does
not ignore bind mountpoints (mount --bind /mnt /mnt) as it does not
depend on st_dev numbers.

Signed-off-by: Karel Zak <kzak@redhat.com>
libmount/docs/libmount-sections.txt
libmount/src/libmount.h.in
libmount/src/libmount.sym
libmount/src/mountP.h
libmount/src/tab.c
libmount/src/utils.c

index 3475630d70faa0fe63b6d99a992b319e5b070f14..2c3dab72259e152850bdb17d4c119c2e7ea923d3 100644 (file)
@@ -283,6 +283,7 @@ mnt_new_table_from_dir
 mnt_new_table_from_file
 mnt_table_add_fs
 mnt_table_find_devno
+mnt_table_find_mountpoint
 mnt_table_find_next_fs
 mnt_table_find_pair
 mnt_table_find_source
index 739f5daee64183e054dc489251e3942f89704179..1b5df82ac861c1b1d9c1ba5b1d203b1772c24898 100644 (file)
@@ -462,6 +462,8 @@ extern int mnt_table_get_root_fs(struct libmnt_table *tb, struct libmnt_fs **roo
 extern int mnt_table_set_iter(struct libmnt_table *tb, struct libmnt_iter *itr,
                              struct libmnt_fs *fs);
 
+extern struct libmnt_fs *mnt_table_find_mountpoint(struct libmnt_table *tb,
+                               const char *path, int direction);
 extern struct libmnt_fs *mnt_table_find_target(struct libmnt_table *tb,
                                const char *path, int direction);
 extern struct libmnt_fs *mnt_table_find_srcpath(struct libmnt_table *tb,
index 9fc0ee6b0e462099662ddb675d56f4113dddfa1d..2ea48398948d4af324daa1bbba0a320207843e51 100644 (file)
@@ -254,4 +254,5 @@ global:
        mnt_fs_get_optional_fields;
        mnt_fs_get_propagation;
        mnt_context_find_umount_fs;
+       mnt_table_find_mountpoint;
 } MOUNT_2.22;
index 1b4ba687bd30c8f87e7fcaca3e018651036d5a4d..065b815c19b486c803d36a245582926757257dc4 100644 (file)
@@ -132,6 +132,8 @@ extern int endswith(const char *s, const char *sx)
 extern int startswith(const char *s, const char *sx)
                        __attribute__((nonnull));
 
+extern char *stripoff_last_component(char *path);
+
 extern int is_file_empty(const char *name);
 
 extern int mkdir_p(const char *path, mode_t mode);
index 5287da4a50d9bd5a565417cf2899377d2eca3201..f70ed7de08288a6e904f5297f78e046a03aa47da 100644 (file)
@@ -425,6 +425,51 @@ int mnt_table_set_iter(struct libmnt_table *tb, struct libmnt_iter *itr, struct
        return 0;
 }
 
+/**
+ * mnt_table_find_mountpoint:
+ * @tb: tab pointer
+ * @path: directory
+ * @direction: MNT_ITER_{FORWARD,BACKWARD}
+ *
+ * Same like mnt_get_mountpoint(), but this function does not rely on
+ * st_dev numbers.
+ *
+ * Returns: a tab entry or NULL.
+ */
+struct libmnt_fs *mnt_table_find_mountpoint(struct libmnt_table *tb,
+                                           const char *path,
+                                           int direction)
+{
+       char *mnt;
+
+       if (!tb || !path)
+               return NULL;
+
+       DBG(TAB, mnt_debug_h(tb, "lookup MOUNTPOINT: %s", path));
+
+       mnt = strdup(path);
+       if (!mnt)
+               return NULL;
+
+       do {
+               char *p;
+               struct libmnt_fs *fs;
+
+               fs = mnt_table_find_target(tb, mnt, direction);
+               if (fs) {
+                       free(mnt);
+                       return fs;
+               }
+
+               p = stripoff_last_component(mnt);
+               if (!p || !*p)
+                       break;
+       } while (mnt && *(mnt + 1) != '\0');
+
+       free(mnt);
+       return mnt_table_find_target(tb, "/", direction);
+}
+
 /**
  * mnt_table_find_target:
  * @tb: tab pointer
@@ -517,6 +562,8 @@ struct libmnt_fs *mnt_table_find_srcpath(struct libmnt_table *tb, const char *pa
        const char *p;
 
        assert(tb);
+       if (!tb || !path)
+               return NULL;
 
        DBG(TAB, mnt_debug_h(tb, "lookup srcpath: %s", path));
 
@@ -1009,6 +1056,7 @@ done:
 }
 
 #ifdef TEST_PROGRAM
+#include "pathnames.h"
 
 static int parser_errcb(struct libmnt_table *tb, const char *filename, int line)
 {
@@ -1171,6 +1219,33 @@ done:
        return rc;
 }
 
+int test_find_mountpoint(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 = mnt_new_table_from_file(_PATH_PROC_MOUNTINFO);
+       if (!tb)
+               return -1;
+       mpc = mnt_new_cache();
+       if (!mpc)
+               goto done;
+       mnt_table_set_cache(tb, mpc);
+
+       fs = mnt_table_find_mountpoint(tb, argv[1], MNT_ITER_BACKWARD);
+       if (!fs)
+               goto done;
+
+       mnt_fs_print_debug(fs, stdout);
+       rc = 0;
+done:
+       mnt_free_table(tb);
+       mnt_free_cache(mpc);
+       return rc;
+}
+
 static int test_is_mounted(struct libmnt_test *ts, int argc, char *argv[])
 {
        struct libmnt_table *tb = NULL, *fstab = NULL;
@@ -1225,6 +1300,7 @@ int main(int argc, char *argv[])
        { "--find-forward",  test_find_fw, "<file> <source|target> <string>" },
        { "--find-backward", test_find_bw, "<file> <source|target> <string>" },
        { "--find-pair",     test_find_pair, "<file> <source> <target>" },
+       { "--find-mountpoint", test_find_mountpoint, "<path>" },
        { "--copy-fs",       test_copy_fs, "<file>  copy root FS from the file" },
        { "--is-mounted",    test_is_mounted, "<fstab> check what from <file> are already mounted" },
        { NULL }
index 1d4fd0e4b3d36ce79d350d8ef8fa71f68eda93f4..5453789e3263ee1fed140527aeeccb6dbb60d75e 100644 (file)
@@ -94,7 +94,7 @@ static int fstype_cmp(const void *v1, const void *v2)
 
 /* returns basename and keeps dirname in the @path, if @path is "/" (root)
  * then returns empty string */
-static char *stripoff_last_component(char *path)
+char *stripoff_last_component(char *path)
 {
        char *p = path ? strrchr(path, '/') : NULL;