Re: Run something on first start of a service

From: Jens Rehsack <rehsack_at_gmail.com>
Date: Mon, 1 Feb 2021 14:10:51 +0100

> Am 01.02.2021 um 13:41 schrieb Laurent Bercot <ska-skaware_at_skarnet.org>:
>
>> I'm struggling to figure out how to start a particular initialization when a service first comes up (since service startup, system startup, or ever).
>> I'm pretty sure it's well documented, but if the question is phrased incorrectly, you can search for a long time.
>
> Do you mean that the "start" script would only be run once, no matter
> how many times the service can die and be restarted later on?
> If so, it's the job of a service manager. Conceptually, "start" is
> not really part of the supervised service, it's something separate that
> needs to run before your service is first brought up.

Indeed - it could be part of the service manager ... I also try to draw
a line here.

In my particular use-case I (since s6-rc isn't packaged already) moved
it out to /etc/init.d/ but starting it like the example below to avoid
long hanging stage 2 start.

Since it's a `wait for device comes up` - a udev rule would be correct.

But another use-cause is:
* creating some file system entries first

> In the s6 world, this would be handled by s6-rc (or anopa). You would
> make a oneshot that contains your "start" script, and your longrun
> (containing your "run" script, the thing you want supervised) would
> depend on the "start" oneshot.
>
> But if it's not what you mean (and it appears it's not), read below.

Conceptional I mean:
1) start once when system starts - let service depend on it (as far as
   I understand, I need s6-rc for this) - maybe with support for systems
   without s6-rc for whatever reason.
2) start once every time $service is down and `s6-svc -[uo] $service`
   is invoked

I do not mean:
3) so something tidying before payload starts - this is the job of the
   run script.

>> What daemontools-encore does with ./start seems pretty ok - and would be near perfect if it were to wait for ./start to finish before running ./run.
>
> After reading
> https://untroubled.org/daemontools-encore/supervise.8.html
> I understand that ./start is run every time the service is started, not
> only the first time, and ./run is only actually executed if ./start
> exits 0. Which is a very different approach: "start" is not a
> oneshot, but part of the service.

I checked the source (since it behaved differently last time I used it)
and the appropriate code (https://github.com/bruceg/daemontools-encore/blob/master/supervise.c#L227)
behaves that ./start is executed the very first time after `svc -[ou] /run/service/foo`
is invoked. Any following service start (re-start after crash), just ./run ist started.

Reading the man page from another perspective, this is also valid:
`svc -u $service`
 -> test -x $service/start && $service/start
    while true; do $service/run; done

> And if it's part of the service and supposed to be run every time,
> then you don't need a separate ./start: it can just as well be part
> of the ./run script.
>
> To emulate this in execline: if -X { ./start } rest-of-run-script
> and in shell: set -e ; ./start ; rest-of-run-script
>
>
>> s6 has a concept for ./finish - so I think a ./start concept is there as well and I just can't find it. Can someone please nudge me on this?
>
> ./finish has to be separate because it's spawned when ./run dies.
> But anything that needs to run *before* ./run can just be integrated
> into ./run instead, there's no need for a separate script.

Sure - ./finish is obvious - but there are reasons for `./sth-to-be-started-once`,
so I wanted to know whether there is something and I'm unable to find it or
it's intentionally left out compared to daemontools-encore ;)

Cheers
--
Jens Rehsack - rehsack_at_gmail.com



Received on Mon Feb 01 2021 - 13:10:51 UTC

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