Currently, the s6-linux-init-runleveld service is an s6-sudod process invoked with options -0, -1 and -2. Therefore, if the scripts/runlevel script prints messages to its standard output, they are lost, because it is redirected to /dev/null. So it can't do that. And messages printed to its standard error go to the catch-all logger, which may or may not display them on the console, depending on configuration.
Right.
However, the only thing that triggers execution of scripts/runlevel is the s6-linux-init-telinit program, right? I expect that in most cases it would be run manually by the administrator from an interactive shell. So wouldn't it be better to drop the -0, -1 and -2 options, so that the script's messages go to s6-linux-init-telinit's standard file descriptors, i.e. display on the controlling terminal of the administrator's shell in most cases?
Well, there's a reason for that choice. A common problem that people have with s6-rc is when they run it from a xterm, and s6-rc downs a set of services that includes the X server, so s6-rc gets killed and cannot perform the rest of its work. The runleveld service is meant to avoid this pitfall. When the admin runs telinit, it usually means a pretty drastic change in the machine state, and there's no guarantee that the admin's shell will even exist in the new state. If you're in runlevel 5 and perform "telinit 2", you will lose your xterm. Connecting the client's standard decriptors to the runleveld service will kill the instance when the client dies, whereas using -0 -1 -2 makes the instance immune to that. ... And writing this I have a doubt, and go check the code, and realize that it's bullsh*t, because s6-sudod kills its child when the client connection is closed without even checking the descriptors. So I need to change something there. Probably a separate option to s6-sudod that says "don't kill the child when the connection dies"; but the -0 -1 -2 options will need to stay, because if the fds become invalid it could be bad for the runlevel script. Thanks for your suggestion, then, it will lead to some bugfixing :D but I think it's more important, in the case of a drastic state change, to honor the expectation that the operation will be completed even if the rug is being swept from under telinit's feet, than to perform cosmetic message redirection.
Woulnd't it be better to drop the -e option from s6-linux-telinit's s6-sudo invocation, so that the script can have access to s6-linux-init-telinit's environment, if written to do so?
That one is a hard no. The runlevel script can also be run by the rc.init script at boot time, for instance. It's important that the behaviour of the script be the same no matter where it's run from - that's a core tenet of supervision. (Ideally the rc.init script would call telinit instead of runlevel, but since it's boot time the environment is controlled and we can save a little time and complexity by not going through the telinit-sudo-runleveld thing.) If you allow the runlevel script to depend on the telinit environment, you can bet your donkey that somebody somewhere is going to do fancy, clever, smart things with the environment, then forget about it, and spend too much time debugging when it inevitably breaks. Note that if you know you need it, nothing prevents you from editing s6-l-i-m's output before using it. :) I just don't want to change the default behaviour on this. -- Laurent
