diff --git a/src/core/namespace.c b/src/core/namespace.c index c0d0cc9715f..4e9292f2de4 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -2051,7 +2051,9 @@ int setup_namespace( DISSECT_IMAGE_RELAX_VAR_CHECK | DISSECT_IMAGE_FSCK | DISSECT_IMAGE_USR_NO_ROOT | - DISSECT_IMAGE_GROWFS; + DISSECT_IMAGE_GROWFS | + DISSECT_IMAGE_ADD_PARTITION_DEVICES | + DISSECT_IMAGE_PIN_PARTITION_DEVICES; size_t n_mounts; int r; diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index 4ff86ba1ded..3cf250e8ec3 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -67,7 +67,9 @@ static DissectImageFlags arg_flags = DISSECT_IMAGE_RELAX_VAR_CHECK | DISSECT_IMAGE_FSCK | DISSECT_IMAGE_USR_NO_ROOT | - DISSECT_IMAGE_GROWFS; + DISSECT_IMAGE_GROWFS | + DISSECT_IMAGE_PIN_PARTITION_DEVICES | + DISSECT_IMAGE_ADD_PARTITION_DEVICES; static VeritySettings arg_verity_settings = VERITY_SETTINGS_DEFAULT; static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF; static PagerFlags arg_pager_flags = 0; diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index f939b2e8c24..23a215231ca 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -665,6 +665,11 @@ static int enumerate_partitions(dev_t devnum) { NULL, NULL, DISSECT_IMAGE_GPT_ONLY| DISSECT_IMAGE_USR_NO_ROOT, + /* NB! Unlike most other places where we dissect block devices we do not use + * DISSECT_IMAGE_ADD_PARTITION_DEVICES here: we want that the kernel finds the + * devices, and udev probes them before we mount them via .mount units much later + * on. And thus we also don't set DISSECT_IMAGE_PIN_PARTITION_DEVICES here, because + * we don't actually mount anything immediately. */ &m); if (r == -ENOPKG) { log_debug_errno(r, "No suitable partition table found, ignoring."); diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index d7b636209eb..f86222d1cc6 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -5656,7 +5656,9 @@ static int run(int argc, char *argv[]) { DISSECT_IMAGE_GENERIC_ROOT | DISSECT_IMAGE_REQUIRE_ROOT | DISSECT_IMAGE_RELAX_VAR_CHECK | - DISSECT_IMAGE_USR_NO_ROOT; + DISSECT_IMAGE_USR_NO_ROOT | + DISSECT_IMAGE_ADD_PARTITION_DEVICES | + DISSECT_IMAGE_PIN_PARTITION_DEVICES; assert(arg_image); assert(!arg_template); diff --git a/src/portable/portable.c b/src/portable/portable.c index 76af743771e..0909e14aab6 100644 --- a/src/portable/portable.c +++ b/src/portable/portable.c @@ -375,7 +375,9 @@ static int portable_extract_by_path( DISSECT_IMAGE_REQUIRE_ROOT | DISSECT_IMAGE_DISCARD_ON_LOOP | DISSECT_IMAGE_RELAX_VAR_CHECK | - DISSECT_IMAGE_USR_NO_ROOT, + DISSECT_IMAGE_USR_NO_ROOT | + DISSECT_IMAGE_ADD_PARTITION_DEVICES | + DISSECT_IMAGE_PIN_PARTITION_DEVICES, &m); if (r == -ENOPKG) sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Couldn't identify a suitable partition table or file system in '%s'.", path); diff --git a/src/shared/discover-image.c b/src/shared/discover-image.c index 073e5e84338..9a7a1c990a7 100644 --- a/src/shared/discover-image.c +++ b/src/shared/discover-image.c @@ -1201,7 +1201,9 @@ int image_read_metadata(Image *i) { DISSECT_IMAGE_REQUIRE_ROOT | DISSECT_IMAGE_RELAX_VAR_CHECK | DISSECT_IMAGE_READ_ONLY | - DISSECT_IMAGE_USR_NO_ROOT, + DISSECT_IMAGE_USR_NO_ROOT | + DISSECT_IMAGE_ADD_PARTITION_DEVICES | + DISSECT_IMAGE_PIN_PARTITION_DEVICES, &m); if (r < 0) return r; diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 4872fe4d6bd..9ce9775049d 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -458,7 +458,7 @@ static int dissect_image( _cleanup_close_ int mount_node_fd = -1; sd_id128_t uuid = SD_ID128_NULL; - if (FLAGS_SET(flags, DISSECT_IMAGE_OPEN_PARTITION_DEVICES)) { + if (FLAGS_SET(flags, DISSECT_IMAGE_PIN_PARTITION_DEVICES)) { mount_node_fd = open_partition(devname, /* is_partition = */ false, m->loop); if (mount_node_fd < 0) return mount_node_fd; @@ -539,7 +539,7 @@ static int dissect_image( if (verity && verity->data_path) return -EBADR; - if (FLAGS_SET(flags, DISSECT_IMAGE_MANAGE_PARTITION_DEVICES)) { + if (FLAGS_SET(flags, DISSECT_IMAGE_ADD_PARTITION_DEVICES)) { /* Safety check: refuse block devices that carry a partition table but for which the kernel doesn't * do partition scanning. */ r = blockdev_partscan_enabled(fd); @@ -615,7 +615,7 @@ static int dissect_image( * Kernel returns EBUSY if there's already a partition by that number or an overlapping * partition already existent. */ - if (FLAGS_SET(flags, DISSECT_IMAGE_MANAGE_PARTITION_DEVICES)) { + if (FLAGS_SET(flags, DISSECT_IMAGE_ADD_PARTITION_DEVICES)) { r = block_device_add_partition(fd, node, nr, (uint64_t) start * 512, (uint64_t) size * 512); if (r < 0) { if (r != -EBUSY) @@ -870,7 +870,7 @@ static int dissect_image( dissected_partition_done(m->partitions + type.designator); } - if (FLAGS_SET(flags, DISSECT_IMAGE_OPEN_PARTITION_DEVICES) && + if (FLAGS_SET(flags, DISSECT_IMAGE_PIN_PARTITION_DEVICES) && type.designator != PARTITION_SWAP) { mount_node_fd = open_partition(node, /* is_partition = */ true, m->loop); if (mount_node_fd < 0) @@ -945,7 +945,7 @@ static int dissect_image( if (m->partitions[PARTITION_XBOOTLDR].found) continue; - if (FLAGS_SET(flags, DISSECT_IMAGE_OPEN_PARTITION_DEVICES)) { + if (FLAGS_SET(flags, DISSECT_IMAGE_PIN_PARTITION_DEVICES)) { mount_node_fd = open_partition(node, /* is_partition = */ true, m->loop); if (mount_node_fd < 0) return mount_node_fd; @@ -1025,7 +1025,7 @@ static int dissect_image( _cleanup_free_ char *o = NULL; const char *options; - if (FLAGS_SET(flags, DISSECT_IMAGE_OPEN_PARTITION_DEVICES)) { + if (FLAGS_SET(flags, DISSECT_IMAGE_PIN_PARTITION_DEVICES)) { mount_node_fd = open_partition(generic_node, /* is_partition = */ true, m->loop); if (mount_node_fd < 0) return mount_node_fd; @@ -1130,7 +1130,6 @@ int dissect_image_file( int r; assert(path); - assert((flags & DISSECT_IMAGE_BLOCK_DEVICE) == 0); assert(ret); fd = open(path, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); @@ -2945,7 +2944,7 @@ int dissect_loop_device( m->loop = loop_device_ref(loop); - r = dissect_image(m, loop->fd, loop->node, verity, mount_options, flags | DISSECT_IMAGE_BLOCK_DEVICE); + r = dissect_image(m, loop->fd, loop->node, verity, mount_options, flags); if (r < 0) return r; @@ -3108,6 +3107,10 @@ int mount_image_privately_interactively( assert(ret_directory); assert(ret_loop_device); + /* We intend to mount this right-away, hence add the partitions if needed and pin them*/ + flags |= DISSECT_IMAGE_ADD_PARTITION_DEVICES | + DISSECT_IMAGE_PIN_PARTITION_DEVICES; + r = verity_settings_load(&verity, image, NULL, NULL); if (r < 0) return log_error_errno(r, "Failed to load root hash data: %m"); @@ -3202,7 +3205,9 @@ int verity_dissect_and_mount( return log_debug_errno(r, "Failed to load root hash: %m"); dissect_image_flags = (verity.data_path ? DISSECT_IMAGE_NO_PARTITION_TABLE : 0) | - (relax_extension_release_check ? DISSECT_IMAGE_RELAX_SYSEXT_CHECK : 0); + (relax_extension_release_check ? DISSECT_IMAGE_RELAX_SYSEXT_CHECK : 0) | + DISSECT_IMAGE_ADD_PARTITION_DEVICES | + DISSECT_IMAGE_PIN_PARTITION_DEVICES; /* Note that we don't use loop_device_make here, as the FD is most likely O_PATH which would not be * accepted by LOOP_CONFIGURE, so just let loop_device_make_by_path reopen it as a regular FD. */ diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h index 1a398010b53..52d8a2e5696 100644 --- a/src/shared/dissect-image.h +++ b/src/shared/dissect-image.h @@ -74,10 +74,8 @@ typedef enum DissectImageFlags { DISSECT_IMAGE_MOUNT_READ_ONLY, DISSECT_IMAGE_GROWFS = 1 << 18, /* Grow file systems in partitions marked for that to the size of the partitions after mount */ DISSECT_IMAGE_MOUNT_IDMAPPED = 1 << 19, /* Mount mounts with kernel 5.12-style userns ID mapping, if file system type doesn't support uid=/gid= */ - DISSECT_IMAGE_MANAGE_PARTITION_DEVICES = 1 << 20, /* Manage partition devices, e.g. probe each partition in more detail */ - DISSECT_IMAGE_OPEN_PARTITION_DEVICES = 1 << 21, /* Open dissected partitions and decrypted partitions */ - DISSECT_IMAGE_BLOCK_DEVICE = DISSECT_IMAGE_MANAGE_PARTITION_DEVICES | - DISSECT_IMAGE_OPEN_PARTITION_DEVICES, + DISSECT_IMAGE_ADD_PARTITION_DEVICES = 1 << 20, /* Create partition devices via BLKPG_ADD_PARTITION */ + DISSECT_IMAGE_PIN_PARTITION_DEVICES = 1 << 21, /* Open dissected partitions and decrypted partitions and pin them by fd */ DISSECT_IMAGE_RELAX_SYSEXT_CHECK = 1 << 22, /* Don't insist that the extension-release file name matches the image name */ } DissectImageFlags; diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c index 9a7ef8eb290..b9147fbd78d 100644 --- a/src/sysext/sysext.c +++ b/src/sysext/sysext.c @@ -522,7 +522,9 @@ static int merge_subprocess(Hashmap *images, const char *workspace) { DISSECT_IMAGE_GENERIC_ROOT | DISSECT_IMAGE_REQUIRE_ROOT | DISSECT_IMAGE_MOUNT_ROOT_ONLY | - DISSECT_IMAGE_USR_NO_ROOT; + DISSECT_IMAGE_USR_NO_ROOT | + DISSECT_IMAGE_ADD_PARTITION_DEVICES | + DISSECT_IMAGE_PIN_PARTITION_DEVICES; r = verity_settings_load(&verity_settings, img->path, NULL, NULL); if (r < 0) diff --git a/src/test/test-loop-block.c b/src/test/test-loop-block.c index e2b97dd56ff..af2a9683a43 100644 --- a/src/test/test-loop-block.c +++ b/src/test/test-loop-block.c @@ -71,7 +71,7 @@ static void* thread_func(void *ptr) { log_notice("Acquired loop device %s, will mount on %s", loop->node, mounted); - r = dissect_loop_device(loop, NULL, NULL, DISSECT_IMAGE_READ_ONLY, &dissected); + r = dissect_loop_device(loop, NULL, NULL, DISSECT_IMAGE_READ_ONLY|DISSECT_IMAGE_ADD_PARTITION_DEVICES|DISSECT_IMAGE_PIN_PARTITION_DEVICES, &dissected); if (r < 0) log_error_errno(r, "Failed dissect loopback device %s: %m", loop->node); assert_se(r >= 0); @@ -220,7 +220,7 @@ static int run(int argc, char *argv[]) { assert_se(loop_device_make(fd, O_RDWR, 0, UINT64_MAX, 0, LO_FLAGS_PARTSCAN, LOCK_EX, &loop) >= 0); #if HAVE_BLKID - assert_se(dissect_loop_device(loop, NULL, NULL, 0, &dissected) >= 0); + assert_se(dissect_loop_device(loop, NULL, NULL, DISSECT_IMAGE_ADD_PARTITION_DEVICES|DISSECT_IMAGE_PIN_PARTITION_DEVICES, &dissected) >= 0); verify_dissected_image(dissected); FOREACH_STRING(fs, "vfat", "ext4") { @@ -246,7 +246,7 @@ static int run(int argc, char *argv[]) { assert_se(make_filesystem(dissected->partitions[PARTITION_HOME].node, "ext4", "home", NULL, id, true) >= 0); dissected = dissected_image_unref(dissected); - assert_se(dissect_loop_device(loop, NULL, NULL, 0, &dissected) >= 0); + assert_se(dissect_loop_device(loop, NULL, NULL, DISSECT_IMAGE_ADD_PARTITION_DEVICES|DISSECT_IMAGE_PIN_PARTITION_DEVICES, &dissected) >= 0); verify_dissected_image(dissected); assert_se(mkdtemp_malloc(NULL, &mounted) >= 0);