70 lines
3.4 KiB
Diff
70 lines
3.4 KiB
Diff
|
From c26e56d08f30a2946dfa1d03781c63bfa9f56c1d Mon Sep 17 00:00:00 2001
|
||
|
From: Luca Boccassi <bluca@debian.org>
|
||
|
Date: Fri, 7 Jun 2024 21:39:45 +0100
|
||
|
Subject: [PATCH] install: allow removing symlinks even for units that are gone
|
||
|
|
||
|
If a symlink is leftover, still allow cleaning it up via 'disable'. This
|
||
|
happens when a unit is stopped and removed, but not disabled, and a reload
|
||
|
has already happened. At that point, cleaning up the old symlinks becomes
|
||
|
impossible through the APIs, and needs to be done manually. Always allow
|
||
|
cleaning up symlinks, if they exist, by only erroring out if there is an
|
||
|
OOM.
|
||
|
|
||
|
Follow-up for f31f10a6207efc9ae9e0b1f73975b5b610914017
|
||
|
|
||
|
(cherry picked from commit 5163c9b1e56293b1bb2803420613c5b374570892)
|
||
|
---
|
||
|
src/shared/install.c | 14 ++++++++++----
|
||
|
test/units/TEST-26-SYSTEMCTL.sh | 6 ++++++
|
||
|
2 files changed, 16 insertions(+), 4 deletions(-)
|
||
|
|
||
|
diff --git a/src/shared/install.c b/src/shared/install.c
|
||
|
index dd2bd5c948..c94b456c21 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 ae7a5d6eb6..1471f3fd9e 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
|