diff --git a/src/core/umount.c b/src/core/umount.c index 8ac40e5759..b46d133920 100644 --- a/src/core/umount.c +++ b/src/core/umount.c @@ -37,7 +37,6 @@ #include "fd-util.h" #include "fstab-util.h" #include "linux-3.13/dm-ioctl.h" -#include "list.h" #include "mount-setup.h" #include "mount-util.h" #include "path-util.h" @@ -52,15 +51,6 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(struct libmnt_table*, mnt_free_table); DEFINE_TRIVIAL_CLEANUP_FUNC(struct libmnt_iter*, mnt_free_iter); -typedef struct MountPoint { - char *path; - char *remount_options; - unsigned long remount_flags; - bool try_remount_ro; - dev_t devnum; - LIST_FIELDS(struct MountPoint, mount_point); -} MountPoint; - static void mount_point_free(MountPoint **head, MountPoint *m) { assert(head); assert(m); @@ -72,14 +62,14 @@ static void mount_point_free(MountPoint **head, MountPoint *m) { free(m); } -static void mount_points_list_free(MountPoint **head) { +void mount_points_list_free(MountPoint **head) { assert(head); while (*head) mount_point_free(head, *head); } -static int mount_points_list_get(MountPoint **head) { +int mount_points_list_get(const char *mountinfo, MountPoint **head) { _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL; _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL; int r; @@ -91,9 +81,9 @@ static int mount_points_list_get(MountPoint **head) { if (!t || !i) return log_oom(); - r = mnt_table_parse_mtab(t, NULL); + r = mnt_table_parse_mtab(t, mountinfo); if (r < 0) - return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m"); + return log_error_errno(r, "Failed to parse %s: %m", mountinfo); for (;;) { struct libmnt_fs *fs; @@ -108,7 +98,7 @@ static int mount_points_list_get(MountPoint **head) { if (r == 1) break; if (r < 0) - return log_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m"); + return log_error_errno(r, "Failed to get next entry from %s: %m", mountinfo); path = mnt_fs_get_target(fs); if (!path) @@ -661,7 +651,7 @@ static int umount_all_once(bool *changed, int umount_log_level) { assert(changed); LIST_HEAD_INIT(mp_list_head); - r = mount_points_list_get(&mp_list_head); + r = mount_points_list_get(NULL, &mp_list_head); if (r < 0) goto end; diff --git a/src/core/umount.h b/src/core/umount.h index a6613e6ad6..fa1c6de90d 100644 --- a/src/core/umount.h +++ b/src/core/umount.h @@ -20,6 +20,8 @@ along with systemd; If not, see . ***/ +#include "list.h" + int umount_all(bool *changed, int umount_log_level); int swapoff_all(bool *changed); @@ -27,3 +29,16 @@ int swapoff_all(bool *changed); int loopback_detach_all(bool *changed, int umount_log_level); int dm_detach_all(bool *changed, int umount_log_level); + +/* This is exported just for testing */ +typedef struct MountPoint { + char *path; + char *remount_options; + unsigned long remount_flags; + bool try_remount_ro; + dev_t devnum; + LIST_FIELDS(struct MountPoint, mount_point); +} MountPoint; + +int mount_points_list_get(const char *mountinfo, MountPoint **head); +void mount_points_list_free(MountPoint **head); diff --git a/src/test/meson.build b/src/test/meson.build index 4f28ef8722..e45618ef88 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -652,6 +652,14 @@ tests += [ [], [libdl], '', 'manual'], + + [['src/test/test-umount.c', + 'src/core/mount-setup.c', + 'src/core/mount-setup.h', + 'src/core/umount.c', + 'src/core/umount.h'], + [], + [libmount]], ] ############################################################ diff --git a/src/test/test-umount.c b/src/test/test-umount.c new file mode 100644 index 0000000000..ca626041f6 --- /dev/null +++ b/src/test/test-umount.c @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include "log.h" +#include "string-util.h" +#include "tests.h" +#include "umount.h" +#include "util.h" + +static void test_mount_points_list(const char *fname) { + LIST_HEAD(MountPoint, mp_list_head); + MountPoint *m; + + log_info("/* %s(\"%s\") */", __func__, fname ?: "/proc/self/mountinfo"); + + LIST_HEAD_INIT(mp_list_head); + assert_se(mount_points_list_get(fname, &mp_list_head) >= 0); + + LIST_FOREACH(mount_point, m, mp_list_head) + log_debug("path=%s o=%s f=0x%lx try-ro=%s dev=%u:%u", + m->path, + strempty(m->remount_options), + m->remount_flags, + yes_no(m->try_remount_ro), + major(m->devnum), minor(m->devnum)); + + mount_points_list_free(&mp_list_head); +} + +int main(int argc, char **argv) { + log_set_max_level(LOG_DEBUG); + log_parse_environment(); + log_open(); + + test_mount_points_list(NULL); + test_mount_points_list(get_testdata_dir("/test-umount/empty.mountinfo")); + test_mount_points_list(get_testdata_dir("/test-umount/garbled.mountinfo")); + test_mount_points_list(get_testdata_dir("/test-umount/rhbug-1554943.mountinfo")); +} diff --git a/test/meson.build b/test/meson.build index f86cf388e0..51c47793e0 100644 --- a/test/meson.build +++ b/test/meson.build @@ -174,6 +174,9 @@ test_data_files = ''' testsuite.target timers.target unstoppable.service + test-umount/empty.mountinfo + test-umount/garbled.mountinfo + test-umount/rhbug-1554943.mountinfo '''.split() if conf.get('ENABLE_RESOLVE') == 1 diff --git a/test/test-umount/empty.mountinfo b/test/test-umount/empty.mountinfo new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/test-umount/garbled.mountinfo b/test/test-umount/garbled.mountinfo new file mode 100644 index 0000000000..5f28aea409 --- /dev/null +++ b/test/test-umount/garbled.mountinfo @@ -0,0 +1,5 @@ +18 63 1000999:110999 / /sys rw,nosuid,nodev,noexec,relatime shared:2 - sysfs sysfs rw +44 44 +asdfasdf asdfasdf asdf asdfasdfasdf +asdfsadfasd +95 63 8:1 / /one-good-entry rw,relatime shared:34 - ext4 /dev/sda1 rw,data=ordered diff --git a/test/test-umount/rhbug-1554943.mountinfo b/test/test-umount/rhbug-1554943.mountinfo new file mode 100644 index 0000000000..d8bdf35862 --- /dev/null +++ b/test/test-umount/rhbug-1554943.mountinfo @@ -0,0 +1,47 @@ +18 63 0:18 / /sys rw,nosuid,nodev,noexec,relatime shared:2 - sysfs sysfs rw +19 63 0:4 / /proc rw,nosuid,nodev,noexec,relatime shared:23 - proc proc rw +20 63 0:6 / /dev rw,nosuid shared:19 - devtmpfs devtmpfs rw,size=3549752k,nr_inodes=887438,mode=755 +21 18 0:7 / /sys/kernel/security rw,nosuid,nodev,noexec,relatime shared:3 - securityfs securityfs rw +22 20 0:19 / /dev/shm rw,nosuid,nodev shared:20 - tmpfs tmpfs rw +23 20 0:20 / /dev/pts rw,nosuid,noexec,relatime shared:21 - devpts devpts rw,gid=5,mode=620,ptmxmode=000 +24 63 0:21 / /run rw,nosuid,nodev shared:22 - tmpfs tmpfs rw,mode=755 +25 18 0:22 / /sys/fs/cgroup ro,nosuid,nodev,noexec shared:4 - tmpfs tmpfs ro,mode=755 +26 25 0:23 / /sys/fs/cgroup/unified rw,nosuid,nodev,noexec,relatime shared:5 - cgroup2 cgroup rw +27 25 0:24 / /sys/fs/cgroup/systemd rw,nosuid,nodev,noexec,relatime shared:6 - cgroup cgroup rw,xattr,name=systemd +28 18 0:25 / /sys/fs/pstore rw,nosuid,nodev,noexec,relatime shared:17 - pstore pstore rw +29 25 0:26 / /sys/fs/cgroup/cpu,cpuacct rw,nosuid,nodev,noexec,relatime shared:7 - cgroup cgroup rw,cpu,cpuacct +30 25 0:27 / /sys/fs/cgroup/perf_event rw,nosuid,nodev,noexec,relatime shared:8 - cgroup cgroup rw,perf_event +31 25 0:28 / /sys/fs/cgroup/freezer rw,nosuid,nodev,noexec,relatime shared:9 - cgroup cgroup rw,freezer +32 25 0:29 / /sys/fs/cgroup/hugetlb rw,nosuid,nodev,noexec,relatime shared:10 - cgroup cgroup rw,hugetlb +33 25 0:30 / /sys/fs/cgroup/cpuset rw,nosuid,nodev,noexec,relatime shared:11 - cgroup cgroup rw,cpuset +34 25 0:31 / /sys/fs/cgroup/net_cls,net_prio rw,nosuid,nodev,noexec,relatime shared:12 - cgroup cgroup rw,net_cls,net_prio +35 25 0:32 / /sys/fs/cgroup/memory rw,nosuid,nodev,noexec,relatime shared:13 - cgroup cgroup rw,memory +36 25 0:33 / /sys/fs/cgroup/pids rw,nosuid,nodev,noexec,relatime shared:14 - cgroup cgroup rw,pids +37 25 0:34 / /sys/fs/cgroup/blkio rw,nosuid,nodev,noexec,relatime shared:15 - cgroup cgroup rw,blkio +38 25 0:35 / /sys/fs/cgroup/devices rw,nosuid,nodev,noexec,relatime shared:16 - cgroup cgroup rw,devices +61 18 0:36 / /sys/kernel/config rw,relatime shared:18 - configfs configfs rw +63 0 8:17 / / rw,relatime shared:1 - ext4 /dev/sdb1 rw,lazytime,commit=30,inode_readahead_blks=16 +39 18 0:8 / /sys/kernel/debug rw,relatime shared:24 - debugfs debugfs rw +40 20 0:37 / /dev/hugepages rw,relatime shared:25 - hugetlbfs hugetlbfs rw,pagesize=2M +41 19 0:38 / /proc/sys/fs/binfmt_misc rw,relatime shared:26 - autofs systemd-1 rw,fd=32,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=14807 +42 20 0:17 / /dev/mqueue rw,relatime shared:27 - mqueue mqueue rw +43 63 0:39 / /var/www/sessiondata rw,nosuid,noexec,noatime shared:28 - tmpfs tmpfs rw,size=4194304k +75 63 0:40 / /usr/share/mysql-test/var rw,noatime shared:29 - tmpfs tmpfs rw,size=4194304k,mode=750,uid=27,gid=27 +77 63 8:33 / /Volumes/dune rw,relatime shared:30 - ext4 /dev/sdc1 rw,lazytime,commit=30,inode_readahead_blks=16 +79 63 8:33 /builduser /home/builduser rw,relatime shared:30 - ext4 /dev/sdc1 rw,lazytime,commit=30,inode_readahead_blks=16 +81 77 0:41 / /Volumes/dune/mysql_data/autotest rw,nosuid,noexec,noatime shared:31 - tmpfs tmpfs rw,size=4194304k,mode=700,uid=27,gid=27 +83 63 8:33 /.tmp /var/tmp rw,relatime shared:30 - ext4 /dev/sdc1 rw,lazytime,commit=30,inode_readahead_blks=16 +85 77 0:42 / /Volumes/dune/www-servers/cms/cms/temp rw,nosuid,noexec,noatime shared:32 - tmpfs tmpfs rw,size=4194304k,mode=770,uid=48,gid=48 +87 77 8:33 /buildserver/autotest /Volumes/dune/www-servers/autotest rw,relatime shared:30 - ext4 /dev/sdc1 rw,lazytime,commit=30,inode_readahead_blks=16 +89 63 8:33 /.tmp /tmp rw,relatime shared:30 - ext4 /dev/sdc1 rw,lazytime,commit=30,inode_readahead_blks=16 +91 77 0:43 / /Volumes/dune/www-servers/cms/cms/logs rw,nosuid,noexec,noatime shared:33 - tmpfs tmpfs rw,size=4194304k,mode=770,uid=48,gid=48 +93 63 8:33 /www-servers/cms /usr/local/sftp-homes/flow/cms rw,relatime shared:30 - ext4 /dev/sdc1 rw,lazytime,commit=30,inode_readahead_blks=16 +95 63 8:1 / /boot rw,relatime shared:34 - ext4 /dev/sda1 rw,data=ordered +97 79 0:44 / /home/builduser/rpmbuild/PHP-PGO/logs rw,nosuid,noatime shared:35 - tmpfs tmpfs rw,size=4194304k,mode=770,uid=5000,gid=5000 +98 77 0:44 / /Volumes/dune/builduser/rpmbuild/PHP-PGO/logs rw,nosuid,noatime shared:35 - tmpfs tmpfs rw,size=4194304k,mode=770,uid=5000,gid=5000 +101 63 9:0 / /mnt/raid10 rw,relatime shared:36 - ext4 /dev/md0 rw,lazytime,commit=30,stripe=128,inode_readahead_blks=16 +558 24 0:52 / /run/user/48 rw,nosuid,nodev,relatime shared:83 - tmpfs tmpfs rw,size=711220k,mode=700,uid=48,gid=48 +588 24 0:53 / /run/user/5000 rw,nosuid,nodev,relatime shared:135 - tmpfs tmpfs rw,size=711220k,mode=700,uid=5000,gid=5000 +613 24 0:54 / /run/user/4503 rw,nosuid,nodev,relatime shared:85 - tmpfs tmpfs rw,size=711220k,mode=700,uid=4503,gid=4503 +653 24 0:45 / /run/user/4500 rw,nosuid,nodev,relatime shared:87 - tmpfs tmpfs rw,size=711220k,mode=700,uid=4500,gid=48 +699 24 0:55 / /run/user/0 rw,nosuid,nodev,relatime shared:89 - tmpfs tmpfs rw,size=711220k,mode=700