[Crash-utility] Re: [RFC] Patch for fixing 'files' command
Dave Anderson
anderson at redhat.com
Thu Dec 22 15:44:33 UTC 2005
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 at in.ibm.com>
> ---
>
> 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;
> _
More information about the Crash-utility
mailing list