1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-02-09 09:57:26 +03:00

Merge pull request #25473 from yuwata/mount-tool-cleanups

mount-tool: several cleanups
This commit is contained in:
Luca Boccassi 2022-11-24 20:40:37 +01:00 committed by GitHub
commit 9af93d7cab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View 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(
@ -914,62 +912,69 @@ 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) {
_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(bus, loop_dev);
return umount_by_device(bus, dev);
}
static int action_umount(
@ -1014,7 +1019,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))
@ -1136,24 +1141,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)
@ -1234,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);
@ -1265,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;
@ -1288,7 +1282,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;