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