]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
shared/install: try harder to find enablement symlinks when disabling a unit
authorFranck Bui <fbui@suse.com>
Mon, 25 Nov 2019 15:05:56 +0000 (16:05 +0100)
committerFranck Bui <fbui@suse.com>
Fri, 10 Jan 2020 13:28:42 +0000 (14:28 +0100)
It might be needed to follow symlinks more deeply when we're looking for
enablement symlinks pointing to the removed service.

Let's consider the case where service 'old' is being renamed 'new' (will happen
most likely during package upgrade). Before the service is going to be renamed,
there's the following enablement symlink:

 /etc/systemd/system/multi-user.target.wants/old.service -> /usr/lib/systemd/system/old.service

In order to rename 'old' into 'new' and transparently restart the service, the
old name is still provided as a 'static' alias for the new service. This should
also help keeping backward compatibilities since the old name might still be
embedded in unit files, scripts, generators and such.

Hence after the package is upgraded, the following symlinks including the
enablement symlink are present:

 /usr/lib/systemd/system/old.service -> new.service
 /etc/systemd/system/multi-user.target.wants/old.service -> /usr/lib/systemd/system/old.service

If later the user decides to disable the service, we should figure out that the
enablement symlink (which still has the old name) is actually referring to 'new'
(indirectly) even if it points to the alias.

src/shared/install.c

index 0e673b33588f8e824640f322b417b73e9b3bab7b..cc628d7369a065afcbf8493f506171c47b891c83 100644 (file)
@@ -585,7 +585,7 @@ static int remove_marked_symlinks_fd(
                                 return -ENOMEM;
                         path_simplify(p, false);
 
-                        q = readlink_malloc(p, &dest);
+                        q = chase_symlinks(p, NULL, CHASE_NONEXISTENT, &dest, NULL);
                         if (q == -ENOENT)
                                 continue;
                         if (q < 0) {