summaryrefslogtreecommitdiffstats
path: root/src/core/service.c
diff options
context:
space:
mode:
authorKenny Levinsen <kl@kl.wtf>2020-04-08 20:19:30 +0200
committerKenny Levinsen <kl@kl.wtf>2020-04-30 19:42:26 +0200
commitcb5a46b84504006196e4415266c1a6414c07c9b3 (patch)
treeaef16cbee4a79b4c5f570fa21a8f1f72e493811c /src/core/service.c
parentnotify: beef up --pid= logic (diff)
downloadsystemd-cb5a46b84504006196e4415266c1a6414c07c9b3.tar.xz
systemd-cb5a46b84504006196e4415266c1a6414c07c9b3.zip
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
Diffstat (limited to '')
-rw-r--r--src/core/service.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/src/core/service.c b/src/core/service.c
index 7d5928e455..cc8b44f1c8 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 */