import kexec-tools-2.0.24-6.el8

c8 imports/c8/kexec-tools-2.0.24-6.el8
CentOS Sources 5 months ago committed by Stepan Oksanichenko
parent f572fac7ad
commit 7f841f0070
  1. 4
      .gitignore
  2. 4
      .kexec-tools.metadata
  3. 112
      SOURCES/kdump-lib.sh
  4. 2
      SOURCES/kdump.sysconfig
  5. 2
      SOURCES/kdump.sysconfig.aarch64
  6. 2
      SOURCES/kdump.sysconfig.i386
  7. 2
      SOURCES/kdump.sysconfig.ppc64
  8. 2
      SOURCES/kdump.sysconfig.ppc64le
  9. 2
      SOURCES/kdump.sysconfig.s390x
  10. 2
      SOURCES/kdump.sysconfig.x86_64
  11. 4
      SOURCES/kdumpctl
  12. 492
      SOURCES/kexec-tools-2.0.20-1-printk-add-support-for-lockless-ringbuffer.patch
  13. 65
      SOURCES/kexec-tools-2.0.20-2-printk-Use-ULL-suffix-for-64-bit-constants.patch
  14. 68
      SOURCES/kexec-tools-2.0.20-3-printk-Use-zu-to-format-size_t.patch
  15. 181
      SOURCES/kexec-tools-2.0.20-Cleanup-move-it-back-from-util_lib-elf_info.c.patch
  16. 84
      SOURCES/kexec-tools-2.0.20-Cleanup-remove-the-read_elf_kcore.patch
  17. 47
      SOURCES/kexec-tools-2.0.20-Fix-an-error-definition-about-the-variable-fname.patch
  18. 55
      SOURCES/kexec-tools-2.0.20-Limit-the-size-of-vmcore-dmesg.txt-to-2G.patch
  19. 99
      SOURCES/kexec-tools-2.0.20-Remove-duplicated-variable-declarations.patch
  20. 82
      SOURCES/kexec-tools-2.0.20-arm64-kdump-deal-with-a-lot-of-resource-entries-in-p.patch
  21. 248
      SOURCES/kexec-tools-2.0.20-arm64-kexec-allocate-memory-space-avoiding-reserved-.patch
  22. 25
      SOURCES/kexec-tools-2.0.20-eppic-Remove-duplicated-variable-declaration.patch
  23. 89
      SOURCES/kexec-tools-2.0.20-kexec-add-variant-helper-functions-for-handling-memo.patch
  24. 38
      SOURCES/kexec-tools-2.0.20-vmcore-dmesg-vmcore-dmesg.c-Fix-shifting-error-repor.patch
  25. 76
      SOURCES/kexec-tools-2.0.24-makedumpfile-Avoid_false_positive_mem_section_validation_with_vmlinux.patch
  26. 4
      SOURCES/mkdumprd
  27. 18
      SOURCES/rhelonly-kexec-tools-2.0.20-makedumpfile-arm64-Add-support-for-ARMv8.2-LVA-52-bi.patch
  28. 91
      SPECS/kexec-tools.spec

4
.gitignore vendored

@ -1,3 +1,3 @@
SOURCES/1.7.0.tar.gz
SOURCES/1.7.1.tar.gz
SOURCES/eppic_050615.tar.gz
SOURCES/kexec-tools-2.0.20.tar.xz
SOURCES/kexec-tools-2.0.24.tar.xz

@ -1,3 +1,3 @@
a931a40b80df204be1b02bfb502921cc618810fd SOURCES/1.7.0.tar.gz
8f8485c2a1edbc730f4fa1b96ae3ec8d8f1f9761 SOURCES/1.7.1.tar.gz
a096c8e0892b559f40b01916aae240652f75b68a SOURCES/eppic_050615.tar.gz
5d9acd2e741d356d4a48fe4f2d63f66ba431051d SOURCES/kexec-tools-2.0.20.tar.xz
62b7a99779d66ffd07a1684f7b640d32c9697f0c SOURCES/kexec-tools-2.0.24.tar.xz

@ -315,9 +315,9 @@ kdump_get_persistent_dev() {
echo $(get_persistent_dev "$dev")
}
is_atomic()
is_ostree()
{
grep -q "ostree" /proc/cmdline
test -f /run/ostree-booted
}
# fixme, try the best to decide whether the ipv6 addr is allocated by slaac or dhcp6
@ -332,11 +332,6 @@ is_ipv6_auto()
fi
}
is_atomic()
{
grep -q "ostree" /proc/cmdline
}
is_ipv6_address()
{
echo $1 | grep -q ":"
@ -692,55 +687,91 @@ prepare_kexec_args()
echo $kexec_args
}
#
# Detect initrd and kernel location, results are stored in global enviromental variables:
# KDUMP_BOOTDIR, KDUMP_KERNELVER, KDUMP_KERNEL, DEFAULT_INITRD, and KDUMP_INITRD
#
# Expectes KDUMP_BOOTDIR, KDUMP_IMG, KDUMP_IMG_EXT, KDUMP_KERNELVER to be loaded from config already
# and will prefer already set values so user can specify custom kernel/initramfs location
#
prepare_kdump_bootinfo()
# prepare_kdump_kernel <kdump_kernelver>
# This function return kdump_kernel given a kernel version.
prepare_kdump_kernel()
{
local boot_imglist boot_dirlist boot_initrdlist curr_kver="$(uname -r)"
local machine_id
if [ -z "$KDUMP_KERNELVER" ]; then
KDUMP_KERNELVER="$(uname -r)"
fi
local kdump_kernelver=$1
local dir img boot_dirlist boot_imglist kdump_kernel machine_id
read -r machine_id < /etc/machine-id
read machine_id < /etc/machine-id
boot_dirlist=${KDUMP_BOOTDIR:-"/boot /boot/efi /efi /"}
boot_imglist="$KDUMP_IMG-$KDUMP_KERNELVER$KDUMP_IMG_EXT $machine_id/$KDUMP_KERNELVER/$KDUMP_IMG"
boot_imglist="$KDUMP_IMG-$kdump_kernelver$KDUMP_IMG_EXT $machine_id/$kdump_kernelver/$KDUMP_IMG"
# The kernel of OSTree based systems is not in the standard locations.
if is_ostree; then
boot_dirlist="$(echo /boot/ostree/*) $boot_dirlist"
fi
# Use BOOT_IMAGE as reference if possible, strip the GRUB root device prefix in (hd0,gpt1) format
local boot_img="$(cat /proc/cmdline | sed "s/^BOOT_IMAGE=\((\S*)\)\?\(\S*\) .*/\2/")"
if [ -n "$boot_img" ]; then
boot_img="$(grep -P -o '^BOOT_IMAGE=(\S+)' /proc/cmdline | sed "s/^BOOT_IMAGE=\((\S*)\)\?\(\S*\)/\2/")"
if [[ "$boot_img" == *"$kdump_kernelver" ]]; then
boot_imglist="$boot_img $boot_imglist"
fi
for dir in $boot_dirlist; do
for img in $boot_imglist; do
if [ -f "$dir/$img" ]; then
KDUMP_KERNEL=$(echo $dir/$img | tr -s '/')
if [[ -f "$dir/$img" ]]; then
kdump_kernel=$(echo "$dir/$img" | tr -s '/')
break 2
fi
done
done
echo "$kdump_kernel"
}
if ! [ -e "$KDUMP_KERNEL" ]; then
#
# Detect initrd and kernel location, results are stored in global enviromental variables:
# KDUMP_BOOTDIR, KDUMP_KERNELVER, KDUMP_KERNEL, DEFAULT_INITRD, and KDUMP_INITRD
#
# Expectes KDUMP_BOOTDIR, KDUMP_IMG, KDUMP_IMG_EXT, KDUMP_KERNELVER to be loaded from config already
# and will prefer already set values so user can specify custom kernel/initramfs location
#
prepare_kdump_bootinfo()
{
local boot_initrdlist nondebug_kernelver debug_kernelver
local default_initrd_base var_target_initrd_dir
if [[ -z $KDUMP_KERNELVER ]]; then
KDUMP_KERNELVER=$(uname -r)
nondebug_kernelver=$(sed -n -e 's/\(.*\)+debug$/\1/p' <<< "$KDUMP_KERNELVER")
fi
# Use nondebug kernel if possible, because debug kernel will consume more memory and may oom.
if [[ -n $nondebug_kernelver ]]; then
dinfo "Trying to use $nondebug_kernelver."
debug_kernelver=$KDUMP_KERNELVER
KDUMP_KERNELVER=$nondebug_kernelver
fi
KDUMP_KERNEL=$(prepare_kdump_kernel "$KDUMP_KERNELVER")
if ! [[ -e $KDUMP_KERNEL ]]; then
if [[ -n $debug_kernelver ]]; then
dinfo "Fallback to using debug kernel"
KDUMP_KERNELVER=$debug_kernelver
KDUMP_KERNEL=$(prepare_kdump_kernel "$KDUMP_KERNELVER")
fi
fi
if ! [[ -e $KDUMP_KERNEL ]]; then
derror "Failed to detect kdump kernel location"
return 1
fi
if [[ "$KDUMP_KERNEL" == *"+debug" ]]; then
dwarn "Using debug kernel, you may need to set a larger crashkernel than the default value."
fi
# Set KDUMP_BOOTDIR to where kernel image is stored
KDUMP_BOOTDIR=$(dirname $KDUMP_KERNEL)
KDUMP_BOOTDIR=$(dirname "$KDUMP_KERNEL")
# Default initrd should just stay aside of kernel image, try to find it in KDUMP_BOOTDIR
boot_initrdlist="initramfs-$KDUMP_KERNELVER.img initrd"
for initrd in $boot_initrdlist; do
if [ -f "$KDUMP_BOOTDIR/$initrd" ]; then
defaut_initrd_base="$initrd"
DEFAULT_INITRD="$KDUMP_BOOTDIR/$defaut_initrd_base"
if [[ -f "$KDUMP_BOOTDIR/$initrd" ]]; then
default_initrd_base="$initrd"
DEFAULT_INITRD="$KDUMP_BOOTDIR/$default_initrd_base"
break
fi
done
@ -748,16 +779,16 @@ prepare_kdump_bootinfo()
# Create kdump initrd basename from default initrd basename
# initramfs-5.7.9-200.fc32.x86_64.img => initramfs-5.7.9-200.fc32.x86_64kdump.img
# initrd => initrdkdump
if [[ -z "$defaut_initrd_base" ]]; then
if [[ -z $default_initrd_base ]]; then
kdump_initrd_base=initramfs-${KDUMP_KERNELVER}kdump.img
elif [[ $defaut_initrd_base == *.* ]]; then
kdump_initrd_base=${defaut_initrd_base%.*}kdump.${DEFAULT_INITRD##*.}
elif [[ $default_initrd_base == *.* ]]; then
kdump_initrd_base=${default_initrd_base%.*}kdump.${DEFAULT_INITRD##*.}
else
kdump_initrd_base=${defaut_initrd_base}kdump
kdump_initrd_base=${default_initrd_base}kdump
fi
# Place kdump initrd in `/var/lib/kdump` if `KDUMP_BOOTDIR` not writable
if [[ ! -w "$KDUMP_BOOTDIR" ]];then
# Place kdump initrd in $(/var/lib/kdump) if $(KDUMP_BOOTDIR) not writable
if [[ ! -w $KDUMP_BOOTDIR ]]; then
var_target_initrd_dir="/var/lib/kdump"
mkdir -p "$var_target_initrd_dir"
KDUMP_INITRD="$var_target_initrd_dir/$kdump_initrd_base"
@ -930,9 +961,12 @@ kdump_get_arch_recommend_size()
# $1: the block device to be checked in maj:min format
get_luks_crypt_dev()
{
local _type
[[ -b /dev/block/$1 ]] || return 1
local _type=$(eval "$(blkid -u filesystem,crypto -o export -- /dev/block/$1); echo \$TYPE")
_type=$(blkid -u filesystem,crypto -o export -- "/dev/block/$1" | \
sed -n -E "s/^TYPE=(.*)$/\1/p")
[[ $_type == "crypto_LUKS" ]] && echo $1
for _x in /sys/dev/block/$1/slaves/*; do

@ -17,7 +17,7 @@ KDUMP_COMMANDLINE=""
# This variable lets us remove arguments from the current kdump commandline
# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
# NOTE: some arguments such as crashkernel will always be removed
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len"
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len ignition.firstboot"
# This variable lets us append arguments to the current kdump commandline
# after processed by KDUMP_COMMANDLINE_REMOVE

@ -17,7 +17,7 @@ KDUMP_COMMANDLINE=""
# This variable lets us remove arguments from the current kdump commandline
# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
# NOTE: some arguments such as crashkernel will always be removed
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb"
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb ignition.firstboot"
# This variable lets us append arguments to the current kdump commandline
# after processed by KDUMP_COMMANDLINE_REMOVE

@ -17,7 +17,7 @@ KDUMP_COMMANDLINE=""
# This variable lets us remove arguments from the current kdump commandline
# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
# NOTE: some arguments such as crashkernel will always be removed
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb"
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb ignition.firstboot"
# This variable lets us append arguments to the current kdump commandline
# after processed by KDUMP_COMMANDLINE_REMOVE

@ -17,7 +17,7 @@ KDUMP_COMMANDLINE=""
# This variable lets us remove arguments from the current kdump commandline
# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
# NOTE: some arguments such as crashkernel will always be removed
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb"
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb ignition.firstboot"
# This variable lets us append arguments to the current kdump commandline
# after processed by KDUMP_COMMANDLINE_REMOVE

@ -17,7 +17,7 @@ KDUMP_COMMANDLINE=""
# This variable lets us remove arguments from the current kdump commandline
# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
# NOTE: some arguments such as crashkernel will always be removed
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb"
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb ignition.firstboot"
# This variable lets us append arguments to the current kdump commandline
# after processed by KDUMP_COMMANDLINE_REMOVE

@ -17,7 +17,7 @@ KDUMP_COMMANDLINE=""
# This variable lets us remove arguments from the current kdump commandline
# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
# NOTE: some arguments such as crashkernel will always be removed
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb prot_virt"
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb prot_virt ignition.firstboot"
# This variable lets us append arguments to the current kdump commandline
# after processed by KDUMP_COMMANDLINE_REMOVE

@ -17,7 +17,7 @@ KDUMP_COMMANDLINE=""
# This variable lets us remove arguments from the current kdump commandline
# as taken from either KDUMP_COMMANDLINE above, or from /proc/cmdline
# NOTE: some arguments such as crashkernel will always be removed
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb"
KDUMP_COMMANDLINE_REMOVE="hugepages hugepagesz slub_debug quiet log_buf_len swiotlb ignition.firstboot"
# This variable lets us append arguments to the current kdump commandline
# after processed by KDUMP_COMMANDLINE_REMOVE

@ -110,6 +110,7 @@ rebuild_fadump_initrd()
return 1
fi
sync -f "$TARGET_INITRD"
return 0
}
@ -132,6 +133,7 @@ rebuild_kdump_initrd()
dwarn "Tips: If early kdump is enabled, also require rebuilding the system initramfs to make the changes take effect for early kdump."
fi
sync -f "$TARGET_INITRD"
return 0
}
@ -214,7 +216,7 @@ restore_default_initrd()
mv $DEFAULT_INITRD_BAK $DEFAULT_INITRD
if [[ $? -eq 0 ]]; then
derror "Restoring original initrd as fadump mode is disabled."
sync
sync -f "$DEFAULT_INITRD"
fi
fi
fi

@ -1,492 +0,0 @@
From 4149df9005f2cdd2ecf70058dfe7d72f48c3a68c Mon Sep 17 00:00:00 2001
From: John Ogness <john.ogness@linutronix.de>
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 <john.ogness@linutronix.de>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
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

@ -1,65 +0,0 @@
From 07b272a07164b902acd7d12794f7be033ebf4525 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert+renesas@glider.be>
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 <geert+renesas@glider.be>
Reviewed-by: John Ogness <john.ogness@linutronix.de>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
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

@ -1,68 +0,0 @@
From 82f7de2724c42a6aecc0cff93881b3dfd09363ce Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert+renesas@glider.be>
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 <geert+renesas@glider.be>
Reviewed-by: John Ogness <john.ogness@linutronix.de>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
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

@ -1,181 +0,0 @@
From a7c4cb8e998571cb3dd62e907935a1e052b15d6c Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
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 <lijiang@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
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

@ -1,84 +0,0 @@
From 545c811050a375f79e0fa0e107cb35b9ae3a1599 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
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 <lijiang@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
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

@ -1,47 +0,0 @@
From 14ad054e7baa788a6629385ffe5e0f1996b7de02 Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
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 <lijiang@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
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

@ -1,55 +0,0 @@
From fa3f0ed47f3e6dbee485722d13713ad495571b7e Mon Sep 17 00:00:00 2001
From: Lianbo Jiang <lijiang@redhat.com>
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 <lijiang@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
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

@ -1,99 +0,0 @@
From cc087b11462af9f971a2c090d07e8d780a867b50 Mon Sep 17 00:00:00 2001
From: Kairui Song <kasong@redhat.com>
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 <kasong@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
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 <arch/options.h>
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

@ -1,82 +0,0 @@
From 2572b8d702e452624bdb8d7b7c39f458e7dcf2ce Mon Sep 17 00:00:00 2001
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
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 <takahiro.akashi@linaro.org>
Tested-by: Bhupesh Sharma <bhsharma@redhat.com>
Tested-by: Masayoshi Mizuma <m.mizuma@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
---
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

@ -1,248 +0,0 @@
From f736104f533290b4ce6fbfbca74abde9ffd3888c Mon Sep 17 00:00:00 2001
From: AKASHI Takahiro <takahiro.akashi@linaro.org>
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