[systemd-commits] 5 commits - TODO configure.ac src/core src/machine src/nspawn src/run src/shared src/test
Lennart Poettering
lennart at kemper.freedesktop.org
Tue Jan 6 18:09:39 PST 2015
TODO | 2
configure.ac | 2
src/core/service.c | 183 ++++++++++++++++++++++++++++-------------------
src/machine/machinectl.c | 51 ++++++++++++-
src/nspawn/nspawn.c | 2
src/run/run.c | 2
src/shared/missing.h | 10 ++
src/shared/ptyfwd.c | 60 +++++++++++++--
src/shared/ptyfwd.h | 5 +
src/shared/util.c | 63 +++++++++++++---
src/test/test-util.c | 35 ++++++++
11 files changed, 315 insertions(+), 100 deletions(-)
New commits:
commit c006826886d2796b10ecc09f88d460ca642d3c63
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Jan 7 03:08:29 2015 +0100
update TODO
diff --git a/TODO b/TODO
index 3aeef66..3aeef3c 100644
--- a/TODO
+++ b/TODO
@@ -33,8 +33,6 @@ Features:
* support mbr raw disk images in systemd-nspawn, so that we can boot fedora cloud images unmodified
-* add fd store to pid 1 serialization
-
* rework sigbus stuff to use mutex
* create importd daemon, move "systemd-import" tool into machinectl
commit 0ec5543c4c0318552a4dcdd83210793347b93081
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Jan 7 03:08:00 2015 +0100
machinectl: make sure that "machinectl login" exits immediately when the machine it is connected to dies
diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c
index 11f2273..7e995ca 100644
--- a/src/machine/machinectl.c
+++ b/src/machine/machinectl.c
@@ -1230,16 +1230,42 @@ finish:
return r;
}
+static int on_machine_removed(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
+ PTYForward ** forward = (PTYForward**) userdata;
+ int r;
+
+ assert(bus);
+ assert(m);
+ assert(forward);
+
+ if (*forward) {
+ /* If the forwarder is already initialized, tell it to
+ * exit on the next hangup */
+
+ r = pty_forward_set_repeat(*forward, false);
+ if (r >= 0)
+ return 0;
+
+ log_error_errno(r, "Failed to set repeat flag: %m");
+ }
+
+ /* On error, or when the forwarder is not initialized yet, quit immediately */
+ sd_event_exit(sd_bus_get_event(bus), EXIT_FAILURE);
+ return 0;
+}
+
static int login_machine(int argc, char *argv[], void *userdata) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
+ _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL;
_cleanup_(pty_forward_freep) PTYForward *forward = NULL;
_cleanup_event_unref_ sd_event *event = NULL;
int master = -1, r, ret = 0;
sd_bus *bus = userdata;
- const char *pty;
+ const char *pty, *match;
sigset_t mask;
char last_char = 0;
+ bool machine_died;
assert(bus);
@@ -1257,6 +1283,19 @@ static int login_machine(int argc, char *argv[], void *userdata) {
if (r < 0)
return log_error_errno(r, "Failed to attach bus to event loop: %m");
+ match = strappenda("type='signal',"
+ "sender='org.freedesktop.machine1',"
+ "path='/org/freedesktop/machine1',",
+ "interface='org.freedesktop.machine1.Manager',"
+ "member='MachineRemoved',"
+ "arg0='",
+ argv[1],
+ "'");
+
+ r = sd_bus_add_match(bus, &slot, match, on_machine_removed, &forward);
+ if (r < 0)
+ return log_error_errno(r, "Failed to add machine removal match: %m");
+
r = sd_bus_message_new_method_call(bus,
&m,
"org.freedesktop.machine1",
@@ -1288,7 +1327,7 @@ static int login_machine(int argc, char *argv[], void *userdata) {
sigset_add_many(&mask, SIGWINCH, SIGTERM, SIGINT, -1);
assert_se(sigprocmask(SIG_BLOCK, &mask, NULL) == 0);
- log_info("Connected to container %s. Press ^] three times within 1s to exit session.", argv[1]);
+ log_info("Connected to machine %s. Press ^] three times within 1s to exit session.", argv[1]);
sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
@@ -1301,14 +1340,18 @@ static int login_machine(int argc, char *argv[], void *userdata) {
if (r < 0)
return log_error_errno(r, "Failed to run event loop: %m");
- pty_forward_last_char(forward, &last_char);
+ pty_forward_get_last_char(forward, &last_char);
+ machine_died = pty_forward_get_repeat(forward) == 0;
forward = pty_forward_free(forward);
if (last_char != '\n')
fputc('\n', stdout);
- log_info("Connection to container %s terminated.", argv[1]);
+ if (machine_died)
+ log_info("Machine %s terminated.", argv[1]);
+ else
+ log_info("Connection to machine %s terminated.", argv[1]);
sd_event_get_exit_code(event, &ret);
return ret;
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 1ac0a70..89bbf2b 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -3668,7 +3668,7 @@ int main(int argc, char *argv[]) {
goto finish;
}
- pty_forward_last_char(forward, &last_char);
+ pty_forward_get_last_char(forward, &last_char);
forward = pty_forward_free(forward);
diff --git a/src/run/run.c b/src/run/run.c
index 22abb0e..d6d0b42 100644
--- a/src/run/run.c
+++ b/src/run/run.c
@@ -789,7 +789,7 @@ static int start_transient_service(
if (r < 0)
return log_error_errno(r, "Failed to run event loop: %m");
- pty_forward_last_char(forward, &last_char);
+ pty_forward_get_last_char(forward, &last_char);
forward = pty_forward_free(forward);
diff --git a/src/shared/ptyfwd.c b/src/shared/ptyfwd.c
index 11356e2..db2445c 100644
--- a/src/shared/ptyfwd.c
+++ b/src/shared/ptyfwd.c
@@ -52,6 +52,7 @@ struct PTYForward {
bool master_readable:1;
bool master_writable:1;
bool master_hangup:1;
+ bool master_suppressed_hangup:1;
bool repeat:1;
@@ -170,16 +171,22 @@ static int shovel(PTYForward *f) {
k = read(f->master, f->out_buffer + f->out_buffer_full, LINE_MAX - f->out_buffer_full);
if (k < 0) {
- /* Note that EIO on the master device
- * might be cause by vhangup() or
- * temporary closing of everything on
- * the other side, we treat it like
- * EAGAIN here and try again, unless
- * repeat is off. */
+ if (errno == EAGAIN)
+ f->master_readable = false;
+
+ else if (errno == EIO && f->repeat) {
+
+ /* Note that EIO on the master device
+ * might be cause by vhangup() or
+ * temporary closing of everything on
+ * the other side, we treat it like
+ * EAGAIN here and try again, unless
+ * repeat is off. */
- if (errno == EAGAIN || (errno == EIO && f->repeat))
f->master_readable = false;
- else if (errno == EPIPE || errno == ECONNRESET || errno == EIO) {
+ f->master_suppressed_hangup = true;
+
+ } else if (errno == EPIPE || errno == ECONNRESET || errno == EIO) {
f->master_readable = f->master_writable = false;
f->master_hangup = true;
@@ -243,6 +250,8 @@ static int on_master_event(sd_event_source *e, int fd, uint32_t revents, void *u
assert(fd >= 0);
assert(fd == f->master);
+ f->master_suppressed_hangup = false;
+
if (revents & (EPOLLIN|EPOLLHUP))
f->master_readable = true;
@@ -403,7 +412,7 @@ PTYForward *pty_forward_free(PTYForward *f) {
return NULL;
}
-int pty_forward_last_char(PTYForward *f, char *ch) {
+int pty_forward_get_last_char(PTYForward *f, char *ch) {
assert(f);
assert(ch);
@@ -413,3 +422,36 @@ int pty_forward_last_char(PTYForward *f, char *ch) {
*ch = f->last_char;
return 0;
}
+
+int pty_forward_set_repeat(PTYForward *f, bool repeat) {
+ int r;
+
+ assert(f);
+
+ if (f->repeat == repeat)
+ return 0;
+
+ f->repeat = repeat;
+
+ /* Are we currently in a suppress hangup phase? If so, let's
+ * immediately terminate things */
+ if (!f->repeat && f->master_suppressed_hangup) {
+
+ /* Let's try to read again from the master fd, and if
+ * it is this will now cause termination of the
+ * session. */
+
+ f->master_readable = true;
+ r = shovel(f);
+ if (r < 0)
+ return r;
+ }
+
+ return 0;
+}
+
+int pty_forward_get_repeat(PTYForward *f) {
+ assert(f);
+
+ return f->repeat;
+}
diff --git a/src/shared/ptyfwd.h b/src/shared/ptyfwd.h
index d7b658e..d557dee 100644
--- a/src/shared/ptyfwd.h
+++ b/src/shared/ptyfwd.h
@@ -31,6 +31,9 @@ typedef struct PTYForward PTYForward;
int pty_forward_new(sd_event *event, int master, bool repeat, PTYForward **f);
PTYForward *pty_forward_free(PTYForward *f);
-int pty_forward_last_char(PTYForward *f, char *ch);
+int pty_forward_get_last_char(PTYForward *f, char *ch);
+
+int pty_forward_set_repeat(PTYForward *f, bool repeat);
+int pty_forward_get_repeat(PTYForward *f);
DEFINE_TRIVIAL_CLEANUP_FUNC(PTYForward*, pty_forward_free);
commit f7ad54a301e4ae8dceab54d3ab3934e56c1134ea
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Jan 7 02:14:14 2015 +0100
util: make use of kcmp() to compare fds, if it is available
diff --git a/configure.ac b/configure.ac
index 0496f5e..3dd40c3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -310,7 +310,7 @@ LIBS="$save_LIBS"
AC_CHECK_FUNCS([memfd_create])
AC_CHECK_FUNCS([__secure_getenv secure_getenv])
-AC_CHECK_DECLS([gettid, pivot_root, name_to_handle_at, setns, getrandom, renameat2, LO_FLAGS_PARTSCAN],
+AC_CHECK_DECLS([gettid, pivot_root, name_to_handle_at, setns, getrandom, renameat2, kcmp, LO_FLAGS_PARTSCAN],
[], [], [[
#include <sys/types.h>
#include <unistd.h>
diff --git a/src/shared/missing.h b/src/shared/missing.h
index 5cf179e..cdc38b2 100644
--- a/src/shared/missing.h
+++ b/src/shared/missing.h
@@ -711,3 +711,13 @@ static inline int renameat2(int oldfd, const char *oldname, int newfd, const cha
#ifndef RENAME_NOREPLACE
#define RENAME_NOREPLACE (1 << 0)
#endif
+
+#if !HAVE_DECL_KCMP
+static inline int kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2) {
+ return syscall(__NR_kcmp, pid1, pid2, type, idx1, idx2);
+}
+#endif
+
+#ifndef KCMP_FILE
+#define KCMP_FILE 0
+#endif
diff --git a/src/shared/util.c b/src/shared/util.c
index 409ccc7..6405906 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -7678,13 +7678,35 @@ int fd_setcrtime(int fd, usec_t usec) {
int same_fd(int a, int b) {
struct stat sta, stb;
+ pid_t pid;
+ int r, fa, fb;
assert(a >= 0);
assert(b >= 0);
+ /* Compares two file descriptors. Note that semantics are
+ * quite different depending on whether we have kcmp() or we
+ * don't. If we have kcmp() this will only return true for
+ * dup()ed file descriptors, but not otherwise. If we don't
+ * have kcmp() this will also return true for two fds of the same
+ * file, created by separate open() calls. Since we use this
+ * call mostly for filtering out duplicates in the fd store
+ * this difference hopefully doesn't matter too much. */
+
if (a == b)
return true;
+ /* Try to use kcmp() if we have it. */
+ pid = getpid();
+ r = kcmp(pid, pid, KCMP_FILE, a, b);
+ if (r == 0)
+ return true;
+ if (r > 0)
+ return false;
+ if (errno != ENOSYS)
+ return -errno;
+
+ /* We don't have kcmp(), use fstat() instead. */
if (fstat(a, &sta) < 0)
return -errno;
@@ -7694,9 +7716,27 @@ int same_fd(int a, int b) {
if ((sta.st_mode & S_IFMT) != (stb.st_mode & S_IFMT))
return false;
- if (S_ISREG(sta.st_mode) || S_ISDIR(sta.st_mode) || S_ISFIFO(sta.st_mode) || S_ISSOCK(sta.st_mode) || S_ISLNK(sta.st_mode))
- return (sta.st_dev == stb.st_dev) && (sta.st_ino == stb.st_ino);
+ /* We consider all device fds different, since two device fds
+ * might refer to quite different device contexts even though
+ * they share the same inode and backing dev_t. */
- /* We consider all device fds different... */
- return false;
+ if (S_ISCHR(sta.st_mode) || S_ISBLK(sta.st_mode))
+ return false;
+
+ if (sta.st_dev != stb.st_dev || sta.st_ino != stb.st_ino)
+ return false;
+
+ /* The fds refer to the same inode on disk, let's also check
+ * if they have the same fd flags. This is useful to
+ * distuingish the read and write side of a pipe created with
+ * pipe(). */
+ fa = fcntl(a, F_GETFL);
+ if (fa < 0)
+ return -errno;
+
+ fb = fcntl(b, F_GETFL);
+ if (fb < 0)
+ return -errno;
+
+ return fa == fb;
}
diff --git a/src/test/test-util.c b/src/test/test-util.c
index 3f1b548..3c79f8f 100644
--- a/src/test/test-util.c
+++ b/src/test/test-util.c
@@ -1381,6 +1381,40 @@ static void test_raw_clone(void) {
}
}
+static void test_same_fd(void) {
+ _cleanup_close_pair_ int p[2] = { -1, -1 };
+ _cleanup_close_ int a = -1, b = -1, c = -1;
+
+ assert_se(pipe2(p, O_CLOEXEC) >= 0);
+ assert_se((a = dup(p[0])) >= 0);
+ assert_se((b = open("/dev/null", O_RDONLY|O_CLOEXEC)) >= 0);
+ assert_se((c = dup(a)) >= 0);
+
+ assert_se(same_fd(p[0], p[0]) > 0);
+ assert_se(same_fd(p[1], p[1]) > 0);
+ assert_se(same_fd(a, a) > 0);
+ assert_se(same_fd(b, b) > 0);
+
+ assert_se(same_fd(a, p[0]) > 0);
+ assert_se(same_fd(p[0], a) > 0);
+ assert_se(same_fd(c, p[0]) > 0);
+ assert_se(same_fd(p[0], c) > 0);
+ assert_se(same_fd(a, c) > 0);
+ assert_se(same_fd(c, a) > 0);
+
+ assert_se(same_fd(p[0], p[1]) == 0);
+ assert_se(same_fd(p[1], p[0]) == 0);
+ assert_se(same_fd(p[0], b) == 0);
+ assert_se(same_fd(b, p[0]) == 0);
+ assert_se(same_fd(p[1], a) == 0);
+ assert_se(same_fd(a, p[1]) == 0);
+ assert_se(same_fd(p[1], b) == 0);
+ assert_se(same_fd(b, p[1]) == 0);
+
+ assert_se(same_fd(a, b) == 0);
+ assert_se(same_fd(b, a) == 0);
+}
+
int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
@@ -1455,6 +1489,7 @@ int main(int argc, char *argv[]) {
test_unquote_many_words();
test_parse_proc_cmdline();
test_raw_clone();
+ test_same_fd();
return 0;
}
commit a7e07206021c6484a8d33c6ee156ecfb5b90534c
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Jan 7 01:32:13 2015 +0100
util: don't fail recursive bind mounting if we cannot read the mount flags from an obstructed mounted
diff --git a/src/shared/util.c b/src/shared/util.c
index f01022e..409ccc7 100644
--- a/src/shared/util.c
+++ b/src/shared/util.c
@@ -6980,10 +6980,10 @@ int bind_remount_recursive(const char *prefix, bool ro) {
if (mount(cleaned, cleaned, NULL, MS_BIND|MS_REC, NULL) < 0)
return -errno;
- r = get_mount_flags(prefix, &orig_flags);
- if (r < 0)
- return r;
+ orig_flags = 0;
+ (void) get_mount_flags(cleaned, &orig_flags);
orig_flags &= ~MS_RDONLY;
+
if (mount(NULL, prefix, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0)
return -errno;
@@ -7004,10 +7004,13 @@ int bind_remount_recursive(const char *prefix, bool ro) {
if (r < 0)
return r;
- r = get_mount_flags(x, &orig_flags);
- if (r < 0)
- return r;
+ /* Try to reuse the original flag set, but
+ * don't care for errors, in case of
+ * obstructed mounts */
+ orig_flags = 0;
+ (void) get_mount_flags(x, &orig_flags);
orig_flags &= ~MS_RDONLY;
+
if (mount(NULL, x, NULL, orig_flags|MS_BIND|MS_REMOUNT|(ro ? MS_RDONLY : 0), NULL) < 0) {
/* Deal with mount points that are
commit 2339fc936a1f0b1c60cc8a3446a1dbf994c6aaf3
Author: Lennart Poettering <lennart at poettering.net>
Date: Wed Jan 7 01:18:13 2015 +0100
core: implement serialization/deserialization of fd store elements
diff --git a/src/core/service.c b/src/core/service.c
index 78232ee..26b9b56 100644
--- a/src/core/service.c
+++ b/src/core/service.c
@@ -326,6 +326,88 @@ static void service_done(Unit *u) {
service_release_resources(u);
}
+static int on_fd_store_io(sd_event_source *e, int fd, uint32_t revents, void *userdata) {
+ ServiceFDStore *fs = userdata;
+
+ assert(e);
+ assert(fs);
+
+ /* If we get either EPOLLHUP or EPOLLERR, it's time to remove this entry from the fd store */
+ service_fd_store_unlink(fs);
+ return 0;
+}
+
+static int service_add_fd_store(Service *s, int fd) {
+ ServiceFDStore *fs;
+ int r;
+
+ assert(s);
+ assert(fd >= 0);
+
+ if (s->n_fd_store >= s->n_fd_store_max)
+ return 0;
+
+ LIST_FOREACH(fd_store, fs, s->fd_store) {
+ r = same_fd(fs->fd, fd);
+ if (r < 0)
+ return r;
+ if (r > 0) {
+ /* Already included */
+ safe_close(fd);
+ return 1;
+ }
+ }
+
+ fs = new0(ServiceFDStore, 1);
+ if (!fs)
+ return -ENOMEM;
+
+ fs->fd = fd;
+ fs->service = s;
+
+ r = sd_event_add_io(UNIT(s)->manager->event, &fs->event_source, fd, 0, on_fd_store_io, fs);
+ if (r < 0) {
+ free(fs);
+ return r;
+ }
+
+ LIST_PREPEND(fd_store, s->fd_store, fs);
+ s->n_fd_store++;
+
+ return 1;
+}
+
+static int service_add_fd_store_set(Service *s, FDSet *fds) {
+ int r;
+
+ assert(s);
+
+ if (fdset_size(fds) <= 0)
+ return 0;
+
+ while (s->n_fd_store < s->n_fd_store_max) {
+ _cleanup_close_ int fd = -1;
+
+ fd = fdset_steal_first(fds);
+ if (fd < 0)
+ break;
+
+ r = service_add_fd_store(s, fd);
+ if (r < 0)
+ return log_unit_error_errno(UNIT(s)->id, r, "%s: Couldn't add fd to fd store: %m", UNIT(s)->id);
+
+ if (r > 0) {
+ log_unit_debug(UNIT(s)->id, "%s: added fd to fd store.", UNIT(s)->id);
+ fd = -1;
+ }
+ }
+
+ if (fdset_size(fds) > 0)
+ log_unit_warning(UNIT(s)->id, "%s: tried to store more fds than FDStoreMax=%u allows, closing remaining.", UNIT(s)->id, s->n_fd_store_max);
+
+ return 0;
+}
+
static int service_arm_timer(Service *s, usec_t usec) {
int r;
@@ -1801,6 +1883,7 @@ _pure_ static bool service_can_reload(Unit *u) {
static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
Service *s = SERVICE(u);
+ ServiceFDStore *fs;
assert(u);
assert(f);
@@ -1832,7 +1915,8 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
if (s->socket_fd >= 0) {
int copy;
- if ((copy = fdset_put_dup(fds, s->socket_fd)) < 0)
+ copy = fdset_put_dup(fds, s->socket_fd);
+ if (copy < 0)
return copy;
unit_serialize_item_format(u, f, "socket-fd", "%i", copy);
@@ -1841,12 +1925,23 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
if (s->bus_endpoint_fd >= 0) {
int copy;
- if ((copy = fdset_put_dup(fds, s->bus_endpoint_fd)) < 0)
+ copy = fdset_put_dup(fds, s->bus_endpoint_fd);
+ if (copy < 0)
return copy;
unit_serialize_item_format(u, f, "endpoint-fd", "%i", copy);
}
+ LIST_FOREACH(fd_store, fs, s->fd_store) {
+ int copy;
+
+ copy = fdset_put_dup(fds, fs->fd);
+ if (copy < 0)
+ return copy;
+
+ unit_serialize_item_format(u, f, "fd-store-fd", "%i", copy);
+ }
+
if (s->main_exec_status.pid > 0) {
unit_serialize_item_format(u, f, "main-exec-status-pid", PID_FMT,
s->main_exec_status.pid);
@@ -1873,6 +1968,7 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
static int service_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
Service *s = SERVICE(u);
+ int r;
assert(u);
assert(key);
@@ -1968,6 +2064,19 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
safe_close(s->bus_endpoint_fd);
s->bus_endpoint_fd = fdset_remove(fds, fd);
}
+ } else if (streq(key, "fd-store-fd")) {
+ int fd;
+
+ if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
+ log_unit_debug(u->id, "Failed to parse fd-store-fd value %s", value);
+ else {
+ r = service_add_fd_store(s, fd);
+ if (r < 0)
+ log_unit_error_errno(u->id, r, "Failed to add fd to store: %m");
+ else if (r > 0)
+ fdset_remove(fds, fd);
+ }
+
} else if (streq(key, "main-exec-status-pid")) {
pid_t pid;
@@ -2598,74 +2707,6 @@ static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void
return 0;
}
-static int on_fd_store_io(sd_event_source *e, int fd, uint32_t revents, void *userdata) {
- ServiceFDStore *fs = userdata;
-
- assert(e);
- assert(fs);
-
- /* If we get either EPOLLHUP or EPOLLERR, it's time to remove this entry from the fd store */
- service_fd_store_unlink(fs);
- return 0;
-}
-
-static int service_add_fd_set(Service *s, FDSet *fds) {
- int r;
-
- assert(s);
-
- if (fdset_size(fds) <= 0)
- return 0;
-
- while (s->n_fd_store < s->n_fd_store_max) {
- _cleanup_close_ int fd = -1;
- ServiceFDStore *fs;
- bool same = false;
-
- fd = fdset_steal_first(fds);
- if (fd < 0)
- break;
-
- LIST_FOREACH(fd_store, fs, s->fd_store) {
- r = same_fd(fs->fd, fd);
- if (r < 0)
- return log_unit_error_errno(UNIT(s)->id, r, "%s: Couldn't check if same fd: %m", UNIT(s)->id);
- if (r > 0) {
- same = true;
- break;
- }
- }
-
- if (same)
- continue;
-
- fs = new0(ServiceFDStore, 1);
- if (!fs)
- return log_oom();
-
- fs->fd = fd;
- fs->service = s;
-
- r = sd_event_add_io(UNIT(s)->manager->event, &fs->event_source, fd, 0, on_fd_store_io, fs);
- if (r < 0) {
- free(fs);
- return log_unit_error_errno(UNIT(s)->id, r, "%s: Failed to add even source: %m", UNIT(s)->id);
- }
-
- LIST_PREPEND(fd_store, s->fd_store, fs);
- s->n_fd_store++;
-
- fd = -1;
-
- log_unit_debug(UNIT(s)->id, "%s: added fd to fd store.", UNIT(s)->id);
- }
-
- if (fdset_size(fds) > 0)
- log_unit_warning(UNIT(s)->id, "%s: tried to store more fds than FDStoreMax=%u allows, closing remaining.", UNIT(s)->id, s->n_fd_store_max);
-
- return 0;
-}
-
static void service_notify_message(Unit *u, pid_t pid, char **tags, FDSet *fds) {
Service *s = SERVICE(u);
_cleanup_free_ char *cc = NULL;
@@ -2801,7 +2842,7 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags, FDSet *fds)
/* Add the passed fds to the fd store */
if (strv_find(tags, "FDSTORE=1")) {
log_unit_debug(u->id, "%s: got FDSTORE=1", u->id);
- service_add_fd_set(s, fds);
+ service_add_fd_store_set(s, fds);
}
/* Notify clients about changed status or main pid */
More information about the systemd-commits
mailing list