Re: [patch] netconsole-2.4.10-B1

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sep 27, 2001  08:38 +0200, Ingo Molnar wrote:
> the patch also includes Andrew Morton's suggestion to add the
> HAVE_POLL_CONTROLLER define for easier network-driver integration. The
> eepro100.c changes now use this define.
> 
> the new utilities-tarball is at:
> 
> http://redhat.com/~mingo/netconsole-patches/netconsole-client-20010927.tar.gz

A few minor changes to the code, after testing it a bit locally (note that I
am using kernel patch C1):

First, a patch to change the MAC address kernel parameter to be in the
standard XX:XX:XX:XX:XX:XX form, instead of separate bytes.  It also
fixes the output of the IP addresses to be unsigned ints.  Isn't there
a function in the kernel to format IP addresses for output already?

Next, a patch to netconsole-server to use the target_mac parameter
instead of the target_eth_byteX parameters.  I thought about keeping
these around for compatibility, but since this is a relatively new
tool there is no point in keeping the extra baggage.

TODO: figure out what "offset" is really supposed to be useful for.  Maybe
      it should be aligned properly, and we add the message priority into
      one of the free bytes?

Finally, a patch to netconsole-client.c which does a few things:
- remove "offset" from output, it appears meaningless and screws formatting.
- allow the client to receive messages from multiple servers, unless a
  single server is specified.
- log to syslog (this is a bit complex because of the desire to write full
  lines into the syslog as opposed to chunks of the size sent by printk().
- (minor) change parameters to use "--" long option names in preparation
  for using getopt-long to do CLI parsing.
- (minor) don't require the --port option (use 6666 as default)
- (minor) don't require the --server option (accept all messages by default)

TODO: don't require the --client option (get ipaddress from interface and/or
      listen on all interfaces by default)
TODO: add getopt_long parsing of options to avoid ordered option requirement
TODO: make syslog and stdout logging optional (need one or the other obviously)
TODO: print server IP/hostname in syslog/stdout output in case we are getting
      messages from multiple servers
TODO: figure out why LOG_KERN does not show up in kernel log, while klogd does
TODO: add timeout for messages in syslog output buffer.
TODO: allow client/server to be specified by both hostname/IP
TODO: allow different client/server port numbers?  Do we care?

As an added bonus, a patch for 8139too.c which adds poll support (Jeff CC'd).

Cheers, Andreas
======================= netconsole-2.4.8-mac.diff =====================
--- linux/drivers/net/netconsole.c.orig	Thu Sep 27 10:11:27 2001
+++ linux/drivers/net/netconsole.c	Thu Sep 27 17:13:24 2001
@@ -219,20 +219,10 @@
 }
 
 static char *dev;
-static int target_eth_byte0 = 255;
-static int target_eth_byte1 = 255;
-static int target_eth_byte2 = 255;
-static int target_eth_byte3 = 255;
-static int target_eth_byte4 = 255;
-static int target_eth_byte5 = 255;
+static char *target_mac;
 
 MODULE_PARM(target_ip, "i");
-MODULE_PARM(target_eth_byte0, "i");
-MODULE_PARM(target_eth_byte1, "i");
-MODULE_PARM(target_eth_byte2, "i");
-MODULE_PARM(target_eth_byte3, "i");
-MODULE_PARM(target_eth_byte4, "i");
-MODULE_PARM(target_eth_byte5, "i");
+MODULE_PARM(target_mac, "s");
 MODULE_PARM(source_port, "h");
 MODULE_PARM(target_port, "h");
 MODULE_PARM(dev, "s");
@@ -267,8 +257,8 @@
 		printk(KERN_ERR "netconsole: network device %s has no local address, aborting.\n", dev);
 		return -1;
 	}
-#define IP(x) ((char *)&source_ip)[x]
-	printk(KERN_INFO "netconsole: using source IP %i.%i.%i.%i\n",
+#define IP(x) ((unsigned char *)&source_ip)[x]
+	printk(KERN_INFO "netconsole: using source IP %u.%u.%u.%u\n",
 		IP(3), IP(2), IP(1), IP(0));
 #undef IP
 	source_ip = htonl(source_ip);
@@ -276,8 +266,8 @@
 		printk(KERN_ERR "netconsole: target_ip parameter not specified, aborting.\n");
 		return -1;
 	}
-#define IP(x) ((char *)&target_ip)[x]
-	printk(KERN_INFO "netconsole: using target IP %i.%i.%i.%i\n",
+#define IP(x) ((unsigned char *)&target_ip)[x]
+	printk(KERN_INFO "netconsole: using target IP %u.%u.%u.%u\n",
 		IP(3), IP(2), IP(1), IP(0));
 #undef IP
 	target_ip = htonl(target_ip);
@@ -294,18 +284,26 @@
 	printk(KERN_INFO "netconsole: using target UDP port: %i\n", target_port);
 	target_port = htons(target_port);
 
-	daddr[0] = target_eth_byte0;
-	daddr[1] = target_eth_byte1;
-	daddr[2] = target_eth_byte2;
-	daddr[3] = target_eth_byte3;
-	daddr[4] = target_eth_byte4;
-	daddr[5] = target_eth_byte5;
-
-	if ((daddr[0] & daddr[1] & daddr[2] & daddr[3] & daddr[4] & daddr[5]) == 255)
-		printk(KERN_INFO "netconsole: using broadcast ethernet frames to send packets.\n");
-	else
-		printk(KERN_INFO "netconsole: using target ethernet address %02x:%02x:%02x:%02x:%02x:%02x.\n", daddr[0], daddr[1], daddr[2], daddr[3], daddr[4], daddr[5]);
-		
+	if (target_mac) {
+		char *ptr = target_mac;
+		int i;
+
+		printk(KERN_INFO "netconsole: using target ethernet MAC: %s\n",
+		       target_mac);
+		for (i = 0; i < 6 && ptr; i++) {
+			int val;
+			char *sep;
+			val = simple_strtoul(ptr, &sep, 16);
+			if (sep != ptr) {
+				daddr[i] = val;
+				ptr = *sep ? sep + 1 : NULL;
+			}
+		}
+	} else
+		printk(KERN_INFO "netconsole: using broadcast ethernet MAC.\n");
+
 	netconsole_dev = ndev;
 #define STARTUP_MSG "[...network console startup...]\n"
 	write_netconsole_msg(NULL, STARTUP_MSG, strlen(STARTUP_MSG));
===================== netconsole-server.diff =============================
--- netconsole-client/netconsole-server.orig	Thu Sep 27 00:32:50 2001
+++ netconsole-client/netconsole-server	Thu Sep 27 17:22:55 2001
@@ -30,9 +30,11 @@
 
 while [ $# -ge 1 ]; do case $1 in
 	-b) NOMAC=1 ;;
-	-d) DEV=$2; shift ;;
-	-m) MAC=$2; shift ;;
-	-p) PORT=$2; shift ;;
+	-d|--device) DEV=$2; shift ;;
+	-m|--mac) MAC=$2; shift ;;
+	-p|--port) PORT=$2; shift ;;
+	--client) TGT=`echo $2| sed "s/:.*//"`;
+		TPORT=`echo $2 | sed "s/.*://"`; shift ;;
 	*:*) TGT=`echo $1 | sed "s/:.*//"`; TPORT=`echo $1 | sed "s/.*://"` ;;
 	*) TGT=$1 ;;
 	esac
@@ -65,16 +67,9 @@
 		echo "$prog: $DEV must be an ethernet interface" 1>&2 && usage
 		
 	IPHEX=`dquad_to_hex $IPADDR`
-	echo $MAC | sed "s/:/ /g" | { read M0 M1 M2 M3 M4 M5;
-		if [ -z "$NOMAC" ]; then
-			TGTMAC="target_eth_byte0=0x$M0 target_eth_byte1=0x$M1 \
-				target_eth_byte2=0x$M2 target_eth_byte3=0x$M3 \
-				target_eth_byte4=0x$M4 target_eth_byte5=0x$M5"
-		fi
-		echo dev=$DEV target_ip=$IPHEX \
-			source_port=$PORT target_port=$TPORT $TGTMAC
-		/sbin/insmod netconsole dev=$DEV target_ip=$IPHEX \
-			source_port=$PORT target_port=$TPORT $TGTMAC
-	}
+	[ -z "$NOMAC" ] && TGTMAC="target_mac=$MAC"
+	echo dev=$DEV target_ip=$IPHEX \
+		source_port=$PORT target_port=$TPORT $TGTMAC
+	insmod netconsole dev=$DEV target_ip=$IPHEX \
+		source_port=$PORT target_port=$TPORT $TGTMAC
 }
-
===================== netconsole-client.diff =============================
--- netconsole-client/netconsole-client.c.orig	Thu Sep 27 08:32:31 2001
+++ netconsole-client/netconsole-client.c	Thu Sep 27 16:07:39 2001
@@ -17,47 +17,59 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <syslog.h>
 
 #define NETCONSOLE_VERSION 0x01
 
 #define BUFLEN 10000
 
+#ifndef min
+#define min(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
 int main (int argc, char **argv)
 {
 	struct sockaddr_in saddr, caddr;
 	int udp_socket;
-	unsigned char buf[BUFLEN];
-	int len, port;
+	unsigned char buf[BUFLEN], sysbuf[BUFLEN];
+	unsigned int sysoff = 0;
+	int len, port = 6666;
 	struct sockaddr_in addr;
 	int addr_len = sizeof(addr);
+	int noserver = 1;
 
 	memset(&addr, 0, addr_len);
 	memset(&saddr, 0, addr_len);
 	memset(&caddr, 0, addr_len);
 
-	if (argc != 7) {
-		fprintf(stderr, "usage: netconsole-client -server <IP> -client <IP> -port <port>\n");
+	if (argc != 3 && argc != 5 && argc != 7) {
+		fprintf(stderr, "usage: netconsole-client --client <IP> [--port <port> [--server <IP>]]\n");
 		exit(-1);
 	}
-	port = atol(argv[6]);
-	printf("displaying netconsole output from server %s, client %s, UDP port %d.\n", argv[2], argv[4], port);
+	if (argc > 4)
+		port = atol(argv[4]);
+	printf("listening on interface %s:%d for server %s:%d.\n", argv[2], port, argc > 6 ? argv[6] : "ANY", port);
 
 
 	udp_socket = socket(PF_INET, SOCK_DGRAM, 0);
 
-	saddr.sin_family = AF_INET;
-	saddr.sin_port = htons(port);
-	saddr.sin_addr.s_addr = inet_addr(argv[2]);
-
 	caddr.sin_family = AF_INET;
 	caddr.sin_port = htons(port);
-	caddr.sin_addr.s_addr = inet_addr(argv[4]);
+	caddr.sin_addr.s_addr = inet_addr(argv[2]);
+
+	if (argc > 5) {
+		saddr.sin_family = AF_INET;
+		saddr.sin_port = htons(port);
+		saddr.sin_addr.s_addr = inet_addr(argv[6]);
+		noserver = 0;
+	}
 
 	if (bind(udp_socket, (struct sockaddr *)&caddr, sizeof(caddr))) {
 		perror("could not bind UDP socket!\n");
 		exit(-1);
 	}
 
+	openlog("netconsole", 0, LOG_KERN);
 	while (1) {
 		len = recvfrom(udp_socket, buf, BUFLEN, 0, (struct sockaddr *)&addr, &addr_len);
 		if (len <= 0) {
@@ -65,10 +77,15 @@
 			exit(-1);
 		}
 		buf[len] = 0;
-		if (!memcmp(&addr, &saddr, addr_len)) {
-			unsigned int offset;
+		if (noserver || !memcmp(&addr, &saddr, addr_len)) {
+			unsigned int offset, skip;
+			unsigned int priority = LOG_WARNING, new_priority;
+			unsigned char *nl;
+
 			if (buf[0] != NETCONSOLE_VERSION) {
-				printf("[netconsole server has version %d, client supports only version %d! exiting.]\n", buf[0], NETCONSOLE_VERSION);
+				printf("[netconsole server has version %d, "
+				       "client supports only version %d! "
+				       "exiting.]\n", *buf, NETCONSOLE_VERSION);
 				exit(-1);
 			}
 
@@ -76,10 +93,42 @@
 			offset = (offset << 8) | buf[2];
 			offset = (offset << 8) | buf[3];
 			offset = (offset << 8) | buf[4];
+			skip = 5;
 
-			printf("(%d): %s", offset, buf+5);
+			printf("%s", buf + skip);
 			fflush(stdout);
+			if (sysoff == 0 &&
+			    sscanf(buf + skip, "<%d>", &new_priority) == 1) {
+				if (new_priority <= LOG_DEBUG) {
+					priority = new_priority;
+					skip += 3;
+				}
+			}
+			while ((nl = strchr(buf + skip, '\n'))) {
+				int used, left;
+
+				used = (nl - (buf + skip)) + 1;
+				left = sizeof(sysbuf) - sysoff - 1;
+
+				strncat(sysbuf + sysoff, buf + skip,
+					min(used, left));
+				/* FIXME: need to print source hostname/IP */
+				syslog(priority, "%s", sysbuf);
+				sysbuf[(sysoff = 0)] = '\0';
+				skip += min(used, left);
+			}
+			if (buf[skip]) {
+				strncat(sysbuf + sysoff, buf + skip,
+					 sizeof(sysbuf) - sysoff - 1);
+				sysoff += strlen(buf + skip);
+				if (sysoff >= sizeof(sysbuf)) {
+					syslog(priority, "%s", sysbuf);
+					sysbuf[(sysoff = 0)] = '\0';
+				}
+			}
+
 		}
 	}
+	closelog();
 	return 0;
 }
========================= 8139too-poll.diff ==============================
--- linux/drivers/net/8139too.c.orig	Tue Jul 31 15:15:28 2001
+++ linux/drivers/net/8139too.c	Thu Sep 27 10:15:59 2001
@@ -619,6 +619,9 @@
 static void rtl8139_init_ring (struct net_device *dev);
 static int rtl8139_start_xmit (struct sk_buff *skb,
 			       struct net_device *dev);
+#ifdef HAVE_POLL_CONTROLLER
+static void rtl8139_poll (struct net_device *dev);
+#endif
 static void rtl8139_interrupt (int irq, void *dev_instance,
 			       struct pt_regs *regs);
 static int rtl8139_close (struct net_device *dev);
@@ -965,6 +968,9 @@
 	dev->get_stats = rtl8139_get_stats;
 	dev->set_multicast_list = rtl8139_set_rx_mode;
 	dev->do_ioctl = netdev_ioctl;
+#ifdef HAVE_POLL_CONTROLLER
+	dev->poll_controller = rtl8139_poll;
+#endif
 	dev->tx_timeout = rtl8139_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
 
@@ -2201,6 +2207,20 @@
 	return 0;
 }
 
+
+#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 rtl8139_poll(struct net_device *dev)
+{
+	disable_irq(dev->irq);
+	rtl8139_interrupt(dev->irq, dev, NULL);
+	enable_irq(dev->irq);
+}
+#endif
 
 static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr)
 {
--
Andreas Dilger  \ "If a man ate a pound of pasta and a pound of antipasto,
                 \  would they cancel out, leaving him still hungry?"
http://www-mddsp.enel.ucalgary.ca/People/adilger/               -- Dogbert

-
: send the line "unsubscribe linux-net" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux 802.1Q VLAN]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Git]     [Bugtraq]     [Yosemite News and Information]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux PCI]     [Linux Admin]     [Samba]

  Powered by Linux