[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