fix command vm/files -d/mount on new kernel
Hello Dave,
New kernel has moved some elements of struct vfsmount to a new struct mount. So crash will not act normally on new kernel. The patch is used to fix the problem. Please check. -- -- Regards Qiao Nuohan -------------------------------------------------- Qiao Nuohan Development Dept.I Nanjing Fujitsu Nanda Software Tech. Co., Ltd.(FNST) No. 6 Wenzhu Road, Nanjing, Nanjing, 210012, China TEL: +86+25-86630566-8526 FUJITSU INTERNAL: 7998-8526 FAX: +86+25-83317685 EMail: qiaonuohan@cn.fujitsu.com -------------------------------------------------- This communication is for use by the intended recipient(s) only and may contain information that is privileged, confidential and exempt from disclosure under applicable law. If you are not an intended recipient of this communication, you are hereby notified that any dissemination, distribution or copying hereof is strictly prohibited. If you have received this communication in error, please notify me by reply e-mail, permanently delete this communication from your system, and destroy any hard copies you may have printed diff --git a/defs.h b/defs.h index a942dbb..0124f5f 100755 --- a/defs.h +++ b/defs.h @@ -1281,6 +1281,11 @@ struct offset_table { /* stash of commonly-used offsets */ long vfsmount_mnt_list; long vfsmount_mnt_mountpoint; long vfsmount_mnt_parent; + long mount_mnt_parent; + long mount_mnt_mountpoint; + long mount_mnt_list; + long mount_mnt_devname; + long mount_mnt; long namespace_root; long namespace_list; long super_block_s_dirty; @@ -1694,6 +1699,7 @@ struct size_table { /* stash of commonly-used sizes */ long fs_struct; long file; long inode; + long mount; long vfsmount; long super_block; long irqdesc; diff --git a/filesys.c b/filesys.c index 55a4677..0f4db2a 100755 --- a/filesys.c +++ b/filesys.c @@ -1298,7 +1298,7 @@ show_mounts(ulong one_vfsmount, int flags, struct task_context *namespace_contex char buf4[BUFSIZE]; ulong *dentry_list, *dp, *mntlist; ulong *vfsmnt; - char *vfsmount_buf, *super_block_buf; + char *vfsmount_buf, *super_block_buf, *mount_buf; ulong dentry, inode, inode_sb, mnt_parent; char *dentry_buf, *inode_buf; int cnt, i, m, files_header_printed; @@ -1336,9 +1336,15 @@ show_mounts(ulong one_vfsmount, int flags, struct task_context *namespace_contex devlen = strlen("DEVNAME"); for (m = 0, vfsmnt = mntlist; m < mount_cnt; m++, vfsmnt++) { - readmem(*vfsmnt + OFFSET(vfsmount_mnt_devname), - KVADDR, &devp, sizeof(void *), - "vfsmount mnt_devname", FAULT_ON_ERROR); + if (VALID_STRUCT(mount)) { + readmem(*vfsmnt+OFFSET(mount_mnt_devname), + KVADDR, &devp, sizeof(void *), + "mount mnt_devname", FAULT_ON_ERROR); + } else { + readmem(*vfsmnt+OFFSET(vfsmount_mnt_devname), + KVADDR, &devp, sizeof(void *), + "vfsmount mnt_devname", FAULT_ON_ERROR); + } if (read_string(devp, buf1, BUFSIZE-1)) { if (strlen(buf1) > devlen) @@ -1366,23 +1372,41 @@ show_mounts(ulong one_vfsmount, int flags, struct task_context *namespace_contex &cnt); } - vfsmount_buf = GETBUF(SIZE(vfsmount)); + if (VALID_STRUCT(mount)) { + mount_buf = GETBUF(SIZE(mount)); + vfsmount_buf = mount_buf + OFFSET(mount_mnt); + } else { + mount_buf = NULL; + vfsmount_buf = GETBUF(SIZE(vfsmount)); + } super_block_buf = GETBUF(SIZE(super_block)); for (m = 0, vfsmnt = mntlist; m < mount_cnt; m++, vfsmnt++) { - readmem(*vfsmnt, KVADDR, vfsmount_buf, SIZE(vfsmount), - "vfsmount buffer", FAULT_ON_ERROR); - - devp = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_devname)); + if (VALID_STRUCT(mount)) { + readmem(*vfsmnt, KVADDR, mount_buf, SIZE(mount), + "mount buffer", FAULT_ON_ERROR); + devp = ULONG(mount_buf + OFFSET(mount_mnt_devname)); + } else { + readmem(*vfsmnt, KVADDR, vfsmount_buf, SIZE(vfsmount), + "vfsmount buffer", FAULT_ON_ERROR); + devp = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_devname)); + } if (VALID_MEMBER(vfsmount_mnt_dirname)) { dirp = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_dirname)); } else { - mnt_parent = ULONG(vfsmount_buf + - OFFSET(vfsmount_mnt_parent)); - dentry = ULONG(vfsmount_buf + - OFFSET(vfsmount_mnt_mountpoint)); + if (VALID_STRUCT(mount)) { + mnt_parent = ULONG(mount_buf + + OFFSET(mount_mnt_parent)); + dentry = ULONG(mount_buf + + OFFSET(mount_mnt_mountpoint)); + } else { + mnt_parent = ULONG(vfsmount_buf + + OFFSET(vfsmount_mnt_parent)); + dentry = ULONG(vfsmount_buf + + OFFSET(vfsmount_mnt_mountpoint)); + } } sbp = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb)); @@ -1484,7 +1508,10 @@ show_mounts(ulong one_vfsmount, int flags, struct task_context *namespace_contex if (!one_vfsmount) FREEBUF(mntlist); - FREEBUF(vfsmount_buf); + if (VALID_STRUCT(mount)) + FREEBUF(mount_buf); + else + FREEBUF(vfsmount_buf); FREEBUF(super_block_buf); } @@ -1520,7 +1547,10 @@ get_mount_list(int *cntptr, struct task_context *namespace_context) RETURN_ON_ERROR|QUIET)) error(FATAL, "cannot determine mount list location! "); - ld->start = root + OFFSET(vfsmount_mnt_list); + if (VALID_STRUCT(mount)) + ld->start = root + OFFSET(mount_mnt_list); + else + ld->start = root + OFFSET(vfsmount_mnt_list); ld->end = mnt_ns + OFFSET(mnt_namespace_list); } else if (VALID_MEMBER(namespace_root)) { @@ -1538,14 +1568,19 @@ get_mount_list(int *cntptr, struct task_context *namespace_context) console("namespace: %lx => root: %lx ", namespace, root); - ld->start = root + OFFSET(vfsmount_mnt_list); + if (VALID_STRUCT(mount)) + ld->start = root + OFFSET(mount_mnt_list); + else + ld->start = root + OFFSET(vfsmount_mnt_list); ld->end = namespace + OFFSET(namespace_list); } else error(FATAL, "cannot determine mount list location! "); if (VALID_MEMBER(vfsmount_mnt_list)) ld->list_head_offset = OFFSET(vfsmount_mnt_list); - else + else if (VALID_STRUCT(mount)) + ld->list_head_offset = OFFSET(mount_mnt_list); + else ld->member_offset = OFFSET(vfsmount_mnt_next); hq_open(); @@ -1566,7 +1601,7 @@ static void display_dentry_info(ulong dentry) { int m, found; - char *dentry_buf, *inode_buf, *vfsmount_buf; + char *dentry_buf, *inode_buf, *vfsmount_buf, *mount_buf; ulong inode, superblock, sb, vfs; ulong *mntlist, *vfsmnt; char pathname[BUFSIZE]; @@ -1601,12 +1636,22 @@ display_dentry_info(ulong dentry) if (VALID_MEMBER(file_f_vfsmnt)) { mntlist = get_mount_list(&mount_cnt, pid_to_context(1)); - vfsmount_buf = GETBUF(SIZE(vfsmount)); + if (VALID_STRUCT(mount)) { + mount_buf = GETBUF(SIZE(mount)); + vfsmount_buf = mount_buf + OFFSET(mount_mnt); + } else { + mount_buf = NULL; + vfsmount_buf = GETBUF(SIZE(vfsmount)); + } for (m = found = 0, vfsmnt = mntlist; m < mount_cnt; m++, vfsmnt++) { - readmem(*vfsmnt, KVADDR, vfsmount_buf, SIZE(vfsmount), - "vfsmount buffer", FAULT_ON_ERROR); + if (VALID_STRUCT(mount)) + readmem(*vfsmnt, KVADDR, mount_buf, SIZE(mount), + "mount buffer", FAULT_ON_ERROR); + else + readmem(*vfsmnt, KVADDR, vfsmount_buf, SIZE(vfsmount), + "vfsmount buffer", FAULT_ON_ERROR); sb = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb)); if (superblock && (sb == superblock)) { get_pathname(dentry, pathname, @@ -1617,21 +1662,31 @@ display_dentry_info(ulong dentry) if (!found && symbol_exists("pipe_mnt")) { get_symbol_data("pipe_mnt", sizeof(long), &vfs); - readmem(vfs, KVADDR, vfsmount_buf, SIZE(vfsmount), - "vfsmount buffer", FAULT_ON_ERROR); + if (VALID_STRUCT(mount)) + readmem(vfs - OFFSET(mount_mnt), KVADDR, mount_buf, SIZE(mount), + "mount buffer", FAULT_ON_ERROR); + else + readmem(vfs, KVADDR, vfsmount_buf, SIZE(vfsmount), + "vfsmount buffer", FAULT_ON_ERROR); sb = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb)); if (superblock && (sb == superblock)) { - get_pathname(dentry, pathname, BUFSIZE, 1, vfs); + get_pathname(dentry, pathname, BUFSIZE, 1, + vfs - OFFSET(mount_mnt)); found = TRUE; } } if (!found && symbol_exists("sock_mnt")) { get_symbol_data("sock_mnt", sizeof(long), &vfs); - readmem(vfs, KVADDR, vfsmount_buf, SIZE(vfsmount), - "vfsmount buffer", FAULT_ON_ERROR); + if (VALID_STRUCT(mount)) + readmem(vfs - OFFSET(mount_mnt), KVADDR, mount_buf, SIZE(mount), + "mount buffer", FAULT_ON_ERROR); + else + readmem(vfs, KVADDR, vfsmount_buf, SIZE(vfsmount), + "vfsmount buffer", FAULT_ON_ERROR); sb = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb)); if (superblock && (sb == superblock)) { - get_pathname(dentry, pathname, BUFSIZE, 1, vfs); + get_pathname(dentry, pathname, BUFSIZE, 1, + vfs - OFFSET(mount_mnt)); found = TRUE; } } @@ -1642,7 +1697,10 @@ display_dentry_info(ulong dentry) if (mntlist) { FREEBUF(mntlist); - FREEBUF(vfsmount_buf); + if (VALID_STRUCT(mount)) + FREEBUF(mount_buf); + else + FREEBUF(vfsmount_buf); } nopath: @@ -1897,12 +1955,26 @@ vfs_init(void) MEMBER_OFFSET_INIT(vfsmount_mnt_next, "vfsmount", "mnt_next"); MEMBER_OFFSET_INIT(vfsmount_mnt_devname, "vfsmount", "mnt_devname"); + if (INVALID_MEMBER(vfsmount_mnt_devname)) { + 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_list, "vfsmount", "mnt_list"); + if (INVALID_MEMBER(vfsmount_mnt_devname)) { + MEMBER_OFFSET_INIT(mount_mnt_list, "mount", "mnt_list"); + } MEMBER_OFFSET_INIT(vfsmount_mnt_parent, "vfsmount", "mnt_parent"); + if (INVALID_MEMBER(vfsmount_mnt_devname)) { + MEMBER_OFFSET_INIT(mount_mnt_parent, "mount", "mnt_parent"); + } MEMBER_OFFSET_INIT(vfsmount_mnt_mountpoint, "vfsmount", "mnt_mountpoint"); + if (INVALID_MEMBER(vfsmount_mnt_devname)) { + MEMBER_OFFSET_INIT(mount_mnt_mountpoint, + "mount", "mnt_mountpoint"); + } + MEMBER_OFFSET_INIT(mount_mnt, "mount", "mnt"); MEMBER_OFFSET_INIT(namespace_root, "namespace", "root"); MEMBER_OFFSET_INIT(task_struct_nsproxy, "task_struct", "nsproxy"); if (VALID_MEMBER(namespace_root)) { @@ -1939,6 +2011,7 @@ vfs_init(void) STRUCT_SIZE_INIT(fdtable, "fdtable"); STRUCT_SIZE_INIT(file, "file"); STRUCT_SIZE_INIT(inode, "inode"); + STRUCT_SIZE_INIT(mount, "mount"); STRUCT_SIZE_INIT(vfsmount, "vfsmount"); STRUCT_SIZE_INIT(fs_struct, "fs_struct"); STRUCT_SIZE_INIT(super_block, "super_block"); @@ -2226,12 +2299,16 @@ open_files_dump(ulong task, int flags, struct reference *ref) if (VALID_MEMBER(fs_struct_rootmnt)) { vfsmnt = ULONG(fs_struct_buf + OFFSET(fs_struct_rootmnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(root_dentry, root_pathname, BUFSIZE, 1, vfsmnt); } else if (use_path) { vfsmnt = ULONG(fs_struct_buf + OFFSET(fs_struct_root) + OFFSET(path_mnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(root_dentry, root_pathname, BUFSIZE, 1, vfsmnt); } else { @@ -2250,12 +2327,16 @@ open_files_dump(ulong task, int flags, struct reference *ref) if (VALID_MEMBER(fs_struct_pwdmnt)) { vfsmnt = ULONG(fs_struct_buf + OFFSET(fs_struct_pwdmnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(pwd_dentry, pwd_pathname, BUFSIZE, 1, vfsmnt); } else if (use_path) { vfsmnt = ULONG(fs_struct_buf + OFFSET(fs_struct_pwd) + OFFSET(path_mnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(pwd_dentry, pwd_pathname, BUFSIZE, 1, vfsmnt); @@ -2686,7 +2767,12 @@ file_dump(ulong file, ulong dentry, ulong inode, int fd, int flags) if (flags & DUMP_FULL_NAME) { if (VALID_MEMBER(file_f_vfsmnt)) { vfsmnt = get_root_vfsmount(file_buf); - get_pathname(dentry, pathname, BUFSIZE, 1, vfsmnt); + if (VALID_STRUCT(mount)) + get_pathname(dentry, pathname, BUFSIZE, 1, + vfsmnt - OFFSET(mount_mnt)); + else + get_pathname(dentry, pathname, BUFSIZE, 1, + vfsmnt); if (STRNEQ(pathname, "/pts/") && STREQ(vfsmount_devname(vfsmnt, buf1, BUFSIZE), "devpts")) @@ -2793,13 +2879,24 @@ get_pathname(ulong dentry, char *pathname, int length, int full, ulong vfsmnt) int d_name_len = 0; ulong d_name_name; ulong tmp_vfsmnt, mnt_parent; - char *dentry_buf, *vfsmnt_buf; + char *dentry_buf, *vfsmnt_buf, *mnt_buf; BZERO(buf, BUFSIZE); BZERO(tmpname, BUFSIZE); BZERO(pathname, length); - vfsmnt_buf = VALID_MEMBER(vfsmount_mnt_mountpoint) ? - GETBUF(SIZE(vfsmount)) : NULL; + if (VALID_STRUCT(mount)) { + if (VALID_MEMBER(mount_mnt_mountpoint)) { + mnt_buf = GETBUF(SIZE(mount)); + vfsmnt_buf = mnt_buf + OFFSET(mount_mnt); + } else { + mnt_buf = NULL; + vfsmnt_buf = NULL; + } + } else { + mnt_buf = NULL; + vfsmnt_buf = VALID_MEMBER(vfsmount_mnt_mountpoint) ? + GETBUF(SIZE(vfsmount)) : NULL; + } parent = dentry; tmp_vfsmnt = vfsmnt; @@ -2861,7 +2958,25 @@ get_pathname(ulong dentry, char *pathname, int length, int full, ulong vfsmnt) else tmp_vfsmnt = mnt_parent; } - } else { + } else if (VALID_STRUCT(mount)) { + if (tmp_vfsmnt) { + if (strncmp(pathname, "//", 2) == 0) + shift_string_left(pathname, 1); + readmem(tmp_vfsmnt, KVADDR, mnt_buf, + SIZE(mount), + "mount buffer", + FAULT_ON_ERROR); + parent = ULONG(mnt_buf + + OFFSET(mount_mnt_mountpoint)); + mnt_parent = ULONG(mnt_buf + + OFFSET(mount_mnt_parent)); + if (tmp_vfsmnt == mnt_parent) + break; + else + tmp_vfsmnt = mnt_parent; + } + } + else { parent = ULONG(dentry_buf + OFFSET(dentry_d_covers)); } @@ -2869,7 +2984,9 @@ get_pathname(ulong dentry, char *pathname, int length, int full, ulong vfsmnt) } while (tmp_dentry != parent && parent); - if (vfsmnt_buf) + if (mnt_buf) + FREEBUF(mnt_buf); + else if (vfsmnt_buf) FREEBUF(vfsmnt_buf); } @@ -3901,10 +4018,17 @@ vfsmount_devname(ulong vfsmnt, char *buf, int maxlen) BZERO(buf, maxlen); - if (!readmem(vfsmnt + OFFSET(vfsmount_mnt_devname), - KVADDR, &devp, sizeof(void *), "vfsmount mnt_devname", - QUIET|RETURN_ON_ERROR)) - return buf; + if (VALID_STRUCT(mount)) { + if (!readmem(vfsmnt - OFFSET(mount_mnt) + OFFSET(mount_mnt_devname), + KVADDR, &devp, sizeof(void *), "mount mnt_devname", + QUIET|RETURN_ON_ERROR)) + return buf; + } else { + if (!readmem(vfsmnt + OFFSET(vfsmount_mnt_devname), + KVADDR, &devp, sizeof(void *), "vfsmount mnt_devname", + QUIET|RETURN_ON_ERROR)) + return buf; + } if (read_string(devp, buf, BUFSIZE-1)) return buf; @@ -3925,10 +4049,17 @@ get_root_vfsmount(char *file_buf) return vfsmnt; if (STREQ(buf, "udev")) { - if (!readmem(vfsmnt + OFFSET(vfsmount_mnt_parent), KVADDR, - &mnt_parent, sizeof(void *), "vfsmount mnt_parent", - QUIET|RETURN_ON_ERROR)) - return vfsmnt; + if (VALID_STRUCT(mount)) { + if (!readmem(vfsmnt - OFFSET(mount_mnt) + OFFSET(mount_mnt_parent), KVADDR, + &mnt_parent, sizeof(void *), "mount mnt_parent", + QUIET|RETURN_ON_ERROR)) + return vfsmnt; + } else { + if (!readmem(vfsmnt + OFFSET(vfsmount_mnt_parent), KVADDR, + &mnt_parent, sizeof(void *), "vfsmount mnt_parent", + QUIET|RETURN_ON_ERROR)) + return vfsmnt; + } if (!strlen(vfsmount_devname(mnt_parent, buf, BUFSIZE))) return vfsmnt; diff --git a/memory.c b/memory.c index 55a184b..98cd2df 100755 --- a/memory.c +++ b/memory.c @@ -3477,6 +3477,8 @@ vm_area_dump(ulong task, ulong flag, ulong vaddr, struct reference *ref) if (VALID_MEMBER(file_f_vfsmnt)) { vfsmnt = ULONG(file_buf + OFFSET(file_f_vfsmnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(dentry, buf1, BUFSIZE, 1, vfsmnt); } else { diff --git a/symbols.c b/symbols.c index f88c016..d141f1b 100755 --- a/symbols.c +++ b/symbols.c @@ -7934,6 +7934,16 @@ dump_offset_table(char *spec, ulong makestruct) OFFSET(vfsmount_mnt_mountpoint)); fprintf(fp, " vfsmount_mnt_parent: %ld ", OFFSET(vfsmount_mnt_parent)); + fprintf(fp, " mount_mnt_parent: %ld ", + OFFSET(mount_mnt_parent)); + fprintf(fp, " mount_mnt_mountpoint: %ld ", + OFFSET(mount_mnt_mountpoint)); + fprintf(fp, " mount_mnt_list: %ld ", + OFFSET(mount_mnt_list)); + fprintf(fp, " mount_mnt_devname: %ld ", + OFFSET(mount_mnt_devname)); + fprintf(fp, " mount_mnt: %ld ", + OFFSET(mount_mnt)); fprintf(fp, " namespace_root: %ld ", OFFSET(namespace_root)); fprintf(fp, " namespace_list: %ld ", @@ -8701,6 +8711,7 @@ dump_offset_table(char *spec, ulong makestruct) fprintf(fp, " file: %ld ", SIZE(file)); fprintf(fp, " inode: %ld ", SIZE(inode)); fprintf(fp, " vfsmount: %ld ", SIZE(vfsmount)); + fprintf(fp, " mount: %ld ", SIZE(mount)); fprintf(fp, " super_block: %ld ", SIZE(super_block)); fprintf(fp, " irqdesc: %ld ", SIZE(irqdesc)); -- Crash-utility mailing list Crash-utility@redhat.com https://www.redhat.com/mailman/listinfo/crash-utility |
fix command vm/files -d/mount on new kernel
At 2012-3-10 5:50, Dave Anderson wrote:
----- Original Message ----- ----- Original Message ----- Hello Dave, New kernel has moved some elements of struct vfsmount to a new struct mount. So crash will not act normally on new kernel. The patch is used to fix the problem. Please check. Hi Qiao, This patch-set is very much appreciated. I saw Al Viro's original LKML patch posted back in December (?), and had been waiting to see an actual kernel with it in place. The most recent in-house RHEL/Fedora test kernels I have on-hand are all 3.2.x-era kernels, which don't have the patch, so I'm presuming you're running on a 3.3.x kernel? Anyway, I'll check this patch out for backwards-compatibility and try to get a more recent kernel to test with. It looks good on paper... And again, thanks for taking on this task. Dave I provisioned a system with a Fedora 3.3.0-0.rc6.git2.1.fc17 kernel, which has the vfsmount->mount patch. The session comes up cleanly, but the following commands fail: crash> mount ... [ cut ] ... mount: invalid structure member offset: vfsmount_mnt_list ... crash> files ... [cut] ... files: invalid structure member offset: dentry_d_covers ... The "fuser" command generates the above error because it uses the "files" command behind the scenes. crash> vm ... [cut] ... vm: invalid structure member offset: dentry_d_covers ... crash> swap ... [cut] ... swap: invalid structure member offset: dentry_d_covers ... With your patch applied, "mount", "files", "fuser" and "vm" all work OK. But "swap" now fails in a different manner: crash> swap FILENAME TYPE SIZE USED PCT PRIORITY swap: invalid kernel virtual address: 1d8ec8 type: "fill_dentry_cache" crash> It's failing in its call to get_pathname(). I haven't had a chance to You are right. I forgot to check every call to get_pathname. The new patch has fixed the problem of swap. fully check into why it's getting a bogus parent dentry address while walking through the swap file's "/dev/mapper/vg_dellpec610002-lv_swap" pathname -- and I won't be able to until next week. But presumably it's related, and so if you (or anybody) gets a chance this weekend, please take a look. Thanks, Dave -- Crash-utility mailing list Crash-utility@redhat.com https://www.redhat.com/mailman/listinfo/crash-utility -- -- Regards Qiao Nuohan -------------------------------------------------- Qiao Nuohan Development Dept.I Nanjing Fujitsu Nanda Software Tech. Co., Ltd.(FNST) No. 6 Wenzhu Road, Nanjing, Nanjing, 210012, China TEL: +86+25-86630566-8526 FUJITSU INTERNAL: 7998-8526 FAX: +86+25-83317685 EMail: qiaonuohan@cn.fujitsu.com -------------------------------------------------- This communication is for use by the intended recipient(s) only and may contain information that is privileged, confidential and exempt from disclosure under applicable law. If you are not an intended recipient of this communication, you are hereby notified that any dissemination, distribution or copying hereof is strictly prohibited. If you have received this communication in error, please notify me by reply e-mail, permanently delete this communication from your system, and destroy any hard copies you may have printed diff --git a/defs.h b/defs.h index a942dbb..0124f5f 100755 --- a/defs.h +++ b/defs.h @@ -1281,6 +1281,11 @@ struct offset_table { /* stash of commonly-used offsets */ long vfsmount_mnt_list; long vfsmount_mnt_mountpoint; long vfsmount_mnt_parent; + long mount_mnt_parent; + long mount_mnt_mountpoint; + long mount_mnt_list; + long mount_mnt_devname; + long mount_mnt; long namespace_root; long namespace_list; long super_block_s_dirty; @@ -1694,6 +1699,7 @@ struct size_table { /* stash of commonly-used sizes */ long fs_struct; long file; long inode; + long mount; long vfsmount; long super_block; long irqdesc; diff --git a/filesys.c b/filesys.c index 55a4677..0f4db2a 100755 --- a/filesys.c +++ b/filesys.c @@ -1298,7 +1298,7 @@ show_mounts(ulong one_vfsmount, int flags, struct task_context *namespace_contex char buf4[BUFSIZE]; ulong *dentry_list, *dp, *mntlist; ulong *vfsmnt; - char *vfsmount_buf, *super_block_buf; + char *vfsmount_buf, *super_block_buf, *mount_buf; ulong dentry, inode, inode_sb, mnt_parent; char *dentry_buf, *inode_buf; int cnt, i, m, files_header_printed; @@ -1336,9 +1336,15 @@ show_mounts(ulong one_vfsmount, int flags, struct task_context *namespace_contex devlen = strlen("DEVNAME"); for (m = 0, vfsmnt = mntlist; m < mount_cnt; m++, vfsmnt++) { - readmem(*vfsmnt + OFFSET(vfsmount_mnt_devname), - KVADDR, &devp, sizeof(void *), - "vfsmount mnt_devname", FAULT_ON_ERROR); + if (VALID_STRUCT(mount)) { + readmem(*vfsmnt+OFFSET(mount_mnt_devname), + KVADDR, &devp, sizeof(void *), + "mount mnt_devname", FAULT_ON_ERROR); + } else { + readmem(*vfsmnt+OFFSET(vfsmount_mnt_devname), + KVADDR, &devp, sizeof(void *), + "vfsmount mnt_devname", FAULT_ON_ERROR); + } if (read_string(devp, buf1, BUFSIZE-1)) { if (strlen(buf1) > devlen) @@ -1366,23 +1372,41 @@ show_mounts(ulong one_vfsmount, int flags, struct task_context *namespace_contex &cnt); } - vfsmount_buf = GETBUF(SIZE(vfsmount)); + if (VALID_STRUCT(mount)) { + mount_buf = GETBUF(SIZE(mount)); + vfsmount_buf = mount_buf + OFFSET(mount_mnt); + } else { + mount_buf = NULL; + vfsmount_buf = GETBUF(SIZE(vfsmount)); + } super_block_buf = GETBUF(SIZE(super_block)); for (m = 0, vfsmnt = mntlist; m < mount_cnt; m++, vfsmnt++) { - readmem(*vfsmnt, KVADDR, vfsmount_buf, SIZE(vfsmount), - "vfsmount buffer", FAULT_ON_ERROR); - - devp = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_devname)); + if (VALID_STRUCT(mount)) { + readmem(*vfsmnt, KVADDR, mount_buf, SIZE(mount), + "mount buffer", FAULT_ON_ERROR); + devp = ULONG(mount_buf + OFFSET(mount_mnt_devname)); + } else { + readmem(*vfsmnt, KVADDR, vfsmount_buf, SIZE(vfsmount), + "vfsmount buffer", FAULT_ON_ERROR); + devp = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_devname)); + } if (VALID_MEMBER(vfsmount_mnt_dirname)) { dirp = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_dirname)); } else { - mnt_parent = ULONG(vfsmount_buf + - OFFSET(vfsmount_mnt_parent)); - dentry = ULONG(vfsmount_buf + - OFFSET(vfsmount_mnt_mountpoint)); + if (VALID_STRUCT(mount)) { + mnt_parent = ULONG(mount_buf + + OFFSET(mount_mnt_parent)); + dentry = ULONG(mount_buf + + OFFSET(mount_mnt_mountpoint)); + } else { + mnt_parent = ULONG(vfsmount_buf + + OFFSET(vfsmount_mnt_parent)); + dentry = ULONG(vfsmount_buf + + OFFSET(vfsmount_mnt_mountpoint)); + } } sbp = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb)); @@ -1484,7 +1508,10 @@ show_mounts(ulong one_vfsmount, int flags, struct task_context *namespace_contex if (!one_vfsmount) FREEBUF(mntlist); - FREEBUF(vfsmount_buf); + if (VALID_STRUCT(mount)) + FREEBUF(mount_buf); + else + FREEBUF(vfsmount_buf); FREEBUF(super_block_buf); } @@ -1520,7 +1547,10 @@ get_mount_list(int *cntptr, struct task_context *namespace_context) RETURN_ON_ERROR|QUIET)) error(FATAL, "cannot determine mount list location! "); - ld->start = root + OFFSET(vfsmount_mnt_list); + if (VALID_STRUCT(mount)) + ld->start = root + OFFSET(mount_mnt_list); + else + ld->start = root + OFFSET(vfsmount_mnt_list); ld->end = mnt_ns + OFFSET(mnt_namespace_list); } else if (VALID_MEMBER(namespace_root)) { @@ -1538,14 +1568,19 @@ get_mount_list(int *cntptr, struct task_context *namespace_context) console("namespace: %lx => root: %lx ", namespace, root); - ld->start = root + OFFSET(vfsmount_mnt_list); + if (VALID_STRUCT(mount)) + ld->start = root + OFFSET(mount_mnt_list); + else + ld->start = root + OFFSET(vfsmount_mnt_list); ld->end = namespace + OFFSET(namespace_list); } else error(FATAL, "cannot determine mount list location! "); if (VALID_MEMBER(vfsmount_mnt_list)) ld->list_head_offset = OFFSET(vfsmount_mnt_list); - else + else if (VALID_STRUCT(mount)) + ld->list_head_offset = OFFSET(mount_mnt_list); + else ld->member_offset = OFFSET(vfsmount_mnt_next); hq_open(); @@ -1566,7 +1601,7 @@ static void display_dentry_info(ulong dentry) { int m, found; - char *dentry_buf, *inode_buf, *vfsmount_buf; + char *dentry_buf, *inode_buf, *vfsmount_buf, *mount_buf; ulong inode, superblock, sb, vfs; ulong *mntlist, *vfsmnt; char pathname[BUFSIZE]; @@ -1601,12 +1636,22 @@ display_dentry_info(ulong dentry) if (VALID_MEMBER(file_f_vfsmnt)) { mntlist = get_mount_list(&mount_cnt, pid_to_context(1)); - vfsmount_buf = GETBUF(SIZE(vfsmount)); + if (VALID_STRUCT(mount)) { + mount_buf = GETBUF(SIZE(mount)); + vfsmount_buf = mount_buf + OFFSET(mount_mnt); + } else { + mount_buf = NULL; + vfsmount_buf = GETBUF(SIZE(vfsmount)); + } for (m = found = 0, vfsmnt = mntlist; m < mount_cnt; m++, vfsmnt++) { - readmem(*vfsmnt, KVADDR, vfsmount_buf, SIZE(vfsmount), - "vfsmount buffer", FAULT_ON_ERROR); + if (VALID_STRUCT(mount)) + readmem(*vfsmnt, KVADDR, mount_buf, SIZE(mount), + "mount buffer", FAULT_ON_ERROR); + else + readmem(*vfsmnt, KVADDR, vfsmount_buf, SIZE(vfsmount), + "vfsmount buffer", FAULT_ON_ERROR); sb = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb)); if (superblock && (sb == superblock)) { get_pathname(dentry, pathname, @@ -1617,21 +1662,31 @@ display_dentry_info(ulong dentry) if (!found && symbol_exists("pipe_mnt")) { get_symbol_data("pipe_mnt", sizeof(long), &vfs); - readmem(vfs, KVADDR, vfsmount_buf, SIZE(vfsmount), - "vfsmount buffer", FAULT_ON_ERROR); + if (VALID_STRUCT(mount)) + readmem(vfs - OFFSET(mount_mnt), KVADDR, mount_buf, SIZE(mount), + "mount buffer", FAULT_ON_ERROR); + else + readmem(vfs, KVADDR, vfsmount_buf, SIZE(vfsmount), + "vfsmount buffer", FAULT_ON_ERROR); sb = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb)); if (superblock && (sb == superblock)) { - get_pathname(dentry, pathname, BUFSIZE, 1, vfs); + get_pathname(dentry, pathname, BUFSIZE, 1, + vfs - OFFSET(mount_mnt)); found = TRUE; } } if (!found && symbol_exists("sock_mnt")) { get_symbol_data("sock_mnt", sizeof(long), &vfs); - readmem(vfs, KVADDR, vfsmount_buf, SIZE(vfsmount), - "vfsmount buffer", FAULT_ON_ERROR); + if (VALID_STRUCT(mount)) + readmem(vfs - OFFSET(mount_mnt), KVADDR, mount_buf, SIZE(mount), + "mount buffer", FAULT_ON_ERROR); + else + readmem(vfs, KVADDR, vfsmount_buf, SIZE(vfsmount), + "vfsmount buffer", FAULT_ON_ERROR); sb = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb)); if (superblock && (sb == superblock)) { - get_pathname(dentry, pathname, BUFSIZE, 1, vfs); + get_pathname(dentry, pathname, BUFSIZE, 1, + vfs - OFFSET(mount_mnt)); found = TRUE; } } @@ -1642,7 +1697,10 @@ display_dentry_info(ulong dentry) if (mntlist) { FREEBUF(mntlist); - FREEBUF(vfsmount_buf); + if (VALID_STRUCT(mount)) + FREEBUF(mount_buf); + else + FREEBUF(vfsmount_buf); } nopath: @@ -1897,12 +1955,26 @@ vfs_init(void) MEMBER_OFFSET_INIT(vfsmount_mnt_next, "vfsmount", "mnt_next"); MEMBER_OFFSET_INIT(vfsmount_mnt_devname, "vfsmount", "mnt_devname"); + if (INVALID_MEMBER(vfsmount_mnt_devname)) { + 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_list, "vfsmount", "mnt_list"); + if (INVALID_MEMBER(vfsmount_mnt_devname)) { + MEMBER_OFFSET_INIT(mount_mnt_list, "mount", "mnt_list"); + } MEMBER_OFFSET_INIT(vfsmount_mnt_parent, "vfsmount", "mnt_parent"); + if (INVALID_MEMBER(vfsmount_mnt_devname)) { + MEMBER_OFFSET_INIT(mount_mnt_parent, "mount", "mnt_parent"); + } MEMBER_OFFSET_INIT(vfsmount_mnt_mountpoint, "vfsmount", "mnt_mountpoint"); + if (INVALID_MEMBER(vfsmount_mnt_devname)) { + MEMBER_OFFSET_INIT(mount_mnt_mountpoint, + "mount", "mnt_mountpoint"); + } + MEMBER_OFFSET_INIT(mount_mnt, "mount", "mnt"); MEMBER_OFFSET_INIT(namespace_root, "namespace", "root"); MEMBER_OFFSET_INIT(task_struct_nsproxy, "task_struct", "nsproxy"); if (VALID_MEMBER(namespace_root)) { @@ -1939,6 +2011,7 @@ vfs_init(void) STRUCT_SIZE_INIT(fdtable, "fdtable"); STRUCT_SIZE_INIT(file, "file"); STRUCT_SIZE_INIT(inode, "inode"); + STRUCT_SIZE_INIT(mount, "mount"); STRUCT_SIZE_INIT(vfsmount, "vfsmount"); STRUCT_SIZE_INIT(fs_struct, "fs_struct"); STRUCT_SIZE_INIT(super_block, "super_block"); @@ -2226,12 +2299,16 @@ open_files_dump(ulong task, int flags, struct reference *ref) if (VALID_MEMBER(fs_struct_rootmnt)) { vfsmnt = ULONG(fs_struct_buf + OFFSET(fs_struct_rootmnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(root_dentry, root_pathname, BUFSIZE, 1, vfsmnt); } else if (use_path) { vfsmnt = ULONG(fs_struct_buf + OFFSET(fs_struct_root) + OFFSET(path_mnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(root_dentry, root_pathname, BUFSIZE, 1, vfsmnt); } else { @@ -2250,12 +2327,16 @@ open_files_dump(ulong task, int flags, struct reference *ref) if (VALID_MEMBER(fs_struct_pwdmnt)) { vfsmnt = ULONG(fs_struct_buf + OFFSET(fs_struct_pwdmnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(pwd_dentry, pwd_pathname, BUFSIZE, 1, vfsmnt); } else if (use_path) { vfsmnt = ULONG(fs_struct_buf + OFFSET(fs_struct_pwd) + OFFSET(path_mnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(pwd_dentry, pwd_pathname, BUFSIZE, 1, vfsmnt); @@ -2686,7 +2767,12 @@ file_dump(ulong file, ulong dentry, ulong inode, int fd, int flags) if (flags & DUMP_FULL_NAME) { if (VALID_MEMBER(file_f_vfsmnt)) { vfsmnt = get_root_vfsmount(file_buf); - get_pathname(dentry, pathname, BUFSIZE, 1, vfsmnt); + if (VALID_STRUCT(mount)) + get_pathname(dentry, pathname, BUFSIZE, 1, + vfsmnt - OFFSET(mount_mnt)); + else + get_pathname(dentry, pathname, BUFSIZE, 1, + vfsmnt); if (STRNEQ(pathname, "/pts/") && STREQ(vfsmount_devname(vfsmnt, buf1, BUFSIZE), "devpts")) @@ -2793,13 +2879,24 @@ get_pathname(ulong dentry, char *pathname, int length, int full, ulong vfsmnt) int d_name_len = 0; ulong d_name_name; ulong tmp_vfsmnt, mnt_parent; - char *dentry_buf, *vfsmnt_buf; + char *dentry_buf, *vfsmnt_buf, *mnt_buf; BZERO(buf, BUFSIZE); BZERO(tmpname, BUFSIZE); BZERO(pathname, length); - vfsmnt_buf = VALID_MEMBER(vfsmount_mnt_mountpoint) ? - GETBUF(SIZE(vfsmount)) : NULL; + if (VALID_STRUCT(mount)) { + if (VALID_MEMBER(mount_mnt_mountpoint)) { + mnt_buf = GETBUF(SIZE(mount)); + vfsmnt_buf = mnt_buf + OFFSET(mount_mnt); + } else { + mnt_buf = NULL; + vfsmnt_buf = NULL; + } + } else { + mnt_buf = NULL; + vfsmnt_buf = VALID_MEMBER(vfsmount_mnt_mountpoint) ? + GETBUF(SIZE(vfsmount)) : NULL; + } parent = dentry; tmp_vfsmnt = vfsmnt; @@ -2861,7 +2958,25 @@ get_pathname(ulong dentry, char *pathname, int length, int full, ulong vfsmnt) else tmp_vfsmnt = mnt_parent; } - } else { + } else if (VALID_STRUCT(mount)) { + if (tmp_vfsmnt) { + if (strncmp(pathname, "//", 2) == 0) + shift_string_left(pathname, 1); + readmem(tmp_vfsmnt, KVADDR, mnt_buf, + SIZE(mount), + "mount buffer", + FAULT_ON_ERROR); + parent = ULONG(mnt_buf + + OFFSET(mount_mnt_mountpoint)); + mnt_parent = ULONG(mnt_buf + + OFFSET(mount_mnt_parent)); + if (tmp_vfsmnt == mnt_parent) + break; + else + tmp_vfsmnt = mnt_parent; + } + } + else { parent = ULONG(dentry_buf + OFFSET(dentry_d_covers)); } @@ -2869,7 +2984,9 @@ get_pathname(ulong dentry, char *pathname, int length, int full, ulong vfsmnt) } while (tmp_dentry != parent && parent); - if (vfsmnt_buf) + if (mnt_buf) + FREEBUF(mnt_buf); + else if (vfsmnt_buf) FREEBUF(vfsmnt_buf); } @@ -3901,10 +4018,17 @@ vfsmount_devname(ulong vfsmnt, char *buf, int maxlen) BZERO(buf, maxlen); - if (!readmem(vfsmnt + OFFSET(vfsmount_mnt_devname), - KVADDR, &devp, sizeof(void *), "vfsmount mnt_devname", - QUIET|RETURN_ON_ERROR)) - return buf; + if (VALID_STRUCT(mount)) { + if (!readmem(vfsmnt - OFFSET(mount_mnt) + OFFSET(mount_mnt_devname), + KVADDR, &devp, sizeof(void *), "mount mnt_devname", + QUIET|RETURN_ON_ERROR)) + return buf; + } else { + if (!readmem(vfsmnt + OFFSET(vfsmount_mnt_devname), + KVADDR, &devp, sizeof(void *), "vfsmount mnt_devname", + QUIET|RETURN_ON_ERROR)) + return buf; + } if (read_string(devp, buf, BUFSIZE-1)) return buf; @@ -3925,10 +4049,17 @@ get_root_vfsmount(char *file_buf) return vfsmnt; if (STREQ(buf, "udev")) { - if (!readmem(vfsmnt + OFFSET(vfsmount_mnt_parent), KVADDR, - &mnt_parent, sizeof(void *), "vfsmount mnt_parent", - QUIET|RETURN_ON_ERROR)) - return vfsmnt; + if (VALID_STRUCT(mount)) { + if (!readmem(vfsmnt - OFFSET(mount_mnt) + OFFSET(mount_mnt_parent), KVADDR, + &mnt_parent, sizeof(void *), "mount mnt_parent", + QUIET|RETURN_ON_ERROR)) + return vfsmnt; + } else { + if (!readmem(vfsmnt + OFFSET(vfsmount_mnt_parent), KVADDR, + &mnt_parent, sizeof(void *), "vfsmount mnt_parent", + QUIET|RETURN_ON_ERROR)) + return vfsmnt; + } if (!strlen(vfsmount_devname(mnt_parent, buf, BUFSIZE))) return vfsmnt; diff --git a/memory.c b/memory.c index 55a184b..9a9d58f 100755 --- a/memory.c +++ b/memory.c @@ -3477,6 +3477,8 @@ vm_area_dump(ulong task, ulong flag, ulong vaddr, struct reference *ref) if (VALID_MEMBER(file_f_vfsmnt)) { vfsmnt = ULONG(file_buf + OFFSET(file_f_vfsmnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(dentry, buf1, BUFSIZE, 1, vfsmnt); } else { @@ -12901,8 +12903,14 @@ dump_swap_info(ulong swapflags, ulong *totalswap_pages, ulong *totalused_pages) 1, vfsmnt); } else if (VALID_MEMBER (swap_info_struct_old_block_size)) { - get_pathname(file_to_dentry(swap_file), - buf, BUFSIZE, 1, file_to_vfsmnt(swap_file)); + if (VALID_STRUCT(mount)) + get_pathname(file_to_dentry(swap_file), + buf, BUFSIZE, 1, + file_to_vfsmnt(swap_file)-OFFSET(mount_mnt)); + else + get_pathname(file_to_dentry(swap_file), + buf, BUFSIZE, 1, + file_to_vfsmnt(swap_file)); } else { get_pathname(swap_file, buf, BUFSIZE, 1, 0); } diff --git a/symbols.c b/symbols.c index f88c016..d141f1b 100755 --- a/symbols.c +++ b/symbols.c @@ -7934,6 +7934,16 @@ dump_offset_table(char *spec, ulong makestruct) OFFSET(vfsmount_mnt_mountpoint)); fprintf(fp, " vfsmount_mnt_parent: %ld ", OFFSET(vfsmount_mnt_parent)); + fprintf(fp, " mount_mnt_parent: %ld ", + OFFSET(mount_mnt_parent)); + fprintf(fp, " mount_mnt_mountpoint: %ld ", + OFFSET(mount_mnt_mountpoint)); + fprintf(fp, " mount_mnt_list: %ld ", + OFFSET(mount_mnt_list)); + fprintf(fp, " mount_mnt_devname: %ld ", + OFFSET(mount_mnt_devname)); + fprintf(fp, " mount_mnt: %ld ", + OFFSET(mount_mnt)); fprintf(fp, " namespace_root: %ld ", OFFSET(namespace_root)); fprintf(fp, " namespace_list: %ld ", @@ -8701,6 +8711,7 @@ dump_offset_table(char *spec, ulong makestruct) fprintf(fp, " file: %ld ", SIZE(file)); fprintf(fp, " inode: %ld ", SIZE(inode)); fprintf(fp, " vfsmount: %ld ", SIZE(vfsmount)); + fprintf(fp, " mount: %ld ", SIZE(mount)); fprintf(fp, " super_block: %ld ", SIZE(super_block)); fprintf(fp, " irqdesc: %ld ", SIZE(irqdesc)); -- Crash-utility mailing list Crash-utility@redhat.com https://www.redhat.com/mailman/listinfo/crash-utility |
fix command vm/files -d/mount on new kernel
At 2012-3-13 3:27, Dave Anderson wrote:
----- Original Message ----- At 2012-3-10 5:50, Dave Anderson wrote: It's failing in its call to get_pathname(). I haven't had a chance to You are right. I forgot to check every call to get_pathname. The new patch has fixed the problem of swap. Although the patch appears to work in the simple cases that I have tested, I have a few issues with it. First, the get_pathname() function prototype is -- and has always been -- this: void get_pathname(ulong dentry, char *pathname, int length, int full, ulong vfsmnt) where the "vfsmnt" argument has always been a struct vfsmount pointer. With your patch, prior to making get_pathname() calls, you typically make a VALID_STRUCT(mount) call first, and if true, you modify the vfsmnt argument to be a struct mount pointer. It would make more sense maintenance-wise, and would simplify the patch, if the get_pathname() "vfsmnt" argument would continue to be a struct vfsmount pointer. And at the top of get_pathname(), you could make the adjustments for when it is embedded inside a struct mount. For example, taking these patches to open_files_dump() and file_dump(): @@ -2226,12 +2299,16 @@ open_files_dump(ulong task, int flags, struct reference *ref) if (VALID_MEMBER(fs_struct_rootmnt)) { vfsmnt = ULONG(fs_struct_buf + OFFSET(fs_struct_rootmnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(root_dentry, root_pathname, BUFSIZE, 1, vfsmnt); } else if (use_path) { vfsmnt = ULONG(fs_struct_buf + OFFSET(fs_struct_root) + OFFSET(path_mnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(root_dentry, root_pathname, BUFSIZE, 1, vfsmnt); } else { @@ -2250,12 +2327,16 @@ open_files_dump(ulong task, int flags, struct reference *ref) if (VALID_MEMBER(fs_struct_pwdmnt)) { vfsmnt = ULONG(fs_struct_buf + OFFSET(fs_struct_pwdmnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(pwd_dentry, pwd_pathname, BUFSIZE, 1, vfsmnt); } else if (use_path) { vfsmnt = ULONG(fs_struct_buf + OFFSET(fs_struct_pwd) + OFFSET(path_mnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(pwd_dentry, pwd_pathname, BUFSIZE, 1, vfsmnt); @@ -2686,7 +2767,12 @@ file_dump(ulong file, ulong dentry, ulong inode, int fd, int flags) if (flags& DUMP_FULL_NAME) { if (VALID_MEMBER(file_f_vfsmnt)) { vfsmnt = get_root_vfsmount(file_buf); - get_pathname(dentry, pathname, BUFSIZE, 1, vfsmnt); + if (VALID_STRUCT(mount)) + get_pathname(dentry, pathname, BUFSIZE, 1, + vfsmnt - OFFSET(mount_mnt)); + else + get_pathname(dentry, pathname, BUFSIZE, 1, + vfsmnt); if (STRNEQ(pathname, "/pts/")&& STREQ(vfsmount_devname(vfsmnt, buf1, BUFSIZE), "devpts")) If the vfsmount-to-mount calculation were always done in get_pathname() itself, then the patches above would be unnecessary. The same is true for a few other parts of the patch. Did you consider doing it that way? And consider the following patched version of display_dentry_info() below. The two get_pathname() calls below would generate fatal errors on older kernels because OFFSET(mount_mnt) will be invalid: if (!found&& symbol_exists("pipe_mnt")) { get_symbol_data("pipe_mnt", sizeof(long),&vfs); if (VALID_STRUCT(mount)) readmem(vfs - OFFSET(mount_mnt), KVADDR, mount_buf, SIZE(mount), "mount buffer", FAULT_ON_ERROR); else readmem(vfs, KVADDR, vfsmount_buf, SIZE(vfsmount), "vfsmount buffer", FAULT_ON_ERROR); sb = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb)); if (superblock&& (sb == superblock)) { get_pathname(dentry, pathname, BUFSIZE, 1, vfs - OFFSET(mount_mnt)); found = TRUE; } } if (!found&& symbol_exists("sock_mnt")) { get_symbol_data("sock_mnt", sizeof(long),&vfs); if (VALID_STRUCT(mount)) readmem(vfs - OFFSET(mount_mnt), KVADDR, mount_buf, SIZE(mount), "mount buffer", FAULT_ON_ERROR); else readmem(vfs, KVADDR, vfsmount_buf, SIZE(vfsmount), "vfsmount buffer", FAULT_ON_ERROR); sb = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb)); if (superblock&& (sb == superblock)) { get_pathname(dentry, pathname, BUFSIZE, 1, vfs - OFFSET(mount_mnt)); found = TRUE; } } If we can continue to have get_pathname() receive a vfsmount pointer, it reduces the chance of introducing new bugs like the above, and future maintenance will be easier. It does reduce complication of the code. Still, places needing the judgement of struct mount's existing remain. I will modify the patch, and post later. About the function, OFFSET_OPTION(), thanks for your advice. Comments? Dave -- Crash-utility mailing list Crash-utility@redhat.com https://www.redhat.com/mailman/listinfo/crash-utility -- -- Regards Qiao Nuohan -- Crash-utility mailing list Crash-utility@redhat.com https://www.redhat.com/mailman/listinfo/crash-utility |
fix command vm/files -d/mount on new kernel
At 2012-3-13 11:45, qiaonuohan wrote:
At 2012-3-13 3:27, Dave Anderson wrote: ----- Original Message ----- At 2012-3-10 5:50, Dave Anderson wrote: It's failing in its call to get_pathname(). I haven't had a chance to You are right. I forgot to check every call to get_pathname. The new patch has fixed the problem of swap. Although the patch appears to work in the simple cases that I have tested, I have a few issues with it. First, the get_pathname() function prototype is -- and has always been -- this: void get_pathname(ulong dentry, char *pathname, int length, int full, ulong vfsmnt) where the "vfsmnt" argument has always been a struct vfsmount pointer. With your patch, prior to making get_pathname() calls, you typically make a VALID_STRUCT(mount) call first, and if true, you modify the vfsmnt argument to be a struct mount pointer. It would make more sense maintenance-wise, and would simplify the patch, if the get_pathname() "vfsmnt" argument would continue to be a struct vfsmount pointer. And at the top of get_pathname(), you could make the adjustments for when it is embedded inside a struct mount. For example, taking these patches to open_files_dump() and file_dump(): @@ -2226,12 +2299,16 @@ open_files_dump(ulong task, int flags, struct reference *ref) if (VALID_MEMBER(fs_struct_rootmnt)) { vfsmnt = ULONG(fs_struct_buf + OFFSET(fs_struct_rootmnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(root_dentry, root_pathname, BUFSIZE, 1, vfsmnt); } else if (use_path) { vfsmnt = ULONG(fs_struct_buf + OFFSET(fs_struct_root) + OFFSET(path_mnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(root_dentry, root_pathname, BUFSIZE, 1, vfsmnt); } else { @@ -2250,12 +2327,16 @@ open_files_dump(ulong task, int flags, struct reference *ref) if (VALID_MEMBER(fs_struct_pwdmnt)) { vfsmnt = ULONG(fs_struct_buf + OFFSET(fs_struct_pwdmnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(pwd_dentry, pwd_pathname, BUFSIZE, 1, vfsmnt); } else if (use_path) { vfsmnt = ULONG(fs_struct_buf + OFFSET(fs_struct_pwd) + OFFSET(path_mnt)); + if (VALID_STRUCT(mount)) + vfsmnt = vfsmnt - OFFSET(mount_mnt); get_pathname(pwd_dentry, pwd_pathname, BUFSIZE, 1, vfsmnt); @@ -2686,7 +2767,12 @@ file_dump(ulong file, ulong dentry, ulong inode, int fd, int flags) if (flags& DUMP_FULL_NAME) { if (VALID_MEMBER(file_f_vfsmnt)) { vfsmnt = get_root_vfsmount(file_buf); - get_pathname(dentry, pathname, BUFSIZE, 1, vfsmnt); + if (VALID_STRUCT(mount)) + get_pathname(dentry, pathname, BUFSIZE, 1, + vfsmnt - OFFSET(mount_mnt)); + else + get_pathname(dentry, pathname, BUFSIZE, 1, + vfsmnt); if (STRNEQ(pathname, "/pts/")&& STREQ(vfsmount_devname(vfsmnt, buf1, BUFSIZE), "devpts")) If the vfsmount-to-mount calculation were always done in get_pathname() itself, then the patches above would be unnecessary. The same is true for a few other parts of the patch. Did you consider doing it that way? And consider the following patched version of display_dentry_info() below. The two get_pathname() calls below would generate fatal errors on older kernels because OFFSET(mount_mnt) will be invalid: if (!found&& symbol_exists("pipe_mnt")) { get_symbol_data("pipe_mnt", sizeof(long),&vfs); if (VALID_STRUCT(mount)) readmem(vfs - OFFSET(mount_mnt), KVADDR, mount_buf, SIZE(mount), "mount buffer", FAULT_ON_ERROR); else readmem(vfs, KVADDR, vfsmount_buf, SIZE(vfsmount), "vfsmount buffer", FAULT_ON_ERROR); sb = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb)); if (superblock&& (sb == superblock)) { get_pathname(dentry, pathname, BUFSIZE, 1, vfs - OFFSET(mount_mnt)); found = TRUE; } } if (!found&& symbol_exists("sock_mnt")) { get_symbol_data("sock_mnt", sizeof(long),&vfs); if (VALID_STRUCT(mount)) readmem(vfs - OFFSET(mount_mnt), KVADDR, mount_buf, SIZE(mount), "mount buffer", FAULT_ON_ERROR); else readmem(vfs, KVADDR, vfsmount_buf, SIZE(vfsmount), "vfsmount buffer", FAULT_ON_ERROR); sb = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb)); if (superblock&& (sb == superblock)) { get_pathname(dentry, pathname, BUFSIZE, 1, vfs - OFFSET(mount_mnt)); found = TRUE; } } If we can continue to have get_pathname() receive a vfsmount pointer, it reduces the chance of introducing new bugs like the above, and future maintenance will be easier. It does reduce complication of the code. Still, places needing the judgement of struct mount's existing remain. I will modify the patch, and post later. About the function, OFFSET_OPTION(), thanks for your advice. The attachment is the modified patch. Comments? Dave -- Crash-utility mailing list Crash-utility@redhat.com https://www.redhat.com/mailman/listinfo/crash-utility -- -- Regards Qiao Nuohan diff --git a/defs.h b/defs.h index a942dbb..0124f5f 100755 --- a/defs.h +++ b/defs.h @@ -1281,6 +1281,11 @@ struct offset_table { /* stash of commonly-used offsets */ long vfsmount_mnt_list; long vfsmount_mnt_mountpoint; long vfsmount_mnt_parent; + long mount_mnt_parent; + long mount_mnt_mountpoint; + long mount_mnt_list; + long mount_mnt_devname; + long mount_mnt; long namespace_root; long namespace_list; long super_block_s_dirty; @@ -1694,6 +1699,7 @@ struct size_table { /* stash of commonly-used sizes */ long fs_struct; long file; long inode; + long mount; long vfsmount; long super_block; long irqdesc; diff --git a/filesys.c b/filesys.c index 55a4677..ddb5377 100755 --- a/filesys.c +++ b/filesys.c @@ -1298,7 +1298,7 @@ show_mounts(ulong one_vfsmount, int flags, struct task_context *namespace_contex char buf4[BUFSIZE]; ulong *dentry_list, *dp, *mntlist; ulong *vfsmnt; - char *vfsmount_buf, *super_block_buf; + char *vfsmount_buf, *super_block_buf, *mount_buf; ulong dentry, inode, inode_sb, mnt_parent; char *dentry_buf, *inode_buf; int cnt, i, m, files_header_printed; @@ -1336,9 +1336,10 @@ show_mounts(ulong one_vfsmount, int flags, struct task_context *namespace_contex devlen = strlen("DEVNAME"); for (m = 0, vfsmnt = mntlist; m < mount_cnt; m++, vfsmnt++) { - readmem(*vfsmnt + OFFSET(vfsmount_mnt_devname), - KVADDR, &devp, sizeof(void *), - "vfsmount mnt_devname", FAULT_ON_ERROR); + readmem(*vfsmnt + + OFFSET_OPTION(vfsmount_mnt_devname,mount_mnt_devna me), + KVADDR, &devp, sizeof(void *), + "[vfs]mount mnt_devname", FAULT_ON_ERROR); if (read_string(devp, buf1, BUFSIZE-1)) { if (strlen(buf1) > devlen) @@ -1366,23 +1367,41 @@ show_mounts(ulong one_vfsmount, int flags, struct task_context *namespace_contex &cnt); } - vfsmount_buf = GETBUF(SIZE(vfsmount)); + if (VALID_STRUCT(mount)) { + mount_buf = GETBUF(SIZE(mount)); + vfsmount_buf = mount_buf + OFFSET(mount_mnt); + } else { + mount_buf = NULL; + vfsmount_buf = GETBUF(SIZE(vfsmount)); + } super_block_buf = GETBUF(SIZE(super_block)); for (m = 0, vfsmnt = mntlist; m < mount_cnt; m++, vfsmnt++) { - readmem(*vfsmnt, KVADDR, vfsmount_buf, SIZE(vfsmount), - "vfsmount buffer", FAULT_ON_ERROR); - - devp = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_devname)); + if (VALID_STRUCT(mount)) { + readmem(*vfsmnt, KVADDR, mount_buf, SIZE(mount), + "mount buffer", FAULT_ON_ERROR); + devp = ULONG(mount_buf + OFFSET(mount_mnt_devname)); + } else { + readmem(*vfsmnt, KVADDR, vfsmount_buf, SIZE(vfsmount), + "vfsmount buffer", FAULT_ON_ERROR); + devp = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_devname)); + } if (VALID_MEMBER(vfsmount_mnt_dirname)) { dirp = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_dirname)); } else { - mnt_parent = ULONG(vfsmount_buf + - OFFSET(vfsmount_mnt_parent)); - dentry = ULONG(vfsmount_buf + - OFFSET(vfsmount_mnt_mountpoint)); + if (VALID_STRUCT(mount)) { + mnt_parent = ULONG(mount_buf + + OFFSET(mount_mnt_parent)); + dentry = ULONG(mount_buf + + OFFSET(mount_mnt_mountpoint)); + } else { + mnt_parent = ULONG(vfsmount_buf + + OFFSET(vfsmount_mnt_parent)); + dentry = ULONG(vfsmount_buf + + OFFSET(vfsmount_mnt_mountpoint)); + } } sbp = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb)); @@ -1419,7 +1438,8 @@ show_mounts(ulong one_vfsmount, int flags, struct task_context *namespace_contex else fprintf(fp, "%-10s ", "(unknown)"); } else { - get_pathname(dentry, buf1, BUFSIZE, 1, mnt_parent); + get_pathname(dentry, buf1, BUFSIZE, 1, VALID_STRUCT(mount) ? + mnt_parent + OFFSET(mount_mnt) : mnt_parent); fprintf(fp, "%-10s ", buf1); } @@ -1484,7 +1504,10 @@ show_mounts(ulong one_vfsmount, int flags, struct task_context *namespace_contex if (!one_vfsmount) FREEBUF(mntlist); - FREEBUF(vfsmount_buf); + if (VALID_STRUCT(mount)) + FREEBUF(mount_buf); + else + FREEBUF(vfsmount_buf); FREEBUF(super_block_buf); } @@ -1520,7 +1543,7 @@ get_mount_list(int *cntptr, struct task_context *namespace_context) RETURN_ON_ERROR|QUIET)) error(FATAL, "cannot determine mount list location! "); - ld->start = root + OFFSET(vfsmount_mnt_list); + ld->start = root + OFFSET_OPTION(vfsmount_mnt_list, mount_mnt_list); ld->end = mnt_ns + OFFSET(mnt_namespace_list); } else if (VALID_MEMBER(namespace_root)) { @@ -1538,14 +1561,16 @@ get_mount_list(int *cntptr, struct task_context *namespace_context) console("namespace: %lx => root: %lx ", namespace, root); - ld->start = root + OFFSET(vfsmount_mnt_list); + ld->start = root + OFFSET_OPTION(vfsmount_mnt_list, mount_mnt_list); ld->end = namespace + OFFSET(namespace_list); } else error(FATAL, "cannot determine mount list location! "); if (VALID_MEMBER(vfsmount_mnt_list)) ld->list_head_offset = OFFSET(vfsmount_mnt_list); - else + else if (VALID_STRUCT(mount)) + ld->list_head_offset = OFFSET(mount_mnt_list); + else ld->member_offset = OFFSET(vfsmount_mnt_next); hq_open(); @@ -1566,7 +1591,7 @@ static void display_dentry_info(ulong dentry) { int m, found; - char *dentry_buf, *inode_buf, *vfsmount_buf; + char *dentry_buf, *inode_buf, *vfsmount_buf, *mount_buf; ulong inode, superblock, sb, vfs; ulong *mntlist, *vfsmnt; char pathname[BUFSIZE]; @@ -1601,24 +1626,39 @@ display_dentry_info(ulong dentry) if (VALID_MEMBER(file_f_vfsmnt)) { mntlist = get_mount_list(&mount_cnt, pid_to_context(1)); - vfsmount_buf = GETBUF(SIZE(vfsmount)); + if (VALID_STRUCT(mount)) { + mount_buf = GETBUF(SIZE(mount)); + vfsmount_buf = mount_buf + OFFSET(mount_mnt); + } else { + mount_buf = NULL; + vfsmount_buf = GETBUF(SIZE(vfsmount)); + } for (m = found = 0, vfsmnt = mntlist; m < mount_cnt; m++, vfsmnt++) { - readmem(*vfsmnt, KVADDR, vfsmount_buf, SIZE(vfsmount), - "vfsmount buffer", FAULT_ON_ERROR); + if (VALID_STRUCT(mount)) + readmem(*vfsmnt, KVADDR, mount_buf, SIZE(mount), + "mount buffer", FAULT_ON_ERROR); + else + readmem(*vfsmnt, KVADDR, vfsmount_buf, SIZE(vfsmount), + "vfsmount buffer", FAULT_ON_ERROR); sb = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb)); if (superblock && (sb == superblock)) { - get_pathname(dentry, pathname, - BUFSIZE, 1, *vfsmnt); + get_pathname(dentry, pathname, BUFSIZE, 1, + VALID_STRUCT(mount) ? + *vfsmnt+OFFSET(mount_mnt) : *vfsmnt); found = TRUE; } } if (!found && symbol_exists("pipe_mnt")) { get_symbol_data("pipe_mnt", sizeof(long), &vfs); - readmem(vfs, KVADDR, vfsmount_buf, SIZE(vfsmount), - "vfsmount buffer", FAULT_ON_ERROR); + if (VALID_STRUCT(mount)) + readmem(vfs - OFFSET(mount_mnt), KVADDR, mount_buf, SIZE(mount), + "mount buffer", FAULT_ON_ERROR); + else + readmem(vfs, KVADDR, vfsmount_buf, SIZE(vfsmount), + "vfsmount buffer", FAULT_ON_ERROR); sb = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb)); if (superblock && (sb == superblock)) { get_pathname(dentry, pathname, BUFSIZE, 1, vfs); @@ -1627,8 +1667,12 @@ display_dentry_info(ulong dentry) } if (!found && symbol_exists("sock_mnt")) { get_symbol_data("sock_mnt", sizeof(long), &vfs); - readmem(vfs, KVADDR, vfsmount_buf, SIZE(vfsmount), - "vfsmount buffer", FAULT_ON_ERROR); + if (VALID_STRUCT(mount)) + readmem(vfs - OFFSET(mount_mnt), KVADDR, mount_buf, SIZE(mount), + "mount buffer", FAULT_ON_ERROR); + else + readmem(vfs, KVADDR, vfsmount_buf, SIZE(vfsmount), + "vfsmount buffer", FAULT_ON_ERROR); sb = ULONG(vfsmount_buf + OFFSET(vfsmount_mnt_sb)); if (superblock && (sb == superblock)) { get_pathname(dentry, pathname, BUFSIZE, 1, vfs); @@ -1642,7 +1686,10 @@ display_dentry_info(ulong dentry) if (mntlist) { FREEBUF(mntlist); - FREEBUF(vfsmount_buf); + if (VALID_STRUCT(mount)) + FREEBUF(mount_buf); + else + FREEBUF(vfsmount_buf); } nopath: @@ -1897,12 +1944,26 @@ vfs_init(void) MEMBER_OFFSET_INIT(vfsmount_mnt_next, "vfsmount", "mnt_next"); MEMBER_OFFSET_INIT(vfsmount_mnt_devname, "vfsmount", "mnt_devname"); + if (INVALID_MEMBER(vfsmount_mnt_devname)) { + 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_list, "vfsmount", "mnt_list"); + if (INVALID_MEMBER(vfsmount_mnt_devname)) { + MEMBER_OFFSET_INIT(mount_mnt_list, "mount", "mnt_list"); + } MEMBER_OFFSET_INIT(vfsmount_mnt_parent, "vfsmount", "mnt_parent"); + if (INVALID_MEMBER(vfsmount_mnt_devname)) { + MEMBER_OFFSET_INIT(mount_mnt_parent, "mount", "mnt_parent"); + } MEMBER_OFFSET_INIT(vfsmount_mnt_mountpoint, "vfsmount", "mnt_mountpoint"); + if (INVALID_MEMBER(vfsmount_mnt_devname)) { + MEMBER_OFFSET_INIT(mount_mnt_mountpoint, + "mount", "mnt_mountpoint"); + } + MEMBER_OFFSET_INIT(mount_mnt, "mount", "mnt"); MEMBER_OFFSET_INIT(namespace_root, "namespace", "root"); MEMBER_OFFSET_INIT(task_struct_nsproxy, "task_struct", "nsproxy"); if (VALID_MEMBER(namespace_root)) { @@ -1939,6 +2000,7 @@ vfs_init(void) STRUCT_SIZE_INIT(fdtable, "fdtable"); STRUCT_SIZE_INIT(file, "file"); STRUCT_SIZE_INIT(inode, "inode"); + STRUCT_SIZE_INIT(mount, "mount"); STRUCT_SIZE_INIT(vfsmount, "vfsmount"); STRUCT_SIZE_INIT(fs_struct, "fs_struct"); STRUCT_SIZE_INIT(super_block, "super_block"); @@ -2793,13 +2855,24 @@ get_pathname(ulong dentry, char *pathname, int length, int full, ulong vfsmnt) int d_name_len = 0; ulong d_name_name; ulong tmp_vfsmnt, mnt_parent; - char *dentry_buf, *vfsmnt_buf; + char *dentry_buf, *vfsmnt_buf, *mnt_buf; BZERO(buf, BUFSIZE); BZERO(tmpname, BUFSIZE); BZERO(pathname, length); - vfsmnt_buf = VALID_MEMBER(vfsmount_mnt_mountpoint) ? - GETBUF(SIZE(vfsmount)) : NULL; + if (VALID_STRUCT(mount)) { + if (VALID_MEMBER(mount_mnt_mountpoint)) { + mnt_buf = GETBUF(SIZE(mount)); + vfsmnt_buf = mnt_buf + OFFSET(mount_mnt); + } else { + mnt_buf = NULL; + vfsmnt_buf = NULL; + } + } else { + mnt_buf = NULL; + vfsmnt_buf = VALID_MEMBER(vfsmount_mnt_mountpoint) ? + GETBUF(SIZE(vfsmount)) : NULL; + } parent = dentry; tmp_vfsmnt = vfsmnt; @@ -2861,7 +2934,26 @@ get_pathname(ulong dentry, char *pathname, int length, int full, ulong vfsmnt) else tmp_vfsmnt = mnt_parent; } - } else { + } else if (VALID_STRUCT(mount)) { + if (tmp_vfsmnt) { + if (strncmp(pathname, "//", 2) == 0) + shift_string_left(pathname, 1); + readmem(tmp_vfsmnt - OFFSET(mount_mnt), + KVADDR, mnt_buf, + SIZE(mount), + "mount buffer", + FAULT_ON_ERROR); + parent = ULONG(mnt_buf + + OFFSET(mount_mnt_mountpoint)); + mnt_parent = ULONG(mnt_buf + + OFFSET(mount_mnt_parent)); + if ((tmp_vfsmnt - OFFSET(mount_mnt)) == mnt_parent) + break; + else + tmp_vfsmnt = mnt_parent + OFFSET(mount_mnt); + } + } + else { parent = ULONG(dentry_buf + OFFSET(dentry_d_covers)); } @@ -2869,7 +2961,9 @@ get_pathname(ulong dentry, char *pathname, int length, int full, ulong vfsmnt) } while (tmp_dentry != parent && parent); - if (vfsmnt_buf) + if (mnt_buf) + FREEBUF(mnt_buf); + else if (vfsmnt_buf) FREEBUF(vfsmnt_buf); } @@ -3901,10 +3995,17 @@ vfsmount_devname(ulong vfsmnt, char *buf, int maxlen) BZERO(buf, maxlen); - if (!readmem(vfsmnt + OFFSET(vfsmount_mnt_devname), - KVADDR, &devp, sizeof(void *), "vfsmount mnt_devname", - QUIET|RETURN_ON_ERROR)) - return buf; + if (VALID_STRUCT(mount)) { + if (!readmem(vfsmnt - OFFSET(mount_mnt) + OFFSET(mount_mnt_devname), + KVADDR, &devp, sizeof(void *), "mount mnt_devname", + QUIET|RETURN_ON_ERROR)) + return buf; + } else { + if (!readmem(vfsmnt + OFFSET(vfsmount_mnt_devname), + KVADDR, &devp, sizeof(void *), "vfsmount mnt_devname", + QUIET|RETURN_ON_ERROR)) + return buf; + } if (read_string(devp, buf, BUFSIZE-1)) return buf; @@ -3925,10 +4026,17 @@ get_root_vfsmount(char *file_buf) return vfsmnt; if (STREQ(buf, "udev")) { - if (!readmem(vfsmnt + OFFSET(vfsmount_mnt_parent), KVADDR, - &mnt_parent, sizeof(void *), "vfsmount mnt_parent", - QUIET|RETURN_ON_ERROR)) - return vfsmnt; + if (VALID_STRUCT(mount)) { + if (!readmem(vfsmnt - OFFSET(mount_mnt) + OFFSET(mount_mnt_parent), KVADDR, + &mnt_parent, sizeof(void *), "mount mnt_parent", + QUIET|RETURN_ON_ERROR)) + return vfsmnt; + } else { + if (!readmem(vfsmnt + OFFSET(vfsmount_mnt_parent), KVADDR, + &mnt_parent, sizeof(void *), "vfsmount mnt_parent", + QUIET|RETURN_ON_ERROR)) + return vfsmnt; + } if (!strlen(vfsmount_devname(mnt_parent, buf, BUFSIZE))) return vfsmnt; diff --git a/symbols.c b/symbols.c index f88c016..d141f1b 100755 --- a/symbols.c +++ b/symbols.c @@ -7934,6 +7934,16 @@ dump_offset_table(char *spec, ulong makestruct) OFFSET(vfsmount_mnt_mountpoint)); fprintf(fp, " vfsmount_mnt_parent: %ld ", OFFSET(vfsmount_mnt_parent)); + fprintf(fp, " mount_mnt_parent: %ld ", + OFFSET(mount_mnt_parent)); + fprintf(fp, " mount_mnt_mountpoint: %ld ", + OFFSET(mount_mnt_mountpoint)); + fprintf(fp, " mount_mnt_list: %ld ", + OFFSET(mount_mnt_list)); + fprintf(fp, " mount_mnt_devname: %ld ", + OFFSET(mount_mnt_devname)); + fprintf(fp, " mount_mnt: %ld ", + OFFSET(mount_mnt)); fprintf(fp, " namespace_root: %ld ", OFFSET(namespace_root)); fprintf(fp, " namespace_list: %ld ", @@ -8701,6 +8711,7 @@ dump_offset_table(char *spec, ulong makestruct) fprintf(fp, " file: %ld ", SIZE(file)); fprintf(fp, " inode: %ld ", SIZE(inode)); fprintf(fp, " vfsmount: %ld ", SIZE(vfsmount)); + fprintf(fp, " mount: %ld ", SIZE(mount)); fprintf(fp, " super_block: %ld ", SIZE(super_block)); fprintf(fp, " irqdesc: %ld ", SIZE(irqdesc)); -- Crash-utility mailing list Crash-utility@redhat.com https://www.redhat.com/mailman/listinfo/crash-utility |
| All times are GMT. The time now is 11:34 AM. |
VBulletin, Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.