parent
6b51ad8c27
commit
f572fac7ad
@ -1,3 +1,3 @@
|
||||
SOURCES/1.6.8.tar.gz
|
||||
SOURCES/1.7.0.tar.gz
|
||||
SOURCES/eppic_050615.tar.gz
|
||||
SOURCES/kexec-tools-2.0.20.tar.xz
|
||||
|
@ -1,3 +1,3 @@
|
||||
7af5b92c69df9f63b9f02ad07a76a2a2581d4660 SOURCES/1.6.8.tar.gz
|
||||
a931a40b80df204be1b02bfb502921cc618810fd SOURCES/1.7.0.tar.gz
|
||||
a096c8e0892b559f40b01916aae240652f75b68a SOURCES/eppic_050615.tar.gz
|
||||
5d9acd2e741d356d4a48fe4f2d63f66ba431051d SOURCES/kexec-tools-2.0.20.tar.xz
|
||||
|
@ -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 </proc/mounts
|
||||
done
|
||||
umount -d -l oldroot
|
||||
|
||||
exec /init
|
||||
fi
|
||||
else
|
||||
exec /init.dracut
|
||||
fi
|
@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
|
||||
check() {
|
||||
return 255
|
||||
}
|
||||
|
||||
depends() {
|
||||
return 0
|
||||
}
|
||||
|
||||
install() {
|
||||
mv -f "$initdir/init" "$initdir/init.dracut"
|
||||
inst_script "$moddir/init-fadump.sh" /init
|
||||
chmod a+x "$initdir/init"
|
||||
|
||||
# Install required binaries for the init script (init-fadump.sh)
|
||||
inst_multiple sh modprobe grep mkdir mount
|
||||
if dracut_module_included "squash"; then
|
||||
inst_multiple cp pivot_root umount
|
||||
else
|
||||
inst_multiple ls mv switch_root
|
||||
fi
|
||||
}
|
@ -0,0 +1,492 @@
|
||||
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,177 +0,0 @@
|
||||
From 3422e1d6bc3511c5af9cb05ba74ad97dd93ffd7f Mon Sep 17 00:00:00 2001
|
||||
From: Julien Thierry <jthierry@redhat.com>
|
||||
Date: Tue, 24 Nov 2020 10:45:24 +0000
|
||||
Subject: [PATCH] [PATCH 1/2] Add --dry-run option to prevent writing the
|
||||
dumpfile
|
||||
|
||||
Add a --dry-run option to run all operations without writing the
|
||||
dump to the output file.
|
||||
|
||||
Signed-off-by: Julien Thierry <jthierry@redhat.com>
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
makedumpfile.8 | 6 ++++++
|
||||
makedumpfile.c | 37 ++++++++++++++++++++++++++++++-------
|
||||
makedumpfile.h | 2 ++
|
||||
print_info.c | 3 +++
|
||||
4 files changed, 41 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/makedumpfile-1.6.8/makedumpfile.8 b/makedumpfile-1.6.8/makedumpfile.8
|
||||
index b68a7e3..5e902cd 100644
|
||||
--- a/makedumpfile-1.6.8/makedumpfile.8
|
||||
+++ b/makedumpfile-1.6.8/makedumpfile.8
|
||||
@@ -637,6 +637,12 @@ Show the version of makedumpfile.
|
||||
Only check whether the command-line parameters are valid or not, and exit.
|
||||
Preferable to be given as the first parameter.
|
||||
|
||||
+.TP
|
||||
+\fB\-\-dry-run\fR
|
||||
+Do not write the output dump file while still performing operations specified
|
||||
+by other options.
|
||||
+This option cannot be used with the --dump-dmesg, --reassemble and -g options.
|
||||
+
|
||||
.SH ENVIRONMENT VARIABLES
|
||||
|
||||
.TP 8
|
||||
diff --git a/makedumpfile-1.6.8/makedumpfile.c b/makedumpfile-1.6.8/makedumpfile.c
|
||||
index ecd63fa..8c80c49 100644
|
||||
--- a/makedumpfile-1.6.8/makedumpfile.c
|
||||
+++ b/makedumpfile-1.6.8/makedumpfile.c
|
||||
@@ -1372,6 +1372,8 @@ open_dump_file(void)
|
||||
if (info->flag_flatten) {
|
||||
fd = STDOUT_FILENO;
|
||||
info->name_dumpfile = filename_stdout;
|
||||
+ } else if (info->flag_dry_run) {
|
||||
+ fd = -1;
|
||||
} else if ((fd = open(info->name_dumpfile, open_flags,
|
||||
S_IRUSR|S_IWUSR)) < 0) {
|
||||
ERRMSG("Can't open the dump file(%s). %s\n",
|
||||
@@ -4711,6 +4713,9 @@ write_and_check_space(int fd, void *buf, size_t buf_size, char *file_name)
|
||||
{
|
||||
int status, written_size = 0;
|
||||
|
||||
+ if (info->flag_dry_run)
|
||||
+ return TRUE;
|
||||
+
|
||||
while (written_size < buf_size) {
|
||||
status = write(fd, buf + written_size,
|
||||
buf_size - written_size);
|
||||
@@ -4748,13 +4753,12 @@ write_buffer(int fd, off_t offset, void *buf, size_t buf_size, char *file_name)
|
||||
}
|
||||
if (!write_and_check_space(fd, &fdh, sizeof(fdh), file_name))
|
||||
return FALSE;
|
||||
- } else {
|
||||
- if (lseek(fd, offset, SEEK_SET) == failed) {
|
||||
- ERRMSG("Can't seek the dump file(%s). %s\n",
|
||||
- file_name, strerror(errno));
|
||||
- return FALSE;
|
||||
- }
|
||||
+ } else if (!info->flag_dry_run &&
|
||||
+ lseek(fd, offset, SEEK_SET) == failed) {
|
||||
+ ERRMSG("Can't seek the dump file(%s). %s\n", file_name, strerror(errno));
|
||||
+ return FALSE;
|
||||
}
|
||||
+
|
||||
if (!write_and_check_space(fd, buf, buf_size, file_name))
|
||||
return FALSE;
|
||||
|
||||
@@ -9112,7 +9116,7 @@ close_dump_memory(void)
|
||||
void
|
||||
close_dump_file(void)
|
||||
{
|
||||
- if (info->flag_flatten)
|
||||
+ if (info->flag_flatten || info->flag_dry_run)
|
||||
return;
|
||||
|
||||
if (close(info->fd_dumpfile) < 0)
|
||||
@@ -10985,6 +10989,11 @@ check_param_for_generating_vmcoreinfo(int argc, char *argv[])
|
||||
|
||||
return FALSE;
|
||||
|
||||
+ if (info->flag_dry_run) {
|
||||
+ MSG("--dry-run cannot be used with -g.\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -11029,6 +11038,11 @@ check_param_for_reassembling_dumpfile(int argc, char *argv[])
|
||||
|| info->flag_exclude_xen_dom || info->flag_split)
|
||||
return FALSE;
|
||||
|
||||
+ if (info->flag_dry_run) {
|
||||
+ MSG("--dry-run cannot be used with --reassemble.\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
if ((info->splitting_info
|
||||
= malloc(sizeof(struct splitting_info) * info->num_dumpfile))
|
||||
== NULL) {
|
||||
@@ -11057,6 +11071,11 @@ check_param_for_creating_dumpfile(int argc, char *argv[])
|
||||
|| (info->flag_read_vmcoreinfo && info->name_xen_syms))
|
||||
return FALSE;
|
||||
|
||||
+ if (info->flag_dry_run && info->flag_dmesg) {
|
||||
+ MSG("--dry-run cannot be used with --dump-dmesg.\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
if (info->flag_flatten && info->flag_split)
|
||||
return FALSE;
|
||||
|
||||
@@ -11520,6 +11539,7 @@ static struct option longopts[] = {
|
||||
{"work-dir", required_argument, NULL, OPT_WORKING_DIR},
|
||||
{"num-threads", required_argument, NULL, OPT_NUM_THREADS},
|
||||
{"check-params", no_argument, NULL, OPT_CHECK_PARAMS},
|
||||
+ {"dry-run", no_argument, NULL, OPT_DRY_RUN},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -11686,6 +11706,9 @@ main(int argc, char *argv[])
|
||||
info->flag_check_params = TRUE;
|
||||
message_level = DEFAULT_MSG_LEVEL;
|
||||
break;
|
||||
+ case OPT_DRY_RUN:
|
||||
+ info->flag_dry_run = TRUE;
|
||||
+ break;
|
||||
case '?':
|
||||
MSG("Commandline parameter is invalid.\n");
|
||||
MSG("Try `makedumpfile --help' for more information.\n");
|
||||
diff --git a/makedumpfile-1.6.8/makedumpfile.h b/makedumpfile-1.6.8/makedumpfile.h
|
||||
index 5f50080..4c4222c 100644
|
||||
--- a/makedumpfile-1.6.8/makedumpfile.h
|
||||
+++ b/makedumpfile-1.6.8/makedumpfile.h
|
||||
@@ -1322,6 +1322,7 @@ struct DumpInfo {
|
||||
int flag_vmemmap; /* kernel supports vmemmap address space */
|
||||
int flag_excludevm; /* -e - excluding unused vmemmap pages */
|
||||
int flag_use_count; /* _refcount is named _count in struct page */
|
||||
+ int flag_dry_run; /* do not create a vmcore file */
|
||||
unsigned long vaddr_for_vtop; /* virtual address for debugging */
|
||||
long page_size; /* size of page */
|
||||
long page_shift;
|
||||
@@ -2425,6 +2426,7 @@ struct elf_prstatus {
|
||||
#define OPT_NUM_THREADS OPT_START+16
|
||||
#define OPT_PARTIAL_DMESG OPT_START+17
|
||||
#define OPT_CHECK_PARAMS OPT_START+18
|
||||
+#define OPT_DRY_RUN OPT_START+19
|
||||
|
||||
/*
|
||||
* Function Prototype.
|
||||
diff --git a/makedumpfile-1.6.8/print_info.c b/makedumpfile-1.6.8/print_info.c
|
||||
index e0c38b4..d2b0cb7 100644
|
||||
--- a/makedumpfile-1.6.8/print_info.c
|
||||
+++ b/makedumpfile-1.6.8/print_info.c
|
||||
@@ -308,6 +308,9 @@ print_usage(void)
|
||||
MSG(" the crashkernel range, then calculates the page number of different kind per\n");
|
||||
MSG(" vmcoreinfo. So currently /proc/kcore need be specified explicitly.\n");
|
||||
MSG("\n");
|
||||
+ MSG(" [--dry-run]:\n");
|
||||
+ MSG(" This option runs makedumpfile without writting output dump file.\n");
|
||||
+ MSG("\n");
|
||||
MSG(" [-D]:\n");
|
||||
MSG(" Print debugging message.\n");
|
||||
MSG("\n");
|
||||
--
|
||||
2.29.2
|
||||
|
@ -1,107 +0,0 @@
|
||||
From 6f3e75a558ed50d6ff0b42e3f61c099b2005b7bb Mon Sep 17 00:00:00 2001
|
||||
From: Julien Thierry <jthierry@redhat.com>
|
||||
Date: Tue, 24 Nov 2020 10:45:25 +0000
|
||||
Subject: [PATCH] [PATCH 2/2] Add shorthand --show-stats option to show report
|
||||
stats
|
||||
|
||||
Provide shorthand --show-stats option to enable report messages
|
||||
without needing to set a particular value for message-level.
|
||||
|
||||
Signed-off-by: Julien Thierry <jthierry@redhat.com>
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
makedumpfile.8 | 5 +++++
|
||||
makedumpfile.c | 9 ++++++++-
|
||||
makedumpfile.h | 1 +
|
||||
print_info.c | 7 ++++++-
|
||||
4 files changed, 20 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/makedumpfile-1.6.8/makedumpfile.8 b/makedumpfile-1.6.8/makedumpfile.8
|
||||
index 5e902cd..dcca2dd 100644
|
||||
--- a/makedumpfile-1.6.8/makedumpfile.8
|
||||
+++ b/makedumpfile-1.6.8/makedumpfile.8
|
||||
@@ -643,6 +643,11 @@ Do not write the output dump file while still performing operations specified
|
||||
by other options.
|
||||
This option cannot be used with the --dump-dmesg, --reassemble and -g options.
|
||||
|
||||
+.TP
|
||||
+\fB\-\-show-stats\fR
|
||||
+Display report messages. This is an alternative to enabling bit 4 in the level
|
||||
+provided to --message-level.
|
||||
+
|
||||
.SH ENVIRONMENT VARIABLES
|
||||
|
||||
.TP 8
|
||||
diff --git a/makedumpfile-1.6.8/makedumpfile.c b/makedumpfile-1.6.8/makedumpfile.c
|
||||
index 8c80c49..ba0003a 100644
|
||||
--- a/makedumpfile-1.6.8/makedumpfile.c
|
||||
+++ b/makedumpfile-1.6.8/makedumpfile.c
|
||||
@@ -11540,13 +11540,14 @@ static struct option longopts[] = {
|
||||
{"num-threads", required_argument, NULL, OPT_NUM_THREADS},
|
||||
{"check-params", no_argument, NULL, OPT_CHECK_PARAMS},
|
||||
{"dry-run", no_argument, NULL, OPT_DRY_RUN},
|
||||
+ {"show-stats", no_argument, NULL, OPT_SHOW_STATS},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
- int i, opt, flag_debug = FALSE;
|
||||
+ int i, opt, flag_debug = FALSE, flag_show_stats = FALSE;
|
||||
|
||||
if ((info = calloc(1, sizeof(struct DumpInfo))) == NULL) {
|
||||
ERRMSG("Can't allocate memory for the pagedesc cache. %s.\n",
|
||||
@@ -11709,6 +11710,9 @@ main(int argc, char *argv[])
|
||||
case OPT_DRY_RUN:
|
||||
info->flag_dry_run = TRUE;
|
||||
break;
|
||||
+ case OPT_SHOW_STATS:
|
||||
+ flag_show_stats = TRUE;
|
||||
+ break;
|
||||
case '?':
|
||||
MSG("Commandline parameter is invalid.\n");
|
||||
MSG("Try `makedumpfile --help' for more information.\n");
|
||||
@@ -11718,6 +11722,9 @@ main(int argc, char *argv[])
|
||||
if (flag_debug)
|
||||
message_level |= ML_PRINT_DEBUG_MSG;
|
||||
|
||||
+ if (flag_show_stats)
|
||||
+ message_level |= ML_PRINT_REPORT_MSG;
|
||||
+
|
||||
if (info->flag_check_params)
|
||||
/* suppress debugging messages */
|
||||
message_level = DEFAULT_MSG_LEVEL;
|
||||
diff --git a/makedumpfile-1.6.8/makedumpfile.h b/makedumpfile-1.6.8/makedumpfile.h
|
||||
index 4c4222c..2fcb62e 100644
|
||||
--- a/makedumpfile-1.6.8/makedumpfile.h
|
||||
+++ b/makedumpfile-1.6.8/makedumpfile.h
|
||||
@@ -2427,6 +2427,7 @@ struct elf_prstatus {
|
||||
#define OPT_PARTIAL_DMESG OPT_START+17
|
||||
#define OPT_CHECK_PARAMS OPT_START+18
|
||||
#define OPT_DRY_RUN OPT_START+19
|
||||
+#define OPT_SHOW_STATS OPT_START+20
|
||||
|
||||
/*
|
||||
* Function Prototype.
|
||||
diff --git a/makedumpfile-1.6.8/print_info.c b/makedumpfile-1.6.8/print_info.c
|
||||
index d2b0cb7..ad4184e 100644
|
||||
--- a/makedumpfile-1.6.8/print_info.c
|
||||
+++ b/makedumpfile-1.6.8/print_info.c
|
||||
@@ -309,7 +309,12 @@ print_usage(void)
|
||||
MSG(" vmcoreinfo. So currently /proc/kcore need be specified explicitly.\n");
|
||||
MSG("\n");
|
||||
MSG(" [--dry-run]:\n");
|
||||
- MSG(" This option runs makedumpfile without writting output dump file.\n");
|
||||
+ MSG(" Do not write the output dump file while still performing operations specified\n");
|
||||
+ MSG(" by other options. This option cannot be used with --dump-dmesg, --reassemble\n");
|
||||
+ MSG(" and -g options.\n");
|
||||
+ MSG("\n");
|
||||
+ MSG(" [--show-stats]:\n");
|
||||
+ MSG(" Set message-level to print report messages\n");
|
||||
MSG("\n");
|
||||
MSG(" [-D]:\n");
|
||||
MSG(" Print debugging message.\n");
|
||||
--
|
||||
2.29.2
|
||||
|
@ -1,59 +0,0 @@
|
||||
From 0ef2ca6c9fa2f61f217a4bf5d7fd70f24e12b2eb Mon Sep 17 00:00:00 2001
|
||||
From: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
Date: Thu, 4 Feb 2021 16:29:06 +0900
|
||||
Subject: [PATCH] [PATCH] Show write byte size in report messages
|
||||
|
||||
Show write byte size in report messages. This value can be different
|
||||
from the size of the actual file because of some holes on dumpfile
|
||||
data structure.
|
||||
|
||||
$ makedumpfile --show-stats -l -d 1 vmcore dump.ld1
|
||||
...
|
||||
Total pages : 0x0000000000080000
|
||||
Write bytes : 377686445
|
||||
...
|
||||
# ls -l dump.ld1
|
||||
-rw------- 1 root root 377691573 Feb 4 16:28 dump.ld1
|
||||
|
||||
Note that this value should not be used with /proc/kcore to determine
|
||||
how much disk space is needed for crash dump, because the real memory
|
||||
usage when a crash occurs can vary widely.
|
||||
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
makedumpfile.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/makedumpfile-1.6.8/makedumpfile.c b/makedumpfile-1.6.8/makedumpfile.c
|
||||
index fcd766b..894c88e 100644
|
||||
--- a/makedumpfile-1.6.8/makedumpfile.c
|
||||
+++ b/makedumpfile-1.6.8/makedumpfile.c
|
||||
@@ -48,6 +48,8 @@ char filename_stdout[] = FILENAME_STDOUT;
|
||||
static unsigned long long cache_hit;
|
||||
static unsigned long long cache_miss;
|
||||
|
||||
+static unsigned long long write_bytes;
|
||||
+
|
||||
static void first_cycle(mdf_pfn_t start, mdf_pfn_t max, struct cycle *cycle)
|
||||
{
|
||||
cycle->start_pfn = round(start, info->pfn_cyclic);
|
||||
@@ -4715,6 +4717,8 @@ write_and_check_space(int fd, void *buf, size_t buf_size, char *file_name)
|
||||
{
|
||||
int status, written_size = 0;
|
||||
|
||||
+ write_bytes += buf_size;
|
||||
+
|
||||
if (info->flag_dry_run)
|
||||
return TRUE;
|
||||
|
||||
@@ -10002,6 +10006,7 @@ print_report(void)
|
||||
REPORT_MSG("Memory Hole : 0x%016llx\n", pfn_memhole);
|
||||
REPORT_MSG("--------------------------------------------------\n");
|
||||
REPORT_MSG("Total pages : 0x%016llx\n", info->max_mapnr);
|
||||
+ REPORT_MSG("Write bytes : %llu\n", write_bytes);
|
||||
REPORT_MSG("\n");
|
||||
REPORT_MSG("Cache hit: %lld, miss: %lld", cache_hit, cache_miss);
|
||||
if (cache_hit + cache_miss)
|
||||
--
|
||||
2.29.2
|
||||
|
@ -1,60 +0,0 @@
|
||||
From 38d921a2ef50ebd36258097553626443ffe27496 Mon Sep 17 00:00:00 2001
|
||||
From: Coiby Xu <coxu@redhat.com>
|
||||
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 <yiyan@redhat.com>
|
||||
Signed-off-by: Coiby Xu <coxu@redhat.com>
|
||||
---
|
||||
elf_info.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/makedumpfile-1.6.8/elf_info.c b/makedumpfile-1.6.8/elf_info.c
|
||||
index e8affb7..bc24083 100644
|
||||
--- a/makedumpfile-1.6.8/elf_info.c
|
||||
+++ b/makedumpfile-1.6.8/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
|
||||
|
@ -1,43 +0,0 @@
|
||||
From 9a6f589d99dcef114c89fde992157f5467028c8f Mon Sep 17 00:00:00 2001
|
||||
From: Tao Liu <ltao@redhat.com>
|
||||
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 <ltao@redhat.com>
|
||||
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
|
||||
---
|
||||
makedumpfile.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/makedumpfile-1.6.8/makedumpfile.c b/makedumpfile-1.6.8/makedumpfile.c
|
||||
index 894c88e..fcb571f 100644
|
||||
--- a/makedumpfile-1.6.8/makedumpfile.c
|
||||
+++ b/makedumpfile-1.6.8/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
|
||||
|
@ -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
|