diff --git a/TODO b/TODO index b21166f90b..fc348a62e7 100644 --- a/TODO +++ b/TODO @@ -126,10 +126,6 @@ Features: * In DynamicUser= mode: before selecting a UID, use disk quota APIs on relevant disks to see if the UID is already in use. -* add dissect_image_warn() as a wrapper around dissect_image() that prints - friendly log messages for the returned errors, so that we don't have to - duplicate that in nspawn, systemd-dissect and PID 1. - * add "systemctl wait" or so, which does what "systemd-run --wait" does, but for all units. It should be both a way to pin units into memory as well as a wait to retrieve their exit data. diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c index c8fb1c80d7..4dde773b56 100644 --- a/src/dissect/dissect.c +++ b/src/dissect/dissect.c @@ -202,31 +202,9 @@ int main(int argc, char *argv[]) { } } - r = dissect_image(d->fd, arg_root_hash, arg_root_hash_size, arg_flags, &m); - if (r == -ENOPKG) { - log_error_errno(r, "Couldn't identify a suitable partition table or file system in %s.", arg_image); + r = dissect_image_and_warn(d->fd, arg_image, arg_root_hash, arg_root_hash_size, arg_flags, &m); + if (r < 0) goto finish; - } - if (r == -EADDRNOTAVAIL) { - log_error_errno(r, "No root partition for specified root hash found in %s.", arg_image); - goto finish; - } - if (r == -ENOTUNIQ) { - log_error_errno(r, "Multiple suitable root partitions found in image %s.", arg_image); - goto finish; - } - if (r == -ENXIO) { - log_error_errno(r, "No suitable root partition found in image %s.", arg_image); - goto finish; - } - if (r == -EPROTONOSUPPORT) { - log_error_errno(r, "Device %s is loopback block device with partition scanning turned off, please turn it on.", arg_image); - goto finish; - } - if (r < 0) { - log_error_errno(r, "Failed to dissect image: %m"); - goto finish; - } switch (arg_action) { diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 4b941edaea..49325f0d22 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -4054,14 +4054,14 @@ int main(int argc, char *argv[]) { goto finish; } - r = dissect_image( + r = dissect_image_and_warn( loop->fd, + arg_image, arg_root_hash, arg_root_hash_size, DISSECT_IMAGE_REQUIRE_ROOT, &dissected_image); if (r == -ENOPKG) { - log_error_errno(r, "Could not find a suitable file system or partition table in image: %s", arg_image); - + /* dissected_image_and_warn() already printed a brief error message. Extend on that with more details */ log_notice("Note that the disk image needs to\n" " a) either contain only a single MBR partition of type 0x83 that is marked bootable\n" " b) or contain a single GPT partition of type 0FC63DAF-8483-4772-8E79-3D69D8477DE4\n" @@ -4070,22 +4070,8 @@ int main(int argc, char *argv[]) { "in order to be bootable with systemd-nspawn."); goto finish; } - if (r == -EADDRNOTAVAIL) { - log_error_errno(r, "No root partition for specified root hash found."); + if (r < 0) goto finish; - } - if (r == -EOPNOTSUPP) { - log_error_errno(r, "--image= is not supported, compiled without blkid support."); - goto finish; - } - if (r == -EPROTONOSUPPORT) { - log_error_errno(r, "Device is loopback block device with partition scanning turned off, please turn it on."); - goto finish; - } - if (r < 0) { - log_error_errno(r, "Failed to dissect image: %m"); - goto finish; - } if (!arg_root_hash && dissected_image->can_verity) log_notice("Note: image %s contains verity information, but no root hash specified! Proceeding without integrity checking.", arg_image); diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 86114e3dd1..faeaddc66e 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -108,7 +108,12 @@ not_found: #endif } -int dissect_image(int fd, const void *root_hash, size_t root_hash_size, DissectImageFlags flags, DissectedImage **ret) { +int dissect_image( + int fd, + const void *root_hash, + size_t root_hash_size, + DissectImageFlags flags, + DissectedImage **ret) { #if HAVE_BLKID sd_id128_t root_uuid = SD_ID128_NULL, verity_uuid = SD_ID128_NULL; @@ -1379,6 +1384,55 @@ finish: return r; } +int dissect_image_and_warn( + int fd, + const char *name, + const void *root_hash, + size_t root_hash_size, + DissectImageFlags flags, + DissectedImage **ret) { + + _cleanup_free_ char *buffer = NULL; + int r; + + if (!name) { + r = fd_get_path(fd, &buffer); + if (r < 0) + return r; + + name = buffer; + } + + r = dissect_image(fd, root_hash, root_hash_size, flags, ret); + + switch (r) { + + case -EOPNOTSUPP: + return log_error_errno(r, "Dissecting images is not supported, compiled without blkid support."); + + case -ENOPKG: + return log_error_errno(r, "Couldn't identify a suitable partition table or file system in '%s'.", name); + + case -EADDRNOTAVAIL: + return log_error_errno(r, "No root partition for specified root hash found in '%s'.", name); + + case -ENOTUNIQ: + return log_error_errno(r, "Multiple suitable root partitions found in image '%s'.", name); + + case -ENXIO: + return log_error_errno(r, "No suitable root partition found in image '%s'.", name); + + case -EPROTONOSUPPORT: + return log_error_errno(r, "Device '%s' is loopback block device with partition scanning turned off, please turn it on.", name); + + default: + if (r < 0) + return log_error_errno(r, "Failed to dissect image '%s': %m", name); + + return r; + } +} + static const char *const partition_designator_table[] = { [PARTITION_ROOT] = "root", [PARTITION_ROOT_SECONDARY] = "root-secondary", diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h index 10e251ff09..5fd14fc312 100644 --- a/src/shared/dissect-image.h +++ b/src/shared/dissect-image.h @@ -92,6 +92,7 @@ struct DissectedImage { int probe_filesystem(const char *node, char **ret_fstype); int dissect_image(int fd, const void *root_hash, size_t root_hash_size, DissectImageFlags flags, DissectedImage **ret); +int dissect_image_and_warn(int fd, const char *name, const void *root_hash, size_t root_hash_size, DissectImageFlags flags, DissectedImage **ret); DissectedImage* dissected_image_unref(DissectedImage *m); DEFINE_TRIVIAL_CLEANUP_FUNC(DissectedImage*, dissected_image_unref);