zdev/dracut: fix kdump by only activating required devices

This prevents out-of-memory (OOM) situations in the kdump crashkernel
environment.

Please note that the new dracut module 95zdev-kdump and the new library
zdev-lib.sh need to be packaged into the same (core) (sub)package as
95zdev.

This patch introduces a new dracut module "zdev-kdump", which is used
instead of module "zdev" when building a kdump initrd:

1. Ignore all persistently configured block devices and disable zfcp auto
LUN scanning => minimize the number of SCSI devices enabled during kdump.

2. Do not rely on chzdev's persistent configuration => work with systems
that do not use chzdev for persistent device configuration.

The detection of kdump is based on strict hostonly mode and on $IN_KDUMP.
See also
https://src.fedoraproject.org/rpms/kexec-tools commit
4eedcae5e154 ("dracut-module-setup.sh: don't include multipath-hostonly")
and https://github.com/dracutdevs/dracut commits
35e86ac117ac ("Merge 90-multipath-hostonly and 90-multipath")
a695250ec7db ("Introduce tri-state hostonly mode")
and
https://src.fedoraproject.org/rpms/kexec-tools/blob/rawhide/f/mkdumprd#_17
https://src.fedoraproject.org/rpms/kexec-tools/blob/rawhide/f/dracut-module-setup.sh#_23.
The detection of kdump is also based on kdump_needed() in
https://github.com/openSUSE/kdump/blob/master/dracut/module-setup.sh.

Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Steffen Maier <maier@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Steffen Maier
2023-01-19 19:09:04 +01:00
committed by Jan Höppner
parent f2c82bf2b5
commit 73c46a3056
4 changed files with 134 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
#!/bin/bash
#
# Copyright IBM Corp. 2023
#
# s390-tools is free software; you can redistribute it and/or modify
# it under the terms of the MIT license. See LICENSE for details.
#
#
# 95zdev-kdump/module_setup.sh
# This module installs configuration files (udev rules and modprobe.conf
# files) required to enable the kdump target on s390.
#
# called by dracut
check() {
local _arch=${DRACUT_ARCH:-$(uname -m)}
# Ensure that we're running on s390
[ "$_arch" = "s390" -o "$_arch" = "s390x" ] || return 1
source "$moddir/../95zdev/zdev-lib.sh"
# Ensure this module is only included when building kdump initrd
is_kdump || return 1
# Ensure that required tools are available
require_binaries chzdev || return 1
return 0
}
# called by dracut
depends() {
return 0
}
# called by dracut
installkernel() {
# Add modules for all device types supported by chzdev (required for
# auto-configuration)
instmods ctcm lcs qeth qeth_l2 qeth_l3 dasd_mod dasd_eckd_mod dasd_fba_mod \
dasd_diag_mod zfcp
}
# called by dracut
install() {
local _tempfile
# Obtain kdump target device configuration
_tempfile=$(mktemp --tmpdir dracut-zdev.XXXXXX)
# work with systems that are not based on chzdev persistent config
local _configuration="--active"
# disable zfcp auto LUN scan to prevent OOM situations on systems with
# many zFCP LUNs
inst_dir /etc/modprobe.d
chzdev zfcp --type "allow_lun_scan=0" --persistent \
--base "/etc=$initdir/etc" --yes --quiet --no-root-update \
--force >/dev/null
# drop /etc/zfcp.conf from dracut module 95zfcp
echo "rd.zfcp.conf=0" > "$initdir/etc/cmdline.d/00-no-zfcp-conf.conf"
# => only activate individual zfcp paths found as required below
function check_zdev() {
local _dev=$1
local _devsysfs _bdevpath
_devsysfs=$(
cd -P /sys/dev/block/"$_dev" && echo "$PWD"
)
_bdevpath=/dev/${_devsysfs##*/}
# do not export device type information potentially unknown on import
chzdev --export - "$_configuration" --by-node "$_bdevpath" --quiet \
2>/dev/null >> "$_tempfile"
}
for_each_host_dev_and_slaves_all check_zdev
sed -i -e 's/^\[active /\[persistent /' "$_tempfile"
# Apply via --import to prevent other devices from being configured
chzdev --import "$_tempfile" --persistent --base "/etc=$initdir/etc" \
--yes --quiet --no-root-update --force >/dev/null
rm -f "$_tempfile"
# these are purely generated udev rules so we have to glob expand
# within $initdir and strip the $initdir prefix for mark_hostonly
local -a _array
local _nullglob=$(shopt -p nullglob)
shopt -u nullglob
readarray -t _array < \
<(ls -1 $initdir/etc/udev/rules.d/41-*.rules 2> /dev/null)
[[ ${#_array[@]} -gt 0 ]] && mark_hostonly "${_array[@]#$initdir}"
readarray -t _array < \
<(ls -1 $initdir/etc/modprobe.d/s390x-*.conf 2> /dev/null)
[[ ${#_array[@]} -gt 0 ]] && mark_hostonly "${_array[@]#$initdir}"
$_nullglob
return 0
}

View File

@@ -19,6 +19,12 @@ check() {
# Ensure that we're running on s390
[ "$_arch" = "s390" -o "$_arch" = "s390x" ] || return 1
source "$moddir/zdev-lib.sh"
# Leave kdump device configuration to module zdev-kdump to
# ensure a minimal device footprint
is_kdump && return 1
# Ensure that required tools are available
require_binaries chzdev lszdev /lib/s390-tools/zdev_id || return 1

View File

@@ -0,0 +1,24 @@
#
# Copyright IBM Corp. 2023
#
# s390-tools is free software; you can redistribute it and/or modify
# it under the terms of the MIT license. See LICENSE for details.
#
#
# 95zdev/zdev-lib.sh
# Common shell library functionality for 95zdev and 95zdev-kdump.
#
is_kdump() {
# https://src.fedoraproject.org/rpms/kexec-tools/c/4eedcae5e1540690a3761857fe2e692774c44960
# https://src.fedoraproject.org/rpms/kexec-tools/blob/rawhide/f/mkdumprd
# https://src.fedoraproject.org/rpms/kexec-tools/blob/rawhide/f/dracut-module-setup.sh
if [[ $hostonly && "$hostonly_mode" == "strict" && -n "$IN_KDUMP" ]]; then
return 0
fi
# https://github.com/openSUSE/kdump/blob/master/dracut/module-setup.sh
if [[ " $dracutmodules $add_dracutmodules $force_add_dracutmodules " == *\ kdump\ * ]]; then
return 0
fi
return 1
}

View File

@@ -2,6 +2,7 @@
include ../../common.mak
ZDEVDIR := 95zdev
ZDEVKDUMPDIR := 95zdev-kdump
# HAVE_DRACUT
#
@@ -19,5 +20,9 @@ install:
$(INSTALL) -m 755 -d $(DESTDIR)$(DRACUTMODDIR)/$(ZDEVDIR)
$(INSTALL) -m 755 $(ZDEVDIR)/module-setup.sh \
$(ZDEVDIR)/parse-zdev.sh \
$(ZDEVDIR)/zdev-lib.sh \
$(DESTDIR)$(DRACUTMODDIR)/$(ZDEVDIR)/
$(INSTALL) -m 755 -d $(DESTDIR)$(DRACUTMODDIR)/$(ZDEVKDUMPDIR)
$(INSTALL) -m 755 $(ZDEVKDUMPDIR)/module-setup.sh \
$(DESTDIR)$(DRACUTMODDIR)/$(ZDEVKDUMPDIR)/
endif