Kernel messages are often assembled from numerical and text fragments. Sending fragments via UDP often produces one line per fragment on the other end.
Example: Pseudo code: printk "a message: " ... printk "%d, " 1234 ... printk "%x, %s\n" 0x5678 "blabla" Log buffer/dmesg (intended format): a message: 1234, 5678, blabla After sending via UDP: a message 1234, 5678, blabla Fragmented messages are very hard to process automatically. Changes by this patch send messages every line after buffering. In practice it is also generally faster as network overhead is incurred only once per line. This patch is in use since June with 2.6.11 to routine monitor a dozen systems. Signed-off-by: Michael Frank <[EMAIL PROTECTED]> --- netconsole.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 9 deletions(-) Patch file: netc-buffer-mhfp17 --- linux-2.6.15-rc2-mhf260/drivers/net/netconsole.c.001 2005-11-21 08:28:58.000000000 +0100 +++ linux-2.6.15-rc2-mhf260/drivers/net/netconsole.c 2005-11-21 09:08:18.000000000 +0100 @@ -15,6 +15,7 @@ * generic card hooks * works non-modular * 2003-09-07 rewritten with netpoll api + * 2005-06-13 Michael Frank <[EMAIL PROTECTED]> Send short messages every line */ /****************************************************************************** @@ -50,10 +51,15 @@ MODULE_DESCRIPTION("Console driver for network interfaces"); MODULE_LICENSE("GPL"); -static char config[256]; -module_param_string(netconsole, config, 256, 0); +#define MAX_LINE 256 + +static char linebuf[MAX_LINE]; +module_param_string(netconsole, linebuf, MAX_LINE, 0); MODULE_PARM_DESC(netconsole, " [EMAIL PROTECTED]/[dev],[tgt-port]@<tgt-ip>/[tgt-macaddr]\n"); +static char *plinebuf = linebuf; +static int nlinebuf; + static struct netpoll np = { .name = "netconsole", .dev_name = "eth0", @@ -68,6 +74,8 @@ static void write_msg(struct console *con, const char *msg, unsigned int len) { + char c; + char *pmsg; int frag, left; unsigned long flags; @@ -76,11 +84,44 @@ local_irq_save(flags); - for (left = len; left;) { - frag = min(left, MAX_PRINT_CHUNK); - netpoll_send_udp(&np, msg, frag); - msg += frag; - left -= frag; + left = len; + pmsg = (char *)msg; + + if (left + nlinebuf <= MAX_LINE) { + /* Kernel messages are often assembled from numerical and text + * fragments. Sending fragments via UDP often produces one line + * per fragment on the other end. Therefor, messages of length + * up to MAX_LINE are sent every line after buffering. + * + * In practice it is also generally faster as network overhead + * is incurred only once per line. + */ + + while (left--) { + c = *pmsg++; + *plinebuf++ = c; + nlinebuf++; + if (c == '\n') { + plinebuf = linebuf; + netpoll_send_udp(&np, plinebuf, nlinebuf); + nlinebuf = 0; + } + } + } else { + /* Messages longer than MAX_LINE are sent by block for maximum + * throughput. The line buffer is flushed prior to sending + * a message longer than MAX_LINE. + */ + + if (nlinebuf) { + plinebuf = linebuf; + netpoll_send_udp(&np, plinebuf, nlinebuf); + nlinebuf = 0; + } + for (; left; left -= frag, pmsg += frag) { + frag = min(left, MAX_PRINT_CHUNK); + netpoll_send_udp(&np, pmsg, frag); + } } local_irq_restore(flags); @@ -101,8 +142,8 @@ static int init_netconsole(void) { - if (strlen(config)) - option_setup(config); + if (strlen(linebuf)) + option_setup(linebuf); if (!configured) { printk("netconsole: not configured, aborting\n"); - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html