Fix "mount <address>" and MNT_CURSOR entries: 1/ "mount <address>" is failing on kernels without "super_block.s_files":
crash> mount ff35d61d80200000 mount: the super_block.s_files linked list does not exist in this kernel mount: -f option not supported or applicable on this architecture or kernel The MOUNT_PRINT_FILES flags should only be passed when "super_block.s_files" is available. 2/ "mount" is not skipping MNT_CURSOR entries (kernel >= 5.8): crash> mount > mount.out WARNING: cannot get super_block from vfsmnt: 0xff35d65eb1cc1820 crash> struct mount.mnt.mnt_sb,mnt.mnt_flags -x 0xff35d65eb1cc1820 mnt.mnt_sb = 0x0, mnt.mnt_flags = 0x10000000, When crashing with running "findmnt" commands, the mount list will have entries with mnt.mnt_flags==MNT_CURSOR (and mnt.mnt_sb==NULL). Such entries should be skipped without errors. Signed-off-by: Georges Aureau <[email protected]> -- defs.h | 1 + filesys.c | 16 +++++++++++++++- symbols.c | 2 ++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/defs.h b/defs.h index 156ac02..9e37f26 100644 --- a/defs.h +++ b/defs.h @@ -1508,6 +1508,7 @@ struct offset_table { /* stash of commonly-used offsets */ long vfsmount_mnt_devname; long vfsmount_mnt_dirname; long vfsmount_mnt_sb; + long vfsmount_mnt_flags; long vfsmount_mnt_list; long vfsmount_mnt_mountpoint; long vfsmount_mnt_parent; diff --git a/filesys.c b/filesys.c index 8d13807..7439c2e 100644 --- a/filesys.c +++ b/filesys.c @@ -1296,7 +1296,7 @@ cmd_mount(void) * through it for each search argument entered. */ open_tmpfile(); - show_mounts(0, MOUNT_PRINT_FILES | + show_mounts(0, (VALID_MEMBER(super_block_s_files) ? MOUNT_PRINT_FILES : 0) | (VALID_MEMBER(super_block_s_dirty) ? MOUNT_PRINT_INODES : 0), namespace_context); @@ -1371,6 +1371,14 @@ cmd_mount(void) * Do the work for cmd_mount(); */ +/* For kernels >= 5.8, we need to skip MNT_CURSOR entries. + * See https://elixir.bootlin.com/linux/v5.8/source/include/linux/mount.h#L73 + * https://elixir.bootlin.com/linux/v5.8/source/fs/namespace.c#L661 + * https://elixir.bootlin.com/linux/v5.8/source/fs/namespace.c#L690 + * https://elixir.bootlin.com/linux/v5.8/source/fs/proc_namespace.c#L283 + */ +#define MNT_CURSOR 0x10000000 + static void show_mounts(ulong one_vfsmount, int flags, struct task_context *namespace_context) { @@ -1492,6 +1500,11 @@ show_mounts(ulong one_vfsmount, int flags, struct task_context *namespace_contex sbp = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb)); if (!IS_KVADDR(sbp)) { + if (sbp == 0 && VALID_MEMBER(vfsmount_mnt_flags)) { + int mnt_flags = INT(vfsmount_buf + OFFSET(vfsmount_mnt_flags)); + if (mnt_flags == MNT_CURSOR) + continue; + } error(WARNING, "cannot get super_block from vfsmnt: 0x%lx\n", *vfsmnt); continue; } @@ -2070,6 +2083,7 @@ vfs_init(void) MEMBER_OFFSET_INIT(mount_mnt_devname, "mount", "mnt_devname"); MEMBER_OFFSET_INIT(vfsmount_mnt_dirname, "vfsmount", "mnt_dirname"); MEMBER_OFFSET_INIT(vfsmount_mnt_sb, "vfsmount", "mnt_sb"); + MEMBER_OFFSET_INIT(vfsmount_mnt_flags, "vfsmount", "mnt_flags"); MEMBER_OFFSET_INIT(vfsmount_mnt_list, "vfsmount", "mnt_list"); if (INVALID_MEMBER(vfsmount_mnt_devname)) MEMBER_OFFSET_INIT(mount_mnt_list, "mount", "mnt_list"); diff --git a/symbols.c b/symbols.c index 112bcc6..92098a8 100644 --- a/symbols.c +++ b/symbols.c @@ -10685,6 +10685,8 @@ dump_offset_table(char *spec, ulong makestruct) OFFSET(vfsmount_mnt_dirname)); fprintf(fp, " vfsmount_mnt_sb: %ld\n", OFFSET(vfsmount_mnt_sb)); + fprintf(fp, " vfsmount_mnt_flags: %ld\n", + OFFSET(vfsmount_mnt_flags)); fprintf(fp, " vfsmount_mnt_list: %ld\n", OFFSET(vfsmount_mnt_list)); fprintf(fp, " vfsmount_mnt_mountpoint: %ld\n", -- Crash-utility mailing list -- [email protected] To unsubscribe send an email to [email protected] https://${domain_name}/admin/lists/devel.lists.crash-utility.osci.io/ Contribution Guidelines: https://github.com/crash-utility/crash/wiki
