Consoles, past and future.

Poul-Henning Kamp phk at phk.freebsd.dk
Fri Sep 2 00:39:22 PDT 2005


	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 at 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.


More information about the freebsd-arch mailing list