uml: terminal cleanup
PATCH 1/1 uml: terminal cleanup
Hi,
This is a major cleanup of the uml terminal drivers and console handling (console as in "where the kernel messages go to", not as in "linux virtual terminals"). The changes in detail:
(1) There is a new console driver calles "stderr" which (as the name implies) simply dumps all kernel messages to stderr. That one is registered very early in the boot process via console_initcall() and will print every almost kernel message instantly: Both very early in the boot process and very late in shutdown. Note that this is not enabled by default, see below for details.
(2) Ditched the early-console-init hackery in stdio_console.c (open_console(NULL) + related stuff) into the waste basket, not needed any more as you can use the new stderr console driver to get the kernel messages if your kernel crashes very early in the boot process.
(3) Handle console initialitation for the uml stdio console and virtual serial lines the normal way using the console->setup() function. Now all kernel messages appear on your console device once it is initialized without any dirty tricks.
(4) The (2) changes allow a number of further cleanups: As we don't open a line without a tty_struct any more we can ...
* hook struct line into tty->driver_data
* pass around tty_struct instead of struct line everythere
* get rid of some trivial wrappers in ssl.c and stdio_console.c because we can get struct line via tty_struct all the time now.
(5) Change the ordering in the arch/um/drivers/Makefile and thus the link and initialization order to make sure the stdio console and not the virtual serial line is the default console device.
(6) Fixed a number of Documentation/CodingStyle issues within the code (not systematically, but usually just the places I was touching anyway or where it bugged me while browsing the code because it was hard to read).
Looks like that cleanup also fixed some strange tty issues I've seen in the past (like console getty not responding to input sometimes, suse's /sbin/blogd causing trouble).
Finally some usage notes for using the new stderr console:
If the stderr console is enabled, then it is the default console device because it registeres very early in the boot process. But as it isn't linked to a tty device this makes init unhappy, you'll see "can't open initial console" error messages. Because you usually don't want that the stderr console is turned off by default. That also maintains the behavior that /dev/tty0 is the first console device registered and thus the default console.
There are basically two useful use cases for the stderr console:
(1) Your kernel dies before the normal console device is initialized and thus you don't see any messages. Just enable the stderr console to see them by adding "stderr=1" to the kernel command line.
(2) You want to have the kernel messages on both stderr and your console terminal device. Try something like this:
$ ./linux stderr=1 console=stderr console=ttyS0 ssl0=xterm
This example sets up the console on a virtual serial line and pops up an xterm for that.
Enjoy!
Gerd
--- arch/um/Kconfig_char | 6 arch/um/drivers/Makefile | 7 arch/um/drivers/chan_kern.c | 42 +++- arch/um/drivers/chan_user.c | 10 - arch/um/drivers/line.c | 265 +++++++++++++++++++------------ arch/um/drivers/pty.c | 3 arch/um/drivers/ssl.c | 126 ++++---------- arch/um/drivers/stderr_console.c | 45 +++++ arch/um/drivers/stdio_console.c | 148 +++++------------ arch/um/drivers/xterm.c | 4 arch/um/include/chan_kern.h | 10 - arch/um/include/chan_user.h | 5 arch/um/include/line.h | 16 + 13 files changed, 364 insertions(+), 323 deletions(-)
arch/um/Kconfig_char +6 -0
@@ -1,6 +1,12 @@ menu "Character Devices" +config STDERR_CONSOLE + bool "stderr console" + default y + help + console driver which dumps all printk messages to stderr. + config STDIO_CONSOLE bool default y
arch/um/drivers/Makefile +4 -3
@@ -20,8 +20,10 @@ ubd-objs := ubd_kern.o ubd_user.o port-objs := port_kern.o port_user.o harddog-objs := harddog_kern.o harddog_user.o -obj-y = -obj-$(CONFIG_SSL) += ssl.o +obj-y := stdio_console.o $(CHAN_OBJS) +obj-$(CONFIG_SSL) += ssl.o +obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o + obj-$(CONFIG_UML_NET_SLIP) += slip.o obj-$(CONFIG_UML_NET_SLIRP) += slirp.o obj-$(CONFIG_UML_NET_DAEMON) += daemon.o
@@ -41,7 +43,6 @@ obj-$(CONFIG_XTERM_CHAN) += xterm.o xter obj-$(CONFIG_UML_WATCHDOG) += harddog.o obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o -obj-y += stdio_console.o $(CHAN_OBJS) USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
arch/um/drivers/chan_kern.c +29 -13
97 lines not on this page · raw message
arch/um/drivers/chan_user.c +5 -5
@@ -110,7 +110,7 @@ static int winch_thread(void *arg) } } -static int winch_tramp (int fd,void *device_data,int *fd_out) +static int winch_tramp (int fd,struct tty_struct *tty,int *fd_out) {struct winch_data data;unsigned long stack;
@@ -144,7 +144,7 @@ static int winch_tramp(int fd, void *devreturn (pid); } -void register_winch (int fd,void *device_data) +void register_winch (int fd,struct tty_struct *tty) {int pid, thread, thread_fd;int count;
@@ -155,10 +155,10 @@ void register_winch(int fd, void *device pid =tcgetpgrp (fd);if (!CHOOSE_MODE_PROC (is_tracer_winch, is_skas_winch, pid, fd, - device_data) && (pid ==-1 )){ - thread =winch_tramp (fd, device_data, &thread_fd); + tty) && (pid ==-1 )){ + thread =winch_tramp (fd, tty, &thread_fd);if (fd !=-1 ){ -register_winch_irq (thread_fd, fd, thread, device_data); +register_winch_irq (thread_fd, fd, thread, tty); count =os_write_file (thread_fd, &c,sizeof (c));if (count !=sizeof (c))
arch/um/drivers/line.c +168 -97
460 lines not on this page · raw message
arch/um/drivers/pty.c +2 -1
@@ -58,7 +58,8 @@ int pts_open(int input, int output, int dev =ptsname (fd);sprintf (data->dev_name,"%s" , dev); *dev_out = data->dev_name; -if (data->announce) (*data->announce)(dev, data->dev); +if (data->announce) + (*data->announce)(dev, data->dev);return (fd); }
arch/um/drivers/ssl.c +38 -88
207 lines not on this page · raw message
arch/um/drivers/stderr_console.c new file +45 -0
45 lines not on this page · raw message
arch/um/drivers/stdio_console.c +46 -102
206 lines not on this page · raw message
arch/um/drivers/xterm.c +2 -2
@@ -126,9 +126,9 @@ int xterm_open(int input, int output, inif (data->stack ==0 )free_stack (stack,0 ); -if (data->direct_rcv) +if (data->direct_rcv) { new =os_rcv_fd (fd, &data->helper_pid); -else { + }else { err =os_set_fd_block (fd,0 );if (err <0 ){ printk("xterm_open : failed to set descriptor "
arch/um/include/chan_kern.h +7 -3
@@ -8,7 +8,9 @@#include "linux/tty.h" #include "linux/list.h" +#include "linux/console.h" #include "chan_user.h" +#include "line.h" struct chan {struct list_head list;
@@ -24,7 +26,7 @@ struct chan { };extern void chan_interrupt (struct list_head *chans,struct work_struct *task, -struct tty_struct *tty,int irq,void *dev); +struct tty_struct *tty,int irq);extern int parse_chan_pair (char *str,struct list_head *chans,int pri,int device,struct chan_opts *opts);extern int open_chan (struct list_head *chans);
@@ -32,9 +34,11 @@ extern int write_chan(struct list_head * int write_irq);extern int console_write_chan (struct list_head *chans,const char *buf,int len); +extern int console_open_chan (struct line *line,struct console *co, +struct chan_opts *opts);extern void close_chan (struct list_head *chans); -extern void chan_enable_winch (struct list_head *chans,void *line); -extern void enable_chan (struct list_head *chans,void *data); +extern void chan_enable_winch (struct list_head *chans,struct tty_struct *tty); +extern void enable_chan (struct list_head *chans,struct tty_struct *tty);extern int chan_window_size (struct list_head *chans,unsigned short *rows_out,unsigned short *cols_out);
arch/um/include/chan_user.h +3 -2
@@ -42,8 +42,9 @@ extern int generic_window_size(int fd, v unsigned short *cols_out);extern void generic_free (void *data); -extern void register_winch (int fd,void *device_data); -extern void register_winch_irq (int fd,int tty_fd,int pid,void *line); +struct tty_struct ; +extern void register_winch (int fd,struct tty_struct *tty); +extern void register_winch_irq (int fd,int tty_fd,int pid,struct tty_struct *tty);#define __channel_help (fn, prefix) \ __uml_help(fn, prefix "[0-9]*=<channel description>\n" \
arch/um/include/line.h +9 -7
@@ -37,7 +37,6 @@ struct line {struct list_head chan_list;int valid;int count; -struct tty_struct *tty;struct semaphore sem;char *buffer;char *head;
@@ -53,8 +52,6 @@ struct line { init_pri : INIT_STATIC, \ chan_list : { }, \ valid : 1, \ - count : 0, \ - tty : NULL, \ sem : { }, \ buffer : NULL, \ head : NULL, \
@@ -69,17 +66,22 @@ struct lines {#define LINES_INIT (n) { num : n } -extern void line_close (struct line *lines,struct tty_struct *tty); +extern void line_close (struct tty_struct *tty,struct file * filp);extern int line_open (struct line *lines,struct tty_struct *tty,struct chan_opts *opts);extern int line_setup (struct line *lines,int num,char *init,int all_allowed); -extern int line_write (struct line *line,struct tty_struct *tty,const char *buf,int len); +extern int line_write (struct tty_struct *tty,const unsigned char *buf,int len); +extern void line_put_char (struct tty_struct *tty,unsigned char ch); +extern void line_set_termios (struct tty_struct *tty,struct termios * old); +extern int line_chars_in_buffer (struct tty_struct *tty);extern int line_write_room (struct tty_struct *tty); +extern int line_ioctl (struct tty_struct *tty,struct file * file, +unsigned int cmd,unsigned long arg);extern char *add_xterm_umid (char *base); -extern int line_setup_irq (int fd,int input,int output,void *data); +extern int line_setup_irq (int fd,int input,int output,struct tty_struct *tty);extern void line_close_chan (struct line *line); -extern void line_disable (struct line *line,int current_irq); +extern void line_disable (struct tty_struct *tty,int current_irq); extern struct tty_driver * line_register_devfs(struct lines *set, struct line_driver *line_driver, struct tty_operations *driver,
Signature · 1 line
#define printk(args...) fprintf(stderr, ## args)