udev: when booting without root= specification, and searching a root partition actually do the version comparison magic

Since 08fe0a5386 when dissecting a disk
image we'll automatically pick the "newest" root fs if multiple exist,
by comparing GPT partition labels. This works in systemd-nspawn,
systemd-dissect, systemd-tmpfiles --image, … and so on. It also works
already in systemd-gpt-auto-generator. However, there was one missing
place: in the logic that automatically finds a root fs in case no root=
was specified on the kernel logic at all. This logic doesn't use the
dissection logic, but a much simpler one.

Let's fill the gap, and implement it there too.
This commit is contained in:
Lennart Poettering 2021-07-02 15:35:39 +02:00
parent 6d8be376e1
commit da636b67a6

View file

@ -114,7 +114,7 @@ static int find_gpt_root(sd_device *dev, blkid_probe pr, bool test) {
#if defined(GPT_ROOT_NATIVE) && ENABLE_EFI
_cleanup_free_ char *root_id = NULL;
_cleanup_free_ char *root_id = NULL, *root_label = NULL;
bool found_esp = false;
blkid_partlist pl;
int i, nvals, r;
@ -133,7 +133,7 @@ static int find_gpt_root(sd_device *dev, blkid_probe pr, bool test) {
nvals = blkid_partlist_numof_partitions(pl);
for (i = 0; i < nvals; i++) {
blkid_partition pp;
const char *stype, *sid;
const char *stype, *sid, *label;
sd_id128_t type;
pp = blkid_partlist_get_partition(pl, i);
@ -144,6 +144,8 @@ static int find_gpt_root(sd_device *dev, blkid_probe pr, bool test) {
if (!sid)
continue;
label = blkid_partition_get_name(pp); /* returns NULL if empty */
stype = blkid_partition_get_type_string(pp);
if (!stype)
continue;
@ -174,13 +176,17 @@ static int find_gpt_root(sd_device *dev, blkid_probe pr, bool test) {
if (flags & GPT_FLAG_NO_AUTO)
continue;
/* We found a suitable root partition, let's
* remember the first one. */
/* We found a suitable root partition, let's remember the first one, or the one with
* the newest version, as determined by comparing the partition labels. */
if (!root_id) {
root_id = strdup(sid);
if (!root_id)
return -ENOMEM;
if (!root_id || strverscmp_improved(label, root_label) > 0) {
r = free_and_strdup(&root_id, sid);
if (r < 0)
return r;
r = free_and_strdup(&root_label, label);
if (r < 0)
return r;
}
}
}