implement tty driver for netconsole
Subsystems (3)
PATCH 1/1 implement tty driver for netconsole
I have a Kuro Box (a small NAS device running Linux), and it has no serial console (nor any other console for that matter). The most convenient way to get boot output is via the netconsole driver, which is what most Kuro owners do. (The u-boot firmware even supports interactive netconsole allowing us to edit boot configuration.)
However, once past kernel boot, userspace currently has no way of outputting data over netconsole. These patches enable that, which is really useful for seeing init script output and debugging ramdisks before they've brought up sshd.
-Hollis
PATCH 1/1 netconsole: add write-only tty driver
This allows userspace to output to netconsole via the /dev/console device, which is very useful to see initscript output, for example. There is only one netconsole TTY device, and TTY output goes to all receivers specified for console output.
Input via /dev/console is still not implemented, however.
drivers/net/netconsole.c +62 -0
@@ -43,6 +43,7 @@#include <linux/netpoll.h> #include <linux/inet.h> #include <linux/configfs.h> +#include <linux/tty.h> MODULE_AUTHOR ("Maintainer: Matt Mackall <[email protected]>" );MODULE_DESCRIPTION ("Console driver for network interfaces" );
@@ -98,6 +99,8 @@ struct netconsole_target {int enabled;struct netpoll np; }; + +static struct tty_driver *netconsole_tty_driver;#ifdef CONFIG_NETCONSOLE_DYNAMIC
@@ -728,15 +731,74 @@ static void netconsole_write_msg(const cspin_unlock_irqrestore (&target_list_lock, flags); } +static int netconsole_tty_open (struct tty_struct *tty,struct file *filp) +{ +return 0 ; +} + +static void netconsole_tty_close (struct tty_struct *tty,struct file *filp) +{ +} + +static int netconsole_tty_write (struct tty_struct *tty,const unsigned char *buf,int count) +{ +netconsole_write_msg (buf, count); +return count; +} + +static int netconsole_tty_write_room (struct tty_struct *tty) +{ +return MAX_PRINT_CHUNK ; +} + +static const struct tty_operations netconsole_tty_ops = { + .open = netconsole_tty_open, + .close = netconsole_tty_close, + .write = netconsole_tty_write, + .write_room = netconsole_tty_write_room, +}; + +static int __init netconsole_tty_init (void ) +{ + netconsole_tty_driver =alloc_tty_driver (1 ); +if (!netconsole_tty_driver) +return -ENOMEM ; + + netconsole_tty_driver->owner =THIS_MODULE ; + netconsole_tty_driver->driver_name ="netcon" ; + netconsole_tty_driver->name ="netcon" ; + netconsole_tty_driver->minor_start =0 ; + netconsole_tty_driver->type =TTY_DRIVER_TYPE_SYSTEM ; + netconsole_tty_driver->init_termios = tty_std_termios; + netconsole_tty_driver->init_termios.c_cflag =B9600 |CS8 |CREAD |HUPCL ; + netconsole_tty_driver->init_termios.c_ispeed =9600 ; + netconsole_tty_driver->init_termios.c_ospeed =9600 ; + netconsole_tty_driver->flags =TTY_DRIVER_REAL_RAW ; +tty_set_operations (netconsole_tty_driver, &netconsole_tty_ops); + +if (tty_register_driver (netconsole_tty_driver)) +printk (KERN_ERR "Couldn't register netconsole tty driver\n" ); + +return 0 ; +} +device_initcall (netconsole_tty_init); +static void netconsole_console_write (struct console *con,const char *msg,unsigned int len) {netconsole_write_msg (msg, len); +} + +static struct tty_driver *netconsole_console_device (struct console *console,int *index) +{ + *index = console->index; +return netconsole_tty_driver; }static struct console netconsole = { .name ="netcon" , .flags =CON_ENABLED , .write = netconsole_console_write, + .device = netconsole_console_device, };static int __init init_netconsole (void )
Re: [PATCH 2 of 2] netconsole: add write-only tty driver
Hi.
Looks good. A short note below.
Quoted 14 lines · Hollis Blanchard
drivers/net/netconsole.c +14
-0+static int __init netconsole_tty_init (void ) +{ + netconsole_tty_driver =alloc_tty_driver (1 ); +if (!netconsole_tty_driver) +return -ENOMEM ; + + netconsole_tty_driver->owner =THIS_MODULE ; + netconsole_tty_driver->driver_name ="netcon" ; + netconsole_tty_driver->name ="netcon" ; + netconsole_tty_driver->minor_start =0 ; + netconsole_tty_driver->type =TTY_DRIVER_TYPE_SYSTEM ; + netconsole_tty_driver->init_termios = tty_std_termios; + netconsole_tty_driver->init_termios.c_cflag =B9600 |CS8 |CREAD |HUPCL ; + netconsole_tty_driver->init_termios.c_ispeed =9600 ;
drivers/net/netconsole.c static void netconsole_write_msg(const c · line 784
Quoted 10 lines
drivers/net/netconsole.c +10
-0+ netconsole_tty_driver->init_termios.c_ospeed =9600 ; + netconsole_tty_driver->flags =TTY_DRIVER_REAL_RAW ; +tty_set_operations (netconsole_tty_driver, &netconsole_tty_ops); + +if (tty_register_driver (netconsole_tty_driver)) +printk (KERN_ERR "Couldn't register netconsole tty driver\n" ); + +return 0 ; +} +device_initcall (netconsole_tty_init);
Would it be better called from init_netconsole()?
Signature · 1 line
Evgeniy Polyakov
Re: [PATCH 2 of 2] netconsole: add write-only tty driver
Quoted 5 lines · On Thursday 27 November 2008 15:47:01 Evgeniy Polyakov wrote:
Hi.
Looks good. A short note below.
On Thu, Nov 27, 2008 at 03:11:02PM -0600, Hollis Blanchard
Quoted 5 lines · ([email protected]) wrote:
Quoted 5 lines
drivers/net/netconsole.c +5
-0+static int __init netconsole_tty_init (void ) +{ + netconsole_tty_driver =alloc_tty_driver (1 ); +if (!netconsole_tty_driver) +return -ENOMEM ;
Quoted 8 lines
drivers/net/netconsole.c static void netconsole_write_msg(const c
Quoted 8 lines
drivers/net/netconsole.c +8
-0+ + netconsole_tty_driver->owner =THIS_MODULE ; + netconsole_tty_driver->driver_name ="netcon" ; + netconsole_tty_driver->name ="netcon" ; + netconsole_tty_driver->minor_start =0 ; + netconsole_tty_driver->type =TTY_DRIVER_TYPE_SYSTEM ; + netconsole_tty_driver->init_termios = tty_std_termios; + netconsole_tty_driver->init_termios.c_cflag = B9600 | CS8 | CREAD |
HUPCL;
Quoted 5 lines
Quoted 5 lines
drivers/net/netconsole.c +5
-0+ netconsole_tty_driver->init_termios.c_ispeed =9600 ; + netconsole_tty_driver->init_termios.c_ospeed =9600 ; + netconsole_tty_driver->flags =TTY_DRIVER_REAL_RAW ; +tty_set_operations (netconsole_tty_driver, &netconsole_tty_ops); +
Quoted 8 lines
drivers/net/netconsole.c static void netconsole_write_msg(const c · line 784
Quoted 6 lines
drivers/net/netconsole.c +6
-0+if (tty_register_driver (netconsole_tty_driver)) +printk (KERN_ERR "Couldn't register netconsole tty driver\n" ); + +return 0 ; +} +device_initcall (netconsole_tty_init);Would it be better called from
init_netconsole()?
Hmm, I don't remember what the ordering is here. "console_initcall", used with most other console-providing drivers, is done before alloc_tty_driver() can work. However, since init_netconsole() is a "module_initcall", I guess that should work. Well, it must, since init_netconsole() calls kzalloc() already...
Signature · 2 lines
Hollis Blanchard IBM Linux Technology Center
Re: [PATCH 2 of 2] netconsole: add write-only tty driver
In reply to Hollis BlanchardQuoted 74 lines · Hollis Blanchard
This allows userspace to output to netconsole via the
/dev/consoledevice, which is very useful to see initscript output, for example. There is only one netconsole TTY device, and TTY output goes to all receivers specified for console output.Input via
/dev/consoleis still not implemented, however.Signed-off-by Hollis Blanchard <[email protected]>drivers/net/netconsole.c +44
-0@@ -43,6 +43,7 @@#include <linux/netpoll.h> #include <linux/inet.h> #include <linux/configfs.h> +#include <linux/tty.h> MODULE_AUTHOR ("Maintainer: Matt Mackall <[email protected]>" );MODULE_DESCRIPTION ("Console driver for network interfaces" );@@ -98,6 +99,8 @@ struct netconsole_target {int enabled;struct netpoll np; }; + +static struct tty_driver *netconsole_tty_driver;#ifdef CONFIG_NETCONSOLE_DYNAMIC @@ -728,15 +731,74 @@ static void netconsole_write_msg(const cspin_unlock_irqrestore (&target_list_lock, flags); } +static int netconsole_tty_open (struct tty_struct *tty,struct file *filp) +{ +return 0 ; +} + +static void netconsole_tty_close (struct tty_struct *tty,struct file *filp) +{ +} + +static int netconsole_tty_write (struct tty_struct *tty,const unsigned char *buf,int count) +{ +netconsole_write_msg (buf, count); +return count; +} + +static int netconsole_tty_write_room (struct tty_struct *tty) +{ +return MAX_PRINT_CHUNK ; +} + +static const struct tty_operations netconsole_tty_ops = { + .open = netconsole_tty_open, + .close = netconsole_tty_close, + .write = netconsole_tty_write, + .write_room = netconsole_tty_write_room, +}; + +static int __init netconsole_tty_init (void ) +{ + netconsole_tty_driver =alloc_tty_driver (1 ); +if (!netconsole_tty_driver) +return -ENOMEM ; + + netconsole_tty_driver->owner =THIS_MODULE ; + netconsole_tty_driver->driver_name ="netcon" ; + netconsole_tty_driver->name ="netcon" ; + netconsole_tty_driver->minor_start =0 ; + netconsole_tty_driver->type =TTY_DRIVER_TYPE_SYSTEM ; + netconsole_tty_driver->init_termios = tty_std_termios; + netconsole_tty_driver->init_termios.c_cflag =B9600 |CS8 |CREAD |HUPCL ; + netconsole_tty_driver->init_termios.c_ispeed =9600 ;
drivers/net/netconsole.c static void netconsole_write_msg(const c · line 784
Quoted 10 lines
drivers/net/netconsole.c +10
-0+ netconsole_tty_driver->init_termios.c_ospeed =9600 ; + netconsole_tty_driver->flags =TTY_DRIVER_REAL_RAW ; +tty_set_operations (netconsole_tty_driver, &netconsole_tty_ops); + +if (tty_register_driver (netconsole_tty_driver)) +printk (KERN_ERR "Couldn't register netconsole tty driver\n" ); + +return 0 ; +} +device_initcall (netconsole_tty_init);
I agree with Evgeniy that this should be merged into the existing init function. Otherwise there's reader ambiguity about the ordering. Otherwise this looks good.
Signature · 1 line
Mathematics is the supreme nostalgia of our time.
PATCH 1/1 netconsole: don't require struct console to send data
In reply to Hollis BlanchardThis will allow callers not on the console path to use write_msg().
drivers/net/netconsole.c +8 -3
@@ -67,7 +67,7 @@ __setup("netconsole=", option_setup);/* Linked list of all configured targets */ static LIST_HEAD (target_list); -/* This needs to be a spinlock because write_msg() cannot sleep */ +/* This needs to be a spinlock because netconsole_write_msg() cannot sleep */ static DEFINE_SPINLOCK (target_list_lock);/**
@@ -694,7 +694,7 @@ static struct notifier_block netconsole_ .notifier_call = netconsole_netdev_event, }; -static void write_msg (struct console *con,const char *msg,unsigned int len) +static void netconsole_write_msg (const char *msg,unsigned int len) {int frag, left;unsigned long flags;
@@ -728,10 +728,15 @@ static void write_msg(struct console *cospin_unlock_irqrestore (&target_list_lock, flags); } +static void netconsole_console_write (struct console *con,const char *msg,unsigned int len) +{ +netconsole_write_msg (msg, len); +} +static struct console netconsole = { .name ="netcon" , .flags =CON_ENABLED , - .write = write_msg, + .write = netconsole_console_write, };static int __init init_netconsole (void )
Re: [PATCH 1 of 2] netconsole: don't require struct console to send data
Quoted 30 lines · Hollis Blanchard
This will allow callers not on the console path to use
write_msg().Signed-off-by Hollis Blanchard <[email protected]>drivers/net/netconsole.c +3
-2@@ -67,7 +67,7 @@ __setup("netconsole=", option_setup);/* Linked list of all configured targets */ static LIST_HEAD (target_list); -/* This needs to be a spinlock because write_msg() cannot sleep */ +/* This needs to be a spinlock because netconsole_write_msg() cannot sleep */ static DEFINE_SPINLOCK (target_list_lock);/** @@ -694,7 +694,7 @@ static struct notifier_block netconsole_ .notifier_call = netconsole_netdev_event, }; -static void write_msg (struct console *con,const char *msg,unsigned int len) +static void netconsole_write_msg (const char *msg,unsigned int len) {int frag, left;unsigned long flags;@@ -728,10 +728,15 @@ static void write_msg(struct console *cospin_unlock_irqrestore (&target_list_lock, flags); } +static void netconsole_console_write (struct console *con,const char *msg,unsigned int len)
drivers/net/netconsole.c static void write_msg(struct console *co · line 740
Quoted 10 lines
drivers/net/netconsole.c +5
-1+{ +netconsole_write_msg (msg, len); +} +static struct console netconsole = { .name ="netcon" , .flags =CON_ENABLED , - .write = write_msg, + .write = netconsole_console_write, };
This looks fine functionally, but the name change strikes me as gratuitous.
Quoted 1 line
drivers/net/netconsole.c +0
-0static int __init init_netconsole (void )
Signature · 1 line
Mathematics is the supreme nostalgia of our time.
Quoted 8 lines · Hollis Blanchard
I have a Kuro Box (a small NAS device running Linux), and it has no serial console (nor any other console for that matter). The most convenient way to get boot output is via the netconsole driver, which is what most Kuro owners do. (The u-boot firmware even supports interactive netconsole allowing us to edit boot configuration.)
However, once past kernel boot, userspace currently has no way of outputting data over netconsole. These patches enable that, which is really useful for seeing init script output and debugging ramdisks before they've brought up sshd.
Awesome! I've been meaning to wire this up for ages. I'll try to look at it over the weekend.
Signature · 1 line
Mathematics is the supreme nostalgia of our time.
David Miller
maintainerFrom: Matt Mackall <[email protected]>
Date: Thu, 27 Nov 2008 17:09:45 -0600
Quoted 6 lines · Hollis Blanchard
Quoted 5 lines
I have a Kuro Box (a small NAS device running Linux), and it has no serial console (nor any other console for that matter). The most convenient way to get boot output is via the netconsole driver, which is what most Kuro owners do. (The u-boot firmware even supports interactive netconsole allowing us to edit boot configuration.)
Quoted 6 lines
Quoted 3 lines
However, once past kernel boot, userspace currently has no way of outputting data over netconsole. These patches enable that, which is really useful for seeing init script output and debugging ramdisks before they've brought up sshd.
Awesome! I've been meaning to wire this up for ages. I'll try to look at it over the weekend.
Matt if your review goes OK please ACK this and I'll toss these patches into net-next-2.6
Thanks