diff --git a/98-kexec.rules b/98-kexec.rules index e32ee13cb2e86dc72f50b1c988db313476496b0d..b73b701ef9f047e408e379b688bd3c461b0931df 100644 --- a/98-kexec.rules +++ b/98-kexec.rules @@ -1,4 +1,16 @@ -SUBSYSTEM=="cpu", ACTION=="add", PROGRAM="/bin/systemctl try-restart kdump.service" -SUBSYSTEM=="cpu", ACTION=="remove", PROGRAM="/bin/systemctl try-restart kdump.service" -SUBSYSTEM=="memory", ACTION=="online", PROGRAM="/bin/systemctl try-restart kdump.service" -SUBSYSTEM=="memory", ACTION=="offline", PROGRAM="/bin/systemctl try-restart kdump.service" +SUBSYSTEM=="cpu", ACTION=="add", GOTO="kdump_reload" +SUBSYSTEM=="cpu", ACTION=="remove", GOTO="kdump_reload" +SUBSYSTEM=="memory", ACTION=="online", GOTO="kdump_reload" +SUBSYSTEM=="memory", ACTION=="offline", GOTO="kdump_reload" + +GOTO="kdump_reload_end" + +LABEL="kdump_reload" + +# If kdump is not loaded, calling kdump-udev-throttle will end up +# doing nothing, but systemd-run will always generate extra logs for +# each call, so trigger the kdump-udev-throttler only if kdump +# service is active to avoid unnecessary logs +RUN+="/bin/sh -c '/usr/bin/systemctl is-active kdump.service || exit 0; /usr/bin/systemd-run --quiet --no-block /usr/lib/udev/kdump-udev-throttler'" + +LABEL="kdump_reload_end" diff --git a/98-kexec.rules.ppc64 b/98-kexec.rules.ppc64 new file mode 100644 index 0000000000000000000000000000000000000000..1a9122094544f8c51085cd7e708d4b62a1051715 --- /dev/null +++ b/98-kexec.rules.ppc64 @@ -0,0 +1,15 @@ +SUBSYSTEM=="cpu", ACTION=="online", GOTO="kdump_reload" +SUBSYSTEM=="memory", ACTION=="online", GOTO="kdump_reload" +SUBSYSTEM=="memory", ACTION=="offline", GOTO="kdump_reload" + +GOTO="kdump_reload_end" + +LABEL="kdump_reload" + +# If kdump is not loaded, calling kdump-udev-throttle will end up +# doing nothing, but systemd-run will always generate extra logs for +# each call, so trigger the kdump-udev-throttler only if kdump +# service is active to avoid unnecessary logs +RUN+="/bin/sh -c '/usr/bin/systemctl is-active kdump.service || exit 0; /usr/bin/systemd-run --quiet --no-block /usr/lib/udev/kdump-udev-throttler'" + +LABEL="kdump_reload_end" diff --git a/add-secure-compile-options-for-makedumpfile.patch b/add-secure-compile-options-for-makedumpfile.patch index 3459730a84b4aa09cfd33f2d2c25a1f9839b114f..c61c18ce8ae0104903fd406bc722ce4ec101fdd5 100644 --- a/add-secure-compile-options-for-makedumpfile.patch +++ b/add-secure-compile-options-for-makedumpfile.patch @@ -7,23 +7,26 @@ reason:add secure compile options for makedumpfile Signed-off-by: pengyeqing --- - Makefile | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) + Makefile | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) -diff --git a/makedumpfile-1.6.4/Makefile b/makedumpfile-1.6.4/Makefile +diff --git a/makedumpfile-1.6.7/Makefile b/makedumpfile-1.6.7/Makefile index 612b9d0..180a64f 100644 ---- a/makedumpfile-1.6.4/Makefile -+++ b/makedumpfile-1.6.4/Makefile -@@ -10,7 +10,8 @@ endif +--- a/makedumpfile-1.6.7/Makefile ++++ b/makedumpfile-1.6.7/Makefile +@@ -10,9 +10,10 @@ endif - CFLAGS = -g -O2 -Wall -D_FILE_OFFSET_BITS=64 \ - -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE \ -- -DVERSION='"$(VERSION)"' -DRELEASE_DATE='"$(DATE)"' -+ -DVERSION='"$(VERSION)"' -DRELEASE_DATE='"$(DATE)"' \ -+ -fstack-protector-strong -Wl,-z,now - CFLAGS_ARCH = -g -O2 -Wall -D_FILE_OFFSET_BITS=64 \ - -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE + CFLAGS_BASE := $(CFLAGS) -g -O2 -Wall -D_FILE_OFFSET_BITS=64 \ + -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE +-CFLAGS := $(CFLAGS_BASE) -DVERSION='"$(VERSION)"' -DRELEASE_DATE='"$(DATE)"' +-CFLAGS_ARCH := $(CFLAGS_BASE) ++CFLAGS := $(CFLAGS_BASE) -DVERSION='"$(VERSION)"' -DRELEASE_DATE='"$(DATE)"' -fstack-protector-strong -Wl,-z,now -fPIE ++CFLAGS_ARCH := $(CFLAGS_BASE) -fPIE # LDFLAGS = -L/usr/local/lib -I/usr/local/include ++LDFLAGS += -pie + + HOST_ARCH := $(shell uname -m) + # Use TARGET as the target architecture if specified. -- 1.8.3.1 diff --git a/arm64-error-out-if-kernel-command-line-is-too-long.patch b/arm64-error-out-if-kernel-command-line-is-too-long.patch deleted file mode 100644 index 119d02b07a5079c6e0dcf09b78c8bd7e3b4cec2c..0000000000000000000000000000000000000000 --- a/arm64-error-out-if-kernel-command-line-is-too-long.patch +++ /dev/null @@ -1,40 +0,0 @@ -From ca4823aa2fc28e00400e65473caeede5cadd0da0 Mon Sep 17 00:00:00 2001 -From: Munehisa Kamata -Date: Tue, 26 Jun 2018 12:47:29 -0700 -Subject: [PATCH 13/37] arm64: error out if kernel command line is too long - -Currently, in arm64, kexec silently truncates kernel command line longer -than COMMAND_LINE_SIZE - 1. Error out in that case as some other -architectures already do that. The error message is copied from x86_64. - -Suggested-by: Tom Kirchner -Signed-off-by: Munehisa Kamata -Signed-off-by: Simon Horman ---- - kexec/arch/arm64/kexec-arm64.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c -index a206c17..7a12479 100644 ---- a/kexec/arch/arm64/kexec-arm64.c -+++ b/kexec/arch/arm64/kexec-arm64.c -@@ -598,8 +598,15 @@ int arm64_load_other_segments(struct kexec_info *info, - char command_line[COMMAND_LINE_SIZE] = ""; - - if (arm64_opts.command_line) { -+ if (strlen(arm64_opts.command_line) > -+ sizeof(command_line) - 1) { -+ fprintf(stderr, -+ "Kernel command line too long for kernel!\n"); -+ return EFAILED; -+ } -+ - strncpy(command_line, arm64_opts.command_line, -- sizeof(command_line)); -+ sizeof(command_line) - 1); - command_line[sizeof(command_line) - 1] = 0; - } - --- -2.6.4.windows.1 - diff --git a/arm64-support-more-than-one-crash-kernel-regions.patch b/arm64-support-more-than-one-crash-kernel-regions.patch index 8d9f4ddfd5da752547bcdf1b62839959ecbab070..c2cd0c6c14f393a61b52ff1b6f066996bc6a70cb 100644 --- a/arm64-support-more-than-one-crash-kernel-regions.patch +++ b/arm64-support-more-than-one-crash-kernel-regions.patch @@ -197,45 +197,43 @@ index 2992bce..2bf8b66 100644 /** * setup_2nd_dtb - Setup the 2nd stage kernel's dtb. */ -@@ -427,7 +455,7 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash) +@@ -428,7 +456,7 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash) + int len, range_len; int nodeoffset; - char *new_buf = NULL; int new_size; -- int result; -+ int i, result; +- int result, kaslr_seed; ++ int i, result, kaslr_seed; result = fdt_check_header(dtb->buf); -@@ -430,19 +430,21 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash) - goto on_error; - } +@@ -459,18 +487,21 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash) + goto on_error; + } -- if (!cells_size_fitted(address_cells, size_cells, -- &crash_reserved_mem)) { -- fprintf(stderr, -- "kexec: usable memory range doesn't fit cells-size.\n"); -- result = -EINVAL; -- goto on_error; -- } -+ for (i = 0; i < usablemem_rgns.size; i++) { -+ if (!cells_size_fitted(address_cells, size_cells, -+ &crash_reserved_mem[i])) { -+ fprintf(stderr, -+ "kexec: usable memory range doesn't fit cells-size.\n"); -+ result = -EINVAL; -+ goto on_error; -+ } -+ } +- if (!cells_size_fitted(address_cells, size_cells, +- &crash_reserved_mem)) { +- fprintf(stderr, "kexec: usable memory range doesn't fit cells-size.\n"); +- result = -EINVAL; +- goto on_error; ++ for (i = 0; i < usablemem_rgns.size; i++) { ++ if (!cells_size_fitted(address_cells, size_cells, ++ &crash_reserved_mem[i])) { ++ fprintf(stderr, ++ "kexec: usable memory range doesn't fit cells-size.\n"); ++ result = -EINVAL; ++ goto on_error; ++ } + } - /* duplicate dt blob */ - range_len = sizeof(uint32_t) * (address_cells + size_cells); - new_size = fdt_totalsize(dtb->buf) - + fdt_prop_len(PROP_ELFCOREHDR, range_len) -- + fdt_prop_len(PROP_USABLE_MEM_RANGE, range_len); -+ + fdt_prop_len(PROP_USABLE_MEM_RANGE, range_len * usablemem_rgns.size); + /* duplicate dt blob */ + range_len = sizeof(uint32_t) * (address_cells + size_cells); + new_size = fdt_totalsize(dtb->buf) + + fdt_prop_len(PROP_ELFCOREHDR, range_len) +- + fdt_prop_len(PROP_USABLE_MEM_RANGE, range_len); ++ + fdt_prop_len(PROP_USABLE_MEM_RANGE, range_len * usablemem_rgns.size); - new_buf = xmalloc(new_size); - result = fdt_open_into(dtb->buf, new_buf, new_size); + new_buf = xmalloc(new_size); + result = fdt_open_into(dtb->buf, new_buf, new_size); @@ -565,8 +596,8 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash) /* add linux,usable-memory-range */ diff --git a/arm64-wipe-old-initrd-addresses-when-patching-the-DT.patch b/arm64-wipe-old-initrd-addresses-when-patching-the-DT.patch deleted file mode 100644 index e39097e877f83f503bbe9f9f993df967f1c8b455..0000000000000000000000000000000000000000 --- a/arm64-wipe-old-initrd-addresses-when-patching-the-DT.patch +++ /dev/null @@ -1,75 +0,0 @@ -From f1f2f9edf8d4c5294e30f20546c5177ab59e53a2 Mon Sep 17 00:00:00 2001 -From: Jean-Philippe Brucker -Date: Fri, 1 Feb 2019 15:50:28 +0000 -Subject: [PATCH 33/37] arm64: wipe old initrd addresses when patching the DTB - -When copying the DTB from the current kernel, if the user didn't pass an -initrd on the command-line, make sure that the new DTB doesn't contain -initrd properties with stale addresses. Otherwise the next kernel will -try to unpack the initramfs from a location that contains junk, since -the initial initrd is long gone: - -[ 49.370026] Initramfs unpacking failed: junk in compressed archive - -This issue used to be hidden by a successful recovery, but since commit -ff1522bb7d98 ("initramfs: cleanup incomplete rootfs") in Linux, the -kernel removes the default /root mountpoint after failing to load an -initramfs, and cannot mount the rootfs passed on the command-line -anymore. - -Signed-off-by: Jean-Philippe Brucker -Signed-off-by: Simon Horman ---- - kexec/arch/arm64/kexec-arm64.c | 5 +++++ - kexec/dt-ops.c | 6 ++++++ - kexec/dt-ops.h | 1 + - 3 files changed, 12 insertions(+) - -diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c -index 1cde75d..2992bce 100644 ---- a/kexec/arch/arm64/kexec-arm64.c -+++ b/kexec/arch/arm64/kexec-arm64.c -@@ -713,6 +713,11 @@ int arm64_load_other_segments(struct kexec_info *info, - } - } - -+ if (!initrd_buf) { -+ /* Don't reuse the initrd addresses from 1st DTB */ -+ dtb_clear_initrd((char **)&dtb.buf, &dtb.size); -+ } -+ - /* Check size limit as specified in booting.txt. */ - - if (dtb.size > MiB(2)) { -diff --git a/kexec/dt-ops.c b/kexec/dt-ops.c -index 5626c47..dd2feaa 100644 ---- a/kexec/dt-ops.c -+++ b/kexec/dt-ops.c -@@ -45,6 +45,12 @@ int dtb_set_initrd(char **dtb, off_t *dtb_size, off_t start, off_t end) - return 0; - } - -+void dtb_clear_initrd(char **dtb, off_t *dtb_size) -+{ -+ dtb_delete_property(*dtb, n_chosen, p_initrd_start); -+ dtb_delete_property(*dtb, n_chosen, p_initrd_end); -+} -+ - int dtb_set_bootargs(char **dtb, off_t *dtb_size, const char *command_line) - { - return dtb_set_property(dtb, dtb_size, n_chosen, p_bootargs, -diff --git a/kexec/dt-ops.h b/kexec/dt-ops.h -index e70d15d..03659ce 100644 ---- a/kexec/dt-ops.h -+++ b/kexec/dt-ops.h -@@ -4,6 +4,7 @@ - #include - - int dtb_set_initrd(char **dtb, off_t *dtb_size, off_t start, off_t end); -+void dtb_clear_initrd(char **dtb, off_t *dtb_size); - int dtb_set_bootargs(char **dtb, off_t *dtb_size, const char *command_line); - int dtb_set_property(char **dtb, off_t *dtb_size, const char *node, - const char *prop, const void *value, int value_len); --- -2.6.4.windows.1 - diff --git a/bugfix-get-the-paddr-of-mem_section-return-error-address.patch b/bugfix-get-the-paddr-of-mem_section-return-error-address.patch index 73d3a3a032957ed9a0ee914ff3806023d2d9af7a..92e84c8638f4b7594d502e676ac5ea87ee90bd2d 100644 --- a/bugfix-get-the-paddr-of-mem_section-return-error-address.patch +++ b/bugfix-get-the-paddr-of-mem_section-return-error-address.patch @@ -7,13 +7,13 @@ reason: get the paddr of mem_section return error address Signed-off-by: kangenbo --- - makedumpfile-1.6.4/arch/arm64.c | 4 ++-- + makedumpfile-1.6.7/arch/arm64.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -diff --git a/makedumpfile-1.6.4/arch/arm64.c b/makedumpfile-1.6.4/arch/arm64.c +diff --git a/makedumpfile-1.6.7/arch/arm64.c b/makedumpfile-1.6.7/arch/arm64.c index 2fd3e18..cc59e63 100644 ---- a/makedumpfile-1.6.4/arch/arm64.c -+++ b/makedumpfile-1.6.4/arch/arm64.c +--- a/makedumpfile-1.6.7/arch/arm64.c ++++ b/makedumpfile-1.6.7/arch/arm64.c @@ -336,7 +336,7 @@ vaddr_to_paddr_arm64(unsigned long vaddr) if ((pud_val(pudv) & PUD_TYPE_MASK) == PUD_TYPE_SECT) { diff --git a/dracut-early-kdump-module-setup.sh b/dracut-early-kdump-module-setup.sh old mode 100644 new mode 100755 index 7613fbcb5ad30690d73162c9b25c9536f19527ec..e069867042ad32b813de70dfc55663d4607850a4 --- a/dracut-early-kdump-module-setup.sh +++ b/dracut-early-kdump-module-setup.sh @@ -24,6 +24,10 @@ prepare_kernel_initrd() { KDUMP_BOOTDIR=$(check_boot_dir "${KDUMP_BOOTDIR}") if [ -z "$KDUMP_KERNELVER" ]; then kdump_kver=`uname -r` + if [ "$kernel" != "$kdump_kver" ]; then + dwarn "Using current kernel version '$kdump_kver' for early kdump," \ + "but the initramfs is generated for kernel version '$kernel'" + fi else kdump_kver=$KDUMP_KERNELVER fi @@ -32,13 +36,30 @@ prepare_kernel_initrd() { } install() { + prepare_kernel_initrd + if [ ! -f "$KDUMP_KERNEL" ]; then + derror "Could not find required kernel for earlykdump," \ + "earlykdump will not work!" + return 1 + fi + if [ ! -f "$KDUMP_INITRD" ]; then + derror "Could not find required kdump initramfs for earlykdump," \ + "please ensure kdump initramfs is generated first," \ + "earlykdump will not work!" + return 1 + fi + inst_multiple tail find cut dirname hexdump inst_simple "/etc/sysconfig/kdump" inst_binary "/usr/sbin/kexec" inst_binary "/usr/bin/gawk" "/usr/bin/awk" inst_script "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh" inst_hook cmdline 00 "$moddir/early-kdump.sh" - prepare_kernel_initrd inst_binary "$KDUMP_KERNEL" inst_binary "$KDUMP_INITRD" + + ln_r "$KDUMP_KERNEL" "${KDUMP_BOOTDIR}/${KDUMP_IMG}-earlykdump${KDUMP_IMG_EXT}" + ln_r "$KDUMP_INITRD" "${KDUMP_BOOTDIR}/initramfs-earlykdump.img" + + chmod -x "${initdir}/$KDUMP_KERNEL" } diff --git a/dracut-early-kdump.sh b/dracut-early-kdump.sh old mode 100644 new mode 100755 index 34a99097675ad1865b99bfeb27d1fb2926785432..6788a6b83431c74eb99e85f39808ec5d99cb72c8 --- a/dracut-early-kdump.sh +++ b/dracut-early-kdump.sh @@ -2,6 +2,7 @@ KEXEC=/sbin/kexec standard_kexec_args="-p" +KDUMP_FILE_LOAD="" EARLY_KDUMP_INITRD="" EARLY_KDUMP_KERNEL="" @@ -18,17 +19,8 @@ prepare_parameters() EARLY_KDUMP_CMDLINE=$(prepare_cmdline "${KDUMP_COMMANDLINE}" "${KDUMP_COMMANDLINE_REMOVE}" "${KDUMP_COMMANDLINE_APPEND}") KDUMP_BOOTDIR=$(check_boot_dir "${KDUMP_BOOTDIR}") - #make early-kdump kernel string - if [ -z "$KDUMP_KERNELVER" ]; then - EARLY_KDUMP_KERNELVER=`uname -r` - else - EARLY_KDUMP_KERNELVER=$KDUMP_KERNELVER - fi - - EARLY_KDUMP_KERNEL="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${EARLY_KDUMP_KERNELVER}${KDUMP_IMG_EXT}" - - #make early-kdump initrd string - EARLY_KDUMP_INITRD="${KDUMP_BOOTDIR}/initramfs-${EARLY_KDUMP_KERNELVER}kdump.img" + EARLY_KDUMP_KERNEL="${KDUMP_BOOTDIR}/${KDUMP_IMG}-earlykdump${KDUMP_IMG_EXT}" + EARLY_KDUMP_INITRD="${KDUMP_BOOTDIR}/initramfs-earlykdump.img" } early_kdump_load() @@ -52,8 +44,8 @@ early_kdump_load() EARLY_KEXEC_ARGS=$(prepare_kexec_args "${KEXEC_ARGS}") - if is_secure_boot_enforced; then - echo "Secure Boot is enabled. Using kexec file based syscall." + if [ "$KDUMP_FILE_LOAD" == "on" ]; then + echo "Using kexec file based syscall." EARLY_KEXEC_ARGS="$EARLY_KEXEC_ARGS -s" fi diff --git a/dracut-kdump-capture.service b/dracut-kdump-capture.service index 57139c95818efea0086a017fcc2b062f5bb40637..3f20aba3dc0f0bcc88730bc7b19fa22049f6374f 100644 --- a/dracut-kdump-capture.service +++ b/dracut-kdump-capture.service @@ -12,7 +12,7 @@ After=dracut-initqueue.service dracut-pre-mount.service dracut-mount.service dra Before=initrd-cleanup.service ConditionPathExists=/etc/initrd-release OnFailure=emergency.target -OnFailureIsolate=yes +OnFailureJobMode=isolate [Service] Environment=DRACUT_SYSTEMD=1 diff --git a/dracut-kdump-error-handler.service b/dracut-kdump-error-handler.service index 13090be50fec2ce41ab5901ffa6e2816466a5c20..a23b75e404e6156162d79fdb7a0580e6689fc393 100644 --- a/dracut-kdump-error-handler.service +++ b/dracut-kdump-error-handler.service @@ -6,7 +6,7 @@ # (at your option) any later version. # This service will run the real kdump error handler code. Executing the -# default action configured in kdump.conf +# failure action configured in kdump.conf [Unit] Description=Kdump Error Handler @@ -21,7 +21,6 @@ Environment=DRACUT_SYSTEMD=1 Environment=NEWROOT=/sysroot WorkingDirectory=/ ExecStart=/bin/kdump-error-handler.sh -ExecStopPost=-/usr/bin/systemctl --fail --no-block default Type=oneshot StandardInput=tty-force StandardOutput=inherit diff --git a/dracut-kdump-error-handler.sh b/dracut-kdump-error-handler.sh old mode 100644 new mode 100755 index 2f0f1d1ef953b75afc187eb85b49e73baf3f163f..fc2b9328d923933f5306df6a8cb162217fc47c48 --- a/dracut-kdump-error-handler.sh +++ b/dracut-kdump-error-handler.sh @@ -6,5 +6,5 @@ set -o pipefail export PATH=$PATH:$KDUMP_SCRIPT_DIR get_kdump_confs -do_default_action +do_failure_action do_final_action diff --git a/dracut-kdump-wait-for-target.sh b/dracut-kdump-wait-for-target.sh new file mode 100755 index 0000000000000000000000000000000000000000..ce984d032c5a81dd1926f95d510fa870b9f852f7 --- /dev/null +++ b/dracut-kdump-wait-for-target.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +# only wait if it's kdump kernel +if [ -f /etc/fadump.initramfs ] && [ ! -f /proc/device-tree/rtas/ibm,kernel-dump ]; then + exit 0 +fi + +. /lib/dracut-lib.sh +. /lib/kdump-lib-initramfs.sh + +# For SSH/NFS target, need to wait for the network to setup +if is_nfs_dump_target; then + get_host_ip + exit $? +fi + +if is_ssh_dump_target; then + get_host_ip + exit $? +fi + +# No need to wait for dump target +exit 0 diff --git a/dracut-kdump.sh b/dracut-kdump.sh old mode 100644 new mode 100755 index b75c2a5ac1e7fb0e745a8c1bb27113eee2ea205f..0f54ddc5e4ee7e8db926f931b94af19aaa8891ae --- a/dracut-kdump.sh +++ b/dracut-kdump.sh @@ -1,8 +1,8 @@ #!/bin/sh # continue here only if we have to save dump. -if [ -f /etc/fadump.initramfs ] && [ ! -f /proc/device-tree/rtas/ibm,kernel-dump ]; then - exit 0 +if [ -f /etc/fadump.initramfs ] && [ ! -f /proc/device-tree/rtas/ibm,kernel-dump ] && [ ! -f /proc/device-tree/ibm,opal/dump/mpipl-boot ]; then + exit 0 fi exec &> /dev/console @@ -81,6 +81,7 @@ dump_ssh() ssh -q $_opt $_host mkdir -p $_dir || return 1 save_vmcore_dmesg_ssh ${DMESG_COLLECTOR} ${_dir} "${_opt}" $_host + save_opalcore_ssh ${_dir} "${_opt}" $_host echo "kdump: saving vmcore" @@ -96,6 +97,32 @@ dump_ssh() return 0 } +save_opalcore_ssh() { + local _path=$1 + local _opts="$2" + local _location=$3 + + if [ ! -f $OPALCORE ]; then + # Check if we are on an old kernel that uses a different path + if [ -f /sys/firmware/opal/core ]; then + OPALCORE="/sys/firmware/opal/core" + else + return 0 + fi + fi + + echo "kdump: saving opalcore" + scp $_opts $OPALCORE $_location:$_path/opalcore-incomplete + if [ $? -ne 0 ]; then + echo "kdump: saving opalcore failed" + return 1 + fi + + ssh $_opts $_location mv $_path/opalcore-incomplete $_path/opalcore + echo "kdump: saving opalcore complete" + return 0 +} + save_vmcore_dmesg_ssh() { local _dmesg_collector=$1 local _path=$2 @@ -114,55 +141,6 @@ save_vmcore_dmesg_ssh() { fi } -get_host_ip() -{ - local _host - if is_nfs_dump_target || is_ssh_dump_target - then - kdumpnic=$(getarg kdumpnic=) - [ -z "$kdumpnic" ] && echo "kdump: failed to get kdumpnic!" && return 1 - _host=`ip addr show dev $kdumpnic|grep '[ ]*inet'` - [ $? -ne 0 ] && echo "kdump: wrong kdumpnic: $kdumpnic" && return 1 - _host=`echo $_host | head -n 1 | cut -d' ' -f2` - _host="${_host%%/*}" - [ -z "$_host" ] && echo "kdump: wrong kdumpnic: $kdumpnic" && return 1 - HOST_IP=$_host - fi - return 0 -} - -read_kdump_conf() -{ - if [ ! -f "$KDUMP_CONF" ]; then - echo "kdump: $KDUMP_CONF not found" - return - fi - - get_kdump_confs - - # rescan for add code for dump target - while read config_opt config_val; - do - # remove inline comments after the end of a directive. - config_val=$(strip_comments $config_val) - case "$config_opt" in - dracut_args) - config_val=$(get_dracut_args_target "$config_val") - [ -n "$config_val" ] && add_dump_code "dump_fs $config_val" - ;; - ext[234]|xfs|btrfs|minix|nfs) - add_dump_code "dump_fs $config_val" - ;; - raw) - add_dump_code "dump_raw $config_val" - ;; - ssh) - add_dump_code "dump_ssh $SSH_KEY_LOCATION $config_val" - ;; - esac - done < $KDUMP_CONF -} - fence_kdump_notify() { if [ -n "$FENCE_KDUMP_NODES" ]; then diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh old mode 100644 new mode 100755 index a10244b730e6ef32ca1d1577b41dbef540050c2e..fdef509d88e29b6c8544d2bd9da580a8328e0cbf --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -20,11 +20,27 @@ check() { depends() { local _dep="base shutdown" + is_squash_available() { + for kmodule in squashfs overlay loop; do + if [ -z "$KDUMP_KERNELVER" ]; then + modprobe --dry-run $kmodule &>/dev/null || return 1 + else + modprobe -S $KDUMP_KERNELVER --dry-run $kmodule &>/dev/null || return 1 + fi + done + } + + if is_squash_available && ! is_fadump_capable; then + _dep="$_dep squash" + else + dwarning "Required modules to build a squashed kdump image is missing!" + fi + if [ -n "$( find /sys/devices -name drm )" ] || [ -d /sys/module/hyperv_fb ]; then _dep="$_dep drm" fi - if is_generic_fence_kdump -o is_pcs_fence_kdump; then + if is_generic_fence_kdump || is_pcs_fence_kdump; then _dep="$_dep network" fi @@ -126,7 +142,8 @@ kdump_static_ip() { echo -n "${_srcaddr}::${_gateway}:${_netmask}::" fi - /sbin/ip $_ipv6_flag route show | grep -v default | grep ".*via.* $_netdev " |\ + /sbin/ip $_ipv6_flag route show | grep -v default |\ + grep ".*via.* $_netdev " | grep -v "^[[:space:]]*nexthop" |\ while read _route; do _target=`echo $_route | cut -d ' ' -f1` _nexthop=`echo $_route | cut -d ' ' -f3` @@ -136,6 +153,44 @@ kdump_static_ip() { fi echo "rd.route=$_target:$_nexthop:$_netdev" done >> ${initdir}/etc/cmdline.d/45route-static.conf + + kdump_handle_mulitpath_route $_netdev $_srcaddr +} + +kdump_handle_mulitpath_route() { + local _netdev="$1" _srcaddr="$2" _ipv6_flag + local _target _nexthop _route _weight _max_weight _rule + + if is_ipv6_address $_srcaddr; then + _ipv6_flag="-6" + fi + + while IFS="" read _route; do + if [[ "$_route" =~ [[:space:]]+nexthop ]]; then + _route=$(echo "$_route" | sed -e 's/^[[:space:]]*//') + # Parse multipath route, using previous _target + [[ "$_target" == 'default' ]] && continue + [[ "$_route" =~ .*via.*\ $_netdev ]] || continue + + _weight=`echo "$_route" | cut -d ' ' -f7` + if [[ "$_weight" -gt "$_max_weight" ]]; then + _nexthop=`echo "$_route" | cut -d ' ' -f3` + _max_weight=$_weight + if [ "x" != "x"$_ipv6_flag ]; then + _rule="rd.route=[$_target]:[$_nexthop]:$_netdev" + else + _rule="rd.route=$_target:$_nexthop:$_netdev" + fi + fi + else + [[ -n "$_rule" ]] && echo "$_rule" + _target=`echo "$_route" | cut -d ' ' -f1` + _rule="" _max_weight=0 _weight=0 + fi + done >> ${initdir}/etc/cmdline.d/45route-static.conf\ + <<< "$(/sbin/ip $_ipv6_flag route show)" + + [[ -n $_rule ]] && echo $_rule >> ${initdir}/etc/cmdline.d/45route-static.conf } kdump_get_mac_addr() { @@ -209,7 +264,7 @@ kdump_setup_bond() { source_ifcfg_file $_netdev - bondoptions="$(echo :$BONDING_OPTS | sed 's/\s\+/,/')" + bondoptions=":$(echo $BONDING_OPTS | xargs echo | tr " " ",")" echo "$bondoptions" >> ${initdir}/etc/cmdline.d/42bond.conf } @@ -252,10 +307,10 @@ kdump_setup_vlan() { exit 1 elif kdump_is_bond "$_phydev"; then kdump_setup_bond "$_phydev" - echo " vlan=$_netdev:$_phydev" > ${initdir}/etc/cmdline.d/43vlan.conf + echo " vlan=$(kdump_setup_ifname $_netdev):$_phydev" > ${initdir}/etc/cmdline.d/43vlan.conf else _kdumpdev="$(kdump_setup_ifname $_phydev)" - echo " vlan=$_netdev:$_kdumpdev ifname=$_kdumpdev:$_netmac" > ${initdir}/etc/cmdline.d/43vlan.conf + echo " vlan=$(kdump_setup_ifname $_netdev):$_kdumpdev ifname=$_kdumpdev:$_netmac" > ${initdir}/etc/cmdline.d/43vlan.conf fi } @@ -272,11 +327,45 @@ kdump_setup_znet() { echo rd.znet=${NETTYPE},${SUBCHANNELS}${_options} > ${initdir}/etc/cmdline.d/30znet.conf } -# Setup dracut to bringup a given network interface -kdump_setup_netdev() { - local _netdev=$1 _srcaddr=$2 +kdump_get_ip_route() +{ + local _route=$(/sbin/ip -o route get to $1 2>&1) + [ $? != 0 ] && die "Bad kdump network destination: $1" + echo $_route +} + +kdump_get_ip_route_field() +{ + if `echo $1 | grep -q $2`; then + echo ${1##*$2} | cut -d ' ' -f1 + fi +} + +kdump_get_remote_ip() +{ + local _remote=$(get_remote_host $1) _remote_temp + if is_hostname $_remote; then + _remote_temp=`getent ahosts $_remote | grep -v : | head -n 1` + if [ -z "$_remote_temp" ]; then + _remote_temp=`getent ahosts $_remote | head -n 1` + fi + _remote=`echo $_remote_temp | cut -d' ' -f1` + fi + echo $_remote +} + +# Setup dracut to bring up network interface that enable +# initramfs accessing giving destination +# $1: destination host +kdump_install_net() { + local _destaddr _srcaddr _route _netdev local _static _proto _ip_conf _ip_opts _ifname_opts - local _netmac=$(kdump_get_mac_addr $_netdev) + + _destaddr=$(kdump_get_remote_ip $1) + _route=$(kdump_get_ip_route $_destaddr) + _srcaddr=$(kdump_get_ip_route_field "$_route" "src") + _netdev=$(kdump_get_ip_route_field "$_route" "dev") + _netmac=$(kdump_get_mac_addr $_netdev) if [ "$(uname -m)" = "s390x" ]; then kdump_setup_znet $_netdev @@ -317,42 +406,8 @@ kdump_setup_netdev() { fi kdump_setup_dns "$_netdev" -} - -get_ip_route_field() -{ - if `echo $1 | grep -q $2`; then - echo ${1##*$2} | cut -d ' ' -f1 - fi -} - -#Function:kdump_install_net -#$1: config values of net line in kdump.conf -#$2: srcaddr of network device -kdump_install_net() { - local _server _netdev _srcaddr _route _serv_tmp - local config_val="$1" - - _server=$(get_remote_host $config_val) - - if is_hostname $_server; then - _serv_tmp=`getent ahosts $_server | grep -v : | head -n 1` - if [ -z "$_serv_tmp" ]; then - _serv_tmp=`getent ahosts $_server | head -n 1` - fi - _server=`echo $_serv_tmp | cut -d' ' -f1` - fi - _route=`/sbin/ip -o route get to $_server 2>&1` - [ $? != 0 ] && echo "Bad kdump location: $config_val" && exit 1 - - #the field in the ip output changes if we go to another subnet - _srcaddr=$(get_ip_route_field "$_route" "src") - _netdev=$(get_ip_route_field "$_route" "dev") - - kdump_setup_netdev "${_netdev}" "${_srcaddr}" - - #save netdev used for kdump as cmdline + # Save netdev used for kdump as cmdline # Whoever calling kdump_install_net() is setting up the default gateway, # ie. bootdev/kdumpnic. So don't override the setting if calling # kdump_install_net() for another time. For example, after setting eth0 as @@ -373,24 +428,9 @@ default_dump_target_install_conf() is_user_configured_dump_target && return - _save_path=$(get_option_value "path") - [ -z "$_save_path" ] && _save_path=$DEFAULT_PATH - - # strip the duplicated "/" - _save_path=$(echo $_save_path | tr -s /) - - _mntpoint=$(get_mntpoint_from_path $_save_path) + _save_path=$(get_bind_mount_source $(get_save_path)) _target=$(get_target_from_path $_save_path) - - if is_atomic && is_bind_mount $_mntpoint; then - _save_path=${_save_path##"$_mntpoint"} - # the real dump path in the 2nd kernel, if the mount point is bind mounted. - _save_path=$(get_bind_mount_directory $_mntpoint)/$_save_path - _mntpoint=$(get_mntpoint_from_target $_target) - - # the absolute path in the 1st kernel - _save_path=$_mntpoint/$_save_path - fi + _mntpoint=$(get_mntpoint_from_target $_target) _fstype=$(get_fs_type_from_target $_target) if is_fs_type_nfs $_fstype; then @@ -402,8 +442,6 @@ default_dump_target_install_conf() echo "$_fstype $_target" >> ${initdir}/tmp/$$-kdump.conf - # strip the duplicated "/" - _save_path=$(echo $_save_path | tr -s /) # don't touch the path under root mount if [ "$_mntpoint" != "/" ]; then _save_path=${_save_path##"$_mntpoint"} @@ -414,39 +452,14 @@ default_dump_target_install_conf() echo "path $_save_path" >> ${initdir}/tmp/$$-kdump.conf } -adjust_bind_mount_path() -{ - local _target=$1 - local _save_path=$(get_option_value "path") - [ -z "$_save_path" ] && _save_path=$DEFAULT_PATH - - # strip the duplicated "/" - _save_path=$(echo $_save_path | tr -s /) - - local _absolute_save_path=$(get_mntpoint_from_target $_target)/$_save_path - _absolute_save_path=$(echo "$_absolute_save_path" | tr -s /) - local _mntpoint=$(get_mntpoint_from_path $_absolute_save_path) - - if is_bind_mount $_mntpoint; then - _save_path=${_absolute_save_path##"$_mntpoint"} - # the real dump path in the 2nd kernel, if the mount point is bind mounted. - _save_path=$(get_bind_mount_directory $_mntpoint)/$_save_path - - #erase the old path line, then insert the parsed path - sed -i "/^path/d" ${initdir}/tmp/$$-kdump.conf - echo "path $_save_path" >> ${initdir}/tmp/$$-kdump.conf - fi -} - #install kdump.conf and what user specifies in kdump.conf kdump_install_conf() { local _opt _val _pdev - sed -ne '/^#/!p' /etc/kdump.conf > ${initdir}/tmp/$$-kdump.conf + (read_strip_comments /etc/kdump.conf) > ${initdir}/tmp/$$-kdump.conf while read _opt _val; do # remove inline comments after the end of a directive. - _val=$(strip_comments $_val) case "$_opt" in raw) _pdev=$(persistent_policy="by-id" kdump_get_persistent_dev $_val) @@ -455,9 +468,6 @@ kdump_install_conf() { ext[234]|xfs|btrfs|minix) _pdev=$(kdump_get_persistent_dev $_val) sed -i -e "s#^$_opt[[:space:]]\+$_val#$_opt $_pdev#" ${initdir}/tmp/$$-kdump.conf - if is_atomic; then - adjust_bind_mount_path "$_val" - fi ;; ssh|nfs) kdump_install_net "$_val" @@ -474,7 +484,7 @@ kdump_install_conf() { dracut_install "${_val%%[[:blank:]]*}" ;; esac - done < /etc/kdump.conf + done <<< "$(read_strip_comments /etc/kdump.conf)" default_dump_target_install_conf @@ -483,16 +493,18 @@ kdump_install_conf() { rm -f ${initdir}/tmp/$$-kdump.conf } -# Default sysctl parameters should suffice for kdump kernel. -# Remove custom configurations sysctl.conf & sysctl.d/* -remove_sysctl_conf() { - +# Remove user custom configurations sysctl.conf & sysctl.d/* +# and apply some optimization for kdump +overwrite_sysctl_conf() { # As custom configurations like vm.min_free_kbytes can lead # to OOM issues in kdump kernel, avoid them rm -f "${initdir}/etc/sysctl.conf" rm -rf "${initdir}/etc/sysctl.d" rm -rf "${initdir}/run/sysctl.d" rm -rf "${initdir}/usr/lib/sysctl.d" + + mkdir -p "${initdir}/etc/sysctl.d" + echo "vm.zone_reclaim_mode = 3" > "${initdir}/etc/sysctl.d/99-zone-reclaim.conf" } kdump_iscsi_get_rec_val() { @@ -538,9 +550,6 @@ kdump_setup_iscsi_device() { local tgt_name; local tgt_ipaddr; local username; local password; local userpwd_str; local username_in; local password_in; local userpwd_in_str; - local netdev - local srcaddr - local idev local netroot_str ; local initiator_str; local netroot_conf="${initdir}/etc/cmdline.d/50iscsi.conf" local initiator_conf="/etc/iscsi/initiatorname.iscsi" @@ -579,12 +588,7 @@ kdump_setup_iscsi_device() { [ -n "$username_in" ] && userpwd_in_str=":$username_in:$password_in" - netdev=$(/sbin/ip route get to ${tgt_ipaddr} | \ - sed 's|.*dev \(.*\).*|\1|g') - srcaddr=$(echo $netdev | awk '{ print $3; exit }') - netdev=$(echo $netdev | awk '{ print $1; exit }') - - kdump_setup_netdev $netdev $srcaddr + kdump_install_net "$tgt_ipaddr" # prepare netroot= command line # FIXME: Do we need to parse and set other parameters like protocol, port @@ -635,6 +639,41 @@ kdump_check_iscsi_targets () { } } +# hostname -a is deprecated, do it by ourself +get_alias() { + local ips + local entries + local alias_set + + ips=$(hostname -I) + for ip in $ips + do + # in /etc/hosts, alias can come at the 2nd column + entries=$(grep $ip /etc/hosts | awk '{ $1=""; print $0 }') + if [ $? -eq 0 ]; then + alias_set="$alias_set $entries" + fi + done + + echo $alias_set +} + +is_localhost() { + local hostnames=$(hostname -A) + local shortnames=$(hostname -A -s) + local aliasname=$(get_alias) + local nodename=$1 + + hostnames="$hostnames $shortnames $aliasname" + + for name in ${hostnames}; do + if [ "$name" == "$nodename" ]; then + return 0 + fi + done + return 1 +} + # retrieves fence_kdump nodes from Pacemaker cluster configuration get_pcs_fence_kdump_nodes() { local nodes @@ -649,7 +688,7 @@ get_pcs_fence_kdump_nodes() { eval $node nodename=$uname # Skip its own node name - if [ "$nodename" = `hostname` -o "$nodename" = `hostname -s` ]; then + if is_localhost $nodename; then continue fi nodes="$nodes $nodename" @@ -666,6 +705,21 @@ get_pcs_fence_kdump_args() { fi } +get_generic_fence_kdump_nodes() { + local filtered + local nodes + + nodes=$(get_option_value "fence_kdump_nodes") + for node in ${nodes}; do + # Skip its own node name + if is_localhost $node; then + continue + fi + filtered="$filtered $node" + done + echo $filtered +} + # setup fence_kdump in cluster # setup proper network and install needed files kdump_configure_fence_kdump () { @@ -674,7 +728,7 @@ kdump_configure_fence_kdump () { local args if is_generic_fence_kdump; then - nodes=$(get_option_value "fence_kdump_nodes") + nodes=$(get_generic_fence_kdump_nodes) elif is_pcs_fence_kdump; then nodes=$(get_pcs_fence_kdump_nodes) @@ -717,7 +771,7 @@ kdump_install_random_seed() { install() { kdump_install_conf - remove_sysctl_conf + overwrite_sysctl_conf if is_ssh_dump_target; then kdump_install_random_seed @@ -731,12 +785,15 @@ install() { inst "/bin/sync" "/bin/sync" inst "/bin/cut" "/bin/cut" inst "/bin/head" "/bin/head" + inst "/bin/awk" "/bin/awk" + inst "/bin/sed" "/bin/sed" inst "/sbin/makedumpfile" "/sbin/makedumpfile" inst "/sbin/vmcore-dmesg" "/sbin/vmcore-dmesg" inst "/lib/kdump/kdump-lib.sh" "/lib/kdump-lib.sh" inst "/lib/kdump/kdump-lib-initramfs.sh" "/lib/kdump-lib-initramfs.sh" inst "$moddir/kdump.sh" "/usr/bin/kdump.sh" inst "$moddir/kdump-capture.service" "$systemdsystemunitdir/kdump-capture.service" + mkdir -p "$initdir/$systemdsystemunitdir/initrd.target.wants" ln_r "$systemdsystemunitdir/kdump-capture.service" "$systemdsystemunitdir/initrd.target.wants/kdump-capture.service" inst "$moddir/kdump-error-handler.sh" "/usr/bin/kdump-error-handler.sh" inst "$moddir/kdump-error-handler.service" "$systemdsystemunitdir/kdump-error-handler.service" @@ -751,6 +808,13 @@ install() { # at some point of time. kdump_check_iscsi_targets + # nfs/ssh dump will need to get host ip in second kernel and need to call 'ip' tool, see get_host_ip for more detail + # also need to let initqueue wait for target to become ready + if is_nfs_dump_target || is_ssh_dump_target; then + inst_hook initqueue/finished 01 $moddir/kdump-wait-for-target.sh + inst "ip" + fi + # For the lvm type target under kdump, in /etc/lvm/lvm.conf we can # safely replace "reserved_memory=XXXX"(default value is 8192) with # "reserved_memory=1024" to lower memory pressure under kdump. We do @@ -768,4 +832,14 @@ install() { echo "[Manager]" > ${initdir}/etc/systemd/system.conf.d/kdump.conf echo "DefaultTimeoutStartSec=300s" >> ${initdir}/etc/systemd/system.conf.d/kdump.conf fi + + # Forward logs to console directly, this avoids unneccessary memory + # consumption and make console output more useful. + # Only do so for non fadump image. + if ! is_fadump_capable; then + mkdir -p ${initdir}/etc/systemd/journald.conf.d + echo "[Journal]" > ${initdir}/etc/systemd/journald.conf.d/kdump.conf + echo "Storage=none" >> ${initdir}/etc/systemd/journald.conf.d/kdump.conf + echo "ForwardToConsole=yes" >> ${initdir}/etc/systemd/journald.conf.d/kdump.conf + fi } diff --git a/early-kdump-howto.txt b/early-kdump-howto.txt index fe4f13f0ea5229901f7037eab9b9ff3019c35100..68b23c7d1f2d56b02edfae9aa566a530f94ad21d 100644 --- a/early-kdump-howto.txt +++ b/early-kdump-howto.txt @@ -1,34 +1,53 @@ Early Kdump HOWTO Introduction +------------ -Kdump service starts too late, so early crashes will have no chance to get -kdump kernel booting, this will cause crash information to be lost. It is -necessary to add a dracut module in order to load crash kernel and initramfs -as early as possible. You can provide "rd.earlykdump" in grub commandline -to enable, then the early kdump will load those files like the normal kdump, -which is disabled by default. +Early kdump is a mechanism to make kdump operational earlier than normal kdump +service. The kdump service starts early enough for general crash cases, but +there are some cases where it has no chance to make kdump operational in boot +sequence, such as detecting devices and starting early services. If you hit +such a case, early kdump may allow you to get more information of it. + +Early kdump is implemented as a dracut module. It adds a kernel (vmlinuz) and +initramfs for kdump to your system's initramfs in order to load them as early +as possible. After that, if you provide "rd.earlykdump" in kernel command line, +then in the initramfs, early kdump will load those files like the normal kdump +service. This is disabled by default. For the normal kdump service, it can check whether the early kdump has loaded the crash kernel and initramfs. It has no conflict with the early kdump. -How to configure early kdump: +How to configure early kdump +---------------------------- We assume if you're reading this document, you should already have kexec-tools installed. You can rebuild the initramfs with earlykdump support with below steps: + 1. start kdump service to make sure kdump initramfs is created. + # systemctl start kdump + NOTE: If a crash occurs during boot process, early kdump captures a vmcore + and reboot the system by default, so the system might go into crash loop. + You can avoid such a crash loop by adding the following settings, which + power off the system after dump capturing, to kdump.conf in advance: + + final_action poweroff + failure_action poweroff + + For the failure_action, you can choose anything other than "reboot". + 2. rebuild system initramfs with earlykdump support. - # dracut --add earlykdump -3. add rd.earlykdump in grub kernel command line. + # dracut --force --add earlykdump + + NOTE: Recommend to backup the original system initramfs before performing + this step to put it back if something happens during boot-up. -Note: earlykdump initramfs size will be large because it includes vmlinuz and -kdump initramfs. And for step 2 if you are sure to overwrite system initramfs -you can backup the original initramfs and use "--force" option. +3. add rd.earlykdump in grub kernel command line. After making said changes, reboot your system to take effect. Of course, if you want to disable early kdump, you can simply remove "rd.earlykdump" from kernel @@ -37,18 +56,40 @@ boot parameters in grub, and reboot system like above. Once the boot is completed, you can check the status of the early kdump support on the command prompt: - # journalctl -x|grep early-kdump + # journalctl -b | grep early-kdump + +Then, you will see some useful logs, for example: + +- if early kdump is successful. + +Mar 09 09:57:56 localhost dracut-cmdline[190]: early-kdump is enabled. +Mar 09 09:57:56 localhost dracut-cmdline[190]: kexec: loaded early-kdump kernel -Then, you will see some useful logs, for exapmle: +- if early kdump is disabled. -1. if early kdump is successful. -Mar 09 09:57:56 localhost.localdomain dracut-cmdline[190]: early-kdump is enabled. -Mar 09 09:57:56 localhost.localdomain dracut-cmdline[190]: kexec: loaded early- -kdump kernel +Mar 09 10:02:47 localhost dracut-cmdline[189]: early-kdump is disabled. -2. if early kdump is disabled. -Mar 09 10:02:47 localhost.localdomain dracut-cmdline[189]: early-kdump is disabled. +Notes +----- + +- The size of early kdump initramfs will be large because it includes vmlinuz + and kdump initramfs. + +- Early kdump inherits the settings of normal kdump, so any changes that + caused normal kdump rebuilding also require rebuilding the system initramfs + to make sure that the changes take effect for early kdump. Therefore, after + the rebuilding of kdump initramfs is completed, provide a prompt message to + tell the fact. + +- If you install an updated kernel and reboot the system with it, the early + kdump will be disabled by default. To enable it with the new kernel, you + need to take the above steps again. Limitation +---------- + +- At present, early kdump doesn't support fadump. -At present, early kdump doesn't support fadump. +- Early kdump loads a crash kernel and initramfs at the beginning of the + process in system's initramfs, so a crash at earlier than that (e.g. in + kernel initialization) cannot be captured even with the early kdump. diff --git a/eppic-d84c354.tar.gz b/eppic-d84c354.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..3422d6d7211daf6ccf8f376a4bc14d5415b4f4e2 Binary files /dev/null and b/eppic-d84c354.tar.gz differ diff --git a/eppic_050615.tar.gz b/eppic_050615.tar.gz deleted file mode 100644 index 3df13bb2cf0d950936ccc049640c27208a698fe2..0000000000000000000000000000000000000000 Binary files a/eppic_050615.tar.gz and /dev/null differ diff --git a/fix-header-offset-overflow-when-large-pfn.patch b/fix-header-offset-overflow-when-large-pfn.patch new file mode 100644 index 0000000000000000000000000000000000000000..ab120a0e85ff3657cc55f0d0b525fb42a9d40172 --- /dev/null +++ b/fix-header-offset-overflow-when-large-pfn.patch @@ -0,0 +1,37 @@ +From bde6d1f1d3f9551fa4ca65247e210c8ac7814168 Mon Sep 17 00:00:00 2001 +From: Jialong Chen +Date: Tue, 3 Dec 2019 20:26:55 +0000 +Subject: [PATCH] fix header offset overflow when large pfn + +info->len_bitmap=0x182000000 +dh->bitmap_blocks * dh->block_size = info->len_bitmap=0x182000000 > int range +so: +cd_header->offset = (DISKDUMP_HEADER_BLOCKS + dh->sub_hdr_size + dh->bitmap_blocks) * dh->block_size; +get cd_header->offset = 0x82015000, but correct size is 0x182015000 +so we set DISKDUMP_HEADER_BLOCKS to 1UL. + +when cd_header->offset overflow, and cd_page->offset get an error offset. +cd_page->offset = cd_header->offset + sizeof(page_desc_t)*info->num_dumpable +later write page data will cover bitmap2. + +Signed-off-by: Jialong Chen +--- + makedumpfile-1.6.4/diskdump_mod.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/makedumpfile-1.6.7/diskdump_mod.h b/makedumpfile-1.6.7/diskdump_mod.h +index 2676817..3733953 100644 +--- a/makedumpfile-1.6.7/diskdump_mod.h ++++ b/makedumpfile-1.6.7/diskdump_mod.h +@@ -22,7 +22,7 @@ + #define DISK_DUMP_SIGNATURE "DISKDUMP" + #define KDUMP_SIGNATURE "KDUMP " + #define SIG_LEN (sizeof(DUMP_PARTITION_SIGNATURE) - 1) +-#define DISKDUMP_HEADER_BLOCKS (1) ++#define DISKDUMP_HEADER_BLOCKS (1UL) + + /* + * These are all remnants of the old "diskdump" facility, +-- +1.8.3.1 + diff --git a/kdump-fix-an-error-that-can-not-parse-the-e820-reser.patch b/kdump-fix-an-error-that-can-not-parse-the-e820-reser.patch deleted file mode 100644 index 8bf7338a9ecefe56360a2e46860e161bfa14cb82..0000000000000000000000000000000000000000 --- a/kdump-fix-an-error-that-can-not-parse-the-e820-reser.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 1ac3e4a570005707260ea3e74ac011bd926b168b Mon Sep 17 00:00:00 2001 -From: Lianbo Jiang -Date: Thu, 6 Sep 2018 13:56:18 +0800 -Subject: [PATCH 51/55] kdump: fix an error that can not parse the e820 - reserved region - -When kexec-tools load the kernel and initramfs for kdump, kexec-tools will -read /proc/iomem and recreate the e820 ranges for kdump kernel. But it fails -to parse the e820 reserved region, because the memcmp() is case sensitive -when comparing the string. In fact, it may be "Reserved" or "reserved" in -the /proc/iomem, so we have to fix these cases. - -Signed-off-by: Lianbo Jiang -Reviewed-by: Dave Young -Signed-off-by: Simon Horman ---- - kexec/arch/i386/crashdump-x86.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/kexec/arch/i386/crashdump-x86.c b/kexec/arch/i386/crashdump-x86.c -index 437e8a8..140f45b 100644 ---- a/kexec/arch/i386/crashdump-x86.c -+++ b/kexec/arch/i386/crashdump-x86.c -@@ -289,6 +289,8 @@ static int get_crash_memory_ranges(struct memory_range **range, int *ranges, - type = RANGE_PMEM; - } else if(memcmp(str,"reserved\n",9) == 0 ) { - type = RANGE_RESERVED; -+ } else if (memcmp(str, "Reserved\n", 9) == 0) { -+ type = RANGE_RESERVED; - } else if (memcmp(str, "GART\n", 5) == 0) { - gart_start = start; - gart_end = end; --- -1.8.3.1 - diff --git a/kdump-lib-initramfs.sh b/kdump-lib-initramfs.sh old mode 100644 new mode 100755 index 2c18c8703fe3c1ddc7a4b803aedafd09fb67a303..a7c0bf9de3cd604bba10fd2a39481f11ccc8e90d --- a/kdump-lib-initramfs.sh +++ b/kdump-lib-initramfs.sh @@ -6,7 +6,7 @@ KDUMP_PATH="/var/crash" CORE_COLLECTOR="" DEFAULT_CORE_COLLECTOR="makedumpfile -l --message-level 1 -d 31" DMESG_COLLECTOR="/sbin/vmcore-dmesg" -DEFAULT_ACTION="systemctl reboot -f" +FAILURE_ACTION="systemctl reboot -f" DATEDIR=`date +%Y-%m-%d-%T` HOST_IP='127.0.0.1' DUMP_INSTRUCTION="" @@ -18,6 +18,7 @@ KDUMP_CONF="/etc/kdump.conf" KDUMP_PRE="" KDUMP_POST="" NEWROOT="/sysroot" +OPALCORE="/sys/firmware/opal/mpipl/core" get_kdump_confs() { @@ -26,7 +27,6 @@ get_kdump_confs() while read config_opt config_val; do # remove inline comments after the end of a directive. - config_val=$(strip_comments $config_val) case "$config_opt" in path) KDUMP_PATH="$config_val" @@ -51,27 +51,40 @@ get_kdump_confs() fence_kdump_nodes) FENCE_KDUMP_NODES="$config_val" ;; - default) + failure_action|default) case $config_val in shell) - DEFAULT_ACTION="kdump_emergency_shell" + FAILURE_ACTION="kdump_emergency_shell" ;; reboot) - DEFAULT_ACTION="systemctl reboot -f" + FAILURE_ACTION="systemctl reboot -f && exit" ;; halt) - DEFAULT_ACTION="halt" + FAILURE_ACTION="halt && exit" ;; poweroff) - DEFAULT_ACTION="poweroff" + FAILURE_ACTION="systemctl poweroff -f && exit" ;; dump_to_rootfs) - DEFAULT_ACTION="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 + done <<< "$(read_strip_comments $KDUMP_CONF)" if [ -z "$CORE_COLLECTOR" ]; then CORE_COLLECTOR="$DEFAULT_CORE_COLLECTOR" @@ -84,15 +97,31 @@ get_kdump_confs() # dump_fs dump_fs() { - + local _do_umount="" local _dev=$(findmnt -k -f -n -r -o SOURCE $1) local _mp=$(findmnt -k -f -n -r -o TARGET $1) - - echo "kdump: dump target is $_dev" + local _op=$(findmnt -k -f -n -r -o OPTIONS $1) if [ -z "$_mp" ]; then - echo "kdump: error: Dump target $_dev is not mounted." - return 1 + _dev=$(findmnt -s -f -n -r -o SOURCE $1) + _mp=$(findmnt -s -f -n -r -o TARGET $1) + _op=$(findmnt -s -f -n -r -o OPTIONS $1) + + if [ -n "$_dev" ] && [ -n "$_mp" ]; then + echo "kdump: dump target $_dev is not mounted, trying to mount..." + mkdir -p $_mp + mount -o $_op $_dev $_mp + + if [ $? -ne 0 ]; then + echo "kdump: mounting failed (mount point: $_mp, option: $_op)" + return 1 + fi + _do_umount=1 + else + echo "kdump: error: Dump target $_dev is not usable" + fi + else + echo "kdump: dump target is $_dev" fi # Remove -F in makedumpfile case. We don't want a flat format dump here. @@ -100,10 +129,16 @@ dump_fs() echo "kdump: saving to $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/" - mount -o remount,rw $_mp || return 1 + # Only remount to read-write mode if the dump target is mounted read-only. + if [[ "$_op" = "ro"* ]]; then + echo "kdump: Mounting Dump target $_dev in rw mode." + mount -o remount,rw $_dev $_mp || return 1 + fi + mkdir -p $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR || return 1 save_vmcore_dmesg_fs ${DMESG_COLLECTOR} "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/" + save_opalcore_fs "$_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/" echo "kdump: saving vmcore" $CORE_COLLECTOR /proc/vmcore $_mp/$KDUMP_PATH/$HOST_IP-$DATEDIR/vmcore-incomplete || return 1 @@ -111,6 +146,11 @@ dump_fs() sync echo "kdump: saving vmcore complete" + + if [ $_do_umount ]; then + umount $_mp || echo "kdump: warn: failed to umount target" + fi + # improper kernel cmdline can cause the failure of echo, we can ignore this kind of failure return 0 } @@ -135,6 +175,30 @@ save_vmcore_dmesg_fs() { fi } +save_opalcore_fs() { + local _path=$1 + + if [ ! -f $OPALCORE ]; then + # Check if we are on an old kernel that uses a different path + if [ -f /sys/firmware/opal/core ]; then + OPALCORE="/sys/firmware/opal/core" + else + return 0 + fi + fi + + echo "kdump: saving opalcore" + cp $OPALCORE ${_path}/opalcore + if [ $? -ne 0 ]; then + echo "kdump: saving opalcore failed" + return 1 + fi + + sync + echo "kdump: saving opalcore complete" + return 0 +} + dump_to_rootfs() { @@ -153,13 +217,61 @@ kdump_emergency_shell() rm -f /etc/profile } -do_default_action() +do_failure_action() { - echo "Kdump: Executing default action $DEFAULT_ACTION" - eval $DEFAULT_ACTION + echo "Kdump: Executing failure action $FAILURE_ACTION" + eval $FAILURE_ACTION } do_final_action() { eval $FINAL_ACTION } + +get_host_ip() +{ + local _host + if is_nfs_dump_target || is_ssh_dump_target + then + kdumpnic=$(getarg kdumpnic=) + [ -z "$kdumpnic" ] && echo "kdump: failed to get kdumpnic!" && return 1 + _host=`ip addr show dev $kdumpnic|grep '[ ]*inet'` + [ $? -ne 0 ] && echo "kdump: wrong kdumpnic: $kdumpnic" && return 1 + _host=`echo $_host | head -n 1 | cut -d' ' -f2` + _host="${_host%%/*}" + [ -z "$_host" ] && echo "kdump: wrong kdumpnic: $kdumpnic" && return 1 + HOST_IP=$_host + fi + return 0 +} + +read_kdump_conf() +{ + if [ ! -f "$KDUMP_CONF" ]; then + echo "kdump: $KDUMP_CONF not found" + return + fi + + get_kdump_confs + + # rescan for add code for dump target + while read config_opt config_val; + do + # remove inline comments after the end of a directive. + case "$config_opt" in + dracut_args) + config_val=$(get_dracut_args_target "$config_val") + [ -n "$config_val" ] && add_dump_code "dump_fs $config_val" + ;; + ext[234]|xfs|btrfs|minix|nfs) + add_dump_code "dump_fs $config_val" + ;; + raw) + add_dump_code "dump_raw $config_val" + ;; + ssh) + add_dump_code "dump_ssh $SSH_KEY_LOCATION $config_val" + ;; + esac + done <<< "$(read_strip_comments $KDUMP_CONF)" +} diff --git a/kdump-lib.sh b/kdump-lib.sh old mode 100644 new mode 100755 index 6acab8cbb74384ed2af91baf2480efc687a84a8c..b079f27dccc7d715433024184a840176b14b5b0c --- a/kdump-lib.sh +++ b/kdump-lib.sh @@ -28,6 +28,11 @@ perror() { echo $@ >&2 } +is_fs_type_nfs() +{ + [ "$1" = "nfs" ] || [ "$1" = "nfs4" ] +} + is_ssh_dump_target() { grep -q "^ssh[[:blank:]].*@" /etc/kdump.conf @@ -35,8 +40,23 @@ is_ssh_dump_target() is_nfs_dump_target() { - grep -q "^nfs" /etc/kdump.conf || \ - [[ $(get_dracut_args_fstype "$(grep "^dracut_args .*\-\-mount" /etc/kdump.conf)") = nfs* ]] + if grep -q "^nfs" /etc/kdump.conf; then + return 0; + fi + + if is_fs_type_nfs $(get_dracut_args_fstype "$(grep "^dracut_args .*\-\-mount" /etc/kdump.conf)"); then + return 0 + fi + + local _save_path=$(get_save_path) + local _target=$(get_target_from_path $_save_path) + local _fstype=$(get_fs_type_from_target $_target) + + if is_fs_type_nfs $_fstype; then + return 0 + fi + + return 1 } is_raw_dump_target() @@ -44,13 +64,6 @@ is_raw_dump_target() grep -q "^raw" /etc/kdump.conf } -is_fs_type_nfs() -{ - local _fstype=$1 - [ $_fstype = "nfs" ] || [ $_fstype = "nfs4" ] && return 0 - return 1 -} - is_fs_dump_target() { egrep -q "^ext[234]|^xfs|^btrfs|^minix" /etc/kdump.conf @@ -61,6 +74,14 @@ strip_comments() echo $@ | sed -e 's/\(.*\)#.*/\1/' } +# Read from kdump config file stripping all comments +read_strip_comments() +{ + # strip heading spaces, and print any content starting with + # neither space or #, and strip everything after # + sed -n -e "s/^\s*\([^# \t][^#]\+\).*/\1/gp" $1 +} + # Check if fence kdump is configured in Pacemaker cluster is_pcs_fence_kdump() { @@ -96,8 +117,7 @@ to_dev_name() { is_user_configured_dump_target() { - return $(is_mount_in_dracut_args || is_ssh_dump_target || is_nfs_dump_target || \ - is_raw_dump_target || is_fs_dump_target) + grep -E -q "^ext[234]|^xfs|^btrfs|^minix|^raw|^nfs|^ssh" /etc/kdump.conf || is_mount_in_dracut_args; } get_user_configured_dump_disk() @@ -113,21 +133,16 @@ get_user_configured_dump_disk() get_root_fs_device() { - local _target - _target=$(findmnt -k -f -n -o SOURCE /) - [ -n "$_target" ] && echo $_target - - return + findmnt -k -f -n -o SOURCE / } get_save_path() { - local _save_path=$(grep "^path" /etc/kdump.conf|awk '{print $2}') - if [ -z "$_save_path" ]; then - _save_path=$DEFAULT_PATH - fi + local _save_path=$(awk '$1 == "path" {print $2}' /etc/kdump.conf) + [ -z "$_save_path" ] && _save_path=$DEFAULT_PATH - echo $_save_path + # strip the duplicated "/" + echo $_save_path | tr -s / } get_block_dump_target() @@ -149,10 +164,10 @@ get_block_dump_target() is_dump_to_rootfs() { - grep "^default[[:space:]]dump_to_rootfs" /etc/kdump.conf >/dev/null + grep -E "^(failure_action|default)[[:space:]]dump_to_rootfs" /etc/kdump.conf >/dev/null } -get_default_action_target() +get_failure_action_target() { local _target @@ -181,7 +196,7 @@ get_kdump_targets() fi # Add the root device if dump_to_rootfs is specified. - _root=$(get_default_action_target) + _root=$(get_failure_action_target) if [ -n "$_root" -a "$kdump_targets" != "$_root" ]; then kdump_targets="$kdump_targets $_root" fi @@ -189,44 +204,39 @@ get_kdump_targets() echo "$kdump_targets" } - +# Return the bind mount source path, return the path itself if it's not bind mounted +# Eg. if /path/to/src is bind mounted to /mnt/bind, then: +# /mnt/bind -> /path/to/src, /mnt/bind/dump -> /path/to/src/dump +# # findmnt uses the option "-v, --nofsroot" to exclusive the [/dir] # in the SOURCE column for bind-mounts, then if $_mntpoint equals to # $_mntpoint_nofsroot, the mountpoint is not bind mounted directory. -is_bind_mount() -{ - local _mntpoint=$(findmnt $1 | tail -n 1 | awk '{print $2}') - local _mntpoint_nofsroot=$(findmnt -v $1 | tail -n 1 | awk '{print $2}') - - if [[ $_mntpoint = $_mntpoint_nofsroot ]]; then - return 1 - else - return 0 - fi -} - +# # Below is just an example for mount info # /dev/mapper/atomicos-root[/ostree/deploy/rhel-atomic-host/var], if the # directory is bind mounted. The former part represents the device path, rest # part is the bind mounted directory which quotes by bracket "[]". -get_bind_mount_directory() +get_bind_mount_source() { - local _mntpoint=$(findmnt $1 | tail -n 1 | awk '{print $2}') - local _mntpoint_nofsroot=$(findmnt -v $1 | tail -n 1 | awk '{print $2}') + local _path=$1 + # In case it's a sub path in a mount point, get the mount point first + local _mnt_top=$(df $_path | tail -1 | awk '{print $NF}') + local _mntpoint=$(findmnt $_mnt_top | tail -n 1 | awk '{print $2}') + local _mntpoint_nofsroot=$(findmnt -v $_mnt_top | tail -n 1 | awk '{print $2}') - _mntpoint=${_mntpoint#*$_mntpoint_nofsroot} + if [[ "$_mntpoint" = $_mntpoint_nofsroot ]]; then + echo $_path && return + fi + _mntpoint=${_mntpoint#*$_mntpoint_nofsroot} _mntpoint=${_mntpoint#[} _mntpoint=${_mntpoint%]} + _path=${_path#$_mnt_top} - echo $_mntpoint -} - -get_mntpoint_from_path() -{ - echo $(df $1 | tail -1 | awk '{print $NF}') + echo $_mntpoint$_path } +# Return the real underlaying device of a path, ignore bind mounts get_target_from_path() { local _target @@ -236,64 +246,22 @@ get_target_from_path() echo $_target } -get_fs_type_from_target() +get_fs_type_from_target() { - echo $(findmnt -k -f -n -r -o FSTYPE $1) + findmnt -k -f -n -r -o FSTYPE $1 } -# input: device path -# output: the general mount point -# find the general mount point, not the bind mounted point in atomic -# As general system, Use the previous code -# -# ERROR and EXIT: -# the device can be umounted the general mount point, if one of the mount point is bind mounted -# For example: -# mount /dev/sda /mnt/ -# mount -o bind /mnt/var /var -# umount /mnt +# Find the general mount point of a dump target, not the bind mount point get_mntpoint_from_target() { - if is_atomic; then - for _mnt in $(findmnt -k -n -r -o TARGET $1) - do - if ! is_bind_mount $_mnt; then - echo $_mnt - return - fi - done - - echo "Mount $1 firstly, without the bind mode" >&2 - exit 1 - else - echo $(findmnt -k -f -n -r -o TARGET $1) - fi + # Expcilitly specify --source to findmnt could ensure non-bind mount is returned + findmnt -k -f -n -r -o TARGET --source $1 } # get_option_value # retrieves value of option defined in kdump.conf get_option_value() { - echo $(strip_comments `grep "^$1[[:space:]]\+" /etc/kdump.conf | tail -1 | cut -d\ -f2-`) -} - -#This function compose a absolute path with the mount -#point and the relative $SAVE_PATH. -#target is passed in as argument, could be UUID, LABEL, -#block device or even nfs server export of the form of -#"my.server.com:/tmp/export"? -#And possibly this could be used for both default case -#as well as when dump taret is specified. When dump -#target is not specified, then $target would be null. -make_absolute_save_path() -{ - local _target=$1 - local _mnt - - [ -n $_target ] && _mnt=$(get_mntpoint_from_target $1) - _mnt="${_mnt}/$SAVE_PATH" - - # strip the duplicated "/" - echo "$_mnt" | tr -s / + strip_comments `grep "^$1[[:space:]]\+" /etc/kdump.conf | tail -1 | cut -d\ -f2-` } check_save_path_fs() @@ -305,6 +273,15 @@ check_save_path_fs() fi } +# Check if path exists within dump target +check_save_path_user_configured() +{ + local _target=$1 _path=$2 + local _mnt=$(get_mntpoint_from_target $_target) + + check_save_path_fs "$_mnt/$_path" +} + is_atomic() { grep -q "ostree" /proc/cmdline @@ -581,35 +558,6 @@ need_64bit_headers() print (strtonum("0x" r[2]) > strtonum("0xffffffff")); }'` } -# Check if secure boot is being enforced. -# -# Per Peter Jones, we need check efivar SecureBoot-$(the UUID) and -# SetupMode-$(the UUID), they are both 5 bytes binary data. The first four -# bytes are the attributes associated with the variable and can safely be -# ignored, the last bytes are one-byte true-or-false variables. If SecureBoot -# is 1 and SetupMode is 0, then secure boot is being enforced. -# -# Assume efivars is mounted at /sys/firmware/efi/efivars. -is_secure_boot_enforced() -{ - local secure_boot_file setup_mode_file - local secure_boot_byte setup_mode_byte - - secure_boot_file=$(find /sys/firmware/efi/efivars -name SecureBoot-* 2>/dev/null) - setup_mode_file=$(find /sys/firmware/efi/efivars -name SetupMode-* 2>/dev/null) - - if [ -f "$secure_boot_file" ] && [ -f "$setup_mode_file" ]; then - secure_boot_byte=$(hexdump -v -e '/1 "%d\ "' $secure_boot_file|cut -d' ' -f 5) - setup_mode_byte=$(hexdump -v -e '/1 "%d\ "' $setup_mode_file|cut -d' ' -f 5) - - if [ "$secure_boot_byte" = "1" ] && [ "$setup_mode_byte" = "0" ]; then - return 0 - fi - fi - - return 1 -} - # # prepare_kexec_args # This function prepares kexec argument. @@ -659,7 +607,7 @@ check_boot_dir() kdump_bootdir="/boot" else eval $(cat /proc/cmdline| grep "BOOT_IMAGE" | cut -d' ' -f1) - kdump_bootdir="/boot"$(dirname $BOOT_IMAGE) + kdump_bootdir="/boot"$(dirname ${BOOT_IMAGE#*)}) fi echo $kdump_bootdir } diff --git a/kdump-udev-throttler b/kdump-udev-throttler new file mode 100755 index 0000000000000000000000000000000000000000..cd77a31932c91dfff3642a40886b001636756b7f --- /dev/null +++ b/kdump-udev-throttler @@ -0,0 +1,42 @@ +#!/bin/bash +# This util helps to reduce the workload of kdump service restarting +# on udev event. When hotplugging memory / CPU, multiple udev +# events may be triggered concurrently, and obviously, we don't want +# to restart kdump service for each event. + +# This script will be called by udev, and make sure kdump service is +# restart after all events we are watching are settled. + +# On each call, this script will update try to aquire the $throttle_lock +# The first instance acquired the file lock will keep waiting for events +# to settle and then reload kdump. Other instances will just exit +# In this way, we can make sure kdump service is restarted immediately +# and for exactly once after udev events are settled. + +throttle_lock="/var/lock/kdump-udev-throttle" + +exec 9>$throttle_lock +if [ $? -ne 0 ]; then + echo "Failed to create the lock file! Fallback to non-throttled kdump service restart" + /bin/kdumpctl reload + exit 1 +fi + +flock -n 9 +if [ $? -ne 0 ]; then + echo "Throttling kdump restart for concurrent udev event" + exit 0 +fi + +# Wait for at least 1 second, at most 4 seconds for udev to settle +# Idealy we will have a less than 1 second lag between udev events settle +# and kdump reload +sleep 1 && udevadm settle --timeout 3 + +# Release the lock, /bin/kdumpctl will block and make the process +# holding two locks at the same time and we might miss some events +exec 9>&- + +/bin/kdumpctl reload + +exit 0 diff --git a/kdump.conf b/kdump.conf index 57af7b6ca52ae1ad33545252126f0deac7ebf780..1f0fc2ddc40b3723f47528d10b0a028c79145933 100644 --- a/kdump.conf +++ b/kdump.conf @@ -6,8 +6,8 @@ # processed. # # Currently, only one dump target and path can be specified. If the dumping to -# the configured target fails, the default action which can be configured via -# the "default" directive will be performed. +# the configured target fails, the failure action which can be configured via +# the "failure_action" directive will be performed. # # Supported options: # @@ -32,7 +32,7 @@ # # # - Will mount -t , and copy -# /proc/vmcore to //%DATE/. +# /proc/vmcore to //%HOST_IP-%DATE/. # NOTE: can be a device node, label or uuid. # It's recommended to use persistent device names # such as /dev/vg/. @@ -99,17 +99,29 @@ # Multiple modules can be listed, separated by spaces, and any # dependent modules will automatically be included. # -# default +# failure_action # - Action to perform in case dumping fails. # reboot: Reboot the system. # halt: Halt the system. # poweroff: Power down the system. # shell: Drop to a bash shell. -# Exiting the shell reboots the system. +# Exiting the shell reboots the system by default, +# or perform "final_action". # dump_to_rootfs: Dump vmcore to rootfs from initramfs context and -# reboot. Useful when non-root dump target is specified. +# reboot by default or perform "final_action". +# Useful when non-root dump target is specified. # The default option is "reboot". # +# default +# - Same as the "failure_action" directive above, but this directive +# is obsolete and will be removed in the future. +# +# final_action +# - Action to perform in case dumping succeeds. Also performed +# when "shell" or "dump_to_rootfs" failure action finishes. +# Each action is same as the "failure_action" directive above. +# The default is "reboot". +# # force_rebuild <0 | 1> # - By default, kdump initrd will only be rebuilt when necessary. # Specify 1 to force rebuilding kdump initrd every time when kdump @@ -155,7 +167,7 @@ core_collector makedumpfile -l --message-level 1 -d 31 #kdump_pre /var/crash/scripts/kdump-pre.sh #extra_bins /usr/bin/lftp #extra_modules gfs2 -#default shell +#failure_action shell #force_rebuild 1 #force_no_rebuild 1 #dracut_args --omit-drivers "cfg80211 snd" --add-drivers "ext2 ext3" diff --git a/kdump.conf.5 b/kdump.conf.5 index 11b1fad559b46bb0381ae05b4b525fb5d828632a..5a0952b29626924c8f1ed8987bc7caedc719ad33 100644 --- a/kdump.conf.5 +++ b/kdump.conf.5 @@ -55,7 +55,7 @@ The default value is /root/.ssh/kdump_id_rsa. .B .RS Will mount -t , and copy /proc/vmcore to -//%DATE/. NOTE: can be a device node, label +//%HOST_IP-%DATE/. NOTE: can be a device node, label or uuid. It's recommended to use persistent device names such as /dev/vg/. Otherwise it's suggested to use label or uuid. .RE @@ -148,16 +148,32 @@ modules can be listed, separated by spaces, and any dependent modules will automatically be included. .RE -.B default +.B failure_action .RS Action to perform in case dumping to the intended target fails. The default is "reboot". reboot: Reboot the system (this is what most people will want, as it returns the system to a normal state). halt: Halt the system and lose the vmcore. poweroff: The system will be powered down. shell: Drop to a shell session inside the initramfs, from which you can manually perform additional recovery actions. Exiting this shell reboots the -system. Note: kdump uses bash as the default shell. dump_to_rootfs: If non-root dump -target is specified, the default action can be set as dump_to_rootfs. That means when -dumping to target fails, dump vmcore to rootfs from initramfs context and reboot. +system by default or performs "final_action". +Note: kdump uses bash as the default shell. dump_to_rootfs: If non-root dump +target is specified, the failure action can be set as dump_to_rootfs. That means when +dumping to target fails, dump vmcore to rootfs from initramfs context and reboot +by default or perform "final_action". +.RE + +.B default +.RS +Same as the "failure_action" directive above, but this directive is obsolete +and will be removed in the future. +.RE + +.B final_action +.RS +Action to perform in case dumping to the intended target succeeds. +Also performed when "shell" or "dump_to_rootfs" failure action finishes. +Each action is same as the "failure_action" directive above. +The default is "reboot". .RE .B force_rebuild <0 | 1> diff --git a/kdump.service b/kdump.service index 5144597acf9dda63724af8de8eeaad16e65d3dc8..f888dd6d5e7a535f327f2cfce4f96ffa4ebbc080 100644 --- a/kdump.service +++ b/kdump.service @@ -7,6 +7,7 @@ DefaultDependencies=no Type=oneshot ExecStart=/usr/bin/kdumpctl start ExecStop=/usr/bin/kdumpctl stop +ExecReload=/usr/bin/kdumpctl reload RemainAfterExit=yes StartLimitInterval=0 diff --git a/kdump.sysconfig b/kdump.sysconfig index 39a39eb032b7fa958a7d0bc1095890d74d3bf3de..df518d64afd8af5ebd74be5472d63ac18c4d589c 100644 --- a/kdump.sysconfig +++ b/kdump.sysconfig @@ -21,7 +21,7 @@ KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet" # This variable lets us append arguments to the current kdump commandline # 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 numa=off" +KDUMP_COMMANDLINE_APPEND="irqpoll maxcpus=1 reset_devices novmcoredd" # Any additional kexec arguments required. In most situations, this should # be left empty diff --git a/kdump.sysconfig.aarch64 b/kdump.sysconfig.aarch64 new file mode 100644 index 0000000000000000000000000000000000000000..39a39eb032b7fa958a7d0bc1095890d74d3bf3de --- /dev/null +++ b/kdump.sysconfig.aarch64 @@ -0,0 +1,37 @@ +# Kernel Version string for the -kdump kernel, such as 2.6.13-1544.FC5kdump +# If no version is specified, then the init script will try to find a +# kdump kernel with the same version number as the running kernel. +KDUMP_KERNELVER="" + +# The kdump commandline is the command line that needs to be passed off to +# the kdump kernel. This will likely match the contents of the grub kernel +# line. For example: +# KDUMP_COMMANDLINE="ro root=LABEL=/" +# Dracut depends on proper root= options, so please make sure that appropriate +# root= options are copied from /proc/cmdline. In general it is best to append +# command line options using "KDUMP_COMMANDLINE_APPEND=". +# If a command line is not specified, the default will be taken from +# /proc/cmdline +KDUMP_COMMANDLINE="" + +# This variable lets us remove arguments from the current kdump commandline +# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline +# NOTE: some arguments such as crashkernel will always be removed +KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet" + +# This variable lets us append arguments to the current kdump commandline +# 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 numa=off" + +# Any additional kexec arguments required. In most situations, this should +# be left empty +# +# Example: +# KEXEC_ARGS="--elf32-core-headers" +KEXEC_ARGS="" + +#Where to find the boot image +#KDUMP_BOOTDIR="/boot" + +#What is the image type used for kdump +KDUMP_IMG="vmlinuz" diff --git a/kdump.sysconfig.i386 b/kdump.sysconfig.i386 index b5ec65336d5a3c82041f0ccdfd540b3e8f0cb83d..c31a8cbe30775d960bea2d2316243317cafce5cc 100644 --- a/kdump.sysconfig.i386 +++ b/kdump.sysconfig.i386 @@ -21,7 +21,7 @@ KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet" # This variable lets us append arguments to the current kdump commandline # after processed by KDUMP_COMMANDLINE_REMOVE -KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices numa=off udev.children-max=2 panic=10 transparent_hugepage=never" +KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices numa=off udev.children-max=2 panic=10 transparent_hugepage=never novmcoredd" # Any additional kexec arguments required. In most situations, this should # be left empty diff --git a/kdump.sysconfig.ppc64 b/kdump.sysconfig.ppc64 index e142c6e38daea1649d22d92950870f8da6c48083..1f954521fd6d99392e045a7ca44c3638e972aa47 100644 --- a/kdump.sysconfig.ppc64 +++ b/kdump.sysconfig.ppc64 @@ -21,7 +21,7 @@ KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet" # This variable lets us append arguments to the current kdump commandline # 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 kvm_cma_resv_ratio=0 transparent_hugepage=never" +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" # Any additional kexec arguments required. In most situations, this should # be left empty diff --git a/kdump.sysconfig.ppc64le b/kdump.sysconfig.ppc64le index e142c6e38daea1649d22d92950870f8da6c48083..1f954521fd6d99392e045a7ca44c3638e972aa47 100644 --- a/kdump.sysconfig.ppc64le +++ b/kdump.sysconfig.ppc64le @@ -21,7 +21,7 @@ KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet" # This variable lets us append arguments to the current kdump commandline # 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 kvm_cma_resv_ratio=0 transparent_hugepage=never" +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" # Any additional kexec arguments required. In most situations, this should # be left empty diff --git a/kdump.sysconfig.s390x b/kdump.sysconfig.s390x index 6edc2fa12417d5ee2090d158c4b8f443ac1c3af0..abd45a2f332da327f175281ab5bb7b5ee2277247 100644 --- a/kdump.sysconfig.s390x +++ b/kdump.sysconfig.s390x @@ -21,7 +21,7 @@ KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet" # This variable lets us append arguments to the current kdump commandline # after processed by KDUMP_COMMANDLINE_REMOVE -KDUMP_COMMANDLINE_APPEND="nr_cpus=1 cgroup_disable=memory numa=off udev.children-max=2 panic=10 transparent_hugepage=never" +KDUMP_COMMANDLINE_APPEND="nr_cpus=1 cgroup_disable=memory numa=off udev.children-max=2 panic=10 transparent_hugepage=never novmcoredd" # Any additional /sbin/mkdumprd arguments required. MKDUMPRD_ARGS="" diff --git a/kdump.sysconfig.x86_64 b/kdump.sysconfig.x86_64 index 4a5ec1c4d023a48feaaa2aa04255466f74e8a17a..82172047864aec4d73766b4b9bd7323f3f3a101d 100644 --- a/kdump.sysconfig.x86_64 +++ b/kdump.sysconfig.x86_64 @@ -21,7 +21,7 @@ KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet" # This variable lets us append arguments to the current kdump commandline # 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 acpi_no_memhotplug transparent_hugepage=never nokaslr" +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" # Any additional kexec arguments required. In most situations, this should # be left empty @@ -38,3 +38,9 @@ KDUMP_IMG="vmlinuz" #What is the images extension. Relocatable kernels don't have one KDUMP_IMG_EXT="" + +# Using kexec file based syscall by default +# +# Here, the "on" is the only valid value to enable the kexec file load and +# anything else is equal to the "off"(disable). +KDUMP_FILE_LOAD="off" diff --git a/kdumpctl b/kdumpctl old mode 100644 new mode 100755 index e07ec06bc01665e6ecb1812a5d990dc33158907f..fb264c32dc82a58a635adcec4827f846cc7870b4 --- a/kdumpctl +++ b/kdumpctl @@ -4,6 +4,7 @@ KEXEC=/sbin/kexec KDUMP_KERNELVER="" KDUMP_COMMANDLINE="" KEXEC_ARGS="" +KDUMP_FILE_LOAD="" KDUMP_CONFIG_FILE="/etc/kdump.conf" MKDUMPRD="/sbin/mkdumprd -f" DRACUT_MODULES_FILE="/usr/lib/dracut/modules.txt" @@ -94,7 +95,7 @@ rebuild_fadump_initrd() # this file tells the initrd is fadump enabled touch /tmp/fadump.initramfs target_initrd_tmp="$TARGET_INITRD.tmp" - $MKDUMPRD $target_initrd_tmp --rebuild $TARGET_INITRD --kver $kdump_kver \ + $MKDUMPRD $target_initrd_tmp --rebuild $DEFAULT_INITRD_BAK --kver $kdump_kver \ -i /tmp/fadump.initramfs /etc/fadump.initramfs if [ $? != 0 ]; then echo "mkdumprd: failed to rebuild initrd with fadump support" >&2 @@ -110,6 +111,12 @@ rebuild_fadump_initrd() return 0 } +check_earlykdump_is_enabled() +{ + grep -q -w "rd.earlykdump" /proc/cmdline + return $? +} + rebuild_kdump_initrd() { $MKDUMPRD $TARGET_INITRD $kdump_kver @@ -118,11 +125,20 @@ rebuild_kdump_initrd() return 1 fi + if check_earlykdump_is_enabled; then + echo "Tips: If early kdump is enabled, also require rebuilding the system initramfs to make the changes take effect for early kdump." + fi + return 0 } rebuild_initrd() { + if [[ ! -w "$KDUMP_BOOTDIR" ]];then + echo "$KDUMP_BOOTDIR does not have write permission. Can not rebuild $TARGET_INITRD" + return 1 + fi + if [ $DEFAULT_DUMP_MODE == "fadump" ]; then rebuild_fadump_initrd else @@ -228,13 +244,15 @@ check_config() case "$config_opt" in \#* | "") ;; - raw|ext2|ext3|ext4|minix|btrfs|xfs|nfs|ssh|sshkey|path|core_collector|kdump_post|kdump_pre|extra_bins|extra_modules|default|force_rebuild|force_no_rebuild|dracut_args|fence_kdump_args|fence_kdump_nodes) + raw|ext2|ext3|ext4|minix|btrfs|xfs|nfs|ssh|sshkey|path|core_collector|kdump_post|kdump_pre|extra_bins|extra_modules|failure_action|default|final_action|force_rebuild|force_no_rebuild|dracut_args|fence_kdump_args|fence_kdump_nodes) # remove inline comments after the end of a directive. - config_val=$(strip_comments $config_val) [ -z "$config_val" ] && { echo "Invalid kdump config value for option $config_opt." return 1; } + if [ -d "/proc/device-tree/ibm,opal/dump" ] && [ "$config_opt" == "raw" ]; then + echo "WARNING: Won't capture opalcore when 'raw' dump target is used." + fi ;; net|options|link_delay|disk_timeout|debug_mem_level|blacklist) echo "Deprecated kdump config option: $config_opt. Refer to kdump.conf manpage for alternatives." @@ -245,9 +263,10 @@ check_config() return 1; ;; esac - done < $KDUMP_CONFIG_FILE + done <<< "$(read_strip_comments $KDUMP_CONFIG_FILE)" - check_default_config || return 1 + check_failure_action_config || return 1 + check_final_action_config || return 1 check_fence_kdump_config || return 1 @@ -283,16 +302,31 @@ get_pcs_cluster_modified_files() setup_initrd() { + KDUMP_BOOTDIR=$(check_boot_dir "${KDUMP_BOOTDIR}") + + if [ -z "$KDUMP_KERNELVER" ]; then + kdump_kver=`uname -r` + else + kdump_kver=$KDUMP_KERNELVER + fi + + kdump_kernel="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${kdump_kver}${KDUMP_IMG_EXT}" + DEFAULT_INITRD="${KDUMP_BOOTDIR}/initramfs-`uname -r`.img" DEFAULT_INITRD_BAK="${KDUMP_BOOTDIR}/.initramfs-`uname -r`.img.default" if [ $DEFAULT_DUMP_MODE == "fadump" ]; then TARGET_INITRD="$DEFAULT_INITRD" - if [ ! -s "$TARGET_INITRD" ]; then - echo "Error: No initrd found to rebuild!" - return 1 - fi + + # backup initrd for reference before replacing it + # with fadump aware initrd + backup_default_initrd else TARGET_INITRD="${KDUMP_BOOTDIR}/initramfs-${kdump_kver}kdump.img" + + # check if a backup of default initrd exists. If yes, + # it signifies a switch from fadump mode. So, restore + # the backed up default initrd. + restore_default_initrd fi } @@ -313,15 +347,49 @@ check_files_modified() files="$KDUMP_CONFIG_FILE $kdump_kernel $EXTRA_BINS $CORE_COLLECTOR" [[ -e /etc/fstab ]] && files="$files /etc/fstab" + # Check for any updated extra module + EXTRA_MODULES="$(grep ^extra_modules $KDUMP_CONFIG_FILE | sed 's/^extra_modules\s*//')" + if [ -n "$EXTRA_MODULES" ]; then + if [ -e /lib/modules/$kdump_kver/modules.dep ]; then + files="$files /lib/modules/$kdump_kver/modules.dep" + fi + for _module in $EXTRA_MODULES; do + _module_file="$(modinfo --set-version "$kdump_kver" --filename "$_module" 2>/dev/null)" + if [[ $? -eq 0 ]]; then + files="$files $_module_file" + for _dep_modules in $(modinfo -F depends $_module | tr ',' ' '); do + files="$files $(modinfo --set-version "$kdump_kver" --filename $_dep_modules 2>/dev/null)" + done + else + # If it's not a module nor builtin, give an error + if ! ( modprobe --set-version "$kdump_kver" --dry-run "$_module" &>/dev/null ); then + echo "Module $_module not found" + fi + fi + done + fi + check_exist "$files" && check_executable "$EXTRA_BINS" [ $? -ne 0 ] && return 2 for file in $files; do - time_stamp=`stat -c "%Y" $file` - if [ "$time_stamp" -gt "$image_time" ]; then - modified_files="$modified_files $file" + if [ -e "$file" ]; then + time_stamp=`stat -c "%Y" $file` + if [ "$time_stamp" -gt "$image_time" ]; then + modified_files="$modified_files $file" + fi + if [ -L "$file" ]; then + file=$(readlink -m $file) + time_stamp=`stat -c "%Y" $file` + if [ "$time_stamp" -gt "$image_time" ]; then + modified_files="$modified_files $file" + fi + fi + else + echo "$file doesn't exist" fi done + if [ -n "$modified_files" ]; then echo "Detected change(s) in the following file(s):" echo -n " "; echo "$modified_files" | sed 's/\s/\n /g' @@ -336,6 +404,9 @@ check_dump_fs_modified() local _old_dev _old_mntpoint _old_fstype local _new_dev _new_mntpoint _new_fstype local _target _path _dracut_args + local _target_drivers _module_name _module_filename + + local _old_drivers="$(lsinitrd $TARGET_INITRD -f /usr/lib/dracut/hostonly-kernel-modules.txt | tr '\n' ' ')" # No need to check in case of mount target specified via "dracut_args". if is_mount_in_dracut_args; then @@ -364,6 +435,36 @@ check_dump_fs_modified() fi fi + _record_block_drivers() { + local _drivers + if [[ -b /dev/block/$1 ]]; then + _drivers=$(udevadm info -a "/dev/block/$1" | sed -n 's/\s*DRIVERS=="\(\S\+\)"/\1/p') + fi + if [[ -b $1 ]]; then + _drivers=$(udevadm info -a "$1" | sed -n 's/\s*DRIVERS=="\(\S\+\)"/\1/p') + fi + for _driver in $_drivers; do + if ! [[ " $_target_drivers " == *" $_driver "* ]]; then + _target_drivers="$_target_drivers $_driver" + fi + done + return 1 + } + + check_block_and_slaves_all _record_block_drivers "$(get_maj_min "$_target")" + for _driver in $_target_drivers; do + # Skip deprecated/invalid driver name or built-in module + _module_name=$(modinfo --set-version "$kdump_kver" -F name $_driver 2>/dev/null) + _module_filename=$(modinfo --set-version "$kdump_kver" -n $_driver 2>/dev/null) + if [ $? -ne 0 ] || [ -z "$_module_name" ] || [[ "$_module_filename" = *"(builtin)"* ]]; then + continue + fi + if ! [[ " $_old_drivers " == *" $_module_name "* ]]; then + echo "Detected change in block device driver, new loaded module: $_module_name" + return 1 + fi + done + if [[ $(expr substr $_new_fstype 1 3) = "nfs" ]];then _new_dev=$_target else @@ -465,31 +566,6 @@ check_wdt_modified() return 1 } -check_kmodules_modified() -{ - # always sort again to avoid LANG/LC inconsistent problem - local _old_modules="$(lsinitrd $TARGET_INITRD -f /usr/lib/dracut/loaded-kernel-modules.txt | sort)" - local _new_modules="$(get_loaded_kernel_modules | sort)" - - [[ -z $_old_modules ]] && echo "Warning: Previous loaded kernel module list is absent or empty" - - local _added_modules=$(comm -13 <(echo "$_old_modules") <(echo "$_new_modules")) - local _dropped_modules=$(comm -23 <(echo "$_old_modules") <(echo "$_new_modules")) - - if [ "$_old_modules" != "$_new_modules" ]; then - echo "Detected change(s) of loaded kernel modules list:" - [[ -n $_added_modules ]] && for _module in $_added_modules; do - echo " +$_module" - done - [[ -n $_dropped_modules ]] && for _module in $_dropped_modules; do - echo " -$_module" - done - return 1 - fi - - return 0 -} - # returns 0 if system is not modified # returns 1 if system is modified # returns 2 if system modification is invalid @@ -517,32 +593,18 @@ check_system_modified() return 1 fi - check_kmodules_modified - if [ $? -ne 0 ]; then - return 1 - fi - return 0 } check_rebuild() { - local extra_modules local capture_capable_initrd="1" local _force_rebuild force_rebuild="0" local _force_no_rebuild force_no_rebuild="0" local ret system_modified="0" - KDUMP_BOOTDIR=$(check_boot_dir "${KDUMP_BOOTDIR}") - - if [ -z "$KDUMP_KERNELVER" ]; then - kdump_kver=`uname -r` - else - kdump_kver=$KDUMP_KERNELVER - fi - - kdump_kernel="${KDUMP_BOOTDIR}/${KDUMP_IMG}-${kdump_kver}${KDUMP_IMG_EXT}" setup_initrd + if [ $? -ne 0 ]; then return 1 fi @@ -575,10 +637,6 @@ check_rebuild() return 0 fi - #will rebuild every time if extra_modules are specified - extra_modules=`grep ^extra_modules $KDUMP_CONFIG_FILE` - [ -n "$extra_modules" ] && force_rebuild="1" - #check to see if dependent files has been modified #since last build of the image file if [ -f $TARGET_INITRD ]; then @@ -599,8 +657,6 @@ check_rebuild() system_modified="1" fi - handle_mode_switch - if [ $image_time -eq 0 ]; then echo -n "No kdump initial ramdisk found."; echo elif [ "$capture_capable_initrd" == "0" ]; then @@ -613,11 +669,6 @@ check_rebuild() return 0 fi - if [[ ! -w "$KDUMP_BOOTDIR" ]];then - echo "$KDUMP_BOOTDIR does not have write permission. Can not rebuild $TARGET_INITRD" - return 1 - fi - echo "Rebuilding $TARGET_INITRD" rebuild_initrd return $? @@ -631,11 +682,8 @@ load_kdump() KEXEC_ARGS=$(prepare_kexec_args "${KEXEC_ARGS}") KDUMP_COMMANDLINE=$(prepare_cmdline "${KDUMP_COMMANDLINE}" "${KDUMP_COMMANDLINE_REMOVE}" "${KDUMP_COMMANDLINE_APPEND}") - # For secureboot enabled machines, use new kexec file based syscall. - # Old syscall will always fail as it does not have capability to - # to kernel signature verification. - if is_secure_boot_enforced; then - echo "Secure Boot is enabled. Using kexec file based syscall." + if [ "$KDUMP_FILE_LOAD" == "on" ]; then + echo "Using kexec file based syscall." KEXEC_ARGS="$KEXEC_ARGS -s" fi @@ -647,6 +695,9 @@ load_kdump() return 0 else echo "kexec: failed to load kdump kernel" >&2 + if [ "$KDUMP_FILE_LOAD" == "on" ]; then + echo "kexec_file_load() failed, please try kexec_load()" >&2 + fi return 1 fi } @@ -657,7 +708,6 @@ check_ssh_config() case "$config_opt" in sshkey) # remove inline comments after the end of a directive. - config_val=$(strip_comments $config_val) if [ -f "$config_val" ]; then # canonicalize the path SSH_KEY_LOCATION=$(/usr/bin/readlink -m $config_val) @@ -666,17 +716,15 @@ check_ssh_config() fi ;; path) - config_val=$(strip_comments $config_val) SAVE_PATH=$config_val ;; ssh) - config_val=$(strip_comments $config_val) DUMP_TARGET=$config_val ;; *) ;; esac - done < $KDUMP_CONFIG_FILE + done <<< "$(read_strip_comments $KDUMP_CONFIG_FILE)" #make sure they've configured kdump.conf for ssh dumps local SSH_TARGET=`echo -n $DUMP_TARGET | sed -n '/.*@/p'` @@ -686,13 +734,60 @@ check_ssh_config() return 0 } +# ipv6 host address may takes a long time to be ready. +# Instead of checking against ipv6 address, we just check the network reachable +# by the return val of 'ssh' +check_and_wait_network_ready() +{ + local start_time=$(date +%s) + local warn_once=1 + local cur + local diff + local retval + local errmsg + + while true; do + errmsg=$(ssh -i $SSH_KEY_LOCATION -o BatchMode=yes $DUMP_TARGET mkdir -p $SAVE_PATH 2>&1) + retval=$? + + # ssh exits with the exit status of the remote command or with 255 if an error occurred + if [ $retval -eq 0 ]; then + return 0 + elif [ $retval -ne 255 ]; then + echo "Could not create $DUMP_TARGET:$SAVE_PATH, you should check the privilege on server side" >&2 + return 1 + fi + + # if server removes the authorized_keys or, no /root/.ssh/kdump_id_rsa + echo $errmsg | grep -q "Permission denied\|No such file or directory\|Host key verification failed" + if [ $? -eq 0 ]; then + echo "Could not create $DUMP_TARGET:$SAVE_PATH, you probably need to run \"kdumpctl propagate\"" >&2 + return 1 + fi + + if [ $warn_once -eq 1 ]; then + echo "Network dump target is not usable, waiting for it to be ready" + warn_once=0 + fi + echo -n . + + cur=$(date +%s) + let "diff = $cur - $start_time" + # 60s time out + if [ $diff -gt 180 ]; then + break; + fi + sleep 1 + done + + echo "Could not create $DUMP_TARGET:$SAVE_PATH, ipaddr is not ready yet. You should check network connection" >&2 + return 1 +} + check_ssh_target() { - local _ret - ssh -q -i $SSH_KEY_LOCATION -o BatchMode=yes $DUMP_TARGET mkdir -p $SAVE_PATH - _ret=$? - if [ $_ret -ne 0 ]; then - echo "Could not create $DUMP_TARGET:$SAVE_PATH, you probably need to run \"kdumpctl propagate\"" >&2 + check_and_wait_network_ready + if [ $? -ne 0 ]; then return 1 fi return 0 @@ -742,20 +837,6 @@ show_reserved_mem() echo "Reserved "$mem_mb"MB memory for crash kernel" } -handle_mode_switch() -{ - if [ "$DEFAULT_DUMP_MODE" == "fadump" ]; then - # backup initrd for reference before replacing it - # with fadump aware initrd - backup_default_initrd - else - # check if a backup of default initrd exists. If yes, - # it signifies a switch from fadump mode. So, restore - # the backed up default initrd. - restore_default_initrd - fi -} - check_current_fadump_status() { # Check if firmware-assisted dump has been registered. @@ -786,6 +867,11 @@ save_raw() echo "raw partition $raw_target not found" return 1 } + check_fs=$(lsblk --nodeps -npo FSTYPE $raw_target) + if [[ $(echo $check_fs | wc -w) -ne 0 ]]; then + echo "Warning: Detected '$check_fs' signature on $raw_target, data loss is expected." + return 0 + fi kdump_dir=`grep ^path $KDUMP_CONFIG_FILE | cut -d' ' -f2-` if [ -z "${kdump_dir}" ]; then coredir="/var/crash/`date +"%Y-%m-%d-%H:%M"`" @@ -810,15 +896,6 @@ save_raw() return 0 } -is_dump_target_configured() -{ - local _target - - _target=$(egrep "^ext[234]|^xfs|^btrfs|^minix|^raw|^ssh|^nfs" /etc/kdump.conf) - - [ -n "$_target" ] -} - local_fs_dump_target() { local _target @@ -833,7 +910,11 @@ path_to_be_relabeled() { local _path _target _mnt="/" _rmnt - if is_dump_target_configured; then + if is_user_configured_dump_target; then + if is_mount_in_dracut_args; then + return; + fi + _target=$(local_fs_dump_target) if [[ -n "$_target" ]]; then _mnt=$(findmnt -k -f -n -r -o TARGET $_target) @@ -845,9 +926,6 @@ path_to_be_relabeled() fi fi - if is_mount_in_dracut_args; then - return; - fi _path=$(get_save_path) # if $_path is masked by other mount, we will not relabel it. _rmnt=$(df $_mnt/$_path 2>/dev/null | tail -1 | awk '{ print $NF }') @@ -928,20 +1006,51 @@ start_dump() return $? } -check_default_config() +check_failure_action_config() { local default_option + local failure_action + local option="failure_action" default_option=$(awk '$1 ~ /^default$/ {print $2;}' $KDUMP_CONFIG_FILE) - if [ -z "$default_option" ]; then + failure_action=$(awk '$1 ~ /^failure_action$/ {print $2;}' $KDUMP_CONFIG_FILE) + + if [ -z "$failure_action" -a -z "$default_option" ]; then + return 0 + elif [ -n "$failure_action" -a -n "$default_option" ]; then + echo "Cannot specify 'failure_action' and 'default' option together" + return 1 + fi + + if [ -n "$default_option" ]; then + option="default" + failure_action="$default_option" + fi + + case "$failure_action" in + reboot|halt|poweroff|shell|dump_to_rootfs) + return 0 + ;; + *) + echo $"Usage kdump.conf: $option {reboot|halt|poweroff|shell|dump_to_rootfs}" + return 1 + esac +} + +check_final_action_config() +{ + local final_action + + final_action=$(awk '$1 ~ /^final_action$/ {print $2;}' $KDUMP_CONFIG_FILE) + if [ -z "$final_action" ]; then return 0 else - case "$default_option" in - reboot|halt|poweroff|shell|dump_to_rootfs) + case "$final_action" in + reboot|halt|poweroff) return 0 ;; *) - echo $"Usage kdump.conf: default {reboot|halt|poweroff|shell|dump_to_rootfs}" + echo $"Usage kdump.conf: final_action {reboot|halt|poweroff}" return 1 esac fi @@ -999,6 +1108,42 @@ start() echo "Starting kdump: [OK]" } +reload() +{ + check_current_status + if [ $? -ne 0 ]; then + echo "Kdump was not running: [WARNING]" + fi + + if [ $DEFAULT_DUMP_MODE == "fadump" ]; then + reload_fadump + return $? + else + stop_kdump + fi + + if [ $? -ne 0 ]; then + echo "Stopping kdump: [FAILED]" + return 1 + fi + + echo "Stopping kdump: [OK]" + + setup_initrd + if [ $? -ne 0 ]; then + echo "Starting kdump: [FAILED]" + return 1 + fi + + start_dump + if [ $? -ne 0 ]; then + echo "Starting kdump: [FAILED]" + return 1 + fi + + echo "Starting kdump: [OK]" +} + stop_fadump() { echo 0 > $FADUMP_REGISTER_SYS_NODE @@ -1013,7 +1158,7 @@ stop_fadump() stop_kdump() { - if is_secure_boot_enforced; then + if [ "$KDUMP_FILE_LOAD" == "on" ]; then $KEXEC -s -p -u else $KEXEC -p -u @@ -1028,6 +1173,26 @@ stop_kdump() return 0 } +reload_fadump() +{ + echo 1 > $FADUMP_REGISTER_SYS_NODE + if [ $? == 0 ]; then + echo "fadump: re-registered successfully" + return 0 + else + # FADump could fail on older kernel where re-register + # support is not enabled. Try stop/start from userspace + # to handle such scenario. + stop_fadump + if [ $? == 0 ]; then + start_fadump + return $? + fi + fi + + return 1 +} + stop() { if [ $DEFAULT_DUMP_MODE == "fadump" ]; then @@ -1045,6 +1210,28 @@ stop() return 0 } +rebuild() { + check_config + if [ $? -ne 0 ]; then + return 1 + fi + + if check_ssh_config; then + if ! check_ssh_target; then + return 1 + fi + fi + + setup_initrd + if [ $? -ne 0 ]; then + return 1 + fi + + echo "Rebuilding $TARGET_INITRD" + rebuild_initrd + return $? +} + if [ ! -f "$KDUMP_CONFIG_FILE" ]; then echo "Error: No kdump config file found!" >&2 exit 1 @@ -1082,10 +1269,16 @@ main () esac exit $EXIT_CODE ;; + reload) + reload + ;; restart) stop start ;; + rebuild) + rebuild + ;; condrestart) ;; propagate) @@ -1095,7 +1288,7 @@ main () show_reserved_mem ;; *) - echo $"Usage: $0 {start|stop|status|restart|propagate|showmem}" + echo $"Usage: $0 {start|stop|status|restart|reload|rebuild|propagate|showmem}" exit 1 esac } diff --git a/kdumpctl.8 b/kdumpctl.8 index 023562b9093a7adee0176d65f03999e7bfd7b025..ae97af7569b09a707b605581fafb10c8267677b7 100644 --- a/kdumpctl.8 +++ b/kdumpctl.8 @@ -32,6 +32,12 @@ It returns non-zero value if kdump is not operational. Is equal to .I start; stop .TP +.I reload +reload crash kernel image and initramfs without triggering a rebuild. +.TP +.I rebuild +rebuild the crash kernel initramfs. +.TP .I propagate Helps to setup key authentication for ssh storage since it's impossible to use password authentication during kdump. diff --git a/kexec-arm64-Add-support-for-handling-zlib-compressed-image.patch b/kexec-arm64-Add-support-for-handling-zlib-compressed-image.patch deleted file mode 100644 index 63220161b5c9de16c6aa9ee29ccac52807c782f6..0000000000000000000000000000000000000000 --- a/kexec-arm64-Add-support-for-handling-zlib-compressed-image.patch +++ /dev/null @@ -1,387 +0,0 @@ -From f4c1caaa97a2e019ccc00ab63e390c60d1c9454c Mon Sep 17 00:00:00 2001 -From: Bhupesh Sharma -Date: Mon, 15 Jul 2019 11:32:56 +0530 -Subject: [PATCH 18/20] kexec/arm64: Add support for handling zlib compressed - (Image.gz) image - -https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/commit/?id=f4c1caaa97a2e019ccc00ab63e390c60d1c9454c - -Currently the kexec_file_load() support for arm64 doesn't allow -handling zlib compressed (i.e. Image.gz) image. - -Since most distributions use 'make zinstall' rule inside -'arch/arm64/boot/Makefile' to install the arm64 -Image.gz compressed file inside the boot destination directory (for e.g. -/boot), currently we cannot use kexec_file_load() to load vmlinuz (or -Image.gz): - - # file /boot/vmlinuz - /boot/vmlinuz: gzip compressed data, was "Image", <..snip..>, max - compression, from Unix, original size 21945120 - - Now, since via kexec_file_load() we pass the 'fd' of Image.gz - (compressed file) via the following command line ... - - # kexec -s -l /boot/vmlinuz-`uname -r` --initrd=/boot/initramfs-`uname - -r`.img --reuse-cmdline - -... kernel returns -EINVAL error value, as it is not able to locate -the magic number =0x644d5241, which is expected in the 64-byte header -of the decompressed kernel image. - -We can fix this in user-space kexec-tools, which handles an -'Image.gz' being passed via kexec_file_load(), using an approach -as follows: - -a). Copy the contents of Image.gz to a temporary file. -b). Decompress (gunzip-decompress) the contents inside the - temporary file. -c). Pass the 'fd' of the temporary file to the kernel space. So - basically the kernel space still gets a decompressed kernel - image to load via kexec-tools - -I tested this patch for the following three use-cases: - -1. Uncompressed Image file: - #kexec -s -l Image --initrd=/boot/initramfs-`uname -r`.img --reuse-cmdline - -2. Signed Image file: - #kexec -s -l Image.signed --initrd=/boot/initramfs-`uname -r`.img --reuse-cmdline - -3. zlib compressed Image.gz file: - #kexec -s -l /boot/vmlinuz-`uname -r` --initrd=/boot/initramfs-`uname -r`.img --reuse-cmdline - -Signed-off-by: Bhupesh Sharma -Signed-off-by: Simon Horman ---- - kexec/arch/arm64/Makefile | 3 +- - kexec/arch/arm64/kexec-arm64.c | 1 + - kexec/arch/arm64/kexec-arm64.h | 7 ++ - kexec/arch/arm64/kexec-image-arm64.c | 4 +- - kexec/arch/arm64/kexec-zImage-arm64.c | 226 ++++++++++++++++++++++++++++++++++ - kexec/kexec.c | 12 ++ - 6 files changed, 250 insertions(+), 3 deletions(-) - create mode 100644 kexec/arch/arm64/kexec-zImage-arm64.c - -diff --git a/kexec/arch/arm64/Makefile b/kexec/arch/arm64/Makefile -index 9d9111c..d27c8ee 100644 ---- a/kexec/arch/arm64/Makefile -+++ b/kexec/arch/arm64/Makefile -@@ -15,7 +15,8 @@ arm64_KEXEC_SRCS += \ - kexec/arch/arm64/kexec-arm64.c \ - kexec/arch/arm64/kexec-elf-arm64.c \ - kexec/arch/arm64/kexec-uImage-arm64.c \ -- kexec/arch/arm64/kexec-image-arm64.c -+ kexec/arch/arm64/kexec-image-arm64.c \ -+ kexec/arch/arm64/kexec-zImage-arm64.c - - arm64_UIMAGE = kexec/kexec-uImage.c - -diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c -index 2992bce..eb3a3a3 100644 ---- a/kexec/arch/arm64/kexec-arm64.c -+++ b/kexec/arch/arm64/kexec-arm64.c -@@ -71,6 +71,7 @@ struct file_type file_type[] = { - {"vmlinux", elf_arm64_probe, elf_arm64_load, elf_arm64_usage}, - {"Image", image_arm64_probe, image_arm64_load, image_arm64_usage}, - {"uImage", uImage_arm64_probe, uImage_arm64_load, uImage_arm64_usage}, -+ {"zImage", zImage_arm64_probe, zImage_arm64_load, zImage_arm64_usage}, - }; - - int file_types = sizeof(file_type) / sizeof(file_type[0]); -diff --git a/kexec/arch/arm64/kexec-arm64.h b/kexec/arch/arm64/kexec-arm64.h -index cc3419f..628de79 100644 ---- a/kexec/arch/arm64/kexec-arm64.h -+++ b/kexec/arch/arm64/kexec-arm64.h -@@ -38,11 +38,18 @@ int image_arm64_probe(const char *kernel_buf, off_t kernel_size); - int image_arm64_load(int argc, char **argv, const char *kernel_buf, - off_t kernel_size, struct kexec_info *info); - void image_arm64_usage(void); -+ - int uImage_arm64_probe(const char *buf, off_t len); - int uImage_arm64_load(int argc, char **argv, const char *buf, off_t len, - struct kexec_info *info); - void uImage_arm64_usage(void); - -+int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size); -+int zImage_arm64_load(int argc, char **argv, const char *kernel_buf, -+ off_t kernel_size, struct kexec_info *info); -+void zImage_arm64_usage(void); -+ -+ - off_t initrd_base; - off_t initrd_size; - -diff --git a/kexec/arch/arm64/kexec-image-arm64.c b/kexec/arch/arm64/kexec-image-arm64.c -index 685a993..aa8f2e2 100644 ---- a/kexec/arch/arm64/kexec-image-arm64.c -+++ b/kexec/arch/arm64/kexec-image-arm64.c -@@ -114,6 +114,6 @@ exit: - void image_arm64_usage(void) - { - printf( --" An ARM64 binary image, compressed or not, big or little endian.\n" --" Typically an Image, Image.gz or Image.lzma file.\n\n"); -+" An ARM64 binary image, uncompressed, big or little endian.\n" -+" Typically an Image file.\n\n"); - } -diff --git a/kexec/arch/arm64/kexec-zImage-arm64.c b/kexec/arch/arm64/kexec-zImage-arm64.c -new file mode 100644 -index 0000000..6ee82ff ---- /dev/null -+++ b/kexec/arch/arm64/kexec-zImage-arm64.c -@@ -0,0 +1,226 @@ -+/* -+ * ARM64 kexec zImage (Image.gz) support. -+ * -+ * Several distros use 'make zinstall' rule inside -+ * 'arch/arm64/boot/Makefile' to install the arm64 -+ * Image.gz compressed file inside the boot destination -+ * directory (for e.g. /boot). -+ * -+ * Currently we cannot use kexec_file_load() to load vmlinuz -+ * (or Image.gz). -+ * -+ * To support Image.gz, we should: -+ * a). Copy the contents of Image.gz to a temporary file. -+ * b). Decompress (gunzip-decompress) the contents inside the -+ * temporary file. -+ * c). Pass the 'fd' of the temporary file to the kernel space. -+ * -+ * So basically the kernel space still gets a decompressed -+ * kernel image to load via kexec-tools. -+ */ -+ -+#define _GNU_SOURCE -+ -+#include -+#include -+#include -+#include -+#include "crashdump-arm64.h" -+#include "image-header.h" -+#include "kexec.h" -+#include "kexec-arm64.h" -+#include "kexec-syscall.h" -+#include "kexec-zlib.h" -+#include "arch/options.h" -+ -+#define FILENAME_IMAGE "/tmp/ImageXXXXXX" -+ -+/* Returns: -+ * -1 : in case of error/invalid format (not a valid Image.gz format. -+ * fd : File descriptor of the temp file containing the decompressed -+ * Image. -+ */ -+int zImage_arm64_probe(const char *kernel_buf, off_t kernel_size) -+{ -+ int ret = -1; -+ int fd = 0; -+ int kernel_fd = 0; -+ char *fname = NULL; -+ char *kernel_uncompressed_buf = NULL; -+ const struct arm64_image_header *h; -+ -+ if (!is_zlib_file(kernel_buf, &kernel_size)) { -+ dbgprintf("%s: Not an zImage file (Image.gz).\n", __func__); -+ return -1; -+ } -+ -+ if (!(fname = strdup(FILENAME_IMAGE))) { -+ dbgprintf("%s: Can't duplicate strings %s\n", __func__, -+ fname); -+ return -1; -+ } -+ -+ if ((fd = mkstemp(fname)) < 0) { -+ dbgprintf("%s: Can't open file %s\n", __func__, -+ fname); -+ ret = -1; -+ goto fail_mkstemp; -+ } -+ -+ kernel_uncompressed_buf = -+ (char *) calloc(kernel_size, sizeof(off_t)); -+ if (!kernel_uncompressed_buf) { -+ dbgprintf("%s: Can't calloc %ld bytes\n", -+ __func__, kernel_size); -+ ret= -ENOMEM; -+ goto fail_calloc; -+ } -+ -+ /* slurp in the input kernel */ -+ dbgprintf("%s: ", __func__); -+ kernel_uncompressed_buf = slurp_decompress_file(kernel_buf, -+ &kernel_size); -+ -+ /* check for correct header magic */ -+ if (kernel_size < sizeof(struct arm64_image_header)) { -+ dbgprintf("%s: No arm64 image header.\n", __func__); -+ ret = -1; -+ goto fail_bad_header; -+ } -+ -+ h = (const struct arm64_image_header *)(kernel_uncompressed_buf); -+ -+ if (!arm64_header_check_magic(h)) { -+ dbgprintf("%s: Bad arm64 image header.\n", __func__); -+ ret = -1; -+ goto fail_bad_header; -+ } -+ -+ if (write(fd, kernel_uncompressed_buf, -+ kernel_size) != kernel_size) { -+ dbgprintf("%s: Can't write the uncompressed file %s\n", -+ __func__, fname); -+ ret = -1; -+ goto fail_bad_header; -+ } -+ -+ close(fd); -+ -+ /* Open the tmp file again, this time in O_RDONLY mode, as -+ * opening the file in O_RDWR and calling kexec_file_load() -+ * causes the kernel to return -ETXTBSY -+ */ -+ kernel_fd = open(fname, O_RDONLY); -+ if (kernel_fd == -1) { -+ dbgprintf("%s: Failed to open file %s\n", -+ __func__, fname); -+ ret = -1; -+ goto fail_bad_header; -+ } -+ -+ unlink(fname); -+ -+ free(kernel_uncompressed_buf); -+ free(fname); -+ -+ return kernel_fd; -+ -+fail_bad_header: -+ free(kernel_uncompressed_buf); -+ -+fail_calloc: -+ if (fd >= 0) -+ close(fd); -+ -+ unlink(fname); -+ -+fail_mkstemp: -+ free(fname); -+ -+ return ret; -+} -+ -+int zImage_arm64_load(int argc, char **argv, const char *kernel_buf, -+ off_t kernel_size, struct kexec_info *info) -+{ -+ const struct arm64_image_header *header; -+ unsigned long kernel_segment; -+ int result; -+ -+ if (info->file_mode) { -+ if (arm64_opts.initrd) { -+ info->initrd_fd = open(arm64_opts.initrd, O_RDONLY); -+ if (info->initrd_fd == -1) { -+ fprintf(stderr, -+ "Could not open initrd file %s:%s\n", -+ arm64_opts.initrd, strerror(errno)); -+ result = EFAILED; -+ goto exit; -+ } -+ } -+ -+ if (arm64_opts.command_line) { -+ info->command_line = (char *)arm64_opts.command_line; -+ info->command_line_len = -+ strlen(arm64_opts.command_line) + 1; -+ } -+ -+ return 0; -+ } -+ -+ header = (const struct arm64_image_header *)(kernel_buf); -+ -+ if (arm64_process_image_header(header)) -+ return EFAILED; -+ -+ kernel_segment = arm64_locate_kernel_segment(info); -+ -+ if (kernel_segment == ULONG_MAX) { -+ dbgprintf("%s: Kernel segment is not allocated\n", __func__); -+ result = EFAILED; -+ goto exit; -+ } -+ -+ dbgprintf("%s: kernel_segment: %016lx\n", __func__, kernel_segment); -+ dbgprintf("%s: text_offset: %016lx\n", __func__, -+ arm64_mem.text_offset); -+ dbgprintf("%s: image_size: %016lx\n", __func__, -+ arm64_mem.image_size); -+ dbgprintf("%s: phys_offset: %016lx\n", __func__, -+ arm64_mem.phys_offset); -+ dbgprintf("%s: vp_offset: %016lx\n", __func__, -+ arm64_mem.vp_offset); -+ dbgprintf("%s: PE format: %s\n", __func__, -+ (arm64_header_check_pe_sig(header) ? "yes" : "no")); -+ -+ /* create and initialize elf core header segment */ -+ if (info->kexec_flags & KEXEC_ON_CRASH) { -+ result = load_crashdump_segments(info); -+ if (result) { -+ dbgprintf("%s: Creating eflcorehdr failed.\n", -+ __func__); -+ goto exit; -+ } -+ } -+ -+ /* load the kernel */ -+ add_segment_phys_virt(info, kernel_buf, kernel_size, -+ kernel_segment + arm64_mem.text_offset, -+ arm64_mem.image_size, 0); -+ -+ /* load additional data */ -+ result = arm64_load_other_segments(info, kernel_segment -+ + arm64_mem.text_offset); -+ -+exit: -+ if (result) -+ fprintf(stderr, "kexec: load failed.\n"); -+ return result; -+} -+ -+void zImage_arm64_usage(void) -+{ -+ printf( -+" An ARM64 zImage, compressed, big or little endian.\n" -+" Typically an Image.gz or Image.lzma file.\n\n"); -+} -diff --git a/kexec/kexec.c b/kexec/kexec.c -index 8ca3b45..bc6ab3d 100644 ---- a/kexec/kexec.c -+++ b/kexec/kexec.c -@@ -1206,8 +1206,20 @@ static int do_kexec_file_load(int fileind, int argc, char **argv, - kernel_buf = slurp_decompress_file(kernel, &kernel_size); - - for (i = 0; i < file_types; i++) { -+#ifdef __aarch64__ -+ /* handle Image.gz like cases */ -+ if (is_zlib_file(kernel, &kernel_size)) { -+ if ((ret = file_type[i].probe(kernel, kernel_size)) >= 0) { -+ kernel_fd = ret; -+ break; -+ } -+ } else -+ if (file_type[i].probe(kernel_buf, kernel_size) >= 0) -+ break; -+#else - if (file_type[i].probe(kernel_buf, kernel_size) >= 0) - break; -+#endif - } - - if (i == file_types) { --- -1.8.3.1 - diff --git a/kexec-dt-ops.c-Fix-adding-chosen-node-for-cases-wher.patch b/kexec-dt-ops.c-Fix-adding-chosen-node-for-cases-wher.patch deleted file mode 100644 index 76debc1b2f147693b8d074bda6d7763ee84cbad3..0000000000000000000000000000000000000000 --- a/kexec-dt-ops.c-Fix-adding-chosen-node-for-cases-wher.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 5570b42444661e212015abaca35b4dc698b9bb97 Mon Sep 17 00:00:00 2001 -From: Bhupesh Sharma -Date: Mon, 17 Dec 2018 00:46:54 +0530 -Subject: [PATCH 23/37] kexec/dt-ops.c: Fix adding '/chosen' node for cases - where it is not available in dtb passed via --dtb option - -While calling 'kexec -l', in case we are passed a .dtb using --dtb -option which doesn't contain a '/chosen' node, we try to create the -'/chosen' node and add bootargs to this node. - -Currently the 'dt-ops.c' code is buggy as it passes '-FDT_ERR_NOTFOUND' -to 'fdt_add_subnode()', which leads to the following error: - - # kexec -d --load Image --append 'debug' --dtb rk3399-sapphire.dtb - - <..snip..> - dtb_set_property: fdt_add_subnode failed: FDT_ERR_NOTFOUND - kexec: Set device tree bootargs failed. - get_cells_size: #address-cells:2 #size-cells:2 - cells_size_fitted: 0-0 - cells_size_fitted: 0-0 - setup_2nd_dtb: no kaslr-seed found - -This patch passes the correct nodeoffset value to 'fdt_add_subnode()', -which fixes this issue: - - # kexec -d -l Image --append 'debug' --dtb rk3399-sapphire.dtb - - <..snip..> - get_cells_size: #address-cells:2 #size-cells:2 - cells_size_fitted: 0-0 - cells_size_fitted: 0-0 - setup_2nd_dtb: no kaslr-seed found - -Reported-by: Vicente Bergas -Signed-off-by: Bhupesh Sharma -Signed-off-by: Simon Horman ---- - kexec/dt-ops.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/kexec/dt-ops.c b/kexec/dt-ops.c -index f15174c..bdc16dc 100644 ---- a/kexec/dt-ops.c -+++ b/kexec/dt-ops.c -@@ -80,15 +80,16 @@ int dtb_set_property(char **dtb, off_t *dtb_size, const char *node, - } - - nodeoffset = fdt_path_offset(new_dtb, node); -- -+ - if (nodeoffset == -FDT_ERR_NOTFOUND) { -- result = fdt_add_subnode(new_dtb, nodeoffset, node); -+ result = fdt_add_subnode(new_dtb, 0, node); - - if (result < 0) { - dbgprintf("%s: fdt_add_subnode failed: %s\n", __func__, - fdt_strerror(result)); - goto on_error; - } -+ nodeoffset = result; - } else if (nodeoffset < 0) { - dbgprintf("%s: fdt_path_offset failed: %s\n", __func__, - fdt_strerror(nodeoffset)); --- -2.6.4.windows.1 - diff --git a/kexec-dt-ops.c-Fix-check-against-fdt_add_subnode-ret.patch b/kexec-dt-ops.c-Fix-check-against-fdt_add_subnode-ret.patch deleted file mode 100644 index 49ba91ba0764896172c192667f35f21332adaf91..0000000000000000000000000000000000000000 --- a/kexec-dt-ops.c-Fix-check-against-fdt_add_subnode-ret.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 583dbd57f99747fa891ddd517930af9699c2e936 Mon Sep 17 00:00:00 2001 -From: Bhupesh Sharma -Date: Mon, 17 Dec 2018 00:46:52 +0530 -Subject: [PATCH 21/37] kexec/dt-ops.c: Fix check against 'fdt_add_subnode' - return value -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Vicenç reported (via [1]) that currently executing kexec with -'--dtb' option and passing a .dtb which doesn't have a '/chosen' node -leads to the following error: - - # kexec -d --dtb dtb_without_chosen_node.dtb --append 'cmdline' --load Image - - dtb_set_property: fdt_add_subnode failed: - kexec: Set device tree bootargs failed. - -This happens because currently we check the return value of -'fdt_add_subnode()' function call in 'dt-ops.c' incorrectly: - - result = fdt_add_subnode(new_dtb, nodeoffset, node); - if (result) { - dbgprintf("%s: fdt_add_subnode failed: %s\n", _func__, - fdt_strerror(result)); - goto on_error; - } - -As we can see in 'fdt_rw.c', a positive return value from -'fdt_add_subnode()' function doesn't indicate an error. - -We can see that the Linux kernel (see 'drivers/firmware/efi/libstub/fdt.c' -for example) also checks the 'fdt_add_subnode()' function against negative -return values for errors. See an example below from 'update_fdt()' function in -'drivers/firmware/efi/libstub/fdt.c': - - node = fdt_add_subnode(fdt, 0, "chosen"); - if (node < 0) { - status = node; - <..snip..> - goto fdt_set_fail; - } - -This patch fixes the same in 'kexec-tools'. - -[1]. http://lists.infradead.org/pipermail/kexec/2018-October/021746.html - -Cc: Simon Horman -Cc: AKASHI Takahiro -Reported-by: Vicente Bergas -Signed-off-by: Bhupesh Sharma -Signed-off-by: Simon Horman ---- - kexec/dt-ops.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/kexec/dt-ops.c b/kexec/dt-ops.c -index 915dbf5..f15174c 100644 ---- a/kexec/dt-ops.c -+++ b/kexec/dt-ops.c -@@ -84,7 +84,7 @@ int dtb_set_property(char **dtb, off_t *dtb_size, const char *node, - if (nodeoffset == -FDT_ERR_NOTFOUND) { - result = fdt_add_subnode(new_dtb, nodeoffset, node); - -- if (result) { -+ if (result < 0) { - dbgprintf("%s: fdt_add_subnode failed: %s\n", __func__, - fdt_strerror(result)); - goto on_error; --- -2.6.4.windows.1 - diff --git a/kexec-dt-ops.c-Fix-chosen-v-s-chosen-node-being-pass.patch b/kexec-dt-ops.c-Fix-chosen-v-s-chosen-node-being-pass.patch deleted file mode 100644 index cb3a656c4043768f91326fbaf6530ca7efd7b3c5..0000000000000000000000000000000000000000 --- a/kexec-dt-ops.c-Fix-chosen-v-s-chosen-node-being-pass.patch +++ /dev/null @@ -1,104 +0,0 @@ -From f56cbcf4c2766e5e7d18808b33f2b71519be5207 Mon Sep 17 00:00:00 2001 -From: Bhupesh Sharma -Date: Mon, 17 Dec 2018 00:46:55 +0530 -Subject: [PATCH 24/37] kexec/dt-ops.c: Fix '/chosen' v/s 'chosen' node being - passed to fdt helper functions - -This patch fixes the incorrect 'chosen' node name being passed to -various fdt helper functions inside 'kexec/dt-ops.c' - -As we can see from the Linux kernel usage inside -'drivers/firmware/efi/libstub/fdt.c', we pass '/chosen' node names to -fdt helper function like 'fdt_path_offset()' whereas 'chosen' to the -rest of the fdt helper functions like 'fdt_subnode_offset()'. - -We need to replicate the same in 'kexec-tools' to fix issues being -reported when we use --dtb option while invoking 'kexec'. - -Signed-off-by: Bhupesh Sharma -Signed-off-by: Simon Horman ---- - kexec/dt-ops.c | 31 +++++++++++++++++++++++++++---- - 1 file changed, 27 insertions(+), 4 deletions(-) - -diff --git a/kexec/dt-ops.c b/kexec/dt-ops.c -index bdc16dc..5626c47 100644 ---- a/kexec/dt-ops.c -+++ b/kexec/dt-ops.c -@@ -8,7 +8,7 @@ - #include "kexec.h" - #include "dt-ops.h" - --static const char n_chosen[] = "/chosen"; -+static const char n_chosen[] = "chosen"; - - static const char p_bootargs[] = "bootargs"; - static const char p_initrd_start[] = "linux,initrd-start"; -@@ -58,6 +58,7 @@ int dtb_set_property(char **dtb, off_t *dtb_size, const char *node, - int nodeoffset; - void *new_dtb; - int new_size; -+ char *new_node = NULL; - - value_len = FDT_TAGALIGN(value_len); - -@@ -79,7 +80,16 @@ int dtb_set_property(char **dtb, off_t *dtb_size, const char *node, - goto on_error; - } - -- nodeoffset = fdt_path_offset(new_dtb, node); -+ new_node = malloc(strlen("/") + strlen(node) + 1); -+ if (!new_node) { -+ dbgprintf("%s: malloc failed\n", __func__); -+ return -ENOMEM; -+ } -+ -+ strcpy(new_node, "/"); -+ strcat(new_node, node); -+ -+ nodeoffset = fdt_path_offset(new_dtb, new_node); - - if (nodeoffset == -FDT_ERR_NOTFOUND) { - result = fdt_add_subnode(new_dtb, 0, node); -@@ -122,17 +132,29 @@ int dtb_set_property(char **dtb, off_t *dtb_size, const char *node, - - on_error: - free(new_dtb); -+ free(new_node); - return result; - } - - int dtb_delete_property(char *dtb, const char *node, const char *prop) - { -- int result; -- int nodeoffset = fdt_path_offset(dtb, node); -+ int result, nodeoffset; -+ char *new_node = NULL; -+ -+ new_node = malloc(strlen("/") + strlen(node) + 1); -+ if (!new_node) { -+ dbgprintf("%s: malloc failed\n", __func__); -+ return -ENOMEM; -+ } -+ -+ strcpy(new_node, "/"); -+ strcat(new_node, node); - -+ nodeoffset = fdt_path_offset(dtb, new_node); - if (nodeoffset < 0) { - dbgprintf("%s: fdt_path_offset failed: %s\n", __func__, - fdt_strerror(nodeoffset)); -+ free(new_node); - return nodeoffset; - } - -@@ -142,5 +164,6 @@ int dtb_delete_property(char *dtb, const char *node, const char *prop) - dbgprintf("%s: fdt_delprop failed: %s\n", __func__, - fdt_strerror(nodeoffset)); - -+ free(new_node); - return result; - } --- -2.6.4.windows.1 - diff --git a/kexec-kexec-arm64.c-Add-error-handling-check-against.patch b/kexec-kexec-arm64.c-Add-error-handling-check-against.patch deleted file mode 100644 index 0a78aa0b116bddd6625d79aefa3e595425e0aa63..0000000000000000000000000000000000000000 --- a/kexec-kexec-arm64.c-Add-error-handling-check-against.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 9dcf363f509a1fa12a4d0d790a309a77c50aacaa Mon Sep 17 00:00:00 2001 -From: Bhupesh Sharma -Date: Mon, 17 Dec 2018 00:46:53 +0530 -Subject: [PATCH 22/37] kexec/kexec-arm64.c: Add error handling check against - return value of 'set_bootargs()' - -This patch adds missing error handling check against the return value of -'set_bootargs()' in 'kexec-arm64.c' - -Signed-off-by: Bhupesh Sharma -Signed-off-by: Simon Horman ---- - kexec/arch/arm64/kexec-arm64.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c -index 8200064..6551b0f 100644 ---- a/kexec/arch/arm64/kexec-arm64.c -+++ b/kexec/arch/arm64/kexec-arm64.c -@@ -406,6 +406,11 @@ static int setup_2nd_dtb(struct dtb *dtb, char *command_line, int on_crash) - } - - result = set_bootargs(dtb, command_line); -+ if (result) { -+ fprintf(stderr, "kexec: cannot set bootargs.\n"); -+ result = -EINVAL; -+ goto on_error; -+ } - - if (on_crash) { - /* determine #address-cells and #size-cells */ --- -2.6.4.windows.1 \ No newline at end of file diff --git a/kexec-kexec-zlib.h-Add-is_zlib_file-helper-function.patch b/kexec-kexec-zlib.h-Add-is_zlib_file-helper-function.patch deleted file mode 100644 index 42c9c252311a136bea33e2d827eda7e35dc37b0c..0000000000000000000000000000000000000000 --- a/kexec-kexec-zlib.h-Add-is_zlib_file-helper-function.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 0e709571bfe7e3b8160044970e2084194f9a963b Mon Sep 17 00:00:00 2001 -From: Bhupesh Sharma -Date: Mon, 15 Jul 2019 11:32:55 +0530 -Subject: [PATCH 17/20] kexec/kexec-zlib.h: Add 'is_zlib_file()' helper - function - -https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/commit/?id=0e709571bfe7e3b8160044970e2084194f9a963b - -This patch adds 'is_zlib_file()' helper function which can be -used to quickly determine with the passed kernel image is a zlib -compressed kernel image. - -This is specifically useful for arm64 zImage (or Image.gz) support, -which is introduced by later patches in this patchset. - -Signed-off-by: Bhupesh Sharma -Signed-off-by: Simon Horman ---- - kexec/kexec-zlib.h | 1 + - kexec/zlib.c | 38 ++++++++++++++++++++++++++++++++++++++ - 2 files changed, 39 insertions(+) - -diff --git a/kexec/kexec-zlib.h b/kexec/kexec-zlib.h -index 43c107b..16300f2 100644 ---- a/kexec/kexec-zlib.h -+++ b/kexec/kexec-zlib.h -@@ -6,5 +6,6 @@ - - #include "config.h" - -+int is_zlib_file(const char *filename, off_t *r_size); - char *zlib_decompress_file(const char *filename, off_t *r_size); - #endif /* __KEXEC_ZLIB_H */ -diff --git a/kexec/zlib.c b/kexec/zlib.c -index 95b6080..9bc340d 100644 ---- a/kexec/zlib.c -+++ b/kexec/zlib.c -@@ -23,6 +23,38 @@ static void _gzerror(gzFile fp, int *errnum, const char **errmsg) - } - } - -+int is_zlib_file(const char *filename, off_t *r_size) -+{ -+ gzFile fp; -+ int errnum; -+ int is_zlib_file = 0; /* default: It's not in gzip format */ -+ const char *msg; -+ ssize_t result; -+ -+ if (!filename) -+ goto out; -+ -+ fp = gzopen(filename, "rb"); -+ if (fp == 0) { -+ _gzerror(fp, &errnum, &msg); -+ dbgprintf("Cannot open `%s': %s\n", filename, msg); -+ goto out; -+ } -+ -+ if (!gzdirect(fp)) -+ /* It's in gzip format */ -+ is_zlib_file = 1; -+ -+ result = gzclose(fp); -+ if (result != Z_OK) { -+ _gzerror(fp, &errnum, &msg); -+ dbgprintf(" Close of %s failed: %s\n", filename, msg); -+ } -+ -+out: -+ return is_zlib_file; -+} -+ - char *zlib_decompress_file(const char *filename, off_t *r_size) - { - gzFile fp; -@@ -84,6 +116,12 @@ fail: - return buf; - } - #else -+ -+int is_zlib_file(const char *filename, off_t *r_size) -+{ -+ return 0; -+} -+ - char *zlib_decompress_file(const char *UNUSED(filename), off_t *UNUSED(r_size)) - { - return NULL; --- -1.8.3.1 - diff --git a/kexec-kexec.c-Add-the-missing-close-for-fd-used-for-kexec_file_load.patch b/kexec-kexec.c-Add-the-missing-close-for-fd-used-for-kexec_file_load.patch deleted file mode 100644 index 9230a96dd3bbf7f53907efe19740becdc702b7da..0000000000000000000000000000000000000000 --- a/kexec-kexec.c-Add-the-missing-close-for-fd-used-for-kexec_file_load.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 019d8258f15c2a716786880c3cbd0f327a4dfc09 Mon Sep 17 00:00:00 2001 -From: Bhupesh Sharma -Date: Mon, 15 Jul 2019 11:32:53 +0530 -Subject: [PATCH 15/20] kexec/kexec.c: Add the missing close() for fd used for - kexec_file_load() - -https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/commit/?id=019d8258f15c2a716786880c3cbd0f327a4dfc09 - -In kexec/kexec.c, we open() the kernel Image file and pass this file -descriptor to the kexec_file_load() system call, but never call a -corresponding close(). - -Fix the same via this patch. - -Signed-off-by: Bhupesh Sharma -Signed-off-by: Simon Horman ---- - kexec/kexec.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/kexec/kexec.c b/kexec/kexec.c -index 32ae56c..8ca3b45 100644 ---- a/kexec/kexec.c -+++ b/kexec/kexec.c -@@ -1234,6 +1234,8 @@ static int do_kexec_file_load(int fileind, int argc, char **argv, - if (ret != 0) - fprintf(stderr, "kexec_file_load failed: %s\n", - strerror(errno)); -+ -+ close(kernel_fd); - return ret; - } - --- -1.8.3.1 - diff --git a/kexec-tools-2.0.17-kexec-fix-for-Unhandled-rela-relocation-R_X86_64_PLT.patch b/kexec-tools-2.0.17-kexec-fix-for-Unhandled-rela-relocation-R_X86_64_PLT.patch deleted file mode 100644 index ace1ea935a0ec543d7be11fa31b1bdb02ae83fa8..0000000000000000000000000000000000000000 --- a/kexec-tools-2.0.17-kexec-fix-for-Unhandled-rela-relocation-R_X86_64_PLT.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 35a2fb50293da9fbd94f29a2ed6a4f114fd8044f Mon Sep 17 00:00:00 2001 -From: Bhupesh Sharma -Date: Tue, 21 Aug 2018 16:22:31 +0530 -Subject: [PATCH] kexec: fix for "Unhandled rela relocation: R_X86_64_PLT32" - error - -In response to a change in binutils, commit b21ebf2fb4c -(x86: Treat R_X86_64_PLT32 as R_X86_64_PC32) was applied to -the linux kernel during the 4.16 development cycle and has -since been backported to earlier stable kernel series. The -change results in the failure message in $SUBJECT when -rebooting via kexec. - -Fix this by replicating the change in kexec. - -Signed-off-by: Chris Clayton ---- - kexec/arch/x86_64/kexec-elf-rel-x86_64.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/kexec/arch/x86_64/kexec-elf-rel-x86_64.c b/kexec/arch/x86_64/kexec-elf-rel-x86_64.c -index 7fdde73a5eca..af33689a7d43 100644 ---- a/kexec/arch/x86_64/kexec-elf-rel-x86_64.c -+++ b/kexec/arch/x86_64/kexec-elf-rel-x86_64.c -@@ -78,7 +78,8 @@ void machine_apply_elf_rel(struct mem_ehdr *UNUSED(ehdr), - if ((int64_t)value != *(int32_t *)location) - goto overflow; - break; -- case R_X86_64_PC32: -+ case R_X86_64_PC32: -+ case R_X86_64_PLT32: - *(uint32_t *)location = value - address; - break; - default: --- -2.7.4 - diff --git a/kexec-tools-2.0.17.tar.xz b/kexec-tools-2.0.17.tar.xz deleted file mode 100644 index 569d7d8acbd2d71f008d406646dac46add09fa42..0000000000000000000000000000000000000000 Binary files a/kexec-tools-2.0.17.tar.xz and /dev/null differ diff --git a/kexec-tools-2.0.20-Remove-duplicated-variable-declarations.patch b/kexec-tools-2.0.20-Remove-duplicated-variable-declarations.patch new file mode 100644 index 0000000000000000000000000000000000000000..966f007db11cd379e6dba966aebbe88c1401e414 --- /dev/null +++ b/kexec-tools-2.0.20-Remove-duplicated-variable-declarations.patch @@ -0,0 +1,98 @@ +From 23daba8bb97ff4291447e54859ed759cfe07975e Mon Sep 17 00:00:00 2001 +From: Kairui Song +Date: Wed, 29 Jan 2020 10:48:27 +0800 +Subject: [PATCH] kexec-tools: Remove duplicated variable declarations + +When building kexec-tools for Fedora 32, following error is observed: + +/usr/bin/ld: kexec/arch/x86_64/kexec-bzImage64.o:(.bss+0x0): multiple definition of `bzImage_support_efi_boot'; +kexec/arch/i386/kexec-bzImage.o:(.bss+0x0): first defined here + +/builddir/build/BUILD/kexec-tools-2.0.20/kexec/arch/arm/../../fs2dt.h:33: multiple definition of `my_debug'; +kexec/fs2dt.o:/builddir/build/BUILD/kexec-tools-2.0.20/kexec/fs2dt.h:33: first defined here + +/builddir/build/BUILD/kexec-tools-2.0.20/kexec/arch/arm64/kexec-arm64.h:68: multiple definition of `arm64_mem'; +kexec/fs2dt.o:/builddir/build/BUILD/kexec-tools-2.0.20/././kexec/arch/arm64/kexec-arm64.h:68: first defined here + +/builddir/build/BUILD/kexec-tools-2.0.20/kexec/arch/arm64/kexec-arm64.h:54: multiple definition of `initrd_size'; +kexec/fs2dt.o:/builddir/build/BUILD/kexec-tools-2.0.20/././kexec/arch/arm64/kexec-arm64.h:54: first defined here + +/builddir/build/BUILD/kexec-tools-2.0.20/kexec/arch/arm64/kexec-arm64.h:53: multiple definition of `initrd_base'; +kexec/fs2dt.o:/builddir/build/BUILD/kexec-tools-2.0.20/././kexec/arch/arm64/kexec-arm64.h:53: first defined here + +And apparently, these variables are wrongly declared multiple times. So +remove duplicated declaration. + +Signed-off-by: Kairui Song +--- + kexec/arch/arm64/kexec-arm64.h | 6 +++--- + kexec/arch/ppc64/kexec-elf-ppc64.c | 2 -- + kexec/arch/x86_64/kexec-bzImage64.c | 1 - + kexec/fs2dt.h | 2 +- + 4 files changed, 4 insertions(+), 7 deletions(-) + +diff --git a/kexec/arch/arm64/kexec-arm64.h b/kexec/arch/arm64/kexec-arm64.h +index 628de79..ed447ac 100644 +--- a/kexec/arch/arm64/kexec-arm64.h ++++ b/kexec/arch/arm64/kexec-arm64.h +@@ -50,8 +50,8 @@ int zImage_arm64_load(int argc, char **argv, const char *kernel_buf, + void zImage_arm64_usage(void); + + +-off_t initrd_base; +-off_t initrd_size; ++extern off_t initrd_base; ++extern off_t initrd_size; + + /** + * struct arm64_mem - Memory layout info. +@@ -65,7 +65,7 @@ struct arm64_mem { + }; + + #define arm64_mem_ngv UINT64_MAX +-struct arm64_mem arm64_mem; ++extern struct arm64_mem arm64_mem; + + uint64_t get_phys_offset(void); + uint64_t get_vp_offset(void); +diff --git a/kexec/arch/ppc64/kexec-elf-ppc64.c b/kexec/arch/ppc64/kexec-elf-ppc64.c +index 3510b70..695b8b0 100644 +--- a/kexec/arch/ppc64/kexec-elf-ppc64.c ++++ b/kexec/arch/ppc64/kexec-elf-ppc64.c +@@ -44,8 +44,6 @@ + uint64_t initrd_base, initrd_size; + unsigned char reuse_initrd = 0; + const char *ramdisk; +-/* Used for enabling printing message from purgatory code */ +-int my_debug = 0; + + int elf_ppc64_probe(const char *buf, off_t len) + { +diff --git a/kexec/arch/x86_64/kexec-bzImage64.c b/kexec/arch/x86_64/kexec-bzImage64.c +index 8edb3e4..ba8dc48 100644 +--- a/kexec/arch/x86_64/kexec-bzImage64.c ++++ b/kexec/arch/x86_64/kexec-bzImage64.c +@@ -42,7 +42,6 @@ + #include + + static const int probe_debug = 0; +-int bzImage_support_efi_boot; + + int bzImage64_probe(const char *buf, off_t len) + { +diff --git a/kexec/fs2dt.h b/kexec/fs2dt.h +index 7633273..fe24931 100644 +--- a/kexec/fs2dt.h ++++ b/kexec/fs2dt.h +@@ -30,7 +30,7 @@ extern struct bootblock bb[1]; + + /* Used for enabling printing message from purgatory code + * Only has implemented for PPC64 */ +-int my_debug; ++extern int my_debug; + extern int dt_no_old_root; + + void reserve(unsigned long long where, unsigned long long length); +-- +2.24.1 + diff --git a/kexec-tools-2.0.20-eppic-Remove-duplicated-variable-declaration.patch b/kexec-tools-2.0.20-eppic-Remove-duplicated-variable-declaration.patch new file mode 100644 index 0000000000000000000000000000000000000000..8d77b9bfda301f27517baa5aa4ed6941cab2935c --- /dev/null +++ b/kexec-tools-2.0.20-eppic-Remove-duplicated-variable-declaration.patch @@ -0,0 +1,36 @@ +From 2837fb1f5f8362976c188b30ebe50dc8b0377f64 Mon Sep 17 00:00:00 2001 +From: Kairui Song +Date: Wed, 29 Jan 2020 11:33:18 +0800 +Subject: [PATCH] Remove duplicated variable declaration + +When building on Fedora 32, following error is observed: + +... +/usr/bin/ld: ../eppic/libeppic/libeppic.a(eppic_stat.o):/builddir/build/BUILD/kexec-tools-2.0.20/eppic/libeppic/eppic.h:474: multiple definition of `lastv'; +../eppic/libeppic/libeppic.a(eppic_func.o):/builddir/build/BUILD/kexec-tools-2.0.20/eppic/libeppic/eppic.h:474: first defined here +... + +And apparently, the variable is wrongly declared multiple times. So +remove duplicated declaration. + +Signed-off-by: Kairui Song +--- + libeppic/eppic.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/libeppic/eppic.h b/libeppic/eppic.h +index 5664583..836b475 100644 +--- a/eppic-d84c3541035d95077aa8571f5d5c3e07c6ef510b/libeppic/eppic.h ++++ b/eppic-d84c3541035d95077aa8571f5d5c3e07c6ef510b/libeppic/eppic.h +@@ -471,7 +471,7 @@ type_t *eppic_addstorage(type_t *t1, type_t *t2); + type_t *eppic_getvoidstruct(int ctype); + + extern int lineno, needvar, instruct, nomacs, eppic_legacy; +-node_t *lastv; ++extern node_t *lastv; + + #define NULLNODE ((node_t*)0) + +-- +2.24.1 + diff --git a/kexec-tools-2.0.20-fix-broken-multiboot2-buliding-for-i386.patch b/kexec-tools-2.0.20-fix-broken-multiboot2-buliding-for-i386.patch new file mode 100644 index 0000000000000000000000000000000000000000..3f0fb33dc53484ec60a0cca69d5f50fbd8ecf46a --- /dev/null +++ b/kexec-tools-2.0.20-fix-broken-multiboot2-buliding-for-i386.patch @@ -0,0 +1,88 @@ +From 940c3a1e1a304fbecc850c593a272215b0f52eab Mon Sep 17 00:00:00 2001 +From: Kairui Song +Date: Wed, 31 Jul 2019 16:30:47 +0800 +Subject: [PATCH] x86: Fix broken multiboot2 buliding for i386 + +When building for i386, an error occured: + +kexec/arch/i386/kexec-x86.c:39:22: error: 'multiboot2_x86_probe' +undeclared here (not in a function); did you mean 'multiboot_x86_probe'? +39 | { "multiboot2-x86", multiboot2_x86_probe, multiboot2_x86_load, + | ^~~~~~~~~~~~~~~~~~~~ + | multiboot_x86_probe + +kexec/arch/i386/kexec-x86.c:39:44: error: 'multiboot2_x86_load' +undeclared here (not in a function); did you mean 'multiboot_x86_load'? +39 | { "multiboot2-x86", multiboot2_x86_probe, multiboot2_x86_load, + | ^~~~~~~~~~~~~~~~~~~ + | multiboot_x86_load +kexec/arch/i386/kexec-x86.c:40:4: error: 'multiboot2_x86_usage' + undeclared here (not in a function); did you mean 'multiboot_x86_usage'? +40 | multiboot2_x86_usage }, + | ^~~~~~~~~~~~~~~~~~~~ + | multiboot_x86_usage + +Fix this issue by putting the definition in the right header, also tidy +up Makefile. + +Fixes: 22a2ed55132e ("x86: Support multiboot2 images") +Signed-off-by: Kairui Song +--- + kexec/arch/i386/Makefile | 2 +- + kexec/arch/i386/kexec-x86.h | 5 +++++ + kexec/arch/x86_64/kexec-x86_64.h | 5 ----- + 3 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/kexec/arch/i386/Makefile b/kexec/arch/i386/Makefile +index 105cefd..f486103 100644 +--- a/kexec/arch/i386/Makefile ++++ b/kexec/arch/i386/Makefile +@@ -7,6 +7,7 @@ i386_KEXEC_SRCS += kexec/arch/i386/kexec-elf-x86.c + i386_KEXEC_SRCS += kexec/arch/i386/kexec-elf-rel-x86.c + i386_KEXEC_SRCS += kexec/arch/i386/kexec-bzImage.c + i386_KEXEC_SRCS += kexec/arch/i386/kexec-multiboot-x86.c ++i386_KEXEC_SRCS += kexec/arch/i386/kexec-mb2-x86.c + i386_KEXEC_SRCS += kexec/arch/i386/kexec-beoboot-x86.c + i386_KEXEC_SRCS += kexec/arch/i386/kexec-nbi.c + i386_KEXEC_SRCS += kexec/arch/i386/x86-linux-setup.c +@@ -14,7 +15,6 @@ i386_KEXEC_SRCS += kexec/arch/i386/crashdump-x86.c + + dist += kexec/arch/i386/Makefile $(i386_KEXEC_SRCS) \ + kexec/arch/i386/crashdump-x86.h \ +- kexec/arch/i386/kexec-mb2-x86.c \ + kexec/arch/i386/kexec-x86.h \ + kexec/arch/i386/x86-linux-setup.h \ + kexec/arch/i386/include/arch/options.h +diff --git a/kexec/arch/i386/kexec-x86.h b/kexec/arch/i386/kexec-x86.h +index 1b58c3b..16d0f6c 100644 +--- a/kexec/arch/i386/kexec-x86.h ++++ b/kexec/arch/i386/kexec-x86.h +@@ -60,6 +60,11 @@ int multiboot_x86_load(int argc, char **argv, const char *buf, off_t len, + struct kexec_info *info); + void multiboot_x86_usage(void); + ++int multiboot2_x86_load(int argc, char **argv, const char *buf, off_t len, ++ struct kexec_info *info); ++void multiboot2_x86_usage(void); ++int multiboot2_x86_probe(const char *buf, off_t buf_len); ++ + int elf_x86_probe(const char *buf, off_t len); + int elf_x86_load(int argc, char **argv, const char *buf, off_t len, + struct kexec_info *info); +diff --git a/kexec/arch/x86_64/kexec-x86_64.h b/kexec/arch/x86_64/kexec-x86_64.h +index 21c3a73..4cdeffb 100644 +--- a/kexec/arch/x86_64/kexec-x86_64.h ++++ b/kexec/arch/x86_64/kexec-x86_64.h +@@ -33,9 +33,4 @@ int bzImage64_load(int argc, char **argv, const char *buf, off_t len, + struct kexec_info *info); + void bzImage64_usage(void); + +-int multiboot2_x86_load(int argc, char **argv, const char *buf, off_t len, +- struct kexec_info *info); +-void multiboot2_x86_usage(void); +-int multiboot2_x86_probe(const char *buf, off_t buf_len); +- + #endif /* KEXEC_X86_64_H */ +-- +2.21.0 + diff --git a/kexec-tools-2.0.20-makedumpfile-Introduce-check-params-option.patch b/kexec-tools-2.0.20-makedumpfile-Introduce-check-params-option.patch new file mode 100644 index 0000000000000000000000000000000000000000..5314ad9a090378834d19a7038c4a7283ffead34e --- /dev/null +++ b/kexec-tools-2.0.20-makedumpfile-Introduce-check-params-option.patch @@ -0,0 +1,255 @@ +From 989152e113bfcb4fbfbad6f3aed6f43be4455919 Mon Sep 17 00:00:00 2001 +From: Kazuhito Hagio +Date: Tue, 25 Feb 2020 16:04:55 -0500 +Subject: [PATCH] Introduce --check-params option + +Currently it's difficult to check whether a makedumpfile command-line +is valid or not without an actual panic. This is inefficient and if +a wrong configuration is not tested, you will miss the vmcore when an +actual panic occurs. + +In order for kdump facilities like kexec-tools to be able to check +the specified command-line parameters in advance, introduce the +--check-params option that only checks them and exits immediately. + +Signed-off-by: Kazuhito Hagio +--- + makedumpfile.8 | 5 ++++ + makedumpfile.c | 75 ++++++++++++++++++++++++++++++++++++++------------ + print_info.c | 4 +++ + 4 files changed, 69 insertions(+), 17 deletions(-) + +diff --git a/makedumpfile-1.6.7/makedumpfile.8 b/makedumpfile-1.6.7/makedumpfile.8 +index bf156a8..c5d4806 100644 +--- a/makedumpfile-1.6.7/makedumpfile.8 ++++ b/makedumpfile-1.6.7/makedumpfile.8 +@@ -632,6 +632,11 @@ Show help message and LZO/snappy support status (enabled/disabled). + \fB\-v\fR + Show the version of makedumpfile. + ++.TP ++\fB\-\-check-params\fR ++Only check whether the command-line parameters are valid or not, and exit. ++Preferable to be given as the first parameter. ++ + .SH ENVIRONMENT VARIABLES + + .TP 8 +diff --git a/makedumpfile-1.6.7/makedumpfile.c b/makedumpfile-1.6.7/makedumpfile.c +index 607e07f..f5860a1 100644 +--- a/makedumpfile-1.6.7/makedumpfile.c ++++ b/makedumpfile-1.6.7/makedumpfile.c +@@ -10978,12 +10978,6 @@ check_param_for_creating_dumpfile(int argc, char *argv[]) + if (info->flag_generate_vmcoreinfo || info->flag_rearrange) + return FALSE; + +- if ((message_level < MIN_MSG_LEVEL) +- || (MAX_MSG_LEVEL < message_level)) { +- message_level = DEFAULT_MSG_LEVEL; +- MSG("Message_level is invalid.\n"); +- return FALSE; +- } + if ((info->flag_compress && info->flag_elf_dumpfile) + || (info->flag_read_vmcoreinfo && info->name_vmlinux) + || (info->flag_read_vmcoreinfo && info->name_xen_syms)) +@@ -11013,6 +11007,11 @@ check_param_for_creating_dumpfile(int argc, char *argv[]) + if (info->flag_partial_dmesg && !info->flag_dmesg) + return FALSE; + ++ if (info->flag_excludevm && !info->working_dir) { ++ MSG("-%c requires --work-dir\n", OPT_EXCLUDE_UNUSED_VM); ++ return FALSE; ++ } ++ + if ((argc == optind + 2) && !info->flag_flatten + && !info->flag_split + && !info->flag_sadump_diskset) { +@@ -11408,6 +11407,23 @@ int show_mem_usage(void) + return TRUE; + } + ++static int set_message_level(char *str_ml) ++{ ++ int ml; ++ ++ ml = atoi(str_ml); ++ if ((ml < MIN_MSG_LEVEL) || (MAX_MSG_LEVEL < ml)) { ++ message_level = DEFAULT_MSG_LEVEL; ++ MSG("Message_level(%d) is invalid.\n", ml); ++ return FALSE; ++ } ++ ++ if (info->flag_check_params) ++ return TRUE; ++ ++ message_level = ml; ++ return TRUE; ++} + + static struct option longopts[] = { + {"split", no_argument, NULL, OPT_SPLIT}, +@@ -11429,6 +11445,7 @@ static struct option longopts[] = { + {"splitblock-size", required_argument, NULL, OPT_SPLITBLOCK_SIZE}, + {"work-dir", required_argument, NULL, OPT_WORKING_DIR}, + {"num-threads", required_argument, NULL, OPT_NUM_THREADS}, ++ {"check-params", no_argument, NULL, OPT_CHECK_PARAMS}, + {0, 0, 0, 0} + }; + +@@ -11527,7 +11544,8 @@ main(int argc, char *argv[]) + info->flag_compress = DUMP_DH_COMPRESSED_LZO; + break; + case OPT_MESSAGE_LEVEL: +- message_level = atoi(optarg); ++ if (!set_message_level(optarg)) ++ goto out; + break; + case OPT_DUMP_DMESG: + info->flag_dmesg = 1; +@@ -11590,6 +11608,10 @@ main(int argc, char *argv[]) + case OPT_NUM_THREADS: + info->num_threads = MAX(atoi(optarg), 0); + break; ++ case OPT_CHECK_PARAMS: ++ info->flag_check_params = TRUE; ++ message_level = DEFAULT_MSG_LEVEL; ++ break; + case '?': + MSG("Commandline parameter is invalid.\n"); + MSG("Try `makedumpfile --help' for more information.\n"); +@@ -11599,11 +11621,9 @@ main(int argc, char *argv[]) + if (flag_debug) + message_level |= ML_PRINT_DEBUG_MSG; + +- if (info->flag_excludevm && !info->working_dir) { +- ERRMSG("Error: -%c requires --work-dir\n", OPT_EXCLUDE_UNUSED_VM); +- ERRMSG("Try `makedumpfile --help' for more information\n"); +- return COMPLETED; +- } ++ if (info->flag_check_params) ++ /* suppress debugging messages */ ++ message_level = DEFAULT_MSG_LEVEL; + + if (info->flag_show_usage) { + print_usage(); +@@ -11634,6 +11654,9 @@ main(int argc, char *argv[]) + MSG("Try `makedumpfile --help' for more information.\n"); + goto out; + } ++ if (info->flag_check_params) ++ goto check_ok; ++ + if (!open_files_for_generating_vmcoreinfo()) + goto out; + +@@ -11657,6 +11680,9 @@ main(int argc, char *argv[]) + MSG("Try `makedumpfile --help' for more information.\n"); + goto out; + } ++ if (info->flag_check_params) ++ goto check_ok; ++ + if (!check_dump_file(info->name_dumpfile)) + goto out; + +@@ -11677,6 +11703,9 @@ main(int argc, char *argv[]) + MSG("Try `makedumpfile --help' for more information.\n"); + goto out; + } ++ if (info->flag_check_params) ++ goto check_ok; ++ + if (!check_dump_file(info->name_dumpfile)) + goto out; + +@@ -11690,6 +11719,9 @@ main(int argc, char *argv[]) + MSG("Try `makedumpfile --help' for more information.\n"); + goto out; + } ++ if (info->flag_check_params) ++ goto check_ok; ++ + if (!check_dump_file(info->name_dumpfile)) + goto out; + if (!dump_dmesg()) +@@ -11703,6 +11735,9 @@ main(int argc, char *argv[]) + MSG("Try `makedumpfile --help' for more information.\n"); + goto out; + } ++ if (info->flag_check_params) ++ goto check_ok; ++ + if (!populate_kernel_version()) + goto out; + +@@ -11721,6 +11756,9 @@ main(int argc, char *argv[]) + MSG("Try `makedumpfile --help' for more information.\n"); + goto out; + } ++ if (info->flag_check_params) ++ goto check_ok; ++ + if (info->flag_split) { + for (i = 0; i < info->num_dumpfile; i++) { + SPLITTING_FD_BITMAP(i) = -1; +@@ -11748,13 +11786,16 @@ main(int argc, char *argv[]) + MSG("The dumpfile is saved to %s.\n", info->name_dumpfile); + } + } ++check_ok: + retcd = COMPLETED; + out: +- MSG("\n"); +- if (retcd != COMPLETED) +- MSG("makedumpfile Failed.\n"); +- else if (!info->flag_mem_usage) +- MSG("makedumpfile Completed.\n"); ++ if (!info->flag_check_params) { ++ MSG("\n"); ++ if (retcd != COMPLETED) ++ MSG("makedumpfile Failed.\n"); ++ else if (!info->flag_mem_usage) ++ MSG("makedumpfile Completed.\n"); ++ } + + free_for_parallel(); + +diff --git a/makedumpfile-1.6.7/makedumpfile.h b/makedumpfile-1.6.7/makedumpfile.h +index 7217407..03fb4ce 100644 +--- a/makedumpfile-1.6.7/makedumpfile.h ++++ b/makedumpfile-1.6.7/makedumpfile.h +@@ -1303,6 +1303,7 @@ struct DumpInfo { + int flag_read_vmcoreinfo; /* flag of reading vmcoreinfo file */ + int flag_show_usage; /* flag of showing usage */ + int flag_show_version; /* flag of showing version */ ++ int flag_check_params; /* only check parameters */ + int flag_flatten; /* flag of outputting flattened + format to a standard out */ + int flag_rearrange; /* flag of creating dumpfile from +@@ -2364,6 +2365,7 @@ struct elf_prstatus { + #define OPT_WORKING_DIR OPT_START+15 + #define OPT_NUM_THREADS OPT_START+16 + #define OPT_PARTIAL_DMESG OPT_START+17 ++#define OPT_CHECK_PARAMS OPT_START+18 + + /* + * Function Prototype. +diff --git a/makedumpfile-1.6.7/print_info.c b/makedumpfile-1.6.7/print_info.c +index 0be12ea..e0c38b4 100644 +--- a/makedumpfile-1.6.7/print_info.c ++++ b/makedumpfile-1.6.7/print_info.c +@@ -321,6 +321,10 @@ print_usage(void) + MSG(" [-v]:\n"); + MSG(" Show the version of makedumpfile.\n"); + MSG("\n"); ++ MSG(" [--check-params]:\n"); ++ MSG(" Only check whether the command-line parameters are valid or not, and exit.\n"); ++ MSG(" Preferable to be given as the first parameter.\n"); ++ MSG("\n"); + MSG(" VMLINUX:\n"); + MSG(" This is a pathname to the first kernel's vmlinux.\n"); + MSG(" This file must have the debug information of the first kernel to analyze\n"); +-- +2.24.1 + + diff --git a/kexec-tools-2.0.20-makedumpfile-Remove-duplicated-variable-declarations.patch b/kexec-tools-2.0.20-makedumpfile-Remove-duplicated-variable-declarations.patch new file mode 100644 index 0000000000000000000000000000000000000000..f240e8c72b0b0dbb7da9d4e8d4c991380852a66e --- /dev/null +++ b/kexec-tools-2.0.20-makedumpfile-Remove-duplicated-variable-declarations.patch @@ -0,0 +1,76 @@ +From efa29d476996a20052be80878767cfe09e4b6224 Mon Sep 17 00:00:00 2001 +From: Kairui Song +Date: Wed, 29 Jan 2020 10:59:08 +0800 +Subject: [PATCH] makedumpfile: Remove duplicated variable declarations + +When building on Fedora 32, following error is observed: + +/usr/bin/ld: erase_info.o:/builddir/build/BUILD/kexec-tools-2.0.20/makedumpfile-1.6.7/makedumpfile.h:2010: +multiple definition of `crash_reserved_mem_nr'; elf_info.o:/builddir/build/BUILD/kexec-tools-2.0.20/makedumpfile-1.6.7/makedumpfile.h:2010: first defined here +/usr/bin/ld: erase_info.o:/builddir/build/BUILD/kexec-tools-2.0.20/makedumpfile-1.6.7/makedumpfile.h:2009: +multiple definition of `crash_reserved_mem'; elf_info.o:/builddir/build/BUILD/kexec-tools-2.0.20/makedumpfile-1.6.7/makedumpfile.h:2009: first defined here +/usr/bin/ld: erase_info.o:/builddir/build/BUILD/kexec-tools-2.0.20/makedumpfile-1.6.7/makedumpfile.h:1278: +multiple definition of `parallel_info_t'; elf_info.o:/builddir/build/BUILD/kexec-tools-2.0.20/makedumpfile-1.6.7/makedumpfile.h:1278: first defined here +/usr/bin/ld: erase_info.o:/builddir/build/BUILD/kexec-tools-2.0.20/makedumpfile-1.6.7/makedumpfile.h:1265: +multiple definition of `splitting_info_t'; elf_info.o:/builddir/build/BUILD/kexec-tools-2.0.20/makedumpfile-1.6.7/makedumpfile.h:1265: first defined here + +And apparently, these variables are wrongly declared multiple times. So +remove duplicated declaration. + +Signed-off-by: Kairui Song +--- + makedumpfile.c | 2 ++ + makedumpfile.h | 10 ++++++---- + 2 files changed, 8 insertions(+), 4 deletions(-) + +diff --git a/makedumpfile.c b/makedumpfile.c +index e290fbd..9aad77b 100644 +--- a/makedumpfile-1.6.7/makedumpfile.c ++++ b/makedumpfile-1.6.7/makedumpfile.c +@@ -34,6 +34,8 @@ struct array_table array_table; + struct number_table number_table; + struct srcfile_table srcfile_table; + struct save_control sc; ++struct parallel_info parallel_info_t; ++struct splitting_info splitting_info_t; + + struct vm_table vt = { 0 }; + struct DumpInfo *info = NULL; +diff --git a/makedumpfile.h b/makedumpfile.h +index 68d9691..614764c 100644 +--- a/makedumpfile-1.6.7/makedumpfile.h ++++ b/makedumpfile-1.6.7/makedumpfile.h +@@ -1262,7 +1262,8 @@ struct splitting_info { + mdf_pfn_t end_pfn; + off_t offset_eraseinfo; + unsigned long size_eraseinfo; +-} splitting_info_t; ++}; ++extern struct splitting_info splitting_info_t; + + struct parallel_info { + int fd_memory; +@@ -1275,7 +1276,8 @@ struct parallel_info { + #ifdef USELZO + lzo_bytep wrkmem; + #endif +-} parallel_info_t; ++}; ++extern struct parallel_info parallel_info_t; + + struct ppc64_vmemmap { + unsigned long phys; +@@ -2006,8 +2008,8 @@ struct memory_range { + }; + + #define CRASH_RESERVED_MEM_NR 8 +-struct memory_range crash_reserved_mem[CRASH_RESERVED_MEM_NR]; +-int crash_reserved_mem_nr; ++extern struct memory_range crash_reserved_mem[CRASH_RESERVED_MEM_NR]; ++extern int crash_reserved_mem_nr; + + unsigned long read_vmcoreinfo_symbol(char *str_symbol); + int readmem(int type_addr, unsigned long long addr, void *bufptr, size_t size); +-- +2.24.1 + diff --git a/kexec-tools-2.0.20.tar.xz b/kexec-tools-2.0.20.tar.xz new file mode 100644 index 0000000000000000000000000000000000000000..6a66fdbcf28e83bff20c544c2bb61bf8aa149210 Binary files /dev/null and b/kexec-tools-2.0.20.tar.xz differ diff --git a/kexec-tools-2.0.8-increase-the-buf-space-to-1536.patch b/kexec-tools-2.0.8-increase-the-buf-space-to-1536.patch deleted file mode 100644 index 1d08ee8282f9f5d241358058e6621db071abee2e..0000000000000000000000000000000000000000 --- a/kexec-tools-2.0.8-increase-the-buf-space-to-1536.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 072c36f24d52f3c3c864ace33da675a8e5c009d8 Mon Sep 17 00:00:00 2001 -From: Jialong Chen -Date: Tue, 24 Oct 2017 17:10:21 +0800 -Subject: [PATCH] kexec-tools: increase the buf space to 1536 - -reason: increase the buf space to 1536 - -Signed-off-by: Jialong Chen ---- - kexec/arch/arm64/kexec-arm64.h | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/kexec/arch/arm64/kexec-arm64.h b/kexec/arch/arm64/kexec-arm64.h -index 7e4d056..0490d07 100644 ---- a/kexec/arch/arm64/kexec-arm64.h -+++ b/kexec/arch/arm64/kexec-arm64.h -@@ -15,7 +15,10 @@ - - #define BOOT_BLOCK_VERSION 17 - #define BOOT_BLOCK_LAST_COMP_VERSION 16 --#define COMMAND_LINE_SIZE 512 -+/* kernel define COMMAND_LINE_SIZE 2048, kexec will append some parameter to follow command_line -+ * so we define COMMAND_LINE_SIZE 1024+512 here. -+*/ -+#define COMMAND_LINE_SIZE 1536 - - #define KiB(x) ((x) * 1024UL) - #define MiB(x) (KiB(x) * 1024UL) --- -1.8.3.1 - diff --git a/kexec-tools.spec b/kexec-tools.spec index 4d5876e049156c20e4991791913775e7b5916d6f..7e30b85a21adc2fea75df93afdffdaa5a021da4e 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -1,6 +1,10 @@ +%global eppic_ver d84c3541035d95077aa8571f5d5c3e07c6ef510b +%global eppic_shortver %(c=%{eppic_ver}; echo ${c:0:7}) +%global mkdf_ver 1.6.7 + Name: kexec-tools -Version: 2.0.17 -Release: 16 +Version: 2.0.20 +Release: 1 License: GPLv2 Summary: The kexec/kdump userspace component URL: https://www.kernel.org/ @@ -12,13 +16,14 @@ Source4: kdump.sysconfig.i386 Source5: kdump.sysconfig.ppc64 Source7: mkdumprd Source8: kdump.conf -Source9: http://downloads.sourceforge.net/project/makedumpfile/makedumpfile/1.6.4/makedumpfile-1.6.4.tar.gz +Source9: http://downloads.sourceforge.net/project/makedumpfile/makedumpfile/%{mkdf_ver}/makedumpfile-%{mkdf_ver}.tar.gz Source12: mkdumprd.8 -Source14: 98-kexec.rules +Source13: 98-kexec.rules +Source14: 98-kexec.rules.ppc64 Source15: kdump.conf.5 Source16: kdump.service Source18: kdump.sysconfig.s390x -Source19: eppic_050615.tar.gz +Source19: https://github.com/lucchouina/eppic/archive/%{eppic_ver}/eppic-%{eppic_shortver}.tar.gz Source20: kdump-lib.sh Source21: kdump-in-cluster-environment.txt Source22: kdump-dep-generator.sh @@ -27,6 +32,8 @@ Source24: kdump.sysconfig.ppc64le Source25: kdumpctl.8 Source26: live-image-kdump-howto.txt Source27: early-kdump-howto.txt +Source28: kdump-udev-throttler +Source29: kdump.sysconfig.aarch64 Source100: dracut-kdump.sh Source101: dracut-module-setup.sh @@ -38,6 +45,7 @@ Source106: dracut-kdump-capture.service Source107: dracut-kdump-emergency.target Source108: dracut-early-kdump.sh Source109: dracut-early-kdump-module-setup.sh +Source110: dracut-kdump-wait-for-target.sh Requires(post): systemd Requires(preun): systemd @@ -45,6 +53,7 @@ Requires(postun): systemd Requires(pre): coreutils sed zlib Requires: dracut >= 047-34.git20180604 Requires: dracut-network >= 044-117 +Requires: dracut-squash >= 049-4 Requires: ethtool BuildRequires: zlib-devel zlib zlib-static elfutils-devel-static glib2-devel bzip2-devel ncurses-devel bison flex lzo-devel snappy-devel BuildRequires: pkgconfig intltool gettext @@ -54,34 +63,27 @@ BuildRequires: automake autoconf libtool Obsoletes: diskdumputils netdump kexec-tools-eppic %endif +%ifnarch s390x +Requires: systemd-udev%{?_isa} +%endif + %undefine _hardened_build -Patch101: kexec-tools-2.0.17-kexec-fix-for-Unhandled-rela-relocation-R_X86_64_PLT.patch - -Patch6000: vmcore-dmesg-fix-infinite-loop-if-log-buffer-wraps-a.patch -Patch6001: arm64-error-out-if-kernel-command-line-is-too-long.patch -Patch6002: kdump-fix-an-error-that-can-not-parse-the-e820-reser.patch -Patch6003: x86-fix-BAD_FREE-in-get_efi_runtime_map.patch -Patch6004: kexec-dt-ops.c-Fix-check-against-fdt_add_subnode-ret.patch -Patch6005: kexec-kexec-arm64.c-Add-error-handling-check-against.patch -Patch6006: kexec-dt-ops.c-Fix-adding-chosen-node-for-cases-wher.patch -Patch6007: kexec-dt-ops.c-Fix-chosen-v-s-chosen-node-being-pass.patch -Patch6008: arm64-wipe-old-initrd-addresses-when-patching-the-DT.patch -Patch6009: xen-Avoid-overlapping-segments-in-low-memory.patch -Patch6010: x86-Check-proc-mounts-before-mtab-for-mounts.patch -Patch6011: x86-Find-mounts-by-FS-type-not-name.patch -Patch6012: kexec-kexec.c-Add-the-missing-close-for-fd-used-for-kexec_file_load.patch -Patch6013: kexec-uImage-arm64.c-Fix-return-value-of-uImage_arm64_probe.patch -Patch6014: kexec-kexec-zlib.h-Add-is_zlib_file-helper-function.patch -Patch6015: kexec-arm64-Add-support-for-handling-zlib-compressed-image.patch +Patch6000: kexec-tools-2.0.20-fix-broken-multiboot2-buliding-for-i386.patch + +Patch6001: kexec-tools-2.0.20-eppic-Remove-duplicated-variable-declaration.patch +Patch6002: kexec-tools-2.0.20-makedumpfile-Remove-duplicated-variable-declarations.patch +Patch6003: kexec-tools-2.0.20-Remove-duplicated-variable-declarations.patch +Patch6004: kexec-tools-2.0.20-makedumpfile-Introduce-check-params-option.patch %ifarch aarch64 -Patch9000: kexec-tools-2.0.8-increase-the-buf-space-to-1536.patch -Patch9001: bugfix-get-the-paddr-of-mem_section-return-error-address.patch -Patch9002: arm64-support-more-than-one-crash-kernel-regions.patch +Patch9000: arm64-support-more-than-one-crash-kernel-regions.patch %endif -Patch9003: add-secure-compile-options-for-makedumpfile.patch +Patch9001: add-secure-compile-options-for-makedumpfile.patch + +Patch9002: bugfix-get-the-paddr-of-mem_section-return-error-address.patch +Patch9003: fix-header-offset-overflow-when-large-pfn.patch %description kexec-tools provides /sbin/kexec binary that facilitates a new @@ -104,26 +106,19 @@ mkdir -p -m755 kcp tar -z -x -v -f %{SOURCE9} tar -z -x -v -f %{SOURCE19} -%patch101 -p1 - -%{lua:for i=0,8 do print(string.format("%%patch600%u -p1\n", i)) end} -%patch6009 -p1 -%patch6010 -p1 -%patch6011 -p1 -%patch6012 -p1 -%patch6013 -p1 -%patch6014 -p1 -%patch6015 -p1 +%{lua:for i=0,4 do print(string.format("%%patch600%u -p1\n", i)) end} %ifarch aarch64 -%{lua:for i=0,2 do print(string.format("%%patch900%u -p1\n", i)) end} +%patch9000 -p1 %endif +%patch9001 -p1 +%patch9002 -p1 %patch9003 -p1 %build autoreconf -%configure --sbindir=/sbin \ +%configure --sbindir=/usr/sbin \ CFLAGS="${CFLAGS} -fstack-protector-strong -Wl,-z,now -pie -fPIC -fPIE" rm -f kexec-tools.spec.in # for docs @@ -131,13 +126,13 @@ cp %{SOURCE21} %{SOURCE26} %{SOURCE27} . make %ifarch %{ix86} x86_64 aarch64 -make -C eppic/libeppic -make -C makedumpfile-1.6.4 LINKTYPE=dynamic USELZO=on USESNAPPY=on -make -C makedumpfile-1.6.4 LDFLAGS="-I../eppic/libeppic -L../eppic/libeppic" eppic_makedumpfile.so +make -C eppic-%{eppic_ver}/libeppic +make -C makedumpfile-%{mkdf_ver} LINKTYPE=dynamic USELZO=on USESNAPPY=on +make -C makedumpfile-%{mkdf_ver} LDFLAGS="$LDFLAGS -I../eppic-%{eppic_ver}/libeppic -L../eppic-%{eppic_ver}/libeppic" eppic_makedumpfile.so %endif %install -mkdir -p -m755 %{buildroot}/sbin +mkdir -p -m755 %{buildroot}/usr/sbin mkdir -p -m755 %{buildroot}%{_sysconfdir}/sysconfig mkdir -p -m755 %{buildroot}%{_localstatedir}/crash mkdir -p -m755 %{buildroot}%{_mandir}/man8/ @@ -151,8 +146,8 @@ mkdir -p -m755 %{buildroot}%{_libdir} mkdir -p -m755 %{buildroot}%{_prefix}/lib/kdump install -m 755 %{SOURCE1} %{buildroot}%{_bindir}/kdumpctl -install -m 755 build/sbin/kexec %{buildroot}/sbin/kexec -install -m 755 build/sbin/vmcore-dmesg %{buildroot}/sbin/vmcore-dmesg +install -m 755 build/sbin/kexec %{buildroot}/usr/sbin/kexec +install -m 755 build/sbin/vmcore-dmesg %{buildroot}/usr/sbin/vmcore-dmesg install -m 644 build/man/man8/kexec.8 %{buildroot}%{_mandir}/man8/ install -m 644 build/man/man8/vmcore-dmesg.8 %{buildroot}%{_mandir}/man8/ @@ -161,26 +156,28 @@ SYSCONFIG=%{_sourcedir}/kdump.sysconfig.%{_target_cpu} [ -f $SYSCONFIG ] || SYSCONFIG=%{_sourcedir}/kdump.sysconfig install -m 644 $SYSCONFIG %{buildroot}%{_sysconfdir}/sysconfig/kdump -install -m 755 %{SOURCE7} %{buildroot}/sbin/mkdumprd +install -m 755 %{SOURCE7} %{buildroot}/usr/sbin/mkdumprd install -m 644 %{SOURCE8} %{buildroot}%{_sysconfdir}/kdump.conf install -m 644 kexec/kexec.8 %{buildroot}%{_mandir}/man8/kexec.8 install -m 644 %{SOURCE12} %{buildroot}%{_mandir}/man8/mkdumprd.8 install -m 644 %{SOURCE25} %{buildroot}%{_mandir}/man8/kdumpctl.8 install -m 755 %{SOURCE20} %{buildroot}%{_prefix}/lib/kdump/kdump-lib.sh install -m 755 %{SOURCE23} %{buildroot}%{_prefix}/lib/kdump/kdump-lib-initramfs.sh +install -m 755 %{SOURCE28} $RPM_BUILD_ROOT%{_udevrulesdir}/../kdump-udev-throttler install -m 644 %{SOURCE15} %{buildroot}%{_mandir}/man5/kdump.conf.5 install -m 644 %{SOURCE16} %{buildroot}%{_unitdir}/kdump.service install -m 755 -D %{SOURCE22} %{buildroot}%{_prefix}/lib/systemd/system-generators/kdump-dep-generator.sh +install -m 644 %{SOURCE13} $RPM_BUILD_ROOT%{_udevrulesdir}/98-kexec.rules install -m 644 %{SOURCE14} %{buildroot}%{_udevrulesdir}/98-kexec.rules %ifarch %{ix86} x86_64 aarch64 -install -m 755 makedumpfile-1.6.4/makedumpfile %{buildroot}/sbin/makedumpfile -install -m 644 makedumpfile-1.6.4/makedumpfile.8.gz %{buildroot}/%{_mandir}/man8/makedumpfile.8.gz -install -m 644 makedumpfile-1.6.4/makedumpfile.conf.5.gz %{buildroot}/%{_mandir}/man5/makedumpfile.conf.5.gz -install -m 644 makedumpfile-1.6.4/makedumpfile.conf %{buildroot}/%{_sysconfdir}/makedumpfile.conf.sample -install -m 755 makedumpfile-1.6.4/eppic_makedumpfile.so %{buildroot}/%{_libdir}/eppic_makedumpfile.so -mkdir -p %{buildroot}/usr/share/makedumpfile/eppic_scripts/ -install -m 644 makedumpfile-1.6.4/eppic_scripts/* %{buildroot}/usr/share/makedumpfile/eppic_scripts/ +install -m 755 makedumpfile-%{mkdf_ver}/makedumpfile $RPM_BUILD_ROOT/usr/sbin/makedumpfile +install -m 644 makedumpfile-%{mkdf_ver}/makedumpfile.8.gz $RPM_BUILD_ROOT/%{_mandir}/man8/makedumpfile.8.gz +install -m 644 makedumpfile-%{mkdf_ver}/makedumpfile.conf.5.gz $RPM_BUILD_ROOT/%{_mandir}/man5/makedumpfile.conf.5.gz +install -m 644 makedumpfile-%{mkdf_ver}/makedumpfile.conf $RPM_BUILD_ROOT/%{_sysconfdir}/makedumpfile.conf.sample +install -m 755 makedumpfile-%{mkdf_ver}/eppic_makedumpfile.so $RPM_BUILD_ROOT/%{_libdir}/eppic_makedumpfile.so +mkdir -p $RPM_BUILD_ROOT/usr/share/makedumpfile/eppic_scripts/ +install -m 644 makedumpfile-%{mkdf_ver}/eppic_scripts/* $RPM_BUILD_ROOT/usr/share/makedumpfile/eppic_scripts/ %endif %define remove_dracut_prefix() %(echo -n %1|sed 's/.*dracut-//g') @@ -196,6 +193,7 @@ cp %{SOURCE104} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase cp %{SOURCE105} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE105}} cp %{SOURCE106} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE106}} cp %{SOURCE107} %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE107}} +cp %{SOURCE110} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE110}} chmod 755 %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE100}} chmod 755 %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase/%{remove_dracut_prefix %{SOURCE101}} mkdir -p -m755 %{buildroot}/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump @@ -264,12 +262,13 @@ done %doc TODO %license COPYING %config(noreplace,missingok) %{_sysconfdir}/sysconfig/kdump -%config(noreplace,missingok) %{_sysconfdir}/kdump.conf +%config(noreplace,missingok) %verify(not mtime) %{_sysconfdir}/kdump.conf %config %{_udevrulesdir} +%{_udevrulesdir}/../kdump-udev-throttler %dir %{_localstatedir}/crash -/sbin/kexec -/sbin/mkdumprd -/sbin/vmcore-dmesg +/usr/sbin/kexec +/usr/sbin/mkdumprd +/usr/sbin/vmcore-dmesg %{_bindir}/* %{_datadir}/kdump %{_prefix}/lib/kdump @@ -284,7 +283,7 @@ done %{_sysconfdir}/makedumpfile.conf.sample %endif %ifarch %{ix86} x86_64 aarch64 -/sbin/makedumpfile +/usr/sbin/makedumpfile %endif %files help @@ -301,6 +300,12 @@ done %endif %changelog +* Thu Jul 23 2020 zhangxingliang - 2.0.20-1 +- Type:update +- ID:NA +- SUG:NA +- DESC:update to 2.0.20 + * Thu May 14 2020 openEuler Buildteam - 2.0.17-16 - Type:enhancement - ID:NA diff --git a/kexec-uImage-arm64.c-Fix-return-value-of-uImage_arm64_probe.patch b/kexec-uImage-arm64.c-Fix-return-value-of-uImage_arm64_probe.patch deleted file mode 100644 index b4fee80ebe3c57955a83d755ad83c9fc859ece09..0000000000000000000000000000000000000000 --- a/kexec-uImage-arm64.c-Fix-return-value-of-uImage_arm64_probe.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 6ef59c03bf2c42f6577c708b58598868e8e8fb0b Mon Sep 17 00:00:00 2001 -From: Bhupesh Sharma -Date: Mon, 15 Jul 2019 11:32:54 +0530 -Subject: [PATCH 16/20] kexec-uImage-arm64.c: Fix return value of - uImage_arm64_probe() - -https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/commit/?id=6ef59c03bf2c42f6577c708b58598868e8e8fb0b - -Commit bf06cf2095e1 ("kexec/uImage: probe to identify a corrupted image"), -defined the 'uImage_probe_kernel()' function return values and -correspondingly ;uImage_arm64_probe()' returns the same (0 -> If the -image is valid 'type' image, -1 -> If the image is corrupted and -1 -> If the image is not a uImage). - -This causes issues because, in later patches we introduce zImage -support for arm64, and since it is probed after uImage, the return -values from 'uImage_arm64_probe()' needs to be fixed to make sure -that kexec will not return with an invalid error code. - -Now, 'uImage_arm64_probe()' returns the following values instead: - 0 - valid uImage. - -1 - uImage is corrupted. - 1 - image is not a uImage. - -Signed-off-by: Bhupesh Sharma -Signed-off-by: Simon Horman ---- - kexec/arch/arm64/kexec-uImage-arm64.c | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - -diff --git a/kexec/arch/arm64/kexec-uImage-arm64.c b/kexec/arch/arm64/kexec-uImage-arm64.c -index 126ea9c..c466913 100644 ---- a/kexec/arch/arm64/kexec-uImage-arm64.c -+++ b/kexec/arch/arm64/kexec-uImage-arm64.c -@@ -11,7 +11,18 @@ - - int uImage_arm64_probe(const char *buf, off_t len) - { -- return uImage_probe_kernel(buf, len, IH_ARCH_ARM64); -+ int ret; -+ -+ ret = uImage_probe_kernel(buf, len, IH_ARCH_ARM64); -+ -+ /* 0 - valid uImage. -+ * -1 - uImage is corrupted. -+ * 1 - image is not a uImage. -+ */ -+ if (!ret) -+ return 0; -+ else -+ return -1; - } - - int uImage_arm64_load(int argc, char **argv, const char *buf, off_t len, --- -1.8.3.1 - diff --git a/makedumpfile-1.6.4.tar.gz b/makedumpfile-1.6.4.tar.gz deleted file mode 100644 index 8d28b217a678da2f56d3fe94f94d028c7cdc3cbf..0000000000000000000000000000000000000000 Binary files a/makedumpfile-1.6.4.tar.gz and /dev/null differ diff --git a/makedumpfile-1.6.7.tar.gz b/makedumpfile-1.6.7.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..a2d2a80578d0be86b8ee185c00ac385d409a129a Binary files /dev/null and b/makedumpfile-1.6.7.tar.gz differ diff --git a/mkdumprd b/mkdumprd index 078f9887b032d142edf1b2a6ce0be6fc1244762b..35f5eedd09091b9919be678c20a9eb98abdb6e84 100644 --- a/mkdumprd +++ b/mkdumprd @@ -13,10 +13,11 @@ export IN_KDUMP=1 conf_file="/etc/kdump.conf" SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa" -SAVE_PATH=$(grep ^path $conf_file| cut -d' ' -f2) -[ -z "$SAVE_PATH" ] && SAVE_PATH=$DEFAULT_PATH -# strip the duplicated "/" -SAVE_PATH=$(echo $SAVE_PATH | tr -s /) +SAVE_PATH=$(get_save_path) +OVERRIDE_RESETTABLE=0 + +extra_modules="" +dracut_args="--quiet --hostonly --hostonly-cmdline --hostonly-i18n --hostonly-mode strict -o \"plymouth dash resume ifcfg earlykdump\"" is_wdt_addition_needed() { local active @@ -32,52 +33,20 @@ is_wdt_addition_needed() { return 1 } -WDTCFG="" -is_wdt_addition_needed -[[ $? -eq 0 ]] && WDTCFG="-a watchdog" - -extra_modules="" -dracut_args=("--quiet" "--hostonly" "--hostonly-cmdline" "--hostonly-i18n" "--hostonly-mode" "strict" "-o" "plymouth dash resume ifcfg" $WDTCFG) -OVERRIDE_RESETTABLE=0 - add_dracut_arg() { - local arg qarg is_quoted=0 - while [ $# -gt 0 ]; - do - arg="${1//\'/\"}" - #Handle quoted substring properly for passing it to dracut_args array. - if [ $is_quoted -eq 0 ]; then - if [[ "$arg" == "\"" ]] || [[ $arg != ${arg#\"} ]]; then - is_quoted=1 - arg=${arg#\"} - fi - fi - if [ $is_quoted -eq 1 ]; then - qarg="$qarg $arg" - if [[ "$arg" == "\"" ]] || [[ $arg != ${arg%\"} ]]; then - is_quoted=0 - arg=${qarg%\"} - qarg="" - else - shift - continue - fi - fi - dracut_args+=("$arg") - shift - done + dracut_args="$dracut_args $@" } add_dracut_module() { - add_dracut_arg "--add" "$1" + add_dracut_arg "--add" "\"$1\"" } add_dracut_mount() { - add_dracut_arg "--mount" "$1" + add_dracut_arg "--mount" "\"$1\"" } add_dracut_sshkey() { - add_dracut_arg "--sshkey" "$1" + add_dracut_arg "--sshkey" "\"$1\"" } # caller should ensure $1 is valid and mounted in 1st kernel @@ -98,15 +67,23 @@ to_mount() { _fstype=$(findmnt -k -f -n -r -o FSTYPE $_dev) [[ -e /etc/fstab ]] && _options=$(findmnt --fstab -f -n -r -o OPTIONS $_dev) - [ -z "$_options" ] && _options=$(findmnt -k -f -n -r -o OPTIONS $_dev) - # with 'noauto' in fstab nfs and non-root disk mount will fail in 2nd - # kernel, filter it out here. - _options=$(echo $_options | sed 's/\bnoauto\b//') - #mount fs target as rw in 2nd kernel - _options=$(echo $_options | sed 's/\bro\b/rw/') + if [ -z "$_options" ]; then + _options=$(findmnt -k -f -n -r -o OPTIONS $_dev) + if [[ $_fstype == "nfs"* ]]; then + _options=$(echo $_options | sed 's/,addr=[^,]*//') + _options=$(echo $_options | sed 's/,proto=[^,]*//') + _options=$(echo $_options | sed 's/,clientaddr=[^,]*//') + fi + fi + # mount fs target as rw in 2nd kernel + _options=$(echo $_options | sed 's/\(^\|,\)ro\($\|,\)/\1rw\2/g') + # filter out 'noauto' here, it will be force appended later, avoid duplication + _options=$(echo $_options | sed 's/\(^\|,\)noauto\($\|,\)/\1/g') # drop nofail or nobootwait - _options=$(echo $_options | sed 's/\bnofail\b//') - _options=$(echo $_options | sed 's/\bnobootwait\b//') + _options=$(echo $_options | sed 's/\(^\|,\)nofail\($\|,\)/\1/g') + _options=$(echo $_options | sed 's/\(^\|,\)nobootwait\($\|,\)/\1/g') + # only mount the dump target when needed. + _options="$_options,noauto" _mntopts="$_target $_fstype $_options" #for non-nfs _dev converting to use udev persistent name @@ -150,7 +127,7 @@ get_ssh_size() { #mkdir if save path does not exist on ssh dump target #$1=ssh dump target -#caller should ensure write permission on $DUMP_TARGET:$SAVE_PATH +#caller should ensure write permission on $1:$SAVE_PATH #called from while loop and shouldn't read from stdin, so we're using "ssh -n" mkdir_save_path_ssh() { @@ -159,14 +136,14 @@ mkdir_save_path_ssh() ssh -qn $_opt $1 mkdir -p $SAVE_PATH 2>&1 > /dev/null _ret=$? if [ $_ret -ne 0 ]; then - perror_exit "mkdir failed on $DUMP_TARGET:$SAVE_PATH" + perror_exit "mkdir failed on $1:$SAVE_PATH" fi - #check whether user has write permission on $SAVE_PATH/$DUMP_TARGET + #check whether user has write permission on $1:$SAVE_PATH _dir=$(ssh -qn $_opt $1 mktemp -dqp $SAVE_PATH 2>/dev/null) _ret=$? if [ $_ret -ne 0 ]; then - perror_exit "Could not create temporary directory on $DUMP_TARGET:$SAVE_PATH. Make sure user has write permission on destination" + perror_exit "Could not create temporary directory on $1:$SAVE_PATH. Make sure user has write permission on destination" fi ssh -qn $_opt $1 rmdir $_dir @@ -219,15 +196,27 @@ check_size() { # $1: core_collector config value verify_core_collector() { - if grep -q "^raw" $conf_file && [ "${1%% *}" != "makedumpfile" ]; then - echo "Warning: specifying a non-makedumpfile core collector, you will have to recover the vmcore manually." + local _cmd="${1%% *}" + local _params="${1#* }" + + if [ "$_cmd" != "makedumpfile" ]; then + if is_raw_dump_target; then + echo "Warning: specifying a non-makedumpfile core collector, you will have to recover the vmcore manually." + fi + return fi + if is_ssh_dump_target || is_raw_dump_target; then - if [ "${1%% *}" = "makedumpfile" ]; then - ! strstr "$1" "-F" && { - perror_exit "The specified dump target needs makedumpfile \"-F\" option." - } + if ! strstr "$_params" "-F"; then + perror_exit "The specified dump target needs makedumpfile \"-F\" option." fi + _params="$_params vmcore" + else + _params="$_params vmcore dumpfile" + fi + + if ! $_cmd --check-params $_params; then + perror_exit "makedumpfile parameter check failed." fi } @@ -251,20 +240,11 @@ handle_default_dump_target() check_save_path_fs $SAVE_PATH - _mntpoint=$(get_mntpoint_from_path $SAVE_PATH) - _target=$(get_target_from_path $SAVE_PATH) - - if is_atomic && is_bind_mount $_mntpoint; then - SAVE_PATH=${SAVE_PATH##"$_mntpoint"} - # the real dump path in the 2nd kernel, if the mount point is bind mounted. - SAVE_PATH=$(get_bind_mount_directory $_mntpoint)/$SAVE_PATH - _mntpoint=$(get_mntpoint_from_target $_target) + _save_path=$(get_bind_mount_source $SAVE_PATH) + _target=$(get_target_from_path $_save_path) + _mntpoint=$(get_mntpoint_from_target $_target) - # the absolute path in the 1st kernel - SAVE_PATH=$_mntpoint/$SAVE_PATH - fi - - SAVE_PATH=${SAVE_PATH##"$_mntpoint"} + SAVE_PATH=${_save_path##"$_mntpoint"} add_mount "$_target" check_size fs $_target } @@ -382,10 +362,13 @@ if [ "$(uname -m)" = "s390x" ]; then add_dracut_module "znet" fi +if is_wdt_addition_needed; then + add_dracut_arg "-a" "watchdog" +fi + while read config_opt config_val; do # remove inline comments after the end of a directive. - config_val=$(strip_comments $config_val) case "$config_opt" in extra_modules) extra_modules="$extra_modules $config_val" @@ -395,20 +378,13 @@ do perror_exit "Dump target $config_val is probably not mounted." fi - _absolute_save_path=$(make_absolute_save_path $config_val) - _mntpoint=$(get_mntpoint_from_path $_absolute_save_path) - if is_atomic && is_bind_mount $_mntpoint; then - SAVE_PATH=${_absolute_save_path##"$_mntpoint"} - # the real dump path in the 2nd kernel, if the mount point is bind mounted. - SAVE_PATH=$(get_bind_mount_directory $_mntpoint)/$SAVE_PATH - fi - + # User configured target, use $SAVE_PATH as the dump path within the target + check_save_path_user_configured "$config_val" "$SAVE_PATH" + check_size fs "$config_val" add_mount "$config_val" - check_save_path_fs $_absolute_save_path - check_size fs $config_val ;; raw) - #checking raw disk writable + # checking raw disk writable dd if=$config_val count=1 of=/dev/null > /dev/null 2>&1 || { perror_exit "Bad raw disk $config_val" } @@ -422,10 +398,10 @@ do ssh) if strstr "$config_val" "@"; then - check_size ssh $config_val mkdir_save_path_ssh $config_val + check_size ssh $config_val add_dracut_module "ssh-client" - add_dracut_sshkey "$SSH_KEY_LOCATION" + add_dracut_sshkey "$SSH_KEY_LOCATION" else perror_exit "Bad ssh dump target $config_val" fi @@ -437,13 +413,9 @@ do add_dracut_arg $config_val ;; *) - if [ -n $(echo $config_opt | grep "^#.*$") ] - then - continue - fi ;; esac -done < $conf_file +done <<< "$(read_strip_comments $conf_file)" handle_default_dump_target @@ -460,7 +432,8 @@ if ! is_fadump_capable; then add_dracut_arg "--no-hostonly-default-device" fi -dracut "${dracut_args[@]}" "$@" +echo "$dracut_args $@" | xargs dracut + _rc=$? sync exit $_rc diff --git a/vmcore-dmesg-fix-infinite-loop-if-log-buffer-wraps-a.patch b/vmcore-dmesg-fix-infinite-loop-if-log-buffer-wraps-a.patch deleted file mode 100644 index 2a1418cb977260a695873ade2def9a170b9e2bdd..0000000000000000000000000000000000000000 --- a/vmcore-dmesg-fix-infinite-loop-if-log-buffer-wraps-a.patch +++ /dev/null @@ -1,37 +0,0 @@ -From e277fa9ec702fea7bd3135393c67327c821d5a3a Mon Sep 17 00:00:00 2001 -From: Omar Sandoval -Date: Wed, 23 May 2018 13:59:31 -0700 -Subject: [PATCH 08/37] vmcore-dmesg: fix infinite loop if log buffer wraps - around - -We hit a bug where vmcore-dmesg would get stuck in a loop, and since we -were redirecting the output to a file, it wouldn't stop until it filled -up the disk. This only happened when the dmesg buffer had filled up and -wrapped around. It turns out that when we hit the end of the buffer, we -are looping back to the first record instead of the beginning of the -buffer, which will always loop forever. - -Fixes: e08d26b3b7f1 ("vmcore-dmesg: avoid allocating large memory chunk for log buf") -Signed-off-by: Omar Sandoval -Acked-by: Baoquan He -Signed-off-by: Simon Horman ---- - vmcore-dmesg/vmcore-dmesg.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c -index e340ef4..7972788 100644 ---- a/vmcore-dmesg/vmcore-dmesg.c -+++ b/vmcore-dmesg/vmcore-dmesg.c -@@ -689,7 +689,7 @@ static void dump_dmesg_structured(int fd) - */ - loglen = struct_val_u16(buf, log_offset_len); - if (!loglen) -- current_idx = log_first_idx; -+ current_idx = 0; - else - /* Move to next record */ - current_idx += loglen; --- -2.6.4.windows.1 - diff --git a/x86-Check-proc-mounts-before-mtab-for-mounts.patch b/x86-Check-proc-mounts-before-mtab-for-mounts.patch deleted file mode 100644 index 958d4a477a64c6d8e64b9432639a0ee88408eef3..0000000000000000000000000000000000000000 --- a/x86-Check-proc-mounts-before-mtab-for-mounts.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 23aaa44614a02d2184951142125cb55b36cef40a Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Niklas=20Hamb=C3=BCchen?= -Date: Mon, 29 Apr 2019 10:22:26 +0200 -Subject: [PATCH 04/20] x86: Check /proc/mounts before mtab for mounts -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/commit/?id=23aaa44614a02d2184951142125cb55b36cef40a - -In many situations, especially on read-only file systems -and initial ramdisks (intramfs/initrd), /etc/mtab does not exist. - -Before this commit, kexec would fail to read mounts on such systems -in `find_mnt_by_fsname()`, such that `get_bootparam()` would not -`boot_params/data`, which would then lead to e.g. `setup_efi_data()` -not being called in `setup_efi_info()`. - -As a result, kexec'ed kernels would not obtain EFI data, -subsequentially lack an `ACPI RSDP` entry, emitting: - - ACPI BIOS Error (bug): A valid RSDP was not found (20180810/tbxfroot-210) - -and thus fail to turn off the machine on poweroff, instead printing only: - - reboot: System halted - -This problem had to be worked around by passing `acpi_rsdp=` manually -before. This commit obviates this workaround. - -See also: - -* https://github.com/coreos/bugs/issues/167#issuecomment-487320879 -* http://lists.infradead.org/pipermail/kexec/2012-October/006924.html - -Signed-off-by: Niklas Hambüchen -Signed-off-by: Simon Horman ---- - kexec/arch/i386/x86-linux-setup.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c -index 8fad115..74fb0c4 100644 ---- a/kexec/arch/i386/x86-linux-setup.c -+++ b/kexec/arch/i386/x86-linux-setup.c -@@ -432,7 +432,7 @@ out: - /* - * This really only makes sense for virtual filesystems that are only expected - * to be mounted once (sysfs, debugsfs, proc), as it will return the first -- * instance listed in mtab. -+ * instance listed in /proc/mounts, falling back to mtab if absent. - */ - char *find_mnt_by_fsname(char *fsname) - { -@@ -440,7 +440,11 @@ char *find_mnt_by_fsname(char *fsname) - struct mntent *mnt; - char *mntdir; - -- mtab = setmntent("/etc/mtab", "r"); -+ mtab = setmntent("/proc/mounts", "r"); -+ if (!mtab) { -+ // Fall back to mtab -+ mtab = setmntent("/etc/mtab", "r"); -+ } - if (!mtab) - return NULL; - for(mnt = getmntent(mtab); mnt; mnt = getmntent(mtab)) { --- -1.8.3.1 - diff --git a/x86-Find-mounts-by-FS-type-not-name.patch b/x86-Find-mounts-by-FS-type-not-name.patch deleted file mode 100644 index 7fc89180ea2e3e6c3538c0763bd52aa49a600dbb..0000000000000000000000000000000000000000 --- a/x86-Find-mounts-by-FS-type-not-name.patch +++ /dev/null @@ -1,84 +0,0 @@ -From c072bd13abbe497d28e4235e2cf416f4aee65754 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Niklas=20Hamb=C3=BCchen?= -Date: Mon, 29 Apr 2019 10:23:14 +0200 -Subject: [PATCH 05/20] x86: Find mounts by FS type, not name -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/commit/?id=c072bd13abbe497d28e4235e2cf416f4aee65754 - -The name in mount invocations like - - mount -t debugfs debugfs /sys/kernel/debug - -is nothing but convention and cannot be relied upon. - -For example, https://www.kernel.org/doc/Documentation/filesystems/debugfs.txt -recommends making the name "none" instead: - - mount -t debugfs none /sys/kernel/debug - -and many existing systems use mounts named "none" or otherwise. - -Using `mnt_type` instead of `mnt_fsname` allows kexec to work -on such systems. - -This fixes another instance of `poweroff` not working on kexec'ed -kernels because the lack of correctly matched mount results in EFI -variables not being read and propagated. - -Signed-off-by: Niklas Hambüchen -Signed-off-by: Simon Horman ---- - kexec/arch/i386/x86-linux-setup.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - -diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c -index 74fb0c4..b643c8b 100644 ---- a/kexec/arch/i386/x86-linux-setup.c -+++ b/kexec/arch/i386/x86-linux-setup.c -@@ -433,8 +433,12 @@ out: - * This really only makes sense for virtual filesystems that are only expected - * to be mounted once (sysfs, debugsfs, proc), as it will return the first - * instance listed in /proc/mounts, falling back to mtab if absent. -+ * We search by type and not by name because the name can be anything; -+ * while setting the name equal to the mount point is common, it cannot be -+ * relied upon, as even kernel documentation examples recommends using -+ * "none" as the name e.g. for debugfs. - */ --char *find_mnt_by_fsname(char *fsname) -+char *find_mnt_by_type(char *type) - { - FILE *mtab; - struct mntent *mnt; -@@ -448,7 +452,7 @@ char *find_mnt_by_fsname(char *fsname) - if (!mtab) - return NULL; - for(mnt = getmntent(mtab); mnt; mnt = getmntent(mtab)) { -- if (strcmp(mnt->mnt_fsname, fsname) == 0) -+ if (strcmp(mnt->mnt_type, type) == 0) - break; - } - mntdir = mnt ? strdup(mnt->mnt_dir) : NULL; -@@ -463,7 +467,7 @@ static int get_bootparam(void *buf, off_t offset, size_t size) - char filename[PATH_MAX]; - int err, has_sysfs_params = 0; - -- sysfs_mnt = find_mnt_by_fsname("sysfs"); -+ sysfs_mnt = find_mnt_by_type("sysfs"); - if (sysfs_mnt) { - snprintf(filename, PATH_MAX, "%s/%s", sysfs_mnt, - "kernel/boot_params/data"); -@@ -474,7 +478,7 @@ static int get_bootparam(void *buf, off_t offset, size_t size) - } - - if (!has_sysfs_params) { -- debugfs_mnt = find_mnt_by_fsname("debugfs"); -+ debugfs_mnt = find_mnt_by_type("debugfs"); - if (!debugfs_mnt) - return 1; - snprintf(filename, PATH_MAX, "%s/%s", debugfs_mnt, --- -1.8.3.1 - diff --git a/x86-fix-BAD_FREE-in-get_efi_runtime_map.patch b/x86-fix-BAD_FREE-in-get_efi_runtime_map.patch deleted file mode 100644 index b8b7029977a43518bad0d62be48f7b0c87c58da4..0000000000000000000000000000000000000000 --- a/x86-fix-BAD_FREE-in-get_efi_runtime_map.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 8db8b6613a00e736e450401cff6121ec550a72f5 Mon Sep 17 00:00:00 2001 -From: Pingfan Liu -Date: Mon, 22 Oct 2018 15:54:16 +0800 -Subject: [PATCH 53/55] x86: fix BAD_FREE in get_efi_runtime_map() - -If the err_out label is reached, address of a stack variable is passed to -free(). Fix it. - -Signed-off-by: Pingfan Liu -Signed-off-by: Simon Horman ---- - kexec/arch/i386/x86-linux-setup.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/kexec/arch/i386/x86-linux-setup.c b/kexec/arch/i386/x86-linux-setup.c -index 6c7d260..6cda12c 100644 ---- a/kexec/arch/i386/x86-linux-setup.c -+++ b/kexec/arch/i386/x86-linux-setup.c -@@ -595,8 +595,8 @@ static int get_efi_runtime_map(struct efi_mem_descriptor **map) - closedir(dirp); - return nr_maps; - err_out: -- if (map) -- free(map); -+ if (*map) -+ free(*map); - closedir(dirp); - return 0; - } --- -1.8.3.1 - diff --git a/xen-Avoid-overlapping-segments-in-low-memory.patch b/xen-Avoid-overlapping-segments-in-low-memory.patch deleted file mode 100644 index 4ce308fd70f2a916d97876ea90405297a66f0510..0000000000000000000000000000000000000000 --- a/xen-Avoid-overlapping-segments-in-low-memory.patch +++ /dev/null @@ -1,153 +0,0 @@ -From eff53089523c331ac946df74ba365072a6fd1a95 Mon Sep 17 00:00:00 2001 -From: David Woodhouse -Date: Sun, 28 Apr 2019 13:52:12 +0300 -Subject: [PATCH 03/20] xen: Avoid overlapping segments in low memory -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -https://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git/commit/?id=eff53089523c331ac946df74ba365072a6fd1a95 - -Unlike Linux which creates a full identity mapping, Xen only maps those -segments which are explicitly requested. Therefore, xen_kexec_load() -silently adds in a segment from zero to 1MiB to ensure that VGA memory -and other things are accessible. - -However, this doesn't work when there are already segments to be loaded -under 1MiB, because the overlap causes Xen to reject the kexec_load. - -Be more careful and just infill the ranges which are required instead -of naïvely adding a full 0-1MiB segment at the end of the list. - -Signed-off-by: David Woodhouse -Signed-off-by: Simon Horman ---- - kexec/kexec-xen.c | 73 ++++++++++++++++++++++++++++++++++++++++--------------- - 1 file changed, 54 insertions(+), 19 deletions(-) - -diff --git a/kexec/kexec-xen.c b/kexec/kexec-xen.c -index 1887390..c326955 100644 ---- a/kexec/kexec-xen.c -+++ b/kexec/kexec-xen.c -@@ -64,15 +64,18 @@ int __xc_interface_close(xc_interface *xch) - } - #endif /* CONFIG_LIBXENCTRL_DL */ - -+#define IDENTMAP_1MiB (1024 * 1024) -+ - int xen_kexec_load(struct kexec_info *info) - { -- uint32_t nr_segments = info->nr_segments; -+ uint32_t nr_segments = info->nr_segments, nr_low_segments = 0; - struct kexec_segment *segments = info->segment; -+ uint64_t low_watermark = 0; - xc_interface *xch; - xc_hypercall_buffer_array_t *array = NULL; - uint8_t type; - uint8_t arch; -- xen_kexec_segment_t *xen_segs; -+ xen_kexec_segment_t *xen_segs, *seg; - int s; - int ret = -1; - -@@ -80,7 +83,28 @@ int xen_kexec_load(struct kexec_info *info) - if (!xch) - return -1; - -- xen_segs = calloc(nr_segments + 1, sizeof(*xen_segs)); -+ /* -+ * Ensure 0 - 1 MiB is mapped and accessible by the image. -+ * This allows access to the VGA memory and the region -+ * purgatory copies in the crash case. -+ * -+ * First, count the number of additional segments which will -+ * need to be added in between the ones in segments[]. -+ * -+ * The segments are already sorted. -+ */ -+ for (s = 0; s < nr_segments && (uint64_t)segments[s].mem <= IDENTMAP_1MiB; s++) { -+ if ((uint64_t)segments[s].mem > low_watermark) -+ nr_low_segments++; -+ -+ low_watermark = (uint64_t)segments[s].mem + segments[s].memsz; -+ } -+ if (low_watermark < IDENTMAP_1MiB) -+ nr_low_segments++; -+ -+ low_watermark = 0; -+ -+ xen_segs = calloc(nr_segments + nr_low_segments, sizeof(*xen_segs)); - if (!xen_segs) - goto out; - -@@ -88,32 +112,43 @@ int xen_kexec_load(struct kexec_info *info) - if (array == NULL) - goto out; - -+ seg = xen_segs; - for (s = 0; s < nr_segments; s++) { - DECLARE_HYPERCALL_BUFFER(void, seg_buf); - -+ if (low_watermark < IDENTMAP_1MiB && (uint64_t)segments[s].mem > low_watermark) { -+ set_xen_guest_handle(seg->buf.h, HYPERCALL_BUFFER_NULL); -+ seg->buf_size = 0; -+ seg->dest_maddr = low_watermark; -+ low_watermark = (uint64_t)segments[s].mem; -+ if (low_watermark > IDENTMAP_1MiB) -+ low_watermark = IDENTMAP_1MiB; -+ seg->dest_size = low_watermark - seg->dest_maddr; -+ seg++; -+ } -+ - seg_buf = xc_hypercall_buffer_array_alloc(xch, array, s, - seg_buf, segments[s].bufsz); - if (seg_buf == NULL) - goto out; - memcpy(seg_buf, segments[s].buf, segments[s].bufsz); - -- set_xen_guest_handle(xen_segs[s].buf.h, seg_buf); -- xen_segs[s].buf_size = segments[s].bufsz; -- xen_segs[s].dest_maddr = (uint64_t)segments[s].mem; -- xen_segs[s].dest_size = segments[s].memsz; -+ set_xen_guest_handle(seg->buf.h, seg_buf); -+ seg->buf_size = segments[s].bufsz; -+ seg->dest_maddr = (uint64_t)segments[s].mem; -+ seg->dest_size = segments[s].memsz; -+ seg++; -+ -+ low_watermark = (uint64_t)segments[s].mem + segments[s].memsz; - } - -- /* -- * Ensure 0 - 1 MiB is mapped and accessible by the image. -- * -- * This allows access to the VGA memory and the region -- * purgatory copies in the crash case. -- */ -- set_xen_guest_handle(xen_segs[s].buf.h, HYPERCALL_BUFFER_NULL); -- xen_segs[s].buf_size = 0; -- xen_segs[s].dest_maddr = 0; -- xen_segs[s].dest_size = 1 * 1024 * 1024; -- nr_segments++; -+ if ((uint64_t)low_watermark < IDENTMAP_1MiB) { -+ set_xen_guest_handle(seg->buf.h, HYPERCALL_BUFFER_NULL); -+ seg->buf_size = 0; -+ seg->dest_maddr = low_watermark; -+ seg->dest_size = IDENTMAP_1MiB - low_watermark; -+ seg++; -+ } - - type = (info->kexec_flags & KEXEC_ON_CRASH) ? KEXEC_TYPE_CRASH - : KEXEC_TYPE_DEFAULT; -@@ -125,7 +160,7 @@ int xen_kexec_load(struct kexec_info *info) - #endif - - ret = xc_kexec_load(xch, type, arch, (uint64_t)info->entry, -- nr_segments, xen_segs); -+ nr_segments + nr_low_segments, xen_segs); - - out: - xc_hypercall_buffer_array_destroy(xch, array); --- -1.8.3.1 -