[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