linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH][RFC] Netconsole debugging tool for 2.6
@ 2003-08-11  8:55 Matt Mackall
  2003-08-26 20:57 ` Peter Osterlund
  2003-08-28 12:38 ` Steffen Klassert
  0 siblings, 2 replies; 9+ messages in thread
From: Matt Mackall @ 2003-08-11  8:55 UTC (permalink / raw)
  To: linux-kernel

Because my development box makes the room it's in uncomfortably warm,
I've decided to take a stab at resurrecting Ingo's netconsole patch.

For those who missed it the first time around (for 2.4.10), this
module is a "serial console over networks" which lets you catch kernel
messages, oopses and so on that can't be caught by syslog.

Since I thought the biggest problem with the first version was
configuration, I went ahead and wrote some reasonable option parsing
and made it also work as built-in so you can now boot with:

  linux netconsole=2525@10.0.0.1/eth1,9353@10.0.0.2/12:34:56:78:9a:bc

    or just

  linux netconsole=@10.0.0.1/,@10.0.0.2/

I've also added support for a third NIC (TLAN). Accepting patches for
other cards (only about 10 lines of code each).

Issues:
 Probably better ways to handle device locking these days
 SMP-safe? 
 Would like to get logging up much earlier in the boot process
 Need support for more cards

diff -urN -X dontdiff orig/Documentation/networking/netlogging.txt work/Documentation/networking/netlogging.txt
--- orig/Documentation/networking/netlogging.txt	1969-12-31 18:00:00.000000000 -0600
+++ work/Documentation/networking/netlogging.txt	2003-08-11 02:55:56.000000000 -0500
@@ -0,0 +1,54 @@
+
+started by Ingo Molnar <mingo@redhat.com>, 2001.09.17
+2.6 port by Matt Mackall <mpm@selenic.com>, 2003.08.11
+
+This module logs kernel printk messages over UDP allowing debugging of
+problem where disk logging fails and serial consoles are impractical.
+
+It can be used either built-in or as a module. It takes a string
+configuration parameter "netconsole" in the following format:
+
+ netconsole=[src-port]@[src-ip]/[<dev>],[tgt-port]@<tgt-ip>/[tgt-macaddr]
+
+   where
+        src-port      source for UDP packets (defaults to 6666)
+        src-ip        source IP to use (interface address)
+        dev           network interface (eth0)
+        tgt-port      port for logging agent (6666)
+        tgt-ip        IP address for logging agent
+        tgt-macaddr   ethernet MAC address for logging agent (broadcast)
+ 
+Examples:
+
+ linux netconsole=@10.0.0.1/eth1,9353@10.0.0.2/12:34:56:78:9a:bc
+
+  or
+
+ insmod netconsole netconsole=@/,@10.0.0.2/
+
+If the module is loaded then all kernel messages are sent to the
+target host via UDP packets. The remote host should run the
+client-side 'netconsole' daemon to display & log the messages.
+Alternately, netcat can be used in a pinch.
+
+WARNING: the default target ethernet setting uses the broadcast
+ethernet address to send packets, which can cause increased load on
+other systems on the same ethernet segment.
+
+NOTE: the network device (eth0 in the above case) can run any kind
+of other network traffic, netconsole is not intrusive. Netconsole
+might cause slight delays in other traffic if the volume of kernel
+messages is high, but should have no other impact.
+
+Netconsole was designed to be as instantaneous as possible, to
+enable the logging of even the most critical kernel bugs. It works
+from IRQ contexts as well, and does not enable interrupts while
+sending packets. Due to these unique needs, configuration can not
+be more automatic, and some fundamental limitations will remain:
+only IP networks, UDP packets and ethernet devices are supported.
+
+Currently supported network drivers:
+
+ eepro100
+ tulip
+ tlan
diff -urN -X dontdiff orig/drivers/net/Kconfig work/drivers/net/Kconfig
--- orig/drivers/net/Kconfig	2003-08-10 18:13:47.000000000 -0500
+++ work/drivers/net/Kconfig	2003-08-10 18:29:48.000000000 -0500
@@ -2711,3 +2711,11 @@
 source "drivers/atm/Kconfig"
 
 source "drivers/s390/net/Kconfig"
+
+config NETCONSOLE
+	tristate "Network console logging support"
+	depends on NETDEVICES
+	---help---
+	  If you want to log kernel messages over the network, then say
+	  "M" here. See Documentation/networking/netlogging.txt for details.
+
diff -urN -X dontdiff orig/drivers/net/Makefile work/drivers/net/Makefile
--- orig/drivers/net/Makefile	2003-08-01 21:44:13.000000000 -0500
+++ work/drivers/net/Makefile	2003-08-10 18:21:38.000000000 -0500
@@ -56,6 +56,8 @@
 obj-$(CONFIG_VIA_RHINE) += via-rhine.o mii.o
 obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o mii.o
 
+obj-$(CONFIG_NETCONSOLE) += netconsole.o
+
 #
 # end link order section
 #
diff -urN -X dontdiff orig/drivers/net/eepro100.c work/drivers/net/eepro100.c
--- orig/drivers/net/eepro100.c	2003-08-10 18:13:47.000000000 -0500
+++ work/drivers/net/eepro100.c	2003-08-10 18:22:50.000000000 -0500
@@ -543,6 +543,7 @@
 static int speedo_rx(struct net_device *dev);
 static void speedo_tx_buffer_gc(struct net_device *dev);
 static irqreturn_t speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
+static void poll_speedo (struct net_device *dev);
 static int speedo_close(struct net_device *dev);
 static struct net_device_stats *speedo_get_stats(struct net_device *dev);
 static int speedo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
@@ -885,6 +886,9 @@
 	dev->get_stats = &speedo_get_stats;
 	dev->set_multicast_list = &set_rx_mode;
 	dev->do_ioctl = &speedo_ioctl;
+#ifdef HAVE_POLL_CONTROLLER
+	dev->poll_controller = &poll_speedo;
+#endif
 
 	if (register_netdevice(dev))
 		goto err_free_unlock;
@@ -1675,6 +1679,23 @@
 	return IRQ_RETVAL(handled);
 }
 
+#ifdef HAVE_POLL_CONTROLLER
+
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+
+static void poll_speedo (struct net_device *dev)
+{
+	disable_irq(dev->irq);
+	speedo_interrupt (dev->irq, dev, NULL);
+	enable_irq(dev->irq);
+}
+
+#endif
+
 static inline struct RxFD *speedo_rx_alloc(struct net_device *dev, int entry)
 {
 	struct speedo_private *sp = (struct speedo_private *)dev->priv;
diff -urN -X dontdiff orig/drivers/net/netconsole.c work/drivers/net/netconsole.c
--- orig/drivers/net/netconsole.c	1969-12-31 18:00:00.000000000 -0600
+++ work/drivers/net/netconsole.c	2003-08-11 03:09:12.000000000 -0500
@@ -0,0 +1,457 @@
+/*
+ *  linux/drivers/net/netconsole.c
+ *
+ *  Copyright (C) 2001  Ingo Molnar <mingo@redhat.com>
+ *
+ *  This file contains the implementation of an IRQ-safe, crash-safe
+ *  kernel console implementation that outputs kernel messages to the
+ *  network.
+ *
+ * Modification history:
+ *
+ * 2001-09-17    started by Ingo Molnar.
+ * 2003-08-11    2.6 port by Matt Mackall
+ *               simplified options
+ *               added TLAN
+ *               works non-modular
+ */
+
+/****************************************************************
+ *      This program is free software; you can redistribute it and/or modify
+ *      it under the terms of the GNU General Public License as published by
+ *      the Free Software Foundation; either version 2, or (at your option)
+ *      any later version.
+ *
+ *      This program is distributed in the hope that it will be useful,
+ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *      GNU General Public License for more details.
+ *
+ *      You should have received a copy of the GNU General Public License
+ *      along with this program; if not, write to the Free Software
+ *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ****************************************************************/
+
+#include <net/tcp.h>
+#include <net/udp.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <asm/unaligned.h>
+#include <linux/console.h>
+#include <linux/smp_lock.h>
+#include <linux/netdevice.h>
+#include <linux/tty_driver.h>
+#include <linux/etherdevice.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/string.h>
+#include <linux/inetdevice.h>
+#include <linux/delay.h>
+
+static struct net_device *netconsole_dev;
+static u16 source_port=6666, target_port=6666;
+static u32 source_ip, target_ip;
+static unsigned char daddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff} ;
+
+#define NETCONSOLE_VERSION 0x01
+#define HEADER_LEN 5
+
+#define MAX_UDP_CHUNK 1460
+#define MAX_PRINT_CHUNK (MAX_UDP_CHUNK-HEADER_LEN)
+
+/*
+ * We maintain a small pool of fully-sized skbs,
+ * to make sure the message gets out even in
+ * extreme OOM situations.
+ */
+#define MAX_NETCONSOLE_SKBS 32
+
+static spinlock_t netconsole_lock = SPIN_LOCK_UNLOCKED;
+static int nr_netconsole_skbs;
+static struct sk_buff *netconsole_skbs;
+
+#define MAX_SKB_SIZE \
+		(MAX_UDP_CHUNK + sizeof(struct udphdr) + \
+				sizeof(struct iphdr) + sizeof(struct ethhdr))
+
+static void __refill_netconsole_skbs(void)
+{
+	struct sk_buff *skb;
+	unsigned long flags;
+
+	spin_lock_irqsave(&netconsole_lock, flags);
+	while (nr_netconsole_skbs < MAX_NETCONSOLE_SKBS) {
+		skb = alloc_skb(MAX_SKB_SIZE, GFP_ATOMIC);
+		if (!skb)
+			break;
+		if (netconsole_skbs)
+			skb->next = netconsole_skbs;
+		else
+			skb->next = NULL;
+		netconsole_skbs = skb;
+		nr_netconsole_skbs++;
+	}
+	spin_unlock_irqrestore(&netconsole_lock, flags);
+}
+
+static struct sk_buff * get_netconsole_skb(void)
+{
+	struct sk_buff *skb;
+
+	unsigned long flags;
+
+	spin_lock_irqsave(&netconsole_lock, flags);
+	skb = netconsole_skbs;
+	if (skb)
+		netconsole_skbs = skb->next;
+	skb->next = NULL;
+	nr_netconsole_skbs--;
+	spin_unlock_irqrestore(&netconsole_lock, flags);
+
+	return skb;
+}
+
+static spinlock_t sequence_lock = SPIN_LOCK_UNLOCKED;
+static unsigned int offset;
+
+static void send_netconsole_skb(struct net_device *dev, const char *msg, unsigned int msg_len)
+{
+	int total_len, eth_len, ip_len, udp_len;
+	unsigned long flags;
+	struct sk_buff *skb;
+	struct udphdr *udph;
+	struct iphdr *iph;
+	struct ethhdr *eth;
+
+	udp_len = msg_len + HEADER_LEN + sizeof(*udph);
+	ip_len = eth_len = udp_len + sizeof(*iph);
+	total_len = eth_len + ETH_HLEN;
+
+	if (nr_netconsole_skbs < MAX_NETCONSOLE_SKBS)
+		__refill_netconsole_skbs();
+
+	skb = alloc_skb(total_len, GFP_ATOMIC);
+	if (!skb) {
+		skb = get_netconsole_skb();
+		if (!skb)
+			/* tough! */
+			return;
+	}
+
+	atomic_set(&skb->users, 1);
+	skb_reserve(skb, total_len - msg_len - HEADER_LEN);
+	skb->data[0] = NETCONSOLE_VERSION;
+
+	spin_lock_irqsave(&sequence_lock, flags);
+	put_unaligned(htonl(offset), (u32 *) (skb->data + 1));
+	offset += msg_len;
+	spin_unlock_irqrestore(&sequence_lock, flags);
+
+	memcpy(skb->data + HEADER_LEN, msg, msg_len);
+	skb->len += msg_len + HEADER_LEN;
+
+	udph = (struct udphdr *) skb_push(skb, sizeof(*udph));
+	udph->source = source_port;
+	udph->dest = target_port;
+	udph->len = htons(udp_len);
+	udph->check = 0;
+
+	iph = (struct iphdr *)skb_push(skb, sizeof(*iph));
+
+	iph->version  = 4;
+	iph->ihl      = 5;
+	iph->tos      = 0;
+        iph->tot_len  = htons(ip_len);
+	iph->id       = 0;
+	iph->frag_off = 0;
+	iph->ttl      = 64;
+        iph->protocol = IPPROTO_UDP;
+	iph->check    = 0;
+        iph->saddr    = source_ip;
+        iph->daddr    = target_ip;
+	iph->check    = ip_fast_csum((unsigned char *)iph, iph->ihl);
+
+	eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
+
+	eth->h_proto = htons(ETH_P_IP);
+	memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
+	memcpy(eth->h_dest, daddr, dev->addr_len);
+
+repeat:
+	spin_lock(&dev->xmit_lock);
+	dev->xmit_lock_owner = smp_processor_id();
+
+	if (netif_queue_stopped(dev)) {
+		dev->xmit_lock_owner = -1;
+		spin_unlock(&dev->xmit_lock);
+
+		dev->poll_controller(dev);
+		goto repeat;
+	}
+
+	dev->hard_start_xmit(skb, dev);
+
+	dev->xmit_lock_owner = -1;
+	spin_unlock(&dev->xmit_lock);
+}
+
+static void write_netconsole_msg(struct console *con, const char *msg, unsigned int msg_len)
+{
+	int len, left;
+	struct net_device *dev;
+
+	dev = netconsole_dev;
+	if (!dev)
+		return;
+
+	if (dev->poll_controller && netif_running(dev)) {
+		unsigned long flags;
+
+		local_irq_save(flags);
+		left = msg_len;
+repeat:
+		if (left > MAX_PRINT_CHUNK)
+			len = MAX_PRINT_CHUNK;
+		else
+			len = left;
+		send_netconsole_skb(dev, msg, len);
+		msg += len;
+		left -= len;
+		if (left)
+			goto repeat;
+		local_irq_restore(flags);
+	}
+}
+
+static char dev_name[16]="eth0";
+static char config[256];
+module_param_string(netconsole, config, 256, 0);
+MODULE_PARM_DESC(netconsole, " netconsole=[src-port]@[src-ip]/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]\n");
+
+static struct console netconsole =
+	 { flags: CON_ENABLED, write: write_netconsole_msg };
+
+static int option_setup(char *opt)
+{
+	char *cur=opt, *delim;
+	int a,b,c,d;
+
+	printk(KERN_INFO "netconsole options: \"%s\"\n", opt);
+
+	if(*cur != '@') {
+		/* src port */
+		if ((delim = strchr(cur, '@')) == NULL)
+			goto parse_failed;
+		*delim=0;
+		source_port=simple_strtol(cur, 0, 10);
+		cur=delim;
+	}
+	cur++;
+	printk(KERN_INFO "netconsole: source port %d\n", source_port);
+
+	if(*cur != '/') {
+		/* src ip */
+		if ((delim = strchr(cur, '.')) == NULL)
+			goto parse_failed;
+		*delim=0;
+		a=simple_strtol(cur, 0, 10);
+		cur=delim+1;
+		if ((delim = strchr(cur, '.')) == NULL)
+			goto parse_failed;
+		*delim=0;
+		b=simple_strtol(cur, 0, 10);
+		cur=delim+1;
+		if ((delim = strchr(cur, '.')) == NULL)
+			goto parse_failed;
+		*delim=0;
+		c=simple_strtol(cur, 0, 10);
+		cur=delim+1;
+		if ((delim = strchr(cur, '/')) == NULL)
+			goto parse_failed;
+		*delim=0;
+		d=simple_strtol(cur, 0, 10);
+		cur=delim;
+		
+		source_ip=(a<<24)+(b<<16)+(c<<8)+d;
+#define IP(x) ((unsigned char *)&source_ip)[x]
+		printk(KERN_INFO "netconsole: source IP %u.%u.%u.%u\n",
+		       IP(3), IP(2), IP(1), IP(0));
+#undef IP
+	}
+	cur++;
+
+	if ( *cur != ',') {
+		/* parse out dev name */
+		if ((delim = strchr(cur, ',')) == NULL)
+			goto parse_failed;
+		*delim=0;
+		strlcpy(dev_name, cur, sizeof(dev_name));
+		cur=delim;
+	}
+	cur++;
+
+	printk(KERN_INFO "netconsole: interface %s\n", dev_name);
+
+	if ( *cur != '@' ) {
+		/* dst port */
+		if ((delim = strchr(cur, '@')) == NULL)
+			goto parse_failed;
+		*delim=0;
+		target_port=simple_strtol(cur, 0, 10);
+		cur=delim;
+	}
+	cur++;
+	printk(KERN_INFO "netconsole: target port %d\n", target_port);
+
+	/* dst ip */
+	if ((delim = strchr(cur, '.')) == NULL)
+		goto parse_failed;
+	*delim=0;
+	a=simple_strtol(cur, 0, 10);
+	cur=delim+1;
+	if ((delim = strchr(cur, '.')) == NULL)
+		goto parse_failed;
+	*delim=0;
+	b=simple_strtol(cur, 0, 10);
+	cur=delim+1;
+	if ((delim = strchr(cur, '.')) == NULL)
+		goto parse_failed;
+	*delim=0;
+	c=simple_strtol(cur, 0, 10);
+	cur=delim+1;
+	if ((delim = strchr(cur, '/')) == NULL)
+		goto parse_failed;
+	*delim=0;
+	d=simple_strtol(cur, 0, 10);
+	cur=delim+1;
+
+	target_ip=(a<<24)+(b<<16)+(c<<8)+d;
+
+#define IP(x) ((unsigned char *)&target_ip)[x]
+		printk(KERN_INFO "netconsole: target IP %u.%u.%u.%u\n",
+		       IP(3), IP(2), IP(1), IP(0));
+#undef IP
+
+	if( *cur != 0 )
+	{
+		/* MAC address */
+		if ((delim = strchr(cur, ':')) == NULL)
+			goto parse_failed;
+		*delim=0;
+		daddr[0]=simple_strtol(cur, 0, 16);
+		cur=delim+1;
+		if ((delim = strchr(cur, ':')) == NULL)
+			goto parse_failed;
+		*delim=0;
+		daddr[1]=simple_strtol(cur, 0, 16);
+		cur=delim+1;
+		if ((delim = strchr(cur, ':')) == NULL)
+			goto parse_failed;
+		*delim=0;
+		daddr[2]=simple_strtol(cur, 0, 16);
+		cur=delim+1;
+		if ((delim = strchr(cur, ':')) == NULL)
+			goto parse_failed;
+		*delim=0;
+		daddr[3]=simple_strtol(cur, 0, 16);
+		cur=delim+1;
+		if ((delim = strchr(cur, ':')) == NULL)
+			goto parse_failed;
+		*delim=0;
+		daddr[4]=simple_strtol(cur, 0, 16);
+		cur=delim+1;
+		daddr[5]=simple_strtol(cur, 0, 16);
+	}
+
+	printk(KERN_INFO "netconsole: target ethernet address "
+	       "%02x:%02x:%02x:%02x:%02x:%02x\n", 
+	       daddr[0], daddr[1], daddr[2], daddr[3], daddr[4], daddr[5]);
+
+	return 0;
+
+ parse_failed:
+	printk(KERN_INFO "netconsole: couldn't parse config at %s!\n",cur);
+	return -1;
+}
+
+__setup("netconsole=", option_setup);
+
+static int init_netconsole(void)
+{
+	struct net_device *ndev = NULL;
+	struct in_device *in_dev;
+	int ret;
+
+	if(strlen(config)) 
+	{
+		ret=option_setup(config);
+		if(ret!=0)
+			return ret;
+	}
+
+	// this will be valid once the device goes up.
+	if (*dev_name != 0)
+		ndev = dev_get_by_name(dev_name);
+	if (!ndev) {
+		printk(KERN_ERR "netconsole: %s doesn't exist, aborting.\n", 
+		       dev_name);
+		return -1;
+	}
+	if (!ndev->poll_controller) {
+		printk(KERN_ERR "netconsole: %s's network driver does not"
+		       " implement netlogging yet, aborting.\n", dev_name);
+		return -1;
+	}
+        in_dev = in_dev_get(ndev);
+	if (!in_dev) {
+		printk(KERN_ERR "netconsole: network device %s is not an" 
+		       " IP protocol device, winging it.\n", dev_name);
+	}
+
+	if (!source_ip) {
+		source_ip = ntohl(in_dev->ifa_list->ifa_local);
+
+		if(!source_ip) {
+			printk(KERN_ERR "netconsole: network device %s has no"
+			       " local address, aborting.\n", dev_name);
+			return -1;
+		}
+
+#define IP(x) ((unsigned char *)&source_ip)[x]
+		printk(KERN_INFO "netconsole: source IP %u.%u.%u.%u\n",
+		       IP(3), IP(2), IP(1), IP(0));
+#undef IP
+	}
+
+	source_ip = htonl(source_ip);
+	source_port = htons(source_port);
+	target_ip = htonl(target_ip);
+	target_port = htons(target_port);
+
+	netconsole_dev = ndev;
+#define STARTUP_MSG "[...network console startup...]\n"
+	write_netconsole_msg(NULL, STARTUP_MSG, strlen(STARTUP_MSG));
+
+	register_console(&netconsole);
+	printk(KERN_INFO "netconsole: network logging started\n");
+
+	return 0;
+}
+
+static void cleanup_netconsole(void)
+{
+	printk(KERN_INFO "netconsole: network logging shut down.\n");
+	unregister_console(&netconsole);
+
+#define SHUTDOWN_MSG "[...network console shutdown...]\n"
+	write_netconsole_msg(NULL, SHUTDOWN_MSG, strlen(SHUTDOWN_MSG));
+	netconsole_dev = NULL;
+}
+
+module_init(init_netconsole);
+module_exit(cleanup_netconsole);
+
+int dummy = MAX_SKB_SIZE;
diff -urN -X dontdiff orig/drivers/net/tlan.c work/drivers/net/tlan.c
--- orig/drivers/net/tlan.c	2003-08-10 18:13:48.000000000 -0500
+++ work/drivers/net/tlan.c	2003-08-10 22:56:51.000000000 -0500
@@ -296,6 +296,7 @@
 static int      TLan_probe1( struct pci_dev *pdev, long ioaddr, int irq, int rev, const struct pci_device_id *ent);
 static void	TLan_tx_timeout( struct net_device *dev);
 static int 	tlan_init_one( struct pci_dev *pdev, const struct pci_device_id *ent);
+static void	TLan_Poll(struct net_device *dev);
 
 static u32	TLan_HandleInvalid( struct net_device *, u16 );
 static u32	TLan_HandleTxEOF( struct net_device *, u16 );
@@ -452,6 +453,25 @@
 	pci_set_drvdata( pdev, NULL );
 } 
 
+#ifdef HAVE_POLL_CONTROLLER
+
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+
+static void TLan_Poll (struct net_device *dev)
+{
+       disable_irq(dev->irq);
+       TLan_HandleInterrupt(dev->irq, dev, NULL);
+       enable_irq(dev->irq);
+}
+
+#endif
+ 
+
+
 static struct pci_driver tlan_driver = {
 	.name		= "tlan",
 	.id_table	= tlan_pci_tbl,
@@ -892,6 +912,9 @@
 	dev->do_ioctl = &TLan_ioctl;
 	dev->tx_timeout = &TLan_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
+#ifdef HAVE_POLL_CONTROLLER
+	dev->poll_controller = &TLan_Poll;
+#endif
 
 	return 0;
 
diff -urN -X dontdiff orig/drivers/net/tulip/tulip_core.c work/drivers/net/tulip/tulip_core.c
--- orig/drivers/net/tulip/tulip_core.c	2003-08-10 18:13:48.000000000 -0500
+++ work/drivers/net/tulip/tulip_core.c	2003-08-10 18:21:38.000000000 -0500
@@ -245,6 +245,7 @@
 static struct net_device_stats *tulip_get_stats(struct net_device *dev);
 static int private_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static void set_rx_mode(struct net_device *dev);
+static void poll_tulip(struct net_device *dev);
 
 
 
@@ -1630,6 +1631,9 @@
 	dev->get_stats = tulip_get_stats;
 	dev->do_ioctl = private_ioctl;
 	dev->set_multicast_list = set_rx_mode;
+#ifdef HAVE_POLL_CONTROLLER
+	dev->poll_controller = &poll_tulip;
+#endif
 
 	if (register_netdev(dev))
 		goto err_out_free_ring;
@@ -1787,6 +1791,24 @@
 }
 
 
+#ifdef HAVE_POLL_CONTROLLER
+
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+
+static void poll_tulip (struct net_device *dev)
+{
+       disable_irq(dev->irq);
+       tulip_interrupt (dev->irq, dev, NULL);
+       enable_irq(dev->irq);
+}
+
+#endif
+
+
 static struct pci_driver tulip_driver = {
 	.name		= DRV_NAME,
 	.id_table	= tulip_pci_tbl,
diff -urN -X dontdiff orig/include/linux/netdevice.h work/include/linux/netdevice.h
--- orig/include/linux/netdevice.h	2003-08-10 18:13:53.000000000 -0500
+++ work/include/linux/netdevice.h	2003-08-10 18:21:38.000000000 -0500
@@ -446,6 +446,8 @@
 						     unsigned char *haddr);
 	int			(*neigh_setup)(struct net_device *dev, struct neigh_parms *);
 	int			(*accept_fastpath)(struct net_device *, struct dst_entry*);
+#define HAVE_POLL_CONTROLLER
+	void			(*poll_controller)(struct net_device *dev);
 
 	/* bridge stuff */
 	struct net_bridge_port	*br_port;


-- 
Matt Mackall : http://www.selenic.com : of or relating to the moon

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][RFC] Netconsole debugging tool for 2.6
  2003-08-11  8:55 [PATCH][RFC] Netconsole debugging tool for 2.6 Matt Mackall
@ 2003-08-26 20:57 ` Peter Osterlund
  2003-08-27 21:08   ` Herbert Pötzl
  2003-08-28 12:38 ` Steffen Klassert
  1 sibling, 1 reply; 9+ messages in thread
From: Peter Osterlund @ 2003-08-26 20:57 UTC (permalink / raw)
  To: Matt Mackall; +Cc: linux-kernel

Matt Mackall <mpm@selenic.com> writes:

> I've decided to take a stab at resurrecting Ingo's netconsole patch.
> 
> For those who missed it the first time around (for 2.4.10), this
> module is a "serial console over networks" which lets you catch kernel
> messages, oopses and so on that can't be caught by syslog.
...
> I've also added support for a third NIC (TLAN). Accepting patches for
> other cards (only about 10 lines of code each).

It works fine on my computer with the patch below. The only problem is
that it taints the kernel because of missing module license information.

Netconsole support for the 8139too NIC.


 linux-petero/Documentation/networking/netlogging.txt |    1 
 linux-petero/drivers/net/8139too.c                   |   22 +++++++++++++++++++
 2 files changed, 23 insertions(+)

diff -puN Documentation/networking/netlogging.txt~netconsole-8139too Documentation/networking/netlogging.txt
--- linux/Documentation/networking/netlogging.txt~netconsole-8139too	2003-08-26 22:21:43.000000000 +0200
+++ linux-petero/Documentation/networking/netlogging.txt	2003-08-26 22:21:43.000000000 +0200
@@ -52,3 +52,4 @@ Currently supported network drivers:
  eepro100
  tulip
  tlan
+ 8139too
diff -puN drivers/net/8139too.c~netconsole-8139too drivers/net/8139too.c
--- linux/drivers/net/8139too.c~netconsole-8139too	2003-08-26 22:22:06.000000000 +0200
+++ linux-petero/drivers/net/8139too.c	2003-08-26 22:26:46.000000000 +0200
@@ -625,6 +625,7 @@ static struct net_device_stats *rtl8139_
 static void rtl8139_set_rx_mode (struct net_device *dev);
 static void __set_rx_mode (struct net_device *dev);
 static void rtl8139_hw_start (struct net_device *dev);
+static void poll_8139 (struct net_device *dev);
 
 #ifdef USE_IO_OPS
 
@@ -973,6 +974,9 @@ static int __devinit rtl8139_init_one (s
 	dev->do_ioctl = netdev_ioctl;
 	dev->tx_timeout = rtl8139_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
+#ifdef HAVE_POLL_CONTROLLER
+	dev->poll_controller = &poll_8139;
+#endif
 
 	/* note: the hardware is not capable of sg/csum/highdma, however
 	 * through the use of skb_copy_and_csum_dev we enable these
@@ -2596,6 +2600,24 @@ static int rtl8139_resume (struct pci_de
 
 #endif /* CONFIG_PM */
 
+#ifdef HAVE_POLL_CONTROLLER
+
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+
+static void poll_8139 (struct net_device *dev)
+{
+       disable_irq(dev->irq);
+       rtl8139_interrupt (dev->irq, dev, NULL);
+       enable_irq(dev->irq);
+}
+
+#endif
+
+
 
 static struct pci_driver rtl8139_pci_driver = {
 	.name		= DRV_NAME,

_

-- 
Peter Osterlund - petero2@telia.com
http://w1.894.telia.com/~u89404340

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][RFC] Netconsole debugging tool for 2.6
  2003-08-26 20:57 ` Peter Osterlund
@ 2003-08-27 21:08   ` Herbert Pötzl
  2003-08-27 21:14     ` J.A. Magallon
  0 siblings, 1 reply; 9+ messages in thread
From: Herbert Pötzl @ 2003-08-27 21:08 UTC (permalink / raw)
  To: Peter Osterlund; +Cc: Matt Mackall, linux-kernel

On Tue, Aug 26, 2003 at 10:57:28PM +0200, Peter Osterlund wrote:
> Matt Mackall <mpm@selenic.com> writes:
> 
> > I've decided to take a stab at resurrecting Ingo's netconsole patch.
> > 
> > For those who missed it the first time around (for 2.4.10), this
> > module is a "serial console over networks" which lets you catch kernel
> > messages, oopses and so on that can't be caught by syslog.

hmm, sounds somewhat familiar, could you give
the location of the patches/tools/etc ...

> > I've also added support for a third NIC (TLAN). Accepting patches for
> > other cards (only about 10 lines of code each).

hmm, which cards are (un)supported ...
(read: I'm interrested ;)

TIA,
Herbert

> 
> It works fine on my computer with the patch below. The only problem is
> that it taints the kernel because of missing module license information.
> 
> Netconsole support for the 8139too NIC.
> 
> 
>  linux-petero/Documentation/networking/netlogging.txt |    1 
>  linux-petero/drivers/net/8139too.c                   |   22 +++++++++++++++++++
>  2 files changed, 23 insertions(+)
> 
> diff -puN Documentation/networking/netlogging.txt~netconsole-8139too Documentation/networking/netlogging.txt
> --- linux/Documentation/networking/netlogging.txt~netconsole-8139too	2003-08-26 22:21:43.000000000 +0200
> +++ linux-petero/Documentation/networking/netlogging.txt	2003-08-26 22:21:43.000000000 +0200
> @@ -52,3 +52,4 @@ Currently supported network drivers:
>   eepro100
>   tulip
>   tlan
> + 8139too
> diff -puN drivers/net/8139too.c~netconsole-8139too drivers/net/8139too.c
> --- linux/drivers/net/8139too.c~netconsole-8139too	2003-08-26 22:22:06.000000000 +0200
> +++ linux-petero/drivers/net/8139too.c	2003-08-26 22:26:46.000000000 +0200
> @@ -625,6 +625,7 @@ static struct net_device_stats *rtl8139_
>  static void rtl8139_set_rx_mode (struct net_device *dev);
>  static void __set_rx_mode (struct net_device *dev);
>  static void rtl8139_hw_start (struct net_device *dev);
> +static void poll_8139 (struct net_device *dev);
>  
>  #ifdef USE_IO_OPS
>  
> @@ -973,6 +974,9 @@ static int __devinit rtl8139_init_one (s
>  	dev->do_ioctl = netdev_ioctl;
>  	dev->tx_timeout = rtl8139_tx_timeout;
>  	dev->watchdog_timeo = TX_TIMEOUT;
> +#ifdef HAVE_POLL_CONTROLLER
> +	dev->poll_controller = &poll_8139;
> +#endif
>  
>  	/* note: the hardware is not capable of sg/csum/highdma, however
>  	 * through the use of skb_copy_and_csum_dev we enable these
> @@ -2596,6 +2600,24 @@ static int rtl8139_resume (struct pci_de
>  
>  #endif /* CONFIG_PM */
>  
> +#ifdef HAVE_POLL_CONTROLLER
> +
> +/*
> + * Polling 'interrupt' - used by things like netconsole to send skbs
> + * without having to re-enable interrupts. It's not called while
> + * the interrupt routine is executing.
> + */
> +
> +static void poll_8139 (struct net_device *dev)
> +{
> +       disable_irq(dev->irq);
> +       rtl8139_interrupt (dev->irq, dev, NULL);
> +       enable_irq(dev->irq);
> +}
> +
> +#endif
> +
> +
>  
>  static struct pci_driver rtl8139_pci_driver = {
>  	.name		= DRV_NAME,
> 
> _
> 
> -- 
> Peter Osterlund - petero2@telia.com
> http://w1.894.telia.com/~u89404340
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][RFC] Netconsole debugging tool for 2.6
  2003-08-27 21:08   ` Herbert Pötzl
@ 2003-08-27 21:14     ` J.A. Magallon
  0 siblings, 0 replies; 9+ messages in thread
From: J.A. Magallon @ 2003-08-27 21:14 UTC (permalink / raw)
  To: herbert; +Cc: Peter Osterlund, Matt Mackall, linux-kernel


On 08.27, Herbert Pötzl wrote:
> On Tue, Aug 26, 2003 at 10:57:28PM +0200, Peter Osterlund wrote:
> > Matt Mackall <mpm@selenic.com> writes:
> > 
> > > I've decided to take a stab at resurrecting Ingo's netconsole patch.
> > > 
> > > For those who missed it the first time around (for 2.4.10), this
> > > module is a "serial console over networks" which lets you catch kernel
> > > messages, oopses and so on that can't be caught by syslog.
> 
> hmm, sounds somewhat familiar, could you give
> the location of the patches/tools/etc ...
> 

I think it is included in -aa, so perhaps that is the most updated
source.

-- 
J.A. Magallon <jamagallon@able.es>      \                 Software is like sex:
werewolf.able.es                         \           It's better when it's free
Mandrake Linux release 9.2 (Cooker) for i586
Linux 2.4.22-jam1m (gcc 3.3.1 (Mandrake Linux 9.2 3.3.1-1mdk))

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][RFC] Netconsole debugging tool for 2.6
  2003-08-11  8:55 [PATCH][RFC] Netconsole debugging tool for 2.6 Matt Mackall
  2003-08-26 20:57 ` Peter Osterlund
@ 2003-08-28 12:38 ` Steffen Klassert
  1 sibling, 0 replies; 9+ messages in thread
From: Steffen Klassert @ 2003-08-28 12:38 UTC (permalink / raw)
  To: Matt Mackall; +Cc: linux-kernel

On Mon, Aug 11, 2003 at 03:55:08AM -0500 or thereabouts, Matt Mackall wrote:
...
> I've also added support for a third NIC (TLAN). Accepting patches for
> other cards (only about 10 lines of code each).
...


With the patch below netconsole works with the ne2k-pci driver.
The patch applies on 2.6.0-test4.
Tested with my RealTek RTL-8029 card.

Are you interested on code cleanup patches etc. for netconsole too?


Steffen


--- vanilla-2.6.0-test4/drivers/net/ne2k-pci.c	Fri Aug 22 23:53:07 2003
+++ linux-2.6.0-test4-sk/drivers/net/ne2k-pci.c	Sat Aug 23 11:04:36 2003
@@ -167,6 +167,7 @@ MODULE_DEVICE_TABLE(pci, ne2k_pci_tbl);
 static int ne2k_pci_open(struct net_device *dev);
 static int ne2k_pci_close(struct net_device *dev);
 
+static void poll_ne2k_pci(struct net_device *dev);
 static void ne2k_pci_reset_8390(struct net_device *dev);
 static void ne2k_pci_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
 			  int ring_page);
@@ -362,6 +363,10 @@ static int __devinit ne2k_pci_init_one (
 	dev->open = &ne2k_pci_open;
 	dev->stop = &ne2k_pci_close;
 	dev->do_ioctl = &netdev_ioctl;
+#ifdef HAVE_POLL_CONTROLLER
+	dev->poll_controller = &poll_ne2k_pci;
+#endif
+
 	NS8390_init(dev, 0);
 
 	i = register_netdev(dev);
@@ -436,6 +441,23 @@ static void ne2k_pci_reset_8390(struct n
 		}
 	outb(ENISR_RESET, NE_BASE + EN0_ISR);	/* Ack intr. */
 }
+
+#ifdef HAVE_POLL_CONTROLLER
+
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+
+static void poll_ne2k_pci (struct net_device *dev)
+{
+	disable_irq(dev->irq);
+	ei_interrupt (dev->irq, dev, NULL);
+	enable_irq(dev->irq);
+}
+
+#endif
 
 /* Grab the 8390 specific header. Similar to the block_input routine, but
    we don't need to be concerned with ring wrap as the header will be at

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][RFC] Netconsole debugging tool for 2.6
  2003-08-12 17:09   ` Jeff Garzik
@ 2003-08-12 17:39     ` Matt Mackall
  0 siblings, 0 replies; 9+ messages in thread
From: Matt Mackall @ 2003-08-12 17:39 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Jon Burgess, linux kernel, netdev

On Tue, Aug 12, 2003 at 01:09:20PM -0400, Jeff Garzik wrote:
> On Tue, Aug 12, 2003 at 11:33:11AM -0500, Matt Mackall wrote:
> > On Tue, Aug 12, 2003 at 03:13:00PM +0100, Jon Burgess wrote:
> > > Matt Mackall wrote:
> > > > I've decided to take a stab at resurrecting Ingo's netconsole patch.
> > > 
> > > Is this different from the netdump patch which RedHat include in their 
> > > kernel?
> > > 
> > > The RH kernel patch is at
> > > http://www.kernelnewbies.org/kernels/rh9/SOURCES/linux-2.4.18-netdump.patch
> > 
> > Ahh, so that's what's become of it.
> > 
> > Theirs:
> > - does crashdumps
> > - does syslog without levels
> > - has hooks for receive
> > 
> > Mine:
> > - works in 2.6
> > - has non-appalling configuration
> > - works as a built-in and is available earlier in boot
> > - does syslog with levels (haven't posted this though)
> 
> netconsole does syslog with levels, too.  I agree netdump/netconsole
> have complete awful configuration.  I was thinking netlink would be a
> good configurator.

My personal goal is to have it configured in time to catch stuff in
the boot process so I can avoid plugging into the serial console,
which means everything on the command line. So I've got code to parse
the following:

netconsole=[src-port]@[src-ip]/[<dev>],[tgt-port]@<tgt-ip>/[tgt-macaddr]

> The kernel printk <foo> prefixes map into syslog quite nicely.

..and are stripped by printk before the console code is called. The
netdump patch logs everything at level 5:

+               send_syslog_skb(dev, syslog_line, syslog_chars, 5);

My patch adds another entry to console struct for writing with levels.
And adds hostname to messages. Still needs timestamp.
 
> In any case, there is my own active effort into cleaning up netdump to
> be less x86-specific, and get it ready for mainline.
>
> Maybe we can start discussing converging all these implementations on
> netdev@oss.sgi.com?  (that's where the networking developers live)

Not sure that's the right place for it, simply because that's the one
group of people it's not terribly useful for. Especially when I start
talking about hooking it up to kgdb. And the network bits are pretty
much there already.

-- 
Matt Mackall : http://www.selenic.com : of or relating to the moon

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][RFC] Netconsole debugging tool for 2.6
  2003-08-12 16:33 ` Matt Mackall
@ 2003-08-12 17:09   ` Jeff Garzik
  2003-08-12 17:39     ` Matt Mackall
  0 siblings, 1 reply; 9+ messages in thread
From: Jeff Garzik @ 2003-08-12 17:09 UTC (permalink / raw)
  To: Matt Mackall; +Cc: Jon Burgess, linux kernel, netdev

On Tue, Aug 12, 2003 at 11:33:11AM -0500, Matt Mackall wrote:
> On Tue, Aug 12, 2003 at 03:13:00PM +0100, Jon Burgess wrote:
> > Matt Mackall wrote:
> > > I've decided to take a stab at resurrecting Ingo's netconsole patch.
> > 
> > Is this different from the netdump patch which RedHat include in their 
> > kernel?
> > 
> > The RH kernel patch is at
> > http://www.kernelnewbies.org/kernels/rh9/SOURCES/linux-2.4.18-netdump.patch
> 
> Ahh, so that's what's become of it.
> 
> Theirs:
> - does crashdumps
> - does syslog without levels
> - has hooks for receive
> 
> Mine:
> - works in 2.6
> - has non-appalling configuration
> - works as a built-in and is available earlier in boot
> - does syslog with levels (haven't posted this though)

netconsole does syslog with levels, too.  I agree netdump/netconsole
have complete awful configuration.  I was thinking netlink would be a
good configurator.

The kernel printk <foo> prefixes map into syslog quite nicely.

In any case, there is my own active effort into cleaning up netdump to
be less x86-specific, and get it ready for mainline.

Maybe we can start discussing converging all these implementations on
netdev@oss.sgi.com?  (that's where the networking developers live)

	Jeff




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][RFC] Netconsole debugging tool for 2.6
  2003-08-12 14:13 Jon Burgess
@ 2003-08-12 16:33 ` Matt Mackall
  2003-08-12 17:09   ` Jeff Garzik
  0 siblings, 1 reply; 9+ messages in thread
From: Matt Mackall @ 2003-08-12 16:33 UTC (permalink / raw)
  To: Jon Burgess; +Cc: linux kernel

On Tue, Aug 12, 2003 at 03:13:00PM +0100, Jon Burgess wrote:
> Matt Mackall wrote:
> > I've decided to take a stab at resurrecting Ingo's netconsole patch.
> 
> Is this different from the netdump patch which RedHat include in their 
> kernel?
> 
> The RH kernel patch is at
> http://www.kernelnewbies.org/kernels/rh9/SOURCES/linux-2.4.18-netdump.patch

Ahh, so that's what's become of it.

Theirs:
- does crashdumps
- does syslog without levels
- has hooks for receive

Mine:
- works in 2.6
- has non-appalling configuration
- works as a built-in and is available earlier in boot
- does syslog with levels (haven't posted this though)


-- 
Matt Mackall : http://www.selenic.com : of or relating to the moon

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][RFC] Netconsole debugging tool for 2.6
@ 2003-08-12 14:13 Jon Burgess
  2003-08-12 16:33 ` Matt Mackall
  0 siblings, 1 reply; 9+ messages in thread
From: Jon Burgess @ 2003-08-12 14:13 UTC (permalink / raw)
  To: mpm, linux kernel

Matt Mackall wrote:
 > I've decided to take a stab at resurrecting Ingo's netconsole patch.

Is this different from the netdump patch which RedHat include in their 
kernel?

The RH kernel patch is at
http://www.kernelnewbies.org/kernels/rh9/SOURCES/linux-2.4.18-netdump.patch

The tools are shipped in netdump-*.rpm with the distribution.

	Jon


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2003-08-28 12:38 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-08-11  8:55 [PATCH][RFC] Netconsole debugging tool for 2.6 Matt Mackall
2003-08-26 20:57 ` Peter Osterlund
2003-08-27 21:08   ` Herbert Pötzl
2003-08-27 21:14     ` J.A. Magallon
2003-08-28 12:38 ` Steffen Klassert
2003-08-12 14:13 Jon Burgess
2003-08-12 16:33 ` Matt Mackall
2003-08-12 17:09   ` Jeff Garzik
2003-08-12 17:39     ` Matt Mackall

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).