]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
socket: New option 'FlushPending' (boolean) to flush socket before entering listening...
authorRenaud Métrich <rmetrich@redhat.com>
Thu, 20 Aug 2020 11:00:37 +0000 (13:00 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 1 Sep 2020 15:20:23 +0000 (17:20 +0200)
Disabled by default. When Enabled, before listening on the socket, flush the content.
Applies when Accept=no only.

docs/TRANSIENT-SETTINGS.md
man/org.freedesktop.systemd1.xml
man/systemd.socket.xml
src/core/dbus-socket.c
src/core/load-fragment-gperf.gperf.m4
src/core/socket.c
src/core/socket.h
src/shared/bus-unit-util.c

index 2c0aea07da292a980a1da96bf2f139d6466e6043..89f0a7e80d137f927bbe6a85ed1d07e969aa7ced 100644 (file)
@@ -415,6 +415,7 @@ Most socket unit settings are available to transient units.
 ✓ SocketMode=
 ✓ DirectoryMode=
 ✓ Accept=
+✓ FlushPending=
 ✓ Writable=
 ✓ MaxConnections=
 ✓ MaxConnectionsPerSource=
index 75909aa9e5234e96b72d21134d24e69fc81f5245..1093458e8927d256a53c52186e9ec3d8749d331b 100644 (file)
@@ -3950,6 +3950,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly u NRefused = ...;
       @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
+      readonly u FlushPending = ...;
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("false")
       readonly s FileDescriptorName = '...';
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
       readonly i SocketProtocol = ...;
@@ -5031,6 +5033,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
 
     <variablelist class="dbus-property" generated="True" extra-ref="NRefused"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="FlushPending"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="FileDescriptorName"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="SocketProtocol"/>
@@ -5508,6 +5512,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
       meaning as they have for the corresponding field of service units (see above). In addition to that,
       the value <literal>service-failed-permanent</literal> indicates that the service of this socket failed
       continuously.</para>
+
+      <para><varname>FlushPending</varname> specifies whether to flush the socket
+      just before entering the listening state. This setting only applies to sockets with
+      <varname>Accept=</varname> set to <literal>no</literal>.</para>
     </refsect2>
   </refsect1>
 
index 29ce0b1c2008749c8aac7be65c1caebe15222766..1bcbef20332f029a08d5116c925c90d1bae4d813 100644 (file)
         false, in read-only mode. Defaults to false.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>FlushPending=</varname></term>
+        <listitem><para>Takes a boolean argument. May only be used when
+        <option>Accept=no</option>. If yes, the socket's buffers are cleared after the
+        triggered service exited. This causes any pending data to be
+        flushed and any pending incoming connections to be rejected. If no, the
+        socket's buffers won't be cleared, permitting the service to handle any
+        pending connections after restart, which is the usually expected behaviour.
+        Defaults to <option>no</option>.
+        </para></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>MaxConnections=</varname></term>
         <listitem><para>The maximum number of connections to
index 90a95c996da20940878ffb25cf5b27035358e85e..07d030adb3a6235f433ff6673d9f74085bb8e648 100644 (file)
@@ -86,6 +86,7 @@ const sd_bus_vtable bus_socket_vtable[] = {
         SD_BUS_PROPERTY("SocketMode", "u", bus_property_get_mode, offsetof(Socket, socket_mode), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("DirectoryMode", "u", bus_property_get_mode, offsetof(Socket, directory_mode), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Accept", "b", bus_property_get_bool, offsetof(Socket, accept), SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("FlushPending", "b", bus_property_get_bool, offsetof(Socket, flush_pending), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("Writable", "b", bus_property_get_bool, offsetof(Socket, writable), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("KeepAlive", "b", bus_property_get_bool, offsetof(Socket, keep_alive), SD_BUS_VTABLE_PROPERTY_CONST),
         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(
         if (streq(name, "Accept"))
                 return bus_set_transient_bool(u, name, &s->accept, message, flags, error);
 
+        if (streq(name, "FlushPending"))
+                return bus_set_transient_bool(u, name, &s->flush_pending, message, flags, error);
+
         if (streq(name, "Writable"))
                 return bus_set_transient_bool(u, name, &s->writable, message, flags, error);
 
index 45147f0d57304ae77c2a1fb37c0e1a12126e08b5..4bad8314dcdb68aaccc91f7faab00f8c2910df54 100644 (file)
@@ -391,6 +391,7 @@ Socket.SocketGroup,              config_parse_user_group_compat,     0,
 Socket.SocketMode,               config_parse_mode,                  0,                             offsetof(Socket, socket_mode)
 Socket.DirectoryMode,            config_parse_mode,                  0,                             offsetof(Socket, directory_mode)
 Socket.Accept,                   config_parse_bool,                  0,                             offsetof(Socket, accept)
+Socket.FlushPending,             config_parse_bool,                  0,                             offsetof(Socket, flush_pending)
 Socket.Writable,                 config_parse_bool,                  0,                             offsetof(Socket, writable)
 Socket.MaxConnections,           config_parse_unsigned,              0,                             offsetof(Socket, max_connections)
 Socket.MaxConnectionsPerSource,  config_parse_unsigned,              0,                             offsetof(Socket, max_connections_per_source)
index 0588a34e3860b6b107fddbcb77fbd12b39e7037d..ac8d1e7aea08983883a8ca677618357307b44d14 100644 (file)
@@ -72,6 +72,7 @@ static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
 
 static int socket_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
 static int socket_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
+static void flush_ports(Socket *s);
 
 static void socket_init(Unit *u) {
         Socket *s = SOCKET(u);
@@ -669,6 +670,11 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
                         prefix, s->n_connections,
                         prefix, s->max_connections,
                         prefix, s->max_connections_per_source);
+        else
+                fprintf(f,
+                        "%sFlushPending: %s\n",
+                         prefix, yes_no(s->flush_pending));
+
 
         if (s->priority >= 0)
                 fprintf(f,
@@ -2201,6 +2207,11 @@ static void socket_enter_listening(Socket *s) {
         int r;
         assert(s);
 
+        if (!s->accept && s->flush_pending) {
+                log_unit_debug(UNIT(s), "Flushing socket before listening.");
+                flush_ports(s);
+        }
+
         r = socket_watch_fds(s);
         if (r < 0) {
                 log_unit_warning_errno(UNIT(s), r, "Failed to watch sockets: %m");
index bb14e6b0f713e123d869e71df2d48b8d6625dd40..cf475e26389fe079e700a9a4c6061c6c5920ac6e 100644 (file)
@@ -110,6 +110,7 @@ struct Socket {
         bool accept;
         bool remove_on_stop;
         bool writable;
+        bool flush_pending;
 
         int socket_protocol;
 
index 2ad196e8244dd10758e693ac06f95dd7c62d16a2..b6def087f63ecaca18c0e3a44349c7a1d85fbb07 100644 (file)
@@ -1956,6 +1956,7 @@ static int bus_append_socket_property(sd_bus_message *m, const char *field, cons
         int r;
 
         if (STR_IN_SET(field, "Accept",
+                              "FlushPending",
                               "Writable",
                               "KeepAlive",
                               "NoDelay",