diff --git a/src/shared/install.c b/src/shared/install.c index dd2bd5c9484..c94b456c21e 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -2282,7 +2282,9 @@ static int install_context_mark_for_removal( else { log_debug_errno(r, "Unit %s not found, removing name.", i->name); r = install_changes_add(changes, n_changes, r, i->path ?: i->name, NULL); - if (r < 0) + /* In case there's no unit, we still want to remove any leftover symlink, even if + * the unit might have been removed already, hence treating ENOENT as non-fatal. */ + if (r != -ENOENT) return r; } } else if (r < 0) { @@ -2874,9 +2876,13 @@ static int do_unit_file_disable( r = install_info_add(&ctx, *name, NULL, lp->root_dir, /* auxiliary= */ false, &info); if (r >= 0) r = install_info_traverse(&ctx, lp, info, SEARCH_LOAD|SEARCH_FOLLOW_CONFIG_SYMLINKS, NULL); - - if (r < 0) - return install_changes_add(changes, n_changes, r, *name, NULL); + if (r < 0) { + r = install_changes_add(changes, n_changes, r, *name, NULL); + /* In case there's no unit, we still want to remove any leftover symlink, even if + * the unit might have been removed already, hence treating ENOENT as non-fatal. */ + if (r != -ENOENT) + return r; + } /* If we enable multiple units, some with install info and others without, * the "empty [Install] section" warning is not shown. Let's make the behavior diff --git a/test/units/TEST-26-SYSTEMCTL.sh b/test/units/TEST-26-SYSTEMCTL.sh index ae7a5d6eb66..1471f3fd9e4 100755 --- a/test/units/TEST-26-SYSTEMCTL.sh +++ b/test/units/TEST-26-SYSTEMCTL.sh @@ -343,6 +343,12 @@ systemctl cat "$UNIT_NAME" systemctl help "$UNIT_NAME" systemctl service-watchdogs systemctl service-watchdogs "$(systemctl service-watchdogs)" +# Ensure that the enablement symlinks can still be removed after the user is gone, to avoid having leftovers +systemctl enable "$UNIT_NAME" +systemctl stop "$UNIT_NAME" +rm -f "/usr/lib/systemd/system/$UNIT_NAME" +systemctl daemon-reload +systemctl disable "$UNIT_NAME" # show/set-environment # Make sure PATH is set