Re: Waiting for all jobs to finish

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





On 28 Apr 2022, at 09:47, Lennart Poettering <lennart@xxxxxxxxxxxxxx> wrote:

On Mi, 27.04.22 18:29, Barry Scott (barry@xxxxxxxxxxxxxxxx) wrote:

I have two target files that I use.

prod.target is used to start up all the production services.
When I use systemctl start prod.target it blocks until all the
services are running.

I also have prod-upgrade.target that is used to stop service
via Conflicts=. When I use systemctl start prod-upgrade.target
it returns immediately but there are stop jobs running.

I believe that this is expected as all the services that need to
be started have been.

Is there a systemctl command that will wait for all the stop jobs
without the need to poll for the systemctl list-jobs to be empty?

There is not.

But the correct way to solve this is by combining Conflicts= with an
order dep (After= or Before=).

In systemd the ordering deps After=/Before= control three things:

1. The literally define the start-up order if two units are started,
i.e. this is the obvious case: if b.service has After=a.service
this means a.service has to finish startup first, before b.service
is started.

2. If two units are stopped they define the order too, but in
reverse. if b.service has After=a.service this hence means that if
both are shutdown, then b.service has to stop *before* a.service is
stopped, i.e. the opposite order of the start-up order.

3. If one unit is started and one is stopped then the existance of an
ordering dep means the stopped unit must complete stopping first,
before the starting of the other is initiated. Note that it doesn't
mattre if you set After= or Before= here, that doesn#t matter. What
matters is that you ordered the unit at all, regardless in which
direction.

Now, this third rule is what matters here: if your target unit has
Conflicst= on some service, then the target unit should not enter
active state until the service fully shutdown. Thus you can place
After= *or* Before= between the two (your choice) and get the desired
behaviour.

I'd have never reasoned my way to this solution.

It work as you described.

But only if I use After= as Before= got a cyclic deps error.

Here is the pattern I now have:

[Unit]
Description=prod.target

Wants=serv1.service
After=serv1.service


[Unit]
Description=prod-upgrade.target

Conflicts=prod.target
Conflicts=serv1.service

# Need a After= so that systemctl start prod-upgrade.target
# will block until conflicting services have stopped
After=serv1.service

Barry



Lennart

--
Lennart Poettering, Berlin


[Index of Archives]     [LARTC]     [Bugtraq]     [Yosemite Forum]     [Photo]

  Powered by Linux