From 73c46a30563d0e562d567fe90a43214a437d1909 Mon Sep 17 00:00:00 2001 From: Steffen Maier Date: Thu, 19 Jan 2023 19:09:04 +0100 Subject: [PATCH] zdev/dracut: fix kdump by only activating required devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: Steffen Maier Signed-off-by: Jan Höppner --- zdev/dracut/95zdev-kdump/module-setup.sh | 99 ++++++++++++++++++++++++ zdev/dracut/95zdev/module-setup.sh | 6 ++ zdev/dracut/95zdev/zdev-lib.sh | 24 ++++++ zdev/dracut/Makefile | 5 ++ 4 files changed, 134 insertions(+) create mode 100755 zdev/dracut/95zdev-kdump/module-setup.sh create mode 100644 zdev/dracut/95zdev/zdev-lib.sh diff --git a/zdev/dracut/95zdev-kdump/module-setup.sh b/zdev/dracut/95zdev-kdump/module-setup.sh new file mode 100755 index 00000000..ad8e3093 --- /dev/null +++ b/zdev/dracut/95zdev-kdump/module-setup.sh @@ -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 +} diff --git a/zdev/dracut/95zdev/module-setup.sh b/zdev/dracut/95zdev/module-setup.sh index 84d8933f..1bae11ff 100644 --- a/zdev/dracut/95zdev/module-setup.sh +++ b/zdev/dracut/95zdev/module-setup.sh @@ -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 diff --git a/zdev/dracut/95zdev/zdev-lib.sh b/zdev/dracut/95zdev/zdev-lib.sh new file mode 100644 index 00000000..fa907cee --- /dev/null +++ b/zdev/dracut/95zdev/zdev-lib.sh @@ -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 +} diff --git a/zdev/dracut/Makefile b/zdev/dracut/Makefile index 17329d22..f7911f71 100644 --- a/zdev/dracut/Makefile +++ b/zdev/dracut/Makefile @@ -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