summaryrefslogtreecommitdiffstats
path: root/misc-utils/findmnt.c
diff options
context:
space:
mode:
authorEric Rannaud2014-06-27 07:18:48 +0200
committerKarel Zak2014-07-01 10:05:16 +0200
commitfb329bbc048861d6f47d33caf61f0c5b4ae68636 (patch)
tree30f503b36dab682083bbd07d05c72e8a830f81c1 /misc-utils/findmnt.c
parentlibmount: mnt_resolve_target: tiptoe around active mount points (diff)
downloadkernel-qcow2-util-linux-fb329bbc048861d6f47d33caf61f0c5b4ae68636.tar.gz
kernel-qcow2-util-linux-fb329bbc048861d6f47d33caf61f0c5b4ae68636.tar.xz
kernel-qcow2-util-linux-fb329bbc048861d6f47d33caf61f0c5b4ae68636.zip
findmnt: use mnt_cache_set_targets() for non-kernel table
findmnt compares the user-supplied path <target> with each entry in the parsed table. To do this comparison, libmount attempts to canonicalize the target path of each table entry, when the entry does not originate from the kernel (kernel supplied target paths are already canonicalized). However, if one of these entries is an active mount point, stat(2) or readlink(2) on the mount target path can hang (e.g. unreachable NFS server). If the main table is not a kernel table, we parse /proc/self/mountinfo into a secondary table and call mnt_cache_set_targets(). This allows libmount to check that the target path of each entry in the main table is not an active mount point, so it can avoid canonicalizing it. Signed-off-by: Eric Rannaud <e@nanocritical.com>
Diffstat (limited to 'misc-utils/findmnt.c')
-rw-r--r--misc-utils/findmnt.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/misc-utils/findmnt.c b/misc-utils/findmnt.c
index 445a9b3f1..0b3e380fb 100644
--- a/misc-utils/findmnt.c
+++ b/misc-utils/findmnt.c
@@ -833,6 +833,36 @@ static struct libmnt_table *parse_tabfiles(char **files,
return tb;
}
+/*
+ * Parses mountinfo and calls mnt_cache_set_targets(cache, mtab). Only
+ * necessary if @tb in main() was read from a non-kernel source.
+ */
+static void cache_set_targets(struct libmnt_cache *cache)
+{
+ struct libmnt_table *tb = NULL;
+ char *path = NULL;
+ int rc = 0;
+
+ tb = mnt_new_table();
+ if (!tb)
+ goto done;
+
+ path = access(_PATH_PROC_MOUNTINFO, R_OK) == 0 ?
+ _PATH_PROC_MOUNTINFO :
+ _PATH_PROC_MOUNTS;
+
+ rc = mnt_table_parse_file(tb, path);
+ if (rc)
+ goto done;
+
+ rc = mnt_cache_set_targets(cache, tb);
+ if (rc)
+ goto done;
+
+done:
+ mnt_unref_table(tb);
+}
+
/* checks if @tb contains parent->child relations */
static int tab_is_tree(struct libmnt_table *tb)
{
@@ -1471,6 +1501,9 @@ int main(int argc, char *argv[])
goto leave;
}
mnt_table_set_cache(tb, cache);
+
+ if (tabtype != TABTYPE_KERNEL)
+ cache_set_targets(cache);
}
if (flags & FL_UNIQ)