[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