summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libmount/src/tab.c34
-rw-r--r--tests/expected/findmnt/outputs-messy-mountinfo31
-rw-r--r--tests/ts/findmnt/files/mountinfo-messy29
-rwxr-xr-xtests/ts/findmnt/outputs5
4 files changed, 95 insertions, 4 deletions
diff --git a/libmount/src/tab.c b/libmount/src/tab.c
index 85fd427b5..0eeefe76d 100644
--- a/libmount/src/tab.c
+++ b/libmount/src/tab.c
@@ -438,15 +438,31 @@ int mnt_table_remove_fs(struct libmnt_table *tb, struct libmnt_fs *fs)
return 0;
}
+static inline struct libmnt_fs *get_parent_fs(struct libmnt_table *tb, struct libmnt_fs *fs)
+{
+ struct libmnt_iter itr;
+ struct libmnt_fs *x;
+ int parent_id = mnt_fs_get_parent_id(fs);
+
+ mnt_reset_iter(&itr, MNT_ITER_FORWARD);
+ while (mnt_table_next_fs(tb, &itr, &x) == 0) {
+ if (mnt_fs_get_id(x) == parent_id)
+ return x;
+ }
+
+ return NULL;
+}
+
/**
* mnt_table_get_root_fs:
* @tb: mountinfo file (/proc/self/mountinfo)
* @root: returns pointer to the root filesystem (/)
*
- * The function uses the parent ID from the mountinfo file to determine the root filesystem
- * (the filesystem with the smallest ID). The function is designed mostly for
- * applications where it is necessary to sort mountpoints by IDs to get the tree
- * of the mountpoints (e.g. findmnt default output).
+ * The function uses the parent ID from the mountinfo file to determine the
+ * root filesystem (the filesystem with the smallest ID with parent ID missing
+ * in the table). The function is designed mostly for applications where it is
+ * necessary to sort mountpoints by IDs to get the tree of the mountpoints
+ * (e.g. findmnt default output).
*
* If you're not sure, then use
*
@@ -469,6 +485,7 @@ int mnt_table_get_root_fs(struct libmnt_table *tb, struct libmnt_fs **root)
*root = NULL;
+ /* get smallest possible ID from the table */
mnt_reset_iter(&itr, MNT_ITER_FORWARD);
while(mnt_table_next_fs(tb, &itr, &fs) == 0) {
int id = mnt_fs_get_parent_id(fs);
@@ -479,6 +496,15 @@ int mnt_table_get_root_fs(struct libmnt_table *tb, struct libmnt_fs **root)
}
}
+ /* go to the root node by "parent_id -> id" relation */
+ while (*root) {
+ struct libmnt_fs *x = get_parent_fs(tb, *root);
+ if (!x || x == *root)
+ break;
+ DBG(TAB, ul_debugobj(tb, " messy mountinfo, walk to %s", mnt_fs_get_target(x)));
+ *root = x;
+ }
+
return *root ? 0 : -EINVAL;
}
diff --git a/tests/expected/findmnt/outputs-messy-mountinfo b/tests/expected/findmnt/outputs-messy-mountinfo
new file mode 100644
index 000000000..c7225a1ba
--- /dev/null
+++ b/tests/expected/findmnt/outputs-messy-mountinfo
@@ -0,0 +1,31 @@
+TARGET SOURCE FSTYPE OPTIONS
+/ /dev/sda3[/arch] ext4 rw,relatime
+|-/sys sysfs sysfs ro,nosuid,nodev,noexec,relatime
+| `-/sys/fs/cgroup tmpfs tmpfs ro,nosuid,nodev,noexec,mode=755
+| |-/sys/fs/cgroup/perf_event cgroup cgroup ro,nosuid,nodev,noexec,relatime,perf_event
+| |-/sys/fs/cgroup/net_cls cgroup cgroup ro,nosuid,nodev,noexec,relatime,net_cls
+| |-/sys/fs/cgroup/blkio cgroup cgroup ro,nosuid,nodev,noexec,relatime,blkio
+| |-/sys/fs/cgroup/memory cgroup cgroup ro,nosuid,nodev,noexec,relatime,memory
+| |-/sys/fs/cgroup/pids cgroup cgroup ro,nosuid,nodev,noexec,relatime,pids
+| |-/sys/fs/cgroup/cpuset cgroup cgroup ro,nosuid,nodev,noexec,relatime,cpuset
+| |-/sys/fs/cgroup/freezer cgroup cgroup ro,nosuid,nodev,noexec,relatime,freezer
+| |-/sys/fs/cgroup/cpu,cpuacct cgroup cgroup ro,nosuid,nodev,noexec,relatime,cpu,cpuacct
+| |-/sys/fs/cgroup/devices cgroup cgroup ro,nosuid,nodev,noexec,relatime,devices
+| `-/sys/fs/cgroup/systemd cgroup cgroup rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd
+|-/dev tmpfs tmpfs rw,nosuid,mode=755
+| |-/dev/mqueue mqueue mqueue rw,relatime
+| |-/dev/hugepages hugetlbfs hugetlbfs rw,relatime
+| |-/dev/shm tmpfs tmpfs rw,nosuid,nodev
+| |-/dev/pts devpts devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666
+| `-/dev/console devpts[/5] devpts rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000
+|-/run tmpfs tmpfs rw,nosuid,nodev,mode=755
+| |-/run/user/0 tmpfs tmpfs rw,nosuid,nodev,relatime,size=1634120k,mode=700
+| `-/run/systemd/nspawn/incoming run[/systemd/nspawn/propagate/arch] tmpfs ro,relatime,mode=755
+|-/tmp tmpfs tmpfs rw
+`-/proc proc proc rw,nosuid,nodev,noexec,relatime
+ |-/proc/sys/kernel/random/boot_id tmpfs[/proc-sys-kernel-random-boot-id//deleted] tmpfs rw,nosuid,nodev,mode=755
+ |-/proc/kmsg tmpfs[/kmsg//deleted] tmpfs rw,nosuid,nodev,mode=755
+ |-/proc/sys proc[/sys] proc ro,nosuid,nodev,noexec,relatime
+ | `-/proc/sys/kernel/random/boot_id tmpfs[/proc-sys-kernel-random-boot-id//deleted] tmpfs ro,nosuid,nodev,mode=755
+ `-/proc/sysrq-trigger proc[/sysrq-trigger] proc ro,nosuid,nodev,noexec,relatime
+rc=0
diff --git a/tests/ts/findmnt/files/mountinfo-messy b/tests/ts/findmnt/files/mountinfo-messy
new file mode 100644
index 000000000..6e2ac9d66
--- /dev/null
+++ b/tests/ts/findmnt/files/mountinfo-messy
@@ -0,0 +1,29 @@
+220 189 8:3 /arch / rw,relatime shared:50 - ext4 /dev/sda3 rw
+221 220 0:17 / /sys ro,nosuid,nodev,noexec,relatime shared:51 - sysfs sysfs rw
+222 220 0:52 / /dev rw,nosuid shared:52 - tmpfs tmpfs rw,mode=755
+223 222 0:53 / /dev/shm rw,nosuid,nodev shared:53 - tmpfs tmpfs rw
+224 222 0:56 / /dev/pts rw,nosuid,noexec,relatime shared:56 - devpts devpts rw,gid=5,mode=620,ptmxmode=666
+225 222 0:21 /5 /dev/console rw,nosuid,noexec,relatime shared:57 master:4 - devpts devpts rw,gid=5,mode=620,ptmxmode=000
+226 220 0:54 / /run rw,nosuid,nodev shared:54 - tmpfs tmpfs rw,mode=755
+227 226 0:18 /systemd/nspawn/propagate/arch /run/systemd/nspawn/incoming ro,relatime master:11 - tmpfs run rw,mode=755
+228 220 0:55 / /tmp rw shared:55 - tmpfs tmpfs rw
+231 220 0:58 / /proc rw,nosuid,nodev,noexec,relatime shared:58 - proc proc rw
+232 231 0:58 /sys /proc/sys ro,nosuid,nodev,noexec,relatime shared:58 - proc proc rw
+233 231 0:58 /sysrq-trigger /proc/sysrq-trigger ro,nosuid,nodev,noexec,relatime shared:58 - proc proc rw
+93 221 0:59 / /sys/fs/cgroup ro,nosuid,nodev,noexec shared:59 - tmpfs tmpfs ro,mode=755
+94 93 0:29 / /sys/fs/cgroup/perf_event ro,nosuid,nodev,noexec,relatime shared:60 - cgroup cgroup rw,perf_event
+95 93 0:31 / /sys/fs/cgroup/net_cls ro,nosuid,nodev,noexec,relatime shared:61 - cgroup cgroup rw,net_cls
+96 93 0:30 / /sys/fs/cgroup/blkio ro,nosuid,nodev,noexec,relatime shared:62 - cgroup cgroup rw,blkio
+98 93 0:33 / /sys/fs/cgroup/memory ro,nosuid,nodev,noexec,relatime shared:63 - cgroup cgroup rw,memory
+99 93 0:32 / /sys/fs/cgroup/pids ro,nosuid,nodev,noexec,relatime shared:64 - cgroup cgroup rw,pids
+100 93 0:27 / /sys/fs/cgroup/cpuset ro,nosuid,nodev,noexec,relatime shared:65 - cgroup cgroup rw,cpuset
+101 93 0:25 / /sys/fs/cgroup/freezer ro,nosuid,nodev,noexec,relatime shared:66 - cgroup cgroup rw,freezer
+102 93 0:28 / /sys/fs/cgroup/cpu,cpuacct ro,nosuid,nodev,noexec,relatime shared:67 - cgroup cgroup rw,cpu,cpuacct
+103 93 0:26 / /sys/fs/cgroup/devices ro,nosuid,nodev,noexec,relatime shared:68 - cgroup cgroup rw,devices
+104 93 0:23 / /sys/fs/cgroup/systemd rw,nosuid,nodev,noexec,relatime shared:69 - cgroup cgroup rw,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd
+105 232 0:54 /proc-sys-kernel-random-boot-id//deleted /proc/sys/kernel/random/boot_id ro,nosuid,nodev shared:54 - tmpfs tmpfs rw,mode=755
+106 231 0:54 /proc-sys-kernel-random-boot-id//deleted /proc/sys/kernel/random/boot_id rw,nosuid,nodev shared:54 - tmpfs tmpfs rw,mode=755
+107 231 0:54 /kmsg//deleted /proc/kmsg rw,nosuid,nodev shared:54 - tmpfs tmpfs rw,mode=755
+97 222 0:57 / /dev/mqueue rw,relatime shared:70 - mqueue mqueue rw
+108 222 0:60 / /dev/hugepages rw,relatime shared:71 - hugetlbfs hugetlbfs rw
+109 226 0:61 / /run/user/0 rw,nosuid,nodev,relatime shared:72 - tmpfs tmpfs rw,size=1634120k,mode=700
diff --git a/tests/ts/findmnt/outputs b/tests/ts/findmnt/outputs
index 818d7194a..3a4422b37 100755
--- a/tests/ts/findmnt/outputs
+++ b/tests/ts/findmnt/outputs
@@ -41,4 +41,9 @@ $TS_CMD_FINDMNT /sys --submounts --kernel --tab-file "$TS_SELF/files/mountinfo"
echo rc=$? >> $TS_OUTPUT
ts_finalize_subtest
+ts_init_subtest "messy-mountinfo"
+$TS_CMD_FINDMNT --tab-file "$TS_SELF/files/mountinfo-messy" &> $TS_OUTPUT
+echo rc=$? >> $TS_OUTPUT
+ts_finalize_subtest
+
ts_finalize