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;
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;
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.");
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);
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);
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;
_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;
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);
* 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)
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)
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;
_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;
int r;
assert(path);
- assert((flags & DISSECT_IMAGE_BLOCK_DEVICE) == 0);
assert(ret);
fd = open(path, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
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;
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");
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. */
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;
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)
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);
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") {
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);