594167
From 5aa2be25e7de16f4d3ff3b322cf8c35574e712c5 Mon Sep 17 00:00:00 2001
594167
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
594167
Date: Wed, 16 Mar 2022 09:51:24 +0100
594167
Subject: [PATCH] =?UTF-8?q?shared/install:=20also=20remove=20symlinks=20li?=
594167
 =?UTF-8?q?ke=20.wants/foo@one.service=20=E2=86=92=20../foo@one.service?=
594167
MIME-Version: 1.0
594167
Content-Type: text/plain; charset=UTF-8
594167
Content-Transfer-Encoding: 8bit
594167
594167
So far 'systemctl enable' would create absolute links to the target template
594167
name. And we would remove such symlinks just fine. But the user may create
594167
symlinks manually in a different form. In particular, symlinks for instanced
594167
units *must* have the instance in the source name, and then it is natural to
594167
also include it in the target name (.wants/foo@one.service → ../foo@one.service
594167
rather than .wants/foo@one.service → ../foo@.service). We would choke on such
594167
links, or not remove them at all. A test is added:
594167
594167
before:
594167
594167
+ build-rawhide/systemctl --root=/tmp/systemctl-test.001xda disable templ1@.service
594167
Removed "/tmp/systemctl-test.001xda/etc/systemd/system/services.target.wants/templ1@seven.service".
594167
Removed "/tmp/systemctl-test.001xda/etc/systemd/system/services.target.wants/templ1@six.service".
594167
Removed "/tmp/systemctl-test.001xda/etc/systemd/system/services.target.wants/templ1@five.service".
594167
Removed "/tmp/systemctl-test.001xda/etc/systemd/system/services.target.wants/templ1@four.service".
594167
Removed "/tmp/systemctl-test.001xda/etc/systemd/system/services.target.wants/templ1@three.service".
594167
Failed to disable unit, refusing to operate on linked unit file /tmp/systemctl-test.001xda/etc/systemd/system/services.target.wants/templ1@two.service.
594167
Failed to disable unit, refusing to operate on linked unit file /tmp/systemctl-test.001xda/etc/systemd/system/services.target.wants/templ1@two.service.
594167
594167
after:
594167
594167
+ build-rawhide/systemctl --root=/tmp/systemctl-test.QVP0ev disable templ1@.service
594167
Removed "/tmp/systemctl-test.QVP0ev/etc/systemd/system/services.target.wants/templ1@seven.service".
594167
Removed "/tmp/systemctl-test.QVP0ev/etc/systemd/system/services.target.wants/templ1@six.service".
594167
Removed "/tmp/systemctl-test.QVP0ev/etc/systemd/system/services.target.wants/templ1@five.service".
594167
Removed "/tmp/systemctl-test.QVP0ev/etc/systemd/system/services.target.wants/templ1@four.service".
594167
Removed "/tmp/systemctl-test.QVP0ev/etc/systemd/system/services.target.wants/templ1@three.service".
594167
Removed "/tmp/systemctl-test.QVP0ev/etc/systemd/system/services.target.wants/templ1@two.service".
594167
Removed "/tmp/systemctl-test.QVP0ev/etc/systemd/system/services.target.wants/templ1@one.service".
594167
+ test '!' -h /tmp/systemctl-test.QVP0ev/etc/systemd/system/services.target.wants/templ1@one.service
594167
+ test '!' -h /tmp/systemctl-test.QVP0ev/etc/systemd/system/services.target.wants/templ1@two.service
594167
+ test '!' -h /tmp/systemctl-test.QVP0ev/etc/systemd/system/services.target.wants/templ1@three.service
594167
+ test '!' -h /tmp/systemctl-test.QVP0ev/etc/systemd/system/services.target.wants/templ1@four.service
594167
+ test '!' -h /tmp/systemctl-test.QVP0ev/etc/systemd/system/services.target.wants/templ1@five.service
594167
+ test '!' -h /tmp/systemctl-test.QVP0ev/etc/systemd/system/services.target.wants/templ1@six.service
594167
+ test '!' -h /tmp/systemctl-test.QVP0ev/etc/systemd/system/services.target.wants/templ1@seven.service
594167
594167
(cherry picked from commit 9f61c9f79e0f77044b71ef2ba5edde20e15c6ad2)
594167
594167
Related: #2082131
594167
---
594167
 src/shared/install.c          | 16 +++++++++++++---
594167
 test/test-systemctl-enable.sh | 20 ++++++++++++++++++++
594167
 2 files changed, 33 insertions(+), 3 deletions(-)
594167
594167
diff --git a/src/shared/install.c b/src/shared/install.c
594167
index 08a9892260..43955519ae 100644
594167
--- a/src/shared/install.c
594167
+++ b/src/shared/install.c
594167
@@ -612,13 +612,23 @@ static int remove_marked_symlinks_fd(
594167
                         path_simplify(p);
594167
 
594167
                         /* We remove all links pointing to a file or path that is marked, as well as all
594167
-                         * files sharing the same name as a file that is marked. Do path chasing only if
594167
-                         * we don't already know that we want to remove the symlink. */
594167
+                         * files sharing the same name as a file that is marked, and files sharing the same
594167
+                         * name after the instance has been removed. Do path chasing only if we don't already
594167
+                         * know that we want to remove the symlink. */
594167
                         found = set_contains(remove_symlinks_to, de->d_name);
594167
 
594167
                         if (!found) {
594167
-                                _cleanup_free_ char *dest = NULL;
594167
+                                _cleanup_free_ char *template = NULL;
594167
+
594167
+                                q = unit_name_template(de->d_name, &template);
594167
+                                if (q < 0 && q != -EINVAL)
594167
+                                        return q;
594167
+                                if (q >= 0)
594167
+                                        found = set_contains(remove_symlinks_to, template);
594167
+                        }
594167
 
594167
+                        if (!found) {
594167
+                                _cleanup_free_ char *dest = NULL;
594167
 
594167
                                 q = chase_symlinks(p, lp->root_dir, CHASE_NONEXISTENT, &dest, NULL);
594167
                                 if (q == -ENOENT)
594167
diff --git a/test/test-systemctl-enable.sh b/test/test-systemctl-enable.sh
594167
index 220ebfdab7..4462fb386e 100644
594167
--- a/test/test-systemctl-enable.sh
594167
+++ b/test/test-systemctl-enable.sh
594167
@@ -333,6 +333,26 @@ test ! -h "$root/etc/systemd/system/other@templ1.target.requires/templ1@one.serv
594167
 test ! -h "$root/etc/systemd/system/services.target.wants/templ1@two.service"
594167
 test ! -h "$root/etc/systemd/system/other@templ1.target.requires/templ1@two.service"
594167
 
594167
+: -------removal of relative enablement symlinks--------------
594167
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@.service"
594167
+ln -s '../templ1@one.service' "$root/etc/systemd/system/services.target.wants/templ1@one.service"
594167
+ln -s 'templ1@two.service' "$root/etc/systemd/system/services.target.wants/templ1@two.service"
594167
+ln -s '../templ1@.service' "$root/etc/systemd/system/services.target.wants/templ1@three.service"
594167
+ln -s 'templ1@.service' "$root/etc/systemd/system/services.target.wants/templ1@four.service"
594167
+ln -s '/usr/lib/systemd/system/templ1@.service' "$root/etc/systemd/system/services.target.wants/templ1@five.service"
594167
+ln -s '/etc/systemd/system/templ1@.service' "$root/etc/systemd/system/services.target.wants/templ1@six.service"
594167
+ln -s '/run/system/templ1@.service' "$root/etc/systemd/system/services.target.wants/templ1@seven.service"
594167
+
594167
+# this should remove all links
594167
+"$systemctl" --root="$root" disable 'templ1@.service'
594167
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@one.service"
594167
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@two.service"
594167
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@three.service"
594167
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@four.service"
594167
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@five.service"
594167
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@six.service"
594167
+test ! -h "$root/etc/systemd/system/services.target.wants/templ1@seven.service"
594167
+
594167
 : -------template enablement for another template-------------
594167
 cat >"$root/etc/systemd/system/templ2@.service" <
594167
 [Install]