From: Kenny Levinsen Date: Wed, 8 Apr 2020 18:19:30 +0000 (+0200) Subject: core: Add optional FDPOLL=0 argument to fdstore X-Git-Tag: v246-rc1~467^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cb5a46b84504006196e4415266c1a6414c07c9b3;p=thirdparty%2Fsystemd.git 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 --- diff --git a/man/sd_notify.xml b/man/sd_notify.xml index 3046ca88ee7..0157ce864a0 100644 --- a/man/sd_notify.xml +++ b/man/sd_notify.xml @@ -219,8 +219,8 @@ in a memfd_create2 memory file descriptor. Note that the service manager will accept messages for a service only if its FileDescriptorStoreMax= setting is non-zero (defaults to zero, see - systemd.service5). If file - descriptors sent are pollable (see + systemd.service5). If + FDPOLL=0 is not set and the file descriptors sent are pollable (see epoll_ctl2), then any EPOLLHUP or EPOLLERR 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. + + FDPOLL=0 + + When used in combination with FDSTORE=1, 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. + + It is recommended to prefix variable names that are not diff --git a/src/core/service.c b/src/core/service.c index 7d5928e455c..cc8b44f1c80 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -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 */