Merge pull request #6922 from poettering/symlink-sockets

Fixes for Symlinks= handling in socket units
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2017-09-27 19:37:25 +02:00
committed by GitHub
3 changed files with 34 additions and 15 deletions
+7 -8
View File
@@ -804,14 +804,13 @@
<varlistentry>
<term><varname>Symlinks=</varname></term>
<listitem><para>Takes a list of file system paths. The
specified paths will be created as symlinks to the AF_UNIX
socket path or FIFO path of this socket unit. If this setting
is used, only one AF_UNIX socket in the file system or one
FIFO may be configured for the socket unit. Use this option to
manage one or more symlinked alias names for a socket, binding
their lifecycle together. If the empty string is assigned, the
list of paths is reset. Defaults to the empty list.</para></listitem>
<listitem><para>Takes a list of file system paths. The specified paths will be created as symlinks to the
<constant>AF_UNIX</constant> socket path or FIFO path of this socket unit. If this setting is used, only one
<constant>AF_UNIX</constant> socket in the file system or one FIFO may be configured for the socket unit. Use
this option to manage one or more symlinked alias names for a socket, binding their lifecycle together. Note
that if creation of a symlink fails this is not considered fatal for the socket unit, and the socket unit may
still start. If an empty string is assigned, the list of paths is reset. Defaults to an empty
list.</para></listitem>
</varlistentry>
<varlistentry>
+7 -4
View File
@@ -359,22 +359,25 @@ int touch(const char *path) {
}
int symlink_idempotent(const char *from, const char *to) {
_cleanup_free_ char *p = NULL;
int r;
assert(from);
assert(to);
if (symlink(from, to) < 0) {
_cleanup_free_ char *p = NULL;
if (errno != EEXIST)
return -errno;
r = readlink_malloc(to, &p);
if (r < 0)
if (r == -EINVAL) /* Not a symlink? In that case return the original error we encountered: -EEXIST */
return -EEXIST;
if (r < 0) /* Any other error? In that case propagate it as is */
return r;
if (!streq(p, from))
return -EINVAL;
if (!streq(p, from)) /* Not the symlink we want it to be? In that case, propagate the original -EEXIST */
return -EEXIST;
}
return 0;
+20 -3
View File
@@ -38,6 +38,7 @@
#include "exit-status.h"
#include "fd-util.h"
#include "format-util.h"
#include "fs-util.h"
#include "in-addr-util.h"
#include "io-util.h"
#include "label.h"
@@ -1174,7 +1175,7 @@ static int fifo_address_create(
assert(path);
mkdir_parents_label(path, directory_mode);
(void) mkdir_parents_label(path, directory_mode);
r = mac_selinux_create_file_prepare(path, S_IFIFO);
if (r < 0)
@@ -1324,6 +1325,7 @@ static int mq_address_create(
static int socket_symlink(Socket *s) {
const char *p;
char **i;
int r;
assert(s);
@@ -1331,8 +1333,23 @@ static int socket_symlink(Socket *s) {
if (!p)
return 0;
STRV_FOREACH(i, s->symlinks)
symlink_label(p, *i);
STRV_FOREACH(i, s->symlinks) {
(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);
}
return 0;
}