[Crash-utility] Re: [RFC] Patch for fixing 'files' command: TAKE 2

Rachita Kothiyal rachita at in.ibm.com
Fri Dec 23 12:14:54 UTC 2005


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 at 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)); 
_




More information about the Crash-utility mailing list