[systemd-devel] Another attempt: Making dependencies properly overridable

Andrei Borzenkov arvidjaar at gmail.com
Sun Apr 19 07:08:04 PDT 2015


В Sun, 19 Apr 2015 13:19:37 +0000
Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl> пишет:

> On Sun, Apr 19, 2015 at 09:29:55AM +0300, Andrei Borzenkov wrote:
> > В Fri, 17 Apr 2015 16:47:58 +0000
> > Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl> пишет:
> > 
> > > On Mon, Feb 16, 2015 at 04:19:47PM +0100, Christian Seiler wrote:
> > > > Am 2015-02-16 14:16, schrieb Lennart Poettering:
> > > > >On Mon, 16.02.15 14:13, Michael Biebl (mbiebl at gmail.com) wrote:
> > > > >>Not quite. While you can use drop-in snippets to amend
> > > > >>orderings/depends, it's (unfortunately) not possible to override
> > > > >>Wants=,Before= etc.
> > > > >
> > > > >There have been discussions to allow masking deps via /dev/null
> > > > >symlinks in .wants/ and .requires/ dirs... I think that'd be a better
> > > > >solution...
> > > > >[...]
> > > > >>Agreed, systemctl edit is much nicer. Unfortunately, as said above,
> > > > >>drop-ins can *not* be used to override all aspects of a native unit
> > > > >>file. So it's not (yet) a complete replacement for insserv
> > > > >>overrides.
> > > > >>
> > > > >>If it would be possible to unset Wants= or After=, just like other
> > > > >>service properties, then things would be different.
> > > > >
> > > > >As mentioned, I'd be happy to take patches to make precisely that
> > > > >work!
> > > > 
> > > > Last time I talked about this here, there was a lot of confusion, so
> > > > I didn't pursue it further. But I would really like to get this to
> > > > work, but before I start with a patch, I'd like to explain what I'd
> > > > like to do before working on it, to see if it works for you.
> > > > 
> > > > The semantics I'd like to see would be the following:
> > > > 
> > > >  - anything in /etc named exactly the same as in /usr/lib overrides
> > > >    the latter, just as is already the case with units and drop-ins
> > > > 
> > > >      => allow masking of .wants/ and .requires/ with symlinks to
> > > >         /dev/null (I think you were in favor of that)
> > > > 
> > > >  - additionally, postpone processing of dependencies in unit files
> > > >    until the entire unit (and all drop-ins) have been read in
> > > > 
> > > >       For example, even without a drop-in:
> > > > 
> > > >       a.service:
> > > >       [Unit]
> > > >       Wants=b.service
> > > >       Wants=
> > > >       Wants=c.service
> > > > 
> > > >       After that, Wants should be set to c.service. Note that this
> > > >       should NOT affect dependencies set in other ways, i.e. via
> > > >       .wants/ directories or by dependencies of other services, this
> > > >       should JUST alter what was specified in the unit itself.
> > > > 
> > > >       A more complex example to illustrate the latter:
> > > > 
> > > >       /usr/lib/.../a.service:
> > > >         [Unit]
> > > >         Wants=b.service
> > > >         After=c.service
> > > > 
> > > >       /usr/lib/.../a.service.wants/d.service -> /usr/lib/.../d.service
> > > >       /usr/lib/.../a.service.wants/e.service -> /usr/lib/.../e.service
> > > > 
> > > >       /usr/lib/.../f.service
> > > >         [Unit]
> > > >         Before=a.service
> > > > 
> > > >       /etc/.../a.service.d/dont-depend-on-b.conf:
> > > >         [Unit]
> > > >         Wants=
> > > > 
> > > >       /etc/.../a.service.d/not-after-c.conf:
> > > >         [Unit]
> > > >         After=
> > > > 
> > > >       /etc/.../a.service.wants/e.service -> /dev/null
> > > > 
> > > >       In the end, the dependnecies should be:
> > > > 
> > > >          Wants=d.service
> > > >             - b.service gets removed via drop-in
> > > >             - e.service gets removed because it's masked
> > > >             - but d.service stays, because it was never defined in
> > > >               the unit file, so a drop-in doesn't override it, only
> > > >               the mask does
> > > > 
> > > >          After=f.service
> > > >             - c.service gets removed via drop-in
> > > >             - f.service is not declared in the original unit file but
> > > >               rather in f.service as a Before= dependency, so you'd
> > > >               have to override that to make this go into effect
> > > > 
> > > >      The general principle would be: you can drop stuff at the same
> > > >      place it's defined. If it's defined as After= in a unit,
> > > >      override it in a drop-in for that unit, if it's defined as
> > > >      Before= in another unit, override it in a drop-in for the other
> > > >      unit, and if it's defined in the filesystem via .wants/ or
> > > >      .requires/, you can override it by masking it in the filesystem.
> > > >      Only in the end will all remaining dependencies be combined to
> > > >      make up the entire list of dependencies for that service.
> > > > 
> > > > Would you be agreeable to these semantics? If so, I'll hack up a
> > > > patch.
> > > Seems quite intuitive to me. Would be great to have this implemented.
> > > 
> > 
> > Unless I'm mistaken, the only real change is that Wants= will clear
> > list, just like it does it for ExecStart=. This should be rather
> > straightforward to implement I guess.
> Also links in .wants and .requires can be masked. It's not a huge change,
> but I not trivial either -- and this part of the code is notriously had to
> get right.
> 

What about Wants-=e.service in dropin? Dropins are processed
after .{wants,requires}.d and has advantage that you can remove also
static dependency from unit definition file, not only mask another
directory.


More information about the systemd-devel mailing list