Date: Fri, 02 Sep 2005 09:39:19 +0200 From: Poul-Henning Kamp <phk@phk.freebsd.dk> To: arch@freebsd.org Subject: Consoles, past and future. Message-ID: <34182.1125646759@phk.freebsd.dk>
next in thread | raw e-mail | index | archive | help
Console n. [From Latin consolatio(n) "comfort, spiritual solace"]. A device for displaying or printing condolences and obituaries for the operator. -- The Devils DP Dictionary As I probably too briefly said in my previous email, the console code is a major headache for tty and device locking and something needs to happen. I would like to propose that we let something radical happen to our rather archaic concept of a "console" which still to a large degree is based on the fact that all PDP and VAX computers came with a hardcopy system console terminal. Here is my analysis: If we look at what the console code _does_ for us right now, (as opposed to what features it sports), we find a number of distinct functionalities: 1. Kernel boot progress indicator. All the device probe and attach etc. API: printf(9) and friends. 2. Single user terminal connection For manually fixing things before /etc/rc is run. API: Any tty(4) (and various other) devices will do. 3. System initialization progress indicator. The output from /etc/rc and its spawn. API: any file, pipe, stream socket and most devices will do. Using a tty(4) gives the ability to SIGINT processes which hang/sleep/get confused during startup. 4. Alert channel to the system responsible person. API: printf(9), log(9) or syslog. 5. Fall back input channel for dump(8) and a few other programs. If dump is run in the background it will ask for tape-changes on /dev/console. API: any tty(4) device which can be opened. 6. Kernel startup input channel Asking for root device. API: printf(9), gets(9). 7. Kernel panic fact recorder API: printf(9) 8. Kernel debugger interface. API: db_printf(9) etc. 9. Remote debugger interface. API: sys/gdb uses special hooks into relevant device driver. If we look at how this is all implemented presently: In the kernel, devices which can support a console publish a few functions, getchar(), putchar() etc. These functions are special in that they can not rely on interrupts and locking to be functional. A (somewhat) central body of code selects which console device(s) to use. kern.console is handled here. printf(9) and all that stuff, calls into the central console code. db_printf(9) is more or less just the same. gdb(9) has its own hooks into the device driver. I'm not sure I know why, but it probably makes sense. A special magic piece of code is the device driver for /dev/console which does not, as one would think, implement a tty which calls the console code, but rather tries to shortcut to the tty device which the device driver has associated with the same hardware as the console functionality. Since open of /dev/console should in principle always succeed, some rather evil stuff happens here. The major part of the trouble comes from the /dev/console implementation and its rather intimate abuse of ttys and this is the bits we need to fix. For now we can just leave point 1, 6, 7, 8 & 9 as is. That leaves 2, 3, 4, 5. Nobody mandates that 2 & 3 has to happen on "/dev/console", /sbin/init could open any device it prefer for this, so if the device drivers export a proposed device name along with their console functions, /sbin/init could pick this up with a sysctl and proceed from there. The loader could present a hint to override this. That leaves us with 4 and 5, which we can't do much about because short-sighted UNIX standards which goldpated the past rather than steer the future and therefore mandate that /dev/console must be a tty(4) device. But we can implement /dev/console as a pseudo device driver without breaking anything. Most people these days view this part of the console functionality through syslog or xconsole(-like) programs anyway which uses various ioctls to get their bit of the cake. In order to stay compatible with old stuff, we could use a null-modem backside device so that people could say "tip console" and interact with dump(8) that way. (Keeping a buffer of the most recent 2K output and replaying that on open would probably be a good idea). The driver would also have the task of directing the output to /dev/console to syslogd for permanent recording. Thanks for listening. -- Poul-Henning Kamp | UNIX since Zilog Zeus 3.20 phk@FreeBSD.ORG | TCP/IP since RFC 956 FreeBSD committer | BSD since 4.3-tahoe Never attribute to malice what can adequately be explained by incompetence.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?34182.1125646759>