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=commit...
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(a)in.ibm.com>
---
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));
_