diff --git a/1.7.0.tar.gz b/1.7.0.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..a713847dfe9995d4e9b9025c307f381f19f89614 Binary files /dev/null and b/1.7.0.tar.gz differ diff --git a/download b/download new file mode 100644 index 0000000000000000000000000000000000000000..44b12685ce8d3df967accd991e14ef1868db4b3d --- /dev/null +++ b/download @@ -0,0 +1,3 @@ +2634194b3735ddfdc9b4bda93e6821f3 1.7.0.tar.gz +43e84f9d3e5b7ba939cc05035a6fb78a eppic_050615.tar.gz +3b3ee68064648b1b9e86ad93b1c50644 kexec-tools-2.0.20.tar.xz diff --git a/dracut-fadump-init-fadump.sh b/dracut-fadump-init-fadump.sh new file mode 100755 index 0000000000000000000000000000000000000000..94a37512bca17698b280b6c5d16ab329865e26d2 --- /dev/null +++ b/dracut-fadump-init-fadump.sh @@ -0,0 +1,48 @@ +#!/bin/sh +export PATH=/usr/bin:/usr/sbin +export SYSTEMD_IN_INITRD=lenient + +[ -e /proc/mounts ] || + (mkdir -p /proc && mount -t proc -o nosuid,noexec,nodev proc /proc) + +grep -q '^sysfs /sys sysfs' /proc/mounts || + (mkdir -p /sys && mount -t sysfs -o nosuid,noexec,nodev sysfs /sys) + +grep -q '^none / ' /proc/mounts || grep -q '^rootfs / ' /proc/mounts && ROOTFS_IS_RAMFS=1 + +if [ -f /proc/device-tree/rtas/ibm,kernel-dump ] || [ -f /proc/device-tree/ibm,opal/dump/mpipl-boot ]; then + mkdir /newroot + mount -t ramfs ramfs /newroot + + if [ $ROOTFS_IS_RAMFS ]; then + for FILE in $(ls -A /fadumproot/); do + mv /fadumproot/$FILE /newroot/ + done + exec switch_root /newroot /init + else + mkdir /newroot/sys /newroot/proc /newroot/dev /newroot/run /newroot/oldroot + + grep -q '^devtmpfs /dev devtmpfs' /proc/mounts && mount --move /dev /newroot/dev + grep -q '^tmpfs /run tmpfs' /proc/mounts && mount --move /run /newroot/run + mount --move /sys /newroot/sys + mount --move /proc /newroot/proc + + cp --reflink=auto --sparse=auto --preserve=mode,timestamps,links -dfr /fadumproot/. /newroot/ + cd /newroot && pivot_root . oldroot + + loop=1 + while [ $loop ]; do + unset loop + while read -r _ mp _; do + case $mp in + /oldroot/*) umount -d "$mp" && loop=1 ;; + esac + done /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 + if is_squash_available; then add_opt_module squash else dwarning "Required modules to build a squashed kdump image is missing!" @@ -1015,7 +1005,5 @@ install() { ${initdir}/etc/lvm/lvm.conf &>/dev/null # Save more memory by dropping switch root capability - if ! is_fadump_capable; then - dracut_no_switch_root - fi + dracut_no_switch_root } diff --git a/kdump-lib.sh b/kdump-lib.sh index 67ee10eb62a145f7deb9b6c600838f3a4d77fb04..bfff5461305445a015ae06a064cd6d5fbe76935b 100755 --- a/kdump-lib.sh +++ b/kdump-lib.sh @@ -19,6 +19,16 @@ is_fadump_capable() return 1 } +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 +} + perror_exit() { derror "$@" exit 1 diff --git a/kdump.conf.5 b/kdump.conf.5 index ce23dea314f4cb4b041f46da28c03d1becd83a7a..ae076df52721a43620bdc0c6bb1f0db5316b6ddf 100644 --- a/kdump.conf.5 +++ b/kdump.conf.5 @@ -118,8 +118,11 @@ All files under /etc/kdump/post.d are collectively sorted and executed in lexical order, before binary or script specified kdump_post parameter is executed. .PP -Note that scripts written for use with this directive must use -the /bin/bash interpreter. +Note that scripts written for use with this directive must use the /bin/bash +interpreter. And since these scripts run in kdump enviroment, the reference to +the storage or network device in the scripts should adhere to the section +\'Supported dump target types and requirements\' in kexec-kdump-howto.txt. + .RE .B kdump_pre @@ -139,8 +142,11 @@ kdump_pre parameter is executed. Even if the binary or script in /etc/kdump/pre.d directory returns non 0 exit status, the processing is continued. .PP -Note that scripts written for this directive must use -the /bin/bash interpreter. +Note that scripts written for use with this directive must use the /bin/bash +interpreter. And since these scripts run in kdump enviroment, the reference to +the storage or network device in the scripts should adhere to the section +\'Supported dump target types and requirements\' in kexec-kdump-howto.txt. + .RE .B extra_bins diff --git a/kdump.sysconfig.aarch64 b/kdump.sysconfig.aarch64 index 6f7830a8c3e8450a9aede5f39cce70833ff49109..2ab28932f543ae9120b2ba866982a7e1c9ba062c 100644 --- a/kdump.sysconfig.aarch64 +++ b/kdump.sysconfig.aarch64 @@ -28,7 +28,7 @@ KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices cgroup_disable=memory # # Example: # KEXEC_ARGS="--elf32-core-headers" -KEXEC_ARGS="" +KEXEC_ARGS="-s" #Where to find the boot image #KDUMP_BOOTDIR="/boot" diff --git a/kdump.sysconfig.x86_64 b/kdump.sysconfig.x86_64 index a3995d0f80565680106e0f8730a8d2cf78568ca1..b136d0ca5c53dc00134cb85a76abc342830e0daf 100644 --- a/kdump.sysconfig.x86_64 +++ b/kdump.sysconfig.x86_64 @@ -28,7 +28,7 @@ KDUMP_COMMANDLINE_APPEND="irqpoll nr_cpus=1 reset_devices cgroup_disable=memory # # Example: # KEXEC_ARGS="--elf32-core-headers" -KEXEC_ARGS="" +KEXEC_ARGS="-s" #Where to find the boot image #KDUMP_BOOTDIR="/boot" diff --git a/kdumpctl b/kdumpctl index e8a7a3af974c39e95beecbd919c78eab2344e8f0..46fa67d7bface3627f7c1a964c491d8c074504f7 100755 --- a/kdumpctl +++ b/kdumpctl @@ -8,6 +8,7 @@ KEXEC_ARGS="" KDUMP_CONFIG_FILE="/etc/kdump.conf" KDUMP_LOG_PATH="/var/log" MKDUMPRD="/sbin/mkdumprd -f" +MKFADUMPRD="/sbin/mkfadumprd" DRACUT_MODULES_FILE="/usr/lib/dracut/modules.txt" SAVE_PATH=/var/crash SSH_KEY_LOCATION="/root/.ssh/kdump_id_rsa" @@ -104,25 +105,10 @@ save_core() rebuild_fadump_initrd() { - local target_initrd_tmp - - # this file tells the initrd is fadump enabled - touch /tmp/fadump.initramfs - target_initrd_tmp="$TARGET_INITRD.tmp" - ddebug "rebuild fadump initrd: $target_initrd_tmp $DEFAULT_INITRD_BAK $KDUMP_KERNELVER" - $MKDUMPRD $target_initrd_tmp --rebuild $DEFAULT_INITRD_BAK --kver $KDUMP_KERNELVER \ - -i /tmp/fadump.initramfs /etc/fadump.initramfs - if [ $? != 0 ]; then - derror "mkdumprd: failed to rebuild initrd with fadump support" - rm -f /tmp/fadump.initramfs + if ! $MKFADUMPRD "$DEFAULT_INITRD_BAK" "$TARGET_INITRD" --kver "$KDUMP_KERNELVER"; then + derror "mkfadumprd: failed to make fadump initrd" return 1 fi - rm -f /tmp/fadump.initramfs - - # updating fadump initrd - ddebug "updating fadump initrd: $target_initrd_tmp $TARGET_INITRD" - mv $target_initrd_tmp $TARGET_INITRD - sync return 0 } @@ -464,7 +450,11 @@ check_drivers_modified() is_dracut_mod_omitted watchdog || is_dracut_mod_omitted watchdog-modules || _new_drivers+=" $(get_watchdog_drvs)" [ -z "$_new_drivers" ] && return 0 - _old_drivers="$(lsinitrd $TARGET_INITRD -f /usr/lib/dracut/loaded-kernel-modules.txt | tr '\n' ' ')" + if is_fadump_capable; then + _old_drivers="$(lsinitrd "$TARGET_INITRD" -f /usr/lib/dracut/fadump-kernel-modules.txt | tr '\n' ' ')" + else + _old_drivers="$(lsinitrd "$TARGET_INITRD" -f /usr/lib/dracut/loaded-kernel-modules.txt | tr '\n' ' ')" + fi ddebug "Modules required for kdump: '$_new_drivers'" ddebug "Modules included in old initramfs: '$_old_drivers'" @@ -617,7 +607,7 @@ check_rebuild() #in case of fadump mode, check whether the default/target #initrd is already built with dump capture capability if [ "$DEFAULT_DUMP_MODE" == "fadump" ]; then - capture_capable_initrd=$(lsinitrd -f $DRACUT_MODULES_FILE $TARGET_INITRD | grep ^kdumpbase$ | wc -l) + capture_capable_initrd=$(lsinitrd -f $DRACUT_MODULES_FILE $TARGET_INITRD | grep -e ^kdumpbase$ -e ^zz-fadumpinit$ | wc -l) fi fi @@ -960,12 +950,12 @@ selinux_relabel() return fi - for _i in $(find $_path); do - _attr=$(getfattr -m "security.selinux" $_i 2>/dev/null) + while IFS= read -r -d '' _i; do + _attr=$(getfattr -m "security.selinux" "$_i" 2>/dev/null) if [ -z "$_attr" ]; then - restorecon $_i; + restorecon "$_i"; fi - done + done < <(find "$_path" -print0) } check_fence_kdump_config() diff --git a/kexec-kdump-howto.txt b/kexec-kdump-howto.txt index 47e11c2dd6b0d553b67580e098002a0bed9d7e54..c39ca7207759b5601f256bafa0046c0604eba241 100644 --- a/kexec-kdump-howto.txt +++ b/kexec-kdump-howto.txt @@ -621,6 +621,9 @@ If /etc/kdump/post.d directory exist, All files in the directory are collectively sorted and executed in lexical order, before binary or script specified kdump_post parameter is executed. +In these scripts, the reference to the storage or network device should adhere +to the section 'Supported dump target types and requirements' + Kdump Pre-Capture Executable ---------------------------- @@ -634,6 +637,9 @@ kdump_pre parameter is executed. Even if the binary or script in /etc/kdump/pre.d directory returns non 0 exit status, the processing is continued. +In these scripts, the reference to the storage or network device should adhere +to the section 'Supported dump target types and requirements' + Extra Binaries -------------- diff --git a/kexec-tools-2.0.20-1-printk-add-support-for-lockless-ringbuffer.patch b/kexec-tools-2.0.20-1-printk-add-support-for-lockless-ringbuffer.patch new file mode 100644 index 0000000000000000000000000000000000000000..dbb208185b28be591a0740f8ddd3a76aeeba2bfd --- /dev/null +++ b/kexec-tools-2.0.20-1-printk-add-support-for-lockless-ringbuffer.patch @@ -0,0 +1,492 @@ +From 4149df9005f2cdd2ecf70058dfe7d72f48c3a68c Mon Sep 17 00:00:00 2001 +From: John Ogness +Date: Wed, 25 Nov 2020 23:26:59 +0106 +Subject: [PATCH] printk: add support for lockless ringbuffer + +Linux 5.10 moved to a new lockless ringbuffer. The new ringbuffer +is structured completely different to the previous iterations. +Add support for retrieving the ringbuffer using vmcoreinfo. The +new ringbuffer is detected based on the availability of the +"prb" symbol. + +Signed-off-by: John Ogness +Signed-off-by: Simon Horman +--- + util_lib/elf_info.c | 438 +++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 437 insertions(+), 1 deletion(-) + +diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c +index 7803a94..2f23a44 100644 +--- a/util_lib/elf_info.c ++++ b/util_lib/elf_info.c +@@ -27,6 +27,32 @@ static int num_pt_loads; + + static char osrelease[4096]; + ++/* VMCOREINFO symbols for lockless printk ringbuffer */ ++static loff_t prb_vaddr; ++static size_t printk_ringbuffer_sz; ++static size_t prb_desc_sz; ++static size_t printk_info_sz; ++static uint64_t printk_ringbuffer_desc_ring_offset; ++static uint64_t printk_ringbuffer_text_data_ring_offset; ++static uint64_t prb_desc_ring_count_bits_offset; ++static uint64_t prb_desc_ring_descs_offset; ++static uint64_t prb_desc_ring_infos_offset; ++static uint64_t prb_data_ring_size_bits_offset; ++static uint64_t prb_data_ring_data_offset; ++static uint64_t prb_desc_ring_head_id_offset; ++static uint64_t prb_desc_ring_tail_id_offset; ++static uint64_t atomic_long_t_counter_offset; ++static uint64_t prb_desc_state_var_offset; ++static uint64_t prb_desc_info_offset; ++static uint64_t prb_desc_text_blk_lpos_offset; ++static uint64_t prb_data_blk_lpos_begin_offset; ++static uint64_t prb_data_blk_lpos_next_offset; ++static uint64_t printk_info_seq_offset; ++static uint64_t printk_info_caller_id_offset; ++static uint64_t printk_info_ts_nsec_offset; ++static uint64_t printk_info_level_offset; ++static uint64_t printk_info_text_len_offset; ++ + static loff_t log_buf_vaddr; + static loff_t log_end_vaddr; + static loff_t log_buf_len_vaddr; +@@ -304,6 +330,7 @@ void scan_vmcoreinfo(char *start, size_t size) + size_t len; + loff_t *vaddr; + } symbol[] = { ++ SYMBOL(prb), + SYMBOL(log_buf), + SYMBOL(log_end), + SYMBOL(log_buf_len), +@@ -361,6 +388,119 @@ void scan_vmcoreinfo(char *start, size_t size) + *symbol[i].vaddr = vaddr; + } + ++ str = "SIZE(printk_ringbuffer)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ printk_ringbuffer_sz = strtoull(pos + strlen(str), ++ NULL, 10); ++ ++ str = "SIZE(prb_desc)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ prb_desc_sz = strtoull(pos + strlen(str), NULL, 10); ++ ++ str = "SIZE(printk_info)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ printk_info_sz = strtoull(pos + strlen(str), NULL, 10); ++ ++ str = "OFFSET(printk_ringbuffer.desc_ring)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ printk_ringbuffer_desc_ring_offset = ++ strtoull(pos + strlen(str), NULL, 10); ++ ++ str = "OFFSET(printk_ringbuffer.text_data_ring)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ printk_ringbuffer_text_data_ring_offset = ++ strtoull(pos + strlen(str), NULL, 10); ++ ++ str = "OFFSET(prb_desc_ring.count_bits)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ prb_desc_ring_count_bits_offset = ++ strtoull(pos + strlen(str), NULL, 10); ++ ++ str = "OFFSET(prb_desc_ring.descs)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ prb_desc_ring_descs_offset = ++ strtoull(pos + strlen(str), NULL, 10); ++ ++ str = "OFFSET(prb_desc_ring.infos)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ prb_desc_ring_infos_offset = ++ strtoull(pos + strlen(str), NULL, 10); ++ ++ str = "OFFSET(prb_data_ring.size_bits)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ prb_data_ring_size_bits_offset = ++ strtoull(pos + strlen(str), NULL, 10); ++ ++ str = "OFFSET(prb_data_ring.data)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ prb_data_ring_data_offset = ++ strtoull(pos + strlen(str), NULL, 10); ++ ++ str = "OFFSET(prb_desc_ring.head_id)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ prb_desc_ring_head_id_offset = ++ strtoull(pos + strlen(str), NULL, 10); ++ ++ str = "OFFSET(prb_desc_ring.tail_id)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ prb_desc_ring_tail_id_offset = ++ strtoull(pos + strlen(str), NULL, 10); ++ ++ str = "OFFSET(atomic_long_t.counter)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ atomic_long_t_counter_offset = ++ strtoull(pos + strlen(str), NULL, 10); ++ ++ str = "OFFSET(prb_desc.state_var)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ prb_desc_state_var_offset = ++ strtoull(pos + strlen(str), NULL, 10); ++ ++ str = "OFFSET(prb_desc.info)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ prb_desc_info_offset = ++ strtoull(pos + strlen(str), NULL, 10); ++ ++ str = "OFFSET(prb_desc.text_blk_lpos)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ prb_desc_text_blk_lpos_offset = ++ strtoull(pos + strlen(str), NULL, 10); ++ ++ str = "OFFSET(prb_data_blk_lpos.begin)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ prb_data_blk_lpos_begin_offset = ++ strtoull(pos + strlen(str), NULL, 10); ++ ++ str = "OFFSET(prb_data_blk_lpos.next)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ prb_data_blk_lpos_next_offset = ++ strtoull(pos + strlen(str), NULL, 10); ++ ++ str = "OFFSET(printk_info.seq)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ printk_info_seq_offset = ++ strtoull(pos + strlen(str), NULL, 10); ++ ++ str = "OFFSET(printk_info.caller_id)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ printk_info_caller_id_offset = ++ strtoull(pos + strlen(str), NULL, 10); ++ ++ str = "OFFSET(printk_info.ts_nsec)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ printk_info_ts_nsec_offset = ++ strtoull(pos + strlen(str), NULL, 10); ++ ++ str = "OFFSET(printk_info.level)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ printk_info_level_offset = ++ strtoull(pos + strlen(str), NULL, 10); ++ ++ str = "OFFSET(printk_info.text_len)="; ++ if (memcmp(str, pos, strlen(str)) == 0) ++ printk_info_text_len_offset = ++ strtoull(pos + strlen(str), NULL, 10); ++ + /* Check for "SIZE(printk_log)" or older "SIZE(log)=" */ + str = "SIZE(log)="; + if (memcmp(str, pos, strlen(str)) == 0) +@@ -746,9 +886,305 @@ static void dump_dmesg_structured(int fd, void (*handler)(char*, unsigned int)) + handler(out_buf, len); + } + ++/* convenience struct for passing many values to helper functions */ ++struct prb_map { ++ char *prb; ++ ++ char *desc_ring; ++ unsigned long desc_ring_count; ++ char *descs; ++ ++ char *infos; ++ ++ char *text_data_ring; ++ unsigned long text_data_ring_size; ++ char *text_data; ++}; ++ ++/* ++ * desc_state and DESC_* definitions taken from kernel source: ++ * ++ * kernel/printk/printk_ringbuffer.h ++ * ++ * DESC_* definitions modified to provide 32-bit and 64-bit variants. ++ */ ++ ++/* The possible responses of a descriptor state-query. */ ++enum desc_state { ++ desc_miss = -1, /* ID mismatch (pseudo state) */ ++ desc_reserved = 0x0, /* reserved, in use by writer */ ++ desc_committed = 0x1, /* committed by writer, could get reopened */ ++ desc_finalized = 0x2, /* committed, no further modification allowed */ ++ desc_reusable = 0x3, /* free, not yet used by any writer */ ++}; ++ ++#define DESC_SV_BITS (sizeof(uint64_t) * 8) ++#define DESC_FLAGS_SHIFT (DESC_SV_BITS - 2) ++#define DESC_FLAGS_MASK (3UL << DESC_FLAGS_SHIFT) ++#define DESC_STATE(sv) (3UL & (sv >> DESC_FLAGS_SHIFT)) ++#define DESC_ID_MASK (~DESC_FLAGS_MASK) ++#define DESC_ID(sv) ((sv) & DESC_ID_MASK) ++ ++#define DESC32_SV_BITS (sizeof(uint32_t) * 8) ++#define DESC32_FLAGS_SHIFT (DESC32_SV_BITS - 2) ++#define DESC32_FLAGS_MASK (3UL << DESC32_FLAGS_SHIFT) ++#define DESC32_STATE(sv) (3UL & (sv >> DESC32_FLAGS_SHIFT)) ++#define DESC32_ID_MASK (~DESC32_FLAGS_MASK) ++#define DESC32_ID(sv) ((sv) & DESC32_ID_MASK) ++ ++/* ++ * get_desc_state() taken from kernel source: ++ * ++ * kernel/printk/printk_ringbuffer.c ++ * ++ * get_desc32_state() added as 32-bit variant. ++ */ ++ ++/* Query the state of a descriptor. */ ++static enum desc_state get_desc_state(unsigned long id, ++ uint64_t state_val) ++{ ++ if (id != DESC_ID(state_val)) ++ return desc_miss; ++ ++ return DESC_STATE(state_val); ++} ++ ++static enum desc_state get_desc32_state(unsigned long id, ++ uint64_t state_val) ++{ ++ if (id != DESC32_ID(state_val)) ++ return desc_miss; ++ ++ return DESC32_STATE(state_val); ++} ++ ++static bool record_committed(unsigned long id, uint64_t state_var) ++{ ++ enum desc_state state; ++ ++ if (machine_pointer_bits() == 32) ++ state = get_desc32_state(id, state_var); ++ else ++ state = get_desc_state(id, state_var); ++ ++ return (state == desc_committed || state == desc_finalized); ++} ++ ++static uint64_t id_inc(uint64_t id) ++{ ++ id++; ++ ++ if (machine_pointer_bits() == 32) ++ return (id & DESC32_ID_MASK); ++ ++ return (id & DESC_ID_MASK); ++} ++ ++static uint64_t get_ulong(char *addr) ++{ ++ if (machine_pointer_bits() == 32) ++ return struct_val_u32(addr, 0); ++ return struct_val_u64(addr, 0); ++} ++ ++static uint64_t sizeof_ulong(void) ++{ ++ return (machine_pointer_bits() >> 3); ++} ++ ++static void dump_record(struct prb_map *m, unsigned long id, ++ void (*handler)(char*, unsigned int)) ++{ ++#define OUT_BUF_SIZE 4096 ++ char out_buf[OUT_BUF_SIZE]; ++ imaxdiv_t imaxdiv_usec; ++ imaxdiv_t imaxdiv_sec; ++ uint32_t offset = 0; ++ unsigned short len; ++ uint64_t state_var; ++ uint64_t ts_nsec; ++ uint64_t begin; ++ uint64_t next; ++ char *info; ++ char *text; ++ char *desc; ++ int i; ++ ++ desc = m->descs + ((id % m->desc_ring_count) * prb_desc_sz); ++ info = m->infos + ((id % m->desc_ring_count) * printk_info_sz); ++ ++ /* skip non-committed record */ ++ state_var = get_ulong(desc + prb_desc_state_var_offset + ++ atomic_long_t_counter_offset); ++ if (!record_committed(id, state_var)) ++ return; ++ ++ begin = get_ulong(desc + prb_desc_text_blk_lpos_offset + ++ prb_data_blk_lpos_begin_offset) % ++ m->text_data_ring_size; ++ next = get_ulong(desc + prb_desc_text_blk_lpos_offset + ++ prb_data_blk_lpos_next_offset) % ++ m->text_data_ring_size; ++ ++ ts_nsec = struct_val_u64(info, printk_info_ts_nsec_offset); ++ imaxdiv_sec = imaxdiv(ts_nsec, 1000000000); ++ imaxdiv_usec = imaxdiv(imaxdiv_sec.rem, 1000); ++ ++ offset += sprintf(out_buf + offset, "[%5llu.%06llu] ", ++ (long long unsigned int)imaxdiv_sec.quot, ++ (long long unsigned int)imaxdiv_usec.quot); ++ ++ /* skip data-less text blocks */ ++ if (begin == next) ++ goto out; ++ ++ len = struct_val_u16(info, printk_info_text_len_offset); ++ ++ /* handle wrapping data block */ ++ if (begin > next) ++ begin = 0; ++ ++ /* skip over descriptor ID */ ++ begin += sizeof_ulong(); ++ ++ /* handle truncated messages */ ++ if (next - begin < len) ++ len = next - begin; ++ ++ text = m->text_data + begin; ++ ++ /* escape non-printable characters */ ++ for (i = 0; i < len; i++) { ++ unsigned char c = text[i]; ++ ++ if (!isprint(c) && !isspace(c)) ++ offset += sprintf(out_buf + offset, "\\x%02x", c); ++ else ++ out_buf[offset++] = c; ++ ++ if (offset >= OUT_BUF_SIZE - 64) { ++ if (handler) ++ handler(out_buf, offset); ++ offset = 0; ++ } ++ } ++out: ++ out_buf[offset++] = '\n'; ++ ++ if (offset && handler) ++ handler(out_buf, offset); ++} ++ ++/* ++ * Handle the lockless printk_ringbuffer. ++ */ ++static void dump_dmesg_lockless(int fd, void (*handler)(char*, unsigned int)) ++{ ++ struct prb_map m; ++ uint64_t head_id; ++ uint64_t tail_id; ++ uint64_t kaddr; ++ uint64_t id; ++ int ret; ++ ++ /* setup printk_ringbuffer */ ++ kaddr = read_file_pointer(fd, vaddr_to_offset(prb_vaddr)); ++ m.prb = calloc(1, printk_ringbuffer_sz); ++ if (!m.prb) { ++ fprintf(stderr, "Failed to malloc %lu bytes for prb: %s\n", ++ printk_ringbuffer_sz, strerror(errno)); ++ exit(64); ++ } ++ ret = pread(fd, m.prb, printk_ringbuffer_sz, vaddr_to_offset(kaddr)); ++ if (ret != printk_ringbuffer_sz) { ++ fprintf(stderr, "Failed to read prb of size %lu bytes: %s\n", ++ printk_ringbuffer_sz, strerror(errno)); ++ exit(65); ++ } ++ ++ /* setup descriptor ring */ ++ m.desc_ring = m.prb + printk_ringbuffer_desc_ring_offset; ++ m.desc_ring_count = 1 << struct_val_u32(m.desc_ring, ++ prb_desc_ring_count_bits_offset); ++ kaddr = get_ulong(m.desc_ring + prb_desc_ring_descs_offset); ++ m.descs = calloc(1, prb_desc_sz * m.desc_ring_count); ++ if (!m.descs) { ++ fprintf(stderr, "Failed to malloc %lu bytes for descs: %s\n", ++ prb_desc_sz * m.desc_ring_count, strerror(errno)); ++ exit(64); ++ } ++ ret = pread(fd, m.descs, prb_desc_sz * m.desc_ring_count, ++ vaddr_to_offset(kaddr)); ++ if (ret != prb_desc_sz * m.desc_ring_count) { ++ fprintf(stderr, ++ "Failed to read descs of size %lu bytes: %s\n", ++ prb_desc_sz * m.desc_ring_count, strerror(errno)); ++ exit(65); ++ } ++ ++ /* setup info ring */ ++ kaddr = get_ulong(m.prb + prb_desc_ring_infos_offset); ++ m.infos = calloc(1, printk_info_sz * m.desc_ring_count); ++ if (!m.infos) { ++ fprintf(stderr, "Failed to malloc %lu bytes for infos: %s\n", ++ printk_info_sz * m.desc_ring_count, strerror(errno)); ++ exit(64); ++ } ++ ret = pread(fd, m.infos, printk_info_sz * m.desc_ring_count, ++ vaddr_to_offset(kaddr)); ++ if (ret != printk_info_sz * m.desc_ring_count) { ++ fprintf(stderr, ++ "Failed to read infos of size %lu bytes: %s\n", ++ printk_info_sz * m.desc_ring_count, strerror(errno)); ++ exit(65); ++ } ++ ++ /* setup text data ring */ ++ m.text_data_ring = m.prb + printk_ringbuffer_text_data_ring_offset; ++ m.text_data_ring_size = 1 << struct_val_u32(m.text_data_ring, ++ prb_data_ring_size_bits_offset); ++ kaddr = get_ulong(m.text_data_ring + prb_data_ring_data_offset); ++ m.text_data = calloc(1, m.text_data_ring_size); ++ if (!m.text_data) { ++ fprintf(stderr, ++ "Failed to malloc %lu bytes for text_data: %s\n", ++ m.text_data_ring_size, strerror(errno)); ++ exit(64); ++ } ++ ret = pread(fd, m.text_data, m.text_data_ring_size, ++ vaddr_to_offset(kaddr)); ++ if (ret != m.text_data_ring_size) { ++ fprintf(stderr, ++ "Failed to read text_data of size %lu bytes: %s\n", ++ m.text_data_ring_size, strerror(errno)); ++ exit(65); ++ } ++ ++ /* ready to go */ ++ ++ tail_id = get_ulong(m.desc_ring + prb_desc_ring_tail_id_offset + ++ atomic_long_t_counter_offset); ++ head_id = get_ulong(m.desc_ring + prb_desc_ring_head_id_offset + ++ atomic_long_t_counter_offset); ++ ++ for (id = tail_id; id != head_id; id = id_inc(id)) ++ dump_record(&m, id, handler); ++ ++ /* dump head record */ ++ dump_record(&m, id, handler); ++ ++ free(m.text_data); ++ free(m.infos); ++ free(m.descs); ++ free(m.prb); ++} ++ + void dump_dmesg(int fd, void (*handler)(char*, unsigned int)) + { +- if (log_first_idx_vaddr) ++ if (prb_vaddr) ++ dump_dmesg_lockless(fd, handler); ++ else if (log_first_idx_vaddr) + dump_dmesg_structured(fd, handler); + else + dump_dmesg_legacy(fd, handler); +-- +2.31.1 + diff --git a/kexec-tools-2.0.20-2-printk-Use-ULL-suffix-for-64-bit-constants.patch b/kexec-tools-2.0.20-2-printk-Use-ULL-suffix-for-64-bit-constants.patch new file mode 100644 index 0000000000000000000000000000000000000000..f40cd3e06ecea701ea417b28ad56f3dbcd562c4c --- /dev/null +++ b/kexec-tools-2.0.20-2-printk-Use-ULL-suffix-for-64-bit-constants.patch @@ -0,0 +1,65 @@ +From 07b272a07164b902acd7d12794f7be033ebf4525 Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven +Date: Wed, 17 Mar 2021 13:14:49 +0100 +Subject: [PATCH] printk: Use ULL suffix for 64-bit constants +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When compiling for 32-bit: + + util_lib/elf_info.c: In function ‘get_desc_state’: + util_lib/elf_info.c:923:31: warning: left shift count >= width of type [-Wshift-count-overflow] + 923 | #define DESC_FLAGS_MASK (3UL << DESC_FLAGS_SHIFT) + | ^~ + util_lib/elf_info.c:925:25: note: in expansion of macro ‘DESC_FLAGS_MASK’ + 925 | #define DESC_ID_MASK (~DESC_FLAGS_MASK) + | ^~~~~~~~~~~~~~~ + util_lib/elf_info.c:926:30: note: in expansion of macro ‘DESC_ID_MASK’ + 926 | #define DESC_ID(sv) ((sv) & DESC_ID_MASK) + | ^~~~~~~~~~~~ + util_lib/elf_info.c:947:12: note: in expansion of macro ‘DESC_ID’ + 947 | if (id != DESC_ID(state_val)) + | ^~~~~~~ + util_lib/elf_info.c: In function ‘id_inc’: + util_lib/elf_info.c:923:31: warning: left shift count >= width of type [-Wshift-count-overflow] + 923 | #define DESC_FLAGS_MASK (3UL << DESC_FLAGS_SHIFT) + | ^~ + util_lib/elf_info.c:925:25: note: in expansion of macro ‘DESC_FLAGS_MASK’ + 925 | #define DESC_ID_MASK (~DESC_FLAGS_MASK) + | ^~~~~~~~~~~~~~~ + util_lib/elf_info.c:981:15: note: in expansion of macro ‘DESC_ID_MASK’ + 981 | return (id & DESC_ID_MASK); + | ^~~~~~~~~~~~ + +Indeed, "unsigned long" constants are 32-bit on 32-bit platforms, and +64-bit on 64-bit platforms. + +Fix this by using a "ULL" suffix instead. + +Fixes: 4149df9005f2cdd2 ("printk: add support for lockless ringbuffer") +Signed-off-by: Geert Uytterhoeven +Reviewed-by: John Ogness +Signed-off-by: Simon Horman +--- + util_lib/elf_info.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c +index 2f23a44..7c0a2c3 100644 +--- a/util_lib/elf_info.c ++++ b/util_lib/elf_info.c +@@ -920,8 +920,8 @@ enum desc_state { + + #define DESC_SV_BITS (sizeof(uint64_t) * 8) + #define DESC_FLAGS_SHIFT (DESC_SV_BITS - 2) +-#define DESC_FLAGS_MASK (3UL << DESC_FLAGS_SHIFT) +-#define DESC_STATE(sv) (3UL & (sv >> DESC_FLAGS_SHIFT)) ++#define DESC_FLAGS_MASK (3ULL << DESC_FLAGS_SHIFT) ++#define DESC_STATE(sv) (3ULL & (sv >> DESC_FLAGS_SHIFT)) + #define DESC_ID_MASK (~DESC_FLAGS_MASK) + #define DESC_ID(sv) ((sv) & DESC_ID_MASK) + +-- +2.31.1 + diff --git a/kexec-tools-2.0.20-3-printk-Use-zu-to-format-size_t.patch b/kexec-tools-2.0.20-3-printk-Use-zu-to-format-size_t.patch new file mode 100644 index 0000000000000000000000000000000000000000..29ac6fc532632e98681c43d521dac9a395c2b027 --- /dev/null +++ b/kexec-tools-2.0.20-3-printk-Use-zu-to-format-size_t.patch @@ -0,0 +1,68 @@ +From 82f7de2724c42a6aecc0cff93881b3dfd09363ce Mon Sep 17 00:00:00 2001 +From: Geert Uytterhoeven +Date: Wed, 17 Mar 2021 13:14:50 +0100 +Subject: [PATCH] printk: Use %zu to format size_t +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When compiling for 32-bit: + + util_lib/elf_info.c: In function ‘dump_dmesg_lockless’: + util_lib/elf_info.c:1095:39: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 3 has type ‘size_t’ {aka ‘unsigned int’} [-Wformat=] + 1095 | fprintf(stderr, "Failed to malloc %lu bytes for prb: %s\n", + | ~~^ + | | + | long unsigned int + | %u + 1096 | printk_ringbuffer_sz, strerror(errno)); + | ~~~~~~~~~~~~~~~~~~~~ + | | + | size_t {aka unsigned int} + util_lib/elf_info.c:1101:49: warning: format ‘%lu’ expects argument of type ‘long unsigned int’, but argument 3 has type ‘size_t’ {aka ‘unsigned int’} [-Wformat=] + 1101 | fprintf(stderr, "Failed to read prb of size %lu bytes: %s\n", + | ~~^ + | | + | long unsigned int + | %u + 1102 | printk_ringbuffer_sz, strerror(errno)); + | ~~~~~~~~~~~~~~~~~~~~ + | | + | size_t {aka unsigned int} + +Indeed, "size_t" is "unsigned int" on 32-bit platforms, and "unsigned +long" on 64-bit platforms. + +Fix this by formatting using "%zu". + +Fixes: 4149df9005f2cdd2 ("printk: add support for lockless ringbuffer") +Signed-off-by: Geert Uytterhoeven +Reviewed-by: John Ogness +Signed-off-by: Simon Horman +--- + util_lib/elf_info.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c +index 7c0a2c3..676926c 100644 +--- a/util_lib/elf_info.c ++++ b/util_lib/elf_info.c +@@ -1092,13 +1092,13 @@ static void dump_dmesg_lockless(int fd, void (*handler)(char*, unsigned int)) + kaddr = read_file_pointer(fd, vaddr_to_offset(prb_vaddr)); + m.prb = calloc(1, printk_ringbuffer_sz); + if (!m.prb) { +- fprintf(stderr, "Failed to malloc %lu bytes for prb: %s\n", ++ fprintf(stderr, "Failed to malloc %zu bytes for prb: %s\n", + printk_ringbuffer_sz, strerror(errno)); + exit(64); + } + ret = pread(fd, m.prb, printk_ringbuffer_sz, vaddr_to_offset(kaddr)); + if (ret != printk_ringbuffer_sz) { +- fprintf(stderr, "Failed to read prb of size %lu bytes: %s\n", ++ fprintf(stderr, "Failed to read prb of size %zu bytes: %s\n", + printk_ringbuffer_sz, strerror(errno)); + exit(65); + } +-- +2.31.1 + diff --git a/kexec-tools-2.0.20-Cleanup-move-it-back-from-util_lib-elf_info.c.patch b/kexec-tools-2.0.20-Cleanup-move-it-back-from-util_lib-elf_info.c.patch new file mode 100644 index 0000000000000000000000000000000000000000..b8759ee427dcc8042a500da45944d92fecae5fbe --- /dev/null +++ b/kexec-tools-2.0.20-Cleanup-move-it-back-from-util_lib-elf_info.c.patch @@ -0,0 +1,181 @@ +From a7c4cb8e998571cb3dd62e907935a1e052b15d6c Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +Date: Fri, 23 Aug 2019 20:05:38 +0800 +Subject: [PATCH 3/5] Cleanup: move it back from util_lib/elf_info.c + +Some code related to vmcore-dmesg.c is put into the util_lib, which +is not very reasonable, so lets move it back and tidy up those code. + +In addition, that will also help to limit the size of vmcore-dmesg.txt +in vmcore-dmesg.c instead of elf_info.c. + +Signed-off-by: Lianbo Jiang +Signed-off-by: Simon Horman +--- + util_lib/elf_info.c | 48 +++++++++---------------------------- + util_lib/include/elf_info.h | 2 +- + vmcore-dmesg/vmcore-dmesg.c | 30 ++++++++++++++++++++++- + 3 files changed, 41 insertions(+), 39 deletions(-) + +diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c +index 5d0efaafab53..2bce5cb1713c 100644 +--- a/util_lib/elf_info.c ++++ b/util_lib/elf_info.c +@@ -531,19 +531,7 @@ static int32_t read_file_s32(int fd, uint64_t addr) + return read_file_u32(fd, addr); + } + +-static void write_to_stdout(char *buf, unsigned int nr) +-{ +- ssize_t ret; +- +- ret = write(STDOUT_FILENO, buf, nr); +- if (ret != nr) { +- fprintf(stderr, "Failed to write out the dmesg log buffer!:" +- " %s\n", strerror(errno)); +- exit(54); +- } +-} +- +-static void dump_dmesg_legacy(int fd) ++static void dump_dmesg_legacy(int fd, void (*handler)(char*, unsigned int)) + { + uint64_t log_buf, log_buf_offset; + unsigned log_end, logged_chars, log_end_wrapped; +@@ -604,7 +592,8 @@ static void dump_dmesg_legacy(int fd) + */ + logged_chars = log_end < log_buf_len ? log_end : log_buf_len; + +- write_to_stdout(buf + (log_buf_len - logged_chars), logged_chars); ++ if (handler) ++ handler(buf + (log_buf_len - logged_chars), logged_chars); + } + + static inline uint16_t struct_val_u16(char *ptr, unsigned int offset) +@@ -623,7 +612,7 @@ static inline uint64_t struct_val_u64(char *ptr, unsigned int offset) + } + + /* Read headers of log records and dump accordingly */ +-static void dump_dmesg_structured(int fd) ++static void dump_dmesg_structured(int fd, void (*handler)(char*, unsigned int)) + { + #define OUT_BUF_SIZE 4096 + uint64_t log_buf, log_buf_offset, ts_nsec; +@@ -733,7 +722,8 @@ static void dump_dmesg_structured(int fd) + out_buf[len++] = c; + + if (len >= OUT_BUF_SIZE - 64) { +- write_to_stdout(out_buf, len); ++ if (handler) ++ handler(out_buf, len); + len = 0; + } + } +@@ -752,16 +742,16 @@ static void dump_dmesg_structured(int fd) + current_idx += loglen; + } + free(buf); +- if (len) +- write_to_stdout(out_buf, len); ++ if (len && handler) ++ handler(out_buf, len); + } + +-static void dump_dmesg(int fd) ++void dump_dmesg(int fd, void (*handler)(char*, unsigned int)) + { + if (log_first_idx_vaddr) +- dump_dmesg_structured(fd); ++ dump_dmesg_structured(fd, handler); + else +- dump_dmesg_legacy(fd); ++ dump_dmesg_legacy(fd, handler); + } + + int read_elf(int fd) +@@ -808,22 +798,6 @@ int read_elf(int fd) + return 0; + } + +-int read_elf_vmcore(int fd) +-{ +- int ret; +- +- ret = read_elf(fd); +- if (ret > 0) { +- fprintf(stderr, "Unable to read ELF information" +- " from vmcore\n"); +- return ret; +- } +- +- dump_dmesg(fd); +- +- return 0; +-} +- + int read_phys_offset_elf_kcore(int fd, unsigned long *phys_off) + { + int ret; +diff --git a/util_lib/include/elf_info.h b/util_lib/include/elf_info.h +index c328a1b0ecf2..4bc9279ba603 100644 +--- a/util_lib/include/elf_info.h ++++ b/util_lib/include/elf_info.h +@@ -30,6 +30,6 @@ int get_pt_load(int idx, + unsigned long long *virt_end); + int read_phys_offset_elf_kcore(int fd, unsigned long *phys_off); + int read_elf(int fd); +-int read_elf_vmcore(int fd); ++void dump_dmesg(int fd, void (*handler)(char*, unsigned int)); + + #endif /* ELF_INFO_H */ +diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c +index bebc348a657e..fe7df8ec372c 100644 +--- a/vmcore-dmesg/vmcore-dmesg.c ++++ b/vmcore-dmesg/vmcore-dmesg.c +@@ -5,6 +5,34 @@ typedef Elf32_Nhdr Elf_Nhdr; + + extern const char *fname; + ++static void write_to_stdout(char *buf, unsigned int nr) ++{ ++ ssize_t ret; ++ ++ ret = write(STDOUT_FILENO, buf, nr); ++ if (ret != nr) { ++ fprintf(stderr, "Failed to write out the dmesg log buffer!:" ++ " %s\n", strerror(errno)); ++ exit(54); ++ } ++} ++ ++static int read_vmcore_dmesg(int fd, void (*handler)(char*, unsigned int)) ++{ ++ int ret; ++ ++ ret = read_elf(fd); ++ if (ret > 0) { ++ fprintf(stderr, "Unable to read ELF information" ++ " from vmcore\n"); ++ return ret; ++ } ++ ++ dump_dmesg(fd, handler); ++ ++ return 0; ++} ++ + int main(int argc, char **argv) + { + ssize_t ret; +@@ -23,7 +51,7 @@ int main(int argc, char **argv) + return 2; + } + +- ret = read_elf_vmcore(fd); ++ ret = read_vmcore_dmesg(fd, write_to_stdout); + + close(fd); + +-- +2.17.1 + diff --git a/kexec-tools-2.0.20-Cleanup-remove-the-read_elf_kcore.patch b/kexec-tools-2.0.20-Cleanup-remove-the-read_elf_kcore.patch new file mode 100644 index 0000000000000000000000000000000000000000..f47b8f60e219b8bc5e509e3dc594a3797bb6c54f --- /dev/null +++ b/kexec-tools-2.0.20-Cleanup-remove-the-read_elf_kcore.patch @@ -0,0 +1,84 @@ +From 545c811050a375f79e0fa0e107cb35b9ae3a1599 Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +Date: Fri, 23 Aug 2019 20:05:36 +0800 +Subject: [PATCH 1/5] Cleanup: remove the read_elf_kcore() + +Here, no need to wrap the read_elf() again, lets invoke it directly. +So remove the read_elf_kcore() and clean up redundant code. + +Signed-off-by: Lianbo Jiang +Signed-off-by: Simon Horman +--- + kexec/arch/arm64/kexec-arm64.c | 2 +- + util_lib/elf_info.c | 15 ++------------- + util_lib/include/elf_info.h | 2 +- + 3 files changed, 4 insertions(+), 15 deletions(-) + +diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c +index eb3a3a37307c..6ad3b0a134b3 100644 +--- a/kexec/arch/arm64/kexec-arm64.c ++++ b/kexec/arch/arm64/kexec-arm64.c +@@ -889,7 +889,7 @@ int get_phys_base_from_pt_load(unsigned long *phys_offset) + return EFAILED; + } + +- read_elf_kcore(fd); ++ read_elf(fd); + + for (i = 0; get_pt_load(i, + &phys_start, NULL, &virt_start, NULL); +diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c +index 90a3b21662e7..d9397ecd8626 100644 +--- a/util_lib/elf_info.c ++++ b/util_lib/elf_info.c +@@ -764,7 +764,7 @@ static void dump_dmesg(int fd) + dump_dmesg_legacy(fd); + } + +-static int read_elf(int fd) ++int read_elf(int fd) + { + int ret; + +@@ -824,24 +824,13 @@ int read_elf_vmcore(int fd) + return 0; + } + +-int read_elf_kcore(int fd) +-{ +- int ret; +- +- ret = read_elf(fd); +- if (ret != 0) +- return ret; +- +- return 0; +-} +- + int read_phys_offset_elf_kcore(int fd, unsigned long *phys_off) + { + int ret; + + *phys_off = UINT64_MAX; + +- ret = read_elf_kcore(fd); ++ ret = read_elf(fd); + if (!ret) { + /* If we have a valid 'PHYS_OFFSET' by now, + * return it to the caller now. +diff --git a/util_lib/include/elf_info.h b/util_lib/include/elf_info.h +index 1a4debd2d4ba..c328a1b0ecf2 100644 +--- a/util_lib/include/elf_info.h ++++ b/util_lib/include/elf_info.h +@@ -29,7 +29,7 @@ int get_pt_load(int idx, + unsigned long long *virt_start, + unsigned long long *virt_end); + int read_phys_offset_elf_kcore(int fd, unsigned long *phys_off); +-int read_elf_kcore(int fd); ++int read_elf(int fd); + int read_elf_vmcore(int fd); + + #endif /* ELF_INFO_H */ +-- +2.17.1 + diff --git a/kexec-tools-2.0.20-Fix-an-error-definition-about-the-variable-fname.patch b/kexec-tools-2.0.20-Fix-an-error-definition-about-the-variable-fname.patch new file mode 100644 index 0000000000000000000000000000000000000000..d68b2115735df7f52bf48819586a315e6e223416 --- /dev/null +++ b/kexec-tools-2.0.20-Fix-an-error-definition-about-the-variable-fname.patch @@ -0,0 +1,47 @@ +From 14ad054e7baa788a6629385ffe5e0f1996b7de02 Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +Date: Fri, 23 Aug 2019 20:05:37 +0800 +Subject: [PATCH 2/5] Fix an error definition about the variable 'fname' + +The variable 'fname' is mistakenly defined two twice, the first definition +is in the vmcore-dmesg.c, and the second definition is in the elf_info.c. +That is confused and incorrect although it's a static type, because the +value of variable 'fname' is not assigned(set) in elf_info.c. Anyway, its +value will be always 'null' when printing an error information. + +Signed-off-by: Lianbo Jiang +Signed-off-by: Simon Horman +--- + util_lib/elf_info.c | 2 +- + vmcore-dmesg/vmcore-dmesg.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/util_lib/elf_info.c b/util_lib/elf_info.c +index d9397ecd8626..5d0efaafab53 100644 +--- a/util_lib/elf_info.c ++++ b/util_lib/elf_info.c +@@ -20,7 +20,7 @@ + /* The 32bit and 64bit note headers make it clear we don't care */ + typedef Elf32_Nhdr Elf_Nhdr; + +-static const char *fname; ++const char *fname; + static Elf64_Ehdr ehdr; + static Elf64_Phdr *phdr; + static int num_pt_loads; +diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c +index 7a386b380291..bebc348a657e 100644 +--- a/vmcore-dmesg/vmcore-dmesg.c ++++ b/vmcore-dmesg/vmcore-dmesg.c +@@ -3,7 +3,7 @@ + /* The 32bit and 64bit note headers make it clear we don't care */ + typedef Elf32_Nhdr Elf_Nhdr; + +-static const char *fname; ++extern const char *fname; + + int main(int argc, char **argv) + { +-- +2.17.1 + diff --git a/kexec-tools-2.0.20-Limit-the-size-of-vmcore-dmesg.txt-to-2G.patch b/kexec-tools-2.0.20-Limit-the-size-of-vmcore-dmesg.txt-to-2G.patch new file mode 100644 index 0000000000000000000000000000000000000000..0146da0bab298617434e8f1dacba27b13b52c67b --- /dev/null +++ b/kexec-tools-2.0.20-Limit-the-size-of-vmcore-dmesg.txt-to-2G.patch @@ -0,0 +1,55 @@ +From fa3f0ed47f3e6dbee485722d13713ad495571b7e Mon Sep 17 00:00:00 2001 +From: Lianbo Jiang +Date: Fri, 23 Aug 2019 20:05:39 +0800 +Subject: [PATCH 4/5] Limit the size of vmcore-dmesg.txt to 2G + +With some corrupted vmcore files, the vmcore-dmesg.txt file may grow +forever till the kdump disk becomes full, and also probably causes +the disk error messages as follow: +... +sd 0:0:0:0: [sda] tag#6 FAILED Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK +sd 0:0:0:0: [sda] tag#6 CDB: Read(10) 28 00 08 06 4c 98 00 00 08 00 +blk_update_request: I/O error, dev sda, sector 134630552 +sd 0:0:0:0: [sda] tag#7 FAILED Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK +sd 0:0:0:0: [sda] tag#7 CDB: Read(10) 28 00 08 06 4c 98 00 00 08 00 +blk_update_request: I/O error, dev sda, sector 134630552 +... + +If vmcore-dmesg.txt occupies the whole disk, the vmcore can not be +saved, this is also a problem. + +Lets limit the size of vmcore-dmesg.txt to avoid such problems. + +Signed-off-by: Lianbo Jiang +Signed-off-by: Simon Horman +--- + vmcore-dmesg/vmcore-dmesg.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/vmcore-dmesg/vmcore-dmesg.c b/vmcore-dmesg/vmcore-dmesg.c +index fe7df8ec372c..81c2a58c9d86 100644 +--- a/vmcore-dmesg/vmcore-dmesg.c ++++ b/vmcore-dmesg/vmcore-dmesg.c +@@ -5,9 +5,19 @@ typedef Elf32_Nhdr Elf_Nhdr; + + extern const char *fname; + ++/* stole this macro from kernel printk.c */ ++#define LOG_BUF_LEN_MAX (uint32_t)(1 << 31) ++ + static void write_to_stdout(char *buf, unsigned int nr) + { + ssize_t ret; ++ static uint32_t n_bytes = 0; ++ ++ n_bytes += nr; ++ if (n_bytes > LOG_BUF_LEN_MAX) { ++ fprintf(stderr, "The vmcore-dmesg.txt over 2G in size is not supported.\n"); ++ exit(53); ++ } + + ret = write(STDOUT_FILENO, buf, nr); + if (ret != nr) { +-- +2.17.1 + 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..d54f45a603009a06c9f2a9f7d12b27646e576466 --- /dev/null +++ b/kexec-tools-2.0.20-Remove-duplicated-variable-declarations.patch @@ -0,0 +1,99 @@ +From cc087b11462af9f971a2c090d07e8d780a867b50 Mon Sep 17 00:00:00 2001 +From: Kairui Song +Date: Wed, 29 Jan 2020 13:38:19 +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 +Signed-off-by: Simon Horman +--- + 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.7.5 + diff --git a/kexec-tools-2.0.20-arm64-kdump-deal-with-a-lot-of-resource-entries-in-p.patch b/kexec-tools-2.0.20-arm64-kdump-deal-with-a-lot-of-resource-entries-in-p.patch new file mode 100644 index 0000000000000000000000000000000000000000..1f51eb270288ade39dfcc5c26c1bce7adf6413c4 --- /dev/null +++ b/kexec-tools-2.0.20-arm64-kdump-deal-with-a-lot-of-resource-entries-in-p.patch @@ -0,0 +1,82 @@ +From 2572b8d702e452624bdb8d7b7c39f458e7dcf2ce Mon Sep 17 00:00:00 2001 +From: AKASHI Takahiro +Date: Wed, 18 Dec 2019 11:42:32 -0500 +Subject: [PATCH 3/3] arm64: kdump: deal with a lot of resource entries in + /proc/iomem + +As described in the commit ("arm64: kexec: allocate memory space avoiding +reserved regions"), /proc/iomem now has a lot of "reserved" entries, and +it's not just enough to have a fixed size of memory range array. + +With this patch, kdump is allowed to handle arbitrary number of memory +ranges, using mem_regions_alloc_and_xxx() functions. + +Signed-off-by: AKASHI Takahiro +Tested-by: Bhupesh Sharma +Tested-by: Masayoshi Mizuma +Signed-off-by: Simon Horman +--- + kexec/arch/arm64/crashdump-arm64.c | 25 ++++++++++--------------- + 1 file changed, 10 insertions(+), 15 deletions(-) + +diff --git a/kexec/arch/arm64/crashdump-arm64.c b/kexec/arch/arm64/crashdump-arm64.c +index 4fd7aa8fd43c..38d1a0f3000d 100644 +--- a/kexec/arch/arm64/crashdump-arm64.c ++++ b/kexec/arch/arm64/crashdump-arm64.c +@@ -23,13 +23,8 @@ + #include "kexec-elf.h" + #include "mem_regions.h" + +-/* memory ranges on crashed kernel */ +-static struct memory_range system_memory_ranges[CRASH_MAX_MEMORY_RANGES]; +-static struct memory_ranges system_memory_rgns = { +- .size = 0, +- .max_size = CRASH_MAX_MEMORY_RANGES, +- .ranges = system_memory_ranges, +-}; ++/* memory ranges of crashed kernel */ ++static struct memory_ranges system_memory_rgns; + + /* memory range reserved for crashkernel */ + struct memory_range crash_reserved_mem; +@@ -82,7 +77,7 @@ static uint64_t get_kernel_page_offset(void) + * + * This function is called once for each memory region found in /proc/iomem. + * It locates system RAM and crashkernel reserved memory and places these to +- * variables, respectively, system_memory_ranges and crash_reserved_mem. ++ * variables, respectively, system_memory_rgns and usablemem_rgns. + */ + + static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr), +@@ -90,11 +85,11 @@ static int iomem_range_callback(void *UNUSED(data), int UNUSED(nr), + unsigned long long length) + { + if (strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL)) == 0) +- return mem_regions_add(&usablemem_rgns, +- base, length, RANGE_RAM); ++ return mem_regions_alloc_and_add(&usablemem_rgns, ++ base, length, RANGE_RAM); + else if (strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) == 0) +- return mem_regions_add(&system_memory_rgns, +- base, length, RANGE_RAM); ++ return mem_regions_alloc_and_add(&system_memory_rgns, ++ base, length, RANGE_RAM); + else if (strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) == 0) + elf_info.kern_paddr_start = base; + else if (strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) == 0) +@@ -135,9 +130,9 @@ static int crash_get_memory_ranges(void) + + dbgprint_mem_range("Reserved memory range", &crash_reserved_mem, 1); + +- if (mem_regions_exclude(&system_memory_rgns, &crash_reserved_mem)) { +- fprintf(stderr, +- "Error: Number of crash memory ranges excedeed the max limit\n"); ++ if (mem_regions_alloc_and_exclude(&system_memory_rgns, ++ &crash_reserved_mem)) { ++ fprintf(stderr, "Cannot allocate memory for ranges\n"); + return -ENOMEM; + } + +-- +2.7.4 + diff --git a/kexec-tools-2.0.20-arm64-kexec-allocate-memory-space-avoiding-reserved-.patch b/kexec-tools-2.0.20-arm64-kexec-allocate-memory-space-avoiding-reserved-.patch new file mode 100644 index 0000000000000000000000000000000000000000..c641b6637d32b7d9ecfa92562a0bad9179d5f292 --- /dev/null +++ b/kexec-tools-2.0.20-arm64-kexec-allocate-memory-space-avoiding-reserved-.patch @@ -0,0 +1,248 @@ +From f736104f533290b4ce6fbfbca74abde9ffd3888c Mon Sep 17 00:00:00 2001 +From: AKASHI Takahiro +Date: Wed, 18 Dec 2019 11:42:31 -0500 +Subject: [PATCH 2/3] arm64: kexec: allocate memory space avoiding reserved + regions + +On UEFI/ACPI-only system, some memory regions, including but not limited +to UEFI memory map and ACPI tables, must be preserved across kexec'ing. +Otherwise, they can be corrupted and result in early failure in booting +a new kernel. + +In recent kernels, /proc/iomem now has an extended file format like: + + 40000000-5871ffff : System RAM + 41800000-426affff : Kernel code + 426b0000-42aaffff : reserved + 42ab0000-42c64fff : Kernel data + 54400000-583fffff : Crash kernel + 58590000-585effff : reserved + 58700000-5871ffff : reserved + 58720000-58b5ffff : reserved + 58b60000-5be3ffff : System RAM + 58b61000-58b61fff : reserved + +where the "reserved" entries at the top level or under System RAM (and +its descendant resources) are ones of such kind and should not be regarded +as usable memory ranges where several free spaces for loading kexec data +will be allocated. + +With this patch, get_memory_ranges() will handle this format of file +correctly. Note that, for safety, unknown regions, in addition to +"reserved" ones, will also be excluded. + +Signed-off-by: AKASHI Takahiro +Tested-by: Bhupesh Sharma +Tested-by: Masayoshi Mizuma +Signed-off-by: Simon Horman +--- + kexec/arch/arm64/kexec-arm64.c | 153 +++++++++++++++++++++++++---------------- + 1 file changed, 94 insertions(+), 59 deletions(-) + +diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c +index 6ad3b0a134b3..45ebc54a9b6f 100644 +--- a/kexec/arch/arm64/kexec-arm64.c ++++ b/kexec/arch/arm64/kexec-arm64.c +@@ -10,7 +10,9 @@ + #include + #include + #include ++#include + #include ++#include + #include + #include + #include +@@ -29,6 +31,7 @@ + #include "fs2dt.h" + #include "iomem.h" + #include "kexec-syscall.h" ++#include "mem_regions.h" + #include "arch/options.h" + + #define ROOT_NODE_ADDR_CELLS_DEFAULT 1 +@@ -905,19 +908,33 @@ int get_phys_base_from_pt_load(unsigned long *phys_offset) + return 0; + } + ++static bool to_be_excluded(char *str) ++{ ++ if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM)) || ++ !strncmp(str, KERNEL_CODE, strlen(KERNEL_CODE)) || ++ !strncmp(str, KERNEL_DATA, strlen(KERNEL_DATA)) || ++ !strncmp(str, CRASH_KERNEL, strlen(CRASH_KERNEL))) ++ return false; ++ else ++ return true; ++} ++ + /** +- * get_memory_ranges_iomem_cb - Helper for get_memory_ranges_iomem. ++ * get_memory_ranges - Try to get the memory ranges from ++ * /proc/iomem. + */ +- +-static int get_memory_ranges_iomem_cb(void *data, int nr, char *str, +- unsigned long long base, unsigned long long length) ++int get_memory_ranges(struct memory_range **range, int *ranges, ++ unsigned long kexec_flags) + { +- int ret; + unsigned long phys_offset = UINT64_MAX; +- struct memory_range *r; +- +- if (nr >= KEXEC_SEGMENT_MAX) +- return -1; ++ FILE *fp; ++ const char *iomem = proc_iomem(); ++ char line[MAX_LINE], *str; ++ unsigned long long start, end; ++ int n, consumed; ++ struct memory_ranges memranges; ++ struct memory_range *last, excl_range; ++ int ret; + + if (!try_read_phys_offset_from_kcore) { + /* Since kernel version 4.19, 'kcore' contains +@@ -951,17 +968,72 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str, + try_read_phys_offset_from_kcore = true; + } + +- r = (struct memory_range *)data + nr; ++ fp = fopen(iomem, "r"); ++ if (!fp) ++ die("Cannot open %s\n", iomem); ++ ++ memranges.ranges = NULL; ++ memranges.size = memranges.max_size = 0; ++ ++ while (fgets(line, sizeof(line), fp) != 0) { ++ n = sscanf(line, "%llx-%llx : %n", &start, &end, &consumed); ++ if (n != 2) ++ continue; ++ str = line + consumed; ++ ++ if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM))) { ++ ret = mem_regions_alloc_and_add(&memranges, ++ start, end - start + 1, RANGE_RAM); ++ if (ret) { ++ fprintf(stderr, ++ "Cannot allocate memory for ranges\n"); ++ fclose(fp); ++ return -ENOMEM; ++ } + +- if (!strncmp(str, SYSTEM_RAM, strlen(SYSTEM_RAM))) +- r->type = RANGE_RAM; +- else if (!strncmp(str, IOMEM_RESERVED, strlen(IOMEM_RESERVED))) +- r->type = RANGE_RESERVED; +- else +- return 1; ++ dbgprintf("%s:+[%d] %016llx - %016llx\n", __func__, ++ memranges.size - 1, ++ memranges.ranges[memranges.size - 1].start, ++ memranges.ranges[memranges.size - 1].end); ++ } else if (to_be_excluded(str)) { ++ if (!memranges.size) ++ continue; ++ ++ /* ++ * Note: mem_regions_exclude() doesn't guarantee ++ * that the ranges are sorted out, but as long as ++ * we cope with /proc/iomem, we only operate on ++ * the last entry and so it is safe. ++ */ + +- r->start = base; +- r->end = base + length - 1; ++ /* The last System RAM range */ ++ last = &memranges.ranges[memranges.size - 1]; ++ ++ if (last->end < start) ++ /* New resource outside of System RAM */ ++ continue; ++ if (end < last->start) ++ /* Already excluded by parent resource */ ++ continue; ++ ++ excl_range.start = start; ++ excl_range.end = end; ++ ret = mem_regions_alloc_and_exclude(&memranges, &excl_range); ++ if (ret) { ++ fprintf(stderr, ++ "Cannot allocate memory for ranges (exclude)\n"); ++ fclose(fp); ++ return -ENOMEM; ++ } ++ dbgprintf("%s:- %016llx - %016llx\n", ++ __func__, start, end); ++ } ++ } ++ ++ fclose(fp); ++ ++ *range = memranges.ranges; ++ *ranges = memranges.size; + + /* As a fallback option, we can try determining the PHYS_OFFSET + * value from the '/proc/iomem' entries as well. +@@ -982,52 +1054,15 @@ static int get_memory_ranges_iomem_cb(void *data, int nr, char *str, + * between the user-space and kernel space 'PHYS_OFFSET' + * value. + */ +- set_phys_offset(r->start, "iomem"); +- +- dbgprintf("%s: %016llx - %016llx : %s", __func__, r->start, +- r->end, str); +- +- return 0; +-} +- +-/** +- * get_memory_ranges_iomem - Try to get the memory ranges from +- * /proc/iomem. +- */ ++ if (memranges.size) ++ set_phys_offset(memranges.ranges[0].start, "iomem"); + +-static int get_memory_ranges_iomem(struct memory_range *array, +- unsigned int *count) +-{ +- *count = kexec_iomem_for_each_line(NULL, +- get_memory_ranges_iomem_cb, array); +- +- if (!*count) { +- dbgprintf("%s: failed: No RAM found.\n", __func__); +- return EFAILED; +- } ++ dbgprint_mem_range("System RAM ranges;", ++ memranges.ranges, memranges.size); + + return 0; + } + +-/** +- * get_memory_ranges - Try to get the memory ranges some how. +- */ +- +-int get_memory_ranges(struct memory_range **range, int *ranges, +- unsigned long kexec_flags) +-{ +- static struct memory_range array[KEXEC_SEGMENT_MAX]; +- unsigned int count; +- int result; +- +- result = get_memory_ranges_iomem(array, &count); +- +- *range = result ? NULL : array; +- *ranges = result ? 0 : count; +- +- return result; +-} +- + int arch_compat_trampoline(struct kexec_info *info) + { + return 0; +-- +2.7.4 + diff --git a/kexec-tools-2.0.20-kexec-add-variant-helper-functions-for-handling-memo.patch b/kexec-tools-2.0.20-kexec-add-variant-helper-functions-for-handling-memo.patch new file mode 100644 index 0000000000000000000000000000000000000000..cc07c0042205064e469aa75766e28e6cb0f1bbc9 --- /dev/null +++ b/kexec-tools-2.0.20-kexec-add-variant-helper-functions-for-handling-memo.patch @@ -0,0 +1,89 @@ +From cf977b1af9ec67fabcc6a625589c49c52d07b11d Mon Sep 17 00:00:00 2001 +From: AKASHI Takahiro +Date: Wed, 18 Dec 2019 11:42:30 -0500 +Subject: [PATCH 1/3] kexec: add variant helper functions for handling memory + regions + +mem_regions_alloc_and_add() and mem_regions_alloc_and_exclude() are +functionally equivalent to, respectively, mem_regions_add() and +mem_regions_exclude() except the formers will re-allocate memory +dynamically when no more entries are available in 'ranges' array. + +Signed-off-by: AKASHI Takahiro +Tested-by: Bhupesh Sharma +Tested-by: Masayoshi Mizuma +Signed-off-by: Simon Horman +--- + kexec/mem_regions.c | 42 ++++++++++++++++++++++++++++++++++++++++++ + kexec/mem_regions.h | 7 +++++++ + 2 files changed, 49 insertions(+) + +diff --git a/kexec/mem_regions.c b/kexec/mem_regions.c +index 50c8abccb93a..ad7d3f13fd84 100644 +--- a/kexec/mem_regions.c ++++ b/kexec/mem_regions.c +@@ -125,3 +125,45 @@ int mem_regions_exclude(struct memory_ranges *ranges, + } + return 0; + } ++ ++#define KEXEC_MEMORY_RANGES 16 ++ ++int mem_regions_alloc_and_add(struct memory_ranges *ranges, ++ unsigned long long base, ++ unsigned long long length, int type) ++{ ++ void *new_ranges; ++ ++ if (ranges->size >= ranges->max_size) { ++ new_ranges = realloc(ranges->ranges, ++ sizeof(struct memory_range) * ++ (ranges->max_size + KEXEC_MEMORY_RANGES)); ++ if (!new_ranges) ++ return -1; ++ ++ ranges->ranges = new_ranges; ++ ranges->max_size += KEXEC_MEMORY_RANGES; ++ } ++ ++ return mem_regions_add(ranges, base, length, type); ++} ++ ++int mem_regions_alloc_and_exclude(struct memory_ranges *ranges, ++ const struct memory_range *range) ++{ ++ void *new_ranges; ++ ++ /* for safety, we should have at least one free entry in ranges */ ++ if (ranges->size >= ranges->max_size) { ++ new_ranges = realloc(ranges->ranges, ++ sizeof(struct memory_range) * ++ (ranges->max_size + KEXEC_MEMORY_RANGES)); ++ if (!new_ranges) ++ return -1; ++ ++ ranges->ranges = new_ranges; ++ ranges->max_size += KEXEC_MEMORY_RANGES; ++ } ++ ++ return mem_regions_exclude(ranges, range); ++} +diff --git a/kexec/mem_regions.h b/kexec/mem_regions.h +index ae9e972b0206..e306d67e3261 100644 +--- a/kexec/mem_regions.h ++++ b/kexec/mem_regions.h +@@ -12,4 +12,11 @@ int mem_regions_exclude(struct memory_ranges *ranges, + int mem_regions_add(struct memory_ranges *ranges, unsigned long long base, + unsigned long long length, int type); + ++int mem_regions_alloc_and_exclude(struct memory_ranges *ranges, ++ const struct memory_range *range); ++ ++int mem_regions_alloc_and_add(struct memory_ranges *ranges, ++ unsigned long long base, ++ unsigned long long length, int type); ++ + #endif +-- +2.7.4 + diff --git a/kexec-tools-2.0.20-vmcore-dmesg-vmcore-dmesg.c-Fix-shifting-error-repor.patch b/kexec-tools-2.0.20-vmcore-dmesg-vmcore-dmesg.c-Fix-shifting-error-repor.patch new file mode 100644 index 0000000000000000000000000000000000000000..e43b45a53424715b79b8d3adaffdf3a683bd24f9 --- /dev/null +++ b/kexec-tools-2.0.20-vmcore-dmesg-vmcore-dmesg.c-Fix-shifting-error-repor.patch @@ -0,0 +1,38 @@ +From a46c686f615a86933134c0924c3391ba598a02b8 Mon Sep 17 00:00:00 2001 +From: Bhupesh Sharma +Date: Tue, 10 Sep 2019 15:51:49 +0530 +Subject: [PATCH 5/5] vmcore-dmesg/vmcore-dmesg.c: Fix shifting error reported + by cppcheck + +Running 'cppcheck' static code analyzer (see cppcheck(1)) + on 'vmcore-dmesg/vmcore-dmesg.c' shows the following +shifting error: + +$ cppcheck --enable=all vmcore-dmesg/vmcore-dmesg.c +Checking vmcore-dmesg/vmcore-dmesg.c ... +[vmcore-dmesg/vmcore-dmesg.c:17]: (error) Shifting signed 32-bit value by 31 bits is undefined behaviour + +Fix the same via this patch. + +Signed-off-by: Bhupesh Sharma +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 81c2a58c9d86..122e53672e01 100644 +--- a/vmcore-dmesg/vmcore-dmesg.c ++++ b/vmcore-dmesg/vmcore-dmesg.c +@@ -6,7 +6,7 @@ typedef Elf32_Nhdr Elf_Nhdr; + extern const char *fname; + + /* stole this macro from kernel printk.c */ +-#define LOG_BUF_LEN_MAX (uint32_t)(1 << 31) ++#define LOG_BUF_LEN_MAX (uint32_t)(1U << 31) + + static void write_to_stdout(char *buf, unsigned int nr) + { +-- +2.17.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.21.tar.gz b/kexec-tools-2.0.21.tar.gz deleted file mode 100644 index de700eeda370abc20f411a84a0aff8d348d73a7e..0000000000000000000000000000000000000000 Binary files a/kexec-tools-2.0.21.tar.gz and /dev/null differ diff --git a/kexec-tools-2.0.22-makedumpfile-check-for-invalid-physical-address-proc-kcore-when-finding-max_paddr.patch b/kexec-tools-2.0.22-makedumpfile-check-for-invalid-physical-address-proc-kcore-when-finding-max_paddr.patch deleted file mode 100644 index f79ea551732f68e8a1e18a030d978d596c595756..0000000000000000000000000000000000000000 --- a/kexec-tools-2.0.22-makedumpfile-check-for-invalid-physical-address-proc-kcore-when-finding-max_paddr.patch +++ /dev/null @@ -1,60 +0,0 @@ -From 38d921a2ef50ebd36258097553626443ffe27496 Mon Sep 17 00:00:00 2001 -From: Coiby Xu -Date: Tue, 15 Jun 2021 18:26:31 +0800 -Subject: [PATCH] check for invalid physical address of /proc/kcore - when finding max_paddr - -Kernel commit 464920104bf7adac12722035bfefb3d772eb04d8 ("/proc/kcore: -update physical address for kcore ram and text") sets an invalid paddr -(0xffffffffffffffff = -1) for PT_LOAD segments of not direct mapped -regions: - - $ readelf -l /proc/kcore - ... - Program Headers: - Type Offset VirtAddr PhysAddr - FileSiz MemSiz Flags Align - NOTE 0x0000000000000120 0x0000000000000000 0x0000000000000000 - 0x0000000000002320 0x0000000000000000 0x0 - LOAD 0x1000000000010000 0xd000000000000000 0xffffffffffffffff - ^^^^^^^^^^^^^^^^^^ - 0x0001f80000000000 0x0001f80000000000 RWE 0x10000 - -makedumpfile uses max_paddr to calculate the number of sections for -sparse memory model thus wrong number is obtained based on max_paddr -(-1). This error could lead to the failure of copying /proc/kcore -for RHEL-8.5 on ppc64le machine [1]: - - $ makedumpfile /proc/kcore vmcore1 - get_mem_section: Could not validate mem_section. - get_mm_sparsemem: Can't get the address of mem_section. - - makedumpfile Failed. - -Let's check if the phys_start of the segment is a valid physical -address to fix this problem. - -[1] https://bugzilla.redhat.com/show_bug.cgi?id=1965267 - -Reported-by: Xiaoying Yan -Signed-off-by: Coiby Xu ---- - elf_info.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/makedumpfile-1.6.9/elf_info.c b/makedumpfile-1.6.9/elf_info.c -index e8affb7..bc24083 100644 ---- a/makedumpfile-1.6.9/elf_info.c -+++ b/makedumpfile-1.6.9/elf_info.c -@@ -628,7 +628,7 @@ get_max_paddr(void) - - for (i = 0; i < num_pt_loads; i++) { - pls = &pt_loads[i]; -- if (max_paddr < pls->phys_end) -+ if (pls->phys_start != NOT_PADDR && max_paddr < pls->phys_end) - max_paddr = pls->phys_end; - } - return max_paddr; --- -2.29.2 - diff --git a/kexec-tools-2.0.22-makedumpfile-check-for-invalid-physical-address-proc-kcore-when-making-ELF-dumpfile.patch b/kexec-tools-2.0.22-makedumpfile-check-for-invalid-physical-address-proc-kcore-when-making-ELF-dumpfile.patch deleted file mode 100644 index 8cf780c6459d8d8177fa316fafa9a60ce8517725..0000000000000000000000000000000000000000 --- a/kexec-tools-2.0.22-makedumpfile-check-for-invalid-physical-address-proc-kcore-when-making-ELF-dumpfile.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 9a6f589d99dcef114c89fde992157f5467028c8f Mon Sep 17 00:00:00 2001 -From: Tao Liu -Date: Fri, 18 Jun 2021 18:28:04 +0800 -Subject: [PATCH] check for invalid physical address of /proc/kcore - when making ELF dumpfile - -Previously when executing makedumpfile with -E option against -/proc/kcore, makedumpfile will fail: - - # makedumpfile -E -d 31 /proc/kcore kcore.dump - ... - write_elf_load_segment: Can't convert physaddr(ffffffffffffffff) to an offset. - - makedumpfile Failed. - -It's because /proc/kcore contains PT_LOAD program headers which have -physaddr (0xffffffffffffffff). With -E option, makedumpfile will -try to convert the physaddr to an offset and fails. - -Skip the PT_LOAD program headers which have such physaddr. - -Signed-off-by: Tao Liu -Signed-off-by: Kazuhito Hagio ---- - makedumpfile.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/makedumpfile-1.6.9/makedumpfile.c b/makedumpfile-1.6.9/makedumpfile.c -index 894c88e..fcb571f 100644 ---- a/makedumpfile-1.6.9/makedumpfile.c -+++ b/makedumpfile-1.6.9/makedumpfile.c -@@ -7764,7 +7764,7 @@ write_elf_pages_cyclic(struct cache_data *cd_header, struct cache_data *cd_page) - if (!get_phdr_memory(i, &load)) - return FALSE; - -- if (load.p_type != PT_LOAD) -+ if (load.p_type != PT_LOAD || load.p_paddr == NOT_PADDR) - continue; - - off_memory= load.p_offset; --- -2.29.2 - diff --git a/kexec-tools.spec b/kexec-tools.spec index d2377b0723fe293cbfa6890ff66f9da0546cc80a..79f596ac032bf3534bc98194b547b0c360db99a5 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -1,14 +1,11 @@ -%define anolis_release 3 -%define makedumpfile_version 1.6.9 - Name: kexec-tools -Version: 2.0.21 -Release: 1.%{anolis_release}%{?dist} +Version: 2.0.20 +Release: 68%{?dist} License: GPLv2 Group: Applications/System Summary: The kexec/kdump userspace component -Source0: http://kernel.org/pub/linux/utils/kernel/kexec/%{name}-%{version}.tar.gz +Source0: http://kernel.org/pub/linux/utils/kernel/kexec/%{name}-%{version}.tar.xz Source1: kdumpctl Source2: kdump.sysconfig Source3: kdump.sysconfig.x86_64 @@ -16,7 +13,7 @@ Source4: kdump.sysconfig.i386 Source5: kdump.sysconfig.ppc64 Source7: mkdumprd Source8: kdump.conf -Source9: https://github.com/makedumpfile/makedumpfile/releases/download/%{makedumpfile_version}/makedumpfile-%{makedumpfile_version}.tar.gz +Source9: https://github.com/makedumpfile/makedumpfile/archive/1.7.0.tar.gz Source10: kexec-kdump-howto.txt Source12: mkdumprd.8 Source13: 98-kexec.rules @@ -41,6 +38,7 @@ Source32: 60-kdump.install Source33: kdump-logger.sh Source34: kdump-migrate-action.sh Source35: kdump-restart.sh +Source36: mkfadumprd ####################################### # These are sources for mkdumpramfs @@ -57,9 +55,14 @@ Source107: dracut-kdump-emergency.target Source108: dracut-early-kdump.sh Source109: dracut-early-kdump-module-setup.sh +Source200: dracut-fadump-init-fadump.sh +Source201: dracut-fadump-module-setup.sh + %ifarch ppc64 ppc64le Requires(post): servicelog +Recommends: keyutils %endif + Requires(post): systemd-units Requires(preun): systemd-units Requires(postun): systemd-units @@ -68,7 +71,7 @@ Requires: dracut >= 049-129 Requires: dracut-network >= 049 Requires: dracut-squash >= 049 Requires: ethtool -BuildRequires: zlib-devel zlib zlib-static elfutils-devel glib2-devel bzip2-devel ncurses-devel bison flex lzo-devel snappy-devel +BuildRequires: zlib-devel zlib zlib-static elfutils-devel glib2-devel bzip2-devel ncurses-devel bison flex lzo-devel snappy-devel libzstd-devel BuildRequires: pkgconfig intltool gettext BuildRequires: systemd-units BuildRequires: automake autoconf libtool @@ -104,13 +107,24 @@ ExcludeArch: i686 # Patch601: rhelonly-kexec-tools-2.0.16-koji-build-fail-workaround.patch Patch602: rhelonly-kexec-tools-2.0.18-eppic-fix-issues-with-hardening-flags.patch -Patch603: kexec-tools-2.0.20-eppic-Remove-duplicated-variable-declaration.patch +#Patch603: rhonly-kexec-tools-2.0.18-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch +Patch604: kexec-tools-2.0.20-Cleanup-remove-the-read_elf_kcore.patch +Patch605: kexec-tools-2.0.20-Fix-an-error-definition-about-the-variable-fname.patch +Patch606: kexec-tools-2.0.20-Cleanup-move-it-back-from-util_lib-elf_info.c.patch +Patch607: kexec-tools-2.0.20-Limit-the-size-of-vmcore-dmesg.txt-to-2G.patch +Patch608: kexec-tools-2.0.20-vmcore-dmesg-vmcore-dmesg.c-Fix-shifting-error-repor.patch +Patch609: kexec-tools-2.0.20-kexec-add-variant-helper-functions-for-handling-memo.patch +Patch610: kexec-tools-2.0.20-arm64-kexec-allocate-memory-space-avoiding-reserved-.patch +Patch611: kexec-tools-2.0.20-arm64-kdump-deal-with-a-lot-of-resource-entries-in-p.patch +Patch612: kexec-tools-2.0.20-Remove-duplicated-variable-declarations.patch +Patch613: kexec-tools-2.0.20-eppic-Remove-duplicated-variable-declaration.patch +Patch614: kexec-tools-2.0.20-1-printk-add-support-for-lockless-ringbuffer.patch +Patch615: kexec-tools-2.0.20-2-printk-Use-ULL-suffix-for-64-bit-constants.patch +Patch616: kexec-tools-2.0.20-3-printk-Use-zu-to-format-size_t.patch # Patches 701 onward for makedumpfile -Patch701: rhelonly-kexec-tools-2.0.21-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch -Patch702: kexec-tools-2.0.22-makedumpfile-check-for-invalid-physical-address-proc-kcore-when-finding-max_paddr.patch -Patch703: kexec-tools-2.0.22-makedumpfile-check-for-invalid-physical-address-proc-kcore-when-making-ELF-dumpfile.patch +Patch701: rhelonly-kexec-tools-2.0.20-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch %description kexec-tools provides /usr/sbin/kexec binary that facilitates a new @@ -128,11 +142,21 @@ tar -z -x -v -f %{SOURCE19} %patch601 -p1 %patch602 -p1 -%patch603 -p1 - +#%patch603 -p1 +%patch604 -p1 +%patch605 -p1 +%patch606 -p1 +%patch607 -p1 +%patch608 -p1 +%patch609 -p1 +%patch610 -p1 +%patch611 -p1 +%patch612 -p1 +%patch613 -p1 +%patch614 -p1 +%patch615 -p1 +%patch616 -p1 %patch701 -p1 -%patch702 -p1 -%patch703 -p1 %ifarch ppc %define archdef ARCH=ppc @@ -162,8 +186,8 @@ cp %{SOURCE31} . make %ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64 make -C eppic/libeppic -make -C makedumpfile-%{makedumpfile_version} LINKTYPE=dynamic USELZO=on USESNAPPY=on -make -C makedumpfile-%{makedumpfile_version} LDFLAGS="$LDFLAGS -I../eppic/libeppic -L../eppic/libeppic" eppic_makedumpfile.so +make -C makedumpfile-1.7.0 LINKTYPE=dynamic USELZO=on USESNAPPY=on USEZSTD=on +make -C makedumpfile-1.7.0 LDFLAGS="$LDFLAGS -I../eppic/libeppic -L../eppic/libeppic" eppic_makedumpfile.so %endif %install @@ -196,6 +220,7 @@ SYSCONFIG=$RPM_SOURCE_DIR/kdump.sysconfig.%{_target_cpu} install -m 644 $SYSCONFIG $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/kdump install -m 755 %{SOURCE7} $RPM_BUILD_ROOT/usr/sbin/mkdumprd +install -m 755 %{SOURCE36} $RPM_BUILD_ROOT/usr/sbin/mkfadumprd install -m 644 %{SOURCE8} $RPM_BUILD_ROOT%{_sysconfdir}/kdump.conf install -m 644 kexec/kexec.8 $RPM_BUILD_ROOT%{_mandir}/man8/kexec.8 install -m 644 %{SOURCE12} $RPM_BUILD_ROOT%{_mandir}/man8/mkdumprd.8 @@ -223,17 +248,18 @@ install -m 755 -D %{SOURCE32} $RPM_BUILD_ROOT%{_prefix}/lib/kernel/install.d/60- %ifarch %{ix86} x86_64 ppc64 s390x ppc64le aarch64 -install -m 755 makedumpfile-%{makedumpfile_version}/makedumpfile $RPM_BUILD_ROOT/usr/sbin/makedumpfile -install -m 644 makedumpfile-%{makedumpfile_version}/makedumpfile.8.gz $RPM_BUILD_ROOT/%{_mandir}/man8/makedumpfile.8.gz -install -m 644 makedumpfile-%{makedumpfile_version}/makedumpfile.conf.5.gz $RPM_BUILD_ROOT/%{_mandir}/man5/makedumpfile.conf.5.gz -install -m 644 makedumpfile-%{makedumpfile_version}/makedumpfile.conf $RPM_BUILD_ROOT/%{_sysconfdir}/makedumpfile.conf.sample -install -m 755 makedumpfile-%{makedumpfile_version}/eppic_makedumpfile.so $RPM_BUILD_ROOT/%{_libdir}/eppic_makedumpfile.so +install -m 755 makedumpfile-1.7.0/makedumpfile $RPM_BUILD_ROOT/usr/sbin/makedumpfile +install -m 644 makedumpfile-1.7.0/makedumpfile.8.gz $RPM_BUILD_ROOT/%{_mandir}/man8/makedumpfile.8.gz +install -m 644 makedumpfile-1.7.0/makedumpfile.conf.5.gz $RPM_BUILD_ROOT/%{_mandir}/man5/makedumpfile.conf.5.gz +install -m 644 makedumpfile-1.7.0/makedumpfile.conf $RPM_BUILD_ROOT/%{_sysconfdir}/makedumpfile.conf.sample +install -m 755 makedumpfile-1.7.0/eppic_makedumpfile.so $RPM_BUILD_ROOT/%{_libdir}/eppic_makedumpfile.so mkdir -p $RPM_BUILD_ROOT/usr/share/makedumpfile/eppic_scripts/ -install -m 644 makedumpfile-%{makedumpfile_version}/eppic_scripts/* $RPM_BUILD_ROOT/usr/share/makedumpfile/eppic_scripts/ +install -m 644 makedumpfile-1.7.0/eppic_scripts/* $RPM_BUILD_ROOT/usr/share/makedumpfile/eppic_scripts/ %endif %define remove_dracut_prefix() %(echo -n %1|sed 's/.*dracut-//g') %define remove_dracut_early_kdump_prefix() %(echo -n %1|sed 's/.*dracut-early-kdump-//g') +%define remove_dracut_fadump_prefix() %(echo -n %1|sed 's/.*dracut-fadump-//g') # deal with dracut modules mkdir -p -m755 $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99kdumpbase @@ -252,6 +278,13 @@ cp %{SOURCE108} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99earlyk cp %{SOURCE109} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump/%{remove_dracut_early_kdump_prefix %{SOURCE109}} chmod 755 $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump/%{remove_dracut_prefix %{SOURCE108}} chmod 755 $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99earlykdump/%{remove_dracut_early_kdump_prefix %{SOURCE109}} +%ifarch ppc64 ppc64le +mkdir -p -m755 $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99zz-fadumpinit +cp %{SOURCE200} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99zz-fadumpinit/%{remove_dracut_fadump_prefix %{SOURCE200}} +cp %{SOURCE201} $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99zz-fadumpinit/%{remove_dracut_fadump_prefix %{SOURCE201}} +chmod 755 $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99zz-fadumpinit/%{remove_dracut_fadump_prefix %{SOURCE200}} +chmod 755 $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/99zz-fadumpinit/%{remove_dracut_fadump_prefix %{SOURCE201}} +%endif %define dracutlibdir %{_prefix}/lib/dracut @@ -266,7 +299,7 @@ mv $RPM_BUILD_ROOT/etc/kdump-adv-conf/kdump_dracut_modules/* $RPM_BUILD_ROOT/%{d touch /etc/kdump.conf %ifarch ppc64 ppc64le -servicelog_notify --remove --command=/usr/lib/kdump/kdump-migrate-action.sh +servicelog_notify --remove --command=/usr/lib/kdump/kdump-migrate-action.sh 2>/dev/null servicelog_notify --add --command=/usr/lib/kdump/kdump-migrate-action.sh --match='refcode="#MIGRATE" and serviceable=0' --type=EVENT --method=pairs_stdin %endif @@ -341,6 +374,7 @@ done /usr/sbin/kexec /usr/sbin/makedumpfile /usr/sbin/mkdumprd +/usr/sbin/mkfadumprd /usr/sbin/vmcore-dmesg %{_bindir}/* %{_datadir}/kdump @@ -384,23 +418,47 @@ done %endif %changelog -* Mon Feb 07 2022 Chunmei Xu - 2.0.21-1.3 -- remove -s from KEXEC_ARGS to prevent bzImange verify +* Thu Jan 27 2022 Pingfan Liu - 2.0.20-68 +- Revert "Remove trace_buf_size and trace_event from the kernel bootparameters of the kdump kernel" -* Mon Feb 07 2022 Weitao Zhou - 2.0.21-1.2 -- rebase makedumpfile to 1.6.9 -- makedumpfile: migrate to RHEL solution on support for ARMv8.2 LVA 52 bit +* Fri Dec 24 2021 Pingfan Liu - 2.0.20-67 +- Remove trace_buf_size and trace_event from the kernel bootparameters of the kdump kernel -* Mon Feb 07 2022 Chunmei Xu - 2.0.21-1.1 -- rebase kexec-tools to 2.0.21 -- rebase makedumpfile to 1.6.8 -- makedumpfile: support for lockless ringbuffer of printk -- makedumpfile: support use 'TCR_EL1.T1SZ' to determine va bits -- makedumpfile: support read register ID_AA64MMFR2_EL1 to get va bits +* Fri Dec 10 2021 Pingfan Liu - 2.0.20-66 +- kdump/ppc64: suppress the error message "Could not find a registered notification tool" from servicelog_notify +- Enable zstd compression for makedumpfile in kexec-tools.spec -* Tue Nov 2 2021 Pingfan Liu - 2.0.20-57.1 +* Thu Dec 2 2021 Pingfan Liu - 2.0.20-65 +- mkdumprd: drop mountaddr/mountproto nfs mount options + +* Fri Nov 26 2021 Pingfan Liu - 2.0.20-64 +- add keytuils as a weak dependency for POWER + +* Fri Nov 19 2021 Pingfan Liu - 2.0.20-63 +- Document/kexec-kdump-howto.txt: fix escape + +* Wed Nov 17 2021 Pingfan Liu - 2.0.20-62 +- Document/kexec-kdump-howto.txt: improve notes for kdump_pre and kdump_post scripts + +* Tue Nov 9 2021 Pingfan Liu - 2.0.20-61 +- rebase makedumpfile to 1.7.0 + +* Fri Oct 22 2021 Pingfan Liu - 2.0.20-60 +- fadump-init: clean up mount points properly +- fadump: kdumpctl should check the modules used by the fadump initramfs +- fadump: isolate fadump initramfs image within the default one - mkdumprd: Use xz for squash image compression +* Mon Oct 18 2021 Pingfan Liu - 2.0.20-59 +- makedumpfile: printk: use committed/finalized state values +- makedumpfile: printk: add support for lockless ringbuffer +- kexec-tools: printk: Use %zu to format size_t +- kexec-tools: printk: Use ULL suffix for 64-bit constants +- kexec-tools: printk: add support for lockless ringbuffer + +* Sun Oct 17 2021 Pingfan Liu - 2.0.20-58 +- kdumpctl: fix fragile loops over find output + * Fri Aug 27 2021 Pingfan Liu - 2.0.20-57 - kdumpctl: enable secure boot on ppc64le LPARs diff --git a/makedumpfile-1.6.9.tar.gz b/makedumpfile-1.6.9.tar.gz deleted file mode 100644 index cd2f83056911e248fecd81e6ae24bbde079c9fc4..0000000000000000000000000000000000000000 Binary files a/makedumpfile-1.6.9.tar.gz and /dev/null differ diff --git a/mkdumprd b/mkdumprd index 1bd3d0ae3c702a98f278d5fe7fe9d55d511cd06f..ce3c0f3bfe7f0d03201385edcf2803e4277f9743 100644 --- a/mkdumprd +++ b/mkdumprd @@ -68,8 +68,8 @@ to_mount() { if [[ "$_fstype" == "nfs"* ]]; then _pdev=$_target - _options=$(echo $_options | sed 's/,addr=[^,]*//') - _options=$(echo $_options | sed 's/,proto=[^,]*//') + _options=$(echo $_options | sed 's/,\(mount\)\?addr=[^,]*//g') + _options=$(echo $_options | sed 's/,\(mount\)\?proto=[^,]*//g') _options=$(echo $_options | sed 's/,clientaddr=[^,]*//') else # for non-nfs _target converting to use udev persistent name @@ -432,6 +432,11 @@ then add_dracut_arg "--add-drivers" \"$extra_modules\" fi +# TODO: The below check is not needed anymore with the introduction of +# 'zz-fadumpinit' module, that isolates fadump's capture kernel initrd, +# but still sysroot.mount unit gets generated based on 'root=' kernel +# parameter available in fadump case. So, find a way to fix that first +# before removing this check. if ! is_fadump_capable; then # The 2nd rootfs mount stays behind the normal dump target mount, # so it doesn't affect the logic of check_dump_fs_modified(). diff --git a/mkfadumprd b/mkfadumprd new file mode 100644 index 0000000000000000000000000000000000000000..5447c7a4391aed72afee8a8fd7d0a9e7dae2a8e3 --- /dev/null +++ b/mkfadumprd @@ -0,0 +1,64 @@ +#!/bin/bash --norc +# Generate an initramfs image that isolates dump capture capability within +# the default initramfs using zz-fadumpinit dracut module. + +if [ -f /etc/sysconfig/kdump ]; then + . /etc/sysconfig/kdump +fi + +[[ $dracutbasedir ]] || dracutbasedir=/usr/lib/dracut +. $dracutbasedir/dracut-functions.sh +. /lib/kdump/kdump-lib.sh +. /lib/kdump/kdump-logger.sh + +#initiate the kdump logger +if ! dlog_init; then + echo "mkfadumprd: failed to initiate the kdump logger." + exit 1 +fi + +readonly MKFADUMPRD_TMPDIR="$(mktemp -d -t mkfadumprd.XXXXXX)" +[ -d "$MKFADUMPRD_TMPDIR" ] || perror_exit "mkfadumprd: mktemp -d -t mkfadumprd.XXXXXX failed." +trap ' + ret=$?; + [[ -d $MKFADUMPRD_TMPDIR ]] && rm --one-file-system -rf -- "$MKFADUMPRD_TMPDIR"; + exit $ret; + ' EXIT + +# clean up after ourselves no matter how we die. +trap 'exit 1;' SIGINT + +MKDUMPRD="/sbin/mkdumprd -f" +# Default boot initramfs to be rebuilt +REBUILD_INITRD="$1" && shift +TARGET_INITRD="$1" && shift +FADUMP_INITRD="$MKFADUMPRD_TMPDIR/fadump.img" + +### First build an initramfs with dump capture capability +# this file tells the initrd is fadump enabled +touch "$MKFADUMPRD_TMPDIR/fadump.initramfs" +ddebug "rebuild fadump initrd: $FADUMP_INITRD $DEFAULT_INITRD $KDUMP_KERNELVER" +if ! $MKDUMPRD "$FADUMP_INITRD" -i "$MKFADUMPRD_TMPDIR/fadump.initramfs" /etc/fadump.initramfs; then + perror_exit "mkfadumprd: failed to build image with dump capture support" +fi + +### Unpack the initramfs having dump capture capability +mkdir -p "$MKFADUMPRD_TMPDIR/fadumproot" +if ! (pushd "$MKFADUMPRD_TMPDIR/fadumproot" > /dev/null && lsinitrd --unpack "$FADUMP_INITRD" && \ + popd > /dev/null); then + derror "mkfadumprd: failed to unpack '$MKFADUMPRD_TMPDIR'" + exit 1 +fi + +### Pack it into the normal boot initramfs with zz-fadumpinit module +_dracut_isolate_args="--rebuild $REBUILD_INITRD --add zz-fadumpinit \ + -i $MKFADUMPRD_TMPDIR/fadumproot /fadumproot \ + -i $MKFADUMPRD_TMPDIR/fadumproot/usr/lib/dracut/loaded-kernel-modules.txt + /usr/lib/dracut/fadump-kernel-modules.txt" + +if is_squash_available; then + _dracut_isolate_args="$_dracut_isolate_args --add squash" +fi +if ! dracut --force --quiet $_dracut_isolate_args $@ "$TARGET_INITRD"; then + perror_exit "mkfadumprd: failed to setup '$TARGET_INITRD' with dump capture capability" +fi diff --git a/rhelonly-kexec-tools-2.0.21-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch b/rhelonly-kexec-tools-2.0.20-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch similarity index 68% rename from rhelonly-kexec-tools-2.0.21-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch rename to rhelonly-kexec-tools-2.0.20-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch index 7f10b245394714f23b58aac7147ad0bc46ca2442..7b7ad6367c654f53a90b9987bcbcfc525bb10f19 100644 --- a/rhelonly-kexec-tools-2.0.21-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch +++ b/rhelonly-kexec-tools-2.0.20-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch @@ -1,18 +1,21 @@ -From 16028a119c85ed73944bcf6ca310a7ee4d2e64fe Mon Sep 17 00:00:00 2001 +From 0f632fa180e5a44219ab6bbe0879c3583f8c65cf Mon Sep 17 00:00:00 2001 From: Pingfan Liu -Date: Mon, 21 Dec 2020 13:35:38 +0800 +Date: Tue, 9 Nov 2021 11:24:22 +0800 Subject: [PATCH] RHEL-only +Cope with RHEL8 kernel + +Signed-off-by: Pingfan Liu --- - makedumpfile-1.6.9/arch/arm64.c | 14 +++++++++++++- - makedumpfile-1.6.9/makedumpfile.c | 2 ++ - makedumpfile-1.6.9/makedumpfile.h | 1 + + arch/arm64.c | 14 +++++++++++++- + makedumpfile.c | 2 ++ + makedumpfile.h | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) -diff --git a/makedumpfile-1.6.9/arch/arm64.c b/makedumpfile-1.6.9/arch/arm64.c +diff --git a/makedumpfile-1.7.0/arch/arm64.c b/makedumpfile-1.7.0/arch/arm64.c index 1072178..95beae6 100644 ---- a/makedumpfile-1.6.9/arch/arm64.c -+++ b/makedumpfile-1.6.9/arch/arm64.c +--- a/makedumpfile-1.7.0/arch/arm64.c ++++ b/makedumpfile-1.7.0/arch/arm64.c @@ -50,6 +50,7 @@ static int va_bits; static int vabits_actual; static int flipped_va; @@ -48,11 +51,11 @@ index 1072178..95beae6 100644 kimage_voffset = NUMBER(kimage_voffset); info->section_size_bits = SECTIONS_SIZE_BITS; -diff --git a/makedumpfile-1.6.9/makedumpfile.c b/makedumpfile-1.6.9/makedumpfile.c -index 894c88e..0071da8 100644 ---- a/makedumpfile-1.6.9/makedumpfile.c -+++ b/makedumpfile-1.6.9/makedumpfile.c -@@ -2398,6 +2398,7 @@ write_vmcoreinfo_data(void) +diff --git a/makedumpfile-1.7.0/makedumpfile.c b/makedumpfile-1.7.0/makedumpfile.c +index 3ad4443..018ea4c 100644 +--- a/makedumpfile-1.7.0/makedumpfile.c ++++ b/makedumpfile-1.7.0/makedumpfile.c +@@ -2417,6 +2417,7 @@ write_vmcoreinfo_data(void) WRITE_NUMBER("HUGETLB_PAGE_DTOR", HUGETLB_PAGE_DTOR); #ifdef __aarch64__ @@ -60,7 +63,7 @@ index 894c88e..0071da8 100644 WRITE_NUMBER("VA_BITS", VA_BITS); /* WRITE_NUMBER("TCR_EL1_T1SZ", TCR_EL1_T1SZ); should not exists */ WRITE_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET); -@@ -2838,6 +2839,7 @@ read_vmcoreinfo(void) +@@ -2863,6 +2864,7 @@ read_vmcoreinfo(void) READ_NUMBER("phys_base", phys_base); READ_NUMBER("KERNEL_IMAGE_SIZE", KERNEL_IMAGE_SIZE); #ifdef __aarch64__ @@ -68,11 +71,11 @@ index 894c88e..0071da8 100644 READ_NUMBER("VA_BITS", VA_BITS); READ_NUMBER("TCR_EL1_T1SZ", TCR_EL1_T1SZ); READ_NUMBER_UNSIGNED("PHYS_OFFSET", PHYS_OFFSET); -diff --git a/makedumpfile-1.6.9/makedumpfile.h b/makedumpfile-1.6.9/makedumpfile.h -index 93aa774..31319e7 100644 ---- a/makedumpfile-1.6.9/makedumpfile.h -+++ b/makedumpfile-1.6.9/makedumpfile.h -@@ -2049,6 +2049,7 @@ struct number_table { +diff --git a/makedumpfile-1.7.0/makedumpfile.h b/makedumpfile-1.7.0/makedumpfile.h +index e59239d..b6236dd 100644 +--- a/makedumpfile-1.7.0/makedumpfile.h ++++ b/makedumpfile-1.7.0/makedumpfile.h +@@ -2064,6 +2064,7 @@ struct number_table { long phys_base; long KERNEL_IMAGE_SIZE; #ifdef __aarch64__ @@ -81,5 +84,5 @@ index 93aa774..31319e7 100644 long TCR_EL1_T1SZ; unsigned long PHYS_OFFSET; -- -2.27.0 +2.31.1