--- linux-2.6.4-orig/arch/um/Kconfig_char Wed Mar 10 23:55:26 2004 +++ linux-2.6.4/arch/um/Kconfig_char Wed Mar 31 22:18:21 2004 @@ -5,6 +5,14 @@ bool default y +config LOSSLESS_STDIO_CONSOLE + bool "Lossless standard output console" + depends on STDIO_CONSOLE + help + When console output goes to standard output, retry write operations + that would block. This is particularly useful when recording the + output of a UML system in a file. + config SSL bool "Virtual serial line" help --- linux-2.6.4-orig/arch/um/drivers/Makefile Tue Mar 16 03:11:43 2004 +++ linux-2.6.4/arch/um/drivers/Makefile Fri Apr 2 16:57:21 2004 @@ -41,6 +41,7 @@ obj-$(CONFIG_UML_WATCHDOG) += harddog.o obj-$(CONFIG_BLK_DEV_COW) += cow_kern.o obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o +obj-$(CONFIG_LOSSLESS_STDIO_CONSOLE) += console_user.o obj-y += stdio_console.o $(CHAN_OBJS) --- linux-2.6.4-orig/arch/um/drivers/stdio_console.h Wed Mar 10 23:55:26 2004 +++ linux-2.6.4/arch/um/drivers/stdio_console.h Fri Apr 2 17:09:00 2004 @@ -7,6 +7,9 @@ #define __STDIO_CONSOLE_H extern void save_console_flags(void); + +void lossless_stdio_console_write(const char *string,unsigned len); + #endif /* --- linux-2.6.4-orig/arch/um/drivers/stdio_console.c Tue Mar 16 03:11:43 2004 +++ linux-2.6.4/arch/um/drivers/stdio_console.c Fri Apr 2 17:09:05 2004 @@ -194,6 +194,9 @@ static void console_write(struct console *console, const char *string, unsigned len) { +#ifdef CONFIG_LOSSLESS_STDIO_CONSOLE + lossless_stdio_console_write(string,len); +#else struct line *line = &vts[console->index]; if(con_init_done) @@ -201,6 +204,7 @@ console_write_chan(&line->chan_list, string, len); if(con_init_done) up(&line->sem); +#endif } static struct tty_driver *console_device(struct console *c, int *index) --- /dev/null Fri Dec 12 23:38:58 2003 +++ linux-2.6.4/arch/um/drivers/console_user.c Fri Apr 2 17:20:37 2004 @@ -0,0 +1,62 @@ +/* + * arch/um/drivers/console_user.c - Lossless console driver using write(2) + * + * Written 2003,2004 by Werner Almesberger + */ + + +#include +#include +#include +#include +#include +#include + +#include "stdio_console.h" + + +/* + * UML makes the console non-blocking. And indeed, even when stdout is + * redirected to a file, we may occasionally get EAGAIN, and lose a message or + * ten. This console write function just retries the write, without affecting + * other users of the console. + */ + + +void lossless_stdio_console_write(const char *string,unsigned len) +{ + static int console_broken = 0; + static char buf[100]; /* check with message size, below */ + const char *p; + int wrote; + + if (console_broken) + return; + + for (p = string; len; p += wrote) { + while (1) { + wrote = write(1,p,len); + if (wrote >= 0) + break; + + if (errno == EINTR) + continue; + if (errno == EAGAIN) { + usleep(100000); /* nap for 100ms */ + continue; + } + + /* + * We're in trouble. Try to get the message out on + * stderr, then turn off the console. + */ + sprintf(buf,"Console write failed with errno %d. " + "Disabling console.\r\n",errno); + (void) write(2,buf,strlen(buf)); + + console_broken = 1; + return; + } + len -= wrote; + } +}