]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
bootspec: honour profile number when sorting properly 41367/head
authorLennart Poettering <lennart@amutable.com>
Thu, 26 Mar 2026 22:44:59 +0000 (23:44 +0100)
committerLennart Poettering <lennart@amutable.com>
Fri, 27 Mar 2026 09:44:14 +0000 (10:44 +0100)
This corrects sorting of menu entries regarding profile numbers:

1. If the profile number is unset, let's treat this identical to profile
   0, when ordering stuff, because an item with no profile is
   conceptually the same as an item with only a profile 0.

2. Let's take the profile number into account also if sort keys are
   used. This was makes profiles work sensibly in type 1 entries, via
   the recently added "profile" stanza.

Follow-up for: 5fb90fa3194d998a971b21e4a643670ae5903f85

src/boot/boot.c
src/shared/bootspec.c

index 4a5102f45c7e4895c2242e5c836174d270791250..904f9bf589457cc871dcf6a396a6969263c5a36d 100644 (file)
@@ -1745,6 +1745,12 @@ static void config_load_smbios_entries(
         }
 }
 
+static unsigned boot_entry_profile(const BootEntry *a) {
+        assert(a);
+
+        return a->profile == UINT_MAX ? 0 : a->profile;
+}
+
 static int boot_entry_compare(const BootEntry *a, const BootEntry *b) {
         int r;
 
@@ -1778,6 +1784,10 @@ static int boot_entry_compare(const BootEntry *a, const BootEntry *b) {
                 r = -strverscmp_improved(a->version, b->version);
                 if (r != 0)
                         return r;
+
+                r = CMP(boot_entry_profile(a), boot_entry_profile(b));
+                if (r != 0)
+                        return r;
         }
 
         /* Now order by ID. The version is likely part of the ID, thus note that this will generatelly put
@@ -1792,7 +1802,7 @@ static int boot_entry_compare(const BootEntry *a, const BootEntry *b) {
                 /* Note: the strverscmp_improved() call above checked for us that we are looking at the very
                  * same id, hence at this point we only need to compare profile numbers, since we know they
                  * belong to the same UKI. */
-                r = CMP(a->profile, b->profile);
+                r = CMP(boot_entry_profile(a), boot_entry_profile(b));
                 if (r != 0)
                         return r;
         }
index 2a898067f81ac40136235cb2975250974f8cfded..36eb2e7086e81f429411d32099d1440f4bcacbe9 100644 (file)
@@ -555,6 +555,12 @@ static int boot_loader_read_conf_path(BootConfig *config, const char *root, cons
         return boot_loader_read_conf(config, f, full);
 }
 
+static unsigned boot_entry_profile(const BootEntry *a) {
+        assert(a);
+
+        return a->profile == UINT_MAX ? 0 : a->profile;
+}
+
 static int boot_entry_compare(const BootEntry *a, const BootEntry *b) {
         int r;
 
@@ -583,6 +589,10 @@ static int boot_entry_compare(const BootEntry *a, const BootEntry *b) {
                 r = -strverscmp_improved(a->version, b->version);
                 if (r != 0)
                         return r;
+
+                r = CMP(boot_entry_profile(a), boot_entry_profile(b));
+                if (r != 0)
+                        return r;
         }
 
         r = -strverscmp_improved(a->id_without_profile ?: a->id, b->id_without_profile ?: b->id);
@@ -592,7 +602,7 @@ static int boot_entry_compare(const BootEntry *a, const BootEntry *b) {
         if (a->id_without_profile && b->id_without_profile) {
                 /* The strverscmp_improved() call above already established that we are talking about the
                  * same image here, hence order by profile, if there is one */
-                r = CMP(a->profile, b->profile);
+                r = CMP(boot_entry_profile(a), boot_entry_profile(b));
                 if (r != 0)
                         return r;
         }