diff --git a/10-devicetree.install b/10-devicetree.install index fdea5ec..3345391 100755 --- a/10-devicetree.install +++ b/10-devicetree.install @@ -2,7 +2,7 @@ # set -x -if [[ "$(uname -m)" == arm* || "$(uname -m)" == aarch64 || "$(uname -m)" == riscv64 ]] +if [[ "$(uname -m)" == arm* || "$(uname -m)" == aarch64 ]] then COMMAND="$1" KERNEL_VERSION="$2" diff --git a/grubby-bls b/grubby-bls index 11b69b1..f09156b 100755 --- a/grubby-bls +++ b/grubby-bls @@ -92,7 +92,7 @@ get_bls_values() { bls="${bls%.conf}" bls="${bls##*/}" echo "${bls}" - done | sort -Vr 2>/dev/null)) || : + done | /usr/libexec/grubby/rpm-sort -c rpmnvrcmp 2>/dev/null | tac)) || : for bls in "${files[@]}" ; do blspath="${blsdir}/${bls}.conf" @@ -356,26 +356,22 @@ get_custom_bls_filename() { prefix="${bls_target%%${arch}}" prefix="${prefix%.*}" - first_gap=$( - first=0 - for bls_entry in $(ls "${prefix}".*~custom*.conf 2>/dev/null | sort -V); do - if [[ -e ${bls_entry} ]]; then - bls_entry="${bls_entry##"${prefix}".}" - bls_entry="${bls_entry%%~custom*}" - if [[ "${bls_entry}" = "${first}" ]]; then - first=$((first+1)) - else - break - fi - fi - done - echo "${first}") || : + last=($(for bls in ${prefix}.*~custom*.conf ; do + if ! [[ -e "${bls}" ]] ; then + continue + fi + bls="${bls##${prefix}.}" + bls="${bls%%~custom*}" + echo "${bls}" + done | tail -n1)) || : - if [[ -z "$first_gap" ]]; then - first_gap="0" + if [[ -z $last ]]; then + last="0" + else + last=$((last+1)) fi - echo "${bls_target}" | sed -e "s!${prefix}!${prefix}.${first_gap}~custom!" + echo "${bls_target}" | sed -e "s!${prefix}!${prefix}.${last}~custom!" } add_bls_fragment() { @@ -504,7 +500,7 @@ update_bls_fragment() { if [[ -n $old_args ]]; then opts="$(update_args "${old_args}" "${remove_args}" "${add_args}")" opts="$(echo "$opts" | sed -e 's/\//\\\//g')" - sed -i -e "s/^GRUB_CMDLINE_LINUX=.*/GRUB_CMDLINE_LINUX=\\\"${opts}\\\"/" "${grub_etc_default}" + sed -i -e "s/^GRUB_CMDLINE_LINUX.*/GRUB_CMDLINE_LINUX=\\\"${opts}\\\"/" "${grub_etc_default}" fi fi @@ -567,7 +563,7 @@ set_default_bls() { echo "default=${default}" >> "${zipl_config}" fi fi - update_grubcfg + print_info "The default is ${bls_file[$index]} with index $index and kernel $(get_prefix)${bls_linux[$index]}" } @@ -599,29 +595,33 @@ remove_var_prefix() { update_grubcfg() { - # Turn on RUN_MKCONFIG on different archs/scenarios - if [[ "${arch}" = 's390' ]] || [[ "${arch}" = 's390x' ]]; then - # On s390/s390x systems, run mkconfig/zipl + # Older ppc64le OPAL firmware (petitboot version < 1.8.0) don't have BLS support + # so grub2-mkconfig has to be run to generate a config with menuentry commands. + if [ "${arch}" = "ppc64le" ] && [ -d /sys/firmware/opal ]; then RUN_MKCONFIG="true" - elif [[ "${arch}" = "ppc64le" ]] && [[ -d /sys/firmware/opal ]]; then - # Older ppc64le OPAL firmware don't have BLS support so grub2-mkconfig has to be run - # to generate a config with menuentry commands. - RUN_MKCONFIG="true" - elif [[ -e /sys/hypervisor/type ]] && grep -q "^xen$" /sys/hypervisor/type; then - if [ ! -e /sys/hypervisor/guest_type ] || ! grep -q "^HVM$" /sys/hypervisor/guest_type; then - # PV and PVH Xen DomU guests boot with pygrub that doesn't have BLS support, - # also Xen Dom0 use the menuentries from 20_linux_xen and not the ones from - # 10_linux. So grub2-mkconfig has to run for both Xen Dom0 and DomU. - RUN_MKCONFIG=true + petitboot_path="/sys/firmware/devicetree/base/ibm,firmware-versions/petitboot" + + if test -e ${petitboot_path}; then + read -r -d '' petitboot_version < ${petitboot_path} + petitboot_version="$(echo ${petitboot_version//v})" + + if test -n ${petitboot_version}; then + major_version="$(echo ${petitboot_version} | cut -d . -f1)" + minor_version="$(echo ${petitboot_version} | cut -d . -f2)" + + re='^[0-9]+$' + if [[ $major_version =~ $re ]] && [[ $minor_version =~ $re ]] && + ([[ ${major_version} -gt 1 ]] || + [[ ${major_version} -eq 1 && + ${minor_version} -ge 8 ]]); then + RUN_MKCONFIG="false" + fi + fi fi fi if [[ $RUN_MKCONFIG = "true" ]]; then - if [[ $bootloader = "zipl" ]]; then - zipl - else - grub2-mkconfig --no-grubenv-update -o "${grub_config}" &> /dev/null - fi + grub2-mkconfig --no-grubenv-update -o "${grub_config}" >& /dev/null fi } @@ -630,7 +630,7 @@ print_usage() cat < - 8.40-86 -- Own `/etc/sysconfig/kernel` which is used for `grubby` configuration - -* Wed Jul 30 2025 Leo Sandoval - 8.40-85 -- Update cfg when setting a default kernel - -* Thu Jul 24 2025 Fedora Release Engineering - 8.40-84 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild - -* Thu Mar 20 2025 Leo Sandoval - 8.40-83 -- grubby-bls: in s390* systems, run zipl on grub cfg update event - Fixes previous commit and formats better the conditions that trigger grub cfg updates - -* Fri Jan 17 2025 Fedora Release Engineering - 8.40-82 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild - -* Mon Jan 06 2025 Nicolas Frayer - 8.40-81 -- Fixups to custom kernel targets - -* Fri Dec 06 2024 Leo Sandoval - 8.40-80 -- grubby-bls: on PPC systems, remove petiboot's version checks - -* Fri Dec 06 2024 Leo Sandoval - 8.40-79 -- grubby-bls: in s390* systems, run zipl on grub cfg update event - -* Mon Dec 02 2024 David Abdurachmanov - 8.40-78 -- Add riscv64 support - -* Mon Nov 25 2024 Leo Sandoval - 8.40-77 -- On grub cfg updates, run grub2-mkconfig for Xen systems - -* Thu Jul 18 2024 Fedora Release Engineering - 8.40-76 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild - -* Wed Jan 24 2024 Fedora Release Engineering - 8.40-75 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild - -* Sat Jan 20 2024 Fedora Release Engineering - 8.40-74 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild - -* Wed Jan 10 2024 Marta Lewandowska - 8.40-73 -- Do not overwrite all vars that start with GRUB_CMDLINE_LINUX - -* Mon Sep 11 2023 Zbigniew Jedrzejewski-Szmek - 8.40-72 -- Drop installkernel so that it can be provided by systemd - -* Thu Jul 20 2023 Fedora Release Engineering - 8.40-71 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild - -* Tue Feb 21 2023 Marta Lewandowska - 8.40-70 -- remove root= when not copying default - -* Thu Jan 19 2023 Fedora Release Engineering - 8.40-69 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild - -* Tue Nov 01 2022 Robbie Harwood - 8.40-68 -- Drop custom rpm-sort -- See-also: https://github.com/rpm-software-management/rpm/pull/2249 - -* Tue Oct 04 2022 Robbie Harwood - 8.40-67 -- Apply Marta's copy-default args fix - * Mon Aug 22 2022 Robbie Harwood - 8.40-66 - Give up and just pull the config from BLS - Suggested-by: Bojan Smojver diff --git a/installkernel-bls b/installkernel-bls new file mode 100755 index 0000000..f2f607e --- /dev/null +++ b/installkernel-bls @@ -0,0 +1,83 @@ +#! /bin/sh +# +# /sbin/installkernel +# +# Copyright 2007-2008 Red Hat, Inc. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Author(s): tyson@rwii.com +# + +usage() { + echo "Usage: `basename $0` " >&2 + exit 1 +} + +cfgLoader= + +if [ -z "$INSTALL_PATH" -o "$INSTALL_PATH" == "/boot" ]; then + INSTALL_PATH=/boot + cfgLoader=1 +fi + +LINK_PATH=/boot +RELATIVE_PATH=`echo "$INSTALL_PATH/" | sed "s|^$LINK_PATH/||"` +KERNEL_VERSION=$1 +BOOTIMAGE=$2 +MAPFILE=$3 +ARCH=$(uname -m) +if [ $ARCH = 'ppc64' -o $ARCH = 'ppc' ]; then + KERNEL_NAME=vmlinux +else + KERNEL_NAME=vmlinuz +fi + +if [ -z "$KERNEL_VERSION" -o -z "$BOOTIMAGE" -o -z "$MAPFILE" ]; then + usage +fi + +if [ -f $INSTALL_PATH/$KERNEL_NAME-$KERNEL_VERSION ]; then + mv $INSTALL_PATH/$KERNEL_NAME-$KERNEL_VERSION \ + $INSTALL_PATH/$KERNEL_NAME-$KERNEL_VERSION.old; +fi + +if [ ! -L $INSTALL_PATH/$KERNEL_NAME ]; then + if [ -e $INSTALLPATH/$KERNEL_NAME ]; then + mv $INSTALL_PATH/$KERNEL_NAME $INSTALL_PATH/$KERNEL_NAME.old + fi +fi + +if [ -f $INSTALL_PATH/System.map-$KERNEL_VERSION ]; then + mv $INSTALL_PATH/System.map-$KERNEL_VERSION \ + $INSTALL_PATH/System.map-$KERNEL_VERSION.old; +fi + +if [ ! -L $INSTALL_PATH/System.map ]; then + if [ -e $INSTALLPATH/System.map ]; then + mv $INSTALL_PATH/System.map $INSTALL_PATH/System.map.old + fi +fi +ln -sf ${RELATIVE_PATH}$INSTALL_PATH/System.map-$KERNEL_VERSION $LINK_PATH/System.map + +cat $BOOTIMAGE > $INSTALL_PATH/$KERNEL_NAME-$KERNEL_VERSION +cp $MAPFILE $INSTALL_PATH/System.map-$KERNEL_VERSION + +ln -fs ${RELATIVE_PATH}$INSTALL_PATH/$KERNEL_NAME-$KERNEL_VERSION $LINK_PATH/$KERNEL_NAME +ln -fs ${RELATIVE_PATH}$INSTALL_PATH/System.map-$KERNEL_VERSION $LINK_PATH/System.map + +if [ -n "$cfgLoader" ]; then + kernel-install add $KERNEL_VERSION $INSTALL_PATH/$KERNEL_NAME-$KERNEL_VERSION + exit $? +fi diff --git a/kernel.sysconfig b/kernel.sysconfig deleted file mode 100644 index 8da1970..0000000 --- a/kernel.sysconfig +++ /dev/null @@ -1,6 +0,0 @@ -# UPDATEDEFAULT specifies if kernel-install should make -# new kernels the default -UPDATEDEFAULT=yes - -# DEFAULTKERNEL specifies the default kernel package type -DEFAULTKERNEL=kernel-core diff --git a/rpm-sort.c b/rpm-sort.c new file mode 100644 index 0000000..274bcb1 --- /dev/null +++ b/rpm-sort.c @@ -0,0 +1,356 @@ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef enum { + RPMNVRCMP, + VERSNVRCMP, + RPMVERCMP, + STRVERSCMP, +} comparitors; + +static comparitors comparitor = RPMNVRCMP; + +static inline void *xmalloc(size_t sz) +{ + void *ret = malloc(sz); + + assert(sz == 0 || ret != NULL); + return ret; +} + +static inline void *xrealloc(void *p, size_t sz) +{ + void *ret = realloc(p, sz); + + assert(sz == 0 || ret != NULL); + return ret; +} + +static inline char *xstrdup(const char * const s) +{ + void *ret = strdup(s); + + assert(s == NULL || ret != NULL); + return ret; +} + +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 = fopen(input, "r"); + + text = xmalloc (sz); + + if (!in) + err(1, "cannot open `%s'", input); + + 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; + } +} + +static int +cmprpmversp(const void *p1, const void *p2) +{ + return rpmvercmp(*(char * const *)p1, *(char * const *)p2); +} + +static int +cmpstrversp(const void *p1, const void *p2) +{ + return strverscmp(*(char * const *)p1, *(char * const *)p2); +} + +/* + * 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; + int (*cmp)(const char *s1, const char *s2); + + switch(comparitor) + { + default: /* just to shut up -Werror=maybe-uninitialized */ + case RPMNVRCMP: + cmp = rpmvercmp; + break; + case VERSNVRCMP: + cmp = strverscmp; + break; + case RPMVERCMP: + return cmprpmversp(p, q); + break; + case STRVERSCMP: + return cmpstrversp(p, q); + break; + } + + 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 = cmp ((lhs_name == NULL ? "" : lhs_name), + (rhs_name == NULL ? "" : rhs_name)); + if (vercmpflag != 0) + return vercmpflag; + + /* Check version and return if unequal */ + vercmpflag = cmp ((lhs_version == NULL ? "" : lhs_version), + (rhs_version == NULL ? "" : rhs_version)); + if (vercmpflag != 0) + return vercmpflag; + + /* Check release and return the version compare value */ + vercmpflag = cmp ((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[] = { + { "comparitor", 'c', "COMPARITOR", 0, "[rpm-nvr-cmp|vers-nvr-cmp|rpmvercmp|strverscmp]", 0}, + { 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 'c': + if (!strcmp(arg, "rpm-nvr-cmp") || !strcmp(arg, "rpmnvrcmp")) + comparitor = RPMNVRCMP; + else if (!strcmp(arg, "vers-nvr-cmp") || !strcmp(arg, "versnvrcmp")) + comparitor = VERSNVRCMP; + else if (!strcmp(arg, "rpmvercmp")) + comparitor = RPMVERCMP; + else if (!strcmp(arg, "strverscmp")) + comparitor = STRVERSCMP; + else + err(1, "Invalid comparitor \"%s\"", arg); + break; + 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, "[INPUT_FILES]", + "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; + + 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) + errx(1, "%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) + errx(1, "Invalid input"); + + 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; +}