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.
When doing nfs mount via "dracut_args", because nfs needn't to be mounted beforehand, some nfs-related ko modules must be explicitly specified as needed together in the "dracut_args"(or via directive "extra_modules" in /etc/kdump.conf). As an nfs example: dracut_args --mount "192.168.1.1:/test /test nfs defaults" --add-driver "nfs nfsv4"
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 in an absolute path. -There must be double quotation marks behind "--mount", i.e. --mount "<mount info>". -Users should do a test first and ensure it works because kdump does not prepare the mount and check all the validity.
Suggested-by: Dave Young dyoung@redhat.com Signed-off-by: Xunlei Pang xlpang@redhat.com --- dracut-kdump.sh | 6 +++++- dracut-module-setup.sh | 5 +++++ kdump-lib.sh | 41 ++++++++++++++++++++++++++++++++++++++++- kdumpctl | 13 ++++++++++++- mkdumprd | 3 +++ 5 files changed, 65 insertions(+), 3 deletions(-)
diff --git a/dracut-kdump.sh b/dracut-kdump.sh index 4aab205..8747dba 100755 --- a/dracut-kdump.sh +++ b/dracut-kdump.sh @@ -117,7 +117,7 @@ save_vmcore_dmesg_ssh() { get_host_ip() { local _host - if is_nfs_dump_target || is_ssh_dump_target + if is_nfs_dump_target || is_ssh_dump_target || does_dracut_args_contain_nfsmount then kdumpnic=$(getarg kdumpnic=) [ -z "$kdumpnic" ] && echo "kdump: failed to get kdumpnic!" && return 1 @@ -146,6 +146,10 @@ read_kdump_conf() # remove inline comments after the end of a directive. config_val=$(strip_comments $config_val) case "$config_opt" in + dracut_args) + config_val=$(get_dracut_args_target "$config_val") + [[ -n "$config_val" ]] && add_dump_code "dump_fs $config_val" + ;; ext[234]|xfs|btrfs|minix|nfs) add_dump_code "dump_fs $config_val" ;; diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 4cd7107..5f03558 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -433,6 +433,11 @@ kdump_install_conf() { ssh|nfs) kdump_install_net "$config_val" ;; + dracut_args) + if is_nfs_in_dracut_args "$config_val"; then + kdump_install_net "$(get_dracut_args_target "$config_val")" + fi + ;; kdump_pre|kdump_post|extra_bins) dracut_install $config_val ;; diff --git a/kdump-lib.sh b/kdump-lib.sh index fc2c036..a486db6 100755 --- a/kdump-lib.sh +++ b/kdump-lib.sh @@ -45,7 +45,8 @@ is_fs_dump_target()
is_user_configured_dump_target() { - return $(is_ssh_dump_target || is_nfs_dump_target || is_raw_dump_target || is_fs_dump_target) + return $(does_dracut_args_contain_mount || is_ssh_dump_target || is_nfs_dump_target || \ + is_raw_dump_target || is_fs_dump_target) }
strip_comments() @@ -279,3 +280,41 @@ is_hostname() fi echo $1 | grep -q "[a-zA-Z]" } + +# If "dracut_args" contains "--mount" information, use it +# directly without any check(users are expected to ensure +# its correctness). +does_dracut_args_contain_mount() +{ + return $(grep ^dracut_args /etc/kdump.conf | grep -q "--mount") +} + +does_dracut_args_contain_nfsmount() +{ + local fstype + + fstype=$(grep "^dracut_args .*--mount" /etc/kdump.conf | sed "s/.*--mount "(.*)/\1/" | cut -d' ' -f3) + [[ $fstype = nfs* ]] && return 0 + + return 1 +} + +# $1: configuration value of "dracut_args". +is_nfs_in_dracut_args() +{ + [[ $(get_dracut_args_fstype "$1") = nfs* ]] && return 0 + + return 1 +} + +# $1: configuration value of "dracut_args". +get_dracut_args_fstype() +{ + echo $1 | grep "--mount" | sed "s/.*--mount "(.*)/\1/" | cut -d' ' -f3 +} + +# $1: configuration value of "dracut_args". +get_dracut_args_target() +{ + echo $1 | grep "--mount" | sed "s/.*--mount "(.*)/\1/" | cut -d' ' -f1 +} diff --git a/kdumpctl b/kdumpctl index fcc9ad0..fbed66d 100755 --- a/kdumpctl +++ b/kdumpctl @@ -236,12 +236,18 @@ check_config() { local nr
- nr=$(awk 'BEGIN{cnt=0} /^raw|^ssh[[:blank:]]|^nfs|^ext[234]|^xfs|^btrfs|^minix/{cnt++} END{print cnt}' $KDUMP_CONFIG_FILE) + nr=$(awk 'BEGIN{cnt=0} /^raw|^ssh[[:blank:]]|^nfs|^ext[234]|^xfs|^btrfs|^minix|^dracut_args .*--mount/{cnt++} END{print cnt}' $KDUMP_CONFIG_FILE) [ $nr -gt 1 ] && { echo "More than one dump targets specified." return 1 }
+ nr=$(grep "^dracut_args .*--mount" $KDUMP_CONFIG_FILE | grep -o "--mount" | wc -l) + [ $nr -gt 1 ] && { + echo "More than one mount targets specified in "dracut_args"." + return 1 + } + while read config_opt config_val; do # remove inline comments after the end of a directive. config_val=$(strip_comments $config_val) @@ -365,6 +371,11 @@ check_dump_fs_modified() local _new_dev _new_mntpoint _new_fstype local _target _path _dracut_args
+ # No need to check in case of mount target specified via "dracut_args". + if does_dracut_args_contain_mount; then + return 0 + fi + # No need to check in case of raw target. # Currently we do not check also if ssh/nfs target is specified if is_ssh_dump_target || is_nfs_dump_target || is_raw_dump_target; then diff --git a/mkdumprd b/mkdumprd index 78afb1a..7a0e733 100644 --- a/mkdumprd +++ b/mkdumprd @@ -544,6 +544,9 @@ do verify_core_collector "$config_val" ;; dracut_args) + if is_nfs_in_dracut_args "$config_val"; then + add_dracut_module "nfs" + fi add_dracut_arg $config_val ;; *)