On Thu, Dec 22, 2005 at 10:44:33AM -0500, Dave Anderson wrote: > > 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 Hi Dave, Thank you for all your suggestions. I have incorporated them and am sending along a revised version of the patch. Kindly review. I looked at the changelog of 2.6.14-rc1 and the fdtable seems to have been introduced then. ftp://ftp.kernel.org/pub/linux/kernel/v2.6/testing/ChangeLog-2.6.14-rc1 http://kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=badf16621c1f9d1ac753be056fce11b43d6e0be5 > > 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) Please correct me if I am wrong, but I don't think this would be possible to do in the vfs_init() while we are initializing these members in the offset table using MEMBER_OFFSET_INIT() and in the size table using STRUCT_SIZE_INIT(). So for this case alone I am using the THIS_KERNEL_VERSION(). But once the members have been initialized, VALID_MEMBER() is definitely a better way to check this. Thanks. > > 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. Had missed this...now done. Thanks. Thanks Rachita 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 ++++++++++++++++++++++++++++++++++++++++++++++---------------- symbols.c | 15 +++++++++++ 3 files changed, 82 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-23 16:08:20.888958472 +0530 +++ crash-4.0-2.17-rachita/filesys.c 2005-12-23 16:08:32.768152560 +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 (VALID_SIZE(fdtable)) + 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-23 16:08:42.453680136 +0530 +++ crash-4.0-2.17-rachita/defs.h 2005-12-23 16:09:01.024856888 +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; diff -puN symbols.c~crash-fix-files-command symbols.c --- crash-4.0-2.17/symbols.c~crash-fix-files-command 2005-12-23 16:09:18.903138976 +0530 +++ crash-4.0-2.17-rachita/symbols.c 2005-12-23 16:13:01.641277632 +0530 @@ -5976,6 +5976,18 @@ dump_offset_table(char *spec, ulong make fprintf(fp, " irq_cpustat_t___softirq_mask: %ld\n", OFFSET(irq_cpustat_t___softirq_mask)); + if (VALID_MEMBER(files_struct_fdt)) { + fprintf(fp, " files_struct_fdt: %ld\n", + OFFSET(files_struct_fdt)); + fprintf(fp, " fdtable_max_fds: %ld\n", + OFFSET(fdtable_max_fds)); + fprintf(fp, " fdtable_max_fdset: %ld\n", + OFFSET(fdtable_max_fdset)); + fprintf(fp, " fdtable_open_fds: %ld\n", + OFFSET(fdtable_open_fds)); + fprintf(fp, " fdtable_fd: %ld\n", + OFFSET(fdtable_fd)); + } else { fprintf(fp, " files_struct_max_fds: %ld\n", OFFSET(files_struct_max_fds)); fprintf(fp, " files_struct_max_fdset: %ld\n", @@ -5984,6 +5996,7 @@ dump_offset_table(char *spec, ulong make OFFSET(files_struct_open_fds)); fprintf(fp, " files_struct_fd: %ld\n", OFFSET(files_struct_fd)); + } fprintf(fp, " files_struct_open_fds_init: %ld\n", OFFSET(files_struct_open_fds_init)); fprintf(fp, " file_f_dentry: %ld\n", @@ -6525,6 +6538,8 @@ dump_offset_table(char *spec, ulong make fprintf(fp, " fs_struct: %ld\n", SIZE(fs_struct)); fprintf(fp, " files_struct: %ld\n", SIZE(files_struct)); + if (VALID_MEMBER(files_struct_fdt)) + fprintf(fp, " fdtable: %ld\n", SIZE(fdtable)); fprintf(fp, " file: %ld\n", SIZE(file)); fprintf(fp, " inode: %ld\n", SIZE(inode)); fprintf(fp, " vfsmount: %ld\n", SIZE(vfsmount)); _