summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarel Zak2013-03-25 13:56:31 +0100
committerKarel Zak2013-03-25 13:56:31 +0100
commitdcc15ce5afc7a5f86f65f9084a780f9509e15613 (patch)
tree72f1d4ee94f8f840598eacaf305107d3bf92b7f4
parentlibmount: make libmount.h consistent with code (diff)
downloadkernel-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>
-rw-r--r--libmount/docs/libmount-sections.txt1
-rw-r--r--libmount/src/libmount.h.in2
-rw-r--r--libmount/src/libmount.sym1
-rw-r--r--libmount/src/mountP.h2
-rw-r--r--libmount/src/tab.c76
-rw-r--r--libmount/src/utils.c2
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;