diff --git a/.gitignore b/.gitignore index abb4bc8..e7cea8f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ SOURCES/eppic_050615.tar.gz SOURCES/kexec-tools-2.0.20.tar.xz -SOURCES/makedumpfile-1.6.6.tar.gz +SOURCES/makedumpfile-1.6.7.tar.gz diff --git a/.kexec-tools.metadata b/.kexec-tools.metadata index 11cef96..431b034 100644 --- a/.kexec-tools.metadata +++ b/.kexec-tools.metadata @@ -1,3 +1,3 @@ a096c8e0892b559f40b01916aae240652f75b68a SOURCES/eppic_050615.tar.gz 5d9acd2e741d356d4a48fe4f2d63f66ba431051d SOURCES/kexec-tools-2.0.20.tar.xz -68f5276d82091b54452f754aa41e2e8746f47814 SOURCES/makedumpfile-1.6.6.tar.gz +42941a0219d57d99909616778835e5d9ba890711 SOURCES/makedumpfile-1.6.7.tar.gz diff --git a/SOURCES/dracut-early-kdump.sh b/SOURCES/dracut-early-kdump.sh index 69a34eb..6788a6b 100755 --- a/SOURCES/dracut-early-kdump.sh +++ b/SOURCES/dracut-early-kdump.sh @@ -2,6 +2,7 @@ KEXEC=/sbin/kexec standard_kexec_args="-p" +KDUMP_FILE_LOAD="" EARLY_KDUMP_INITRD="" EARLY_KDUMP_KERNEL="" @@ -43,8 +44,8 @@ early_kdump_load() EARLY_KEXEC_ARGS=$(prepare_kexec_args "${KEXEC_ARGS}") - if is_secure_boot_enforced; then - echo "Secure Boot is enabled. Using kexec file based syscall." + if [ "$KDUMP_FILE_LOAD" == "on" ]; then + echo "Using kexec file based syscall." EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS -s" fi diff --git a/SOURCES/dracut-kdump-error-handler.service b/SOURCES/dracut-kdump-error-handler.service index 32b74ab..a23b75e 100644 --- a/SOURCES/dracut-kdump-error-handler.service +++ b/SOURCES/dracut-kdump-error-handler.service @@ -21,7 +21,6 @@ Environment=DRACUT_SYSTEMD=1 Environment=NEWROOT=/sysroot WorkingDirectory=/ ExecStart=/bin/kdump-error-handler.sh -ExecStopPost=-/usr/bin/systemctl --fail --no-block default Type=oneshot StandardInput=tty-force StandardOutput=inherit diff --git a/SOURCES/dracut-kdump.sh b/SOURCES/dracut-kdump.sh index 2ae1c7c..b71278d 100755 --- a/SOURCES/dracut-kdump.sh +++ b/SOURCES/dracut-kdump.sh @@ -1,8 +1,8 @@ #!/bin/sh # continue here only if we have to save dump. -if [ -f /etc/fadump.initramfs ] && [ ! -f /proc/device-tree/rtas/ibm,kernel-dump ]; then - exit 0 +if [ -f /etc/fadump.initramfs ] && [ ! -f /proc/device-tree/rtas/ibm,kernel-dump ] && [ ! -f /proc/device-tree/ibm,opal/dump/mpipl-boot ]; then + exit 0 fi exec &> /dev/console @@ -30,15 +30,49 @@ do_dump() do_kdump_pre() { + local _ret + if [ -n "$KDUMP_PRE" ]; then "$KDUMP_PRE" + _ret=$? + if [ $_ret -ne 0 ]; then + echo "kdump: $KDUMP_PRE exited with $_ret status" + return $_ret + fi + fi + + if [ -d /etc/kdump/pre.d ]; then + for file in /etc/kdump/pre.d/*; do + "$file" + _ret=$? + if [ $_ret -ne 0 ]; then + echo "kdump: $file exited with $_ret status" + fi + done fi + return 0 } do_kdump_post() { + local _ret + + if [ -d /etc/kdump/post.d ]; then + for file in /etc/kdump/post.d/*; do + "$file" "$1" + _ret=$? + if [ $_ret -ne 0 ]; then + echo "kdump: $file exited with $_ret status" + fi + done + fi + if [ -n "$KDUMP_POST" ]; then "$KDUMP_POST" "$1" + _ret=$? + if [ $_ret -ne 0 ]; then + echo "kdump: $KDUMP_POST exited with $_ret status" + fi fi } @@ -81,6 +115,7 @@ dump_ssh() ssh -q $_opt $_host mkdir -p $_dir || return 1 save_vmcore_dmesg_ssh ${DMESG_COLLECTOR} ${_dir} "${_opt}" $_host + save_opalcore_ssh ${_dir} "${_opt}" $_host echo "kdump: saving vmcore" @@ -96,6 +131,32 @@ dump_ssh() return 0 } +save_opalcore_ssh() { + local _path=$1 + local _opts="$2" + local _location=$3 + + if [ ! -f $OPALCORE ]; then + # Check if we are on an old kernel that uses a different path + if [ -f /sys/firmware/opal/core ]; then + OPALCORE="/sys/firmware/opal/core" + else + return 0 + fi + fi + + echo "kdump: saving opalcore" + scp $_opts $OPALCORE $_location:$_path/opalcore-incomplete + if [ $? -ne 0 ]; then + echo "kdump: saving opalcore failed" + return 1 + fi + + ssh $_opts $_location mv $_path/opalcore-incomplete $_path/opalcore + echo "kdump: saving opalcore complete" + return 0 +} + save_vmcore_dmesg_ssh() { local _dmesg_collector=$1 local _path=$2 @@ -147,9 +208,13 @@ read_kdump_conf() case "$config_opt" in dracut_args) config_val=$(get_dracut_args_target "$config_val") - [ -n "$config_val" ] && add_dump_code "dump_fs $config_val" + if [ -n "$config_val" ]; then + config_val=$(get_mntpoint_from_target "$config_val") + add_dump_code "dump_fs $config_val" + fi ;; ext[234]|xfs|btrfs|minix|nfs) + config_val=$(get_mntpoint_from_target "$config_val") add_dump_code "dump_fs $config_val" ;; raw) diff --git a/SOURCES/dracut-module-setup.sh b/SOURCES/dracut-module-setup.sh index c6d2d8c..596ee57 100755 --- a/SOURCES/dracut-module-setup.sh +++ b/SOURCES/dracut-module-setup.sh @@ -48,20 +48,6 @@ depends() { return 0 } -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") -} - kdump_is_bridge() { [ -d /sys/class/net/"$1"/bridge ] } @@ -268,10 +254,10 @@ kdump_setup_vlan() { exit 1 elif kdump_is_bond "$_phydev"; then kdump_setup_bond "$_phydev" - echo " vlan=$_netdev:$_phydev" > ${initdir}/etc/cmdline.d/43vlan.conf + echo " vlan=$(kdump_setup_ifname $_netdev):$_phydev" > ${initdir}/etc/cmdline.d/43vlan.conf else _kdumpdev="$(kdump_setup_ifname $_phydev)" - echo " vlan=$_netdev:$_kdumpdev ifname=$_kdumpdev:$_netmac" > ${initdir}/etc/cmdline.d/43vlan.conf + echo " vlan=$(kdump_setup_ifname $_netdev):$_kdumpdev ifname=$_kdumpdev:$_netmac" > ${initdir}/etc/cmdline.d/43vlan.conf fi } @@ -279,13 +265,14 @@ kdump_setup_vlan() { # $1: netdev name kdump_setup_znet() { local _options="" + local _netdev=$1 - source_ifcfg_file $1 + source_ifcfg_file $_netdev for i in $OPTIONS; do _options=${_options},$i done - echo rd.znet=${NETTYPE},${SUBCHANNELS}${_options} > ${initdir}/etc/cmdline.d/30znet.conf + echo rd.znet=${NETTYPE},${SUBCHANNELS}${_options} rd.znet_ifname=$_netdev:${SUBCHANNELS} > ${initdir}/etc/cmdline.d/30znet.conf } # Setup dracut to bringup a given network interface @@ -333,6 +320,11 @@ kdump_setup_netdev() { fi kdump_setup_dns "$_netdev" + + if [ ! -f ${initdir}/etc/cmdline.d/50neednet.conf ]; then + # network-manager module needs this parameter + echo "rd.neednet" >> ${initdir}/etc/cmdline.d/50neednet.conf + fi } get_ip_route_field() @@ -382,6 +374,29 @@ kdump_install_net() { fi } +# install etc/kdump/pre.d and /etc/kdump/post.d +kdump_install_pre_post_conf() { + if [ -d /etc/kdump/pre.d ]; then + for file in /etc/kdump/pre.d/*; do + if [ -x "$file" ]; then + dracut_install $file + else + echo "$file is not executable" + fi + done + fi + + if [ -d /etc/kdump/post.d ]; then + for file in /etc/kdump/post.d/*; do + if [ -x "$file" ]; then + dracut_install $file + else + echo "$file is not executable" + fi + done + fi +} + default_dump_target_install_conf() { local _target _fstype @@ -389,24 +404,9 @@ default_dump_target_install_conf() is_user_configured_dump_target && return - _save_path=$(get_option_value "path") - [ -z "$_save_path" ] && _save_path=$DEFAULT_PATH - - # strip the duplicated "/" - _save_path=$(echo $_save_path | tr -s /) - - _mntpoint=$(get_mntpoint_from_path $_save_path) + _save_path=$(get_bind_mount_source $(get_save_path)) _target=$(get_target_from_path $_save_path) - - if is_atomic && is_bind_mount $_mntpoint; then - _save_path=${_save_path##"$_mntpoint"} - # the real dump path in the 2nd kernel, if the mount point is bind mounted. - _save_path=$(get_bind_mount_directory $_mntpoint)/$_save_path - _mntpoint=$(get_mntpoint_from_target $_target) - - # the absolute path in the 1st kernel - _save_path=$_mntpoint/$_save_path - fi + _mntpoint=$(get_mntpoint_from_target $_target) _fstype=$(get_fs_type_from_target $_target) if is_fs_type_nfs $_fstype; then @@ -418,8 +418,6 @@ default_dump_target_install_conf() echo "$_fstype $_target" >> ${initdir}/tmp/$$-kdump.conf - # strip the duplicated "/" - _save_path=$(echo $_save_path | tr -s /) # don't touch the path under root mount if [ "$_mntpoint" != "/" ]; then _save_path=${_save_path##"$_mntpoint"} @@ -430,30 +428,6 @@ default_dump_target_install_conf() echo "path $_save_path" >> ${initdir}/tmp/$$-kdump.conf } -adjust_bind_mount_path() -{ - local _target=$1 - local _save_path=$(get_option_value "path") - [ -z "$_save_path" ] && _save_path=$DEFAULT_PATH - - # strip the duplicated "/" - _save_path=$(echo $_save_path | tr -s /) - - local _absolute_save_path=$(get_mntpoint_from_target $_target)/$_save_path - _absolute_save_path=$(echo "$_absolute_save_path" | tr -s /) - local _mntpoint=$(get_mntpoint_from_path $_absolute_save_path) - - if is_bind_mount $_mntpoint; then - _save_path=${_absolute_save_path##"$_mntpoint"} - # the real dump path in the 2nd kernel, if the mount point is bind mounted. - _save_path=$(get_bind_mount_directory $_mntpoint)/$_save_path - - #erase the old path line, then insert the parsed path - sed -i "/^path/d" ${initdir}/tmp/$$-kdump.conf - echo "path $_save_path" >> ${initdir}/tmp/$$-kdump.conf - fi -} - #install kdump.conf and what user specifies in kdump.conf kdump_install_conf() { local _opt _val _pdev @@ -470,9 +444,6 @@ kdump_install_conf() { ext[234]|xfs|btrfs|minix) _pdev=$(kdump_get_persistent_dev $_val) sed -i -e "s#^$_opt[[:space:]]\+$_val#$_opt $_pdev#" ${initdir}/tmp/$$-kdump.conf - if is_atomic; then - adjust_bind_mount_path "$_val" - fi ;; ssh|nfs) kdump_install_net "$_val" @@ -491,6 +462,8 @@ kdump_install_conf() { esac done <<< "$(read_strip_comments /etc/kdump.conf)" + kdump_install_pre_post_conf + default_dump_target_install_conf kdump_configure_fence_kdump "${initdir}/tmp/$$-kdump.conf" @@ -659,7 +632,8 @@ get_alias() { ips=$(hostname -I) for ip in $ips do - entries=$(grep $ip /etc/hosts | awk '{ $1=$2=""; print $0 }') + # in /etc/hosts, alias can come at the 2nd column + entries=$(grep $ip /etc/hosts | awk '{ $1=""; print $0 }') if [ $? -eq 0 ]; then alias_set="$alias_set $entries" fi diff --git a/SOURCES/early-kdump-howto.txt b/SOURCES/early-kdump-howto.txt index b8cab6a..68b23c7 100644 --- a/SOURCES/early-kdump-howto.txt +++ b/SOURCES/early-kdump-howto.txt @@ -3,12 +3,17 @@ Early Kdump HOWTO Introduction ------------ -Kdump service starts too late, so early crashes will have no chance to get -kdump kernel booting, this will cause crash information to be lost. It is -necessary to add a dracut module in order to load crash kernel and initramfs -as early as possible. You can provide "rd.earlykdump" in grub commandline -to enable, then the early kdump will load those files like the normal kdump, -which is disabled by default. +Early kdump is a mechanism to make kdump operational earlier than normal kdump +service. The kdump service starts early enough for general crash cases, but +there are some cases where it has no chance to make kdump operational in boot +sequence, such as detecting devices and starting early services. If you hit +such a case, early kdump may allow you to get more information of it. + +Early kdump is implemented as a dracut module. It adds a kernel (vmlinuz) and +initramfs for kdump to your system's initramfs in order to load them as early +as possible. After that, if you provide "rd.earlykdump" in kernel command line, +then in the initramfs, early kdump will load those files like the normal kdump +service. This is disabled by default. For the normal kdump service, it can check whether the early kdump has loaded the crash kernel and initramfs. It has no conflict with the early kdump. @@ -20,7 +25,9 @@ We assume if you're reading this document, you should already have kexec-tools installed. You can rebuild the initramfs with earlykdump support with below steps: + 1. start kdump service to make sure kdump initramfs is created. + # systemctl start kdump NOTE: If a crash occurs during boot process, early kdump captures a vmcore @@ -34,20 +41,13 @@ You can rebuild the initramfs with earlykdump support with below steps: For the failure_action, you can choose anything other than "reboot". 2. rebuild system initramfs with earlykdump support. - # dracut --add earlykdump -3. add rd.earlykdump in grub kernel command line. + # dracut --force --add earlykdump -Note: -[1]. Early kdump initramfs size will be large because it includes vmlinuz and -kdump initramfs. And for step 2 if you are sure to overwrite system initramfs -you can backup the original initramfs and use "--force" option. + NOTE: Recommend to backup the original system initramfs before performing + this step to put it back if something happens during boot-up. -[2]. Early kdump inherits the settings of normal kdump, so any changes that -caused normal kdump rebuilding also require rebuilding the system initramfs -to make sure that the changes take effect for early kdump. Therefore, after -the rebuilding of kdump initramfs is completed, provide a prompt message to -tell the fact. +3. add rd.earlykdump in grub kernel command line. After making said changes, reboot your system to take effect. Of course, if you want to disable early kdump, you can simply remove "rd.earlykdump" from kernel @@ -56,19 +56,40 @@ boot parameters in grub, and reboot system like above. Once the boot is completed, you can check the status of the early kdump support on the command prompt: - # journalctl -x|grep early-kdump + # journalctl -b | grep early-kdump + +Then, you will see some useful logs, for example: + +- if early kdump is successful. -Then, you will see some useful logs, for exapmle: +Mar 09 09:57:56 localhost dracut-cmdline[190]: early-kdump is enabled. +Mar 09 09:57:56 localhost dracut-cmdline[190]: kexec: loaded early-kdump kernel -1. if early kdump is successful. -Mar 09 09:57:56 localhost.localdomain dracut-cmdline[190]: early-kdump is enabled. -Mar 09 09:57:56 localhost.localdomain dracut-cmdline[190]: kexec: loaded early- -kdump kernel +- if early kdump is disabled. -2. if early kdump is disabled. -Mar 09 10:02:47 localhost.localdomain dracut-cmdline[189]: early-kdump is disabled. +Mar 09 10:02:47 localhost dracut-cmdline[189]: early-kdump is disabled. + +Notes +----- + +- The size of early kdump initramfs will be large because it includes vmlinuz + and kdump initramfs. + +- Early kdump inherits the settings of normal kdump, so any changes that + caused normal kdump rebuilding also require rebuilding the system initramfs + to make sure that the changes take effect for early kdump. Therefore, after + the rebuilding of kdump initramfs is completed, provide a prompt message to + tell the fact. + +- If you install an updated kernel and reboot the system with it, the early + kdump will be disabled by default. To enable it with the new kernel, you + need to take the above steps again. Limitation ---------- -At present, early kdump doesn't support fadump. +- At present, early kdump doesn't support fadump. + +- Early kdump loads a crash kernel and initramfs at the beginning of the + process in system's initramfs, so a crash at earlier than that (e.g. in + kernel initialization) cannot be captured even with the early kdump. diff --git a/SOURCES/fadump-howto.txt b/SOURCES/fadump-howto.txt new file mode 100644 index 0000000..c891e37 --- /dev/null +++ b/SOURCES/fadump-howto.txt @@ -0,0 +1,338 @@ +Firmware assisted dump (fadump) HOWTO + +Introduction + +Firmware assisted dump is a new feature in the 3.4 mainline kernel supported +only on powerpc architecture. The goal of firmware-assisted dump is to enable +the dump of a crashed system, and to do so from a fully-reset system, and to +minimize the total elapsed time until the system is back in production use. A +complete documentation on implementation can be found at +Documentation/powerpc/firmware-assisted-dump.txt in upstream linux kernel tree +from 3.4 version and above. + +Please note that the firmware-assisted dump feature is only available on Power6 +and above systems with recent firmware versions. + +Overview + +Fadump + +Fadump is a robust kernel crash dumping mechanism to get reliable kernel crash +dump with assistance from firmware. This approach does not use kexec, instead +firmware assists in booting the kdump kernel while preserving memory contents. +Unlike kdump, the system is fully reset, and loaded with a fresh copy of the +kernel. In particular, PCI and I/O devices are reinitialized and are in a +clean, consistent state. This second kernel, often called a capture kernel, +boots with very little memory and captures the dump image. + +The first kernel registers the sections of memory with the Power firmware for +dump preservation during OS initialization. These registered sections of memory +are reserved by the first kernel during early boot. When a system crashes, the +Power firmware fully resets the system, preserves all the system memory +contents, save the low memory (boot memory of size larger of 5% of system +RAM or 256MB) of RAM to the previous registered region. It will also save +system registers, and hardware PTE's. + +Fadump is supported only on ppc64 platform. The standard kernel and capture +kernel are one and the same on ppc64. + +If you're reading this document, you should already have kexec-tools +installed. If not, you install it via the following command: + + # yum install kexec-tools + +Fadump Operational Flow: + +Like kdump, fadump also exports the ELF formatted kernel crash dump through +/proc/vmcore. Hence existing kdump infrastructure can be used to capture fadump +vmcore. The idea is to keep the functionality transparent to end user. From +user perspective there is no change in the way kdump init script works. + +However, unlike kdump, fadump does not pre-load kdump kernel and initrd into +reserved memory, instead it always uses default OS initrd during second boot +after crash. Hence, for fadump, we rebuild the new kdump initrd and replace it +with default initrd. Before replacing existing default initrd we take a backup +of original default initrd for user's reference. The dracut package has been +enhanced to rebuild the default initrd with vmcore capture steps. The initrd +image is rebuilt as per the configuration in /etc/kdump.conf file. + +The control flow of fadump works as follows: +01. System panics. +02. At the crash, kernel informs power firmware that kernel has crashed. +03. Firmware takes the control and reboots the entire system preserving + only the memory (resets all other devices). +04. The reboot follows the normal booting process (non-kexec). +05. The boot loader loads the default kernel and initrd from /boot +06. The default initrd loads and runs /init +07. dracut-kdump.sh script present in fadump aware default initrd checks if + '/proc/device-tree/rtas/ibm,kernel-dump' file exists before executing + steps to capture vmcore. + (This check will help to bypass the vmcore capture steps during normal boot + process.) +09. Captures dump according to /etc/kdump.conf +10. Is dump capture successful (yes goto 12, no goto 11) +11. Perform the failure action specified in /etc/kdump.conf + (The default failure action is reboot, if unspecified) +12. Perform the final action specified in /etc/kdump.conf + (The default final action is reboot, if unspecified) + + +How to configure fadump: + +Again, we assume if you're reading this document, you should already have +kexec-tools installed. If not, you install it via the following command: + + # yum install kexec-tools + +Make the kernel to be configured with FADump as the default boot entry, if +it isn't already: + + # grubby --set-default=/boot/vmlinuz- + +Boot into the kernel to be configured for FADump. To be able to do much of +anything interesting in the way of debug analysis, you'll also need to install +the kernel-debuginfo package, of the same arch as your running kernel, and the +crash utility: + + # yum --enablerepo=\*debuginfo install kernel-debuginfo.$(uname -m) crash + +Next up, we need to modify some boot parameters to enable firmware assisted +dump. With the help of grubby, it's very easy to append "fadump=on" to the end +of your kernel boot parameters. To reserve the appropriate amount of memory +for boot memory preservation, pass 'crashkernel=X' kernel cmdline parameter. +For the recommended value of X, see 'FADump Memory Requirements' section. + + # grubby --args="fadump=on crashkernel=6G" --update-kernel=/boot/vmlinuz-`uname -r` + +The term 'boot memory' means size of the low memory chunk that is required for +a kernel to boot successfully when booted with restricted memory. By default, +the boot memory size will be the larger of 5% of system RAM or 256MB. +Alternatively, user can also specify boot memory size through boot parameter +'fadump_reserve_mem=' which will override the default calculated size. Use this +option if default boot memory size is not sufficient for second kernel to boot +successfully. + +After making said changes, reboot your system, so that the specified memory is +reserved and left untouched by the normal system. Take note that the output of +'free -m' will show X MB less memory than without this parameter, which is +expected. If you see OOM (Out Of Memory) error messages while loading capture +kernel, then you should bump up the memory reservation size. + +Now that you've got that reserved memory region set up, you want to turn on +the kdump init script: + + # systemctl enable kdump.service + +Then, start up kdump as well: + + # systemctl start kdump.service + +This should turn on the firmware assisted functionality in kernel by +echo'ing 1 to /sys/kernel/fadump_registered, leaving the system ready +to capture a vmcore upon crashing. For journaling filesystems like XFS an +additional step is required to ensure bootloader does not pick the +older initrd (without vmcore capture scripts): + + * If /boot is a separate partition, run the below commands as the root user, + or as a user with CAP_SYS_ADMIN rights: + + # fsfreeze -f + # fsfreeze -u + + * If /boot is not a separate partition, reboot the system. + +After reboot check if the kdump service is up and running with: + + # systemctl status kdump.service + +To test out whether FADump is configured properly, you can force-crash your +system by echo'ing a 'c' into /proc/sysrq-trigger: + + # echo c > /proc/sysrq-trigger + +You should see some panic output, followed by the system reset and booting into +fresh copy of kernel. When default initrd loads and runs /init, vmcore should +be copied out to disk (by default, in /var/crash//vmcore), +then the system rebooted back into your normal kernel. + +Once back to your normal kernel, you can use the previously installed crash +kernel in conjunction with the previously installed kernel-debuginfo to +perform postmortem analysis: + + # crash /usr/lib/debug/lib/modules/2.6.17-1.2621.el5/vmlinux + /var/crash/2006-08-23-15:34/vmcore + + crash> bt + +and so on... + +Saving vmcore-dmesg.txt +----------------------- +Kernel log bufferes are one of the most important information available +in vmcore. Now before saving vmcore, kernel log bufferes are extracted +from /proc/vmcore and saved into a file vmcore-dmesg.txt. After +vmcore-dmesg.txt, vmcore is saved. Destination disk and directory for +vmcore-dmesg.txt is same as vmcore. Note that kernel log buffers will +not be available if dump target is raw device. + +FADump Memory Requirements: + + System Memory Recommended memory +--------------------- ---------------------- + 4 GB - 16 GB : 768 MB + 16 GB - 64 GB : 1024 MB + 64 GB - 128 GB : 2 GB + 128 GB - 1 TB : 4 GB + 1 TB - 2 TB : 6 GB + 2 TB - 4 TB : 12 GB + 4 TB - 8 TB : 20 GB + 8 TB - 16 TB : 36 GB + 16 TB - 32 TB : 64 GB + 32 TB - 64 TB : 128 GB + 64 TB & above : 180 GB + +Things to remember: + +1) The memory required to boot capture Kernel is a moving target that depends + on many factors like hardware attached to the system, kernel and modules in + use, packages installed and services enabled, there is no one-size-fits-all. + But the above recommendations are based on system memory. So, the above + recommendations for FADump come with a few assumptions, based on available + system memory, about the resources the system could have. So, please take + the recommendations with a pinch of salt and remember to try capturing dump + a few times to confirm that the system is configured successfully with dump + capturing support. + +2) Though the memory requirements for FADump seem high, this memory is not + completely set aside but made available for userspace applications to use, + through the CMA allocator. + +3) As the same initrd is used for booting production kernel as well as capture + kernel and with dump being captured in a restricted memory environment, few + optimizations (like not inclding network dracut module, disabling multipath + and such) are applied while building the initrd. In case, the production + environment needs these optimizations to be avoided, dracut_args option in + /etc/kdump.conf file could be leveraged. For example, if a user wishes for + network module to be included in the initrd, adding the below entry in + /etc/kdump.conf file and restarting kdump service would take care of it. + + dracut_args --add "network" + +4) If FADump is configured to capture vmcore to a remote dump target using SSH + or NFS protocol, the network interface is renamed to kdump- + if is generic, for example, *eth#, or net#. This problem + occurs because the vmcore capture scripts in the initial RAM disk (initrd) + add the kdump- prefix to the network interface name to secure persistent + naming. As the same initrd is used for production kernel boot, the interface + name is changed for the production kernel too. + +Dump Triggering methods: + +This section talks about the various ways, other than a Kernel Panic, in which +fadump can be triggered. The following methods assume that fadump is configured +on your system, with the scripts enabled as described in the section above. + +1) AltSysRq C + +FAdump can be triggered with the combination of the 'Alt','SysRq' and 'C' +keyboard keys. Please refer to the following link for more details: + +https://fedoraproject.org/wiki/QA/Sysrq + +In addition, on PowerPC boxes, fadump can also be triggered via Hardware +Management Console(HMC) using 'Ctrl', 'O' and 'C' keyboard keys. + +2) Kernel OOPs + +If we want to generate a dump everytime the Kernel OOPses, we can achieve this +by setting the 'Panic On OOPs' option as follows: + + # echo 1 > /proc/sys/kernel/panic_on_oops + +3) PowerPC specific methods: + +On IBM PowerPC machines, issuing a soft reset invokes the XMON debugger(if +XMON is configured). To configure XMON one needs to compile the kernel with +the CONFIG_XMON and CONFIG_XMON_DEFAULT options, or by compiling with +CONFIG_XMON and booting the kernel with xmon=on option. + +Following are the ways to remotely issue a soft reset on PowerPC boxes, which +would drop you to XMON. Pressing a 'X' (capital alphabet X) followed by an +'Enter' here will trigger the dump. + +3.1) HMC + +Hardware Management Console(HMC) available on Power4 and Power5 machines allow +partitions to be reset remotely. This is specially useful in hang situations +where the system is not accepting any keyboard inputs. + +Once you have HMC configured, the following steps will enable you to trigger +fadump via a soft reset: + +On Power4 + Using GUI + + * In the right pane, right click on the partition you wish to dump. + * Select "Operating System->Reset". + * Select "Soft Reset". + * Select "Yes". + + Using HMC Commandline + + # reset_partition -m -p -t soft + +On Power5 + Using GUI + + * In the right pane, right click on the partition you wish to dump. + * Select "Restart Partition". + * Select "Dump". + * Select "OK". + + Using HMC Commandline + + # chsysstate -m -n -o dumprestart -r lpar + +3.2) Blade Management Console for Blade Center + +To initiate a dump operation, go to Power/Restart option under "Blade Tasks" in +the Blade Management Console. Select the corresponding blade for which you want +to initate the dump and then click "Restart blade with NMI". This issues a +system reset and invokes xmon debugger. + + +Advanced Setups & Failure action: + +Kdump and fadump exhibit similar behavior in terms of setup & failure action. +For fadump advanced setup related information see section "Advanced Setups" in +"kexec-kdump-howto.txt" document. Refer to "Failure action" section in "kexec- +kdump-howto.txt" document for fadump failure action related information. + +Compression and filtering + +Refer "Compression and filtering" section in "kexec-kdump-howto.txt" document. +Compression and filtering are same for kdump & fadump. + + +Notes on rootfs mount: +Dracut is designed to mount rootfs by default. If rootfs mounting fails it +will refuse to go on. So fadump leaves rootfs mounting to dracut currently. +We make the assumtion that proper root= cmdline is being passed to dracut +initramfs for the time being. If you need modify "KDUMP_COMMANDLINE=" in +/etc/sysconfig/kdump, you will need to make sure that appropriate root= +options are copied from /proc/cmdline. In general it is best to append +command line options using "KDUMP_COMMANDLINE_APPEND=" instead of replacing +the original command line completely. + +How to disable FADump: + +Remove "fadump=on" from kernel cmdline parameters: + + # grubby --update-kernel=/boot/vmlinuz-`uname -r` --remove-args="fadump=on" + +If KDump is to be used as the dump capturing mechanism, update the crashkernel +parameter (Else, remove "crashkernel=" parameter too, using grubby): + + # grubby --update-kernel=/boot/vmlinuz-$kver --args="crashkernl=auto" + +Reboot the system for the settings to take effect. diff --git a/SOURCES/kdump-lib-initramfs.sh b/SOURCES/kdump-lib-initramfs.sh index c7f9522..2a7b613 100755 --- a/SOURCES/kdump-lib-initramfs.sh +++ b/SOURCES/kdump-lib-initramfs.sh @@ -18,6 +18,7 @@ KDUMP_CONF="/etc/kdump.conf" KDUMP_PRE="" KDUMP_POST="" NEWROOT="/sysroot" +OPALCORE="/sys/firmware/opal/mpipl/core" get_kdump_confs() { @@ -93,20 +94,16 @@ get_kdump_confs() fi } -# dump_fs +# dump_fs dump_fs() { - local _do_umount="" - local _dev=$(findmnt -k -f -n -r -o SOURCE $1) - local _mp=$(findmnt -k -f -n -r -o TARGET $1) - local _op=$(findmnt -k -f -n -r -o OPTIONS $1) + local _mp=$1 + local _dev=$(get_mount_info SOURCE target $_mp -f) + local _op=$(get_mount_info OPTIONS target $_mp -f) - if [ -z "$_mp" ]; then - _dev=$(findmnt -s -f -n -r -o SOURCE $1) - _mp=$(findmnt -s -f -n -r -o TARGET $1) - _op=$(findmnt -s -f -n -r -o OPTIONS $1) - - if [ -n "$_dev" ] && [ -n "$_mp" ]; then + # If dump path have a corresponding device entry but not mounted, mount it. + if [ -n "$_dev" ] || [ "$_dev" == "rootfs" ]; then + if ! is_mounted "$_mp"; then echo "kdump: dump target $_dev is not mounted, trying to mount..." mkdir -p $_mp mount -o $_op $_dev $_mp @@ -115,12 +112,10 @@ dump_fs() echo "kdump: mounting failed (mount point: $_mp, option: $_op)" return 1 fi - _do_umount=1 - else - echo "kdump: error: Dump target $_dev is not usable" fi else - echo "kdump: dump target is $_dev" + echo "kdump: failed to dump to \"$_mp\", it's not a mount point!" + return 1 fi # Remove -F in makedumpfile case. We don't want a flat format dump here. @@ -132,6 +127,7 @@ dump_fs() mkdir -p $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR || return 1 save_vmcore_dmesg_fs ${DMESG_COLLECTOR} "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/" + save_opalcore_fs "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/" echo "kdump: saving vmcore" $CORE_COLLECTOR /proc/vmcore $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore-incomplete || return 1 @@ -140,10 +136,6 @@ dump_fs() echo "kdump: saving vmcore complete" - if [ $_do_umount ]; then - umount $_mp || echo "kdump: warn: failed to umount target" - fi - # improper kernel cmdline can cause the failure of echo, we can ignore this kind of failure return 0 } @@ -168,6 +160,30 @@ save_vmcore_dmesg_fs() { fi } +save_opalcore_fs() { + local _path=$1 + + if [ ! -f $OPALCORE ]; then + # Check if we are on an old kernel that uses a different path + if [ -f /sys/firmware/opal/core ]; then + OPALCORE="/sys/firmware/opal/core" + else + return 0 + fi + fi + + echo "kdump: saving opalcore" + cp $OPALCORE ${_path}/opalcore + if [ $? -ne 0 ]; then + echo "kdump: saving opalcore failed" + return 1 + fi + + sync + echo "kdump: saving opalcore complete" + return 0 +} + dump_to_rootfs() { diff --git a/SOURCES/kdump-lib.sh b/SOURCES/kdump-lib.sh index ef0151f..c88c3f5 100755 --- a/SOURCES/kdump-lib.sh +++ b/SOURCES/kdump-lib.sh @@ -121,21 +121,16 @@ get_user_configured_dump_disk() get_root_fs_device() { - local _target - _target=$(findmnt -k -f -n -o SOURCE /) - [ -n "$_target" ] && echo $_target - - return + findmnt -k -f -n -o SOURCE / } get_save_path() { - local _save_path=$(grep "^path" /etc/kdump.conf|awk '{print $2}') - if [ -z "$_save_path" ]; then - _save_path=$DEFAULT_PATH - fi + local _save_path=$(awk '$1 == "path" {print $2}' /etc/kdump.conf) + [ -z "$_save_path" ] && _save_path=$DEFAULT_PATH - echo $_save_path + # strip the duplicated "/" + echo $_save_path | tr -s / } get_block_dump_target() @@ -197,44 +192,39 @@ get_kdump_targets() echo "$kdump_targets" } - +# 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 +# # findmnt uses the option "-v, --nofsroot" to exclusive the [/dir] # in the SOURCE column for bind-mounts, then if $_mntpoint equals to # $_mntpoint_nofsroot, the mountpoint is not bind mounted directory. -is_bind_mount() -{ - local _mntpoint=$(findmnt $1 | tail -n 1 | awk '{print $2}') - local _mntpoint_nofsroot=$(findmnt -v $1 | tail -n 1 | awk '{print $2}') - - if [[ $_mntpoint = $_mntpoint_nofsroot ]]; then - return 1 - else - return 0 - fi -} - +# # 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 "[]". -get_bind_mount_directory() +get_bind_mount_source() { - local _mntpoint=$(findmnt $1 | tail -n 1 | awk '{print $2}') - local _mntpoint_nofsroot=$(findmnt -v $1 | tail -n 1 | awk '{print $2}') + local _path=$1 + # In case it's a sub path in a mount point, get the mount point first + local _mnt_top=$(df $_path | tail -1 | awk '{print $NF}') + local _mntpoint=$(findmnt $_mnt_top | tail -n 1 | awk '{print $2}') + local _mntpoint_nofsroot=$(findmnt -v $_mnt_top | tail -n 1 | awk '{print $2}') - _mntpoint=${_mntpoint#*$_mntpoint_nofsroot} + if [[ "$_mntpoint" = $_mntpoint_nofsroot ]]; then + echo $_path && return + fi + _mntpoint=${_mntpoint#*$_mntpoint_nofsroot} _mntpoint=${_mntpoint#[} _mntpoint=${_mntpoint%]} + _path=${_path#$_mnt_top} - echo $_mntpoint -} - -get_mntpoint_from_path() -{ - echo $(df $1 | tail -1 | awk '{print $NF}') + echo $_mntpoint$_path } +# Return the current underlaying device of a path, ignore bind mounts get_target_from_path() { local _target @@ -244,73 +234,79 @@ get_target_from_path() echo $_target } -get_fs_type_from_target() +is_mounted() { - echo $(findmnt -k -f -n -r -o FSTYPE $1) + findmnt -k -n $1 &>/dev/null } -# input: device path -# output: the general mount point -# find the general mount point, not the bind mounted point in atomic -# As general system, Use the previous code -# -# ERROR and EXIT: -# the device can be umounted the general mount point, if one of the mount point is bind mounted -# For example: -# mount /dev/sda /mnt/ -# mount -o bind /mnt/var /var -# umount /mnt +get_mount_info() +{ + local _info_type=$1 _src_type=$2 _src=$3; shift 3 + local _info=$(findmnt -k -n -r -o $_info_type --$_src_type $_src $@) + + [ -z "$_info" ] && [ -e "/etc/fstab" ] && _info=$(findmnt -s -n -r -o $_info_type --$_src_type $_src $@) + + echo $_info +} + +get_fs_type_from_target() +{ + get_mount_info FSTYPE source $1 -f +} + +get_mntopt_from_target() +{ + get_mount_info OPTIONS source $1 -f +} +# Find the general mount point of a dump target, not the bind mount point get_mntpoint_from_target() { - if is_atomic; then - for _mnt in $(findmnt -k -n -r -o TARGET $1) - do - if ! is_bind_mount $_mnt; then - echo $_mnt - return - fi - done + # Expcilitly specify --source to findmnt could ensure non-bind mount is returned + get_mount_info TARGET source $1 -f +} - echo "Mount $1 firstly, without the bind mode" >&2 - exit 1 +# 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 + # 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 - echo $(findmnt -k -f -n -r -o TARGET $1) + if [ "$_mntpoint" = "/" ];then + _mntpoint="/sysroot" + else + _mntpoint="/kdumproot/$_mntpoint" + fi fi + + # strip duplicated "/" + echo $_mntpoint | tr -s "/" } # get_option_value # retrieves value of option defined in kdump.conf get_option_value() { - echo $(strip_comments `grep "^$1[[:space:]]\+" /etc/kdump.conf | tail -1 | cut -d\ -f2-`) + strip_comments `grep "^$1[[:space:]]\+" /etc/kdump.conf | tail -1 | cut -d\ -f2-` } -#This function compose a absolute path with the mount -#point and the relative $SAVE_PATH. -#target is passed in as argument, could be UUID, LABEL, -#block device or even nfs server export of the form of -#"my.server.com:/tmp/export"? -#And possibly this could be used for both default case -#as well as when dump taret is specified. When dump -#target is not specified, then $target would be null. -make_absolute_save_path() -{ - local _target=$1 - local _mnt - - [ -n $_target ] && _mnt=$(get_mntpoint_from_target $1) - _mnt="${_mnt}/$SAVE_PATH" - - # strip the duplicated "/" - echo "$_mnt" | tr -s / -} - -check_save_path_fs() -{ - local _path=$1 +kdump_get_persistent_dev() { + local dev="${1//\"/}" - if [ ! -d $_path ]; then - perror_exit "Dump path $_path does not exist." - fi + case "$dev" in + UUID=*) + dev=`blkid -U "${dev#UUID=}"` + ;; + LABEL=*) + dev=`blkid -L "${dev#LABEL=}"` + ;; + esac + echo $(get_persistent_dev "$dev") } is_atomic() @@ -601,35 +597,6 @@ need_64bit_headers() print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }'` } -# 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 - - 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 - - return 1 -} - # # prepare_kexec_args # This function prepares kexec argument. diff --git a/SOURCES/kdump.conf b/SOURCES/kdump.conf index 2b2fc89..4f3e30e 100644 --- a/SOURCES/kdump.conf +++ b/SOURCES/kdump.conf @@ -79,13 +79,23 @@ # or script after the vmcore dump process terminates. # The exit status of the current dump process is fed to # the executable binary or script as its first argument. +# If /etc/kdump/post.d directory is exist, All files in +# the directory are collectively sorted and executed in +# lexical order, before binary or script specified +# kdump_post parameter is executed. # # kdump_pre # - Works like the "kdump_post" directive, but instead of running # after the dump process, runs immediately before it. # Exit status of this binary is interpreted as follows: -# 0 - continue with dump process as usual -# non 0 - reboot the system +# 0 - continue with dump process as usual +# non 0 - reboot the system +# If /etc/kdump/pre.d directory exists, all files in +# the directory are collectively sorted and executed in +# lexical order, after binary or script specified +# kdump_pre parameter is executed. +# Even if the binary or script in /etc/kdump/pre.d directory +# returns non 0 exit status, the processing is continued. # # extra_bins # - This directive allows you to specify additional binaries or diff --git a/SOURCES/kdump.conf.5 b/SOURCES/kdump.conf.5 index adfc372..ea3e770 100644 --- a/SOURCES/kdump.conf.5 +++ b/SOURCES/kdump.conf.5 @@ -109,6 +109,11 @@ status of the current dump process is fed to the kdump_post executable as its first argument($1). Executable can modify it to indicate the new exit status of succeeding dump process, .PP +If /etc/kdump/post.d directory exists, All files in +the directory are collectively sorted and executed in +lexical order, before binary or script specified +kdump_post parameter is executed. +.PP Note that scripts written for use with this directive must use the /bin/bash interpreter. .RE @@ -124,6 +129,13 @@ as follows: .PP non 0 - reboot the system .PP +If /etc/kdump/pre.d directory exists, all files in +the directory are collectively sorted and executed in +lexical order, after binary or script specified +kdump_pre parameter is executed. +Even if the binary or script in /etc/kdump/pre.d directory +returns non 0 exit status, the processing is continued. +.PP Note that scripts written for this directive must use the /bin/bash interpreter. .RE diff --git a/SOURCES/kdump.sysconfig b/SOURCES/kdump.sysconfig index df518d6..7c5641a 100644 --- a/SOURCES/kdump.sysconfig +++ b/SOURCES/kdump.sysconfig @@ -17,7 +17,7 @@ KDUMP_COMMANDLINE="" # This variable lets us remove arguments from the current kdump commandline # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline # NOTE: some arguments such as crashkernel will always be removed -KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet" +KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len" # This variable lets us append arguments to the current kdump commandline # after processed by KDUMP_COMMANDLINE_REMOVE diff --git a/SOURCES/kdump.sysconfig.aarch64 b/SOURCES/kdump.sysconfig.aarch64 index d5d7624..6f55c03 100644 --- a/SOURCES/kdump.sysconfig.aarch64 +++ b/SOURCES/kdump.sysconfig.aarch64 @@ -17,7 +17,7 @@ KDUMP_COMMANDLINE="" # This variable lets us remove arguments from the current kdump commandline # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline # NOTE: some arguments such as crashkernel will always be removed -KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet" +KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb" # This variable lets us append arguments to the current kdump commandline # after processed by KDUMP_COMMANDLINE_REMOVE diff --git a/SOURCES/kdump.sysconfig.i386 b/SOURCES/kdump.sysconfig.i386 index 976aea6..84f0df1 100644 --- a/SOURCES/kdump.sysconfig.i386 +++ b/SOURCES/kdump.sysconfig.i386 @@ -17,7 +17,7 @@ KDUMP_COMMANDLINE="" # This variable lets us remove arguments from the current kdump commandline # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline # NOTE: some arguments such as crashkernel will always be removed -KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet" +KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb" # This variable lets us append arguments to the current kdump commandline # after processed by KDUMP_COMMANDLINE_REMOVE diff --git a/SOURCES/kdump.sysconfig.ppc64 b/SOURCES/kdump.sysconfig.ppc64 index 6ddfc3d..7ce41e3 100644 --- a/SOURCES/kdump.sysconfig.ppc64 +++ b/SOURCES/kdump.sysconfig.ppc64 @@ -17,7 +17,7 @@ KDUMP_COMMANDLINE="" # This variable lets us remove arguments from the current kdump commandline # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline # NOTE: some arguments such as crashkernel will always be removed -KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet" +KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb" # This variable lets us append arguments to the current kdump commandline # after processed by KDUMP_COMMANDLINE_REMOVE diff --git a/SOURCES/kdump.sysconfig.ppc64le b/SOURCES/kdump.sysconfig.ppc64le index 6ddfc3d..7ce41e3 100644 --- a/SOURCES/kdump.sysconfig.ppc64le +++ b/SOURCES/kdump.sysconfig.ppc64le @@ -17,7 +17,7 @@ KDUMP_COMMANDLINE="" # This variable lets us remove arguments from the current kdump commandline # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline # NOTE: some arguments such as crashkernel will always be removed -KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet" +KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb" # This variable lets us append arguments to the current kdump commandline # after processed by KDUMP_COMMANDLINE_REMOVE diff --git a/SOURCES/kdump.sysconfig.s390x b/SOURCES/kdump.sysconfig.s390x index 68705f9..de0ac49 100644 --- a/SOURCES/kdump.sysconfig.s390x +++ b/SOURCES/kdump.sysconfig.s390x @@ -17,7 +17,7 @@ KDUMP_COMMANDLINE="" # This variable lets us remove arguments from the current kdump commandline # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline # NOTE: some arguments such as crashkernel will always be removed -KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet" +KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb" # This variable lets us append arguments to the current kdump commandline # after processed by KDUMP_COMMANDLINE_REMOVE diff --git a/SOURCES/kdump.sysconfig.x86_64 b/SOURCES/kdump.sysconfig.x86_64 index e4aafc9..ef1da2d 100644 --- a/SOURCES/kdump.sysconfig.x86_64 +++ b/SOURCES/kdump.sysconfig.x86_64 @@ -17,7 +17,7 @@ KDUMP_COMMANDLINE="" # This variable lets us remove arguments from the current kdump commandline # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline # NOTE: some arguments such as crashkernel will always be removed -KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet" +KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb" # This variable lets us append arguments to the current kdump commandline # after processed by KDUMP_COMMANDLINE_REMOVE @@ -38,3 +38,9 @@ KDUMP_IMG="vmlinuz" #What is the images extension. Relocatable kernels don't have one KDUMP_IMG_EXT="" + +# Using kexec file based syscall by default +# +# Here, the "on" is the only valid value to enable the kexec file load and +# anything else is equal to the "off"(disable). +KDUMP_FILE_LOAD="off" diff --git a/SOURCES/kdumpctl b/SOURCES/kdumpctl index 694c7ae..73f45d3 100755 --- a/SOURCES/kdumpctl +++ b/SOURCES/kdumpctl @@ -4,6 +4,7 @@ KEXEC=/sbin/kexec KDUMP_KERNELVER="" KDUMP_COMMANDLINE="" KEXEC_ARGS="" +KDUMP_FILE_LOAD="" KDUMP_CONFIG_FILE="/etc/kdump.conf" MKDUMPRD="/sbin/mkdumprd -f" DRACUT_MODULES_FILE="/usr/lib/dracut/modules.txt" @@ -242,6 +243,9 @@ check_config() echo "Invalid kdump config value for option $config_opt." return 1; } + if [ -d "/proc/device-tree/ibm,opal/dump" ] && [ "$config_opt" == "raw" ]; then + echo "WARNING: Won't capture opalcore when 'raw' dump target is used." + fi ;; net|options|link_delay|disk_timeout|debug_mem_level|blacklist) echo "Deprecated kdump config option: $config_opt. Refer to kdump.conf manpage for alternatives." @@ -332,9 +336,23 @@ check_files_modified() EXTRA_BINS=`grep ^kdump_post $KDUMP_CONFIG_FILE | cut -d\ -f2` CHECK_FILES=`grep ^kdump_pre $KDUMP_CONFIG_FILE | cut -d\ -f2` + if [ -d /etc/kdump/post.d ]; then + for file in /etc/kdump/post.d/*; do + if [ -x "$file" ]; then + POST_FILES="$POST_FILES $file" + fi + done + fi + if [ -d /etc/kdump/pre.d ]; then + for file in /etc/kdump/pre.d/*; do + if [ -x "$file" ]; then + PRE_FILES="$PRE_FILES $file" + fi + done + fi CORE_COLLECTOR=`grep ^core_collector $KDUMP_CONFIG_FILE | cut -d\ -f2` CORE_COLLECTOR=`type -P $CORE_COLLECTOR` - EXTRA_BINS="$EXTRA_BINS $CHECK_FILES" + EXTRA_BINS="$EXTRA_BINS $CHECK_FILES $POST_FILES $PRE_FILES" CHECK_FILES=`grep ^extra_bins $KDUMP_CONFIG_FILE | cut -d\ -f2-` EXTRA_BINS="$EXTRA_BINS $CHECK_FILES" files="$KDUMP_CONFIG_FILE $kdump_kernel $EXTRA_BINS $CORE_COLLECTOR" @@ -461,24 +479,14 @@ check_dump_fs_modified() if [[ $(expr substr $_new_fstype 1 3) = "nfs" ]];then _new_dev=$_target else - _new_dev=$(get_persistent_dev $_target) + _new_dev=$(kdump_get_persistent_dev $_target) if [ -z "$_new_dev" ]; then echo "Get persistent device name failed" return 2 fi fi - if ! findmnt $_target >/dev/null; then - echo "Dump target $_target is probably not mounted." - return 2 - fi - - if [[ "$_target" = "$(get_root_fs_device)" ]]; then - _new_mntpoint="/sysroot" - else - _new_mntpoint="/kdumproot/$(get_mntpoint_from_target $_target)" - fi - + _new_mntpoint="$(get_kdump_mntpoint_from_target $_target)" _dracut_args=$(lsinitrd $TARGET_INITRD -f usr/lib/dracut/build-parameter.txt) if [[ -z "$_dracut_args" ]];then echo "Warning: No dracut arguments found in initrd" @@ -675,11 +683,8 @@ load_kdump() KEXEC_ARGS=$(prepare_kexec_args "${KEXEC_ARGS}") KDUMP_COMMANDLINE=$(prepare_cmdline "${KDUMP_COMMANDLINE}" "${KDUMP_COMMANDLINE_REMOVE}" "${KDUMP_COMMANDLINE_APPEND}") - # For secureboot enabled machines, use new kexec file based syscall. - # Old syscall will always fail as it does not have capability to - # to kernel signature verification. - if is_secure_boot_enforced; then - echo "Secure Boot is enabled. Using kexec file based syscall." + if [ "$KDUMP_FILE_LOAD" == "on" ]; then + echo "Using kexec file based syscall." KEXEC_ARGS="$KEXEC_ARGS -s" fi @@ -691,6 +696,9 @@ load_kdump() return 0 else echo "kexec: failed to load kdump kernel" >&2 + if [ "$KDUMP_FILE_LOAD" == "on" ]; then + echo "kexec_file_load() failed, please try kexec_load()" >&2 + fi return 1 fi } @@ -884,15 +892,6 @@ save_raw() return 0 } -is_dump_target_configured() -{ - local _target - - _target=$(egrep "^ext[234]|^xfs|^btrfs|^minix|^raw|^ssh|^nfs" /etc/kdump.conf) - - [ -n "$_target" ] -} - local_fs_dump_target() { local _target @@ -907,11 +906,15 @@ path_to_be_relabeled() { local _path _target _mnt="/" _rmnt - if is_dump_target_configured; then + if is_user_configured_dump_target; then + if is_mount_in_dracut_args; then + return; + fi + _target=$(local_fs_dump_target) if [[ -n "$_target" ]]; then - _mnt=$(findmnt -k -f -n -r -o TARGET $_target) - if [ -z "$_mnt" ]; then + _mnt=$(get_mntpoint_from_target $_target) + if ! is_mounted "$_mnt"; then return fi else @@ -919,9 +922,6 @@ path_to_be_relabeled() fi fi - if is_mount_in_dracut_args; then - return; - fi _path=$(get_save_path) # if $_path is masked by other mount, we will not relabel it. _rmnt=$(df $_mnt/$_path 2>/dev/null | tail -1 | awk '{ print $NF }') @@ -1154,7 +1154,7 @@ stop_fadump() stop_kdump() { - if is_secure_boot_enforced; then + if [ "$KDUMP_FILE_LOAD" == "on" ]; then $KEXEC -s -p -u else $KEXEC -p -u diff --git a/SOURCES/kexec-kdump-howto.txt b/SOURCES/kexec-kdump-howto.txt index 0da938e..449855e 100644 --- a/SOURCES/kexec-kdump-howto.txt +++ b/SOURCES/kexec-kdump-howto.txt @@ -1,15 +1,22 @@ +================= Kexec/Kdump HOWTO +================= + Introduction +============ Kexec and kdump are new features in the 2.6 mainstream kernel. These features are included in Red Hat Enterprise Linux 5. The purpose of these features is to ensure faster boot up and creation of reliable kernel vmcores for diagnostic purposes. + Overview +======== Kexec +----- Kexec is a fastboot mechanism which allows booting a Linux kernel from the context of already running kernel without going through BIOS. BIOS can be very @@ -17,6 +24,7 @@ time consuming especially on the big servers with lots of peripherals. This can save a lot of time for developers who end up booting a machine numerous times. Kdump +----- Kdump is a new kernel crash dumping mechanism and is very reliable because the crash dump is captured from the context of a freshly booted kernel and @@ -52,7 +60,8 @@ Now reboot your system, taking note that it should bypass the BIOS: # reboot -How to configure kdump: +How to configure kdump +====================== Again, we assume if you're reading this document, you should already have kexec-tools installed. If not, you install it via the following command: @@ -136,7 +145,9 @@ perform postmortem analysis: and so on... -Notes: + +Notes on kdump +============== When kdump starts, the kdump kernel is loaded together with the kdump initramfs. To save memory usage and disk space, the kdump initramfs is @@ -152,8 +163,10 @@ recommended to rebuild the initramfs manually with following command: # kdumpctl rebuild + Saving vmcore-dmesg.txt ----------------------- +======================= + Kernel log bufferes are one of the most important information available in vmcore. Now before saving vmcore, kernel log bufferes are extracted from /proc/vmcore and saved into a file vmcore-dmesg.txt. After @@ -161,7 +174,9 @@ vmcore-dmesg.txt, vmcore is saved. Destination disk and directory for vmcore-dmesg.txt is same as vmcore. Note that kernel log buffers will not be available if dump target is raw device. -Dump Triggering methods: + +Dump Triggering methods +======================= This section talks about the various ways, other than a Kernel Panic, in which Kdump can be triggered. The following methods assume that Kdump is configured @@ -268,7 +283,8 @@ to initate the dump and then click "Restart blade with NMI". This issues a system reset and invokes xmon debugger. -Advanced Setups: +Dump targets +============ In addition to being able to capture a vmcore to your system's local file system, kdump can be configured to capture a vmcore to a number of other @@ -276,7 +292,8 @@ locations, including a raw disk partition, a dedicated file system, an NFS mounted file system, or a remote system via ssh/scp. Additional options exist for specifying the relative path under which the dump is captured, what to do if the capture fails, and for compressing and filtering the dump -(so as to produce smaller, more manageable, vmcore files). +(so as to produce smaller, more manageable, vmcore files, see "Advanced Setups" +for more detail on these options). In theory, dumping to a location other than the local file system should be safer than kdump's default setup, as its possible the default setup will try @@ -289,32 +306,133 @@ as allowing for the centralization of vmcore files, should you have several systems from which you'd like to obtain vmcore files. Of course, note that these configurations could present problems if your network is unreliable. -Advanced setups are configured via modifications to /etc/kdump.conf, -which out of the box, is fairly well documented itself. Any alterations to -/etc/kdump.conf should be followed by a restart of the kdump service, so -the changes can be incorporated in the kdump initrd. Restarting the kdump -service is as simple as '/sbin/systemctl restart kdump.service'. - - -Note that kdump.conf is used as a configuration mechanism for capturing dump -files from the initramfs (in the interests of safety), the root file system is -mounted, and the init process is started, only as a last resort if the -initramfs fails to capture the vmcore. As such, configuration made in -/etc/kdump.conf is only applicable to capture recorded in the initramfs. If -for any reason the init process is started on the root file system, only a -simple copying of the vmcore from /proc/vmcore to /var/crash/$DATE/vmcore will -be preformed. - -For both local filesystem and nfs dump the dump target must be mounted before -building kdump initramfs. That means one needs to put an entry for the dump -file system in /etc/fstab so that after reboot when kdump service starts, -it can find the dump target and build initramfs instead of failing. +Kdump target and advanced setups are configured via modifications to +/etc/kdump.conf, which out of the box, is fairly well documented itself. +Any alterations to /etc/kdump.conf should be followed by a restart of the +kdump service, so the changes can be incorporated in the kdump initrd. +Restarting the kdump service is as simple as '/sbin/systemctl restart kdump.service'. + +There are two ways to config the dump target, config dump target only +using "path", and config dump target explicitly. Interpretation of "path" +also differs in two config styles. + +Config dump target only using "path" +------------------------------------ + +You can change the dump target by setting "path" to a mount point where +dump target is mounted. When there is no explicitly configured dump target, +"path" in kdump.conf represents the current file system path in which vmcore +will be saved. Kdump will automatically detect the underlying device of +"path" and use that as the dump target. + +In fact, upon dump, kdump creates a directory $hostip-$date with-in "path" +and saves vmcore there. So practically dump is saved in $path/$hostip-$date/. + +Kdump will only check current mount status for mount entry corresponding to +"path". So please ensure the dump target is mounted on "path" before kdump +service starts. + +NOTES: + +- It's strongly recommanded to put an mount entry for "path" in /etc/fstab + and have it auto mounted on boot. This make sure the dump target is + reachable from the machine and kdump's configuration is stable. + +EXAMPLES: + +- path /var/crash/ + + This is the default configuration. Assuming there is no disk mounted + on /var/ or on /var/crash, dump will be saved on disk backing rootfs + in directory /var/crash. + +- path /var/crash/ (A separate disk mounted on /var/crash) + + Say a disk /dev/sdb is mounted on /var. In this case dump target will + become /dev/sdb and path will become "/" and dump will be saved + on "sdb:/var/crash/" directory. + +- path /var/crash/ (NFS mounted on /var) + + Say foo.com:/export/tmp is mounted on /var. In this case dump target is + nfs server and path will be adjusted to "/crash" and dump will be saved to + foo.com:/export/tmp/crash/ directory. + +Config dump target explicitely +------------------------------ + +You can set the dump target explicitly in kdump.conf, and "path" will be +the relative path in the specified dump target. For example, if dump +target is "ext4 /dev/sda", then dump will be saved in "path" directory +on /dev/sda. + +Same is the case for nfs dump. If user specified "nfs foo.com:/export/tmp/" +as dump target, then dump will effectively be saved in +"foo.com:/export/tmp/var/crash/" directory. + +If the dump target is "raw", then "path" is ignored. + +If it's a filesystem target, kdump will need to know the right mount option. +Kdump will check current mount status, and then /etc/fstab for mount options +corresponding to the specified dump target and use it. If there are +special mount option required for the dump target, it could be set by put +an entry in fstab. + +If there are no related mount entry, mount option is set to "defaults". + +NOTES: + +- It's recommended to put an entry for the dump target in /etc/fstab + and have it auto mounted on boot. This make sure the dump target is + reachable from the machine and kdump won't fail. + +- Kdump ignores some mount options, including "noauto", "ro". This + make it possible to keep the dump target unmounted or read-only + when not used. + +EXAMPLES: + +- ext4 /dev/sda (mounted) + path /var/crash/ + + In this case dump target is set to /dev/sdb, path is the absolute path + "/var/crash" in /dev/sda, vmcore path will saved on + "sda:/var/crash" directory. + +- nfs foo.com:/export/tmp (mounted) + path /var/crash/ + + In this case dump target is nfs server, path is the absolute path + "/var/crash", vmcore path will saved on "foo.com:/export/tmp/crash/" directory. + +- nfs foo.com:/export/tmp (not mounted) + path /var/crash/ + + Same with above case, kdump will use "defaults" as the mount option + for the dump target. + +- nfs foo.com:/export/tmp (not mounted, entry with option "noauto,nolock" exists in /etc/fstab) + path /var/crash/ + + In this case dump target is nfs server, vmcore path will saved on + "foo.com:/export/tmp/crash/" directory, and kdump will inherit "nolock" option. + +Dump target and mkdumprd +------------------------ + +MKdumprd is the tool used to create kdump initramfs, and it may change +the mount status of the dump target in some condition. + Usually the dump target should be used only for kdump. If you worry about someone uses the filesystem for something else other than dumping vmcore -you can mount it as read-only. Mkdumprd will still remount it as read-write -for creating dump directory and will move it back to read-only afterwards. +you can mount it as read-only or make it a noauto mount. Mkdumprd will +mount/remount it as read-write for creating dump directory and will +move it back to it's original state afterwards. -Raw partition +Supported dump target types and requirements +-------------------------------------------- + +1) Raw partition Raw partition dumping requires that a disk partition in the system, at least as large as the amount of memory in the system, be left unformatted. Assuming @@ -325,7 +443,7 @@ onto partition /dev/vg/lv_kdump. Restart the kdump service via initrd. Dump target should be persistent device name, such as lvm or device mapper canonical name. -Dedicated file system +2) Dedicated file system Similar to raw partition dumping, you can format a partition with the file system of your choice, Again, it should be at least as large as the amount @@ -349,7 +467,7 @@ Be careful of your filesystem selection when using this target. It is recommended to use persistent device names or UUID/LABEL for file system dumps. One example of persistent device is /dev/vg/. -NFS mount +3) NFS mount Dumping over NFS requires an NFS server configured to export a file system with full read/write access for the root user. All operations done within @@ -367,7 +485,7 @@ mount the NFS mount and copy out the vmcore to your NFS server. Restart the kdump service via '/sbin/systemctl restart kdump.service' to commit this change to your kdump initrd. -Special mount via "dracut_args" +4) Special mount via "dracut_args" You can utilize "dracut_args" to pass "--mount" to kdump, see dracut manpage about the format of "--mount" for details. If there is any "--mount" specified @@ -385,7 +503,7 @@ dracut_args --mount "192.168.1.1:/share /mnt/test nfs4 defaults" NOTE: - must be specified as an absolute path. -Remote system via ssh/scp +5) Remote system via ssh/scp Dumping over ssh/scp requires setting up passwordless ssh keys for every machine you wish to have dump via this method. First up, configure kdump.conf @@ -403,49 +521,12 @@ you've connected to it, and then input the target system user's password to send over the necessary ssh key file. Restart the kdump service via '/sbin/systemctl restart kdump.service' to commit this change to your kdump initrd. -Path -==== -"path" represents the file system path in which vmcore will be saved. In -fact kdump creates a directory $hostip-$date with-in "path" and saves -vmcore there. So practically dump is saved in $path/$hostip-$date/. To -simplify discussion further, if we say dump will be saved in $path, it -is implied that kdump will create another directory inside path and -save vmcore there. - -If a dump target is specified in kdump.conf, then "path" is relative to the -specified dump target. For example, if dump target is "ext4 /dev/sda", then -dump will be saved in "$path" directory on /dev/sda. - -Same is the case for nfs dump. If user specified "nfs foo.com:/export/tmp/" -as dump target, then dump will effectively be saved in -"foo.com:/export/tmp/var/crash/" directory. - -Interpretation of path changes a bit if user has not specified a dump -target explicitly in kdump.conf. In this case, "path" represents the -absolute path from root. And dump target and adjusted path are arrived -at automatically depending on what's mounted in the current system. - -Following are few examples. - -path /var/crash/ ----------------- -Assuming there is no disk mounted on /var/ or on /var/crash, dump will -be saved on disk backing rootfs in directory /var/crash. - -path /var/crash/ (A separate disk mounted on /var) --------------------------------------------------- -Say a disk /dev/sdb is mouted on /var. In this case dump target will -become /dev/sdb and path will become "/crash" and dump will be saved -on "sdb:/crash/" directory. - -path /var/crash/ (NFS mounted on /var) -------------------------------------- -Say foo.com:/export/tmp is mounted on /var. In this case dump target is -nfs server and path will be adjusted to "/crash" and dump will be saved to -foo.com:/export/tmp/crash/ directory. +Advanced Setups +=============== Kdump boot directory -==================== +-------------------- + Usually kdump kernel is the same as 1st kernel. So kdump will try to find kdump kernel under /boot according to /proc/cmdline. E.g we execute below command and get an output: @@ -456,20 +537,31 @@ However a variable KDUMP_BOOTDIR in /etc/sysconfig/kdump is provided to user if kdump kernel is put in a different directory. Kdump Post-Capture Executable +----------------------------- It is possible to specify a custom script or binary you wish to run following an attempt to capture a vmcore. The executable is passed an exit code from the capture process, which can be used to trigger different actions from within your post-capture executable. +If /etc/kdump/post.d directory exist, All files in the directory are +collectively sorted and executed in lexical order, before binary or script +specified kdump_post parameter is executed. Kdump Pre-Capture Executable +---------------------------- It is possible to specify a custom script or binary you wish to run before capturing a vmcore. Exit status of this binary is interpreted: 0 - continue with dump process as usual non 0 - reboot the system +If /etc/kdump/pre.d directory exists, all files in the directory are collectively +sorted and executed in lexical order, after binary or script specified +kdump_pre parameter is executed. +Even if the binary or script in /etc/kdump/pre.d directory returns non 0 +exit status, the processing is continued. Extra Binaries +-------------- If you have specific binaries or scripts you want to have made available within your kdump initrd, you can specify them by their full path, and they @@ -478,6 +570,7 @@ This may be particularly useful for those running post-capture scripts that rely on other binaries. Extra Modules +------------- By default, only the bare minimum of kernel modules will be included in your kdump initrd. Should you wish to capture your vmcore files to a non-boot-path @@ -486,7 +579,8 @@ need to manually specify additional kernel modules to load into your kdump initrd. Failure action -============== +-------------- + Failure action specifies what to do when dump to configured dump target fails. By default, failure action is "reboot" and that is system reboots if attempt to save dump to dump target fails. @@ -494,21 +588,24 @@ if attempt to save dump to dump target fails. There are other failure actions available though. - dump_to_rootfs - This option tries to mount root and save dump on root filesystem - in a path specified by "path". This option will generally make - sense when dump target is not root filesystem. For example, if - dump is being saved over network using "ssh" then one can specify - failure action to "dump_to_rootfs" to try saving dump to root - filesystem if dump over network fails. + This option tries to mount root and save dump on root filesystem + in a path specified by "path". This option will generally make + sense when dump target is not root filesystem. For example, if + dump is being saved over network using "ssh" then one can specify + failure action to "dump_to_rootfs" to try saving dump to root + filesystem if dump over network fails. - shell - Drop into a shell session inside initramfs. + Drop into a shell session inside initramfs. + - halt - Halt system after failure + Halt system after failure + - poweroff - Poweroff system after failure. + Poweroff system after failure. Compression and filtering +------------------------- The 'core_collector' parameter in kdump.conf allows you to specify a custom dump capture method. The most common alternate method is makedumpfile, which @@ -526,22 +623,21 @@ Core collector command format depends on dump target type. Typically for filesystem (local/remote), core_collector should accept two arguments. First one is source file and second one is target file. For ex. -ex1. ---- -core_collector "cp --sparse=always" +- ex1. + + core_collector "cp --sparse=always" -Above will effectively be translated to: + Above will effectively be translated to: -cp --sparse=always /proc/vmcore /vmcore + cp --sparse=always /proc/vmcore /vmcore -ex2. ---- -core_collector "makedumpfile -l --message-level 1 -d 31" +- ex2. -Above will effectively be translated to: + core_collector "makedumpfile -l --message-level 1 -d 31" -makedumpfile -l --message-level 1 -d 31 /proc/vmcore /vmcore + Above will effectively be translated to: + makedumpfile -l --message-level 1 -d 31 /proc/vmcore /vmcore For dump targets like raw and ssh, in general, core collector should expect one argument (source file) and should output the processed core on standard @@ -549,55 +645,56 @@ output (There is one exception of "scp", discussed later). This standard output will be saved to destination using appropriate commands. raw dumps core_collector examples: ---------- -ex3. ---- -core_collector "cat" -Above will effectively be translated to. +- ex3. + + core_collector "cat" -cat /proc/vmcore | dd of= + Above will effectively be translated to. -ex4. ---- -core_collector "makedumpfile -F -l --message-level 1 -d 31" + cat /proc/vmcore | dd of= -Above will effectively be translated to. +- ex4. -makedumpfile -F -l --message-level 1 -d 31 | dd of= + core_collector "makedumpfile -F -l --message-level 1 -d 31" + + Above will effectively be translated to. + + makedumpfile -F -l --message-level 1 -d 31 | dd of= ssh dumps core_collector examples: ---------- -ex5. ---- -core_collector "cat" -Above will effectively be translated to. +- ex5. + + core_collector "cat" -cat /proc/vmcore | ssh "dd of=path/vmcore" + Above will effectively be translated to. -ex6. ---- -core_collector "makedumpfile -F -l --message-level 1 -d 31" + cat /proc/vmcore | ssh "dd of=path/vmcore" -Above will effectively be translated to. +- ex6. -makedumpfile -F -l --message-level 1 -d 31 | ssh "dd of=path/vmcore" + core_collector "makedumpfile -F -l --message-level 1 -d 31" + + Above will effectively be translated to. + + makedumpfile -F -l --message-level 1 -d 31 | ssh "dd of=path/vmcore" There is one exception to standard output rule for ssh dumps. And that is scp. As scp can handle ssh destinations for file transfers, one can specify "scp" as core collector for ssh targets (no output on stdout). -ex7. ----- -core_collector "scp" +- ex7. + + core_collector "scp" -Above will effectively be translated to. + Above will effectively be translated to. -scp /proc/vmcore :path/vmcore + scp /proc/vmcore :path/vmcore About default core collector ---------------------------- + Default core_collector for ssh/raw dump is: "makedumpfile -F -l --message-level 1 -d 31". Default core_collector for other targets is: @@ -615,7 +712,9 @@ dump data from stdard input to a normal dumpfile (readable with analysis tools). For example: "makedumpfile -R vmcore < vmcore.flat" -Caveats: + +Caveats +======= Console frame-buffers and X are not properly supported. If you typically run with something along the lines of "vga=791" in your kernel config line or @@ -624,7 +723,11 @@ kexec. Note that the kdump kernel should still be able to create a dump, and when the system reboots, video should be restored to normal. +Notes +===== + Notes on resetting video: +------------------------- Video is a notoriously difficult issue with kexec. Video cards contain ROM code that controls their initial configuration and setup. This code is nominally @@ -646,7 +749,9 @@ Secondly, it may be worth trying to add vga15fb.ko to the extra_modules list in /etc/kdump.conf. This will attempt to use the video card in framebuffer mode, which can blank the screen prior to the start of a dump capture. -Notes on rootfs mount: +Notes on rootfs mount +--------------------- + Dracut is designed to mount rootfs by default. If rootfs mounting fails it will refuse to go on. So kdump leaves rootfs mounting to dracut currently. We make the assumtion that proper root= cmdline is being passed to dracut @@ -656,7 +761,8 @@ options are copied from /proc/cmdline. In general it is best to append command line options using "KDUMP_COMMANDLINE_APPEND=" instead of replacing the original command line completely. -Notes on watchdog module handling: +Notes on watchdog module handling +--------------------------------- If a watchdog is active in first kernel then, we must have it's module loaded in crash kernel, so that either watchdog is deactivated or started @@ -670,7 +776,8 @@ not been written in watchdog-core framework then this option will not have any effect and module will not be added. Please note that only systemd watchdog daemon is supported as watchdog kick application. -Notes for disk images: +Notes for disk images +--------------------- Kdump initramfs is a critical component for capturing the crash dump. But it's strictly generated for the machine it will run on, and have @@ -684,7 +791,8 @@ a machine with a disk image which have kdump initramfs embedded, you should rebuild the initramfs using "kdumpctl rebuild" command manually, or else kdump may not work as expeceted. -Notes on encrypted dump target: +Notes on encrypted dump target +------------------------------ Currently, kdump is not working well with encrypted dump target. First, user have to give the password manually in capture kernel, @@ -698,7 +806,8 @@ crash kernel according, or update your encryption setup. It's recommanded to use a non-encrypted target (eg. remote target) instead. -Notes on device dump: +Notes on device dump +-------------------- Device dump allows drivers to append dump data to vmcore, so you can collect driver specified debug info. The drivers could append the @@ -715,8 +824,10 @@ the dump target setup will be included. To ensure the device dump data will be included in the vmcore, you need to force include related device drivers by using "extra_modules" option in /etc/kdump.conf + Parallel Dumping Operation ========================== + Kexec allows kdump using multiple cpus. So parallel feature can accelerate dumping substantially, especially in executing compression and filter. For example: @@ -746,8 +857,10 @@ may lead to panic due to Out Of Memory. hang, system reset or power-off at boot, depending on your system and runtime situation at the time of crash. + Debugging Tips --------------- +============== + - One can drop into a shell before/after saving vmcore with the help of using kdump_pre/kdump_post hooks. Use following in one of the pre/post scripts to drop into a shell. @@ -772,5 +885,3 @@ Debugging Tips minicom -C /tmp/console-logs Now minicom should be logging serial console in file console-logs. - - diff --git a/SOURCES/kexec-tools-2.0.20-arm64-kdump-deal-with-a-lot-of-resource-entries-in-p.patch b/SOURCES/kexec-tools-2.0.20-arm64-kdump-deal-with-a-lot-of-resource-entries-in-p.patch new file mode 100644 index 0000000..1f51eb2 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.20-arm64-kdump-deal-with-a-lot-of-resource-entries-in-p.patch @@ -0,0 +1,82 @@ +From 2572b8d702e452624bdb8d7b7c39f458e7dcf2ce Mon Sep 17 00:00:00 2001 +From: AKASHI Takahiro +Date: Wed, 18 Dec 2019 11:42:32 -0500 +Subject: [PATCH 3/3] arm64: kdump: deal with a lot of resource entries in + /proc/iomem + +As described in the commit ("arm64: kexec: allocate memory space avoiding +reserved regions"), /proc/iomem now has a lot of "reserved" entries, and +it's not just enough to have a fixed size of memory range array. + +With this patch, kdump is allowed to handle arbitrary number of memory +ranges, using mem_regions_alloc_and_xxx() functions. + +Signed-off-by: AKASHI Takahiro +Tested-by: Bhupesh Sharma +Tested-by: Masayoshi Mizuma +Signed-off-by: Simon Horman +--- + kexec/arch/arm64/crashdump-arm64.c | 25 ++++++++++--------------- + 1 file changed, 10 insertions(+), 15 deletions(-) + +diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c +index 4fd7aa8fd43c..38d1a0f3000d 100644 +--- a/kexec/arch/arm64/crashdump-arm64.c ++++ b/kexec/arch/arm64/crashdump-arm64.c +@@ -23,13 +23,8 @@ + #include "kexec-elf.h" + #include "mem_regions.h" + +-/* memory ranges on crashed kernel */ +-static struct memory_range system_memory_ranges[CRASH_MAX_MEMORY_RANGES]; +-static struct memory_ranges system_memory_rgns = { +- .size = 0, +- .max_size = CRASH_MAX_MEMORY_RANGES, +- .ranges = system_memory_ranges, +-}; ++/* memory ranges of crashed kernel */ ++static struct memory_ranges system_memory_rgns; + + /* memory range reserved for crashkernel */ + struct memory_range crash_reserved_mem; +@@ -82,7 +77,7 @@ static uint64_t get_kernel_page_offset(void) + * + * This function is called once for each memory region found in /proc/iomem. + * It locates system RAM and crashkernel reserved memory and places these to +- * variables, respectively, system_memory_ranges and crash_reserved_mem. ++ * variables, respectively, system_memory_rgns and usablemem_rgns. + */ + + static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr), +@@ -90,11 +85,11 @@ static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr), + unsigned long long length) + { + if (strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) == 0) +- return mem_regions_add(&usablemem_rgns, +- base, length, RANGE_RAM); ++ return mem_regions_alloc_and_add(&usablemem_rgns, ++ base, length, RANGE_RAM); + else if (strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) == 0) +- return mem_regions_add(&system_memory_rgns, +- base, length, RANGE_RAM); ++ return mem_regions_alloc_and_add(&system_memory_rgns, ++ base, length, RANGE_RAM); + else if (strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) == 0) + elf_info.kern_paddr_start = base; + else if (strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) == 0) +@@ -135,9 +130,9 @@ static int crash_get_memory_ranges(void) + + dbgprint_mem_range("Reserved memory range", &crash_reserved_mem, 1); + +- if (mem_regions_exclude(&system_memory_rgns, &crash_reserved_mem)) { +- fprintf(stderr, +- "Error: Number of crash memory ranges excedeed the max limit\n"); ++ if (mem_regions_alloc_and_exclude(&system_memory_rgns, ++ &crash_reserved_mem)) { ++ fprintf(stderr, "Cannot allocate memory for ranges\n"); + return -ENOMEM; + } + +-- +2.7.4 + diff --git a/SOURCES/kexec-tools-2.0.20-arm64-kexec-allocate-memory-space-avoiding-reserved-.patch b/SOURCES/kexec-tools-2.0.20-arm64-kexec-allocate-memory-space-avoiding-reserved-.patch new file mode 100644 index 0000000..c641b66 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.20-arm64-kexec-allocate-memory-space-avoiding-reserved-.patch @@ -0,0 +1,248 @@ +From f736104f533290b4ce6fbfbca74abde9ffd3888c Mon Sep 17 00:00:00 2001 +From: AKASHI Takahiro +Date: Wed, 18 Dec 2019 11:42:31 -0500 +Subject: [PATCH 2/3] arm64: kexec: allocate memory space avoiding reserved + regions + +On UEFI/ACPI-only system, some memory regions, including but not limited +to UEFI memory map and ACPI tables, must be preserved across kexec'ing. +Otherwise, they can be corrupted and result in early failure in booting +a new kernel. + +In recent kernels, /proc/iomem now has an extended file format like: + + 40000000-5871ffff : System RAM + 41800000-426affff : Kernel code + 426b0000-42aaffff : reserved + 42ab0000-42c64fff : Kernel data + 54400000-583fffff : Crash kernel + 58590000-585effff : reserved + 58700000-5871ffff : reserved + 58720000-58b5ffff : reserved + 58b60000-5be3ffff : System RAM + 58b61000-58b61fff : reserved + +where the "reserved" entries at the top level or under System RAM (and +its descendant resources) are ones of such kind and should not be regarded +as usable memory ranges where several free spaces for loading kexec data +will be allocated. + +With this patch, get_memory_ranges() will handle this format of file +correctly. Note that, for safety, unknown regions, in addition to +"reserved" ones, will also be excluded. + +Signed-off-by: AKASHI Takahiro +Tested-by: Bhupesh Sharma +Tested-by: Masayoshi Mizuma +Signed-off-by: Simon Horman +--- + kexec/arch/arm64/kexec-arm64.c | 153 +++++++++++++++++++++++++---------------- + 1 file changed, 94 insertions(+), 59 deletions(-) + +diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c +index 6ad3b0a134b3..45ebc54a9b6f 100644 +--- a/kexec/arch/arm64/kexec-arm64.c ++++ b/kexec/arch/arm64/kexec-arm64.c +@@ -10,7 +10,9 @@ + #include + #include + #include ++#include + #include ++#include + #include + #include + #include +@@ -29,6 +31,7 @@ + #include "fs2dt.h" + #include "iomem.h" + #include "kexec-syscall.h" ++#include "mem_regions.h" + #include "arch/options.h" + + #define ROOT_NODE_ADDR_CELLS_DEFAULT 1 +@@ -905,19 +908,33 @@ int get_phys_base_from_pt_load(unsigned long *phys_offset) + return 0; + } + ++static bool to_be_excluded(char *str) ++{ ++ if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) || ++ !strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) || ++ !strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) || ++ !strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL))) ++ return false; ++ else ++ return true; ++} ++ + /** +- * get_memory_ranges_iomem_cb - Helper for get_memory_ranges_iomem. ++ * get_memory_ranges - Try to get the memory ranges from ++ * /proc/iomem. + */ +- +-static int get_memory_ranges_iomem_cb(void *data, int nr, char *str, +- unsigned long long base, unsigned long long length) ++int get_memory_ranges(struct memory_range **range, int *ranges, ++ unsigned long kexec_flags) + { +- int ret; + unsigned long phys_offset = UINT64_MAX; +- struct memory_range *r; +- +- if (nr >= KEXEC_SEGMENT_MAX) +- return -1; ++ FILE *fp; ++ const char *iomem = proc_iomem(); ++ char line[MAX_LINE], *str; ++ unsigned long long start, end; ++ int n, consumed; ++ struct memory_ranges memranges; ++ struct memory_range *last, excl_range; ++ int ret; + + if (!try_read_phys_offset_from_kcore) { + /* Since kernel version 4.19, 'kcore' contains +@@ -951,17 +968,72 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str, + try_read_phys_offset_from_kcore = true; + } + +- r = (struct memory_range *)data + nr; ++ fp = fopen(iomem, "r"); ++ if (!fp) ++ die("Cannot open %s\n", iomem); ++ ++ memranges.ranges = NULL; ++ memranges.size = memranges.max_size = 0; ++ ++ while (fgets(line, sizeof(line), fp) != 0) { ++ n = sscanf(line, "%llx-%llx : %n", &start, &end, &consumed); ++ if (n != 2) ++ continue; ++ str = line + consumed; ++ ++ if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM))) { ++ ret = mem_regions_alloc_and_add(&memranges, ++ start, end - start + 1, RANGE_RAM); ++ if (ret) { ++ fprintf(stderr, ++ "Cannot allocate memory for ranges\n"); ++ fclose(fp); ++ return -ENOMEM; ++ } + +- if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM))) +- r->type = RANGE_RAM; +- else if (!strncmp(str, IOMEM_RESERVED, strlen(IOMEM_RESERVED))) +- r->type = RANGE_RESERVED; +- else +- return 1; ++ dbgprintf("%s:+[%d] %016llx - %016llx\n", __func__, ++ memranges.size - 1, ++ memranges.ranges[memranges.size - 1].start, ++ memranges.ranges[memranges.size - 1].end); ++ } else if (to_be_excluded(str)) { ++ if (!memranges.size) ++ continue; ++ ++ /* ++ * Note: mem_regions_exclude() doesn't guarantee ++ * that the ranges are sorted out, but as long as ++ * we cope with /proc/iomem, we only operate on ++ * the last entry and so it is safe. ++ */ + +- r->start = base; +- r->end = base + length - 1; ++ /* The last System RAM range */ ++ last = &memranges.ranges[memranges.size - 1]; ++ ++ if (last->end < start) ++ /* New resource outside of System RAM */ ++ continue; ++ if (end < last->start) ++ /* Already excluded by parent resource */ ++ continue; ++ ++ excl_range.start = start; ++ excl_range.end = end; ++ ret = mem_regions_alloc_and_exclude(&memranges, &excl_range); ++ if (ret) { ++ fprintf(stderr, ++ "Cannot allocate memory for ranges (exclude)\n"); ++ fclose(fp); ++ return -ENOMEM; ++ } ++ dbgprintf("%s:- %016llx - %016llx\n", ++ __func__, start, end); ++ } ++ } ++ ++ fclose(fp); ++ ++ *range = memranges.ranges; ++ *ranges = memranges.size; + + /* As a fallback option, we can try determining the PHYS_OFFSET + * value from the '/proc/iomem' entries as well. +@@ -982,52 +1054,15 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str, + * between the user-space and kernel space 'PHYS_OFFSET' + * value. + */ +- set_phys_offset(r->start, "iomem"); +- +- dbgprintf("%s: %016llx - %016llx : %s", __func__, r->start, +- r->end, str); +- +- return 0; +-} +- +-/** +- * get_memory_ranges_iomem - Try to get the memory ranges from +- * /proc/iomem. +- */ ++ if (memranges.size) ++ set_phys_offset(memranges.ranges[0].start, "iomem"); + +-static int get_memory_ranges_iomem(struct memory_range *array, +- unsigned int *count) +-{ +- *count = kexec_iomem_for_each_line(NULL, +- get_memory_ranges_iomem_cb, array); +- +- if (!*count) { +- dbgprintf("%s: failed: No RAM found.\n", __func__); +- return EFAILED; +- } ++ dbgprint_mem_range("System RAM ranges;", ++ memranges.ranges, memranges.size); + + return 0; + } + +-/** +- * get_memory_ranges - Try to get the memory ranges some how. +- */ +- +-int get_memory_ranges(struct memory_range **range, int *ranges, +- unsigned long kexec_flags) +-{ +- static struct memory_range array[KEXEC_SEGMENT_MAX]; +- unsigned int count; +- int result; +- +- result = get_memory_ranges_iomem(array, &count); +- +- *range = result ? NULL : array; +- *ranges = result ? 0 : count; +- +- return result; +-} +- + int arch_compat_trampoline(struct kexec_info *info) + { + return 0; +-- +2.7.4 + diff --git a/SOURCES/kexec-tools-2.0.20-kexec-add-variant-helper-functions-for-handling-memo.patch b/SOURCES/kexec-tools-2.0.20-kexec-add-variant-helper-functions-for-handling-memo.patch new file mode 100644 index 0000000..cc07c00 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.20-kexec-add-variant-helper-functions-for-handling-memo.patch @@ -0,0 +1,89 @@ +From cf977b1af9ec67fabcc6a625589c49c52d07b11d Mon Sep 17 00:00:00 2001 +From: AKASHI Takahiro +Date: Wed, 18 Dec 2019 11:42:30 -0500 +Subject: [PATCH 1/3] kexec: add variant helper functions for handling memory + regions + +mem_regions_alloc_and_add() and mem_regions_alloc_and_exclude() are +functionally equivalent to, respectively, mem_regions_add() and +mem_regions_exclude() except the formers will re-allocate memory +dynamically when no more entries are available in 'ranges' array. + +Signed-off-by: AKASHI Takahiro +Tested-by: Bhupesh Sharma +Tested-by: Masayoshi Mizuma +Signed-off-by: Simon Horman +--- + kexec/mem_regions.c | 42 ++++++++++++++++++++++++++++++++++++++++++ + kexec/mem_regions.h | 7 +++++++ + 2 files changed, 49 insertions(+) + +diff --git a/kexec/mem_regions.c b/kexec/mem_regions.c +index 50c8abccb93a..ad7d3f13fd84 100644 +--- a/kexec/mem_regions.c ++++ b/kexec/mem_regions.c +@@ -125,3 +125,45 @@ int mem_regions_exclude(struct memory_ranges *ranges, + } + return 0; + } ++ ++#define KEXEC_MEMORY_RANGES 16 ++ ++int mem_regions_alloc_and_add(struct memory_ranges *ranges, ++ unsigned long long base, ++ unsigned long long length, int type) ++{ ++ void *new_ranges; ++ ++ if (ranges->size >= ranges->max_size) { ++ new_ranges = realloc(ranges->ranges, ++ sizeof(struct memory_range) * ++ (ranges->max_size + KEXEC_MEMORY_RANGES)); ++ if (!new_ranges) ++ return -1; ++ ++ ranges->ranges = new_ranges; ++ ranges->max_size += KEXEC_MEMORY_RANGES; ++ } ++ ++ return mem_regions_add(ranges, base, length, type); ++} ++ ++int mem_regions_alloc_and_exclude(struct memory_ranges *ranges, ++ const struct memory_range *range) ++{ ++ void *new_ranges; ++ ++ /* for safety, we should have at least one free entry in ranges */ ++ if (ranges->size >= ranges->max_size) { ++ new_ranges = realloc(ranges->ranges, ++ sizeof(struct memory_range) * ++ (ranges->max_size + KEXEC_MEMORY_RANGES)); ++ if (!new_ranges) ++ return -1; ++ ++ ranges->ranges = new_ranges; ++ ranges->max_size += KEXEC_MEMORY_RANGES; ++ } ++ ++ return mem_regions_exclude(ranges, range); ++} +diff --git a/kexec/mem_regions.h b/kexec/mem_regions.h +index ae9e972b0206..e306d67e3261 100644 +--- a/kexec/mem_regions.h ++++ b/kexec/mem_regions.h +@@ -12,4 +12,11 @@ int mem_regions_exclude(struct memory_ranges *ranges, + int mem_regions_add(struct memory_ranges *ranges, unsigned long long base, + unsigned long long length, int type); + ++int mem_regions_alloc_and_exclude(struct memory_ranges *ranges, ++ const struct memory_range *range); ++ ++int mem_regions_alloc_and_add(struct memory_ranges *ranges, ++ unsigned long long base, ++ unsigned long long length, int type); ++ + #endif +-- +2.7.4 + diff --git a/SOURCES/kexec-tools-2.0.20-makedumpfile-Fix-off-by-one-issue-in-exclude_nodata_pages.patch b/SOURCES/kexec-tools-2.0.20-makedumpfile-Fix-off-by-one-issue-in-exclude_nodata_pages.patch deleted file mode 100644 index 454b3a3..0000000 --- a/SOURCES/kexec-tools-2.0.20-makedumpfile-Fix-off-by-one-issue-in-exclude_nodata_pages.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 56511628fa6714b189509b2842eadce0842bfeb5 Mon Sep 17 00:00:00 2001 -From: Mikhail Zaslonko -Date: Mon, 4 Nov 2019 14:05:15 +0100 -Subject: [PATCH] [PATCH] Fix off-by-one issue in exclude_nodata_pages() - -When building a dump bitmap (2nd bitmap) for the ELF dump, the last pfn -of the cycle is always ignored in exclude_nodata_pages() function due to -off-by-one error on cycle boundary check. Thus, the respective bit of -the bitmap is never cleared. - -That can lead to the error when such a pfn should not be dumpable (e.g. -the last pfn of the ELF-load of zero filesize). Based on the bit in the -bitmap the page is treated as dumpable in write_elf_pages_cyclic() function -and the follow on error is triggered in write_elf_load_segment() function -due to the failing sanity check of paddr_to_offset2(): - - $ makedumpfile -E dump.elf dump.elf.E - Checking for memory holes : [100.0 %] | - write_elf_load_segment: Can't convert physaddr(7ffff000) to an offset. - makedumpfile Failed. - -Signed-off-by: Mikhail Zaslonko ---- - makedumpfile.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/makedumpfile-1.6.6/makedumpfile.c b/makedumpfile-1.6.6/makedumpfile.c -index de0973f9e763..4a000112ba59 100644 ---- a/makedumpfile-1.6.6/makedumpfile.c -+++ b/makedumpfile-1.6.6/makedumpfile.c -@@ -4740,7 +4740,7 @@ exclude_nodata_pages(struct cycle *cycle) - if (pfn < cycle->start_pfn) - pfn = cycle->start_pfn; - if (pfn_end >= cycle->end_pfn) -- pfn_end = cycle->end_pfn - 1; -+ pfn_end = cycle->end_pfn; - while (pfn < pfn_end) { - clear_bit_on_2nd_bitmap(pfn, cycle); - ++pfn; --- -2.17.1 - diff --git a/SOURCES/kexec-tools-2.0.20-makedumpfile-Increase-SECTION_MAP_LAST_BIT-to-4.patch b/SOURCES/kexec-tools-2.0.20-makedumpfile-Increase-SECTION_MAP_LAST_BIT-to-4.patch deleted file mode 100644 index b9c5eff..0000000 --- a/SOURCES/kexec-tools-2.0.20-makedumpfile-Increase-SECTION_MAP_LAST_BIT-to-4.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 7bdb468c2c99dd780c9a5321f93c79cbfdce2527 Mon Sep 17 00:00:00 2001 -From: Kazuhito Hagio -Date: Tue, 23 Jul 2019 12:24:47 -0400 -Subject: [PATCH] [PATCH] Increase SECTION_MAP_LAST_BIT to 4 - -kernel commit 326e1b8f83a4 ("mm/sparsemem: introduce a SECTION_IS_EARLY -flag") added the flag to mem_section->section_mem_map value, and it caused -makedumpfile an error like the following: - - readmem: Can't convert a virtual address(fffffc97d1000000) to physical address. - readmem: type_addr: 0, addr:fffffc97d1000000, size:32768 - __exclude_unnecessary_pages: Can't read the buffer of struct page. - create_2nd_bitmap: Can't exclude unnecessary pages. - -To fix this, SECTION_MAP_LAST_BIT needs to be updated. The bit has not -been used until the addition, so we can just increase the value. - -Signed-off-by: Kazuhito Hagio ---- - makedumpfile.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/makedumpfile-1.6.6/makedumpfile.h b/makedumpfile-1.6.6/makedumpfile.h -index 24b2f69f400c..df745b9f53e5 100644 ---- a/makedumpfile-1.6.6/makedumpfile.h -+++ b/makedumpfile-1.6.6/makedumpfile.h -@@ -195,7 +195,7 @@ isAnon(unsigned long mapping) - * 2. it has been verified that (1UL<<2) was never set, so it is - * safe to mask that bit off even in old kernels. - */ --#define SECTION_MAP_LAST_BIT (1UL<<3) -+#define SECTION_MAP_LAST_BIT (1UL<<4) - #define SECTION_MAP_MASK (~(SECTION_MAP_LAST_BIT-1)) - #define NR_SECTION_ROOTS() divideup(num_section, SECTIONS_PER_ROOT()) - #define SECTION_NR_TO_PFN(sec) ((sec) << PFN_SECTION_SHIFT()) --- -2.17.2 - diff --git a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Align-PMD_SECTION_MASK-with-PHYS_MASK.patch b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Align-PMD_SECTION_MASK-with-PHYS_MASK.patch new file mode 100644 index 0000000..e165b7d --- /dev/null +++ b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Align-PMD_SECTION_MASK-with-PHYS_MASK.patch @@ -0,0 +1,36 @@ +From 7242ae4cb5288df626f464ced0a8b60fd669100b Mon Sep 17 00:00:00 2001 +From: Michal Suchanek +Date: Mon, 16 Mar 2020 19:39:58 +0100 +Subject: [PATCH 6/7] [PATCH] Align PMD_SECTION_MASK with PHYS_MASK + +Reportedly on some arm64 systems makedumpfile loops forever exhausting +all memory when filtering kernel core. It turns out the reason is it +cannot resolve some addresses because the PMD mask is wrong. When +physical address mask allows up to 48bits pmd mask should allow the +same. +I suppose you would need a system that needs physical addresses over 1TB +to be able to reproduce this. This may be either because you have a lot +of memory or because the firmware mapped some memory above 1TB for some +reason. + +Signed-off-by: Michal Suchanek +--- + arch/arm64.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/makedumpfile-1.6.7/arch/arm64.c b/makedumpfile-1.6.7/arch/arm64.c +index 43164cc..54d60b4 100644 +--- a/makedumpfile-1.6.7/arch/arm64.c ++++ b/makedumpfile-1.6.7/arch/arm64.c +@@ -81,7 +81,7 @@ static unsigned long kimage_voffset; + * Remove the highest order bits that are not a part of the + * physical address in a section + */ +-#define PMD_SECTION_MASK ((1UL << 40) - 1) ++#define PMD_SECTION_MASK ((1UL << PHYS_MASK_SHIFT) - 1) + + #define PMD_TYPE_MASK 3 + #define PMD_TYPE_SECT 1 +-- +2.7.5 + diff --git a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Avoid-false-positive-failure-in-mem_seciton-va.patch b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Avoid-false-positive-failure-in-mem_seciton-va.patch new file mode 100644 index 0000000..1033494 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Avoid-false-positive-failure-in-mem_seciton-va.patch @@ -0,0 +1,80 @@ +From 81b79c514ff6fc881f1df4cb04ecb2d7cb22badc Mon Sep 17 00:00:00 2001 +From: Kazuhito Hagio +Date: Wed, 19 Feb 2020 12:48:13 -0500 +Subject: [PATCH] [PATCH] Avoid false-positive failure in mem_seciton + validation + +Currently in get_mem_section(), we check whether SYMBOL(mem_section) +is a pointer to the array or a pointer to the pointer to the array +for some cases. + +However, with commit e113f1c974c8 ("[PATCH] cope with not-present +mem section") relaxing the check, there was a report that the function +failed because both of two validate_mem_section() calls return TRUE. + +Avoid the false-positive failure by not calling the second one if the +first one returns TRUE. + +Reported-by: Pingfan Liu +Acked-by: Thadeu Lima de Souza Cascardo +Signed-off-by: Kazuhito Hagio +--- + makedumpfile.c | 29 ++++++----------------------- + 1 file changed, 6 insertions(+), 23 deletions(-) + +diff --git a/makedumpfile-1.6.7/makedumpfile.c b/makedumpfile-1.6.7/makedumpfile.c +index f5860a1..4c4251e 100644 +--- a/makedumpfile-1.6.7/makedumpfile.c ++++ b/makedumpfile-1.6.7/makedumpfile.c +@@ -3472,7 +3472,6 @@ static int + get_mem_section(unsigned int mem_section_size, unsigned long *mem_maps, + unsigned int num_section) + { +- unsigned long mem_section_ptr; + int ret = FALSE; + unsigned long *mem_sec = NULL; + +@@ -3484,34 +3483,18 @@ get_mem_section(unsigned int mem_section_size, unsigned long *mem_maps, + ret = validate_mem_section(mem_sec, SYMBOL(mem_section), + mem_section_size, mem_maps, num_section); + +- if (is_sparsemem_extreme()) { +- int symbol_valid = ret; +- int pointer_valid; +- int mem_maps_size = sizeof(*mem_maps) * num_section; +- unsigned long *mem_maps_ex = NULL; ++ if (!ret && is_sparsemem_extreme()) { ++ unsigned long mem_section_ptr; ++ + if (!readmem(VADDR, SYMBOL(mem_section), &mem_section_ptr, + sizeof(mem_section_ptr))) + goto out; + +- if ((mem_maps_ex = malloc(mem_maps_size)) == NULL) { +- ERRMSG("Can't allocate memory for the mem_maps. %s\n", +- strerror(errno)); +- goto out; +- } ++ ret = validate_mem_section(mem_sec, mem_section_ptr, ++ mem_section_size, mem_maps, num_section); + +- pointer_valid = validate_mem_section(mem_sec, +- mem_section_ptr, +- mem_section_size, +- mem_maps_ex, +- num_section); +- if (pointer_valid) +- memcpy(mem_maps, mem_maps_ex, mem_maps_size); +- if (mem_maps_ex) +- free(mem_maps_ex); +- ret = symbol_valid ^ pointer_valid; +- if (!ret) { ++ if (!ret) + ERRMSG("Could not validate mem_section.\n"); +- } + } + out: + if (mem_sec != NULL) +-- +2.7.5 + diff --git a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Fix-cd_header-offset-overflow-with-large-pfn.patch b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Fix-cd_header-offset-overflow-with-large-pfn.patch new file mode 100644 index 0000000..85b5048 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Fix-cd_header-offset-overflow-with-large-pfn.patch @@ -0,0 +1,42 @@ +From 6e4b2dfaed5e5e5c617e0e45f969c1f571c13e27 Mon Sep 17 00:00:00 2001 +From: Jialong Chen +Date: Mon, 23 Mar 2020 16:42:01 -0400 +Subject: [PATCH 7/7] [PATCH] Fix cd_header offset overflow with large pfn + +In function write_kdump_pages_and_bitmap_cyclic(), cd_header->offset is +calculated by the following formula: + + cd_header->offset + = (DISKDUMP_HEADER_BLOCKS + dh->sub_hdr_size + dh->bitmap_blocks) + * dh->block_size; + +However, the variables of the right side are only int and unsigned int, +so if dh->bitmap_blocks is very large, it causes an interger overflow. + +As a result, makedumpfile created a broken vmcore in a system with a +physical address range from 0x602770ecf000 to 0x6027ffffffff, and the +crash utility failed during session initialization, ending with the +error message "crash: vmlinux and vmcore do not match!". + +Signed-off-by: Jialong Chen +Signed-off-by: Kazuhito Hagio +--- + diskdump_mod.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/makedumpfile-1.6.7/diskdump_mod.h b/makedumpfile-1.6.7/diskdump_mod.h +index 2676817..3733953 100644 +--- a/makedumpfile-1.6.7/diskdump_mod.h ++++ b/makedumpfile-1.6.7/diskdump_mod.h +@@ -22,7 +22,7 @@ + #define DISK_DUMP_SIGNATURE "DISKDUMP" + #define KDUMP_SIGNATURE "KDUMP " + #define SIG_LEN (sizeof(DUMP_PARTITION_SIGNATURE) - 1) +-#define DISKDUMP_HEADER_BLOCKS (1) ++#define DISKDUMP_HEADER_BLOCKS (1UL) + + /* + * These are all remnants of the old "diskdump" facility, +-- +2.7.5 + diff --git a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Introduce-check-params-option.patch b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Introduce-check-params-option.patch new file mode 100644 index 0000000..b83d083 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Introduce-check-params-option.patch @@ -0,0 +1,255 @@ +From 989152e113bfcb4fbfbad6f3aed6f43be4455919 Mon Sep 17 00:00:00 2001 +From: Kazuhito Hagio +Date: Tue, 25 Feb 2020 16:04:55 -0500 +Subject: [PATCH 4/7] [PATCH] Introduce --check-params option + +Currently it's difficult to check whether a makedumpfile command-line +is valid or not without an actual panic. This is inefficient and if +a wrong configuration is not tested, you will miss the vmcore when an +actual panic occurs. + +In order for kdump facilities like kexec-tools to be able to check +the specified command-line parameters in advance, introduce the +--check-params option that only checks them and exits immediately. + +Signed-off-by: Kazuhito Hagio +--- + makedumpfile.8 | 5 ++++ + makedumpfile.c | 75 +++++++++++++++++++++++++++++++++++++++++++++------------- + makedumpfile.h | 2 ++ + print_info.c | 4 ++++ + 4 files changed, 69 insertions(+), 17 deletions(-) + +diff --git a/makedumpfile-1.6.7/makedumpfile.8 b/makedumpfile-1.6.7/makedumpfile.8 +index bf156a8..c5d4806 100644 +--- a/makedumpfile-1.6.7/makedumpfile.8 ++++ b/makedumpfile-1.6.7/makedumpfile.8 +@@ -632,6 +632,11 @@ Show help message and LZO/snappy support status (enabled/disabled). + \fB\-v\fR + Show the version of makedumpfile. + ++.TP ++\fB\-\-check-params\fR ++Only check whether the command-line parameters are valid or not, and exit. ++Preferable to be given as the first parameter. ++ + .SH ENVIRONMENT VARIABLES + + .TP 8 +diff --git a/makedumpfile-1.6.7/makedumpfile.c b/makedumpfile-1.6.7/makedumpfile.c +index 607e07f..f5860a1 100644 +--- a/makedumpfile-1.6.7/makedumpfile.c ++++ b/makedumpfile-1.6.7/makedumpfile.c +@@ -10972,12 +10972,6 @@ check_param_for_creating_dumpfile(int argc, char *argv[]) + if (info->flag_generate_vmcoreinfo || info->flag_rearrange) + return FALSE; + +- if ((message_level < MIN_MSG_LEVEL) +- || (MAX_MSG_LEVEL < message_level)) { +- message_level = DEFAULT_MSG_LEVEL; +- MSG("Message_level is invalid.\n"); +- return FALSE; +- } + if ((info->flag_compress && info->flag_elf_dumpfile) + || (info->flag_read_vmcoreinfo && info->name_vmlinux) + || (info->flag_read_vmcoreinfo && info->name_xen_syms)) +@@ -11007,6 +11001,11 @@ check_param_for_creating_dumpfile(int argc, char *argv[]) + if (info->flag_partial_dmesg && !info->flag_dmesg) + return FALSE; + ++ if (info->flag_excludevm && !info->working_dir) { ++ MSG("-%c requires --work-dir\n", OPT_EXCLUDE_UNUSED_VM); ++ return FALSE; ++ } ++ + if ((argc == optind + 2) && !info->flag_flatten + && !info->flag_split + && !info->flag_sadump_diskset) { +@@ -11402,6 +11401,23 @@ int show_mem_usage(void) + return TRUE; + } + ++static int set_message_level(char *str_ml) ++{ ++ int ml; ++ ++ ml = atoi(str_ml); ++ if ((ml < MIN_MSG_LEVEL) || (MAX_MSG_LEVEL < ml)) { ++ message_level = DEFAULT_MSG_LEVEL; ++ MSG("Message_level(%d) is invalid.\n", ml); ++ return FALSE; ++ } ++ ++ if (info->flag_check_params) ++ return TRUE; ++ ++ message_level = ml; ++ return TRUE; ++} + + static struct option longopts[] = { + {"split", no_argument, NULL, OPT_SPLIT}, +@@ -11423,6 +11439,7 @@ static struct option longopts[] = { + {"splitblock-size", required_argument, NULL, OPT_SPLITBLOCK_SIZE}, + {"work-dir", required_argument, NULL, OPT_WORKING_DIR}, + {"num-threads", required_argument, NULL, OPT_NUM_THREADS}, ++ {"check-params", no_argument, NULL, OPT_CHECK_PARAMS}, + {0, 0, 0, 0} + }; + +@@ -11521,7 +11538,8 @@ main(int argc, char *argv[]) + info->flag_compress = DUMP_DH_COMPRESSED_LZO; + break; + case OPT_MESSAGE_LEVEL: +- message_level = atoi(optarg); ++ if (!set_message_level(optarg)) ++ goto out; + break; + case OPT_DUMP_DMESG: + info->flag_dmesg = 1; +@@ -11584,6 +11602,10 @@ main(int argc, char *argv[]) + case OPT_NUM_THREADS: + info->num_threads = MAX(atoi(optarg), 0); + break; ++ case OPT_CHECK_PARAMS: ++ info->flag_check_params = TRUE; ++ message_level = DEFAULT_MSG_LEVEL; ++ break; + case '?': + MSG("Commandline parameter is invalid.\n"); + MSG("Try `makedumpfile --help' for more information.\n"); +@@ -11593,11 +11615,9 @@ main(int argc, char *argv[]) + if (flag_debug) + message_level |= ML_PRINT_DEBUG_MSG; + +- if (info->flag_excludevm && !info->working_dir) { +- ERRMSG("Error: -%c requires --work-dir\n", OPT_EXCLUDE_UNUSED_VM); +- ERRMSG("Try `makedumpfile --help' for more information\n"); +- return COMPLETED; +- } ++ if (info->flag_check_params) ++ /* suppress debugging messages */ ++ message_level = DEFAULT_MSG_LEVEL; + + if (info->flag_show_usage) { + print_usage(); +@@ -11628,6 +11648,9 @@ main(int argc, char *argv[]) + MSG("Try `makedumpfile --help' for more information.\n"); + goto out; + } ++ if (info->flag_check_params) ++ goto check_ok; ++ + if (!open_files_for_generating_vmcoreinfo()) + goto out; + +@@ -11651,6 +11674,9 @@ main(int argc, char *argv[]) + MSG("Try `makedumpfile --help' for more information.\n"); + goto out; + } ++ if (info->flag_check_params) ++ goto check_ok; ++ + if (!check_dump_file(info->name_dumpfile)) + goto out; + +@@ -11671,6 +11697,9 @@ main(int argc, char *argv[]) + MSG("Try `makedumpfile --help' for more information.\n"); + goto out; + } ++ if (info->flag_check_params) ++ goto check_ok; ++ + if (!check_dump_file(info->name_dumpfile)) + goto out; + +@@ -11684,6 +11713,9 @@ main(int argc, char *argv[]) + MSG("Try `makedumpfile --help' for more information.\n"); + goto out; + } ++ if (info->flag_check_params) ++ goto check_ok; ++ + if (!check_dump_file(info->name_dumpfile)) + goto out; + if (!dump_dmesg()) +@@ -11697,6 +11729,9 @@ main(int argc, char *argv[]) + MSG("Try `makedumpfile --help' for more information.\n"); + goto out; + } ++ if (info->flag_check_params) ++ goto check_ok; ++ + if (!populate_kernel_version()) + goto out; + +@@ -11715,6 +11750,9 @@ main(int argc, char *argv[]) + MSG("Try `makedumpfile --help' for more information.\n"); + goto out; + } ++ if (info->flag_check_params) ++ goto check_ok; ++ + if (info->flag_split) { + for (i = 0; i < info->num_dumpfile; i++) { + SPLITTING_FD_BITMAP(i) = -1; +@@ -11742,13 +11780,16 @@ main(int argc, char *argv[]) + MSG("The dumpfile is saved to %s.\n", info->name_dumpfile); + } + } ++check_ok: + retcd = COMPLETED; + out: +- MSG("\n"); +- if (retcd != COMPLETED) +- MSG("makedumpfile Failed.\n"); +- else if (!info->flag_mem_usage) +- MSG("makedumpfile Completed.\n"); ++ if (!info->flag_check_params) { ++ MSG("\n"); ++ if (retcd != COMPLETED) ++ MSG("makedumpfile Failed.\n"); ++ else if (!info->flag_mem_usage) ++ MSG("makedumpfile Completed.\n"); ++ } + + free_for_parallel(); + +diff --git a/makedumpfile-1.6.7/makedumpfile.h b/makedumpfile-1.6.7/makedumpfile.h +index 7217407..03fb4ce 100644 +--- a/makedumpfile-1.6.7/makedumpfile.h ++++ b/makedumpfile-1.6.7/makedumpfile.h +@@ -1301,6 +1301,7 @@ struct DumpInfo { + int flag_read_vmcoreinfo; /* flag of reading vmcoreinfo file */ + int flag_show_usage; /* flag of showing usage */ + int flag_show_version; /* flag of showing version */ ++ int flag_check_params; /* only check parameters */ + int flag_flatten; /* flag of outputting flattened + format to a standard out */ + int flag_rearrange; /* flag of creating dumpfile from +@@ -2362,6 +2363,7 @@ struct elf_prstatus { + #define OPT_WORKING_DIR OPT_START+15 + #define OPT_NUM_THREADS OPT_START+16 + #define OPT_PARTIAL_DMESG OPT_START+17 ++#define OPT_CHECK_PARAMS OPT_START+18 + + /* + * Function Prototype. +diff --git a/makedumpfile-1.6.7/print_info.c b/makedumpfile-1.6.7/print_info.c +index 0be12ea..e0c38b4 100644 +--- a/makedumpfile-1.6.7/print_info.c ++++ b/makedumpfile-1.6.7/print_info.c +@@ -321,6 +321,10 @@ print_usage(void) + MSG(" [-v]:\n"); + MSG(" Show the version of makedumpfile.\n"); + MSG("\n"); ++ MSG(" [--check-params]:\n"); ++ MSG(" Only check whether the command-line parameters are valid or not, and exit.\n"); ++ MSG(" Preferable to be given as the first parameter.\n"); ++ MSG("\n"); + MSG(" VMLINUX:\n"); + MSG(" This is a pathname to the first kernel's vmlinux.\n"); + MSG(" This file must have the debug information of the first kernel to analyze\n"); +-- +2.7.5 + diff --git a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Makefile-Fix-build-errors-in-static-build.patch b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Makefile-Fix-build-errors-in-static-build.patch new file mode 100644 index 0000000..f2f2153 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Makefile-Fix-build-errors-in-static-build.patch @@ -0,0 +1,65 @@ +From 12250baa02584dc713cdb1a12fb366f643fdc8b3 Mon Sep 17 00:00:00 2001 +From: Kazuhito Hagio +Date: Mon, 9 Mar 2020 17:17:31 -0400 +Subject: [PATCH 5/7] [PATCH] Makefile: Fix build errors in static build + +When building makedumpfile statically (without LINKTYPE=dynamic), +the following error is observed: + + /usr/bin/ld: /usr/lib/makedumpfile-1.6.7/gcc/x86_64-redhat-linux/9/../../../../lib64/libdw.a(lzma.o): in function `__libdw_unlzma': + (.text+0xbd): undefined reference to `lzma_auto_decoder' + /usr/bin/ld: (.text+0x23a): undefined reference to `lzma_code' + /usr/bin/ld: (.text+0x269): undefined reference to `lzma_end' + /usr/bin/ld: (.text+0x2aa): undefined reference to `lzma_end' + /usr/bin/ld: (.text+0x3ac): undefined reference to `lzma_end' + /usr/bin/ld: (.text+0x427): undefined reference to `lzma_end' + /usr/bin/ld: (.text+0x62b): undefined reference to `lzma_end' + collect2: error: ld returned 1 exit status + make: *** [Makefile:97: makedumpfile] Error 1 + +Also, when doing it with USESNAPPY=on: + + /usr/bin/ld: /usr/local/lib64/libsnappy.a(snappy.cc.o): in function `snappy::internal::WorkingMemory::WorkingMemory(unsigned long)': + snappy.cc:(.text+0x7d4): undefined reference to `std::allocator::allocator()' + /usr/bin/ld: snappy.cc:(.text+0x803): undefined reference to `std::allocator::~allocator()' + /usr/bin/ld: snappy.cc:(.text+0x853): undefined reference to `std::allocator::~allocator()' + /usr/bin/ld: /usr/local/lib64/libsnappy.a(snappy.cc.o): in function `snappy::internal::WorkingMemory::~WorkingMemory()': + snappy.cc:(.text+0x87e): undefined reference to `std::allocator::allocator()' + /usr/bin/ld: snappy.cc:(.text+0x8a8): undefined reference to `std::allocator::~allocator()' + ... + +Fix these errors by adding -llzma and -lstd++ to LIBS respectively +if LINKTYPE=dynamic is not specified. + +Reported-by: Prabhakar Kushwaha +Signed-off-by: Kazuhito Hagio +--- + Makefile | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/makedumpfile-1.6.7/Makefile b/makedumpfile-1.6.7/Makefile +index 868eea6..ef20672 100644 +--- a/makedumpfile-1.6.7/Makefile ++++ b/makedumpfile-1.6.7/Makefile +@@ -52,7 +52,7 @@ OBJ_ARCH=$(patsubst %.c,%.o,$(SRC_ARCH)) + + LIBS = -ldw -lbz2 -ldl -lelf -lz + ifneq ($(LINKTYPE), dynamic) +-LIBS := -static $(LIBS) ++LIBS := -static $(LIBS) -llzma + endif + + ifeq ($(USELZO), on) +@@ -62,6 +62,9 @@ endif + + ifeq ($(USESNAPPY), on) + LIBS := -lsnappy $(LIBS) ++ifneq ($(LINKTYPE), dynamic) ++LIBS := $(LIBS) -lstdc++ ++endif + CFLAGS += -DUSESNAPPY + endif + +-- +2.7.5 + diff --git a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Remove-duplicated-variable-definitions.patch b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Remove-duplicated-variable-definitions.patch new file mode 100644 index 0000000..691cd05 --- /dev/null +++ b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-Remove-duplicated-variable-definitions.patch @@ -0,0 +1,103 @@ +From 399f2c9a3acd5bd913e50a4dde52dee6527b297e Mon Sep 17 00:00:00 2001 +From: Kairui Song +Date: Wed, 29 Jan 2020 13:37:13 +0800 +Subject: [PATCH 2/7] [PATCH] Remove duplicated variable definitions + +When building on Fedora 32 (with GCC 10), following error is observed: + +/usr/bin/ld: erase_info.o:/tmp/makedumpfile/makedumpfile.h:2010: multiple definition of + `crash_reserved_mem_nr'; elf_info.o:/tmp/makedumpfile/makedumpfile.h:2010: first defined here +/usr/bin/ld: erase_info.o:/tmp/makedumpfile/makedumpfile.h:2009: multiple definition of + `crash_reserved_mem'; elf_info.o:/tmp/makedumpfile/makedumpfile.h:2009: first defined here +/usr/bin/ld: erase_info.o:/tmp/makedumpfile/makedumpfile.h:1278: multiple definition of + `parallel_info_t'; elf_info.o:/tmp/makedumpfile/makedumpfile.h:1278: first defined here +/usr/bin/ld: erase_info.o:/tmp/makedumpfile/makedumpfile.h:1265: multiple definition of + `splitting_info_t'; elf_info.o:/tmp/makedumpfile/makedumpfile.h:1265: first defined here +... +collect2: error: ld returned 1 exit status +make: *** [Makefile:97: makedumpfile] Error 1 + +These variables are wrongly defined multiple times. So remove the +duplicated definitions. + +Signed-off-by: Kairui Song +Signed-off-by: Kazuhito Hagio +--- + makedumpfile.c | 8 ++++---- + makedumpfile.h | 8 ++++---- + 2 files changed, 8 insertions(+), 8 deletions(-) + +diff --git a/makedumpfile-1.6.7/makedumpfile.c b/makedumpfile-1.6.7/makedumpfile.c +index e290fbd..ae7336a 100644 +--- a/makedumpfile-1.6.7/makedumpfile.c ++++ b/makedumpfile-1.6.7/makedumpfile.c +@@ -10954,7 +10954,7 @@ check_param_for_reassembling_dumpfile(int argc, char *argv[]) + return FALSE; + + if ((info->splitting_info +- = malloc(sizeof(splitting_info_t) * info->num_dumpfile)) ++ = malloc(sizeof(struct splitting_info) * info->num_dumpfile)) + == NULL) { + MSG("Can't allocate memory for splitting_info.\n"); + return FALSE; +@@ -11042,7 +11042,7 @@ check_param_for_creating_dumpfile(int argc, char *argv[]) + return FALSE; + } + if ((info->splitting_info +- = malloc(sizeof(splitting_info_t) * info->num_dumpfile)) ++ = malloc(sizeof(struct splitting_info) * info->num_dumpfile)) + == NULL) { + MSG("Can't allocate memory for splitting_info.\n"); + return FALSE; +@@ -11077,13 +11077,13 @@ check_param_for_creating_dumpfile(int argc, char *argv[]) + + if (info->num_threads) { + if ((info->parallel_info = +- malloc(sizeof(parallel_info_t) * info->num_threads)) ++ malloc(sizeof(struct parallel_info) * info->num_threads)) + == NULL) { + MSG("Can't allocate memory for parallel_info.\n"); + return FALSE; + } + +- memset(info->parallel_info, 0, sizeof(parallel_info_t) ++ memset(info->parallel_info, 0, sizeof(struct parallel_info) + * info->num_threads); + } + +diff --git a/makedumpfile-1.6.7/makedumpfile.h b/makedumpfile-1.6.7/makedumpfile.h +index 68d9691..7217407 100644 +--- a/makedumpfile-1.6.7/makedumpfile.h ++++ b/makedumpfile-1.6.7/makedumpfile.h +@@ -1262,7 +1262,7 @@ struct splitting_info { + mdf_pfn_t end_pfn; + off_t offset_eraseinfo; + unsigned long size_eraseinfo; +-} splitting_info_t; ++}; + + struct parallel_info { + int fd_memory; +@@ -1275,7 +1275,7 @@ struct parallel_info { + #ifdef USELZO + lzo_bytep wrkmem; + #endif +-} parallel_info_t; ++}; + + struct ppc64_vmemmap { + unsigned long phys; +@@ -2006,8 +2006,8 @@ struct memory_range { + }; + + #define CRASH_RESERVED_MEM_NR 8 +-struct memory_range crash_reserved_mem[CRASH_RESERVED_MEM_NR]; +-int crash_reserved_mem_nr; ++extern struct memory_range crash_reserved_mem[CRASH_RESERVED_MEM_NR]; ++extern int crash_reserved_mem_nr; + + unsigned long read_vmcoreinfo_symbol(char *str_symbol); + int readmem(int type_addr, unsigned long long addr, void *bufptr, size_t size); +-- +2.7.5 + diff --git a/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-cope-with-not-present-mem-section.patch b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-cope-with-not-present-mem-section.patch new file mode 100644 index 0000000..2e9832c --- /dev/null +++ b/SOURCES/kexec-tools-2.0.20-makedumpfile-PATCH-cope-with-not-present-mem-section.patch @@ -0,0 +1,65 @@ +From e113f1c974c820f9633dc0073eda525d7575f365 Mon Sep 17 00:00:00 2001 +From: Pingfan Liu +Date: Mon, 20 Jan 2020 10:25:24 +0800 +Subject: [PATCH 3/7] [PATCH] cope with not-present mem section + +After kernel commit ba72b4c8cf60 ("mm/sparsemem: support sub-section +hotplug"), when hot-removed, section_mem_map is still encoded with section +start pfn, not NULL. This break the current makedumpfile. + + # makedumpfile -x vmlinux -l -d 31 vmcore vmcore.dump + get_mem_section: Could not validate mem_section. + get_mm_sparsemem: Can't get the address of mem_section. + + makedumpfile Failed. + +Whatever section_mem_map coding info after hot-removed, it is reliable +just to work on SECTION_MARKED_PRESENT bit. Fixing makedumpfile by this +way. + +[ This issue occurs on kernel 5.3 through 5.5, and should be fixed by +commit 1f503443e7df ("mm/sparse.c: reset section's mem_map when fully +deactivated") in 5.6-rc1, 5.5.3 and 5.4.19. ] + +Signed-off-by: Pingfan Liu +To: kexec@lists.infradead.org +Cc: Kazuhito Hagio +Cc: Baoquan He +Cc: David Hildenbrand +Cc: Andrew Morton +Cc: Dan Williams +Cc: Oscar Salvador +Cc: Michal Hocko +Cc: Qian Cai +--- + makedumpfile.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +diff --git a/makedumpfile-1.6.7/makedumpfile.c b/makedumpfile-1.6.7/makedumpfile.c +index ae7336a..607e07f 100644 +--- a/makedumpfile-1.6.7/makedumpfile.c ++++ b/makedumpfile-1.6.7/makedumpfile.c +@@ -3406,8 +3406,6 @@ section_mem_map_addr(unsigned long addr, unsigned long *map_mask) + map = ULONG(mem_section + OFFSET(mem_section.section_mem_map)); + mask = SECTION_MAP_MASK; + *map_mask = map & ~mask; +- if (map == 0x0) +- *map_mask |= SECTION_MARKED_PRESENT; + map &= mask; + free(mem_section); + +@@ -3453,10 +3451,8 @@ validate_mem_section(unsigned long *mem_sec, + mem_map = NOT_MEMMAP_ADDR; + } else { + mem_map = section_mem_map_addr(section, &map_mask); ++ /* for either no mem_map or hot-removed */ + if (!(map_mask & SECTION_MARKED_PRESENT)) { +- return FALSE; +- } +- if (mem_map == 0) { + mem_map = NOT_MEMMAP_ADDR; + } else { + mem_map = sparse_decode_mem_map(mem_map, +-- +2.7.5 + diff --git a/SOURCES/kexec-tools-2.0.20-makedumpfile-assign-bitmap1-2-fd-for-subprocess-in-non-cycl.patch b/SOURCES/kexec-tools-2.0.20-makedumpfile-assign-bitmap1-2-fd-for-subprocess-in-non-cycl.patch deleted file mode 100644 index 7f347cc..0000000 --- a/SOURCES/kexec-tools-2.0.20-makedumpfile-assign-bitmap1-2-fd-for-subprocess-in-non-cycl.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 5519b3eba68544dc484d85e9540d440d93f8c924 Mon Sep 17 00:00:00 2001 -From: Pingfan Liu -Date: Tue, 3 Dec 2019 15:37:07 +0800 -Subject: [PATCH] [PATCH] assign bitmap1/2 fd for subprocess in non-cyclic mode - -In non-cyclic mode with the --split option, each subprocess inherits -bitmap1/2->fd from parent. Then they lseek()/read() on the same fd, -which means that they interfere with each other. - -This breaks the purpose of SPLITTING_FD_BITMAP(i) for each subprocess. -Without this patch, makedumpfile can fail with error like the following -in refiltering, or can break the dumpfile silently by excluding pages -wrongly. - - readpage_kdump_compressed: pfn(2fc1000) is excluded from vmcore. - readmem: type_addr: 1, addr:2fc1000000, size:4096 - read_pfn: Can't get the page data. - -Fix it by assigning a subprocess dedicated fd to bitmap1/2->fd. - -Signed-off-by: Pingfan Liu -Signed-off-by: Kazuhito Hagio ---- - makedumpfile.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/makedumpfile-1.6.6/makedumpfile.c b/makedumpfile-1.6.6/makedumpfile.c -index 43107d9..7586d7c 100644 ---- a/makedumpfile-1.6.6/makedumpfile.c -+++ b/makedumpfile-1.6.6/makedumpfile.c -@@ -10091,6 +10091,10 @@ writeout_multiple_dumpfiles(void) - info->split_start_pfn = SPLITTING_START_PFN(i); - info->split_end_pfn = SPLITTING_END_PFN(i); - -+ if (!info->flag_cyclic) { -+ info->bitmap1->fd = info->fd_bitmap; -+ info->bitmap2->fd = info->fd_bitmap; -+ } - if (!reopen_dump_memory()) - exit(1); - if ((status = writeout_dumpfile()) == FALSE) --- -2.7.5 - diff --git a/SOURCES/kexec-tools-2.0.20-makedumpfile-x86_64-Fix-incorrect-exclusion-by-e-option-wit.patch b/SOURCES/kexec-tools-2.0.20-makedumpfile-x86_64-Fix-incorrect-exclusion-by-e-option-wit.patch deleted file mode 100644 index 343c83d..0000000 --- a/SOURCES/kexec-tools-2.0.20-makedumpfile-x86_64-Fix-incorrect-exclusion-by-e-option-wit.patch +++ /dev/null @@ -1,41 +0,0 @@ -From aa5ab4cf6c7335392094577380d2eaee8a0a8d52 Mon Sep 17 00:00:00 2001 -From: Kazuhito Hagio -Date: Thu, 29 Aug 2019 12:26:34 -0400 -Subject: [PATCH] x86_64: Fix incorrect exclusion by -e option with KASLR - -The -e option uses info->vmemmap_start for creating a table to determine -the positions of page structures that should be excluded, but it is a -hardcoded value even with KASLR-enabled vmcore. As a result, the option -excludes incorrect pages from it. - -To fix this, get the vmemmap start address from info->mem_map_data. - -Signed-off-by: Kazuhito Hagio ---- - arch/x86_64.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/makedumpfile-1.6.6/arch/x86_64.c b/makedumpfile-1.6.6/arch/x86_64.c -index 3c0fdc5e72fb..4eeaf4925f43 100644 ---- a/makedumpfile-1.6.6/arch/x86_64.c -+++ b/makedumpfile-1.6.6/arch/x86_64.c -@@ -679,6 +679,16 @@ find_vmemmap_x86_64() - if (NUMBER(sme_mask) != NOT_FOUND_NUMBER) - pmask &= ~(NUMBER(sme_mask)); - -+ /* -+ * vmemmap region can be randomized by KASLR. -+ * (currently we don't utilize info->vmemmap_end on x86_64.) -+ */ -+ if (info->mem_map_data && -+ info->mem_map_data[0].mem_map != NOT_MEMMAP_ADDR) -+ info->vmemmap_start = info->mem_map_data[0].mem_map; -+ -+ DEBUG_MSG("vmemmap_start: %16lx\n", info->vmemmap_start); -+ - pagestructsize = size_table.page; - hugepagesize = PTRS_PER_PMD * info->page_size; - vaddr_base = info->vmemmap_start; --- -2.18.1 - diff --git a/SOURCES/mkdumprd b/SOURCES/mkdumprd index cd1b592..8b09710 100644 --- a/SOURCES/mkdumprd +++ b/SOURCES/mkdumprd @@ -13,10 +13,25 @@ export IN_KDUMP=1 conf_file="/etc/kdump.conf" SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa" -SAVE_PATH=$(awk '/^path/ {print $2}' $conf_file) -[ -z "$SAVE_PATH" ] && SAVE_PATH=$DEFAULT_PATH -# strip the duplicated "/" -SAVE_PATH=$(echo $SAVE_PATH | tr -s /) +SAVE_PATH=$(get_save_path) +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 @@ -32,109 +47,54 @@ is_wdt_addition_needed() { return 1 } -WDTCFG="" -is_wdt_addition_needed -[[ $? -eq 0 ]] && WDTCFG="-a watchdog" - -extra_modules="" -dracut_args=("--quiet" "--hostonly" "--hostonly-cmdline" "--hostonly-i18n" "--hostonly-mode" "strict" "-o" "plymouth dash resume ifcfg earlykdump" $WDTCFG) -OVERRIDE_RESETTABLE=0 - add_dracut_arg() { - local arg qarg is_quoted=0 - while [ $# -gt 0 ]; - do - arg="${1//\'/\"}" - #Handle quoted substring properly for passing it to dracut_args array. - if [ $is_quoted -eq 0 ]; then - if [[ "$arg" == "\"" ]] || [[ $arg != ${arg#\"} ]]; then - is_quoted=1 - arg=${arg#\"} - fi - fi - if [ $is_quoted -eq 1 ]; then - qarg="$qarg $arg" - if [[ "$arg" == "\"" ]] || [[ $arg != ${arg%\"} ]]; then - is_quoted=0 - arg=${qarg%\"} - qarg="" - else - shift - continue - fi - fi - dracut_args+=("$arg") - shift - done + dracut_args="$dracut_args $@" } add_dracut_module() { - add_dracut_arg "--add" "$1" + add_dracut_arg "--add" "\"$1\"" } add_dracut_mount() { - add_dracut_arg "--mount" "$1" + add_dracut_arg "--mount" "\"$1\"" } add_dracut_sshkey() { - add_dracut_arg "--sshkey" "$1" + add_dracut_arg "--sshkey" "\"$1\"" } # caller should ensure $1 is valid and mounted in 1st kernel to_mount() { - local _dev=$1 _source _target _fstype _options _mntopts _pdev - - _source=$(findmnt -k -f -n -r -o SOURCE $_dev) - _target=$(get_mntpoint_from_target $_dev) - # mount under /sysroot if dump to root disk or mount under - #/kdumproot/$_target in other cases in 2nd kernel. systemd - #will be in charge to umount it. - - if [ "$_target" = "/" ];then - _target="/sysroot" + local _target=$1 _fstype=$2 _options=$3 _new_mntpoint _pdev + + _new_mntpoint=$(get_kdump_mntpoint_from_target $_target) + _fstype="${_fstype:-$(get_fs_type_from_target $_target)}" + _options="${_options:-$(get_mntopt_from_target $_target)}" + _options="${_options:-defaults}" + + if [[ "$_fstype" == "nfs"* ]]; then + _pdev=$_target + _options=$(echo $_options | sed 's/,addr=[^,]*//') + _options=$(echo $_options | sed 's/,proto=[^,]*//') + _options=$(echo $_options | sed 's/,clientaddr=[^,]*//') else - _target="/kdumproot/$_target" - fi - - _fstype=$(findmnt -k -f -n -r -o FSTYPE $_dev) - [[ -e /etc/fstab ]] && _options=$(findmnt --fstab -f -n -r -o OPTIONS $_dev) - if [ -z "$_options" ]; then - _options=$(findmnt -k -f -n -r -o OPTIONS $_dev) - if [[ $_fstype == "nfs"* ]]; then - _options=$(echo $_options | sed 's/,addr=[^,]*//') - _options=$(echo $_options | sed 's/,proto=[^,]*//') - _options=$(echo $_options | sed 's/,clientaddr=[^,]*//') - fi - fi - #mount fs target as rw in 2nd kernel - _options=$(echo $_options | sed 's/\(^\|,\)ro\($\|,\)/\1rw\2/g') - # filter out 'noauto' here, it will be force appended later, avoid duplication - _options=$(echo $_options | sed 's/\(^\|,\)noauto\($\|,\)/\1/g') - # only mount the dump target when needed. - _options="$_options,noauto" - - _mntopts="$_target $_fstype $_options" - #for non-nfs _dev converting to use udev persistent name - if [ -b "$_source" ]; then - _pdev="$(get_persistent_dev $_source)" + # for non-nfs _target converting to use udev persistent name + _pdev="$(kdump_get_persistent_dev $_target)" if [ -z "$_pdev" ]; then return 1 fi - - else - _pdev=$_dev fi - echo "$_pdev $_mntopts" -} - -is_readonly_mount() { - local _mnt - _mnt=$(findmnt -k -f -n -r -o OPTIONS $1) + #mount fs target as rw in 2nd kernel + _options=$(echo $_options | sed 's/\(^\|,\)ro\($\|,\)/\1rw\2/g') + # with 'noauto' in fstab nfs and non-root disk mount will fail in 2nd + # kernel, filter it out here. + _options=$(echo $_options | sed 's/\(^\|,\)noauto\($\|,\)/\1/g') + # use both nofail and x-systemd.before to ensure systemd will try best to + # mount it before kdump starts, this is an attempt to improve robustness + _options="$_options,nofail,x-systemd.before=initrd-fs.target" - #fs/proc_namespace.c: show_mountinfo(): - #seq_puts(m, mnt->mnt_flags & MNT_READONLY ? " ro" : " rw"); - [[ "$_mnt" =~ ^ro ]] + echo "$_pdev $_new_mntpoint $_fstype $_options" } #Function: get_ssh_size @@ -155,7 +115,7 @@ get_ssh_size() { #mkdir if save path does not exist on ssh dump target #$1=ssh dump target -#caller should ensure write permission on $DUMP_TARGET:$SAVE_PATH +#caller should ensure write permission on $1:$SAVE_PATH #called from while loop and shouldn't read from stdin, so we're using "ssh -n" mkdir_save_path_ssh() { @@ -164,14 +124,14 @@ mkdir_save_path_ssh() ssh -qn $_opt $1 mkdir -p $SAVE_PATH 2>&1 > /dev/null _ret=$? if [ $_ret -ne 0 ]; then - perror_exit "mkdir failed on $DUMP_TARGET:$SAVE_PATH" + perror_exit "mkdir failed on $1:$SAVE_PATH" fi - #check whether user has write permission on $SAVE_PATH/$DUMP_TARGET + #check whether user has write permission on $1:$SAVE_PATH _dir=$(ssh -qn $_opt $1 mktemp -dqp $SAVE_PATH 2>/dev/null) _ret=$? if [ $_ret -ne 0 ]; then - perror_exit "Could not create temporary directory on $DUMP_TARGET:$SAVE_PATH. Make sure user has write permission on destination" + perror_exit "Could not create temporary directory on $1:$SAVE_PATH. Make sure user has write permission on destination" fi ssh -qn $_opt $1 rmdir $_dir @@ -222,22 +182,95 @@ 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 "Dump target \"$_target\" is neither mounted nor configured as \"noauto\"" + 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() { - if grep -q "^raw" $conf_file && [ "${1%% *}" != "makedumpfile" ]; then - echo "Warning: specifying a non-makedumpfile core collector, you will have to recover the vmcore manually." + local _cmd="${1%% *}" + local _params="${1#* }" + + if [ "$_cmd" != "makedumpfile" ]; then + if is_raw_dump_target; then + echo "Warning: specifying a non-makedumpfile core collector, you will have to recover the vmcore manually." + fi + return fi + if is_ssh_dump_target || is_raw_dump_target; then - if [ "${1%% *}" = "makedumpfile" ]; then - ! strstr "$1" "-F" && { - perror_exit "The specified dump target needs makedumpfile \"-F\" option." - } + if ! strstr "$_params" "-F"; then + perror_exit "The specified dump target needs makedumpfile \"-F\" option." fi + _params="$_params vmcore" + else + _params="$_params vmcore dumpfile" + fi + + if ! $_cmd --check-params $_params; then + perror_exit "makedumpfile parameter check failed." fi } add_mount() { - local _mnt=$(to_mount "$1") + local _mnt=$(to_mount $@) if [ $? -ne 0 ]; then exit 1 @@ -256,20 +289,11 @@ handle_default_dump_target() check_save_path_fs $SAVE_PATH - _mntpoint=$(get_mntpoint_from_path $SAVE_PATH) - _target=$(get_target_from_path $SAVE_PATH) - - if is_atomic && is_bind_mount $_mntpoint; then - SAVE_PATH=${SAVE_PATH##"$_mntpoint"} - # the real dump path in the 2nd kernel, if the mount point is bind mounted. - SAVE_PATH=$(get_bind_mount_directory $_mntpoint)/$SAVE_PATH - _mntpoint=$(get_mntpoint_from_target $_target) + _save_path=$(get_bind_mount_source $SAVE_PATH) + _target=$(get_target_from_path $_save_path) + _mntpoint=$(get_mntpoint_from_target $_target) - # the absolute path in the 1st kernel - SAVE_PATH=$_mntpoint/$SAVE_PATH - fi - - SAVE_PATH=${SAVE_PATH##"$_mntpoint"} + SAVE_PATH=${_save_path##"$_mntpoint"} add_mount "$_target" check_size fs $_target } @@ -387,6 +411,10 @@ if [ "$(uname -m)" = "s390x" ]; then add_dracut_module "znet" fi +if is_wdt_addition_needed; then + add_dracut_arg "-a" "watchdog" +fi + while read config_opt config_val; do # remove inline comments after the end of a directive. @@ -395,28 +423,15 @@ do extra_modules="$extra_modules $config_val" ;; ext[234]|xfs|btrfs|minix|nfs) - if ! findmnt $config_val >/dev/null; then - perror_exit "Dump target $config_val is probably not mounted." - fi - - _absolute_save_path=$(make_absolute_save_path $config_val) - _mntpoint=$(get_mntpoint_from_path $_absolute_save_path) - if is_atomic && is_bind_mount $_mntpoint; then - SAVE_PATH=${_absolute_save_path##"$_mntpoint"} - # the real dump path in the 2nd kernel, if the mount point is bind mounted. - SAVE_PATH=$(get_bind_mount_directory $_mntpoint)/$SAVE_PATH - fi - - add_mount "$config_val" - check_save_path_fs $_absolute_save_path - check_size fs $config_val + check_user_configured_target "$config_val" "$config_opt" + add_mount "$config_val" "$config_opt" ;; raw) - #checking raw disk writable + # checking raw disk writable dd if=$config_val count=1 of=/dev/null > /dev/null 2>&1 || { perror_exit "Bad raw disk $config_val" } - _praw=$(persistent_policy="by-id" get_persistent_dev $config_val) + _praw=$(persistent_policy="by-id" kdump_get_persistent_dev $config_val) if [ -z "$_praw" ]; then exit 1 fi @@ -449,7 +464,7 @@ handle_default_dump_target if [ -n "$extra_modules" ] then - add_dracut_arg "--add-drivers" "$extra_modules" + add_dracut_arg "--add-drivers" \"$extra_modules\" fi if ! is_fadump_capable; then @@ -460,7 +475,8 @@ if ! is_fadump_capable; then add_dracut_arg "--no-hostonly-default-device" fi -dracut "${dracut_args[@]}" "$@" +echo "$dracut_args $@" | xargs dracut + _rc=$? sync exit $_rc diff --git a/SOURCES/rhelonly-kexec-tools-2.0.20-makedumpfile-remove-lebl.patch b/SOURCES/rhelonly-kexec-tools-2.0.20-makedumpfile-remove-lebl.patch deleted file mode 100644 index ca63d82..0000000 --- a/SOURCES/rhelonly-kexec-tools-2.0.20-makedumpfile-remove-lebl.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 3beef142bc003d9cf2e957c6a21e51d661f9b13e Mon Sep 17 00:00:00 2001 -From: Pingfan Liu -Date: Thu, 28 Nov 2019 21:23:00 +0800 -Subject: [PATCH] makedumpfile: remove -lebl - -Signed-off-by: Pingfan Liu ---- - makedumpfile-1.6.6/Makefile | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/makedumpfile-1.6.6/Makefile b/makedumpfile-1.6.6/Makefile -index 1fdb628..df21b93 100644 ---- a/makedumpfile-1.6.6/Makefile -+++ b/makedumpfile-1.6.6/Makefile -@@ -50,7 +50,7 @@ OBJ_PART=$(patsubst %.c,%.o,$(SRC_PART)) - SRC_ARCH = arch/arm.c arch/arm64.c arch/x86.c arch/x86_64.c arch/ia64.c arch/ppc64.c arch/s390x.c arch/ppc.c arch/sparc64.c - OBJ_ARCH=$(patsubst %.c,%.o,$(SRC_ARCH)) - --LIBS = -ldw -lbz2 -lebl -ldl -lelf -lz -+LIBS = -ldw -lbz2 -ldl -lelf -lz - ifneq ($(LINKTYPE), dynamic) - LIBS := -static $(LIBS) - endif --- -2.20.1 - diff --git a/SOURCES/rhonly-kexec-tools-2.0.18-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch b/SOURCES/rhonly-kexec-tools-2.0.18-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch index dad84d1..71bdca4 100644 --- a/SOURCES/rhonly-kexec-tools-2.0.18-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch +++ b/SOURCES/rhonly-kexec-tools-2.0.18-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch @@ -42,10 +42,10 @@ Signed-off-by: Bhupesh Sharma makedumpfile.h | 1 + 3 files changed, 83 insertions(+), 29 deletions(-) -diff --git a/makedumpfile-1.6.6/arch/arm64.c b/makedumpfile-1.6.6/arch/arm64.c +diff --git a/makedumpfile-1.6.7/arch/arm64.c b/makedumpfile-1.6.7/arch/arm64.c index 0535193..5fcf59d 100644 ---- a/makedumpfile-1.6.6/arch/arm64.c -+++ b/makedumpfile-1.6.6/arch/arm64.c +--- a/makedumpfile-1.6.7/arch/arm64.c ++++ b/makedumpfile-1.6.7/arch/arm64.c @@ -41,6 +41,7 @@ typedef struct { static int pgtable_level; @@ -198,10 +198,10 @@ index 0535193..5fcf59d 100644 return TRUE; } -diff --git a/makedumpfile-1.6.6/makedumpfile.c b/makedumpfile-1.6.6/makedumpfile.c +diff --git a/makedumpfile-1.6.7/makedumpfile.c b/makedumpfile-1.6.7/makedumpfile.c index d76a435..c8906b5 100644 ---- a/makedumpfile-1.6.6/makedumpfile.c -+++ b/makedumpfile-1.6.6/makedumpfile.c +--- a/makedumpfile-1.6.7/makedumpfile.c ++++ b/makedumpfile-1.6.7/makedumpfile.c @@ -2313,6 +2313,7 @@ write_vmcoreinfo_data(void) WRITE_NUMBER("HUGETLB_PAGE_DTOR", HUGETLB_PAGE_DTOR); @@ -218,10 +218,10 @@ index d76a435..c8906b5 100644 READ_NUMBER("VA_BITS", VA_BITS); READ_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET); READ_NUMBER_UNSIGNED("kimage_voffset", kimage_voffset); -diff --git a/makedumpfile-1.6.6/makedumpfile.h b/makedumpfile-1.6.6/makedumpfile.h +diff --git a/makedumpfile-1.6.7/makedumpfile.h b/makedumpfile-1.6.7/makedumpfile.h index 24b2f69..cccb52a 100644 ---- a/makedumpfile-1.6.6/makedumpfile.h -+++ b/makedumpfile-1.6.6/makedumpfile.h +--- a/makedumpfile-1.6.7/makedumpfile.h ++++ b/makedumpfile-1.6.7/makedumpfile.h @@ -1937,6 +1937,7 @@ struct number_table { long phys_base; long KERNEL_IMAGE_SIZE; diff --git a/SOURCES/supported-kdump-targets.txt b/SOURCES/supported-kdump-targets.txt index 64b7f59..f540f59 100644 --- a/SOURCES/supported-kdump-targets.txt +++ b/SOURCES/supported-kdump-targets.txt @@ -42,6 +42,9 @@ storage: hardware RAID (cciss, hpsa, megaraid_sas, mpt2sas, aacraid) SCSI/SATA disks iSCSI HBA (all offload) + hardware FCoE (qla2xxx, lpfc) + software FCoE (bnx2fc) (Extra configuration required, + please read "Note on FCoE" section below) network: Hardware using kernel modules: (tg3, igb, ixgbe, sfc, e1000e, bna, @@ -104,6 +107,21 @@ hypervisor: Hyper-V 2012 +Note on FCoE +===================== +If you are trying to dump to a software FCoE target, you may encounter OOM +issue, because some software FCoE requires more memory to work. In such case, +you may need to increase the kdump reserved memory size in "crashkernel=" +kernel parameter. + +By default, RHEL systems have "crashkernel=auto" in kernel boot arguments. +The auto reserved memory size is designed to balance the coverage of use cases +and an acceptable memory overhead, so not every use case could fit in, software +FCoE is one of the case. + +For hardware FCoE, kdump should work naturally as firmware will do the +initialization job. The capture kernel and kdump tools will run just fine. + Useful Links ============ [1] RHEL6: Enabling kdump for full-virt (HVM) Xen DomU diff --git a/SPECS/kexec-tools.spec b/SPECS/kexec-tools.spec index 1df65a1..49e1d46 100644 --- a/SPECS/kexec-tools.spec +++ b/SPECS/kexec-tools.spec @@ -1,6 +1,6 @@ Name: kexec-tools Version: 2.0.20 -Release: 9%{?dist} +Release: 29%{?dist} License: GPLv2 Group: Applications/System Summary: The kexec/kdump userspace component @@ -13,7 +13,7 @@ Source4: kdump.sysconfig.i386 Source5: kdump.sysconfig.ppc64 Source7: mkdumprd Source8: kdump.conf -Source9: http://downloads.sourceforge.net/project/makedumpfile/makedumpfile/1.6.6/makedumpfile-1.6.6.tar.gz +Source9: http://downloads.sourceforge.net/project/makedumpfile/makedumpfile/1.6.7/makedumpfile-1.6.7.tar.gz Source10: kexec-kdump-howto.txt Source12: mkdumprd.8 Source13: 98-kexec.rules @@ -33,6 +33,7 @@ Source27: early-kdump-howto.txt Source28: supported-kdump-targets.txt Source29: kdump-udev-throttler Source30: kdump.sysconfig.aarch64 +Source31: fadump-howto.txt ####################################### # These are sources for mkdumpramfs @@ -94,16 +95,24 @@ ExcludeArch: i686 Patch601: rhelonly-kexec-tools-2.0.16-koji-build-fail-workaround.patch Patch602: rhelonly-kexec-tools-2.0.18-eppic-fix-issues-with-hardening-flags.patch Patch603: rhonly-kexec-tools-2.0.18-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch -Patch604: kexec-tools-2.0.20-makedumpfile-x86_64-Fix-incorrect-exclusion-by-e-option-wit.patch -Patch605: kexec-tools-2.0.20-Cleanup-remove-the-read_elf_kcore.patch -Patch606: kexec-tools-2.0.20-Fix-an-error-definition-about-the-variable-fname.patch -Patch607: kexec-tools-2.0.20-Cleanup-move-it-back-from-util_lib-elf_info.c.patch -Patch608: kexec-tools-2.0.20-Limit-the-size-of-vmcore-dmesg.txt-to-2G.patch -Patch609: kexec-tools-2.0.20-vmcore-dmesg-vmcore-dmesg.c-Fix-shifting-error-repor.patch -Patch610: kexec-tools-2.0.20-makedumpfile-Increase-SECTION_MAP_LAST_BIT-to-4.patch -Patch611: kexec-tools-2.0.20-makedumpfile-Fix-off-by-one-issue-in-exclude_nodata_pages.patch -Patch612: rhelonly-kexec-tools-2.0.20-makedumpfile-remove-lebl.patch -Patch613: kexec-tools-2.0.20-makedumpfile-assign-bitmap1-2-fd-for-subprocess-in-non-cycl.patch +Patch604: kexec-tools-2.0.20-Cleanup-remove-the-read_elf_kcore.patch +Patch605: kexec-tools-2.0.20-Fix-an-error-definition-about-the-variable-fname.patch +Patch606: kexec-tools-2.0.20-Cleanup-move-it-back-from-util_lib-elf_info.c.patch +Patch607: kexec-tools-2.0.20-Limit-the-size-of-vmcore-dmesg.txt-to-2G.patch +Patch608: kexec-tools-2.0.20-vmcore-dmesg-vmcore-dmesg.c-Fix-shifting-error-repor.patch +Patch609: kexec-tools-2.0.20-kexec-add-variant-helper-functions-for-handling-memo.patch +Patch610: kexec-tools-2.0.20-arm64-kexec-allocate-memory-space-avoiding-reserved-.patch +Patch611: kexec-tools-2.0.20-arm64-kdump-deal-with-a-lot-of-resource-entries-in-p.patch + +# Patches 701 onward for makedumpfile +Patch701: kexec-tools-2.0.20-makedumpfile-PATCH-Remove-duplicated-variable-definitions.patch +Patch702: kexec-tools-2.0.20-makedumpfile-PATCH-cope-with-not-present-mem-section.patch +Patch703: kexec-tools-2.0.20-makedumpfile-PATCH-Introduce-check-params-option.patch +Patch704: kexec-tools-2.0.20-makedumpfile-PATCH-Makefile-Fix-build-errors-in-static-build.patch +Patch705: kexec-tools-2.0.20-makedumpfile-PATCH-Align-PMD_SECTION_MASK-with-PHYS_MASK.patch +Patch706: kexec-tools-2.0.20-makedumpfile-PATCH-Fix-cd_header-offset-overflow-with-large-pfn.patch +Patch707: kexec-tools-2.0.20-makedumpfile-PATCH-Avoid-false-positive-failure-in-mem_seciton-va.patch + %description kexec-tools provides /usr/sbin/kexec binary that facilitates a new @@ -130,8 +139,13 @@ tar -z -x -v -f %{SOURCE19} %patch609 -p1 %patch610 -p1 %patch611 -p1 -%patch612 -p1 -%patch613 -p1 +%patch701 -p1 +%patch702 -p1 +%patch703 -p1 +%patch704 -p1 +%patch705 -p1 +%patch706 -p1 +%patch707 -p1 %ifarch ppc %define archdef ARCH=ppc @@ -156,12 +170,13 @@ cp %{SOURCE21} . cp %{SOURCE26} . cp %{SOURCE27} . cp %{SOURCE28} . +cp %{SOURCE31} . make %ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64 make -C eppic/libeppic -make -C makedumpfile-1.6.6 LINKTYPE=dynamic USELZO=on USESNAPPY=on -make -C makedumpfile-1.6.6 LDFLAGS="$LDFLAGS -I../eppic/libeppic -L../eppic/libeppic" eppic_makedumpfile.so +make -C makedumpfile-1.6.7 LINKTYPE=dynamic USELZO=on USESNAPPY=on +make -C makedumpfile-1.6.7 LDFLAGS="$LDFLAGS -I../eppic/libeppic -L../eppic/libeppic" eppic_makedumpfile.so %endif %install @@ -212,13 +227,13 @@ install -m 644 %{SOURCE16} $RPM_BUILD_ROOT%{_unitdir}/kdump.service install -m 755 -D %{SOURCE22} $RPM_BUILD_ROOT%{_prefix}/lib/systemd/system-generators/kdump-dep-generator.sh %ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64 -install -m 755 makedumpfile-1.6.6/makedumpfile $RPM_BUILD_ROOT/usr/sbin/makedumpfile -install -m 644 makedumpfile-1.6.6/makedumpfile.8.gz $RPM_BUILD_ROOT/%{_mandir}/man8/makedumpfile.8.gz -install -m 644 makedumpfile-1.6.6/makedumpfile.conf.5.gz $RPM_BUILD_ROOT/%{_mandir}/man5/makedumpfile.conf.5.gz -install -m 644 makedumpfile-1.6.6/makedumpfile.conf $RPM_BUILD_ROOT/%{_sysconfdir}/makedumpfile.conf.sample -install -m 755 makedumpfile-1.6.6/eppic_makedumpfile.so $RPM_BUILD_ROOT/%{_libdir}/eppic_makedumpfile.so +install -m 755 makedumpfile-1.6.7/makedumpfile $RPM_BUILD_ROOT/usr/sbin/makedumpfile +install -m 644 makedumpfile-1.6.7/makedumpfile.8.gz $RPM_BUILD_ROOT/%{_mandir}/man8/makedumpfile.8.gz +install -m 644 makedumpfile-1.6.7/makedumpfile.conf.5.gz $RPM_BUILD_ROOT/%{_mandir}/man5/makedumpfile.conf.5.gz +install -m 644 makedumpfile-1.6.7/makedumpfile.conf $RPM_BUILD_ROOT/%{_sysconfdir}/makedumpfile.conf.sample +install -m 755 makedumpfile-1.6.7/eppic_makedumpfile.so $RPM_BUILD_ROOT/%{_libdir}/eppic_makedumpfile.so mkdir -p $RPM_BUILD_ROOT/usr/share/makedumpfile/eppic_scripts/ -install -m 644 makedumpfile-1.6.6/eppic_scripts/* $RPM_BUILD_ROOT/usr/share/makedumpfile/eppic_scripts/ +install -m 644 makedumpfile-1.6.7/eppic_scripts/* $RPM_BUILD_ROOT/usr/share/makedumpfile/eppic_scripts/ %endif %define remove_dracut_prefix() %(echo -n %1|sed 's/.*dracut-//g') @@ -348,6 +363,7 @@ done %doc TODO %doc kexec-kdump-howto.txt %doc early-kdump-howto.txt +%doc fadump-howto.txt %doc supported-kdump-targets.txt %doc kdump-in-cluster-environment.txt %doc live-image-kdump-howto.txt @@ -357,6 +373,101 @@ done %endif %changelog +* Wed Jun 24 2020 Pingfan Liu - 2.0.20-29 +- mkdumprd: Improve the error message for umounted dump target + +* Wed Jun 24 2020 Pingfan Liu - 2.0.20-28 +- mkdumprd: Fix nfs detection in to_mount +- Always wrap up call to dracut get_persistent_dev function +- man: improve description about /etc/kdump/{pre.d,post.d}interface + +* Tue Jun 16 2020 Pingfan Liu - 2.0.20-27 +- kdump-lib: switch to the kexec_file_load() syscall on x86_64 by default + +* Mon Jun 15 2020 Pingfan Liu - 2.0.20-26 +- Fix kdump failure when mount target specified by dracut_args +- mkdumprd: Fix dracut error on multiple extra_modules + +* Mon Jun 15 2020 Pingfan Liu - 2.0.20-25 +- kdump.conf: Specify /etc/kdump/{pre.d,post.d}interface +- dracut-kdump.sh: Execute the binary and script filesin /etc/kdump/{pre.d,post.d} +- kdumpctl: Check the update of the binary and script files in /etc/kdump/{pre.d,post.d} +- dracut-module-setup.sh: Install files under /etc/kdump/{pre.d,post.d} into kdump initramfs + +* Thu Jun 4 2020 Pingfan Liu - 2.0.20-24 +- fadump: update fadump-howto.txt with some more troubleshooting help + +* Wed Jun 3 2020 Pingfan Liu - 2.0.20-23 +- fadump-howto.txt: source it in spec file + +* Mon Jun 1 2020 Pingfan Liu - 2.0.20-22 +- mkdumprd: Use DUMP_TARGET which printing error message during ssh + +* Mon Jun 1 2020 Pingfan Liu - 2.0.20-21 +- Don't inherit swiotlb parameter form 1st kernel by default +- Add a new option 'rd.znet_ifname' in order to use it in udev rules +- kdump.sysconfig: Remove the option 'log_buf_len' from kdump command line +- kdump-error-handler.service: Remove ExecStopPost +- module-setup.sh: Add "rd.neednet" parameter if network is needed + +* Thu May 28 2020 Pingfan Liu - 2.0.20-20 +- Update docs for the new noauto dump target support +- kexec-kdump-howto.txt: Add some format to the document +- mkdumprd: generate usable kdump initramfs even target is not mounted +- Use get_mount_info to replace findmnt calls +- kdump-lib.sh: add fstab failback helper for getting mount info +- Allow calling mkdumprd from kdumpctl even if targat not mounted +- Add a is_mounted helper +- Introduce get_kdump_mntpoint_from_target and fix duplicated / +- Doc: Improves the early-kdump-howto.txt document in several points +- Doc: Add --force option to step 2 in early-kdump-howto.txt +- Doc: Fix typo in early-kdump-howto.txt +- Remove adjust_bind_mount_path call +- No longer treat atomic/silverblue specially +- mkdumprd: Simplify handling of user specified target +- mkdumprd: Use get_save_path instead of parsing config +- Remove is_dump_target_configured +- Always use get_save_path to get the 'path' option +- kdump-lib: Don't abuse echo, and clean up +- mkdumprd: Fix dracut args parsing +- mkdumprd: simplify dracut args parsing + +* Thu May 21 2020 Pingfan Liu - 2.0.20-19 +- dracut-module-setup.sh: improve get_alias() +- fadump: update fadump-howto.txt with some troubleshooting help +- Append both nofail and x-systemd.before to kdump mount target +- Partially Revert "Don't mount the dump target unless needed" +- Don't unmount the dump target just after saving vmcore + +* Mon May 11 2020 Pingfan Liu - 2.0.20-18 +- makedumpfile: Avoid false-positive failure in mem_seciton validation + +* Tue Apr 21 2020 Pingfan Liu - 2.0.20-17 +- mkdumprd: Use makedumpfile --check-params option + +* Thu Apr 9 2020 Pingfan Liu - 2.0.20-16 +- makedumpfile update to latest + +* Wed Apr 1 2020 Pingfan Liu - 2.0.20-15 +- makedumpfile rebase to 1.6.7 + +* Tue Feb 18 2020 Pingfan Liu - 2.0.20-14 +- kexec-tools/module-setup: Ensure eth devices get IP address for VLAN + +* Wed Feb 12 2020 Pingfan Liu - 2.0.20-13 +- Add document to declare FCoE support + +* Wed Feb 12 2020 Pingfan Liu - 2.0.20-12 +- powerpc: enable the scripts to capture dump on POWERNV platform + +* Tue Feb 4 2020 Pingfan Liu - 2.0.20-11 +- s390: Use get_kaslr_offset_general() for s390x + +* Fri Jan 10 2020 Pingfan Liu - 2.0.20-10 +- arm64: kdump: deal with a lot of resource entries in /proc/iomem +- arm64: kexec: allocate memory space avoiding reserved regions +- kexec: add variant helper functions for handling memory regions + * Thu Dec 12 2019 Pingfan Liu - 2.0.20-9 - makedumpfile: assign bitmap1/2 fd for subprocess in non-cyclic mode