diff --git a/0001-Fix-kmem-i-and-swap-commands-on-Linux-6.10-rc1-and-l.patch b/0001-Fix-kmem-i-and-swap-commands-on-Linux-6.10-rc1-and-l.patch new file mode 100644 index 0000000..72a7c92 --- /dev/null +++ b/0001-Fix-kmem-i-and-swap-commands-on-Linux-6.10-rc1-and-l.patch @@ -0,0 +1,127 @@ +From 3452fe802bf94d15879b3c5fd17c793a2b67a231 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?HAGIO=20KAZUHITO=28=E8=90=A9=E5=B0=BE=E3=80=80=E4=B8=80?= + =?UTF-8?q?=E4=BB=81=29?= +Date: Tue, 11 Jun 2024 02:40:55 +0000 +Subject: [PATCH 1/2] Fix "kmem -i" and "swap" commands on Linux 6.10-rc1 and + later kernels + +Kernel commit 798cb7f9aec3 ("swapon(2)/swapoff(2): don't bother with +block size") removed swap_info_struct.old_block_size member at Linux +6.10-rc1. The crash-utility has used this to determine whether a swap +is a partition or file and to determine the way to get the swap path. + +Withtout the patch, the "kmem -i" and "swap" commands fail with the +following error messsage: + + crash> kmem -i + ... + TOTAL HUGE 13179392 50.3 GB ---- + HUGE FREE 13179392 50.3 GB 100% of TOTAL HUGE + + swap: invalid (optional) structure member offsets: swap_info_struct_swap_device or swap_info_struct_old_block_size + FILE: memory.c LINE: 16032 FUNCTION: dump_swap_info() + +The swap_file member of recent swap_info_struct is a pointer to a +struct file (once upon a time it was dentry), use this fact directly. + +Tested-by: Li Zhijian +Signed-off-by: Kazuhito Hagio +--- + defs.h | 1 + + filesys.c | 1 + + memory.c | 28 +++++++++++++++++++++++----- + symbols.c | 1 + + 4 files changed, 26 insertions(+), 5 deletions(-) + +diff --git a/defs.h b/defs.h +index da856c0..49e6923 100644 +--- a/defs.h ++++ b/defs.h +@@ -2242,6 +2242,7 @@ struct offset_table { /* stash of commonly-used offsets */ + long log_caller_id; + long vmap_node_busy; + long rb_list_head; ++ long file_f_inode; + }; + + struct size_table { /* stash of commonly-used sizes */ +diff --git a/filesys.c b/filesys.c +index 81fe856..406ebb2 100644 +--- a/filesys.c ++++ b/filesys.c +@@ -2038,6 +2038,7 @@ vfs_init(void) + MEMBER_OFFSET_INIT(file_f_dentry, "file", "f_dentry"); + MEMBER_OFFSET_INIT(file_f_vfsmnt, "file", "f_vfsmnt"); + MEMBER_OFFSET_INIT(file_f_count, "file", "f_count"); ++ MEMBER_OFFSET_INIT(file_f_inode, "file", "f_inode"); + MEMBER_OFFSET_INIT(path_mnt, "path", "mnt"); + MEMBER_OFFSET_INIT(path_dentry, "path", "dentry"); + if (INVALID_MEMBER(file_f_dentry)) { +diff --git a/memory.c b/memory.c +index acb8507..a74ebaf 100644 +--- a/memory.c ++++ b/memory.c +@@ -16075,6 +16075,8 @@ dump_swap_info(ulong swapflags, ulong *totalswap_pages, ulong *totalused_pages) + char buf3[BUFSIZE]; + char buf4[BUFSIZE]; + char buf5[BUFSIZE]; ++ int swap_file_is_file = ++ STREQ(MEMBER_TYPE_NAME("swap_info_struct", "swap_file"), "file"); + + if (!symbol_exists("nr_swapfiles")) + error(FATAL, "nr_swapfiles doesn't exist in this kernel!\n"); +@@ -16118,9 +16120,21 @@ dump_swap_info(ulong swapflags, ulong *totalswap_pages, ulong *totalused_pages) + swap_file = ULONG(vt->swap_info_struct + + OFFSET(swap_info_struct_swap_file)); + +- swap_device = INT(vt->swap_info_struct + +- OFFSET_OPTION(swap_info_struct_swap_device, +- swap_info_struct_old_block_size)); ++ /* Linux 6.10 and later */ ++ if (INVALID_MEMBER(swap_info_struct_swap_device) && ++ INVALID_MEMBER(swap_info_struct_old_block_size) && ++ swap_file_is_file) { ++ ulong inode; ++ ushort mode; ++ readmem(swap_file + OFFSET(file_f_inode), KVADDR, &inode, ++ sizeof(ulong), "swap_file.f_inode", FAULT_ON_ERROR); ++ readmem(inode + OFFSET(inode_i_mode), KVADDR, &mode, ++ sizeof(ushort), "inode.i_mode", FAULT_ON_ERROR); ++ swap_device = S_ISBLK(mode); ++ } else ++ swap_device = INT(vt->swap_info_struct + ++ OFFSET_OPTION(swap_info_struct_swap_device, ++ swap_info_struct_old_block_size)); + + pages = INT(vt->swap_info_struct + + OFFSET(swap_info_struct_pages)); +@@ -16161,8 +16175,12 @@ dump_swap_info(ulong swapflags, ulong *totalswap_pages, ulong *totalused_pages) + OFFSET(swap_info_struct_swap_vfsmnt)); + get_pathname(swap_file, buf, BUFSIZE, + 1, vfsmnt); +- } else if (VALID_MEMBER +- (swap_info_struct_old_block_size)) { ++ } else if (VALID_MEMBER(swap_info_struct_old_block_size) || ++ swap_file_is_file) { ++ /* ++ * Linux 6.10 and later kernels do not have old_block_size, ++ * but this still should work, if swap_file is file. ++ */ + devname = vfsmount_devname(file_to_vfsmnt(swap_file), + buf1, BUFSIZE); + get_pathname(file_to_dentry(swap_file), +diff --git a/symbols.c b/symbols.c +index f3c94b0..69a1fbb 100644 +--- a/symbols.c ++++ b/symbols.c +@@ -10522,6 +10522,7 @@ dump_offset_table(char *spec, ulong makestruct) + OFFSET(file_f_count)); + fprintf(fp, " file_f_path: %ld\n", + OFFSET(file_f_path)); ++ fprintf(fp, " file_f_inode: %ld\n", OFFSET(file_f_inode)); + fprintf(fp, " path_mnt: %ld\n", + OFFSET(path_mnt)); + fprintf(fp, " path_dentry: %ld\n", +-- +2.40.1 + diff --git a/0002-List-enable-LIST_HEAD_FORMAT-for-r-option.patch b/0002-List-enable-LIST_HEAD_FORMAT-for-r-option.patch new file mode 100644 index 0000000..02d31af --- /dev/null +++ b/0002-List-enable-LIST_HEAD_FORMAT-for-r-option.patch @@ -0,0 +1,31 @@ +From ce4ddc742fbdde2fc966e79a19d6aa962e79448a Mon Sep 17 00:00:00 2001 +From: Li Zhijian +Date: Tue, 2 Jul 2024 14:31:30 +0800 +Subject: [PATCH 2/2] List: enable LIST_HEAD_FORMAT for -r option + +Currently, the LIST_HEAD_FORMAT is not set, 'list -r' will list the +traversal results in order, not in the reverse order. This is not +the expected behavior. + +Let's enable the LIST_HEAD_FORMAT for -r option by default. + +Signed-off-by: Li Zhijian +--- + tools.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/tools.c b/tools.c +index 0f2db10..1022d57 100644 +--- a/tools.c ++++ b/tools.c +@@ -3370,6 +3370,7 @@ cmd_list(void) + break; + + case 'r': ++ ld->flags |= LIST_HEAD_FORMAT; + ld->flags |= LIST_HEAD_REVERSE; + break; + +-- +2.40.1 + diff --git a/crash.spec b/crash.spec index 116df8e..9447eb6 100644 --- a/crash.spec +++ b/crash.spec @@ -4,7 +4,7 @@ Summary: Kernel analysis utility for live systems, netdump, diskdump, kdump, LKCD or mcore dumpfiles Name: crash Version: 8.0.5 -Release: 3%{?dist} +Release: 4%{?dist} License: GPL-3.0-only Source0: https://github.com/crash-utility/crash/archive/crash-%{version}.tar.gz Source1: http://ftp.gnu.org/gnu/gdb/gdb-10.2.tar.gz @@ -28,6 +28,8 @@ Patch7: 0006-Fix-kmem-v-option-on-Linux-6.9-and-later-kernels.patch Patch8: 0007-X86-64-fix-for-crash-session-loading-failure.patch Patch9: 0008-Fix-for-failing-to-load-kernel-module.patch Patch10: 0009-X86-64-fix-a-regression-issue-about-kernel-stack-pad.patch +Patch11: 0001-Fix-kmem-i-and-swap-commands-on-Linux-6.10-rc1-and-l.patch +Patch12: 0002-List-enable-LIST_HEAD_FORMAT-for-r-option.patch %description The core analysis suite is a self-contained tool that can be used to @@ -58,6 +60,8 @@ offered by Mission Critical Linux, or the LKCD kernel patch. %patch -P 8 -p1 %patch -P 9 -p1 %patch -P 10 -p1 +%patch -P 11 -p1 +%patch -P 12 -p1 %build @@ -83,6 +87,9 @@ cp -p defs.h %{buildroot}%{_includedir}/crash %{_includedir}/* %changelog +* Wed Jul 3 2024 Tao Liu - 8.0.5-4 +- Rebase to upstream crash 8.0.5 ce4ddc742fbdd + * Mon Jun 24 2024 Troy Dawson - 8.0.5-3 - Bump release for June 2024 mass rebuild