diff --git a/20-zipl-kernel.install b/20-zipl-kernel.install new file mode 100755 index 0000000..9c87f41 --- /dev/null +++ b/20-zipl-kernel.install @@ -0,0 +1,152 @@ +#!/bin/bash + +[[ -f /etc/sysconfig/kernel ]] && . /etc/sysconfig/kernel + +COMMAND="$1" +KERNEL_VERSION="$2" +BOOT_DIR_ABS="$3" +KERNEL_IMAGE="$4" + +KERNEL_DIR="${KERNEL_IMAGE%/*}" + +MACHINE_ID=$KERNEL_INSTALL_MACHINE_ID + +# Remove it, since for zipl the images are always installed in /boot +rm -rf "${BOOT_DIR_ABS%/*}" + +BLS_DIR="/boot/loader/entries" +CMDLINE_LINUX_DEBUG=" systemd.log_level=debug systemd.log_target=kmsg" +LINUX_DEBUG_VERSION_POSTFIX="_with_debugging" +LINUX_DEBUG_TITLE_POSTFIX=" with debugging" + +mkbls() { + local kernelver=$1 && shift + local datetime=$1 && shift + local kernelopts=$1 && shift + + local debugname="" + local flavor="" + + if [[ "$kernelver" == *\+* ]] ; then + local flavor=-"${kernelver##*+}" + if [[ "${flavor}" == "-debug" ]]; then + local debugname=" with debugging" + local debugid="-debug" + fi + fi + + cat </dev/null && \ + restorecon -R "/boot/${i##*/}-${KERNEL_VERSION}" + done + # hmac is .vmlinuz-.hmac so needs a special treatment + i="$KERNEL_DIR/.${KERNEL_IMAGE##*/}.hmac" + if [[ -e "$i" ]]; then + cp -a "$i" "/boot/.${KERNEL_IMAGE##*/}-${KERNEL_VERSION}.hmac" + command -v restorecon &>/dev/null && \ + restorecon "/boot/.${KERNEL_IMAGE##*/}-${KERNEL_VERSION}.hmac" + fi + fi + + if [[ ! -f /sbin/new-kernel-pkg ]]; then + declare -a BOOT_OPTIONS + if [[ -f /etc/kernel/cmdline ]]; then + read -r -d '' -a BOOT_OPTIONS < /etc/kernel/cmdline + fi + + if ! [[ ${BOOT_OPTIONS[*]} ]]; then + read -r -d '' -a line < /proc/cmdline + for i in "${line[@]}"; do + [[ "${i#initrd=*}" != "$i" ]] && continue + BOOT_OPTIONS+=("$i") + done + fi + + if ! [[ ${BOOT_OPTIONS[*]} ]]; then + echo "Could not determine the kernel command line parameters." >&2 + echo "Please specify the kernel command line in /etc/kernel/cmdline!" >&2 + exit 1 + fi + + [[ -d "$BLS_DIR" ]] || mkdir -m 0700 -p "$BLS_DIR" + BLS_TARGET="${BLS_DIR}/${MACHINE_ID}-${KERNEL_VERSION}.conf" + if [[ -f "${KERNEL_DIR}/bls.conf" ]]; then + cp -aT "${KERNEL_DIR}/bls.conf" "${BLS_TARGET}" || exit $? + sed -i -e "s,^linux.*,linux /boot/vmlinuz-${KERNEL_VERSION},g" "${BLS_TARGET}" + sed -i -e "s,^initrd.*,initrd /boot/initramfs-${KERNEL_VERSION}.img,g" "${BLS_TARGET}" + sed -i -e "s,^options.*,options ${BOOT_OPTIONS[*]},g" "${BLS_TARGET}" + else + mkbls "${KERNEL_VERSION}" \ + "$(date -u +%Y%m%d%H%M%S -d "$(stat -c '%y' "${KERNEL_DIR}")")" \ + "${BOOT_OPTIONS[*]}" >"${BLS_TARGET}" + fi + + if [ "x${MAKEDEBUG}" = "xyes" ]; then + ARCH="$(uname -m)" + BLS_DEBUG="$(echo ${BLS_TARGET} | sed -e "s/\.${ARCH}/-debug.${ARCH}/")" + cp -aT "${BLS_TARGET}" "${BLS_DEBUG}" + TITLE="$(grep '^title[ \t]' "${BLS_DEBUG}" | sed -e 's/^title[ \t]*//')" + VERSION="$(grep '^version[ \t]' "${BLS_DEBUG}" | sed -e 's/^version[ \t]*//')" + BLSID="$(grep '^id[ \t]' "${BLS_DEBUG}" | sed -e "s/\.${ARCH}/-debug.${ARCH}/")" + sed -i -e "s/^title.*/title ${TITLE}${LINUX_DEBUG_TITLE_POSTFIX}/" "${BLS_DEBUG}" + sed -i -e "s/^version.*/version ${VERSION}${LINUX_DEBUG_VERSION_POSTFIX}/" "${BLS_DEBUG}" + sed -i -e "s/^id.*/${BLSID}/" "${BLS_DEBUG}" + sed -i -e "s,^options.*,options ${BOOT_OPTIONS[*]}${CMDLINE_LINUX_DEBUG}," "${BLS_DEBUG}" + fi + + exit 0 + fi + + /sbin/new-kernel-pkg --package "kernel${flavor}" --install "$KERNEL_VERSION" || exit $? + /sbin/new-kernel-pkg --package "kernel${flavor}" --mkinitrd --dracut --depmod --update "$KERNEL_VERSION" || exit $? + /sbin/new-kernel-pkg --package "kernel${flavor}" --rpmposttrans "$KERNEL_VERSION" || exit $? + # If grubby is used there's no need to run other installation plugins + exit 77 + ;; + remove) + if [[ ! -f /sbin/new-kernel-pkg ]]; then + ARCH="$(uname -m)" + BLS_TARGET="${BLS_DIR}/${MACHINE_ID}-${KERNEL_VERSION}.conf" + BLS_DEBUG="$(echo ${BLS_TARGET} | sed -e "s/\.${ARCH}/-debug.${ARCH}/")" + rm -f "${BLS_TARGET}" "${BLS_DEBUG}" + + for i in vmlinuz System.map config zImage.stub dtb; do + rm -rf "/boot/${i}-${KERNEL_VERSION}" + done + # hmac is .vmlinuz-.hmac so needs a special treatment + rm -f "/boot/.vmlinuz-${KERNEL_VERSION}.hmac" + + exit 0 + fi + + /sbin/new-kernel-pkg --package "kernel${flavor+-$flavor}" --rminitrd --rmmoddep --remove "$KERNEL_VERSION" || exit $? + # If grubby is used there's no need to run other installation plugins + exit 77 + ;; + *) + ;; +esac diff --git a/52-zipl-rescue.install b/52-zipl-rescue.install new file mode 100755 index 0000000..314b9ab --- /dev/null +++ b/52-zipl-rescue.install @@ -0,0 +1,48 @@ +#!/bin/bash + +[[ -f /etc/os-release ]] && . /etc/os-release +[[ -f /etc/sysconfig/kernel ]] && . /etc/sysconfig/kernel + +COMMAND="$1" +KERNEL_VERSION="$2" +BOOT_DIR_ABS="$3" +KERNEL_IMAGE="$4" + +MACHINE_ID=$KERNEL_INSTALL_MACHINE_ID + +BLS_DIR="/boot/loader/entries" + +[[ "$KERNEL_VERSION" == *\+* ]] && flavor=-"${KERNEL_VERSION##*+}" +case "$COMMAND" in + add) + if [[ ! -f /sbin/new-kernel-pkg ]]; then + declare -a BOOT_OPTIONS + if [[ -f /etc/kernel/cmdline ]]; then + read -r -d '' -a BOOT_OPTIONS < /etc/kernel/cmdline + fi + + if ! [[ ${BOOT_OPTIONS[*]} ]]; then + read -r -d '' -a line < /proc/cmdline + for i in "${line[@]}"; do + [[ "${i#initrd=*}" != "$i" ]] && continue + BOOT_OPTIONS+=("$i") + done + fi + + if ! [[ ${BOOT_OPTIONS[*]} ]]; then + echo "Could not determine the kernel command line parameters." >&2 + echo "Please specify the kernel command line in /etc/kernel/cmdline!" >&2 + exit 1 + fi + + BLS_RESCUE="${BLS_DIR}/${MACHINE_ID}-0-rescue.conf" + if [[ -f "${BLS_RESCUE}" ]] && grep -q '^options.*$kernelopts' "${BLS_RESCUE}"; then + sed -i -e "s,^linux.*,linux /boot/vmlinuz-0-rescue-${MACHINE_ID},g" "${BLS_RESCUE}" + sed -i -e "s,^initrd.*,initrd /boot/initramfs-0-rescue-${MACHINE_ID}.img,g" "${BLS_RESCUE}" + sed -i -e "s,^options.*,options ${BOOT_OPTIONS[*]},g" "${BLS_RESCUE}" + fi + fi + ;; + *) + ;; +esac diff --git a/91-zipl.install b/91-zipl.install new file mode 100755 index 0000000..6b46f82 --- /dev/null +++ b/91-zipl.install @@ -0,0 +1,11 @@ +#!/bin/bash + +COMMAND="$1" + +case "$COMMAND" in + add|remove) + zipl > /dev/null + ;; + *) + ;; +esac diff --git a/s390-tools-add-zipl-switch-to-blscfg-script.patch b/s390-tools-add-zipl-switch-to-blscfg-script.patch new file mode 100644 index 0000000..6267afb --- /dev/null +++ b/s390-tools-add-zipl-switch-to-blscfg-script.patch @@ -0,0 +1,300 @@ +From 24369c7677048518858dfbc6d5e609f64a42eff6 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Wed, 2 May 2018 12:27:05 +0200 +Subject: [PATCH] scripts: Add script to switch zipl config to a + BootLoaderSpec setup + +Add a zipl-switch-to-blscfg script that can be used to switch the zipl +configuration in a system to use the BootLoaderSpec (BLS) config files +to define the IPL sections instead of having them defined in zipl.conf. + +Signed-off-by: Javier Martinez Canillas +--- + scripts/Makefile | 4 +- + scripts/zipl-switch-to-blscfg | 207 ++++++++++++++++++++++++++++++++ + scripts/zipl-switch-to-blscfg.1 | 45 +++++++ + 3 files changed, 254 insertions(+), 2 deletions(-) + create mode 100755 scripts/zipl-switch-to-blscfg + create mode 100644 scripts/zipl-switch-to-blscfg.1 + +diff --git a/scripts/Makefile b/scripts/Makefile +index dc5b0f0dbe7..1a33e319693 100644 +--- a/scripts/Makefile ++++ b/scripts/Makefile +@@ -1,7 +1,7 @@ + include ../common.mak + +-SCRIPTS = dbginfo.sh zfcpdbf scsi_logging_level +-MAN_PAGES = dbginfo.sh.1 zfcpdbf.1 ++SCRIPTS = dbginfo.sh zfcpdbf zipl-switch-to-blscfg scsi_logging_level ++MAN_PAGES = dbginfo.sh.1 zfcpdbf.1 zipl-switch-to-blscfg.1 + + all: + +diff --git a/scripts/zipl-switch-to-blscfg b/scripts/zipl-switch-to-blscfg +new file mode 100755 +index 00000000000..871935c783f +--- /dev/null ++++ b/scripts/zipl-switch-to-blscfg +@@ -0,0 +1,207 @@ ++#!/bin/bash ++# ++# zipl-switch-to-blscfg - Switch zipl to use BootLoaderSpec configuration ++# ++# Copyright 2018 Red Hat, Inc. ++# ++# s390-tools is free software; you can redistribute it and/or modify ++# it under the terms of the MIT license. See LICENSE for details. ++# ++ ++readonly SCRIPTNAME="${0##*/}" ++ ++declare -A zipl_to_bls ++zipl_to_bls["image"]="linux" ++zipl_to_bls["ramdisk"]="initrd" ++zipl_to_bls["parameters"]="options" ++ ++print_error() { ++ echo "$1" >&2 ++ exit 1 ++} ++ ++function on_exit() { ++ if ! rm -rf $TMP; then ++ echo "Delete temporary files failed!" >&2 ++ exit 1 ++ fi ++} ++ ++if ! TMP="$(mktemp -d)"; then ++ print_error "Creating a temporary dir for config files failed!" ++fi ++ ++trap 'on_exit' EXIT ++ ++print_version() { ++ cat <&2 ++ echo "${SCRIPTNAME}: invalid option \"${1}\"" >&2 ++ echo "Try '${SCRIPTNAME} --help' for more information" >&2 ++ echo >&2 ++ exit 1 ++ ;; ++ esac ++ shift ++done ++ ++TMP_CONFIG="${TMP}/${CONFIG##*/}" ++ ++[[ -d "$BLS_DIR" ]] || mkdir -m 0700 -p "$BLS_DIR" ++ ++if [ -f /etc/machine-id ]; then ++ read MACHINE_ID < /etc/machine-id ++ MACHINE_ID=${MACHINE_ID}- ++fi ++ ++count=0 ++OUTPUT="" ++TARGET="" ++while IFS='= ' read key val; do ++ # for BLS the default kernel is always the latest one ++ if [[ $key == \#* ]] || [[ $key == "default" && $ignore_default == true ]]; then ++ continue ++ fi ++ ++ # remove spaces ++ key="$(echo $key | sed -e 's/^[ \t"]*//;s/[ \t"]*$//')" ++ ++ if [[ $key = \[*] ]]; then ++ if [[ $key == "[defaultboot]" ]]; then ++ OUTPUT=${TMP_CONFIG} ++ echo $key >> ${OUTPUT} ++ else ++ key="${key%\]}" ++ key="${key#\[}" ++ OUTPUT=${BLS_DIR}/${MACHINE_ID}${key}.conf ++ if [ -f "${OUTPUT}" ]; then ++ print_error "BLS file ${OUTPUT} already exists" ++ fi ++ fi ++ elif [[ $val ]]; then ++ val="$(echo $val | sed -e 's/^[ \t"]*//;s/[ \t"]*$//')" ++ if [[ $key == "target" ]]; then ++ if [ -z ${TARGET} ]; then ++ echo $key=$val >> ${TMP_CONFIG} ++ TARGET=$val ++ else if [ "${TARGET}" != "${val}" ]; then ++ print_error "BLS is only supported if all sections have the same target" ++ fi ++ fi ++ else ++ if [ -n "${zipl_to_bls[$key]}" ]; then ++ if [[ $key = "image" ]]; then ++ if [[ $val = *"vmlinuz-"* ]]; then ++ version="${val##*/vmlinuz-}" ++ else ++ version="${val##*/}" ++ fi ++ echo "version $version" >> ${OUTPUT} ++ if [[ $version = *"rescue"* ]]; then ++ FILENAME=${BLS_DIR}/${MACHINE_ID}0-rescue.conf ++ else ++ FILENAME=${BLS_DIR}/${MACHINE_ID}${version}.conf ++ fi ++ ++ if [[ ${OUTPUT} != ${FILENAME} && $version_name == true ]]; then ++ mv ${OUTPUT} ${FILENAME} ++ if [ ! $? -eq 0 ]; then ++ print_error "Creating BLS file ${FILENAME} failed" ++ fi ++ OUTPUT=${FILENAME} ++ fi ++ fi ++ ++ echo "${zipl_to_bls[$key]} ${val}" >> ${OUTPUT} ++ else ++ echo $key=$val >> ${TMP_CONFIG} ++ fi ++ fi ++ fi ++done < "${CONFIG}" ++ ++if [ -f "${CONFIG}${BACKUP_SUFFIX}" ]; then ++ print_error "Backup file ${CONFIG}${BACKUP_SUFFIX} already exists" ++fi ++ ++cp -af "${CONFIG}" "${CONFIG}${BACKUP_SUFFIX}" ++mv "${TMP_CONFIG}" "${CONFIG}" ++ ++zipl > /dev/null ++if [ ! $? -eq 0 ]; then ++ mv "${CONFIG}${BACKUP_SUFFIX}" "${CONFIG}" ++fi ++ ++exit 0 +diff --git a/scripts/zipl-switch-to-blscfg.1 b/scripts/zipl-switch-to-blscfg.1 +new file mode 100644 +index 00000000000..6bd14d00d14 +--- /dev/null ++++ b/scripts/zipl-switch-to-blscfg.1 +@@ -0,0 +1,45 @@ ++.TH ZIPL-SWITCH-TO-BLSCFG 1 "April 2018" "s390-tools" ++ ++.SH NAME ++zipl-switch-to-blscfg \- Switch zipl to use BootLoaderSpec configuration ++ ++.SH SYNOPSIS ++.br ++\fBzipl-switch-to-blscfg\fP [OPTIONS] ++.br ++\fBzipl-switch-to-blscfg\fP {\-h|\-v} ++ ++.SH DESCRIPTION ++This script switches the zipl boot-loader configuration to use BootLoaderSpec files ++to define IPL sections. For each Linux kernel defined in the zipl.conf config file, ++a BLS fragment is generated in the BLS directory specified. Also, the zipl.conf is ++modified it only contains global configurations, all IPL sections comes from BLS. ++ ++.SH OPTIONS ++.TP ++\fB\-h\fP, \fB\-\-help\fP ++Print this help and exit ++ ++.TP ++\fB\-v\fP, \fB\-\-version\fP ++Print version information and exit ++ ++.TP ++\fB\-\-backup-suffix \fP ++The suffix used for backup files, defaults to .bak. ++ ++.TP ++\fB\-\-bls-directory \fP ++The DIRECTORY where the BLS fragments will be generated. The directory is created if it doesn't exists, by default /boot/loader/entries is used. ++ ++.TP ++\fB\-\-config-file \fP ++The FILE used for zipl configuration file, defaults to /etc/zipl.conf. ++ ++.TP ++\fB\-\-ignore-default\fP ++Ignore the default option from the zipl configuration file ++ ++.TP ++\fB\-\-use-version-name\fP ++Use the section kernel version as the BLS file name +-- +2.17.0 + diff --git a/s390-tools-zipl-Add-BootLoaderSpec-support.patch b/s390-tools-zipl-Add-BootLoaderSpec-support.patch new file mode 100644 index 0000000..1ca0080 --- /dev/null +++ b/s390-tools-zipl-Add-BootLoaderSpec-support.patch @@ -0,0 +1,411 @@ +From 4d3fb60159566dfb011a855d899425e972ed951a Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Wed, 2 May 2018 12:26:58 +0200 +Subject: [PATCH] zipl: Add BootLoaderSpec support + +The BootLoaderSpec (BLS) defines a file format for boot configurations, +so bootloaders can parse these files and create their boot menu entries +by using the information provided by them [0]. + +This allow to configure the boot items as drop-in files in a directory +instead of having to parse and modify a bootloader configuration file. + +If the /boot/loader/entries exists and there are BLS files there, then +these are parsed and configuration sections are added without the need +to have these in a zipl.conf file. + +A different BLS directory can be specified from the command line using +the --blsdir option. + +[0]: https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/ + +Signed-off-by: Javier Martinez Canillas +--- + zipl/include/scan.h | 1 + + zipl/include/zipl.h | 1 + + zipl/man/zipl.8 | 12 ++- + zipl/man/zipl.conf.5 | 21 +++++ + zipl/src/job.c | 24 +++++- + zipl/src/scan.c | 179 +++++++++++++++++++++++++++++++++++++++++++ + zipl/src/zipl.c | 1 + + 7 files changed, 237 insertions(+), 2 deletions(-) + +diff --git a/zipl/include/scan.h b/zipl/include/scan.h +index f2c7b1b094a..0fe415c9b2d 100644 +--- a/zipl/include/scan.h ++++ b/zipl/include/scan.h +@@ -119,6 +119,7 @@ extern enum scan_key_state scan_key_table[SCAN_SECTION_NUM][SCAN_KEYWORD_NUM]; + + + int scan_file(const char* filename, struct scan_token** array); ++int scan_bls(const char* blsdir, struct scan_token** token, int scan_size); + void scan_free(struct scan_token* array); + char* scan_keyword_name(enum scan_keyword_id id); + int scan_check_defaultboot(struct scan_token* scan); +diff --git a/zipl/include/zipl.h b/zipl/include/zipl.h +index 8dc6b6db1a5..2aed54fb2b5 100644 +--- a/zipl/include/zipl.h ++++ b/zipl/include/zipl.h +@@ -43,6 +43,7 @@ + + #define ZIPL_CONF_VAR "ZIPLCONF" + #define ZIPL_DEFAULT_CONF "/etc/zipl.conf" ++#define ZIPL_DEFAULT_BLSDIR "/boot/loader/entries" + + #define MENU_DEFAULT_PROMPT 0 + #define MENU_DEFAULT_TIMEOUT 0 +diff --git a/zipl/man/zipl.8 b/zipl/man/zipl.8 +index 873d680465a..989197590e4 100644 +--- a/zipl/man/zipl.8 ++++ b/zipl/man/zipl.8 +@@ -25,7 +25,7 @@ loading a data file to initialize named saved segments (NSS) + Each of these operations is characterized by a boot configuration, i.e. a + set of required parameters. + .B zipl +-supports two ways of specifying a boot configuration: ++supports three ways of specifying a boot configuration: + .IP " -" + .B command line: + all parameters are provided through the command line switches described below. +@@ -37,6 +37,11 @@ parameters are provided by sections defined in a configuration file (see + Using a configuration file, you can either specify a single boot configuration + or a menu, i.e. a list of configurations from which users can choose at boot + time. ++.IP " -" ++.B BLS config files: ++boot configurations are specified using BootLoaderSpec (BLS) configuration files. The ++.BR zipl.conf (5) ++configuration file is still used to specify parameters or aditional boot configurations. + .PP + + To use a single boot configuration section, provide its name as parameter to +@@ -117,6 +122,11 @@ Print version information, then exit. + Use the specified . If none is supplied, the environment + variable ZIPLCONF is evaluated if set, otherwise /etc/zipl.conf is used. + ++.TP ++.BR "\-b " " or " "\-\-blsdir=" ++Use the specified to parse BootLoaderSpec config files. ++If none is supplied, the /boot/loader/entries directory is used. ++ + .TP + .BR "\-t " " or " "\-\-target=" + Use the specified . +diff --git a/zipl/man/zipl.conf.5 b/zipl/man/zipl.conf.5 +index 8c454cd01e6..d4877d884fc 100644 +--- a/zipl/man/zipl.conf.5 ++++ b/zipl/man/zipl.conf.5 +@@ -117,6 +117,27 @@ timeout = 0 + .br + .PP + ++.B BootLoaderSpec configuration files ++ ++Another way to specify IPL sections is to use BLS config files. These are ++configuration files located by default at /boot/loader/entries, but another ++location can be specified using the '\-\-blsdir' option of zipl. ++ ++.IP ++# An example for a BLS configuration file ++.br ++ ++version 4.15.9 ++.br ++linux /vmlinuz-4.15.9 ++.br ++initrd /initramfs-4.15.9 ++.br ++options root=/dev/dasda1 console=ttyS0 ++.PP ++ ++The location of the linux and initrd has to be specified relative to the boot partition. The BLS config files are only used to specify the IPL sections, a zipl.conf configuration files is still needed for global parameters. ++ + .B Boot menu + + The +diff --git a/zipl/src/job.c b/zipl/src/job.c +index 9d5f00b6bdc..e6d298188d5 100644 +--- a/zipl/src/job.c ++++ b/zipl/src/job.c +@@ -27,6 +27,7 @@ + /* Command line options */ + static struct option options[] = { + { "config", required_argument, NULL, 'c'}, ++ { "blsdir", required_argument, NULL, 'b'}, + { "target", required_argument, NULL, 't'}, + { "targetbase", required_argument, NULL, 0xaa}, + { "targettype", required_argument, NULL, 0xab}, +@@ -55,11 +56,12 @@ static struct option options[] = { + }; + + /* Command line option abbreviations */ +-static const char option_string[] = "-c:t:i:r:p:P:d:D:M:s:m:hHnVvaT:fk:"; ++static const char option_string[] = "-c:b:t:i:r:p:P:d:D:M:s:m:hHnVvaT:fk:"; + + struct command_line { + char* data[SCAN_KEYWORD_NUM]; + char* config; ++ char *blsdir; + char* menu; + char* section; + int help; +@@ -197,6 +199,14 @@ get_command_line(int argc, char* argv[], struct command_line* line) + } else + cmdline.config = optarg; + break; ++ case 'b': ++ if (cmdline.blsdir != NULL) { ++ error_reason("Option 'blsdir' specified more " ++ "than once"); ++ rc = -1; ++ } else ++ cmdline.blsdir = optarg; ++ break; + case 'm': + if (cmdline.menu != NULL) { + error_reason("Option 'menu' specified more " +@@ -1731,6 +1741,7 @@ get_job_from_config_file(struct command_line* cmdline, struct job_data* job) + struct scan_token* scan; + struct scan_token* new_scan; + char* filename; ++ char *blsdir; + char* source; + int rc, scan_size; + +@@ -1755,6 +1766,17 @@ get_job_from_config_file(struct command_line* cmdline, struct job_data* job) + error_text("Config file '%s'", filename); + return scan_size; + } ++ /* Check if a BLS directory was provided on command line */ ++ if (cmdline->blsdir != NULL) { ++ blsdir = cmdline->blsdir; ++ } else { ++ blsdir = ZIPL_DEFAULT_BLSDIR; ++ } ++ rc = scan_bls(blsdir, &scan, scan_size); ++ if (rc) { ++ error_text("BLS parsing '%s'", blsdir); ++ return rc; ++ } + if ((cmdline->menu == NULL) && (cmdline->section == NULL)) { + rc = scan_check_defaultboot(scan); + if (rc < 0) { +diff --git a/zipl/src/scan.c b/zipl/src/scan.c +index adb288e0626..fe72e9ab13d 100644 +--- a/zipl/src/scan.c ++++ b/zipl/src/scan.c +@@ -16,13 +16,21 @@ + #define __USE_ISOC99 + #endif + ++/* Need GNU function strverscmp() in dirent.h */ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE ++#endif ++ + #include ++#include + #include + #include + #include + #include + #include + ++#include ++ + #include "lib/util_base.h" + + #include "boot.h" +@@ -633,6 +641,177 @@ scan_file(const char* filename, struct scan_token** token) + } + + ++static int ++bls_filter(const struct dirent *ent) ++{ ++ int offset = strlen(ent->d_name) - strlen(".conf"); ++ ++ if (offset < 0) ++ return 0; ++ ++ return strncmp(ent->d_name + offset, ".conf", strlen(".conf")) == 0; ++} ++ ++ ++static int ++bls_sort(const struct dirent **ent_a, const struct dirent **ent_b) ++{ ++ return strverscmp((*ent_a)->d_name, (*ent_b)->d_name); ++} ++ ++ ++static int ++scan_append_section_heading(struct scan_token* scan, int* index, char* name); ++static int ++scan_append_keyword_assignment(struct scan_token* scan, int* index, ++ enum scan_keyword_id id, char* value); ++ ++ ++static int ++scan_bls_field(struct misc_file_buffer *file, struct scan_token* scan, ++ int* index) ++{ ++ int current; ++ int key_start, key_end; ++ int val_start, val_end; ++ char *val; ++ ++ for (key_start = file->pos; ; file->pos++) { ++ current = misc_get_char(file, 0); ++ ++ if (isblank(current)) { ++ key_end = file->pos; ++ skip_blanks(file); ++ val_start = file->pos; ++ break; ++ } ++ ++ if (!isalnum(current) && current != '_' && current != '-') ++ return -1; ++ } ++ ++ for (; ; file->pos++) { ++ current = misc_get_char(file, 0); ++ ++ if (current == '\n' || current == EOF) ++ break; ++ } ++ ++ val_end = file->pos; ++ file->buffer[key_end] = '\0'; ++ file->buffer[val_end] = '\0'; ++ ++ if (strncmp("version", &file->buffer[key_start], key_end - key_start) == 0) { ++ scan_append_section_heading(scan, index, &file->buffer[val_start]); ++ } ++ ++ if (strncmp("linux", &file->buffer[key_start], key_end - key_start) == 0) { ++ misc_asprintf(&val, "%s", &file->buffer[val_start]); ++ scan_append_keyword_assignment(scan, index, scan_keyword_image, val); ++ free(val); ++ } ++ ++ if (strncmp("options", &file->buffer[key_start], key_end - key_start) == 0) { ++ scan_append_keyword_assignment(scan, index, scan_keyword_parameters, ++ &file->buffer[val_start]); ++ } ++ ++ if (strncmp("initrd", &file->buffer[key_start], key_end - key_start) == 0) { ++ misc_asprintf(&val, "%s", &file->buffer[val_start]); ++ scan_append_keyword_assignment(scan, index, scan_keyword_ramdisk, val); ++ free(val); ++ } ++ ++ return 0; ++} ++ ++ ++int ++scan_bls(const char* blsdir, struct scan_token** token, int scan_size) ++{ ++ int count = 0; ++ int size, remaining = 0, n, current, rc = -1; ++ struct scan_token* buffer; ++ struct scan_token* array = *token; ++ struct dirent** bls_entries; ++ struct misc_file_buffer file; ++ struct stat sb; ++ char filename[PATH_MAX]; ++ ++ if (!(stat(blsdir, &sb) == 0 && S_ISDIR(sb.st_mode))) ++ return 0; ++ ++ n = scandir(blsdir, &bls_entries, bls_filter, bls_sort); ++ if (n <= 0) ++ return n; ++ ++ while (array[count].id != 0) ++ count++; ++ ++ remaining = scan_size - count; ++ ++ if (remaining < n) { ++ size = scan_size - remaining + n; ++ buffer = (struct scan_token *)misc_malloc(size * sizeof(struct scan_token)); ++ if (!buffer) ++ goto err; ++ memset(buffer, 0, size * sizeof(struct scan_token)); ++ memcpy(buffer, array, count * sizeof(struct scan_token)); ++ } else { ++ buffer = array; ++ } ++ ++ while (n--) { ++ sprintf(filename, "%s/%s", blsdir, bls_entries[n]->d_name); ++ printf("Using BLS config file '%s'\n", filename); ++ ++ rc = misc_get_file_buffer(filename, &file); ++ if (rc) ++ goto err; ++ ++ while ((size_t)file.pos < file.length) { ++ current = misc_get_char(&file, 0); ++ switch (current) { ++ case '#': ++ file.pos++; ++ skip_line(&file); ++ break; ++ case EOF: ++ break; ++ case '\t': ++ case '\0': ++ case ' ': ++ file.pos++; ++ break; ++ default: ++ rc = scan_bls_field(&file, buffer, &count); ++ if (rc) { ++ error_reason("Incorrect BLS field in " ++ "config file %s\n", filename); ++ goto err; ++ } ++ break; ++ } ++ } ++ ++ misc_free_file_buffer(&file); ++ free(bls_entries[n]); ++ } ++ ++ *token = buffer; ++ rc = 0; ++err: ++ if (n > 0) { ++ do { ++ free(bls_entries[n]); ++ } while (n-- > 0); ++ } ++ ++ free(bls_entries); ++ return rc; ++} ++ ++ + /* Search scanned tokens SCAN for a section/menu heading (according to + * TYPE) of the given NAME, beginning at token OFFSET. Return the index of + * the section/menu heading on success, a negative value on error. */ +diff --git a/zipl/src/zipl.c b/zipl/src/zipl.c +index 1eaa82b9f43..65eefdb2d99 100644 +--- a/zipl/src/zipl.c ++++ b/zipl/src/zipl.c +@@ -54,6 +54,7 @@ static const char* usage_text[] = { + "-h, --help Print this help, then exit", + "-v, --version Print version information, then exit", + "-c, --config CONFIGFILE Read configuration from CONFIGFILE", ++"-b, --blsdir BLSDIR Parse BootLoaderSpec files from BLSDIR", + "-t, --target TARGETDIR Write bootmap file to TARGETDIR and install", + " bootloader on device containing TARGETDIR", + " --targetbase BASEDEVICE Install bootloader on BASEDEVICE", +-- +2.17.0 + diff --git a/s390-tools-zipl-Return-number-allocated-tokens.patch b/s390-tools-zipl-Return-number-allocated-tokens.patch new file mode 100644 index 0000000..aeb8075 --- /dev/null +++ b/s390-tools-zipl-Return-number-allocated-tokens.patch @@ -0,0 +1,81 @@ +From ccc3beeb9920ba2a1087ae828b9c1de1fc5fb135 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Wed, 2 May 2018 12:26:49 +0200 +Subject: [PATCH] zipl: Return number of allocated tokens in scan_file() + +The function returns 0 on success and a negative number on error but is +useful to know how many tokens were allocated. This will be used by the +BLS parsing code to determine if needs to allocate mor tokens or not to +parse the BLS fragments. + +Signed-off-by: Javier Martinez Canillas +--- + zipl/src/job.c | 8 ++++---- + zipl/src/scan.c | 16 +++++++++------- + 2 files changed, 13 insertions(+), 11 deletions(-) + +diff --git a/zipl/src/job.c b/zipl/src/job.c +index b06a4824333..9d5f00b6bdc 100644 +--- a/zipl/src/job.c ++++ b/zipl/src/job.c +@@ -1732,7 +1732,7 @@ get_job_from_config_file(struct command_line* cmdline, struct job_data* job) + struct scan_token* new_scan; + char* filename; + char* source; +- int rc; ++ int rc, scan_size; + + /* Read configuration file */ + if (cmdline->config != NULL) { +@@ -1750,10 +1750,10 @@ get_job_from_config_file(struct command_line* cmdline, struct job_data* job) + source = ""; + } + printf("Using config file '%s'%s\n", filename, source); +- rc = scan_file(filename, &scan); +- if (rc) { ++ scan_size = scan_file(filename, &scan); ++ if (scan_size <= 0) { + error_text("Config file '%s'", filename); +- return rc; ++ return scan_size; + } + if ((cmdline->menu == NULL) && (cmdline->section == NULL)) { + rc = scan_check_defaultboot(scan); +diff --git a/zipl/src/scan.c b/zipl/src/scan.c +index 7465d6ccb6c..adb288e0626 100644 +--- a/zipl/src/scan.c ++++ b/zipl/src/scan.c +@@ -538,9 +538,9 @@ scan_free(struct scan_token* array) + + #define INITIAL_ARRAY_LENGTH 40 + +-/* Scan file FILENAME for tokens. Upon success, return zero and set TOKEN +- * to point to a NULL-terminated array of scan_tokens, i.e. the token id +- * of the last token is 0. Return non-zero otherwise. */ ++/* Scan file FILENAME for tokens. Upon success, return the number allocated ++ * tokens and set TOKEN to point to a NULL-terminated array of scan_tokens, ++ * i.e. the token id of the last token is 0. Return non-zero otherwise. */ + int + scan_file(const char* filename, struct scan_token** token) + { +@@ -623,11 +623,13 @@ scan_file(const char* filename, struct scan_token** token) + } + } + misc_free_file_buffer(&file); +- if (rc) ++ if (rc) { + scan_free(array); +- else +- *token = array; +- return rc; ++ return rc; ++ } ++ ++ *token = array; ++ return size; + } + + +-- +2.17.0 + diff --git a/s390-tools-zipl-invert-script-options.patch b/s390-tools-zipl-invert-script-options.patch new file mode 100644 index 0000000..93d5cc7 --- /dev/null +++ b/s390-tools-zipl-invert-script-options.patch @@ -0,0 +1,84 @@ +From 2faae5cf51c49e3f166b8526eee276dab2fe7308 Mon Sep 17 00:00:00 2001 +From: Javier Martinez Canillas +Date: Wed, 30 May 2018 14:33:25 +0200 +Subject: [PATCH] zipl-switch-to-blscfg: invert ignore-default and + use-version-name options + +These options were added because the zipl maintainers wanted a different +default behaviour for the migration script than the one we use. Instead +of requiring to always use these options, just invert the logic for us. + +Signed-off-by: Javier Martinez Canillas +--- + scripts/zipl-switch-to-blscfg | 16 +++++++++------- + scripts/zipl-switch-to-blscfg.1 | 8 ++++---- + 2 files changed, 13 insertions(+), 11 deletions(-) + +diff --git a/scripts/zipl-switch-to-blscfg b/scripts/zipl-switch-to-blscfg +index 871935c783f..d8d5eca5867 100755 +--- a/scripts/zipl-switch-to-blscfg ++++ b/scripts/zipl-switch-to-blscfg +@@ -57,14 +57,14 @@ Options: + --backup-suffix=SUFFIX suffix used for backup files, defaults to .bak + --bls-directory=DIR path to generate BLS files, defaults to /boot/loader/entries + --config-file=FILE path to zipl configuration file, defaults to /etc/zipl.conf +- --ignore-default ignore the default option from the zipl configuration file +- --use-version-name use the section kernel version as the BLS file name ++ --leave-default leave the default option from the zipl configuration file ++ --use-section-name use the section name as the BLS file name + + EOF + } + + OPTS="$(getopt -o hv --long help,version,backup-suffix:,bls-directory:,config-file:,\ +-ignore-default,use-version-name -n \'$SCRIPTNAME\' -- "$@")" ++leave-default,use-section-name -n \'$SCRIPTNAME\' -- "$@")" + eval set -- "$OPTS" + + BACKUP_SUFFIX=.bak +@@ -73,6 +73,8 @@ CMDLINE_LINUX_DEBUG=" systemd.log_level=debug systemd.log_target=kmsg" + LINUX_DEBUG_VERSION_POSTFIX="_with_debugging" + LINUX_DEBUG_TITLE_POSTFIX=" with debugging" + CONFIG="/etc/zipl.conf" ++ignore_default=true ++version_name=true + + while [ ${#} -gt 0 ]; do + case "$1" in +@@ -96,11 +98,11 @@ while [ ${#} -gt 0 ]; do + CONFIG=${2} + shift + ;; +- --ignore-default) +- ignore_default=true ++ --leave-default) ++ ignore_default=false + ;; +- --use-version-name) +- version_name=true ++ --use-section-name) ++ version_name=false + ;; + --) + shift +diff --git a/scripts/zipl-switch-to-blscfg.1 b/scripts/zipl-switch-to-blscfg.1 +index 6bd14d00d14..71b904ffd1c 100644 +--- a/scripts/zipl-switch-to-blscfg.1 ++++ b/scripts/zipl-switch-to-blscfg.1 +@@ -37,9 +37,9 @@ The DIRECTORY where the BLS fragments will be generated. The directory is create + The FILE used for zipl configuration file, defaults to /etc/zipl.conf. + + .TP +-\fB\-\-ignore-default\fP +-Ignore the default option from the zipl configuration file ++\fB\-\-leave-default\fP ++Leave the default option from the zipl configuration file + + .TP +-\fB\-\-use-version-name\fP +-Use the section kernel version as the BLS file name ++\fB\-\-use-section-name\fP ++Use the section name as the BLS file name +-- +2.17.0 + diff --git a/s390utils.spec b/s390utils.spec index 81d16e8..c744efb 100644 --- a/s390utils.spec +++ b/s390utils.spec @@ -5,7 +5,7 @@ Name: s390utils Summary: Utilities and daemons for IBM z Systems Group: System Environment/Base Version: 2.4.0 -Release: 1%{?dist} +Release: 2%{?dist} Epoch: 2 License: MIT ExclusiveArch: s390 s390x @@ -27,9 +27,17 @@ Source15: device_cio_free.service Source16: ccw_init Source17: ccw.udev Source21: normalize_dasd_arg +Source22: 20-zipl-kernel.install +Source23: 52-zipl-rescue.install +Source24: 91-zipl.install # https://bugzilla.redhat.com/show_bug.cgi?id=1566140 Patch0: s390-tools-2.3.0-zipl-pie.patch +# https://github.com/ibm-s390-tools/s390-tools/pull/28 +Patch1: s390-tools-zipl-Return-number-allocated-tokens.patch +Patch2: s390-tools-zipl-Add-BootLoaderSpec-support.patch +Patch3: s390-tools-add-zipl-switch-to-blscfg-script.patch +Patch4: s390-tools-zipl-invert-script-options.patch Patch1000: cmsfs-1.1.8-warnings.patch Patch1001: cmsfs-1.1.8-kernel26.patch @@ -57,6 +65,10 @@ be used together with the zSeries (s390) Linux kernel and device drivers. # Fedora/RHEL changes %patch0 -p1 -b .zipl-pie +%patch1 -p1 -b .number-allocated-tokens +%patch2 -p1 -b .add-BootLoaderSpec-support +%patch3 -p1 -b .add-zipl-switch-to-blscfg +%patch4 -p1 -b .zipl-invert-script-options # # cmsfs @@ -140,6 +152,14 @@ install -p -m 644 systemd/cpi.service $RPM_BUILD_ROOT%{_unitdir}/ install -Dp -m 644 etc/udev/rules.d/*.rules $RPM_BUILD_ROOT%{_udevrulesdir} +# Install kernel-install scripts +install -d -m 0755 %{buildroot}%{_prefix}/lib/kernel/install.d/ +install -D -m 0755 -t %{buildroot}%{_prefix}/lib/kernel/install.d/ %{SOURCE22} +install -D -m 0755 -t %{buildroot}%{_prefix}/lib/kernel/install.d/ %{SOURCE23} +install -D -m 0755 -t %{buildroot}%{_prefix}/lib/kernel/install.d/ %{SOURCE24} +install -d -m 0755 %{buildroot}%{_sysconfdir}/kernel/install.d/ +install -m 0644 /dev/null %{buildroot}%{_sysconfdir}/kernel/install.d/20-grubby.install + # cmsfs tools must be available in /sbin for f in cat lst vol cp ck; do install -p -m 755 cmsfs-%{cmsfsver}/cmsfs${f} $RPM_BUILD_ROOT%{_sbindir} @@ -382,6 +402,7 @@ For more information refer to the following publications: %{_sbindir}/zfcpdbf %{_sbindir}/zgetdump %{_sbindir}/zipl +%{_sbindir}/zipl-switch-to-blscfg %{_sbindir}/znetconf %{_bindir}/lscpumf %{_bindir}/dump2tar @@ -398,6 +419,7 @@ For more information refer to the following publications: %{_mandir}/man1/lscpumf.1* %{_mandir}/man1/vmconvert.1* %{_mandir}/man1/zfcpdbf.1* +%{_mandir}/man1/zipl-switch-to-blscfg.1* %{_mandir}/man1/zkey.1* %{_mandir}/man4/prandom.4* %{_mandir}/man5/zipl.conf.5* @@ -467,6 +489,10 @@ For more information refer to the following publications: %{_udevrulesdir}/60-readahead.rules %{_udevrulesdir}/81-ccw.rules %{_udevrulesdir}/90-cpi.rules +%{_sysconfdir}/kernel/install.d/20-grubby.install +%{_prefix}/lib/kernel/install.d/20-zipl-kernel.install +%{_prefix}/lib/kernel/install.d/52-zipl-rescue.install +%{_prefix}/lib/kernel/install.d/91-zipl.install # src_vipa %{_bindir}/src_vipa.sh @@ -788,6 +814,10 @@ User-space development files for the s390/s390x architecture. %changelog +* Thu May 24 2018 Javier Martinez Canillas - 2:2.4.0-2 +- zipl: Add BootLoaderSpec support +- Add kernel-install scripts to create BLS fragment files + * Wed May 09 2018 Dan HorĂ¡k - 2:2.4.0-1 - rebased to 2.4.0