mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-11 05:17:44 +03:00
core: Add optional FDPOLL=0 argument to fdstore
A service can specify FDSTORE=1 FDPOLL=0 to request that PID1 does not poll the fd to remove them on error. If set, fds will only be removed on FDSTOREREMOVE=1 or when the service is done. Fixes: #12086
This commit is contained in:
parent
9dcd43b149
commit
cb5a46b845
@ -219,8 +219,8 @@
|
||||
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>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>). If
|
||||
<varname>FDPOLL=0</varname> is not set and the 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
|
||||
@ -251,6 +251,16 @@
|
||||
submitted name does not follow these restrictions, it is ignored.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>FDPOLL=0</term>
|
||||
|
||||
<listitem><para>When used in combination with <varname>FDSTORE=1</varname>, disables polling of the stored
|
||||
file descriptors regardless of whether or not they are pollable. As this option disables automatic cleanup
|
||||
of the stored file descriptors on EPOLLERR and EPOLLHUP, care must be taken to ensure proper manual cleanup.
|
||||
Use of this option is not generally recommended except for when automatic cleanup has unwanted behavior such
|
||||
as prematurely discarding file descriptors from the store.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<para>It is recommended to prefix variable names that are not
|
||||
|
@ -423,7 +423,7 @@ static int on_fd_store_io(sd_event_source *e, int fd, uint32_t revents, void *us
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int service_add_fd_store(Service *s, int fd, const char *name) {
|
||||
static int service_add_fd_store(Service *s, int fd, const char *name, bool do_poll) {
|
||||
ServiceFDStore *fs;
|
||||
int r;
|
||||
|
||||
@ -459,13 +459,15 @@ static int service_add_fd_store(Service *s, int fd, const char *name) {
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
r = sd_event_add_io(UNIT(s)->manager->event, &fs->event_source, fd, 0, on_fd_store_io, fs);
|
||||
if (r < 0 && r != -EPERM) { /* EPERM indicates fds that aren't pollable, which is OK */
|
||||
free(fs->fdname);
|
||||
free(fs);
|
||||
return r;
|
||||
} else if (r >= 0)
|
||||
(void) sd_event_source_set_description(fs->event_source, "service-fd-store");
|
||||
if (do_poll) {
|
||||
r = sd_event_add_io(UNIT(s)->manager->event, &fs->event_source, fd, 0, on_fd_store_io, fs);
|
||||
if (r < 0 && r != -EPERM) { /* EPERM indicates fds that aren't pollable, which is OK */
|
||||
free(fs->fdname);
|
||||
free(fs);
|
||||
return r;
|
||||
} 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++;
|
||||
@ -473,7 +475,7 @@ static int service_add_fd_store(Service *s, int fd, const char *name) {
|
||||
return 1; /* fd newly stored */
|
||||
}
|
||||
|
||||
static int service_add_fd_store_set(Service *s, FDSet *fds, const char *name) {
|
||||
static int service_add_fd_store_set(Service *s, FDSet *fds, const char *name, bool do_poll) {
|
||||
int r;
|
||||
|
||||
assert(s);
|
||||
@ -485,7 +487,7 @@ static int service_add_fd_store_set(Service *s, FDSet *fds, const char *name) {
|
||||
if (fd < 0)
|
||||
break;
|
||||
|
||||
r = service_add_fd_store(s, fd, name);
|
||||
r = service_add_fd_store(s, fd, name, do_poll);
|
||||
if (r == -EXFULL)
|
||||
return log_unit_warning_errno(UNIT(s), r,
|
||||
"Cannot store more fds than FileDescriptorStoreMax=%u, closing remaining.",
|
||||
@ -2961,7 +2963,7 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
|
||||
fdn += strspn(fdn, WHITESPACE);
|
||||
(void) cunescape(fdn, 0, &t);
|
||||
|
||||
r = service_add_fd_store(s, fd, t);
|
||||
r = service_add_fd_store(s, fd, t, true);
|
||||
if (r < 0)
|
||||
log_unit_error_errno(u, r, "Failed to add fd to store: %m");
|
||||
else
|
||||
@ -4068,7 +4070,7 @@ static void service_notify_message(
|
||||
name = NULL;
|
||||
}
|
||||
|
||||
(void) service_add_fd_store_set(s, fds, name);
|
||||
(void) service_add_fd_store_set(s, fds, name, !strv_contains(tags, "FDPOLL=0"));
|
||||
}
|
||||
|
||||
/* Notify clients about changed status or main pid */
|
||||
|
Loading…
Reference in New Issue
Block a user