From 5c1b257faf87cb4f93aee8866f45a8cb98230af9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 18 Jan 2022 17:40:13 +0100 Subject: [PATCH 1/5] kernel-install: add new variable $KERNEL_INSTALL_INITRD_GENERATOR The idea is that when not set, we do whatever we did in the past. But with a new setting of initrd_generator=mkosi-initrd, mkosi-initrd will generate an initrd. --- man/kernel-install.xml | 6 +++++- src/kernel-install/install.conf | 1 + src/kernel-install/kernel-install | 5 ++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/man/kernel-install.xml b/man/kernel-install.xml index 83255bb932..bb76074d2e 100644 --- a/man/kernel-install.xml +++ b/man/kernel-install.xml @@ -171,11 +171,15 @@ KERNEL_INSTALL_BOOT_ROOT= is set for the plugins to the root directory (mount point, usually) of the hierarchy where boot-loader entries, kernel images, and associated resources should be placed. Can be overridden by setting BOOT_ROOT=. - KERNEL_INSTALL_LAYOUT=bls|other|... specifies the installation layout. + KERNEL_INSTALL_LAYOUT=bls|other|... is set for the plugins to specify the installation layout. Defaults to if $BOOT/MACHINE-ID exists, or otherwise. Additional layout names may be defined by convention. If a plugin uses a special layout, it's encouraged to declare its own layout name and configure layout= in install.conf upon initial installation. + KERNEL_INSTALL_INITRD_GENERATOR=... is set for plugins to select the initrd generator. + This should be configured as initrd_generator= in install.conf. + + bls diff --git a/src/kernel-install/install.conf b/src/kernel-install/install.conf index e4802e6fae..43b6e7d792 100644 --- a/src/kernel-install/install.conf +++ b/src/kernel-install/install.conf @@ -8,3 +8,4 @@ # See kernel-install(8) for details. #layout=bls|other|... +#initrd_generator=dracut|... diff --git a/src/kernel-install/kernel-install b/src/kernel-install/kernel-install index e56483ef96..fe457c1070 100755 --- a/src/kernel-install/kernel-install +++ b/src/kernel-install/kernel-install @@ -80,6 +80,9 @@ fi KERNEL_VERSION="$1" shift +layout= +initrd_generator= + if [ -r "/etc/kernel/install.conf" ]; then . /etc/kernel/install.conf elif [ -r "/usr/lib/kernel/install.conf" ]; then @@ -123,12 +126,12 @@ if [ -z "$layout" ]; then fi fi - ENTRY_DIR_ABS="$BOOT_ROOT/$MACHINE_ID/$KERNEL_VERSION" export KERNEL_INSTALL_MACHINE_ID="$MACHINE_ID" export KERNEL_INSTALL_BOOT_ROOT="$BOOT_ROOT" export KERNEL_INSTALL_LAYOUT="$layout" +export KERNEL_INSTALL_INITRD_GENERATOR="$initrd_generator" [ "$layout" = "bls" ] MAKE_ENTRY_DIR_ABS=$? From a520d5dddb991cd713392d4de0e342e312547a2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 19 Jan 2022 12:10:37 +0100 Subject: [PATCH 2/5] kernel-install: k-i already creates $ENTRY_DIR_ABS, no need to do it again --- src/kernel-install/90-loaderentry.install | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/kernel-install/90-loaderentry.install b/src/kernel-install/90-loaderentry.install index e588e72bf9..7b768457c1 100644 --- a/src/kernel-install/90-loaderentry.install +++ b/src/kernel-install/90-loaderentry.install @@ -78,12 +78,8 @@ else fi if ! [ -d "$ENTRY_DIR_ABS" ]; then - if [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ]; then - echo "+mkdir -v -p $ENTRY_DIR_ABS" - mkdir -v -p "$ENTRY_DIR_ABS" - else - mkdir -p "$ENTRY_DIR_ABS" - fi + echo "Error: entry directory '$ENTRY_DIR_ABS' does not exist" >&2 + exit 1 fi install -g root -o root -m 0644 "$KERNEL_IMAGE" "$ENTRY_DIR_ABS/linux" || { From 680cec6b4ddb356d7dd087b197718712cb5c1662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 19 Jan 2022 12:15:16 +0100 Subject: [PATCH 3/5] kernel-install: prefix errors with "Error:", exit immediately MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit kernel-install would continue after errors… We don't want this, as it makes the results totally unpredicatable. If we didn't install the kernel or didn't do some important part of the setup, let's just return an error and let the user deal with it. When looking at output, the error was often hard to distinguish, esp. with -v. Add "Error:" everywhere to make the output easier to parse. --- src/kernel-install/90-loaderentry.install | 10 +++++----- src/kernel-install/kernel-install | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/kernel-install/90-loaderentry.install b/src/kernel-install/90-loaderentry.install index 7b768457c1..6a396910cb 100644 --- a/src/kernel-install/90-loaderentry.install +++ b/src/kernel-install/90-loaderentry.install @@ -83,27 +83,27 @@ if ! [ -d "$ENTRY_DIR_ABS" ]; then fi install -g root -o root -m 0644 "$KERNEL_IMAGE" "$ENTRY_DIR_ABS/linux" || { - echo "Could not copy '$KERNEL_IMAGE' to '$ENTRY_DIR_ABS/linux'." >&2 + echo "Error: could not copy '$KERNEL_IMAGE' to '$ENTRY_DIR_ABS/linux'." >&2 exit 1 } shift "$INITRD_OPTIONS_SHIFT" for initrd; do [ -f "$initrd" ] || { - echo "Initrd '$initrd' not a file." >&2 + echo "Error: initrd '$initrd' not a file." >&2 exit 1 } initrd_basename="${initrd##*/}" [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && echo "Installing $ENTRY_DIR_ABS/$initrd_basename" install -g root -o root -m 0644 "$initrd" "$ENTRY_DIR_ABS/$initrd_basename" || { - echo "Could not copy '$initrd' to '$ENTRY_DIR_ABS/$initrd_basename'." >&2 + echo "Error: could not copy '$initrd' to '$ENTRY_DIR_ABS/$initrd_basename'." >&2 exit 1 } done mkdir -p "${LOADER_ENTRY%/*}" || { - echo "Could not create loader entry directory '${LOADER_ENTRY%/*}'." >&2 + echo "Error: could not create loader entry directory '${LOADER_ENTRY%/*}'." >&2 exit 1 } @@ -121,7 +121,7 @@ mkdir -p "${LOADER_ENTRY%/*}" || { [ $# -eq 0 ] && [ -f "$ENTRY_DIR_ABS/initrd" ] && echo "initrd $ENTRY_DIR/initrd" : } >"$LOADER_ENTRY" || { - echo "Could not create loader entry '$LOADER_ENTRY'." >&2 + echo "Error: could not create loader entry '$LOADER_ENTRY'." >&2 exit 1 } exit 0 diff --git a/src/kernel-install/kernel-install b/src/kernel-install/kernel-install index fe457c1070..a73a205d79 100755 --- a/src/kernel-install/kernel-install +++ b/src/kernel-install/kernel-install @@ -73,7 +73,7 @@ else fi if [ $# -lt 1 ]; then - echo "Not enough arguments" >&2 + echo "Error: not enough arguments" >&2 exit 1 fi @@ -150,12 +150,12 @@ IFS=" case "$COMMAND" in add) if [ $# -lt 1 ]; then - echo "Command 'add' requires a kernel image" >&2 + echo "Error: command 'add' requires a kernel image" >&2 exit 1 fi if ! [ -f "$1" ]; then - echo "Kernel image argument $1 not a file" >&2 + echo "Error: kernel image argument $1 not a file" >&2 exit 1 fi @@ -165,9 +165,9 @@ case "$COMMAND" in # to serve as the indication to use or to not use the BLS if [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ]; then echo "+mkdir -v -p $ENTRY_DIR_ABS" - mkdir -v -p "$ENTRY_DIR_ABS" + mkdir -v -p "$ENTRY_DIR_ABS" || exit 1 else - mkdir -p "$ENTRY_DIR_ABS" + mkdir -p "$ENTRY_DIR_ABS" || exit 1 fi fi @@ -196,7 +196,7 @@ case "$COMMAND" in ;; *) - echo "Unknown command '$COMMAND'" >&2 + echo "Error: unknown command '$COMMAND'" >&2 exit 1 ;; esac From 367165a4069ac0c04882a05a8a80f6afb1e42760 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 19 Jan 2022 12:20:22 +0100 Subject: [PATCH 4/5] kernel-install: add "$KERNEL_INSTALL_STAGING_AREA" directory The general approach of kernel-install was that each plugin would drop in some files into the entry directory. But this doesn't scale well, because if we have multiple initrd generators, or multiple initrds, each generator would need to recreate the logic to put the generated files in the right place. Also, effective cleanup is impossible if anything goes wrong on the way, so we could end up with unused files in $BOOT. So let's invert the process: plugins drop files into $KERNEL_INSTALL_STAGING_AREA, and at the end 90-loaderentry.install DTRT with those files. This allow new plugins like 50-mkosi-initrd.install to be significantly simpler. --- man/kernel-install.xml | 4 ++++ src/kernel-install/90-loaderentry.install | 13 ++++++++++--- src/kernel-install/kernel-install | 10 ++++++++++ 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/man/kernel-install.xml b/man/kernel-install.xml index bb76074d2e..685617863e 100644 --- a/man/kernel-install.xml +++ b/man/kernel-install.xml @@ -180,6 +180,10 @@ This should be configured as initrd_generator= in install.conf. + KERNEL_INSTALL_STAGING_AREA=... is set for plugins to a path to a directory. + Plugins may drop files in that directory, and they will be installed as part of the loader entry, based + on the file name and extension. + bls diff --git a/src/kernel-install/90-loaderentry.install b/src/kernel-install/90-loaderentry.install index 6a396910cb..0888c260e2 100644 --- a/src/kernel-install/90-loaderentry.install +++ b/src/kernel-install/90-loaderentry.install @@ -18,6 +18,8 @@ # You should have received a copy of the GNU Lesser General Public License # along with systemd; If not, see . +shopt -s nullglob + COMMAND="$1" KERNEL_VERSION="$2" ENTRY_DIR_ABS="$3" @@ -88,7 +90,8 @@ install -g root -o root -m 0644 "$KERNEL_IMAGE" "$ENTRY_DIR_ABS/linux" || { } shift "$INITRD_OPTIONS_SHIFT" -for initrd; do +# All files listed as arguments, and staged files called "initrd*" are installed as initrds. +for initrd in "$@" "${KERNEL_INSTALL_STAGING_AREA}"/initrd*; do [ -f "$initrd" ] || { echo "Error: initrd '$initrd' not a file." >&2 exit 1 @@ -114,11 +117,15 @@ mkdir -p "${LOADER_ENTRY%/*}" || { echo "machine-id $MACHINE_ID" echo "options $BOOT_OPTIONS" echo "linux $ENTRY_DIR/linux" - for initrd; do + + have_initrd= + for initrd in "${@}" "${KERNEL_INSTALL_STAGING_AREA}"/initrd*; do echo "initrd $ENTRY_DIR/${initrd##*/}" + have_initrd=yes done + # Try "initrd", generated by dracut in its kernel-install hook, if no initrds were supplied - [ $# -eq 0 ] && [ -f "$ENTRY_DIR_ABS/initrd" ] && echo "initrd $ENTRY_DIR/initrd" + [ -z "$have_initrd" ] && [ -f "$ENTRY_DIR_ABS/initrd" ] && echo "initrd $ENTRY_DIR/initrd" : } >"$LOADER_ENTRY" || { echo "Error: could not create loader entry '$LOADER_ENTRY'." >&2 diff --git a/src/kernel-install/kernel-install b/src/kernel-install/kernel-install index a73a205d79..8cfef3208d 100755 --- a/src/kernel-install/kernel-install +++ b/src/kernel-install/kernel-install @@ -128,10 +128,20 @@ fi ENTRY_DIR_ABS="$BOOT_ROOT/$MACHINE_ID/$KERNEL_VERSION" +# Provide a directory where to store generated initrds +cleanup() { + [ -n "$KERNEL_INSTALL_STAGING_AREA" ] && rm -rf "$KERNEL_INSTALL_STAGING_AREA" +} + +trap cleanup EXIT + +KERNEL_INSTALL_STAGING_AREA="$(mktemp -d -t -p /tmp kernel-install.staging.XXXXXXX)" + export KERNEL_INSTALL_MACHINE_ID="$MACHINE_ID" export KERNEL_INSTALL_BOOT_ROOT="$BOOT_ROOT" export KERNEL_INSTALL_LAYOUT="$layout" export KERNEL_INSTALL_INITRD_GENERATOR="$initrd_generator" +export KERNEL_INSTALL_STAGING_AREA [ "$layout" = "bls" ] MAKE_ENTRY_DIR_ABS=$? From 29f604131b2c0b82dca7d6ffaa5e6bc6a253620d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 19 Jan 2022 14:03:24 +0100 Subject: [PATCH 5/5] kernel-install: add missing log line --- src/kernel-install/90-loaderentry.install | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/kernel-install/90-loaderentry.install b/src/kernel-install/90-loaderentry.install index 0888c260e2..3edefdefb4 100644 --- a/src/kernel-install/90-loaderentry.install +++ b/src/kernel-install/90-loaderentry.install @@ -40,6 +40,8 @@ fi case "$COMMAND" in remove) + [ "$KERNEL_INSTALL_VERBOSE" -gt 0 ] && \ + echo "Removing $BOOT_ROOT/loader/entries/$MACHINE_ID-$KERNEL_VERSION*.conf" exec rm -f \ "$BOOT_ROOT/loader/entries/$MACHINE_ID-$KERNEL_VERSION.conf" \ "$BOOT_ROOT/loader/entries/$MACHINE_ID-$KERNEL_VERSION+"*".conf"