From cc5bae6cc27ba85a6efa5331fabb4c7447186e52 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 6 Sep 2022 04:35:54 +0900 Subject: [PATCH 01/12] loop-util: store sd_device object for the loop device It will be used in later commits. --- src/shared/loop-util.c | 52 ++++++++++++++++++-------------------- src/shared/loop-util.h | 3 +++ src/test/test-loop-block.c | 1 + 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c index ed237c6f20..ac873b0154 100644 --- a/src/shared/loop-util.c +++ b/src/shared/loop-util.c @@ -132,6 +132,7 @@ static int open_lock_fd(int primary_fd, int operation) { } static int loop_configure( + sd_device *dev, int fd, int nr, const struct loop_config *c, @@ -140,8 +141,6 @@ static int loop_configure( usec_t *ret_timestamp_not_before, int *ret_lock_fd) { - _cleanup_(sd_device_unrefp) sd_device *d = NULL; - _cleanup_free_ char *sysname = NULL; _cleanup_close_ int lock_fd = -1; struct loop_info64 info_copy; uint64_t seqnum; @@ -153,13 +152,6 @@ static int loop_configure( assert(c); assert(try_loop_configure); - if (asprintf(&sysname, "loop%i", nr) < 0) - return -ENOMEM; - - r = sd_device_new_from_subsystem_sysname(&d, "block", sysname); - if (r < 0) - return r; - /* Let's lock the device before we do anything. We take the BSD lock on a second, separately opened * fd for the device. udev after all watches for close() events (specifically IN_CLOSE_WRITE) on * block devices to reprobe them, hence by having a separate fd we will later close() we can ensure @@ -176,7 +168,7 @@ static int loop_configure( * superficially is detached but still has partition block devices associated for it. Let's then * manually remove the partitions via BLKPG, and tell the caller we did that via EUCLEAN, so they try * again. */ - r = device_has_block_children(d); + r = device_has_block_children(dev); if (r < 0) return r; if (r > 0) { @@ -357,6 +349,7 @@ static int loop_device_make_internal( int lock_op, LoopDevice **ret) { + _cleanup_(sd_device_unrefp) sd_device *dev = NULL; _cleanup_close_ int direct_io_fd = -1; _cleanup_free_ char *node = NULL; bool try_loop_configure = true; @@ -456,14 +449,19 @@ static int loop_device_make_internal( if (asprintf(&node, "/dev/loop%i", nr) < 0) return -ENOMEM; - loop = open(node, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|open_flags); + dev = sd_device_unref(dev); + r = sd_device_new_from_devname(&dev, node); + if (r < 0) + return r; + + loop = sd_device_open(dev, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|open_flags); if (loop < 0) { /* Somebody might've gotten the same number from the kernel, used the device, * and called LOOP_CTL_REMOVE on it. Let's retry with a new number. */ if (!ERRNO_IS_DEVICE_ABSENT(errno)) return -errno; } else { - r = loop_configure(loop, nr, &config, &try_loop_configure, &seqnum, ×tamp, &lock_fd); + r = loop_configure(dev, loop, nr, &config, &try_loop_configure, &seqnum, ×tamp, &lock_fd); if (r >= 0) { loop_with_fd = TAKE_FD(loop); break; @@ -545,6 +543,7 @@ static int loop_device_make_internal( .node = TAKE_PTR(node), .nr = nr, .devno = st.st_rdev, + .dev = TAKE_PTR(dev), .diskseq = diskseq, .uevent_seqnum_not_before = seqnum, .timestamp_not_before = timestamp, @@ -720,6 +719,7 @@ LoopDevice* loop_device_unref(LoopDevice *d) { } free(d->node); + sd_device_unref(d->dev); return mfree(d); } @@ -744,6 +744,7 @@ int loop_device_open_full( int lock_op, LoopDevice **ret) { + _cleanup_(sd_device_unrefp) sd_device *dev = NULL; _cleanup_close_ int fd = -1, lock_fd = -1; _cleanup_free_ char *p = NULL; struct loop_info64 info; @@ -768,6 +769,10 @@ int loop_device_open_full( if (!S_ISBLK(st.st_mode)) return -ENOTBLK; + r = sd_device_new_from_stat_rdev(&dev, &st); + if (r < 0) + return r; + if (fd < 0) { /* If loop_fd is provided through the argument, then we reopen the inode here, instead of * keeping just a dup() clone of it around, since we want to ensure that the O_DIRECT @@ -797,21 +802,13 @@ int loop_device_open_full( return lock_fd; } - if (loop_path) { - /* If loop_path is provided, then honor it. */ - p = strdup(loop_path); - if (!p) - return -ENOMEM; - } else if (nr >= 0) { - /* This is a loopback block device. Use its index. */ - if (asprintf(&p, "/dev/loop%i", nr) < 0) - return -ENOMEM; - } else { - /* This is a non-loopback block device. Let's get the path to the device node. */ - r = devname_from_stat_rdev(&st, &p); - if (r < 0) - return r; - } + r = sd_device_get_devname(dev, &loop_path); + if (r < 0) + return r; + + p = strdup(loop_path); + if (!p) + return -ENOMEM; d = new(LoopDevice, 1); if (!d) @@ -822,6 +819,7 @@ int loop_device_open_full( .lock_fd = TAKE_FD(lock_fd), .nr = nr, .node = TAKE_PTR(p), + .dev = TAKE_PTR(dev), .relinquished = true, /* It's not ours, don't try to destroy it when this object is freed */ .devno = st.st_rdev, .diskseq = diskseq, diff --git a/src/shared/loop-util.h b/src/shared/loop-util.h index 89fcbc00a0..43bd25d445 100644 --- a/src/shared/loop-util.h +++ b/src/shared/loop-util.h @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once +#include "sd-device.h" + #include "macro.h" #include "time-util.h" @@ -14,6 +16,7 @@ struct LoopDevice { int nr; /* The loopback device index (i.e. 4 for /dev/loop4); if this object encapsulates a non-loopback block device, set to -1 */ dev_t devno; char *node; + sd_device *dev; bool relinquished; uint64_t diskseq; /* Block device sequence number, monothonically incremented by the kernel on create/attach, or 0 if we don't know */ uint64_t uevent_seqnum_not_before; /* uevent sequm right before we attached the loopback device, or UINT64_MAX if we don't know */ diff --git a/src/test/test-loop-block.c b/src/test/test-loop-block.c index 143e5a61e0..1809d9f3b8 100644 --- a/src/test/test-loop-block.c +++ b/src/test/test-loop-block.c @@ -54,6 +54,7 @@ static void* thread_func(void *ptr) { if (r < 0) log_error_errno(r, "Failed to allocate loopback device: %m"); assert_se(r >= 0); + assert_se(loop->dev); log_notice("Acquired loop device %s, will mount on %s", loop->node, mounted); From 46c3a288454a45a7fefb8615188e61f6ce62490f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 6 Sep 2022 04:46:04 +0900 Subject: [PATCH 02/12] blockdev-util: make block_device_remove_all_partitions() take sd_device object Then, it is not necessary to recreate sd_device object when we already have. --- src/shared/blockdev-util.c | 32 ++++++++++++++++++++++++-------- src/shared/blockdev-util.h | 4 +++- src/shared/loop-util.c | 4 ++-- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/shared/blockdev-util.c b/src/shared/blockdev-util.c index 0b2554d4b2..1a7419c549 100644 --- a/src/shared/blockdev-util.c +++ b/src/shared/blockdev-util.c @@ -509,19 +509,27 @@ int block_device_resize_partition( return RET_NERRNO(ioctl(fd, BLKPG, &ba)); } -int block_device_remove_all_partitions(int fd) { - struct stat stat; - _cleanup_(sd_device_unrefp) sd_device *dev = NULL; +int block_device_remove_all_partitions(sd_device *dev, int fd) { _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; + _cleanup_(sd_device_unrefp) sd_device *dev_unref = NULL; + _cleanup_close_ int fd_close = -1; sd_device *part; int r, k = 0; - if (fstat(fd, &stat) < 0) - return -errno; + assert(dev || fd >= 0); - r = sd_device_new_from_devnum(&dev, 'b', stat.st_rdev); - if (r < 0) - return r; + if (!dev) { + struct stat st; + + if (fstat(fd, &st) < 0) + return -errno; + + r = sd_device_new_from_stat_rdev(&dev_unref, &st); + if (r < 0) + return r; + + dev = dev_unref; + } r = sd_device_enumerator_new(&e); if (r < 0) @@ -539,6 +547,14 @@ int block_device_remove_all_partitions(int fd) { if (r < 0) return r; + if (fd < 0) { + fd_close = sd_device_open(dev, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|O_RDONLY); + if (fd_close < 0) + return fd_close; + + fd = fd_close; + } + FOREACH_DEVICE(e, part) { const char *v, *devname; int nr; diff --git a/src/shared/blockdev-util.h b/src/shared/blockdev-util.h index 2f1f347d09..e63c447331 100644 --- a/src/shared/blockdev-util.h +++ b/src/shared/blockdev-util.h @@ -3,6 +3,8 @@ #include +#include "sd-device.h" + #include "macro.h" #include "stdio-util.h" #include "string-util.h" @@ -34,4 +36,4 @@ int path_get_whole_disk(const char *path, bool backing, dev_t *ret); int block_device_add_partition(int fd, const char *name, int nr, uint64_t start, uint64_t size); int block_device_remove_partition(int fd, const char *name, int nr); int block_device_resize_partition(int fd, int nr, uint64_t start, uint64_t size); -int block_device_remove_all_partitions(int fd); +int block_device_remove_all_partitions(sd_device *dev, int fd); diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c index ac873b0154..56574ee7f2 100644 --- a/src/shared/loop-util.c +++ b/src/shared/loop-util.c @@ -181,7 +181,7 @@ static int loop_configure( /* Unbound but has children? Remove all partitions, and report this to the caller, to try * again, and count this as an attempt. */ - r = block_device_remove_all_partitions(fd); + r = block_device_remove_all_partitions(dev, fd); if (r < 0) return r; @@ -695,7 +695,7 @@ LoopDevice* loop_device_unref(LoopDevice *d) { if (flock(d->fd, LOCK_EX) < 0) log_debug_errno(errno, "Failed to lock loop block device, ignoring: %m"); - r = block_device_remove_all_partitions(d->fd); + r = block_device_remove_all_partitions(d->dev, d->fd); if (r < 0) log_debug_errno(r, "Failed to remove partitions of loopback block device, ignoring: %m"); From af15ee0368b96d95061ae7d28db99d7e341a6208 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 6 Sep 2022 05:00:49 +0900 Subject: [PATCH 03/12] blockdev-util: check if provided sd_device is for a whole block device And split out partition_generator_new(), to make it usable in other functions. --- src/shared/blockdev-util.c | 60 +++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/src/shared/blockdev-util.c b/src/shared/blockdev-util.c index 1a7419c549..9f3c9053dd 100644 --- a/src/shared/blockdev-util.c +++ b/src/shared/blockdev-util.c @@ -509,6 +509,52 @@ int block_device_resize_partition( return RET_NERRNO(ioctl(fd, BLKPG, &ba)); } +static int partition_enumerator_new(sd_device *dev, sd_device_enumerator **ret) { + _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; + const char *s; + int r; + + assert(dev); + assert(ret); + + r = sd_device_get_subsystem(dev, &s); + if (r < 0) + return r; + + if (!streq(s, "block")) + return -ENOTBLK; + + r = sd_device_get_devtype(dev, &s); + if (r < 0) + return r; + + if (!streq(s, "disk")) /* Refuse invocation on partition block device, insist on "whole" device */ + return -EINVAL; + + r = sd_device_enumerator_new(&e); + if (r < 0) + return r; + + r = sd_device_enumerator_allow_uninitialized(e); + if (r < 0) + return r; + + r = sd_device_enumerator_add_match_parent(e, dev); + if (r < 0) + return r; + + r = sd_device_enumerator_add_match_subsystem(e, "block", /* match = */ true); + if (r < 0) + return r; + + r = sd_device_enumerator_add_match_property(e, "DEVTYPE", "partition"); + if (r < 0) + return r; + + *ret = TAKE_PTR(e); + return 0; +} + int block_device_remove_all_partitions(sd_device *dev, int fd) { _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; _cleanup_(sd_device_unrefp) sd_device *dev_unref = NULL; @@ -531,19 +577,7 @@ int block_device_remove_all_partitions(sd_device *dev, int fd) { dev = dev_unref; } - r = sd_device_enumerator_new(&e); - if (r < 0) - return r; - - r = sd_device_enumerator_add_match_parent(e, dev); - if (r < 0) - return r; - - r = sd_device_enumerator_add_match_subsystem(e, "block", true); - if (r < 0) - return r; - - r = sd_device_enumerator_add_match_property(e, "DEVTYPE", "partition"); + r = partition_enumerator_new(dev, &e); if (r < 0) return r; From aa0295f1d9ac2b94f9506e707a01905c6af591d4 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 6 Sep 2022 05:01:34 +0900 Subject: [PATCH 04/12] loop-util: move device_has_block_children() to blockdev-util.c As the function is not only for loopback block device. No actual code changes, just refactoring. --- src/shared/blockdev-util.c | 15 ++++++++++++ src/shared/blockdev-util.h | 1 + src/shared/loop-util.c | 49 +------------------------------------- 3 files changed, 17 insertions(+), 48 deletions(-) diff --git a/src/shared/blockdev-util.c b/src/shared/blockdev-util.c index 9f3c9053dd..66807c673d 100644 --- a/src/shared/blockdev-util.c +++ b/src/shared/blockdev-util.c @@ -621,3 +621,18 @@ int block_device_remove_all_partitions(sd_device *dev, int fd) { return k; } + +int block_device_has_partitions(sd_device *dev) { + _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; + int r; + + assert(dev); + + /* Checks if the specified device currently has partitions. */ + + r = partition_enumerator_new(dev, &e); + if (r < 0) + return r; + + return !!sd_device_enumerator_get_device_first(e); +} diff --git a/src/shared/blockdev-util.h b/src/shared/blockdev-util.h index e63c447331..fb041bf619 100644 --- a/src/shared/blockdev-util.h +++ b/src/shared/blockdev-util.h @@ -37,3 +37,4 @@ int block_device_add_partition(int fd, const char *name, int nr, uint64_t start, int block_device_remove_partition(int fd, const char *name, int nr); int block_device_resize_partition(int fd, int nr, uint64_t start, uint64_t size); int block_device_remove_all_partitions(sd_device *dev, int fd); +int block_device_has_partitions(sd_device *dev); diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c index 56574ee7f2..b5c16b0b0e 100644 --- a/src/shared/loop-util.c +++ b/src/shared/loop-util.c @@ -70,53 +70,6 @@ static int get_current_uevent_seqnum(uint64_t *ret) { return 0; } -static int device_has_block_children(sd_device *d) { - _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; - const char *main_ss, *main_dt; - int r; - - assert(d); - - /* Checks if the specified device currently has block device children (i.e. partition block - * devices). */ - - r = sd_device_get_subsystem(d, &main_ss); - if (r < 0) - return r; - - if (!streq(main_ss, "block")) - return -EINVAL; - - r = sd_device_get_devtype(d, &main_dt); - if (r < 0) - return r; - - if (!streq(main_dt, "disk")) /* Refuse invocation on partition block device, insist on "whole" device */ - return -EINVAL; - - r = sd_device_enumerator_new(&e); - if (r < 0) - return r; - - r = sd_device_enumerator_allow_uninitialized(e); - if (r < 0) - return r; - - r = sd_device_enumerator_add_match_parent(e, d); - if (r < 0) - return r; - - r = sd_device_enumerator_add_match_subsystem(e, "block", /* match = */ true); - if (r < 0) - return r; - - r = sd_device_enumerator_add_match_property(e, "DEVTYPE", "partition"); - if (r < 0) - return r; - - return !!sd_device_enumerator_get_device_first(e); -} - static int open_lock_fd(int primary_fd, int operation) { int lock_fd; @@ -168,7 +121,7 @@ static int loop_configure( * superficially is detached but still has partition block devices associated for it. Let's then * manually remove the partitions via BLKPG, and tell the caller we did that via EUCLEAN, so they try * again. */ - r = device_has_block_children(dev); + r = block_device_has_partitions(dev); if (r < 0) return r; if (r > 0) { From e77cab824829f33e7870eb188ccd014acac49075 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 6 Sep 2022 05:19:46 +0900 Subject: [PATCH 05/12] loop-util: save backing file of loopback block device It will be used in later commits. --- src/shared/loop-util.c | 32 +++++++++++++++++++++++++++++--- src/shared/loop-util.h | 1 + src/test/test-loop-block.c | 1 + 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/shared/loop-util.c b/src/shared/loop-util.c index b5c16b0b0e..7a1b5ad2d3 100644 --- a/src/shared/loop-util.c +++ b/src/shared/loop-util.c @@ -26,6 +26,7 @@ #include "loop-util.h" #include "missing_loop.h" #include "parse-util.h" +#include "path-util.h" #include "random-util.h" #include "stat-util.h" #include "stdio-util.h" @@ -294,6 +295,7 @@ fail: } static int loop_device_make_internal( + const char *path, int fd, int open_flags, uint64_t offset, @@ -304,7 +306,7 @@ static int loop_device_make_internal( _cleanup_(sd_device_unrefp) sd_device *dev = NULL; _cleanup_close_ int direct_io_fd = -1; - _cleanup_free_ char *node = NULL; + _cleanup_free_ char *node = NULL, *backing_file = NULL; bool try_loop_configure = true; struct loop_config config; LoopDevice *d; @@ -332,6 +334,18 @@ static int loop_device_make_internal( return r; } + if (path) { + r = path_make_absolute_cwd(path, &backing_file); + if (r < 0) + return r; + + path_simplify(backing_file); + } else { + r = fd_get_path(fd, &backing_file); + if (r < 0) + return r; + } + f_flags = fcntl(fd, F_GETFL); if (f_flags < 0) return -errno; @@ -497,6 +511,7 @@ static int loop_device_make_internal( .nr = nr, .devno = st.st_rdev, .dev = TAKE_PTR(dev), + .backing_file = TAKE_PTR(backing_file), .diskseq = diskseq, .uevent_seqnum_not_before = seqnum, .timestamp_not_before = timestamp, @@ -535,6 +550,7 @@ int loop_device_make( assert(ret); return loop_device_make_internal( + NULL, fd, open_flags, offset, @@ -602,7 +618,7 @@ int loop_device_make_by_path( direct ? "enabled" : "disabled", direct != (direct_flags != 0) ? " (O_DIRECT was requested but not supported)" : ""); - return loop_device_make_internal(fd, open_flags, 0, 0, loop_flags, lock_op, ret); + return loop_device_make_internal(path, fd, open_flags, 0, 0, loop_flags, lock_op, ret); } LoopDevice* loop_device_unref(LoopDevice *d) { @@ -673,6 +689,7 @@ LoopDevice* loop_device_unref(LoopDevice *d) { free(d->node); sd_device_unref(d->dev); + free(d->backing_file); return mfree(d); } @@ -699,7 +716,7 @@ int loop_device_open_full( _cleanup_(sd_device_unrefp) sd_device *dev = NULL; _cleanup_close_ int fd = -1, lock_fd = -1; - _cleanup_free_ char *p = NULL; + _cleanup_free_ char *p = NULL, *backing_file = NULL; struct loop_info64 info; uint64_t diskseq = 0; struct stat st; @@ -738,11 +755,19 @@ int loop_device_open_full( } if (ioctl(loop_fd, LOOP_GET_STATUS64, &info) >= 0) { + const char *s; + #if HAVE_VALGRIND_MEMCHECK_H /* Valgrind currently doesn't know LOOP_GET_STATUS64. Remove this once it does */ VALGRIND_MAKE_MEM_DEFINED(&info, sizeof(info)); #endif nr = info.lo_number; + + if (sd_device_get_sysattr_value(dev, "loop/backing_file", &s) >= 0) { + backing_file = strdup(s); + if (!backing_file) + return -ENOMEM; + } } r = fd_get_diskseq(loop_fd, &diskseq); @@ -773,6 +798,7 @@ int loop_device_open_full( .nr = nr, .node = TAKE_PTR(p), .dev = TAKE_PTR(dev), + .backing_file = TAKE_PTR(backing_file), .relinquished = true, /* It's not ours, don't try to destroy it when this object is freed */ .devno = st.st_rdev, .diskseq = diskseq, diff --git a/src/shared/loop-util.h b/src/shared/loop-util.h index 43bd25d445..cb0183ba07 100644 --- a/src/shared/loop-util.h +++ b/src/shared/loop-util.h @@ -17,6 +17,7 @@ struct LoopDevice { dev_t devno; char *node; sd_device *dev; + char *backing_file; bool relinquished; uint64_t diskseq; /* Block device sequence number, monothonically incremented by the kernel on create/attach, or 0 if we don't know */ uint64_t uevent_seqnum_not_before; /* uevent sequm right before we attached the loopback device, or UINT64_MAX if we don't know */ diff --git a/src/test/test-loop-block.c b/src/test/test-loop-block.c index 1809d9f3b8..70d4aedb42 100644 --- a/src/test/test-loop-block.c +++ b/src/test/test-loop-block.c @@ -55,6 +55,7 @@ static void* thread_func(void *ptr) { log_error_errno(r, "Failed to allocate loopback device: %m"); assert_se(r >= 0); assert_se(loop->dev); + assert_se(loop->backing_file); log_notice("Acquired loop device %s, will mount on %s", loop->node, mounted); From 369de26fdf7152e7f2ff790b65533d101772e073 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 6 Sep 2022 05:37:13 +0900 Subject: [PATCH 06/12] dissect-image: use backing_file stored in LoopDevice object to generate image name Follow-up for e374439f4b8def786031ddbbd7dfdae3a335d4d2 (#24322). This also simplify the logic of generating image name from image path. --- src/core/namespace.c | 1 - src/portable/portable.c | 1 - src/shared/discover-image.c | 1 - src/shared/dissect-image.c | 68 ++++++++++++++++--------------------- src/shared/dissect-image.h | 15 ++++++-- src/test/test-loop-block.c | 12 ++----- 6 files changed, 45 insertions(+), 53 deletions(-) diff --git a/src/core/namespace.c b/src/core/namespace.c index 3fbf094851..468b27905e 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -2065,7 +2065,6 @@ int setup_namespace( r = dissect_loop_device( loop_device, - root_image, &verity, root_image_options, dissect_image_flags, diff --git a/src/portable/portable.c b/src/portable/portable.c index 9ac34ced6d..5d0a965db5 100644 --- a/src/portable/portable.c +++ b/src/portable/portable.c @@ -367,7 +367,6 @@ static int portable_extract_by_path( r = dissect_loop_device( d, - path, NULL, NULL, DISSECT_IMAGE_READ_ONLY | DISSECT_IMAGE_GENERIC_ROOT | diff --git a/src/shared/discover-image.c b/src/shared/discover-image.c index 6ddb279f0d..b3b59fc0bb 100644 --- a/src/shared/discover-image.c +++ b/src/shared/discover-image.c @@ -1198,7 +1198,6 @@ int image_read_metadata(Image *i) { r = dissect_loop_device( d, - i->path, NULL, NULL, DISSECT_IMAGE_GENERIC_ROOT | DISSECT_IMAGE_REQUIRE_ROOT | diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index dc7cf817f3..fce05bcfbd 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -193,7 +193,7 @@ static int make_partition_devname( int dissect_image( int fd, - const char *original_path, + const char *image_path, const VeritySettings *verity, const MountOptions *mount_options, uint64_t diskseq, @@ -213,7 +213,7 @@ int dissect_image( _cleanup_(blkid_free_probep) blkid_probe b = NULL; _cleanup_free_ char *generic_node = NULL; sd_id128_t generic_uuid = SD_ID128_NULL; - const char *pttype = NULL, *sysname = NULL, *devname = NULL; + const char *pttype = NULL, *devname = NULL; blkid_partlist pl; int r, generic_nr = -1, n_partitions; struct stat st; @@ -305,51 +305,45 @@ int dissect_image( .has_init_system = -1, }; - r = sd_device_get_sysname(d, &sysname); - if (r < 0) - return log_debug_errno(r, "Failed to get device sysname: %m"); - if (original_path) { + if (!image_path) { + const char *sysname; + + /* If image_path is not provided and the device is a loopback block device, then use the path + * to the backing file. Note that the backing_file reference resolves symlinks, while for + * sysext images we want the original path. */ + + r = sd_device_get_sysname(d, &sysname); + if (r < 0) + return log_debug_errno(r, "Failed to get device sysname: %m"); + + if (startswith(sysname, "loop")) { + r = sd_device_get_sysattr_value(d, "loop/backing_file", &image_path); + if (r < 0) + log_debug_errno(r, "Failed to lookup image name via loop device backing file sysattr, ignoring: %m"); + } + } + + if (image_path) { _cleanup_free_ char *extracted_filename = NULL, *name_stripped = NULL; - r = path_extract_filename(original_path, &extracted_filename); + + r = path_extract_filename(image_path, &extracted_filename); if (r < 0) return r; + r = raw_strip_suffixes(extracted_filename, &name_stripped); if (r < 0) return r; - free_and_replace(m->image_name, name_stripped); - } else if (startswith(sysname, "loop")) { - _cleanup_free_ char *extracted_filename = NULL, *name_stripped = NULL; - const char *full_path; - - /* Note that the backing_file reference resolves symlinks, while for sysext images we want the original path */ - r = sd_device_get_sysattr_value(d, "loop/backing_file", &full_path); - if (r < 0) - log_debug_errno(r, "Failed to lookup image name via loop device backing file sysattr, ignoring: %m"); - else { - r = path_extract_filename(full_path, &extracted_filename); - if (r < 0) - return r; - r = raw_strip_suffixes(extracted_filename, &name_stripped); - if (r < 0) - return r; - } - - free_and_replace(m->image_name, name_stripped); - } else { - r = free_and_strdup(&m->image_name, sysname); - if (r < 0) - return r; + if (!image_name_is_valid(name_stripped)) + log_debug("Image name %s is not valid, ignoring.", strna(name_stripped)); + else + m->image_name = TAKE_PTR(name_stripped); } + r = sd_device_get_devname(d, &devname); if (r < 0) return log_debug_errno(r, "Failed to get device devname: %m"); - if (!image_name_is_valid(m->image_name)) { - log_debug("Image name %s is not valid, ignoring", strempty(m->image_name)); - m->image_name = mfree(m->image_name); - } - if ((!(flags & DISSECT_IMAGE_GPT_ONLY) && (flags & DISSECT_IMAGE_GENERIC_ROOT)) || (flags & DISSECT_IMAGE_NO_PARTITION_TABLE)) { @@ -2827,7 +2821,7 @@ int dissect_loop_device_and_warn( if (!name) name = ASSERT_PTR(loop->node); - r = dissect_loop_device(loop, name, verity, mount_options, flags, ret); + r = dissect_loop_device(loop, verity, mount_options, flags, ret); switch (r) { case -EOPNOTSUPP: @@ -3093,7 +3087,6 @@ int verity_dissect_and_mount( r = dissect_loop_device( loop_device, - src, &verity, options, dissect_image_flags, @@ -3102,7 +3095,6 @@ int verity_dissect_and_mount( if (!verity.data_path && r == -ENOPKG) r = dissect_loop_device( loop_device, - src, &verity, options, dissect_image_flags | DISSECT_IMAGE_NO_PARTITION_TABLE, diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h index cc0cf66180..c8d2e6de8f 100644 --- a/src/shared/dissect-image.h +++ b/src/shared/dissect-image.h @@ -253,10 +253,19 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(MountOptions*, mount_options_free_all); const char* mount_options_from_designator(const MountOptions *options, PartitionDesignator designator); int probe_filesystem(const char *node, char **ret_fstype); -int dissect_image(int fd, const char *original_path, const VeritySettings *verity, const MountOptions *mount_options, uint64_t diskseq, uint64_t uevent_seqnum_not_before, usec_t timestamp_not_before, DissectImageFlags flags, DissectedImage **ret); -static inline int dissect_loop_device(const LoopDevice *loop, const char *original_path, const VeritySettings *verity, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret) { +int dissect_image( + int fd, + const char *image_path, + const VeritySettings *verity, + const MountOptions *mount_options, + uint64_t diskseq, + uint64_t uevent_seqnum_not_before, + usec_t timestamp_not_before, + DissectImageFlags flags, + DissectedImage **ret); +static inline int dissect_loop_device(const LoopDevice *loop, const VeritySettings *verity, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret) { assert(loop); - return dissect_image(loop->fd, original_path, verity, mount_options, loop->diskseq, loop->uevent_seqnum_not_before, loop->timestamp_not_before, flags, ret); + return dissect_image(loop->fd, loop->backing_file, verity, mount_options, loop->diskseq, loop->uevent_seqnum_not_before, loop->timestamp_not_before, flags, ret); } int dissect_loop_device_and_warn(const char *name, const LoopDevice *loop, const VeritySettings *verity, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret); diff --git a/src/test/test-loop-block.c b/src/test/test-loop-block.c index 70d4aedb42..ee28ad4235 100644 --- a/src/test/test-loop-block.c +++ b/src/test/test-loop-block.c @@ -39,7 +39,6 @@ static void* thread_func(void *ptr) { _cleanup_(loop_device_unrefp) LoopDevice *loop = NULL; _cleanup_(umount_and_rmdir_and_freep) char *mounted = NULL; _cleanup_(dissected_image_unrefp) DissectedImage *dissected = NULL; - _cleanup_free_ char *path = NULL; if (now(CLOCK_MONOTONIC) >= end) { log_notice("Time's up, exiting thread's loop"); @@ -59,12 +58,7 @@ static void* thread_func(void *ptr) { log_notice("Acquired loop device %s, will mount on %s", loop->node, mounted); - r = fd_get_path(fd, &path); - if (r < 0) - log_error_errno(r, "Failed to get path from fd: %m"); - assert_se(r >= 0); - - r = dissect_loop_device(loop, path, NULL, NULL, DISSECT_IMAGE_READ_ONLY, &dissected); + r = dissect_loop_device(loop, NULL, NULL, DISSECT_IMAGE_READ_ONLY, &dissected); if (r < 0) log_error_errno(r, "Failed dissect loopback device %s: %m", loop->node); assert_se(r >= 0); @@ -228,7 +222,7 @@ static int run(int argc, char *argv[]) { pthread_t threads[arg_n_threads]; sd_id128_t id; - assert_se(dissect_loop_device(loop, p, NULL, NULL, 0, &dissected) >= 0); + assert_se(dissect_loop_device(loop, NULL, NULL, 0, &dissected) >= 0); assert_se(dissected->partitions[PARTITION_ESP].found); assert_se(dissected->partitions[PARTITION_ESP].node); @@ -252,7 +246,7 @@ static int run(int argc, char *argv[]) { assert_se(make_filesystem(dissected->partitions[PARTITION_HOME].node, "ext4", "home", id, true) >= 0); dissected = dissected_image_unref(dissected); - assert_se(dissect_loop_device(loop, p, NULL, NULL, 0, &dissected) >= 0); + assert_se(dissect_loop_device(loop, NULL, NULL, 0, &dissected) >= 0); assert_se(mkdtemp_malloc(NULL, &mounted) >= 0); From 55a065cd30f303578ce5f8a36bd859763c99ba51 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 6 Sep 2022 10:25:56 +0900 Subject: [PATCH 07/12] gpt-auto: use LoopDevice object to manage whole block disk --- src/gpt-auto-generator/gpt-auto-generator.c | 93 ++++----------------- 1 file changed, 16 insertions(+), 77 deletions(-) diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index baa72e77ba..9b04e6e5f7 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -42,71 +42,6 @@ static bool arg_enabled = true; static bool arg_root_enabled = true; static int arg_root_rw = -1; -static int open_parent_block_device(dev_t devnum, int *ret_fd) { - _cleanup_(sd_device_unrefp) sd_device *d = NULL; - const char *name, *devtype, *node; - sd_device *parent; - dev_t pn; - int fd, r; - - assert(ret_fd); - - r = sd_device_new_from_devnum(&d, 'b', devnum); - if (r < 0) - return log_debug_errno(r, "Failed to create device object for block device "DEVNUM_FORMAT_STR": %m", - DEVNUM_FORMAT_VAL(devnum)); - - if (sd_device_get_devname(d, &name) < 0) { - r = sd_device_get_syspath(d, &name); - if (r < 0) { - log_device_debug_errno(d, r, "Device " DEVNUM_FORMAT_STR " does not have a name, ignoring: %m", - DEVNUM_FORMAT_VAL(devnum)); - return 0; - } - } - - r = sd_device_get_parent(d, &parent); - if (r < 0) { - log_device_debug_errno(d, r, "Not a partitioned device, ignoring: %m"); - return 0; - } - - /* Does it have a devtype? */ - r = sd_device_get_devtype(parent, &devtype); - if (r < 0) { - log_device_debug_errno(parent, r, "Parent doesn't have a device type, ignoring: %m"); - return 0; - } - - /* Is this a disk or a partition? We only care for disks... */ - if (!streq(devtype, "disk")) { - log_device_debug(parent, "Parent isn't a raw disk, ignoring."); - return 0; - } - - /* Does it have a device node? */ - r = sd_device_get_devname(parent, &node); - if (r < 0) { - log_device_debug_errno(parent, r, "Parent device does not have device node, ignoring: %m"); - return 0; - } - - log_device_debug(d, "Root device %s.", node); - - r = sd_device_get_devnum(parent, &pn); - if (r < 0) { - log_device_debug_errno(parent, r, "Parent device is not a proper block device, ignoring: %m"); - return 0; - } - - fd = open(node, O_RDONLY|O_CLOEXEC|O_NOCTTY); - if (fd < 0) - return log_error_errno(errno, "Failed to open %s: %m", node); - - *ret_fd = fd; - return 1; -} - static int add_cryptsetup(const char *id, const char *what, bool rw, bool require, char **device) { #if HAVE_LIBCRYPTSETUP _cleanup_free_ char *e = NULL, *n = NULL, *d = NULL; @@ -694,27 +629,31 @@ static int add_root_mount(void) { } static int enumerate_partitions(dev_t devnum) { - _cleanup_close_ int fd = -1; _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL; + _cleanup_(loop_device_unrefp) LoopDevice *loop = NULL; + _cleanup_free_ char *devname = NULL; int r, k; - r = open_parent_block_device(devnum, &fd); - if (r <= 0) - return r; + r = block_get_whole_disk(devnum, &devnum); + if (r < 0) + return log_debug_errno(r, "Failed to get whole block device for " DEVNUM_FORMAT_STR ": %m", + DEVNUM_FORMAT_VAL(devnum)); + + r = devname_from_devnum(S_IFBLK, devnum, &devname); + if (r < 0) + return log_debug_errno(r, "Failed to get device node of " DEVNUM_FORMAT_STR ": %m", + DEVNUM_FORMAT_VAL(devnum)); /* Let's take a LOCK_SH lock on the block device, in case udevd is already running. If we don't take * the lock, udevd might end up issuing BLKRRPART in the middle, and we don't want that, since that * might remove all partitions while we are operating on them. */ - if (flock(fd, LOCK_SH) < 0) - return log_error_errno(errno, "Failed to lock root block device: %m"); + r = loop_device_open(devname, O_RDONLY, LOCK_SH, &loop); + if (r < 0) + return log_debug_errno(r, "Failed to opne %s: %m", devname); - r = dissect_image( - fd, - NULL, + r = dissect_loop_device( + loop, NULL, NULL, - /* diskseq= */ 0, - UINT64_MAX, - USEC_INFINITY, DISSECT_IMAGE_GPT_ONLY| DISSECT_IMAGE_USR_NO_ROOT, &m); From 64dd3a245f0964b8a15923da68b77e932a40536b Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 6 Sep 2022 10:58:26 +0900 Subject: [PATCH 08/12] dissect-image: use loop backing file or device node as name of the image Note, currently, for each call of dissect_loop_device_and_warn(), the specified name is equivalent to the path passed to loop_device_make_by_path(). Hence, this should not change the current behavios. --- src/dissect/dissect.c | 1 - src/nspawn/nspawn.c | 1 - src/shared/dissect-image.c | 7 +++---- src/shared/dissect-image.h | 4 ++-- src/sysext/sysext.c | 1 - 5 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index 22872d803c..b075222ec5 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -946,7 +946,6 @@ static int run(int argc, char *argv[]) { return log_error_errno(r, "Failed to set up loopback device for %s: %m", arg_image); r = dissect_loop_device_and_warn( - arg_image, d, &arg_verity_settings, NULL, diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 50c7f78f1c..7c703acf9c 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -5754,7 +5754,6 @@ static int run(int argc, char *argv[]) { } r = dissect_loop_device_and_warn( - arg_image, loop, &arg_verity_settings, NULL, diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index fce05bcfbd..b5c963656b 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -2806,20 +2806,19 @@ finish: } int dissect_loop_device_and_warn( - const char *name, const LoopDevice *loop, const VeritySettings *verity, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret) { + const char *name; int r; assert(loop); assert(loop->fd >= 0); - if (!name) - name = ASSERT_PTR(loop->node); + name = ASSERT_PTR(loop->backing_file ?: loop->node); r = dissect_loop_device(loop, verity, mount_options, flags, ret); switch (r) { @@ -2974,7 +2973,7 @@ int mount_image_privately_interactively( if (r < 0) return log_error_errno(r, "Failed to set up loopback device for %s: %m", image); - r = dissect_loop_device_and_warn(image, d, &verity, NULL, flags, &dissected_image); + r = dissect_loop_device_and_warn(d, &verity, NULL, flags, &dissected_image); if (r < 0) return r; diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h index c8d2e6de8f..39af311833 100644 --- a/src/shared/dissect-image.h +++ b/src/shared/dissect-image.h @@ -265,9 +265,9 @@ int dissect_image( DissectedImage **ret); static inline int dissect_loop_device(const LoopDevice *loop, const VeritySettings *verity, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret) { assert(loop); - return dissect_image(loop->fd, loop->backing_file, verity, mount_options, loop->diskseq, loop->uevent_seqnum_not_before, loop->timestamp_not_before, flags, ret); + return dissect_image(loop->fd, loop->backing_file ?: loop->node, verity, mount_options, loop->diskseq, loop->uevent_seqnum_not_before, loop->timestamp_not_before, flags, ret); } -int dissect_loop_device_and_warn(const char *name, const LoopDevice *loop, const VeritySettings *verity, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret); +int dissect_loop_device_and_warn(const LoopDevice *loop, const VeritySettings *verity, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret); DissectedImage* dissected_image_unref(DissectedImage *m); DEFINE_TRIVIAL_CLEANUP_FUNC(DissectedImage*, dissected_image_unref); diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c index 93ddc73b46..e45fa61640 100644 --- a/src/sysext/sysext.c +++ b/src/sysext/sysext.c @@ -540,7 +540,6 @@ static int merge_subprocess(Hashmap *images, const char *workspace) { return log_error_errno(r, "Failed to set up loopback device for %s: %m", img->path); r = dissect_loop_device_and_warn( - img->path, d, &verity_settings, NULL, From 7726bd4b03b07f3aee4a4405ab1ffd8928567eda Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 6 Sep 2022 22:50:33 +0900 Subject: [PATCH 09/12] dissect-image: drop currently unused code Currently, dissect_image() is called only through dissect_loop_device(), and image_path is always specified. Let's drop it. --- src/shared/dissect-image.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index b5c963656b..d69a7bebc4 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -305,24 +305,6 @@ int dissect_image( .has_init_system = -1, }; - if (!image_path) { - const char *sysname; - - /* If image_path is not provided and the device is a loopback block device, then use the path - * to the backing file. Note that the backing_file reference resolves symlinks, while for - * sysext images we want the original path. */ - - r = sd_device_get_sysname(d, &sysname); - if (r < 0) - return log_debug_errno(r, "Failed to get device sysname: %m"); - - if (startswith(sysname, "loop")) { - r = sd_device_get_sysattr_value(d, "loop/backing_file", &image_path); - if (r < 0) - log_debug_errno(r, "Failed to lookup image name via loop device backing file sysattr, ignoring: %m"); - } - } - if (image_path) { _cleanup_free_ char *extracted_filename = NULL, *name_stripped = NULL; From bec0c37c9eb8174ca92f98547169c082fd6d2854 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 6 Sep 2022 22:39:31 +0900 Subject: [PATCH 10/12] dissect-image: drop currently unused arguments --- src/shared/dissect-image.c | 3 --- src/shared/dissect-image.h | 5 +---- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index d69a7bebc4..06f2037952 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -196,9 +196,6 @@ int dissect_image( const char *image_path, const VeritySettings *verity, const MountOptions *mount_options, - uint64_t diskseq, - uint64_t uevent_seqnum_not_before, - usec_t timestamp_not_before, DissectImageFlags flags, DissectedImage **ret) { diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h index 39af311833..b9aa3ad63a 100644 --- a/src/shared/dissect-image.h +++ b/src/shared/dissect-image.h @@ -258,14 +258,11 @@ int dissect_image( const char *image_path, const VeritySettings *verity, const MountOptions *mount_options, - uint64_t diskseq, - uint64_t uevent_seqnum_not_before, - usec_t timestamp_not_before, DissectImageFlags flags, DissectedImage **ret); static inline int dissect_loop_device(const LoopDevice *loop, const VeritySettings *verity, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret) { assert(loop); - return dissect_image(loop->fd, loop->backing_file ?: loop->node, verity, mount_options, loop->diskseq, loop->uevent_seqnum_not_before, loop->timestamp_not_before, flags, ret); + return dissect_image(loop->fd, loop->backing_file ?: loop->node, verity, mount_options, flags, ret); } int dissect_loop_device_and_warn(const LoopDevice *loop, const VeritySettings *verity, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret); From 0b214aa0d0f287f14cca91b66ff7f0c253d22172 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 6 Sep 2022 22:43:47 +0900 Subject: [PATCH 11/12] dissect-image: reuse LoopDevice.node in dissect_image() Currently, dissect_image() is only called through dissect_loop_device(), and the LoopDevice object has device name. Hence, it is not necessary to get device name in dissect_image(). --- src/shared/dissect-image.c | 20 +++----------------- src/shared/dissect-image.h | 3 ++- 2 files changed, 5 insertions(+), 18 deletions(-) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 06f2037952..d5425c4de4 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -193,6 +193,7 @@ static int make_partition_devname( int dissect_image( int fd, + const char *devname, const char *image_path, const VeritySettings *verity, const MountOptions *mount_options, @@ -205,17 +206,16 @@ int dissect_image( bool is_gpt, is_mbr, multiple_generic = false, generic_rw = false, /* initialize to appease gcc */ generic_growfs = false; - _cleanup_(sd_device_unrefp) sd_device *d = NULL; _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL; _cleanup_(blkid_free_probep) blkid_probe b = NULL; _cleanup_free_ char *generic_node = NULL; sd_id128_t generic_uuid = SD_ID128_NULL; - const char *pttype = NULL, *devname = NULL; + const char *pttype = NULL; blkid_partlist pl; int r, generic_nr = -1, n_partitions; - struct stat st; assert(fd >= 0); + assert(devname); assert(ret); assert(!verity || verity->designator < 0 || IN_SET(verity->designator, PARTITION_ROOT, PARTITION_USR)); assert(!verity || verity->root_hash || verity->root_hash_size == 0); @@ -259,16 +259,6 @@ int dissect_image( } } - if (fstat(fd, &st) < 0) - return -errno; - - if (!S_ISBLK(st.st_mode)) - return -ENOTBLK; - - r = sd_device_new_from_stat_rdev(&d, &st); - if (r < 0) - return r; - b = blkid_new_probe(); if (!b) return -ENOMEM; @@ -319,10 +309,6 @@ int dissect_image( m->image_name = TAKE_PTR(name_stripped); } - r = sd_device_get_devname(d, &devname); - if (r < 0) - return log_debug_errno(r, "Failed to get device devname: %m"); - if ((!(flags & DISSECT_IMAGE_GPT_ONLY) && (flags & DISSECT_IMAGE_GENERIC_ROOT)) || (flags & DISSECT_IMAGE_NO_PARTITION_TABLE)) { diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h index b9aa3ad63a..fe478bde49 100644 --- a/src/shared/dissect-image.h +++ b/src/shared/dissect-image.h @@ -255,6 +255,7 @@ const char* mount_options_from_designator(const MountOptions *options, Partition int probe_filesystem(const char *node, char **ret_fstype); int dissect_image( int fd, + const char *devname, const char *image_path, const VeritySettings *verity, const MountOptions *mount_options, @@ -262,7 +263,7 @@ int dissect_image( DissectedImage **ret); static inline int dissect_loop_device(const LoopDevice *loop, const VeritySettings *verity, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret) { assert(loop); - return dissect_image(loop->fd, loop->backing_file ?: loop->node, verity, mount_options, flags, ret); + return dissect_image(loop->fd, loop->node, loop->backing_file ?: loop->node, verity, mount_options, flags, ret); } int dissect_loop_device_and_warn(const LoopDevice *loop, const VeritySettings *verity, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret); From 0fb5036f4db918bdc3eec1a09602878f28850a27 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 6 Sep 2022 10:50:19 +0900 Subject: [PATCH 12/12] dissect-image: drop unnecessary duplication of partition device node --- src/shared/dissect-image.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index d5425c4de4..b186c3a728 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -723,7 +723,7 @@ int dissect_image( } if (designator != _PARTITION_DESIGNATOR_INVALID) { - _cleanup_free_ char *t = NULL, *n = NULL, *o = NULL, *l = NULL; + _cleanup_free_ char *t = NULL, *o = NULL, *l = NULL; const char *options = NULL; if (m->partitions[designator].found) { @@ -745,10 +745,6 @@ int dissect_image( return -ENOMEM; } - n = strdup(node); - if (!n) - return -ENOMEM; - if (label) { l = strdup(label); if (!l) @@ -768,7 +764,7 @@ int dissect_image( .rw = rw, .growfs = growfs, .architecture = architecture, - .node = TAKE_PTR(n), + .node = TAKE_PTR(node), .fstype = TAKE_PTR(t), .label = TAKE_PTR(l), .uuid = id, @@ -801,7 +797,7 @@ int dissect_image( break; case 0xEA: { /* Boot Loader Spec extended $BOOT partition */ - _cleanup_free_ char *n = NULL, *o = NULL; + _cleanup_free_ char *o = NULL; sd_id128_t id = SD_ID128_NULL; const char *sid, *options = NULL; @@ -813,10 +809,6 @@ int dissect_image( if (sid) (void) sd_id128_from_string(sid, &id); - n = strdup(node); - if (!n) - return -ENOMEM; - options = mount_options_from_designator(mount_options, PARTITION_XBOOTLDR); if (options) { o = strdup(options); @@ -830,7 +822,7 @@ int dissect_image( .rw = true, .growfs = false, .architecture = _ARCHITECTURE_INVALID, - .node = TAKE_PTR(n), + .node = TAKE_PTR(node), .uuid = id, .mount_options = TAKE_PTR(o), .offset = (uint64_t) start * 512,