From patchwork Wed Apr 2 18:59:04 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Struan Bartlett X-Patchwork-Id: 336410 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id E31F7140125 for ; Thu, 3 Apr 2014 06:06:09 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932958AbaDBTF1 (ORCPT ); Wed, 2 Apr 2014 15:05:27 -0400 Received: from coen-mx.newsnow.co.uk ([213.146.191.129]:45355 "EHLO coen-mx.newsnow.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932850AbaDBTF0 (ORCPT ); Wed, 2 Apr 2014 15:05:26 -0400 X-Greylist: delayed 376 seconds by postgrey-1.27 at vger.kernel.org; Wed, 02 Apr 2014 15:05:25 EDT Received: from vm8.vm.dc.lan ([192.168.2.28] helo=sb-wheezy) by coen-mx.newsnow.co.uk with esmtp (Exim 4.80) (envelope-from ) id 1WVQNM-00032m-Dr; Wed, 02 Apr 2014 19:59:04 +0100 Received: from struan by sb-wheezy with local (Exim 4.80) (envelope-from ) id 1WVQNM-00039L-Co; Wed, 02 Apr 2014 19:59:04 +0100 Date: Wed, 2 Apr 2014 19:59:04 +0100 From: Struan Bartlett To: Matt Mackall Cc: linux-kernel@vger.kernel.org, Andreas Schwab , netdev@vger.kernel.org, "David S. Miller" , Nikolay Aleksandrov , Andy Shevchenko , Greg Kroah-Hartman , Jiri Pirko , Joe Perches , Dan Aloni Subject: [PATCH v3] netconsole: Add tty driver Message-ID: <20140402185904.GD11734@NewsNow.co.uk> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Adds tty driver to netconsole module. When module is loaded, creates /dev/netcon0 device and enables support for console=netcon0 kernel cmdline option, causing /dev/console output to be sent to /dev/netcon0. This allows startup/shutdown script output from headless platforms to be logged over (secure) network (subject to availability of specified network device). To: Matt Mackall Signed-off-by: Struan Bartlett --- Changes since v1: * Fixed whitespace mangled by broken mailer Changes since v2: * Fixed general mangling by email client (hopefully) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html --- a/drivers/net/netconsole.c 2014-03-31 04:40:15.000000000 +0100 +++ b/drivers/net/netconsole.c 2014-04-01 11:58:50.000000000 +0100 @@ -15,6 +15,7 @@ * generic card hooks * works non-modular * 2003-09-07 rewritten with netpoll api + * 2014-03-31 tty driver by Struan Bartlett */ /**************************************************************** @@ -47,6 +48,7 @@ #include #include #include +#include MODULE_AUTHOR("Maintainer: Matt Mackall "); MODULE_DESCRIPTION("Console driver for network interfaces"); @@ -728,7 +730,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 _write_msg(const char *msg, unsigned int len) { int frag, left; unsigned long flags; @@ -764,10 +766,63 @@ static void write_msg(struct console *co spin_unlock_irqrestore(&target_list_lock, flags); } +static void write_msg(struct console *con, const char *msg, unsigned int len) +{ + _write_msg(msg, len); +} + +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) +{ + _write_msg(buf, count); + return count; +} + +static int netconsole_tty_put_char(struct tty_struct *tty, unsigned char ch) +{ + char temp[2] = { ch, 0 }; + _write_msg(temp, 1); + return 1; +} + +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, + .put_char = netconsole_tty_put_char, + .write_room = netconsole_tty_write_room, +}; + +static struct tty_port netconsole_tty_port; +static struct tty_driver *netconsole_tty_driver; + +static struct tty_driver *netconsole_device(struct console *co, int *index) +{ + if (!(co->flags & CON_ENABLED)) + return NULL; + *index = co->index; + return netconsole_tty_driver; +} + static struct console netconsole = { .name = "netcon", .flags = CON_ENABLED, .write = write_msg, + .device = netconsole_device }; static int __init init_netconsole(void) @@ -802,11 +857,39 @@ static int __init init_netconsole(void) if (err) goto undonotifier; + netconsole_tty_driver = alloc_tty_driver(1); + if (!netconsole_tty_driver) { + err = -ENOMEM; + goto undonotifier; + } + + tty_port_init(&netconsole_tty_port); + + netconsole_tty_driver->driver_name = "netcon"; + netconsole_tty_driver->name = "netcon"; + netconsole_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM; + netconsole_tty_driver->subtype = SYSTEM_TYPE_TTY; + netconsole_tty_driver->init_termios = tty_std_termios; + netconsole_tty_driver->init_termios.c_iflag = 0; + netconsole_tty_driver->init_termios.c_oflag = 0; + netconsole_tty_driver->flags = TTY_DRIVER_REAL_RAW; + + tty_set_operations(netconsole_tty_driver, &netconsole_tty_ops); + tty_port_link_device(&netconsole_tty_port, netconsole_tty_driver, 0); + + err = tty_register_driver(netconsole_tty_driver); + if (err) + goto undotty; + register_console(&netconsole); pr_info("network logging started\n"); return err; +undotty: + put_tty_driver(netconsole_tty_driver); + tty_port_destroy(&netconsole_tty_port); + undonotifier: unregister_netdevice_notifier(&netconsole_netdev_notifier); @@ -830,6 +913,10 @@ static void __exit cleanup_netconsole(vo { struct netconsole_target *nt, *tmp; + tty_unregister_driver(netconsole_tty_driver); + put_tty_driver(netconsole_tty_driver); + tty_port_destroy(&netconsole_tty_port); + unregister_console(&netconsole); dynamic_netconsole_exit(); unregister_netdevice_notifier(&netconsole_netdev_notifier);