From 040d34390301977f90ee2655300be15f8fa7a2e8 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 30 Nov 2022 13:00:42 +0900 Subject: [PATCH 1/2] dissect: use sd-device to find and open loopback block device --- src/dissect/dissect.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index 3cf250e8ec..395294ebb4 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -1176,9 +1176,9 @@ static int action_list_or_mtree_or_copy(DissectedImage *m, LoopDevice *d) { static int action_umount(const char *path) { _cleanup_close_ int fd = -1; - _cleanup_free_ char *canonical = NULL, *devname = NULL; + _cleanup_free_ char *canonical = NULL; _cleanup_(loop_device_unrefp) LoopDevice *d = NULL; - dev_t devno; + _cleanup_(sd_device_unrefp) sd_device *dev = NULL; int r; fd = chase_symlinks_and_open(path, NULL, 0, O_DIRECTORY, &canonical); @@ -1193,18 +1193,13 @@ static int action_umount(const char *path) { if (r < 0) return log_error_errno(r, "Failed to determine whether '%s' is a mount point: %m", canonical); - r = fd_get_whole_disk(fd, /*backing=*/ true, &devno); + r = block_device_new_from_fd(fd, BLOCK_DEVICE_LOOKUP_WHOLE_DISK | BLOCK_DEVICE_LOOKUP_BACKING, &dev); if (r < 0) return log_error_errno(r, "Failed to find backing block device for '%s': %m", canonical); - r = devname_from_devnum(S_IFBLK, devno, &devname); + r = loop_device_open(dev, 0, LOCK_EX, &d); if (r < 0) - return log_error_errno(r, "Failed to get devname of block device " DEVNUM_FORMAT_STR ": %m", - DEVNUM_FORMAT_VAL(devno)); - - r = loop_device_open_from_path(devname, 0, LOCK_EX, &d); - if (r < 0) - return log_error_errno(r, "Failed to open loop device '%s': %m", devname); + return log_device_error_errno(dev, r, "Failed to open loopback block device: %m"); /* We've locked the loop device, now we're ready to unmount. To allow the unmount to succeed, we have * to close the O_PATH fd we opened earlier. */ From 41a95b18bd5dfbaee583270768f156f5b39c8499 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 30 Nov 2022 12:55:13 +0900 Subject: [PATCH 2/2] dissect: support to unmount image without root partition Fixes #25480. --- src/dissect/dissect.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index 395294ebb4..3892bfb208 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -1194,6 +1194,19 @@ static int action_umount(const char *path) { return log_error_errno(r, "Failed to determine whether '%s' is a mount point: %m", canonical); r = block_device_new_from_fd(fd, BLOCK_DEVICE_LOOKUP_WHOLE_DISK | BLOCK_DEVICE_LOOKUP_BACKING, &dev); + if (r < 0) { + _cleanup_close_ int usr_fd = -1; + + /* The command `systemd-dissect --mount` expects that the image at least has the root or /usr + * partition. If it does not have the root partition, then we mount the /usr partition on a + * tmpfs. Hence, let's try to find the backing block device through the /usr partition. */ + + usr_fd = openat(fd, "usr", O_CLOEXEC | O_DIRECTORY | O_NOFOLLOW); + if (usr_fd < 0) + return log_error_errno(errno, "Failed to open '%s/usr': %m", canonical); + + r = block_device_new_from_fd(usr_fd, BLOCK_DEVICE_LOOKUP_WHOLE_DISK | BLOCK_DEVICE_LOOKUP_BACKING, &dev); + } if (r < 0) return log_error_errno(r, "Failed to find backing block device for '%s': %m", canonical);