]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
mount: use device enumerator to find matching loopback block device 25473/head
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 22 Nov 2022 02:22:20 +0000 (11:22 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 24 Nov 2022 05:17:35 +0000 (14:17 +0900)
No functional change, just refactoring.

src/mount/mount-tool.c

index b4007e58a9246e927723dfaaec0dfb50535b2f65..f7dd705c5e6865b2844b7c7a2defbb9bbf27987e 100644 (file)
@@ -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;