From f02deaf8cd4262c2773b98994a78a3b404817457 Mon Sep 17 00:00:00 2001 From: zhangyao Date: Wed, 26 Jun 2024 16:12:00 +0800 Subject: [PATCH] Revert Add the FileDescriptorStorePreserve= option to the service --- ...-implicit-sentinel-to-strv_env_merge.patch | 310 ------------ ...ronize-explicitly-instead-of-by-time.patch | 166 ------ ...e-variables-and-modernize-style-a-bi.patch | 453 ----------------- ...-unit-if-it-is-in-cgroup_empty_queue.patch | 92 ---- ...nits-jobs-that-are-in-the-D-Bus-queu.patch | 84 ---- ...y-getter-method-for-NFileDescriptorS.patch | 72 --- ...e-directory-removal-into-release_res.patch | 90 ---- ...rriding-NOTIFYACCESS-through-sd-noti.patch | 294 ----------- ...util-introduce-dir_fd_is_root_or_cwd.patch | 27 - ...t-fdset-add-new-fdset_consume-helper.patch | 52 -- ...lper-to-convert-an-fdset-to-an-array.patch | 86 ---- ...itattributes-when-using-install_subd.patch | 95 ---- ...xec-switch-for-chaining-other-comman.patch | 150 ------ ...rt-for-sending-fds-with-notification.patch | 258 ---------- ...bug-logging-when-stashing-ds-into-th.patch | 54 -- ...-service-add-ability-to-pin-fd-store.patch | 476 ------------------ ...low-freeing-the-fdstore-via-cleaning.patch | 283 ----------- ...service-close-fdstore-asynchronously.patch | 90 ---- ...e-drop-redundant-unit_ref_unset-call.patch | 31 -- ...resources-from-a-seperate-queue-not-.patch | 286 ----------- ...ervice_close_socket_fd-service_relea.patch | 95 ---- ...vice-rework-how-we-release-resources.patch | 137 ----- ...ss-socket-fd-and-SocketPeer-ownershi.patch | 174 ------- backport-socket-various-modernizations.patch | 94 ---- ...py_n-helper-for-copying-part-of-a-n-.patch | 125 ----- ...v_copy-with-cleanup-attribute-and-ST.patch | 56 --- ...or-NOTIFYACCESS-override-through-sd_.patch | 160 ------ ...-validate-that-fdstore-pinning-works.patch | 186 ------- ...port-unit-don-t-gc-unit-in-oom-queue.patch | 49 -- systemd.spec | 34 +- 30 files changed, 4 insertions(+), 4555 deletions(-) delete mode 100644 backport-Add-implicit-sentinel-to-strv_env_merge.patch delete mode 100644 backport-TEST-80-synchronize-explicitly-instead-of-by-time.patch delete mode 100644 backport-basic-strv-inline-variables-and-modernize-style-a-bi.patch delete mode 100644 backport-core-Don-t-GC-unit-if-it-is-in-cgroup_empty_queue.patch delete mode 100644 backport-core-do-not-GC-units-jobs-that-are-in-the-D-Bus-queu.patch delete mode 100644 backport-core-fix-property-getter-method-for-NFileDescriptorS.patch delete mode 100644 backport-core-move-runtime-directory-removal-into-release_res.patch delete mode 100644 backport-core-support-overriding-NOTIFYACCESS-through-sd-noti.patch delete mode 100644 backport-fd-util-introduce-dir_fd_is_root_or_cwd.patch delete mode 100644 backport-fdset-add-new-fdset_consume-helper.patch delete mode 100644 backport-fdset-add-new-helper-to-convert-an-fdset-to-an-array.patch delete mode 100644 backport-meson-exclude-.gitattributes-when-using-install_subd.patch delete mode 100644 backport-notify-add-new-exec-switch-for-chaining-other-comman.patch delete mode 100644 backport-notify-add-support-for-sending-fds-with-notification.patch delete mode 100644 backport-pid1-add-some-debug-logging-when-stashing-ds-into-th.patch delete mode 100644 backport-service-add-ability-to-pin-fd-store.patch delete mode 100644 backport-service-allow-freeing-the-fdstore-via-cleaning.patch delete mode 100644 backport-service-close-fdstore-asynchronously.patch delete mode 100644 backport-service-drop-redundant-unit_ref_unset-call.patch delete mode 100644 backport-service-release-resources-from-a-seperate-queue-not-.patch delete mode 100644 backport-service-rename-service_close_socket_fd-service_relea.patch delete mode 100644 backport-service-rework-how-we-release-resources.patch delete mode 100644 backport-socket-always-pass-socket-fd-and-SocketPeer-ownershi.patch delete mode 100644 backport-socket-various-modernizations.patch delete mode 100644 backport-strv-add-strv_copy_n-helper-for-copying-part-of-a-n-.patch delete mode 100644 backport-strv-rewrite-strv_copy-with-cleanup-attribute-and-ST.patch delete mode 100644 backport-test-add-tests-for-NOTIFYACCESS-override-through-sd_.patch delete mode 100644 backport-test-validate-that-fdstore-pinning-works.patch delete mode 100644 backport-unit-don-t-gc-unit-in-oom-queue.patch diff --git a/backport-Add-implicit-sentinel-to-strv_env_merge.patch b/backport-Add-implicit-sentinel-to-strv_env_merge.patch deleted file mode 100644 index 444fc63..0000000 --- a/backport-Add-implicit-sentinel-to-strv_env_merge.patch +++ /dev/null @@ -1,310 +0,0 @@ -From 4ab3d29ff03c0508f47846875d9310cbc5b8cd0f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= -Date: Sat, 7 Aug 2021 10:16:19 +0200 -Subject: [PATCH] Add implicit sentinel to strv_env_merge() - -Just to make it a tiny bit nicer to use. - ---- - src/basic/env-util.c | 40 ++++++++++++++++++++++++++-------------- - src/basic/env-util.h | 3 ++- - src/core/dbus-execute.c | 4 ++-- - src/core/execute.c | 5 ++--- - src/core/locale-setup.c | 2 +- - src/core/manager.c | 6 +++--- - src/core/service.c | 2 +- - src/notify/notify.c | 2 +- - src/nspawn/nspawn.c | 20 ++++++++++---------- - src/run/run.c | 2 +- - src/test/test-env-util.c | 2 +- - 11 files changed, 50 insertions(+), 38 deletions(-) - -diff --git a/src/basic/env-util.c b/src/basic/env-util.c -index 81b1e3f10e..0c30ddc277 100644 ---- a/src/basic/env-util.c -+++ b/src/basic/env-util.c -@@ -183,39 +183,51 @@ static int env_append(char **r, char ***k, char **a) { - return 0; - } - --char **strv_env_merge(size_t n_lists, ...) { -- _cleanup_strv_free_ char **ret = NULL; -- size_t n = 0; -- char **l, **k; -+char** _strv_env_merge(char **first, ...) { -+ _cleanup_strv_free_ char **merged = NULL; -+ char **k; - va_list ap; - - /* Merges an arbitrary number of environment sets */ - -- va_start(ap, n_lists); -- for (size_t i = 0; i < n_lists; i++) { -+ size_t n = strv_length(first); -+ -+ va_start(ap, first); -+ for (;;) { -+ char **l; -+ - l = va_arg(ap, char**); -+ if (l == POINTER_MAX) -+ break; -+ - n += strv_length(l); - } - va_end(ap); - -- ret = new(char*, n+1); -- if (!ret) -+ k = merged = new(char*, n + 1); -+ if (!merged) - return NULL; -+ merged[0] = NULL; - -- *ret = NULL; -- k = ret; -+ if (env_append(merged, &k, first) < 0) -+ return NULL; -+ -+ va_start(ap, first); -+ for (;;) { -+ char **l; - -- va_start(ap, n_lists); -- for (size_t i = 0; i < n_lists; i++) { - l = va_arg(ap, char**); -- if (env_append(ret, &k, l) < 0) { -+ if (l == POINTER_MAX) -+ break; -+ -+ if (env_append(merged, &k, l) < 0) { - va_end(ap); - return NULL; - } - } - va_end(ap); - -- return TAKE_PTR(ret); -+ return TAKE_PTR(merged); - } - - static bool env_match(const char *t, const char *pattern) { -diff --git a/src/basic/env-util.h b/src/basic/env-util.h -index 1fbe7e4270..18d10ebab8 100644 ---- a/src/basic/env-util.h -+++ b/src/basic/env-util.h -@@ -39,7 +39,8 @@ char **strv_env_clean_with_callback(char **l, void (*invalid_callback)(const cha - bool strv_env_name_is_valid(char **l); - bool strv_env_name_or_assignment_is_valid(char **l); - --char **strv_env_merge(size_t n_lists, ...); -+char** _strv_env_merge(char **first, ...); -+#define strv_env_merge(first, ...) _strv_env_merge(first, __VA_ARGS__, POINTER_MAX) - char **strv_env_delete(char **x, size_t n_lists, ...); /* New copy */ - - char **strv_env_unset(char **l, const char *p); /* In place ... */ -diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c -index f6783e924a..5ea97b9194 100644 ---- a/src/core/dbus-execute.c -+++ b/src/core/dbus-execute.c -@@ -2888,7 +2888,7 @@ int bus_exec_context_set_transient_property( - if (!joined) - return -ENOMEM; - -- e = strv_env_merge(2, c->environment, l); -+ e = strv_env_merge(c->environment, l); - if (!e) - return -ENOMEM; - -@@ -2922,7 +2922,7 @@ int bus_exec_context_set_transient_property( - if (!joined) - return -ENOMEM; - -- e = strv_env_merge(2, c->unset_environment, l); -+ e = strv_env_merge(c->unset_environment, l); - if (!e) - return -ENOMEM; - -diff --git a/src/core/execute.c b/src/core/execute.c -index 4608956259..5bee44ac7b 100644 ---- a/src/core/execute.c -+++ b/src/core/execute.c -@@ -4158,8 +4158,7 @@ static int exec_child( - return log_oom(); - } - -- accum_env = strv_env_merge(5, -- params->environment, -+ accum_env = strv_env_merge(params->environment, - our_env, - pass_env, - context->environment, -@@ -5214,7 +5213,7 @@ static int exec_context_load_environment(const Unit *unit, const ExecContext *c, - else { - char **m; - -- m = strv_env_merge(2, r, p); -+ m = strv_env_merge(r, p); - strv_free(r); - strv_free(p); - if (!m) -diff --git a/src/core/locale-setup.c b/src/core/locale-setup.c -index 64761ddb11..59ddb9c487 100644 ---- a/src/core/locale-setup.c -+++ b/src/core/locale-setup.c -@@ -85,7 +85,7 @@ int locale_setup(char ***environment) { - else { - char **merged; - -- merged = strv_env_merge(2, *environment, add); -+ merged = strv_env_merge(*environment, add); - if (!merged) - return -ENOMEM; - -diff --git a/src/core/manager.c b/src/core/manager.c -index 24dfe9fc06..d76b7b2b16 100644 ---- a/src/core/manager.c -+++ b/src/core/manager.c -@@ -3672,7 +3672,7 @@ int manager_transient_environment_add(Manager *m, char **plus) { - if (strv_isempty(plus)) - return 0; - -- a = strv_env_merge(2, m->transient_environment, plus); -+ a = strv_env_merge(m->transient_environment, plus); - if (!a) - return log_oom(); - -@@ -3704,7 +3704,7 @@ int manager_client_environment_modify( - } - - if (!strv_isempty(plus)) { -- b = strv_env_merge(2, l, plus); -+ b = strv_env_merge(l, plus); - if (!b) { - strv_free(a); - return -ENOMEM; -@@ -3731,7 +3731,7 @@ int manager_get_effective_environment(Manager *m, char ***ret) { - assert(m); - assert(ret); - -- l = strv_env_merge(2, m->transient_environment, m->client_environment); -+ l = strv_env_merge(m->transient_environment, m->client_environment); - if (!l) - return -ENOMEM; - -diff --git a/src/core/service.c b/src/core/service.c -index ddcfeb8523..4115db0a30 100644 ---- a/src/core/service.c -+++ b/src/core/service.c -@@ -1546,7 +1546,7 @@ static int service_spawn( - if (r < 0) - return r; - -- final_env = strv_env_merge(2, exec_params.environment, our_env, NULL); -+ final_env = strv_env_merge(exec_params.environment, our_env); - if (!final_env) - return -ENOMEM; - -diff --git a/src/notify/notify.c b/src/notify/notify.c -index 49d5f3ec92..b468a5bc44 100644 ---- a/src/notify/notify.c -+++ b/src/notify/notify.c -@@ -232,7 +232,7 @@ static int run(int argc, char* argv[]) { - - our_env[i++] = NULL; - -- final_env = strv_env_merge(2, our_env, argv + optind); -+ final_env = strv_env_merge(our_env, argv + optind); - if (!final_env) - return log_oom(); - -diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c -index d75cce408e..cf89b27dfa 100644 ---- a/src/nspawn/nspawn.c -+++ b/src/nspawn/nspawn.c -@@ -3189,8 +3189,8 @@ static int inner_child( - _cleanup_free_ char *home = NULL; - char as_uuid[ID128_UUID_STRING_MAX]; - size_t n_env = 1; -- const char *envp[] = { -- "PATH=" DEFAULT_PATH_COMPAT, -+ char *envp[] = { -+ (char*) "PATH=" DEFAULT_PATH_COMPAT, - NULL, /* container */ - NULL, /* TERM */ - NULL, /* HOME */ -@@ -3426,17 +3426,17 @@ static int inner_child( - n_env++; - - if (home || !uid_is_valid(arg_uid) || arg_uid == 0) -- if (asprintf((char**)(envp + n_env++), "HOME=%s", home ?: "/root") < 0) -+ if (asprintf(envp + n_env++, "HOME=%s", home ?: "/root") < 0) - return log_oom(); - - if (arg_user || !uid_is_valid(arg_uid) || arg_uid == 0) -- if (asprintf((char**)(envp + n_env++), "USER=%s", arg_user ?: "root") < 0 || -- asprintf((char**)(envp + n_env++), "LOGNAME=%s", arg_user ? arg_user : "root") < 0) -+ if (asprintf(envp + n_env++, "USER=%s", arg_user ?: "root") < 0 || -+ asprintf(envp + n_env++, "LOGNAME=%s", arg_user ? arg_user : "root") < 0) - return log_oom(); - - assert(!sd_id128_is_null(arg_uuid)); - -- if (asprintf((char**)(envp + n_env++), "container_uuid=%s", id128_to_uuid_string(arg_uuid, as_uuid)) < 0) -+ if (asprintf(envp + n_env++, "container_uuid=%s", id128_to_uuid_string(arg_uuid, as_uuid)) < 0) - return log_oom(); - - if (fdset_size(fds) > 0) { -@@ -3444,11 +3444,11 @@ static int inner_child( - if (r < 0) - return log_error_errno(r, "Failed to unset O_CLOEXEC for file descriptors."); - -- if ((asprintf((char **)(envp + n_env++), "LISTEN_FDS=%u", fdset_size(fds)) < 0) || -- (asprintf((char **)(envp + n_env++), "LISTEN_PID=1") < 0)) -+ if ((asprintf(envp + n_env++, "LISTEN_FDS=%u", fdset_size(fds)) < 0) || -+ (asprintf(envp + n_env++, "LISTEN_PID=1") < 0)) - return log_oom(); - } -- if (asprintf((char **)(envp + n_env++), "NOTIFY_SOCKET=%s", NSPAWN_NOTIFY_SOCKET_PATH) < 0) -+ if (asprintf(envp + n_env++, "NOTIFY_SOCKET=%s", NSPAWN_NOTIFY_SOCKET_PATH) < 0) - return log_oom(); - - if (arg_n_credentials > 0) { -@@ -3458,7 +3458,7 @@ static int inner_child( - n_env++; - } - -- env_use = strv_env_merge(3, envp, os_release_pairs, arg_setenv); -+ env_use = strv_env_merge(envp, os_release_pairs, arg_setenv); - if (!env_use) - return log_oom(); - -diff --git a/src/run/run.c b/src/run/run.c -index 0be974f03a..993f1bc4f4 100644 ---- a/src/run/run.c -+++ b/src/run/run.c -@@ -1526,7 +1526,7 @@ static int start_transient_scope(sd_bus *bus) { - return log_error_errno(errno, "Failed to change UID to " UID_FMT ": %m", uid); - } - -- env = strv_env_merge(3, environ, user_env, arg_environment); -+ env = strv_env_merge(environ, user_env, arg_environment); - if (!env) - return log_oom(); - -diff --git a/src/test/test-env-util.c b/src/test/test-env-util.c -index ed4580e4af..5bf130ed86 100644 ---- a/src/test/test-env-util.c -+++ b/src/test/test-env-util.c -@@ -81,7 +81,7 @@ static void test_strv_env_merge(void) { - b = strv_new("FOO=KKK", "FOO=", "PIEP=", "SCHLUMPF=SMURFF", "NANANANA=YES"); - assert_se(b); - -- r = strv_env_merge(2, a, b); -+ r = strv_env_merge(a, b); - assert_se(r); - assert_se(streq(r[0], "FOO=")); - assert_se(streq(r[1], "WALDO=")); --- -2.33.0 - diff --git a/backport-TEST-80-synchronize-explicitly-instead-of-by-time.patch b/backport-TEST-80-synchronize-explicitly-instead-of-by-time.patch deleted file mode 100644 index d53e2cc..0000000 --- a/backport-TEST-80-synchronize-explicitly-instead-of-by-time.patch +++ /dev/null @@ -1,166 +0,0 @@ -From 09ba6d1a14ba027f2bc4e3426c7dd85db19e720e Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Tue, 28 Mar 2023 16:35:35 +0200 -Subject: [PATCH] TEST-80: synchronize explicitly instead of by time - -This removes "sleep" invocations, and makes the notify access testcase a -lot more robust to runtime jitter. We use a pair of fifos in the fs to -sync instead. - -Also various other improvoements, including comments. - -(Also removes the unnecessary "no-qemu" restriction) - -Conflict:NA -Reference:https://github.com/systemd/systemd/commit/09ba6d1a14ba027f2bc4e3426c7dd85db19e720e - ---- - test/TEST-80-NOTIFYACCESS/test.sh | 1 - - test/testsuite-80.units/test.sh | 59 +++++++++++++++++++++++++------ - test/units/testsuite-80.sh | 30 +++++++++++++--- - 3 files changed, 73 insertions(+), 17 deletions(-) - -diff --git a/test/TEST-80-NOTIFYACCESS/test.sh b/test/TEST-80-NOTIFYACCESS/test.sh -index b4d2452b75..8ec5b1bc5f 100755 ---- a/test/TEST-80-NOTIFYACCESS/test.sh -+++ b/test/TEST-80-NOTIFYACCESS/test.sh -@@ -3,7 +3,6 @@ - set -e - - TEST_DESCRIPTION="test NotifyAccess through sd-notify" --TEST_NO_QEMU=1 - - # shellcheck source=test/test-functions - . "${TEST_BASE_DIR:?}/test-functions" -diff --git a/test/testsuite-80.units/test.sh b/test/testsuite-80.units/test.sh -index 3ca71d5648..565ed8d35a 100755 ---- a/test/testsuite-80.units/test.sh -+++ b/test/testsuite-80.units/test.sh -@@ -4,23 +4,60 @@ - set -eux - set -o pipefail - --systemd-notify --status="Test starts, waiting for 5 seconds" --sleep 5 -+sync_in() { -+ read -r x < /tmp/syncfifo2 -+ test "$x" = "$1" -+} - -+sync_out() { -+ echo "$1" > /tmp/syncfifo1 -+} -+ -+export SYSTEMD_LOG_LEVEL=debug -+ -+echo "toplevel PID: $BASHPID" -+ -+systemd-notify --status="Test starts" -+sync_out a -+sync_in b - ( -- systemd-notify --pid=auto -+ echo "subshell PID: $BASHPID" -+ -+ # Make us main process -+ systemd-notify --pid="$BASHPID" -+ -+ # Lock down access to just us - systemd-notify "NOTIFYACCESS=main" - -- systemd-notify --status="Sending READY=1 in an unpriviledged process" -- ( -- sleep 0.1 -- systemd-notify --ready -- ) -- sleep 10 -+ # This should still work -+ systemd-notify --status="Sending READY=1 in an unprivileged process" -+ -+ # Send as subprocess of the subshell, this should not work -+ systemd-notify --ready --pid=self --status "BOGUS1" - -- systemd-notify "MAINPID=$$" -+ sync_out c -+ sync_in d -+ -+ # Move main process back to toplevel -+ systemd-notify --pid=parent "MAINPID=$$" -+ -+ # Should be dropped again -+ systemd-notify --status="BOGUS2" --pid=parent -+ -+ # Apparently, bash will automatically invoke the last command in a subshell -+ # via a simple execve() rather than fork()ing first. But we want that the -+ # previous command uses the subshell's PID, hence let's insert a final, -+ # bogus redundant command as last command to run in the subshell, so that -+ # bash can't optimize things like that. -+ echo "bye" - ) - -+echo "toplevel again: $BASHPID" -+ - systemd-notify --ready --status="OK" - systemd-notify "NOTIFYACCESS=none" --sleep infinity -+systemd-notify --status="BOGUS3" -+ -+sync_out e -+ -+exec sleep infinity -diff --git a/test/units/testsuite-80.sh b/test/units/testsuite-80.sh -index 5f57569b07..43647a707f 100755 ---- a/test/units/testsuite-80.sh -+++ b/test/units/testsuite-80.sh -@@ -9,17 +9,35 @@ set -o pipefail - - : >/failed - -+mkfifo /tmp/syncfifo1 /tmp/syncfifo2 -+ -+sync_in() { -+ read -r x < /tmp/syncfifo1 -+ test "$x" = "$1" -+} -+ -+sync_out() { -+ echo "$1" > /tmp/syncfifo2 -+} -+ -+export SYSTEMD_LOG_LEVEL=debug -+ - systemctl --no-block start notify.service --sleep 2 - --assert_eq "$(systemctl show notify.service -p StatusText --value)" "Test starts, waiting for 5 seconds" -+sync_in a -+ - assert_eq "$(systemctl show notify.service -p NotifyAccess --value)" "all" --sleep 5 -+assert_eq "$(systemctl show notify.service -p StatusText --value)" "Test starts" -+ -+sync_out b -+sync_in c - - assert_eq "$(systemctl show notify.service -p NotifyAccess --value)" "main" --assert_eq "$(systemctl show notify.service -p StatusText --value)" "Sending READY=1 in an unpriviledged process" -+assert_eq "$(systemctl show notify.service -p StatusText --value)" "Sending READY=1 in an unprivileged process" - assert_rc 3 systemctl --quiet is-active notify.service --sleep 10 -+ -+sync_out d -+sync_in e - - systemctl --quiet is-active notify.service - assert_eq "$(systemctl show notify.service -p StatusText --value)" "OK" -@@ -28,5 +46,7 @@ assert_eq "$(systemctl show notify.service -p NotifyAccess --value)" "none" - systemctl stop notify.service - assert_eq "$(systemctl show notify.service -p NotifyAccess --value)" "all" - -+rm /tmp/syncfifo1 /tmp/syncfifo2 -+ - touch /testok - rm /failed --- -2.33.0 - diff --git a/backport-basic-strv-inline-variables-and-modernize-style-a-bi.patch b/backport-basic-strv-inline-variables-and-modernize-style-a-bi.patch deleted file mode 100644 index 3ed2c9b..0000000 --- a/backport-basic-strv-inline-variables-and-modernize-style-a-bi.patch +++ /dev/null @@ -1,453 +0,0 @@ -From 14337c374a641badf55cf9ce6ec1fb387886b651 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= -Date: Fri, 26 Nov 2021 09:47:44 +0100 -Subject: [PATCH] basic/strv: inline variables and modernize style a bit - -Conflict:Context Adaptation. -Reference:https://github.com/systemd/systemd/commit/14337c374a641badf55cf9ce6ec1fb387886b651 - ---- - src/basic/strv.c | 82 +++++++++++++++++++++--------------------------- - src/basic/strv.h | 42 ++++++++++++------------- - 2 files changed, 56 insertions(+), 68 deletions(-) - -diff --git a/src/basic/strv.c b/src/basic/strv.c -index 3adf3c5..e10af33 100644 ---- a/src/basic/strv.c -+++ b/src/basic/strv.c -@@ -16,7 +16,7 @@ - #include "string-util.h" - #include "strv.h" - --char *strv_find(char * const *l, const char *name) { -+char* strv_find(char * const *l, const char *name) { - char * const *i; - - assert(name); -@@ -28,7 +28,7 @@ char *strv_find(char * const *l, const char *name) { - return NULL; - } - --char *strv_find_case(char * const *l, const char *name) { -+char* strv_find_case(char * const *l, const char *name) { - char * const *i; - - assert(name); -@@ -40,7 +40,7 @@ char *strv_find_case(char * const *l, const char *name) { - return NULL; - } - --char *strv_find_prefix(char * const *l, const char *name) { -+char* strv_find_prefix(char * const *l, const char *name) { - char * const *i; - - assert(name); -@@ -52,7 +52,7 @@ char *strv_find_prefix(char * const *l, const char *name) { - return NULL; - } - --char *strv_find_startswith(char * const *l, const char *name) { -+char* strv_find_startswith(char * const *l, const char *name) { - char * const *i, *e; - - assert(name); -@@ -69,19 +69,17 @@ char *strv_find_startswith(char * const *l, const char *name) { - return NULL; - } - --char **strv_free(char **l) { -- char **k; -- -+char** strv_free(char **l) { - if (!l) - return NULL; - -- for (k = l; *k; k++) -+ for (char **k = l; *k; k++) - free(*k); - - return mfree(l); - } - --char **strv_free_erase(char **l) { -+char** strv_free_erase(char **l) { - char **i; - - STRV_FOREACH(i, l) -@@ -90,7 +88,7 @@ char **strv_free_erase(char **l) { - return mfree(l); - } - --char **strv_copy(char * const *l) { -+char** strv_copy(char * const *l) { - char **r, **k; - - k = r = new(char*, strv_length(l) + 1); -@@ -122,7 +120,7 @@ size_t strv_length(char * const *l) { - return n; - } - --char **strv_new_ap(const char *x, va_list ap) { -+char** strv_new_ap(const char *x, va_list ap) { - _cleanup_strv_free_ char **a = NULL; - size_t n = 0, i = 0; - va_list aq; -@@ -161,7 +159,7 @@ char **strv_new_ap(const char *x, va_list ap) { - return TAKE_PTR(a); - } - --char **strv_new_internal(const char *x, ...) { -+char** strv_new_internal(const char *x, ...) { - char **r; - va_list ap; - -@@ -174,7 +172,7 @@ char **strv_new_internal(const char *x, ...) { - - int strv_extend_strv(char ***a, char * const *b, bool filter_duplicates) { - char * const *s, **t; -- size_t p, q, i = 0, j; -+ size_t p, q, i = 0; - - assert(a); - -@@ -195,7 +193,6 @@ int strv_extend_strv(char ***a, char * const *b, bool filter_duplicates) { - *a = t; - - STRV_FOREACH(s, b) { -- - if (filter_duplicates && strv_contains(t, *s)) - continue; - -@@ -212,7 +209,7 @@ int strv_extend_strv(char ***a, char * const *b, bool filter_duplicates) { - return (int) i; - - rollback: -- for (j = 0; j < i; j++) -+ for (size_t j = 0; j < i; j++) - free(t[p + j]); - - t[p] = NULL; -@@ -285,7 +282,6 @@ int strv_split_full(char ***t, const char *s, const char *separators, ExtractFla - return -ENOMEM; - - l[n++] = TAKE_PTR(word); -- - l[n] = NULL; - } - -@@ -352,7 +348,7 @@ int strv_split_colon_pairs(char ***t, const char *s) { - return (int) n; - } - --char *strv_join_full(char * const *l, const char *separator, const char *prefix, bool unescape_separators) { -+char* strv_join_full(char * const *l, const char *separator, const char *prefix, bool unescape_separators) { - char * const *s; - char *r, *e; - size_t n, k, m; -@@ -459,7 +455,7 @@ int strv_push_pair(char ***l, char *a, char *b) { - - int strv_insert(char ***l, size_t position, char *value) { - char **c; -- size_t n, m, i; -+ size_t n, m; - - if (!value) - return 0; -@@ -476,18 +472,14 @@ int strv_insert(char ***l, size_t position, char *value) { - if (!c) - return -ENOMEM; - -- for (i = 0; i < position; i++) -+ for (size_t i = 0; i < position; i++) - c[i] = (*l)[i]; - c[position] = value; -- for (i = position; i < n; i++) -+ for (size_t i = position; i < n; i++) - c[i+1] = (*l)[i]; -- - c[n+1] = NULL; - -- free(*l); -- *l = c; -- -- return 0; -+ return free_and_replace(*l, c); - } - - int strv_consume(char ***l, char *value) { -@@ -584,7 +576,7 @@ int strv_extend_front(char ***l, const char *value) { - return 0; - } - --char **strv_uniq(char **l) { -+char** strv_uniq(char **l) { - char **i; - - /* Drops duplicate entries. The first identical string will be -@@ -606,7 +598,7 @@ bool strv_is_uniq(char * const *l) { - return true; - } - --char **strv_remove(char **l, const char *s) { -+char** strv_remove(char **l, const char *s) { - char **f, **t; - - if (!l) -@@ -627,7 +619,7 @@ char **strv_remove(char **l, const char *s) { - return l; - } - --char **strv_parse_nulstr(const char *s, size_t l) { -+char** strv_parse_nulstr(const char *s, size_t l) { - /* l is the length of the input data, which will be split at NULs into - * elements of the resulting strv. Hence, the number of items in the resulting strv - * will be equal to one plus the number of NUL bytes in the l bytes starting at s, -@@ -639,7 +631,6 @@ char **strv_parse_nulstr(const char *s, size_t l) { - * empty strings in s. - */ - -- const char *p; - size_t c = 0, i = 0; - char **v; - -@@ -648,7 +639,7 @@ char **strv_parse_nulstr(const char *s, size_t l) { - if (l <= 0) - return new0(char*, 1); - -- for (p = s; p < s + l; p++) -+ for (const char *p = s; p < s + l; p++) - if (*p == 0) - c++; - -@@ -659,8 +650,7 @@ char **strv_parse_nulstr(const char *s, size_t l) { - if (!v) - return NULL; - -- p = s; -- while (p < s + l) { -+ for (const char *p = s; p < s + l; ) { - const char *e; - - e = memchr(p, 0, s + l - p); -@@ -684,7 +674,7 @@ char **strv_parse_nulstr(const char *s, size_t l) { - return v; - } - --char **strv_split_nulstr(const char *s) { -+char** strv_split_nulstr(const char *s) { - const char *i; - char **r = NULL; - -@@ -759,7 +749,7 @@ static int str_compare(char * const *a, char * const *b) { - return strcmp(*a, *b); - } - --char **strv_sort(char **l) { -+char** strv_sort(char **l) { - typesafe_qsort(l, strv_length(l), str_compare); - return l; - } -@@ -808,20 +798,20 @@ int strv_extendf(char ***l, const char *format, ...) { - return strv_consume(l, x); - } - --char **strv_reverse(char **l) { -- size_t n, i; -+char** strv_reverse(char **l) { -+ size_t n; - - n = strv_length(l); - if (n <= 1) - return l; - -- for (i = 0; i < n / 2; i++) -+ for (size_t i = 0; i < n / 2; i++) - SWAP_TWO(l[i], l[n-1-i]); - - return l; - } - --char **strv_shell_escape(char **l, const char *bad) { -+char** strv_shell_escape(char **l, const char *bad) { - char **s; - - /* Escapes every character in every string in l that is in bad, -@@ -852,19 +842,17 @@ bool strv_fnmatch_full(char* const* patterns, const char *s, int flags, size_t * - return false; - } - --char ***strv_free_free(char ***l) { -- char ***i; -- -+char*** strv_free_free(char ***l) { - if (!l) - return NULL; - -- for (i = l; *i; i++) -+ for (char ***i = l; *i; i++) - strv_free(*i); - - return mfree(l); - } - --char **strv_skip(char **l, size_t n) { -+char** strv_skip(char **l, size_t n) { - - while (n > 0) { - if (strv_isempty(l)) -@@ -877,7 +865,7 @@ char **strv_skip(char **l, size_t n) { - } - - int strv_extend_n(char ***l, const char *value, size_t n) { -- size_t i, j, k; -+ size_t i, k; - char **nl; - - assert(l); -@@ -904,15 +892,15 @@ int strv_extend_n(char ***l, const char *value, size_t n) { - if (!nl[i]) - goto rollback; - } -- - nl[i] = NULL; -+ - return 0; - - rollback: -- for (j = k; j < i; j++) -+ for (size_t j = k; j < i; j++) - free(nl[j]); -- - nl[k] = NULL; -+ - return -ENOMEM; - } - -diff --git a/src/basic/strv.h b/src/basic/strv.h -index 911528f..8674bfd 100644 ---- a/src/basic/strv.h -+++ b/src/basic/strv.h -@@ -13,23 +13,23 @@ - #include "macro.h" - #include "string-util.h" - --char *strv_find(char * const *l, const char *name) _pure_; --char *strv_find_case(char * const *l, const char *name) _pure_; --char *strv_find_prefix(char * const *l, const char *name) _pure_; --char *strv_find_startswith(char * const *l, const char *name) _pure_; -+char* strv_find(char * const *l, const char *name) _pure_; -+char* strv_find_case(char * const *l, const char *name) _pure_; -+char* strv_find_prefix(char * const *l, const char *name) _pure_; -+char* strv_find_startswith(char * const *l, const char *name) _pure_; - - #define strv_contains(l, s) (!!strv_find((l), (s))) - #define strv_contains_case(l, s) (!!strv_find_case((l), (s))) - --char **strv_free(char **l); -+char** strv_free(char **l); - DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free); - #define _cleanup_strv_free_ _cleanup_(strv_freep) - --char **strv_free_erase(char **l); -+char** strv_free_erase(char **l); - DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free_erase); - #define _cleanup_strv_free_erase_ _cleanup_(strv_free_erasep) - --char **strv_copy(char * const *l); -+char** strv_copy(char * const *l); - size_t strv_length(char * const *l) _pure_; - - int strv_extend_strv(char ***a, char * const *b, bool filter_duplicates); -@@ -50,8 +50,8 @@ int strv_consume(char ***l, char *value); - int strv_consume_pair(char ***l, char *a, char *b); - int strv_consume_prepend(char ***l, char *value); - --char **strv_remove(char **l, const char *s); --char **strv_uniq(char **l); -+char** strv_remove(char **l, const char *s); -+char** strv_uniq(char **l); - bool strv_is_uniq(char * const *l); - - int strv_compare(char * const *a, char * const *b); -@@ -59,8 +59,8 @@ static inline bool strv_equal(char * const *a, char * const *b) { - return strv_compare(a, b) == 0; - } - --char **strv_new_internal(const char *x, ...) _sentinel_; --char **strv_new_ap(const char *x, va_list ap); -+char** strv_new_internal(const char *x, ...) _sentinel_; -+char** strv_new_ap(const char *x, va_list ap); - #define strv_new(...) strv_new_internal(__VA_ARGS__, NULL) - - #define STRV_IGNORE ((const char *) POINTER_MAX) -@@ -74,7 +74,7 @@ static inline bool strv_isempty(char * const *l) { - } - - int strv_split_full(char ***t, const char *s, const char *separators, ExtractFlags flags); --static inline char **strv_split(const char *s, const char *separators) { -+static inline char** strv_split(const char *s, const char *separators) { - char **ret; - - if (strv_split_full(&ret, s, separators, 0) < 0) -@@ -84,7 +84,7 @@ static inline char **strv_split(const char *s, const char *separators) { - } - - int strv_split_newlines_full(char ***ret, const char *s, ExtractFlags flags); --static inline char **strv_split_newlines(const char *s) { -+static inline char** strv_split_newlines(const char *s) { - char **ret; - - if (strv_split_newlines_full(&ret, s, 0) < 0) -@@ -98,13 +98,13 @@ static inline char **strv_split_newlines(const char *s) { - * string in the vector is an empty string. */ - int strv_split_colon_pairs(char ***t, const char *s); - --char *strv_join_full(char * const *l, const char *separator, const char *prefix, bool escape_separtor); -+char* strv_join_full(char * const *l, const char *separator, const char *prefix, bool escape_separtor); - static inline char *strv_join(char * const *l, const char *separator) { - return strv_join_full(l, separator, NULL, false); - } - --char **strv_parse_nulstr(const char *s, size_t l); --char **strv_split_nulstr(const char *s); -+char** strv_parse_nulstr(const char *s, size_t l); -+char** strv_split_nulstr(const char *s); - int strv_make_nulstr(char * const *l, char **p, size_t *n); - - static inline int strv_from_nulstr(char ***a, const char *nulstr) { -@@ -133,7 +133,7 @@ bool strv_overlap(char * const *a, char * const *b) _pure_; - #define STRV_FOREACH_PAIR(x, y, l) \ - for ((x) = (l), (y) = (x) ? (x+1) : NULL; (x) && *(x) && *(y); (x) += 2, (y) = (x + 1)) - --char **strv_sort(char **l); -+char** strv_sort(char **l); - void strv_print(char * const *l); - - #define strv_from_stdarg_alloca(first) \ -@@ -208,8 +208,8 @@ void strv_print(char * const *l); - x; \ - x = *(++_l)) - --char **strv_reverse(char **l); --char **strv_shell_escape(char **l, const char *bad); -+char** strv_reverse(char **l); -+char** strv_shell_escape(char **l, const char *bad); - - bool strv_fnmatch_full(char* const* patterns, const char *s, int flags, size_t *matched_pos); - static inline bool strv_fnmatch(char* const* patterns, const char *s) { -@@ -222,10 +222,10 @@ static inline bool strv_fnmatch_or_empty(char* const* patterns, const char *s, i - strv_fnmatch_full(patterns, s, flags, NULL); - } - --char ***strv_free_free(char ***l); -+char*** strv_free_free(char ***l); - DEFINE_TRIVIAL_CLEANUP_FUNC(char***, strv_free_free); - --char **strv_skip(char **l, size_t n); -+char** strv_skip(char **l, size_t n); - - int strv_extend_n(char ***l, const char *value, size_t n); - --- -2.33.0 - diff --git a/backport-core-Don-t-GC-unit-if-it-is-in-cgroup_empty_queue.patch b/backport-core-Don-t-GC-unit-if-it-is-in-cgroup_empty_queue.patch deleted file mode 100644 index 659f88f..0000000 --- a/backport-core-Don-t-GC-unit-if-it-is-in-cgroup_empty_queue.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 8db998981a4fefd0122bcf5f965726b63c9045c2 Mon Sep 17 00:00:00 2001 -From: Richard Phibel -Date: Tue, 23 May 2023 16:09:40 +0200 -Subject: [PATCH] core: Don't GC unit if it is in cgroup_empty_queue - -The gc_unit_queue is dispatched before the cgroup_empty_queue. Because -of this, when we enter in on_cgroup_empty_event, the unit in -cgroup_empty_queue may already have been freed and we don't clean up the -corresponding cgroup. With this change, we prevent the unit from being -garbage collected if it is in the cgroup_empty_queue. - -Conflict:NA -Reference:https://github.com/systemd/systemd/commit/8db998981a4fefd0122bcf5f965726b63c9045c2 - ---- - src/core/unit.c | 3 ++ - test/units/testsuite-19.cleanup-slice.sh | 49 ++++++++++++++++++++++++ - 2 files changed, 52 insertions(+) - create mode 100755 test/units/testsuite-19.cleanup-slice.sh - -diff --git a/src/core/unit.c b/src/core/unit.c -index 90f87a95f5..84e9185e82 100644 ---- a/src/core/unit.c -+++ b/src/core/unit.c -@@ -441,6 +441,9 @@ bool unit_may_gc(Unit *u) { - if (u->perpetual) - return false; - -+ if (u->in_cgroup_empty_queue) -+ return false; -+ - if (sd_bus_track_count(u->bus_track) > 0) - return false; - -diff --git a/test/units/testsuite-19.cleanup-slice.sh b/test/units/testsuite-19.cleanup-slice.sh -new file mode 100755 -index 0000000000..5d63160334 ---- /dev/null -+++ b/test/units/testsuite-19.cleanup-slice.sh -@@ -0,0 +1,49 @@ -+#!/usr/bin/env bash -+# SPDX-License-Identifier: LGPL-2.1-or-later -+set -eux -+set -o pipefail -+ -+# shellcheck source=test/units/util.sh -+. "$(dirname "$0")"/util.sh -+ -+export SYSTEMD_LOG_LEVEL=debug -+ -+# Create service with KillMode=none inside a slice -+cat </run/systemd/system/test19cleanup.service -+[Unit] -+Description=Test 19 cleanup Service -+[Service] -+Slice=test19cleanup.slice -+Type=exec -+ExecStart=sleep infinity -+KillMode=none -+EOF -+cat </run/systemd/system/test19cleanup.slice -+[Unit] -+Description=Test 19 cleanup Slice -+EOF -+ -+# Start service -+systemctl start test19cleanup.service -+assert_rc 0 systemd-cgls /test19cleanup.slice -+ -+pid=$(systemctl show --property MainPID --value test19cleanup) -+ps "$pid" -+ -+# Stop slice -+# The sleep process will not be killed because of KillMode=none -+# Since there is still a process running under it, the /test19cleanup.slice cgroup won't be removed -+systemctl stop test19cleanup.slice -+ -+ps "$pid" -+ -+# Kill sleep process manually -+kill -s TERM "$pid" -+while kill -0 "$pid" 2>/dev/null; do sleep 0.1; done -+ -+timeout 30 bash -c 'while systemd-cgls /test19cleanup.slice/test19cleanup.service >& /dev/null; do sleep .5; done' -+assert_rc 1 systemd-cgls /test19cleanup.slice/test19cleanup.service -+ -+# Check that empty cgroup /test19cleanup.slice has been removed -+timeout 30 bash -c 'while systemd-cgls /test19cleanup.slice >& /dev/null; do sleep .5; done' -+assert_rc 1 systemd-cgls /test19cleanup.slice --- -2.33.0 - diff --git a/backport-core-do-not-GC-units-jobs-that-are-in-the-D-Bus-queu.patch b/backport-core-do-not-GC-units-jobs-that-are-in-the-D-Bus-queu.patch deleted file mode 100644 index e475fc0..0000000 --- a/backport-core-do-not-GC-units-jobs-that-are-in-the-D-Bus-queu.patch +++ /dev/null @@ -1,84 +0,0 @@ -From af05bb971731fe7280e4e85fde71c2e671772c18 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Thu, 8 Jun 2023 11:11:49 +0200 -Subject: [PATCH] core: do not GC units/jobs that are in the D-Bus queue - -Let's make sure that D-Bus messages are always sent out when pending, -before we might GC a unit/job. - -This is kinda a follow-up for 8db998981a4fefd0122bcf5f965726b63c9045c2, -and a similar logic really applies: GC should only be done if we -processed everything else, generated evertyhing else and really don't -need it anymore. - -Conflict:NA -Reference:https://github.com/systemd/systemd/commit/af05bb971731fe7280e4e85fde71c2e671772c18 - ---- - src/core/dbus-job.c | 3 +++ - src/core/dbus-unit.c | 3 +++ - src/core/job.c | 4 ++++ - src/core/unit.c | 4 ++++ - 4 files changed, 14 insertions(+) - -diff --git a/src/core/dbus-job.c b/src/core/dbus-job.c -index 9792a5c44a..c88d8c2dd5 100644 ---- a/src/core/dbus-job.c -+++ b/src/core/dbus-job.c -@@ -241,6 +241,9 @@ void bus_job_send_change_signal(Job *j) { - if (j->in_dbus_queue) { - LIST_REMOVE(dbus_queue, j->manager->dbus_job_queue, j); - j->in_dbus_queue = false; -+ -+ /* The job might be good to be GC once its pending signals have been sent */ -+ job_add_to_gc_queue(j); - } - - r = bus_foreach_bus(j->manager, j->bus_track, j->sent_dbus_new_signal ? send_changed_signal : send_new_signal, j); -diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c -index 59d541ebfe..629f08ebcc 100644 ---- a/src/core/dbus-unit.c -+++ b/src/core/dbus-unit.c -@@ -1648,6 +1648,9 @@ void bus_unit_send_change_signal(Unit *u) { - if (u->in_dbus_queue) { - LIST_REMOVE(dbus_queue, u->manager->dbus_unit_queue, u); - u->in_dbus_queue = false; -+ -+ /* The unit might be good to be GC once its pending signals have been sent */ -+ unit_add_to_gc_queue(u); - } - - if (!u->id) -diff --git a/src/core/job.c b/src/core/job.c -index f87b0f7c74..50f9581d72 100644 ---- a/src/core/job.c -+++ b/src/core/job.c -@@ -1444,6 +1444,10 @@ bool job_may_gc(Job *j) { - if (!UNIT_VTABLE(j->unit)->gc_jobs) - return false; - -+ /* Make sure to send out pending D-Bus events before we unload the unit */ -+ if (j->in_dbus_queue) -+ return false; -+ - if (sd_bus_track_count(j->bus_track) > 0) - return false; - -diff --git a/src/core/unit.c b/src/core/unit.c -index 80f398c309..7b2e8c5f5c 100644 ---- a/src/core/unit.c -+++ b/src/core/unit.c -@@ -447,6 +447,10 @@ bool unit_may_gc(Unit *u) { - if (u->in_cgroup_empty_queue || u->in_cgroup_oom_queue) - return false; - -+ /* Make sure to send out D-Bus events before we unload the unit */ -+ if (u->in_dbus_queue) -+ return false; -+ - if (sd_bus_track_count(u->bus_track) > 0) - return false; - --- -2.33.0 - diff --git a/backport-core-fix-property-getter-method-for-NFileDescriptorS.patch b/backport-core-fix-property-getter-method-for-NFileDescriptorS.patch deleted file mode 100644 index a0cba00..0000000 --- a/backport-core-fix-property-getter-method-for-NFileDescriptorS.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 47226e893b24f1aa84caaa6be266fb3c03442904 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Wed, 12 Apr 2023 20:51:23 +0200 -Subject: [PATCH] core: fix property getter method for NFileDescriptorStore bus - property - -Since da6053d0a7c16795e7fac1f9ba6694863918a597 this is a size_t, not an -unsigned. The difference doesn't matter on LE archs, but it matters on -BE (i.e. s390x), since we'll return entirely nonsensical data. - -Let's fix that. - -Follow-up-for: da6053d0a7c16795e7fac1f9ba6694863918a597 - -An embarassing bug introduced in 2018... That made me scratch my head -for way too long, as it made #27135 fail on s390x while it passed -everywhere else. - -Conflict:Adaptation Context. ASSERT_PTR function adaptation. -Reference:https://github.com/systemd/systemd/commit/47226e893b24f1aa84caaa6be266fb3c03442904 - ---- - src/core/dbus-service.c | 26 +++++++++++++++++++++++++- - 1 file changed, 25 insertions(+), 1 deletion(-) - -diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c -index 02628cd..c0ec277 100644 ---- a/src/core/dbus-service.c -+++ b/src/core/dbus-service.c -@@ -189,6 +189,30 @@ int bus_service_method_mount_image(sd_bus_message *message, void *userdata, sd_b - return bus_service_method_mount(message, userdata, error, true); - } - -+#if __SIZEOF_SIZE_T__ == 8 -+static int property_get_size_as_uint32( -+ sd_bus *bus, -+ const char *path, -+ const char *interface, -+ const char *property, -+ sd_bus_message *reply, -+ void *userdata, -+ sd_bus_error *error) { -+ -+ size_t *value = userdata; -+ assert(value); -+ uint32_t sz = *value >= UINT32_MAX ? UINT32_MAX : (uint32_t) *value; -+ -+ /* Returns a size_t as a D-Bus "u" type, i.e. as 32bit value, even if size_t is 64bit. We'll saturate if it doesn't fit. */ -+ -+ return sd_bus_message_append_basic(reply, 'u', &sz); -+} -+#elif __SIZEOF_SIZE_T__ == 4 -+#define property_get_size_as_uint32 ((sd_bus_property_get_t) NULL) -+#else -+#error "Unexpected size of size_t" -+#endif -+ - const sd_bus_vtable bus_service_vtable[] = { - SD_BUS_VTABLE_START(0), - SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Service, type), SD_BUS_VTABLE_PROPERTY_CONST), -@@ -215,7 +239,7 @@ const sd_bus_vtable bus_service_vtable[] = { - SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(Service, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("BusName", "s", NULL, offsetof(Service, bus_name), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("FileDescriptorStoreMax", "u", bus_property_get_unsigned, offsetof(Service, n_fd_store_max), SD_BUS_VTABLE_PROPERTY_CONST), -- SD_BUS_PROPERTY("NFileDescriptorStore", "u", bus_property_get_unsigned, offsetof(Service, n_fd_store), 0), -+ SD_BUS_PROPERTY("NFileDescriptorStore", "u", property_get_size_as_uint32, offsetof(Service, n_fd_store), 0), - SD_BUS_PROPERTY("StatusText", "s", NULL, offsetof(Service, status_text), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("StatusErrno", "i", bus_property_get_int, offsetof(Service, status_errno), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Service, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), --- -2.33.0 - diff --git a/backport-core-move-runtime-directory-removal-into-release_res.patch b/backport-core-move-runtime-directory-removal-into-release_res.patch deleted file mode 100644 index 615a212..0000000 --- a/backport-core-move-runtime-directory-removal-into-release_res.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 1ba84fef3c1e505cb1413ef446a85c0c7ec439c6 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Tue, 4 Apr 2023 13:42:08 +0200 -Subject: [PATCH] core: move runtime directory removal into release_resource - handler - -We already clear the various fds we keep from the release_resources() -handler, let's also destroy the runtime dir from there if this -preservation mode is selected. - -This makes a minor semantic change: previously we'd keep a runtime -directory around if RuntimeDirectoryPreserve=restart is selected and at -least one JOB_START job was around. With this logic we'll keep it around -a tiny bit longer: as long as any job for the unit is around. - -Conflict:NA -Reference:https://github.com/systemd/systemd/commit/1ba84fef3c1e505cb1413ef446a85c0c7ec439c6 - ---- - src/core/unit.c | 26 +++++++++++++++++++++++--- - 1 file changed, 23 insertions(+), 3 deletions(-) - -diff --git a/src/core/unit.c b/src/core/unit.c -index 089213cf88..d632c34f98 100644 ---- a/src/core/unit.c -+++ b/src/core/unit.c -@@ -396,6 +396,7 @@ static bool unit_success_failure_handler_has_jobs(Unit *unit) { - - void unit_release_resources(Unit *u) { - UnitActiveState state; -+ ExecContext *ec; - - assert(u); - -@@ -412,6 +413,10 @@ void unit_release_resources(Unit *u) { - if (unit_will_restart(u)) - return; - -+ ec = unit_get_exec_context(u); -+ if (ec && ec->runtime_directory_preserve_mode == EXEC_PRESERVE_RESTART) -+ exec_context_destroy_runtime_directory(ec, u->manager->prefix[EXEC_DIRECTORY_RUNTIME]); -+ - if (UNIT_VTABLE(u)->release_resources) - UNIT_VTABLE(u)->release_resources(u); - } -@@ -582,6 +587,21 @@ void unit_submit_to_stop_when_bound_queue(Unit *u) { - u->in_stop_when_bound_queue = true; - } - -+static bool unit_can_release_resources(Unit *u) { -+ ExecContext *ec; -+ -+ assert(u); -+ -+ if (UNIT_VTABLE(u)->release_resources) -+ return true; -+ -+ ec = unit_get_exec_context(u); -+ if (ec && ec->runtime_directory_preserve_mode == EXEC_PRESERVE_RESTART) -+ return true; -+ -+ return false; -+} -+ - void unit_submit_to_release_resources_queue(Unit *u) { - assert(u); - -@@ -594,7 +614,7 @@ void unit_submit_to_release_resources_queue(Unit *u) { - if (u->perpetual) - return; - -- if (!UNIT_VTABLE(u)->release_resources) -+ if (!unit_can_release_resources(u)) - return; - - LIST_PREPEND(release_resources_queue, u->manager->release_resources_queue, u); -@@ -5863,8 +5883,8 @@ void unit_destroy_runtime_data(Unit *u, const ExecContext *context) { - assert(u); - assert(context); - -- if (context->runtime_directory_preserve_mode == EXEC_PRESERVE_NO || -- (context->runtime_directory_preserve_mode == EXEC_PRESERVE_RESTART && !unit_will_restart(u))) -+ /* EXEC_PRESERVE_RESTART is handled via unit_release_resources()! */ -+ if (context->runtime_directory_preserve_mode == EXEC_PRESERVE_NO) - exec_context_destroy_runtime_directory(context, u->manager->prefix[EXEC_DIRECTORY_RUNTIME]); - - exec_context_destroy_credentials(context, u->manager->prefix[EXEC_DIRECTORY_RUNTIME], u->id); --- -2.33.0 - diff --git a/backport-core-support-overriding-NOTIFYACCESS-through-sd-noti.patch b/backport-core-support-overriding-NOTIFYACCESS-through-sd-noti.patch deleted file mode 100644 index ffd8d6e..0000000 --- a/backport-core-support-overriding-NOTIFYACCESS-through-sd-noti.patch +++ /dev/null @@ -1,294 +0,0 @@ -From 19dff6914dee94b36320dbfda94f60af30ac65c1 Mon Sep 17 00:00:00 2001 -From: Mike Yuan -Date: Thu, 26 Jan 2023 17:44:03 +0800 -Subject: [PATCH] core: support overriding NOTIFYACCESS= through sd-notify - during runtime - -Closes #25963 - -Conflict:Adaptation Context. -Reference:https://github.com/systemd/systemd/commit/19dff6914dee94b36320dbfda94f60af30ac65c1 - ---- - man/org.freedesktop.systemd1.xml | 1 - - man/sd_notify.xml | 10 +++++ - src/core/dbus-service.c | 4 +- - src/core/service.c | 67 +++++++++++++++++++++++++++----- - src/core/service.h | 6 +++ - src/systemd/sd-daemon.h | 4 ++ - 6 files changed, 80 insertions(+), 12 deletions(-) - -diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml -index ec2148d..40b5223 100644 ---- a/man/org.freedesktop.systemd1.xml -+++ b/man/org.freedesktop.systemd1.xml -@@ -2301,7 +2301,6 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { - readonly s Restart = '...'; - @org.freedesktop.DBus.Property.EmitsChangedSignal("const") - readonly s PIDFile = '...'; -- @org.freedesktop.DBus.Property.EmitsChangedSignal("const") - readonly s NotifyAccess = '...'; - @org.freedesktop.DBus.Property.EmitsChangedSignal("const") - readonly t RestartUSec = ...; -diff --git a/man/sd_notify.xml b/man/sd_notify.xml -index 69e1b02..c00889b 100644 ---- a/man/sd_notify.xml -+++ b/man/sd_notify.xml -@@ -142,6 +142,16 @@ - system check… - - -+ -+ NOTIFYACCESS=… -+ -+ Reset the access to the service status notification -+ socket during runtime, overriding NotifyAccess= setting -+ in the service unit file. See systemd.service5 -+ for details, specifically NotifyAccess= for a list of -+ accepted values. -+ -+ - - ERRNO=… - -diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c -index c301948..115c256 100644 ---- a/src/core/dbus-service.c -+++ b/src/core/dbus-service.c -@@ -29,8 +29,8 @@ - static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, service_type, ServiceType); - static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, service_result, ServiceResult); - static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_restart, service_restart, ServiceRestart); --static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_notify_access, notify_access, NotifyAccess); - static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_emergency_action, emergency_action, EmergencyAction); -+static BUS_DEFINE_PROPERTY_GET2(property_get_notify_access, "s", Service, service_get_notify_access, notify_access_to_string); - static BUS_DEFINE_PROPERTY_GET(property_get_timeout_abort_usec, "t", Service, service_timeout_abort_usec); - static BUS_DEFINE_PROPERTY_GET(property_get_watchdog_usec, "t", Service, service_get_watchdog_usec); - static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_timeout_failure_mode, service_timeout_failure_mode, ServiceTimeoutFailureMode); -@@ -194,7 +194,7 @@ const sd_bus_vtable bus_service_vtable[] = { - SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Service, type), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("Restart", "s", property_get_restart, offsetof(Service, restart), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("PIDFile", "s", NULL, offsetof(Service, pid_file), SD_BUS_VTABLE_PROPERTY_CONST), -- SD_BUS_PROPERTY("NotifyAccess", "s", property_get_notify_access, offsetof(Service, notify_access), SD_BUS_VTABLE_PROPERTY_CONST), -+ SD_BUS_PROPERTY("NotifyAccess", "s", property_get_notify_access, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("RestartUSec", "t", bus_property_get_usec, offsetof(Service, restart_usec), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("TimeoutStartUSec", "t", bus_property_get_usec, offsetof(Service, timeout_start_usec), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("TimeoutStopUSec", "t", bus_property_get_usec, offsetof(Service, timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST), -diff --git a/src/core/service.c b/src/core/service.c -index 9426060..f05cac8 100644 ---- a/src/core/service.c -+++ b/src/core/service.c -@@ -124,6 +124,8 @@ static void service_init(Unit *u) { - s->exec_context.keyring_mode = MANAGER_IS_SYSTEM(u->manager) ? - EXEC_KEYRING_PRIVATE : EXEC_KEYRING_INHERIT; - -+ s->notify_access_override = _NOTIFY_ACCESS_INVALID; -+ - s->watchdog_original_usec = USEC_INFINITY; - - s->oom_policy = _OOM_POLICY_INVALID; -@@ -208,6 +210,15 @@ void service_release_socket_fd(Service *s) { - s->socket_peer = socket_peer_unref(s->socket_peer); - } - -+static void service_override_notify_access(Service *s, NotifyAccess notify_access_override) { -+ assert(s); -+ -+ s->notify_access_override = notify_access_override; -+ -+ log_unit_debug(UNIT(s), "notify_access=%s", notify_access_to_string(s->notify_access)); -+ log_unit_debug(UNIT(s), "notify_access_override=%s", notify_access_to_string(s->notify_access_override)); -+} -+ - static void service_stop_watchdog(Service *s) { - assert(s); - -@@ -839,7 +850,7 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) { - prefix, yes_no(s->guess_main_pid), - prefix, service_type_to_string(s->type), - prefix, service_restart_to_string(s->restart), -- prefix, notify_access_to_string(s->notify_access), -+ prefix, notify_access_to_string(service_get_notify_access(s)), - prefix, notify_state_to_string(s->notify_state), - prefix, oom_policy_to_string(s->oom_policy)); - -@@ -1435,11 +1446,11 @@ static bool service_exec_needs_notify_socket(Service *s, ExecFlags flags) { - - if (flags & EXEC_IS_CONTROL) - /* A control process */ -- return IN_SET(s->notify_access, NOTIFY_EXEC, NOTIFY_ALL); -+ return IN_SET(service_get_notify_access(s), NOTIFY_EXEC, NOTIFY_ALL); - - /* We only spawn main processes and control processes, so any - * process that is not a control process is a main process */ -- return s->notify_access != NOTIFY_NONE; -+ return service_get_notify_access(s) != NOTIFY_NONE; - } - - static int service_spawn( -@@ -1820,6 +1831,9 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) - /* The next restart might not be a manual stop, hence reset the flag indicating manual stops */ - s->forbid_restart = false; - -+ /* Reset NotifyAccess override */ -+ s->notify_access_override = _NOTIFY_ACCESS_INVALID; -+ - /* We want fresh tmpdirs in case service is started again immediately */ - s->exec_runtime = exec_runtime_unref(s->exec_runtime, true); - -@@ -2318,6 +2332,8 @@ static void service_enter_restart(Service *s) { - s->n_restarts ++; - s->flush_n_restarts = false; - -+ s->notify_access_override = _NOTIFY_ACCESS_INVALID; -+ - log_unit_struct(UNIT(s), LOG_INFO, - "MESSAGE_ID=" SD_MESSAGE_UNIT_RESTART_SCHEDULED_STR, - LOG_UNIT_INVOCATION_ID(UNIT(s)), -@@ -2498,6 +2514,7 @@ static int service_start(Unit *u) { - s->status_text = mfree(s->status_text); - s->status_errno = 0; - -+ s->notify_access_override = _NOTIFY_ACCESS_INVALID; - s->notify_state = NOTIFY_UNKNOWN; - - s->watchdog_original_usec = s->watchdog_usec; -@@ -2760,6 +2777,9 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) { - } - } - -+ if (s->notify_access_override >= 0) -+ (void) serialize_item(f, "notify-access-override", notify_access_to_string(s->notify_access_override)); -+ - (void) serialize_dual_timestamp(f, "watchdog-timestamp", &s->watchdog_timestamp); - (void) serialize_bool(f, "forbid-restart", s->forbid_restart); - -@@ -3028,7 +3048,15 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value, - deserialize_dual_timestamp(value, &s->main_exec_status.start_timestamp); - else if (streq(key, "main-exec-status-exit")) - deserialize_dual_timestamp(value, &s->main_exec_status.exit_timestamp); -- else if (streq(key, "watchdog-timestamp")) -+ else if (streq(key, "notify-access-override")) { -+ NotifyAccess notify_access; -+ -+ notify_access = notify_access_from_string(value); -+ if (notify_access < 0) -+ log_unit_debug(u, "Failed to parse notify-access-override value: %s", value); -+ else -+ s->notify_access_override = notify_access; -+ } else if (streq(key, "watchdog-timestamp")) - deserialize_dual_timestamp(value, &s->watchdog_timestamp); - else if (streq(key, "forbid-restart")) { - int b; -@@ -3549,7 +3577,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { - * has been received */ - if (f != SERVICE_SUCCESS) - service_enter_signal(s, SERVICE_STOP_SIGTERM, f); -- else if (!s->remain_after_exit || s->notify_access == NOTIFY_MAIN) -+ else if (!s->remain_after_exit || service_get_notify_access(s) == NOTIFY_MAIN) - /* The service has never been and will never be active */ - service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_PROTOCOL); - break; -@@ -4007,12 +4035,14 @@ static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void - static bool service_notify_message_authorized(Service *s, pid_t pid, FDSet *fds) { - assert(s); - -- if (s->notify_access == NOTIFY_NONE) { -+ NotifyAccess notify_access = service_get_notify_access(s); -+ -+ if (notify_access == NOTIFY_NONE) { - log_unit_warning(UNIT(s), "Got notification message from PID "PID_FMT", but reception is disabled.", pid); - return false; - } - -- if (s->notify_access == NOTIFY_MAIN && pid != s->main_pid) { -+ if (notify_access == NOTIFY_MAIN && pid != s->main_pid) { - if (s->main_pid != 0) - log_unit_warning(UNIT(s), "Got notification message from PID "PID_FMT", but reception only permitted for main PID "PID_FMT, pid, s->main_pid); - else -@@ -4021,7 +4051,7 @@ static bool service_notify_message_authorized(Service *s, pid_t pid, FDSet *fds) - return false; - } - -- if (s->notify_access == NOTIFY_EXEC && pid != s->main_pid && pid != s->control_pid) { -+ if (notify_access == NOTIFY_EXEC && pid != s->main_pid && pid != s->control_pid) { - if (s->main_pid != 0 && s->control_pid != 0) - log_unit_warning(UNIT(s), "Got notification message from PID "PID_FMT", but reception only permitted for main PID "PID_FMT" and control PID "PID_FMT, - pid, s->main_pid, s->control_pid); -@@ -4063,7 +4093,7 @@ static void service_notify_message( - assert(u); - assert(ucred); - -- if (!service_notify_message_authorized(SERVICE(u), ucred->pid, fds)) -+ if (!service_notify_message_authorized(s, ucred->pid, fds)) - return; - - if (DEBUG_LOGGING) { -@@ -4168,6 +4198,25 @@ static void service_notify_message( - } - } - -+ /* Interpret NOTIFYACCESS= */ -+ e = strv_find_startswith(tags, "NOTIFYACCESS="); -+ if (e) { -+ NotifyAccess notify_access; -+ -+ notify_access = notify_access_from_string(e); -+ if (notify_access < 0) -+ log_unit_warning_errno(u, notify_access, -+ "Failed to parse NOTIFYACCESS= field value '%s' in notification message, ignoring: %m", e); -+ -+ /* We don't need to check whether the new access mode is more strict than what is -+ * already in use, since only the privileged process is allowed to change it -+ * in the first place. */ -+ if (service_get_notify_access(s) != notify_access) { -+ service_override_notify_access(s, notify_access); -+ notify_dbus = true; -+ } -+ } -+ - /* Interpret ERRNO= */ - e = strv_find_startswith(tags, "ERRNO="); - if (e) { -diff --git a/src/core/service.h b/src/core/service.h -index 4a4ab8a..a65ade3 100644 ---- a/src/core/service.h -+++ b/src/core/service.h -@@ -184,6 +184,7 @@ struct Service { - PathSpec *pid_file_pathspec; - - NotifyAccess notify_access; -+ NotifyAccess notify_access_override; - NotifyState notify_state; - - sd_bus_slot *bus_name_pid_lookup_slot; -@@ -213,6 +214,11 @@ static inline usec_t service_timeout_abort_usec(Service *s) { - return s->timeout_abort_set ? s->timeout_abort_usec : s->timeout_stop_usec; - } - -+static inline NotifyAccess service_get_notify_access(Service *s) { -+ assert(s); -+ return s->notify_access_override < 0 ? s->notify_access : s->notify_access_override; -+} -+ - static inline usec_t service_get_watchdog_usec(Service *s) { - assert(s); - return s->watchdog_override_enable ? s->watchdog_override_usec : s->watchdog_original_usec; -diff --git a/src/systemd/sd-daemon.h b/src/systemd/sd-daemon.h -index f42a5d8..a93ce9c 100644 ---- a/src/systemd/sd-daemon.h -+++ b/src/systemd/sd-daemon.h -@@ -195,6 +195,10 @@ int sd_is_mq(int fd, const char *path); - readable error message. Example: "STATUS=Completed - 66% of file system check..." - -+ NOTIFYACCESS=... -+ Reset the access to the service status notification socket. -+ Example: "NOTIFYACCESS=main" -+ - ERRNO=... If a daemon fails, the errno-style error code, - formatted as string. Example: "ERRNO=2" for ENOENT. - --- -2.33.0 - diff --git a/backport-fd-util-introduce-dir_fd_is_root_or_cwd.patch b/backport-fd-util-introduce-dir_fd_is_root_or_cwd.patch deleted file mode 100644 index 22daf99..0000000 --- a/backport-fd-util-introduce-dir_fd_is_root_or_cwd.patch +++ /dev/null @@ -1,27 +0,0 @@ -From e212f422796da9e626030289faf083407c8955df Mon Sep 17 00:00:00 2001 -From: Yu Watanabe -Date: Sun, 2 Apr 2023 01:25:46 +0900 -Subject: [PATCH] fd-util: introduce dir_fd_is_root_or_cwd() - -Conflict:Import only fcntl.h to prevent dependency failures. -Reference:https://github.com/systemd/systemd/commit/e212f422796da9e626030289faf083407c8955df - ---- - src/basic/fd-util.h | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/src/basic/fd-util.h b/src/basic/fd-util.h -index 9529a47..a08907e 100644 ---- a/src/basic/fd-util.h -+++ b/src/basic/fd-util.h -@@ -2,6 +2,7 @@ - #pragma once - - #include -+#include - #include - #include - #include --- -2.33.0 - diff --git a/backport-fdset-add-new-fdset_consume-helper.patch b/backport-fdset-add-new-fdset_consume-helper.patch deleted file mode 100644 index c45caef..0000000 --- a/backport-fdset-add-new-fdset_consume-helper.patch +++ /dev/null @@ -1,52 +0,0 @@ -From e829f28c1bc6e6865261bfb3bc26089f50e0c7bd Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Wed, 29 Mar 2023 18:52:25 +0200 -Subject: [PATCH] fdset: add new fdset_consume() helper - -Conflict:Context Adaptation. Delete the code that is not involved. -Reference:https://github.com/systemd/systemd/commit/e829f28c1bc6e6865261bfb3bc26089f50e0c7bd - ---- - src/shared/fdset.c | 13 +++++++++++++ - src/shared/fdset.h | 1 + - 2 files changed, 14 insertions(+) - -diff --git a/src/shared/fdset.c b/src/shared/fdset.c -index 443aa7f..68a465f 100644 ---- a/src/shared/fdset.c -+++ b/src/shared/fdset.c -@@ -81,6 +81,19 @@ int fdset_put(FDSet *s, int fd) { - return set_put(MAKE_SET(s), FD_TO_PTR(fd)); - } - -+int fdset_consume(FDSet *s, int fd) { -+ int r; -+ -+ assert(s); -+ assert(fd >= 0); -+ -+ r = fdset_put(s, fd); -+ if (r < 0) -+ safe_close(fd); -+ -+ return r; -+} -+ - int fdset_put_dup(FDSet *s, int fd) { - int copy, r; - -diff --git a/src/shared/fdset.h b/src/shared/fdset.h -index e8a6b48..ac5ec76 100644 ---- a/src/shared/fdset.h -+++ b/src/shared/fdset.h -@@ -13,6 +13,7 @@ FDSet* fdset_new(void); - FDSet* fdset_free(FDSet *s); - - int fdset_put(FDSet *s, int fd); -+int fdset_consume(FDSet *s, int fd); - int fdset_put_dup(FDSet *s, int fd); - - bool fdset_contains(FDSet *s, int fd); --- -2.33.0 - diff --git a/backport-fdset-add-new-helper-to-convert-an-fdset-to-an-array.patch b/backport-fdset-add-new-helper-to-convert-an-fdset-to-an-array.patch deleted file mode 100644 index b78471b..0000000 --- a/backport-fdset-add-new-helper-to-convert-an-fdset-to-an-array.patch +++ /dev/null @@ -1,86 +0,0 @@ -From bdcad22e8e508308032cba5f8c2d5c093adb7d87 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Tue, 28 Mar 2023 11:17:23 +0200 -Subject: [PATCH] fdset: add new helper to convert an fdset to an array - -Conflict:fdset_close_others removes different code, but the end result is the same. -Reference:https://github.com/systemd/systemd/commit/bdcad22e8e508308032cba5f8c2d5c093adb7d87 - ---- - src/shared/fdset.c | 39 ++++++++++++++++++++++++++++++--------- - src/shared/fdset.h | 2 ++ - 2 files changed, 32 insertions(+), 9 deletions(-) - -diff --git a/src/shared/fdset.c b/src/shared/fdset.c -index 443aa7f..cb7a340 100644 ---- a/src/shared/fdset.c -+++ b/src/shared/fdset.c -@@ -236,22 +236,43 @@ fail: - return r; - } - --int fdset_close_others(FDSet *fds) { -+int fdset_to_array(FDSet *fds, int **ret) { -+ unsigned j = 0, m; - void *e; -- int *a = NULL; -- size_t j = 0, m; -+ int *a; - -- m = fdset_size(fds); -+ assert(ret); - -- if (m > 0) { -- a = newa(int, m); -- SET_FOREACH(e, MAKE_SET(fds)) -- a[j++] = PTR_TO_FD(e); -+ m = fdset_size(fds); -+ if (m > INT_MAX) /* We want to be able to return an "int" */ -+ return -ENOMEM; -+ if (m == 0) { -+ *ret = NULL; /* suppress array allocation if empty */ -+ return 0; - } - -+ a = new(int, m); -+ if (!a) -+ return -ENOMEM; -+ -+ SET_FOREACH(e, MAKE_SET(fds)) -+ a[j++] = PTR_TO_FD(e); -+ - assert(j == m); - -- return close_all_fds(a, j); -+ *ret = TAKE_PTR(a); -+ return (int) m; -+} -+ -+int fdset_close_others(FDSet *fds) { -+ _cleanup_free_ int *a = NULL; -+ int n; -+ -+ n = fdset_to_array(fds, &a); -+ if (n < 0) -+ return n; -+ -+ return close_all_fds(a, n); - } - - unsigned fdset_size(FDSet *fds) { -diff --git a/src/shared/fdset.h b/src/shared/fdset.h -index e8a6b48..5f4304e 100644 ---- a/src/shared/fdset.h -+++ b/src/shared/fdset.h -@@ -24,6 +24,8 @@ int fdset_new_listen_fds(FDSet **ret, bool unset); - - int fdset_cloexec(FDSet *fds, bool b); - -+int fdset_to_array(FDSet *fds, int **ret); -+ - int fdset_close_others(FDSet *fds); - - unsigned fdset_size(FDSet *fds); --- -2.33.0 - diff --git a/backport-meson-exclude-.gitattributes-when-using-install_subd.patch b/backport-meson-exclude-.gitattributes-when-using-install_subd.patch deleted file mode 100644 index 4d22868..0000000 --- a/backport-meson-exclude-.gitattributes-when-using-install_subd.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 082c67616511c7c08627eaf19af7e59a7f360479 Mon Sep 17 00:00:00 2001 -From: Luca Boccassi -Date: Thu, 9 Dec 2021 22:16:19 +0000 -Subject: [PATCH] meson: exclude .gitattributes when using install_subdir - -It picks the whole content of the directory by default, but we don't -want to install .gitattributes files. Add it to all invocations, not -just the ones on subdirs with .gitattributes, so that we don't regress -in the future. - -Fixes #21715 - -Conflict:Adaptation Context. -Reference:https://github.com/systemd/systemd/commit/082c67616511c7c08627eaf19af7e59a7f360479 - ---- - test/meson.build | 18 ++++++++++++++++++ - 1 file changed, 18 insertions(+) - -diff --git a/test/meson.build b/test/meson.build -index 6f8f257..8727e66 100644 ---- a/test/meson.build -+++ b/test/meson.build -@@ -4,36 +4,52 @@ if install_tests - testdata_dir = testsdir + '/testdata/' - - install_subdir('journal-data', -+ exclude_files : '.gitattributes', - install_dir : testdata_dir) - install_subdir('units', -+ exclude_files : '.gitattributes', - install_dir : testdata_dir) - install_subdir('test-execute', -+ exclude_files : '.gitattributes', - install_dir : testdata_dir) - install_subdir('test-path', -+ exclude_files : '.gitattributes', - install_dir : testdata_dir) - install_subdir('test-path-util', -+ exclude_files : '.gitattributes', - install_dir : testdata_dir) - install_subdir('test-umount', -+ exclude_files : '.gitattributes', - install_dir : testdata_dir) - install_subdir('test-network-generator-conversion', -+ exclude_files : '.gitattributes', - install_dir : testdata_dir) - install_subdir('testsuite-04.units', -+ exclude_files : '.gitattributes', - install_dir : testdata_dir) - install_subdir('testsuite-06.units', -+ exclude_files : '.gitattributes', - install_dir : testdata_dir) - install_subdir('testsuite-10.units', -+ exclude_files : '.gitattributes', - install_dir : testdata_dir) - install_subdir('testsuite-11.units', -+ exclude_files : '.gitattributes', - install_dir : testdata_dir) - install_subdir('testsuite-16.units', -+ exclude_files : '.gitattributes', - install_dir : testdata_dir) - install_subdir('testsuite-28.units', -+ exclude_files : '.gitattributes', - install_dir : testdata_dir) - install_subdir('testsuite-30.units', -+ exclude_files : '.gitattributes', - install_dir : testdata_dir) - install_subdir('testsuite-52.units', -+ exclude_files : '.gitattributes', - install_dir : testdata_dir) - install_subdir('testsuite-63.units', -+ exclude_files : '.gitattributes', - install_dir : testdata_dir) - - testsuite08_dir = testdata_dir + '/testsuite-08.units' -@@ -50,6 +66,7 @@ if install_tests - - if conf.get('ENABLE_RESOLVE') == 1 - install_subdir('test-resolve', -+ exclude_files : '.gitattributes', - install_dir : testdata_dir) - endif - -@@ -72,6 +89,7 @@ if install_tests and conf.get('ENABLE_SYSUSERS') == 1 - install_data(test_sysusers_sh, - install_dir : testsdir) - install_subdir('test-sysusers', -+ exclude_files : '.gitattributes', - install_dir : testdata_dir) - endif - --- -2.33.0 - diff --git a/backport-notify-add-new-exec-switch-for-chaining-other-comman.patch b/backport-notify-add-new-exec-switch-for-chaining-other-comman.patch deleted file mode 100644 index 1c02866..0000000 --- a/backport-notify-add-new-exec-switch-for-chaining-other-comman.patch +++ /dev/null @@ -1,150 +0,0 @@ -From 9175338e09de56c99cebf0b9f215f3e9e0016cb9 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Thu, 16 Feb 2023 15:42:49 +0100 -Subject: [PATCH] notify: add new --exec switch for chaining other commands to - systemd-notify - -This is useful in tests, so that we can first send a READY message and -then continue doing something else without changing PID. - -Conflict:NA -Reference:https://github.com/systemd/systemd/commit/9175338e09de56c99cebf0b9f215f3e9e0016cb9 - ---- - src/notify/notify.c | 59 ++++++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 56 insertions(+), 3 deletions(-) - -diff --git a/src/notify/notify.c b/src/notify/notify.c -index b1348383f5..7320ffebde 100644 ---- a/src/notify/notify.c -+++ b/src/notify/notify.c -@@ -31,6 +31,11 @@ static bool arg_booted = false; - static uid_t arg_uid = UID_INVALID; - static gid_t arg_gid = GID_INVALID; - static bool arg_no_block = false; -+static char **arg_env = NULL; -+static char **arg_exec = NULL; -+ -+STATIC_DESTRUCTOR_REGISTER(arg_env, strv_freep); -+STATIC_DESTRUCTOR_REGISTER(arg_exec, strv_freep); - - static int help(void) { - _cleanup_free_ char *link = NULL; -@@ -41,6 +46,7 @@ static int help(void) { - return log_oom(); - - printf("%s [OPTIONS...] [VARIABLE=VALUE...]\n" -+ "%s [OPTIONS...] --exec [VARIABLE=VALUE...] ; CMDLINE...\n" - "\n%sNotify the init system about service status updates.%s\n\n" - " -h --help Show this help\n" - " --version Show package version\n" -@@ -53,8 +59,10 @@ static int help(void) { - " --status=TEXT Set status text\n" - " --booted Check if the system was booted up with systemd\n" - " --no-block Do not wait until operation finished\n" -+ " --exec Execute command line separated by ';' once done\n" - "\nSee the %s for details.\n", - program_invocation_short_name, -+ program_invocation_short_name, - ansi_highlight(), - ansi_normal(), - link); -@@ -93,7 +101,8 @@ static int parse_argv(int argc, char *argv[]) { - ARG_STATUS, - ARG_BOOTED, - ARG_UID, -- ARG_NO_BLOCK -+ ARG_NO_BLOCK, -+ ARG_EXEC, - }; - - static const struct option options[] = { -@@ -107,10 +116,12 @@ static int parse_argv(int argc, char *argv[]) { - { "booted", no_argument, NULL, ARG_BOOTED }, - { "uid", required_argument, NULL, ARG_UID }, - { "no-block", no_argument, NULL, ARG_NO_BLOCK }, -+ { "exec", no_argument, NULL, ARG_EXEC }, - {} - }; - -- int c, r; -+ bool do_exec = false; -+ int c, r, n_env; - - assert(argc >= 0); - assert(argv); -@@ -183,6 +194,10 @@ static int parse_argv(int argc, char *argv[]) { - arg_no_block = true; - break; - -+ case ARG_EXEC: -+ do_exec = true; -+ break; -+ - case '?': - return -EINVAL; - -@@ -202,6 +217,32 @@ static int parse_argv(int argc, char *argv[]) { - return -EINVAL; - } - -+ if (do_exec) { -+ int i; -+ -+ for (i = optind; i < argc; i++) -+ if (streq(argv[i], ";")) -+ break; -+ -+ if (i >= argc) -+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "If --exec is used argument list must contain ';' separator, refusing."); -+ if (i+1 == argc) -+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Empty command line specified after ';' separator, refusing"); -+ -+ arg_exec = strv_copy_n(argv + i + 1, argc - i - 1); -+ if (!arg_exec) -+ return log_oom(); -+ -+ n_env = i - optind; -+ } else -+ n_env = argc - optind; -+ -+ if (n_env > 0) { -+ arg_env = strv_copy_n(argv + optind, n_env); -+ if (!arg_env) -+ return log_oom(); -+ } -+ - return 1; - } - -@@ -263,7 +304,7 @@ static int run(int argc, char* argv[]) { - - our_env[i++] = NULL; - -- final_env = strv_env_merge(our_env, argv + optind); -+ final_env = strv_env_merge(our_env, arg_env); - if (!final_env) - return log_oom(); - -@@ -313,6 +354,18 @@ static int run(int argc, char* argv[]) { - "No status data could be sent: $NOTIFY_SOCKET was not set"); - } - -+ if (arg_exec) { -+ _cleanup_free_ char *cmdline = NULL; -+ -+ execvp(arg_exec[0], arg_exec); -+ -+ cmdline = strv_join(arg_exec, " "); -+ if (!cmdline) -+ return log_oom(); -+ -+ return log_error_errno(errno, "Failed to execute command line: %s", cmdline); -+ } -+ - return 0; - } - --- -2.33.0 - diff --git a/backport-notify-add-support-for-sending-fds-with-notification.patch b/backport-notify-add-support-for-sending-fds-with-notification.patch deleted file mode 100644 index d7d8b38..0000000 --- a/backport-notify-add-support-for-sending-fds-with-notification.patch +++ /dev/null @@ -1,258 +0,0 @@ -From 6e4a324574d5f1b2296799324dbdb54326078233 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Tue, 28 Mar 2023 11:17:44 +0200 -Subject: [PATCH] notify: add support for sending fds with notification - messages - -This exposes the fd passing we support via sd_pid_notify_with_fds() also -via the command line tool systemd-notify. - -Conflict:Context Adaptation. fdset_new_fill adaptation. -Reference:https://github.com/systemd/systemd/commit/6e4a324574d5f1b2296799324dbdb54326078233 - ---- - man/systemd-notify.xml | 23 +++++++++ - src/notify/notify.c | 109 +++++++++++++++++++++++++++++++++++++++-- - 2 files changed, 128 insertions(+), 4 deletions(-) - -diff --git a/man/systemd-notify.xml b/man/systemd-notify.xml -index 3fed92e..586d09e 100644 ---- a/man/systemd-notify.xml -+++ b/man/systemd-notify.xml -@@ -143,6 +143,29 @@ - this option set is prone to race conditions in all other cases. - - -+ -+ -+ -+ Send a file descriptor along with the notification message. This is useful when -+ invoked in services that have the FileDescriptorStoreMax= setting enabled, see -+ systemd.service5 -+ for details. The specified file descriptor must be passed to systemd-notify when -+ invoked. This option may be used multiple times to pass multiple file descriptors in a single -+ notification message. -+ -+ To use this functionality from a bash shell, use an expression like the following: -+ systemd-notify --fd=4 --fd=5 4</some/file 5</some/other/file -+ -+ -+ -+ -+ -+ Set a name to assign to the file descriptors passed via (see -+ above). This controls the FDNAME= field. This setting may only be specified once, -+ and applies to all file descriptors passed. Invoke this tool multiple times in case multiple file -+ descriptors with different file descriptor names shall be submitted. -+ -+ - - - -diff --git a/src/notify/notify.c b/src/notify/notify.c -index 5afea7f..ad0ae89 100644 ---- a/src/notify/notify.c -+++ b/src/notify/notify.c -@@ -10,6 +10,8 @@ - - #include "alloc-util.h" - #include "env-util.h" -+#include "fd-util.h" -+#include "fdset.h" - #include "format-util.h" - #include "log.h" - #include "main-func.h" -@@ -31,9 +33,13 @@ static gid_t arg_gid = GID_INVALID; - static bool arg_no_block = false; - static char **arg_env = NULL; - static char **arg_exec = NULL; -+static FDSet *arg_fds = NULL; -+static char *arg_fdname = NULL; - - STATIC_DESTRUCTOR_REGISTER(arg_env, strv_freep); - STATIC_DESTRUCTOR_REGISTER(arg_exec, strv_freep); -+STATIC_DESTRUCTOR_REGISTER(arg_fds, fdset_freep); -+STATIC_DESTRUCTOR_REGISTER(arg_fdname, freep); - - static int help(void) { - _cleanup_free_ char *link = NULL; -@@ -55,6 +61,8 @@ static int help(void) { - " --booted Check if the system was booted up with systemd\n" - " --no-block Do not wait until operation finished\n" - " --exec Execute command line separated by ';' once done\n" -+ " --fd=FD Pass specified file descriptor with along with message\n" -+ " --fdname=NAME Name to assign to passed file descriptor(s)\n" - "\nSee the %s for details.\n", - program_invocation_short_name, - program_invocation_short_name, -@@ -96,6 +104,8 @@ static int parse_argv(int argc, char *argv[]) { - ARG_UID, - ARG_NO_BLOCK, - ARG_EXEC, -+ ARG_FD, -+ ARG_FDNAME, - }; - - static const struct option options[] = { -@@ -108,9 +118,12 @@ static int parse_argv(int argc, char *argv[]) { - { "uid", required_argument, NULL, ARG_UID }, - { "no-block", no_argument, NULL, ARG_NO_BLOCK }, - { "exec", no_argument, NULL, ARG_EXEC }, -+ { "fd", required_argument, NULL, ARG_FD }, -+ { "fdname", required_argument, NULL, ARG_FDNAME }, - {} - }; - -+ _cleanup_(fdset_freep) FDSet *passed = NULL; - bool do_exec = false; - int c, r, n_env; - -@@ -181,6 +194,60 @@ static int parse_argv(int argc, char *argv[]) { - do_exec = true; - break; - -+ case ARG_FD: { -+ _cleanup_close_ int owned_fd = -EBADF; -+ int fdnr; -+ -+ r = safe_atoi(optarg, &fdnr); -+ if (r < 0) -+ return log_error_errno(r, "Failed to parse file descriptor: %s", optarg); -+ if (fdnr < 0) -+ return log_error_errno(SYNTHETIC_ERRNO(ERANGE), "File descriptor can't be negative: %i", fdnr); -+ -+ if (!passed) { -+ /* Take possession of all passed fds */ -+ r = fdset_new_fill(/* filter_cloexec= */ 0, &passed); -+ if (r < 0) -+ return log_error_errno(r, "Failed to take possession of passed file descriptors: %m"); -+ -+ r = fdset_cloexec(passed, true); -+ if (r < 0) -+ return log_error_errno(r, "Failed to enable O_CLOEXEC for passed file descriptors: %m"); -+ } -+ -+ if (fdnr < 3) { -+ /* For stdin/stdout/stderr we want to keep the fd, too, hence make a copy */ -+ owned_fd = fcntl(fdnr, F_DUPFD_CLOEXEC, 3); -+ if (owned_fd < 0) -+ return log_error_errno(errno, "Failed to duplicate file descriptor: %m"); -+ } else { -+ /* Otherwise, move the fd over */ -+ owned_fd = fdset_remove(passed, fdnr); -+ if (owned_fd < 0) -+ return log_error_errno(owned_fd, "Specified file descriptor '%i' not passed or specified more than once: %m", fdnr); -+ } -+ -+ if (!arg_fds) { -+ arg_fds = fdset_new(); -+ if (!arg_fds) -+ return log_oom(); -+ } -+ -+ r = fdset_consume(arg_fds, TAKE_FD(owned_fd)); -+ if (r < 0) -+ return log_error_errno(r, "Failed to add file descriptor to set: %m"); -+ break; -+ } -+ -+ case ARG_FDNAME: -+ if (!fdname_is_valid(optarg)) -+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "File descriptor name invalid: %s", optarg); -+ -+ if (free_and_strdup(&arg_fdname, optarg) < 0) -+ return log_oom(); -+ -+ break; -+ - case '?': - return -EINVAL; - -@@ -193,11 +260,15 @@ static int parse_argv(int argc, char *argv[]) { - !arg_ready && - !arg_status && - !arg_pid && -- !arg_booted) { -+ !arg_booted && -+ fdset_isempty(arg_fds)) { - help(); - return -EINVAL; - } - -+ if (arg_fdname && fdset_isempty(arg_fds)) -+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No file descriptors passed, but --fdname= set, refusing."); -+ - if (do_exec) { - int i; - -@@ -224,13 +295,16 @@ static int parse_argv(int argc, char *argv[]) { - return log_oom(); - } - -+ if (!fdset_isempty(passed)) -+ log_warning("Warning: %u more file descriptors passed than referenced with --fd=.", fdset_size(passed)); -+ - return 1; - } - - static int run(int argc, char* argv[]) { -- _cleanup_free_ char *status = NULL, *cpid = NULL, *n = NULL; -+ _cleanup_free_ char *status = NULL, *cpid = NULL, *n = NULL, *fdn = NULL; - _cleanup_strv_free_ char **final_env = NULL; -- char* our_env[4]; -+ char* our_env[6]; - unsigned i = 0; - pid_t source_pid; - int r; -@@ -271,6 +345,18 @@ static int run(int argc, char* argv[]) { - our_env[i++] = cpid; - } - -+ if (!fdset_isempty(arg_fds)) { -+ our_env[i++] = (char*) "FDSTORE=1"; -+ -+ if (arg_fdname) { -+ fdn = strjoin("FDNAME=", arg_fdname); -+ if (!fdn) -+ return log_oom(); -+ -+ our_env[i++] = fdn; -+ } -+ } -+ - our_env[i++] = NULL; - - final_env = strv_env_merge(our_env, arg_env); -@@ -307,13 +393,28 @@ static int run(int argc, char* argv[]) { - * or the service manager itself */ - source_pid = 0; - } -- r = sd_pid_notify(source_pid, false, n); -+ -+ if (fdset_isempty(arg_fds)) -+ r = sd_pid_notify(source_pid, /* unset_environment= */ false, n); -+ else { -+ _cleanup_free_ int *a = NULL; -+ int k; -+ -+ k = fdset_to_array(arg_fds, &a); -+ if (k < 0) -+ return log_error_errno(k, "Failed to convert file descriptor set to array: %m"); -+ -+ r = sd_pid_notify_with_fds(source_pid, /* unset_environment= */ false, n, a, k); -+ -+ } - if (r < 0) - return log_error_errno(r, "Failed to notify init system: %m"); - if (r == 0) - return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), - "No status data could be sent: $NOTIFY_SOCKET was not set"); - -+ arg_fds = fdset_free(arg_fds); /* Close before we execute anything */ -+ - if (!arg_no_block) { - r = sd_notify_barrier(0, 5 * USEC_PER_SEC); - if (r < 0) --- -2.33.0 - diff --git a/backport-pid1-add-some-debug-logging-when-stashing-ds-into-th.patch b/backport-pid1-add-some-debug-logging-when-stashing-ds-into-th.patch deleted file mode 100644 index 325d7f8..0000000 --- a/backport-pid1-add-some-debug-logging-when-stashing-ds-into-th.patch +++ /dev/null @@ -1,54 +0,0 @@ -From e8783d7620e4811738be078480aa5ffc9bbdcf9b Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Wed, 12 Apr 2023 21:07:29 +0200 -Subject: [PATCH] pid1: add some debug logging when stashing ds into the - fdstore - -Conflict:Context Adaptation. Log Adaptation. -Reference:https://github.com/systemd/systemd/commit/e8783d7620e4811738be078480aa5ffc9bbdcf9b - ---- - src/core/service.c | 13 ++++++++++--- - 1 file changed, 10 insertions(+), 3 deletions(-) - -diff --git a/src/core/service.c b/src/core/service.c -index a7d5f3f..103c8a5 100644 ---- a/src/core/service.c -+++ b/src/core/service.c -@@ -427,6 +427,7 @@ static int on_fd_store_io(sd_event_source *e, int fd, uint32_t revents, void *us - } - - static int service_add_fd_store(Service *s, int fd, const char *name, bool do_poll) { -+ struct stat st; - ServiceFDStore *fs; - int r; - -@@ -435,16 +436,22 @@ static int service_add_fd_store(Service *s, int fd, const char *name, bool do_po - assert(s); - assert(fd >= 0); - -+ if (fstat(fd, &st) < 0) -+ return -errno; -+ -+ log_unit_debug(UNIT(s), "Trying to stash fd for dev=" "%u:%u" "/inode=%" PRIu64, major(st.st_dev), minor(st.st_dev), (uint64_t) st.st_ino); -+ - if (s->n_fd_store >= s->n_fd_store_max) -- return -EXFULL; /* Our store is full. -- * Use this errno rather than E[NM]FILE to distinguish from -- * the case where systemd itself hits the file limit. */ -+ /* Our store is full. Use this errno rather than E[NM]FILE to distinguish from the case -+ * where systemd itself hits the file limit. */ -+ return log_unit_debug_errno(UNIT(s), SYNTHETIC_ERRNO(EXFULL), "Hit fd store limit."); - - LIST_FOREACH(fd_store, fs, s->fd_store) { - r = same_fd(fs->fd, fd); - if (r < 0) - return r; - if (r > 0) { -+ log_unit_debug(UNIT(s), "Suppressing duplicate fd in fd store."); - asynchronous_close(fd); - return 0; /* fd already included */ - } --- -2.33.0 - diff --git a/backport-service-add-ability-to-pin-fd-store.patch b/backport-service-add-ability-to-pin-fd-store.patch deleted file mode 100644 index 86cc1ff..0000000 --- a/backport-service-add-ability-to-pin-fd-store.patch +++ /dev/null @@ -1,476 +0,0 @@ -From b9c1883a9cd9b5126fe648f3e198143dc19a222d Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Wed, 29 Mar 2023 22:07:22 +0200 -Subject: [PATCH] service: add ability to pin fd store -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Oftentimes it is useful to allow the per-service fd store to survive -longer than for a restart. This is useful in various scenarios: - -1. An fd to some security relevant object needs to be stashed somewhere, - that should not be cleaned automatically, because the security - enforcement would be dropped then. - -2. A user namespace fd should be allocated on first invocation and be - kept around until the user logs out (i.e. systemd --user ends), á la - #16328 (This does not implement what #16318 asks for, but should - solve the use-case discussed there.) - -3. There's interest in allow a concept of "userspace reboots" where the - kernel stays running, and userspace is swapped out (i.e. all services - exit, and the rootfs transitioned into a new version of it) while - keeping some select resources pinned, very similar to how we - implement a switch root. Thus it is useful to allow services to exit, - while leaving their fds around till the very end. - -This is exposed through a new FileDescriptorStorePreserve= setting that -is closely modelled after RuntimeDirectoryPreserve= (in fact it reused -the same internal type), since we want similar behaviour in the end, and -quite often they probably want to be used together. - -Conflict:Adaptation Context.The FileDescriptorStorePreserve= field is added to the directives.service file to prevent test case failures. -Reference:https://github.com/systemd/systemd/commit/b9c1883a9cd9b5126fe648f3e198143dc19a222d - ---- - man/org.freedesktop.systemd1.xml | 6 +++ - man/systemd.service.xml | 21 +++++++++- - src/basic/unit-def.c | 1 + - src/basic/unit-def.h | 1 + - src/core/dbus-execute.c | 8 ++-- - src/core/dbus-execute.h | 2 + - src/core/dbus-service.c | 4 ++ - src/core/load-fragment-gperf.gperf.in | 3 +- - src/core/load-fragment.c | 2 +- - src/core/load-fragment.h | 2 +- - src/core/service.c | 43 ++++++++++++++++----- - src/core/service.h | 1 + - src/shared/bus-unit-util.c | 3 +- - test/fuzz/fuzz-unit-file/directives.service | 1 + - 14 files changed, 78 insertions(+), 20 deletions(-) - -diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml -index 74a9202..ec2148d 100644 ---- a/man/org.freedesktop.systemd1.xml -+++ b/man/org.freedesktop.systemd1.xml -@@ -2343,6 +2343,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { - readonly u FileDescriptorStoreMax = ...; - @org.freedesktop.DBus.Property.EmitsChangedSignal("false") - readonly u NFileDescriptorStore = ...; -+ @org.freedesktop.DBus.Property.EmitsChangedSignal("false") -+ readonly s FileDescriptorStorePreserve = '...'; - readonly s StatusText = '...'; - readonly i StatusErrno = ...; - readonly s Result = '...'; -@@ -2898,6 +2900,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { - - - -+ -+ - - - -@@ -3430,6 +3434,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { - - - -+ -+ - - - -diff --git a/man/systemd.service.xml b/man/systemd.service.xml -index 350bc5f..ed9b410 100644 ---- a/man/systemd.service.xml -+++ b/man/systemd.service.xml -@@ -1050,7 +1050,7 @@ - FDSTORE=1 messages. This is useful for implementing services that can restart - after an explicit request or a crash without losing state. Any open sockets and other file - descriptors which should not be closed during the restart may be stored this way. Application state -- can either be serialized to a file in /run/, or better, stored in a -+ can either be serialized to a file in RuntimeDirectory=, or stored in a - memfd_create2 - memory file descriptor. Defaults to 0, i.e. no file descriptors may be stored in the service - manager. All file descriptors passed to the service manager from a specific service are passed back -@@ -1059,12 +1059,29 @@ - details about the precise protocol used and the order in which the file descriptors are passed). Any - file descriptors passed to the service manager are automatically closed when - POLLHUP or POLLERR is seen on them, or when the service is -- fully stopped and no job is queued or being executed for it. If this option is used, -+ fully stopped and no job is queued or being executed for it (the latter can be tweaked with -+ FileDescriptorStorePreserve=, see below). If this option is used, - NotifyAccess= (see above) should be set to open access to the notification socket - provided by systemd. If NotifyAccess= is not set, it will be implicitly set to - . - - -+ -+ FileDescriptorStorePreserve= -+ Takes one of no, yes, -+ restart and controls when to release the service's file descriptor store -+ (i.e. when to close the contained file descriptors, if any). If set to no the -+ file descriptor store is automatically released when the service is stopped; if -+ restart (the default) it is kept around as long as the unit is neither inactive -+ nor failed, or a job is queued for the service, or the service is expected to be restarted. If -+ yes the file descriptor store is kept around until the unit is removed from -+ memory (i.e. is not referenced anymore and inactive). The latter is useful to keep entries in the -+ file descriptor store pinned until the service manage exits. -+ -+ Use systemctl clean --what=fdstore … to release the file descriptor store -+ explicitly. -+ -+ - - USBFunctionDescriptors= - Configure the location of a file containing -diff --git a/src/basic/unit-def.c b/src/basic/unit-def.c -index 2667e61..09b2747 100644 ---- a/src/basic/unit-def.c -+++ b/src/basic/unit-def.c -@@ -196,6 +196,7 @@ static const char* const service_state_table[_SERVICE_STATE_MAX] = { - [SERVICE_FINAL_SIGTERM] = "final-sigterm", - [SERVICE_FINAL_SIGKILL] = "final-sigkill", - [SERVICE_FAILED] = "failed", -+ [SERVICE_DEAD_RESOURCES_PINNED] = "dead-resources-pinned", - [SERVICE_AUTO_RESTART] = "auto-restart", - [SERVICE_CLEANING] = "cleaning", - }; -diff --git a/src/basic/unit-def.h b/src/basic/unit-def.h -index 08651ef..c9e41bd 100644 ---- a/src/basic/unit-def.h -+++ b/src/basic/unit-def.h -@@ -141,6 +141,7 @@ typedef enum ServiceState { - SERVICE_FINAL_SIGTERM, /* In case the STOP_POST executable hangs, we shoot that down, too */ - SERVICE_FINAL_SIGKILL, - SERVICE_FAILED, -+ SERVICE_DEAD_RESOURCES_PINNED, /* Like SERVICE_DEAD, but with pinned resources */ - SERVICE_AUTO_RESTART, - SERVICE_CLEANING, - _SERVICE_STATE_MAX, -diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c -index d8931c1..97277ca 100644 ---- a/src/core/dbus-execute.c -+++ b/src/core/dbus-execute.c -@@ -46,7 +46,7 @@ - BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_output, exec_output, ExecOutput); - static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_input, exec_input, ExecInput); - static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_utmp_mode, exec_utmp_mode, ExecUtmpMode); --static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_preserve_mode, exec_preserve_mode, ExecPreserveMode); -+BUS_DEFINE_PROPERTY_GET_ENUM(bus_property_get_exec_preserve_mode, exec_preserve_mode, ExecPreserveMode); - static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exec_keyring_mode, exec_keyring_mode, ExecKeyringMode); - static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_protect_proc, protect_proc, ProtectProc); - static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_proc_subset, proc_subset, ProcSubset); -@@ -1181,7 +1181,7 @@ const sd_bus_vtable bus_exec_vtable[] = { - SD_BUS_PROPERTY("Personality", "s", property_get_personality, offsetof(ExecContext, personality), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("LockPersonality", "b", bus_property_get_bool, offsetof(ExecContext, lock_personality), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("RestrictAddressFamilies", "(bas)", property_get_address_families, 0, SD_BUS_VTABLE_PROPERTY_CONST), -- SD_BUS_PROPERTY("RuntimeDirectoryPreserve", "s", property_get_exec_preserve_mode, offsetof(ExecContext, runtime_directory_preserve_mode), SD_BUS_VTABLE_PROPERTY_CONST), -+ SD_BUS_PROPERTY("RuntimeDirectoryPreserve", "s", bus_property_get_exec_preserve_mode, offsetof(ExecContext, runtime_directory_preserve_mode), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("RuntimeDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME].mode), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("RuntimeDirectory", "as", NULL, offsetof(ExecContext, directories[EXEC_DIRECTORY_RUNTIME].paths), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("StateDirectoryMode", "u", bus_property_get_mode, offsetof(ExecContext, directories[EXEC_DIRECTORY_STATE].mode), SD_BUS_VTABLE_PROPERTY_CONST), -@@ -1551,7 +1551,7 @@ static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_home, ProtectHome, protect_home_fr - static BUS_DEFINE_SET_TRANSIENT_PARSE(keyring_mode, ExecKeyringMode, exec_keyring_mode_from_string); - static BUS_DEFINE_SET_TRANSIENT_PARSE(protect_proc, ProtectProc, protect_proc_from_string); - static BUS_DEFINE_SET_TRANSIENT_PARSE(proc_subset, ProcSubset, proc_subset_from_string); --static BUS_DEFINE_SET_TRANSIENT_PARSE(preserve_mode, ExecPreserveMode, exec_preserve_mode_from_string); -+BUS_DEFINE_SET_TRANSIENT_PARSE(exec_preserve_mode, ExecPreserveMode, exec_preserve_mode_from_string); - static BUS_DEFINE_SET_TRANSIENT_PARSE_PTR(personality, unsigned long, parse_personality); - static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(secure_bits, "i", int32_t, int, "%" PRIi32, secure_bits_to_string_alloc_with_check); - static BUS_DEFINE_SET_TRANSIENT_TO_STRING_ALLOC(capability, "t", uint64_t, uint64_t, "%" PRIu64, capability_set_to_string_alloc); -@@ -1842,7 +1842,7 @@ int bus_exec_context_set_transient_property( - return bus_set_transient_proc_subset(u, name, &c->proc_subset, message, flags, error); - - if (streq(name, "RuntimeDirectoryPreserve")) -- return bus_set_transient_preserve_mode(u, name, &c->runtime_directory_preserve_mode, message, flags, error); -+ return bus_set_transient_exec_preserve_mode(u, name, &c->runtime_directory_preserve_mode, message, flags, error); - - if (streq(name, "UMask")) - return bus_set_transient_mode_t(u, name, &c->umask, message, flags, error); -diff --git a/src/core/dbus-execute.h b/src/core/dbus-execute.h -index c538341..5926bdb 100644 ---- a/src/core/dbus-execute.h -+++ b/src/core/dbus-execute.h -@@ -28,6 +28,8 @@ int bus_property_get_exec_output(sd_bus *bus, const char *path, const char *inte - int bus_property_get_exec_command(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error); - int bus_property_get_exec_command_list(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error); - int bus_property_get_exec_ex_command_list(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error); -+int bus_property_get_exec_preserve_mode(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error); - - int bus_exec_context_set_transient_property(Unit *u, ExecContext *c, const char *name, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); - int bus_set_transient_exec_command(Unit *u, const char *name, ExecCommand **exec_command, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); -+int bus_set_transient_exec_preserve_mode(Unit *u, const char *name, ExecPreserveMode *p, sd_bus_message *message, UnitWriteFlags flags, sd_bus_error *error); -diff --git a/src/core/dbus-service.c b/src/core/dbus-service.c -index c0ec277..4b05968 100644 ---- a/src/core/dbus-service.c -+++ b/src/core/dbus-service.c -@@ -240,6 +240,7 @@ const sd_bus_vtable bus_service_vtable[] = { - SD_BUS_PROPERTY("BusName", "s", NULL, offsetof(Service, bus_name), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("FileDescriptorStoreMax", "u", bus_property_get_unsigned, offsetof(Service, n_fd_store_max), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("NFileDescriptorStore", "u", property_get_size_as_uint32, offsetof(Service, n_fd_store), 0), -+ SD_BUS_PROPERTY("FileDescriptorStorePreserve", "s", bus_property_get_exec_preserve_mode, offsetof(Service, fd_store_preserve_mode), 0), - SD_BUS_PROPERTY("StatusText", "s", NULL, offsetof(Service, status_text), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("StatusErrno", "i", bus_property_get_int, offsetof(Service, status_errno), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), - SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Service, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE), -@@ -477,6 +478,9 @@ static int bus_service_set_transient_property( - if (streq(name, "FileDescriptorStoreMax")) - return bus_set_transient_unsigned(u, name, &s->n_fd_store_max, message, flags, error); - -+ if (streq(name, "FileDescriptorStorePreserve")) -+ return bus_set_transient_exec_preserve_mode(u, name, &s->fd_store_preserve_mode, message, flags, error); -+ - if (streq(name, "NotifyAccess")) - return bus_set_transient_notify_access(u, name, &s->notify_access, message, flags, error); - -diff --git a/src/core/load-fragment-gperf.gperf.in b/src/core/load-fragment-gperf.gperf.in -index 42441ea..49e036f 100644 ---- a/src/core/load-fragment-gperf.gperf.in -+++ b/src/core/load-fragment-gperf.gperf.in -@@ -127,7 +127,7 @@ - {{type}}.MountFlags, config_parse_exec_mount_flags, 0, offsetof({{type}}, exec_context.mount_flags) - {{type}}.MountAPIVFS, config_parse_exec_mount_apivfs, 0, offsetof({{type}}, exec_context) - {{type}}.Personality, config_parse_personality, 0, offsetof({{type}}, exec_context.personality) --{{type}}.RuntimeDirectoryPreserve, config_parse_runtime_preserve_mode, 0, offsetof({{type}}, exec_context.runtime_directory_preserve_mode) -+{{type}}.RuntimeDirectoryPreserve, config_parse_exec_preserve_mode, 0, offsetof({{type}}, exec_context.runtime_directory_preserve_mode) - {{type}}.RuntimeDirectoryMode, config_parse_mode, 0, offsetof({{type}}, exec_context.directories[EXEC_DIRECTORY_RUNTIME].mode) - {{type}}.RuntimeDirectory, config_parse_exec_directories, 0, offsetof({{type}}, exec_context.directories[EXEC_DIRECTORY_RUNTIME].paths) - {{type}}.StateDirectoryMode, config_parse_mode, 0, offsetof({{type}}, exec_context.directories[EXEC_DIRECTORY_STATE].mode) -@@ -395,6 +395,7 @@ Service.SysVStartPriority, config_parse_warn_compat, - Service.NonBlocking, config_parse_bool, 0, offsetof(Service, exec_context.non_blocking) - Service.BusName, config_parse_bus_name, 0, offsetof(Service, bus_name) - Service.FileDescriptorStoreMax, config_parse_unsigned, 0, offsetof(Service, n_fd_store_max) -+Service.FileDescriptorStorePreserve, config_parse_exec_preserve_mode, 0, offsetof(Service, fd_store_preserve_mode) - Service.NotifyAccess, config_parse_notify_access, 0, offsetof(Service, notify_access) - Service.Sockets, config_parse_service_sockets, 0, 0 - Service.BusPolicy, config_parse_warn_compat, DISABLED_LEGACY, 0 -diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c -index f357408..7e5f919 100644 ---- a/src/core/load-fragment.c -+++ b/src/core/load-fragment.c -@@ -133,7 +133,7 @@ DEFINE_CONFIG_PARSE_ENUM(config_parse_job_mode, job_mode, JobMode, "Failed to pa - DEFINE_CONFIG_PARSE_ENUM(config_parse_notify_access, notify_access, NotifyAccess, "Failed to parse notify access specifier"); - DEFINE_CONFIG_PARSE_ENUM(config_parse_protect_home, protect_home, ProtectHome, "Failed to parse protect home value"); - DEFINE_CONFIG_PARSE_ENUM(config_parse_protect_system, protect_system, ProtectSystem, "Failed to parse protect system value"); --DEFINE_CONFIG_PARSE_ENUM(config_parse_runtime_preserve_mode, exec_preserve_mode, ExecPreserveMode, "Failed to parse runtime directory preserve mode"); -+DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_preserve_mode, exec_preserve_mode, ExecPreserveMode, "Failed to parse resource preserve mode"); - DEFINE_CONFIG_PARSE_ENUM(config_parse_service_type, service_type, ServiceType, "Failed to parse service type"); - DEFINE_CONFIG_PARSE_ENUM(config_parse_service_restart, service_restart, ServiceRestart, "Failed to parse service restart specifier"); - DEFINE_CONFIG_PARSE_ENUM(config_parse_service_timeout_failure_mode, service_timeout_failure_mode, ServiceTimeoutFailureMode, "Failed to parse timeout failure mode"); -diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h -index 45e9c39..974bb42 100644 ---- a/src/core/load-fragment.h -+++ b/src/core/load-fragment.h -@@ -93,7 +93,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_exec_selinux_context); - CONFIG_PARSER_PROTOTYPE(config_parse_exec_apparmor_profile); - CONFIG_PARSER_PROTOTYPE(config_parse_exec_smack_process_label); - CONFIG_PARSER_PROTOTYPE(config_parse_address_families); --CONFIG_PARSER_PROTOTYPE(config_parse_runtime_preserve_mode); -+CONFIG_PARSER_PROTOTYPE(config_parse_exec_preserve_mode); - CONFIG_PARSER_PROTOTYPE(config_parse_exec_directories); - CONFIG_PARSER_PROTOTYPE(config_parse_set_credential); - CONFIG_PARSER_PROTOTYPE(config_parse_load_credential); -diff --git a/src/core/service.c b/src/core/service.c -index af6360e..9f16790 100644 ---- a/src/core/service.c -+++ b/src/core/service.c -@@ -60,6 +60,7 @@ static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = { - [SERVICE_FINAL_SIGTERM] = UNIT_DEACTIVATING, - [SERVICE_FINAL_SIGKILL] = UNIT_DEACTIVATING, - [SERVICE_FAILED] = UNIT_FAILED, -+ [SERVICE_DEAD_RESOURCES_PINNED] = UNIT_INACTIVE, - [SERVICE_AUTO_RESTART] = UNIT_ACTIVATING, - [SERVICE_CLEANING] = UNIT_MAINTENANCE, - }; -@@ -84,6 +85,7 @@ static const UnitActiveState state_translation_table_idle[_SERVICE_STATE_MAX] = - [SERVICE_FINAL_SIGTERM] = UNIT_DEACTIVATING, - [SERVICE_FINAL_SIGKILL] = UNIT_DEACTIVATING, - [SERVICE_FAILED] = UNIT_FAILED, -+ [SERVICE_DEAD_RESOURCES_PINNED] = UNIT_INACTIVE, - [SERVICE_AUTO_RESTART] = UNIT_ACTIVATING, - [SERVICE_CLEANING] = UNIT_MAINTENANCE, - }; -@@ -121,6 +123,8 @@ static void service_init(Unit *u) { - s->watchdog_original_usec = USEC_INFINITY; - - s->oom_policy = _OOM_POLICY_INVALID; -+ -+ s->fd_store_preserve_mode = EXEC_PRESERVE_RESTART; - } - - static void service_unwatch_control_pid(Service *s) { -@@ -906,8 +910,10 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) { - if (s->n_fd_store_max > 0) - fprintf(f, - "%sFile Descriptor Store Max: %u\n" -+ "%sFile Descriptor Store Pin: %s\n" - "%sFile Descriptor Store Current: %zu\n", - prefix, s->n_fd_store_max, -+ prefix, exec_preserve_mode_to_string(s->fd_store_preserve_mode), - prefix, s->n_fd_store); - - cgroup_context_dump(UNIT(s), f, prefix); -@@ -1101,7 +1107,7 @@ static void service_set_state(Service *s, ServiceState state) { - s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID; - } - -- if (IN_SET(state, SERVICE_DEAD, SERVICE_FAILED, SERVICE_AUTO_RESTART)) { -+ if (IN_SET(state, SERVICE_DEAD, SERVICE_FAILED, SERVICE_AUTO_RESTART, SERVICE_DEAD_RESOURCES_PINNED)) { - unit_unwatch_all_pids(UNIT(s)); - unit_dequeue_rewatch_pids(UNIT(s)); - } -@@ -1202,7 +1208,8 @@ static int service_coldplug(Unit *u) { - return r; - } - -- if (!IN_SET(s->deserialized_state, SERVICE_DEAD, SERVICE_FAILED, SERVICE_AUTO_RESTART, SERVICE_CLEANING)) { -+ if (!IN_SET(s->deserialized_state, SERVICE_DEAD, SERVICE_FAILED, SERVICE_AUTO_RESTART, SERVICE_CLEANING, -+ SERVICE_DEAD_RESOURCES_PINNED)) { - (void) unit_enqueue_rewatch_pids(u); - (void) unit_setup_dynamic_creds(u); - (void) unit_setup_exec_runtime(u); -@@ -1718,6 +1725,12 @@ static bool service_will_restart(Unit *u) { - return unit_will_restart_default(u); - } - -+static ServiceState service_determine_dead_state(Service *s) { -+ assert(s); -+ -+ return s->fd_store && s->fd_store_preserve_mode == EXEC_PRESERVE_YES ? SERVICE_DEAD_RESOURCES_PINNED : SERVICE_DEAD; -+} -+ - static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) { - ServiceState end_state; - int r; -@@ -1734,10 +1747,10 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) - - if (s->result == SERVICE_SUCCESS) { - unit_log_success(UNIT(s)); -- end_state = SERVICE_DEAD; -+ end_state = service_determine_dead_state(s); - } else if (s->result == SERVICE_SKIP_CONDITION) { - unit_log_skip(UNIT(s), service_result_to_string(s->result)); -- end_state = SERVICE_DEAD; -+ end_state = service_determine_dead_state(s); - } else { - unit_log_failure(UNIT(s), service_result_to_string(s->result)); - end_state = SERVICE_FAILED; -@@ -1793,6 +1806,10 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) - /* Also, remove the runtime directory */ - unit_destroy_runtime_data(UNIT(s), &s->exec_context); - -+ /* Also get rid of the fd store, if that's configured. */ -+ if (s->fd_store_preserve_mode == EXEC_PRESERVE_NO) -+ service_release_fd_store(s); -+ - /* Get rid of the IPC bits of the user */ - unit_unref_uid_gid(UNIT(s), true); - -@@ -2449,7 +2466,7 @@ static int service_start(Unit *u) { - if (s->state == SERVICE_AUTO_RESTART) - return -EAGAIN; - -- assert(IN_SET(s->state, SERVICE_DEAD, SERVICE_FAILED)); -+ assert(IN_SET(s->state, SERVICE_DEAD, SERVICE_FAILED, SERVICE_DEAD_RESOURCES_PINNED)); - - r = unit_acquire_invocation_id(u); - if (r < 0) -@@ -2501,7 +2518,7 @@ static int service_stop(Unit *u) { - - /* A restart will be scheduled or is in progress. */ - if (s->state == SERVICE_AUTO_RESTART) { -- service_set_state(s, SERVICE_DEAD); -+ service_set_state(s, service_determine_dead_state(s)); - return 0; - } - -@@ -3312,6 +3332,7 @@ static void service_notify_cgroup_empty_event(Unit *u) { - * up the cgroup earlier and should do it now. */ - case SERVICE_DEAD: - case SERVICE_FAILED: -+ case SERVICE_DEAD_RESOURCES_PINNED: - unit_prune_cgroup(u); - break; - -@@ -4332,7 +4353,7 @@ int service_set_socket_fd( - - assert(!s->socket_peer); - -- if (s->state != SERVICE_DEAD) -+ if (!IN_SET(s->state, SERVICE_DEAD, SERVICE_DEAD_RESOURCES_PINNED)) - return -EAGAIN; - - if (getpeername_pretty(fd, true, &peer_text) >= 0) { -@@ -4369,7 +4390,7 @@ static void service_reset_failed(Unit *u) { - assert(s); - - if (s->state == SERVICE_FAILED) -- service_set_state(s, SERVICE_DEAD); -+ service_set_state(s, service_determine_dead_state(s)); - - s->result = SERVICE_SUCCESS; - s->reload_result = SERVICE_SUCCESS; -@@ -4531,14 +4552,19 @@ static void service_release_resources(Unit *u) { - /* Don't release resources if this is a transitionary failed/dead state - * (i.e. SERVICE_DEAD_BEFORE_AUTO_RESTART/SERVICE_FAILED_BEFORE_AUTO_RESTART), insist on a permanent - * failure state. */ -- if (!IN_SET(s->state, SERVICE_DEAD, SERVICE_FAILED)) -+ if (!IN_SET(s->state, SERVICE_DEAD, SERVICE_FAILED, SERVICE_DEAD_RESOURCES_PINNED)) - return; - - log_unit_debug(u, "Releasing resources..."); - - service_close_socket_fd(s); - service_release_stdio_fd(s); -- service_release_fd_store(s); -+ -+ if (s->fd_store_preserve_mode != EXEC_PRESERVE_YES) -+ service_release_fd_store(s); -+ -+ if (s->state == SERVICE_DEAD_RESOURCES_PINNED && !s->fd_store) -+ service_set_state(s, SERVICE_DEAD); - } - - static const char* const service_restart_table[_SERVICE_RESTART_MAX] = { -diff --git a/src/core/service.h b/src/core/service.h -index 2e803a3..04bdcb2 100644 ---- a/src/core/service.h -+++ b/src/core/service.h -@@ -194,6 +194,7 @@ struct Service { - size_t n_fd_store; - unsigned n_fd_store_max; - unsigned n_keep_fd_store; -+ ExecPreserveMode fd_store_preserve_mode; - - char *usb_function_descriptors; - char *usb_function_strings; -diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c -index d3a5b25..b944cd0 100644 ---- a/src/shared/bus-unit-util.c -+++ b/src/shared/bus-unit-util.c -@@ -1999,7 +1999,8 @@ static int bus_append_service_property(sd_bus_message *m, const char *field, con - "USBFunctionStrings", - "OOMPolicy", - "TimeoutStartFailureMode", -- "TimeoutStopFailureMode")) -+ "TimeoutStopFailureMode", -+ "FileDescriptorStorePreserve")) - return bus_append_string(m, field, eq); - - if (STR_IN_SET(field, "PermissionsStartOnly", -diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service -index de7d2c7..0509c36 100644 ---- a/test/fuzz/fuzz-unit-file/directives.service -+++ b/test/fuzz/fuzz-unit-file/directives.service -@@ -163,6 +163,7 @@ ExecStopPost= - ExtensionImages= - FailureAction= - FileDescriptorStoreMax= -+FileDescriptorStorePreserve= - FinalKillSignal= - Group= - GuessMainPID= --- -2.33.0 - diff --git a/backport-service-allow-freeing-the-fdstore-via-cleaning.patch b/backport-service-allow-freeing-the-fdstore-via-cleaning.patch deleted file mode 100644 index 86dd6be..0000000 --- a/backport-service-allow-freeing-the-fdstore-via-cleaning.patch +++ /dev/null @@ -1,283 +0,0 @@ -From 4fb8f1e88322b94b0fa051d3c6fd19cac0227aaa Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Wed, 29 Mar 2023 22:10:01 +0200 -Subject: [PATCH] service: allow freeing the fdstore via cleaning - -Now that we have a potentially pinned fdstore let's add a concept for -cleaning it explicitly on user requested. Let's expose this via -"systemctl clean", i.e. the same way as user directories are cleaned. - -Conflict:Adaptation context. -Reference:https://github.com/systemd/systemd/commit/4fb8f1e88322b94b0fa051d3c6fd19cac0227aaa - ---- - man/systemctl.xml | 28 +++++++++++------- - src/core/dbus-unit.c | 21 ++++++------- - src/core/execute.c | 17 +++++++++++ - src/core/execute.h | 5 +++- - src/core/service.c | 36 ++++++++++++++++++++--- - src/core/timer.c | 1 + - src/systemctl/systemctl-clean-or-freeze.c | 2 +- - src/systemctl/systemctl.c | 3 +- - 8 files changed, 86 insertions(+), 27 deletions(-) - -diff --git a/man/systemctl.xml b/man/systemctl.xml -index 8402b95..a2cc54c 100644 ---- a/man/systemctl.xml -+++ b/man/systemctl.xml -@@ -484,12 +484,16 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err - StateDirectory=, CacheDirectory=, - LogsDirectory= and RuntimeDirectory=, see - systemd.exec5 -- for details. For timer units this may be used to clear out the persistent timestamp data if -+ for details. It may also be used to clear the file decriptor store as enabled via -+ FileDescriptorStoreMax=, see -+ systemd.service5 -+ for details. For timer units this may be used to clear out the persistent timestamp data if - Persistent= is used and is selected, see - systemd.timer5. This - command only applies to units that use either of these settings. If is -- not specified, both the cache and runtime data are removed (as these two types of data are -- generally redundant and reproducible on the next invocation of the unit). -+ not specified, the cache and runtime data as well as the file descriptor store are removed (as -+ these three types of resources are generally redundant and reproducible on the next invocation of -+ the unit). Note that the specified units must be stopped to invoke this operation. - - - -@@ -2076,13 +2080,17 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err - - - Select what type of per-unit resources to remove when the clean command is -- invoked, see below. Takes one of configuration, state, -- cache, logs, runtime to select the -- type of resource. This option may be specified more than once, in which case all specified resource -- types are removed. Also accepts the special value all as a shortcut for -- specifying all five resource types. If this option is not specified defaults to the combination of -- cache and runtime, i.e. the two kinds of resources that -- are generally considered to be redundant and can be reconstructed on next invocation. -+ invoked, see above. Takes one of configuration, state, -+ cache, logs, runtime, -+ fdstore to select the type of resource. This option may be specified more than -+ once, in which case all specified resource types are removed. Also accepts the special value -+ all as a shortcut for specifying all six resource types. If this option is not -+ specified defaults to the combination of cache, runtime -+ and fdstore, i.e. the three kinds of resources that are generally considered -+ to be redundant and can be reconstructed on next invocation. Note that the explicit removal of the -+ fdstore resource type is only useful if the -+ FileDescriptorStorePreserve= option is enabled, since the file descriptor store -+ is otherwise cleaned automatically when the unit is stopped. - - - -diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c -index 24e4d25..eefb08e 100644 ---- a/src/core/dbus-unit.c -+++ b/src/core/dbus-unit.c -@@ -91,6 +91,12 @@ static int property_get_can_clean( - return r; - } - -+ if (FLAGS_SET(mask, EXEC_CLEAN_FDSTORE)) { -+ r = sd_bus_message_append(reply, "s", "fdstore"); -+ if (r < 0) -+ return r; -+ } -+ - return sd_bus_message_close_container(reply); - } - -@@ -684,6 +690,7 @@ int bus_unit_method_clean(sd_bus_message *message, void *userdata, sd_bus_error - return r; - - for (;;) { -+ ExecCleanMask m; - const char *i; - - r = sd_bus_message_read(message, "s", &i); -@@ -692,17 +699,11 @@ int bus_unit_method_clean(sd_bus_message *message, void *userdata, sd_bus_error - if (r == 0) - break; - -- if (streq(i, "all")) -- mask |= EXEC_CLEAN_ALL; -- else { -- ExecDirectoryType t; -- -- t = exec_resource_type_from_string(i); -- if (t < 0) -- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid resource type: %s", i); -+ m = exec_clean_mask_from_string(i); -+ if (m < 0) -+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid resource type: %s", i); - -- mask |= 1U << t; -- } -+ mask |= m; - } - - r = sd_bus_message_exit_container(message); -diff --git a/src/core/execute.c b/src/core/execute.c -index 9185a6f..e4c9e94 100644 ---- a/src/core/execute.c -+++ b/src/core/execute.c -@@ -6584,6 +6584,23 @@ ExecSetCredential *exec_set_credential_free(ExecSetCredential *sc) { - return mfree(sc); - } - -+ExecCleanMask exec_clean_mask_from_string(const char *s) { -+ ExecDirectoryType t; -+ -+ assert(s); -+ -+ if (streq(s, "all")) -+ return EXEC_CLEAN_ALL; -+ if (streq(s, "fdstore")) -+ return EXEC_CLEAN_FDSTORE; -+ -+ t = exec_resource_type_from_string(s); -+ if (t < 0) -+ return (ExecCleanMask) t; -+ -+ return 1U << t; -+} -+ - DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(exec_set_credential_hash_ops, char, string_hash_func, string_compare_func, ExecSetCredential, exec_set_credential_free); - - static const char* const exec_input_table[_EXEC_INPUT_MAX] = { -diff --git a/src/core/execute.h b/src/core/execute.h -index f1f0ee4..fd83a8c 100644 ---- a/src/core/execute.h -+++ b/src/core/execute.h -@@ -145,8 +145,9 @@ typedef enum ExecCleanMask { - EXEC_CLEAN_CACHE = 1U << EXEC_DIRECTORY_CACHE, - EXEC_CLEAN_LOGS = 1U << EXEC_DIRECTORY_LOGS, - EXEC_CLEAN_CONFIGURATION = 1U << EXEC_DIRECTORY_CONFIGURATION, -+ EXEC_CLEAN_FDSTORE = 1U << _EXEC_DIRECTORY_TYPE_MAX, - EXEC_CLEAN_NONE = 0, -- EXEC_CLEAN_ALL = (1U << _EXEC_DIRECTORY_TYPE_MAX) - 1, -+ EXEC_CLEAN_ALL = (1U << (_EXEC_DIRECTORY_TYPE_MAX+1)) - 1, - _EXEC_CLEAN_MASK_INVALID = -EINVAL, - } ExecCleanMask; - -@@ -459,6 +460,8 @@ bool exec_context_get_cpu_affinity_from_numa(const ExecContext *c); - ExecSetCredential *exec_set_credential_free(ExecSetCredential *sc); - DEFINE_TRIVIAL_CLEANUP_FUNC(ExecSetCredential*, exec_set_credential_free); - -+ExecCleanMask exec_clean_mask_from_string(const char *s); -+ - extern const struct hash_ops exec_set_credential_hash_ops; - - const char* exec_output_to_string(ExecOutput i) _const_; -diff --git a/src/core/service.c b/src/core/service.c -index 25aec40..d52ffe7 100644 ---- a/src/core/service.c -+++ b/src/core/service.c -@@ -4500,22 +4500,39 @@ static int service_exit_status(Unit *u) { - - static int service_clean(Unit *u, ExecCleanMask mask) { - _cleanup_strv_free_ char **l = NULL; -+ bool may_clean_fdstore = false; - Service *s = SERVICE(u); - int r; - - assert(s); - assert(mask != 0); - -- if (s->state != SERVICE_DEAD) -+ if (!IN_SET(s->state, SERVICE_DEAD, SERVICE_DEAD_RESOURCES_PINNED)) - return -EBUSY; - -+ /* Determine if there's anything we could potentially clean */ - r = exec_context_get_clean_directories(&s->exec_context, u->manager->prefix, mask, &l); - if (r < 0) - return r; - -- if (strv_isempty(l)) -- return -EUNATCH; -+ if (mask & EXEC_CLEAN_FDSTORE) -+ may_clean_fdstore = s->n_fd_store > 0 || s->n_fd_store_max > 0; -+ -+ if (strv_isempty(l) && !may_clean_fdstore) -+ return -EUNATCH; /* Nothing to potentially clean */ -+ -+ /* Let's clean the stuff we can clean quickly */ -+ if (may_clean_fdstore) -+ service_release_fd_store(s); -+ -+ /* If we are done, leave quickly */ -+ if (strv_isempty(l)) { -+ if (s->state == SERVICE_DEAD_RESOURCES_PINNED && !s->fd_store) -+ service_set_state(s, SERVICE_DEAD); -+ return 0; -+ } - -+ /* We need to clean disk stuff. This is slow, hence do it out of process, and change state */ - service_unwatch_control_pid(s); - s->clean_result = SERVICE_SUCCESS; - s->control_command = NULL; -@@ -4542,10 +4559,21 @@ fail: - - static int service_can_clean(Unit *u, ExecCleanMask *ret) { - Service *s = SERVICE(u); -+ ExecCleanMask mask = 0; -+ int r; - - assert(s); -+ assert(ret); -+ -+ r = exec_context_get_clean_mask(&s->exec_context, &mask); -+ if (r < 0) -+ return r; - -- return exec_context_get_clean_mask(&s->exec_context, ret); -+ if (s->n_fd_store_max > 0) -+ mask |= EXEC_CLEAN_FDSTORE; -+ -+ *ret = mask; -+ return 0; - } - - static const char *service_finished_job(Unit *u, JobType t, JobResult result) { -diff --git a/src/core/timer.c b/src/core/timer.c -index 77c8ce4..b038004 100644 ---- a/src/core/timer.c -+++ b/src/core/timer.c -@@ -891,6 +891,7 @@ static int timer_can_clean(Unit *u, ExecCleanMask *ret) { - Timer *t = TIMER(u); - - assert(t); -+ assert(ret); - - *ret = t->persistent ? EXEC_CLEAN_STATE : 0; - return 0; -diff --git a/src/systemctl/systemctl-clean-or-freeze.c b/src/systemctl/systemctl-clean-or-freeze.c -index eca3a6d..0fe9441 100644 ---- a/src/systemctl/systemctl-clean-or-freeze.c -+++ b/src/systemctl/systemctl-clean-or-freeze.c -@@ -22,7 +22,7 @@ int clean_or_freeze_unit(int argc, char *argv[], void *userdata) { - polkit_agent_open_maybe(); - - if (!arg_clean_what) { -- arg_clean_what = strv_new("cache", "runtime"); -+ arg_clean_what = strv_new("cache", "runtime", "fdstore"); - if (!arg_clean_what) - return log_oom(); - } -diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c -index 2f6f581..887bb47 100644 ---- a/src/systemctl/systemctl.c -+++ b/src/systemctl/systemctl.c -@@ -870,7 +870,8 @@ static int systemctl_parse_argv(int argc, char *argv[]) { - "state\n" - "cache\n" - "logs\n" -- "configuration"); -+ "configuration\n" -+ "fdstore"); - return 0; - } - --- -2.33.0 - diff --git a/backport-service-close-fdstore-asynchronously.patch b/backport-service-close-fdstore-asynchronously.patch deleted file mode 100644 index 3140062..0000000 --- a/backport-service-close-fdstore-asynchronously.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 99620f457ed0886852ba18c9093b59767299121c Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Tue, 4 Apr 2023 12:17:16 +0200 -Subject: [PATCH] service: close fdstore asynchronously - -The file descriptors we keep in the fdstore might be basically anything, -let's clean it up with our asynchronous closing feature, to not -deadlock on close(). - -(Let's also do the same for stdin/stdout/stderr fds, since they might -point to network services these days.) - -Conflict:fd adaptation, the actual code function does not change. -Reference:https://github.com/systemd/systemd/commit/99620f457ed0886852ba18c9093b59767299121c - ---- - TODO | 2 -- - src/core/service.c | 15 ++++++++------- - 2 files changed, 8 insertions(+), 9 deletions(-) - -diff --git a/TODO b/TODO -index 75f885c..27b85ea 100644 ---- a/TODO -+++ b/TODO -@@ -531,8 +531,6 @@ Features: - * maybe rework get_user_creds() to query the user database if $SHELL is used - for root, but only then. - --* be stricter with fds we receive for the fdstore: close them asynchronously -- - * calenderspec: add support for week numbers and day numbers within a - year. This would allow us to define "bi-weekly" triggers safely. - -diff --git a/src/core/service.c b/src/core/service.c -index d52ffe7..1b18a83 100644 ---- a/src/core/service.c -+++ b/src/core/service.c -@@ -334,7 +334,7 @@ static void service_fd_store_unlink(ServiceFDStore *fs) { - sd_event_source_disable_unref(fs->event_source); - - free(fs->fdname); -- safe_close(fs->fd); -+ asynchronous_close(fs->fd); - free(fs); - } - -@@ -360,9 +360,9 @@ static void service_release_stdio_fd(Service *s) { - - log_unit_debug(UNIT(s), "Releasing stdin/stdout/stderr file descriptors."); - -- s->stdin_fd = safe_close(s->stdin_fd); -- s->stdout_fd = safe_close(s->stdout_fd); -- s->stderr_fd = safe_close(s->stderr_fd); -+ s->stdin_fd = asynchronous_close(s->stdin_fd); -+ s->stdout_fd = asynchronous_close(s->stdout_fd); -+ s->stderr_fd = asynchronous_close(s->stderr_fd); - } - static void service_done(Unit *u) { - Service *s = SERVICE(u); -@@ -448,7 +448,7 @@ static int service_add_fd_store(Service *s, int fd, const char *name, bool do_po - if (r < 0) - return r; - if (r > 0) { -- safe_close(fd); -+ asynchronous_close(fd); - return 0; /* fd already included */ - } - } -@@ -491,7 +491,7 @@ static int service_add_fd_store_set(Service *s, FDSet *fds, const char *name, bo - assert(s); - - while (fdset_size(fds) > 0) { -- _cleanup_close_ int fd = -1; -+ _cleanup_(asynchronous_closep) int fd = -EBADF; - - fd = fdset_steal_first(fds); - if (fd < 0) -@@ -506,7 +506,8 @@ static int service_add_fd_store_set(Service *s, FDSet *fds, const char *name, bo - return log_unit_error_errno(UNIT(s), r, "Failed to add fd to store: %m"); - if (r > 0) - log_unit_debug(UNIT(s), "Added fd %u (%s) to fd store.", fd, strna(name)); -- fd = -1; -+ -+ TAKE_FD(fd); - } - - return 0; --- -2.33.0 - diff --git a/backport-service-drop-redundant-unit_ref_unset-call.patch b/backport-service-drop-redundant-unit_ref_unset-call.patch deleted file mode 100644 index b7e95b9..0000000 --- a/backport-service-drop-redundant-unit_ref_unset-call.patch +++ /dev/null @@ -1,31 +0,0 @@ -From d53bda316be6ba226788b40e101a3bff5aa75a5f Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Wed, 29 Mar 2023 22:04:26 +0200 -Subject: [PATCH] service: drop redundant unit_ref_unset() call - -The immediately preceeding service_close_socket_fd() call does that -internally anyway. No need to do this again right after. - -Conflict:NA -Reference:https://github.com/systemd/systemd/commit/d53bda316be6ba226788b40e101a3bff5aa75a5f - ---- - src/core/service.c | 2 -- - 1 file changed, 2 deletions(-) - -diff --git a/src/core/service.c b/src/core/service.c -index d73feb363e..c4a7be890d 100644 ---- a/src/core/service.c -+++ b/src/core/service.c -@@ -452,8 +452,6 @@ static void service_done(Unit *u) { - - service_close_socket_fd(s); - -- unit_ref_unset(&s->accept_socket); -- - service_stop_watchdog(s); - - s->timer_event_source = sd_event_source_disable_unref(s->timer_event_source); --- -2.33.0 - diff --git a/backport-service-release-resources-from-a-seperate-queue-not-.patch b/backport-service-release-resources-from-a-seperate-queue-not-.patch deleted file mode 100644 index 0fb3a54..0000000 --- a/backport-service-release-resources-from-a-seperate-queue-not-.patch +++ /dev/null @@ -1,286 +0,0 @@ -From 6ac62d61db737b01ad3776a7688d8a4c57b3f7d9 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Wed, 29 Mar 2023 21:52:41 +0200 -Subject: [PATCH] service: release resources from a seperate queue, not - unit_check_gc() - -The per-unit-type release_resources() hook (most prominent use: to -release a service unit's fdstore once a unit is entirely dead and has no -jobs more) was currently invoked as part of unit_check_gc(), whose -primary purpose is to determine if a unit should be GC'ed. This was -always a bit ugly, as release_resources() changes state of the unit, -while unit_check_gc() is otherwise (and was before release_resources() -was added) a "passive" function that just checks for a couple of -conditions. - -unit_check_gc() is called at various places, including when we wonder if -we should add a unit to the gc queue, and then again when we take it out -of the gc queue to dtermine whether to really gc it now. The fact that -these checks have side effects so far wasn't too problematic, as the -state changes (primarily: that services would empty their fdstores) were -relatively limited and scope. - -A later patch in this series is supposed to extend the service state -engine with a separate state distinct from SERVICE_DEAD that is very -much like it but indicates that the service still has active resources -(specifically the fdstore). For cases like that the releasing of the -fdstore would result in state changes (as we'd then return to a classic -SERVICE_DEAD state). And this is where the fact that the -release_resources() is called as side-effect becomes problematic: it -would mean that unit state changes would instantly propagate to state -changes elsewhere, though we usually want this to be done through the -run queue for coalescing and avoidance of recursion. - -Hence, let's clean this up: let's move the release_resources() logic -into a queue of its own, and then enqueue items into it from the general -state change notification handle in unit_notify(). - -Conflict:Adapt to context -Reference:https://github.com/systemd/systemd/commit/6ac62d61db737b01ad3776a7688d8a4c57b3f7d9 - ---- - src/core/manager.c | 23 ++++++++++++++ - src/core/manager.h | 3 ++ - src/core/unit.c | 75 +++++++++++++++++++++++++++++++++++----------- - src/core/unit.h | 7 +++++ - 4 files changed, 91 insertions(+), 17 deletions(-) - -diff --git a/src/core/manager.c b/src/core/manager.c -index 3c83c82..3245acd 100644 ---- a/src/core/manager.c -+++ b/src/core/manager.c -@@ -1108,6 +1108,26 @@ static unsigned manager_dispatch_cleanup_queue(Manager *m) { - return n; - } - -+static unsigned manager_dispatch_release_resources_queue(Manager *m) { -+ unsigned n = 0; -+ Unit *u; -+ -+ assert(m); -+ -+ while ((u = m->release_resources_queue)) { -+ assert(u->in_release_resources_queue); -+ -+ LIST_REMOVE(release_resources_queue, m->release_resources_queue, u); -+ u->in_release_resources_queue = false; -+ -+ n++; -+ -+ unit_release_resources(u); -+ } -+ -+ return n; -+} -+ - enum { - GC_OFFSET_IN_PATH, /* This one is on the path we were traveling */ - GC_OFFSET_UNSURE, /* No clue */ -@@ -2966,6 +2986,9 @@ int manager_loop(Manager *m) { - if (manager_dispatch_stop_when_unneeded_queue(m) > 0) - continue; - -+ if (manager_dispatch_release_resources_queue(m) > 0) -+ continue; -+ - if (manager_dispatch_dbus_queue(m) > 0) - continue; - -diff --git a/src/core/manager.h b/src/core/manager.h -index 226cfc9..f53e5d5 100644 ---- a/src/core/manager.h -+++ b/src/core/manager.h -@@ -193,6 +193,9 @@ struct Manager { - /* Units that have BindsTo= another unit, and might need to be shutdown because the bound unit is not active. */ - LIST_HEAD(Unit, stop_when_bound_queue); - -+ /* Units that have resources open, and where it might be good to check if they can be released now */ -+ LIST_HEAD(Unit, release_resources_queue); -+ - sd_event *event; - - /* This maps PIDs we care about to units that are interested in. We allow multiple units to be interested in -diff --git a/src/core/unit.c b/src/core/unit.c -index d75c8a9..af225e2 100644 ---- a/src/core/unit.c -+++ b/src/core/unit.c -@@ -370,18 +370,39 @@ int unit_set_description(Unit *u, const char *description) { - return 0; - } - -+void unit_release_resources(Unit *u) { -+ UnitActiveState state; -+ -+ assert(u); -+ -+ if (u->job || u->nop_job) -+ return; -+ -+ if (u->perpetual) -+ return; -+ -+ state = unit_active_state(u); -+ if (!IN_SET(state, UNIT_INACTIVE, UNIT_FAILED)) -+ return; -+ -+ if (unit_will_restart(u)) -+ return; -+ -+ if (UNIT_VTABLE(u)->release_resources) -+ UNIT_VTABLE(u)->release_resources(u); -+} -+ - bool unit_may_gc(Unit *u) { - UnitActiveState state; - int r; - - assert(u); - -- /* Checks whether the unit is ready to be unloaded for garbage collection. -- * Returns true when the unit may be collected, and false if there's some -- * reason to keep it loaded. -+ /* Checks whether the unit is ready to be unloaded for garbage collection. Returns true when the -+ * unit may be collected, and false if there's some reason to keep it loaded. - * -- * References from other units are *not* checked here. Instead, this is done -- * in unit_gc_sweep(), but using markers to properly collect dependency loops. -+ * References from other units are *not* checked here. Instead, this is done in unit_gc_sweep(), but -+ * using markers to properly collect dependency loops. - */ - - if (u->job) -@@ -390,20 +411,16 @@ bool unit_may_gc(Unit *u) { - if (u->nop_job) - return false; - -- state = unit_active_state(u); -- -- /* If the unit is inactive and failed and no job is queued for it, then release its runtime resources */ -- if (UNIT_IS_INACTIVE_OR_FAILED(state) && -- UNIT_VTABLE(u)->release_resources) -- UNIT_VTABLE(u)->release_resources(u); -- - if (u->perpetual) - return false; - - if (sd_bus_track_count(u->bus_track) > 0) - return false; - -- /* But we keep the unit object around for longer when it is referenced or configured to not be gc'ed */ -+ state = unit_active_state(u); -+ -+ /* But we keep the unit object around for longer when it is referenced or configured to not be -+ * gc'ed */ - switch (u->collect_mode) { - - case COLLECT_INACTIVE: -@@ -433,10 +450,10 @@ bool unit_may_gc(Unit *u) { - return false; - } - -- if (UNIT_VTABLE(u)->may_gc && !UNIT_VTABLE(u)->may_gc(u)) -- return false; -+ if (!UNIT_VTABLE(u)->may_gc) -+ return true; - -- return true; -+ return UNIT_VTABLE(u)->may_gc(u); - } - - void unit_add_to_load_queue(Unit *u) { -@@ -540,6 +557,25 @@ void unit_submit_to_stop_when_bound_queue(Unit *u) { - u->in_stop_when_bound_queue = true; - } - -+void unit_submit_to_release_resources_queue(Unit *u) { -+ assert(u); -+ -+ if (u->in_release_resources_queue) -+ return; -+ -+ if (u->job || u->nop_job) -+ return; -+ -+ if (u->perpetual) -+ return; -+ -+ if (!UNIT_VTABLE(u)->release_resources) -+ return; -+ -+ LIST_PREPEND(release_resources_queue, u->manager->release_resources_queue, u); -+ u->in_release_resources_queue = true; -+} -+ - static void unit_clear_dependencies(Unit *u) { - assert(u); - -@@ -761,6 +797,9 @@ Unit* unit_free(Unit *u) { - if (u->in_stop_when_bound_queue) - LIST_REMOVE(stop_when_bound_queue, u->manager->stop_when_bound_queue, u); - -+ if (u->in_release_resources_queue) -+ LIST_REMOVE(release_resources_queue, u->manager->release_resources_queue, u); -+ - bpf_firewall_close(u); - - hashmap_free(u->bpf_foreign_by_key); -@@ -2494,7 +2533,6 @@ static bool unit_process_job(Job *j, UnitActiveState ns, UnitNotifyFlags flags) - assert(j); - - if (j->state == JOB_WAITING) -- - /* So we reached a different state for this job. Let's see if we can run it now if it failed previously - * due to EAGAIN. */ - job_add_to_run_queue(j); -@@ -2698,6 +2736,9 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlag - - /* Maybe the unit should be GC'ed now? */ - unit_add_to_gc_queue(u); -+ -+ /* Maybe we can release some resources now? */ -+ unit_submit_to_release_resources_queue(u); - } - - if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) { -diff --git a/src/core/unit.h b/src/core/unit.h -index 6485858..16c65d9 100644 ---- a/src/core/unit.h -+++ b/src/core/unit.h -@@ -241,6 +241,9 @@ typedef struct Unit { - /* Queue of units that have a BindTo= dependency on some other unit, and should possibly be shut down */ - LIST_FIELDS(Unit, stop_when_bound_queue); - -+ /* Queue of units that should be checked if they can release resources now */ -+ LIST_FIELDS(Unit, release_resources_queue); -+ - /* PIDs we keep an eye on. Note that a unit might have many - * more, but these are the ones we care enough about to - * process SIGCHLD for */ -@@ -393,6 +396,7 @@ typedef struct Unit { - bool in_stop_when_unneeded_queue:1; - bool in_start_when_upheld_queue:1; - bool in_stop_when_bound_queue:1; -+ bool in_release_resources_queue:1; - - bool sent_dbus_new_signal:1; - -@@ -744,6 +748,8 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c); - int unit_choose_id(Unit *u, const char *name); - int unit_set_description(Unit *u, const char *description); - -+void unit_release_resources(Unit *u); -+ - bool unit_may_gc(Unit *u); - - static inline bool unit_is_extrinsic(Unit *u) { -@@ -759,6 +765,7 @@ void unit_add_to_target_deps_queue(Unit *u); - void unit_submit_to_stop_when_unneeded_queue(Unit *u); - void unit_submit_to_start_when_upheld_queue(Unit *u); - void unit_submit_to_stop_when_bound_queue(Unit *u); -+void unit_submit_to_release_resources_queue(Unit *u); - - int unit_merge(Unit *u, Unit *other); - int unit_merge_by_name(Unit *u, const char *other); --- -2.33.0 - diff --git a/backport-service-rename-service_close_socket_fd-service_relea.patch b/backport-service-rename-service_close_socket_fd-service_relea.patch deleted file mode 100644 index edcc768..0000000 --- a/backport-service-rename-service_close_socket_fd-service_relea.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 81a1d6d6790ad6ae8ff63147dfab68e6835178c3 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Tue, 4 Apr 2023 15:51:07 +0200 -Subject: [PATCH] =?UTF-8?q?service:=20rename=20service=5Fclose=5Fsocket=5F?= - =?UTF-8?q?fd()=20=E2=86=92=20service=5Frelease=5Fsocket=5Ffd()?= -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Just to match service_release_stdio_fd() and service_release_fd_store() -in the name, since they do similar things. - -This follows the concept that we "release" resources, and this is all -generically wrapped in "service_release_resources()". - -Conflict:Context Adaptation. -Reference:https://github.com/systemd/systemd/commit/81a1d6d6790ad6ae8ff63147dfab68e6835178c3 - ---- - src/core/service.c | 9 ++++----- - src/core/service.h | 2 +- - src/core/socket.c | 2 +- - 3 files changed, 6 insertions(+), 7 deletions(-) - -diff --git a/src/core/service.c b/src/core/service.c -index 9bd82fc..a7d5f3f 100644 ---- a/src/core/service.c -+++ b/src/core/service.c -@@ -188,7 +188,7 @@ static int service_set_main_pid(Service *s, pid_t pid) { - return 0; - } - --void service_close_socket_fd(Service *s) { -+void service_release_socket_fd(Service *s) { - assert(s); - - if (s->socket_fd < 0 && !UNIT_ISSET(s->accept_socket) && !s->socket_peer) -@@ -399,8 +399,6 @@ static void service_done(Unit *u) { - s->usb_function_descriptors = mfree(s->usb_function_descriptors); - s->usb_function_strings = mfree(s->usb_function_strings); - -- service_close_socket_fd(s); -- - service_stop_watchdog(s); - - s->timer_event_source = sd_event_source_disable_unref(s->timer_event_source); -@@ -408,8 +406,9 @@ static void service_done(Unit *u) { - - s->bus_name_pid_lookup_slot = sd_bus_slot_unref(s->bus_name_pid_lookup_slot); - -- service_release_fd_store(s); -+ service_release_socket_fd(s); - service_release_stdio_fd(s); -+ service_release_fd_store(s); - } - - static int on_fd_store_io(sd_event_source *e, int fd, uint32_t revents, void *userdata) { -@@ -4616,7 +4615,7 @@ static void service_release_resources(Unit *u) { - - log_unit_debug(u, "Releasing resources..."); - -- service_close_socket_fd(s); -+ service_release_socket_fd(s); - service_release_stdio_fd(s); - - if (s->fd_store_preserve_mode != EXEC_PRESERVE_YES) -diff --git a/src/core/service.h b/src/core/service.h -index 78a0f97..4a4ab8a 100644 ---- a/src/core/service.h -+++ b/src/core/service.h -@@ -221,7 +221,7 @@ static inline usec_t service_get_watchdog_usec(Service *s) { - extern const UnitVTable service_vtable; - - int service_set_socket_fd(Service *s, int fd, struct Socket *socket, struct SocketPeer *peer, bool selinux_context_net); --void service_close_socket_fd(Service *s); -+void service_release_socket_fd(Service *s); - - const char* service_restart_to_string(ServiceRestart i) _const_; - ServiceRestart service_restart_from_string(const char *s) _pure_; -diff --git a/src/core/socket.c b/src/core/socket.c -index b1c534b..f61c302 100644 ---- a/src/core/socket.c -+++ b/src/core/socket.c -@@ -2426,7 +2426,7 @@ static void socket_enter_running(Socket *s, int cfd_in) { - if (r < 0) { - /* We failed to activate the new service, but it still exists. Let's make sure the - * service closes and forgets the connection fd again, immediately. */ -- service_close_socket_fd(SERVICE(service)); -+ service_release_socket_fd(SERVICE(service)); - goto fail; - } - --- -2.33.0 - diff --git a/backport-service-rework-how-we-release-resources.patch b/backport-service-rework-how-we-release-resources.patch deleted file mode 100644 index cd88cd9..0000000 --- a/backport-service-rework-how-we-release-resources.patch +++ /dev/null @@ -1,137 +0,0 @@ -From c25fac9a17b95271bb6f8d967d33c5a9aa9e4bc9 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Wed, 29 Mar 2023 22:06:39 +0200 -Subject: [PATCH] service: rework how we release resources - -Let's normalize how we release service resources, i.e. the three types -of fds we maintain for each service: - -1. the fdstore -2. the socket fd for per-connection socket activated services -3. stdin/stdout/stderr - -The generic service_release_resources() hook now calls into -service_release_fd_store() + service_close_socket_fd() -service_release_stdio_fd() one after the other, releasing them all for -the generic "release_resources" infra of the unit lifecycle. - -We do no longer close the socket fd from service_set_state(), moving -this exclusively into service_release_resources(), so that all fds are -closed the same way. - -Conflict:Adaptation context. Deleted the features that are not introduced. -Reference:https://github.com/systemd/systemd/commit/c25fac9a17b95271bb6f8d967d33c5a9aa9e4bc9 - ---- - src/core/service.c | 51 ++++++++++++++++++++++++++++++---------------- - 1 file changed, 34 insertions(+), 17 deletions(-) - -diff --git a/src/core/service.c b/src/core/service.c -index 7d823dd..af6360e 100644 ---- a/src/core/service.c -+++ b/src/core/service.c -@@ -183,6 +183,11 @@ static int service_set_main_pid(Service *s, pid_t pid) { - void service_close_socket_fd(Service *s) { - assert(s); - -+ if (s->socket_fd < 0 && !UNIT_ISSET(s->accept_socket) && !s->socket_peer) -+ return; -+ -+ log_unit_debug(UNIT(s), "Closing connection socket."); -+ - /* Undo the effect of service_set_socket_fd(). */ - - s->socket_fd = asynchronous_close(s->socket_fd); -@@ -331,30 +336,29 @@ static void service_release_fd_store(Service *s) { - if (s->n_keep_fd_store > 0) - return; - -+ if (!s->fd_store) -+ return; -+ - log_unit_debug(UNIT(s), "Releasing all stored fds"); -+ - while (s->fd_store) - service_fd_store_unlink(s->fd_store); - - assert(s->n_fd_store == 0); - } - --static void service_release_resources(Unit *u) { -- Service *s = SERVICE(u); -- -+static void service_release_stdio_fd(Service *s) { - assert(s); - -- if (!s->fd_store && s->stdin_fd < 0 && s->stdout_fd < 0 && s->stderr_fd < 0) -+ if (s->stdin_fd < 0 && s->stdout_fd < 0 && s->stdout_fd < 0) - return; - -- log_unit_debug(u, "Releasing resources."); -+ log_unit_debug(UNIT(s), "Releasing stdin/stdout/stderr file descriptors."); - - s->stdin_fd = safe_close(s->stdin_fd); - s->stdout_fd = safe_close(s->stdout_fd); - s->stderr_fd = safe_close(s->stderr_fd); -- -- service_release_fd_store(s); - } -- - static void service_done(Unit *u) { - Service *s = SERVICE(u); - -@@ -399,7 +403,8 @@ static void service_done(Unit *u) { - - s->bus_name_pid_lookup_slot = sd_bus_slot_unref(s->bus_name_pid_lookup_slot); - -- service_release_resources(u); -+ service_release_fd_store(s); -+ service_release_stdio_fd(s); - } - - static int on_fd_store_io(sd_event_source *e, int fd, uint32_t revents, void *userdata) { -@@ -1101,14 +1106,6 @@ static void service_set_state(Service *s, ServiceState state) { - unit_dequeue_rewatch_pids(UNIT(s)); - } - -- if (!IN_SET(state, -- SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, -- SERVICE_RUNNING, SERVICE_RELOAD, -- SERVICE_STOP, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST, -- SERVICE_FINAL_WATCHDOG, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL) && -- !(state == SERVICE_DEAD && UNIT(s)->job)) -- service_close_socket_fd(s); -- - if (state != SERVICE_START) - s->exec_fd_event_source = sd_event_source_disable_unref(s->exec_fd_event_source); - -@@ -4524,6 +4521,26 @@ static int service_can_start(Unit *u) { - return 1; - } - -+static void service_release_resources(Unit *u) { -+ Service *s = SERVICE(u); -+ assert(s); -+ -+ /* Invoked by the unit state engine, whenever it realizes that unit is dead and there's no job -+ * anymore for it, and it hence is a good idea to release resources */ -+ -+ /* Don't release resources if this is a transitionary failed/dead state -+ * (i.e. SERVICE_DEAD_BEFORE_AUTO_RESTART/SERVICE_FAILED_BEFORE_AUTO_RESTART), insist on a permanent -+ * failure state. */ -+ if (!IN_SET(s->state, SERVICE_DEAD, SERVICE_FAILED)) -+ return; -+ -+ log_unit_debug(u, "Releasing resources..."); -+ -+ service_close_socket_fd(s); -+ service_release_stdio_fd(s); -+ service_release_fd_store(s); -+} -+ - static const char* const service_restart_table[_SERVICE_RESTART_MAX] = { - [SERVICE_RESTART_NO] = "no", - [SERVICE_RESTART_ON_SUCCESS] = "on-success", --- -2.33.0 - diff --git a/backport-socket-always-pass-socket-fd-and-SocketPeer-ownershi.patch b/backport-socket-always-pass-socket-fd-and-SocketPeer-ownershi.patch deleted file mode 100644 index 9cd4289..0000000 --- a/backport-socket-always-pass-socket-fd-and-SocketPeer-ownershi.patch +++ /dev/null @@ -1,174 +0,0 @@ -From 3fabebf45e268a0e1e8f9e7688b2428f8ee8a802 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Wed, 24 Nov 2021 23:50:07 +0100 -Subject: [PATCH] socket: always pass socket, fd and SocketPeer ownership to - service together - -Per-connection socket instances we currently maintain three fields -related to the socket: a reference to the Socket unit, the connection fd, -and a reference to the SocketPeer object that counts socket peers. - -Let's synchronize their lifetime, i.e. always set them all three -together or unset them together, so that their reference counters stay -synchronous. - -THis will in particuar ensure that we'll drop the SocketPeer reference -whenever we leave an active state of the service unit, i.e. at the same -time we close the fd for it. - -Fixes: #20685 - -Conflict:NA -Reference:https://github.com/systemd/systemd/commit/3fabebf45e268a0e1e8f9e7688b2428f8ee8a802 - ---- - src/core/service.c | 27 ++++++++++++++++++--------- - src/core/service.h | 9 +++++---- - src/core/socket.c | 4 +--- - 3 files changed, 24 insertions(+), 16 deletions(-) - -diff --git a/src/core/service.c b/src/core/service.c -index 17c19a2c4a..49579f7998 100644 ---- a/src/core/service.c -+++ b/src/core/service.c -@@ -190,6 +190,8 @@ void service_close_socket_fd(Service *s) { - socket_connection_unref(SOCKET(UNIT_DEREF(s->accept_socket))); - unit_ref_unset(&s->accept_socket); - } -+ -+ s->socket_peer = socket_peer_unref(s->socket_peer); - } - - static void service_stop_watchdog(Service *s) { -@@ -388,7 +390,6 @@ static void service_done(Unit *u) { - s->usb_function_strings = mfree(s->usb_function_strings); - - service_close_socket_fd(s); -- s->peer = socket_peer_unref(s->peer); - - unit_ref_unset(&s->accept_socket); - -@@ -1237,8 +1238,8 @@ static int service_coldplug(Unit *u) { - - /* Make a best-effort attempt at bumping the connection count */ - if (socket_acquire_peer(socket, s->socket_fd, &peer) > 0) { -- socket_peer_unref(s->peer); -- s->peer = peer; -+ socket_peer_unref(s->socket_peer); -+ s->socket_peer = peer; - } - } - } -@@ -4285,8 +4286,14 @@ static void service_bus_name_owner_change(Unit *u, const char *new_owner) { - } - } - --int service_set_socket_fd(Service *s, int fd, Socket *sock, bool selinux_context_net) { -- _cleanup_free_ char *peer = NULL; -+int service_set_socket_fd( -+ Service *s, -+ int fd, -+ Socket *sock, -+ SocketPeer *peer, -+ bool selinux_context_net) { -+ -+ _cleanup_free_ char *peer_text = NULL; - int r; - - assert(s); -@@ -4301,22 +4308,23 @@ int service_set_socket_fd(Service *s, int fd, Socket *sock, bool selinux_context - if (s->socket_fd >= 0) - return -EBUSY; - -+ assert(!s->socket_peer); -+ - if (s->state != SERVICE_DEAD) - return -EAGAIN; - -- if (getpeername_pretty(fd, true, &peer) >= 0) { -+ if (getpeername_pretty(fd, true, &peer_text) >= 0) { - - if (UNIT(s)->description) { - _cleanup_free_ char *a = NULL; - -- a = strjoin(UNIT(s)->description, " (", peer, ")"); -+ a = strjoin(UNIT(s)->description, " (", peer_text, ")"); - if (!a) - return -ENOMEM; - - r = unit_set_description(UNIT(s), a); - } else -- r = unit_set_description(UNIT(s), peer); -- -+ r = unit_set_description(UNIT(s), peer_text); - if (r < 0) - return r; - } -@@ -4326,6 +4334,7 @@ int service_set_socket_fd(Service *s, int fd, Socket *sock, bool selinux_context - return r; - - s->socket_fd = fd; -+ s->socket_peer = socket_peer_ref(peer); - s->socket_fd_selinux_context_net = selinux_context_net; - - unit_ref_set(&s->accept_socket, UNIT(s), UNIT(sock)); -diff --git a/src/core/service.h b/src/core/service.h -index 70ce70fba5..778551d844 100644 ---- a/src/core/service.h -+++ b/src/core/service.h -@@ -157,8 +157,11 @@ struct Service { - DynamicCreds dynamic_creds; - - pid_t main_pid, control_pid; -+ -+ /* if we are a socket activated service instance, store information of the connection/peer/socket */ - int socket_fd; -- SocketPeer *peer; -+ SocketPeer *socket_peer; -+ UnitRef accept_socket; - bool socket_fd_selinux_context_net; - - bool permissions_start_only; -@@ -186,8 +189,6 @@ struct Service { - char *status_text; - int status_errno; - -- UnitRef accept_socket; -- - sd_event_source *timer_event_source; - PathSpec *pid_file_pathspec; - -@@ -226,7 +227,7 @@ static inline usec_t service_get_watchdog_usec(Service *s) { - - extern const UnitVTable service_vtable; - --int service_set_socket_fd(Service *s, int fd, struct Socket *socket, bool selinux_context_net); -+int service_set_socket_fd(Service *s, int fd, struct Socket *socket, struct SocketPeer *peer, bool selinux_context_net); - void service_close_socket_fd(Service *s); - - const char* service_restart_to_string(ServiceRestart i) _const_; -diff --git a/src/core/socket.c b/src/core/socket.c -index e6d168188a..d9db1edd3c 100644 ---- a/src/core/socket.c -+++ b/src/core/socket.c -@@ -2409,7 +2409,7 @@ static void socket_enter_running(Socket *s, int cfd_in) { - - s->n_accepted++; - -- r = service_set_socket_fd(SERVICE(service), cfd, s, s->selinux_context_from_net); -+ r = service_set_socket_fd(SERVICE(service), cfd, s, p, s->selinux_context_from_net); - if (ERRNO_IS_DISCONNECT(r)) - return; - if (r < 0) -@@ -2418,8 +2418,6 @@ static void socket_enter_running(Socket *s, int cfd_in) { - TAKE_FD(cfd); /* We passed ownership of the fd to the service now. Forget it here. */ - s->n_connections++; - -- SERVICE(service)->peer = TAKE_PTR(p); /* Pass ownership of the peer reference */ -- - r = manager_add_job(UNIT(s)->manager, JOB_START, service, JOB_REPLACE, NULL, &error, NULL); - if (r < 0) { - /* We failed to activate the new service, but it still exists. Let's make sure the --- -2.33.0 - diff --git a/backport-socket-various-modernizations.patch b/backport-socket-various-modernizations.patch deleted file mode 100644 index 6a0fc42..0000000 --- a/backport-socket-various-modernizations.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 000b61b980abba1a69d7a5e2a2a073930eca5e08 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Wed, 24 Nov 2021 23:53:10 +0100 -Subject: [PATCH] socket: various modernizations - -Conflict:NA -Reference:https://github.com/systemd/systemd/commit/000b61b980abba1a69d7a5e2a2a073930eca5e08 - ---- - src/core/socket.c | 25 +++++++++++++------------ - 1 file changed, 13 insertions(+), 12 deletions(-) - -diff --git a/src/core/socket.c b/src/core/socket.c -index d9db1edd3c..6b5ec9d987 100644 ---- a/src/core/socket.c -+++ b/src/core/socket.c -@@ -463,10 +463,6 @@ static int socket_load(Unit *u) { - assert(u); - assert(u->load_state == UNIT_STUB); - -- r = set_ensure_allocated(&s->peers_by_address, &peer_address_hash_ops); -- if (r < 0) -- return r; -- - r = unit_load_fragment_and_dropin(u, true); - if (r < 0) - return r; -@@ -485,12 +481,13 @@ static int socket_load(Unit *u) { - static SocketPeer *socket_peer_new(void) { - SocketPeer *p; - -- p = new0(SocketPeer, 1); -+ p = new(SocketPeer, 1); - if (!p) - return NULL; - -- p->n_ref = 1; -- -+ *p = (SocketPeer) { -+ .n_ref = 1, -+ }; - return p; - } - -@@ -507,14 +504,15 @@ DEFINE_TRIVIAL_REF_UNREF_FUNC(SocketPeer, socket_peer, socket_peer_free); - - int socket_acquire_peer(Socket *s, int fd, SocketPeer **p) { - _cleanup_(socket_peer_unrefp) SocketPeer *remote = NULL; -- SocketPeer sa = {}, *i; -- socklen_t salen = sizeof(sa.peer); -+ SocketPeer sa = { -+ .peer_salen = sizeof(union sockaddr_union), -+ }, *i; - int r; - - assert(fd >= 0); - assert(s); - -- if (getpeername(fd, &sa.peer.sa, &salen) < 0) -+ if (getpeername(fd, &sa.peer.sa, &sa.peer_salen) < 0) - return log_unit_error_errno(UNIT(s), errno, "getpeername failed: %m"); - - if (!IN_SET(sa.peer.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)) { -@@ -522,6 +520,10 @@ int socket_acquire_peer(Socket *s, int fd, SocketPeer **p) { - return 0; - } - -+ r = set_ensure_allocated(&s->peers_by_address, &peer_address_hash_ops); -+ if (r < 0) -+ return r; -+ - i = set_get(s->peers_by_address, &sa); - if (i) { - *p = socket_peer_ref(i); -@@ -533,7 +535,7 @@ int socket_acquire_peer(Socket *s, int fd, SocketPeer **p) { - return log_oom(); - - remote->peer = sa.peer; -- remote->peer_salen = salen; -+ remote->peer_salen = sa.peer_salen; - - r = set_put(s->peers_by_address, remote); - if (r < 0) -@@ -542,7 +544,6 @@ int socket_acquire_peer(Socket *s, int fd, SocketPeer **p) { - remote->socket = s; - - *p = TAKE_PTR(remote); -- - return 1; - } - --- -2.33.0 - diff --git a/backport-strv-add-strv_copy_n-helper-for-copying-part-of-a-n-.patch b/backport-strv-add-strv_copy_n-helper-for-copying-part-of-a-n-.patch deleted file mode 100644 index 8f7981d..0000000 --- a/backport-strv-add-strv_copy_n-helper-for-copying-part-of-a-n-.patch +++ /dev/null @@ -1,125 +0,0 @@ -From 4ea517a6e07f47117348c68c6fe087bf6d401558 Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Thu, 16 Feb 2023 15:41:55 +0100 -Subject: [PATCH] strv: add strv_copy_n() helper for copying part of a n strv - -Conflict:Context Adaptation. Test case adaptation. -Reference:https://github.com/systemd/systemd/commit/4ea517a6e07f47117348c68c6fe087bf6d401558 - ---- - src/basic/strv.c | 10 ++++++++-- - src/basic/strv.h | 5 ++++- - src/test/test-strv.c | 41 +++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 53 insertions(+), 3 deletions(-) - -diff --git a/src/basic/strv.c b/src/basic/strv.c -index 6a2e44c..d6c50f5 100644 ---- a/src/basic/strv.c -+++ b/src/basic/strv.c -@@ -88,20 +88,26 @@ char** strv_free_erase(char **l) { - return mfree(l); - } - --char** strv_copy(char * const *l) { -+char** strv_copy_n(char * const *l, size_t m) { - _cleanup_strv_free_ char **result = NULL; - char **k, * const *i; - -- result = new(char*, strv_length(l) + 1); -+ result = new(char*, MIN(strv_length(l), m) + 1); - if (!result) - return NULL; - - k = result; - STRV_FOREACH(i, l) { -+ if (m == 0) -+ break; -+ - *k = strdup(*i); - if (!*k) - return NULL; - k++; -+ -+ if (m != SIZE_MAX) -+ m--; - } - - *k = NULL; -diff --git a/src/basic/strv.h b/src/basic/strv.h -index 8674bfd..108ec25 100644 ---- a/src/basic/strv.h -+++ b/src/basic/strv.h -@@ -29,7 +29,10 @@ char** strv_free_erase(char **l); - DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free_erase); - #define _cleanup_strv_free_erase_ _cleanup_(strv_free_erasep) - --char** strv_copy(char * const *l); -+char** strv_copy_n(char * const *l, size_t n); -+static inline char** strv_copy(char * const *l) { -+ return strv_copy_n(l, SIZE_MAX); -+} - size_t strv_length(char * const *l) _pure_; - - int strv_extend_strv(char ***a, char * const *b, bool filter_duplicates); -diff --git a/src/test/test-strv.c b/src/test/test-strv.c -index 1345252..dd119a8 100644 ---- a/src/test/test-strv.c -+++ b/src/test/test-strv.c -@@ -988,6 +988,46 @@ static void test_strv_fnmatch(void) { - assert(pos == 1); - } - -+static void test_strv_copy_n(void) { -+ char **x = STRV_MAKE("a", "b", "c", "d", "e"); -+ _cleanup_strv_free_ char **l = NULL; -+ -+ l = strv_copy_n(x, 0); -+ assert_se(strv_equal(l, NULL)); -+ strv_free(l); -+ -+ l = strv_copy_n(x, 0); -+ assert_se(strv_equal(l, (char**) { NULL })); -+ strv_free(l); -+ -+ l = strv_copy_n(x, 1); -+ assert_se(strv_equal(l, STRV_MAKE("a"))); -+ strv_free(l); -+ -+ l = strv_copy_n(x, 2); -+ assert_se(strv_equal(l, STRV_MAKE("a", "b"))); -+ strv_free(l); -+ -+ l = strv_copy_n(x, 3); -+ assert_se(strv_equal(l, STRV_MAKE("a", "b", "c"))); -+ strv_free(l); -+ -+ l = strv_copy_n(x, 4); -+ assert_se(strv_equal(l, STRV_MAKE("a", "b", "c", "d"))); -+ strv_free(l); -+ -+ l = strv_copy_n(x, 5); -+ assert_se(strv_equal(l, STRV_MAKE("a", "b", "c", "d", "e"))); -+ strv_free(l); -+ -+ l = strv_copy_n(x, 6); -+ assert_se(strv_equal(l, STRV_MAKE("a", "b", "c", "d", "e"))); -+ strv_free(l); -+ -+ l = strv_copy_n(x, SIZE_MAX); -+ assert_se(strv_equal(l, STRV_MAKE("a", "b", "c", "d", "e"))); -+} -+ - int main(int argc, char *argv[]) { - test_str_in_set(); - test_strptr_in_set(); -@@ -1054,6 +1094,7 @@ int main(int argc, char *argv[]) { - - test_foreach_string(); - test_strv_fnmatch(); -+ test_strv_copy_n(); - - return 0; - } --- -2.33.0 - diff --git a/backport-strv-rewrite-strv_copy-with-cleanup-attribute-and-ST.patch b/backport-strv-rewrite-strv_copy-with-cleanup-attribute-and-ST.patch deleted file mode 100644 index 5ad4b58..0000000 --- a/backport-strv-rewrite-strv_copy-with-cleanup-attribute-and-ST.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 9eb814818d0c35f0c9e05cb596508c1536b0e654 Mon Sep 17 00:00:00 2001 -From: Yu Watanabe -Date: Wed, 16 Mar 2022 22:29:32 +0900 -Subject: [PATCH] strv: rewrite strv_copy() with cleanup attribute and - STRV_FOREACH() - -Conflict:NA -Reference:https://github.com/systemd/systemd/commit/9eb814818d0c35f0c9e05cb596508c1536b0e654 - ---- - src/basic/strv.c | 24 ++++++++++++------------ - 1 file changed, 12 insertions(+), 12 deletions(-) - -diff --git a/src/basic/strv.c b/src/basic/strv.c -index cf573a3783..07a6c49b50 100644 ---- a/src/basic/strv.c -+++ b/src/basic/strv.c -@@ -89,23 +89,23 @@ char** strv_free_erase(char **l) { - } - - char** strv_copy(char * const *l) { -- char **r, **k; -+ _cleanup_strv_free_ char **result = NULL; -+ char **k, * const *i; - -- k = r = new(char*, strv_length(l) + 1); -- if (!r) -+ result = new(char*, strv_length(l) + 1); -+ if (!result) - return NULL; - -- if (l) -- for (; *l; k++, l++) { -- *k = strdup(*l); -- if (!*k) { -- strv_free(r); -- return NULL; -- } -- } -+ k = result; -+ STRV_FOREACH(i, l) { -+ *k = strdup(*i); -+ if (!*k) -+ return NULL; -+ k++; -+ } - - *k = NULL; -- return r; -+ return TAKE_PTR(result); - } - - size_t strv_length(char * const *l) { --- -2.33.0 - diff --git a/backport-test-add-tests-for-NOTIFYACCESS-override-through-sd_.patch b/backport-test-add-tests-for-NOTIFYACCESS-override-through-sd_.patch deleted file mode 100644 index ba17612..0000000 --- a/backport-test-add-tests-for-NOTIFYACCESS-override-through-sd_.patch +++ /dev/null @@ -1,160 +0,0 @@ -From b64f5ddacad725d5e4e021691fad52aa2eb32c46 Mon Sep 17 00:00:00 2001 -From: Mike Yuan -Date: Wed, 22 Mar 2023 03:40:52 +0800 -Subject: [PATCH] test: add tests for NOTIFYACCESS override through sd_notify - -Conflict:Adaptation Context. -Reference:https://github.com/systemd/systemd/commit/b64f5ddacad725d5e4e021691fad52aa2eb32c46 - ---- - test/TEST-80-NOTIFYACCESS/Makefile | 1 + - test/TEST-80-NOTIFYACCESS/test.sh | 11 +++++++++ - test/meson.build | 3 +++ - test/testsuite-80.units/notify.service | 4 ++++ - test/testsuite-80.units/test.sh | 26 +++++++++++++++++++++ - test/units/testsuite-80.service | 8 +++++++ - test/units/testsuite-80.sh | 32 ++++++++++++++++++++++++++ - 7 files changed, 85 insertions(+) - create mode 120000 test/TEST-80-NOTIFYACCESS/Makefile - create mode 100755 test/TEST-80-NOTIFYACCESS/test.sh - create mode 100644 test/testsuite-80.units/notify.service - create mode 100755 test/testsuite-80.units/test.sh - create mode 100644 test/units/testsuite-80.service - create mode 100755 test/units/testsuite-80.sh - -diff --git a/test/TEST-80-NOTIFYACCESS/Makefile b/test/TEST-80-NOTIFYACCESS/Makefile -new file mode 120000 -index 0000000..e9f93b1 ---- /dev/null -+++ b/test/TEST-80-NOTIFYACCESS/Makefile -@@ -0,0 +1 @@ -+../TEST-01-BASIC/Makefile -\ No newline at end of file -diff --git a/test/TEST-80-NOTIFYACCESS/test.sh b/test/TEST-80-NOTIFYACCESS/test.sh -new file mode 100755 -index 0000000..b4d2452 ---- /dev/null -+++ b/test/TEST-80-NOTIFYACCESS/test.sh -@@ -0,0 +1,11 @@ -+#!/usr/bin/env bash -+# SPDX-License-Identifier: LGPL-2.1-or-later -+set -e -+ -+TEST_DESCRIPTION="test NotifyAccess through sd-notify" -+TEST_NO_QEMU=1 -+ -+# shellcheck source=test/test-functions -+. "${TEST_BASE_DIR:?}/test-functions" -+ -+do_test "$@" -diff --git a/test/meson.build b/test/meson.build -index 8727e66..8eb9bc4 100644 ---- a/test/meson.build -+++ b/test/meson.build -@@ -51,6 +51,9 @@ if install_tests - install_subdir('testsuite-63.units', - exclude_files : '.gitattributes', - install_dir : testdata_dir) -+ install_subdir('testsuite-80.units', -+ exclude_files : '.gitattributes', -+ install_dir : testdata_dir) - - testsuite08_dir = testdata_dir + '/testsuite-08.units' - install_data('testsuite-08.units/-.mount', -diff --git a/test/testsuite-80.units/notify.service b/test/testsuite-80.units/notify.service -new file mode 100644 -index 0000000..196b076 ---- /dev/null -+++ b/test/testsuite-80.units/notify.service -@@ -0,0 +1,4 @@ -+[Service] -+Type=notify -+NotifyAccess=all -+ExecStart=/usr/lib/systemd/tests/testdata/testsuite-80.units/test.sh -diff --git a/test/testsuite-80.units/test.sh b/test/testsuite-80.units/test.sh -new file mode 100755 -index 0000000..3ca71d5 ---- /dev/null -+++ b/test/testsuite-80.units/test.sh -@@ -0,0 +1,26 @@ -+#!/usr/bin/env bash -+# SPDX-License-Identifier: LGPL-2.1-or-later -+# shellcheck disable=SC2016 -+set -eux -+set -o pipefail -+ -+systemd-notify --status="Test starts, waiting for 5 seconds" -+sleep 5 -+ -+( -+ systemd-notify --pid=auto -+ systemd-notify "NOTIFYACCESS=main" -+ -+ systemd-notify --status="Sending READY=1 in an unpriviledged process" -+ ( -+ sleep 0.1 -+ systemd-notify --ready -+ ) -+ sleep 10 -+ -+ systemd-notify "MAINPID=$$" -+) -+ -+systemd-notify --ready --status="OK" -+systemd-notify "NOTIFYACCESS=none" -+sleep infinity -diff --git a/test/units/testsuite-80.service b/test/units/testsuite-80.service -new file mode 100644 -index 0000000..4c7f5d5 ---- /dev/null -+++ b/test/units/testsuite-80.service -@@ -0,0 +1,8 @@ -+# SPDX-License-Identifier: LGPL-2.1-or-later -+[Unit] -+Description=TEST-80-NOTIFYACCESS -+ -+[Service] -+ExecStartPre=rm -f /failed /testok -+ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh -+Type=oneshot -diff --git a/test/units/testsuite-80.sh b/test/units/testsuite-80.sh -new file mode 100755 -index 0000000..5f57569 ---- /dev/null -+++ b/test/units/testsuite-80.sh -@@ -0,0 +1,32 @@ -+#!/usr/bin/env bash -+# SPDX-License-Identifier: LGPL-2.1-or-later -+# shellcheck disable=SC2016 -+set -eux -+set -o pipefail -+ -+# shellcheck source=test/units/assert.sh -+. "$(dirname "$0")"/assert.sh -+ -+: >/failed -+ -+systemctl --no-block start notify.service -+sleep 2 -+ -+assert_eq "$(systemctl show notify.service -p StatusText --value)" "Test starts, waiting for 5 seconds" -+assert_eq "$(systemctl show notify.service -p NotifyAccess --value)" "all" -+sleep 5 -+ -+assert_eq "$(systemctl show notify.service -p NotifyAccess --value)" "main" -+assert_eq "$(systemctl show notify.service -p StatusText --value)" "Sending READY=1 in an unpriviledged process" -+assert_rc 3 systemctl --quiet is-active notify.service -+sleep 10 -+ -+systemctl --quiet is-active notify.service -+assert_eq "$(systemctl show notify.service -p StatusText --value)" "OK" -+assert_eq "$(systemctl show notify.service -p NotifyAccess --value)" "none" -+ -+systemctl stop notify.service -+assert_eq "$(systemctl show notify.service -p NotifyAccess --value)" "all" -+ -+touch /testok -+rm /failed --- -2.33.0 - diff --git a/backport-test-validate-that-fdstore-pinning-works.patch b/backport-test-validate-that-fdstore-pinning-works.patch deleted file mode 100644 index 17159d8..0000000 --- a/backport-test-validate-that-fdstore-pinning-works.patch +++ /dev/null @@ -1,186 +0,0 @@ -From 3540ce8587cbd21ce9c2dbec72ea7fa3d1b38a5f Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Tue, 4 Apr 2023 11:41:55 +0200 -Subject: [PATCH] test: validate that fdstore pinning works - -Conflict:Adaptation Context. -Reference:https://github.com/systemd/systemd/commit/3540ce8587cbd21ce9c2dbec72ea7fa3d1b38a5f - ---- - test/testsuite-80.units/fdstore-nopin.service | 8 +++ - test/testsuite-80.units/fdstore-pin.service | 8 +++ - test/testsuite-80.units/fdstore-pin.sh | 47 +++++++++++++++++ - test/testsuite-80.units/fdstore-pin.target | 3 ++ - test/units/testsuite-80.service | 2 + - test/units/testsuite-80.sh | 51 +++++++++++++++++++ - 6 files changed, 119 insertions(+) - create mode 100644 test/testsuite-80.units/fdstore-nopin.service - create mode 100644 test/testsuite-80.units/fdstore-pin.service - create mode 100755 test/testsuite-80.units/fdstore-pin.sh - create mode 100644 test/testsuite-80.units/fdstore-pin.target - -diff --git a/test/testsuite-80.units/fdstore-nopin.service b/test/testsuite-80.units/fdstore-nopin.service -new file mode 100644 -index 0000000..58a687a ---- /dev/null -+++ b/test/testsuite-80.units/fdstore-nopin.service -@@ -0,0 +1,8 @@ -+[Service] -+Type=notify -+NotifyAccess=all -+FileDescriptorStoreMax=10 -+FileDescriptorStorePreserve=restart -+ExecStart=/usr/lib/systemd/tests/testdata/testsuite-80.units/fdstore-pin.sh 0 -+StandardOutput=journal+console -+StandardError=journal+console -diff --git a/test/testsuite-80.units/fdstore-pin.service b/test/testsuite-80.units/fdstore-pin.service -new file mode 100644 -index 0000000..bc78ee0 ---- /dev/null -+++ b/test/testsuite-80.units/fdstore-pin.service -@@ -0,0 +1,8 @@ -+[Service] -+Type=notify -+NotifyAccess=all -+FileDescriptorStoreMax=10 -+FileDescriptorStorePreserve=yes -+ExecStart=/usr/lib/systemd/tests/testdata/testsuite-80.units/fdstore-pin.sh 1 -+StandardOutput=journal+console -+StandardError=journal+console -diff --git a/test/testsuite-80.units/fdstore-pin.sh b/test/testsuite-80.units/fdstore-pin.sh -new file mode 100755 -index 0000000..4cb041a ---- /dev/null -+++ b/test/testsuite-80.units/fdstore-pin.sh -@@ -0,0 +1,47 @@ -+#!/usr/bin/env bash -+# SPDX-License-Identifier: LGPL-2.1-or-later -+set -eux -+set -o pipefail -+ -+PINNED="$1" -+COUNTER="/tmp/fdstore-invoked.$PINNED" -+FILE="/tmp/fdstore-data.$PINNED" -+ -+# This script is called six times: thrice from a service unit where the fdstore -+# is pinned, and thrice where it isn't. The second iteration of each series is -+# a restart, the third a stop followed by a start -+ -+if [ -e "$COUNTER" ] ; then -+ read -r N < "$COUNTER" -+else -+ N=0 -+fi -+ -+echo "Invocation #$N with PINNED=$PINNED." -+ -+if [ "$N" -eq 0 ] ; then -+ # First iteration -+ test "${LISTEN_FDS:-0}" -eq 0 -+ test ! -e "$FILE" -+ echo waldi > "$FILE" -+ systemd-notify --fd=3 --fdname="fd-$N-$PINNED" 3< "$FILE" -+elif [ "$N" -eq 1 ] || { [ "$N" -eq 2 ] && [ "$PINNED" -eq 1 ]; } ; then -+ # Second iteration, or iteration with pinning on -+ test "${LISTEN_FDS:-0}" -eq 1 -+ # We reopen fd #3 here, so that the read offset is at zero each time (hence no <&3 here…) -+ read -r word < /proc/self/fd/3 -+ test "$word" = "waldi" -+else -+ test "${LISTEN_FDS:-0}" -eq 0 -+ test -e "$FILE" -+fi -+ -+if [ "$N" -ge 2 ] ; then -+ rm "$COUNTER" "$FILE" -+else -+ echo $((N + 1)) > "$COUNTER" -+fi -+ -+systemd-notify --ready --status="Ready" -+ -+exec sleep infinity -diff --git a/test/testsuite-80.units/fdstore-pin.target b/test/testsuite-80.units/fdstore-pin.target -new file mode 100644 -index 0000000..319b7e1 ---- /dev/null -+++ b/test/testsuite-80.units/fdstore-pin.target -@@ -0,0 +1,3 @@ -+[Unit] -+After=fdstore-pin.service fdstore-nopin.service -+Wants=fdstore-pin.service fdstore-nopin.service -diff --git a/test/units/testsuite-80.service b/test/units/testsuite-80.service -index 4c7f5d5..82b08a1 100644 ---- a/test/units/testsuite-80.service -+++ b/test/units/testsuite-80.service -@@ -6,3 +6,5 @@ Description=TEST-80-NOTIFYACCESS - ExecStartPre=rm -f /failed /testok - ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh - Type=oneshot -+StandardOutput=journal+console -+StandardError=journal+console -diff --git a/test/units/testsuite-80.sh b/test/units/testsuite-80.sh -index 43647a7..9a979b9 100755 ---- a/test/units/testsuite-80.sh -+++ b/test/units/testsuite-80.sh -@@ -48,5 +48,56 @@ assert_eq "$(systemctl show notify.service -p NotifyAccess --value)" "all" - - rm /tmp/syncfifo1 /tmp/syncfifo2 - -+# Now test basic fdstore behaviour -+ -+systemd-analyze log-level debug -+ -+# Test fdstore pinning (this will pull in fdstore-pin.service fdstore-nopin.service) -+systemctl start fdstore-pin.target -+ -+assert_eq "$(systemctl show fdstore-pin.service -P FileDescriptorStorePreserve)" yes -+assert_eq "$(systemctl show fdstore-nopin.service -P FileDescriptorStorePreserve)" restart -+assert_eq "$(systemctl show fdstore-pin.service -P SubState)" running -+assert_eq "$(systemctl show fdstore-nopin.service -P SubState)" running -+assert_eq "$(systemctl show fdstore-pin.service -P NFileDescriptorStore)" 1 -+assert_eq "$(systemctl show fdstore-nopin.service -P NFileDescriptorStore)" 1 -+ -+# The file descriptor store should survive service restarts -+systemctl restart fdstore-pin.service fdstore-nopin.service -+ -+assert_eq "$(systemctl show fdstore-pin.service -P NFileDescriptorStore)" 1 -+assert_eq "$(systemctl show fdstore-nopin.service -P NFileDescriptorStore)" 1 -+assert_eq "$(systemctl show fdstore-pin.service -P SubState)" running -+assert_eq "$(systemctl show fdstore-nopin.service -P SubState)" running -+ -+# It should not survive the service stop plus a later start (unless pinned) -+systemctl stop fdstore-pin.service fdstore-nopin.service -+ -+assert_eq "$(systemctl show fdstore-pin.service -P NFileDescriptorStore)" 1 -+assert_eq "$(systemctl show fdstore-nopin.service -P NFileDescriptorStore)" 0 -+assert_eq "$(systemctl show fdstore-pin.service -P SubState)" dead-resources-pinned -+assert_eq "$(systemctl show fdstore-nopin.service -P SubState)" dead -+ -+systemctl start fdstore-pin.service fdstore-nopin.service -+ -+assert_eq "$(systemctl show fdstore-pin.service -P NFileDescriptorStore)" 1 -+assert_eq "$(systemctl show fdstore-nopin.service -P NFileDescriptorStore)" 0 -+assert_eq "$(systemctl show fdstore-pin.service -P SubState)" running -+assert_eq "$(systemctl show fdstore-nopin.service -P SubState)" running -+ -+systemctl stop fdstore-pin.service fdstore-nopin.service -+ -+assert_eq "$(systemctl show fdstore-pin.service -P NFileDescriptorStore)" 1 -+assert_eq "$(systemctl show fdstore-nopin.service -P NFileDescriptorStore)" 0 -+assert_eq "$(systemctl show fdstore-pin.service -P SubState)" dead-resources-pinned -+assert_eq "$(systemctl show fdstore-nopin.service -P SubState)" dead -+ -+systemctl clean fdstore-pin.service --what=fdstore -+ -+assert_eq "$(systemctl show fdstore-pin.service -P NFileDescriptorStore)" 0 -+assert_eq "$(systemctl show fdstore-nopin.service -P NFileDescriptorStore)" 0 -+assert_eq "$(systemctl show fdstore-pin.service -P SubState)" dead -+assert_eq "$(systemctl show fdstore-nopin.service -P SubState)" dead -+ - touch /testok - rm /failed - --- -2.33.0 - diff --git a/backport-unit-don-t-gc-unit-in-oom-queue.patch b/backport-unit-don-t-gc-unit-in-oom-queue.patch deleted file mode 100644 index a11d30d..0000000 --- a/backport-unit-don-t-gc-unit-in-oom-queue.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 935f80428fd3220c83163cc4b5a637873e68babb Mon Sep 17 00:00:00 2001 -From: Lennart Poettering -Date: Thu, 8 Jun 2023 11:11:28 +0200 -Subject: [PATCH] unit: don't gc unit in oom queue - -This is a follow-up for 8db998981a4fefd0122bcf5f965726b63c9045c2, and -follows a similar logic: a pending OOM event really trumps everything: -we should not GC a unit while it is pending. - -Conflict:NA -Reference:https://github.com/systemd/systemd/commit/935f80428fd3220c83163cc4b5a637873e68babb - ---- - src/core/cgroup.c | 2 ++ - src/core/unit.c | 5 ++++- - 2 files changed, 6 insertions(+), 1 deletion(-) - -diff --git a/src/core/cgroup.c b/src/core/cgroup.c -index 839b1676c8..34643b242c 100644 ---- a/src/core/cgroup.c -+++ b/src/core/cgroup.c -@@ -3319,6 +3319,8 @@ static int on_cgroup_oom_event(sd_event_source *s, void *userdata) { - } - - (void) unit_check_oom(u); -+ unit_add_to_gc_queue(u); -+ - return 0; - } - -diff --git a/src/core/unit.c b/src/core/unit.c -index 7b6d50e0ea..80f398c309 100644 ---- a/src/core/unit.c -+++ b/src/core/unit.c -@@ -441,7 +441,10 @@ bool unit_may_gc(Unit *u) { - if (u->perpetual) - return false; - -- if (u->in_cgroup_empty_queue) -+ /* if we saw a cgroup empty event for this unit, stay around until we processed it so that we remove -+ * the empty cgroup if possible. Similar, process any pending OOM events if they are already queued -+ * before we release the unit. */ -+ if (u->in_cgroup_empty_queue || u->in_cgroup_oom_queue) - return false; - - if (sd_bus_track_count(u->bus_track) > 0) --- -2.33.0 - diff --git a/systemd.spec b/systemd.spec index 98c5196..022b437 100644 --- a/systemd.spec +++ b/systemd.spec @@ -21,7 +21,7 @@ Name: systemd Url: https://systemd.io/ Version: 249 -Release: 78 +Release: 79 License: MIT and LGPLv2+ and GPLv2+ Summary: System and Service Manager @@ -642,35 +642,6 @@ Patch6593: backport-CVE-2023-50387.patch Patch6594: backport-CVE-2023-50868.patch Patch6595: backport-login-user-runtime-dir-properly-check-for-mount-poin.patch Patch6596: backport-user-util-validate-the-right-field.patch -Patch6597: backport-core-fix-property-getter-method-for-NFileDescriptorS.patch -Patch6598: backport-Add-implicit-sentinel-to-strv_env_merge.patch -Patch6599: backport-basic-strv-inline-variables-and-modernize-style-a-bi.patch -Patch6600: backport-strv-rewrite-strv_copy-with-cleanup-attribute-and-ST.patch -Patch6601: backport-strv-add-strv_copy_n-helper-for-copying-part-of-a-n-.patch -Patch6602: backport-fd-util-introduce-dir_fd_is_root_or_cwd.patch -Patch6603: backport-notify-add-new-exec-switch-for-chaining-other-comman.patch -Patch6604: backport-fdset-add-new-fdset_consume-helper.patch -Patch6605: backport-notify-add-support-for-sending-fds-with-notification.patch -Patch6606: backport-socket-various-modernizations.patch -Patch6607: backport-socket-always-pass-socket-fd-and-SocketPeer-ownershi.patch -Patch6608: backport-fdset-add-new-helper-to-convert-an-fdset-to-an-array.patch -Patch6609: backport-service-release-resources-from-a-seperate-queue-not-.patch -Patch6610: backport-service-drop-redundant-unit_ref_unset-call.patch -Patch6611: backport-service-rework-how-we-release-resources.patch -Patch6612: backport-service-add-ability-to-pin-fd-store.patch -Patch6613: backport-service-allow-freeing-the-fdstore-via-cleaning.patch -Patch6614: backport-service-close-fdstore-asynchronously.patch -Patch6615: backport-core-move-runtime-directory-removal-into-release_res.patch -Patch6616: backport-service-rename-service_close_socket_fd-service_relea.patch -Patch6617: backport-pid1-add-some-debug-logging-when-stashing-ds-into-th.patch -Patch6618: backport-meson-exclude-.gitattributes-when-using-install_subd.patch -Patch6619: backport-core-support-overriding-NOTIFYACCESS-through-sd-noti.patch -Patch6620: backport-test-add-tests-for-NOTIFYACCESS-override-through-sd_.patch -Patch6621: backport-TEST-80-synchronize-explicitly-instead-of-by-time.patch -Patch6622: backport-test-validate-that-fdstore-pinning-works.patch -Patch6623: backport-core-Don-t-GC-unit-if-it-is-in-cgroup_empty_queue.patch -Patch6624: backport-unit-don-t-gc-unit-in-oom-queue.patch -Patch6625: backport-core-do-not-GC-units-jobs-that-are-in-the-D-Bus-queu.patch Patch9001: update-rtc-with-system-clock-when-shutdown.patch Patch9002: udev-add-actions-while-rename-netif-failed.patch @@ -2157,6 +2128,9 @@ grep -q -E '^KEYMAP="?fi-latin[19]"?' /etc/vconsole.conf 2>/dev/null && %{_libdir}/security/pam_systemd.so %changelog +* Wed Jun 26 2024 zhangyao - 249-79 +- Revert "Add the FileDescriptorStorePreserve= option to the service" + * Mon Jun 17 2024 zhangyao - 249-78 - Add the FileDescriptorStorePreserve= option to the service -- Gitee