initramfs: Switch to the alpm-hooks approach, supporting both initcpio/dracut

This is one of the major changes/refactors so far, touches a lot of
files, and more important, it completely changes some premises.
With this patch, we now support fully both dracut-based and initcpio
initramfs systems.

For that to happen, we needed to decouple the initramfs creation from
scripts, by using alpm-hooks. These hooks allow scripts to be run on
events like kernel package installation or in the installation of the very
package responsible to create the initramfs image. We still have the
"kdump-load create-initrd" command though.

One of the biggest modifications here was in the Makefile, that now
composes multiple files by changing keywords (like INITRD) to the
respective initramfs system (dracut or mkinitcpio). Notice that this
brought some extra complexity to the package.

The logic used for supporting both initramfs systems was basically
de-duplicate all possible code (having dup code in common files),
using Makefile tricks to merge such files and have the unique
bits in dracut/initcpio specific files. We currently support dracut
and both mkinitcpio and mkinitcpio-git packages.

Caveats: currently the initramfs specific package removal is not handled
here. So, if the user has dracut and installs kdump, we install the
dracut hooks. In case this user decides to remove dracut and installs
mkinitcpio, we install the mkinitcpio hooks and all should work, but
the previous dracut hooks installed are not unistalled by us; likely
the dracut package removal would drop the files itself.

This was a deliberate move to avoid even more alpm-hooks, should be
a rare case and as said, the package removal should clear the files
itself, without requiring our interaction. Also, by using the
alpm-hooks, we see "errors" (warnings really) about the other
initramfs package not being present - not sure if it's possible to
disable this behavior.

Finally, while at it:

* Added a new approach to dracut initramfs creation to pick the most
common block drivers - since it's hostonly, it doesn't add the ones
that aren't loaded, hence image is not bloated by that.

* Chenged the "command -v makedumpfile" validation to something
more elegant - thanks for the suggestion Clayton (@craftyguy).

Signed-off-by: Guilherme G. Piccoli <gpiccoli@igalia.com>
This commit is contained in:
Guilherme G. Piccoli
2022-12-21 13:17:29 -03:00
parent e24d6d9b46
commit b834754cf9
13 changed files with 348 additions and 76 deletions

View File

@ -0,0 +1,34 @@
# Functions to deal with dracut specifics, both for building
# the initramfs for dracut users, but also with regards to
# installing dracut specific hooks/scripts.
#
# IMPORTANT: it is assumed that kdump configuration was loaded
# before running any of these functions!
#
create_initramfs_dracut() {
rm -f "${MOUNT_FOLDER}/kdump-initrd-$1.img"
DRACUT_NO_XATTR=1 dracut --no-early-microcode --host-only -q -m\
"bash systemd systemd-initrd systemd-sysusers modsign dbus-daemon kdump dbus udev-rules dracut-systemd base fs-lib shutdown"\
--kver "$1" "${MOUNT_FOLDER}/kdump-initrd-$1.img"
if [ -s "${MOUNT_FOLDER}/kdump-initrd-$1.img" ]; then
logger "kdump: created dracut minimal initramfs"
fi
}
dracut_installation() {
HOOKS_DIR="/usr/lib/kdump/dracut/"
DRACUT_DIR="$(pkg-config --variable=dracutmodulesdir dracut 2>/dev/null)"
if [ -z "${DRACUT_DIR}" ]; then
DRACUT_DIR="/usr/lib/dracut/modules.d/"
fi
if [ ! -d "${DRACUT_DIR}"/55kdump/ ]; then
install -D -m0755 "${HOOKS_DIR}"/kdump-collect.sh "${DRACUT_DIR}"/55kdump/kdump-collect.sh
install -D -m0755 "${HOOKS_DIR}"/module-setup.sh "${DRACUT_DIR}"/55kdump/module-setup.sh
logger "kdump: dracut hooks/scripts installed"
fi
}

View File

@ -0,0 +1,10 @@
#!/bin/bash
#
# SPDX-License-Identifier: LGPL-2.1+
#
# Copyright (c) 2021 Valve.
# Maintainer: Guilherme G. Piccoli <gpiccoli@igalia.com>
#
# Kdump-initrd module construction/inclusion script for
# Dracut-based initramfs.
#

View File

@ -0,0 +1,76 @@
# Only include kdump if it is explicitly asked in the argument list
check() {
return 255
}
installkernel() {
load_kdump_config
# First clear all unnecessary firmwares/drivers added by drm in order
# to reduce the size of the minimal initramfs being created - kdump
# is an non-graphical environment. This should have been already done
# via dracut cmdline arguments, but play safe and delete here as well.
# Our list includes the most common FWs/drivers (amd, i915, nvidia).
rm -rf "$initdir"/usr/lib/firmware/{amdgpu,i915,nvidia,radeon}
rm -rf "$initdir"/usr/lib/modules/*/kernel/drivers/gpu/drm/{amd,i915,nouveau,radeon}
FSMOD="$(findmnt -n -o FSTYPE --target "${MOUNT_FOLDER}")"
if [ -z "${FSMOD}" ]; then
logger "kdump: error on filesystem discovery"
exit 1
fi
instmods "${FSMOD}"
# We try here to be comprehensive and include the most common
# block modules to allow mounting the target device - notice
# that since we use hostonly, only the ones that make sense would
# get added, hence this list won't bloat the minimal image!
instmods aacraid
instmods ahci
instmods hpsa
instmods megaraid_sas
instmods mpt3sas
instmods nvme
instmods virtio_blk
instmods virtio-scsi
}
install() {
# A valid makedumpfile is essential for the kdump initrd creation.
if ! command -v makedumpfile 1>/dev/null; then
logger "kdump: failed to create dracut initrd, makedumpfile is missing"
exit 1
fi
load_kdump_config
# Install necessary binaries
inst date
inst sync
inst makedumpfile
# Copying kdump config/lib files is essential for a functional kdump.
cp -LR --preserve=all /usr/share/kdump.d/ "$initdir"/usr/share/
cp -LR --preserve=all /usr/lib/kdump/ "$initdir"/usr/lib/
# Finally, we need to derive the proper place to save the dump from the
# config files, in a way that makes possible to mount it in early boot.
DEVNODE="$(findmnt -n -o SOURCE --target "${MOUNT_FOLDER}")"
if [ -z "${DEVNODE}" ]; then
logger "kdump: error on devnode discovery"
exit 1
fi
echo "${DEVNODE}" > "$initdir"/usr/lib/kdump/kdump.mnt
TGT="$(findmnt -n -o TARGET --target "${MOUNT_FOLDER}")"
if [ -z "${TGT}" ]; then
logger "kdump: error on base folder discovery"
exit 1
fi
BASE_FLD="${MOUNT_FOLDER#*$TGT}"
echo "${BASE_FLD}" > "$initdir"/usr/lib/kdump/kdump.dir
inst_hook pre-mount 01 "$moddir/kdump-collect.sh"
}