From 7d0122bd5dd67f1896d4cbf84281a665706b6c75 Mon Sep 17 00:00:00 2001 From: DistroBaker Date: Wed, 23 Dec 2020 10:00:07 +0000 Subject: [PATCH] Merged update from upstream sources This is an automated DistroBaker update from upstream sources. If you do not know what this is about or would like to opt out, contact the OSCI team. Source: https://src.fedoraproject.org/rpms/kexec-tools.git#7cb4be80cdaaf85b7dcbdf8f15b113192159026b --- dracut-module-setup.sh | 5 +- kdump-lib-initramfs.sh | 3 +- ...-broken-multiboot2-buliding-for-i386.patch | 88 --- ...-add-support-for-lockless-ringbuffer.patch | 587 ++++++++++++++++++ ...-use-committed-finalized-state-value.patch | 99 +++ kexec-tools.spec | 21 +- mkdumprd.8 | 8 +- sources | 2 +- 8 files changed, 712 insertions(+), 101 deletions(-) delete mode 100644 kexec-tools-2.0.20-fix-broken-multiboot2-buliding-for-i386.patch create mode 100644 kexec-tools-2.0.20-makedumpfile-printk-add-support-for-lockless-ringbuffer.patch create mode 100644 kexec-tools-2.0.20-makedumpfile-printk-use-committed-finalized-state-value.patch diff --git a/dracut-module-setup.sh b/dracut-module-setup.sh index 5c41e63..21f7105 100755 --- a/dracut-module-setup.sh +++ b/dracut-module-setup.sh @@ -373,7 +373,7 @@ kdump_install_net() { if [ -n "$_static" ]; then _proto=none elif is_ipv6_address $_srcaddr; then - _proto=either6 + _proto=auto6 else _proto=dhcp fi @@ -849,8 +849,7 @@ install() { inst "/lib/kdump/kdump-logger.sh" "/lib/kdump-logger.sh" inst "$moddir/kdump.sh" "/usr/bin/kdump.sh" inst "$moddir/kdump-capture.service" "$systemdsystemunitdir/kdump-capture.service" - mkdir -p "$initdir/$systemdsystemunitdir/initrd.target.wants" - ln_r "$systemdsystemunitdir/kdump-capture.service" "$systemdsystemunitdir/initrd.target.wants/kdump-capture.service" + systemctl -q --root "$initdir" add-wants initrd.target kdump-capture.service inst "$moddir/kdump-error-handler.sh" "/usr/bin/kdump-error-handler.sh" inst "$moddir/kdump-error-handler.service" "$systemdsystemunitdir/kdump-error-handler.service" # Replace existing emergency service and emergency target diff --git a/kdump-lib-initramfs.sh b/kdump-lib-initramfs.sh index 9275c83..791d141 100755 --- a/kdump-lib-initramfs.sh +++ b/kdump-lib-initramfs.sh @@ -222,7 +222,8 @@ dump_to_rootfs() { dinfo "Trying to bring up rootfs device" - systemctl start dracut-initqueue + systemctl is-failed dracut-initqueue || systemctl start dracut-initqueue + dinfo "Waiting for rootfs mount, will timeout after 90 seconds" systemctl start sysroot.mount diff --git a/kexec-tools-2.0.20-fix-broken-multiboot2-buliding-for-i386.patch b/kexec-tools-2.0.20-fix-broken-multiboot2-buliding-for-i386.patch deleted file mode 100644 index 3f0fb33..0000000 --- a/kexec-tools-2.0.20-fix-broken-multiboot2-buliding-for-i386.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 940c3a1e1a304fbecc850c593a272215b0f52eab Mon Sep 17 00:00:00 2001 -From: Kairui Song -Date: Wed, 31 Jul 2019 16:30:47 +0800 -Subject: [PATCH] x86: Fix broken multiboot2 buliding for i386 - -When building for i386, an error occured: - -kexec/arch/i386/kexec-x86.c:39:22: error: 'multiboot2_x86_probe' -undeclared here (not in a function); did you mean 'multiboot_x86_probe'? -39 | { "multiboot2-x86", multiboot2_x86_probe, multiboot2_x86_load, - | ^~~~~~~~~~~~~~~~~~~~ - | multiboot_x86_probe - -kexec/arch/i386/kexec-x86.c:39:44: error: 'multiboot2_x86_load' -undeclared here (not in a function); did you mean 'multiboot_x86_load'? -39 | { "multiboot2-x86", multiboot2_x86_probe, multiboot2_x86_load, - | ^~~~~~~~~~~~~~~~~~~ - | multiboot_x86_load -kexec/arch/i386/kexec-x86.c:40:4: error: 'multiboot2_x86_usage' - undeclared here (not in a function); did you mean 'multiboot_x86_usage'? -40 | multiboot2_x86_usage }, - | ^~~~~~~~~~~~~~~~~~~~ - | multiboot_x86_usage - -Fix this issue by putting the definition in the right header, also tidy -up Makefile. - -Fixes: 22a2ed55132e ("x86: Support multiboot2 images") -Signed-off-by: Kairui Song ---- - kexec/arch/i386/Makefile | 2 +- - kexec/arch/i386/kexec-x86.h | 5 +++++ - kexec/arch/x86_64/kexec-x86_64.h | 5 ----- - 3 files changed, 6 insertions(+), 6 deletions(-) - -diff --git a/kexec/arch/i386/Makefile b/kexec/arch/i386/Makefile -index 105cefd..f486103 100644 ---- a/kexec/arch/i386/Makefile -+++ b/kexec/arch/i386/Makefile -@@ -7,6 +7,7 @@ i386_KEXEC_SRCS += kexec/arch/i386/kexec-elf-x86.c - i386_KEXEC_SRCS += kexec/arch/i386/kexec-elf-rel-x86.c - i386_KEXEC_SRCS += kexec/arch/i386/kexec-bzImage.c - i386_KEXEC_SRCS += kexec/arch/i386/kexec-multiboot-x86.c -+i386_KEXEC_SRCS += kexec/arch/i386/kexec-mb2-x86.c - i386_KEXEC_SRCS += kexec/arch/i386/kexec-beoboot-x86.c - i386_KEXEC_SRCS += kexec/arch/i386/kexec-nbi.c - i386_KEXEC_SRCS += kexec/arch/i386/x86-linux-setup.c -@@ -14,7 +15,6 @@ i386_KEXEC_SRCS += kexec/arch/i386/crashdump-x86.c - - dist += kexec/arch/i386/Makefile $(i386_KEXEC_SRCS) \ - kexec/arch/i386/crashdump-x86.h \ -- kexec/arch/i386/kexec-mb2-x86.c \ - kexec/arch/i386/kexec-x86.h \ - kexec/arch/i386/x86-linux-setup.h \ - kexec/arch/i386/include/arch/options.h -diff --git a/kexec/arch/i386/kexec-x86.h b/kexec/arch/i386/kexec-x86.h -index 1b58c3b..16d0f6c 100644 ---- a/kexec/arch/i386/kexec-x86.h -+++ b/kexec/arch/i386/kexec-x86.h -@@ -60,6 +60,11 @@ int multiboot_x86_load(int argc, char **argv, const char *buf, off_t len, - struct kexec_info *info); - void multiboot_x86_usage(void); - -+int multiboot2_x86_load(int argc, char **argv, const char *buf, off_t len, -+ struct kexec_info *info); -+void multiboot2_x86_usage(void); -+int multiboot2_x86_probe(const char *buf, off_t buf_len); -+ - int elf_x86_probe(const char *buf, off_t len); - int elf_x86_load(int argc, char **argv, const char *buf, off_t len, - struct kexec_info *info); -diff --git a/kexec/arch/x86_64/kexec-x86_64.h b/kexec/arch/x86_64/kexec-x86_64.h -index 21c3a73..4cdeffb 100644 ---- a/kexec/arch/x86_64/kexec-x86_64.h -+++ b/kexec/arch/x86_64/kexec-x86_64.h -@@ -33,9 +33,4 @@ int bzImage64_load(int argc, char **argv, const char *buf, off_t len, - struct kexec_info *info); - void bzImage64_usage(void); - --int multiboot2_x86_load(int argc, char **argv, const char *buf, off_t len, -- struct kexec_info *info); --void multiboot2_x86_usage(void); --int multiboot2_x86_probe(const char *buf, off_t buf_len); -- - #endif /* KEXEC_X86_64_H */ --- -2.21.0 - diff --git a/kexec-tools-2.0.20-makedumpfile-printk-add-support-for-lockless-ringbuffer.patch b/kexec-tools-2.0.20-makedumpfile-printk-add-support-for-lockless-ringbuffer.patch new file mode 100644 index 0000000..c445e76 --- /dev/null +++ b/kexec-tools-2.0.20-makedumpfile-printk-add-support-for-lockless-ringbuffer.patch @@ -0,0 +1,587 @@ +From c617ec63339222f3a44d73e36677a9acc8954ccd Mon Sep 17 00:00:00 2001 +From: John Ogness +Date: Thu, 19 Nov 2020 02:41:21 +0000 +Subject: [PATCH 1/2] [PATCH 1/2] printk: add support for lockless ringbuffer + +* Required for kernel 5.10 + +Linux 5.10 introduces a new lockless ringbuffer. The new ringbuffer +is structured completely different to the previous iterations. +Add support for retrieving the ringbuffer from debug information +and/or using vmcoreinfo. The new ringbuffer is detected based on +the availability of the "prb" symbol. + +Signed-off-by: John Ogness +Signed-off-by: Kazuhito Hagio +--- + Makefile | 2 +- + dwarf_info.c | 36 ++++++++- + makedumpfile.c | 103 +++++++++++++++++++++++- + makedumpfile.h | 58 ++++++++++++++ + printk.c | 207 +++++++++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 399 insertions(+), 7 deletions(-) + create mode 100644 printk.c + +diff --git a/makedumpfile-1.6.8/Makefile b/makedumpfile-1.6.8/Makefile +index e5ac71a..cb6bd42 100644 +--- a/makedumpfile-1.6.8/Makefile ++++ b/makedumpfile-1.6.8/Makefile +@@ -45,7 +45,7 @@ CFLAGS_ARCH += -m32 + endif + + SRC_BASE = makedumpfile.c makedumpfile.h diskdump_mod.h sadump_mod.h sadump_info.h +-SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c sadump_info.c cache.c tools.c ++SRC_PART = print_info.c dwarf_info.c elf_info.c erase_info.c sadump_info.c cache.c tools.c printk.c + OBJ_PART=$(patsubst %.c,%.o,$(SRC_PART)) + SRC_ARCH = arch/arm.c arch/arm64.c arch/x86.c arch/x86_64.c arch/ia64.c arch/ppc64.c arch/s390x.c arch/ppc.c arch/sparc64.c + OBJ_ARCH=$(patsubst %.c,%.o,$(SRC_ARCH)) +diff --git a/makedumpfile-1.6.8/dwarf_info.c b/makedumpfile-1.6.8/dwarf_info.c +index e42a9f5..543588b 100644 +--- a/makedumpfile-1.6.8/dwarf_info.c ++++ b/makedumpfile-1.6.8/dwarf_info.c +@@ -614,6 +614,7 @@ search_structure(Dwarf_Die *die, int *found) + { + int tag; + const char *name; ++ Dwarf_Die die_type; + + /* + * If we get to here then we don't have any more +@@ -622,9 +623,31 @@ search_structure(Dwarf_Die *die, int *found) + do { + tag = dwarf_tag(die); + name = dwarf_diename(die); +- if ((tag != DW_TAG_structure_type) || (!name) +- || strcmp(name, dwarf_info.struct_name)) ++ if ((!name) || strcmp(name, dwarf_info.struct_name)) ++ continue; ++ ++ if (tag == DW_TAG_typedef) { ++ if (!get_die_type(die, &die_type)) { ++ ERRMSG("Can't get CU die of DW_AT_type.\n"); ++ break; ++ } ++ ++ /* Resolve typedefs of typedefs. */ ++ while ((tag = dwarf_tag(&die_type)) == DW_TAG_typedef) { ++ if (!get_die_type(&die_type, &die_type)) { ++ ERRMSG("Can't get CU die of DW_AT_type.\n"); ++ return; ++ } ++ } ++ ++ if (tag != DW_TAG_structure_type) ++ continue; ++ die = &die_type; ++ ++ } else if (tag != DW_TAG_structure_type) { + continue; ++ } ++ + /* + * Skip if DW_AT_byte_size is not included. + */ +@@ -740,6 +763,15 @@ search_typedef(Dwarf_Die *die, int *found) + ERRMSG("Can't get CU die of DW_AT_type.\n"); + break; + } ++ ++ /* Resolve typedefs of typedefs. */ ++ while ((tag = dwarf_tag(&die_type)) == DW_TAG_typedef) { ++ if (!get_die_type(&die_type, &die_type)) { ++ ERRMSG("Can't get CU die of DW_AT_type.\n"); ++ return; ++ } ++ } ++ + dwarf_info.struct_size = dwarf_bytesize(&die_type); + if (dwarf_info.struct_size <= 0) + continue; +diff --git a/makedumpfile-1.6.8/makedumpfile.c b/makedumpfile-1.6.8/makedumpfile.c +index cdde040..061741f 100644 +--- a/makedumpfile-1.6.8/makedumpfile.c ++++ b/makedumpfile-1.6.8/makedumpfile.c +@@ -1555,6 +1555,7 @@ get_symbol_info(void) + SYMBOL_INIT(node_data, "node_data"); + SYMBOL_INIT(pgdat_list, "pgdat_list"); + SYMBOL_INIT(contig_page_data, "contig_page_data"); ++ SYMBOL_INIT(prb, "prb"); + SYMBOL_INIT(log_buf, "log_buf"); + SYMBOL_INIT(log_buf_len, "log_buf_len"); + SYMBOL_INIT(log_end, "log_end"); +@@ -1971,16 +1972,47 @@ get_structure_info(void) + OFFSET_INIT(elf64_phdr.p_memsz, "elf64_phdr", "p_memsz"); + + SIZE_INIT(printk_log, "printk_log"); +- if (SIZE(printk_log) != NOT_FOUND_STRUCTURE) { ++ SIZE_INIT(printk_ringbuffer, "printk_ringbuffer"); ++ if ((SIZE(printk_ringbuffer) != NOT_FOUND_STRUCTURE)) { ++ info->flag_use_printk_ringbuffer = TRUE; ++ info->flag_use_printk_log = FALSE; ++ ++ OFFSET_INIT(printk_ringbuffer.desc_ring, "printk_ringbuffer", "desc_ring"); ++ OFFSET_INIT(printk_ringbuffer.text_data_ring, "printk_ringbuffer", "text_data_ring"); ++ ++ OFFSET_INIT(prb_desc_ring.count_bits, "prb_desc_ring", "count_bits"); ++ OFFSET_INIT(prb_desc_ring.descs, "prb_desc_ring", "descs"); ++ OFFSET_INIT(prb_desc_ring.infos, "prb_desc_ring", "infos"); ++ OFFSET_INIT(prb_desc_ring.head_id, "prb_desc_ring", "head_id"); ++ OFFSET_INIT(prb_desc_ring.tail_id, "prb_desc_ring", "tail_id"); ++ ++ SIZE_INIT(prb_desc, "prb_desc"); ++ OFFSET_INIT(prb_desc.state_var, "prb_desc", "state_var"); ++ OFFSET_INIT(prb_desc.text_blk_lpos, "prb_desc", "text_blk_lpos"); ++ ++ OFFSET_INIT(prb_data_blk_lpos.begin, "prb_data_blk_lpos", "begin"); ++ OFFSET_INIT(prb_data_blk_lpos.next, "prb_data_blk_lpos", "next"); ++ ++ OFFSET_INIT(prb_data_ring.size_bits, "prb_data_ring", "size_bits"); ++ OFFSET_INIT(prb_data_ring.data, "prb_data_ring", "data"); ++ ++ SIZE_INIT(printk_info, "printk_info"); ++ OFFSET_INIT(printk_info.ts_nsec, "printk_info", "ts_nsec"); ++ OFFSET_INIT(printk_info.text_len, "printk_info", "text_len"); ++ ++ OFFSET_INIT(atomic_long_t.counter, "atomic_long_t", "counter"); ++ } else if (SIZE(printk_log) != NOT_FOUND_STRUCTURE) { + /* + * In kernel 3.11-rc4 the log structure name was renamed + * to "printk_log". + */ ++ info->flag_use_printk_ringbuffer = FALSE; + info->flag_use_printk_log = TRUE; + OFFSET_INIT(printk_log.ts_nsec, "printk_log", "ts_nsec"); + OFFSET_INIT(printk_log.len, "printk_log", "len"); + OFFSET_INIT(printk_log.text_len, "printk_log", "text_len"); + } else { ++ info->flag_use_printk_ringbuffer = FALSE; + info->flag_use_printk_log = FALSE; + SIZE_INIT(printk_log, "log"); + OFFSET_INIT(printk_log.ts_nsec, "log", "ts_nsec"); +@@ -2191,6 +2223,7 @@ write_vmcoreinfo_data(void) + WRITE_SYMBOL("node_data", node_data); + WRITE_SYMBOL("pgdat_list", pgdat_list); + WRITE_SYMBOL("contig_page_data", contig_page_data); ++ WRITE_SYMBOL("prb", prb); + WRITE_SYMBOL("log_buf", log_buf); + WRITE_SYMBOL("log_buf_len", log_buf_len); + WRITE_SYMBOL("log_end", log_end); +@@ -2222,7 +2255,11 @@ write_vmcoreinfo_data(void) + WRITE_STRUCTURE_SIZE("node_memblk_s", node_memblk_s); + WRITE_STRUCTURE_SIZE("nodemask_t", nodemask_t); + WRITE_STRUCTURE_SIZE("pageflags", pageflags); +- if (info->flag_use_printk_log) ++ if (info->flag_use_printk_ringbuffer) { ++ WRITE_STRUCTURE_SIZE("printk_ringbuffer", printk_ringbuffer); ++ WRITE_STRUCTURE_SIZE("prb_desc", prb_desc); ++ WRITE_STRUCTURE_SIZE("printk_info", printk_info); ++ } else if (info->flag_use_printk_log) + WRITE_STRUCTURE_SIZE("printk_log", printk_log); + else + WRITE_STRUCTURE_SIZE("log", printk_log); +@@ -2268,7 +2305,30 @@ write_vmcoreinfo_data(void) + WRITE_MEMBER_OFFSET("vm_struct.addr", vm_struct.addr); + WRITE_MEMBER_OFFSET("vmap_area.va_start", vmap_area.va_start); + WRITE_MEMBER_OFFSET("vmap_area.list", vmap_area.list); +- if (info->flag_use_printk_log) { ++ if (info->flag_use_printk_ringbuffer) { ++ WRITE_MEMBER_OFFSET("printk_ringbuffer.desc_ring", printk_ringbuffer.desc_ring); ++ WRITE_MEMBER_OFFSET("printk_ringbuffer.text_data_ring", printk_ringbuffer.text_data_ring); ++ ++ WRITE_MEMBER_OFFSET("prb_desc_ring.count_bits", prb_desc_ring.count_bits); ++ WRITE_MEMBER_OFFSET("prb_desc_ring.descs", prb_desc_ring.descs); ++ WRITE_MEMBER_OFFSET("prb_desc_ring.infos", prb_desc_ring.infos); ++ WRITE_MEMBER_OFFSET("prb_desc_ring.head_id", prb_desc_ring.head_id); ++ WRITE_MEMBER_OFFSET("prb_desc_ring.tail_id", prb_desc_ring.tail_id); ++ ++ WRITE_MEMBER_OFFSET("prb_desc.state_var", prb_desc.state_var); ++ WRITE_MEMBER_OFFSET("prb_desc.text_blk_lpos", prb_desc.text_blk_lpos); ++ ++ WRITE_MEMBER_OFFSET("prb_data_blk_lpos.begin", prb_data_blk_lpos.begin); ++ WRITE_MEMBER_OFFSET("prb_data_blk_lpos.next", prb_data_blk_lpos.next); ++ ++ WRITE_MEMBER_OFFSET("prb_data_ring.size_bits", prb_data_ring.size_bits); ++ WRITE_MEMBER_OFFSET("prb_data_ring.data", prb_data_ring.data); ++ ++ WRITE_MEMBER_OFFSET("printk_info.ts_nsec", printk_info.ts_nsec); ++ WRITE_MEMBER_OFFSET("printk_info.text_len", printk_info.text_len); ++ ++ WRITE_MEMBER_OFFSET("atomic_long_t.counter", atomic_long_t.counter); ++ } else if (info->flag_use_printk_log) { + WRITE_MEMBER_OFFSET("printk_log.ts_nsec", printk_log.ts_nsec); + WRITE_MEMBER_OFFSET("printk_log.len", printk_log.len); + WRITE_MEMBER_OFFSET("printk_log.text_len", printk_log.text_len); +@@ -2606,6 +2666,7 @@ read_vmcoreinfo(void) + READ_SYMBOL("node_data", node_data); + READ_SYMBOL("pgdat_list", pgdat_list); + READ_SYMBOL("contig_page_data", contig_page_data); ++ READ_SYMBOL("prb", prb); + READ_SYMBOL("log_buf", log_buf); + READ_SYMBOL("log_buf_len", log_buf_len); + READ_SYMBOL("log_end", log_end); +@@ -2684,12 +2745,43 @@ read_vmcoreinfo(void) + READ_MEMBER_OFFSET("cpu_spec.mmu_features", cpu_spec.mmu_features); + + READ_STRUCTURE_SIZE("printk_log", printk_log); +- if (SIZE(printk_log) != NOT_FOUND_STRUCTURE) { ++ READ_STRUCTURE_SIZE("printk_ringbuffer", printk_ringbuffer); ++ if (SIZE(printk_ringbuffer) != NOT_FOUND_STRUCTURE) { ++ info->flag_use_printk_ringbuffer = TRUE; ++ info->flag_use_printk_log = FALSE; ++ ++ READ_MEMBER_OFFSET("printk_ringbuffer.desc_ring", printk_ringbuffer.desc_ring); ++ READ_MEMBER_OFFSET("printk_ringbuffer.text_data_ring", printk_ringbuffer.text_data_ring); ++ ++ READ_MEMBER_OFFSET("prb_desc_ring.count_bits", prb_desc_ring.count_bits); ++ READ_MEMBER_OFFSET("prb_desc_ring.descs", prb_desc_ring.descs); ++ READ_MEMBER_OFFSET("prb_desc_ring.infos", prb_desc_ring.infos); ++ READ_MEMBER_OFFSET("prb_desc_ring.head_id", prb_desc_ring.head_id); ++ READ_MEMBER_OFFSET("prb_desc_ring.tail_id", prb_desc_ring.tail_id); ++ ++ READ_STRUCTURE_SIZE("prb_desc", prb_desc); ++ READ_MEMBER_OFFSET("prb_desc.state_var", prb_desc.state_var); ++ READ_MEMBER_OFFSET("prb_desc.text_blk_lpos", prb_desc.text_blk_lpos); ++ ++ READ_MEMBER_OFFSET("prb_data_blk_lpos.begin", prb_data_blk_lpos.begin); ++ READ_MEMBER_OFFSET("prb_data_blk_lpos.next", prb_data_blk_lpos.next); ++ ++ READ_MEMBER_OFFSET("prb_data_ring.size_bits", prb_data_ring.size_bits); ++ READ_MEMBER_OFFSET("prb_data_ring.data", prb_data_ring.data); ++ ++ READ_STRUCTURE_SIZE("printk_info", printk_info); ++ READ_MEMBER_OFFSET("printk_info.ts_nsec", printk_info.ts_nsec); ++ READ_MEMBER_OFFSET("printk_info.text_len", printk_info.text_len); ++ ++ READ_MEMBER_OFFSET("atomic_long_t.counter", atomic_long_t.counter); ++ } else if (SIZE(printk_log) != NOT_FOUND_STRUCTURE) { ++ info->flag_use_printk_ringbuffer = FALSE; + info->flag_use_printk_log = TRUE; + READ_MEMBER_OFFSET("printk_log.ts_nsec", printk_log.ts_nsec); + READ_MEMBER_OFFSET("printk_log.len", printk_log.len); + READ_MEMBER_OFFSET("printk_log.text_len", printk_log.text_len); + } else { ++ info->flag_use_printk_ringbuffer = FALSE; + info->flag_use_printk_log = FALSE; + READ_STRUCTURE_SIZE("log", printk_log); + READ_MEMBER_OFFSET("log.ts_nsec", printk_log.ts_nsec); +@@ -5286,6 +5378,9 @@ dump_dmesg() + if (!initial()) + return FALSE; + ++ if ((SYMBOL(prb) != NOT_FOUND_SYMBOL)) ++ return dump_lockless_dmesg(); ++ + if ((SYMBOL(log_buf) == NOT_FOUND_SYMBOL) + || (SYMBOL(log_buf_len) == NOT_FOUND_SYMBOL)) { + ERRMSG("Can't find some symbols for log_buf.\n"); +diff --git a/makedumpfile-1.6.8/makedumpfile.h b/makedumpfile-1.6.8/makedumpfile.h +index 698c054..47f7e79 100644 +--- a/makedumpfile-1.6.8/makedumpfile.h ++++ b/makedumpfile-1.6.8/makedumpfile.h +@@ -1317,6 +1317,7 @@ struct DumpInfo { + int flag_partial_dmesg; /* dmesg dump only from the last cleared index*/ + int flag_mem_usage; /*show the page number of memory in different use*/ + int flag_use_printk_log; /* did we read printk_log symbol name? */ ++ int flag_use_printk_ringbuffer; /* using lockless printk ringbuffer? */ + int flag_nospace; /* the flag of "No space on device" error */ + int flag_vmemmap; /* kernel supports vmemmap address space */ + int flag_excludevm; /* -e - excluding unused vmemmap pages */ +@@ -1602,6 +1603,7 @@ struct symbol_table { + unsigned long long node_data; + unsigned long long pgdat_list; + unsigned long long contig_page_data; ++ unsigned long long prb; + unsigned long long log_buf; + unsigned long long log_buf_len; + unsigned long long log_end; +@@ -1689,6 +1691,13 @@ struct size_table { + long nodemask_t; + long printk_log; + ++ /* ++ * for lockless printk ringbuffer ++ */ ++ long printk_ringbuffer; ++ long prb_desc; ++ long printk_info; ++ + /* + * for Xen extraction + */ +@@ -1864,6 +1873,52 @@ struct offset_table { + long text_len; + } printk_log; + ++ /* ++ * for lockless printk ringbuffer ++ */ ++ struct printk_ringbuffer_s { ++ long desc_ring; ++ long text_data_ring; ++ long fail; ++ } printk_ringbuffer; ++ ++ struct prb_desc_ring_s { ++ long count_bits; ++ long descs; ++ long infos; ++ long head_id; ++ long tail_id; ++ } prb_desc_ring; ++ ++ struct prb_desc_s { ++ long state_var; ++ long text_blk_lpos; ++ } prb_desc; ++ ++ struct prb_data_blk_lpos_s { ++ long begin; ++ long next; ++ } prb_data_blk_lpos; ++ ++ struct printk_info_s { ++ long seq; ++ long ts_nsec; ++ long text_len; ++ long caller_id; ++ long dev_info; ++ } printk_info; ++ ++ struct prb_data_ring_s { ++ long size_bits; ++ long data; ++ long head_lpos; ++ long tail_lpos; ++ } prb_data_ring; ++ ++ struct atomic_long_t_s { ++ long counter; ++ } atomic_long_t; ++ + /* + * symbols on ppc64 arch + */ +@@ -2390,4 +2445,7 @@ int hexadecimal(char *s, int count); + int decimal(char *s, int count); + int file_exists(char *file); + ++int open_dump_file(void); ++int dump_lockless_dmesg(void); ++ + #endif /* MAKEDUMPFILE_H */ +diff --git a/makedumpfile-1.6.8/printk.c b/makedumpfile-1.6.8/printk.c +new file mode 100644 +index 0000000..acffb6c +--- /dev/null ++++ b/makedumpfile-1.6.8/printk.c +@@ -0,0 +1,207 @@ ++#include "makedumpfile.h" ++#include ++ ++#define DESC_SV_BITS (sizeof(unsigned long) * 8) ++#define DESC_COMMITTED_MASK (1UL << (DESC_SV_BITS - 1)) ++#define DESC_REUSE_MASK (1UL << (DESC_SV_BITS - 2)) ++#define DESC_FLAGS_MASK (DESC_COMMITTED_MASK | DESC_REUSE_MASK) ++#define DESC_ID_MASK (~DESC_FLAGS_MASK) ++ ++/* 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; ++}; ++ ++static void ++dump_record(struct prb_map *m, unsigned long id) ++{ ++ unsigned long long ts_nsec; ++ unsigned long state_var; ++ unsigned short text_len; ++ unsigned long begin; ++ unsigned long next; ++ char buf[BUFSIZE]; ++ ulonglong nanos; ++ int indent_len; ++ int buf_need; ++ char *bufp; ++ char *text; ++ char *desc; ++ char *inf; ++ ulong rem; ++ char *p; ++ int i; ++ ++ desc = m->descs + ((id % m->desc_ring_count) * SIZE(prb_desc)); ++ ++ /* skip non-committed record */ ++ state_var = ULONG(desc + OFFSET(prb_desc.state_var) + OFFSET(atomic_long_t.counter)); ++ if ((state_var & DESC_FLAGS_MASK) != DESC_COMMITTED_MASK) ++ return; ++ ++ begin = ULONG(desc + OFFSET(prb_desc.text_blk_lpos) + OFFSET(prb_data_blk_lpos.begin)) % ++ m->text_data_ring_size; ++ next = ULONG(desc + OFFSET(prb_desc.text_blk_lpos) + OFFSET(prb_data_blk_lpos.next)) % ++ m->text_data_ring_size; ++ ++ /* skip data-less text blocks */ ++ if (begin == next) ++ return; ++ ++ inf = m->infos + ((id % m->desc_ring_count) * SIZE(printk_info)); ++ ++ text_len = USHORT(inf + OFFSET(printk_info.text_len)); ++ ++ /* handle wrapping data block */ ++ if (begin > next) ++ begin = 0; ++ ++ /* skip over descriptor ID */ ++ begin += sizeof(unsigned long); ++ ++ /* handle truncated messages */ ++ if (next - begin < text_len) ++ text_len = next - begin; ++ ++ text = m->text_data + begin; ++ ++ ts_nsec = ULONGLONG(inf + OFFSET(printk_info.ts_nsec)); ++ nanos = (ulonglong)ts_nsec / (ulonglong)1000000000; ++ rem = (ulonglong)ts_nsec % (ulonglong)1000000000; ++ ++ bufp = buf; ++ bufp += sprintf(buf, "[%5lld.%06ld] ", nanos, rem/1000); ++ indent_len = strlen(buf); ++ ++ /* How much buffer space is needed in the worst case */ ++ buf_need = MAX(sizeof("\\xXX\n"), sizeof("\n") + indent_len); ++ ++ for (i = 0, p = text; i < text_len; i++, p++) { ++ if (bufp - buf >= sizeof(buf) - buf_need) { ++ if (write(info->fd_dumpfile, buf, bufp - buf) < 0) ++ return; ++ bufp = buf; ++ } ++ ++ if (*p == '\n') ++ bufp += sprintf(bufp, "\n%-*s", indent_len, ""); ++ else if (isprint(*p) || isspace(*p)) ++ *bufp++ = *p; ++ else ++ bufp += sprintf(bufp, "\\x%02x", *p); ++ } ++ ++ *bufp++ = '\n'; ++ ++ write(info->fd_dumpfile, buf, bufp - buf); ++} ++ ++int ++dump_lockless_dmesg(void) ++{ ++ unsigned long head_id; ++ unsigned long tail_id; ++ unsigned long kaddr; ++ unsigned long id; ++ struct prb_map m; ++ int ret = FALSE; ++ ++ /* setup printk_ringbuffer */ ++ if (!readmem(VADDR, SYMBOL(prb), &kaddr, sizeof(kaddr))) { ++ ERRMSG("Can't get the prb address.\n"); ++ return ret; ++ } ++ ++ m.prb = malloc(SIZE(printk_ringbuffer)); ++ if (!m.prb) { ++ ERRMSG("Can't allocate memory for prb.\n"); ++ return ret; ++ } ++ if (!readmem(VADDR, kaddr, m.prb, SIZE(printk_ringbuffer))) { ++ ERRMSG("Can't get prb.\n"); ++ goto out_prb; ++ } ++ ++ /* setup descriptor ring */ ++ m.desc_ring = m.prb + OFFSET(printk_ringbuffer.desc_ring); ++ m.desc_ring_count = 1 << UINT(m.desc_ring + OFFSET(prb_desc_ring.count_bits)); ++ ++ kaddr = ULONG(m.desc_ring + OFFSET(prb_desc_ring.descs)); ++ m.descs = malloc(SIZE(prb_desc) * m.desc_ring_count); ++ if (!m.descs) { ++ ERRMSG("Can't allocate memory for prb.desc_ring.descs.\n"); ++ goto out_prb; ++ } ++ if (!readmem(VADDR, kaddr, m.descs, ++ SIZE(prb_desc) * m.desc_ring_count)) { ++ ERRMSG("Can't get prb.desc_ring.descs.\n"); ++ goto out_descs; ++ } ++ ++ kaddr = ULONG(m.desc_ring + OFFSET(prb_desc_ring.infos)); ++ m.infos = malloc(SIZE(printk_info) * m.desc_ring_count); ++ if (!m.infos) { ++ ERRMSG("Can't allocate memory for prb.desc_ring.infos.\n"); ++ goto out_descs; ++ } ++ if (!readmem(VADDR, kaddr, m.infos, SIZE(printk_info) * m.desc_ring_count)) { ++ ERRMSG("Can't get prb.desc_ring.infos.\n"); ++ goto out_infos; ++ } ++ ++ /* setup text data ring */ ++ m.text_data_ring = m.prb + OFFSET(printk_ringbuffer.text_data_ring); ++ m.text_data_ring_size = 1 << UINT(m.text_data_ring + OFFSET(prb_data_ring.size_bits)); ++ ++ kaddr = ULONG(m.text_data_ring + OFFSET(prb_data_ring.data)); ++ m.text_data = malloc(m.text_data_ring_size); ++ if (!m.text_data) { ++ ERRMSG("Can't allocate memory for prb.text_data_ring.data.\n"); ++ goto out_infos; ++ } ++ if (!readmem(VADDR, kaddr, m.text_data, m.text_data_ring_size)) { ++ ERRMSG("Can't get prb.text_data_ring.\n"); ++ goto out_text_data; ++ } ++ ++ /* ready to go */ ++ ++ tail_id = ULONG(m.desc_ring + OFFSET(prb_desc_ring.tail_id) + ++ OFFSET(atomic_long_t.counter)); ++ head_id = ULONG(m.desc_ring + OFFSET(prb_desc_ring.head_id) + ++ OFFSET(atomic_long_t.counter)); ++ ++ if (!open_dump_file()) { ++ ERRMSG("Can't open output file.\n"); ++ goto out_text_data; ++ } ++ ++ for (id = tail_id; id != head_id; id = (id + 1) & DESC_ID_MASK) ++ dump_record(&m, id); ++ ++ /* dump head record */ ++ dump_record(&m, id); ++ ++ if (!close_files_for_creating_dumpfile()) ++ goto out_text_data; ++ ++ ret = TRUE; ++out_text_data: ++ free(m.text_data); ++out_infos: ++ free(m.infos); ++out_descs: ++ free(m.descs); ++out_prb: ++ free(m.prb); ++ return ret; ++} +-- +2.29.2 + diff --git a/kexec-tools-2.0.20-makedumpfile-printk-use-committed-finalized-state-value.patch b/kexec-tools-2.0.20-makedumpfile-printk-use-committed-finalized-state-value.patch new file mode 100644 index 0000000..8ec27bf --- /dev/null +++ b/kexec-tools-2.0.20-makedumpfile-printk-use-committed-finalized-state-value.patch @@ -0,0 +1,99 @@ +From 44b073b7ec467aee0d7de381d455b8ace1199184 Mon Sep 17 00:00:00 2001 +From: John Ogness +Date: Wed, 25 Nov 2020 10:10:31 +0106 +Subject: [PATCH 2/2] [PATCH 2/2] printk: use committed/finalized state values + +* Required for kernel 5.10 + +The ringbuffer entries use 2 state values (committed and finalized) +rather than a single flag to represent being available for reading. +Copy the definitions and state lookup function directly from the +kernel source and use the new states. + +Signed-off-by: John Ogness +--- + printk.c | 48 +++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 41 insertions(+), 7 deletions(-) + +diff --git a/makedumpfile-1.6.8/printk.c b/makedumpfile-1.6.8/printk.c +index acffb6c..2af8562 100644 +--- a/makedumpfile-1.6.8/printk.c ++++ b/makedumpfile-1.6.8/printk.c +@@ -1,12 +1,6 @@ + #include "makedumpfile.h" + #include + +-#define DESC_SV_BITS (sizeof(unsigned long) * 8) +-#define DESC_COMMITTED_MASK (1UL << (DESC_SV_BITS - 1)) +-#define DESC_REUSE_MASK (1UL << (DESC_SV_BITS - 2)) +-#define DESC_FLAGS_MASK (DESC_COMMITTED_MASK | DESC_REUSE_MASK) +-#define DESC_ID_MASK (~DESC_FLAGS_MASK) +- + /* convenience struct for passing many values to helper functions */ + struct prb_map { + char *prb; +@@ -21,12 +15,51 @@ struct prb_map { + char *text_data; + }; + ++/* ++ * desc_state and DESC_* definitions taken from kernel source: ++ * ++ * kernel/printk/printk_ringbuffer.h ++ */ ++ ++/* 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(unsigned long) * 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) ++ ++/* ++ * get_desc_state() taken from kernel source: ++ * ++ * kernel/printk/printk_ringbuffer.c ++ */ ++ ++/* Query the state of a descriptor. */ ++static enum desc_state get_desc_state(unsigned long id, ++ unsigned long state_val) ++{ ++ if (id != DESC_ID(state_val)) ++ return desc_miss; ++ ++ return DESC_STATE(state_val); ++} ++ + static void + dump_record(struct prb_map *m, unsigned long id) + { + unsigned long long ts_nsec; + unsigned long state_var; + unsigned short text_len; ++ enum desc_state state; + unsigned long begin; + unsigned long next; + char buf[BUFSIZE]; +@@ -45,7 +78,8 @@ dump_record(struct prb_map *m, unsigned long id) + + /* skip non-committed record */ + state_var = ULONG(desc + OFFSET(prb_desc.state_var) + OFFSET(atomic_long_t.counter)); +- if ((state_var & DESC_FLAGS_MASK) != DESC_COMMITTED_MASK) ++ state = get_desc_state(id, state_var); ++ if (state != desc_committed && state != desc_finalized) + return; + + begin = ULONG(desc + OFFSET(prb_desc.text_blk_lpos) + OFFSET(prb_data_blk_lpos.begin)) % +-- +2.29.2 + diff --git a/kexec-tools.spec b/kexec-tools.spec index 11743a4..3f94bcb 100644 --- a/kexec-tools.spec +++ b/kexec-tools.spec @@ -4,8 +4,8 @@ %global mkdf_shortver %(c=%{mkdf_ver}; echo ${c:0:7}) Name: kexec-tools -Version: 2.0.20 -Release: 21%{?dist} +Version: 2.0.21 +Release: 1%{?dist} License: GPLv2 Summary: The kexec/kdump userspace component @@ -80,7 +80,6 @@ Requires: systemd-udev%{?_isa} # # Patches 0 through 100 are meant for x86 kexec-tools enablement # -Patch0: kexec-tools-2.0.20-fix-broken-multiboot2-buliding-for-i386.patch # # Patches 101 through 200 are meant for x86_64 kexec-tools enablement @@ -101,7 +100,8 @@ Patch0: kexec-tools-2.0.20-fix-broken-multiboot2-buliding-for-i386.patch # Patches 601 onward are generic patches # Patch601: ./kexec-tools-2.0.20-eppic-Remove-duplicated-variable-declaration.patch -Patch602: ./kexec-tools-2.0.20-Remove-duplicated-variable-declarations.patch +Patch603: ./kexec-tools-2.0.20-makedumpfile-printk-add-support-for-lockless-ringbuffer.patch +Patch604: ./kexec-tools-2.0.20-makedumpfile-printk-use-committed-finalized-state-value.patch %description kexec-tools provides /sbin/kexec binary that facilitates a new @@ -117,10 +117,9 @@ mkdir -p -m755 kcp tar -z -x -v -f %{SOURCE9} tar -z -x -v -f %{SOURCE19} -%patch0 -p1 - %patch601 -p1 -%patch602 -p1 +%patch603 -p1 +%patch604 -p1 %ifarch ppc %define archdef ARCH=ppc @@ -359,6 +358,14 @@ done %endif %changelog +* Wed Dec 23 2020 Kairui Song - 2.0.21-1 +- makedumpfile: printk: use committed/finalized state values +- makedumpfile: printk: add support for lockless ringbuffer +- dracut-module-setup.sh: Use systemctl call to replace ln_r +- Doc: improve mkdumprd man page +- Don's try to restart dracut-initqueue if it's already failed +- dracut-module-setup.sh: use auto6 for ipv6 + * Mon Nov 30 2020 Kairui Song - 2.0.20-21 - Rebase makedumpfile to 1.6.8 - fadump-howto: update about 'nocma' and 'off' options for 'fadump=' parameter diff --git a/mkdumprd.8 b/mkdumprd.8 index 7faae57..2ac3d5a 100644 --- a/mkdumprd.8 +++ b/mkdumprd.8 @@ -15,7 +15,13 @@ be loaded in the initramfs (based on configuration retrieved from \fI/etc/kdump.conf)\fR \fBmkdumprd\fR add a new \fBdracut\fR module 99kdumpbase and use \fBdracut\fR -utility to generate the initramfs. +utility to generate the initramfs. When generating a kdump initramfs, \fBmkdumprd\fR +will determine how much disk space is available, if the dump target's available +space is not greater than the total system memory, \fBmkdumprd\fR will print a +warning to remind that there might not be enough space to save a vmcore. The +warning covers extreme scenarios such as the slab explodes with non-zero data or +a full vmcore, etc. Therefore, need to prevent users from having minimum disk +space for crash dump. \fBmkdumprd\fR was not intended for casual use outside of the service initialization script for the kdump utility, and should not be run manually. If diff --git a/sources b/sources index cc14d5b..58d314e 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ SHA512 (eppic-d84c354.tar.gz) = 455b3386c3e4cc546b858f1f8b0e6874072aaae708ebe072452fb5f0b6a81b1f3a315b40f94c3967f38525cadd276864a7bc7f0f12fa421655dcc3b15b70914d -SHA512 (kexec-tools-2.0.20.tar.xz) = 3112b6202c1030705c53e3f65a2b58aec14d65333a35aad681d48b9f2bd1c51a2e05c985a1e5e867ab02f8a9c97708483d9d225619db7c6993676f1a242e2d99 SHA512 (makedumpfile-1.6.8.tar.gz) = 15e60688b06013bf86e339ec855774ea2c904d425371ea867101704ba0611c69da891eb3cc96f67eb10197d8c42d217ea28bf11bcaa93ddc2495cbf984c0b7ec +SHA512 (kexec-tools-2.0.21.tar.xz) = f487d2e243c2c4f29fbc9da7d06806f65210f717904655fc84d8d162b9c4614c3dd62e1bb47104a79f0dc2af04e462baf764fb309b5d7e6d287264cb48fd2a3e