Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Jan 2002 19:58:58 -0800
From:      Terry Lambert <tlambert2@mindspring.com>
To:        Leo Bicknell <bicknell@ufp.org>
Cc:        John Baldwin <jhb@FreeBSD.org>, freebsd-hackers@FreeBSD.org, Alfred Perlstein <bright@mu.org>
Subject:   Re: serial console + boot blip
Message-ID:  <3C3E6302.9EF1ADBC@mindspring.com>
References:  <20020111001143.GA19003@ussenterprise.ufp.org> <XFMail.020110161607.jhb@FreeBSD.org> <20020111004218.GA19608@ussenterprise.ufp.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Leo Bicknell wrote:
> So that leaves getty.  I'm a bit confused here, but it appears getty
> (for the console) looks like this:
> 
> initialize to getty defaults
> initialize to configured values (from gettytab)
> log in user
> 
> I believe the problem is occuring with the initalize to defaults.  I
> think that's causing the port to lower DTR, and hang up the session,
> then it gets the gettytab values and is good to go again.

No.

DTR is dropped fron on-to-off on final close.  So that means
that if you log out, get the terminal revoked from everyone,
then there is an on-to-off DTR as the number of openers drops
to 0.

The DTR goes high again when the number of opener goes from
0->1 (the first open).

Getty opens the tty, but that open doesn't complete unless
O_NDELAY is set.  What happens instead is that the open
hangs, pending off-to-on transition of DCD from the modem
(or DTR, if you are using a nullmodem cable to connect to
a terminal, and it's correctly wired -- see "Technical aspects
of data communication" by McKneely, from Digital Press).

In any case, the settings on the port are not set away from
the compile time defaults to the gettytab values until *after*
the open completes (this is, incidently, after the modem has
sent the "my baud rate I connected at is XXX and I got a
data/fax/voice call", so that's discarded completely).

The reason the open doesn't complete is so that you can open
the port from another process: an outbound dialing process (the
open is always O_NDELAY), and that open will block the open in
the getty from completing.  Traditionally, this was managed by
setting O_EXCL on the getty open, and, since an exclusive open
could not be completed, then when DCD from the outbound call
went high, the open would not complete.

This was problematic for programs that spawned children to do
things like file transfers or terminal emulation, since there
was a bug in SYSV where the O_EXCL bit would be set before the
open was completed, and not reset if another opener with
O_NDELAY opened the port.  To get around this, you attempted
a blocking open without O_EXCL set, alarmed out of it, and
then opened O_NDELAY (this unset the O_EXCL bit in the tty
data structure in the driver; eventually, USL moved the 12
lines of code for this 22 lines further down in the driver,
fixing this bug).

HDB UUCP added "uugetty"; this is sort of like "mgetty"; it
opens the port O_NDELAY.  This means that it can change the
settings, if it wants.  But the open in that case was done
*always*, so what it had to do was periodically check to
see if there was a lock file present, or if data was there;
if a lock file was present (outbound UUCP locked the tty),
then the getty would back off for a time period, and retry
once the lock file went away (as bidirectional port code went,
this sucked).

FreeBSD has "mgetty".  Actually, it would probably be more
correct to cause the open to hand until RI went high -- the
modem rand because of an incoming call -- instead of DCD
going high, but since Apple 8 pin serial cables discard RI,
no one has done the code for this yet.

Unfortunately, it's even more complicated, since the DCD
semantics only effect the first open in a process, so if you
set O_NDELAY, then subsequent open attempts succeed.

Actually, since on lder systems, you could not turn off the
O_NDELAY non-blocking I/O once triggered, you had to:

1)	Blocking open with alarm to unset the O_EXCL
2)	Open with O_NDELAY to get open without DCD present
3)	Open without O_NDELAY to get blocking I/O (the
	open succeeded because of #2)
4)	Close the descriptor from step #2.

Wheee!  Platform independent UNIX serial I/O is fun!


> I'm not sure if the defaults are needed for some reason (there are a
> lot of oddball terminals out there), but I find it likely the right
> thing to do is a single init, that is:
> 
> get default values
> merge in configured values (from gettytab)
> init with default+merged values

You have to use mgetty for this, if you want to use "standard"
stuff to do the job without having to write your own code.  An
alternative is to open the port with another process O_NDELAY,
spam the settings on it, and just keep them there.

Alternately, you could change the compiled in default settings
at the time you build your kernel.

At ClickArray, we used another process to open the serial port
and SPAM the settings so that we could echo out boot time
messages to the serial port from the startup scripts, without
also echoing out the FreeBSD startup code (technical customers
kept asking to have all the messages, but there was some insane
idea that FreeBSD messages coming out the serial port would be
a bad thing marketing-wise; I never understood the paranoia,
and I still don't).

> getty is a bit, well, cryptic to someone who doesn't normally write
> terminal code, is there a getty expert in the house?

Just realize that it never does anything until after the init
scripts are done running, no matter what (nothing run from
/etc/tys can), and realize that it doesn't change the port
settings until the open is complete, and that it resets to the
compile-time defaults every time the last opener closes it.


If you could describe *exactly* what behaviour you wanted and
*exactly* when you wanted it, someone could probably give you
a better approach to what you are trying to do thatn futzing
with the gettytab.

-- Terry

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3C3E6302.9EF1ADBC>