[systemd-devel] /usr vs /etc for default distro units enablement

Didier Roche didrocks at ubuntu.com
Tue Nov 18 05:58:17 PST 2014


Le 18/11/2014 14:10, Tom Gundersen a écrit :
> Hi Didier,

Thanks for your answer Tom and sharing your thoughts on this.

>
> On Tue, Nov 18, 2014 at 12:11 PM, Didier Roche <didrocks at ubuntu.com> wrote:
>> This has 3 drawbacks:
>> - Duplicate symlinks for the same targets between /etc and units enabled in
>> /usr/lib for units which are already enabled via /usr/lib, if the admin runs
>> "enable"
> This I think should be considered a bug in the unit file. If a unit
> has a /usr/lib symlink, then it is statically enabled (i.e.,
> 'enable'/'disable' has no effect), so it should not install symlinks
> in /etc, and hence not have an [Install] section. At least with the
> current semantics.

Shouldn't then systemctl status detects that there is a symlink in /usr 
and list it as a static unit instead of disabled? (or even better: warn 
that the unit is mis-formatted).
The current "disable" status would let the admin think if he doesn't 
know about the implementation that this unit will never be active until 
I systemctl start it explicitly, which isn't the case.

>
>> - Wrt. the "golden image, /etc reset" approach of reducing base os
>> installation defaults in /etc, this is another instance of "always needs to
>> be there" clutter in /etc. If the package default is  to start the service,
>> then it's better to just ship that wants.d/ symlink in the package (and thus
>> in /usr) instead of always having to create the symlink in /etc at package
>> install time or after a factory reset.
> I get where you are coming from, but presets will give you the same result, no?

Apart from what we discussed on this thread with Martin about the "/etc" 
clutterness having distro-specific information and not only system ones, 
right.

However, this is kind of a complex case in D/U where we have the policy 
to start most of the service on package installation. For instance, if 
you apt install docker.io, people using those distros will expect to be 
then able to do $ docker run <…> (which starts the docker service 
through socket activation).
>
>> - We are mixing sys admin information and distro default choices in the same
>> directories, and can't tell apart what is what.
> That is true. Could we perhaps improve on systemctl by printing
> "enabled (preset)"/"disable (preset)" for units that are in the
> default state? I know this does not change the fact that you have
> distro-default (via presets) links in /etc, but it should give the
> end-user a nicer experienc I guess?

This would be maybe a nice way for the admin to know what's coming from 
a distribution default or not. However, let's say I want to ensure that 
ssh will always be available on my server, I would (even if it's in my 
server preset) then systemctl enable openssh, no matter whatever future 
preset updates does (like disable it in the next batch upgrade).

With a shared distro/admin /etc, we have no way to take that fact into 
account and the next one would follow distro policy, right?
Also, after running systemctl enable opensshn, systemctl status openssh 
will still say "enabled (preset)" even if the admin wanted to "stick it 
for good" as it's part of the preset.


>
>> We were thus thinking about having all default distro choices shipping
>> target symlinks in /usr/lib, and having the administrator overrides this in
>> /etc via systemctl. This could look similar to masking a unit, i. e. a
>> symlink "/etc/.../wants.d/foo -> /dev/null" overrides
>> "/usr/lib/.../wants.d/foo -> ../foo.service", and would be an explicit
>> representation of "the admin does not want foo.service to autostart" in
>> /etc.
> So you are essentially proposing to replace the preset concept?
>
> We now have:
>
> enabeld - [Install] section and symlink in /etc/**/*.wants.d/
> disabled - [Install] section and no symlink in /etc/**/*.wants.d/
> static - no [Install] section and symlink in /usr/lib/**/*.wants.d/
> masked - symlink from the unit file-name to /dev/null in /etc
>
> you want in addition:
>
> preset (or something like that) - [Install] section and symlink in
> /usr/lib/**/*.wants.d/
> unpreset (or something like that) - [Install] section and symlink in
> /usr/lib/**/*.wants.d/ and an overriding symlink in /etc pointing at
> /dev/null
>
> Doing 'enable' on a preset unit will then just delete the symlink to
> /dev/null from /etc (if it exists) and doing 'disable' will add it.
> This would also entail changing the current logic to check the target
> of /**/*.wants.d/ symlinks to see if they point to /dev/null, in which
> case they should be ignored.
>
> Did I understand that correctly?

Right, maybe the implementation can diverge a little bit from that, but 
the intent would cover most of the admin/distro separation, while 
enabling sysadmin to "stick" some of the services disregarding future 
distro choices and keeping a clean /etc.
>
>> However, we did notice the following: taking an unit, with an [Install]
>> section and a symlink to enable in via that target in /usr/lib:
> Yeah, I would not expect this to work with the current semantics, as
> it appears to be a contradiction. We can probably improve on the
> status-quo even if your proposal is not implemented.

Indeed, this is quite orthogonal, but this whole discussion started 
actually when I analyzed those use cases, hence the mention. :)
>
>> - systemctl status <unit> will report "disabled", where it's actually
>> enabled and starting for that unit. This is a bug which should be fixed in
>> any case, as "disabled" is outright wrong. On IRC it was suggested that
>> those are "static" units, but then it should say at least that.
> I agree, this should be fixed to report them as 'static' (as any state
> in /etc apart from masking is irrelevant).
agreed (if we want to keep the current logic of not shipping other kind 
of units in /usr)
>
>> - systemctl enable <unit> will duplicate the symlink in /etc
> I guess this should also be dropped (though the situation here is
> weird as it anyway is a noop). Maybe a warning should be printed.

agreed as well, or, this would be a way for the sysadmin to "stick" this 
unit/service whatever future distro will choose in the next upgrade.
>
>> - If we ln -s /dev/null /etc/<…>/<…>.wants/<unit>, then systemctl status
>> <unit> will display the unit as being enabled, and it will activated once
>> the target is reached.  This is also counterintuitive, as usually this means
>> to mask/completely disable the unit.
> You cannot mask an wants.d/* symlink, only the unit itself, so this is
> actually not defined. My understanding is that this is a concept you
> would like to introduce rather than a bug. I don't know how/if we
> should change this behaviour under the current semantics.

ack.
>
>> Part of the discussion on #systemd pointed out that the admin should then
>> use systemctl mask <unit>. However, that means:
>> - The admin can't retarget a default installed unit without recreating
>> another unit file
> Correct. But is that something we want? I mean, how I would retarget a
> unit file is to make a copy, edit the [Install] section and then
> "systemctl enable" it. I guess we should not encourage admins to go
> fiddling with the symlinks manually?

Indeed, this is quite a niche-case, they would rather I think copy it to 
/etc and override the [Install] section as you told.
>
>> - There are 2 commands to "disable" an unit: mask for some, disable for
>> others, this can bring confusion and admins won't know the semantic
>> difference between the two (and indeed this is rather technical and
>> unintuitive)
> Well, the meaning we have been using so far is that statically enabled
> units are things that does not really make sense to disable (which is
> different from it being enabled by default), and for all other units
> the way to enable/disable them (be it by default or manually) is by
> installing symlinks in /etc. If the admin wants to insist to ignore
> the "does not make sense to disable part" and really force something
> to never start, then masking is the tool for that. Either way, the
> admin should never (need to) go poking in /etc manually, but use
> systemctl as the interface.

Indeed, I'm getting where you are coming from now and see the real 
difference you mean with default symlinks in /usr. However, it would 
seem weird to me to have to systemctl mask plymouth-quit.service for 
instance without knowing the internals of systemd to be able to really 
"disable" (I know the term is wrong, just trying to feel how they could 
interprete it) a certain class of units.
>
>> - The status reported with systemctl is still disabled when it's not.
> We can probably improve on that. I guess no one really explored the
> case of static units with [Install] sections. Even if we end up
> thinking of these as bugs, people can still end up with them, so we
> should probably make sure our tools report something sensible.

Agreed, I can open a bug independently of this discussion and work on 
this, as it seems we all agree that this status report needs to be 
improved even with units not following the current expected semantics.
>
>> Tested with systemd 216 on fedora 21 and systemd 215 on ubuntu vivid.
>>
>> It will be great if we can come to some common grounds on how we should
>> separate admin choices and default distro choices, while still working on
>> the "remove /etc default distro configuration" . I'm happy to give a hand on
>> the desired solutions there.
> My take on this is: make sure presets are applied on "firstboot"
> (which I think they are), so empty /etc works just fine, and then
> improve on systemctl to better show the distinction between 'enabled
> by default' or 'enabled by choice' (and same for 'disabled').

Thanks again for your feedback. If the whole proposal is rejected, I 
think we'll try to have debian following this as a first step.

Cheers,
Didier


More information about the systemd-devel mailing list