e1531466e1
This change updates grub to the 2.04 release. The new release changed how grub is built, so the bootstrap and bootstrap.conf files have to be added to the dist-git. Also, the gitignore file changed so it has to be updated. Since the patches have been forward ported to 2.04, there's no need for a logic to maintain a patch with the delta between the release and the grub master branch. So the release-to-master.patch is dropped and no longer is updated by the do-rebase script. Also since gnulib isn't part of the grub repository anymore and cloned by the boostrap tool, a gnulib tarball is included as other source file and copied before calling the bootstrap tool. That way grub can be built even in builders that only have access to the sources lookaside cache. Resolves: rhbz#1727279 Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
448 lines
12 KiB
Diff
448 lines
12 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Robert Marshall <rmarshall@redhat.com>
|
|
Date: Mon, 16 Mar 2015 14:14:19 -0400
|
|
Subject: [PATCH] Use Distribution Package Sort for grub2-mkconfig (#1124074)
|
|
|
|
Users reported that newly installed kernels on their systems installed
|
|
with grub-mkconfig would not appear on the grub boot list in order
|
|
starting with the most recent. Added an option for rpm-based systems to
|
|
use the rpm-sort library to sort kernels instead.
|
|
|
|
Resolves rhbz#1124074
|
|
|
|
Signed-off-by: Robert Marshall <rmarshall@redhat.com>
|
|
[pjones: fix --enable-rpm-sort configure option]
|
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
---
|
|
configure.ac | 29 +++++
|
|
Makefile.util.def | 16 +++
|
|
util/grub-rpm-sort.c | 281 ++++++++++++++++++++++++++++++++++++++++++++++
|
|
util/grub-mkconfig_lib.in | 11 +-
|
|
util/grub-rpm-sort.8 | 12 ++
|
|
5 files changed, 348 insertions(+), 1 deletion(-)
|
|
create mode 100644 util/grub-rpm-sort.c
|
|
create mode 100644 util/grub-rpm-sort.8
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index 8df400e0a8b..6927615819b 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -69,6 +69,7 @@ grub_TRANSFORM([grub-mkrelpath])
|
|
grub_TRANSFORM([grub-mkrescue])
|
|
grub_TRANSFORM([grub-probe])
|
|
grub_TRANSFORM([grub-reboot])
|
|
+grub_TRANSFORM([grub-rpm-sort])
|
|
grub_TRANSFORM([grub-script-check])
|
|
grub_TRANSFORM([grub-set-default])
|
|
grub_TRANSFORM([grub-sparc64-setup])
|
|
@@ -92,6 +93,7 @@ grub_TRANSFORM([grub-mkrescue.1])
|
|
grub_TRANSFORM([grub-mkstandalone.3])
|
|
grub_TRANSFORM([grub-ofpathname.3])
|
|
grub_TRANSFORM([grub-probe.3])
|
|
+grub_TRANSFORM([grub-rpm-sort.8])
|
|
grub_TRANSFORM([grub-reboot.3])
|
|
grub_TRANSFORM([grub-render-label.3])
|
|
grub_TRANSFORM([grub-script-check.3])
|
|
@@ -1802,6 +1804,33 @@ fi
|
|
|
|
AC_SUBST([LIBDEVMAPPER])
|
|
|
|
+AC_ARG_ENABLE([rpm-sort],
|
|
+ [AS_HELP_STRING([--enable-rpm-sort],
|
|
+ [enable native rpm sorting of kernels in grub (default=guessed)])])
|
|
+if test x"$enable_rpm_sort" = xno ; then
|
|
+ rpm_sort_excuse="explicitly disabled"
|
|
+fi
|
|
+
|
|
+if test x"$rpm_sort_excuse" = x ; then
|
|
+ # Check for rpmlib header.
|
|
+ AC_CHECK_HEADER([rpm/rpmlib.h], [],
|
|
+ [rpm_sort_excuse="need rpm/rpmlib header"])
|
|
+fi
|
|
+
|
|
+if test x"$rpm_sort_excuse" = x ; then
|
|
+ # Check for rpm library.
|
|
+ AC_CHECK_LIB([rpm], [rpmvercmp], [],
|
|
+ [rpm_sort_excuse="rpmlib missing rpmvercmp"])
|
|
+fi
|
|
+
|
|
+if test x"$rpm_sort_excuse" = x ; then
|
|
+ LIBRPM="-lrpm";
|
|
+ AC_DEFINE([HAVE_RPM], [1],
|
|
+ [Define to 1 if you have the rpm library.])
|
|
+fi
|
|
+
|
|
+AC_SUBST([LIBRPM])
|
|
+
|
|
LIBGEOM=
|
|
if test x$host_kernel = xkfreebsd; then
|
|
AC_CHECK_LIB([geom], [geom_gettree], [],
|
|
diff --git a/Makefile.util.def b/Makefile.util.def
|
|
index 1f298d05f3d..843ce092b94 100644
|
|
--- a/Makefile.util.def
|
|
+++ b/Makefile.util.def
|
|
@@ -696,6 +696,22 @@ program = {
|
|
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
|
|
};
|
|
|
|
+program = {
|
|
+ name = grub-rpm-sort;
|
|
+ mansection = 8;
|
|
+ installdir = sbin;
|
|
+
|
|
+ common = grub-core/kern/emu/misc.c;
|
|
+ common = grub-core/kern/emu/argp_common.c;
|
|
+ common = grub-core/osdep/init.c;
|
|
+ common = util/misc.c;
|
|
+ common = util/grub-rpm-sort.c;
|
|
+
|
|
+ ldadd = libgrubkern.a;
|
|
+ ldadd = grub-core/lib/gnulib/libgnu.a;
|
|
+ ldadd = '$(LIBDEVMAPPER) $(LIBRPM)';
|
|
+};
|
|
+
|
|
script = {
|
|
name = grub-mkconfig;
|
|
common = util/grub-mkconfig.in;
|
|
diff --git a/util/grub-rpm-sort.c b/util/grub-rpm-sort.c
|
|
new file mode 100644
|
|
index 00000000000..f33bd1ed568
|
|
--- /dev/null
|
|
+++ b/util/grub-rpm-sort.c
|
|
@@ -0,0 +1,281 @@
|
|
+#include <config.h>
|
|
+#include <grub/types.h>
|
|
+#include <grub/util/misc.h>
|
|
+#include <stdio.h>
|
|
+#include <stdlib.h>
|
|
+#include <unistd.h>
|
|
+#include <errno.h>
|
|
+#include <assert.h>
|
|
+#include <argp.h>
|
|
+#include <rpm/rpmlib.h>
|
|
+
|
|
+static size_t
|
|
+read_file (const char *input, char **ret)
|
|
+{
|
|
+ FILE *in;
|
|
+ size_t s;
|
|
+ size_t sz = 2048;
|
|
+ size_t offset = 0;
|
|
+ char *text;
|
|
+
|
|
+ if (!strcmp(input, "-"))
|
|
+ in = stdin;
|
|
+ else
|
|
+ in = grub_util_fopen(input, "r");
|
|
+
|
|
+ text = xmalloc (sz);
|
|
+
|
|
+ if (!in)
|
|
+ grub_util_error (_("cannot open `%s': %s"), input, strerror (errno));
|
|
+
|
|
+ while ((s = fread (text + offset, 1, sz - offset, in)) != 0)
|
|
+ {
|
|
+ offset += s;
|
|
+ if (sz - offset == 0)
|
|
+ {
|
|
+ sz += 2048;
|
|
+ text = xrealloc (text, sz);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ text[offset] = '\0';
|
|
+ *ret = text;
|
|
+
|
|
+ if (in != stdin)
|
|
+ fclose(in);
|
|
+
|
|
+ return offset + 1;
|
|
+}
|
|
+
|
|
+/* returns name/version/release */
|
|
+/* NULL string pointer returned if nothing found */
|
|
+static void
|
|
+split_package_string (char *package_string, char **name,
|
|
+ char **version, char **release)
|
|
+{
|
|
+ char *package_version, *package_release;
|
|
+
|
|
+ /* Release */
|
|
+ package_release = strrchr (package_string, '-');
|
|
+
|
|
+ if (package_release != NULL)
|
|
+ *package_release++ = '\0';
|
|
+
|
|
+ *release = package_release;
|
|
+
|
|
+ /* Version */
|
|
+ package_version = strrchr(package_string, '-');
|
|
+
|
|
+ if (package_version != NULL)
|
|
+ *package_version++ = '\0';
|
|
+
|
|
+ *version = package_version;
|
|
+ /* Name */
|
|
+ *name = package_string;
|
|
+
|
|
+ /* Bubble up non-null values from release to name */
|
|
+ if (*name == NULL)
|
|
+ {
|
|
+ *name = (*version == NULL ? *release : *version);
|
|
+ *version = *release;
|
|
+ *release = NULL;
|
|
+ }
|
|
+ if (*version == NULL)
|
|
+ {
|
|
+ *version = *release;
|
|
+ *release = NULL;
|
|
+ }
|
|
+}
|
|
+
|
|
+/*
|
|
+ * package name-version-release comparator for qsort
|
|
+ * expects p, q which are pointers to character strings (char *)
|
|
+ * which will not be altered in this function
|
|
+ */
|
|
+static int
|
|
+package_version_compare (const void *p, const void *q)
|
|
+{
|
|
+ char *local_p, *local_q;
|
|
+ char *lhs_name, *lhs_version, *lhs_release;
|
|
+ char *rhs_name, *rhs_version, *rhs_release;
|
|
+ int vercmpflag = 0;
|
|
+
|
|
+ local_p = alloca (strlen (*(char * const *)p) + 1);
|
|
+ local_q = alloca (strlen (*(char * const *)q) + 1);
|
|
+
|
|
+ /* make sure these allocated */
|
|
+ assert (local_p);
|
|
+ assert (local_q);
|
|
+
|
|
+ strcpy (local_p, *(char * const *)p);
|
|
+ strcpy (local_q, *(char * const *)q);
|
|
+
|
|
+ split_package_string (local_p, &lhs_name, &lhs_version, &lhs_release);
|
|
+ split_package_string (local_q, &rhs_name, &rhs_version, &rhs_release);
|
|
+
|
|
+ /* Check Name and return if unequal */
|
|
+ vercmpflag = rpmvercmp ((lhs_name == NULL ? "" : lhs_name),
|
|
+ (rhs_name == NULL ? "" : rhs_name));
|
|
+ if (vercmpflag != 0)
|
|
+ return vercmpflag;
|
|
+
|
|
+ /* Check version and return if unequal */
|
|
+ vercmpflag = rpmvercmp ((lhs_version == NULL ? "" : lhs_version),
|
|
+ (rhs_version == NULL ? "" : rhs_version));
|
|
+ if (vercmpflag != 0)
|
|
+ return vercmpflag;
|
|
+
|
|
+ /* Check release and return the version compare value */
|
|
+ vercmpflag = rpmvercmp ((lhs_release == NULL ? "" : lhs_release),
|
|
+ (rhs_release == NULL ? "" : rhs_release));
|
|
+
|
|
+ return vercmpflag;
|
|
+}
|
|
+
|
|
+static void
|
|
+add_input (const char *filename, char ***package_names, size_t *n_package_names)
|
|
+{
|
|
+ char *orig_input_buffer = NULL;
|
|
+ char *input_buffer;
|
|
+ char *position_of_newline;
|
|
+ char **names = *package_names;
|
|
+ char **new_names = NULL;
|
|
+ size_t n_names = *n_package_names;
|
|
+
|
|
+ if (!*package_names)
|
|
+ new_names = names = xmalloc (sizeof (char *) * 2);
|
|
+
|
|
+ if (read_file (filename, &orig_input_buffer) < 2)
|
|
+ {
|
|
+ if (new_names)
|
|
+ free (new_names);
|
|
+ if (orig_input_buffer)
|
|
+ free (orig_input_buffer);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ input_buffer = orig_input_buffer;
|
|
+ while (input_buffer && *input_buffer &&
|
|
+ (position_of_newline = strchrnul (input_buffer, '\n')))
|
|
+ {
|
|
+ size_t sz = position_of_newline - input_buffer;
|
|
+ char *new;
|
|
+
|
|
+ if (sz == 0)
|
|
+ {
|
|
+ input_buffer = position_of_newline + 1;
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ new = xmalloc (sz+1);
|
|
+ strncpy (new, input_buffer, sz);
|
|
+ new[sz] = '\0';
|
|
+
|
|
+ names = xrealloc (names, sizeof (char *) * (n_names + 1));
|
|
+ names[n_names] = new;
|
|
+ n_names++;
|
|
+
|
|
+ /* move buffer ahead to next line */
|
|
+ input_buffer = position_of_newline + 1;
|
|
+ if (*position_of_newline == '\0')
|
|
+ input_buffer = NULL;
|
|
+ }
|
|
+
|
|
+ free (orig_input_buffer);
|
|
+
|
|
+ *package_names = names;
|
|
+ *n_package_names = n_names;
|
|
+}
|
|
+
|
|
+static char *
|
|
+help_filter (int key, const char *text, void *input __attribute__ ((unused)))
|
|
+{
|
|
+ return (char *)text;
|
|
+}
|
|
+
|
|
+static struct argp_option options[] = {
|
|
+ { 0, }
|
|
+};
|
|
+
|
|
+struct arguments
|
|
+{
|
|
+ size_t ninputs;
|
|
+ size_t input_max;
|
|
+ char **inputs;
|
|
+};
|
|
+
|
|
+static error_t
|
|
+argp_parser (int key, char *arg, struct argp_state *state)
|
|
+{
|
|
+ struct arguments *arguments = state->input;
|
|
+ switch (key)
|
|
+ {
|
|
+ case ARGP_KEY_ARG:
|
|
+ assert (arguments->ninputs < arguments->input_max);
|
|
+ arguments->inputs[arguments->ninputs++] = xstrdup (arg);
|
|
+ break;
|
|
+ default:
|
|
+ return ARGP_ERR_UNKNOWN;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static struct argp argp = {
|
|
+ options, argp_parser, N_("[INPUT_FILES]"),
|
|
+ N_("Sort a list of strings in RPM version sort order."),
|
|
+ NULL, help_filter, NULL
|
|
+};
|
|
+
|
|
+int
|
|
+main (int argc, char *argv[])
|
|
+{
|
|
+ struct arguments arguments;
|
|
+ char **package_names = NULL;
|
|
+ size_t n_package_names = 0;
|
|
+ int i;
|
|
+
|
|
+ grub_util_host_init (&argc, &argv);
|
|
+
|
|
+ memset (&arguments, 0, sizeof (struct arguments));
|
|
+ arguments.input_max = argc+1;
|
|
+ arguments.inputs = xmalloc ((arguments.input_max + 1)
|
|
+ * sizeof (arguments.inputs[0]));
|
|
+ memset (arguments.inputs, 0, (arguments.input_max + 1)
|
|
+ * sizeof (arguments.inputs[0]));
|
|
+
|
|
+ /* Parse our arguments */
|
|
+ if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0)
|
|
+ grub_util_error ("%s", _("Error in parsing command line arguments\n"));
|
|
+
|
|
+ /* If there's no inputs in argv, add one for stdin */
|
|
+ if (!arguments.ninputs)
|
|
+ {
|
|
+ arguments.ninputs = 1;
|
|
+ arguments.inputs[0] = xmalloc (2);
|
|
+ strcpy(arguments.inputs[0], "-");
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < arguments.ninputs; i++)
|
|
+ add_input(arguments.inputs[i], &package_names, &n_package_names);
|
|
+
|
|
+ if (package_names == NULL || n_package_names < 1)
|
|
+ grub_util_error ("%s", _("Invalid input\n"));
|
|
+
|
|
+ qsort (package_names, n_package_names, sizeof (char *),
|
|
+ package_version_compare);
|
|
+
|
|
+ /* send sorted list to stdout */
|
|
+ for (i = 0; i < n_package_names; i++)
|
|
+ {
|
|
+ fprintf (stdout, "%s\n", package_names[i]);
|
|
+ free (package_names[i]);
|
|
+ }
|
|
+
|
|
+ free (package_names);
|
|
+ for (i = 0; i < arguments.ninputs; i++)
|
|
+ free (arguments.inputs[i]);
|
|
+
|
|
+ free (arguments.inputs);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in
|
|
index 1a4a57898f9..113a41f9409 100644
|
|
--- a/util/grub-mkconfig_lib.in
|
|
+++ b/util/grub-mkconfig_lib.in
|
|
@@ -33,6 +33,9 @@ fi
|
|
if test "x$grub_mkrelpath" = x; then
|
|
grub_mkrelpath="${bindir}/@grub_mkrelpath@"
|
|
fi
|
|
+if test "x$grub_rpm_sort" = x; then
|
|
+ grub_rpm_sort="${sbindir}/@grub_rpm_sort@"
|
|
+fi
|
|
|
|
if which gettext >/dev/null 2>/dev/null; then
|
|
:
|
|
@@ -214,6 +217,12 @@ version_sort ()
|
|
esac
|
|
}
|
|
|
|
+if [ "x$grub_rpm_sort" != x -a -x "$grub_rpm_sort" ]; then
|
|
+ kernel_sort="$grub_rpm_sort"
|
|
+else
|
|
+ kernel_sort=version_sort
|
|
+fi
|
|
+
|
|
version_test_numeric ()
|
|
{
|
|
version_test_numeric_a="$1"
|
|
@@ -230,7 +239,7 @@ version_test_numeric ()
|
|
version_test_numeric_a="$version_test_numeric_b"
|
|
version_test_numeric_b="$version_test_numeric_c"
|
|
fi
|
|
- if (echo "$version_test_numeric_a" ; echo "$version_test_numeric_b") | version_sort | head -n 1 | grep -qx "$version_test_numeric_b" ; then
|
|
+ if (echo "$version_test_numeric_a" ; echo "$version_test_numeric_b") | "$kernel_sort" | head -n 1 | grep -qx "$version_test_numeric_b" ; then
|
|
return 0
|
|
else
|
|
return 1
|
|
diff --git a/util/grub-rpm-sort.8 b/util/grub-rpm-sort.8
|
|
new file mode 100644
|
|
index 00000000000..8ce21488448
|
|
--- /dev/null
|
|
+++ b/util/grub-rpm-sort.8
|
|
@@ -0,0 +1,12 @@
|
|
+.TH GRUB-RPM-SORT 8 "Wed Feb 26 2014"
|
|
+.SH NAME
|
|
+\fBgrub-rpm-sort\fR \(em Sort input according to RPM version compare.
|
|
+
|
|
+.SH SYNOPSIS
|
|
+\fBgrub-rpm-sort\fR [OPTIONS].
|
|
+
|
|
+.SH DESCRIPTION
|
|
+You should not normally run this program directly. Use grub-mkconfig instead.
|
|
+
|
|
+.SH SEE ALSO
|
|
+.BR "info grub"
|