]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
gpt-auto-generator: optionally, set up root fs via dissection logic
authorLennart Poettering <lennart@poettering.net>
Fri, 14 Mar 2025 14:44:50 +0000 (15:44 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 3 Apr 2025 09:08:57 +0000 (11:08 +0200)
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.

src/gpt-auto-generator/gpt-auto-generator.c
src/shared/generator.c
src/shared/generator.h

index 167d15318f4ce6c94f60126bcd1e36082ff9a818..28242850ac113bd4b6e65aa096f227eb91551e7f 100644 (file)
@@ -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()) {
index c3e3eeabb21451ac48147836227dc91080414458..0fa7dca86721d02d4ba67e6f2d09c1420aa9d581 100644 (file)
@@ -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;
 }
index fd342a280c7885c254aeb2c88e25dfb6d0b9619b..4ded62d011e349c916e9af0cdfa4bc18e2aa292e 100644 (file)
@@ -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;