> On 28 Apr 2022, at 09:47, Lennart Poettering <[email protected]> wrote: > > On Mi, 27.04.22 18:29, Barry Scott ([email protected] > <mailto:[email protected]>) 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
