diff options
author | Lennart Poettering <lennart@poettering.net> | 2017-02-10 12:23:22 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2017-02-10 14:36:17 +0100 |
commit | 637d6e5b9c97afdd284f684c319cb4274bb8abcf (patch) | |
tree | 22bce3a5de4f072cb5289a86d3dd057d770e2626 /src/shared | |
parent | 807fa5d9a01b2bd80ac821d3a165bfef0323c20c (diff) |
install: when disabling units, do so even if the unit is missing
In some cases there might be unit symlinks in .wants/ or .requires/
directories even though the unit is otherwise fully removed. In this
case, don't fail removal, but still remove the symlinks.
This reworks the symlink marking logic to always add unit files that we
are missing to the changes list, but proceed with any symlink removal
for them. This way we'll still generate useful hints that a unit is
missing if you invoke "systemctl disable idontexist.service", but also
still remove any link to it.
Fixes: #4995
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/install.c | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/src/shared/install.c b/src/shared/install.c index f25ed685f6..c027f8ecd3 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -389,6 +389,12 @@ void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *chang verb, changes[i].path); logged = true; break; + + case -ENOENT: + log_error_errno(changes[i].type, "Failed to %s unit, unit %s does not exist.", verb, changes[i].path); + logged = true; + break; + default: assert(changes[i].type < 0); log_error_errno(changes[i].type, "Failed to %s unit, file %s: %m.", @@ -1807,7 +1813,9 @@ static int install_context_mark_for_removal( InstallContext *c, const LookupPaths *paths, Set **remove_symlinks_to, - const char *config_path) { + const char *config_path, + UnitFileChange **changes, + unsigned *n_changes) { UnitFileInstallInfo *i; int r; @@ -1833,19 +1841,26 @@ static int install_context_mark_for_removal( r = install_info_traverse(scope, c, paths, i, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, NULL); if (r == -ENOLINK) { - log_debug_errno(r, "Name %s leads to a dangling symlink, ignoring.", i->name); - continue; - } else if (r == -ENOENT && i->auxiliary) { - /* some unit specified in Also= or similar is missing */ - log_debug_errno(r, "Auxiliary unit %s not found, ignoring.", i->name); - continue; - } else if (r < 0) - return log_debug_errno(r, "Failed to find unit %s: %m", i->name); + log_debug_errno(r, "Name %s leads to a dangling symlink, removing name.", i->name); + unit_file_changes_add(changes, n_changes, UNIT_FILE_IS_DANGLING, i->path ?: i->name, NULL); + } else if (r == -ENOENT) { + + if (i->auxiliary) /* some unit specified in Also= or similar is missing */ + log_debug_errno(r, "Auxiliary unit of %s not found, removing name.", i->name); + else { + log_debug_errno(r, "Unit %s not found, removing name.", i->name); + unit_file_changes_add(changes, n_changes, r, i->path ?: i->name, NULL); + } - if (i->type != UNIT_FILE_TYPE_REGULAR) { - log_debug("Unit %s has type %s, ignoring.", - i->name, - unit_file_type_to_string(i->type) ?: "invalid"); + } else if (r < 0) { + log_debug_errno(r, "Failed to find unit %s, removing name: %m", i->name); + unit_file_changes_add(changes, n_changes, r, i->path ?: i->name, NULL); + } else if (i->type == UNIT_FILE_TYPE_MASKED) { + log_debug("Unit file %s is masked, ignoring.", i->name); + unit_file_changes_add(changes, n_changes, UNIT_FILE_IS_MASKED, i->path ?: i->name, NULL); + continue; + } else if (i->type != UNIT_FILE_TYPE_REGULAR) { + log_debug("Unit %s has type %s, ignoring.", i->name, unit_file_type_to_string(i->type) ?: "invalid"); continue; } @@ -2401,7 +2416,7 @@ int unit_file_disable( return r; } - r = install_context_mark_for_removal(scope, &c, &paths, &remove_symlinks_to, config_path); + r = install_context_mark_for_removal(scope, &c, &paths, &remove_symlinks_to, config_path, changes, n_changes); if (r < 0) return r; @@ -2790,7 +2805,7 @@ static int execute_preset( if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) { _cleanup_set_free_free_ Set *remove_symlinks_to = NULL; - r = install_context_mark_for_removal(scope, minus, paths, &remove_symlinks_to, config_path); + r = install_context_mark_for_removal(scope, minus, paths, &remove_symlinks_to, config_path, changes, n_changes); if (r < 0) return r; |