[Crash-utility] [PATCH] crash: add dev_base_head support for net command

Eugene Teo eteo at redhat.com
Sun Mar 16 06:22:35 UTC 2008


Hi Dave,

I found that the net command in crash 4.0-6.1 does not work with Fedora
kernel 2.6.23.14-115.fc8. There was a rework on dev_base[1] to replace
the use of dev_base variable, and dev->next pointer with for_each_netdev
loop. This patch fixes this problem.

$ uname -rm
2.6.23.14-115.fc8 i686
$ sudo ./crash
[...]
crash> net
net: dev_base does not exist!

With the patch,

$ sudo ./crash
[...]
crash> net
NET_DEVICE  NAME   IP ADDRESS(ES)
 c0714480   lo     127.0.0.1
 f7031000   wmaster0 
 f7031800   wlan0  
 f775c000   eth0   a.b.c.d
 f6d3a000   redhat0 w.x.y.z

[1] linux-2.6 commit: 7562f876cd93800f2f8c89445f2a563590b24e09
    [NET]: Rework dev_base via list_head (v3)

Signed-off-by: Eugene Teo <eugeneteo at kernel.sg>

diff -uprN crash-4.0-6.1.default/defs.h crash-4.0-6.1/defs.h
--- crash-4.0-6.1.default/defs.h	2008-02-29 00:09:10.000000000 +0800
+++ crash-4.0-6.1/defs.h	2008-03-16 13:51:32.000000000 +0800
@@ -1234,6 +1234,7 @@ struct offset_table {                   
 	long net_device_type;
 	long net_device_addr_len;
 	long net_device_ip_ptr;
+	long net_device_dev_list;
 	long device_next;
 	long device_name;
 	long device_type;
diff -uprN crash-4.0-6.1.default/net.c crash-4.0-6.1/net.c
--- crash-4.0-6.1.default/net.c	2008-02-29 00:09:10.000000000 +0800
+++ crash-4.0-6.1/net.c	2008-03-16 14:01:39.000000000 +0800
@@ -65,6 +65,7 @@ struct devinfo {
 #define BYTES_IP_TUPLE	(BYTES_IP_ADDR + BYTES_PORT_NUM + 1)
 
 static void show_net_devices(void);
+static void show_net_devices_v2(void);
 static void print_neighbour_q(ulong, int);
 static void get_netdev_info(ulong, struct devinfo *);
 static void get_device_name(ulong, char *);
@@ -111,6 +112,7 @@ net_init(void)
 			"net_device", "addr_len");
 		net->dev_ip_ptr = MEMBER_OFFSET_INIT(net_device_ip_ptr,
 			"net_device", "ip_ptr");
+		MEMBER_OFFSET_INIT(net_device_dev_list, "net_device", "dev_list");
 		ARRAY_LENGTH_INIT(net->net_device_name_index,
 			net_device_name, "net_device.name", NULL, sizeof(char));
 		net->flags |= (NETDEV_INIT|STRUCT_NET_DEVICE);
@@ -355,6 +357,11 @@ show_net_devices(void)
 	long flen;
 	char buf[BUFSIZE];
 
+	if (symbol_exists("dev_base_head")) {
+		show_net_devices_v2();
+		return;
+	}
+
 	if (!symbol_exists("dev_base"))
 		error(FATAL, "dev_base does not exist!\n");
 
@@ -384,6 +391,58 @@ show_net_devices(void)
 	} while (next);
 }
 
+static void
+show_net_devices_v2(void)
+{
+	struct list_data list_data, *ld;
+	char *net_device_buf;
+	char buf[BUFSIZE];
+	ulong *ndevlist;
+	int ndevcnt, i;
+	long flen;
+
+	if (!net->netdevice) /* initialized in net_init() */
+		return;
+
+	flen = MAX(VADDR_PRLEN, strlen(net->netdevice));
+
+	fprintf(fp, "%s  NAME   IP ADDRESS(ES)\n",
+		mkstring(upper_case(net->netdevice, buf), 
+			flen, CENTER|LJUST, NULL));
+
+	net_device_buf = GETBUF(SIZE(net_device));
+
+	ld =  &list_data;
+	BZERO(ld, sizeof(struct list_data));
+	get_symbol_data("dev_base_head", sizeof(void *), &ld->start);
+	ld->end = symbol_value("dev_base_head");
+	ld->list_head_offset = OFFSET(net_device_dev_list);
+
+	hq_open();
+	ndevcnt = do_list(ld);
+	ndevlist = (ulong *)GETBUF(ndevcnt * sizeof(ulong));
+	ndevcnt = retrieve_list(ndevlist, ndevcnt);
+	hq_close();
+
+	for (i = 0; i < ndevcnt; ++i) {
+		readmem(ndevlist[i], KVADDR, net_device_buf,
+			SIZE(net_device), "net_device buffer",
+			FAULT_ON_ERROR);
+
+                fprintf(fp, "%s  ",
+			mkstring(buf, flen, CENTER|RJUST|LONG_HEX,
+			MKSTR(ndevlist[i])));
+
+		get_device_name(ndevlist[i], buf);
+		fprintf(fp, "%-6s ", buf);
+
+		get_device_address(ndevlist[i], buf);
+		fprintf(fp, "%s\n", buf);
+	}
+	
+	FREEBUF(ndevlist);
+	FREEBUF(net_device_buf);
+}
 
 /*
  * Perform the actual work of dumping the ARP table...




More information about the Crash-utility mailing list