diff options
author | Lennart Poettering <lennart@poettering.net> | 2017-06-20 23:30:30 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2017-06-26 15:14:41 +0200 |
commit | 3ceb72e5582948cd81fa7018716c67ac7f17905e (patch) | |
tree | 219ba2207c2120ea9803cd429720dc57ebd24431 | |
parent | hwdb: Add ID_INPUT_JOYSTICK_INTEGRATION property (#5413) (diff) | |
download | systemd-3ceb72e5582948cd81fa7018716c67ac7f17905e.tar.xz systemd-3ceb72e5582948cd81fa7018716c67ac7f17905e.zip |
core: permit FDSTORE=1 messages with non-pollable fds
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
-rw-r--r-- | man/sd_notify.xml | 52 | ||||
-rw-r--r-- | man/systemd.service.xml | 25 | ||||
-rw-r--r-- | src/core/service.c | 7 |
3 files changed, 40 insertions, 44 deletions
diff --git a/man/sd_notify.xml b/man/sd_notify.xml index 4dcefc4baf..e8ddea2f5f 100644 --- a/man/sd_notify.xml +++ b/man/sd_notify.xml @@ -205,25 +205,24 @@ <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> @@ -312,13 +311,14 @@ <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> diff --git a/man/systemd.service.xml b/man/systemd.service.xml index 95c16fded7..1faac0f762 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -853,21 +853,18 @@ <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> diff --git a/src/core/service.c b/src/core/service.c index df7f1f3053..e1f02ccde1 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -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++; |