supervision - discussion about system services, daemon supervision, init, runlevel management, and tools such as s6 and runit
 help / color / mirror / Atom feed
* s6-rc-update does not create pipes when already-running service becomes a consumer
@ 2023-09-26 14:33 Adam Joseph
  2023-09-26 19:23 ` Laurent Bercot
  0 siblings, 1 reply; 3+ messages in thread
From: Adam Joseph @ 2023-09-26 14:33 UTC (permalink / raw)
  To: supervision

A simple script to demonstrate this problem is attached below.

It appears that s6-rc-update will neglect to create the needed pipes in the
following situation:

1. A service X is already running before s6-rc-update is invoked
2. Service X was not the consumer-for any other service prior to s6-rc-update
3. Service X is the consumer-for at least one service after s6-rc-update

A similar problem occurs with producer-for.

The fix is relatively straightforward; in fill_convtable_and_flags() a check is
needed to detect if olddb->services[i].x.longrun.nproducers==0 is different from
newdb->services[x].x.longrun.nproducers==0; if so, the
NEWSTATE_IS_BIJECTIVE_CONVERSION_TARGET flag should not be added to newstate[x]
and instead OLDSTATE_RESTART should be added to oldstate[i].  I have a patch
that implements this, and the corresponding check for longrun.consumer.

Below is a crude shell script which demonstrates the bug.  It does not require
root.  Before running the script below, you must run the following command on a
different terminal (you'll want to observe its output):

mkdir -p /tmp/live/service
s6-svscan -- /tmp/live/service/

Here is the script:

#!/bin/bash
mkdir -p source/consumer
echo longrun > source/consumer/type
echo -e '#!/bin/bash\ncat > /dev/null' > source/consumer/run
chmod +x source/consumer/run

mkdir source/producer
echo longrun > source/producer/type
echo -e '#!/bin/bash\nwhile true; do sleep 1; date; done\n' > source/producer/run
chmod +x source/producer/run

s6-rc-compile compiled source
s6-rc-init -l /tmp/live/compiled -c $(pwd)/compiled /tmp/live/service/
s6-rc -l /tmp/live/compiled start producer consumer s6rc-fdholder

echo <<EOF
at this point you will see the output of "producer" in the terminal
window where s6-svscan is running -- its output goes to the catch-all logger

next, we will add the producer/consumer funnel links.  however since the
services have already started, they will not be *re*started, and s6-fdholder
wont have the necessary file descriptors
EOF
sleep 5

echo producer > source/consumer/consumer-for
echo consumer > source/producer/producer-for
s6-rc-compile compiled2 source
s6-rc-update -l /tmp/live/compiled $(pwd)/compiled2

echo <<EOF
next we restart the producer (only); you should see messages like the following
on the catch-all logger:
  s6-fdholder-retrieve: fatal: unable to retrieve fd for id pipe:s6rc-w-consumer: No such file or directory
EOF
sleep 5
s6-rc -l /tmp/live/compiled stop producer
s6-rc -l /tmp/live/compiled start producer

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: s6-rc-update does not create pipes when already-running service becomes a consumer
  2023-09-26 14:33 s6-rc-update does not create pipes when already-running service becomes a consumer Adam Joseph
@ 2023-09-26 19:23 ` Laurent Bercot
  2023-09-27 16:09   ` Samuel Holland
  0 siblings, 1 reply; 3+ messages in thread
From: Laurent Bercot @ 2023-09-26 19:23 UTC (permalink / raw)
  To: supervision


  I agree with all you're saying here...
  ... except that this case makes no sense in the first place. A consumer
and a non-consumer are fundamentally different things.

  A running service that is not a consumer does not read anything on its
stdin. It runs autonomously.
  A consumer, by essence, is waiting on stdin input, in order to process
it and do something with it.

  If a non-consumer were to become a consumer, it would mean its very
nature would be transformed. It would not behave in the same way at all.
And so, it makes no sense for it to be the "same" service. It should not
be treated the same way; it should not keep the same name.

  So, if anything, the change I would make is, when a non-consumer
becomes a consumer, s6-rc-update just throws an error and exits.

  The situation is different with a non-producer becoming a producer,
because a non-producer can already naturally write to its stdout, and
its output simply falls through to the catch-all logger. When becoming
a producer, it just needs to write into a pipe instead, and the pipe
already exists since it's created on the consumer side, which already
exists, so indeed it's all a matter of restarting the service.

--
  Laurent


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: s6-rc-update does not create pipes when already-running service becomes a consumer
  2023-09-26 19:23 ` Laurent Bercot
@ 2023-09-27 16:09   ` Samuel Holland
  0 siblings, 0 replies; 3+ messages in thread
From: Samuel Holland @ 2023-09-27 16:09 UTC (permalink / raw)
  To: Laurent Bercot, supervision

On 9/26/23 14:23, Laurent Bercot wrote:
> 
>  I agree with all you're saying here...
>  ... except that this case makes no sense in the first place. A consumer
> and a non-consumer are fundamentally different things.
> 
>  A running service that is not a consumer does not read anything on its
> stdin. It runs autonomously.
>  A consumer, by essence, is waiting on stdin input, in order to process
> it and do something with it.
> 
>  If a non-consumer were to become a consumer, it would mean its very
> nature would be transformed. It would not behave in the same way at all.

That's not necessarily the case. A service may be a non-consumer but
still waiting on input from a socket or named pipe. Converting a pair of
services to communicate via an anonymous pipe instead of a named pipe is
not a very transformational change.

> And so, it makes no sense for it to be the "same" service. It should not
> be treated the same way; it should not keep the same name.

I would disagree here. There is no reason why the service named "foo"
before s6-rc-update and the service named "foo" after s6-rc-update need
to be related in any way. The naming convention is the user's policy.
After all, s6-rc-update already supports converting a service between a
oneshot and a longrun, which is an even more fundamental change.

>  So, if anything, the change I would make is, when a non-consumer
> becomes a consumer, s6-rc-update just throws an error and exits.
That all said, this sounds reasonable, assuming the error can be avoided
by using a conversion file.


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-09-27 16:09 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-26 14:33 s6-rc-update does not create pipes when already-running service becomes a consumer Adam Joseph
2023-09-26 19:23 ` Laurent Bercot
2023-09-27 16:09   ` Samuel Holland

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).