Rachita Kothiyal wrote: > Hi Dave > > 'files' command in crash failed when analysing core files > generated by kdump for kernels later than 2.6.14. This is > because of the change in the 'files_struct' structure from > 2.6.14 kernel onwards. The following patch attempts to fix > this. Kindly review. > > This patch has been generated against crash-4.0-2.17. > > Thanks > Rachita > Hi Rachita, Nice work! When you say the patch "attempts" to fix this, I'm presuming that it *does* address the new files_struct and fdtable changes... ;-) A couple things... How confident are you that the change was introduced precisely during the changeover from 2.6.13 to 2.6.14? The reason I ask is that I have a leftover 2.6.13-era source tree -- although I have no idea where it came from -- and it includes the fdtable introduction. I just have a source tree labeled "2.6.13", and its Makefile shows this at the top: VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 13 EXTRAVERSION = -prep NAME=Affluent Albatross In any case, if there are any 2.6.13 era kernels with the new stuff in them, the use of THIS_KERNEL_VERSION() wouldn't be appropriate; instead it would be safer to use the existence of the new structure member, as in: if (VALID_MEMBER(files_struct_fdt) The other issue is minor -- whenever adding any new members to the offset_table, size_table or array_table, their values should be dumpable in the dump_offset_table() function in symbols.c, which is only accessible with the unadvertised "help -o" option, which is a behind-the-scenes-for-crash-utility-debugging-only option. But the "real" work you've done here is excellent and very much appreciated -- thanks again. Dave > > o Following changes in the 'files_struct' structure from > kernels 2.6.14 onwards, this patch attempts to fix the > broken files command. > > Signed-off-by: Rachita Kothiyal <rachita@xxxxxxxxxx> > --- > > defs.h | 6 ++++ > filesys.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++---------------- > 2 files changed, 67 insertions(+), 21 deletions(-) > > diff -puN filesys.c~crash-fix-files-command filesys.c > --- crash-4.0-2.17/filesys.c~crash-fix-files-command 2005-12-22 18:11:27.000000000 +0530 > +++ crash-4.0-2.17-rachita/filesys.c 2005-12-22 18:23:02.000000000 +0530 > @@ -1710,12 +1710,20 @@ vfs_init(void) > MEMBER_OFFSET_INIT(fs_struct_pwd, "fs_struct", "pwd"); > MEMBER_OFFSET_INIT(fs_struct_rootmnt, "fs_struct", "rootmnt"); > MEMBER_OFFSET_INIT(fs_struct_pwdmnt, "fs_struct", "pwdmnt"); > - MEMBER_OFFSET_INIT(files_struct_max_fds, "files_struct", "max_fds"); > - MEMBER_OFFSET_INIT(files_struct_max_fdset, "files_struct", "max_fdset"); > - MEMBER_OFFSET_INIT(files_struct_open_fds, "files_struct", "open_fds"); > MEMBER_OFFSET_INIT(files_struct_open_fds_init, > "files_struct", "open_fds_init"); > - MEMBER_OFFSET_INIT(files_struct_fd, "files_struct", "fd"); > + if (THIS_KERNEL_VERSION < LINUX(2,6,14)) { > + MEMBER_OFFSET_INIT(files_struct_max_fds, "files_struct", "max_fds"); > + MEMBER_OFFSET_INIT(files_struct_max_fdset, "files_struct", "max_fdset"); > + MEMBER_OFFSET_INIT(files_struct_open_fds, "files_struct", "open_fds"); > + MEMBER_OFFSET_INIT(files_struct_fd, "files_struct", "fd"); > + } else { > + MEMBER_OFFSET_INIT(files_struct_fdt, "files_struct", "fdt"); > + MEMBER_OFFSET_INIT(fdtable_max_fds, "fdtable", "max_fds"); > + MEMBER_OFFSET_INIT(fdtable_max_fdset, "fdtable", "max_fdset"); > + MEMBER_OFFSET_INIT(fdtable_open_fds, "fdtable", "open_fds"); > + MEMBER_OFFSET_INIT(fdtable_fd, "fdtable", "fd"); > + } > 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"); > @@ -1766,6 +1774,8 @@ vfs_init(void) > STRUCT_SIZE_INIT(umode_t, "umode_t"); > STRUCT_SIZE_INIT(dentry, "dentry"); > STRUCT_SIZE_INIT(files_struct, "files_struct"); > + if (THIS_KERNEL_VERSION >= LINUX(2,6,14)) > + STRUCT_SIZE_INIT(fdtable, "fdtable"); > STRUCT_SIZE_INIT(file, "file"); > STRUCT_SIZE_INIT(inode, "inode"); > STRUCT_SIZE_INIT(vfsmount, "vfsmount"); > @@ -2002,8 +2012,8 @@ void > open_files_dump(ulong task, int flags, struct reference *ref) > { > struct task_context *tc; > - ulong files_struct_addr; > - char *files_struct_buf; > + ulong files_struct_addr, fdtable_addr; > + char *files_struct_buf, *fdtable_buf = NULL; > ulong fs_struct_addr; > char *dentry_buf, *fs_struct_buf; > ulong root_dentry, pwd_dentry; > @@ -2031,6 +2041,8 @@ open_files_dump(ulong task, int flags, s > BZERO(root_pathname, BUFSIZE); > BZERO(pwd_pathname, BUFSIZE); > files_struct_buf = GETBUF(SIZE(files_struct)); > + if ( THIS_KERNEL_VERSION >= LINUX(2,6,14) ) > + fdtable_buf = GETBUF(SIZE(fdtable)); > fill_task_struct(task); > > sprintf(files_header, " FD%s%s%s%s%s%s%sTYPE%sPATH\n", > @@ -2111,24 +2123,41 @@ open_files_dump(ulong task, int flags, s > > files_struct_addr = ULONG(tt->task_struct + OFFSET(task_struct_files)); > > - if (files_struct_addr) { > - readmem(files_struct_addr, KVADDR, files_struct_buf, > - SIZE(files_struct), "files_struct buffer", > - FAULT_ON_ERROR); > - > - max_fdset = INT(files_struct_buf + > + if (files_struct_addr) { > + readmem(files_struct_addr, KVADDR, files_struct_buf, > + SIZE(files_struct), "files_struct buffer", > + FAULT_ON_ERROR); > + > + if (VALID_MEMBER(files_struct_max_fdset)) { > + max_fdset = INT(files_struct_buf + > OFFSET(files_struct_max_fdset)); > > - max_fds = INT(files_struct_buf + > - OFFSET(files_struct_max_fds)); > - } > + max_fds = INT(files_struct_buf + > + OFFSET(files_struct_max_fds)); > + } > + } > + > + if (VALID_MEMBER(files_struct_fdt)) { > + fdtable_addr = ULONG(files_struct_buf + OFFSET(files_struct_fdt)); > > - if (!files_struct_addr || max_fdset == 0 || max_fds == 0) { > + if (fdtable_addr) { > + readmem(fdtable_addr, KVADDR, fdtable_buf, SIZE(fdtable), "fdtable buffer", FAULT_ON_ERROR); > + > + max_fdset = INT(fdtable_buf + > + OFFSET(fdtable_max_fdset)); > + max_fds = INT(fdtable_buf + > + OFFSET(fdtable_max_fds)); > + } > + } > + > + if (!fdtable_addr || !files_struct_addr || max_fdset == 0 || max_fds == 0) { > if (ref) { > if (ref->cmdflags & FILES_REF_FOUND) > fprintf(fp, "\n"); > } else > fprintf(fp, "No open files\n"); > + if (fdtable_buf) > + FREEBUF(fdtable_buf); > FREEBUF(files_struct_buf); > return; > } > @@ -2150,8 +2179,12 @@ open_files_dump(ulong task, int flags, s > } > } > > - open_fds_addr = ULONG(files_struct_buf + > - OFFSET(files_struct_open_fds)); > + if (VALID_MEMBER(fdtable_open_fds)) > + open_fds_addr = ULONG(fdtable_buf + > + OFFSET(fdtable_open_fds)); > + else > + open_fds_addr = ULONG(files_struct_buf + > + OFFSET(files_struct_open_fds)); > > if (open_fds_addr) { > if (VALID_MEMBER(files_struct_open_fds_init) && > @@ -2161,16 +2194,21 @@ open_files_dump(ulong task, int flags, s > OFFSET(files_struct_open_fds_init), > &open_fds, sizeof(fd_set)); > else > - readmem(open_fds_addr, KVADDR, &open_fds, > - sizeof(fd_set), "files_struct open_fds", > + readmem(open_fds_addr, KVADDR, &open_fds, > + sizeof(fd_set), "fdtable open_fds", > FAULT_ON_ERROR); > } > > - fd = ULONG(files_struct_buf + OFFSET(files_struct_fd)); > + if (VALID_MEMBER(fdtable_fd)) > + fd = ULONG(fdtable_buf + OFFSET(fdtable_fd)); > + else > + fd = ULONG(files_struct_buf + OFFSET(files_struct_fd)); > > if (!open_fds_addr || !fd) { > if (ref && (ref->cmdflags & FILES_REF_FOUND)) > fprintf(fp, "\n"); > + if (fdtable_buf) > + FREEBUF(fdtable_buf); > FREEBUF(files_struct_buf); > return; > } > @@ -2224,6 +2262,8 @@ open_files_dump(ulong task, int flags, s > if (ref && (ref->cmdflags & FILES_REF_FOUND)) > fprintf(fp, "\n"); > > + if (fdtable_buf) > + FREEBUF(fdtable_buf); > FREEBUF(files_struct_buf); > } > > diff -puN defs.h~crash-fix-files-command defs.h > --- crash-4.0-2.17/defs.h~crash-fix-files-command 2005-12-22 18:24:02.000000000 +0530 > +++ crash-4.0-2.17-rachita/defs.h 2005-12-22 18:24:44.000000000 +0530 > @@ -980,6 +980,11 @@ struct offset_table { > long hw_interrupt_type_set_affinity; > long irq_cpustat_t___softirq_active; > long irq_cpustat_t___softirq_mask; > + long fdtable_max_fds; > + long fdtable_max_fdset; > + long fdtable_open_fds; > + long fdtable_fd; > + long files_struct_fdt; > long files_struct_max_fds; > long files_struct_max_fdset; > long files_struct_open_fds; > @@ -1253,6 +1258,7 @@ struct size_table { /* stash of > long umode_t; > long dentry; > long files_struct; > + long fdtable; > long fs_struct; > long file; > long inode; > _