Skip to content

Commit 3e5f04b

Browse files
rmetrichpoettering
authored andcommitted
socket: New option 'FlushPending' (boolean) to flush socket before entering listening state
Disabled by default. When Enabled, before listening on the socket, flush the content. Applies when Accept=no only.
1 parent f77d6ec commit 3e5f04b

File tree

8 files changed

+39
-0
lines changed

8 files changed

+39
-0
lines changed

docs/TRANSIENT-SETTINGS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ Most socket unit settings are available to transient units.
415415
✓ SocketMode=
416416
✓ DirectoryMode=
417417
✓ Accept=
418+
✓ FlushPending=
418419
✓ Writable=
419420
✓ MaxConnections=
420421
✓ MaxConnectionsPerSource=

man/org.freedesktop.systemd1.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3950,6 +3950,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
39503950
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
39513951
readonly u NRefused = ...;
39523952
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
3953+
readonly u FlushPending = ...;
3954+
@org.freedesktop.DBus.Property.EmitsChangedSignal("false")
39533955
readonly s FileDescriptorName = '...';
39543956
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
39553957
readonly i SocketProtocol = ...;
@@ -5031,6 +5033,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
50315033

50325034
<variablelist class="dbus-property" generated="True" extra-ref="NRefused"/>
50335035

5036+
<variablelist class="dbus-property" generated="True" extra-ref="FlushPending"/>
5037+
50345038
<variablelist class="dbus-property" generated="True" extra-ref="FileDescriptorName"/>
50355039

50365040
<variablelist class="dbus-property" generated="True" extra-ref="SocketProtocol"/>
@@ -5508,6 +5512,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
55085512
meaning as they have for the corresponding field of service units (see above). In addition to that,
55095513
the value <literal>service-failed-permanent</literal> indicates that the service of this socket failed
55105514
continuously.</para>
5515+
5516+
<para><varname>FlushPending</varname> specifies whether to flush the socket
5517+
just before entering the listening state. This setting only applies to sockets with
5518+
<varname>Accept=</varname> set to <literal>no</literal>.</para>
55115519
</refsect2>
55125520
</refsect1>
55135521

man/systemd.socket.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,18 @@
427427
false, in read-only mode. Defaults to false.</para></listitem>
428428
</varlistentry>
429429

430+
<varlistentry>
431+
<term><varname>FlushPending=</varname></term>
432+
<listitem><para>Takes a boolean argument. May only be used when
433+
<option>Accept=no</option>. If yes, the socket's buffers are cleared after the
434+
triggered service exited. This causes any pending data to be
435+
flushed and any pending incoming connections to be rejected. If no, the
436+
socket's buffers won't be cleared, permitting the service to handle any
437+
pending connections after restart, which is the usually expected behaviour.
438+
Defaults to <option>no</option>.
439+
</para></listitem>
440+
</varlistentry>
441+
430442
<varlistentry>
431443
<term><varname>MaxConnections=</varname></term>
432444
<listitem><para>The maximum number of connections to

src/core/dbus-socket.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ const sd_bus_vtable bus_socket_vtable[] = {
8686
SD_BUS_PROPERTY("SocketMode", "u", bus_property_get_mode, offsetof(Socket, socket_mode), SD_BUS_VTABLE_PROPERTY_CONST),
8787
SD_BUS_PROPERTY("DirectoryMode", "u", bus_property_get_mode, offsetof(Socket, directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
8888
SD_BUS_PROPERTY("Accept", "b", bus_property_get_bool, offsetof(Socket, accept), SD_BUS_VTABLE_PROPERTY_CONST),
89+
SD_BUS_PROPERTY("FlushPending", "b", bus_property_get_bool, offsetof(Socket, flush_pending), SD_BUS_VTABLE_PROPERTY_CONST),
8990
SD_BUS_PROPERTY("Writable", "b", bus_property_get_bool, offsetof(Socket, writable), SD_BUS_VTABLE_PROPERTY_CONST),
9091
SD_BUS_PROPERTY("KeepAlive", "b", bus_property_get_bool, offsetof(Socket, keep_alive), SD_BUS_VTABLE_PROPERTY_CONST),
9192
SD_BUS_PROPERTY("KeepAliveTimeUSec", "t", bus_property_get_usec, offsetof(Socket, keep_alive_time), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -179,6 +180,9 @@ static int bus_socket_set_transient_property(
179180
if (streq(name, "Accept"))
180181
return bus_set_transient_bool(u, name, &s->accept, message, flags, error);
181182

183+
if (streq(name, "FlushPending"))
184+
return bus_set_transient_bool(u, name, &s->flush_pending, message, flags, error);
185+
182186
if (streq(name, "Writable"))
183187
return bus_set_transient_bool(u, name, &s->writable, message, flags, error);
184188

src/core/load-fragment-gperf.gperf.m4

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@ Socket.SocketGroup, config_parse_user_group_compat, 0,
391391
Socket.SocketMode, config_parse_mode, 0, offsetof(Socket, socket_mode)
392392
Socket.DirectoryMode, config_parse_mode, 0, offsetof(Socket, directory_mode)
393393
Socket.Accept, config_parse_bool, 0, offsetof(Socket, accept)
394+
Socket.FlushPending, config_parse_bool, 0, offsetof(Socket, flush_pending)
394395
Socket.Writable, config_parse_bool, 0, offsetof(Socket, writable)
395396
Socket.MaxConnections, config_parse_unsigned, 0, offsetof(Socket, max_connections)
396397
Socket.MaxConnectionsPerSource, config_parse_unsigned, 0, offsetof(Socket, max_connections_per_source)

src/core/socket.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
7272

7373
static int socket_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
7474
static int socket_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
75+
static void flush_ports(Socket *s);
7576

7677
static void socket_init(Unit *u) {
7778
Socket *s = SOCKET(u);
@@ -669,6 +670,11 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
669670
prefix, s->n_connections,
670671
prefix, s->max_connections,
671672
prefix, s->max_connections_per_source);
673+
else
674+
fprintf(f,
675+
"%sFlushPending: %s\n",
676+
prefix, yes_no(s->flush_pending));
677+
672678

673679
if (s->priority >= 0)
674680
fprintf(f,
@@ -2201,6 +2207,11 @@ static void socket_enter_listening(Socket *s) {
22012207
int r;
22022208
assert(s);
22032209

2210+
if (!s->accept && s->flush_pending) {
2211+
log_unit_debug(UNIT(s), "Flushing socket before listening.");
2212+
flush_ports(s);
2213+
}
2214+
22042215
r = socket_watch_fds(s);
22052216
if (r < 0) {
22062217
log_unit_warning_errno(UNIT(s), r, "Failed to watch sockets: %m");

src/core/socket.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ struct Socket {
110110
bool accept;
111111
bool remove_on_stop;
112112
bool writable;
113+
bool flush_pending;
113114

114115
int socket_protocol;
115116

src/shared/bus-unit-util.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1956,6 +1956,7 @@ static int bus_append_socket_property(sd_bus_message *m, const char *field, cons
19561956
int r;
19571957

19581958
if (STR_IN_SET(field, "Accept",
1959+
"FlushPending",
19591960
"Writable",
19601961
"KeepAlive",
19611962
"NoDelay",

0 commit comments

Comments
 (0)