diff options
author | Lennart Poettering <lennart@poettering.net> | 2015-10-08 22:31:56 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2015-11-12 17:57:04 +0100 |
commit | 0ec0deaa30d0e68430f03fa6f32affa576481d18 (patch) | |
tree | ecfd89525b710466dc7785dfc877645bc1f12540 /src/sysv-generator | |
parent | d073dea0a89c271fc4a769d5b3b2db395aa0239a (diff) |
install: follow unit file symlinks in /usr, but not /etc when looking for [Install] data
Some distributions use alias unit files via symlinks in /usr to cover
for legacy service names. With this change we'll allow "systemctl
enable" on such aliases.
Previously, our rule was that symlinks are user configuration that
"systemctl enable" + "systemctl disable" creates and removes, while unit
files is where the instructions to do so are store. As a result of the
rule we'd never read install information through symlinks, since that
would mix enablement state with installation instructions.
Now, the new rule is that only symlinks inside of /etc are
configuration. Unit files, and symlinks in /usr are now valid for
installation instructions.
This patch is quite a rework of the whole install logic, and makes the
following addional changes:
- Adds a complete test "test-instal-root" that tests the install logic
pretty comprehensively.
- Never uses canonicalize_file_name(), because that's incompatible with
operation relative to a specific root directory.
- unit_file_get_state() is reworked to return a proper error, and
returns the state in a call-by-ref parameter. This cleans up confusion
between the enum type and errno-like errors.
- The new logic puts a limit on how long to follow unit file symlinks:
it will do so only for 64 steps at max.
- The InstallContext object's fields are renamed to will_process and
has_processed (will_install and has_installed) since they are also
used for deinstallation and all kinds of other operations.
- The root directory is always verified before use.
- install.c is reordered to place the exported functions together.
- Stricter rules are followed when traversing symlinks: the unit suffix
must say identical, and it's not allowed to link between regular units
and templated units.
- Various modernizations
- The "invalid" unit file state has been renamed to "bad", in order to
avoid confusion between UNIT_FILE_INVALID and
_UNIT_FILE_STATE_INVALID. Given that the state should normally not be
seen and is not documented this should not be a problematic change.
The new name is now documented however.
Fixes #1375, #1718, #1706
Diffstat (limited to 'src/sysv-generator')
-rw-r--r-- | src/sysv-generator/sysv-generator.c | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c index 042be97840..5075548507 100644 --- a/src/sysv-generator/sysv-generator.c +++ b/src/sysv-generator/sysv-generator.c @@ -742,6 +742,7 @@ static int fix_order(SysvStub *s, Hashmap *all_services) { static int enumerate_sysv(const LookupPaths *lp, Hashmap *all_services) { char **path; + int r; assert(lp); assert(all_services); @@ -761,7 +762,6 @@ static int enumerate_sysv(const LookupPaths *lp, Hashmap *all_services) { _cleanup_free_ char *fpath = NULL, *name = NULL; _cleanup_(free_sysvstubp) SysvStub *service = NULL; struct stat st; - int r; if (fstatat(dirfd(d), de->d_name, &st, 0) < 0) { log_warning_errno(errno, "stat() failed on %s/%s, ignoring: %m", *path, de->d_name); @@ -781,8 +781,12 @@ static int enumerate_sysv(const LookupPaths *lp, Hashmap *all_services) { if (hashmap_contains(all_services, name)) continue; - if (unit_file_lookup_state(UNIT_FILE_SYSTEM, NULL, lp, name) >= 0) { - log_debug("Native unit for %s already exists, skipping", name); + r = unit_file_lookup_state(UNIT_FILE_SYSTEM, NULL, lp, name, NULL); + if (r < 0 && r != -ENOENT) { + log_debug_errno(r, "Failed to detect whether %s exists, skipping: %m", name); + continue; + } else if (r >= 0) { + log_debug("Native unit for %s already exists, skipping.", name); continue; } |