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(
}
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(
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);
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;