2003-08-11 08:55:58

by Matt Mackall

[permalink] [raw]
Subject: [PATCH][RFC] Netconsole debugging tool for 2.6

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 [email protected]/eth1,[email protected]/12:34:56:78:9a:bc

or just

linux [email protected]/,@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 <[email protected]>, 2001.09.17
+2.6 port by Matt Mackall <[email protected]>, 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 [email protected]/eth1,[email protected]/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 <[email protected]>
+ *
+ * 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


2003-08-12 14:13:13

by Jon Burgess

[permalink] [raw]
Subject: Re: [PATCH][RFC] Netconsole debugging tool for 2.6

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

2003-08-12 16:33:18

by Matt Mackall

[permalink] [raw]
Subject: Re: [PATCH][RFC] Netconsole debugging tool for 2.6

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

2003-08-12 17:09:26

by Jeff Garzik

[permalink] [raw]
Subject: Re: [PATCH][RFC] Netconsole debugging tool for 2.6

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
[email protected]? (that's where the networking developers live)

Jeff



2003-08-12 17:39:35

by Matt Mackall

[permalink] [raw]
Subject: Re: [PATCH][RFC] Netconsole debugging tool for 2.6

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
> [email protected]? (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

2003-08-26 20:57:52

by Peter Osterlund

[permalink] [raw]
Subject: Re: [PATCH][RFC] Netconsole debugging tool for 2.6

Matt Mackall <[email protected]> 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 - [email protected]
http://w1.894.telia.com/~u89404340

2003-08-27 21:08:21

by Herbert Poetzl

[permalink] [raw]
Subject: Re: [PATCH][RFC] Netconsole debugging tool for 2.6

On Tue, Aug 26, 2003 at 10:57:28PM +0200, Peter Osterlund wrote:
> Matt Mackall <[email protected]> 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 - [email protected]
> http://w1.894.telia.com/~u89404340
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/

2003-08-27 21:14:57

by J.A. Magallon

[permalink] [raw]
Subject: Re: [PATCH][RFC] Netconsole debugging tool for 2.6


On 08.27, Herbert P?tzl wrote:
> On Tue, Aug 26, 2003 at 10:57:28PM +0200, Peter Osterlund wrote:
> > Matt Mackall <[email protected]> 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 <[email protected]> \ 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))

2003-08-28 12:38:43

by Steffen Klassert

[permalink] [raw]
Subject: Re: [PATCH][RFC] Netconsole debugging tool for 2.6

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