socket: if RemoveOnStop= is turned on for a socket, try to unlink() pre-existing...
authorLennart Poettering <lennart@poettering.net>
Wed, 27 Sep 2017 15:48:28 +0000 (17:48 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 27 Sep 2017 15:53:00 +0000 (17:53 +0200)
Normally, Symlinks= failing is not considered fatal nor destructive.
Let's slightly alter behaviour here if RemoveOnStop= is turned on. In
that case the use in a way opted for destructive behaviour and we do
unlink all sockets and symlinks when the socket unit goes down. And that
means we might as well unlink any pre-existing if this mode is selected.

Yeah, it's a bit of a stretch to do this, but @OhNoMoreGit is right: if
RemoveOnStop= is on we are destructive regarding any pre-existing
symlinks on stop, and it would be quite weird if we wouldn't be on
start.

src/core/socket.c

index 157a6db..ba70756 100644 (file)
@@ -1337,6 +1337,16 @@ static int socket_symlink(Socket *s) {
                 (void) mkdir_parents_label(*i, s->directory_mode);
 
                 r = symlink_idempotent(p, *i);
+
+                if (r == -EEXIST && s->remove_on_stop) {
+                        /* If there's already something where we want to create the symlink, and the destructive
+                         * RemoveOnStop= mode is set, then we might as well try to remove what already exists and try
+                         * again. */
+
+                        if (unlink(*i) >= 0)
+                                r = symlink_idempotent(p, *i);
+                }
+
                 if (r < 0)
                         log_unit_warning_errno(UNIT(s), r, "Failed to create symlink %s → %s, ignoring: %m", p, *i);
         }