| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| From: Javier Martinez Canillas <javierm@redhat.com> |
| Date: Wed, 18 Jul 2018 00:58:44 +0200 |
| Subject: [PATCH] blscfg: Don't attempt to sort by version if not present in |
| all BLS files |
| |
| Commit a16805341cc ("blscfg: sort BLS entries by 'version' field") made to |
| sort by the version field take precedence over the BLS fragment file name. |
| |
| But it also uses the lack of the version field in one BLS fragment as sort |
| criterion, which means that entries could be wrongly sorted if one of them |
| doesn't have a version field and others do. |
| |
| So only sort by version if all the BLS entries have this field defined, |
| otherwise just fallback to sorting by the BLS file name. |
| |
| Reported-by: Hans de Goede <hdegoede@redhat.com> |
| Suggested-by: Will Thompson <wjt@endlessm.com> |
| Signed-off-by: Javier Martinez Canillas <javierm@redhat.com> |
| |
| grub-core/commands/blscfg.c | 27 ++++++++++++++++----------- |
| 1 file changed, 16 insertions(+), 11 deletions(-) |
| |
| diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c |
| index 321c93069f2..69bfb5db295 100644 |
| |
| |
| @@ -324,23 +324,21 @@ finish: |
| /* return 1: p0 is newer than p1 */ |
| /* 0: p0 and p1 are the same version */ |
| /* -1: p1 is newer than p0 */ |
| -static int bls_cmp(const void *p0, const void *p1, void *state UNUSED) |
| +static int bls_cmp(const void *p0, const void *p1, void *state) |
| { |
| struct bls_entry * e0 = *(struct bls_entry **)p0; |
| struct bls_entry * e1 = *(struct bls_entry **)p1; |
| + bool use_version = *(bool *)state; |
| const char *v0, *v1; |
| int r; |
| |
| - v0 = bls_get_val(e0, "version", NULL); |
| - v1 = bls_get_val(e1, "version", NULL); |
| + if (use_version) { |
| + v0 = bls_get_val(e0, "version", NULL); |
| + v1 = bls_get_val(e1, "version", NULL); |
| |
| - if (v0 && !v1) |
| - return -1; |
| - if (!v0 && v1) |
| - return 1; |
| - |
| - if ((r = vercmp(v0, v1)) != 0) |
| - return r; |
| + if ((r = vercmp(v0, v1)) != 0) |
| + return r; |
| + } |
| |
| return vercmp(e0->filename, e1->filename); |
| } |
| @@ -692,6 +690,7 @@ static int find_entry (const char *filename, |
| grub_device_t blsdir_dev = NULL; |
| const char *blsdir = NULL; |
| char *saved_env_buf = NULL; |
| + bool use_version = true; |
| int fallback = 0; |
| int r = 0; |
| const char *devid = grub_env_get ("boot"); |
| @@ -819,7 +818,13 @@ read_fallback: |
| } |
| |
| grub_dprintf ("blscfg", "Sorting %d entries\n", nentries); |
| - grub_qsort(&entries[0], nentries, sizeof (struct bls_entry *), bls_cmp, NULL); |
| + |
| + for (r = 0; r < nentries && use_version; r++) { |
| + if (!bls_get_val(entries[r], "version", NULL)) |
| + use_version = false; |
| + } |
| + |
| + grub_qsort(&entries[0], nentries, sizeof (struct bls_entry *), bls_cmp, &use_version); |
| |
| grub_dprintf ("blscfg", "%s Creating %d entries from bls\n", __func__, nentries); |
| for (r = nentries - 1; r >= 0; r--) |