2021-09-13 19:25:46 +00:00
|
|
|
#!/bin/bash
|
2013-09-24 13:33:27 +00:00
|
|
|
#
|
2013-12-17 06:54:15 +00:00
|
|
|
# Kdump common variables and functions
|
2013-09-24 13:33:27 +00:00
|
|
|
#
|
2022-01-04 06:04:38 +00:00
|
|
|
if [[ ${__SOURCED__:+x} ]]; then
|
|
|
|
. ./kdump-lib-initramfs.sh
|
|
|
|
else
|
|
|
|
. /lib/kdump/kdump-lib-initramfs.sh
|
|
|
|
fi
|
2021-09-13 19:25:46 +00:00
|
|
|
|
2017-08-30 08:45:45 +00:00
|
|
|
FADUMP_ENABLED_SYS_NODE="/sys/kernel/fadump_enabled"
|
2023-01-12 15:31:02 +00:00
|
|
|
FADUMP_REGISTER_SYS_NODE="/sys/kernel/fadump_registered"
|
2017-08-30 08:45:45 +00:00
|
|
|
|
2023-05-05 15:14:42 +00:00
|
|
|
is_uki()
|
|
|
|
{
|
|
|
|
local img
|
|
|
|
|
|
|
|
img="$1"
|
|
|
|
|
|
|
|
[[ -f "$img" ]] || return
|
|
|
|
[[ "$(file -b --mime-type "$img")" == application/x-dosexec ]] || return
|
|
|
|
objdump -h -j .linux "$img" &> /dev/null
|
|
|
|
}
|
|
|
|
|
2017-08-30 08:45:45 +00:00
|
|
|
is_fadump_capable()
|
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
# Check if firmware-assisted dump is enabled
|
|
|
|
# if no, fallback to kdump check
|
|
|
|
if [[ -f $FADUMP_ENABLED_SYS_NODE ]]; then
|
|
|
|
rc=$(< $FADUMP_ENABLED_SYS_NODE)
|
|
|
|
[[ $rc -eq 1 ]] && return 0
|
|
|
|
fi
|
|
|
|
return 1
|
2017-08-30 08:45:45 +00:00
|
|
|
}
|
2013-12-17 06:54:15 +00:00
|
|
|
|
2023-01-12 15:31:06 +00:00
|
|
|
is_aws_aarch64()
|
|
|
|
{
|
|
|
|
[[ "$(lscpu | grep "BIOS Model name")" =~ "AWS Graviton" ]]
|
|
|
|
}
|
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
is_squash_available()
|
|
|
|
{
|
2023-01-12 15:31:04 +00:00
|
|
|
local _version kmodule
|
|
|
|
|
|
|
|
_version=$(_get_kdump_kernel_version)
|
2021-09-13 19:09:30 +00:00
|
|
|
for kmodule in squashfs overlay loop; do
|
2023-01-12 15:31:04 +00:00
|
|
|
modprobe -S "$_version" --dry-run $kmodule &> /dev/null || return 1
|
2021-09-13 19:09:30 +00:00
|
|
|
done
|
2021-06-23 14:36:48 +00:00
|
|
|
}
|
|
|
|
|
2022-01-10 13:51:16 +00:00
|
|
|
is_zstd_command_available()
|
|
|
|
{
|
|
|
|
[[ -x "$(command -v zstd)" ]]
|
|
|
|
}
|
|
|
|
|
Seperate dracut and dracut-squash compressor for zstd
Previously kexec-tools will pass "--compress zstd" to dracut. It
will make dracut to decide whether: a) call mksquashfs to make a
zstd format squash-root.img, b) call cmd zstd to make a initramfs.
Since dracut(>= 057) has decoupled the compressor for dracut and
dracut-squash, So in this patch, we will pass the compressor seperately.
Note:
The is_squash_available && !dracut_has_option --squash-compressor
&& !is_zsdt_command_available case is left unprocessed on purpose.
Actually, the situation when we want to call zstd compression is:
1) If squash function OK, we want dracut to invoke mksquashfs to make
a zstd format squash-root.img within initramfs.
2) If squash function is not OK, and cmd zstd presents, we want dracut
to invoke cmd zstd to make a zstd format initramfs.
is_zstd_command_available check can handle case 2 completely.
However, for the is_squash_available check, it cannot handle case 1
completely. It only checks if the kernel supports squashfs, it doesn't
check whether the squash module has been added by dracut when making
initramfs. In fact, in kexec-tools we are unable to do the check,
there are multiple ways to forbit dracut to load a module, such as
"dracut -o module" and "omit_dracutmodules in dracut.conf".
When squash dracut module is omitted, is_squash_available check will
still pass, so "--compress zstd" will be appended to dracut cmdline,
and it will call cmd zstd to do the compression. However cmd zstd may
not exist, so it fails.
The previous "--compress zstd" is ambiguous, after the intro of
"--squash-compressor", "--squash-compressor" only effect for
mksquashfs and "--compress" only effect for specific cmd.
So for the is_squash_available && !dracut_has_option
--squash-compressor && !is_zsdt_command_available case, we just leave
it to be handled the default way.
Reviewed-by: Philipp Rudo <prudo@redhat.com>
Signed-off-by: Tao Liu <ltao@redhat.com>
2022-10-08 04:09:08 +00:00
|
|
|
dracut_have_option()
|
|
|
|
{
|
|
|
|
local _option=$1
|
|
|
|
! dracut "$_option" 2>&1 | grep -q "unrecognized option"
|
|
|
|
}
|
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
perror_exit()
|
|
|
|
{
|
|
|
|
derror "$@"
|
|
|
|
exit 1
|
2016-05-09 08:17:54 +00:00
|
|
|
}
|
|
|
|
|
2014-04-02 08:33:43 +00:00
|
|
|
# Check if fence kdump is configured in Pacemaker cluster
|
|
|
|
is_pcs_fence_kdump()
|
2013-12-17 06:54:15 +00:00
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
# no pcs or fence_kdump_send executables installed?
|
|
|
|
type -P pcs > /dev/null || return 1
|
|
|
|
[[ -x $FENCE_KDUMP_SEND ]] || return 1
|
2013-12-17 06:54:15 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
# fence kdump not configured?
|
|
|
|
(pcs cluster cib | grep 'type="fence_kdump"') &> /dev/null || return 1
|
2013-12-17 06:54:15 +00:00
|
|
|
}
|
2014-03-03 10:37:14 +00:00
|
|
|
|
2014-04-02 08:33:47 +00:00
|
|
|
# Check if fence_kdump is configured using kdump options
|
|
|
|
is_generic_fence_kdump()
|
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
[[ -x $FENCE_KDUMP_SEND ]] || return 1
|
2014-04-02 08:33:47 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
[[ $(kdump_get_conf_val fence_kdump_nodes) ]]
|
2014-04-02 08:33:47 +00:00
|
|
|
}
|
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
to_dev_name()
|
|
|
|
{
|
|
|
|
local dev="${1//\"/}"
|
2016-05-09 08:17:54 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
case "$dev" in
|
|
|
|
UUID=*)
|
|
|
|
blkid -U "${dev#UUID=}"
|
|
|
|
;;
|
|
|
|
LABEL=*)
|
|
|
|
blkid -L "${dev#LABEL=}"
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
echo "$dev"
|
|
|
|
;;
|
|
|
|
esac
|
2016-05-09 08:17:54 +00:00
|
|
|
}
|
|
|
|
|
2017-07-07 07:48:52 +00:00
|
|
|
is_user_configured_dump_target()
|
|
|
|
{
|
2022-09-23 10:13:11 +00:00
|
|
|
[[ $(kdump_get_conf_val "ext[234]\|xfs\|btrfs\|minix\|raw\|nfs\|ssh\|virtiofs") ]] || is_mount_in_dracut_args
|
2014-03-03 10:37:14 +00:00
|
|
|
}
|
|
|
|
|
2017-07-07 07:48:52 +00:00
|
|
|
get_block_dump_target()
|
|
|
|
{
|
2022-09-23 10:13:11 +00:00
|
|
|
local _target _fstype
|
2017-07-07 07:48:52 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
if is_ssh_dump_target || is_nfs_dump_target; then
|
|
|
|
return
|
|
|
|
fi
|
2017-07-07 07:48:52 +00:00
|
|
|
|
2022-09-23 10:13:11 +00:00
|
|
|
_target=$(kdump_get_conf_val "ext[234]\|xfs\|btrfs\|minix\|raw\|virtiofs")
|
2021-09-13 19:09:30 +00:00
|
|
|
[[ -n $_target ]] && to_dev_name "$_target" && return
|
2017-07-07 07:48:52 +00:00
|
|
|
|
2022-09-23 10:13:11 +00:00
|
|
|
_target=$(get_dracut_args_target "$(kdump_get_conf_val "dracut_args")")
|
|
|
|
[[ -b $_target ]] && to_dev_name "$_target" && return
|
|
|
|
|
|
|
|
_fstype=$(get_dracut_args_fstype "$(kdump_get_conf_val "dracut_args")")
|
|
|
|
is_fs_type_virtiofs "$_fstype" && echo "$_target" && return
|
|
|
|
|
|
|
|
_target=$(get_target_from_path "$(get_save_path)")
|
|
|
|
[[ -b $_target ]] && to_dev_name "$_target" && return
|
|
|
|
|
|
|
|
_fstype=$(get_fs_type_from_target "$_target")
|
|
|
|
is_fs_type_virtiofs "$_fstype" && echo "$_target" && return
|
2017-07-07 07:48:52 +00:00
|
|
|
}
|
|
|
|
|
2017-07-07 07:48:53 +00:00
|
|
|
is_dump_to_rootfs()
|
|
|
|
{
|
2022-01-06 03:46:54 +00:00
|
|
|
[[ $(kdump_get_conf_val 'failure_action\|default') == dump_to_rootfs ]]
|
2017-07-07 07:48:53 +00:00
|
|
|
}
|
|
|
|
|
2022-10-08 07:41:39 +00:00
|
|
|
is_lvm2_thinp_dump_target()
|
|
|
|
{
|
|
|
|
_target=$(get_block_dump_target)
|
|
|
|
[ -n "$_target" ] && is_lvm2_thinp_device "$_target"
|
|
|
|
}
|
|
|
|
|
2019-01-17 20:31:23 +00:00
|
|
|
get_failure_action_target()
|
2017-07-07 07:48:53 +00:00
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
local _target
|
2017-07-07 07:48:53 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
if is_dump_to_rootfs; then
|
|
|
|
# Get rootfs device name
|
|
|
|
_target=$(get_root_fs_device)
|
|
|
|
[[ -b $_target ]] && to_dev_name "$_target" && return
|
2022-09-23 10:13:11 +00:00
|
|
|
is_fs_type_virtiofs "$(get_fs_type_from_target "$_target")" && echo "$_target" && return
|
2021-09-13 19:09:30 +00:00
|
|
|
# Then, must be nfs root
|
|
|
|
echo "nfs"
|
|
|
|
fi
|
2017-07-07 07:48:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# Get kdump targets(including root in case of dump_to_rootfs).
|
|
|
|
get_kdump_targets()
|
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
local _target _root
|
|
|
|
local kdump_targets
|
2017-07-07 07:48:53 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
_target=$(get_block_dump_target)
|
|
|
|
if [[ -n $_target ]]; then
|
|
|
|
kdump_targets=$_target
|
|
|
|
elif is_ssh_dump_target; then
|
|
|
|
kdump_targets="ssh"
|
|
|
|
else
|
|
|
|
kdump_targets="nfs"
|
|
|
|
fi
|
2017-07-07 07:48:53 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
# Add the root device if dump_to_rootfs is specified.
|
|
|
|
_root=$(get_failure_action_target)
|
|
|
|
if [[ -n $_root ]] && [[ $kdump_targets != "$_root" ]]; then
|
|
|
|
kdump_targets="$kdump_targets $_root"
|
|
|
|
fi
|
2017-07-07 07:48:53 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
echo "$kdump_targets"
|
2017-07-07 07:48:53 +00:00
|
|
|
}
|
|
|
|
|
2020-03-10 15:52:33 +00:00
|
|
|
# Return the bind mount source path, return the path itself if it's not bind mounted
|
|
|
|
# Eg. if /path/to/src is bind mounted to /mnt/bind, then:
|
|
|
|
# /mnt/bind -> /path/to/src, /mnt/bind/dump -> /path/to/src/dump
|
|
|
|
#
|
2015-04-17 08:26:24 +00:00
|
|
|
# findmnt uses the option "-v, --nofsroot" to exclusive the [/dir]
|
kdump-lib: Fix get_bind_mount_source to support btrfs and fstab
Currently get_bind_mount_source will not work on btrfs, that's because
this function relies on findmnt to detect bind mount.
For a bind mount, findmnt will return different value with "-v" option.
For example, we have /dev/sdc mounted on /mnt/source, and then bind
mount /mnt/source/sub/path to /mnt/bind:
$ findmnt /mnt/bind
TARGET SOURCE FSTYPE OPTIONS
/mnt/bind /dev/sdc[/sub/path] ext4 rw,relatime,seclabel
$ findmnt -v /mnt/bind
TARGET SOURCE FSTYPE OPTIONS
/mnt/bind /dev/sdc ext4 rw,relatime,seclabel
But findmnt also return similiar result for btrfs, on a fresh installed
Fedora 33:
$ findmnt /
TARGET SOURCE FSTYPE OPTIONS
/ /dev/sdb7[/root] btrfs rw,relatime,seclabel,ssd,space_cache,subvolid=256,subvol=/root
$ findmnt -v /
TARGET SOURCE FSTYPE OPTIONS
/ /dev/sdb7 btrfs rw,relatime,seclabel,ssd,space_cache,subvolid=256,subvol=/root
The [...] indicator will contain the subvol of btrfs as well. And if
it's bind mounted under btrfs, it will contain a mixup of btrfs subvol
and the actuall fsroot.
And also, if the bind mount source device is not mounted on /,
get_bind_mount_source will also not work.
So rewrite the get_bind_mount_source function, make it work in every
cases.
Tested with:
- Silverblue's bind mount
- Bind mount with source device mounted not under /
- Btrfs
- Bind mount and source device is Btrfs
Signed-off-by: Kairui Song <kasong@redhat.com>
Acked-by: Pingfan Liu <piliu@redhat.com>
2020-11-25 09:06:12 +00:00
|
|
|
# in the SOURCE column for bind-mounts, then if $_src equals to
|
|
|
|
# $_src_nofsroot, the mountpoint is not bind mounted directory.
|
2020-03-10 15:52:33 +00:00
|
|
|
#
|
2015-04-17 08:26:24 +00:00
|
|
|
# Below is just an example for mount info
|
|
|
|
# /dev/mapper/atomicos-root[/ostree/deploy/rhel-atomic-host/var], if the
|
|
|
|
# directory is bind mounted. The former part represents the device path, rest
|
|
|
|
# part is the bind mounted directory which quotes by bracket "[]".
|
2020-03-10 15:52:33 +00:00
|
|
|
get_bind_mount_source()
|
2015-04-17 08:26:24 +00:00
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
local _mnt _path _src _opt _fstype
|
|
|
|
local _fsroot _src_nofsroot
|
kdump-lib: Fix get_bind_mount_source to support btrfs and fstab
Currently get_bind_mount_source will not work on btrfs, that's because
this function relies on findmnt to detect bind mount.
For a bind mount, findmnt will return different value with "-v" option.
For example, we have /dev/sdc mounted on /mnt/source, and then bind
mount /mnt/source/sub/path to /mnt/bind:
$ findmnt /mnt/bind
TARGET SOURCE FSTYPE OPTIONS
/mnt/bind /dev/sdc[/sub/path] ext4 rw,relatime,seclabel
$ findmnt -v /mnt/bind
TARGET SOURCE FSTYPE OPTIONS
/mnt/bind /dev/sdc ext4 rw,relatime,seclabel
But findmnt also return similiar result for btrfs, on a fresh installed
Fedora 33:
$ findmnt /
TARGET SOURCE FSTYPE OPTIONS
/ /dev/sdb7[/root] btrfs rw,relatime,seclabel,ssd,space_cache,subvolid=256,subvol=/root
$ findmnt -v /
TARGET SOURCE FSTYPE OPTIONS
/ /dev/sdb7 btrfs rw,relatime,seclabel,ssd,space_cache,subvolid=256,subvol=/root
The [...] indicator will contain the subvol of btrfs as well. And if
it's bind mounted under btrfs, it will contain a mixup of btrfs subvol
and the actuall fsroot.
And also, if the bind mount source device is not mounted on /,
get_bind_mount_source will also not work.
So rewrite the get_bind_mount_source function, make it work in every
cases.
Tested with:
- Silverblue's bind mount
- Bind mount with source device mounted not under /
- Btrfs
- Bind mount and source device is Btrfs
Signed-off-by: Kairui Song <kasong@redhat.com>
Acked-by: Pingfan Liu <piliu@redhat.com>
2020-11-25 09:06:12 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
_mnt=$(df "$1" | tail -1 | awk '{print $NF}')
|
|
|
|
_path=${1#$_mnt}
|
2021-09-07 19:48:19 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
_src=$(get_mount_info SOURCE target "$_mnt" -f)
|
|
|
|
_opt=$(get_mount_info OPTIONS target "$_mnt" -f)
|
|
|
|
_fstype=$(get_mount_info FSTYPE target "$_mnt" -f)
|
kdump-lib: Fix get_bind_mount_source to support btrfs and fstab
Currently get_bind_mount_source will not work on btrfs, that's because
this function relies on findmnt to detect bind mount.
For a bind mount, findmnt will return different value with "-v" option.
For example, we have /dev/sdc mounted on /mnt/source, and then bind
mount /mnt/source/sub/path to /mnt/bind:
$ findmnt /mnt/bind
TARGET SOURCE FSTYPE OPTIONS
/mnt/bind /dev/sdc[/sub/path] ext4 rw,relatime,seclabel
$ findmnt -v /mnt/bind
TARGET SOURCE FSTYPE OPTIONS
/mnt/bind /dev/sdc ext4 rw,relatime,seclabel
But findmnt also return similiar result for btrfs, on a fresh installed
Fedora 33:
$ findmnt /
TARGET SOURCE FSTYPE OPTIONS
/ /dev/sdb7[/root] btrfs rw,relatime,seclabel,ssd,space_cache,subvolid=256,subvol=/root
$ findmnt -v /
TARGET SOURCE FSTYPE OPTIONS
/ /dev/sdb7 btrfs rw,relatime,seclabel,ssd,space_cache,subvolid=256,subvol=/root
The [...] indicator will contain the subvol of btrfs as well. And if
it's bind mounted under btrfs, it will contain a mixup of btrfs subvol
and the actuall fsroot.
And also, if the bind mount source device is not mounted on /,
get_bind_mount_source will also not work.
So rewrite the get_bind_mount_source function, make it work in every
cases.
Tested with:
- Silverblue's bind mount
- Bind mount with source device mounted not under /
- Btrfs
- Bind mount and source device is Btrfs
Signed-off-by: Kairui Song <kasong@redhat.com>
Acked-by: Pingfan Liu <piliu@redhat.com>
2020-11-25 09:06:12 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
# bind mount in fstab
|
|
|
|
if [[ -d $_src ]] && [[ $_fstype == none ]] && (echo "$_opt" | grep -q "\bbind\b"); then
|
|
|
|
echo "$_src$_path" && return
|
|
|
|
fi
|
2015-04-17 08:26:24 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
# direct mount
|
|
|
|
_src_nofsroot=$(get_mount_info SOURCE target "$_mnt" -v -f)
|
|
|
|
if [[ $_src_nofsroot == "$_src" ]]; then
|
|
|
|
echo "$_mnt$_path" && return
|
|
|
|
fi
|
2015-04-17 08:26:24 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
_fsroot=${_src#${_src_nofsroot}[}
|
|
|
|
_fsroot=${_fsroot%]}
|
|
|
|
_mnt=$(get_mount_info TARGET source "$_src_nofsroot" -f)
|
kdump-lib: Fix get_bind_mount_source to support btrfs and fstab
Currently get_bind_mount_source will not work on btrfs, that's because
this function relies on findmnt to detect bind mount.
For a bind mount, findmnt will return different value with "-v" option.
For example, we have /dev/sdc mounted on /mnt/source, and then bind
mount /mnt/source/sub/path to /mnt/bind:
$ findmnt /mnt/bind
TARGET SOURCE FSTYPE OPTIONS
/mnt/bind /dev/sdc[/sub/path] ext4 rw,relatime,seclabel
$ findmnt -v /mnt/bind
TARGET SOURCE FSTYPE OPTIONS
/mnt/bind /dev/sdc ext4 rw,relatime,seclabel
But findmnt also return similiar result for btrfs, on a fresh installed
Fedora 33:
$ findmnt /
TARGET SOURCE FSTYPE OPTIONS
/ /dev/sdb7[/root] btrfs rw,relatime,seclabel,ssd,space_cache,subvolid=256,subvol=/root
$ findmnt -v /
TARGET SOURCE FSTYPE OPTIONS
/ /dev/sdb7 btrfs rw,relatime,seclabel,ssd,space_cache,subvolid=256,subvol=/root
The [...] indicator will contain the subvol of btrfs as well. And if
it's bind mounted under btrfs, it will contain a mixup of btrfs subvol
and the actuall fsroot.
And also, if the bind mount source device is not mounted on /,
get_bind_mount_source will also not work.
So rewrite the get_bind_mount_source function, make it work in every
cases.
Tested with:
- Silverblue's bind mount
- Bind mount with source device mounted not under /
- Btrfs
- Bind mount and source device is Btrfs
Signed-off-by: Kairui Song <kasong@redhat.com>
Acked-by: Pingfan Liu <piliu@redhat.com>
2020-11-25 09:06:12 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
# for btrfs, _fsroot will also contain the subvol value as well, strip it
|
|
|
|
if [[ $_fstype == btrfs ]]; then
|
|
|
|
local _subvol
|
|
|
|
_subvol=${_opt#*subvol=}
|
|
|
|
_subvol=${_subvol%,*}
|
|
|
|
_fsroot=${_fsroot#$_subvol}
|
|
|
|
fi
|
|
|
|
echo "$_mnt$_fsroot$_path"
|
2014-04-11 12:26:59 +00:00
|
|
|
}
|
|
|
|
|
2020-03-12 05:52:55 +00:00
|
|
|
get_mntopt_from_target()
|
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
get_mount_info OPTIONS source "$1" -f
|
2014-04-11 12:26:59 +00:00
|
|
|
}
|
|
|
|
|
2020-03-05 15:28:53 +00:00
|
|
|
# Get the path where the target will be mounted in kdump kernel
|
|
|
|
# $1: kdump target device
|
|
|
|
get_kdump_mntpoint_from_target()
|
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
local _mntpoint
|
|
|
|
|
|
|
|
_mntpoint=$(get_mntpoint_from_target "$1")
|
|
|
|
# mount under /sysroot if dump to root disk or mount under
|
|
|
|
# mount under /kdumproot if dump target is not mounted in first kernel
|
|
|
|
# mount under /kdumproot/$_mntpoint in other cases in 2nd kernel.
|
|
|
|
# systemd will be in charge to umount it.
|
|
|
|
if [[ -z $_mntpoint ]]; then
|
|
|
|
_mntpoint="/kdumproot"
|
|
|
|
else
|
|
|
|
if [[ $_mntpoint == "/" ]]; then
|
|
|
|
_mntpoint="/sysroot"
|
|
|
|
else
|
|
|
|
_mntpoint="/kdumproot/$_mntpoint"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
# strip duplicated "/"
|
|
|
|
echo $_mntpoint | tr -s "/"
|
|
|
|
}
|
|
|
|
|
|
|
|
kdump_get_persistent_dev()
|
|
|
|
{
|
|
|
|
local dev="${1//\"/}"
|
|
|
|
|
|
|
|
case "$dev" in
|
|
|
|
UUID=*)
|
|
|
|
dev=$(blkid -U "${dev#UUID=}")
|
|
|
|
;;
|
|
|
|
LABEL=*)
|
|
|
|
dev=$(blkid -L "${dev#LABEL=}")
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
echo $(get_persistent_dev "$dev")
|
2020-06-16 03:25:26 +00:00
|
|
|
}
|
|
|
|
|
2022-06-22 15:58:31 +00:00
|
|
|
is_ostree()
|
2021-06-24 19:42:19 +00:00
|
|
|
{
|
2022-06-24 13:57:03 +00:00
|
|
|
test -f /run/ostree-booted
|
2021-06-24 19:42:19 +00:00
|
|
|
}
|
|
|
|
|
2015-07-23 10:29:24 +00:00
|
|
|
# get ip address or hostname from nfs/ssh config value
|
|
|
|
get_remote_host()
|
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
local _config_val=$1
|
2015-07-23 10:29:24 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
# ipv6 address in kdump.conf is around with "[]",
|
|
|
|
# factor out the ipv6 address
|
|
|
|
_config_val=${_config_val#*@}
|
|
|
|
_config_val=${_config_val%:/*}
|
|
|
|
_config_val=${_config_val#[}
|
|
|
|
_config_val=${_config_val%]}
|
|
|
|
echo "$_config_val"
|
2015-07-23 10:29:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
is_hostname()
|
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
local _hostname
|
2015-07-23 10:29:24 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
_hostname=$(echo "$1" | grep ":")
|
|
|
|
if [[ -n $_hostname ]]; then
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
echo "$1" | grep -q "[a-zA-Z]"
|
2015-07-23 10:29:24 +00:00
|
|
|
}
|
2016-06-06 05:01:44 +00:00
|
|
|
|
2021-04-01 07:32:08 +00:00
|
|
|
# Get value by a field using "nmcli -g"
|
2021-09-08 07:20:42 +00:00
|
|
|
# Usage: get_nmcli_value_by_field <field> <nmcli command>
|
2021-04-01 07:32:08 +00:00
|
|
|
#
|
|
|
|
# "nmcli --get-values" allows us to retrive value(s) by field, for example,
|
|
|
|
# nmcli --get-values <field> connection show /org/freedesktop/NetworkManager/ActiveConnection/1
|
|
|
|
# returns the following value for the corresponding field respectively,
|
|
|
|
# Field Value
|
|
|
|
# IP4.DNS "10.19.42.41 | 10.11.5.19 | 10.5.30.160"
|
|
|
|
# 802-3-ethernet.s390-subchannels ""
|
|
|
|
# bond.options "mode=balance-rr"
|
|
|
|
get_nmcli_value_by_field()
|
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
LANG=C nmcli --get-values "$@"
|
2021-09-08 07:20:42 +00:00
|
|
|
}
|
2021-04-01 07:32:08 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
is_wdt_active()
|
|
|
|
{
|
|
|
|
local active
|
2020-10-15 10:16:44 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
[[ -d /sys/class/watchdog ]] || return 1
|
|
|
|
for dir in /sys/class/watchdog/*; do
|
|
|
|
[[ -f "$dir/state" ]] || continue
|
|
|
|
active=$(< "$dir/state")
|
|
|
|
[[ $active == "active" ]] && return 0
|
|
|
|
done
|
|
|
|
return 1
|
2020-10-15 10:16:44 +00:00
|
|
|
}
|
|
|
|
|
2022-01-05 09:42:12 +00:00
|
|
|
have_compression_in_dracut_args()
|
|
|
|
{
|
Seperate dracut and dracut-squash compressor for zstd
Previously kexec-tools will pass "--compress zstd" to dracut. It
will make dracut to decide whether: a) call mksquashfs to make a
zstd format squash-root.img, b) call cmd zstd to make a initramfs.
Since dracut(>= 057) has decoupled the compressor for dracut and
dracut-squash, So in this patch, we will pass the compressor seperately.
Note:
The is_squash_available && !dracut_has_option --squash-compressor
&& !is_zsdt_command_available case is left unprocessed on purpose.
Actually, the situation when we want to call zstd compression is:
1) If squash function OK, we want dracut to invoke mksquashfs to make
a zstd format squash-root.img within initramfs.
2) If squash function is not OK, and cmd zstd presents, we want dracut
to invoke cmd zstd to make a zstd format initramfs.
is_zstd_command_available check can handle case 2 completely.
However, for the is_squash_available check, it cannot handle case 1
completely. It only checks if the kernel supports squashfs, it doesn't
check whether the squash module has been added by dracut when making
initramfs. In fact, in kexec-tools we are unable to do the check,
there are multiple ways to forbit dracut to load a module, such as
"dracut -o module" and "omit_dracutmodules in dracut.conf".
When squash dracut module is omitted, is_squash_available check will
still pass, so "--compress zstd" will be appended to dracut cmdline,
and it will call cmd zstd to do the compression. However cmd zstd may
not exist, so it fails.
The previous "--compress zstd" is ambiguous, after the intro of
"--squash-compressor", "--squash-compressor" only effect for
mksquashfs and "--compress" only effect for specific cmd.
So for the is_squash_available && !dracut_has_option
--squash-compressor && !is_zsdt_command_available case, we just leave
it to be handled the default way.
Reviewed-by: Philipp Rudo <prudo@redhat.com>
Signed-off-by: Tao Liu <ltao@redhat.com>
2022-10-08 04:09:08 +00:00
|
|
|
[[ "$(kdump_get_conf_val dracut_args)" =~ (^|[[:space:]])--(gzip|bzip2|lzma|xz|lzo|lz4|zstd|no-compress|compress|squash-compressor)([[:space:]]|$) ]]
|
2022-01-05 09:42:12 +00:00
|
|
|
}
|
|
|
|
|
Support special mount information via "dracut_args"
There are some complaints about nfs kdump that users must mount
nfs beforehand, which may cause some overhead to nfs server.
For example, there're thounsands of diskless clients deployed with
nfs dumping, each time the client is boot up, it will trigger
kdump rebuilding so will mount nfs, thus resulting in thousands
of nfs request concurrently imposed on the same nfs server.
We introduce a new way of specifying mount information via the
already-existent "dracut_args" directive(so avoid adding extra
directives in /etc/kdump.conf), we will skip all the filesystem
mounting and checking stuff for it. So it can be used in the
above-mentioned nfs scenario to avoid severe nfs server overhead.
Specifically, if there is any "--mount" information specified via
"dracut_args" in /etc/kdump.conf, always use it as the final mount
without any validation(mounting or checking like mount options,
fs size, etc), so users are expected to ensure its correctness.
NOTE:
-Only one mount target is allowed using "dracut_args" globally.
-Dracut will create <mountpoint> if it doesn't exist in kdump kernel,
<mountpoint> must be specified as an absolute path.
-Users should do a test first and ensure it works because kdump does
not prepare the mount or check all the validity.
Reviewed-by: Pratyush Anand <panand@redhat.com>
Suggested-by: Dave Young <dyoung@redhat.com>
Acked-by: Dave Young <dyoung@redhat.com>
Signed-off-by: Xunlei Pang <xlpang@redhat.com>
2016-08-26 03:23:35 +00:00
|
|
|
# If "dracut_args" contains "--mount" information, use it
|
|
|
|
# directly without any check(users are expected to ensure
|
|
|
|
# its correctness).
|
|
|
|
is_mount_in_dracut_args()
|
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
[[ " $(kdump_get_conf_val dracut_args)" =~ .*[[:space:]]--mount[=[:space:]].* ]]
|
Support special mount information via "dracut_args"
There are some complaints about nfs kdump that users must mount
nfs beforehand, which may cause some overhead to nfs server.
For example, there're thounsands of diskless clients deployed with
nfs dumping, each time the client is boot up, it will trigger
kdump rebuilding so will mount nfs, thus resulting in thousands
of nfs request concurrently imposed on the same nfs server.
We introduce a new way of specifying mount information via the
already-existent "dracut_args" directive(so avoid adding extra
directives in /etc/kdump.conf), we will skip all the filesystem
mounting and checking stuff for it. So it can be used in the
above-mentioned nfs scenario to avoid severe nfs server overhead.
Specifically, if there is any "--mount" information specified via
"dracut_args" in /etc/kdump.conf, always use it as the final mount
without any validation(mounting or checking like mount options,
fs size, etc), so users are expected to ensure its correctness.
NOTE:
-Only one mount target is allowed using "dracut_args" globally.
-Dracut will create <mountpoint> if it doesn't exist in kdump kernel,
<mountpoint> must be specified as an absolute path.
-Users should do a test first and ensure it works because kdump does
not prepare the mount or check all the validity.
Reviewed-by: Pratyush Anand <panand@redhat.com>
Suggested-by: Dave Young <dyoung@redhat.com>
Acked-by: Dave Young <dyoung@redhat.com>
Signed-off-by: Xunlei Pang <xlpang@redhat.com>
2016-08-26 03:23:35 +00:00
|
|
|
}
|
|
|
|
|
2018-05-22 10:15:07 +00:00
|
|
|
check_crash_mem_reserved()
|
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
local mem_reserved
|
2018-05-22 10:15:07 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
mem_reserved=$(< /sys/kernel/kexec_crash_size)
|
|
|
|
if [[ $mem_reserved -eq 0 ]]; then
|
|
|
|
derror "No memory reserved for crash kernel"
|
|
|
|
return 1
|
|
|
|
fi
|
2018-05-22 10:15:07 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
return 0
|
2018-05-22 10:15:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
check_kdump_feasibility()
|
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
if [[ ! -e /sys/kernel/kexec_crash_loaded ]]; then
|
|
|
|
derror "Kdump is not supported on this kernel"
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
check_crash_mem_reserved
|
|
|
|
return $?
|
2018-05-22 10:15:07 +00:00
|
|
|
}
|
|
|
|
|
2023-01-12 15:31:02 +00:00
|
|
|
is_kernel_loaded()
|
2018-05-22 10:15:07 +00:00
|
|
|
{
|
2023-01-12 15:31:02 +00:00
|
|
|
local _sysfs _mode
|
|
|
|
|
|
|
|
_mode=$1
|
|
|
|
|
|
|
|
case "$_mode" in
|
|
|
|
kdump)
|
|
|
|
_sysfs="/sys/kernel/kexec_crash_loaded"
|
|
|
|
;;
|
|
|
|
fadump)
|
|
|
|
_sysfs="$FADUMP_REGISTER_SYS_NODE"
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
derror "Unknown dump mode '$_mode' provided"
|
2021-09-13 19:09:30 +00:00
|
|
|
return 1
|
2023-01-12 15:31:02 +00:00
|
|
|
;;
|
|
|
|
esac
|
2018-05-22 10:15:07 +00:00
|
|
|
|
2023-01-12 15:31:02 +00:00
|
|
|
if [[ ! -f $_sysfs ]]; then
|
|
|
|
derror "$_mode is not supported on this kernel"
|
2021-09-13 19:09:30 +00:00
|
|
|
return 1
|
|
|
|
fi
|
2023-01-12 15:31:02 +00:00
|
|
|
|
|
|
|
[[ $(< $_sysfs) -eq 1 ]]
|
2018-05-22 10:15:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#
|
|
|
|
# This function returns the "apicid" of the boot
|
|
|
|
# cpu (cpu 0) if present.
|
|
|
|
#
|
|
|
|
get_bootcpu_apicid()
|
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
awk ' \
|
2018-05-22 10:15:07 +00:00
|
|
|
BEGIN { CPU = "-1"; } \
|
|
|
|
$1=="processor" && $2==":" { CPU = $NF; } \
|
|
|
|
CPU=="0" && /^apicid/ { print $NF; } \
|
2021-09-13 19:09:30 +00:00
|
|
|
' \
|
|
|
|
/proc/cpuinfo
|
2018-05-22 10:15:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# This function check iomem and determines if we have more than
|
|
|
|
# 4GB of ram available. Returns 1 if we do, 0 if we dont
|
|
|
|
need_64bit_headers()
|
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
return "$(tail -n 1 /proc/iomem | awk '{ split ($1, r, "-");
|
2021-09-12 17:17:05 +00:00
|
|
|
print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }')"
|
2018-05-22 10:15:07 +00:00
|
|
|
}
|
|
|
|
|
2020-06-29 13:13:54 +00:00
|
|
|
# Check if secure boot is being enforced.
|
|
|
|
#
|
|
|
|
# Per Peter Jones, we need check efivar SecureBoot-$(the UUID) and
|
|
|
|
# SetupMode-$(the UUID), they are both 5 bytes binary data. The first four
|
|
|
|
# bytes are the attributes associated with the variable and can safely be
|
|
|
|
# ignored, the last bytes are one-byte true-or-false variables. If SecureBoot
|
|
|
|
# is 1 and SetupMode is 0, then secure boot is being enforced.
|
|
|
|
#
|
|
|
|
# Assume efivars is mounted at /sys/firmware/efi/efivars.
|
|
|
|
is_secure_boot_enforced()
|
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
local secure_boot_file setup_mode_file
|
|
|
|
local secure_boot_byte setup_mode_byte
|
2020-06-29 13:13:54 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
# On powerpc, secure boot is enforced if:
|
|
|
|
# host secure boot: /ibm,secure-boot/os-secureboot-enforcing DT property exists
|
|
|
|
# guest secure boot: /ibm,secure-boot >= 2
|
|
|
|
if [[ -f /proc/device-tree/ibm,secureboot/os-secureboot-enforcing ]]; then
|
2020-07-09 15:16:55 +00:00
|
|
|
return 0
|
2021-09-13 19:09:30 +00:00
|
|
|
fi
|
|
|
|
if [[ -f /proc/device-tree/ibm,secure-boot ]] &&
|
|
|
|
[[ $(lsprop /proc/device-tree/ibm,secure-boot | tail -1) -ge 2 ]]; then
|
2021-02-18 06:01:18 +00:00
|
|
|
return 0
|
2021-09-13 19:09:30 +00:00
|
|
|
fi
|
2020-07-09 15:16:55 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
# Detect secure boot on x86 and arm64
|
|
|
|
secure_boot_file=$(find /sys/firmware/efi/efivars -name "SecureBoot-*" 2> /dev/null)
|
|
|
|
setup_mode_file=$(find /sys/firmware/efi/efivars -name "SetupMode-*" 2> /dev/null)
|
2020-06-29 13:13:54 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
if [[ -f $secure_boot_file ]] && [[ -f $setup_mode_file ]]; then
|
|
|
|
secure_boot_byte=$(hexdump -v -e '/1 "%d\ "' "$secure_boot_file" | cut -d' ' -f 5)
|
|
|
|
setup_mode_byte=$(hexdump -v -e '/1 "%d\ "' "$setup_mode_file" | cut -d' ' -f 5)
|
2020-06-29 13:13:54 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
if [[ $secure_boot_byte == "1" ]] && [[ $setup_mode_byte == "0" ]]; then
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
fi
|
2020-06-29 13:13:54 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
# Detect secure boot on s390x
|
|
|
|
if [[ -e "/sys/firmware/ipl/secure" && "$(< /sys/firmware/ipl/secure)" == "1" ]]; then
|
|
|
|
return 0
|
|
|
|
fi
|
2020-09-15 13:21:28 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
return 1
|
2020-06-29 13:13:54 +00:00
|
|
|
}
|
|
|
|
|
2018-05-22 10:15:07 +00:00
|
|
|
#
|
|
|
|
# prepare_kexec_args <kexec args>
|
|
|
|
# This function prepares kexec argument.
|
|
|
|
#
|
|
|
|
prepare_kexec_args()
|
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
local kexec_args=$1
|
|
|
|
local found_elf_args
|
|
|
|
|
|
|
|
ARCH=$(uname -m)
|
|
|
|
if [[ $ARCH == "i686" ]] || [[ $ARCH == "i386" ]]; then
|
|
|
|
need_64bit_headers
|
|
|
|
if [[ $? == 1 ]]; then
|
|
|
|
found_elf_args=$(echo "$kexec_args" | grep elf32-core-headers)
|
|
|
|
if [[ -n $found_elf_args ]]; then
|
|
|
|
dwarn "Warning: elf32-core-headers overrides correct elf64 setting"
|
|
|
|
else
|
|
|
|
kexec_args="$kexec_args --elf64-core-headers"
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
found_elf_args=$(echo "$kexec_args" | grep elf64-core-headers)
|
|
|
|
if [[ -z $found_elf_args ]]; then
|
|
|
|
kexec_args="$kexec_args --elf32-core-headers"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
echo "$kexec_args"
|
2018-05-22 10:15:07 +00:00
|
|
|
}
|
|
|
|
|
2022-06-13 04:08:08 +00:00
|
|
|
# prepare_kdump_kernel <kdump_kernelver>
|
|
|
|
# This function return kdump_kernel given a kernel version.
|
|
|
|
prepare_kdump_kernel()
|
2020-07-27 18:40:20 +00:00
|
|
|
{
|
2022-06-13 04:08:08 +00:00
|
|
|
local kdump_kernelver=$1
|
|
|
|
local dir img boot_dirlist boot_imglist kdump_kernel machine_id
|
2021-09-13 19:09:30 +00:00
|
|
|
read -r machine_id < /etc/machine-id
|
2022-06-13 04:08:08 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
boot_dirlist=${KDUMP_BOOTDIR:-"/boot /boot/efi /efi /"}
|
2023-05-05 15:14:42 +00:00
|
|
|
boot_imglist="$KDUMP_IMG-$kdump_kernelver$KDUMP_IMG_EXT \
|
|
|
|
$machine_id/$kdump_kernelver/$KDUMP_IMG \
|
|
|
|
EFI/Linux/$machine_id-$kdump_kernelver.efi"
|
2021-09-13 19:09:30 +00:00
|
|
|
|
2022-06-21 08:55:09 +00:00
|
|
|
# The kernel of OSTree based systems is not in the standard locations.
|
|
|
|
if is_ostree; then
|
|
|
|
boot_dirlist="$(echo /boot/ostree/*) $boot_dirlist"
|
|
|
|
fi
|
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
# Use BOOT_IMAGE as reference if possible, strip the GRUB root device prefix in (hd0,gpt1) format
|
2022-06-22 16:34:12 +00:00
|
|
|
boot_img="$(grep -P -o '^BOOT_IMAGE=(\S+)' /proc/cmdline | sed "s/^BOOT_IMAGE=\((\S*)\)\?\(\S*\)/\2/")"
|
2022-06-13 04:08:08 +00:00
|
|
|
if [[ "$boot_img" == *"$kdump_kernelver" ]]; then
|
2021-09-13 19:09:30 +00:00
|
|
|
boot_imglist="$boot_img $boot_imglist"
|
|
|
|
fi
|
|
|
|
|
|
|
|
for dir in $boot_dirlist; do
|
|
|
|
for img in $boot_imglist; do
|
|
|
|
if [[ -f "$dir/$img" ]]; then
|
2022-06-13 04:08:08 +00:00
|
|
|
kdump_kernel=$(echo "$dir/$img" | tr -s '/')
|
2021-09-13 19:09:30 +00:00
|
|
|
break 2
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
done
|
2022-06-13 04:08:08 +00:00
|
|
|
echo "$kdump_kernel"
|
|
|
|
}
|
|
|
|
|
2023-01-12 15:31:04 +00:00
|
|
|
_get_kdump_kernel_version()
|
|
|
|
{
|
|
|
|
local _version _version_nondebug
|
|
|
|
|
|
|
|
if [[ -n "$KDUMP_KERNELVER" ]]; then
|
|
|
|
echo "$KDUMP_KERNELVER"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
_version=$(uname -r)
|
|
|
|
if [[ ! "$_version" =~ \+debug$ ]]; then
|
|
|
|
echo "$_version"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
_version_nondebug=${_version%+debug}
|
|
|
|
if [[ -f "$(prepare_kdump_kernel "$_version_nondebug")" ]]; then
|
|
|
|
dinfo "Use of debug kernel detected. Trying to use $_version_nondebug"
|
|
|
|
echo "$_version_nondebug"
|
|
|
|
else
|
|
|
|
dinfo "Use of debug kernel detected but cannot find $_version_nondebug. Falling back to $_version"
|
|
|
|
echo "$_version"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2022-06-13 04:08:08 +00:00
|
|
|
#
|
|
|
|
# Detect initrd and kernel location, results are stored in global environmental variables:
|
|
|
|
# KDUMP_BOOTDIR, KDUMP_KERNELVER, KDUMP_KERNEL, DEFAULT_INITRD, and KDUMP_INITRD
|
|
|
|
#
|
|
|
|
# Expectes KDUMP_BOOTDIR, KDUMP_IMG, KDUMP_IMG_EXT, KDUMP_KERNELVER to be loaded from config already
|
|
|
|
# and will prefer already set values so user can specify custom kernel/initramfs location
|
|
|
|
#
|
|
|
|
prepare_kdump_bootinfo()
|
|
|
|
{
|
2023-01-12 15:31:04 +00:00
|
|
|
local boot_initrdlist default_initrd_base var_target_initrd_dir
|
2022-06-13 04:08:08 +00:00
|
|
|
|
2023-01-12 15:31:04 +00:00
|
|
|
KDUMP_KERNELVER=$(_get_kdump_kernel_version)
|
2022-06-13 04:08:08 +00:00
|
|
|
KDUMP_KERNEL=$(prepare_kdump_kernel "$KDUMP_KERNELVER")
|
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
if ! [[ -e $KDUMP_KERNEL ]]; then
|
|
|
|
derror "Failed to detect kdump kernel location"
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
2022-06-13 04:08:08 +00:00
|
|
|
if [[ "$KDUMP_KERNEL" == *"+debug" ]]; then
|
|
|
|
dwarn "Using debug kernel, you may need to set a larger crashkernel than the default value."
|
|
|
|
fi
|
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
# Set KDUMP_BOOTDIR to where kernel image is stored
|
2023-05-05 15:14:42 +00:00
|
|
|
if is_uki "$KDUMP_KERNEL"; then
|
|
|
|
KDUMP_BOOTDIR=/boot
|
|
|
|
else
|
|
|
|
KDUMP_BOOTDIR=$(dirname "$KDUMP_KERNEL")
|
|
|
|
fi
|
2021-09-13 19:09:30 +00:00
|
|
|
|
|
|
|
# Default initrd should just stay aside of kernel image, try to find it in KDUMP_BOOTDIR
|
|
|
|
boot_initrdlist="initramfs-$KDUMP_KERNELVER.img initrd"
|
|
|
|
for initrd in $boot_initrdlist; do
|
|
|
|
if [[ -f "$KDUMP_BOOTDIR/$initrd" ]]; then
|
2022-03-25 14:46:59 +00:00
|
|
|
default_initrd_base="$initrd"
|
|
|
|
DEFAULT_INITRD="$KDUMP_BOOTDIR/$default_initrd_base"
|
2021-09-13 19:09:30 +00:00
|
|
|
break
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
# Create kdump initrd basename from default initrd basename
|
|
|
|
# initramfs-5.7.9-200.fc32.x86_64.img => initramfs-5.7.9-200.fc32.x86_64kdump.img
|
|
|
|
# initrd => initrdkdump
|
2022-03-25 14:46:59 +00:00
|
|
|
if [[ -z $default_initrd_base ]]; then
|
2021-09-13 19:09:30 +00:00
|
|
|
kdump_initrd_base=initramfs-${KDUMP_KERNELVER}kdump.img
|
2022-03-25 14:46:59 +00:00
|
|
|
elif [[ $default_initrd_base == *.* ]]; then
|
|
|
|
kdump_initrd_base=${default_initrd_base%.*}kdump.${DEFAULT_INITRD##*.}
|
2021-09-13 19:09:30 +00:00
|
|
|
else
|
2022-03-25 14:46:59 +00:00
|
|
|
kdump_initrd_base=${default_initrd_base}kdump
|
2021-09-13 19:09:30 +00:00
|
|
|
fi
|
|
|
|
|
|
|
|
# Place kdump initrd in $(/var/lib/kdump) if $(KDUMP_BOOTDIR) not writable
|
|
|
|
if [[ ! -w $KDUMP_BOOTDIR ]]; then
|
|
|
|
var_target_initrd_dir="/var/lib/kdump"
|
|
|
|
mkdir -p "$var_target_initrd_dir"
|
|
|
|
KDUMP_INITRD="$var_target_initrd_dir/$kdump_initrd_base"
|
|
|
|
else
|
|
|
|
KDUMP_INITRD="$KDUMP_BOOTDIR/$kdump_initrd_base"
|
|
|
|
fi
|
2018-05-22 10:15:07 +00:00
|
|
|
}
|
|
|
|
|
2020-11-19 09:06:58 +00:00
|
|
|
get_watchdog_drvs()
|
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
local _wdtdrvs _drv _dir
|
2020-11-19 09:06:58 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
for _dir in /sys/class/watchdog/*; do
|
|
|
|
# device/modalias will return driver of this device
|
|
|
|
[[ -f "$_dir/device/modalias" ]] || continue
|
|
|
|
_drv=$(< "$_dir/device/modalias")
|
|
|
|
_drv=$(modprobe --set-version "$KDUMP_KERNELVER" -R "$_drv" 2> /dev/null)
|
|
|
|
for i in $_drv; do
|
|
|
|
if ! [[ " $_wdtdrvs " == *" $i "* ]]; then
|
|
|
|
_wdtdrvs="$_wdtdrvs $i"
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
done
|
2020-11-19 09:06:58 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
echo "$_wdtdrvs"
|
2020-11-19 09:06:58 +00:00
|
|
|
}
|
|
|
|
|
2023-01-12 15:31:07 +00:00
|
|
|
_cmdline_parse()
|
|
|
|
{
|
|
|
|
local opt val
|
|
|
|
|
|
|
|
while read -r opt; do
|
|
|
|
if [[ $opt =~ = ]]; then
|
|
|
|
val=${opt#*=}
|
|
|
|
opt=${opt%%=*}
|
|
|
|
# ignore options like 'foo='
|
|
|
|
[[ -z $val ]] && continue
|
|
|
|
# xargs removes quotes, add them again
|
|
|
|
[[ $val =~ [[:space:]] ]] && val="\"$val\""
|
|
|
|
else
|
|
|
|
val=""
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo "$opt $val"
|
|
|
|
done <<< "$(echo "$1" | xargs -n 1 echo)"
|
|
|
|
}
|
|
|
|
|
2018-05-22 10:15:07 +00:00
|
|
|
#
|
|
|
|
# prepare_cmdline <commandline> <commandline remove> <commandline append>
|
|
|
|
# This function performs a series of edits on the command line.
|
|
|
|
# Store the final result in global $KDUMP_COMMANDLINE.
|
|
|
|
prepare_cmdline()
|
|
|
|
{
|
2023-01-12 15:31:07 +00:00
|
|
|
local in out append opt val id drv
|
|
|
|
local -A remove
|
|
|
|
|
|
|
|
in=${1:-$(< /proc/cmdline)}
|
|
|
|
while read -r opt val; do
|
|
|
|
[[ -n "$opt" ]] || continue
|
|
|
|
remove[$opt]=1
|
|
|
|
done <<< "$(_cmdline_parse "$2")"
|
|
|
|
append=$3
|
2021-09-13 19:09:30 +00:00
|
|
|
|
|
|
|
|
|
|
|
# These params should always be removed
|
2023-01-12 15:31:07 +00:00
|
|
|
remove[crashkernel]=1
|
|
|
|
remove[panic_on_warn]=1
|
2021-09-13 19:09:30 +00:00
|
|
|
|
|
|
|
# Always remove "root=X", as we now explicitly generate all kinds
|
|
|
|
# of dump target mount information including root fs.
|
|
|
|
#
|
|
|
|
# We do this before KDUMP_COMMANDLINE_APPEND, if one really cares
|
|
|
|
# about it(e.g. for debug purpose), then can pass "root=X" using
|
|
|
|
# KDUMP_COMMANDLINE_APPEND.
|
2023-01-12 15:31:07 +00:00
|
|
|
remove[root]=1
|
2021-09-13 19:09:30 +00:00
|
|
|
|
|
|
|
# With the help of "--hostonly-cmdline", we can avoid some interitage.
|
2023-01-12 15:31:07 +00:00
|
|
|
remove[rd.lvm.lv]=1
|
|
|
|
remove[rd.luks.uuid]=1
|
|
|
|
remove[rd.dm.uuid]=1
|
|
|
|
remove[rd.md.uuid]=1
|
|
|
|
remove[fcoe]=1
|
2021-09-13 19:09:30 +00:00
|
|
|
|
|
|
|
# Remove netroot, rd.iscsi.initiator and iscsi_initiator since
|
|
|
|
# we get duplicate entries for the same in case iscsi code adds
|
|
|
|
# it as well.
|
2023-01-12 15:31:07 +00:00
|
|
|
remove[netroot]=1
|
|
|
|
remove[rd.iscsi.initiator]=1
|
|
|
|
remove[iscsi_initiator]=1
|
|
|
|
|
|
|
|
while read -r opt val; do
|
|
|
|
[[ -n "$opt" ]] || continue
|
|
|
|
[[ -n "${remove[$opt]}" ]] && continue
|
|
|
|
|
|
|
|
if [[ -n "$val" ]]; then
|
|
|
|
out+="$opt=$val "
|
|
|
|
else
|
|
|
|
out+="$opt "
|
|
|
|
fi
|
|
|
|
done <<< "$(_cmdline_parse "$in")"
|
2021-09-13 19:09:30 +00:00
|
|
|
|
2023-01-12 15:31:07 +00:00
|
|
|
out+="$append "
|
2021-09-13 19:09:30 +00:00
|
|
|
|
|
|
|
id=$(get_bootcpu_apicid)
|
2023-01-12 15:31:07 +00:00
|
|
|
if [[ -n "${id}" ]]; then
|
|
|
|
out+="disable_cpu_apicid=$id "
|
2021-09-13 19:09:30 +00:00
|
|
|
fi
|
|
|
|
|
|
|
|
# If any watchdog is used, set it's pretimeout to 0. pretimeout let
|
|
|
|
# watchdog panic the kernel first, and reset the system after the
|
|
|
|
# panic. If the system is already in kdump, panic is not helpful
|
|
|
|
# and only increase the chance of watchdog failure.
|
2023-01-12 15:31:07 +00:00
|
|
|
for drv in $(get_watchdog_drvs); do
|
|
|
|
out+="$drv.pretimeout=0 "
|
|
|
|
|
|
|
|
if [[ $drv == hpwdt ]]; then
|
|
|
|
# hpwdt have a special parameter kdumptimeout, it is
|
|
|
|
# only supposed to be set to non-zero in first kernel.
|
|
|
|
# In kdump, non-zero value could prevent the watchdog
|
|
|
|
# from resetting the system.
|
|
|
|
out+="$drv.kdumptimeout=0 "
|
2021-09-13 19:09:30 +00:00
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
2023-01-12 15:31:06 +00:00
|
|
|
# This is a workaround on AWS platform. Always remove irqpoll since it
|
|
|
|
# may cause the hot-remove of some pci hotplug device.
|
2023-01-12 15:31:07 +00:00
|
|
|
is_aws_aarch64 && out=$(echo "$out" | sed -e "/\<irqpoll\>//")
|
2023-01-12 15:31:06 +00:00
|
|
|
|
2023-05-05 15:14:42 +00:00
|
|
|
# Always disable gpt-auto-generator as it hangs during boot of the
|
|
|
|
# crash kernel. Furthermore we know which disk will be used for dumping
|
|
|
|
# (if at all) and add it explicitly.
|
|
|
|
is_uki "$KDUMP_KERNEL" && out+="rd.systemd.gpt_auto=no "
|
|
|
|
|
2023-01-12 15:31:07 +00:00
|
|
|
# Trim unnecessary whitespaces
|
|
|
|
echo "$out" | sed -e "s/^ *//g" -e "s/ *$//g" -e "s/ \+/ /g"
|
2018-05-22 10:15:07 +00:00
|
|
|
}
|
2021-02-04 01:45:36 +00:00
|
|
|
|
2022-05-07 08:30:39 +00:00
|
|
|
PROC_IOMEM=/proc/iomem
|
|
|
|
#get system memory size i.e. memblock.memory.total_size in the unit of GB
|
2021-02-04 01:45:36 +00:00
|
|
|
get_system_size()
|
|
|
|
{
|
2022-05-07 08:30:39 +00:00
|
|
|
sum=$(sed -n "s/\s*\([0-9a-fA-F]\+\)-\([0-9a-fA-F]\+\) : System RAM$/+ 0x\2 - 0x\1 + 1/p" $PROC_IOMEM)
|
|
|
|
echo $(( (sum) / 1024 / 1024 / 1024))
|
2021-02-04 01:45:36 +00:00
|
|
|
}
|
|
|
|
|
2022-05-12 02:48:31 +00:00
|
|
|
# Return the recommended size for the reserved crashkernel memory
|
|
|
|
# depending on the system memory size.
|
|
|
|
#
|
|
|
|
# This functions is expected to be consistent with the parse_crashkernel_mem()
|
|
|
|
# in kernel i.e. how kernel allocates the kdump memory given the crashkernel
|
|
|
|
# parameter crashkernel=range1:size1[,range2:size2,…] and the system memory
|
|
|
|
# size.
|
2021-02-04 01:45:36 +00:00
|
|
|
get_recommend_size()
|
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
local mem_size=$1
|
|
|
|
local _ck_cmdline=$2
|
2022-05-12 02:48:31 +00:00
|
|
|
local range start start_unit end end_unit size
|
2021-09-13 19:09:30 +00:00
|
|
|
|
2022-05-12 02:48:31 +00:00
|
|
|
while read -r -d , range; do
|
|
|
|
# need to use non-default IFS as double spaces are used as a
|
|
|
|
# single delimiter while commas aren't...
|
|
|
|
IFS=, read start start_unit end end_unit size <<< \
|
|
|
|
"$(echo "$range" | sed -n "s/\([0-9]\+\)\([GT]\?\)-\([0-9]*\)\([GT]\?\):\([0-9]\+[MG]\)/\1,\2,\3,\4,\5/p")"
|
|
|
|
|
|
|
|
# aka. 102400T
|
|
|
|
end=${end:-104857600}
|
|
|
|
[[ "$end_unit" == T ]] && end=$((end * 1024))
|
|
|
|
[[ "$start_unit" == T ]] && start=$((start * 1024))
|
|
|
|
|
|
|
|
if [[ $mem_size -ge $start ]] && [[ $mem_size -lt $end ]]; then
|
|
|
|
echo "$size"
|
2021-09-13 19:09:30 +00:00
|
|
|
return
|
|
|
|
fi
|
2022-05-12 02:48:31 +00:00
|
|
|
|
|
|
|
# append a ',' as read expects the 'file' to end with a delimiter
|
|
|
|
done <<< "$_ck_cmdline,"
|
|
|
|
|
|
|
|
# no matching range found
|
|
|
|
echo "0M"
|
2021-02-04 01:45:36 +00:00
|
|
|
}
|
|
|
|
|
2021-11-16 03:26:31 +00:00
|
|
|
# get default crashkernel
|
|
|
|
# $1 dump mode, if not specified, dump_mode will be judged by is_fadump_capable
|
|
|
|
kdump_get_arch_recommend_crashkernel()
|
|
|
|
{
|
|
|
|
local _arch _ck_cmdline _dump_mode
|
|
|
|
|
|
|
|
if [[ -z "$1" ]]; then
|
|
|
|
if is_fadump_capable; then
|
|
|
|
_dump_mode=fadump
|
|
|
|
else
|
|
|
|
_dump_mode=kdump
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
_dump_mode=$1
|
|
|
|
fi
|
|
|
|
|
|
|
|
_arch=$(uname -m)
|
|
|
|
|
|
|
|
if [[ $_arch == "x86_64" ]] || [[ $_arch == "s390x" ]]; then
|
|
|
|
_ck_cmdline="1G-4G:192M,4G-64G:256M,64G-:512M"
|
|
|
|
elif [[ $_arch == "aarch64" ]]; then
|
2022-06-13 02:25:26 +00:00
|
|
|
# For 4KB page size, the formula is based on x86 plus extra = 64M
|
|
|
|
_ck_cmdline="1G-4G:256M,4G-64G:320M,64G-:576M"
|
2021-11-16 03:26:31 +00:00
|
|
|
elif [[ $_arch == "ppc64le" ]]; then
|
|
|
|
if [[ $_dump_mode == "fadump" ]]; then
|
|
|
|
_ck_cmdline="4G-16G:768M,16G-64G:1G,64G-128G:2G,128G-1T:4G,1T-2T:6G,2T-4T:12G,4T-8T:20G,8T-16T:36G,16T-32T:64G,32T-64T:128G,64T-:180G"
|
|
|
|
else
|
|
|
|
_ck_cmdline="2G-4G:384M,4G-16G:512M,16G-64G:1G,64G-128G:2G,128G-:4G"
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo -n "$_ck_cmdline"
|
|
|
|
}
|
|
|
|
|
2021-02-04 01:45:36 +00:00
|
|
|
# return recommended size based on current system RAM size
|
2021-09-12 17:17:05 +00:00
|
|
|
# $1: kernel version, if not set, will defaults to $(uname -r)
|
2021-02-04 01:45:36 +00:00
|
|
|
kdump_get_arch_recommend_size()
|
|
|
|
{
|
2022-01-26 00:48:18 +00:00
|
|
|
local _ck_cmdline _sys_mem
|
2021-07-01 17:31:26 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
if ! [[ -r "/proc/iomem" ]]; then
|
|
|
|
echo "Error, can not access /proc/iomem."
|
|
|
|
return 1
|
|
|
|
fi
|
2022-01-26 00:48:18 +00:00
|
|
|
_sys_mem=$(get_system_size)
|
2021-11-16 03:26:31 +00:00
|
|
|
_ck_cmdline=$(kdump_get_arch_recommend_crashkernel)
|
2022-01-25 08:16:58 +00:00
|
|
|
_ck_cmdline=${_ck_cmdline//-:/-102400T:}
|
2022-01-26 00:48:18 +00:00
|
|
|
get_recommend_size "$_sys_mem" "$_ck_cmdline"
|
2021-02-04 01:45:36 +00:00
|
|
|
}
|
2021-04-07 17:36:49 +00:00
|
|
|
|
|
|
|
# Print all underlying crypt devices of a block device
|
|
|
|
# print nothing if device is not on top of a crypt device
|
|
|
|
# $1: the block device to be checked in maj:min format
|
|
|
|
get_luks_crypt_dev()
|
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
local _type
|
2021-09-07 19:48:19 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
[[ -b /dev/block/$1 ]] || return 1
|
2021-04-07 17:36:49 +00:00
|
|
|
|
2022-02-16 06:26:38 +00:00
|
|
|
_type=$(blkid -u filesystem,crypto -o export -- "/dev/block/$1" | \
|
|
|
|
sed -n -E "s/^TYPE=(.*)$/\1/p")
|
2021-09-13 19:09:30 +00:00
|
|
|
[[ $_type == "crypto_LUKS" ]] && echo "$1"
|
2021-04-07 17:36:49 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
for _x in "/sys/dev/block/$1/slaves/"*; do
|
|
|
|
[[ -f $_x/dev ]] || continue
|
|
|
|
[[ $_x/subsystem -ef /sys/class/block ]] || continue
|
|
|
|
get_luks_crypt_dev "$(< "$_x/dev")"
|
|
|
|
done
|
2021-04-07 17:36:49 +00:00
|
|
|
}
|
2021-05-18 08:13:16 +00:00
|
|
|
|
|
|
|
# kdump_get_maj_min <device>
|
|
|
|
# Prints the major and minor of a device node.
|
|
|
|
# Example:
|
|
|
|
# $ get_maj_min /dev/sda2
|
|
|
|
# 8:2
|
2021-09-13 19:09:30 +00:00
|
|
|
kdump_get_maj_min()
|
|
|
|
{
|
|
|
|
local _majmin
|
|
|
|
_majmin="$(stat -L -c '%t:%T' "$1" 2> /dev/null)"
|
|
|
|
printf "%s" "$((0x${_majmin%:*})):$((0x${_majmin#*:}))"
|
2021-05-18 08:13:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
get_all_kdump_crypt_dev()
|
|
|
|
{
|
2021-09-13 19:09:30 +00:00
|
|
|
local _dev
|
2021-05-18 08:13:16 +00:00
|
|
|
|
2021-09-13 19:09:30 +00:00
|
|
|
for _dev in $(get_block_dump_target); do
|
|
|
|
get_luks_crypt_dev "$(kdump_get_maj_min "$_dev")"
|
|
|
|
done
|
2021-05-18 08:13:16 +00:00
|
|
|
}
|