Compare commits
	
		
			No commits in common. "c8" and "a9" have entirely different histories.
		
	
	
		
	
		
							
								
								
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,3 +1,3 @@ | |||||||
| SOURCES/1.7.2.tar.gz | SOURCES/eppic-e8844d3.tar.gz | ||||||
| SOURCES/eppic_050615.tar.gz | SOURCES/kexec-tools-2.0.27.tar.xz | ||||||
| SOURCES/kexec-tools-2.0.26.tar.xz | SOURCES/makedumpfile-1.7.4.tar.gz | ||||||
|  | |||||||
| @ -1,3 +1,3 @@ | |||||||
| 24bce02cd42cdbb960ada4d9e733355582e35784 SOURCES/1.7.2.tar.gz | 80ac3f5e77d3c79883edadf14428734db4720009 SOURCES/eppic-e8844d3.tar.gz | ||||||
| a096c8e0892b559f40b01916aae240652f75b68a SOURCES/eppic_050615.tar.gz | ed15f191adee22ab0721ba62af1cae67eb981670 SOURCES/kexec-tools-2.0.27.tar.xz | ||||||
| 27cea5d032ec1e93506b8110222420abf754df2d SOURCES/kexec-tools-2.0.26.tar.xz | 98cae2b1062871905795918c32b6d46ccd115074 SOURCES/makedumpfile-1.7.4.tar.gz | ||||||
|  | |||||||
							
								
								
									
										31
									
								
								SOURCES/60-fadump.install
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										31
									
								
								SOURCES/60-fadump.install
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,31 @@ | |||||||
|  | #!/usr/bin/bash | ||||||
|  | 
 | ||||||
|  | COMMAND="$1" | ||||||
|  | KERNEL_VERSION="$2" | ||||||
|  | 
 | ||||||
|  | if ! [[ ${KERNEL_INSTALL_MACHINE_ID-x} ]]; then | ||||||
|  |     exit 0 | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | # Currently, fadump is supported only in environments with | ||||||
|  | # writable /boot directory. | ||||||
|  | if [[ ! -w "/boot" ]]; then | ||||||
|  |     exit 0 | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | FADUMP_INITRD="/boot/.initramfs-${KERNEL_VERSION}.img.default" | ||||||
|  | FADUMP_INITRD_CHECKSUM="$FADUMP_INITRD.checksum" | ||||||
|  | 
 | ||||||
|  | ret=0 | ||||||
|  | case "$COMMAND" in | ||||||
|  |     add) | ||||||
|  |         # Do nothing, fadump initramfs is strictly host only | ||||||
|  |         # and managed by kdump service | ||||||
|  |         ;; | ||||||
|  |     remove) | ||||||
|  |         rm -f -- "$FADUMP_INITRD" | ||||||
|  |         rm -f -- "$FADUMP_INITRD_CHECKSUM" | ||||||
|  |         ret=$? | ||||||
|  |         ;; | ||||||
|  | esac | ||||||
|  | exit $ret | ||||||
							
								
								
									
										13
									
								
								SOURCES/92-crashkernel.install
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										13
									
								
								SOURCES/92-crashkernel.install
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,13 @@ | |||||||
|  | #!/usr/bin/bash | ||||||
|  | 
 | ||||||
|  | COMMAND="$1" | ||||||
|  | KERNEL_VERSION="$2" | ||||||
|  | KDUMP_INITRD_DIR_ABS="$3" | ||||||
|  | KERNEL_IMAGE="$4" | ||||||
|  | 
 | ||||||
|  | case "$COMMAND" in | ||||||
|  | add) | ||||||
|  | 	kdumpctl _reset-crashkernel-for-installed_kernel "$KERNEL_VERSION" | ||||||
|  | 	exit 0 | ||||||
|  | 	;; | ||||||
|  | esac | ||||||
| @ -17,6 +17,6 @@ GOTO="kdump_reload_end" | |||||||
| 
 | 
 | ||||||
| LABEL="kdump_reload_cpu" | LABEL="kdump_reload_cpu" | ||||||
| 
 | 
 | ||||||
| RUN+="/bin/sh -c '/usr/bin/systemctl is-active kdump.service || exit 0; ! test -f /sys/kernel/fadump_enabled || cat /sys/kernel/fadump_enabled | grep 0  || exit 0; /usr/bin/systemd-run --quiet --no-block /usr/lib/udev/kdump-udev-throttler'" | RUN+="/bin/sh -c '/usr/bin/systemctl is-active kdump.service || exit 0; ! test -f /sys/kernel/fadump/enabled || cat /sys/kernel/fadump/enabled | grep 0  || exit 0; /usr/bin/systemd-run --quiet --no-block /usr/lib/udev/kdump-udev-throttler'" | ||||||
| 
 | 
 | ||||||
| LABEL="kdump_reload_end" | LABEL="kdump_reload_end" | ||||||
|  | |||||||
							
								
								
									
										120
									
								
								SOURCES/crashkernel-howto.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								SOURCES/crashkernel-howto.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,120 @@ | |||||||
|  | Introduction | ||||||
|  | ============ | ||||||
|  | 
 | ||||||
|  | This document describes features the kexec-tools package provides for setting | ||||||
|  | and estimating the crashkernel value. | ||||||
|  | 
 | ||||||
|  | Kdump lives in a pre-reserved chunk of memory, and the size of the reserved | ||||||
|  | memory is specified by the `crashkernel=` kernel parameter. It's hard to | ||||||
|  | estimate an accurate `crashkernel=` value, so it's always recommended to test | ||||||
|  | kdump after you updated the `crashkernel=` value or changed the dump target. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Default crashkernel value | ||||||
|  | ========================= | ||||||
|  | 
 | ||||||
|  | Latest kexec-tools provides "kdumpctl get-default-crashkernel" to retrieve | ||||||
|  | the default crashkernel value, | ||||||
|  | 
 | ||||||
|  | 	$ echo $(kdumpctl get-default-crashkernel) | ||||||
|  | 	1G-4G:192M,4G-64G:256M,64G-:512M | ||||||
|  | 
 | ||||||
|  | It will be taken as the default value of 'crashkernel=', you can use | ||||||
|  | this value as a reference for setting crashkernel value manually. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | New installed system | ||||||
|  | ==================== | ||||||
|  | 
 | ||||||
|  | Anaconda is the OS installer which sets all the kernel boot cmdline on a newly | ||||||
|  | installed system. If kdump is enabled during Anaconda installation, Anaconda | ||||||
|  | will use the default crashkernel value as the default `crashkernel=` value on | ||||||
|  | the newly installed system. | ||||||
|  | 
 | ||||||
|  | Users can override the value during Anaconda installation manually. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Auto update of crashkernel boot parameter | ||||||
|  | ========================================= | ||||||
|  | 
 | ||||||
|  | A new release of kexec-tools could update the default crashkernel value.  By | ||||||
|  | default, kexec-tools would reset crashkernel to the new default value if it | ||||||
|  | detects the old default crashkernel value is used by installed kernels. If you | ||||||
|  | don't want kexec-tools to update the old default crashkernel to the new default | ||||||
|  | crashkernel, you can change auto_reset_crashkernel to no in kdump.conf. | ||||||
|  | 
 | ||||||
|  | Supported Bootloaders | ||||||
|  | --------------------- | ||||||
|  | 
 | ||||||
|  | This auto update only works with GRUB2 and ZIPL, as kexec-tools heavily depends | ||||||
|  | on `grubby`. If other boot loaders are used, the user will have to update the | ||||||
|  | `crashkernel=` value manually. | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | Reset crashkernel to default value | ||||||
|  | ================================== | ||||||
|  | 
 | ||||||
|  | kexec-tools only perform the auto update of crashkernel value when it can | ||||||
|  | confirm the boot kernel's crashkernel value is using its corresponding default | ||||||
|  | value and auto_reset_crashkernel=yes in kdump.conf. In other cases, the user | ||||||
|  | can reset the crashkernel value by themselves. | ||||||
|  | 
 | ||||||
|  | Reset using kdumpctl | ||||||
|  | -------------------- | ||||||
|  | 
 | ||||||
|  | To make it easier to reset the `crashkernel=` kernel cmdline to this default | ||||||
|  | value properly, `kdumpctl` also provides a sub-command: | ||||||
|  | 
 | ||||||
|  | 	`kdumpctl reset-crashkernel [--kernel=path_to_kernel] [--reboot]` | ||||||
|  | 
 | ||||||
|  | This command will reset the bootloader's kernel cmdline to the default value. | ||||||
|  | It will also update bootloader config if the bootloader has a standalone config | ||||||
|  | file. User will have to reboot the machine after this command to make it take | ||||||
|  | effect if --reboot is not specified. For more details, please refer to the | ||||||
|  | reset-crashkernel command in `man kdumpctl`. | ||||||
|  | 
 | ||||||
|  | Reset manually | ||||||
|  | -------------- | ||||||
|  | 
 | ||||||
|  | To reset the crashkernel value manually, it's recommended to use utils like | ||||||
|  | `grubby`. A one liner script for resetting `crashkernel=` value of all installed | ||||||
|  | kernels to the default value is: | ||||||
|  | 
 | ||||||
|  | 	grubby --update-kernel ALL --args "crashkernel=$(kdumpctl get-default-crashkernel)" | ||||||
|  | 
 | ||||||
|  | NOTE: On s390x you also need to run zipl for the change to take effect. | ||||||
|  | 
 | ||||||
|  | Estimate crashkernel | ||||||
|  | ==================== | ||||||
|  | 
 | ||||||
|  | The best way to estimate a usable crashkernel value is by testing kdump | ||||||
|  | manually.  And you can set crashkernel to a large value, then adjust the | ||||||
|  | crashkernel value to an acceptable value gradually. | ||||||
|  | 
 | ||||||
|  | `kdumpctl` also provides a sub-command for doing rough estimating without | ||||||
|  | triggering kdump: | ||||||
|  | 
 | ||||||
|  | 	`kdumpctl estimate` | ||||||
|  | 
 | ||||||
|  | The output will be like this: | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  |       Encrypted kdump target requires extra memory, assuming using the keyslot with minimum memory requirement | ||||||
|  | 
 | ||||||
|  |       Reserved crashkernel:    256M | ||||||
|  |       Recommended crashkernel: 655M | ||||||
|  | 
 | ||||||
|  |       Kernel image size:   47M | ||||||
|  |       Kernel modules size: 12M | ||||||
|  |       Initramfs size:      19M | ||||||
|  |       Runtime reservation: 64M | ||||||
|  |       LUKS required size:  512M | ||||||
|  |       Large modules: | ||||||
|  |           xfs: 1892352 | ||||||
|  |           nouveau: 2318336 | ||||||
|  |       WARNING: Current crashkernel size is lower than recommended size 655M. | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | It will generate a summary report about the estimated memory consumption | ||||||
|  | of each component of kdump. The value may not be accurate enough, but | ||||||
|  | would be a good start for finding a suitable crashkernel value. | ||||||
| @ -6,9 +6,8 @@ KDUMP_KERNEL="" | |||||||
| KDUMP_INITRD="" | KDUMP_INITRD="" | ||||||
| 
 | 
 | ||||||
| check() { | check() { | ||||||
|     if [ ! -f /etc/sysconfig/kdump ] || [ ! -f /lib/kdump/kdump-lib.sh ]\ |     if [[ ! -f /etc/sysconfig/kdump ]] || [[ ! -f /lib/kdump/kdump-lib.sh ]] \ | ||||||
|         || [ -n "${IN_KDUMP}" ] |         || [[ -n ${IN_KDUMP} ]]; then | ||||||
|     then |  | ||||||
|         return 1 |         return 1 | ||||||
|     fi |     fi | ||||||
|     return 255 |     return 255 | ||||||
| @ -25,7 +24,7 @@ prepare_kernel_initrd() { | |||||||
|     prepare_kdump_bootinfo |     prepare_kdump_bootinfo | ||||||
| 
 | 
 | ||||||
|     # $kernel is a variable from dracut |     # $kernel is a variable from dracut | ||||||
|     if [ "$KDUMP_KERNELVER" != $kernel ]; then |     if [[ $KDUMP_KERNELVER != "$kernel" ]]; then | ||||||
|         dwarn "Using kernel version '$KDUMP_KERNELVER' for early kdump," \ |         dwarn "Using kernel version '$KDUMP_KERNELVER' for early kdump," \ | ||||||
|             "but the initramfs is generated for kernel version '$kernel'" |             "but the initramfs is generated for kernel version '$kernel'" | ||||||
|     fi |     fi | ||||||
| @ -33,12 +32,12 @@ prepare_kernel_initrd() { | |||||||
| 
 | 
 | ||||||
| install() { | install() { | ||||||
|     prepare_kernel_initrd |     prepare_kernel_initrd | ||||||
|     if [ ! -f "$KDUMP_KERNEL" ]; then |     if [[ ! -f $KDUMP_KERNEL ]]; then | ||||||
|         derror "Could not find required kernel for earlykdump," \ |         derror "Could not find required kernel for earlykdump," \ | ||||||
|             "earlykdump will not work!" |             "earlykdump will not work!" | ||||||
|         return 1 |         return 1 | ||||||
|     fi |     fi | ||||||
|     if [ ! -f "$KDUMP_INITRD" ]; then |     if [[ ! -f $KDUMP_INITRD ]]; then | ||||||
|         derror "Could not find required kdump initramfs for earlykdump," \ |         derror "Could not find required kdump initramfs for earlykdump," \ | ||||||
|             "please ensure kdump initramfs is generated first," \ |             "please ensure kdump initramfs is generated first," \ | ||||||
|             "earlykdump will not work!" |             "earlykdump will not work!" | ||||||
| @ -51,7 +50,9 @@ install() { | |||||||
|     inst_binary "/usr/bin/gawk" "/usr/bin/awk" |     inst_binary "/usr/bin/gawk" "/usr/bin/awk" | ||||||
|     inst_binary "/usr/bin/logger" "/usr/bin/logger" |     inst_binary "/usr/bin/logger" "/usr/bin/logger" | ||||||
|     inst_binary "/usr/bin/printf" "/usr/bin/printf" |     inst_binary "/usr/bin/printf" "/usr/bin/printf" | ||||||
|  |     inst_binary "/usr/bin/xargs" "/usr/bin/xargs" | ||||||
|     inst_script "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh" |     inst_script "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh" | ||||||
|  |     inst_script "/lib/kdump/kdump-lib-initramfs.sh" "/lib/kdump/kdump-lib-initramfs.sh" | ||||||
|     inst_script "/lib/kdump/kdump-logger.sh" "/lib/kdump-logger.sh" |     inst_script "/lib/kdump/kdump-logger.sh" "/lib/kdump-logger.sh" | ||||||
|     inst_hook cmdline 00 "$moddir/early-kdump.sh" |     inst_hook cmdline 00 "$moddir/early-kdump.sh" | ||||||
|     inst_binary "$KDUMP_KERNEL" |     inst_binary "$KDUMP_KERNEL" | ||||||
|  | |||||||
| @ -14,9 +14,8 @@ EARLY_KEXEC_ARGS="" | |||||||
| . /lib/kdump-lib.sh | . /lib/kdump-lib.sh | ||||||
| . /lib/kdump-logger.sh | . /lib/kdump-logger.sh | ||||||
| 
 | 
 | ||||||
| #initiate the kdump logger | # initiate the kdump logger | ||||||
| dlog_init | if ! dlog_init; then | ||||||
| if [ $? -ne 0 ]; then |  | ||||||
|         echo "failed to initiate the kdump logger." |         echo "failed to initiate the kdump logger." | ||||||
|         exit 1 |         exit 1 | ||||||
| fi | fi | ||||||
| @ -30,8 +29,7 @@ prepare_parameters() | |||||||
| 
 | 
 | ||||||
| early_kdump_load() | early_kdump_load() | ||||||
| { | { | ||||||
|     check_kdump_feasibility |     if ! check_kdump_feasibility; then | ||||||
|     if [ $? -ne 0 ]; then |  | ||||||
|         return 1 |         return 1 | ||||||
|     fi |     fi | ||||||
| 
 | 
 | ||||||
| @ -40,8 +38,7 @@ early_kdump_load() | |||||||
|         return 1 |         return 1 | ||||||
|     fi |     fi | ||||||
| 
 | 
 | ||||||
|     check_current_kdump_status |     if is_kernel_loaded "kdump"; then | ||||||
|     if [ $? == 0 ]; then |  | ||||||
|         return 1 |         return 1 | ||||||
|     fi |     fi | ||||||
| 
 | 
 | ||||||
| @ -56,10 +53,9 @@ early_kdump_load() | |||||||
| 	--command-line=$EARLY_KDUMP_CMDLINE --initrd=$EARLY_KDUMP_INITRD \ | 	--command-line=$EARLY_KDUMP_CMDLINE --initrd=$EARLY_KDUMP_INITRD \ | ||||||
| 	$EARLY_KDUMP_KERNEL" | 	$EARLY_KDUMP_KERNEL" | ||||||
| 
 | 
 | ||||||
|     $KEXEC ${EARLY_KEXEC_ARGS} $standard_kexec_args \ |     if $KEXEC $EARLY_KEXEC_ARGS $standard_kexec_args \ | ||||||
|         --command-line="$EARLY_KDUMP_CMDLINE" \ |         --command-line="$EARLY_KDUMP_CMDLINE" \ | ||||||
|         --initrd=$EARLY_KDUMP_INITRD $EARLY_KDUMP_KERNEL |         --initrd=$EARLY_KDUMP_INITRD $EARLY_KDUMP_KERNEL; then | ||||||
|     if [ $? == 0 ]; then |  | ||||||
|         dinfo "kexec: loaded early-kdump kernel" |         dinfo "kexec: loaded early-kdump kernel" | ||||||
|         return 0 |         return 0 | ||||||
|     else |     else | ||||||
|  | |||||||
| @ -1,27 +1,26 @@ | |||||||
| #  This file is part of systemd. | # This service will run the real kdump error handler code. Executing the | ||||||
| # | # failure action configured in kdump.conf | ||||||
| #  systemd is free software; you can redistribute it and/or modify it |  | ||||||
| #  under the terms of the GNU Lesser General Public License as published by |  | ||||||
| #  the Free Software Foundation; either version 2.1 of the License, or |  | ||||||
| #  (at your option) any later version. |  | ||||||
| 
 |  | ||||||
| # This service will be placed in kdump initramfs and replace both the systemd |  | ||||||
| # emergency service and dracut emergency shell. IOW, any emergency will be |  | ||||||
| # kick this service and in turn isolating to kdump error handler. |  | ||||||
| 
 | 
 | ||||||
| [Unit] | [Unit] | ||||||
| Description=Kdump Emergency | Description=Kdump Error Handler | ||||||
| DefaultDependencies=no | DefaultDependencies=no | ||||||
| IgnoreOnIsolate=yes | After=systemd-vconsole-setup.service | ||||||
|  | Wants=systemd-vconsole-setup.service | ||||||
| 
 | 
 | ||||||
| [Service] | [Service] | ||||||
| ExecStart=/usr/bin/systemctl --no-block isolate kdump-error-handler.service | Environment=HOME=/ | ||||||
|  | Environment=DRACUT_SYSTEMD=1 | ||||||
|  | Environment=NEWROOT=/sysroot | ||||||
|  | WorkingDirectory=/ | ||||||
|  | ExecStart=/bin/kdump.sh --error-handler | ||||||
|  | ExecStopPost=-/bin/rm -f -- /.console_lock | ||||||
| Type=oneshot | Type=oneshot | ||||||
| StandardInput=tty-force | StandardInput=tty-force | ||||||
| StandardOutput=inherit | StandardOutput=inherit | ||||||
| StandardError=inherit | StandardError=inherit | ||||||
| KillMode=process | KillMode=process | ||||||
| IgnoreSIGPIPE=no | IgnoreSIGPIPE=no | ||||||
|  | TasksMax=infinity | ||||||
| 
 | 
 | ||||||
| # Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash | # Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash | ||||||
| # terminates cleanly. | # terminates cleanly. | ||||||
|  | |||||||
| @ -1,33 +0,0 @@ | |||||||
| #  This file is part of systemd. |  | ||||||
| # |  | ||||||
| #  systemd is free software; you can redistribute it and/or modify it |  | ||||||
| #  under the terms of the GNU Lesser General Public License as published by |  | ||||||
| #  the Free Software Foundation; either version 2.1 of the License, or |  | ||||||
| #  (at your option) any later version. |  | ||||||
| 
 |  | ||||||
| # This service will run the real kdump error handler code. Executing the |  | ||||||
| # failure action configured in kdump.conf |  | ||||||
| 
 |  | ||||||
| [Unit] |  | ||||||
| Description=Kdump Error Handler |  | ||||||
| DefaultDependencies=no |  | ||||||
| After=systemd-vconsole-setup.service |  | ||||||
| Wants=systemd-vconsole-setup.service |  | ||||||
| AllowIsolate=yes |  | ||||||
| 
 |  | ||||||
| [Service] |  | ||||||
| Environment=HOME=/ |  | ||||||
| Environment=DRACUT_SYSTEMD=1 |  | ||||||
| Environment=NEWROOT=/sysroot |  | ||||||
| WorkingDirectory=/ |  | ||||||
| ExecStart=/bin/kdump-error-handler.sh |  | ||||||
| Type=oneshot |  | ||||||
| StandardInput=tty-force |  | ||||||
| StandardOutput=inherit |  | ||||||
| StandardError=inherit |  | ||||||
| KillMode=process |  | ||||||
| IgnoreSIGPIPE=no |  | ||||||
| 
 |  | ||||||
| # Bash ignores SIGTERM, so we send SIGHUP instead, to ensure that bash |  | ||||||
| # terminates cleanly. |  | ||||||
| KillSignal=SIGHUP |  | ||||||
| @ -1,10 +0,0 @@ | |||||||
| #!/bin/sh |  | ||||||
| 
 |  | ||||||
| . /lib/kdump-lib-initramfs.sh |  | ||||||
| 
 |  | ||||||
| set -o pipefail |  | ||||||
| export PATH=$PATH:$KDUMP_SCRIPT_DIR |  | ||||||
| 
 |  | ||||||
| get_kdump_confs |  | ||||||
| do_failure_action |  | ||||||
| do_final_action |  | ||||||
| @ -1,324 +1,618 @@ | |||||||
| #!/bin/sh | #!/bin/sh | ||||||
| 
 | # | ||||||
| # continue here only if we have to save dump. | # The main kdump routine in capture kernel, bash may not be the | ||||||
| if [ -f /etc/fadump.initramfs ] && [ ! -f /proc/device-tree/rtas/ibm,kernel-dump ] && [ ! -f /proc/device-tree/ibm,opal/dump/mpipl-boot ]; then | # default shell. Any code added must be POSIX compliant. | ||||||
|     exit 0 |  | ||||||
| fi |  | ||||||
| 
 | 
 | ||||||
| . /lib/dracut-lib.sh | . /lib/dracut-lib.sh | ||||||
|  | . /lib/kdump-logger.sh | ||||||
| . /lib/kdump-lib-initramfs.sh | . /lib/kdump-lib-initramfs.sh | ||||||
| 
 | 
 | ||||||
| set -o pipefail | #initiate the kdump logger | ||||||
|  | if ! dlog_init; then | ||||||
|  | 	echo "failed to initiate the kdump logger." | ||||||
|  | 	exit 1 | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | KDUMP_PATH="/var/crash" | ||||||
|  | KDUMP_LOG_FILE="/run/initramfs/kexec-dmesg.log" | ||||||
|  | CORE_COLLECTOR="" | ||||||
|  | DEFAULT_CORE_COLLECTOR="makedumpfile -l --message-level 7 -d 31" | ||||||
|  | DMESG_COLLECTOR="/sbin/vmcore-dmesg" | ||||||
|  | FAILURE_ACTION="systemctl reboot -f" | ||||||
|  | DATEDIR=$(date +%Y-%m-%d-%T) | ||||||
|  | HOST_IP='127.0.0.1' | ||||||
|  | DUMP_INSTRUCTION="" | ||||||
|  | SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa" | ||||||
|  | DD_BLKSIZE=512 | ||||||
|  | FINAL_ACTION="systemctl reboot -f" | ||||||
|  | KDUMP_PRE="" | ||||||
|  | KDUMP_POST="" | ||||||
|  | NEWROOT="/sysroot" | ||||||
|  | OPALCORE="/sys/firmware/opal/mpipl/core" | ||||||
|  | KDUMP_CONF_PARSED="/tmp/kdump.conf.$$" | ||||||
|  | 
 | ||||||
|  | # POSIX doesn't have pipefail, only apply when using bash | ||||||
|  | # shellcheck disable=SC3040 | ||||||
|  | [ -n "$BASH" ] && set -o pipefail | ||||||
|  | 
 | ||||||
| DUMP_RETVAL=0 | DUMP_RETVAL=0 | ||||||
| 
 | 
 | ||||||
| export PATH=$PATH:$KDUMP_SCRIPT_DIR | kdump_read_conf > $KDUMP_CONF_PARSED | ||||||
|  | 
 | ||||||
|  | get_kdump_confs() | ||||||
|  | { | ||||||
|  | 	while read -r config_opt config_val; do | ||||||
|  | 		# remove inline comments after the end of a directive. | ||||||
|  | 		case "$config_opt" in | ||||||
|  | 		path) | ||||||
|  | 			KDUMP_PATH="$config_val" | ||||||
|  | 			;; | ||||||
|  | 		core_collector) | ||||||
|  | 			[ -n "$config_val" ] && CORE_COLLECTOR="$config_val" | ||||||
|  | 			;; | ||||||
|  | 		sshkey) | ||||||
|  | 			if [ -f "$config_val" ]; then | ||||||
|  | 				SSH_KEY_LOCATION=$config_val | ||||||
|  | 			fi | ||||||
|  | 			;; | ||||||
|  | 		kdump_pre) | ||||||
|  | 			KDUMP_PRE="$config_val" | ||||||
|  | 			;; | ||||||
|  | 		kdump_post) | ||||||
|  | 			KDUMP_POST="$config_val" | ||||||
|  | 			;; | ||||||
|  | 		fence_kdump_args) | ||||||
|  | 			FENCE_KDUMP_ARGS="$config_val" | ||||||
|  | 			;; | ||||||
|  | 		fence_kdump_nodes) | ||||||
|  | 			FENCE_KDUMP_NODES="$config_val" | ||||||
|  | 			;; | ||||||
|  | 		failure_action | default) | ||||||
|  | 			case $config_val in | ||||||
|  | 			shell) | ||||||
|  | 				FAILURE_ACTION="kdump_emergency_shell" | ||||||
|  | 				;; | ||||||
|  | 			reboot) | ||||||
|  | 				FAILURE_ACTION="systemctl reboot -f && exit" | ||||||
|  | 				;; | ||||||
|  | 			halt) | ||||||
|  | 				FAILURE_ACTION="halt && exit" | ||||||
|  | 				;; | ||||||
|  | 			poweroff) | ||||||
|  | 				FAILURE_ACTION="systemctl poweroff -f && exit" | ||||||
|  | 				;; | ||||||
|  | 			dump_to_rootfs) | ||||||
|  | 				FAILURE_ACTION="dump_to_rootfs" | ||||||
|  | 				;; | ||||||
|  | 			esac | ||||||
|  | 			;; | ||||||
|  | 		final_action) | ||||||
|  | 			case $config_val in | ||||||
|  | 			reboot) | ||||||
|  | 				FINAL_ACTION="systemctl reboot -f" | ||||||
|  | 				;; | ||||||
|  | 			halt) | ||||||
|  | 				FINAL_ACTION="halt" | ||||||
|  | 				;; | ||||||
|  | 			poweroff) | ||||||
|  | 				FINAL_ACTION="systemctl poweroff -f" | ||||||
|  | 				;; | ||||||
|  | 			esac | ||||||
|  | 			;; | ||||||
|  | 		esac | ||||||
|  | 	done < "$KDUMP_CONF_PARSED" | ||||||
|  | 
 | ||||||
|  | 	if [ -z "$CORE_COLLECTOR" ]; then | ||||||
|  | 		CORE_COLLECTOR="$DEFAULT_CORE_COLLECTOR" | ||||||
|  | 		if is_ssh_dump_target || is_raw_dump_target; then | ||||||
|  | 			CORE_COLLECTOR="$CORE_COLLECTOR -F" | ||||||
|  | 		fi | ||||||
|  | 	fi | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | # store the kexec kernel log to a file. | ||||||
|  | save_log() | ||||||
|  | { | ||||||
|  | 	dmesg -T > $KDUMP_LOG_FILE | ||||||
|  | 
 | ||||||
|  | 	if command -v journalctl > /dev/null; then | ||||||
|  | 		journalctl -ab >> $KDUMP_LOG_FILE | ||||||
|  | 	fi | ||||||
|  | 	chmod 600 $KDUMP_LOG_FILE | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | # $1: dump path, must be a mount point | ||||||
|  | dump_fs() | ||||||
|  | { | ||||||
|  | 	ddebug "dump_fs _mp=$1" | ||||||
|  | 
 | ||||||
|  | 	if ! is_mounted "$1"; then | ||||||
|  | 		dinfo "dump path '$1' is not mounted, trying to mount..." | ||||||
|  | 		if ! mount --target "$1"; then | ||||||
|  | 			derror "failed to dump to '$1', it's not a mount point!" | ||||||
|  | 			return 1 | ||||||
|  | 		fi | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	# Remove -F in makedumpfile case. We don't want a flat format dump here. | ||||||
|  | 	case $CORE_COLLECTOR in | ||||||
|  | 	*makedumpfile*) | ||||||
|  | 		CORE_COLLECTOR=$(echo "$CORE_COLLECTOR" | sed -e "s/-F//g") | ||||||
|  | 		;; | ||||||
|  | 	esac | ||||||
|  | 
 | ||||||
|  | 	_dump_fs_path=$(echo "$1/$KDUMP_PATH/$HOST_IP-$DATEDIR/" | tr -s /) | ||||||
|  | 	dinfo "saving to $_dump_fs_path" | ||||||
|  | 
 | ||||||
|  | 	# Only remount to read-write mode if the dump target is mounted read-only. | ||||||
|  | 	_dump_mnt_op=$(get_mount_info OPTIONS target "$1" -f) | ||||||
|  | 	case $_dump_mnt_op in | ||||||
|  | 	ro*) | ||||||
|  | 		dinfo "Remounting the dump target in rw mode." | ||||||
|  | 		mount -o remount,rw "$1" || return 1 | ||||||
|  | 		;; | ||||||
|  | 	esac | ||||||
|  | 
 | ||||||
|  | 	mkdir -p "$_dump_fs_path" || return 1 | ||||||
|  | 
 | ||||||
|  | 	save_vmcore_dmesg_fs ${DMESG_COLLECTOR} "$_dump_fs_path" | ||||||
|  | 	save_opalcore_fs "$_dump_fs_path" | ||||||
|  | 
 | ||||||
|  | 	dinfo "saving vmcore" | ||||||
|  | 	$CORE_COLLECTOR /proc/vmcore "$_dump_fs_path/vmcore-incomplete" | ||||||
|  | 	_dump_exitcode=$? | ||||||
|  | 	if [ $_dump_exitcode -eq 0 ]; then | ||||||
|  | 		sync -f "$_dump_fs_path/vmcore-incomplete" | ||||||
|  | 		_sync_exitcode=$? | ||||||
|  | 		if [ $_sync_exitcode -eq 0 ]; then | ||||||
|  | 			mv "$_dump_fs_path/vmcore-incomplete" "$_dump_fs_path/vmcore" | ||||||
|  | 			dinfo "saving vmcore complete" | ||||||
|  | 		else | ||||||
|  | 			derror "sync vmcore failed, exitcode:$_sync_exitcode" | ||||||
|  | 			return 1 | ||||||
|  | 		fi | ||||||
|  | 	else | ||||||
|  | 		derror "saving vmcore failed, exitcode:$_dump_exitcode" | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	dinfo "saving the $KDUMP_LOG_FILE to $_dump_fs_path/" | ||||||
|  | 	save_log | ||||||
|  | 	mv "$KDUMP_LOG_FILE" "$_dump_fs_path/" | ||||||
|  | 	if [ $_dump_exitcode -ne 0 ]; then | ||||||
|  | 		return 1 | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	# improper kernel cmdline can cause the failure of echo, we can ignore this kind of failure | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | # $1: dmesg collector | ||||||
|  | # $2: dump path | ||||||
|  | save_vmcore_dmesg_fs() | ||||||
|  | { | ||||||
|  | 	dinfo "saving vmcore-dmesg.txt to $2" | ||||||
|  | 	if $1 /proc/vmcore > "$2/vmcore-dmesg-incomplete.txt"; then | ||||||
|  | 		mv "$2/vmcore-dmesg-incomplete.txt" "$2/vmcore-dmesg.txt" | ||||||
|  | 		chmod 600 "$2/vmcore-dmesg.txt" | ||||||
|  | 
 | ||||||
|  | 		# Make sure file is on disk. There have been instances where later | ||||||
|  | 		# saving vmcore failed and system rebooted without sync and there | ||||||
|  | 		# was no vmcore-dmesg.txt available. | ||||||
|  | 		sync | ||||||
|  | 		dinfo "saving vmcore-dmesg.txt complete" | ||||||
|  | 	else | ||||||
|  | 		if [ -f "$2/vmcore-dmesg-incomplete.txt" ]; then | ||||||
|  | 			chmod 600 "$2/vmcore-dmesg-incomplete.txt" | ||||||
|  | 		fi | ||||||
|  | 		derror "saving vmcore-dmesg.txt failed" | ||||||
|  | 	fi | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | # $1: dump path | ||||||
|  | save_opalcore_fs() | ||||||
|  | { | ||||||
|  | 	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 | ||||||
|  | 
 | ||||||
|  | 	dinfo "saving opalcore:$OPALCORE to $1/opalcore" | ||||||
|  | 	if ! cp $OPALCORE "$1/opalcore"; then | ||||||
|  | 		derror "saving opalcore failed" | ||||||
|  | 		return 1 | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	sync | ||||||
|  | 	dinfo "saving opalcore complete" | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | dump_to_rootfs() | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | 	if [ "$(systemctl status dracut-initqueue | sed -n "s/^\s*Active: \(\S*\)\s.*$/\1/p")" = "inactive" ]; then | ||||||
|  | 		dinfo "Trying to bring up initqueue for rootfs mount" | ||||||
|  | 		systemctl start dracut-initqueue | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	dinfo "Clean up dead systemd services" | ||||||
|  | 	systemctl cancel | ||||||
|  | 	dinfo "Waiting for rootfs mount, will timeout after 90 seconds" | ||||||
|  | 	systemctl start --no-block sysroot.mount | ||||||
|  | 
 | ||||||
|  | 	_loop=0 | ||||||
|  | 	while [ $_loop -lt 90 ] && ! is_mounted /sysroot; do | ||||||
|  | 		sleep 1 | ||||||
|  | 		_loop=$((_loop + 1)) | ||||||
|  | 	done | ||||||
|  | 
 | ||||||
|  | 	if ! is_mounted /sysroot; then | ||||||
|  | 		derror "Failed to mount rootfs" | ||||||
|  | 		return | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	ddebug "NEWROOT=$NEWROOT" | ||||||
|  | 	dump_fs $NEWROOT | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | kdump_emergency_shell() | ||||||
|  | { | ||||||
|  | 	ddebug "Switching to kdump emergency shell..." | ||||||
|  | 
 | ||||||
|  | 	[ -f /etc/profile ] && . /etc/profile | ||||||
|  | 	export PS1='kdump:${PWD}# ' | ||||||
|  | 
 | ||||||
|  | 	. /lib/dracut-lib.sh | ||||||
|  | 	if [ -f /dracut-state.sh ]; then | ||||||
|  | 		. /dracut-state.sh 2> /dev/null | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	source_conf /etc/conf.d | ||||||
|  | 
 | ||||||
|  | 	type plymouth > /dev/null 2>&1 && plymouth quit | ||||||
|  | 
 | ||||||
|  | 	source_hook "emergency" | ||||||
|  | 	while read -r _tty rest; do | ||||||
|  | 		( | ||||||
|  | 			echo | ||||||
|  | 			echo | ||||||
|  | 			echo 'Entering kdump emergency mode.' | ||||||
|  | 			echo 'Type "journalctl" to view system logs.' | ||||||
|  | 			echo 'Type "rdsosreport" to generate a sosreport, you can then' | ||||||
|  | 			echo 'save it elsewhere and attach it to a bug report.' | ||||||
|  | 			echo | ||||||
|  | 			echo | ||||||
|  | 		) > "/dev/$_tty" | ||||||
|  | 	done < /proc/consoles | ||||||
|  | 	sh -i -l | ||||||
|  | 	/bin/rm -f -- /.console_lock | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | do_failure_action() | ||||||
|  | { | ||||||
|  | 	dinfo "Executing failure action $FAILURE_ACTION" | ||||||
|  | 	eval $FAILURE_ACTION | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | do_final_action() | ||||||
|  | { | ||||||
|  | 	dinfo "Executing final action $FINAL_ACTION" | ||||||
|  | 	eval $FINAL_ACTION | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| do_dump() | do_dump() | ||||||
| { | { | ||||||
|     local _ret | 	eval $DUMP_INSTRUCTION | ||||||
|  | 	_ret=$? | ||||||
| 
 | 
 | ||||||
|     eval $DUMP_INSTRUCTION | 	if [ $_ret -ne 0 ]; then | ||||||
|     _ret=$? | 		derror "saving vmcore failed" | ||||||
|  | 	fi | ||||||
| 
 | 
 | ||||||
|     if [ $_ret -ne 0 ]; then | 	return $_ret | ||||||
|         derror "saving vmcore failed" |  | ||||||
|     fi |  | ||||||
| 
 |  | ||||||
|     return $_ret |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| do_kdump_pre() | do_kdump_pre() | ||||||
| { | { | ||||||
|     local _ret | 	if [ -n "$KDUMP_PRE" ]; then | ||||||
|  | 		"$KDUMP_PRE" | ||||||
|  | 		_ret=$? | ||||||
|  | 		if [ $_ret -ne 0 ]; then | ||||||
|  | 			derror "$KDUMP_PRE exited with $_ret status" | ||||||
|  | 			return $_ret | ||||||
|  | 		fi | ||||||
|  | 	fi | ||||||
| 
 | 
 | ||||||
|     if [ -n "$KDUMP_PRE" ]; then | 	# if any script fails, it just raises warning and continues | ||||||
|         "$KDUMP_PRE" | 	if [ -d /etc/kdump/pre.d ]; then | ||||||
|         _ret=$? | 		for file in /etc/kdump/pre.d/*; do | ||||||
|         if [ $_ret -ne 0 ]; then | 			"$file" | ||||||
|             derror "$KDUMP_PRE exited with $_ret status" | 			_ret=$? | ||||||
|             return $_ret | 			if [ $_ret -ne 0 ]; then | ||||||
|         fi | 				derror "$file exited with $_ret status" | ||||||
|     fi | 			fi | ||||||
| 
 | 		done | ||||||
|     # if any script fails, it just raises warning and continues | 	fi | ||||||
|     if [ -d /etc/kdump/pre.d ]; then | 	return 0 | ||||||
|         for file in /etc/kdump/pre.d/*; do |  | ||||||
|             "$file" |  | ||||||
|             _ret=$? |  | ||||||
|             if [ $_ret -ne 0 ]; then |  | ||||||
|                 derror "$file exited with $_ret status" |  | ||||||
|             fi |  | ||||||
|         done |  | ||||||
|     fi |  | ||||||
|     return 0 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| do_kdump_post() | 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 | ||||||
|  | 				derror "$file exited with $_ret status" | ||||||
|  | 			fi | ||||||
|  | 		done | ||||||
|  | 	fi | ||||||
| 
 | 
 | ||||||
|     if [ -d /etc/kdump/post.d ]; then | 	if [ -n "$KDUMP_POST" ]; then | ||||||
|         for file in /etc/kdump/post.d/*; do | 		"$KDUMP_POST" "$1" | ||||||
|             "$file" "$1" | 		_ret=$? | ||||||
|             _ret=$? | 		if [ $_ret -ne 0 ]; then | ||||||
|             if [ $_ret -ne 0 ]; then | 			derror "$KDUMP_POST exited with $_ret status" | ||||||
|                 derror "$file exited with $_ret status" | 		fi | ||||||
|             fi | 	fi | ||||||
|         done |  | ||||||
|     fi |  | ||||||
| 
 |  | ||||||
|     if [ -n "$KDUMP_POST" ]; then |  | ||||||
|         "$KDUMP_POST" "$1" |  | ||||||
|         _ret=$? |  | ||||||
|         if [ $_ret -ne 0 ]; then |  | ||||||
|             derror "$KDUMP_POST exited with $_ret status" |  | ||||||
|         fi |  | ||||||
|     fi |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| add_dump_code() |  | ||||||
| { |  | ||||||
|     DUMP_INSTRUCTION=$1 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | # $1: block target, eg. /dev/sda | ||||||
| dump_raw() | dump_raw() | ||||||
| { | { | ||||||
|     local _raw=$1 | 	[ -b "$1" ] || return 1 | ||||||
| 
 | 
 | ||||||
|     [ -b "$_raw" ] || return 1 | 	dinfo "saving to raw disk $1" | ||||||
| 
 | 
 | ||||||
|     dinfo "saving to raw disk $_raw" | 	if ! echo "$CORE_COLLECTOR" | grep -q makedumpfile; then | ||||||
|  | 		_src_size=$(stat --format %s /proc/vmcore) | ||||||
|  | 		_src_size_mb=$((_src_size / 1048576)) | ||||||
|  | 		/kdumpscripts/monitor_dd_progress $_src_size_mb & | ||||||
|  | 	fi | ||||||
| 
 | 
 | ||||||
|     if ! $(echo -n $CORE_COLLECTOR|grep -q makedumpfile); then | 	dinfo "saving vmcore" | ||||||
|         _src_size=`ls -l /proc/vmcore | cut -d' ' -f5` | 	$CORE_COLLECTOR /proc/vmcore | dd of="$1" bs=$DD_BLKSIZE >> /tmp/dd_progress_file 2>&1 || return 1 | ||||||
|         _src_size_mb=$(($_src_size / 1048576)) | 	sync | ||||||
|         monitor_dd_progress $_src_size_mb & |  | ||||||
|     fi |  | ||||||
| 
 | 
 | ||||||
|     dinfo "saving vmcore" | 	dinfo "saving vmcore complete" | ||||||
|     $CORE_COLLECTOR /proc/vmcore | dd of=$_raw bs=$DD_BLKSIZE >> /tmp/dd_progress_file 2>&1 || return 1 | 	return 0 | ||||||
|     sync |  | ||||||
| 
 |  | ||||||
|     dinfo "saving vmcore complete" |  | ||||||
|     return 0 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | # $1: ssh key file | ||||||
|  | # $2: ssh address in <user>@<host> format | ||||||
| dump_ssh() | dump_ssh() | ||||||
| { | { | ||||||
|     local _ret=0 | 	_ret=0 | ||||||
|     local _exitcode=0 _exitcode2=0 | 	_ssh_opt="-i $1 -o BatchMode=yes -o StrictHostKeyChecking=yes" | ||||||
|     local _opt="-i $1 -o BatchMode=yes -o StrictHostKeyChecking=yes" | 	_ssh_dir="$KDUMP_PATH/$HOST_IP-$DATEDIR" | ||||||
|     local _dir="$KDUMP_PATH/$HOST_IP-$DATEDIR" | 	if is_ipv6_address "$2"; then | ||||||
|     local _host=$2 | 		_scp_address=${2%@*}@"[${2#*@}]" | ||||||
|     local _vmcore="vmcore" | 	else | ||||||
|     local _ipv6_addr="" _username="" | 		_scp_address=$2 | ||||||
|  | 	fi | ||||||
| 
 | 
 | ||||||
|     dinfo "saving to $_host:$_dir" | 	dinfo "saving to $2:$_ssh_dir" | ||||||
| 
 | 
 | ||||||
|     cat /var/lib/random-seed > /dev/urandom | 	cat /var/lib/random-seed > /dev/urandom | ||||||
|     ssh -q $_opt $_host mkdir -p $_dir || return 1 | 	ssh -q $_ssh_opt "$2" mkdir -p "$_ssh_dir" || return 1 | ||||||
| 
 | 
 | ||||||
|     save_vmcore_dmesg_ssh ${DMESG_COLLECTOR} ${_dir} "${_opt}" $_host | 	save_vmcore_dmesg_ssh "$DMESG_COLLECTOR" "$_ssh_dir" "$_ssh_opt" "$2" | ||||||
|     save_opalcore_ssh ${_dir} "${_opt}" $_host | 	dinfo "saving vmcore" | ||||||
| 
 | 
 | ||||||
|     dinfo "saving vmcore" | 	save_opalcore_ssh "$_ssh_dir" "$_ssh_opt" "$2" "$_scp_address" | ||||||
| 
 | 
 | ||||||
|     if is_ipv6_address "$_host"; then | 	if [ "${CORE_COLLECTOR%%[[:blank:]]*}" = "scp" ]; then | ||||||
|         _username=${_host%@*} | 		scp -q $_ssh_opt /proc/vmcore "$_scp_address:$_ssh_dir/vmcore-incomplete" | ||||||
|         _ipv6_addr="[${_host#*@}]" | 		_ret=$? | ||||||
|     fi | 		_vmcore="vmcore" | ||||||
|  | 	else | ||||||
|  | 		$CORE_COLLECTOR /proc/vmcore | ssh $_ssh_opt "$2" "umask 0077 && dd bs=512 of='$_ssh_dir/vmcore-incomplete'" | ||||||
|  | 		_ret=$? | ||||||
|  | 		_vmcore="vmcore.flat" | ||||||
|  | 	fi | ||||||
| 
 | 
 | ||||||
|     if [ "${CORE_COLLECTOR%%[[:blank:]]*}" = "scp" ]; then | 	if [ $_ret -eq 0 ]; then | ||||||
|         if [ -n "$_username" ] && [ -n "$_ipv6_addr" ]; then | 		ssh $_ssh_opt "$2" "mv '$_ssh_dir/vmcore-incomplete' '$_ssh_dir/$_vmcore'" | ||||||
|             scp -q $_opt /proc/vmcore "$_username@$_ipv6_addr:$_dir/vmcore-incomplete" | 		_ret=$? | ||||||
|         else | 		if [ $_ret -ne 0 ]; then | ||||||
|             scp -q $_opt /proc/vmcore "$_host:$_dir/vmcore-incomplete" | 			derror "moving vmcore failed, exitcode:$_ret" | ||||||
|         fi | 		else | ||||||
|         _exitcode=$? | 			dinfo "saving vmcore complete" | ||||||
|     else | 		fi | ||||||
|         $CORE_COLLECTOR /proc/vmcore | ssh $_opt $_host "umask 0077 && dd bs=512 of=$_dir/vmcore-incomplete" | 	else | ||||||
|         _exitcode=$? | 		derror "saving vmcore failed, exitcode:$_ret" | ||||||
|         _vmcore="vmcore.flat" | 	fi | ||||||
|     fi |  | ||||||
| 
 | 
 | ||||||
|     if [ $_exitcode -eq 0 ]; then | 	dinfo "saving the $KDUMP_LOG_FILE to $2:$_ssh_dir/" | ||||||
|         ssh $_opt $_host "mv $_dir/vmcore-incomplete $_dir/$_vmcore" | 	save_log | ||||||
|         _exitcode2=$? | 	if ! scp -q $_ssh_opt $KDUMP_LOG_FILE "$_scp_address:$_ssh_dir/"; then | ||||||
|         if [ $_exitcode2 -ne 0 ]; then | 		derror "saving log file failed, _exitcode:$_ret" | ||||||
|             derror "moving vmcore failed, _exitcode:$_exitcode2" | 	fi | ||||||
|         else |  | ||||||
|             dinfo "saving vmcore complete" |  | ||||||
|         fi |  | ||||||
|     else |  | ||||||
|         derror "saving vmcore failed, _exitcode:$_exitcode" |  | ||||||
|     fi |  | ||||||
| 
 | 
 | ||||||
|     dinfo "saving the $KDUMP_LOG_FILE to $_host:$_dir/" | 	return $_ret | ||||||
|     save_log |  | ||||||
|     if [ -n "$_username" ] && [ -n "$_ipv6_addr" ]; then |  | ||||||
|         scp -q $_opt $KDUMP_LOG_FILE "$_username@$_ipv6_addr:$_dir/" |  | ||||||
|     else |  | ||||||
|         scp -q $_opt $KDUMP_LOG_FILE "$_host:$_dir/" |  | ||||||
|     fi |  | ||||||
|     _ret=$? |  | ||||||
|     if [ $_ret -ne 0 ]; then |  | ||||||
|         derror "saving log file failed, _exitcode:$_ret" |  | ||||||
|     fi |  | ||||||
| 
 |  | ||||||
|     if [ $_exitcode -ne 0 ] || [ $_exitcode2 -ne 0 ];then |  | ||||||
|         return 1 |  | ||||||
|     fi |  | ||||||
| 
 |  | ||||||
|     return 0 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| save_opalcore_ssh() { | # $1: dump path | ||||||
|     local _path=$1 | # $2: ssh opts | ||||||
|     local _opts="$2" | # $3: ssh address in <user>@<host> format | ||||||
|     local _location=$3 | # $4: scp address, similar with ssh address but IPv6 addresses are quoted | ||||||
|     local _user_name="" _ipv6addr="" | save_opalcore_ssh() | ||||||
|  | { | ||||||
|  | 	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 | ||||||
| 
 | 
 | ||||||
|     ddebug "_path=$_path _opts=$_opts _location=$_location" | 	dinfo "saving opalcore:$OPALCORE to $3:$1" | ||||||
| 
 | 
 | ||||||
|     if [ ! -f $OPALCORE ]; then | 	if ! scp $2 $OPALCORE "$4:$1/opalcore-incomplete"; then | ||||||
|         # Check if we are on an old kernel that uses a different path | 		derror "saving opalcore failed" | ||||||
|         if [ -f /sys/firmware/opal/core ]; then | 		return 1 | ||||||
|             OPALCORE="/sys/firmware/opal/core" | 	fi | ||||||
|         else |  | ||||||
|             return 0 |  | ||||||
|         fi |  | ||||||
|     fi |  | ||||||
| 
 | 
 | ||||||
|     if is_ipv6_address "$_host"; then | 	ssh $2 "$3" mv "$1/opalcore-incomplete" "$1/opalcore" | ||||||
|         _user_name=${_location%@*} | 	dinfo "saving opalcore complete" | ||||||
|         _ipv6addr="[${_location#*@}]" | 	return 0 | ||||||
|     fi |  | ||||||
| 
 |  | ||||||
|     dinfo "saving opalcore:$OPALCORE to $_location:$_path" |  | ||||||
| 
 |  | ||||||
|     if [ -n "$_user_name" ] && [ -n "$_ipv6addr" ]; then |  | ||||||
|         scp $_opts $OPALCORE $_user_name@$_ipv6addr:$_path/opalcore-incomplete |  | ||||||
|     else |  | ||||||
|         scp $_opts $OPALCORE $_location:$_path/opalcore-incomplete |  | ||||||
|     fi |  | ||||||
|     if [ $? -ne 0 ]; then |  | ||||||
|         derror "saving opalcore failed" |  | ||||||
|        return 1 |  | ||||||
|     fi |  | ||||||
| 
 |  | ||||||
|     ssh $_opts $_location mv $_path/opalcore-incomplete $_path/opalcore |  | ||||||
|     dinfo "saving opalcore complete" |  | ||||||
|     return 0 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| save_vmcore_dmesg_ssh() { | # $1: dmesg collector | ||||||
|     local _dmesg_collector=$1 | # $2: dump path | ||||||
|     local _path=$2 | # $3: ssh opts | ||||||
|     local _opts="$3" | # $4: ssh address in <user>@<host> format | ||||||
|     local _location=$4 | save_vmcore_dmesg_ssh() | ||||||
|  | { | ||||||
|  | 	dinfo "saving vmcore-dmesg.txt to $4:$2" | ||||||
|  | 	if $1 /proc/vmcore | ssh $3 "$4" "umask 0077 && dd of='$2/vmcore-dmesg-incomplete.txt'"; then | ||||||
|  | 		ssh -q $3 "$4" mv "$2/vmcore-dmesg-incomplete.txt" "$2/vmcore-dmesg.txt" | ||||||
|  | 		dinfo "saving vmcore-dmesg.txt complete" | ||||||
|  | 	else | ||||||
|  | 		derror "saving vmcore-dmesg.txt failed" | ||||||
|  | 	fi | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
|     dinfo "saving vmcore-dmesg.txt to $_location:$_path" | wait_online_network() | ||||||
|     $_dmesg_collector /proc/vmcore | ssh $_opts $_location "umask 0077 && dd of=$_path/vmcore-dmesg-incomplete.txt" | { | ||||||
|     _exitcode=$? | 	# In some cases, network may still not be ready because nm-online is called | ||||||
|  | 	# with "-s" which means to wait for NetworkManager startup to complete, rather | ||||||
|  | 	# than waiting for network connectivity specifically. Wait 10mins more for the | ||||||
|  | 	# network to be truely ready in these cases. | ||||||
|  | 	_loop=0 | ||||||
|  | 	while [ $_loop -lt 600 ]; do | ||||||
|  | 		sleep 1 | ||||||
|  | 		_loop=$((_loop + 1)) | ||||||
|  | 		if _route=$(kdump_get_ip_route "$1" 2> /dev/null); then | ||||||
|  | 			printf "%s" "$_route" | ||||||
|  | 			return | ||||||
|  | 		else | ||||||
|  | 			dwarn "Waiting for network to be ready (${_loop}s / 10min)" | ||||||
|  | 		fi | ||||||
|  | 	done | ||||||
| 
 | 
 | ||||||
|     if [ $_exitcode -eq 0 ]; then | 	derror "Oops. The network still isn't ready after waiting 10mins." | ||||||
|         ssh -q $_opts $_location mv $_path/vmcore-dmesg-incomplete.txt $_path/vmcore-dmesg.txt | 	exit 1 | ||||||
|         dinfo "saving vmcore-dmesg.txt complete" |  | ||||||
|     else |  | ||||||
|         derror "saving vmcore-dmesg.txt failed" |  | ||||||
|     fi |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| get_host_ip() | get_host_ip() | ||||||
| { | { | ||||||
|     local _host | 
 | ||||||
|     if is_nfs_dump_target || is_ssh_dump_target | 	if ! is_nfs_dump_target && ! is_ssh_dump_target; then | ||||||
|     then | 		return 0 | ||||||
|         kdumpnic=$(getarg kdumpnic=) | 	fi | ||||||
|         [ -z "$kdumpnic" ] && derror "failed to get kdumpnic!" && return 1 | 
 | ||||||
|         _host=`ip addr show dev $kdumpnic|grep '[ ]*inet'` | 	_kdump_remote_ip=$(getarg kdump_remote_ip=) | ||||||
|         [ $? -ne 0 ] && derror "wrong kdumpnic: $kdumpnic" && return 1 | 
 | ||||||
|         _host=`echo $_host | head -n 1 | cut -d' ' -f2` | 	if [ -z "$_kdump_remote_ip" ]; then | ||||||
|         _host="${_host%%/*}" | 		derror "failed to get remote IP address!" | ||||||
|         [ -z "$_host" ] && derror "wrong kdumpnic: $kdumpnic" && return 1 | 		return 1 | ||||||
|         HOST_IP=$_host | 	fi | ||||||
|     fi | 
 | ||||||
|     return 0 | 	if ! _route=$(wait_online_network "$_kdump_remote_ip"); then | ||||||
|  | 		return 1 | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	_netdev=$(kdump_get_ip_route_field "$_route" "dev") | ||||||
|  | 
 | ||||||
|  | 	if ! _kdumpip=$(ip addr show dev "$_netdev" | grep '[ ]*inet'); then | ||||||
|  | 		derror "Failed to get IP of $_netdev" | ||||||
|  | 		return 1 | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	_kdumpip=$(echo "$_kdumpip" | head -n 1 | awk '{print $2}') | ||||||
|  | 	_kdumpip="${_kdumpip%%/*}" | ||||||
|  | 	HOST_IP=$_kdumpip | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| read_kdump_conf() | read_kdump_confs() | ||||||
| { | { | ||||||
|     if [ ! -f "$KDUMP_CONF" ]; then | 	if [ ! -f "$KDUMP_CONFIG_FILE" ]; then | ||||||
|         derror "$KDUMP_CONF not found" | 		derror "$KDUMP_CONFIG_FILE not found" | ||||||
|         return | 		return | ||||||
|     fi | 	fi | ||||||
| 
 | 
 | ||||||
|     get_kdump_confs | 	get_kdump_confs | ||||||
| 
 | 
 | ||||||
|     # rescan for add code for dump target | 	# rescan for add code for dump target | ||||||
|     while read config_opt config_val; | 	while read -r config_opt config_val; do | ||||||
|     do | 		# remove inline comments after the end of a directive. | ||||||
|         # remove inline comments after the end of a directive. | 		case "$config_opt" in | ||||||
|         case "$config_opt" in | 		dracut_args) | ||||||
|         dracut_args) | 			config_val=$(get_dracut_args_target "$config_val") | ||||||
|             config_val=$(get_dracut_args_target "$config_val") | 			if [ -n "$config_val" ]; then | ||||||
|             if [ -n "$config_val" ]; then | 				config_val=$(get_mntpoint_from_target "$config_val") | ||||||
|                 config_val=$(get_mntpoint_from_target "$config_val") | 				DUMP_INSTRUCTION="dump_fs $config_val" | ||||||
|                 add_dump_code "dump_fs $config_val" | 			fi | ||||||
|             fi | 			;; | ||||||
|             ;; | 		ext[234] | xfs | btrfs | minix | nfs | virtiofs) | ||||||
|         ext[234]|xfs|btrfs|minix|nfs) | 			config_val=$(get_mntpoint_from_target "$config_val") | ||||||
|             config_val=$(get_mntpoint_from_target "$config_val") | 			DUMP_INSTRUCTION="dump_fs $config_val" | ||||||
|             add_dump_code "dump_fs $config_val" | 			;; | ||||||
|             ;; | 		raw) | ||||||
|         raw) | 			DUMP_INSTRUCTION="dump_raw $config_val" | ||||||
|             add_dump_code "dump_raw $config_val" | 			;; | ||||||
|             ;; | 		ssh) | ||||||
|         ssh) | 			DUMP_INSTRUCTION="dump_ssh $SSH_KEY_LOCATION $config_val" | ||||||
|             add_dump_code "dump_ssh $SSH_KEY_LOCATION $config_val" | 			;; | ||||||
|             ;; | 		esac | ||||||
|         esac | 	done < "$KDUMP_CONF_PARSED" | ||||||
|     done <<< "$(read_strip_comments $KDUMP_CONF)" |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fence_kdump_notify() | fence_kdump_notify() | ||||||
| { | { | ||||||
|     if [ -n "$FENCE_KDUMP_NODES" ]; then | 	if [ -n "$FENCE_KDUMP_NODES" ]; then | ||||||
|         $FENCE_KDUMP_SEND $FENCE_KDUMP_ARGS $FENCE_KDUMP_NODES & | 		# shellcheck disable=SC2086 | ||||||
|     fi | 		$FENCE_KDUMP_SEND $FENCE_KDUMP_ARGS $FENCE_KDUMP_NODES & | ||||||
|  | 	fi | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| read_kdump_conf | if [ "$1" = "--error-handler" ]; then | ||||||
|  | 	get_kdump_confs | ||||||
|  | 	do_failure_action | ||||||
|  | 	do_final_action | ||||||
|  | 
 | ||||||
|  | 	exit $? | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | # continue here only if we have to save dump. | ||||||
|  | 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 | ||||||
|  | 
 | ||||||
|  | read_kdump_confs | ||||||
| fence_kdump_notify | fence_kdump_notify | ||||||
| 
 | 
 | ||||||
| get_host_ip | if ! get_host_ip; then | ||||||
| if [ $? -ne 0 ]; then | 	derror "get_host_ip exited with non-zero status!" | ||||||
|     derror "get_host_ip exited with non-zero status!" | 	exit 1 | ||||||
|     exit 1 |  | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| if [ -z "$DUMP_INSTRUCTION" ]; then | if [ -z "$DUMP_INSTRUCTION" ]; then | ||||||
|     add_dump_code "dump_fs $NEWROOT" | 	DUMP_INSTRUCTION="dump_fs $NEWROOT" | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| do_kdump_pre | if ! do_kdump_pre; then | ||||||
| if [ $? -ne 0 ]; then | 	derror "kdump_pre script exited with non-zero status!" | ||||||
|     derror "kdump_pre script exited with non-zero status!" | 	do_final_action | ||||||
|     do_final_action | 	# During systemd service to reboot the machine, stop this shell script running | ||||||
|     # During systemd service to reboot the machine, stop this shell script running | 	exit 1 | ||||||
|     exit 1 |  | ||||||
| fi | fi | ||||||
| make_trace_mem "kdump saving vmcore" '1:shortmem' '2+:mem' '3+:slab' | make_trace_mem "kdump saving vmcore" '1:shortmem' '2+:mem' '3+:slab' | ||||||
| do_dump | do_dump | ||||||
| DUMP_RETVAL=$? | DUMP_RETVAL=$? | ||||||
| 
 | 
 | ||||||
| do_kdump_post $DUMP_RETVAL | if ! do_kdump_post $DUMP_RETVAL; then | ||||||
| if [ $? -ne 0 ]; then | 	derror "kdump_post script exited with non-zero status!" | ||||||
|     derror "kdump_post script exited with non-zero status!" |  | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| if [ $DUMP_RETVAL -ne 0 ]; then | if [ $DUMP_RETVAL -ne 0 ]; then | ||||||
|     exit 1 | 	exit 1 | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| do_final_action | do_final_action | ||||||
|  | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -39,7 +39,7 @@ kernel are one and the same on ppc64. | |||||||
| If you're reading this document, you should already have kexec-tools | If you're reading this document, you should already have kexec-tools | ||||||
| installed. If not, you install it via the following command: | installed. If not, you install it via the following command: | ||||||
| 
 | 
 | ||||||
|     # yum install kexec-tools |     # dnf install kexec-tools | ||||||
| 
 | 
 | ||||||
| Fadump Operational Flow: | Fadump Operational Flow: | ||||||
| 
 | 
 | ||||||
| @ -82,7 +82,7 @@ How to configure fadump: | |||||||
| Again, we assume if you're reading this document, you should already have | 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: | kexec-tools installed. If not, you install it via the following command: | ||||||
| 
 | 
 | ||||||
|     # yum install kexec-tools |     # dnf install kexec-tools | ||||||
| 
 | 
 | ||||||
| Make the kernel to be configured with FADump as the default boot entry, if | Make the kernel to be configured with FADump as the default boot entry, if | ||||||
| it isn't already: | it isn't already: | ||||||
| @ -94,20 +94,24 @@ 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 | the kernel-debuginfo package, of the same arch as your running kernel, and the | ||||||
| crash utility: | crash utility: | ||||||
| 
 | 
 | ||||||
|     # yum --enablerepo=\*debuginfo install kernel-debuginfo.$(uname -m) crash |     # dnf --enablerepo=\*debuginfo install kernel-debuginfo.$(uname -m) crash | ||||||
| 
 | 
 | ||||||
| Next up, we need to modify some boot parameters to enable firmware assisted | Next up, we can enable firmware assisted dump and reserve the memory for boot | ||||||
| dump. With the help of grubby, it's very easy to append "fadump=on" to the end | memory preservation as specified in in the table of 'FADump Memory Requirements' | ||||||
| of your kernel boot parameters. To reserve the appropriate amount of memory | section: | ||||||
| for boot memory preservation, pass 'crashkernel=X' kernel cmdline parameter. | 
 | ||||||
| For the recommended value of X, see 'FADump Memory Requirements' section. |    # kdumpctl reset-crashkernel --fadump=on | ||||||
|  | 
 | ||||||
|  | Alternatively, you can use grubby to reserve custom amount of memory: | ||||||
| 
 | 
 | ||||||
|    # grubby --args="fadump=on crashkernel=6G" --update-kernel=/boot/vmlinuz-`uname -r` |    # grubby --args="fadump=on crashkernel=6G" --update-kernel=/boot/vmlinuz-`uname -r` | ||||||
| 
 | 
 | ||||||
| By default, FADump reserved memory will be initialized as CMA area to make the | By default, FADump reserved memory will be initialized as CMA area to make the | ||||||
| memory available through CMA allocator on the production kernel. We can opt out | memory available through CMA allocator on the production kernel. We can opt out | ||||||
| of this, making reserved memory unavailable to production kernel, by booting the | of this, making reserved memory unavailable to production kernel, by booting the | ||||||
| linux kernel with 'fadump=nocma' instead of 'fadump=on'. | linux kernel with 'fadump=nocma' instead of 'fadump=on': | ||||||
|  | 
 | ||||||
|  |    # kdumpctl reset-crashkernel --fadump=nocma | ||||||
| 
 | 
 | ||||||
| The term 'boot memory' means size of the low memory chunk that is required for | 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, | a kernel to boot successfully when booted with restricted memory.  By default, | ||||||
| @ -133,7 +137,7 @@ Then, start up kdump as well: | |||||||
|     # systemctl start kdump.service |     # systemctl start kdump.service | ||||||
| 
 | 
 | ||||||
| This should turn on the firmware assisted functionality in kernel by | This should turn on the firmware assisted functionality in kernel by | ||||||
| echo'ing 1 to /sys/kernel/fadump_registered, leaving the system ready | echo'ing 1 to /sys/kernel/fadump/registered, leaving the system ready | ||||||
| to capture a vmcore upon crashing. For journaling filesystems like XFS an | to capture a vmcore upon crashing. For journaling filesystems like XFS an | ||||||
| additional step is required to ensure bootloader does not pick the | additional step is required to ensure bootloader does not pick the | ||||||
| older initrd (without vmcore capture scripts): | older initrd (without vmcore capture scripts): | ||||||
| @ -344,9 +348,12 @@ or | |||||||
| OR | OR | ||||||
|    # grubby --update-kernel=/boot/vmlinuz-`uname -r` --args="fadump=off" |    # grubby --update-kernel=/boot/vmlinuz-`uname -r` --args="fadump=off" | ||||||
| 
 | 
 | ||||||
| If KDump is to be used as the dump capturing mechanism, update the crashkernel | Remove "crashkernel=" from kernel cmdline parameters: | ||||||
| parameter (Else, remove "crashkernel=" parameter too, using grubby): |  | ||||||
| 
 | 
 | ||||||
|    # grubby --update-kernel=/boot/vmlinuz-$kver --args="crashkernl=auto" |    # grubby --update-kernel=/boot/vmlinuz-`uname -r` --remove-args="crashkernel" | ||||||
|  | 
 | ||||||
|  | If KDump is to be used as the dump capturing mechanism, reset the crashkernel parameter: | ||||||
|  | 
 | ||||||
|  |    # kdumpctl reset-crashkernel --fadump=off | ||||||
| 
 | 
 | ||||||
| Reboot the system for the settings to take effect. | Reboot the system for the settings to take effect. | ||||||
|  | |||||||
| @ -1,7 +1,6 @@ | |||||||
| #!/bin/bash | #!/bin/bash | ||||||
| # $1: target arch | # $1: target arch | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| SED_EXP="" | SED_EXP="" | ||||||
| 
 | 
 | ||||||
| generate() | generate() | ||||||
| @ -20,6 +19,12 @@ generate() | |||||||
| # | # | ||||||
| # Supported options: | # Supported options: | ||||||
| # | # | ||||||
|  | # auto_reset_crashkernel <yes|no> | ||||||
|  | #           - whether to reset kernel crashkernel to new default value | ||||||
|  | #             or not when kexec-tools updates the default crashkernel value and | ||||||
|  | #             existing kernels using the old default kernel crashkernel value. | ||||||
|  | #             The default value is yes. | ||||||
|  | # | ||||||
| # raw <partition> | # raw <partition> | ||||||
| #           - Will dd /proc/vmcore into <partition>. | #           - Will dd /proc/vmcore into <partition>. | ||||||
| #             Use persistent device names for partition devices, | #             Use persistent device names for partition devices, | ||||||
| @ -41,11 +46,12 @@ generate() | |||||||
| # | # | ||||||
| # <fs type> <partition> | # <fs type> <partition> | ||||||
| #           - Will mount -t <fs type> <partition> <mnt>, and copy | #           - Will mount -t <fs type> <partition> <mnt>, and copy | ||||||
| #             /proc/vmcore to <mnt>/<path>/%DATE/. | #             /proc/vmcore to <mnt>/<path>/%HOST_IP-%DATE/. | ||||||
| #             NOTE: <partition> can be a device node, label or uuid. | #             NOTE: <partition> can be a device node, label or uuid. | ||||||
| #             It's recommended to use persistent device names | #             It's recommended to use persistent device names | ||||||
| #             such as /dev/vg/<devname>. | #             such as /dev/vg/<devname>. | ||||||
| #             Otherwise it's suggested to use label or uuid. | #             Otherwise it's suggested to use label or uuid. | ||||||
|  | #             Supported fs types: ext[234], xfs, btrfs, minix, virtiofs | ||||||
| # | # | ||||||
| # path <path> | # path <path> | ||||||
| #           - "path" represents the file system path in which vmcore | #           - "path" represents the file system path in which vmcore | ||||||
| @ -174,11 +180,13 @@ generate() | |||||||
| #ext4 /dev/vg/lv_kdump | #ext4 /dev/vg/lv_kdump | ||||||
| #ext4 LABEL=/boot | #ext4 LABEL=/boot | ||||||
| #ext4 UUID=03138356-5e61-4ab3-b58e-27507ac41937 | #ext4 UUID=03138356-5e61-4ab3-b58e-27507ac41937 | ||||||
|  | #virtiofs myfs | ||||||
| #nfs my.server.com:/export/tmp | #nfs my.server.com:/export/tmp | ||||||
| #nfs [2001:db8::1:2:3:4]:/export/tmp | #nfs [2001:db8::1:2:3:4]:/export/tmp | ||||||
| #ssh user@my.server.com | #ssh user@my.server.com | ||||||
| #ssh user@2001:db8::1:2:3:4 | #ssh user@2001:db8::1:2:3:4 | ||||||
| #sshkey /root/.ssh/kdump_id_rsa | #sshkey /root/.ssh/kdump_id_rsa | ||||||
|  | auto_reset_crashkernel yes | ||||||
| path /var/crash | path /var/crash | ||||||
| core_collector makedumpfile -l --message-level 7 -d 31 | core_collector makedumpfile -l --message-level 7 -d 31 | ||||||
| #core_collector scp | #core_collector scp | ||||||
| @ -201,20 +209,20 @@ update_param() | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| case "$1" in | case "$1" in | ||||||
| aarch64) | aarch64) ;; | ||||||
| 	;; | 
 | ||||||
| i386) | i386) ;; | ||||||
| 	;; | 
 | ||||||
| ppc64) | ppc64) ;; | ||||||
| 	;; | 
 | ||||||
| ppc64le) | ppc64le) ;; | ||||||
| 	;; | 
 | ||||||
| s390x) | s390x) | ||||||
| 	update_param core_collector \ | 	update_param core_collector \ | ||||||
| 		"makedumpfile -c --message-level 7 -d 31" | 		"makedumpfile -c --message-level 7 -d 31" | ||||||
| 	;; | 	;; | ||||||
| x86_64) | x86_64) ;; | ||||||
| 	;; | 
 | ||||||
| *) | *) | ||||||
| 	echo "Warning: Unknown architecture '$1', using default kdump.conf template." | 	echo "Warning: Unknown architecture '$1', using default kdump.conf template." | ||||||
| 	;; | 	;; | ||||||
|  | |||||||
| @ -1,248 +1,186 @@ | |||||||
| # These variables and functions are useful in 2nd kernel | #!/bin/sh | ||||||
|  | # | ||||||
|  | # The code in this file will be used in initramfs environment, bash may | ||||||
|  | # not be the default shell. Any code added must be POSIX compliant. | ||||||
| 
 | 
 | ||||||
| . /lib/kdump-lib.sh | DEFAULT_PATH="/var/crash/" | ||||||
| . /lib/kdump-logger.sh | KDUMP_CONFIG_FILE="/etc/kdump.conf" | ||||||
|  | FENCE_KDUMP_CONFIG_FILE="/etc/sysconfig/fence_kdump" | ||||||
|  | FENCE_KDUMP_SEND="/usr/libexec/fence_kdump_send" | ||||||
|  | LVM_CONF="/etc/lvm/lvm.conf" | ||||||
| 
 | 
 | ||||||
| KDUMP_PATH="/var/crash" | # Read kdump config in well formated style | ||||||
| KDUMP_LOG_FILE="/run/initramfs/kexec-dmesg.log" | kdump_read_conf() | ||||||
| CORE_COLLECTOR="" |  | ||||||
| DEFAULT_CORE_COLLECTOR="makedumpfile -l --message-level 7 -d 31" |  | ||||||
| DMESG_COLLECTOR="/sbin/vmcore-dmesg" |  | ||||||
| FAILURE_ACTION="systemctl reboot -f" |  | ||||||
| DATEDIR=`date +%Y-%m-%d-%T` |  | ||||||
| HOST_IP='127.0.0.1' |  | ||||||
| DUMP_INSTRUCTION="" |  | ||||||
| SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa" |  | ||||||
| KDUMP_SCRIPT_DIR="/kdumpscripts" |  | ||||||
| DD_BLKSIZE=512 |  | ||||||
| FINAL_ACTION="systemctl reboot -f" |  | ||||||
| KDUMP_CONF="/etc/kdump.conf" |  | ||||||
| KDUMP_PRE="" |  | ||||||
| KDUMP_POST="" |  | ||||||
| NEWROOT="/sysroot" |  | ||||||
| OPALCORE="/sys/firmware/opal/mpipl/core" |  | ||||||
| 
 |  | ||||||
| #initiate the kdump logger |  | ||||||
| dlog_init |  | ||||||
| if [ $? -ne 0 ]; then |  | ||||||
|     echo "failed to initiate the kdump logger." |  | ||||||
|     exit 1 |  | ||||||
| fi |  | ||||||
| 
 |  | ||||||
| get_kdump_confs() |  | ||||||
| { | { | ||||||
|     local config_opt config_val | 	# Following steps are applied in order: strip trailing comment, strip trailing space, | ||||||
| 
 | 	# strip heading space, match non-empty line, remove duplicated spaces between conf name and value | ||||||
|     while read config_opt config_val; | 	[ -f "$KDUMP_CONFIG_FILE" ] && sed -n -e "s/#.*//;s/\s*$//;s/^\s*//;s/\(\S\+\)\s*\(.*\)/\1 \2/p" $KDUMP_CONFIG_FILE | ||||||
|     do |  | ||||||
|         # remove inline comments after the end of a directive. |  | ||||||
|         case "$config_opt" in |  | ||||||
|             path) |  | ||||||
|                 KDUMP_PATH="$config_val" |  | ||||||
|             ;; |  | ||||||
|             core_collector) |  | ||||||
|                 [ -n "$config_val" ] && CORE_COLLECTOR="$config_val" |  | ||||||
|             ;; |  | ||||||
|             sshkey) |  | ||||||
|                 if [ -f "$config_val" ]; then |  | ||||||
|                     SSH_KEY_LOCATION=$config_val |  | ||||||
|                 fi |  | ||||||
|             ;; |  | ||||||
|             kdump_pre) |  | ||||||
|                 KDUMP_PRE="$config_val" |  | ||||||
|             ;; |  | ||||||
|             kdump_post) |  | ||||||
|                 KDUMP_POST="$config_val" |  | ||||||
|             ;; |  | ||||||
|             fence_kdump_args) |  | ||||||
|                 FENCE_KDUMP_ARGS="$config_val" |  | ||||||
|             ;; |  | ||||||
|             fence_kdump_nodes) |  | ||||||
|                 FENCE_KDUMP_NODES="$config_val" |  | ||||||
|             ;; |  | ||||||
|             failure_action|default) |  | ||||||
|                 case $config_val in |  | ||||||
|                     shell) |  | ||||||
|                         FAILURE_ACTION="kdump_emergency_shell" |  | ||||||
|                     ;; |  | ||||||
|                     reboot) |  | ||||||
|                         FAILURE_ACTION="systemctl reboot -f && exit" |  | ||||||
|                     ;; |  | ||||||
|                     halt) |  | ||||||
|                         FAILURE_ACTION="halt && exit" |  | ||||||
|                     ;; |  | ||||||
|                     poweroff) |  | ||||||
|                         FAILURE_ACTION="systemctl poweroff -f && exit" |  | ||||||
|                     ;; |  | ||||||
|                     dump_to_rootfs) |  | ||||||
|                         FAILURE_ACTION="dump_to_rootfs" |  | ||||||
|                     ;; |  | ||||||
|                 esac |  | ||||||
|             ;; |  | ||||||
|             final_action) |  | ||||||
|                 case $config_val in |  | ||||||
|                     reboot) |  | ||||||
|                         FINAL_ACTION="systemctl reboot -f" |  | ||||||
|                     ;; |  | ||||||
|                     halt) |  | ||||||
|                         FINAL_ACTION="halt" |  | ||||||
|                     ;; |  | ||||||
|                     poweroff) |  | ||||||
|                         FINAL_ACTION="systemctl poweroff -f" |  | ||||||
|                     ;; |  | ||||||
|                 esac |  | ||||||
|             ;; |  | ||||||
|         esac |  | ||||||
|     done <<< "$(read_strip_comments $KDUMP_CONF)" |  | ||||||
| 
 |  | ||||||
|     if [ -z "$CORE_COLLECTOR" ]; then |  | ||||||
|         CORE_COLLECTOR="$DEFAULT_CORE_COLLECTOR" |  | ||||||
|         if is_ssh_dump_target || is_raw_dump_target; then |  | ||||||
|             CORE_COLLECTOR="$CORE_COLLECTOR -F" |  | ||||||
|         fi |  | ||||||
|     fi |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| # store the kexec kernel log to a file. | # Retrieves config value defined in kdump.conf | ||||||
| save_log() | # $1: config name, sed regexp compatible | ||||||
|  | kdump_get_conf_val() | ||||||
| { | { | ||||||
|     dmesg -T > $KDUMP_LOG_FILE | 	# For lines matching "^\s*$1\s+", remove matched part (config name including space), | ||||||
| 
 | 	# remove tailing comment, space, then store in hold space. Print out the hold buffer on last line. | ||||||
|     if command -v journalctl > /dev/null; then | 	[ -f "$KDUMP_CONFIG_FILE" ] && | ||||||
|         journalctl -ab >> $KDUMP_LOG_FILE | 		sed -n -e "/^\s*\($1\)\s\+/{s/^\s*\($1\)\s\+//;s/#.*//;s/\s*$//;h};\${x;p}" $KDUMP_CONFIG_FILE | ||||||
|     fi |  | ||||||
|     chmod 600 $KDUMP_LOG_FILE |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| # dump_fs <mount point> | is_mounted() | ||||||
| dump_fs() |  | ||||||
| { | { | ||||||
|     local _exitcode | 	findmnt -k -n "$1" > /dev/null 2>&1 | ||||||
|     local _mp=$1 |  | ||||||
|     ddebug "dump_fs _mp=$_mp" |  | ||||||
| 
 |  | ||||||
|     if ! is_mounted "$_mp"; then |  | ||||||
|         dinfo "dump path \"$_mp\" is not mounted, trying to mount..." |  | ||||||
|         mount --target $_mp |  | ||||||
|         if [ $? -ne 0 ]; then |  | ||||||
|             derror "failed to dump to \"$_mp\", it's not a mount point!" |  | ||||||
|             return 1 |  | ||||||
|         fi |  | ||||||
|     fi |  | ||||||
| 
 |  | ||||||
|     # Remove -F in makedumpfile case. We don't want a flat format dump here. |  | ||||||
|     [[ $CORE_COLLECTOR = *makedumpfile* ]] && CORE_COLLECTOR=`echo $CORE_COLLECTOR | sed -e "s/-F//g"` |  | ||||||
| 
 |  | ||||||
|     dinfo "saving to $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/" |  | ||||||
| 
 |  | ||||||
|     mount -o remount,rw $_mp || return 1 |  | ||||||
|     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/" |  | ||||||
| 
 |  | ||||||
|     dinfo "saving vmcore" |  | ||||||
|     $CORE_COLLECTOR /proc/vmcore $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore-incomplete |  | ||||||
|     _exitcode=$? |  | ||||||
|     if [ $_exitcode -eq 0 ]; then |  | ||||||
|         sync -f "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore-incomplete" |  | ||||||
|         _sync_exitcode=$? |  | ||||||
|         if [ $_sync_exitcode -eq 0 ]; then |  | ||||||
|             mv "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore-incomplete" "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore" |  | ||||||
|             dinfo "saving vmcore complete" |  | ||||||
|         else |  | ||||||
|             derror "sync vmcore failed, _exitcode:$_sync_exitcode" |  | ||||||
|             return 1 |  | ||||||
|         fi |  | ||||||
|     else |  | ||||||
|         derror "saving vmcore failed, _exitcode:$_exitcode" |  | ||||||
|     fi |  | ||||||
| 
 |  | ||||||
|     dinfo "saving the $KDUMP_LOG_FILE to $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/" |  | ||||||
|     save_log |  | ||||||
|     mv $KDUMP_LOG_FILE $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/ |  | ||||||
|     if [ $_exitcode -ne 0 ]; then |  | ||||||
|         return 1 |  | ||||||
|     fi |  | ||||||
| 
 |  | ||||||
|     # improper kernel cmdline can cause the failure of echo, we can ignore this kind of failure |  | ||||||
|     return 0 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| save_vmcore_dmesg_fs() { | # $1: info type | ||||||
|     local _dmesg_collector=$1 | # $2: mount source type | ||||||
|     local _path=$2 | # $3: mount source | ||||||
| 
 | # $4: extra args | ||||||
|     dinfo "saving vmcore-dmesg.txt to ${_path}" | get_mount_info() | ||||||
|     $_dmesg_collector /proc/vmcore > ${_path}/vmcore-dmesg-incomplete.txt |  | ||||||
|     _exitcode=$? |  | ||||||
|     if [ $_exitcode -eq 0 ]; then |  | ||||||
|         mv ${_path}/vmcore-dmesg-incomplete.txt ${_path}/vmcore-dmesg.txt |  | ||||||
|         chmod 600 ${_path}/vmcore-dmesg.txt |  | ||||||
| 
 |  | ||||||
|         # Make sure file is on disk. There have been instances where later |  | ||||||
|         # saving vmcore failed and system rebooted without sync and there |  | ||||||
|         # was no vmcore-dmesg.txt available. |  | ||||||
|         sync |  | ||||||
|         dinfo "saving vmcore-dmesg.txt complete" |  | ||||||
|     else |  | ||||||
|         derror "saving vmcore-dmesg.txt failed" |  | ||||||
|     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 |  | ||||||
| 
 |  | ||||||
|     dinfo "saving opalcore:$OPALCORE to ${_path}/opalcore" |  | ||||||
|     cp $OPALCORE ${_path}/opalcore |  | ||||||
|     if [ $? -ne 0 ]; then |  | ||||||
|         derror "saving opalcore failed" |  | ||||||
|         return 1 |  | ||||||
|     fi |  | ||||||
| 
 |  | ||||||
|     sync |  | ||||||
|     dinfo "saving opalcore complete" |  | ||||||
|     return 0 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| dump_to_rootfs() |  | ||||||
| { | { | ||||||
|  | 	__kdump_mnt=$(findmnt -k -n -r -o "$1" "--$2" "$3" $4) | ||||||
| 
 | 
 | ||||||
|     dinfo "Trying to bring up rootfs device" | 	[ -z "$__kdump_mnt" ] && [ -e "/etc/fstab" ] && __kdump_mnt=$(findmnt -s -n -r -o "$1" "--$2" "$3" $4) | ||||||
|     systemctl start dracut-initqueue |  | ||||||
|     dinfo "Waiting for rootfs mount, will timeout after 90 seconds" |  | ||||||
|     systemctl start sysroot.mount |  | ||||||
| 
 | 
 | ||||||
|     ddebug "NEWROOT=$NEWROOT" | 	echo "$__kdump_mnt" | ||||||
| 
 |  | ||||||
|     dump_fs $NEWROOT |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| kdump_emergency_shell() | is_ipv6_address() | ||||||
| { | { | ||||||
|     echo "PS1=\"kdump:\\\${PWD}# \"" >/etc/profile | 	echo "$1" | grep -q ":" | ||||||
|     ddebug "Switching to dracut emergency..." |  | ||||||
|     /bin/dracut-emergency |  | ||||||
|     rm -f /etc/profile |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| do_failure_action() | is_fs_type_nfs() | ||||||
| { | { | ||||||
|     dinfo "Executing failure action $FAILURE_ACTION" | 	[ "$1" = "nfs" ] || [ "$1" = "nfs4" ] | ||||||
|     eval $FAILURE_ACTION |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| do_final_action() | is_fs_type_virtiofs() | ||||||
| { | { | ||||||
|     dinfo "Executing final action $FINAL_ACTION" | 	[ "$1" = "virtiofs" ] | ||||||
|     eval $FINAL_ACTION | } | ||||||
|  | 
 | ||||||
|  | # If $1 contains dracut_args "--mount", return <filesystem type> | ||||||
|  | get_dracut_args_fstype() | ||||||
|  | { | ||||||
|  | 	echo $1 | grep "\-\-mount" | sed "s/.*--mount .\(.*\)/\1/" | cut -d' ' -f3 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | # If $1 contains dracut_args "--mount", return <device> | ||||||
|  | get_dracut_args_target() | ||||||
|  | { | ||||||
|  | 	echo $1 | grep "\-\-mount" | sed "s/.*--mount .\(.*\)/\1/" | cut -d' ' -f1 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | get_save_path() | ||||||
|  | { | ||||||
|  | 	__kdump_path=$(kdump_get_conf_val path) | ||||||
|  | 	[ -z "$__kdump_path" ] && __kdump_path=$DEFAULT_PATH | ||||||
|  | 
 | ||||||
|  | 	# strip the duplicated "/" | ||||||
|  | 	echo "$__kdump_path" | tr -s / | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | get_root_fs_device() | ||||||
|  | { | ||||||
|  | 	findmnt -k -f -n -o SOURCE / | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | # Return the current underlying device of a path, ignore bind mounts | ||||||
|  | get_target_from_path() | ||||||
|  | { | ||||||
|  | 	__kdump_target=$(df "$1" 2> /dev/null | tail -1 | awk '{print $1}') | ||||||
|  | 	[ "$__kdump_target" = "/dev/root" ] && [ ! -e /dev/root ] && __kdump_target=$(get_root_fs_device) | ||||||
|  | 	echo "$__kdump_target" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | get_fs_type_from_target() | ||||||
|  | { | ||||||
|  | 	get_mount_info FSTYPE source "$1" -f | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | get_mntpoint_from_target() | ||||||
|  | { | ||||||
|  | 	# --source is applied to ensure non-bind mount is returned | ||||||
|  | 	local SOURCE TARGET | ||||||
|  | 	findmnt -k --pairs -o SOURCE,TARGET "$1" | while read line; do | ||||||
|  | 		eval "$line" | ||||||
|  | 		# omit sources that are bind mounts i.e. they contain a [/path/to/subpath]. | ||||||
|  | 		if [[ ! "$SOURCE" =~ \[ ]]; then | ||||||
|  | 			echo $TARGET | ||||||
|  | 			break | ||||||
|  | 		fi | ||||||
|  | 	done | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | is_ssh_dump_target() | ||||||
|  | { | ||||||
|  | 	kdump_get_conf_val ssh | grep -q @ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | is_raw_dump_target() | ||||||
|  | { | ||||||
|  | 	[ -n "$(kdump_get_conf_val raw)" ] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | is_virtiofs_dump_target() | ||||||
|  | { | ||||||
|  | 	if [ -n "$(kdump_get_conf_val virtiofs)" ]; then | ||||||
|  | 		return 0 | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	if is_fs_type_virtiofs "$(get_dracut_args_fstype "$(kdump_get_conf_val dracut_args)")"; then | ||||||
|  | 		return 0 | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	if is_fs_type_virtiofs "$(get_fs_type_from_target "$(get_target_from_path "$(get_save_path)")")"; then | ||||||
|  | 		return 0 | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	return 1 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | is_nfs_dump_target() | ||||||
|  | { | ||||||
|  | 	if [ -n "$(kdump_get_conf_val nfs)" ]; then | ||||||
|  | 		return 0 | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	if is_fs_type_nfs "$(get_dracut_args_fstype "$(kdump_get_conf_val dracut_args)")"; then | ||||||
|  | 		return 0 | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	if is_fs_type_nfs "$(get_fs_type_from_target "$(get_target_from_path "$(get_save_path)")")"; then | ||||||
|  | 		return 0 | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	return 1 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | is_fs_dump_target() | ||||||
|  | { | ||||||
|  | 	[ -n "$(kdump_get_conf_val "ext[234]\|xfs\|btrfs\|minix\|virtiofs")" ] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | is_lvm2_thinp_device() | ||||||
|  | { | ||||||
|  | 	_device_path=$1 | ||||||
|  | 	_lvm2_thin_device=$(lvm lvs -S 'lv_layout=sparse && lv_layout=thin' \ | ||||||
|  | 		--nosuffix --noheadings -o vg_name,lv_name "$_device_path" 2> /dev/null) | ||||||
|  | 
 | ||||||
|  | 	[ -n "$_lvm2_thin_device" ] | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | kdump_get_ip_route() | ||||||
|  | { | ||||||
|  | 	if ! _route=$(/sbin/ip -o route get to "$1" 2>&1); then | ||||||
|  | 		exit 1 | ||||||
|  | 	fi | ||||||
|  | 	echo "$_route" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | kdump_get_ip_route_field() | ||||||
|  | { | ||||||
|  | 	echo "$1" | sed -n -e "s/^.*\<$2\>\s\+\(\S\+\).*$/\1/p" | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										1657
									
								
								SOURCES/kdump-lib.sh
									
									
									
									
									
								
							
							
						
						
									
										1657
									
								
								SOURCES/kdump-lib.sh
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,4 +1,4 @@ | |||||||
| #!/bin/bash | #!/bin/sh | ||||||
| # | # | ||||||
| # This comes from the dracut-logger.sh | # This comes from the dracut-logger.sh | ||||||
| # | # | ||||||
| @ -34,6 +34,8 @@ | |||||||
| # First of all you have to start with dlog_init() function which initializes | # First of all you have to start with dlog_init() function which initializes | ||||||
| # required variables. Don't call any other logging function before that one! | # required variables. Don't call any other logging function before that one! | ||||||
| # | # | ||||||
|  | # The code in this file might be run in an environment without bash. | ||||||
|  | # Any code added must be POSIX compliant. | ||||||
| 
 | 
 | ||||||
| # Define vairables for the log levels in this module. | # Define vairables for the log levels in this module. | ||||||
| kdump_stdloglvl="" | kdump_stdloglvl="" | ||||||
| @ -53,11 +55,12 @@ fi | |||||||
| # | # | ||||||
| get_kdump_loglvl() | get_kdump_loglvl() | ||||||
| { | { | ||||||
|     (type -p getarg) && kdump_sysloglvl=$(getarg rd.kdumploglvl) |     [ -f /lib/dracut-lib.sh ] && kdump_sysloglvl=$(getarg rd.kdumploglvl) | ||||||
|     [ -z "$kdump_sysloglvl" ] && return 1; |     [ -z "$kdump_sysloglvl" ] && return 1; | ||||||
| 
 | 
 | ||||||
|     (type -p isdigit) && isdigit $kdump_sysloglvl |     if [ -f /lib/dracut-lib.sh ] && ! isdigit "$kdump_sysloglvl"; then | ||||||
|     [ $? -ne 0 ] && return 1; |         return 1 | ||||||
|  |     fi | ||||||
| 
 | 
 | ||||||
|     return 0 |     return 0 | ||||||
| } | } | ||||||
| @ -83,11 +86,10 @@ check_loglvl() | |||||||
| # @retval 0 on success. | # @retval 0 on success. | ||||||
| # | # | ||||||
| dlog_init() { | dlog_init() { | ||||||
|     local ret=0; local errmsg |     ret=0 | ||||||
| 
 | 
 | ||||||
|     if [ -s /proc/vmcore ];then |     if [ -s /proc/vmcore ];then | ||||||
|         get_kdump_loglvl |         if ! get_kdump_loglvl; then | ||||||
|         if [ $? -ne 0 ];then |  | ||||||
|             logger -t "kdump[$$]" -p warn -- "Kdump is using the default log level(3)." |             logger -t "kdump[$$]" -p warn -- "Kdump is using the default log level(3)." | ||||||
|             kdump_sysloglvl=3 |             kdump_sysloglvl=3 | ||||||
|         fi |         fi | ||||||
| @ -104,8 +106,7 @@ dlog_init() { | |||||||
|     [ -z "$kdump_kmsgloglvl" ] && kdump_kmsgloglvl=0 |     [ -z "$kdump_kmsgloglvl" ] && kdump_kmsgloglvl=0 | ||||||
| 
 | 
 | ||||||
|     for loglvl in "$kdump_stdloglvl" "$kdump_kmsgloglvl" "$kdump_sysloglvl"; do |     for loglvl in "$kdump_stdloglvl" "$kdump_kmsgloglvl" "$kdump_sysloglvl"; do | ||||||
|         check_loglvl "$loglvl" |         if ! check_loglvl "$loglvl"; then | ||||||
|         if [ $? -ne 0 ]; then |  | ||||||
|             echo "Illegal log level: $kdump_stdloglvl $kdump_kmsgloglvl $kdump_sysloglvl" |             echo "Illegal log level: $kdump_stdloglvl $kdump_kmsgloglvl $kdump_sysloglvl" | ||||||
|             return 1 |             return 1 | ||||||
|         fi |         fi | ||||||
| @ -114,21 +115,21 @@ dlog_init() { | |||||||
|     # Skip initialization if it's already done. |     # Skip initialization if it's already done. | ||||||
|     [ -n "$kdump_maxloglvl" ] && return 0 |     [ -n "$kdump_maxloglvl" ] && return 0 | ||||||
| 
 | 
 | ||||||
|     if [[ $UID -ne 0 ]]; then |     if [ "$UID" -ne 0 ]; then | ||||||
|         kdump_kmsgloglvl=0 |         kdump_kmsgloglvl=0 | ||||||
|         kdump_sysloglvl=0 |         kdump_sysloglvl=0 | ||||||
|     fi |     fi | ||||||
| 
 | 
 | ||||||
|     if [[ $kdump_sysloglvl -gt 0 ]]; then |     if [ "$kdump_sysloglvl" -gt 0 ]; then | ||||||
|         if [[ -d /run/systemd/journal ]] \ |         if [ -d /run/systemd/journal ] \ | ||||||
|             && type -P systemd-cat &>/dev/null \ |             && systemd-cat --version 1>/dev/null 2>&1 \ | ||||||
|             && systemctl --quiet is-active systemd-journald.socket &>/dev/null; then |             && systemctl --quiet is-active systemd-journald.socket 1>/dev/null 2>&1; then | ||||||
|             readonly _systemdcatfile="/var/tmp/systemd-cat" |             readonly _systemdcatfile="/var/tmp/systemd-cat" | ||||||
|             mkfifo "$_systemdcatfile" &>/dev/null |             mkfifo "$_systemdcatfile" 1>/dev/null 2>&1 | ||||||
|             readonly _dlogfd=15 |             readonly _dlogfd=15 | ||||||
|             systemd-cat -t 'kdump' --level-prefix=true <"$_systemdcatfile" & |             systemd-cat -t 'kdump' --level-prefix=true <"$_systemdcatfile" & | ||||||
|             exec 15>"$_systemdcatfile" |             exec 15>"$_systemdcatfile" | ||||||
|         elif ! [ -S /dev/log -a -w /dev/log ] || ! command -v logger >/dev/null; then |         elif ! [ -S /dev/log ] && [ -w /dev/log ] || ! command -v logger >/dev/null; then | ||||||
|             # We cannot log to syslog, so turn this facility off. |             # We cannot log to syslog, so turn this facility off. | ||||||
|             kdump_kmsgloglvl=$kdump_sysloglvl |             kdump_kmsgloglvl=$kdump_sysloglvl | ||||||
|             kdump_sysloglvl=0 |             kdump_sysloglvl=0 | ||||||
| @ -137,31 +138,31 @@ dlog_init() { | |||||||
|         fi |         fi | ||||||
|     fi |     fi | ||||||
| 
 | 
 | ||||||
|     local lvl; local maxloglvl_l=0 |     kdump_maxloglvl=0 | ||||||
|     for lvl in $kdump_stdloglvl $kdump_sysloglvl $kdump_kmsgloglvl; do |     for _dlog_lvl in $kdump_stdloglvl $kdump_sysloglvl $kdump_kmsgloglvl; do | ||||||
|         [[ $lvl -gt $maxloglvl_l ]] && maxloglvl_l=$lvl |         [ $_dlog_lvl -gt $kdump_maxloglvl ] && kdump_maxloglvl=$_dlog_lvl | ||||||
|     done |     done | ||||||
|     readonly kdump_maxloglvl=$maxloglvl_l |     readonly kdump_maxloglvl | ||||||
|     export kdump_maxloglvl |     export kdump_maxloglvl | ||||||
| 
 | 
 | ||||||
|     if [[ $kdump_stdloglvl -lt 4 ]] && [[ $kdump_kmsgloglvl -lt 4 ]] && [[ $kdump_sysloglvl -lt 4 ]]; then |     if [ $kdump_stdloglvl -lt 4 ] && [ $kdump_kmsgloglvl -lt 4 ] && [ $kdump_sysloglvl -lt 4 ]; then | ||||||
|         unset ddebug |         unset ddebug | ||||||
|         ddebug() { :; }; |         ddebug() { :; }; | ||||||
|     fi |     fi | ||||||
| 
 | 
 | ||||||
|     if [[ $kdump_stdloglvl -lt 3 ]] && [[ $kdump_kmsgloglvl -lt 3 ]] && [[ $kdump_sysloglvl -lt 3 ]]; then |     if [ $kdump_stdloglvl -lt 3 ] && [ $kdump_kmsgloglvl -lt 3 ] && [ $kdump_sysloglvl -lt 3 ]; then | ||||||
|         unset dinfo |         unset dinfo | ||||||
|         dinfo() { :; }; |         dinfo() { :; }; | ||||||
|     fi |     fi | ||||||
| 
 | 
 | ||||||
|     if [[ $kdump_stdloglvl -lt 2 ]] && [[ $kdump_kmsgloglvl -lt 2 ]] && [[ $kdump_sysloglvl -lt 2 ]]; then |     if [ $kdump_stdloglvl -lt 2 ] && [ $kdump_kmsgloglvl -lt 2 ] && [ $kdump_sysloglvl -lt 2 ]; then | ||||||
|         unset dwarn |         unset dwarn | ||||||
|         dwarn() { :; }; |         dwarn() { :; }; | ||||||
|         unset dwarning |         unset dwarning | ||||||
|         dwarning() { :; }; |         dwarning() { :; }; | ||||||
|     fi |     fi | ||||||
| 
 | 
 | ||||||
|     if [[ $kdump_stdloglvl -lt 1 ]] && [[ $kdump_kmsgloglvl -lt 1 ]] && [[ $kdump_sysloglvl -lt 1 ]]; then |     if [ $kdump_stdloglvl -lt 1 ] && [ $kdump_kmsgloglvl -lt 1 ] && [ $kdump_sysloglvl -lt 1 ]; then | ||||||
|         unset derror |         unset derror | ||||||
|         derror() { :; }; |         derror() { :; }; | ||||||
|     fi |     fi | ||||||
| @ -173,7 +174,7 @@ dlog_init() { | |||||||
| 
 | 
 | ||||||
| ## @brief Converts numeric level to logger priority defined by POSIX.2. | ## @brief Converts numeric level to logger priority defined by POSIX.2. | ||||||
| # | # | ||||||
| # @param lvl Numeric logging level in range from 1 to 4. | # @param $1: Numeric logging level in range from 1 to 4. | ||||||
| # @retval 1 if @a lvl is out of range. | # @retval 1 if @a lvl is out of range. | ||||||
| # @retval 0 if @a lvl is correct. | # @retval 0 if @a lvl is correct. | ||||||
| # @result Echoes logger priority. | # @result Echoes logger priority. | ||||||
| @ -189,7 +190,7 @@ _lvl2syspri() { | |||||||
| 
 | 
 | ||||||
| ## @brief Converts logger numeric level to syslog log level | ## @brief Converts logger numeric level to syslog log level | ||||||
| # | # | ||||||
| # @param lvl Numeric logging level in range from 1 to 4. | # @param $1: Numeric logging level in range from 1 to 4. | ||||||
| # @retval 1 if @a lvl is out of range. | # @retval 1 if @a lvl is out of range. | ||||||
| # @retval 0 if @a lvl is correct. | # @retval 0 if @a lvl is correct. | ||||||
| # @result Echoes kernel console numeric log level | # @result Echoes kernel console numeric log level | ||||||
| @ -209,27 +210,25 @@ _lvl2syspri() { | |||||||
| # | # | ||||||
| # @see /usr/include/sys/syslog.h | # @see /usr/include/sys/syslog.h | ||||||
| _dlvl2syslvl() { | _dlvl2syslvl() { | ||||||
|     local lvl |  | ||||||
| 
 |  | ||||||
|     case "$1" in |     case "$1" in | ||||||
|         1) lvl=3;; |         1) set -- 3;; | ||||||
|         2) lvl=4;; |         2) set -- 4;; | ||||||
|         3) lvl=6;; |         3) set -- 6;; | ||||||
|         4) lvl=7;; |         4) set -- 7;; | ||||||
|         *) return 1;; |         *) return 1;; | ||||||
|     esac |     esac | ||||||
| 
 | 
 | ||||||
|     # The number is constructed by multiplying the facility by 8 and then |     # The number is constructed by multiplying the facility by 8 and then | ||||||
|     # adding the level. |     # adding the level. | ||||||
|     # About The Syslog Protocol, please refer to the RFC5424 for more details. |     # About The Syslog Protocol, please refer to the RFC5424 for more details. | ||||||
|     echo $((24+$lvl)) |     echo $((24 + $1)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ## @brief Prints to stderr, to syslog and/or /dev/kmsg given message with | ## @brief Prints to stderr, to syslog and/or /dev/kmsg given message with | ||||||
| #  given level (priority). | #  given level (priority). | ||||||
| # | # | ||||||
| # @param lvl Numeric logging level. | # @param $1: Numeric logging level. | ||||||
| # @param msg Message. | # @param $2: Message. | ||||||
| # @retval 0 It's always returned, even if logging failed. | # @retval 0 It's always returned, even if logging failed. | ||||||
| # | # | ||||||
| # @note This function is not supposed to be called manually. Please use | # @note This function is not supposed to be called manually. Please use | ||||||
| @ -251,27 +250,24 @@ _dlvl2syslvl() { | |||||||
| #   - @c INFO to @c info | #   - @c INFO to @c info | ||||||
| #   - @c DEBUG to @c debug | #   - @c DEBUG to @c debug | ||||||
| _do_dlog() { | _do_dlog() { | ||||||
|     local lvl="$1"; shift |     [ "$1" -le $kdump_stdloglvl ] && printf -- 'kdump: %s\n' "$2" >&2 | ||||||
|     local msg="$*" |  | ||||||
| 
 | 
 | ||||||
|     [[ $lvl -le $kdump_stdloglvl ]] && printf -- 'kdump: %s\n' "$msg" >&2 |     if [ "$1" -le $kdump_sysloglvl ]; then | ||||||
| 
 |         if [ "$_dlogfd" ]; then | ||||||
|     if [[ $lvl -le $kdump_sysloglvl ]]; then |             printf -- "<%s>%s\n" "$(($(_dlvl2syslvl "$1") & 7))" "$2" 1>&$_dlogfd | ||||||
|         if [[ "$_dlogfd" ]]; then |  | ||||||
|             printf -- "<%s>%s\n" "$(($(_dlvl2syslvl $lvl) & 7))" "$msg" >&$_dlogfd |  | ||||||
|         else |         else | ||||||
|             logger -t "kdump[$$]" -p $(_lvl2syspri $lvl) -- "$msg" |             logger -t "kdump[$$]" -p "$(_lvl2syspri "$1")" -- "$2" | ||||||
|         fi |         fi | ||||||
|     fi |     fi | ||||||
| 
 | 
 | ||||||
|     [[ $lvl -le $kdump_kmsgloglvl ]] && \ |     [ "$1" -le $kdump_kmsgloglvl ] && \ | ||||||
|         echo "<$(_dlvl2syslvl $lvl)>kdump[$$] $msg" >/dev/kmsg |         echo "<$(_dlvl2syslvl "$1")>kdump[$$] $2" >/dev/kmsg | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ## @brief Internal helper function for _do_dlog() | ## @brief Internal helper function for _do_dlog() | ||||||
| # | # | ||||||
| # @param lvl Numeric logging level. | # @param $1: Numeric logging level. | ||||||
| # @param msg Message. | # @param $2 [...]: Message. | ||||||
| # @retval 0 It's always returned, even if logging failed. | # @retval 0 It's always returned, even if logging failed. | ||||||
| # | # | ||||||
| # @note This function is not supposed to be called manually. Please use | # @note This function is not supposed to be called manually. Please use | ||||||
| @ -286,12 +282,13 @@ _do_dlog() { | |||||||
| # echo "This is a warning" | dwarn | # echo "This is a warning" | dwarn | ||||||
| dlog() { | dlog() { | ||||||
|     [ -z "$kdump_maxloglvl" ] && return 0 |     [ -z "$kdump_maxloglvl" ] && return 0 | ||||||
|     [[ $1 -le $kdump_maxloglvl ]] || return 0 |     [ "$1" -le "$kdump_maxloglvl" ] || return 0 | ||||||
| 
 | 
 | ||||||
|     if [[ $# -gt 1 ]]; then |     if [ $# -gt 1 ]; then | ||||||
|         _do_dlog "$@" |         _dlog_lvl=$1; shift | ||||||
|  |         _do_dlog "$_dlog_lvl" "$*" | ||||||
|     else |     else | ||||||
|         while read line || [ -n "$line" ]; do |         while read -r line || [ -n "$line" ]; do | ||||||
|             _do_dlog "$1" "$line" |             _do_dlog "$1" "$line" | ||||||
|         done |         done | ||||||
|     fi |     fi | ||||||
| @ -304,7 +301,9 @@ dlog() { | |||||||
| ddebug() { | ddebug() { | ||||||
|     set +x |     set +x | ||||||
|     dlog 4 "$@" |     dlog 4 "$@" | ||||||
|     [ -n "$debug" ] && set -x || : |     if [ -n "$debug" ]; then | ||||||
|  |         set -x | ||||||
|  |     fi | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ## @brief Logs message at INFO level (3) | ## @brief Logs message at INFO level (3) | ||||||
| @ -314,7 +313,9 @@ ddebug() { | |||||||
| dinfo() { | dinfo() { | ||||||
|     set +x |     set +x | ||||||
|     dlog 3 "$@" |     dlog 3 "$@" | ||||||
|     [ -n "$debug" ] && set -x || : |     if [ -n "$debug" ]; then | ||||||
|  |         set -x | ||||||
|  |     fi | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ## @brief Logs message at WARN level (2) | ## @brief Logs message at WARN level (2) | ||||||
| @ -324,7 +325,9 @@ dinfo() { | |||||||
| dwarn() { | dwarn() { | ||||||
|     set +x |     set +x | ||||||
|     dlog 2 "$@" |     dlog 2 "$@" | ||||||
|     [ -n "$debug" ] && set -x || : |     if [ -n "$debug" ]; then | ||||||
|  |         set -x | ||||||
|  |     fi | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ## @brief It's an alias to dwarn() function. | ## @brief It's an alias to dwarn() function. | ||||||
| @ -334,7 +337,9 @@ dwarn() { | |||||||
| dwarning() { | dwarning() { | ||||||
|     set +x |     set +x | ||||||
|     dwarn "$@" |     dwarn "$@" | ||||||
|     [ -n "$debug" ] && set -x || : |     if [ -n "$debug" ]; then | ||||||
|  |         set -x | ||||||
|  |     fi | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ## @brief Logs message at ERROR level (1) | ## @brief Logs message at ERROR level (1) | ||||||
| @ -344,5 +349,7 @@ dwarning() { | |||||||
| derror() { | derror() { | ||||||
|     set +x |     set +x | ||||||
|     dlog 1 "$@" |     dlog 1 "$@" | ||||||
|     [ -n "$debug" ] && set -x || : |     if [ -n "$debug" ]; then | ||||||
|  |         set -x | ||||||
|  |     fi | ||||||
| } | } | ||||||
|  | |||||||
| @ -26,6 +26,24 @@ understand how this configuration file affects the behavior of kdump. | |||||||
| 
 | 
 | ||||||
| .SH OPTIONS | .SH OPTIONS | ||||||
| 
 | 
 | ||||||
|  | .B auto_reset_crashkernel <yes|no> | ||||||
|  | .RS | ||||||
|  | determine whether to reset kernel crashkernel parameter to the default value | ||||||
|  | or not when kexec-tools is updated or a new kernel is installed. The default | ||||||
|  | crashkernel values are different for different architectures and also take the | ||||||
|  | following factors into consideration, | ||||||
|  | 	- AMD Secure Memory Encryption (SME) and Secure Encrypted Virtualization (SEV) | ||||||
|  | 	- Mellanox 5th generation network driver | ||||||
|  | 	- aarch64 64k kernel | ||||||
|  | 	- Firmware-assisted dump (FADump) | ||||||
|  | 
 | ||||||
|  | Since the kernel crasherkernel parameter will be only reset when kexec-tools is | ||||||
|  | updated or a new kernel is installed, you need to call "kdumpctl | ||||||
|  | reset-crashkernel [--kernel=path_to_kernel]" if you want to use the default | ||||||
|  | value set after having enabled features like SME/SEV for a specific kernel. And | ||||||
|  | you should also reboot the system for the new crashkernel value to take effect. | ||||||
|  | Also see kdumpctl(8). | ||||||
|  | 
 | ||||||
| .B raw <partition> | .B raw <partition> | ||||||
| .RS | .RS | ||||||
| Will dd /proc/vmcore into <partition>.  Use persistent device names for | Will dd /proc/vmcore into <partition>.  Use persistent device names for | ||||||
| @ -41,7 +59,7 @@ mount point. | |||||||
| 
 | 
 | ||||||
| .B ssh <user@server> | .B ssh <user@server> | ||||||
| .RS | .RS | ||||||
| Will scp /proc/vmcore to <user@server>:<path>/%HOST-%DATE/, | Will save /proc/vmcore through ssh pipe to <user@server>:<path>/%HOST-%DATE/, | ||||||
| supports DNS. NOTE: make sure user has necessary write permissions on | supports DNS. NOTE: make sure user has necessary write permissions on | ||||||
| server and that a fqdn is used as the server name. | server and that a fqdn is used as the server name. | ||||||
| .RE | .RE | ||||||
| @ -55,7 +73,7 @@ The default value is /root/.ssh/kdump_id_rsa. | |||||||
| .B <fs type> <partition> | .B <fs type> <partition> | ||||||
| .RS | .RS | ||||||
| Will mount -t <fs type> <partition> <mnt>, and copy /proc/vmcore to | Will mount -t <fs type> <partition> <mnt>, and copy /proc/vmcore to | ||||||
| <mnt>/<path>/%DATE/.  NOTE: <partition> can be a device node, label | <mnt>/<path>/%HOST_IP-%DATE/.  NOTE: <partition> can be a device node, label | ||||||
| or uuid.  It's recommended to use persistent device names such as | or uuid.  It's recommended to use persistent device names such as | ||||||
| /dev/vg/<devname>.  Otherwise it's suggested to use label or uuid. | /dev/vg/<devname>.  Otherwise it's suggested to use label or uuid. | ||||||
| .RE | .RE | ||||||
| @ -121,7 +139,7 @@ specified kdump_post parameter is executed. | |||||||
| Note that scripts written for use with this directive must use the /bin/bash | Note that scripts written for use with this directive must use the /bin/bash | ||||||
| interpreter. And since these scripts run in kdump enviroment, the reference to | interpreter. And since these scripts run in kdump enviroment, the reference to | ||||||
| the storage or network device in the scripts should adhere to the section | the storage or network device in the scripts should adhere to the section | ||||||
| \'Supported dump target types and requirements\' in kexec-kdump-howto.txt. | 'Supported dump target types and requirements' in kexec-kdump-howto.txt. | ||||||
| 
 | 
 | ||||||
| .RE | .RE | ||||||
| 
 | 
 | ||||||
| @ -145,7 +163,7 @@ returns non 0 exit status, the processing is continued. | |||||||
| Note that scripts written for use with this directive must use the /bin/bash | Note that scripts written for use with this directive must use the /bin/bash | ||||||
| interpreter. And since these scripts run in kdump enviroment, the reference to | interpreter. And since these scripts run in kdump enviroment, the reference to | ||||||
| the storage or network device in the scripts should adhere to the section | the storage or network device in the scripts should adhere to the section | ||||||
| \'Supported dump target types and requirements\' in kexec-kdump-howto.txt. | 'Supported dump target types and requirements' in kexec-kdump-howto.txt. | ||||||
| 
 | 
 | ||||||
| .RE | .RE | ||||||
| 
 | 
 | ||||||
| @ -296,7 +314,7 @@ retaining blacklist option creates more confusing behavior. It has been | |||||||
| deprecated. | deprecated. | ||||||
| .PP | .PP | ||||||
| Instead, use rd.driver.blacklist option on second kernel to blacklist | Instead, use rd.driver.blacklist option on second kernel to blacklist | ||||||
| a certain module. One can edit /etc/sysconfig/kdump and edit | a certain module. One can edit /etc/sysconfig/kdump.conf and edit | ||||||
| KDUMP_COMMANDLINE_APPEND to pass kernel command line options. Refer | KDUMP_COMMANDLINE_APPEND to pass kernel command line options. Refer | ||||||
| to dracut.cmdline man page for more details on module blacklist option. | to dracut.cmdline man page for more details on module blacklist option. | ||||||
| .RE | .RE | ||||||
|  | |||||||
| @ -11,6 +11,7 @@ ExecStop=/usr/bin/kdumpctl stop | |||||||
| ExecReload=/usr/bin/kdumpctl reload | ExecReload=/usr/bin/kdumpctl reload | ||||||
| RemainAfterExit=yes | RemainAfterExit=yes | ||||||
| StartLimitInterval=0 | StartLimitInterval=0 | ||||||
|  | PrivateTmp=yes | ||||||
| 
 | 
 | ||||||
| [Install] | [Install] | ||||||
| WantedBy=multi-user.target | WantedBy=multi-user.target | ||||||
|  | |||||||
| @ -17,11 +17,11 @@ KDUMP_COMMANDLINE="" | |||||||
| # This variable lets us remove arguments from the current kdump commandline | # This variable lets us remove arguments from the current kdump commandline | ||||||
| # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline | # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline | ||||||
| # NOTE: some arguments such as crashkernel will always be removed | # NOTE: some arguments such as crashkernel will always be removed | ||||||
| KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len ignition.firstboot" | KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb cma hugetlb_cma ignition.firstboot" | ||||||
| 
 | 
 | ||||||
| # This variable lets us append arguments to the current kdump commandline | # This variable lets us append arguments to the current kdump commandline | ||||||
| # after processed by KDUMP_COMMANDLINE_REMOVE | # after processed by KDUMP_COMMANDLINE_REMOVE | ||||||
| KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 reset_devices novmcoredd" | KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 reset_devices novmcoredd cma=0 hugetlb_cma=0" | ||||||
| 
 | 
 | ||||||
| # Any additional kexec arguments required.  In most situations, this should | # Any additional kexec arguments required.  In most situations, this should | ||||||
| # be left empty | # be left empty | ||||||
|  | |||||||
| @ -17,11 +17,11 @@ KDUMP_COMMANDLINE="" | |||||||
| # This variable lets us remove arguments from the current kdump commandline | # This variable lets us remove arguments from the current kdump commandline | ||||||
| # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline | # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline | ||||||
| # NOTE: some arguments such as crashkernel will always be removed | # NOTE: some arguments such as crashkernel will always be removed | ||||||
| KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb ignition.firstboot" | KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb cma hugetlb_cma ignition.firstboot" | ||||||
| 
 | 
 | ||||||
| # This variable lets us append arguments to the current kdump commandline | # This variable lets us append arguments to the current kdump commandline | ||||||
| # after processed by KDUMP_COMMANDLINE_REMOVE | # after processed by KDUMP_COMMANDLINE_REMOVE | ||||||
| KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices cgroup_disable=memory udev.children-max=2 panic=10 swiotlb=noforce novmcoredd" | KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices cgroup_disable=memory udev.children-max=2 panic=10 swiotlb=noforce novmcoredd cma=0 hugetlb_cma=0" | ||||||
| 
 | 
 | ||||||
| # Any additional kexec arguments required.  In most situations, this should | # Any additional kexec arguments required.  In most situations, this should | ||||||
| # be left empty | # be left empty | ||||||
|  | |||||||
| @ -17,11 +17,11 @@ KDUMP_COMMANDLINE="" | |||||||
| # This variable lets us remove arguments from the current kdump commandline | # This variable lets us remove arguments from the current kdump commandline | ||||||
| # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline | # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline | ||||||
| # NOTE: some arguments such as crashkernel will always be removed | # NOTE: some arguments such as crashkernel will always be removed | ||||||
| KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb ignition.firstboot" | KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb cma hugetlb_cma ignition.firstboot" | ||||||
| 
 | 
 | ||||||
| # This variable lets us append arguments to the current kdump commandline | # This variable lets us append arguments to the current kdump commandline | ||||||
| # after processed by KDUMP_COMMANDLINE_REMOVE | # after processed by KDUMP_COMMANDLINE_REMOVE | ||||||
| KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices numa=off udev.children-max=2 panic=10 rootflags=nofail transparent_hugepage=never novmcoredd" | KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices numa=off udev.children-max=2 panic=10 transparent_hugepage=never novmcoredd cma=0 hugetlb_cma=0" | ||||||
| 
 | 
 | ||||||
| # Any additional kexec arguments required.  In most situations, this should | # Any additional kexec arguments required.  In most situations, this should | ||||||
| # be left empty | # be left empty | ||||||
|  | |||||||
| @ -17,11 +17,11 @@ KDUMP_COMMANDLINE="" | |||||||
| # This variable lets us remove arguments from the current kdump commandline | # This variable lets us remove arguments from the current kdump commandline | ||||||
| # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline | # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline | ||||||
| # NOTE: some arguments such as crashkernel will always be removed | # NOTE: some arguments such as crashkernel will always be removed | ||||||
| KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb ignition.firstboot" | KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb hugetlb_cma ignition.firstboot" | ||||||
| 
 | 
 | ||||||
| # This variable lets us append arguments to the current kdump commandline | # This variable lets us append arguments to the current kdump commandline | ||||||
| # after processed by KDUMP_COMMANDLINE_REMOVE | # after processed by KDUMP_COMMANDLINE_REMOVE | ||||||
| KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 noirqdistrib reset_devices cgroup_disable=memory numa=off udev.children-max=2 ehea.use_mcs=0 panic=10 rootflags=nofail kvm_cma_resv_ratio=0 transparent_hugepage=never novmcoredd" | KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 noirqdistrib reset_devices cgroup_disable=memory numa=off udev.children-max=2 ehea.use_mcs=0 panic=10 kvm_cma_resv_ratio=0 transparent_hugepage=never novmcoredd hugetlb_cma=0" | ||||||
| 
 | 
 | ||||||
| # Any additional kexec arguments required.  In most situations, this should | # Any additional kexec arguments required.  In most situations, this should | ||||||
| # be left empty | # be left empty | ||||||
|  | |||||||
| @ -17,18 +17,18 @@ KDUMP_COMMANDLINE="" | |||||||
| # This variable lets us remove arguments from the current kdump commandline | # This variable lets us remove arguments from the current kdump commandline | ||||||
| # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline | # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline | ||||||
| # NOTE: some arguments such as crashkernel will always be removed | # NOTE: some arguments such as crashkernel will always be removed | ||||||
| KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb ignition.firstboot" | KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb hugetlb_cma ignition.firstboot" | ||||||
| 
 | 
 | ||||||
| # This variable lets us append arguments to the current kdump commandline | # This variable lets us append arguments to the current kdump commandline | ||||||
| # after processed by KDUMP_COMMANDLINE_REMOVE | # after processed by KDUMP_COMMANDLINE_REMOVE | ||||||
| KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 noirqdistrib reset_devices cgroup_disable=memory numa=off udev.children-max=2 ehea.use_mcs=0 panic=10 rootflags=nofail kvm_cma_resv_ratio=0 transparent_hugepage=never novmcoredd" | KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 noirqdistrib reset_devices cgroup_disable=memory numa=off udev.children-max=2 ehea.use_mcs=0 panic=10 kvm_cma_resv_ratio=0 transparent_hugepage=never novmcoredd hugetlb_cma=0" | ||||||
| 
 | 
 | ||||||
| # Any additional kexec arguments required.  In most situations, this should | # Any additional kexec arguments required.  In most situations, this should | ||||||
| # be left empty | # be left empty | ||||||
| # | # | ||||||
| # Example: | # Example: | ||||||
| #   KEXEC_ARGS="--elf32-core-headers" | #   KEXEC_ARGS="--elf32-core-headers" | ||||||
| KEXEC_ARGS="--dt-no-old-root" | KEXEC_ARGS="--dt-no-old-root -s" | ||||||
| 
 | 
 | ||||||
| #Where to find the boot image | #Where to find the boot image | ||||||
| #KDUMP_BOOTDIR="/boot" | #KDUMP_BOOTDIR="/boot" | ||||||
|  | |||||||
| @ -17,11 +17,11 @@ KDUMP_COMMANDLINE="" | |||||||
| # This variable lets us remove arguments from the current kdump commandline | # This variable lets us remove arguments from the current kdump commandline | ||||||
| # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline | # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline | ||||||
| # NOTE: some arguments such as crashkernel will always be removed | # NOTE: some arguments such as crashkernel will always be removed | ||||||
| KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb prot_virt ignition.firstboot zfcp.allow_lun_scan" | KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb vmcp_cma cma hugetlb_cma prot_virt ignition.firstboot zfcp.allow_lun_scan" | ||||||
| 
 | 
 | ||||||
| # This variable lets us append arguments to the current kdump commandline | # This variable lets us append arguments to the current kdump commandline | ||||||
| # after processed by KDUMP_COMMANDLINE_REMOVE | # after processed by KDUMP_COMMANDLINE_REMOVE | ||||||
| KDUMP_COMMANDLINE_APPEND="nr_cpus=1 cgroup_disable=memory numa=off udev.children-max=2 panic=10 rootflags=nofail transparent_hugepage=never novmcoredd" | KDUMP_COMMANDLINE_APPEND="nr_cpus=1 cgroup_disable=memory numa=off udev.children-max=2 panic=10 transparent_hugepage=never novmcoredd vmcp_cma=0 cma=0 hugetlb_cma=0" | ||||||
| 
 | 
 | ||||||
| # Any additional /sbin/mkdumprd arguments required. | # Any additional /sbin/mkdumprd arguments required. | ||||||
| MKDUMPRD_ARGS="" | MKDUMPRD_ARGS="" | ||||||
|  | |||||||
| @ -17,11 +17,11 @@ KDUMP_COMMANDLINE="" | |||||||
| # This variable lets us remove arguments from the current kdump commandline | # This variable lets us remove arguments from the current kdump commandline | ||||||
| # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline | # as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline | ||||||
| # NOTE: some arguments such as crashkernel will always be removed | # NOTE: some arguments such as crashkernel will always be removed | ||||||
| KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb ignition.firstboot" | KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb cma hugetlb_cma ignition.firstboot" | ||||||
| 
 | 
 | ||||||
| # This variable lets us append arguments to the current kdump commandline | # This variable lets us append arguments to the current kdump commandline | ||||||
| # after processed by KDUMP_COMMANDLINE_REMOVE | # after processed by KDUMP_COMMANDLINE_REMOVE | ||||||
| KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices cgroup_disable=memory mce=off numa=off udev.children-max=2 panic=10 rootflags=nofail acpi_no_memhotplug transparent_hugepage=never nokaslr novmcoredd hest_disable" | KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices cgroup_disable=memory mce=off numa=off udev.children-max=2 panic=10 acpi_no_memhotplug transparent_hugepage=never nokaslr hest_disable novmcoredd cma=0 hugetlb_cma=0" | ||||||
| 
 | 
 | ||||||
| # Any additional kexec arguments required.  In most situations, this should | # Any additional kexec arguments required.  In most situations, this should | ||||||
| # be left empty | # be left empty | ||||||
|  | |||||||
							
								
								
									
										1161
									
								
								SOURCES/kdumpctl
									
									
									
									
									
								
							
							
						
						
									
										1161
									
								
								SOURCES/kdumpctl
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -14,7 +14,7 @@ In most cases, you should use | |||||||
| .B systemctl | .B systemctl | ||||||
| to start / stop / enable kdump service instead. However, | to start / stop / enable kdump service instead. However, | ||||||
| .B kdumpctl | .B kdumpctl | ||||||
| provides more details for debug and a helper to setup ssh key authentication. | provides more details for debugging and a helper to set up ssh key authentication. | ||||||
| 
 | 
 | ||||||
| .SH COMMANDS | .SH COMMANDS | ||||||
| .TP | .TP | ||||||
| @ -26,14 +26,14 @@ Stop the service. | |||||||
| .TP | .TP | ||||||
| .I status | .I status | ||||||
| Prints the current status of kdump service. | Prints the current status of kdump service. | ||||||
| It returns non-zero value if kdump is not operational. | It returns a non-zero value if kdump is not operational. | ||||||
| .TP | .TP | ||||||
| .I restart | .I restart | ||||||
| Is equal to | Is equal to | ||||||
| .I start; stop | .I start; stop | ||||||
| .TP | .TP | ||||||
| .I reload | .I reload | ||||||
| reload crash kernel image and initramfs without triggering a rebuild. | reload the crash kernel image and initramfs without triggering a rebuild. | ||||||
| .TP | .TP | ||||||
| .I rebuild | .I rebuild | ||||||
| rebuild the crash kernel initramfs. | rebuild the crash kernel initramfs. | ||||||
| @ -43,12 +43,29 @@ Helps to setup key authentication for ssh storage since it's | |||||||
| impossible to use password authentication during kdump. | impossible to use password authentication during kdump. | ||||||
| .TP | .TP | ||||||
| .I showmem | .I showmem | ||||||
| Prints the size of reserved memory for crash kernel in megabytes. | Prints the size of reserved memory for the crash kernel in megabytes. | ||||||
| .TP | .TP | ||||||
| .I estimate | .I estimate | ||||||
| Estimate a suitable crashkernel value for current machine. This is a | Estimate a suitable crashkernel value for the current machine. This is a | ||||||
| best-effort estimate. It will print a recommanded crashkernel value | best-effort estimate. It will print a recommended crashkernel value | ||||||
| based on current kdump setup, and list some details of memory usage. | based on the current kdump setup, and list some details of memory usage. | ||||||
|  | .TP | ||||||
|  | .I get-default-crashkernel | ||||||
|  | Return the default crashkernel value provided by kexec-tools. | ||||||
|  | .TP | ||||||
|  | .I reset-crashkernel [--kernel=path_to_kernel] [--reboot] | ||||||
|  | Reset crashkernel to default value recommended by kexec-tools. If no kernel | ||||||
|  | is specified, will reset KDUMP_KERNELVER if it's defined in /etc/sysconfig/kdump | ||||||
|  | or the current running kernel's crashkernel value if KDUMP_KERNELVER is empty. You can | ||||||
|  | also specify --kernel=ALL and --kernel=DEFAULT which have the same meaning as | ||||||
|  | grubby's kernel-path=ALL and kernel-path=DEFAULT. ppc64le supports FADump and | ||||||
|  | supports an additional [--fadump=[on|off|nocma]] parameter to toggle FADump | ||||||
|  | on/off. | ||||||
|  | 
 | ||||||
|  | Note: The memory requirements for kdump varies heavily depending on the | ||||||
|  | used hardware and system configuration. Thus the recommended | ||||||
|  | crashkernel might not work for your specific setup. Please test if | ||||||
|  | kdump works after resetting the crashkernel value. | ||||||
| 
 | 
 | ||||||
| .SH "SEE ALSO" | .SH "SEE ALSO" | ||||||
| .BR kdump.conf (5), | .BR kdump.conf (5), | ||||||
|  | |||||||
| @ -44,7 +44,7 @@ ia64 and ppc64. | |||||||
| If you're reading this document, you should already have kexec-tools | If you're reading this document, you should already have kexec-tools | ||||||
| installed. If not, you install it via the following command: | installed. If not, you install it via the following command: | ||||||
| 
 | 
 | ||||||
|     # yum install kexec-tools |     # dnf install kexec-tools | ||||||
| 
 | 
 | ||||||
| Now load a kernel with kexec: | Now load a kernel with kexec: | ||||||
| 
 | 
 | ||||||
| @ -66,23 +66,31 @@ How to configure kdump | |||||||
| Again, we assume if you're reading this document, you should already have | 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: | kexec-tools installed. If not, you install it via the following command: | ||||||
| 
 | 
 | ||||||
|     # yum install kexec-tools |     # dnf install kexec-tools | ||||||
| 
 | 
 | ||||||
| To be able to do much of anything interesting in the way of debug analysis, | 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 | you'll also need to install the kernel-debuginfo package, of the same arch | ||||||
| as your running kernel, and the crash utility: | as your running kernel, and the crash utility: | ||||||
| 
 | 
 | ||||||
|     # yum --enablerepo=\*debuginfo install kernel-debuginfo.$(uname -m) crash |     # dnf --enablerepo=\*debuginfo install kernel-debuginfo.$(uname -m) crash | ||||||
| 
 | 
 | ||||||
| Next up, we need to modify some boot parameters to reserve a chunk of memory for | Next up, we need to reserve a chunk of memory for the capture kernel. To use | ||||||
| the capture kernel. With the help of grubby, it's very easy to append | the default crashkernel value, you can kdumpctl: | ||||||
| "crashkernel=128M" to the end of your kernel boot parameters. Note that the X |  | ||||||
| values are such that X = the amount of memory to reserve for the capture kernel. |  | ||||||
| And based on arch and system configuration, one might require more than 128M to |  | ||||||
| be reserved for kdump. One need to experiment and test kdump, if 128M is not |  | ||||||
| sufficient, try reserving more memory. |  | ||||||
| 
 | 
 | ||||||
|    # grubby --args="crashkernel=128M" --update-kernel=/boot/vmlinuz-`uname -r` |     # kdumpctl reset-crashkernel --kernel=/boot/vmlinuz-`uname -r` | ||||||
|  | 
 | ||||||
|  | If the default value does not work for your setup you can use | ||||||
|  | 
 | ||||||
|  |   # grubby --args="crashkernel=256M" --update-kernel=/boot/vmlinuz-`uname -r` | ||||||
|  | 
 | ||||||
|  | to specify a larger value, in this case 256M. You need to experiment to | ||||||
|  | find the best value that works for your setup. To begin with | ||||||
|  | 
 | ||||||
|  |   # kdumpctl estimate | ||||||
|  | 
 | ||||||
|  | gives you an estimation for the crashkernel value based on the currently | ||||||
|  | running kernel. For more details, please refer to the "Estimate crashkernel" | ||||||
|  | section in /usr/share/doc/kexec-tools/crashkernel-howto.txt. | ||||||
| 
 | 
 | ||||||
| Note that there is an alternative form in which to specify a crashkernel | Note that there is an alternative form in which to specify a crashkernel | ||||||
| memory reservation, in the event that more control is needed over the size and | memory reservation, in the event that more control is needed over the size and | ||||||
| @ -135,7 +143,7 @@ in /var/crash/<YYYY-MM-DD-HH:MM>/vmcore), then the system rebooted back into | |||||||
| your normal kernel. | your normal kernel. | ||||||
| 
 | 
 | ||||||
| Once back to your normal kernel, you can use the previously installed crash | Once back to your normal kernel, you can use the previously installed crash | ||||||
| kernel in conjunction with the previously installed kernel-debuginfo to | utility in conjunction with the previously installed kernel-debuginfo to | ||||||
| perform postmortem analysis: | perform postmortem analysis: | ||||||
| 
 | 
 | ||||||
|     # crash /usr/lib/debug/lib/modules/2.6.17-1.2621.el5/vmlinux |     # crash /usr/lib/debug/lib/modules/2.6.17-1.2621.el5/vmlinux | ||||||
| @ -187,7 +195,7 @@ on your system, with the scripts enabled as described in the section above. | |||||||
| Kdump can be triggered with the combination of the 'Alt','SysRq' and 'C' | Kdump can be triggered with the combination of the 'Alt','SysRq' and 'C' | ||||||
| keyboard keys. Please refer to the following link for more details: | keyboard keys. Please refer to the following link for more details: | ||||||
| 
 | 
 | ||||||
| https://access.redhat.com/solutions/2023 | http://kbase.redhat.com/faq/FAQ_43_5559.shtm | ||||||
| 
 | 
 | ||||||
| In addition, on PowerPC boxes, Kdump can also be triggered via Hardware | In addition, on PowerPC boxes, Kdump can also be triggered via Hardware | ||||||
| Management Console(HMC) using 'Ctrl', 'O' and 'C' keyboard keys. | Management Console(HMC) using 'Ctrl', 'O' and 'C' keyboard keys. | ||||||
| @ -199,7 +207,7 @@ respond to keyboard interrupts. As a result 'Alt-SysRq' keys will not help | |||||||
| trigger a dump. In such scenarios Nmi Watchdog feature can prove to be useful. | trigger a dump. In such scenarios Nmi Watchdog feature can prove to be useful. | ||||||
| The following link has more details on configuring Nmi watchdog option. | The following link has more details on configuring Nmi watchdog option. | ||||||
| 
 | 
 | ||||||
| https://access.redhat.com/solutions/125103 | http://kbase.redhat.com/faq/FAQ_85_9129.shtm | ||||||
| 
 | 
 | ||||||
| Once this feature has been enabled in the kernel, any lockups will result in an | Once this feature has been enabled in the kernel, any lockups will result in an | ||||||
| OOPs message to be generated, followed by Kdump being triggered. | OOPs message to be generated, followed by Kdump being triggered. | ||||||
|  | |||||||
| @ -1,72 +0,0 @@ | |||||||
| From 58553ad03187f0cf208d6c4a0dc026c6338e5edd Mon Sep 17 00:00:00 2001 |  | ||||||
| From: "Daisuke Hatayama (Fujitsu)" <d.hatayama@fujitsu.com> |  | ||||||
| Date: Wed, 29 Mar 2023 12:44:10 +0000 |  | ||||||
| Subject: [PATCH] [PATCH] sadump: fix failure of reading memory when 5-level |  | ||||||
|  paging is enabled |  | ||||||
| 
 |  | ||||||
| makedumpfile fails as follows for memory dumps collected by sadump |  | ||||||
| when 5-level paging is enabled on the corresponding systems: |  | ||||||
| 
 |  | ||||||
|     # makedumpfile -l -d 31 -x ./vmlinux ./dump.sadump dump.sadump-ld31 |  | ||||||
|     __vtop4_x86_64: Can't get a valid pgd. |  | ||||||
|     ...snip... |  | ||||||
|     __vtop4_x86_64: Can't get a valid pgd. |  | ||||||
|     calc_kaslr_offset: failed to calculate kaslr_offset and phys_base; default to 0 |  | ||||||
|     __vtop4_x86_64: Can't get a valid pgd. |  | ||||||
|     readmem: Can't convert a virtual address(ffffffff82fce960) to physical address. |  | ||||||
|     readmem: type_addr: 0, addr:ffffffff82fce960, size:1024 |  | ||||||
|     cpu_online_mask_init: Can't read cpu_online_mask memory. |  | ||||||
| 
 |  | ||||||
|     makedumpfile Failed. |  | ||||||
| 
 |  | ||||||
| This is because 5-level paging support has not been done yet for |  | ||||||
| sadump; the work of the 5-level paging support was done by the commit |  | ||||||
| 30a3214a7193e94c551c0cebda5918a72a35c589 (PATCH 4/4 arch/x86_64: Add |  | ||||||
| 5-level paging support) but that was focused on the core part only. |  | ||||||
| 
 |  | ||||||
| Having said that, most of things has already been finished in the |  | ||||||
| commit. What needs to be newly added for sadump is just how to check |  | ||||||
| if 5-level paging is enabled for a given memory dump. |  | ||||||
| 
 |  | ||||||
| For that purpose, let's refer to CR4.LA57, bit 12 of CR4, representing |  | ||||||
| whether 5-level paging is enabled or not. We can do this because |  | ||||||
| memory dumps collected by sadump have SMRAM as note information and |  | ||||||
| they include CR4 together with the other control registers. |  | ||||||
| 
 |  | ||||||
| Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com> |  | ||||||
| ---
 |  | ||||||
|  sadump_info.c | 4 ++++ |  | ||||||
|  1 file changed, 4 insertions(+) |  | ||||||
| 
 |  | ||||||
| diff --git a/makedumpfile-1.7.2/sadump_info.c b/makedumpfile-1.7.2/sadump_info.c
 |  | ||||||
| index adfa8dc..2c44068 100644
 |  | ||||||
| --- a/makedumpfile-1.7.2/sadump_info.c
 |  | ||||||
| +++ b/makedumpfile-1.7.2/sadump_info.c
 |  | ||||||
| @@ -1362,6 +1362,7 @@ static int linux_banner_sanity_check(ulong cr3)
 |  | ||||||
|  #define PTI_USER_PGTABLE_BIT		(info->page_shift) |  | ||||||
|  #define PTI_USER_PGTABLE_MASK		(1 << PTI_USER_PGTABLE_BIT) |  | ||||||
|  #define CR3_PCID_MASK			0xFFFull |  | ||||||
| +#define CR4_LA57			(1 << 12)
 |  | ||||||
|  int |  | ||||||
|  calc_kaslr_offset(void) |  | ||||||
|  { |  | ||||||
| @@ -1397,6 +1398,8 @@ calc_kaslr_offset(void)
 |  | ||||||
|  		else |  | ||||||
|  			cr3 = smram.Cr3 & ~CR3_PCID_MASK; |  | ||||||
|   |  | ||||||
| +		NUMBER(pgtable_l5_enabled) = !!(smram.Cr4 & CR4_LA57);
 |  | ||||||
| +
 |  | ||||||
|  		/* Convert virtual address of IDT table to physical address */ |  | ||||||
|  		idtr_paddr = vtop4_x86_64_pagetable(idtr, cr3); |  | ||||||
|  		if (idtr_paddr == NOT_PADDR) { |  | ||||||
| @@ -1417,6 +1420,7 @@ calc_kaslr_offset(void)
 |  | ||||||
|   |  | ||||||
|  		DEBUG_MSG("sadump: idtr=%" PRIx64 "\n", idtr); |  | ||||||
|  		DEBUG_MSG("sadump: cr3=%" PRIx64 "\n", cr3); |  | ||||||
| +		DEBUG_MSG("sadump: cr4=%" PRIx32 "\n", smram.Cr4);
 |  | ||||||
|  		DEBUG_MSG("sadump: idtr(phys)=%" PRIx64 "\n", idtr_paddr); |  | ||||||
|  		DEBUG_MSG("sadump: devide_error(vmlinux)=%lx\n", |  | ||||||
|  			  divide_error_vmlinux); |  | ||||||
| -- 
 |  | ||||||
| 2.31.1 |  | ||||||
| 
 |  | ||||||
| @ -0,0 +1,39 @@ | |||||||
|  | From bd0200c47c45dd420244b39ddabcecdab1fb9a8e Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Hari Bathini <hbathini@linux.ibm.com> | ||||||
|  | Date: Wed, 20 Sep 2023 17:29:27 +0530 | ||||||
|  | Subject: [PATCH] kexec: update manpage with explicit mention of clean kexec | ||||||
|  | 
 | ||||||
|  | While the manpage does mention about kexec boot with a clean shutdown, | ||||||
|  | it is not explicit about it. Make it explicit. | ||||||
|  | 
 | ||||||
|  | Signed-off-by: Hari Bathini <hbathini@linux.ibm.com> | ||||||
|  | Signed-off-by: Simon Horman <horms@kernel.org> | ||||||
|  | ---
 | ||||||
|  |  kexec/kexec.8 | 11 +++++++++-- | ||||||
|  |  1 file changed, 9 insertions(+), 2 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/kexec/kexec.8 b/kexec/kexec.8
 | ||||||
|  | index 3a344c5..179dcf2 100644
 | ||||||
|  | --- a/kexec/kexec.8
 | ||||||
|  | +++ b/kexec/kexec.8
 | ||||||
|  | @@ -95,8 +95,15 @@ then you would use the following command to load the kernel:
 | ||||||
|  |  .RB "\-\-append=" "root=/dev/hda1" "\ \-\-initrd=" /boot/initrd | ||||||
|  |  .RE | ||||||
|  |  .PP | ||||||
|  | -After this kernel is loaded, it can be booted to at any time using the
 | ||||||
|  | -command:
 | ||||||
|  | +After this kernel is loaded, assuming the user-space supports kexec-based
 | ||||||
|  | +rebooting, it can be booted to, with a clean shutdown, using the command:
 | ||||||
|  | +
 | ||||||
|  | +.RS
 | ||||||
|  | +.BR reboot
 | ||||||
|  | +.RE
 | ||||||
|  | +.PP
 | ||||||
|  | +Alternatively, it can also be booted to, without calling shutdown(8), with
 | ||||||
|  | +the command:
 | ||||||
|  | 
 | ||||||
|  |  .RS | ||||||
|  |  .BR kexec \ \-e | ||||||
|  | --
 | ||||||
|  | 2.41.0 | ||||||
|  | 
 | ||||||
							
								
								
									
										583
									
								
								SOURCES/mkdumprd
									
									
									
									
									
								
							
							
						
						
									
										583
									
								
								SOURCES/mkdumprd
									
									
									
									
									
								
							| @ -6,7 +6,7 @@ | |||||||
| # Written by Cong Wang <amwang@redhat.com> | # Written by Cong Wang <amwang@redhat.com> | ||||||
| # | # | ||||||
| 
 | 
 | ||||||
| if [ -f /etc/sysconfig/kdump ]; then | if [[ -f /etc/sysconfig/kdump ]]; then | ||||||
| 	. /etc/sysconfig/kdump | 	. /etc/sysconfig/kdump | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| @ -17,23 +17,21 @@ fi | |||||||
| export IN_KDUMP=1 | export IN_KDUMP=1 | ||||||
| 
 | 
 | ||||||
| #initiate the kdump logger | #initiate the kdump logger | ||||||
| dlog_init | if ! dlog_init; then | ||||||
| if [ $? -ne 0 ]; then |  | ||||||
| 	echo "failed to initiate the kdump logger." | 	echo "failed to initiate the kdump logger." | ||||||
| 	exit 1 | 	exit 1 | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| conf_file="/etc/kdump.conf" |  | ||||||
| SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa" | SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa" | ||||||
| SAVE_PATH=$(get_save_path) | SAVE_PATH=$(get_save_path) | ||||||
| OVERRIDE_RESETTABLE=0 | OVERRIDE_RESETTABLE=0 | ||||||
| 
 | 
 | ||||||
| extra_modules="" | extra_modules="" | ||||||
| dracut_args="--add kdumpbase --quiet --hostonly --hostonly-cmdline --hostonly-i18n --hostonly-mode strict --hostonly-nics '' -o \"plymouth dash resume ifcfg earlykdump\" --compress=xz" | dracut_args=(--add kdumpbase --quiet --hostonly --hostonly-cmdline --hostonly-i18n --hostonly-mode strict --hostonly-nics '' -o "plymouth resume ifcfg earlykdump") | ||||||
| 
 | 
 | ||||||
| readonly MKDUMPRD_TMPDIR="$(mktemp -d -t mkdumprd.XXXXXX)" | MKDUMPRD_TMPDIR="$(mktemp -d -t mkdumprd.XXXXXX)" | ||||||
| [ -d "$MKDUMPRD_TMPDIR" ] || perror_exit "dracut: mktemp -p -d -t dracut.XXXXXX failed." | [ -d "$MKDUMPRD_TMPDIR" ] || perror_exit "dracut: mktemp -p -d -t dracut.XXXXXX failed." | ||||||
| readonly MKDUMPRD_TMPMNT="$MKDUMPRD_TMPDIR/target" | MKDUMPRD_TMPMNT="$MKDUMPRD_TMPDIR/target" | ||||||
| 
 | 
 | ||||||
| trap ' | trap ' | ||||||
|     ret=$?; |     ret=$?; | ||||||
| @ -45,66 +43,71 @@ trap ' | |||||||
| # clean up after ourselves no matter how we die. | # clean up after ourselves no matter how we die. | ||||||
| trap 'exit 1;' SIGINT | trap 'exit 1;' SIGINT | ||||||
| 
 | 
 | ||||||
| add_dracut_arg() { | add_dracut_arg() | ||||||
|     dracut_args="$dracut_args $@" | { | ||||||
|  | 	dracut_args+=("$@") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| add_dracut_mount() { | add_dracut_mount() | ||||||
|     add_dracut_arg "--mount" "\"$1\"" | { | ||||||
|  | 	add_dracut_arg "--mount" "$1" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| add_dracut_sshkey() { | add_dracut_sshkey() | ||||||
|     add_dracut_arg "--sshkey" "\"$1\"" | { | ||||||
|  | 	add_dracut_arg "--sshkey" "$1" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| # caller should ensure $1 is valid and mounted in 1st kernel | # caller should ensure $1 is valid and mounted in 1st kernel | ||||||
| to_mount() { | to_mount() | ||||||
|     local _target=$1 _fstype=$2 _options=$3 _new_mntpoint _pdev | { | ||||||
|  | 	local _target=$1 _fstype=$2 _options=$3 _sed_cmd _new_mntpoint _pdev | ||||||
| 
 | 
 | ||||||
|     _new_mntpoint=$(get_kdump_mntpoint_from_target $_target) | 	_new_mntpoint=$(get_kdump_mntpoint_from_target "$_target") | ||||||
|     _fstype="${_fstype:-$(get_fs_type_from_target $_target)}" | 	_fstype="${_fstype:-$(get_fs_type_from_target "$_target")}" | ||||||
|     _options="${_options:-$(get_mntopt_from_target $_target)}" | 	_options="${_options:-$(get_mntopt_from_target "$_target")}" | ||||||
|     _options="${_options:-defaults}" | 	_options="${_options:-defaults}" | ||||||
| 
 | 
 | ||||||
|     if [[ "$_fstype" == "nfs"* ]]; then | 	if [[ $_fstype == "nfs"* ]]; then | ||||||
|         _pdev=$_target | 		_pdev=$_target | ||||||
|         _options=$(echo $_options | sed 's/,\(mount\)\?addr=[^,]*//g') | 		_sed_cmd+='s/,\(mount\)\?addr=[^,]*//g;' | ||||||
|         _options=$(echo $_options | sed 's/,\(mount\)\?proto=[^,]*//g') | 		_sed_cmd+='s/,\(mount\)\?proto=[^,]*//g;' | ||||||
|         _options=$(echo $_options | sed 's/,clientaddr=[^,]*//') | 		_sed_cmd+='s/,clientaddr=[^,]*//;' | ||||||
|     else | 	else | ||||||
|         # for non-nfs _target converting to use udev persistent name | 		# for non-nfs _target converting to use udev persistent name | ||||||
|         _pdev="$(kdump_get_persistent_dev $_target)" | 		_pdev="$(kdump_get_persistent_dev "$_target")" | ||||||
|         if [ -z "$_pdev" ]; then | 		if [[ -z $_pdev ]]; then | ||||||
|             return 1 | 			return 1 | ||||||
|         fi | 		fi | ||||||
|     fi | 	fi | ||||||
| 
 | 
 | ||||||
|     #mount fs target as rw in 2nd kernel | 	# mount fs target as rw in 2nd kernel | ||||||
|     _options=$(echo $_options | sed 's/\(^\|,\)ro\($\|,\)/\1rw\2/g') | 	_sed_cmd+='s/\(^\|,\)ro\($\|,\)/\1rw\2/g;' | ||||||
|     # with 'noauto' in fstab nfs and non-root disk mount will fail in 2nd | 	# with 'noauto' in fstab nfs and non-root disk mount will fail in 2nd | ||||||
|     # kernel, filter it out here. | 	# kernel, filter it out here. | ||||||
|     _options=$(echo $_options | sed 's/\(^\|,\)noauto\($\|,\)/\1/g') | 	_sed_cmd+='s/\(^\|,\)noauto\($\|,\)/\1/g;' | ||||||
|     # use both nofail and x-systemd.before to ensure systemd will try best to | 	# drop nofail or nobootwait | ||||||
|     # mount it before kdump starts, this is an attempt to improve robustness | 	_sed_cmd+='s/\(^\|,\)nofail\($\|,\)/\1/g;' | ||||||
|     _options="$_options,nofail,x-systemd.before=initrd-fs.target" | 	_sed_cmd+='s/\(^\|,\)nobootwait\($\|,\)/\1/g;' | ||||||
| 
 | 
 | ||||||
|     echo "$_pdev $_new_mntpoint $_fstype $_options" | 	_options=$(echo "$_options" | sed "$_sed_cmd") | ||||||
|  | 
 | ||||||
|  | 	echo "$_pdev $_new_mntpoint $_fstype $_options" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #Function: get_ssh_size | #Function: get_ssh_size | ||||||
| #$1=dump target | #$1=dump target | ||||||
| #called from while loop and shouldn't read from stdin, so we're using "ssh -n" | #called from while loop and shouldn't read from stdin, so we're using "ssh -n" | ||||||
| get_ssh_size() { | get_ssh_size() | ||||||
|     local _opt _out _size | { | ||||||
|     _opt="-i $SSH_KEY_LOCATION -o BatchMode=yes -o StrictHostKeyChecking=yes" | 	local _out | ||||||
|     _out=$(ssh -q -n $_opt $1 "df -P $SAVE_PATH") | 	local _opt=("-i" "$SSH_KEY_LOCATION" "-o" "BatchMode=yes" "-o" "StrictHostKeyChecking=yes") | ||||||
|     [ $? -ne 0 ] && { |  | ||||||
|         perror_exit "checking remote ssh server available size failed." |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     #ssh output removed the line break, so print field NF-2 | 	if ! _out=$(ssh -q -n "${_opt[@]}" "$1" "df" "--output=avail" "$SAVE_PATH"); then | ||||||
|     _size=$(echo -n $_out| awk '{avail=NF-2; print $avail}') | 		perror_exit "checking remote ssh server available size failed." | ||||||
|     echo -n $_size | 	fi | ||||||
|  | 
 | ||||||
|  | 	echo -n "$_out" | tail -1 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #mkdir if save path does not exist on ssh dump target | #mkdir if save path does not exist on ssh dump target | ||||||
| @ -113,323 +116,340 @@ get_ssh_size() { | |||||||
| #called from while loop and shouldn't read from stdin, so we're using "ssh -n" | #called from while loop and shouldn't read from stdin, so we're using "ssh -n" | ||||||
| mkdir_save_path_ssh() | mkdir_save_path_ssh() | ||||||
| { | { | ||||||
|     local _opt _dir | 	local _opt _dir | ||||||
|     _opt="-i $SSH_KEY_LOCATION -o BatchMode=yes -o StrictHostKeyChecking=yes" | 	_opt=(-i "$SSH_KEY_LOCATION" -o BatchMode=yes -o StrictHostKeyChecking=yes) | ||||||
|     ssh -qn $_opt $1 mkdir -p $SAVE_PATH 2>&1 > /dev/null | 	ssh -qn "${_opt[@]}" "$1" mkdir -p "$SAVE_PATH" &> /dev/null || | ||||||
|     _ret=$? | 		perror_exit "mkdir failed on $1:$SAVE_PATH" | ||||||
|     if [ $_ret -ne 0 ]; then |  | ||||||
|         perror_exit "mkdir failed on $1:$SAVE_PATH" |  | ||||||
|     fi |  | ||||||
| 
 | 
 | ||||||
|     #check whether user has write permission on $1:$SAVE_PATH | 	# check whether user has write permission on $1:$SAVE_PATH | ||||||
|     _dir=$(ssh -qn $_opt $1 mktemp -dqp $SAVE_PATH 2>/dev/null) | 	_dir=$(ssh -qn "${_opt[@]}" "$1" mktemp -dqp "$SAVE_PATH" 2> /dev/null) || | ||||||
|     _ret=$? | 		perror_exit "Could not create temporary directory on $1:$SAVE_PATH. Make sure user has write permission on destination" | ||||||
|     if [ $_ret -ne 0 ]; then | 	ssh -qn "${_opt[@]}" "$1" rmdir "$_dir" | ||||||
|         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 |  | ||||||
| 
 | 
 | ||||||
|     return 0 | 	return 0 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #Function: get_fs_size | #Function: get_fs_size | ||||||
| #$1=dump target | #$1=dump target | ||||||
| get_fs_size() { | get_fs_size() | ||||||
|     local _mnt=$(get_mntpoint_from_target $1) | { | ||||||
|     echo -n $(df -P "${_mnt}/$SAVE_PATH"|tail -1|awk '{print $4}') | 	df --output=avail "$(get_mntpoint_from_target "$1")/$SAVE_PATH" | tail -1 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #Function: get_raw_size | #Function: get_raw_size | ||||||
| #$1=dump target | #$1=dump target | ||||||
| get_raw_size() { | get_raw_size() | ||||||
|         echo -n $(fdisk -s "$1") | { | ||||||
|  | 	fdisk -s "$1" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #Function: check_size | #Function: check_size | ||||||
| #$1: dump type string ('raw', 'fs', 'ssh') | #$1: dump type string ('raw', 'fs', 'ssh') | ||||||
| #$2: dump target | #$2: dump target | ||||||
| check_size() { | check_size() | ||||||
|     local avail memtotal | { | ||||||
|  | 	local avail memtotal | ||||||
| 
 | 
 | ||||||
|     memtotal=$(awk '/MemTotal/{print $2}' /proc/meminfo) | 	memtotal=$(awk '/MemTotal/{print $2}' /proc/meminfo) | ||||||
|     case "$1" in | 	case "$1" in | ||||||
|         raw) | 	raw) | ||||||
|             avail=$(get_raw_size "$2") | 		avail=$(get_raw_size "$2") | ||||||
|             ;; | 		;; | ||||||
|         ssh) | 	ssh) | ||||||
|             avail=$(get_ssh_size "$2") | 		avail=$(get_ssh_size "$2") | ||||||
|             ;; | 		;; | ||||||
|         fs) | 	fs) | ||||||
|             avail=$(get_fs_size "$2") | 		avail=$(get_fs_size "$2") | ||||||
|             ;; | 		;; | ||||||
|         *) | 	*) | ||||||
|             return | 		return | ||||||
|     esac | 		;; | ||||||
|  | 	esac || perror_exit "Check dump target size failed" | ||||||
| 
 | 
 | ||||||
|     if [ $? -ne 0 ]; then | 	if [[ $avail -lt $memtotal ]]; then | ||||||
|             perror_exit "Check dump target size failed" | 		dwarn "Warning: There might not be enough space to save a vmcore." | ||||||
|     fi | 		dwarn "         The size of $2 should be greater than $memtotal kilo bytes." | ||||||
| 
 | 	fi | ||||||
|     if [ $avail -lt $memtotal ]; then |  | ||||||
|         dwarn "Warning: There might not be enough space to save a vmcore." |  | ||||||
|         dwarn "         The size of $2 should be greater than $memtotal kilo bytes." |  | ||||||
|     fi |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| check_save_path_fs() | check_save_path_fs() | ||||||
| { | { | ||||||
|     local _path=$1 | 	local _path=$1 | ||||||
| 
 | 
 | ||||||
|     if [ ! -d $_path ]; then | 	if [[ ! -d $_path ]]; then | ||||||
|         perror_exit "Dump path $_path does not exist." | 		perror_exit "Dump path $_path does not exist." | ||||||
|     fi | 	fi | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | mount_failure() | ||||||
|  | { | ||||||
|  | 	local _target=$1 | ||||||
|  | 	local _mnt=$2 | ||||||
|  | 	local _fstype=$3 | ||||||
|  | 	local msg="Failed to mount $_target" | ||||||
|  | 
 | ||||||
|  | 	if [[ -n $_mnt ]]; then | ||||||
|  | 		msg="$msg on $_mnt" | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	msg="$msg for kdump preflight check." | ||||||
|  | 
 | ||||||
|  | 	if [[ $_fstype == "nfs" ]]; then | ||||||
|  | 		msg="$msg Please make sure nfs-utils has been installed." | ||||||
|  | 	fi | ||||||
|  | 
 | ||||||
|  | 	perror_exit "$msg" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| check_user_configured_target() | check_user_configured_target() | ||||||
| { | { | ||||||
|     local _target=$1 _cfg_fs_type=$2 _mounted | 	local _target=$1 _cfg_fs_type=$2 _mounted | ||||||
|     local _mnt=$(get_mntpoint_from_target $_target) | 	local _mnt _opt _fstype | ||||||
|     local _opt=$(get_mntopt_from_target $_target) |  | ||||||
|     local _fstype=$(get_fs_type_from_target $_target) |  | ||||||
| 
 | 
 | ||||||
|     if [ -n "$_fstype" ]; then | 	_mnt=$(get_mntpoint_from_target "$_target") | ||||||
|         # In case of nfs4, nfs should be used instead, nfs* options is deprecated in kdump.conf | 	_opt=$(get_mntopt_from_target "$_target") | ||||||
|         [[ $_fstype = "nfs"* ]] && _fstype=nfs | 	_fstype=$(get_fs_type_from_target "$_target") | ||||||
| 
 | 
 | ||||||
|         if [ -n "$_cfg_fs_type" ] && [ "$_fstype" != "$_cfg_fs_type" ]; then | 	if [[ -n $_fstype ]]; then | ||||||
|             perror_exit "\"$_target\" have a wrong type config \"$_cfg_fs_type\", expected \"$_fstype\"" | 		# In case of nfs4, nfs should be used instead, nfs* options is deprecated in kdump.conf | ||||||
|         fi | 		[[ $_fstype == "nfs"* ]] && _fstype=nfs | ||||||
|     else |  | ||||||
|         _fstype="$_cfg_fs_type" |  | ||||||
|         _fstype="$_cfg_fs_type" |  | ||||||
|     fi |  | ||||||
| 
 | 
 | ||||||
|     # For noauto mount, mount it inplace with default value. | 		if [[ -n $_cfg_fs_type ]] && [[ $_fstype != "$_cfg_fs_type" ]]; then | ||||||
|     # Else use the temporary target directory | 			perror_exit "\"$_target\" have a wrong type config \"$_cfg_fs_type\", expected \"$_fstype\"" | ||||||
|     if [ -n "$_mnt" ]; then | 		fi | ||||||
|         if ! is_mounted "$_mnt"; then | 	else | ||||||
|             if [[ $_opt  = *",noauto"* ]]; then | 		_fstype="$_cfg_fs_type" | ||||||
|                 mount $_mnt | 		_fstype="$_cfg_fs_type" | ||||||
|                 [ $? -ne 0 ] && perror_exit "Failed to mount $_target on $_mnt for kdump preflight check." | 	fi | ||||||
|                 _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 | 	# For noauto mount, mount it inplace with default value. | ||||||
|     if [ ! -d "$_mnt/$SAVE_PATH" ]; then | 	# Else use the temporary target directory | ||||||
|         perror_exit "Dump path \"$SAVE_PATH\" does not exist in dump target \"$_target\"" | 	if [[ -n $_mnt ]]; then | ||||||
|     fi | 		if ! is_mounted "$_mnt"; then | ||||||
|  | 			if [[ $_opt == *",noauto"* ]]; then | ||||||
|  | 				mount "$_mnt" || mount_failure "$_target" "$_mnt" "$_fstype" | ||||||
|  | 				_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 || mount_failure "$_target" "" "$_fstype" | ||||||
|  | 		_mounted=$_mnt | ||||||
|  | 	fi | ||||||
| 
 | 
 | ||||||
|     check_size fs "$_target" | 	# 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 | ||||||
| 
 | 
 | ||||||
|     # Unmount it early, if function is interrupted and didn't reach here, the shell trap will clear it up anyway | 	check_size fs "$_target" | ||||||
|     if [ -n "$_mounted" ]; then | 
 | ||||||
|         umount -f -- $_mounted | 	# Unmount it early, if function is interrupted and didn't reach here, the shell trap will clear it up anyway | ||||||
|     fi | 	if [[ -n $_mounted ]]; then | ||||||
|  | 		umount -f -- "$_mounted" | ||||||
|  | 	fi | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| # $1: core_collector config value | # $1: core_collector config value | ||||||
| verify_core_collector() { | verify_core_collector() | ||||||
|     local _cmd="${1%% *}" | { | ||||||
|     local _params="${1#${_cmd}}" | 	local _cmd="${1%% *}" | ||||||
|  | 	local _params="${1#${_cmd}}" | ||||||
| 
 | 
 | ||||||
|     if [ "$_cmd" != "makedumpfile" ]; then | 	if [[ $_cmd != "makedumpfile" ]]; then | ||||||
|         if is_raw_dump_target; then | 		if is_raw_dump_target; then | ||||||
|             dwarn "Warning: specifying a non-makedumpfile core collector, you will have to recover the vmcore manually." | 			dwarn "Warning: specifying a non-makedumpfile core collector, you will have to recover the vmcore manually." | ||||||
|         fi | 		fi | ||||||
|         return | 		return | ||||||
|     fi | 	fi | ||||||
| 
 | 
 | ||||||
|     if is_ssh_dump_target || is_raw_dump_target; then | 	if is_ssh_dump_target || is_raw_dump_target; then | ||||||
|         if ! strstr "$_params" "-F"; then | 		if ! strstr "$_params" "-F"; then | ||||||
|             perror_exit "The specified dump target needs makedumpfile \"-F\" option." | 			perror_exit 'The specified dump target needs makedumpfile "-F" option.' | ||||||
|         fi | 		fi | ||||||
|         _params="$_params vmcore" | 		_params="$_params vmcore" | ||||||
|     else | 	else | ||||||
|         _params="$_params vmcore dumpfile" | 		_params="$_params vmcore dumpfile" | ||||||
|     fi | 	fi | ||||||
| 
 | 
 | ||||||
|     if ! $_cmd --check-params $_params; then | 	# shellcheck disable=SC2086 | ||||||
|         perror_exit "makedumpfile parameter check failed." | 	if ! $_cmd --check-params $_params; then | ||||||
|     fi | 		perror_exit "makedumpfile parameter check failed." | ||||||
|  | 	fi | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| add_mount() { | add_mount() | ||||||
|     local _mnt=$(to_mount $@) | { | ||||||
|  | 	local _mnt | ||||||
| 
 | 
 | ||||||
|     if [ $? -ne 0 ]; then | 	_mnt=$(to_mount "$@") || exit 1 | ||||||
|         exit 1 |  | ||||||
|     fi |  | ||||||
| 
 | 
 | ||||||
|     add_dracut_mount "$_mnt" | 	add_dracut_mount "$_mnt" | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #handle the case user does not specify the dump target explicitly | #handle the case user does not specify the dump target explicitly | ||||||
| handle_default_dump_target() | handle_default_dump_target() | ||||||
| { | { | ||||||
|     local _target | 	local _target | ||||||
|     local _mntpoint | 	local _mntpoint | ||||||
| 
 | 
 | ||||||
|     is_user_configured_dump_target && return | 	is_user_configured_dump_target && return | ||||||
| 
 | 
 | ||||||
|     check_save_path_fs $SAVE_PATH | 	check_save_path_fs "$SAVE_PATH" | ||||||
| 
 | 
 | ||||||
|     _save_path=$(get_bind_mount_source $SAVE_PATH) | 	_save_path=$(get_bind_mount_source "$SAVE_PATH") | ||||||
|     _target=$(get_target_from_path $_save_path) | 	_target=$(get_target_from_path "$_save_path") | ||||||
|     _mntpoint=$(get_mntpoint_from_target $_target) | 	_mntpoint=$(get_mntpoint_from_target "$_target") | ||||||
| 
 | 
 | ||||||
|     SAVE_PATH=${_save_path##"$_mntpoint"} | 	SAVE_PATH=${_save_path##"$_mntpoint"} | ||||||
|     add_mount "$_target" | 	add_mount "$_target" | ||||||
|     check_size fs $_target | 	check_size fs "$_target" | ||||||
| } |  | ||||||
| 
 |  | ||||||
| get_override_resettable() |  | ||||||
| { |  | ||||||
|     local override_resettable |  | ||||||
| 
 |  | ||||||
|     override_resettable=$(grep "^override_resettable" $conf_file) |  | ||||||
|     if [ -n "$override_resettable" ]; then |  | ||||||
|         OVERRIDE_RESETTABLE=$(echo $override_resettable | cut -d' '  -f2) |  | ||||||
|         if [ "$OVERRIDE_RESETTABLE" != "0" ] && [ "$OVERRIDE_RESETTABLE" != "1" ];then |  | ||||||
|             perror_exit "override_resettable value $OVERRIDE_RESETTABLE is invalid" |  | ||||||
|         fi |  | ||||||
|     fi |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| # $1: function name | # $1: function name | ||||||
| for_each_block_target() | for_each_block_target() | ||||||
| { | { | ||||||
|     local dev majmin | 	local dev majmin | ||||||
| 
 | 
 | ||||||
|     for dev in $(get_kdump_targets); do | 	for dev in $(get_kdump_targets); do | ||||||
|         [ -b "$dev" ] || continue | 		[[ -b $dev ]] || continue | ||||||
|         majmin=$(get_maj_min $dev) | 		majmin=$(get_maj_min "$dev") | ||||||
|         check_block_and_slaves $1 $majmin && return 1 | 		check_block_and_slaves "$1" "$majmin" && return 1 | ||||||
|     done | 	done | ||||||
| 
 | 
 | ||||||
|     return 0 | 	return 0 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #judge if a specific device with $1 is unresettable | #judge if a specific device with $1 is unresettable | ||||||
| #return false if unresettable. | #return false if unresettable. | ||||||
| is_unresettable() | is_unresettable() | ||||||
| { | { | ||||||
|     local path="/sys/$(udevadm info --query=all --path=/sys/dev/block/$1 | awk '/^P:/ {print $2}' | sed -e 's/\(cciss[0-9]\+\/\).*/\1/g' -e 's/\/block\/.*$//')/resettable" | 	local path device resettable=1 | ||||||
|     local resettable=1 |  | ||||||
| 
 | 
 | ||||||
|     if [ -f "$path" ] | 	path="/sys/$(udevadm info --query=all --path="/sys/dev/block/$1" | awk '/^P:/ {print $2}' | sed -e 's/\(cciss[0-9]\+\/\).*/\1/g' -e 's/\/block\/.*$//')/resettable" | ||||||
|     then | 	if [[ -f $path ]]; then | ||||||
|         resettable="$(cat $path)" | 		resettable="$(< "$path")" | ||||||
|         [ $resettable -eq 0 -a "$OVERRIDE_RESETTABLE" -eq 0 ] && { | 		[[ $resettable -eq 0 ]] && [[ $OVERRIDE_RESETTABLE -eq 0 ]] && { | ||||||
|             local device=$(udevadm info --query=all --path=/sys/dev/block/$1 | awk -F= '/DEVNAME/{print $2}') | 			device=$(udevadm info --query=all --path="/sys/dev/block/$1" | awk -F= '/DEVNAME/{print $2}') | ||||||
|             derror "Error: Can not save vmcore because device $device is unresettable" | 			derror "Error: Can not save vmcore because device $device is unresettable" | ||||||
|             return 0 | 			return 0 | ||||||
|         } | 		} | ||||||
|     fi | 	fi | ||||||
| 
 | 
 | ||||||
|     return 1 | 	return 1 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #check if machine is resettable. | #check if machine is resettable. | ||||||
| #return true if resettable | #return true if resettable | ||||||
| check_resettable() | check_resettable() | ||||||
| { | { | ||||||
|     local _ret _target | 	local _target _override_resettable | ||||||
| 
 | 
 | ||||||
|     get_override_resettable | 	_override_resettable=$(kdump_get_conf_val override_resettable) | ||||||
|  | 	OVERRIDE_RESETTABLE=${_override_resettable:-$OVERRIDE_RESETTABLE} | ||||||
|  | 	if [ "$OVERRIDE_RESETTABLE" != "0" ] && [ "$OVERRIDE_RESETTABLE" != "1" ]; then | ||||||
|  | 		perror_exit "override_resettable value '$OVERRIDE_RESETTABLE' is invalid" | ||||||
|  | 	fi | ||||||
| 
 | 
 | ||||||
|     for_each_block_target is_unresettable | 	for_each_block_target is_unresettable && return | ||||||
|     _ret=$? |  | ||||||
| 
 | 
 | ||||||
|     [ $_ret -eq 0 ] && return | 	return 1 | ||||||
| 
 |  | ||||||
|     return 1 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| check_crypt() | check_crypt() | ||||||
| { | { | ||||||
|     local _dev | 	local _dev | ||||||
| 
 | 
 | ||||||
|     for _dev in $(get_kdump_targets); do | 	for _dev in $(get_kdump_targets); do | ||||||
|         if [[ -n $(get_luks_crypt_dev "$(get_maj_min "$_dev")") ]]; then | 		if [[ -n $(get_luks_crypt_dev "$(get_maj_min "$_dev")") ]]; then | ||||||
|             derror "Device $_dev is encrypted." && return 1 | 			derror "Device $_dev is encrypted." && return 1 | ||||||
|         fi | 		fi | ||||||
|     done | 	done | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| if ! check_resettable; then | if ! check_resettable; then | ||||||
|     exit 1 | 	exit 1 | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| if ! check_crypt; then | if ! check_crypt; then | ||||||
|     dwarn "Warning: Encrypted device is in dump path. User will prompted for password during second kernel boot."  | 	dwarn "Warning: Encrypted device is in dump path, which is not recommended, see kexec-kdump-howto.txt for more details." | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| # firstly get right SSH_KEY_LOCATION | # firstly get right SSH_KEY_LOCATION | ||||||
| keyfile=$(awk '/^sshkey/ {print $2}' $conf_file) | keyfile=$(kdump_get_conf_val sshkey) | ||||||
| if [ -f "$keyfile" ]; then | if [[ -f $keyfile ]]; then | ||||||
|     # canonicalize the path | 	# canonicalize the path | ||||||
|     SSH_KEY_LOCATION=$(/usr/bin/readlink -m $keyfile) | 	SSH_KEY_LOCATION=$(/usr/bin/readlink -m "$keyfile") | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| while read config_opt config_val; | while read -r config_opt config_val; do | ||||||
| do | 	# remove inline comments after the end of a directive. | ||||||
|     # remove inline comments after the end of a directive. | 	case "$config_opt" in | ||||||
|     case "$config_opt" in | 	extra_modules) | ||||||
|     extra_modules) | 		extra_modules="$extra_modules $config_val" | ||||||
|         extra_modules="$extra_modules $config_val" | 		;; | ||||||
|         ;; | 	ext[234] | xfs | btrfs | minix | nfs | virtiofs) | ||||||
|     ext[234]|xfs|btrfs|minix|nfs) | 		check_user_configured_target "$config_val" "$config_opt" | ||||||
|         check_user_configured_target "$config_val" "$config_opt" | 		add_mount "$config_val" "$config_opt" | ||||||
|         add_mount "$config_val" "$config_opt" | 		;; | ||||||
|         ;; | 	raw) | ||||||
|     raw) | 		# checking raw disk writable | ||||||
|         # checking raw disk writable | 		dd if="$config_val" count=1 of=/dev/null > /dev/null 2>&1 || { | ||||||
|         dd if=$config_val count=1 of=/dev/null > /dev/null 2>&1 || { | 			perror_exit "Bad raw disk $config_val" | ||||||
|             perror_exit "Bad raw disk $config_val" | 		} | ||||||
|         } | 		_praw=$(persistent_policy="by-id" kdump_get_persistent_dev "$config_val") | ||||||
|         _praw=$(persistent_policy="by-id" kdump_get_persistent_dev $config_val) | 		if [[ -z $_praw ]]; then | ||||||
|         if [ -z "$_praw" ]; then | 			exit 1 | ||||||
|             exit 1 | 		fi | ||||||
|         fi | 		add_dracut_arg "--device" "$_praw" | ||||||
|         add_dracut_arg "--device" "$_praw" | 		check_size raw "$config_val" | ||||||
|         check_size raw $config_val | 		;; | ||||||
|         ;; | 	ssh) | ||||||
|     ssh) | 		if strstr "$config_val" "@"; then | ||||||
|         if strstr "$config_val" "@"; | 			mkdir_save_path_ssh "$config_val" | ||||||
|         then | 			check_size ssh "$config_val" | ||||||
|             mkdir_save_path_ssh $config_val | 			add_dracut_sshkey "$SSH_KEY_LOCATION" | ||||||
|             check_size ssh $config_val | 		else | ||||||
|             add_dracut_sshkey "$SSH_KEY_LOCATION" | 			perror_exit "Bad ssh dump target $config_val" | ||||||
|         else | 		fi | ||||||
|             perror_exit "Bad ssh dump target $config_val" | 		;; | ||||||
|         fi | 	core_collector) | ||||||
|         ;; | 		verify_core_collector "$config_val" | ||||||
|     core_collector) | 		;; | ||||||
|         verify_core_collector "$config_val" | 	dracut_args) | ||||||
|         ;; | 
 | ||||||
|     dracut_args) | 		# When users specify nfs dumping via dracut_args, kexec-tools won't | ||||||
|         add_dracut_arg $config_val | 		# mount nfs fs beforehand thus nfsv4-related drivers won't be installed | ||||||
|         ;; | 		# because we call dracut with --hostonly-mode strict. So manually install | ||||||
|     *) | 		# nfsv4-related drivers. | ||||||
|         ;; | 		if [[ $(get_dracut_args_fstype "$config_val") == nfs* ]]; then | ||||||
|     esac | 			add_dracut_arg "--add-drivers" nfs_layout_nfsv41_files | ||||||
| done <<< "$(read_strip_comments $conf_file)" | 		fi | ||||||
|  | 
 | ||||||
|  | 		while read -r dracut_arg; do | ||||||
|  | 			add_dracut_arg "$dracut_arg" | ||||||
|  | 		done <<< "$(echo "$config_val" | xargs -n 1 echo)" | ||||||
|  | 		;; | ||||||
|  | 	*) ;; | ||||||
|  | 
 | ||||||
|  | 	esac | ||||||
|  | done <<< "$(kdump_read_conf)" | ||||||
| 
 | 
 | ||||||
| handle_default_dump_target | handle_default_dump_target | ||||||
| 
 | 
 | ||||||
| if [ -n "$extra_modules" ] | if ! have_compression_in_dracut_args; then | ||||||
| then | 	if is_squash_available && dracut_have_option "--squash-compressor"; then | ||||||
|     add_dracut_arg "--add-drivers" \"$extra_modules\" | 		add_dracut_arg "--squash-compressor" "zstd" | ||||||
|  | 	elif is_zstd_command_available; then | ||||||
|  | 		add_dracut_arg "--compress" "zstd" | ||||||
|  | 	fi | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | if [[ -n $extra_modules ]]; then | ||||||
|  | 	add_dracut_arg "--add-drivers" "$extra_modules" | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| # TODO: The below check is not needed anymore with the introduction of | # TODO: The below check is not needed anymore with the introduction of | ||||||
| @ -438,9 +458,9 @@ fi | |||||||
| #       parameter available in fadump case. So, find a way to fix that first | #       parameter available in fadump case. So, find a way to fix that first | ||||||
| #       before removing this check. | #       before removing this check. | ||||||
| if ! is_fadump_capable; then | if ! is_fadump_capable; then | ||||||
|     # The 2nd rootfs mount stays behind the normal dump target mount, | 	# The 2nd rootfs mount stays behind the normal dump target mount, | ||||||
|     # so it doesn't affect the logic of check_dump_fs_modified(). | 	# so it doesn't affect the logic of check_dump_fs_modified(). | ||||||
|     is_dump_to_rootfs && add_mount "$(to_dev_name $(get_root_fs_device))" | 	is_dump_to_rootfs && add_mount "$(to_dev_name "$(get_root_fs_device)")" | ||||||
| 
 | 
 | ||||||
| 	add_dracut_arg "--no-hostonly-default-device" | 	add_dracut_arg "--no-hostonly-default-device" | ||||||
| 
 | 
 | ||||||
| @ -449,4 +469,13 @@ if ! is_fadump_capable; then | |||||||
| 	fi | 	fi | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| echo "$dracut_args $@" | xargs dracut | # This is RHEL-only to work around nvme problem, then real fix should go to dracut | ||||||
|  | if [[ -d /sys/module/nvme ]]; then | ||||||
|  | 	add_dracut_arg "--add-drivers" "nvme" | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | dracut "${dracut_args[@]}" "$@" | ||||||
|  | 
 | ||||||
|  | _rc=$? | ||||||
|  | sync | ||||||
|  | exit $_rc | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
| # Generate an initramfs image that isolates dump capture capability within | # Generate an initramfs image that isolates dump capture capability within | ||||||
| # the default initramfs using zz-fadumpinit dracut module. | # the default initramfs using zz-fadumpinit dracut module. | ||||||
| 
 | 
 | ||||||
| if [ -f /etc/sysconfig/kdump ]; then | if [[ -f /etc/sysconfig/kdump ]]; then | ||||||
| 	. /etc/sysconfig/kdump | 	. /etc/sysconfig/kdump | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| @ -17,7 +17,7 @@ if ! dlog_init; then | |||||||
| 	exit 1 | 	exit 1 | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| readonly MKFADUMPRD_TMPDIR="$(mktemp -d -t mkfadumprd.XXXXXX)" | MKFADUMPRD_TMPDIR="$(mktemp -d -t mkfadumprd.XXXXXX)" | ||||||
| [ -d "$MKFADUMPRD_TMPDIR" ] || perror_exit "mkfadumprd: mktemp -d -t mkfadumprd.XXXXXX failed." | [ -d "$MKFADUMPRD_TMPDIR" ] || perror_exit "mkfadumprd: mktemp -d -t mkfadumprd.XXXXXX failed." | ||||||
| trap ' | trap ' | ||||||
|     ret=$?; |     ret=$?; | ||||||
| @ -38,27 +38,37 @@ FADUMP_INITRD="$MKFADUMPRD_TMPDIR/fadump.img" | |||||||
| # this file tells the initrd is fadump enabled | # this file tells the initrd is fadump enabled | ||||||
| touch "$MKFADUMPRD_TMPDIR/fadump.initramfs" | touch "$MKFADUMPRD_TMPDIR/fadump.initramfs" | ||||||
| ddebug "rebuild fadump initrd: $FADUMP_INITRD $DEFAULT_INITRD $KDUMP_KERNELVER" | ddebug "rebuild fadump initrd: $FADUMP_INITRD $DEFAULT_INITRD $KDUMP_KERNELVER" | ||||||
| if ! $MKDUMPRD "$FADUMP_INITRD" -i "$MKFADUMPRD_TMPDIR/fadump.initramfs" /etc/fadump.initramfs; then | # Don't use squash for capture image or default image as it negatively impacts | ||||||
|  | # compression ratio and increases the size of the initramfs image. | ||||||
|  | # Don't compress the capture image as uncompressed image is needed immediately. | ||||||
|  | # Also, early microcode would not be needed here. | ||||||
|  | if ! $MKDUMPRD "$FADUMP_INITRD" -i "$MKFADUMPRD_TMPDIR/fadump.initramfs" /etc/fadump.initramfs --omit squash --no-compress --no-early-microcode; then | ||||||
| 	perror_exit "mkfadumprd: failed to build image with dump capture support" | 	perror_exit "mkfadumprd: failed to build image with dump capture support" | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| ### Unpack the initramfs having dump capture capability | ### Unpack the initramfs having dump capture capability retaining previous file modification time. | ||||||
|  | # This helps in saving space by hardlinking identical files. | ||||||
| mkdir -p "$MKFADUMPRD_TMPDIR/fadumproot" | mkdir -p "$MKFADUMPRD_TMPDIR/fadumproot" | ||||||
| if ! (pushd "$MKFADUMPRD_TMPDIR/fadumproot" > /dev/null && lsinitrd --unpack "$FADUMP_INITRD" && \ | if ! cpio -id --preserve-modification-time --quiet -D "$MKFADUMPRD_TMPDIR/fadumproot" < "$FADUMP_INITRD"; then | ||||||
| 	popd > /dev/null); then |  | ||||||
| 	derror "mkfadumprd: failed to unpack '$MKFADUMPRD_TMPDIR'" | 	derror "mkfadumprd: failed to unpack '$MKFADUMPRD_TMPDIR'" | ||||||
| 	exit 1 | 	exit 1 | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| ### Pack it into the normal boot initramfs with zz-fadumpinit module | ### Pack it into the normal boot initramfs with zz-fadumpinit module | ||||||
| _dracut_isolate_args="--rebuild $REBUILD_INITRD --add zz-fadumpinit \ | _dracut_isolate_args=( | ||||||
| 	-i $MKFADUMPRD_TMPDIR/fadumproot /fadumproot \ | 	--rebuild "$REBUILD_INITRD" --add zz-fadumpinit | ||||||
| 	-i $MKFADUMPRD_TMPDIR/fadumproot/usr/lib/dracut/loaded-kernel-modules.txt | 	-i "$MKFADUMPRD_TMPDIR/fadumproot" /fadumproot | ||||||
| 	   /usr/lib/dracut/fadump-kernel-modules.txt" | 	-i "$MKFADUMPRD_TMPDIR/fadumproot/usr/lib/dracut/hostonly-kernel-modules.txt" | ||||||
|  | 	/usr/lib/dracut/fadump-kernel-modules.txt | ||||||
|  | ) | ||||||
| 
 | 
 | ||||||
| if is_squash_available; then | # Use zstd compression method, if available | ||||||
| 	_dracut_isolate_args="$_dracut_isolate_args --add squash" | if ! have_compression_in_dracut_args; then | ||||||
|  | 	if is_zstd_command_available; then | ||||||
|  | 		_dracut_isolate_args+=(--compress zstd) | ||||||
|  | 	fi | ||||||
| fi | fi | ||||||
| if ! dracut --force --quiet $_dracut_isolate_args $@ "$TARGET_INITRD"; then | 
 | ||||||
|  | if ! dracut --force --quiet "${_dracut_isolate_args[@]}" "$@" "$TARGET_INITRD"; then | ||||||
| 	perror_exit "mkfadumprd: failed to setup '$TARGET_INITRD' with dump capture capability" | 	perror_exit "mkfadumprd: failed to setup '$TARGET_INITRD' with dump capture capability" | ||||||
| fi | fi | ||||||
|  | |||||||
| @ -1,13 +0,0 @@ | |||||||
| diff --git a/purgatory/Makefile b/purgatory/Makefile
 |  | ||||||
| index 49ce80a..97b7a03 100644
 |  | ||||||
| --- a/purgatory/Makefile
 |  | ||||||
| +++ b/purgatory/Makefile
 |  | ||||||
| @@ -67,7 +67,7 @@ $(PURGATORY): $(PURGATORY_OBJS)
 |  | ||||||
|  	$(MKDIR) -p $(@D) |  | ||||||
|  	$(CC) $(CFLAGS) $(LDFLAGS) -o $@.sym $^ |  | ||||||
|  #	$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) --no-undefined -e purgatory_start -r -o $@ $(PURGATORY_OBJS) $(UTIL_LIB) |  | ||||||
| -	$(STRIP) --strip-debug -o $@ $@.sym
 |  | ||||||
| +	$(STRIP) --strip-debug --no-merge-notes -o $@ $@.sym
 |  | ||||||
|   |  | ||||||
|  echo:: |  | ||||||
|  	@echo "PURGATORY_SRCS $(PURGATORY_SRCS)" |  | ||||||
| @ -1,51 +0,0 @@ | |||||||
| From ce720608d5933e62f77f2c2f216859cf4f06adf8 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Kairui Song <kasong@redhat.com> |  | ||||||
| Date: Wed, 13 Feb 2019 00:03:51 +0800 |  | ||||||
| Subject: [PATCH] Fix eppic issue with hardening flags |  | ||||||
| 
 |  | ||||||
| This is stash of two commits: |  | ||||||
| 
 |  | ||||||
| commit f98cf5fe07f390554696755f0a5843f6bb9c4716 |  | ||||||
| Author: ryncsn <ryncsn@gmail.com> |  | ||||||
| Date:   Tue Mar 19 13:39:25 2019 +0800 |  | ||||||
| 
 |  | ||||||
|     Tell gcc not to omit frame pointer |  | ||||||
| 
 |  | ||||||
|     After commit 0209874, it's now possible to enable optimization above O0. |  | ||||||
|     But eppic might call __builtin_return_address(1). With O1, |  | ||||||
|     -fomit-frame-pointer is enabled gcc may omit frame pointer. |  | ||||||
|     __builtin_return_address(1) relies on callee preserves RBP as the stack |  | ||||||
|     base, which is untrue if optimization is usded. In this case it may return |  | ||||||
|     wrong value or crash. |  | ||||||
| 
 |  | ||||||
|     In case of any potential failure, use -fno-omit-frame-pointer globally. |  | ||||||
| 
 |  | ||||||
|     Signed-off-by: Kairui Song <ryncsn@gmail.com> |  | ||||||
| 
 |  | ||||||
| commit 0209874f4b46b8af5a2d42662ba6775cf5a1dc44 |  | ||||||
| Author: Kairui Song <kasong@redhat.com> |  | ||||||
| Date:   Wed Feb 13 00:03:51 2019 +0800 |  | ||||||
| 
 |  | ||||||
|     Drop O0 CFLAGS override in Makefile |  | ||||||
| 
 |  | ||||||
| Signed-off-by: Kairui Song <kasong@redhat.com> |  | ||||||
| ---
 |  | ||||||
|  libeppic/Makefile | 2 +- |  | ||||||
|  1 file changed, 1 insertion(+), 1 deletion(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/libeppic/Makefile b/libeppic/Makefile
 |  | ||||||
| index bcf2edf..8b97c87 100644
 |  | ||||||
| --- a/eppic/libeppic/Makefile
 |  | ||||||
| +++ b/eppic/libeppic/Makefile
 |  | ||||||
| @@ -24,7 +24,7 @@ LDIRT    = lex.eppic.c lex.eppicpp.c eppic.tab.c eppic.tab.h eppicpp.tab.c \
 |  | ||||||
|  LIBDIR	 = /usr/lib |  | ||||||
|  TARGETS  = libeppic.a |  | ||||||
|   |  | ||||||
| -CFLAGS += -O0 -g -fPIC
 |  | ||||||
| +CFLAGS += -g -fno-omit-frame-pointer -fPIC
 |  | ||||||
|  ifeq ($(TARGET), PPC64) |  | ||||||
|  	CFLAGS += -m64 |  | ||||||
|  endif |  | ||||||
| -- 
 |  | ||||||
| 2.20.1 |  | ||||||
| 
 |  | ||||||
| @ -1,88 +0,0 @@ | |||||||
| From 0f632fa180e5a44219ab6bbe0879c3583f8c65cf Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Pingfan Liu <piliu@redhat.com> |  | ||||||
| Date: Tue, 9 Nov 2021 11:24:22 +0800 |  | ||||||
| Subject: [PATCH] RHEL-only |  | ||||||
| 
 |  | ||||||
| Cope with RHEL8 kernel |  | ||||||
| 
 |  | ||||||
| Signed-off-by: Pingfan Liu <piliu@redhat.com> |  | ||||||
| ---
 |  | ||||||
|  arch/arm64.c   | 14 +++++++++++++- |  | ||||||
|  makedumpfile.c |  2 ++ |  | ||||||
|  makedumpfile.h |  1 + |  | ||||||
|  3 files changed, 16 insertions(+), 1 deletion(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/makedumpfile-1.7.2/arch/arm64.c b/makedumpfile-1.7.2/arch/arm64.c
 |  | ||||||
| index 1072178..95beae6 100644
 |  | ||||||
| --- a/makedumpfile-1.7.2/arch/arm64.c
 |  | ||||||
| +++ b/makedumpfile-1.7.2/arch/arm64.c
 |  | ||||||
| @@ -50,6 +50,7 @@ static int va_bits;
 |  | ||||||
|  static int vabits_actual; |  | ||||||
|  static int flipped_va; |  | ||||||
|  static unsigned long kimage_voffset; |  | ||||||
| +static int max_user_va_bits;
 |  | ||||||
|   |  | ||||||
|  #define SZ_4K			4096 |  | ||||||
|  #define SZ_16K			16384 |  | ||||||
| @@ -108,7 +109,7 @@ typedef unsigned long pgdval_t;
 |  | ||||||
|  #define PGDIR_SHIFT		ARM64_HW_PGTABLE_LEVEL_SHIFT(4 - (pgtable_level)) |  | ||||||
|  #define PGDIR_SIZE		(_AC(1, UL) << PGDIR_SHIFT) |  | ||||||
|  #define PGDIR_MASK		(~(PGDIR_SIZE-1)) |  | ||||||
| -#define PTRS_PER_PGD		(1 << ((va_bits) - PGDIR_SHIFT))
 |  | ||||||
| +#define PTRS_PER_PGD           (1 << ((max_user_va_bits) - PGDIR_SHIFT))
 |  | ||||||
|   |  | ||||||
|  /* |  | ||||||
|   * Section address mask and size definitions. |  | ||||||
| @@ -449,6 +450,17 @@ get_machdep_info_arm64(void)
 |  | ||||||
|  		ERRMSG("Can't determine platform config values\n"); |  | ||||||
|  		return FALSE; |  | ||||||
|  	} |  | ||||||
| +	if (NUMBER(MAX_USER_VA_BITS) != NOT_FOUND_NUMBER) {
 |  | ||||||
| +		max_user_va_bits = NUMBER(MAX_USER_VA_BITS);
 |  | ||||||
| +		DEBUG_MSG("max_user_va_bits : %d (vmcoreinfo)\n",
 |  | ||||||
| +		                max_user_va_bits);
 |  | ||||||
| +	}
 |  | ||||||
| +	if (!max_user_va_bits) {
 |  | ||||||
| +		max_user_va_bits = va_bits;
 |  | ||||||
| +		DEBUG_MSG("max_user_va_bits : %d (default = va_bits)\n",
 |  | ||||||
| +		                max_user_va_bits);
 |  | ||||||
| +	}
 |  | ||||||
| +
 |  | ||||||
|   |  | ||||||
|  	kimage_voffset = NUMBER(kimage_voffset); |  | ||||||
|  	info->section_size_bits = SECTIONS_SIZE_BITS; |  | ||||||
| diff --git a/makedumpfile-1.7.2/makedumpfile.c b/makedumpfile-1.7.2/makedumpfile.c
 |  | ||||||
| index 3ad4443..018ea4c 100644
 |  | ||||||
| --- a/makedumpfile-1.7.2/makedumpfile.c
 |  | ||||||
| +++ b/makedumpfile-1.7.2/makedumpfile.c
 |  | ||||||
| @@ -2417,6 +2417,7 @@ write_vmcoreinfo_data(void)
 |  | ||||||
|   |  | ||||||
|  	WRITE_NUMBER("HUGETLB_PAGE_DTOR", HUGETLB_PAGE_DTOR); |  | ||||||
|  #ifdef __aarch64__ |  | ||||||
| +	WRITE_NUMBER("MAX_USER_VA_BITS", MAX_USER_VA_BITS);
 |  | ||||||
|  	WRITE_NUMBER("VA_BITS", VA_BITS); |  | ||||||
|  	/* WRITE_NUMBER("TCR_EL1_T1SZ", TCR_EL1_T1SZ); should not exists */ |  | ||||||
|  	WRITE_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET); |  | ||||||
| @@ -2863,6 +2864,7 @@ read_vmcoreinfo(void)
 |  | ||||||
|  	READ_NUMBER("phys_base", phys_base); |  | ||||||
|  	READ_NUMBER("KERNEL_IMAGE_SIZE", KERNEL_IMAGE_SIZE); |  | ||||||
|  #ifdef __aarch64__ |  | ||||||
| +	READ_NUMBER("MAX_USER_VA_BITS", MAX_USER_VA_BITS);
 |  | ||||||
|  	READ_NUMBER("VA_BITS", VA_BITS); |  | ||||||
|  	READ_NUMBER("TCR_EL1_T1SZ", TCR_EL1_T1SZ); |  | ||||||
|  	READ_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET); |  | ||||||
| diff --git a/makedumpfile-1.7.2/makedumpfile.h b/makedumpfile-1.7.2/makedumpfile.h
 |  | ||||||
| index e59239d..b6236dd 100644
 |  | ||||||
| --- a/makedumpfile-1.7.2/makedumpfile.h
 |  | ||||||
| +++ b/makedumpfile-1.7.2/makedumpfile.h
 |  | ||||||
| @@ -2064,6 +2064,7 @@ struct number_table {
 |  | ||||||
|  	long	phys_base; |  | ||||||
|  	long	KERNEL_IMAGE_SIZE; |  | ||||||
|  #ifdef __aarch64__ |  | ||||||
| +	long    MAX_USER_VA_BITS;
 |  | ||||||
|  	long 	VA_BITS; |  | ||||||
|  	long	TCR_EL1_T1SZ; |  | ||||||
|  	unsigned long	PHYS_OFFSET; |  | ||||||
| -- 
 |  | ||||||
| 2.31.1 |  | ||||||
| 
 |  | ||||||
| @ -40,24 +40,24 @@ storage: | |||||||
|         FC disks (qla2xxx, lpfc, bnx2fc, bfa) |         FC disks (qla2xxx, lpfc, bnx2fc, bfa) | ||||||
|         software initiator based iSCSI |         software initiator based iSCSI | ||||||
|         software RAID (mdraid) |         software RAID (mdraid) | ||||||
|         hardware RAID (cciss, hpsa, megaraid_sas, mpt2sas, aacraid) |         hardware RAID (smartpqi, hpsa, megaraid, mpt3sas, aacraid, mpi3mr) | ||||||
|         SCSI/SATA disks |         SCSI/SATA disks | ||||||
|         iSCSI HBA (all offload) |         iSCSI HBA (all offload) | ||||||
|         hardware FCoE (qla2xxx, lpfc) |         hardware FCoE (qla2xxx, lpfc) | ||||||
|         software FCoE (bnx2fc) (Extra configuration required, |         software FCoE (bnx2fc) (Extra configuration required, | ||||||
|             please read "Note on FCoE" section below) |             please read "Note on FCoE" section below) | ||||||
|  |         NVMe-FC (qla2xxx, lpfc) | ||||||
| 
 | 
 | ||||||
| network: | network: | ||||||
|         Hardware using kernel modules: (tg3, igb, ixgbe, sfc, e1000e, bna, |         Hardware using kernel modules: (igb, ixgbe, ice, i40e, e1000e, igc, | ||||||
|               cnic, netxen_nic, qlge, bnx2x, bnx, qlcnic, be2net, enic, |               tg3, bnx2x, bnxt_en, qede, cxgb4, be2net, enic, sfc, mlx4_en, | ||||||
|               virtio-net, ixgbevf, igbvf) |               mlx5_core, r8169, atlantic, nfp, ionic; nicvf (aarch64 only)) | ||||||
|         protocol: ipv4 |         protocol: ipv4 | ||||||
|         bonding |         bonding | ||||||
|         vlan |         vlan | ||||||
|         bridge |         bridge | ||||||
|         team |  | ||||||
|         vlan tagged bonding |         vlan tagged bonding | ||||||
|         bridge over bond/team/vlan |         bridge over bond/vlan | ||||||
| 
 | 
 | ||||||
| hypervisor: | hypervisor: | ||||||
|         kvm |         kvm | ||||||
| @ -67,14 +67,17 @@ filesystem: | |||||||
|         ext[234] |         ext[234] | ||||||
|         xfs |         xfs | ||||||
|         nfs |         nfs | ||||||
|  |         virtiofs | ||||||
| 
 | 
 | ||||||
| firmware: | firmware: | ||||||
|         BIOS |         BIOS | ||||||
|         UEFI |         UEFI | ||||||
| 
 | 
 | ||||||
| hypervisor: | hypervisor: | ||||||
|         VMWare ESXi 4.1 and 5.1 |         VMWare ESXi 4.x 5.x would not be tested/supported any more. | ||||||
|         Hyper-V 2012 R2 (RHEL Gen1 UP Guest only) |             only support ESXi 6.6, 6.7, 7.0 | ||||||
|  |         Hyper-V 2012 R2 (RHEL Gen1 UP Guest only), later version will | ||||||
|  | 	    also be tested/supported | ||||||
| 
 | 
 | ||||||
| Unsupported Dump targets | Unsupported Dump targets | ||||||
| ------------------------ | ------------------------ | ||||||
| @ -114,15 +117,5 @@ 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=" | you may need to increase the kdump reserved memory size in "crashkernel=" | ||||||
| kernel parameter. | 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 | For hardware FCoE, kdump should work naturally as firmware will do the | ||||||
| initialization job. The capture kernel and kdump tools will run just fine. | initialization job. The capture kernel and kdump tools will run just fine. | ||||||
| 
 |  | ||||||
| Useful Links |  | ||||||
| ============ |  | ||||||
| [1] RHEL6: Enabling kdump for full-virt (HVM) Xen DomU |  | ||||||
|     (https://access.redhat.com/knowledge/solutions/92943) |  | ||||||
|  | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user