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

Reply via email to