diff options
author | Karel Zak | 2013-03-25 13:56:31 +0100 |
---|---|---|
committer | Karel Zak | 2013-03-25 13:56:31 +0100 |
commit | dcc15ce5afc7a5f86f65f9084a780f9509e15613 (patch) | |
tree | 72f1d4ee94f8f840598eacaf305107d3bf92b7f4 /libmount | |
parent | libmount: make libmount.h consistent with code (diff) | |
download | kernel-qcow2-util-linux-dcc15ce5afc7a5f86f65f9084a780f9509e15613.tar.gz kernel-qcow2-util-linux-dcc15ce5afc7a5f86f65f9084a780f9509e15613.tar.xz kernel-qcow2-util-linux-dcc15ce5afc7a5f86f65f9084a780f9509e15613.zip |
libmount: add mnt_table_find_mountpoint()
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>
Diffstat (limited to 'libmount')
-rw-r--r-- | libmount/docs/libmount-sections.txt | 1 | ||||
-rw-r--r-- | libmount/src/libmount.h.in | 2 | ||||
-rw-r--r-- | libmount/src/libmount.sym | 1 | ||||
-rw-r--r-- | libmount/src/mountP.h | 2 | ||||
-rw-r--r-- | libmount/src/tab.c | 76 | ||||
-rw-r--r-- | libmount/src/utils.c | 2 |
6 files changed, 83 insertions, 1 deletions
diff --git a/libmount/docs/libmount-sections.txt b/libmount/docs/libmount-sections.txt index 3475630d7..2c3dab722 100644 --- a/libmount/docs/libmount-sections.txt +++ b/libmount/docs/libmount-sections.txt @@ -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 diff --git a/libmount/src/libmount.h.in b/libmount/src/libmount.h.in index 739f5daee..1b5df82ac 100644 --- a/libmount/src/libmount.h.in +++ b/libmount/src/libmount.h.in @@ -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, diff --git a/libmount/src/libmount.sym b/libmount/src/libmount.sym index 9fc0ee6b0..2ea483989 100644 --- a/libmount/src/libmount.sym +++ b/libmount/src/libmount.sym @@ -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; diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h index 1b4ba687b..065b815c1 100644 --- a/libmount/src/mountP.h +++ b/libmount/src/mountP.h @@ -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); diff --git a/libmount/src/tab.c b/libmount/src/tab.c index 5287da4a5..f70ed7de0 100644 --- a/libmount/src/tab.c +++ b/libmount/src/tab.c @@ -426,6 +426,51 @@ int mnt_table_set_iter(struct libmnt_table *tb, struct libmnt_iter *itr, struct } /** + * 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 * @path: mountpoint directory @@ -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 } diff --git a/libmount/src/utils.c b/libmount/src/utils.c index 1d4fd0e4b..5453789e3 100644 --- a/libmount/src/utils.c +++ b/libmount/src/utils.c @@ -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; |