diff options
author | Lennart Poettering <lennart@poettering.net> | 2016-05-06 13:29:26 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2016-05-06 13:29:26 +0200 |
commit | 60d9771c593e0702a892a4372443e63b38cdbcba (patch) | |
tree | 8c9e737e8ada747d89705e68e6b136cba0365bf1 /src/core/socket.c | |
parent | 01a8b4675739463b8d6abf0931099b244c6f072b (diff) |
core: rework how we flush incoming traffic when a socket unit goes down
Previously, we'd simply close and reopen the socket file descriptors. This is
problematic however, as we won't transition through the SOCKET_CHOWN state
then, and thus the file ownership won't be correct for the sockets.
Rework the flushing logic, and actually read any queued data from the sockets
for flushing, and accept any queued messages and disconnect them.
Diffstat (limited to 'src/core/socket.c')
-rw-r--r-- | src/core/socket.c | 39 |
1 files changed, 19 insertions, 20 deletions
diff --git a/src/core/socket.c b/src/core/socket.c index 50912c33dd..091567ed4f 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -28,7 +28,6 @@ #include <unistd.h> #include <linux/sctp.h> -#include "sd-event.h" #include "alloc-util.h" #include "bus-error.h" #include "bus-util.h" @@ -38,6 +37,7 @@ #include "exit-status.h" #include "fd-util.h" #include "formats-util.h" +#include "io-util.h" #include "label.h" #include "log.h" #include "missing.h" @@ -1960,6 +1960,21 @@ fail: socket_enter_dead(s, SOCKET_FAILURE_RESOURCES); } +static void flush_ports(Socket *s) { + SocketPort *p; + + /* Flush all incoming traffic, regardless if actual bytes or new connections, so that this socket isn't busy + * anymore */ + + LIST_FOREACH(port, p, s->ports) { + if (p->fd < 0) + continue; + + (void) flush_accept(p->fd); + (void) flush_fd(p->fd); + } +} + static void socket_enter_running(Socket *s, int cfd) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; int r; @@ -1969,31 +1984,15 @@ static void socket_enter_running(Socket *s, int cfd) { assert(s); - /* We don't take connections anymore if we are supposed to - * shut down anyway */ + /* We don't take connections anymore if we are supposed to shut down anyway */ if (unit_stop_pending(UNIT(s))) { log_unit_debug(UNIT(s), "Suppressing connection request since unit stop is scheduled."); if (cfd >= 0) cfd = safe_close(cfd); - else { - /* Flush all sockets by closing and reopening them */ - socket_close_fds(s); - - r = socket_open_fds(s); - if (r < 0) { - log_unit_warning_errno(UNIT(s), r, "Failed to listen on sockets: %m"); - socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES); - return; - } - - r = socket_watch_fds(s); - if (r < 0) { - log_unit_warning_errno(UNIT(s), r, "Failed to watch sockets: %m"); - socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES); - } - } + else + flush_ports(s); return; } |