Merge pull request #6922 from poettering/symlink-sockets
Fixes for Symlinks= handling in socket units
This commit is contained in:
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user