From 95a45a87d6425864b8fc962b45efc7d1f92bc593 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 22 Nov 2022 11:43:57 +0900 Subject: [PATCH 1/3] mount: make acquire_mount_where_for_loop_dev() take sd-device object No functional change, just refactoring. --- src/mount/mount-tool.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c index 95dcf1bab0..72570f6fa6 100644 --- a/src/mount/mount-tool.c +++ b/src/mount/mount-tool.c @@ -1136,24 +1136,31 @@ static int acquire_mount_where(sd_device *d) { return 1; } -static int acquire_mount_where_for_loop_dev(const char *loop_dev) { +static int acquire_mount_where_for_loop_dev(sd_device *dev) { _cleanup_strv_free_ char **list = NULL; + const char *node; int r; + assert(dev); + if (arg_mount_where) return 0; - r = find_mount_points(loop_dev, &list); + r = sd_device_get_devname(dev, &node); if (r < 0) return r; - else if (r == 0) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Can't find mount point of %s. It is expected that %s is already mounted on a place.", - loop_dev, loop_dev); - else if (r >= 2) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "%s is mounted on %d places. It is expected that %s is mounted on a place.", - loop_dev, r, loop_dev); + + r = find_mount_points(node, &list); + if (r < 0) + return r; + if (r == 0) + return log_device_error_errno(dev, SYNTHETIC_ERRNO(EINVAL), + "Can't find mount point of %s. It is expected that %s is already mounted on a place.", + node, node); + if (r >= 2) + return log_device_error_errno(dev, SYNTHETIC_ERRNO(EINVAL), + "%s is mounted on %d places. It is expected that %s is mounted on a place.", + node, r, node); arg_mount_where = strdup(list[0]); if (!arg_mount_where) @@ -1288,7 +1295,7 @@ static int discover_loop_backing_file(void) { if (r < 0) return r; - r = acquire_mount_where_for_loop_dev(loop_dev); + r = acquire_mount_where_for_loop_dev(d); if (r < 0) return r; From 961d08cadb814dca9be60be55b119fc3a926e3e2 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 22 Nov 2022 11:04:33 +0900 Subject: [PATCH 2/3] mount: split umount_by_device() into two No functional change, just refactoring and preparation for later commits. --- src/mount/mount-tool.c | 69 +++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c index 72570f6fa6..b4007e58a9 100644 --- a/src/mount/mount-tool.c +++ b/src/mount/mount-tool.c @@ -914,49 +914,56 @@ static int stop_mounts( return 0; } -static int umount_by_device(sd_bus *bus, const char *what) { +static int umount_by_device(sd_bus *bus, sd_device *dev) { _cleanup_(sd_device_unrefp) sd_device *d = NULL; _cleanup_strv_free_ char **list = NULL; - struct stat st; const char *v; - char **l; - int r, r2 = 0; + int r, ret = 0; - assert(what); - - if (stat(what, &st) < 0) - return log_error_errno(errno, "Can't stat %s: %m", what); - - if (!S_ISBLK(st.st_mode)) - return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK), - "Not a block device: %s", what); - - r = sd_device_new_from_stat_rdev(&d, &st); - if (r < 0) - return log_error_errno(r, "Failed to get device from device number: %m"); - - r = sd_device_get_property_value(d, "ID_FS_USAGE", &v); - if (r < 0) - return log_device_error_errno(d, r, "Failed to get device property: %m"); - - if (!streq(v, "filesystem")) - return log_device_error_errno(d, SYNTHETIC_ERRNO(EINVAL), - "%s does not contain a known file system.", what); + assert(bus); + assert(dev); if (sd_device_get_property_value(d, "SYSTEMD_MOUNT_WHERE", &v) >= 0) - r2 = stop_mounts(bus, v); + ret = stop_mounts(bus, v); - r = find_mount_points(what, &list); + r = sd_device_get_devname(dev, &v); if (r < 0) return r; - for (l = list; *l; l++) { + r = find_mount_points(v, &list); + if (r < 0) + return r; + + STRV_FOREACH(l, list) { r = stop_mounts(bus, *l); if (r < 0) - r2 = r; + ret = r; } - return r2; + return ret; +} + +static int umount_by_device_node(sd_bus *bus, const char *node) { + _cleanup_(sd_device_unrefp) sd_device *dev = NULL; + const char *v; + int r; + + assert(bus); + assert(node); + + r = sd_device_new_from_devname(&dev, node); + if (r < 0) + return log_error_errno(r, "Failed to get device from %s: %m", node); + + r = sd_device_get_property_value(dev, "ID_FS_USAGE", &v); + if (r < 0) + return log_device_error_errno(dev, r, "Failed to get \"ID_FS_USAGE\" device property: %m"); + + if (!streq(v, "filesystem")) + return log_device_error_errno(dev, SYNTHETIC_ERRNO(EINVAL), + "%s does not contain a known file system.", node); + + return umount_by_device(bus, dev); } static int umount_loop(sd_bus *bus, const char *backing_file) { @@ -969,7 +976,7 @@ static int umount_loop(sd_bus *bus, const char *backing_file) { if (r < 0) return log_error_errno(r, r == -ENXIO ? "File %s is not mounted." : "Can't get loop device for %s: %m", backing_file); - return umount_by_device(bus, loop_dev); + return umount_by_device_node(bus, loop_dev); } static int action_umount( @@ -1014,7 +1021,7 @@ static int action_umount( return log_error_errno(errno, "Can't stat %s (from %s): %m", p, argv[i]); if (S_ISBLK(st.st_mode)) - r = umount_by_device(bus, p); + r = umount_by_device_node(bus, p); else if (S_ISREG(st.st_mode)) r = umount_loop(bus, p); else if (S_ISDIR(st.st_mode)) From 1480c23199d53383b7949c75892f2640849581fa Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 22 Nov 2022 11:22:20 +0900 Subject: [PATCH 3/3] mount: use device enumerator to find matching loopback block device No functional change, just refactoring. --- src/mount/mount-tool.c | 86 ++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 53 deletions(-) diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c index b4007e58a9..f7dd705c5e 100644 --- a/src/mount/mount-tool.c +++ b/src/mount/mount-tool.c @@ -776,53 +776,51 @@ static int find_mount_points(const char *what, char ***list) { return n; } -static int find_loop_device(const char *backing_file, char **loop_dev) { - _cleanup_closedir_ DIR *d = NULL; - _cleanup_free_ char *l = NULL; +static int find_loop_device(const char *backing_file, sd_device **ret) { + _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; + sd_device *dev; + int r; assert(backing_file); - assert(loop_dev); + assert(ret); - d = opendir("/sys/devices/virtual/block"); - if (!d) - return -errno; + r = sd_device_enumerator_new(&e); + if (r < 0) + return log_oom(); - FOREACH_DIRENT(de, d, return -errno) { - _cleanup_free_ char *sys = NULL, *fname = NULL; - int r; + r = sd_device_enumerator_add_match_subsystem(e, "block", /* match = */ true); + if (r < 0) + return log_error_errno(r, "Failed to add subsystem match: %m"); - if (de->d_type != DT_DIR) - continue; + r = sd_device_enumerator_add_match_property(e, "ID_FS_USAGE", "filesystem"); + if (r < 0) + return log_error_errno(r, "Failed to add property match: %m"); - if (!startswith(de->d_name, "loop")) - continue; + r = sd_device_enumerator_add_match_sysname(e, "loop*"); + if (r < 0) + return log_error_errno(r, "Failed to add sysname match: %m"); - sys = path_join("/sys/devices/virtual/block", de->d_name, "loop/backing_file"); - if (!sys) - return -ENOMEM; + r = sd_device_enumerator_add_match_sysattr(e, "loop/backing_file", /* value = */ NULL, /* match = */ true); + if (r < 0) + return log_error_errno(r, "Failed to add sysattr match: %m"); - r = read_one_line_file(sys, &fname); + FOREACH_DEVICE(e, dev) { + const char *s; + + r = sd_device_get_sysattr_value(dev, "loop/backing_file", &s); if (r < 0) { - log_debug_errno(r, "Failed to read %s, ignoring: %m", sys); + log_device_debug_errno(dev, r, "Failed to read \"loop/backing_file\" sysattr, ignoring: %m"); continue; } - if (files_same(fname, backing_file, 0) <= 0) + if (files_same(s, backing_file, 0) <= 0) continue; - l = path_join("/dev", de->d_name); - if (!l) - return -ENOMEM; - - break; + *ret = sd_device_ref(dev); + return 0; } - if (!l) - return -ENXIO; - - *loop_dev = TAKE_PTR(l); - - return 0; + return -ENXIO; } static int stop_mount( @@ -967,16 +965,16 @@ static int umount_by_device_node(sd_bus *bus, const char *node) { } static int umount_loop(sd_bus *bus, const char *backing_file) { - _cleanup_free_ char *loop_dev = NULL; + _cleanup_(sd_device_unrefp) sd_device *dev = NULL; int r; assert(backing_file); - r = find_loop_device(backing_file, &loop_dev); + r = find_loop_device(backing_file, &dev); if (r < 0) return log_error_errno(r, r == -ENXIO ? "File %s is not mounted." : "Can't get loop device for %s: %m", backing_file); - return umount_by_device_node(bus, loop_dev); + return umount_by_device(bus, dev); } static int action_umount( @@ -1248,12 +1246,9 @@ static int acquire_removable(sd_device *d) { static int discover_loop_backing_file(void) { _cleanup_(sd_device_unrefp) sd_device *d = NULL; - _cleanup_free_ char *loop_dev = NULL; - struct stat st; - const char *v; int r; - r = find_loop_device(arg_mount_what, &loop_dev); + r = find_loop_device(arg_mount_what, &d); if (r < 0 && r != -ENXIO) return log_error_errno(errno, "Can't get loop device for %s: %m", arg_mount_what); @@ -1279,21 +1274,6 @@ static int discover_loop_backing_file(void) { return 0; } - if (stat(loop_dev, &st) < 0) - return log_error_errno(errno, "Can't stat %s: %m", loop_dev); - - if (!S_ISBLK(st.st_mode)) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Invalid file type: %s", loop_dev); - - r = sd_device_new_from_stat_rdev(&d, &st); - if (r < 0) - return log_error_errno(r, "Failed to get device from device number: %m"); - - if (sd_device_get_property_value(d, "ID_FS_USAGE", &v) < 0 || !streq(v, "filesystem")) - return log_device_error_errno(d, SYNTHETIC_ERRNO(EINVAL), - "%s does not contain a known file system.", arg_mount_what); - r = acquire_mount_type(d); if (r < 0) return r;