Re: Understanding the syslogd-linux Service Script

From: Colin Booth <>
Date: Tue, 8 Sep 2020 18:15:30 +0000

On Tue, Sep 08, 2020 at 12:53:37PM -0400, Scott Colby wrote:
> Hello,
> I am faced with running a program in a container that will only log
> to syslog and cannot be configured otherwise. I am looking to using
> s6 within the container to supervise this program and some
> implementation of syslog. I thought that there must be something
> simpler than rsyslog or syslog-ng, and my investigations led me to
> the s6/examples/syslogd-linux service directory.
> I am only slightly experienced with writing execline scripts and
> would like to better understand exactly what each line in the example
> run script is doing. Here it is, annotated with my understanding
> and questions.
Responses inline.
> #!/command/execlineb -P
> # Redirects stderr to stdout, but why is this necessary?
> fdmove -c 2 1
This is necessary because by default only stdout goes to the appendant
logger managed by s6-supervise. stderr is forwarded up to s6-svscan (and
the catch-all logger). It is also needed to prepare for stuff later on
in the script. Semanticaly this is actually pointing fd2 at the target
of fd1.
> # Clears the environment, I assume for general
> # security/isolation/cleanliness reasons?
> exec -c
Yup. Mostly cleanup, a little security.
> # Prepares for setting uid/gid later
> s6-envuidgid nobody
> # Redirects stdout to fd 3, I think because s6-ipcserver closes fd
> # 1; what happens to things sent to fd 3?
> # Also, why is the -c option not used here?
> fdmove 1 3
Welcome to Being Confused By Shell Redirection (don't worry, it happens
to everyone). fdmove 1 3 does not redirecct stdout to fd3, it points fd1
to fd3's target. Omitting the -c means that fd3 is closed after we
rewrite fd1's target. We close fd3 after this point because we don't
need it anymore.
> # Listens on /dev/log, this makes sense to me
> s6-ipcserver -U -1 -- /dev/log
> # Redirects stdout to stderr, because this is where log messages
> # are expected to go
> fdmove -c 1 2
s6-ipcserver -1 signals readyness on fd 1 and then closes it. This
re-opens fd1 (pointed at fd2's target, which was fd1's original target
at the start of the script) before launching ucspilogd log handlers.
This is needed because ucspilogd reads syslog type messages on stdin
(fd0) and writes the processed output on stdout (fd1). Note that this
happens individually for every new message flow established by
s6-ipcserver and not within the main control flow of the program, though
this doesn't matter here since the last thing the main program does is
establish an s6-ipcserver listener on /dev/log.
> # writes stdin to stdout with the values of the remote UID and GID
> # prepended, plus whatever other functionality of ucspidlogd
> Please let me know if I have made any mistakes in my annotation and
> what the answers to my questions are.
The fully annotated flow of the script is:
fd1 open, pointed at s6-log; fd2 open, pointed at catch-all; fd3 open,
pointed at s6-supervise readyness reader
fdmove -c 2 1:
fd1 open, pointed at s6-log; fd2 open, pointed at s6-log; fd3 open,
pointed at s6-supervise readyness reader
fdmove 1 3:
fd1 open, pointed at s6-supervise readyness reader; fd2 open, pointed at
s6-log; fd3 closed
s6-ipcserver -U -1 -- /dev/log
fd1 signaled ready and then closed; fd2 open, pointed at s6-log; fd3 closed
--- for each new sender attached to /dev/log ---
fd0 open, reading from /dev/log, fd1 open, writing to s6-log, fd2 open, writing to s6-log, fd3 closed.

Colin Booth
Received on Tue Sep 08 2020 - 18:15:30 UTC

This archive was generated by hypermail 2.3.0 : Sun May 09 2021 - 19:44:19 UTC