From: Lennart Poettering Date: Fri, 14 Mar 2025 14:44:50 +0000 (+0100) Subject: gpt-auto-generator: optionally, set up root fs via dissection logic X-Git-Tag: v258-rc1~923^2~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=198f7badaa884714439fbf96074acff404dc5bf2;p=thirdparty%2Fsystemd.git gpt-auto-generator: optionally, set up root fs via dissection logic This introduces root=dissect, which is a lot like root=gpt-auto, but uses the image dissection logic to find the root partition. It's also based on the GPT efi var telling us about the root disk, but instead of just picking some suitable root disk manually it uses the dissection logic. This is a big step forward, since it means we can actually make use of the image policy logic for the root fs too. --- diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 167d15318f4..28242850ac1 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -656,19 +656,27 @@ static int add_partition_root_flags(DissectedPartition *p) { static int add_root_cryptsetup(void) { #if HAVE_LIBCRYPTSETUP - /* If a device /dev/gpt-auto-root-luks appears, then make it pull in systemd-cryptsetup-root.service, which - * sets it up, and causes /dev/gpt-auto-root to appear which is all we are looking for. */ + assert(arg_auto_root != GPT_AUTO_ROOT_OFF); - const char *bdev = "/dev/gpt-auto-root-luks"; + /* If a device /dev/gpt-auto-root-luks or /dev/disk/by-designator/root-luks appears, then make it + * pull in systemd-cryptsetup@root.service, which sets it up, and causes /dev/gpt-auto-root or + * /dev/disk/by-designator/root to appear which is all we are looking for. */ - if (arg_auto_root == GPT_AUTO_ROOT_FORCE) { + const char *bdev = + IN_SET(arg_auto_root, GPT_AUTO_ROOT_DISSECT, GPT_AUTO_ROOT_DISSECT_FORCE) ? + "/dev/disk/by-designator/root-luks" : "/dev/gpt-auto-root-luks"; + + if (IN_SET(arg_auto_root, GPT_AUTO_ROOT_FORCE, GPT_AUTO_ROOT_DISSECT_FORCE)) { /* Similar logic as in add_root_mount(), see below */ FactoryResetMode f = factory_reset_mode(); if (f < 0) log_warning_errno(f, "Failed to determine whether we are in factory reset mode, assuming not: %m"); if (IN_SET(f, FACTORY_RESET_ON, FACTORY_RESET_COMPLETE)) - bdev = "/dev/gpt-auto-root-luks-ignore-factory-reset"; + bdev = + IN_SET(arg_auto_root, GPT_AUTO_ROOT_DISSECT, GPT_AUTO_ROOT_DISSECT_FORCE) ? + "/dev/disk/by-designator/root-luks-ignore-factory-reset" : + "/dev/gpt-auto-root-luks-ignore-factory-reset"; } return add_cryptsetup("root", bdev, arg_root_options, MOUNT_RW|MOUNT_MEASURE, /* require= */ false, NULL); @@ -715,14 +723,19 @@ static int add_root_mount(void) { * factory reset the latter is the link to use, otherwise the former (so that we don't accidentally * mount a root partition too early that is about to be wiped and replaced by another one). */ - const char *bdev = "/dev/gpt-auto-root"; - if (arg_auto_root == GPT_AUTO_ROOT_FORCE) { + const char *bdev = + IN_SET(arg_auto_root, GPT_AUTO_ROOT_DISSECT, GPT_AUTO_ROOT_DISSECT_FORCE) ? + "/dev/disk/by-designator/root" : "/dev/gpt-auto-root"; + if (IN_SET(arg_auto_root, GPT_AUTO_ROOT_FORCE, GPT_AUTO_ROOT_DISSECT_FORCE)) { FactoryResetMode f = factory_reset_mode(); if (f < 0) log_warning_errno(f, "Failed to determine whether we are in factory reset mode, assuming not: %m"); if (IN_SET(f, FACTORY_RESET_ON, FACTORY_RESET_COMPLETE)) - bdev = "/dev/gpt-auto-root-ignore-factory-reset"; + bdev = + IN_SET(arg_auto_root, GPT_AUTO_ROOT_DISSECT, GPT_AUTO_ROOT_DISSECT_FORCE) ? + "/dev/disk/by-designator/root-ignore-factory-reset" : + "/dev/gpt-auto-root-ignore-factory-reset"; } if (in_initrd()) { diff --git a/src/shared/generator.c b/src/shared/generator.c index c3e3eeabb21..0fa7dca8672 100644 --- a/src/shared/generator.c +++ b/src/shared/generator.c @@ -1089,7 +1089,10 @@ bool generator_soft_rebooted(void) { GptAutoRoot parse_gpt_auto_root(const char *value) { assert(value); - /* Parses the 'gpt-auto'/'gpt-auto-root' parameters to root= */ + /* Parses the 'gpt-auto'/'gpt-auto-root'/'dissect'/'dissect-force' parameters to root= + * + * note that we are not using a regular string table here, because the mode names don't fully match + * the parameter names. And root= being something else is not an error. */ if (streq(value, "gpt-auto")) { log_debug("Enabling root partition auto-detection (respecting factory reset mode), root= is explicitly set to 'gpt-auto'."); @@ -1101,6 +1104,16 @@ GptAutoRoot parse_gpt_auto_root(const char *value) { return GPT_AUTO_ROOT_FORCE; } - log_debug("Disabling root partition auto-detection, root= is neither unset, nor set to 'gpt-auto' or 'gpt-auto-force'."); + if (streq(value, "dissect")) { + log_debug("Enabling root partition auto-detection via full image dissection (respecting factory reset mode), root= is explicitly set to 'dissect'."); + return GPT_AUTO_ROOT_DISSECT; + } + + if (streq(value, "dissect-force")) { + log_debug("Enabling root partition auto-detection via full image dissection (ignoring factory reset mode), root= is explicitly set to 'dissect-force'."); + return GPT_AUTO_ROOT_DISSECT_FORCE; + } + + log_debug("Disabling root partition auto-detection, root= is neither unset, nor set to 'gpt-auto', 'gpt-auto-force', 'dissect' or 'dissect-force'."); return GPT_AUTO_ROOT_OFF; } diff --git a/src/shared/generator.h b/src/shared/generator.h index fd342a280c7..4ded62d011e 100644 --- a/src/shared/generator.h +++ b/src/shared/generator.h @@ -122,9 +122,11 @@ bool generator_soft_rebooted(void); exit_failure_if_negative) typedef enum GptAutoRoot { - GPT_AUTO_ROOT_OFF = 0, /* root= set to something else */ - GPT_AUTO_ROOT_ON, /* root= set explicitly to "gpt-auto" */ - GPT_AUTO_ROOT_FORCE, /* root= set explicitly to "gpt-auto-force" → ignores factory reset mode */ + GPT_AUTO_ROOT_OFF = 0, /* root= set to something else */ + GPT_AUTO_ROOT_ON, /* root= set explicitly to "gpt-auto" */ + GPT_AUTO_ROOT_FORCE, /* root= set explicitly to "gpt-auto-force" → ignores factory reset mode */ + GPT_AUTO_ROOT_DISSECT, /* root= set to "dissect" */ + GPT_AUTO_ROOT_DISSECT_FORCE, /* root= set to "dissect-force" → ignores factory reset mode */ _GPT_AUTO_ROOT_MAX, _GPT_AUTO_ROOT_INVALID = -EINVAL, } GptAutoRoot;