supervision - discussion about system services, daemon supervision, init, runlevel management, and tools such as s6 and runit
 help / color / mirror / Atom feed
From: Ellenor Bjornsdottir <ellenor@umbrellix.net>
To: supervision@list.skarnet.org
Subject: Re: First time caller to the show - am I understanding the fifo trick correctly?
Date: Wed, 25 Aug 2021 12:19:54 +0000	[thread overview]
Message-ID: <1C375DE4-A780-473D-8F34-8E0CA1F171EF@umbrellix.net> (raw)
In-Reply-To: <em94f287eb-7715-45b2-a9bf-538ac6825a48@elzian>

[-- Attachment #1: Type: text/plain, Size: 4521 bytes --]

Personally, I'm ~banging my head against the wall by~ writing a fork of FreeBSD init which, instead of moving to its read_ttys stage, achieves what s6-l-i does with spawning runcom2 and (s6-)svscan (but does so in a sufficiently generic manner that you don't have to do the blocking fifo trick during runcom2 if you don't want to).

On 25 August 2021 11:57:11 UTC, Laurent Bercot <ska-supervision@skarnet.org> wrote:
>>Forgiving privilege separation failures and minor grammatical mistakes, does it look as if I understand the fifo trick's application in practice?
>
>  Hi Ellenor,
>  Yes, I think you have the right idea.
>
>  The goal here is to redirect s6-svscan's own stdout and stderr to
>the stdin of the catch-all logger process, so that the supervision
>tree's messages, and the messages from every service that lacks a
>dedicated logger, go to the catch-all logger instead of /dev/console.
>(Because /dev/console is a terrible default place to send logs and
>should only be used for very critical messages such as kernel panics,
>or, in our userland case, for catch-all logger failures.)
>
>  The problem is that we want the catch-all logger to run as a service
>under the supervision tree, so the s6-log process does not exist yet
>when we exec into s6-svscan: it will be spawned later as a grandchild
>of s6-svscan (with an s6-supervise intermediary). So we cannot use an
>anonymous pipe for this.
>
>  We use a fifo instead: we can redirect init's stdout and stderr to
>a fifo, and later on, when the catch-all logger starts, we can
>instruct it (in its run script) to read from the fifo.
>
>  But the Unix fifo semantics say that we *cannot* open a fifo for
>writing while there is no reader: open() would either block (default
>flags) or return -1 ENXIO (with O_NONBLOCK). So the "fifo trick" is:
>1. open the fifo for reading
>2. open it for writing, which now works
>3. close the reading end
>
>At this point, any write() to the fifo will fail with -1 EPIPE. That is
>not a problem per se, except it will also generate a SIGPIPE, so in
>order to avoid crashing and burning, it is important to ignore SIGPIPE
>at the very least - or, better, to make sure that no process writes to
>the fifo until the catch-all logger is up. This is the case for 
>s6-svscan
>and s6-supervise, so our system structure is safe; but we need to make
>sure that no other process starts before the catch-all logger is up,
>else they will just eat a SIGPIPE and die.
>
>  In the s6-l-i model, s6-svscan is executed as soon as possible, on a
>very minimal supervision tree that only contains the catch-all logger
>and a few other essential "early services" (such as the shutdown daemon
>and an early getty). All the rest of the initialization is done in
>"stage 2 init", which is a script run as a child of s6-l-i's.
>So the end of the "fifo trick" uses the Unix fifo semantics as a
>synchronization mechanism:
>4. fork
>5. In the child, close our fd to the fifo
>6. In the child, open the fifo for writing once again,
>    *without* O_NONBLOCK.
>
>  This last open() will block until the fifo has a reader. That
>ensures the child will only resume once the parent has completed
>its work and executed into s6-svscan, and the supervision tree has
>started and the catch-all logger is running. Then the child can exec
>into stage 2 init and perform the rest of the work with the guarantee
>that the supervision tree is operational and all the stdout and stderr
>messages go to the catch-all logger by default.
>
>  To see exactly how to implement stage 1 init and the fifo trick as
>an execline script, you can checkout (or download) any version of
>s6-l-i *prior to* 1.0.0.0; try version 0.4.0.1, downloadable from
>skarnet.org if you type the URL by hand, and accessible via the
>v0.4.0.1 tag in git. It is very different from what it is now, as in
>there is no sysv compatibility at all, but stage 1 should be
>understandable.
>
>  A few months ago, I tried adding a few conditional compilation options
>to s6-l-i to make it work under FreeBSD, but unfortunately the
>organization of the FreeBSD init is so different from Linux's,
>especially shutdown-wise, that my attempt only succeeded in turning
>the package into an unholy plate of spaghetti. At some point in the
>future, however, a similar-but-separate s6-freebsd-init package may
>make sense.
>
>--
>  Laurent
>

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.

  reply	other threads:[~2021-08-25 12:20 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <202108250806.17P86E1p031259@invictus.wa.us.umbrellix.net>
2021-08-25 11:57 ` Laurent Bercot
2021-08-25 12:19   ` Ellenor Bjornsdottir [this message]
2021-08-25  8:06 Ellenor Malik

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1C375DE4-A780-473D-8F34-8E0CA1F171EF@umbrellix.net \
    --to=ellenor@umbrellix.net \
    --cc=supervision@list.skarnet.org \
    --subject='Re: First time caller to the show - am I understanding the fifo trick correctly?' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).