Hi Dave
Following changes in the 2.6.14 kernel in the files_struct,
the 'net' command was broken. The following patch fixes it.
I have done basic testing on kernels before and after 2.6.14
to ensure that backward compatibility is maintained.
Kindly review and provide your comments.
Thanks
Rachita
o From 2.6.14 kernel onwards, there were changes introduced
in the files_struct. This patch accomodates those kernel
changes in crash to keep the 'net' command working.
Signed-off-by: Rachita Kothiyal <rachita(a)in.ibm.com>
---
net.c | 57 ++++++++++++++++++++++++++++++++++++++-------------------
1 files changed, 38 insertions(+), 19 deletions(-)
diff -puN net.c~fix-net-command net.c
--- crash-4.0-2.23/net.c~fix-net-command 2006-04-17 19:16:18.000000000 +0530
+++ crash-4.0-2.23-rachita/net.c 2006-04-17 20:41:16.000000000 +0530
@@ -1082,7 +1082,7 @@ dump_sockets(ulong flag, struct referenc
void
dump_sockets_workhorse(ulong task, ulong flag, struct reference *ref)
{
- ulong files_struct_addr = 0;
+ ulong files_struct_addr = 0, fdtable_addr = 0;
int max_fdset = 0;
int max_fds = 0;
ulong open_fds_addr = 0;
@@ -1114,32 +1114,51 @@ dump_sockets_workhorse(ulong task, ulong
sizeof(void *), "task files contents", FAULT_ON_ERROR);
if (files_struct_addr) {
- readmem(files_struct_addr + OFFSET(files_struct_max_fdset),
- KVADDR, &max_fdset, sizeof(int),
- "files_struct max_fdset", FAULT_ON_ERROR);
-
- readmem(files_struct_addr + OFFSET(files_struct_max_fds),
- KVADDR, &max_fds, sizeof(int), "files_struct
max_fds",
- FAULT_ON_ERROR);
- }
+ if (VALID_MEMBER(files_struct_max_fdset)) {
+ readmem(files_struct_addr + OFFSET(files_struct_max_fdset),
+ KVADDR, &max_fdset, sizeof(int),
+ "files_struct max_fdset", FAULT_ON_ERROR);
+ readmem(files_struct_addr + OFFSET(files_struct_max_fds),
+ KVADDR, &max_fds, sizeof(int), "files_struct max_fds",
+ FAULT_ON_ERROR);
+ }
+ else if (VALID_MEMBER(files_struct_fdt)) {
+ readmem(files_struct_addr + OFFSET(files_struct_fdt), KVADDR,
+ &fdtable_addr, sizeof(void *), "fdtable buffer",
+ FAULT_ON_ERROR);
+ readmem(fdtable_addr + OFFSET(fdtable_max_fdset),
+ KVADDR, &max_fdset, sizeof(int),
+ "fdtable_struct max_fdset", FAULT_ON_ERROR);
+ readmem(fdtable_addr + OFFSET(fdtable_max_fds),
+ KVADDR, &max_fds, sizeof(int), "fdtable_struct
max_fds",
+ FAULT_ON_ERROR);
+ }
+ }
- if (!files_struct_addr || (max_fdset == 0) || (max_fds == 0)) {
+ if ((VALID_MEMBER(files_struct_fdt) && !fdtable_addr) ||
+ !files_struct_addr || (max_fdset == 0) || (max_fds == 0)) {
if (!NET_REFERENCE_CHECK(ref))
fprintf(fp, "No open sockets.\n");
return;
}
- readmem(files_struct_addr + OFFSET(files_struct_open_fds), KVADDR,
- &open_fds_addr, sizeof(void *), "files_struct open_fds addr",
- FAULT_ON_ERROR);
+ if (VALID_MEMBER(fdtable_open_fds)){
+ readmem(fdtable_addr + OFFSET(fdtable_open_fds), KVADDR,
+ &open_fds_addr, sizeof(void *), "files_struct open_fds addr",
+ FAULT_ON_ERROR);
+ readmem(fdtable_addr + OFFSET(fdtable_fd), KVADDR, &fd,
+ sizeof(void *), "files_struct fd addr", FAULT_ON_ERROR);
+ } else {
+ readmem(files_struct_addr + OFFSET(files_struct_open_fds), KVADDR,
+ &open_fds_addr, sizeof(void *), "files_struct open_fds
addr",
+ FAULT_ON_ERROR);
+ readmem(files_struct_addr + OFFSET(files_struct_fd), KVADDR, &fd,
+ sizeof(void *), "files_struct fd addr", FAULT_ON_ERROR);
+ }
if (open_fds_addr)
- readmem(open_fds_addr, KVADDR, &open_fds, sizeof(fd_set),
- "files_struct open_fds", FAULT_ON_ERROR);
-
- readmem(files_struct_addr + OFFSET(files_struct_fd), KVADDR, &fd,
- sizeof(void *), "files_struct fd addr", FAULT_ON_ERROR);
-
+ readmem(open_fds_addr, KVADDR, &open_fds, sizeof(fd_set),
+ "files_struct open_fds", FAULT_ON_ERROR);
if (!open_fds_addr || !fd) {
if (!NET_REFERENCE_CHECK(ref))
fprintf(fp, "No open sockets.\n");
_