From 33dd8945461f8d0ae10d11801fd517d4ea299591 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 17 Oct 2024 09:43:37 +0200 Subject: fdset: optionally, close remaining fds asynchronously --- src/core/bpf-restrict-ifaces.c | 2 +- src/core/bpf-socket-bind.c | 2 +- src/nspawn/nspawn.c | 2 +- src/shared/fdset.c | 16 +++++++++++++--- src/shared/fdset.h | 5 ++++- 5 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/core/bpf-restrict-ifaces.c b/src/core/bpf-restrict-ifaces.c index a39f4895f2..af49abd677 100644 --- a/src/core/bpf-restrict-ifaces.c +++ b/src/core/bpf-restrict-ifaces.c @@ -159,7 +159,7 @@ int bpf_restrict_ifaces_install(Unit *u) { return 0; r = restrict_ifaces_install_impl(u); - fdset_close(crt->initial_restrict_ifaces_link_fds); + fdset_close(crt->initial_restrict_ifaces_link_fds, /* async= */ false); return r; } diff --git a/src/core/bpf-socket-bind.c b/src/core/bpf-socket-bind.c index 2a1a0278d5..8853f3eecc 100644 --- a/src/core/bpf-socket-bind.c +++ b/src/core/bpf-socket-bind.c @@ -229,7 +229,7 @@ int bpf_socket_bind_install(Unit *u) { return 0; r = socket_bind_install_impl(u); - fdset_close(crt->initial_socket_bind_link_fds); + fdset_close(crt->initial_socket_bind_link_fds, /* async= */ false); return r; } diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 70ce4e6d79..8fc58665e4 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -5267,7 +5267,7 @@ static int run_container( barrier_set_role(&barrier, BARRIER_PARENT); - fdset_close(fds); + fdset_close(fds, /* async= */ false); fd_inner_socket_pair[1] = safe_close(fd_inner_socket_pair[1]); fd_outer_socket_pair[1] = safe_close(fd_outer_socket_pair[1]); diff --git a/src/shared/fdset.c b/src/shared/fdset.c index cb5a69ef22..b3d3cfa784 100644 --- a/src/shared/fdset.c +++ b/src/shared/fdset.c @@ -8,6 +8,7 @@ #include "sd-daemon.h" #include "alloc-util.h" +#include "async.h" #include "dirent-util.h" #include "fd-util.h" #include "fdset.h" @@ -51,7 +52,7 @@ int fdset_new_array(FDSet **ret, const int fds[], size_t n_fds) { return 0; } -void fdset_close(FDSet *s) { +void fdset_close(FDSet *s, bool async) { void *p; while ((p = set_steal_first(MAKE_SET(s)))) { @@ -72,12 +73,21 @@ void fdset_close(FDSet *s) { log_debug("Closing set fd %i (%s)", fd, strna(path)); } - (void) close(fd); + if (async) + (void) asynchronous_close(fd); + else + (void) close(fd); } } FDSet* fdset_free(FDSet *s) { - fdset_close(s); + fdset_close(s, /* async= */ false); + set_free(MAKE_SET(s)); + return NULL; +} + +FDSet* fdset_free_async(FDSet *s) { + fdset_close(s, /* async= */ true); set_free(MAKE_SET(s)); return NULL; } diff --git a/src/shared/fdset.h b/src/shared/fdset.h index 70a764fb4d..3e69d32146 100644 --- a/src/shared/fdset.h +++ b/src/shared/fdset.h @@ -11,6 +11,7 @@ typedef struct FDSet FDSet; FDSet* fdset_new(void); FDSet* fdset_free(FDSet *s); +FDSet* fdset_free_async(FDSet *s); int fdset_put(FDSet *s, int fd); int fdset_consume(FDSet *s, int fd); @@ -36,7 +37,7 @@ int fdset_iterate(FDSet *s, Iterator *i); int fdset_steal_first(FDSet *fds); -void fdset_close(FDSet *fds); +void fdset_close(FDSet *fds, bool async); #define _FDSET_FOREACH(fd, fds, i) \ for (Iterator i = ITERATOR_FIRST; ((fd) = fdset_iterate((fds), &i)) >= 0; ) @@ -45,3 +46,5 @@ void fdset_close(FDSet *fds); DEFINE_TRIVIAL_CLEANUP_FUNC(FDSet*, fdset_free); #define _cleanup_fdset_free_ _cleanup_(fdset_freep) + +DEFINE_TRIVIAL_CLEANUP_FUNC(FDSet*, fdset_free_async); -- cgit v1.2.3 From 4b3d7feb1944ad627879c12a23edcced24e2c6f7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 17 Oct 2024 09:46:16 +0200 Subject: pid1: close fds we receive via sd_notify() and cannot make use of asynchronously This addresses #11112 fully. It mostly was addressed by 99620f457ed0886852ba18c9093b59767299121c already, but for fds not even passed to the fdstore, this adds the missing asynchronous close codepath. Fixes: #11112 --- src/core/manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/manager.c b/src/core/manager.c index b9ea79a7ad..8e033c69c4 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -2793,7 +2793,7 @@ static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t } } - _cleanup_fdset_free_ FDSet *fds = NULL; + _cleanup_(fdset_free_asyncp) FDSet *fds = NULL; if (n_fds > 0) { assert(fd_array); -- cgit v1.2.3