Consider a machine with an s6-linux-init-maker-style setup, that also
uses s6-rc in the stage2 and stage2_finish scripts. Longruns managed
by s6-rc without a 'producer-for' file in their definition directory
have their stdout and stderr redirected to the catch-all logger, and
so do oneshots via the s6rc-oneshot-runner service. So if one wants to
have a service output to the console instead (e.g. an early one in the
boot process), its definition would have to do explicit redirections
to /dev/console. But should the service also be turned into a session
leader and set a controlling terminal, or only in special cases?

 s6-supervise already runs its run script as a session leader, unless
there's a ./nosetsid file in the service directory. (Not doing so would
mean running all the services in the same session as the supervision
tree, which can have bad consequences if there's a controlling terminal
attached to the session.)

 Few services need a controlling terminal, and the ones that do, like
for instance getty, usually allocate one themselves. Standard daemons
that "run in the background" absolutely do not want one. A controlling
terminal is the exception rather than the rule - so it's not the
supervisor's job to provide one.

 If you want a service to output to the console, or to a terminal,
then an explicit redirection is indeed the right way to do it, and
you most likely have no use for a controlling terminal.


I thought that this was needed only in special cases, like in
processes that end up spawning a shell, but I see other init systems
sometimes do it automatically. For example, with nosh, a service
configured to output to a terminal AND defined using a systemd unit
file, when converted to a bundle directory (nosh's version of a
service definition directory) with the converter tool, has a 'run'
script that calls open-controlling-tty (nosh's chainloading utility to
open a device as a controlling terminal). And sysvinit's code has
setsid() and TIOCSCTTY ioctl() calls for child processes, depending on
the 'runlevel' and 'action' fields of the corresponding line in
/etc/inittab.

 The setsid() is normal: init wants the daemons it supervises to run
in their own session, that makes sense. s6-supervise does the same thing.

 I have no idea what the TIOCSCTTY is for, though. *What* device would
you open as a controlling terminal in the general case? When init starts,
/dev/console is explicitly *not* a terminal (which is why you can't have
job control when using a shell as init).
 The only explanation I can see is that the supervision abilities of
sysvinit are only used for gettys, and sysvinit opens /dev/ttyN, N
being specified on the getty line in /etc/inittab. But it's a wild
guess, and probably inaccurate.

 I have no idea what systemd does and I don't think it would be a good
indicator of what *should* be done anyway. I suspect that the use of
open-controlling-tty is there to mimic systemd's behaviour exactly;
maybe Jonathan can shed more light on this. I'm not sure he's on the
skaware ML though; this conversation would have a place on the
supervision ML (I'll repost tomorrow night when I'm at home with my
usual tools and more time).


What those two cases have in common is that the mechanism involved
also unconditionally redirects stdin to a terminal device; in the nosh
case, I'm not sure if because of a limitation of the unit
file-to-bundle directory converter. But I don't know why the
"controlling terminal maneuver" is done there, so I now wonder if
s6-rc service definitions would also require it in more cases than I
thought, instead of simple FD redirections.

 I honestly believe the controlling terminal thing is a historical
artefact that should not be there, because it is useless or even detrimental
for most daemons, and supervised programs that do need a controlling
terminal perform the maneuvers themselves. But it would be interesting
indeed to hear confirmation, and in particular to have Jonathan's opinion
about this.

--
 Laurent

Reply via email to