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
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(a)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;
_