2013-09-24 13:33:27 +00:00
|
|
|
#!/bin/sh
|
|
|
|
#
|
2013-12-17 06:54:15 +00:00
|
|
|
# Kdump common variables and functions
|
2013-09-24 13:33:27 +00:00
|
|
|
#
|
|
|
|
|
2014-04-11 12:26:59 +00:00
|
|
|
DEFAULT_PATH="/var/crash/"
|
2014-04-02 08:33:41 +00:00
|
|
|
FENCE_KDUMP_CONFIG_FILE="/etc/sysconfig/fence_kdump"
|
2013-12-17 06:54:15 +00:00
|
|
|
FENCE_KDUMP_SEND="/usr/libexec/fence_kdump_send"
|
2017-08-30 08:45:45 +00:00
|
|
|
FADUMP_ENABLED_SYS_NODE="/sys/kernel/fadump_enabled"
|
2021-08-03 11:49:51 +00:00
|
|
|
KDUMP_CONFIG_FILE="/etc/kdump.conf"
|
2017-08-30 08:45:45 +00:00
|
|
|
|
|
|
|
is_fadump_capable()
|
|
|
|
{
|
|
|
|
# Check if firmware-assisted dump is enabled
|
|
|
|
# if no, fallback to kdump check
|
|
|
|
if [ -f $FADUMP_ENABLED_SYS_NODE ]; then
|
|
|
|
rc=`cat $FADUMP_ENABLED_SYS_NODE`
|
|
|
|
[ $rc -eq 1 ] && return 0
|
|
|
|
fi
|
|
|
|
return 1
|
|
|
|
}
|
2013-12-17 06:54:15 +00:00
|
|
|
|
2021-06-23 14:36:48 +00:00
|
|
|
is_squash_available() {
|
|
|
|
for kmodule in squashfs overlay loop; do
|
|
|
|
if [ -z "$KDUMP_KERNELVER" ]; then
|
|
|
|
modprobe --dry-run $kmodule &>/dev/null || return 1
|
|
|
|
else
|
|
|
|
modprobe -S $KDUMP_KERNELVER --dry-run $kmodule &>/dev/null || return 1
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
2016-05-09 08:17:54 +00:00
|
|
|
perror_exit() {
|
2020-10-27 09:04:22 +00:00
|
|
|
derror "$@"
|
2016-05-09 08:17:54 +00:00
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
2019-11-30 15:53:02 +00:00
|
|
|
is_fs_type_nfs()
|
|
|
|
{
|
|
|
|
[ "$1" = "nfs" ] || [ "$1" = "nfs4" ]
|
|
|
|
}
|
|
|
|
|
2013-09-24 13:33:27 +00:00
|
|
|
is_ssh_dump_target()
|
|
|
|
{
|
2021-08-03 17:18:48 +00:00
|
|
|
[[ $(kdump_get_conf_val ssh) == *@* ]]
|
2013-09-24 13:33:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
is_nfs_dump_target()
|
|
|
|
{
|
2021-08-03 17:18:48 +00:00
|
|
|
if [[ $(kdump_get_conf_val nfs) ]]; then
|
2019-11-30 15:53:02 +00:00
|
|
|
return 0;
|
|
|
|
fi
|
|
|
|
|
2021-08-03 17:18:48 +00:00
|
|
|
if is_fs_type_nfs $(get_dracut_args_fstype "$(kdump_get_conf_val dracut_args)"); then
|
2019-11-30 15:53:02 +00:00
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
|
|
|
|
local _save_path=$(get_save_path)
|
|
|
|
local _target=$(get_target_from_path $_save_path)
|
|
|
|
local _fstype=$(get_fs_type_from_target $_target)
|
|
|
|
|
|
|
|
if is_fs_type_nfs $_fstype; then
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
|
|
|
|
return 1
|
2013-09-24 13:33:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
is_raw_dump_target()
|
|
|
|
{
|
2021-08-03 17:18:48 +00:00
|
|
|
[[ $(kdump_get_conf_val raw) ]]
|
2013-09-24 13:33:27 +00:00
|
|
|
}
|
2013-09-26 11:35:59 +00:00
|
|
|
|
pass mount info to dracut when default target is a separate disk
When user does not specify dump target explicitly, it's better to
dump to the "path" specified. That means after dump user enter into
1st kernel, can find vmcore in the "path". If that path is in root
fs, vmcore is stored in root fs. If separate disk is mounted on
any tier of "path", we just dump vmcore into the left path on the
left separate disk.
E.g in kdump.conf
path /mnt/nfs
in mount info,
/dev/vdb on /mnt type ext4 (rw,relatime,seclabel,data=ordered)
Then vmcore will be saved in /nfs of /dev/vdb.
In this patch, pass mount info to dracut in this case if separate
disk is mounted on any tier of "path".
Meanwhile introduce a function in kdump-lib.sh to check if any
target is specified.
v4->v5:
Per Vivek's comment, add a helper function is_fs_dump_target.
Then is_user_configured_dump_target is rewrite with these helper
functions.
v5->v7:
No v6 for this patch. Just use newly introduced function
is_fs_type_nfs in handle_default_dump_target.
Signed-off-by: Baoquan He <bhe@redhat.com>
Acked-by: Vivek Goyal <vgoyal@redhat.com>
2014-04-11 12:27:01 +00:00
|
|
|
is_fs_dump_target()
|
|
|
|
{
|
2021-08-03 17:18:48 +00:00
|
|
|
[[ $(kdump_get_conf_val "ext[234]\|xfs\|btrfs\|minix") ]]
|
pass mount info to dracut when default target is a separate disk
When user does not specify dump target explicitly, it's better to
dump to the "path" specified. That means after dump user enter into
1st kernel, can find vmcore in the "path". If that path is in root
fs, vmcore is stored in root fs. If separate disk is mounted on
any tier of "path", we just dump vmcore into the left path on the
left separate disk.
E.g in kdump.conf
path /mnt/nfs
in mount info,
/dev/vdb on /mnt type ext4 (rw,relatime,seclabel,data=ordered)
Then vmcore will be saved in /nfs of /dev/vdb.
In this patch, pass mount info to dracut in this case if separate
disk is mounted on any tier of "path".
Meanwhile introduce a function in kdump-lib.sh to check if any
target is specified.
v4->v5:
Per Vivek's comment, add a helper function is_fs_dump_target.
Then is_user_configured_dump_target is rewrite with these helper
functions.
v5->v7:
No v6 for this patch. Just use newly introduced function
is_fs_type_nfs in handle_default_dump_target.
Signed-off-by: Baoquan He <bhe@redhat.com>
Acked-by: Vivek Goyal <vgoyal@redhat.com>
2014-04-11 12:27:01 +00:00
|
|
|
}
|
|
|
|
|
2021-08-03 11:49:51 +00:00
|
|
|
# Read kdump config in well formatted style
|
|
|
|
kdump_read_conf()
|
2019-05-17 08:48:46 +00:00
|
|
|
{
|
2021-08-03 11:49:51 +00:00
|
|
|
# Following steps are applied in order: strip trailing comment, strip trailing space,
|
|
|
|
# strip heading space, match non-empty line, remove duplicated spaces between conf name and value
|
|
|
|
[ -f "$KDUMP_CONFIG_FILE" ] && sed -n -e "s/#.*//;s/\s*$//;s/^\s*//;s/\(\S\+\)\s*\(.*\)/\1 \2/p" $KDUMP_CONFIG_FILE
|
2019-05-17 08:48:46 +00:00
|
|
|
}
|
|
|
|
|
kdump-lib.sh: add a config value retrive helper
Add a helper kdump_get_conf_val to replace get_option_value.
It can help cover more corner cases in the code, like when there are
multiple spaces in config file, config value separated by a tab,
heading spaces, or trailing comments.
And this uses "sed group command" and "sed hold buffer", make it much
faster than previous `grep <config> | tail -1`.
This helper is supposed to provide a universal way for kexec-tools
scripts to read in config value. Currently, different scripts are
reading the config in many different fragile ways.
For example, following codes are found in kexec-tools script code base:
1. grep ^force_rebuild $KDUMP_CONFIG_FILE
echo $_force_rebuild | cut -d' ' -f2
2. grep ^kdump_post $KDUMP_CONFIG_FILE | cut -d\ -f2
3. awk '/^sshkey/ {print $2}' $conf_file
4. grep ^path $KDUMP_CONFIG_FILE | cut -d' ' -f2-
1, 2, and 4 will fail if the space is replaced by, e.g. a tab
1 and 2 might fail if there are multiple spaces between config name
and config value:
"kdump_post /var/crash/scripts/kdump-post.sh"
A space will be read instead of config value.
1, 2, 3 will fail if there are space in file path, like:
"kdump_post /var/crash/scripts dir/kdump-post.sh"
4 will fail if there are trailing comments:
"path /var/crash # some comment here"
And all will fail if there are heading space,
" path /var/crash"
And all will most likely cause problems if the config file contains
the same option more than once.
And all of them are slower than the new sed call. Old get_option_value
is also very slow and doesn't handle heading space.
Although we never claim to support heading space or tailing comments
before, it's harmless to be more robust on config reading, and many
conf files in /etc support heading spaces. And have a faster and
safer config reading helper makes it easier to clean up the code.
Signed-off-by: Kairui Song <kasong@redhat.com>
Acked-by: Philipp Rudo <prudo@redhat.com>
2021-08-16 15:25:14 +00:00
|
|
|
# Retrieves config value defined in kdump.conf
|
|
|
|
# $1: config name, sed regexp compatible
|
|
|
|
kdump_get_conf_val() {
|
|
|
|
# For lines matching "^\s*$1\s+", remove matched part (config name including space),
|
|
|
|
# remove tailing comment, space, then store in hold space. Print out the hold buffer on last line.
|
|
|
|
[ -f "$KDUMP_CONFIG_FILE" ] && \
|
|
|
|
sed -n -e "/^\s*\($1\)\s\+/{s/^\s*\($1\)\s\+//;s/#.*//;s/\s*$//;h};\${x;p}" $KDUMP_CONFIG_FILE
|
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
|
|
|
# no pcs or fence_kdump_send executables installed?
|
|
|
|
type -P pcs > /dev/null || return 1
|
|
|
|
[ -x $FENCE_KDUMP_SEND ] || return 1
|
|
|
|
|
|
|
|
# fence kdump not configured?
|
2017-02-10 02:20:57 +00:00
|
|
|
(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()
|
|
|
|
{
|
|
|
|
[ -x $FENCE_KDUMP_SEND ] || return 1
|
|
|
|
|
2021-08-03 17:18:48 +00:00
|
|
|
[[ $(kdump_get_conf_val fence_kdump_nodes) ]]
|
2014-04-02 08:33:47 +00:00
|
|
|
}
|
|
|
|
|
2016-05-09 08:17:54 +00:00
|
|
|
to_dev_name() {
|
|
|
|
local dev="${1//\"/}"
|
|
|
|
|
|
|
|
case "$dev" in
|
|
|
|
UUID=*)
|
|
|
|
dev=`blkid -U "${dev#UUID=}"`
|
|
|
|
;;
|
|
|
|
LABEL=*)
|
|
|
|
dev=`blkid -L "${dev#LABEL=}"`
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
echo $dev
|
|
|
|
}
|
|
|
|
|
2017-07-07 07:48:52 +00:00
|
|
|
is_user_configured_dump_target()
|
|
|
|
{
|
2021-08-03 17:18:48 +00:00
|
|
|
[[ $(kdump_get_conf_val "ext[234]\|xfs\|btrfs\|minix\|raw\|nfs\|ssh") ]] || is_mount_in_dracut_args
|
2017-07-07 07:48:52 +00:00
|
|
|
}
|
|
|
|
|
2014-03-03 10:37:14 +00:00
|
|
|
get_user_configured_dump_disk()
|
|
|
|
{
|
|
|
|
local _target
|
|
|
|
|
2021-08-03 17:18:48 +00:00
|
|
|
_target=$(kdump_get_conf_val "ext[234]\|xfs\|btrfs\|minix\|raw")
|
2017-07-07 07:48:52 +00:00
|
|
|
[ -n "$_target" ] && echo $_target && return
|
2014-03-03 10:37:14 +00:00
|
|
|
|
2021-08-03 17:18:48 +00:00
|
|
|
_target=$(get_dracut_args_target "$(kdump_get_conf_val "dracut_args")")
|
2017-07-07 07:48:52 +00:00
|
|
|
[ -b "$_target" ] && echo $_target
|
2014-03-03 10:37:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
get_root_fs_device()
|
|
|
|
{
|
2019-05-09 06:31:24 +00:00
|
|
|
findmnt -k -f -n -o SOURCE /
|
2014-03-03 10:37:14 +00:00
|
|
|
}
|
|
|
|
|
2017-07-07 07:48:52 +00:00
|
|
|
get_save_path()
|
|
|
|
{
|
2021-08-03 17:18:48 +00:00
|
|
|
local _save_path=$(kdump_get_conf_val path)
|
2019-11-30 15:46:55 +00:00
|
|
|
[ -z "$_save_path" ] && _save_path=$DEFAULT_PATH
|
2017-07-07 07:48:52 +00:00
|
|
|
|
2019-11-30 15:46:55 +00:00
|
|
|
# strip the duplicated "/"
|
2020-03-08 08:41:10 +00:00
|
|
|
echo $_save_path | tr -s /
|
2017-07-07 07:48:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
get_block_dump_target()
|
|
|
|
{
|
|
|
|
local _target _path
|
|
|
|
|
|
|
|
if is_ssh_dump_target || is_nfs_dump_target; then
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
_target=$(get_user_configured_dump_disk)
|
|
|
|
[ -n "$_target" ] && echo $(to_dev_name $_target) && return
|
|
|
|
|
|
|
|
# Get block device name from local save path
|
|
|
|
_path=$(get_save_path)
|
|
|
|
_target=$(get_target_from_path $_path)
|
|
|
|
[ -b "$_target" ] && echo $(to_dev_name $_target)
|
|
|
|
}
|
|
|
|
|
2017-07-07 07:48:53 +00:00
|
|
|
is_dump_to_rootfs()
|
|
|
|
{
|
2021-08-03 17:18:48 +00:00
|
|
|
[[ $(kdump_get_conf_val "failure_action|default") == dump_to_rootfs ]]
|
2017-07-07 07:48:53 +00:00
|
|
|
}
|
|
|
|
|
2019-01-17 20:31:23 +00:00
|
|
|
get_failure_action_target()
|
2017-07-07 07:48:53 +00:00
|
|
|
{
|
|
|
|
local _target
|
|
|
|
|
|
|
|
if is_dump_to_rootfs; then
|
|
|
|
# Get rootfs device name
|
|
|
|
_target=$(get_root_fs_device)
|
|
|
|
[ -b "$_target" ] && echo $(to_dev_name $_target) && return
|
|
|
|
# Then, must be nfs root
|
|
|
|
echo "nfs"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# Get kdump targets(including root in case of dump_to_rootfs).
|
|
|
|
get_kdump_targets()
|
|
|
|
{
|
|
|
|
local _target _root
|
|
|
|
local kdump_targets
|
|
|
|
|
|
|
|
_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
|
|
|
|
|
|
|
|
# Add the root device if dump_to_rootfs is specified.
|
2019-01-17 20:31:23 +00:00
|
|
|
_root=$(get_failure_action_target)
|
2017-07-07 07:48:53 +00:00
|
|
|
if [ -n "$_root" -a "$kdump_targets" != "$_root" ]; then
|
|
|
|
kdump_targets="$kdump_targets $_root"
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo "$kdump_targets"
|
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
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
|
|
|
local _mnt=$(df $1 | tail -1 | awk '{print $NF}')
|
|
|
|
local _path=${1#$_mnt}
|
|
|
|
|
|
|
|
local _src=$(get_mount_info SOURCE target $_mnt -f)
|
|
|
|
local _opt=$(get_mount_info OPTIONS target $_mnt -f)
|
|
|
|
local _fstype=$(get_mount_info FSTYPE target $_mnt -f)
|
|
|
|
|
|
|
|
# bind mount in fstab
|
|
|
|
if [[ -d "$_src" ]] && [[ "$_fstype" = none ]] && (echo "$_opt" | grep -q "\bbind\b"); then
|
|
|
|
echo $_src$_path && return
|
2020-03-10 15:52:33 +00:00
|
|
|
fi
|
2015-04-17 08:26:24 +00:00
|
|
|
|
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
|
|
|
# direct mount
|
|
|
|
local _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
|
|
|
|
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
|
|
|
local _fsroot=${_src#$_src_nofsroot[}
|
|
|
|
_fsroot=${_fsroot%]}
|
|
|
|
_mnt=$(get_mount_info TARGET source $_src_nofsroot -f)
|
|
|
|
|
|
|
|
# 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
|
|
|
# Return the current underlaying device of a path, ignore bind mounts
|
2014-04-11 12:26:59 +00:00
|
|
|
get_target_from_path()
|
|
|
|
{
|
2016-09-12 07:10:04 +00:00
|
|
|
local _target
|
|
|
|
|
|
|
|
_target=$(df $1 2>/dev/null | tail -1 | awk '{print $1}')
|
|
|
|
[[ "$_target" == "/dev/root" ]] && [[ ! -e /dev/root ]] && _target=$(get_root_fs_device)
|
|
|
|
echo $_target
|
2014-04-11 12:26:59 +00:00
|
|
|
}
|
|
|
|
|
2020-03-11 13:06:03 +00:00
|
|
|
is_mounted()
|
|
|
|
{
|
|
|
|
findmnt -k -n $1 &>/dev/null
|
|
|
|
}
|
|
|
|
|
2020-03-12 05:52:55 +00:00
|
|
|
get_mount_info()
|
|
|
|
{
|
|
|
|
local _info_type=$1 _src_type=$2 _src=$3; shift 3
|
2020-11-23 13:41:51 +00:00
|
|
|
local _info=$(findmnt -k -n -r -o $_info_type --$_src_type $_src $@)
|
2020-03-12 05:52:55 +00:00
|
|
|
|
2020-11-23 13:41:51 +00:00
|
|
|
[ -z "$_info" ] && [ -e "/etc/fstab" ] && _info=$(findmnt -s -n -r -o $_info_type --$_src_type $_src $@)
|
2020-03-12 05:52:55 +00:00
|
|
|
|
|
|
|
echo $_info
|
|
|
|
}
|
|
|
|
|
2019-05-09 06:31:24 +00:00
|
|
|
get_fs_type_from_target()
|
2014-04-11 12:26:59 +00:00
|
|
|
{
|
2020-03-12 05:52:55 +00:00
|
|
|
get_mount_info FSTYPE source $1 -f
|
|
|
|
}
|
|
|
|
|
|
|
|
get_mntopt_from_target()
|
|
|
|
{
|
|
|
|
get_mount_info OPTIONS source $1 -f
|
2014-04-11 12:26:59 +00:00
|
|
|
}
|
2020-03-10 15:52:33 +00:00
|
|
|
# Find the general mount point of a dump target, not the bind mount point
|
2014-04-11 12:26:59 +00:00
|
|
|
get_mntpoint_from_target()
|
|
|
|
{
|
2020-03-10 15:52:33 +00:00
|
|
|
# Expcilitly specify --source to findmnt could ensure non-bind mount is returned
|
2020-03-12 05:52:55 +00:00
|
|
|
get_mount_info TARGET 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()
|
|
|
|
{
|
|
|
|
local _mntpoint=$(get_mntpoint_from_target $1)
|
|
|
|
|
|
|
|
# mount under /sysroot if dump to root disk or mount under
|
mkdumprd: generate usable kdump initramfs even target is not mounted
Currently kexec-tools always depend on dump target to be mounted, which
caused some inconvenience for setup.
So for user configured target, allow kdump to start and build initramfs
even if target is not mounted.
When a mounted user configured target is used, the behavior is not
changed.
When a unmounted user configured target is used, mkdumprd will look for
corresponding mount info in fstab, and a entry with noauto option is
founded, mkdumprd will try to mount it inplace with optoins specified
in fstab and do basic checks on the device, then umount it.
If there is no fstab entry, mkdumprd will try to mount it in temporary
path with defaults option, do same basic check and umount it.
If there is a fstab entry but "noauto" option is not used, then there
must be some reason that the target device is not mounted, mkdumprd will
error out.
When path based target is used, there is no behavior change.
Signed-off-by: Kairui Song <kasong@redhat.com>
Acked-by: Pingfan Liu <piliu@redhat.com>
2020-05-12 10:47:19 +00:00
|
|
|
# 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"
|
2020-03-05 15:28:53 +00:00
|
|
|
else
|
mkdumprd: generate usable kdump initramfs even target is not mounted
Currently kexec-tools always depend on dump target to be mounted, which
caused some inconvenience for setup.
So for user configured target, allow kdump to start and build initramfs
even if target is not mounted.
When a mounted user configured target is used, the behavior is not
changed.
When a unmounted user configured target is used, mkdumprd will look for
corresponding mount info in fstab, and a entry with noauto option is
founded, mkdumprd will try to mount it inplace with optoins specified
in fstab and do basic checks on the device, then umount it.
If there is no fstab entry, mkdumprd will try to mount it in temporary
path with defaults option, do same basic check and umount it.
If there is a fstab entry but "noauto" option is not used, then there
must be some reason that the target device is not mounted, mkdumprd will
error out.
When path based target is used, there is no behavior change.
Signed-off-by: Kairui Song <kasong@redhat.com>
Acked-by: Pingfan Liu <piliu@redhat.com>
2020-05-12 10:47:19 +00:00
|
|
|
if [ "$_mntpoint" = "/" ];then
|
|
|
|
_mntpoint="/sysroot"
|
|
|
|
else
|
|
|
|
_mntpoint="/kdumproot/$_mntpoint"
|
|
|
|
fi
|
2020-03-05 15:28:53 +00:00
|
|
|
fi
|
|
|
|
|
|
|
|
# strip duplicated "/"
|
|
|
|
echo $_mntpoint | tr -s "/"
|
|
|
|
}
|
|
|
|
|
2020-06-16 03:25:26 +00:00
|
|
|
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")
|
|
|
|
}
|
|
|
|
|
2021-06-24 19:42:19 +00:00
|
|
|
is_atomic()
|
|
|
|
{
|
|
|
|
grep -q "ostree" /proc/cmdline
|
|
|
|
}
|
|
|
|
|
2015-07-23 10:29:24 +00:00
|
|
|
is_ipv6_address()
|
|
|
|
{
|
|
|
|
echo $1 | grep -q ":"
|
|
|
|
}
|
|
|
|
|
|
|
|
# get ip address or hostname from nfs/ssh config value
|
|
|
|
get_remote_host()
|
|
|
|
{
|
|
|
|
local _config_val=$1
|
|
|
|
|
|
|
|
# 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
|
|
|
|
}
|
|
|
|
|
|
|
|
is_hostname()
|
|
|
|
{
|
|
|
|
local _hostname=`echo $1 | grep ":"`
|
|
|
|
|
|
|
|
if [ -n "$_hostname" ]; then
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
echo $1 | grep -q "[a-zA-Z]"
|
|
|
|
}
|
2016-06-06 05:01:44 +00:00
|
|
|
|
|
|
|
# Copied from "/etc/sysconfig/network-scripts/network-functions"
|
|
|
|
get_hwaddr()
|
|
|
|
{
|
|
|
|
if [ -f "/sys/class/net/${1}/address" ]; then
|
|
|
|
awk '{ print toupper($0) }' < /sys/class/net/${1}/address
|
|
|
|
elif [ -d "/sys/class/net/${1}" ]; then
|
|
|
|
LC_ALL= LANG= ip -o link show ${1} 2>/dev/null | \
|
|
|
|
awk '{ print toupper(gensub(/.*link\/[^ ]* ([[:alnum:]:]*).*/,
|
|
|
|
"\\1", 1)); }'
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2021-04-01 07:32:08 +00:00
|
|
|
|
|
|
|
# Get value by a field using "nmcli -g"
|
|
|
|
#
|
|
|
|
# "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()
|
|
|
|
{
|
|
|
|
local _nm_show_cmd=$1
|
|
|
|
local _field=$2
|
|
|
|
|
|
|
|
local val=$(LANG=C nmcli --get-values $_field $_nm_show_cmd)
|
|
|
|
|
|
|
|
echo -n "$val"
|
|
|
|
}
|
|
|
|
|
2021-04-01 07:32:09 +00:00
|
|
|
# Get nmcli connection apath (a D-Bus active connection path ) by ifname
|
|
|
|
#
|
|
|
|
# apath is used for nmcli connection operations, e.g.
|
|
|
|
# $ nmcli connection show $apath
|
|
|
|
get_nmcli_connection_apath_by_ifname()
|
|
|
|
{
|
|
|
|
local _ifname=$1
|
|
|
|
local _nm_show_cmd="device show $_ifname"
|
|
|
|
|
|
|
|
local _apath=$(get_nmcli_value_by_field "$_nm_show_cmd" "GENERAL.CON-PATH")
|
|
|
|
|
|
|
|
echo -n "$_apath"
|
|
|
|
}
|
|
|
|
|
2021-04-01 07:32:10 +00:00
|
|
|
# Get nmcli connection show cmd by ifname
|
|
|
|
#
|
|
|
|
# "$_apath" is supposed to not contain any chracter that
|
|
|
|
# need to be escapded, e.g. space. Otherwise get_nmcli_value_by_field
|
|
|
|
# would fail.
|
|
|
|
get_nmcli_connection_show_cmd_by_ifname()
|
|
|
|
{
|
|
|
|
local _ifname="$1"
|
|
|
|
local _apath=$(get_nmcli_connection_apath_by_ifname "$_ifname")
|
|
|
|
local _nm_show_cmd="connection show $_apath"
|
|
|
|
|
|
|
|
echo -n "$_nm_show_cmd"
|
|
|
|
}
|
|
|
|
|
2016-06-06 05:01:44 +00:00
|
|
|
get_ifcfg_by_device()
|
|
|
|
{
|
|
|
|
grep -E -i -l "^[[:space:]]*DEVICE=\"*${1}\"*[[:space:]]*$" \
|
|
|
|
/etc/sysconfig/network-scripts/ifcfg-* 2>/dev/null | head -1
|
|
|
|
}
|
|
|
|
|
|
|
|
get_ifcfg_by_hwaddr()
|
|
|
|
{
|
|
|
|
grep -E -i -l "^[[:space:]]*HWADDR=\"*${1}\"*[[:space:]]*$" \
|
|
|
|
/etc/sysconfig/network-scripts/ifcfg-* 2>/dev/null | head -1
|
|
|
|
}
|
|
|
|
|
|
|
|
get_ifcfg_by_uuid()
|
|
|
|
{
|
|
|
|
grep -E -i -l "^[[:space:]]*UUID=\"*${1}\"*[[:space:]]*$" \
|
|
|
|
/etc/sysconfig/network-scripts/ifcfg-* 2>/dev/null | head -1
|
|
|
|
}
|
|
|
|
|
|
|
|
get_ifcfg_by_name()
|
|
|
|
{
|
|
|
|
grep -E -i -l "^[[:space:]]*NAME=\"*${1}\"*[[:space:]]*$" \
|
|
|
|
/etc/sysconfig/network-scripts/ifcfg-* 2>/dev/null | head -1
|
|
|
|
}
|
|
|
|
|
|
|
|
is_nm_running()
|
|
|
|
{
|
|
|
|
[ "$(LANG=C nmcli -t --fields running general status 2>/dev/null)" = "running" ]
|
|
|
|
}
|
|
|
|
|
|
|
|
is_nm_handling()
|
|
|
|
{
|
|
|
|
LANG=C nmcli -t --fields device,state dev status 2>/dev/null \
|
|
|
|
| grep -q "^\(${1}:connected\)\|\(${1}:connecting.*\)$"
|
|
|
|
}
|
|
|
|
|
|
|
|
# $1: netdev name
|
|
|
|
get_ifcfg_nmcli()
|
|
|
|
{
|
|
|
|
local nm_uuid nm_name
|
|
|
|
local ifcfg_file
|
|
|
|
|
|
|
|
# Get the active nmcli config name of $1
|
|
|
|
if is_nm_running && is_nm_handling "${1}" ; then
|
|
|
|
# The configuration "uuid" and "name" generated by nm is wrote to
|
|
|
|
# the ifcfg file as "UUID=<nm_uuid>" and "NAME=<nm_name>".
|
|
|
|
nm_uuid=$(LANG=C nmcli -t --fields uuid,device c show --active 2>/dev/null \
|
|
|
|
| grep "${1}" | head -1 | cut -d':' -f1)
|
|
|
|
nm_name=$(LANG=C nmcli -t --fields name,device c show --active 2>/dev/null \
|
|
|
|
| grep "${1}" | head -1 | cut -d':' -f1)
|
|
|
|
ifcfg_file=$(get_ifcfg_by_uuid "${nm_uuid}")
|
|
|
|
[ -z "${ifcfg_file}" ] && ifcfg_file=$(get_ifcfg_by_name "${nm_name}")
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo -n "${ifcfg_file}"
|
|
|
|
}
|
|
|
|
|
|
|
|
# $1: netdev name
|
|
|
|
get_ifcfg_legacy()
|
|
|
|
{
|
|
|
|
local ifcfg_file
|
|
|
|
|
|
|
|
ifcfg_file="/etc/sysconfig/network-scripts/ifcfg-${1}"
|
|
|
|
[ -f "${ifcfg_file}" ] && echo -n "${ifcfg_file}" && return
|
|
|
|
|
|
|
|
ifcfg_file=$(get_ifcfg_by_name "${1}")
|
|
|
|
[ -f "${ifcfg_file}" ] && echo -n "${ifcfg_file}" && return
|
|
|
|
|
|
|
|
local hwaddr=$(get_hwaddr "${1}")
|
|
|
|
if [ -n "$hwaddr" ]; then
|
|
|
|
ifcfg_file=$(get_ifcfg_by_hwaddr "${hwaddr}")
|
|
|
|
[ -f "${ifcfg_file}" ] && echo -n "${ifcfg_file}" && return
|
|
|
|
fi
|
|
|
|
|
|
|
|
ifcfg_file=$(get_ifcfg_by_device "${1}")
|
|
|
|
|
|
|
|
echo -n "${ifcfg_file}"
|
|
|
|
}
|
|
|
|
|
|
|
|
# $1: netdev name
|
|
|
|
# Return the ifcfg file whole name(including the path) of $1 if any.
|
|
|
|
get_ifcfg_filename() {
|
|
|
|
local ifcfg_file
|
|
|
|
|
|
|
|
ifcfg_file=$(get_ifcfg_nmcli "${1}")
|
|
|
|
if [ -z "${ifcfg_file}" ]; then
|
|
|
|
ifcfg_file=$(get_ifcfg_legacy "${1}")
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo -n "${ifcfg_file}"
|
|
|
|
}
|
2016-07-20 18:12:20 +00:00
|
|
|
|
2020-10-15 10:22:15 +00:00
|
|
|
# returns 0 when omission of a module is desired in dracut_args
|
2016-07-20 18:12:20 +00:00
|
|
|
# returns 1 otherwise
|
2020-10-15 10:22:15 +00:00
|
|
|
is_dracut_mod_omitted() {
|
|
|
|
local dracut_args dracut_mod=$1
|
|
|
|
|
2021-08-03 17:18:48 +00:00
|
|
|
set -- $(kdump_get_conf_val dracut_args)
|
2020-10-15 10:22:15 +00:00
|
|
|
while [ $# -gt 0 ]; do
|
|
|
|
case $1 in
|
|
|
|
-o|--omit)
|
|
|
|
[[ " ${2//[^[:alnum:]]/ } " == *" $dracut_mod "* ]] && return 0
|
|
|
|
esac
|
|
|
|
shift
|
|
|
|
done
|
|
|
|
|
|
|
|
return 1
|
2016-07-20 18:12:20 +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
|
|
|
|
2020-10-15 10:16:44 +00:00
|
|
|
is_wdt_active() {
|
|
|
|
local active
|
|
|
|
|
|
|
|
[ -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
|
|
|
|
}
|
|
|
|
|
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-08-03 17:18:48 +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
|
|
|
}
|
|
|
|
|
|
|
|
# If $1 contains dracut_args "--mount", return <filesystem type>
|
|
|
|
get_dracut_args_fstype()
|
|
|
|
{
|
|
|
|
echo $1 | grep "\-\-mount" | sed "s/.*--mount .\(.*\)/\1/" | cut -d' ' -f3
|
|
|
|
}
|
|
|
|
|
|
|
|
# If $1 contains dracut_args "--mount", return <device>
|
|
|
|
get_dracut_args_target()
|
|
|
|
{
|
|
|
|
echo $1 | grep "\-\-mount" | sed "s/.*--mount .\(.*\)/\1/" | cut -d' ' -f1
|
|
|
|
}
|
2018-05-22 10:15:07 +00:00
|
|
|
|
|
|
|
check_crash_mem_reserved()
|
|
|
|
{
|
|
|
|
local mem_reserved
|
|
|
|
|
|
|
|
mem_reserved=$(cat /sys/kernel/kexec_crash_size)
|
|
|
|
if [ $mem_reserved -eq 0 ]; then
|
2020-10-27 09:04:22 +00:00
|
|
|
derror "No memory reserved for crash kernel"
|
2018-05-22 10:15:07 +00:00
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
|
|
|
check_kdump_feasibility()
|
|
|
|
{
|
|
|
|
if [ ! -e /sys/kernel/kexec_crash_loaded ]; then
|
2020-10-27 09:04:22 +00:00
|
|
|
derror "Kdump is not supported on this kernel"
|
2018-05-22 10:15:07 +00:00
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
check_crash_mem_reserved
|
|
|
|
return $?
|
|
|
|
}
|
|
|
|
|
|
|
|
check_current_kdump_status()
|
|
|
|
{
|
|
|
|
if [ ! -f /sys/kernel/kexec_crash_loaded ];then
|
2020-10-27 09:04:22 +00:00
|
|
|
derror "Perhaps CONFIG_CRASH_DUMP is not enabled in kernel"
|
2018-05-22 10:15:07 +00:00
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
rc=`cat /sys/kernel/kexec_crash_loaded`
|
|
|
|
if [ $rc == 1 ]; then
|
|
|
|
return 0
|
|
|
|
else
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# remove_cmdline_param <kernel cmdline> <param1> [<param2>] ... [<paramN>]
|
|
|
|
# Remove a list of kernel parameters from a given kernel cmdline and print the result.
|
|
|
|
# For each "arg" in the removing params list, "arg" and "arg=xxx" will be removed if exists.
|
|
|
|
remove_cmdline_param()
|
|
|
|
{
|
|
|
|
local cmdline=$1
|
|
|
|
shift
|
|
|
|
|
|
|
|
for arg in $@; do
|
|
|
|
cmdline=`echo $cmdline | \
|
|
|
|
sed -e "s/\b$arg=[^ ]*//g" \
|
|
|
|
-e "s/^$arg\b//g" \
|
|
|
|
-e "s/[[:space:]]$arg\b//g" \
|
|
|
|
-e "s/\s\+/ /g"`
|
|
|
|
done
|
|
|
|
echo $cmdline
|
|
|
|
}
|
|
|
|
|
|
|
|
#
|
|
|
|
# This function returns the "apicid" of the boot
|
|
|
|
# cpu (cpu 0) if present.
|
|
|
|
#
|
|
|
|
get_bootcpu_apicid()
|
|
|
|
{
|
|
|
|
awk ' \
|
|
|
|
BEGIN { CPU = "-1"; } \
|
|
|
|
$1=="processor" && $2==":" { CPU = $NF; } \
|
|
|
|
CPU=="0" && /^apicid/ { print $NF; } \
|
|
|
|
' \
|
|
|
|
/proc/cpuinfo
|
|
|
|
}
|
|
|
|
|
|
|
|
#
|
|
|
|
# append_cmdline <kernel cmdline> <parameter name> <parameter value>
|
|
|
|
# This function appends argument "$2=$3" to string ($1) if not already present.
|
|
|
|
#
|
|
|
|
append_cmdline()
|
|
|
|
{
|
|
|
|
local cmdline=$1
|
|
|
|
local newstr=${cmdline/$2/""}
|
|
|
|
|
|
|
|
# unchanged str implies argument wasn't there
|
|
|
|
if [ "$cmdline" == "$newstr" ]; then
|
|
|
|
cmdline="${cmdline} ${2}=${3}"
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo $cmdline
|
|
|
|
}
|
|
|
|
|
|
|
|
# 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()
|
|
|
|
{
|
|
|
|
return `tail -n 1 /proc/iomem | awk '{ split ($1, r, "-"); \
|
|
|
|
print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }'`
|
|
|
|
}
|
|
|
|
|
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()
|
|
|
|
{
|
|
|
|
local secure_boot_file setup_mode_file
|
|
|
|
local secure_boot_byte setup_mode_byte
|
|
|
|
|
2021-02-18 06:01:18 +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
|
2020-07-09 15:16:55 +00:00
|
|
|
if [ -f /proc/device-tree/ibm,secureboot/os-secureboot-enforcing ]; then
|
|
|
|
return 0
|
|
|
|
fi
|
2021-02-18 06:01:18 +00:00
|
|
|
if [ -f /proc/device-tree/ibm,secure-boot ] && \
|
|
|
|
[ $(lsprop /proc/device-tree/ibm,secure-boot | tail -1) -ge 2 ]; then
|
|
|
|
return 0
|
|
|
|
fi
|
2020-07-09 15:16:55 +00:00
|
|
|
|
2020-09-15 13:21:28 +00:00
|
|
|
# Detect secure boot on x86 and arm64
|
2020-06-29 13:13:54 +00:00
|
|
|
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)
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
|
|
if [ "$secure_boot_byte" = "1" ] && [ "$setup_mode_byte" = "0" ]; then
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
2020-09-15 13:21:28 +00:00
|
|
|
# Detect secure boot on s390x
|
|
|
|
if [[ -e "/sys/firmware/ipl/secure" && "$(cat /sys/firmware/ipl/secure)" == "1" ]]; then
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
|
2020-06-29 13:13:54 +00:00
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
2018-05-22 10:15:07 +00:00
|
|
|
#
|
|
|
|
# prepare_kexec_args <kexec args>
|
|
|
|
# This function prepares kexec argument.
|
|
|
|
#
|
|
|
|
prepare_kexec_args()
|
|
|
|
{
|
|
|
|
local kexec_args=$1
|
|
|
|
local found_elf_args
|
|
|
|
|
|
|
|
ARCH=`uname -m`
|
|
|
|
if [ "$ARCH" == "i686" -o "$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
|
2020-10-27 09:04:22 +00:00
|
|
|
dwarn "Warning: elf32-core-headers overrides correct elf64 setting"
|
2018-05-22 10:15:07 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2020-07-27 18:40:20 +00:00
|
|
|
#
|
|
|
|
# Detect initrd and kernel location, results are stored in global enviromental 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()
|
|
|
|
{
|
|
|
|
local boot_imglist boot_dirlist boot_initrdlist curr_kver="$(uname -r)"
|
|
|
|
local machine_id
|
|
|
|
|
2021-06-01 11:16:58 +00:00
|
|
|
if [ -z "$KDUMP_KERNELVER" ]; then
|
2020-07-27 18:40:20 +00:00
|
|
|
KDUMP_KERNELVER="$(uname -r)"
|
2018-05-22 10:15:07 +00:00
|
|
|
fi
|
|
|
|
|
2020-07-27 18:40:20 +00:00
|
|
|
read machine_id < /etc/machine-id
|
|
|
|
boot_dirlist=${KDUMP_BOOTDIR:-"/boot /boot/efi /efi /"}
|
|
|
|
boot_imglist="$KDUMP_IMG-$KDUMP_KERNELVER$KDUMP_IMG_EXT $machine_id/$KDUMP_KERNELVER/$KDUMP_IMG"
|
|
|
|
|
|
|
|
# Use BOOT_IMAGE as reference if possible, strip the GRUB root device prefix in (hd0,gpt1) format
|
|
|
|
local boot_img="$(cat /proc/cmdline | sed "s/^BOOT_IMAGE=\((\S*)\)\?\(\S*\) .*/\2/")"
|
|
|
|
if [ -n "$boot_img" ]; then
|
|
|
|
boot_imglist="$boot_img $boot_imglist"
|
|
|
|
fi
|
|
|
|
|
|
|
|
for dir in $boot_dirlist; do
|
|
|
|
for img in $boot_imglist; do
|
|
|
|
if [ -f "$dir/$img" ]; then
|
|
|
|
KDUMP_KERNEL=$(echo $dir/$img | tr -s '/')
|
|
|
|
break 2
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
done
|
|
|
|
|
|
|
|
if ! [ -e "$KDUMP_KERNEL" ]; then
|
2020-10-27 09:04:22 +00:00
|
|
|
derror "Failed to detect kdump kernel location"
|
2020-07-27 18:40:20 +00:00
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Set KDUMP_BOOTDIR to where kernel image is stored
|
|
|
|
KDUMP_BOOTDIR=$(dirname $KDUMP_KERNEL)
|
|
|
|
|
|
|
|
# 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
|
2021-04-16 22:31:13 +00:00
|
|
|
defaut_initrd_base="$initrd"
|
|
|
|
DEFAULT_INITRD="$KDUMP_BOOTDIR/$defaut_initrd_base"
|
2020-07-27 18:40:20 +00:00
|
|
|
break
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
2021-04-16 22:31:13 +00:00
|
|
|
# Create kdump initrd basename from default initrd basename
|
2020-07-27 18:40:20 +00:00
|
|
|
# initramfs-5.7.9-200.fc32.x86_64.img => initramfs-5.7.9-200.fc32.x86_64kdump.img
|
|
|
|
# initrd => initrdkdump
|
2021-04-16 22:31:13 +00:00
|
|
|
if [[ -z "$defaut_initrd_base" ]]; then
|
|
|
|
kdump_initrd_base=initramfs-${KDUMP_KERNELVER}kdump.img
|
|
|
|
elif [[ $defaut_initrd_base == *.* ]]; then
|
|
|
|
kdump_initrd_base=${defaut_initrd_base%.*}kdump.${DEFAULT_INITRD##*.}
|
2018-05-22 10:15:07 +00:00
|
|
|
else
|
2021-04-16 22:31:13 +00:00
|
|
|
kdump_initrd_base=${defaut_initrd_base}kdump
|
|
|
|
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"
|
2018-05-22 10:15:07 +00:00
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2020-11-19 09:06:58 +00:00
|
|
|
get_watchdog_drvs()
|
|
|
|
{
|
|
|
|
local _wdtdrvs _drv _dir
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
echo $_wdtdrvs
|
|
|
|
}
|
|
|
|
|
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()
|
|
|
|
{
|
|
|
|
local cmdline id
|
|
|
|
|
|
|
|
if [ -z "$1" ]; then
|
|
|
|
cmdline=$(cat /proc/cmdline)
|
|
|
|
else
|
|
|
|
cmdline="$1"
|
|
|
|
fi
|
|
|
|
|
|
|
|
# These params should always be removed
|
|
|
|
cmdline=$(remove_cmdline_param "$cmdline" crashkernel panic_on_warn)
|
|
|
|
# These params can be removed configurably
|
|
|
|
cmdline=$(remove_cmdline_param "$cmdline" "$2")
|
|
|
|
|
|
|
|
# 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.
|
|
|
|
cmdline=$(remove_cmdline_param "$cmdline" root)
|
|
|
|
|
|
|
|
# With the help of "--hostonly-cmdline", we can avoid some interitage.
|
|
|
|
cmdline=$(remove_cmdline_param "$cmdline" rd.lvm.lv rd.luks.uuid rd.dm.uuid rd.md.uuid fcoe)
|
|
|
|
|
|
|
|
# Remove netroot, rd.iscsi.initiator and iscsi_initiator since
|
|
|
|
# we get duplicate entries for the same in case iscsi code adds
|
|
|
|
# it as well.
|
|
|
|
cmdline=$(remove_cmdline_param "$cmdline" netroot rd.iscsi.initiator iscsi_initiator)
|
|
|
|
|
|
|
|
cmdline="${cmdline} $3"
|
|
|
|
|
|
|
|
id=$(get_bootcpu_apicid)
|
|
|
|
if [ ! -z ${id} ] ; then
|
|
|
|
cmdline=$(append_cmdline "${cmdline}" disable_cpu_apicid ${id})
|
|
|
|
fi
|
Set watchdog's pretimeout to zero in kdump kernel
Most watchdogs have a parameter pretimeout, if set to non-zero, it means
before the watchdog really reset the system, it will try to panic the
kernel first, so kdump could kick in, or, just print a panic stacktrace
and then kernel should reset it self.
If we are already in kdump kernel, this is not really helpful, only
increase kernel hanging chance. And it also make thing become complex
as some watchdog triggers the kernel panic in NMI context, which
could also hang the kernel in strange ways, and fail the watchdog it
self. So just disable this parameter.
Also for hpwdt, it have another parameter kdumptimeout, which is
just designed for first kernel. The default behaviour is the watchdog
will simply stop working if timeouted, trigger a panic, and leave the
kernel to kdump. Again, if we are already in kdump this is not helpful.
So also disable that.
Signed-off-by: Kairui Song <kasong@redhat.com>
Acked-by: Lianbo Jiang <lijiang@redhat.com>
2020-11-19 14:07:09 +00:00
|
|
|
|
|
|
|
# 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.
|
|
|
|
for i in $(get_watchdog_drvs); do
|
|
|
|
cmdline+=" $i.pretimeout=0"
|
|
|
|
|
|
|
|
if [[ $i == hpwdt ]]; then
|
|
|
|
# hpwdt have a special parameter kdumptimeout, is's only suppose
|
|
|
|
# to be set to non-zero in first kernel. In kdump, non-zero
|
|
|
|
# value could prevent the watchdog from resetting the system.
|
|
|
|
cmdline+=" $i.kdumptimeout=0"
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
2021-01-26 06:37:28 +00:00
|
|
|
# Remove trace_buf_size, trace_event
|
|
|
|
cmdline=$(remove_cmdline_param "$cmdline" trace_buf_size trace_event)
|
|
|
|
cmdline="${cmdline} trace_buf_size=1"
|
|
|
|
|
2018-05-22 10:15:07 +00:00
|
|
|
echo ${cmdline}
|
|
|
|
}
|
2021-02-04 01:45:36 +00:00
|
|
|
|
|
|
|
#get system memory size in the unit of GB
|
|
|
|
get_system_size()
|
|
|
|
{
|
|
|
|
result=$(cat /proc/iomem | grep "System RAM" | awk -F ":" '{ print $1 }' | tr [:lower:] [:upper:] | paste -sd+)
|
|
|
|
result="+$result"
|
|
|
|
# replace '-' with '+0x' and '+' with '-0x'
|
|
|
|
sum=$( echo $result | sed -e 's/-/K0x/g' | sed -e 's/+/-0x/g' | sed -e 's/K/+/g' )
|
|
|
|
size=$(printf "%d\n" $(($sum)))
|
|
|
|
let size=$size/1024/1024/1024
|
|
|
|
|
|
|
|
echo $size
|
|
|
|
}
|
|
|
|
|
|
|
|
get_recommend_size()
|
|
|
|
{
|
|
|
|
local mem_size=$1
|
|
|
|
local _ck_cmdline=$2
|
|
|
|
local OLDIFS="$IFS"
|
|
|
|
|
|
|
|
last_sz=""
|
|
|
|
last_unit=""
|
|
|
|
|
2021-05-25 01:26:09 +00:00
|
|
|
start=${_ck_cmdline: :1}
|
|
|
|
if [ $mem_size -lt $start ]; then
|
|
|
|
echo "0M"
|
|
|
|
return
|
|
|
|
fi
|
2021-02-04 01:45:36 +00:00
|
|
|
IFS=','
|
|
|
|
for i in $_ck_cmdline; do
|
|
|
|
end=$(echo $i | awk -F "-" '{ print $2 }' | awk -F ":" '{ print $1 }')
|
|
|
|
recommend=$(echo $i | awk -F "-" '{ print $2 }' | awk -F ":" '{ print $2 }')
|
|
|
|
size=${end: : -1}
|
|
|
|
unit=${end: -1}
|
|
|
|
if [ $unit == 'T' ]; then
|
|
|
|
let size=$size*1024
|
|
|
|
fi
|
|
|
|
if [ $mem_size -lt $size ]; then
|
|
|
|
echo $recommend
|
|
|
|
IFS="$OLDIFS"
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
IFS="$OLDIFS"
|
|
|
|
}
|
|
|
|
|
|
|
|
# return recommended size based on current system RAM size
|
2021-07-01 17:31:26 +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()
|
|
|
|
{
|
2021-07-01 17:31:26 +00:00
|
|
|
local kernel=$1 arch
|
|
|
|
|
|
|
|
if ! [ -r "/proc/iomem" ] ; then
|
2021-02-04 01:45:36 +00:00
|
|
|
echo "Error, can not access /proc/iomem."
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
|
2021-07-01 17:31:26 +00:00
|
|
|
[ -z "$kernel" ] && kernel=$(uname -r)
|
|
|
|
ck_cmdline=$(cat "/usr/lib/modules/$kernel/crashkernel.default" 2>/dev/null)
|
|
|
|
|
|
|
|
if [ -n "$ck_cmdline" ]; then
|
|
|
|
ck_cmdline=${ck_cmdline#crashkernel=}
|
|
|
|
else
|
|
|
|
arch=$(lscpu | grep Architecture | awk -F ":" '{ print $2 }' | tr '[:lower:]' '[:upper:]')
|
|
|
|
if [ "$arch" = "X86_64" ] || [ "$arch" = "S390X" ]; then
|
|
|
|
ck_cmdline="1G-4G:160M,4G-64G:192M,64G-1T:256M,1T-:512M"
|
|
|
|
elif [ "$arch" = "AARCH64" ]; then
|
|
|
|
ck_cmdline="2G-:448M"
|
|
|
|
elif [ "$arch" = "PPC64LE" ]; then
|
|
|
|
if is_fadump_capable; 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
|
2021-02-04 01:45:36 +00:00
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
ck_cmdline=$(echo $ck_cmdline | sed -e 's/-:/-102400T:/g')
|
|
|
|
sys_mem=$(get_system_size)
|
2021-07-01 17:31:26 +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()
|
|
|
|
{
|
|
|
|
[[ -b /dev/block/$1 ]] || return 1
|
|
|
|
|
|
|
|
local _type=$(eval "$(blkid -u filesystem,crypto -o export -- /dev/block/$1); echo \$TYPE")
|
|
|
|
[[ $_type == "crypto_LUKS" ]] && echo $1
|
|
|
|
|
|
|
|
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-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
|
|
|
|
kdump_get_maj_min() {
|
|
|
|
local _majmin
|
|
|
|
_majmin="$(stat -L -c '%t:%T' "$1" 2> /dev/null)"
|
|
|
|
printf "%s" "$((0x${_majmin%:*})):$((0x${_majmin#*:}))"
|
|
|
|
}
|
|
|
|
|
|
|
|
get_all_kdump_crypt_dev()
|
|
|
|
{
|
|
|
|
local _dev _crypt
|
|
|
|
|
|
|
|
for _dev in $(get_block_dump_target); do
|
|
|
|
_crypt=$(get_luks_crypt_dev $(kdump_get_maj_min "$_dev"))
|
|
|
|
[[ -n "$_crypt" ]] && echo $_crypt
|
|
|
|
done
|
|
|
|
}
|
2021-04-21 19:27:10 +00:00
|
|
|
|
|
|
|
check_vmlinux()
|
|
|
|
{
|
|
|
|
# Use readelf to check if it's a valid ELF
|
|
|
|
readelf -h $1 &>/dev/null || return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
get_vmlinux_size()
|
|
|
|
{
|
|
|
|
local size=0
|
|
|
|
|
|
|
|
while read _type _offset _virtaddr _physaddr _fsize _msize _flg _aln; do
|
|
|
|
size=$(( $size + $_msize ))
|
|
|
|
done <<< $(readelf -l -W $1 | grep "^ LOAD" 2>/dev/stderr)
|
|
|
|
|
|
|
|
echo $size
|
|
|
|
}
|
|
|
|
|
|
|
|
try_decompress()
|
|
|
|
{
|
|
|
|
# The obscure use of the "tr" filter is to work around older versions of
|
|
|
|
# "grep" that report the byte offset of the line instead of the pattern.
|
|
|
|
|
|
|
|
# Try to find the header ($1) and decompress from here
|
|
|
|
for pos in `tr "$1\n$2" "\n$2=" < "$4" | grep -abo "^$2"`
|
|
|
|
do
|
|
|
|
if ! type -P $3 > /dev/null; then
|
|
|
|
ddebug "Signiature detected but '$3' is missing, skip this decompressor"
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
|
|
|
|
pos=${pos%%:*}
|
|
|
|
tail -c+$pos "$img" | $3 > $5 2> /dev/null
|
|
|
|
if check_vmlinux $5; then
|
|
|
|
ddebug "Kernel is extracted with '$3'"
|
|
|
|
return 0
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
# Borrowed from linux/scripts/extract-vmlinux
|
|
|
|
get_kernel_size()
|
|
|
|
{
|
|
|
|
# Prepare temp files:
|
|
|
|
local img=$1 tmp=$(mktemp /tmp/vmlinux-XXX)
|
|
|
|
trap "rm -f $tmp" 0
|
|
|
|
|
|
|
|
# Try to check if it's a vmlinux already
|
|
|
|
check_vmlinux $img && get_vmlinux_size $img && return 0
|
|
|
|
|
|
|
|
# That didn't work, so retry after decompression.
|
|
|
|
try_decompress '\037\213\010' xy gunzip $img $tmp || \
|
|
|
|
try_decompress '\3757zXZ\000' abcde unxz $img $tmp || \
|
|
|
|
try_decompress 'BZh' xy bunzip2 $img $tmp || \
|
|
|
|
try_decompress '\135\0\0\0' xxx unlzma $img $tmp || \
|
|
|
|
try_decompress '\211\114\132' xy 'lzop -d' $img $tmp || \
|
|
|
|
try_decompress '\002!L\030' xxx 'lz4 -d' $img $tmp || \
|
|
|
|
try_decompress '(\265/\375' xxx unzstd $img $tmp
|
|
|
|
|
|
|
|
# Finally check for uncompressed images or objects:
|
|
|
|
[[ $? -eq 0 ]] && get_vmlinux_size $tmp && return 0
|
|
|
|
|
|
|
|
# Fallback to use iomem
|
|
|
|
local _size=0
|
|
|
|
for _seg in $(cat /proc/iomem | grep -E "Kernel (code|rodata|data|bss)" | cut -d ":" -f 1); do
|
|
|
|
_size=$(( $_size + 0x${_seg#*-} - 0x${_seg%-*} ))
|
|
|
|
done
|
|
|
|
echo $_size
|
|
|
|
}
|