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(a)redhat.com>
---
kdump-lib.sh | 33 ++++++------------
mkdumprd | 94 +++++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 92 insertions(+), 35 deletions(-)
diff --git a/kdump-lib.sh b/kdump-lib.sh
index 691a14d..74dac4c 100755
--- a/kdump-lib.sh
+++ b/kdump-lib.sh
@@ -284,12 +284,17 @@ get_kdump_mntpoint_from_target()
local _mntpoint=$(get_mntpoint_from_target $1)
# mount under /sysroot if dump to root disk or mount under
- # /kdumproot/$_mntpoint in other cases in 2nd kernel. systemd
- # will be in charge to umount it.
- if [ "$_mntpoint" = "/" ];then
- _mntpoint="/sysroot"
+ # 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
- _mntpoint="/kdumproot/$_mntpoint"
+ if [ "$_mntpoint" = "/" ];then
+ _mntpoint="/sysroot"
+ else
+ _mntpoint="/kdumproot/$_mntpoint"
+ fi
fi
# strip duplicated "/"
@@ -302,24 +307,6 @@ get_option_value() {
strip_comments `grep "^$1[[:space:]]\+" /etc/kdump.conf | tail -1 | cut -d\
-f2-`
}
-check_save_path_fs()
-{
- local _path=$1
-
- if [ ! -d $_path ]; then
- perror_exit "Dump path $_path does not exist."
- fi
-}
-
-# Check if path exists within dump target
-check_save_path_user_configured()
-{
- local _target=$1 _path=$2
- local _mnt=$(get_mntpoint_from_target $_target)
-
- check_save_path_fs "$_mnt/$_path"
-}
-
is_atomic()
{
grep -q "ostree" /proc/cmdline
diff --git a/mkdumprd b/mkdumprd
index d08a34d..dc4e0a5 100644
--- a/mkdumprd
+++ b/mkdumprd
@@ -19,6 +19,20 @@ OVERRIDE_RESETTABLE=0
extra_modules=""
dracut_args="--quiet --hostonly --hostonly-cmdline --hostonly-i18n --hostonly-mode
strict -o \"plymouth dash resume ifcfg earlykdump\""
+readonly MKDUMPRD_TMPDIR="$(mktemp -d -t mkdumprd.XXXXXX)"
+[ -d "$MKDUMPRD_TMPDIR" ] || perror_exit "dracut: mktemp -p -d -t
dracut.XXXXXX failed."
+readonly MKDUMPRD_TMPMNT="$MKDUMPRD_TMPDIR/target"
+
+trap '
+ ret=$?;
+ is_mounted $MKDUMPRD_TMPMNT && umount -f $MKDUMPRD_TMPMNT;
+ [[ -d $MKDUMPRD_TMPDIR ]] && rm --one-file-system -rf --
"$MKDUMPRD_TMPDIR";
+ exit $ret;
+ ' EXIT
+
+# clean up after ourselves no matter how we die.
+trap 'exit 1;' SIGINT
+
is_wdt_addition_needed() {
local active
@@ -51,11 +65,12 @@ add_dracut_sshkey() {
# caller should ensure $1 is valid and mounted in 1st kernel
to_mount() {
- local _target=$1 _new_mntpoint _fstype _options _mntopts _pdev
+ local _target=$1 _fstype=$2 _options=$3 _new_mntpoint _mntopts _pdev
- _fstype=$(get_fs_type_from_target $_target)
- _options=$(get_mntopt_from_target $_target)
_new_mntpoint=$(get_kdump_mntpoint_from_target $_target)
+ _fstype="${_fstype:-$(get_fs_type_from_target $_target)}"
+ _options="${_options:-$(get_mntopt_from_target $_options)}"
+ _options="${_options:-defaults}"
if [[ "$_fstype" == "nfs"* ]]; then
_options=$(echo $_options | sed 's/,addr=[^,]*//')
@@ -174,6 +189,67 @@ check_size() {
fi
}
+check_save_path_fs()
+{
+ local _path=$1
+
+ if [ ! -d $_path ]; then
+ perror_exit "Dump path $_path does not exist."
+ fi
+}
+
+check_user_configured_target()
+{
+ local _target=$1 _cfg_fs_type=$2 _mounted
+ local _mnt=$(get_mntpoint_from_target $_target)
+ local _opt=$(get_mntopt_from_target $_target)
+ local _fstype=$(get_fs_type_from_target $_target)
+
+ if [ -n "$_fstype" ]; then
+ # In case of nfs4, nfs should be used instead, nfs* options is deprecated in
kdump.conf
+ [[ $_fstype = "nfs"* ]] && _fstype=nfs
+
+ if [ -n "$_cfg_fs_type" ] && [ "$_fstype" !=
"$_cfg_fs_type" ]; then
+ perror_exit "\"$_target\" have a wrong type config
\"$_cfg_fs_type\", expected \"$_fstype\""
+ fi
+ else
+ _fstype="$_cfg_fs_type"
+ _fstype="$_cfg_fs_type"
+ fi
+
+ # For noauto mount, mount it inplace with default value.
+ # Else use the temporary target directory
+ if [ -n "$_mnt" ]; then
+ if ! is_mounted "$_mnt"; then
+ if [[ $_opt = *",noauto"* ]]; then
+ mount $_mnt
+ [ $? -ne 0 ] && perror_exit "Failed to mount $_target on
$_mnt for kdump preflight check."
+ _mounted=$_mnt
+ else
+ perror_exit "$_target is configured in fstab but not mounted, please
check its usability."
+ fi
+ fi
+ else
+ _mnt=$MKDUMPRD_TMPMNT
+ mkdir -p $_mnt
+ mount $_target $_mnt -t $_fstype -o defaults
+ [ $? -ne 0 ] && perror_exit "Failed to mount $_target for kdump
preflight check."
+ _mounted=$_mnt
+ fi
+
+ # For user configured target, use $SAVE_PATH as the dump path within the target
+ if [ ! -d "$_mnt/$SAVE_PATH" ]; then
+ perror_exit "Dump path \"$SAVE_PATH\" does not exist in dump
target \"$_target\""
+ fi
+
+ check_size fs "$_target"
+
+ # Unmount it early, if function is interrupted and didn't reach here, the shell
trap will clear it up anyway
+ if [ -n "$_mounted" ]; then
+ umount -f -- $_mounted
+ fi
+}
+
# $1: core_collector config value
verify_core_collector() {
local _cmd="${1%% *}"
@@ -201,7 +277,7 @@ verify_core_collector() {
}
add_mount() {
- local _mnt=$(to_mount "$1")
+ local _mnt=$(to_mount $@)
if [ $? -ne 0 ]; then
exit 1
@@ -354,14 +430,8 @@ do
extra_modules="$extra_modules $config_val"
;;
ext[234]|xfs|btrfs|minix|nfs)
- if ! is_mounted $config_val; then
- perror_exit "Dump target $config_val is probably not mounted."
- fi
-
- # User configured target, use $SAVE_PATH as the dump path within the target
- check_save_path_user_configured "$config_val" "$SAVE_PATH"
- check_size fs "$config_val"
- add_mount "$config_val"
+ check_user_configured_target "$config_val" "$config_opt"
+ add_mount "$config_val" "$config_opt"
;;
raw)
# checking raw disk writable
--
2.26.2