Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mask individual .wants/.requires symlinks #5231

Merged
merged 6 commits into from
Feb 8, 2017

Conversation

keszybz
Copy link
Member

@keszybz keszybz commented Feb 5, 2017

This is an alternative version of #5195, that implements the logic suggested in #4830 (comment).

It does away with the cache of deps and deferred loading, and unifies the logic of loading .d/*.conf with the loading of .wants/* and .wants/*. I think this is a superior solution because it is much simpler (in fact the diffstat of the first two commits is negative), unifies two different ways of loading "stuff" from drop-in directories, and seems more in line with the way we handle other deps.

In #5195, adding a mask on a .wants dependency not only kills that exact dependency, but also dependencies specified through aliases. But it does not kill aliases specified as Wants=. I dislike this special treatment of aliases and magic behaviour. In my solution, masking a dep in .wants is like removing the symlink that created that dep, it changes nothing else.

This should probably get some documentation, but I'll wait to see if people like this approach.

@keszybz
Copy link
Member Author

keszybz commented Feb 5, 2017

Rebased.

@fbuihuu
Copy link
Contributor

fbuihuu commented Feb 6, 2017

I think your first commit is a mix of 2 unrelated things: the rewrite of the loading of .wants/.requires symlinks by using unit_file_find_dropin_paths() which is great and the handling of the dropin masks. I think you should split this off into 2 different commits.

Regarding the implementation of the dropin mask: your version is much simpler because you chose to not handle dependencies specified via aliases.

In #5195, adding a mask on a .wants dependency not only kills that exact dependency, but also dependencies specified through aliases.

yeah and that's where all the troubles are coming from.

I think this should be clarified/discussed further as in my understanding some people expect that a mask using an alias name should mask the 'target' unit and all its aliases. And similarly a mask using an exact unit name should also mask all symlink dependencies specified through aliases.

After all, an alias is nothing more than an additional name given to a unit and I don't see why this mechanism should work except for the dropin symlink mask.

But it does not kill aliases specified as Wants=.

I don't follow here. I don't see why a symlink dropin mask should also mask all Wants= specified in .d/*.conf dropins (if that's what you meant).

Copy link
Member

@poettering poettering left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I love this approach, as we reuse what we already got.

continue;
}
if (r == 0) {
log_unit_warning(u, "%s dependency dropin %s is not a symlink, ignoring",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sentence should end with a full stop...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added dots to "all" full sentences. (Not really all, because "XXX: %m" is also a full sentence, but we don't use a dot there.) I think those dots only make messages longer, but OK.

@poettering
Copy link
Member

I am fine with not covering the alias-case btw. I think masking a unit should really have the effect that the unit is masked by all names, even if it has many (which is something we don't implement correctly right now — see #4122). However, for dependencies I think that only the precise specified dependency should be masked, not necessary under all names.

keszybz and others added 6 commits February 7, 2017 21:06
…conf dropins

Essentially, instead of sequentially adding deps based on all symlinks
encountered in .wants and .requires dirs for each name and each unit file load
path, iteratate over the load paths and unit names gathering symlinks, then
order them based on priority, and then iterate over the final list, adding
dependencies.

This patch doesn't change the logic too much, except that the order in which
dependencies are applied might be different. It wasn't defined before, so that
not really a change. Adding filtering on the symlinks is left for later
patches.
Fixes systemd#1169.
Fixes systemd#4830.

Example log errors:
Feb 04 22:13:28 systemd[1462]: foo.service: Wants dependency on empty_file.service is masked by /home/zbyszek/.config/systemd/user/foo.service.wants/empty_file.service, ignoring
Feb 04 22:13:28 systemd[1462]: foo.service: Wants dependency on masked.service is masked by /home/zbyszek/.config/systemd/user/foo.service.wants/masked.service, ignoring
Feb 04 22:35:42 systemd[1462]: foo.service: Wants dependency dropin /home/zbyszek/.config/systemd/user/foo.service.wants/diffname.service target ../barbar.service has different name
Feb 04 22:35:42 systemd[1462]: foo.service: Wants dependency dropin /home/zbyszek/.config/systemd/user/foo.service.wants/wrongname is not a valid unit name, ignoring
[zj: tests assertions adjusted to the different logic in which masking
     of a dependency through one name, does not forbid the dependency
     being added through another name.]
@keszybz
Copy link
Member Author

keszybz commented Feb 8, 2017

I think your first commit is a mix of 2 unrelated things: the rewrite of the loading of .wants/.requires symlinks by using unit_file_find_dropin_paths() which is great and the handling of the dropin masks. I think you should split this off into 2 different commits.

OK. I don't think it makes that much of a difference, but I did a split into three commits:
a preparatory commit, the change of implementation, and masking. The interesting part, i.e. support for masking, is now one added if.

I think this should be clarified/discussed further as in my understanding some people expect that a mask using an alias name should mask the 'target' unit and all its aliases. And similarly a mask using an exact unit name should also mask all symlink dependencies specified through aliases.

I don't see it this way. In this patchset, the mask operates only a specific symlink. Doing anything else would be inconsistent. In particular consider a unit which has Wants=some.target in the unit file and also a .wants/some.target. I'm stating that I think that masking the symlink should not interfere with the unit file, i.e. the dependency should still be present.

Also, let's consider the case where a unit has .wants/multi-user.target and .wants/default.target. And default.target is symlinked to multi-user.target. If I now mask the dep on default.target, it doesn't necessarily mean that I want to lose both deps. In fact, I might expect the opposite.

Anyway, I think such doubled deps should be a rare case. If this turns out to be a problem and causes user confusion, we can always reconsider.

@fbuihuu
Copy link
Contributor

fbuihuu commented Feb 8, 2017 via email

@poettering poettering merged commit b6f08ec into systemd:master Feb 8, 2017
@keszybz keszybz deleted the mask-wants branch February 9, 2017 01:06
@fbuihuu
Copy link
Contributor

fbuihuu commented Feb 9, 2017

BTW I think you should document the symlink mask somewhere since it introduces a new concept and also the limitation regarding the alias names when used as masks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

None yet

3 participants