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 anorder 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.servicethis means a.service has to finish startup first, before b.serviceis started.2. If two units are stopped they define the order too, but inreverse. if b.service has After=a.service this hence means that ifboth are shutdown, then b.service has to stop *before* a.service isstopped, i.e. the opposite order of the start-up order.3. If one unit is started and one is stopped then the existance of anordering dep means the stopped unit must complete stopping first,before the starting of the other is initiated. Note that it doesn'tmattre if you set After= or Before= here, that doesn#t matter. Whatmatters is that you ordered the unit at all, regardless in whichdirection.Now, this third rule is what matters here: if your target unit hasConflicst= on some service, then the target unit should not enteractive state until the service fully shutdown. Thus you can placeAfter= *or* Before= between the two (your choice) and get the desiredbehaviour.
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