core: add FileDescriptorStorePreserve=on-success option (#42160)

Currently with FileDescriptorStorePreserve=yes the FD store is kept
around
regardless of what happens to a unit, which is useful in many cases. But
in
some cases, for example when complex services crash horribly, it's hard
to
reason about what was in the intermediate state, and it's better to
start
fresh.

Add a new 'on-success' option for the FileDescriptorStorePreserve=
setting
that keeps it around only for as long as the unit doesn't go to a
persistently
failed state.

This is especially useful in combination with LUO, where we don't want
to
keep around LUO sessions created by units that then proceeded to crash
and
burn, and might be in a bad state afterwards.
This commit is contained in:
Luca Boccassi
2026-05-21 12:08:33 +01:00
committed by GitHub
10 changed files with 150 additions and 36 deletions
+17 -4
View File
@@ -6,6 +6,7 @@
*
* This binary is intentionally linked against libsystemd only so that it can go in the minimal image. */
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@@ -28,6 +29,10 @@ static void closep(int *fd) {
*fd = -EBADF;
}
static _Noreturn void exit_handler(int sig) {
_exit(EXIT_SUCCESS);
}
static int push_one(const char *fdname, const char *content) {
_cleanup_(closep) int fd = -EBADF;
int r;
@@ -159,8 +164,16 @@ int main(int argc, char *argv[]) {
if (r != EXIT_SUCCESS)
return r;
/* On success, become sleep so if we are a container payload it can stay alive. */
execlp("sleep", "sleep", "infinity", (char *) NULL);
fprintf(stderr, "execlp(sleep) failed: %m\n");
return EXIT_FAILURE;
/* On success, stay alive so if we are a container payload we keep it running. Install handlers
* for the signals an outer supervisor may use to terminate us, so we exit cleanly (with status 0)
* and the container service ends up in 'inactive' rather than 'failed'. */
struct sigaction sa = { .sa_handler = exit_handler };
if (sigaction(SIGTERM, &sa, /* __oact= */ NULL) < 0 ||
sigaction(SIGINT, &sa, /* __oact= */ NULL) < 0) {
fprintf(stderr, "Failed to install signal handlers: %m\n");
return EXIT_FAILURE;
}
for (;;)
pause();
}