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

Christian Seiler christian at iwakd.de
Mon Feb 16 07:19:47 PST 2015


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.

Christian



More information about the systemd-devel mailing list