summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2021-03-10 17:41:18 +0100
committerLennart Poettering <lennart@poettering.net>2021-03-16 14:57:40 +0100
commit4b5de5dd6c930276628c84755d33187e2dfca5cc (patch)
tree95b821f1bd49dd0b08428b5eae496c75d9541b28
parent2679f407353aa408c5e48f86866a45390c247e45 (diff)
downloadsystemd-4b5de5dd6c930276628c84755d33187e2dfca5cc.tar.gz
dissect-image: split DISSECT_IMAGE_REQUIRE_ROOT in two
Previously, the flag did two things at once: enable support for using generic partitions as root fs if there were only one/allow use of partition-table-less images as root fs. And secondly, insist that there was a rootfs, and fail if not. Let's split these two in two separate options so that they can be used independently of each other. There are cases where one wants to use one without the other (i.e. when inspecting things with systemd-dissect tool it should be OK to do so even if image has no root fs), and it's cleaner anyway.
-rw-r--r--src/core/namespace.c2
-rw-r--r--src/dissect/dissect.c8
-rw-r--r--src/firstboot/firstboot.c6
-rw-r--r--src/journal/journalctl.c5
-rw-r--r--src/nspawn/nspawn.c1
-rw-r--r--src/portable/portable.c11
-rw-r--r--src/shared/discover-image.c5
-rw-r--r--src/shared/dissect-image.c60
-rw-r--r--src/shared/dissect-image.h3
-rw-r--r--src/sysext/sysext.c7
-rw-r--r--src/sysusers/sysusers.c6
-rw-r--r--src/tmpfiles/tmpfiles.c6
12 files changed, 78 insertions, 42 deletions
diff --git a/src/core/namespace.c b/src/core/namespace.c
index c5897c6c94..56385270d8 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -1825,7 +1825,7 @@ int setup_namespace(
mount_flags = MS_SHARED;
if (root_image) {
- dissect_image_flags |= DISSECT_IMAGE_REQUIRE_ROOT;
+ dissect_image_flags |= DISSECT_IMAGE_GENERIC_ROOT | DISSECT_IMAGE_REQUIRE_ROOT;
/* Make the whole image read-only if we can determine that we only access it in a read-only fashion. */
if (root_read_only(read_only_paths,
diff --git a/src/dissect/dissect.c b/src/dissect/dissect.c
index 06808a231e..10ab834f0d 100644
--- a/src/dissect/dissect.c
+++ b/src/dissect/dissect.c
@@ -44,7 +44,13 @@ static const char *arg_image = NULL;
static const char *arg_path = NULL;
static const char *arg_source = NULL;
static const char *arg_target = NULL;
-static DissectImageFlags arg_flags = DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_DISCARD_ON_LOOP|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_FSCK|DISSECT_IMAGE_USR_NO_ROOT;
+static DissectImageFlags arg_flags =
+ DISSECT_IMAGE_GENERIC_ROOT |
+ DISSECT_IMAGE_REQUIRE_ROOT |
+ DISSECT_IMAGE_DISCARD_ON_LOOP |
+ DISSECT_IMAGE_RELAX_VAR_CHECK |
+ DISSECT_IMAGE_FSCK |
+ DISSECT_IMAGE_USR_NO_ROOT;
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/firstboot/firstboot.c b/src/firstboot/firstboot.c
index 8e3028717e..aa7251d1ef 100644
--- a/src/firstboot/firstboot.c
+++ b/src/firstboot/firstboot.c
@@ -1291,7 +1291,11 @@ static int run(int argc, char *argv[]) {
r = mount_image_privately_interactively(
arg_image,
- DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_VALIDATE_OS|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_FSCK,
+ DISSECT_IMAGE_GENERIC_ROOT |
+ DISSECT_IMAGE_REQUIRE_ROOT |
+ DISSECT_IMAGE_VALIDATE_OS |
+ DISSECT_IMAGE_RELAX_VAR_CHECK |
+ DISSECT_IMAGE_FSCK,
&unlink_dir,
&loop_device,
&decrypted_image);
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 6b06320d78..4b3e697855 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -2150,7 +2150,10 @@ int main(int argc, char *argv[]) {
r = mount_image_privately_interactively(
arg_image,
- DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_VALIDATE_OS|DISSECT_IMAGE_RELAX_VAR_CHECK|
+ DISSECT_IMAGE_GENERIC_ROOT |
+ DISSECT_IMAGE_REQUIRE_ROOT |
+ DISSECT_IMAGE_VALIDATE_OS |
+ DISSECT_IMAGE_RELAX_VAR_CHECK |
(arg_action == ACTION_UPDATE_CATALOG ? DISSECT_IMAGE_FSCK : DISSECT_IMAGE_READ_ONLY),
&unlink_dir,
&loop_device,
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 00e2ba2654..f89fa1a573 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -5389,6 +5389,7 @@ static int run(int argc, char *argv[]) {
} else {
DissectImageFlags dissect_image_flags =
+ DISSECT_IMAGE_GENERIC_ROOT |
DISSECT_IMAGE_REQUIRE_ROOT |
DISSECT_IMAGE_RELAX_VAR_CHECK |
DISSECT_IMAGE_USR_NO_ROOT;
diff --git a/src/portable/portable.c b/src/portable/portable.c
index aacc573ef6..5651db6722 100644
--- a/src/portable/portable.c
+++ b/src/portable/portable.c
@@ -380,7 +380,16 @@ static int portable_extract_by_path(
if (r < 0)
return log_debug_errno(r, "Failed to create temporary directory: %m");
- r = dissect_image(d->fd, NULL, NULL, DISSECT_IMAGE_READ_ONLY|DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_DISCARD_ON_LOOP|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_USR_NO_ROOT, &m);
+ r = dissect_image(
+ d->fd,
+ NULL, NULL,
+ DISSECT_IMAGE_READ_ONLY |
+ DISSECT_IMAGE_GENERIC_ROOT |
+ DISSECT_IMAGE_REQUIRE_ROOT |
+ DISSECT_IMAGE_DISCARD_ON_LOOP |
+ DISSECT_IMAGE_RELAX_VAR_CHECK |
+ DISSECT_IMAGE_USR_NO_ROOT,
+ &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);
else if (r == -EADDRNOTAVAIL)
diff --git a/src/shared/discover-image.c b/src/shared/discover-image.c
index a2f2261980..43138e0a6f 100644
--- a/src/shared/discover-image.c
+++ b/src/shared/discover-image.c
@@ -1201,8 +1201,9 @@ int image_read_metadata(Image *i) {
r = dissect_image(
d->fd,
NULL, NULL,
- DISSECT_IMAGE_REQUIRE_ROOT|
- DISSECT_IMAGE_RELAX_VAR_CHECK|
+ DISSECT_IMAGE_GENERIC_ROOT |
+ DISSECT_IMAGE_REQUIRE_ROOT |
+ DISSECT_IMAGE_RELAX_VAR_CHECK |
DISSECT_IMAGE_USR_NO_ROOT, &m);
if (r < 0)
return r;
diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c
index 843fd41bb9..bdd3570348 100644
--- a/src/shared/dissect-image.c
+++ b/src/shared/dissect-image.c
@@ -630,7 +630,7 @@ int dissect_image(
}
if ((!(flags & DISSECT_IMAGE_GPT_ONLY) &&
- (flags & DISSECT_IMAGE_REQUIRE_ROOT)) ||
+ (flags & DISSECT_IMAGE_GENERIC_ROOT)) ||
(flags & DISSECT_IMAGE_NO_PARTITION_TABLE)) {
const char *usage = NULL;
@@ -1178,45 +1178,47 @@ int dissect_image(
} else if (m->partitions[PARTITION_USR_SECONDARY_VERITY].found)
return -EADDRNOTAVAIL; /* as above */
- else if (flags & DISSECT_IMAGE_REQUIRE_ROOT) {
- _cleanup_free_ char *o = NULL;
- const char *options = NULL;
+ else if ((flags & DISSECT_IMAGE_GENERIC_ROOT) &&
+ (!verity || !verity->root_hash)) {
/* OK, we found nothing usable, then check if there's a single generic one distro, and use
- * that. */
-
- /* If the root hash was set, then we won't fall back to a generic node, because the root hash
- * decides. */
- if (verity && verity->root_hash)
- return -EADDRNOTAVAIL;
-
- /* If we didn't find a generic node, then we can't fix this up either */
- if (!generic_node)
- return -ENXIO;
+ * that. If the root hash was set however, then we won't fall back to a generic node, because
+ * the root hash decides. */
/* If we didn't find a properly marked root partition, but we did find a single suitable
* generic Linux partition, then use this as root partition, if the caller asked for it. */
if (multiple_generic)
return -ENOTUNIQ;
- options = mount_options_from_designator(mount_options, PARTITION_ROOT);
- if (options) {
- o = strdup(options);
- if (!o)
- return -ENOMEM;
- }
+ /* If we didn't find a generic node, then we can't fix this up either */
+ if (generic_node) {
+ _cleanup_free_ char *o = NULL;
+ const char *options;
+
+ options = mount_options_from_designator(mount_options, PARTITION_ROOT);
+ if (options) {
+ o = strdup(options);
+ if (!o)
+ return -ENOMEM;
+ }
- m->partitions[PARTITION_ROOT] = (DissectedPartition) {
- .found = true,
- .rw = generic_rw,
- .partno = generic_nr,
- .architecture = _ARCHITECTURE_INVALID,
- .node = TAKE_PTR(generic_node),
- .uuid = generic_uuid,
- .mount_options = TAKE_PTR(o),
- };
+ m->partitions[PARTITION_ROOT] = (DissectedPartition) {
+ .found = true,
+ .rw = generic_rw,
+ .partno = generic_nr,
+ .architecture = _ARCHITECTURE_INVALID,
+ .node = TAKE_PTR(generic_node),
+ .uuid = generic_uuid,
+ .mount_options = TAKE_PTR(o),
+ };
+ }
}
+ /* Check if we have a root fs if we are told to do check. /usr alone is fine too, but only if appropriate flag for that is set too */
+ if (FLAGS_SET(flags, DISSECT_IMAGE_REQUIRE_ROOT) &&
+ !(m->partitions[PARTITION_ROOT].found || (m->partitions[PARTITION_USR].found && FLAGS_SET(flags, DISSECT_IMAGE_USR_NO_ROOT))))
+ return -ENXIO;
+
/* Refuse if we found a verity partition for /usr but no matching file system partition */
if (!m->partitions[PARTITION_USR].found && m->partitions[PARTITION_USR_VERITY].found)
return -EADDRNOTAVAIL;
diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h
index 0e01c5e403..f07955230b 100644
--- a/src/shared/dissect-image.h
+++ b/src/shared/dissect-image.h
@@ -95,7 +95,7 @@ typedef enum DissectImageFlags {
DISSECT_IMAGE_DISCARD |
DISSECT_IMAGE_DISCARD_ON_CRYPTO,
DISSECT_IMAGE_GPT_ONLY = 1 << 4, /* Only recognize images with GPT partition tables */
- DISSECT_IMAGE_REQUIRE_ROOT = 1 << 5, /* Don't accept disks without root partition (and if no partition table or only single generic partition, assume it's root) */
+ DISSECT_IMAGE_GENERIC_ROOT = 1 << 5, /* If no partition table or only single generic partition, assume it's the root fs */
DISSECT_IMAGE_MOUNT_ROOT_ONLY = 1 << 6, /* Mount only the root and /usr partitions */
DISSECT_IMAGE_MOUNT_NON_ROOT_ONLY = 1 << 7, /* Mount only the non-root and non-/usr partitions */
DISSECT_IMAGE_VALIDATE_OS = 1 << 8, /* Refuse mounting images that aren't identifiable as OS images */
@@ -106,6 +106,7 @@ typedef enum DissectImageFlags {
DISSECT_IMAGE_VERITY_SHARE = 1 << 13, /* When activating a verity device, reuse existing one if already open */
DISSECT_IMAGE_MKDIR = 1 << 14, /* Make top-level directory to mount right before mounting, if missing */
DISSECT_IMAGE_USR_NO_ROOT = 1 << 15, /* If no root fs is in the image, but /usr is, then allow this (so that we can mount the rootfs as tmpfs or so */
+ DISSECT_IMAGE_REQUIRE_ROOT = 1 << 16, /* Don't accept disks without root partition (or at least /usr partition if DISSECT_IMAGE_USR_NO_ROOT is set) */
} DissectImageFlags;
struct DissectedImage {
diff --git a/src/sysext/sysext.c b/src/sysext/sysext.c
index 2ebb96c397..49ec23d934 100644
--- a/src/sysext/sysext.c
+++ b/src/sysext/sysext.c
@@ -510,9 +510,10 @@ static int merge_subprocess(Hashmap *images, const char *workspace) {
_cleanup_(decrypted_image_unrefp) DecryptedImage *di = NULL;
_cleanup_(verity_settings_done) VeritySettings verity_settings = VERITY_SETTINGS_DEFAULT;
DissectImageFlags flags =
- DISSECT_IMAGE_READ_ONLY|
- DISSECT_IMAGE_REQUIRE_ROOT|
- DISSECT_IMAGE_MOUNT_ROOT_ONLY|
+ DISSECT_IMAGE_READ_ONLY |
+ DISSECT_IMAGE_GENERIC_ROOT |
+ DISSECT_IMAGE_REQUIRE_ROOT |
+ DISSECT_IMAGE_MOUNT_ROOT_ONLY |
DISSECT_IMAGE_USR_NO_ROOT;
r = verity_settings_load(&verity_settings, img->path, NULL, NULL);
diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c
index b098eb27cd..27573b74e6 100644
--- a/src/sysusers/sysusers.c
+++ b/src/sysusers/sysusers.c
@@ -1946,7 +1946,11 @@ static int run(int argc, char *argv[]) {
r = mount_image_privately_interactively(
arg_image,
- DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_VALIDATE_OS|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_FSCK,
+ DISSECT_IMAGE_GENERIC_ROOT |
+ DISSECT_IMAGE_REQUIRE_ROOT |
+ DISSECT_IMAGE_VALIDATE_OS |
+ DISSECT_IMAGE_RELAX_VAR_CHECK |
+ DISSECT_IMAGE_FSCK,
&unlink_dir,
&loop_device,
&decrypted_image);
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index 846e456551..f11b4eed7c 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -3431,7 +3431,11 @@ static int run(int argc, char *argv[]) {
r = mount_image_privately_interactively(
arg_image,
- DISSECT_IMAGE_REQUIRE_ROOT|DISSECT_IMAGE_VALIDATE_OS|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_FSCK,
+ DISSECT_IMAGE_GENERIC_ROOT |
+ DISSECT_IMAGE_REQUIRE_ROOT |
+ DISSECT_IMAGE_VALIDATE_OS |
+ DISSECT_IMAGE_RELAX_VAR_CHECK |
+ DISSECT_IMAGE_FSCK,
&unlink_dir,
&loop_device,
&decrypted_image);