]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: permit FDSTORE=1 messages with non-pollable fds
authorLennart Poettering <lennart@poettering.net>
Tue, 20 Jun 2017 21:30:30 +0000 (23:30 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 26 Jun 2017 13:14:41 +0000 (15:14 +0200)
This also alters the documentation to recommend memfds rather than /run
for serializing state across reboots. That's because /run doesn't
actually have the same lifecycle as the fd store, as it is cleared out
on restarts.

Fixes: #5606
man/sd_notify.xml
man/systemd.service.xml
src/core/service.c

index 4dcefc4bafb8a8be375c218c997b2b7b425e0831..e8ddea2f5fba91a02dedea98ea6e1634491bc4e3 100644 (file)
       <varlistentry>
         <term>FDSTORE=1</term>
 
-        <listitem><para>Stores additional file descriptors in the service manager. File
-        descriptors sent this way will be maintained per-service by the service manager
-        and will be passed again using the usual file descriptor passing logic on the next
-        invocation of the service, see
-        <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
-        This is useful for implementing service restart schemes where services serialize
-        their state to <filename>/run</filename>, push their file descriptors to the
-        system manager, and are then restarted, retrieving their state again via socket
-        passing and <filename>/run</filename>. Note that the service manager will accept
-        messages for a service only if <varname>FileDescriptorStoreMax=</varname> is set
-        to non-zero for it (defaults to zero, see
-        <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
-        File descriptors must be pollable, see
-        <citerefentry><refentrytitle>epoll_ctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>.
-        Multiple arrays of file descriptors may be sent in separate messages, in which
-        case the arrays are combined.  Note that the service manager removes duplicate
-        file descriptors before passing them to the service. Use
-        <function>sd_pid_notify_with_fds()</function> to send messages with
-        <literal>FDSTORE=1</literal>, see below.</para></listitem>
+        <listitem><para>Stores additional file descriptors in the service manager. File descriptors sent this way will
+        be maintained per-service by the service manager and will later be handed back using the usual file descriptor
+        passing logic at the next invocation of the service, see
+        <citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>.  This is
+        useful for implementing services that can restart after an explicit request or a crash without losing
+        state. Any open sockets and other file descriptors which should not be closed during the restart may be stored
+        this way. Application state can either be serialized to a file in <filename>/run</filename>, or better, stored
+        in a <citerefentry><refentrytitle>memfd_create</refentrytitle><manvolnum>2</manvolnum></citerefentry> memory
+        file descriptor. Note that the service manager will accept messages for a service only if its
+        <varname>FileDescriptorStoreMax=</varname> setting is non-zero (defaults to zero, see
+        <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>). If file
+        descriptors sent are pollable (see
+        <citerefentry><refentrytitle>epoll_ctl</refentrytitle><manvolnum>2</manvolnum></citerefentry>), then any
+        <constant>EPOLLHUP</constant> or <constant>EPOLLERR</constant> event seen on them will result in their
+        automatic removal from the store. Multiple arrays of file descriptors may be sent in separate messages, in
+        which case the arrays are combined. Note that the service manager removes duplicate (pointing to the same
+        object) file descriptors before passing them to the service. Use <function>sd_pid_notify_with_fds()</function>
+        to send messages with <literal>FDSTORE=1</literal>, see below.</para></listitem>
       </varlistentry>
 
       <varlistentry>
   <refsect1>
     <title>Return Value</title>
 
-    <para>On failure, these calls return a negative errno-style error
-    code. If <varname>$NOTIFY_SOCKET</varname> was not set and hence
-    no status data could be sent, 0 is returned. If the status was
-    sent, these functions return with a positive return value. In
-    order to support both, init systems that implement this scheme and
-    those which do not, it is generally recommended to ignore the
-    return value of this call.</para>
+    <para>On failure, these calls return a negative errno-style error code. If <varname>$NOTIFY_SOCKET</varname> was
+    not set and hence no status message could be sent, 0 is returned. If the status was sent, these functions return a
+    positive value. In order to support both service managers that implement this scheme and those which do not, it is
+    generally recommended to ignore the return value of this call. Note that the return value simply indicates whether
+    the notification message was enqueued properly, it does not reflect whether the message could be processed
+    successfully. Specifically, no error is returned when a file descriptor is attempted to be stored using
+    <varname>FDSTORE=1</varname> but the service is not actually configured to permit storing of file descriptors (see
+    above).</para>
   </refsect1>
 
   <refsect1>
index 95c16fded7c43072b5185e5eb590209c65c34e4b..1faac0f76226ef4fbe9ea4c9a9583933471326ad 100644 (file)
 
       <varlistentry>
         <term><varname>FileDescriptorStoreMax=</varname></term>
-        <listitem><para>Configure how many file descriptors may be
-        stored in the service manager for the service using
+        <listitem><para>Configure how many file descriptors may be stored in the service manager for the service using
         <citerefentry><refentrytitle>sd_pid_notify_with_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>'s
-        <literal>FDSTORE=1</literal> messages. This is useful for
-        implementing service restart schemes where the state is
-        serialized to <filename>/run</filename> and the file
-        descriptors passed to the service manager, to allow restarts
-        without losing state. Defaults to 0, i.e. no file descriptors
-        may be stored in the service manager. All file
-        descriptors passed to the service manager from a specific
-        service are passed back to the service's main process on the
-        next service restart. Any file descriptors passed to the
-        service manager are automatically closed when POLLHUP or
-        POLLERR is seen on them, or when the service is fully stopped
-        and no job is queued or being executed for it.</para></listitem>
+        <literal>FDSTORE=1</literal> messages. This is useful for implementing services that can restart after an
+        explicit request or a crash without losing state. Any open sockets and other file descriptors which should not
+        be closed during the restart may be stored this way. Application state can either be serialized to a file in
+        <filename>/run</filename>, or better, stored in a
+        <citerefentry><refentrytitle>memfd_create</refentrytitle><manvolnum>2</manvolnum></citerefentry> memory file
+        descriptor. Defaults to 0, i.e. no file descriptors may be stored in the service manager. All file descriptors
+        passed to the service manager from a specific service are passed back to the service's main process on the next
+        service restart. Any file descriptors passed to the service manager are automatically closed when
+        <constant>POLLHUP</constant> or <constant>POLLERR</constant> is seen on them, or when the service is fully
+        stopped and no job is queued or being executed for it.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index df7f1f3053a815f3613164d8f2744226475992e6..e1f02ccde1939b8be70d95b7fb921ef0d104f4b4 100644 (file)
@@ -413,13 +413,12 @@ static int service_add_fd_store(Service *s, int fd, const char *name) {
         }
 
         r = sd_event_add_io(UNIT(s)->manager->event, &fs->event_source, fd, 0, on_fd_store_io, fs);
-        if (r < 0) {
+        if (r < 0 && r != -EPERM) { /* EPERM indicates fds that aren't pollable, which is OK */
                 free(fs->fdname);
                 free(fs);
                 return r;
-        }
-
-        (void) sd_event_source_set_description(fs->event_source, "service-fd-store");
+        } else if (r >= 0)
+                (void) sd_event_source_set_description(fs->event_source, "service-fd-store");
 
         LIST_PREPEND(fd_store, s->fd_store, fs);
         s->n_fd_store++;