diff options
-rw-r--r-- | libmount/src/tab.c | 34 | ||||
-rw-r--r-- | tests/expected/findmnt/outputs-messy-mountinfo | 31 | ||||
-rw-r--r-- | tests/ts/findmnt/files/mountinfo-messy | 29 | ||||
-rwxr-xr-x | tests/ts/findmnt/outputs | 5 |
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 |