From ef967387bca1cb09df536b7bb603615b36418183 Mon Sep 17 00:00:00 2001 From: Jan Macku Date: Tue, 22 Aug 2023 16:01:05 +0200 Subject: [PATCH] systemd-239-78 Resolves: #2156620,#2158167,#2179309,#2211358,#2211416,#2215925,#2223582,#2231846 --- ...ing-error-check-for-session_set_lead.patch | 32 ++ ...sion-leader-if-we-know-for-a-fact-th.patch | 77 +++ ...consistency-checks-when-logind-is-no.patch | 170 ++++++ ...t-remove-dead-code-and-use-_cleanup_.patch | 91 +++ ...estroy-inotify-data-structures-from-.patch | 100 ++++ ...ent-add-sd_event_add_inotify_fd-call.patch | 232 ++++++++ ...ase-for-self-destroy-inotify-handler.patch | 65 +++ ...add-downstream-CONTRIBUTING-document.patch | 86 +++ ...c-use-link-with-prefilled-Jira-issue.patch | 25 + ...nk-downstream-CONTRIBUTING-in-README.patch | 52 ++ ...-ordering-of-special-type.d-drop-ins.patch | 47 ++ ...-to-show-service.d-global-drop-in-do.patch | 57 ++ 0963-test-set-indentation-to-4-spaces.patch | 522 ++++++++++++++++++ ...EST-15-remove-all-created-unit-files.patch | 31 ++ 0965-test-use-quotes-where-necessary.patch | 95 ++++ ...anually-crafted-message-for-missing-.patch | 43 ++ ...-boolean-expression-in-unit_is_prist.patch | 41 ++ ...low-transient-units-to-have-drop-ins.patch | 88 +++ ...lper-functions-to-accept-other-unit-.patch | 135 +++++ ...est-hierarchical-drop-ins-for-slices.patch | 79 +++ ...st-for-transient-units-with-drop-ins.patch | 109 ++++ ...one-more-test-for-drop-in-precedence.patch | 66 +++ ...introduce-naming-scheme-for-RHEL-8.9.patch | 50 ++ ...-remove-libdw-dependency-from-pstore.patch | 27 + ...oduce-tmpfiles.d-systemd-pstore.conf.patch | 113 ++++ ...omplain-if-we-can-t-enable-pstore-in.patch | 25 + ...ble-crash_kexec_post_notifiers-by-de.patch | 66 +++ ...te-yes-is-set-for-a-unit-run-ExecSta.patch | 217 ++++++++ ...e-documentation-up-with-the-markdown.patch | 26 + systemd.spec | 62 ++- 30 files changed, 2828 insertions(+), 1 deletion(-) create mode 100644 0951-login-add-a-missing-error-check-for-session_set_lead.patch create mode 100644 0952-logind-reset-session-leader-if-we-know-for-a-fact-th.patch create mode 100644 0953-test-login-skip-consistency-checks-when-logind-is-no.patch create mode 100644 0954-sd-event-remove-dead-code-and-use-_cleanup_.patch create mode 100644 0955-sd-event-don-t-destroy-inotify-data-structures-from-.patch create mode 100644 0956-sd-event-add-sd_event_add_inotify_fd-call.patch create mode 100644 0957-test-add-test-case-for-self-destroy-inotify-handler.patch create mode 100644 0958-doc-add-downstream-CONTRIBUTING-document.patch create mode 100644 0959-doc-use-link-with-prefilled-Jira-issue.patch create mode 100644 0960-docs-link-downstream-CONTRIBUTING-in-README.patch create mode 100644 0961-unit-drop-in-Fix-ordering-of-special-type.d-drop-ins.patch create mode 100644 0962-Add-failing-test-to-show-service.d-global-drop-in-do.patch create mode 100644 0963-test-set-indentation-to-4-spaces.patch create mode 100644 0964-test-TEST-15-remove-all-created-unit-files.patch create mode 100644 0965-test-use-quotes-where-necessary.patch create mode 100644 0966-tree-wide-drop-manually-crafted-message-for-missing-.patch create mode 100644 0967-manager-reformat-boolean-expression-in-unit_is_prist.patch create mode 100644 0968-manager-allow-transient-units-to-have-drop-ins.patch create mode 100644 0969-TEST-15-allow-helper-functions-to-accept-other-unit-.patch create mode 100644 0970-TEST-15-also-test-hierarchical-drop-ins-for-slices.patch create mode 100644 0971-TEST-15-add-test-for-transient-units-with-drop-ins.patch create mode 100644 0972-TEST-15-add-one-more-test-for-drop-in-precedence.patch create mode 100644 0973-udev-net_id-introduce-naming-scheme-for-RHEL-8.9.patch create mode 100644 0974-meson-remove-libdw-dependency-from-pstore.patch create mode 100644 0975-pstore-introduce-tmpfiles.d-systemd-pstore.conf.patch create mode 100644 0976-tmpfiles-don-t-complain-if-we-can-t-enable-pstore-in.patch create mode 100644 0977-pstore-don-t-enable-crash_kexec_post_notifiers-by-de.patch create mode 100644 0978-core-when-Delegate-yes-is-set-for-a-unit-run-ExecSta.patch create mode 100644 0979-man-link-Delegate-documentation-up-with-the-markdown.patch diff --git a/0951-login-add-a-missing-error-check-for-session_set_lead.patch b/0951-login-add-a-missing-error-check-for-session_set_lead.patch new file mode 100644 index 0000000..3004e81 --- /dev/null +++ b/0951-login-add-a-missing-error-check-for-session_set_lead.patch @@ -0,0 +1,32 @@ +From fd6e63d9c24845c0e9f97d0929d89dbe0c4a4434 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Thu, 14 Feb 2019 10:59:13 +0900 +Subject: [PATCH] login: add a missing error check for session_set_leader() + +session_set_leader() may fail. If it fails, then manager_start_scope() +will trigger assertion. + +This may be related to RHBZ#1663704. + +(cherry picked from commit fe3ab8458b9c0ead4b3e14ac25b342d8c34376fe) + +Related: #2158167 +--- + src/login/logind-dbus.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c +index 81aacb4eed..5edcf4e43f 100644 +--- a/src/login/logind-dbus.c ++++ b/src/login/logind-dbus.c +@@ -784,7 +784,9 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus + goto fail; + + session_set_user(session, user); +- session_set_leader(session, leader); ++ r = session_set_leader(session, leader); ++ if (r < 0) ++ goto fail; + + session->type = t; + session->class = c; diff --git a/0952-logind-reset-session-leader-if-we-know-for-a-fact-th.patch b/0952-logind-reset-session-leader-if-we-know-for-a-fact-th.patch new file mode 100644 index 0000000..fe3fdb9 --- /dev/null +++ b/0952-logind-reset-session-leader-if-we-know-for-a-fact-th.patch @@ -0,0 +1,77 @@ +From ab53c4f5c39ab8d34a3cca652de67fe31dbb776d Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 5 Jul 2023 15:27:38 +0200 +Subject: [PATCH] logind: reset session leader if we know for a fact that it is + gone + +rhel-only + +Related: #2158167 +--- + src/login/logind-dbus.c | 3 +++ + src/login/logind-session.c | 18 ++++++++++++++++++ + src/login/logind-session.h | 1 + + 3 files changed, 22 insertions(+) + +diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c +index 5edcf4e43f..dbac406035 100644 +--- a/src/login/logind-dbus.c ++++ b/src/login/logind-dbus.c +@@ -3169,6 +3169,9 @@ int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *err + session->scope_job = mfree(session->scope_job); + (void) session_jobs_reply(session, unit, result); + ++ /* Scope job is done so leader should be gone as well. */ ++ session_invalidate_leader(session); ++ + session_save(session); + user_save(session->user); + } +diff --git a/src/login/logind-session.c b/src/login/logind-session.c +index fabf680b61..4edc4b9b88 100644 +--- a/src/login/logind-session.c ++++ b/src/login/logind-session.c +@@ -179,6 +179,23 @@ int session_set_leader(Session *s, pid_t pid) { + return 1; + } + ++int session_invalidate_leader(Session *s) { ++ assert(s); ++ ++ if (s->leader <= 0) ++ return 0; ++ ++ if (pid_is_alive(s->leader)) ++ return 0; ++ ++ (void) hashmap_remove_value(s->manager->sessions_by_leader, PID_TO_PTR(s->leader), s); ++ s->leader = 0; ++ ++ (void) session_save(s); ++ ++ return 1; ++} ++ + static void session_save_devices(Session *s, FILE *f) { + SessionDevice *sd; + Iterator i; +@@ -1092,6 +1109,7 @@ static int session_dispatch_fifo(sd_event_source *es, int fd, uint32_t revents, + /* EOF on the FIFO means the session died abnormally. */ + + session_remove_fifo(s); ++ session_invalidate_leader(s); + session_stop(s, false); + + return 1; +diff --git a/src/login/logind-session.h b/src/login/logind-session.h +index 6678441bb9..0557696761 100644 +--- a/src/login/logind-session.h ++++ b/src/login/logind-session.h +@@ -127,6 +127,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Session *, session_free); + + void session_set_user(Session *s, User *u); + int session_set_leader(Session *s, pid_t pid); ++int session_invalidate_leader(Session *s); + bool session_may_gc(Session *s, bool drop_not_started); + void session_add_to_gc_queue(Session *s); + int session_activate(Session *s); diff --git a/0953-test-login-skip-consistency-checks-when-logind-is-no.patch b/0953-test-login-skip-consistency-checks-when-logind-is-no.patch new file mode 100644 index 0000000..b7c0b43 --- /dev/null +++ b/0953-test-login-skip-consistency-checks-when-logind-is-no.patch @@ -0,0 +1,170 @@ +From f80320d15ba6815f0b385e4b8f86f3293fed66ce Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 16 Dec 2020 15:56:44 +0100 +Subject: [PATCH] test-login: skip consistency checks when logind is not active +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There are two ways in swich sd_login_* functions acquire data: +some are derived from the cgroup path, but others use the data serialized +by logind. + +When the tests are executed under Fedora's mock, without systemd-spawn +but instead in a traditional chroot, test-login gets confused: +the "outside" cgroup path is visible, so sd_pid_get_unit() and +sd_pid_get_session() work, but sd_session_is_active() and other functions +that need logind data fail. + +Such a buildroot setup is fairly bad, but it can be encountered in the wild, so +let's just skip the tests in that case. + +/* Information printed is from the live system */ +sd_pid_get_unit(0, …) → "session-237.scope" +sd_pid_get_user_unit(0, …) → "n/a" +sd_pid_get_slice(0, …) → "user-1000.slice" +sd_pid_get_session(0, …) → "237" +sd_pid_get_owner_uid(0, …) → 1000 +sd_pid_get_cgroup(0, …) → "/user.slice/user-1000.slice/session-237.scope" +sd_uid_get_display(1000, …) → "(null)" +sd_uid_get_sessions(1000, …) → [0] "" +sd_uid_get_seats(1000, …) → [0] "" +Assertion 'r >= 0' failed at src/libsystemd/sd-login/test-login.c:104, function test_login(). Aborting. + +(cherry picked from commit ac5644635dba54ce5eb0ff394fc0bc772a984849) + +Resolves: #2223582 +--- + src/libsystemd/sd-login/test-login.c | 98 +++++++++++++++------------- + 1 file changed, 52 insertions(+), 46 deletions(-) + +diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c +index d24a04ccc8..5a64aef868 100644 +--- a/src/libsystemd/sd-login/test-login.c ++++ b/src/libsystemd/sd-login/test-login.c +@@ -115,65 +115,71 @@ static void test_login(void) { + + if (session) { + r = sd_session_is_active(session); +- assert_se(r >= 0); +- log_info("sd_session_is_active(\"%s\") → %s", session, yes_no(r)); ++ if (r == -ENXIO) ++ log_notice("sd_session_is_active() failed with ENXIO, it seems logind is not running."); ++ else { ++ /* All those tests will fail with ENXIO, so let's skip them. */ + +- r = sd_session_is_remote(session); +- assert_se(r >= 0); +- log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r)); ++ assert_se(r >= 0); ++ log_info("sd_session_is_active(\"%s\") → %s", session, yes_no(r)); + +- r = sd_session_get_state(session, &state); +- assert_se(r == 0); +- log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state); ++ r = sd_session_is_remote(session); ++ assert_se(r >= 0); ++ log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r)); + +- assert_se(sd_session_get_uid(session, &u) >= 0); +- log_info("sd_session_get_uid(\"%s\") → "UID_FMT, session, u); +- assert_se(u == u2); ++ r = sd_session_get_state(session, &state); ++ assert_se(r == 0); ++ log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state); + +- assert_se(sd_session_get_type(session, &type) >= 0); +- log_info("sd_session_get_type(\"%s\") → \"%s\"", session, type); ++ assert_se(sd_session_get_uid(session, &u) >= 0); ++ log_info("sd_session_get_uid(\"%s\") → "UID_FMT, session, u); ++ assert_se(u == u2); + +- assert_se(sd_session_get_class(session, &class) >= 0); +- log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class); ++ assert_se(sd_session_get_type(session, &type) >= 0); ++ log_info("sd_session_get_type(\"%s\") → \"%s\"", session, type); + +- r = sd_session_get_display(session, &display); +- assert_se(IN_SET(r, 0, -ENODATA)); +- log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display)); ++ assert_se(sd_session_get_class(session, &class) >= 0); ++ log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class); + +- r = sd_session_get_remote_user(session, &remote_user); +- assert_se(IN_SET(r, 0, -ENODATA)); +- log_info("sd_session_get_remote_user(\"%s\") → \"%s\"", +- session, strna(remote_user)); ++ r = sd_session_get_display(session, &display); ++ assert_se(IN_SET(r, 0, -ENODATA)); ++ log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display)); + +- r = sd_session_get_remote_host(session, &remote_host); +- assert_se(IN_SET(r, 0, -ENODATA)); +- log_info("sd_session_get_remote_host(\"%s\") → \"%s\"", +- session, strna(remote_host)); ++ r = sd_session_get_remote_user(session, &remote_user); ++ assert_se(IN_SET(r, 0, -ENODATA)); ++ log_info("sd_session_get_remote_user(\"%s\") → \"%s\"", ++ session, strna(remote_user)); + +- r = sd_session_get_seat(session, &seat); +- if (r >= 0) { +- assert_se(seat); ++ r = sd_session_get_remote_host(session, &remote_host); ++ assert_se(IN_SET(r, 0, -ENODATA)); ++ log_info("sd_session_get_remote_host(\"%s\") → \"%s\"", ++ session, strna(remote_host)); + +- log_info("sd_session_get_seat(\"%s\") → \"%s\"", session, seat); ++ r = sd_session_get_seat(session, &seat); ++ if (r >= 0) { ++ assert_se(seat); + +- r = sd_seat_can_multi_session(seat); +- assert_se(r >= 0); +- log_info("sd_session_can_multi_seat(\"%s\") → %s", seat, yes_no(r)); ++ log_info("sd_session_get_seat(\"%s\") → \"%s\"", session, seat); + +- r = sd_seat_can_tty(seat); +- assert_se(r >= 0); +- log_info("sd_session_can_tty(\"%s\") → %s", seat, yes_no(r)); ++ r = sd_seat_can_multi_session(seat); ++ assert_se(r >= 0); ++ log_info("sd_session_can_multi_seat(\"%s\") → %s", seat, yes_no(r)); + +- r = sd_seat_can_graphical(seat); +- assert_se(r >= 0); +- log_info("sd_session_can_graphical(\"%s\") → %s", seat, yes_no(r)); +- } else { +- log_info_errno(r, "sd_session_get_seat(\"%s\"): %m", session); +- assert_se(r == -ENODATA); +- } ++ r = sd_seat_can_tty(seat); ++ assert_se(r >= 0); ++ log_info("sd_session_can_tty(\"%s\") → %s", seat, yes_no(r)); + +- assert_se(sd_uid_get_state(u, &state2) == 0); +- log_info("sd_uid_get_state("UID_FMT", …) → %s", u, state2); ++ r = sd_seat_can_graphical(seat); ++ assert_se(r >= 0); ++ log_info("sd_session_can_graphical(\"%s\") → %s", seat, yes_no(r)); ++ } else { ++ log_info_errno(r, "sd_session_get_seat(\"%s\"): %m", session); ++ assert_se(r == -ENODATA); ++ } ++ ++ assert_se(sd_uid_get_state(u, &state2) == 0); ++ log_info("sd_uid_get_state("UID_FMT", …) → %s", u, state2); ++ } + } + + if (seat) { +@@ -214,7 +220,7 @@ static void test_login(void) { + assert_se(sd_get_seats(NULL) == r); + + r = sd_seat_get_active(NULL, &t, NULL); +- assert_se(IN_SET(r, 0, -ENODATA)); ++ assert_se(IN_SET(r, 0, -ENODATA, -ENXIO)); + log_info("sd_seat_get_active(NULL, …) (active session on current seat) → %s / \"%s\"", e(r), strnull(t)); + free(t); + diff --git a/0954-sd-event-remove-dead-code-and-use-_cleanup_.patch b/0954-sd-event-remove-dead-code-and-use-_cleanup_.patch new file mode 100644 index 0000000..aabdbcd --- /dev/null +++ b/0954-sd-event-remove-dead-code-and-use-_cleanup_.patch @@ -0,0 +1,91 @@ +From 7bbad13204b3c0870caa80e738d5d5ca39e956c9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 25 Sep 2018 11:10:12 +0200 +Subject: [PATCH] sd-event: remove dead code and use _cleanup_ + +CID #1393250. + +(cherry picked from commit 8c75fe1765341b538ddded29be6f98e1619f1996) + +Related: #2211358 +--- + src/libsystemd/sd-event/sd-event.c | 30 +++++++++--------------------- + 1 file changed, 9 insertions(+), 21 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 549103bc6f..5e22190366 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -1129,6 +1129,7 @@ static void source_free(sd_event_source *s) { + free(s->description); + free(s); + } ++DEFINE_TRIVIAL_CLEANUP_FUNC(sd_event_source*, source_free); + + static int source_set_pending(sd_event_source *s, bool b) { + int r; +@@ -1993,11 +1994,10 @@ _public_ int sd_event_add_inotify( + sd_event_inotify_handler_t callback, + void *userdata) { + +- bool rm_inotify = false, rm_inode = false; + struct inotify_data *inotify_data = NULL; + struct inode_data *inode_data = NULL; + _cleanup_close_ int fd = -1; +- sd_event_source *s; ++ _cleanup_(source_freep) sd_event_source *s = NULL; + struct stat st; + int r; + +@@ -2035,13 +2035,13 @@ _public_ int sd_event_add_inotify( + /* Allocate an inotify object for this priority, and an inode object within it */ + r = event_make_inotify_data(e, SD_EVENT_PRIORITY_NORMAL, &inotify_data); + if (r < 0) +- goto fail; +- rm_inotify = r > 0; ++ return r; + + r = event_make_inode_data(e, inotify_data, st.st_dev, st.st_ino, &inode_data); +- if (r < 0) +- goto fail; +- rm_inode = r > 0; ++ if (r < 0) { ++ event_free_inotify_data(e, inotify_data); ++ return r; ++ } + + /* Keep the O_PATH fd around until the first iteration of the loop, so that we can still change the priority of + * the event source, until then, for which we need the original inode. */ +@@ -2054,30 +2054,18 @@ _public_ int sd_event_add_inotify( + LIST_PREPEND(inotify.by_inode_data, inode_data->event_sources, s); + s->inotify.inode_data = inode_data; + +- rm_inode = rm_inotify = false; +- + /* Actually realize the watch now */ + r = inode_data_realize_watch(e, inode_data); + if (r < 0) +- goto fail; ++ return r; + + (void) sd_event_source_set_description(s, path); + + if (ret) + *ret = s; ++ TAKE_PTR(s); + + return 0; +- +-fail: +- source_free(s); +- +- if (rm_inode) +- event_free_inode_data(e, inode_data); +- +- if (rm_inotify) +- event_free_inotify_data(e, inotify_data); +- +- return r; + } + + _public_ sd_event_source* sd_event_source_ref(sd_event_source *s) { diff --git a/0955-sd-event-don-t-destroy-inotify-data-structures-from-.patch b/0955-sd-event-don-t-destroy-inotify-data-structures-from-.patch new file mode 100644 index 0000000..6fb60e2 --- /dev/null +++ b/0955-sd-event-don-t-destroy-inotify-data-structures-from-.patch @@ -0,0 +1,100 @@ +From 4436c767d45c6568cbdb7aa73e5efba6d0f31f1f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 9 Nov 2021 00:11:38 +0100 +Subject: [PATCH] sd-event: don't destroy inotify data structures from inotify + event handler + +This fixes a bad memory access when we destroy an inotify source handler +from the handler itself, and thus destroy the associated inotify_data +structures. + +Fixes: #20177 +(cherry picked from commit 53baf2efa420cab6c4b1904c9a0c46a0c4ec80a1) + +Resolves: #2211358 +--- + src/libsystemd/sd-event/sd-event.c | 45 +++++++++++++++++++++++++++--- + 1 file changed, 41 insertions(+), 4 deletions(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 5e22190366..01a97a4801 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -263,6 +263,11 @@ struct inotify_data { + * the events locally if they can't be coalesced). */ + unsigned n_pending; + ++ /* If this counter is non-zero, don't GC the inotify data object even if not used to watch any inode ++ * anymore. This is useful to pin the object for a bit longer, after the last event source needing it ++ * is gone. */ ++ unsigned n_busy; ++ + /* A linked list of all inotify objects with data already read, that still need processing. We keep this list + * to make it efficient to figure out what inotify objects to process data on next. */ + LIST_FIELDS(struct inotify_data, buffered); +@@ -1845,6 +1850,29 @@ static void event_free_inode_data( + free(d); + } + ++static void event_gc_inotify_data( ++ sd_event *e, ++ struct inotify_data *d) { ++ ++ assert(e); ++ ++ /* GCs the inotify data object if we don't need it anymore. That's the case if we don't want to watch ++ * any inode with it anymore, which in turn happens if no event source of this priority is interested ++ * in any inode any longer. That said, we maintain an extra busy counter: if non-zero we'll delay GC ++ * (under the expectation that the GC is called again once the counter is decremented). */ ++ ++ if (!d) ++ return; ++ ++ if (!hashmap_isempty(d->inodes)) ++ return; ++ ++ if (d->n_busy > 0) ++ return; ++ ++ event_free_inotify_data(e, d); ++} ++ + static void event_gc_inode_data( + sd_event *e, + struct inode_data *d) { +@@ -1862,8 +1890,7 @@ static void event_gc_inode_data( + inotify_data = d->inotify_data; + event_free_inode_data(e, d); + +- if (inotify_data && hashmap_isempty(inotify_data->inodes)) +- event_free_inotify_data(e, inotify_data); ++ event_gc_inotify_data(e, inotify_data); + } + + static int event_make_inode_data( +@@ -3447,13 +3474,23 @@ static int source_dispatch(sd_event_source *s) { + sz = offsetof(struct inotify_event, name) + d->buffer.ev.len; + assert(d->buffer_filled >= sz); + ++ /* If the inotify callback destroys the event source then this likely means we don't need to ++ * watch the inode anymore, and thus also won't need the inotify object anymore. But if we'd ++ * free it immediately, then we couldn't drop the event from the inotify event queue without ++ * memory corruption anymore, as below. Hence, let's not free it immediately, but mark it ++ * "busy" with a counter (which will ensure it's not GC'ed away prematurely). Let's then ++ * explicitly GC it after we are done dropping the inotify event from the buffer. */ ++ d->n_busy++; + r = s->inotify.callback(s, &d->buffer.ev, s->userdata); ++ d->n_busy--; + +- /* When no event is pending anymore on this inotify object, then let's drop the event from the +- * buffer. */ ++ /* When no event is pending anymore on this inotify object, then let's drop the event from ++ * the inotify event queue buffer. */ + if (d->n_pending == 0) + event_inotify_data_drop(e, d, sz); + ++ /* Now we don't want to access 'd' anymore, it's OK to GC now. */ ++ event_gc_inotify_data(e, d); + break; + } + diff --git a/0956-sd-event-add-sd_event_add_inotify_fd-call.patch b/0956-sd-event-add-sd_event_add_inotify_fd-call.patch new file mode 100644 index 0000000..726c029 --- /dev/null +++ b/0956-sd-event-add-sd_event_add_inotify_fd-call.patch @@ -0,0 +1,232 @@ +From a78186fbbc05637ef9678b20c630597f2e5d6270 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 9 Nov 2021 00:10:58 +0100 +Subject: [PATCH] sd-event: add sd_event_add_inotify_fd() call + +sd_event_add_inotify_fd() is like sd_event_add_inotify(), but takes an +fd to an inode instead of a path, and is hence a ton nicer. + +(cherry picked from commit e67d738a8771c220a2e1ee81d5499a90589dd15d) + +Related: #2211358 +--- + man/rules/meson.build | 4 +- + man/sd_event_add_inotify.xml | 16 +++++++ + src/libsystemd/libsystemd.sym | 1 + + src/libsystemd/sd-event/sd-event.c | 76 +++++++++++++++++++++++------- + src/systemd/sd-event.h | 1 + + 5 files changed, 81 insertions(+), 17 deletions(-) + +diff --git a/man/rules/meson.build b/man/rules/meson.build +index 05eb0a1604..431a1cf269 100644 +--- a/man/rules/meson.build ++++ b/man/rules/meson.build +@@ -272,7 +272,9 @@ manpages = [ + ''], + ['sd_event_add_inotify', + '3', +- ['sd_event_inotify_handler_t', 'sd_event_source_get_inotify_mask'], ++ ['sd_event_add_inotify_fd', ++ 'sd_event_inotify_handler_t', ++ 'sd_event_source_get_inotify_mask'], + ''], + ['sd_event_add_io', + '3', +diff --git a/man/sd_event_add_inotify.xml b/man/sd_event_add_inotify.xml +index 605863c356..17415bbc17 100644 +--- a/man/sd_event_add_inotify.xml ++++ b/man/sd_event_add_inotify.xml +@@ -18,6 +18,7 @@ + + + sd_event_add_inotify ++ sd_event_add_inotify_fd + sd_event_source_get_inotify_mask + sd_event_inotify_handler_t + +@@ -47,6 +48,16 @@ + void *userdata + + ++ ++ int sd_event_add_inotify_fd ++ sd_event *event ++ sd_event_source **source ++ int fd ++ uint32_t mask ++ sd_event_inotify_handler_t handler ++ void *userdata ++ ++ + + int sd_event_source_get_inotify_mask + sd_event_source *source +@@ -72,6 +83,11 @@ + inotify7 for + further information. + ++ sd_event_add_inotify_fd() is identical to ++ sd_event_add_inotify(), except that it takes a file descriptor to an inode (possibly ++ an O_PATH one, but any other will do too) instead of a path in the file ++ system. ++ + If multiple event sources are installed for the same inode the backing inotify watch descriptor is + automatically shared. The mask parameter may contain any flag defined by the inotify API, with the exception of + IN_MASK_ADD. +diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym +index 449918093c..dc37472b18 100644 +--- a/src/libsystemd/libsystemd.sym ++++ b/src/libsystemd/libsystemd.sym +@@ -593,5 +593,6 @@ global: + + LIBSYSTEMD_250 { + global: ++ sd_event_add_inotify_fd; + sd_event_source_set_ratelimit_expire_callback; + } LIBSYSTEMD_248; +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 01a97a4801..9247087c41 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -2013,25 +2013,25 @@ static int inode_data_realize_watch(sd_event *e, struct inode_data *d) { + return 1; + } + +-_public_ int sd_event_add_inotify( ++static int event_add_inotify_fd_internal( + sd_event *e, + sd_event_source **ret, +- const char *path, ++ int fd, ++ bool donate, + uint32_t mask, + sd_event_inotify_handler_t callback, + void *userdata) { + ++ _cleanup_close_ int donated_fd = donate ? fd : -1; ++ _cleanup_(source_freep) sd_event_source *s = NULL; + struct inotify_data *inotify_data = NULL; + struct inode_data *inode_data = NULL; +- _cleanup_close_ int fd = -1; +- _cleanup_(source_freep) sd_event_source *s = NULL; + struct stat st; + int r; + + assert_return(e, -EINVAL); + assert_return(e = event_resolve(e), -ENOPKG); +- assert_return(path, -EINVAL); +- assert_return(callback, -EINVAL); ++ assert_return(fd >= 0, -EBADF); + assert_return(e->state != SD_EVENT_FINISHED, -ESTALE); + assert_return(!event_pid_changed(e), -ECHILD); + +@@ -2041,12 +2041,6 @@ _public_ int sd_event_add_inotify( + if (mask & IN_MASK_ADD) + return -EINVAL; + +- fd = open(path, O_PATH|O_CLOEXEC| +- (mask & IN_ONLYDIR ? O_DIRECTORY : 0)| +- (mask & IN_DONT_FOLLOW ? O_NOFOLLOW : 0)); +- if (fd < 0) +- return -errno; +- + if (fstat(fd, &st) < 0) + return -errno; + +@@ -2066,14 +2060,24 @@ _public_ int sd_event_add_inotify( + + r = event_make_inode_data(e, inotify_data, st.st_dev, st.st_ino, &inode_data); + if (r < 0) { +- event_free_inotify_data(e, inotify_data); ++ event_gc_inotify_data(e, inotify_data); + return r; + } + + /* Keep the O_PATH fd around until the first iteration of the loop, so that we can still change the priority of + * the event source, until then, for which we need the original inode. */ + if (inode_data->fd < 0) { +- inode_data->fd = TAKE_FD(fd); ++ if (donated_fd >= 0) ++ inode_data->fd = TAKE_FD(donated_fd); ++ else { ++ inode_data->fd = fcntl(fd, F_DUPFD_CLOEXEC, 3); ++ if (inode_data->fd < 0) { ++ r = -errno; ++ event_gc_inode_data(e, inode_data); ++ return r; ++ } ++ } ++ + LIST_PREPEND(to_close, e->inode_data_to_close, inode_data); + } + +@@ -2086,8 +2090,6 @@ _public_ int sd_event_add_inotify( + if (r < 0) + return r; + +- (void) sd_event_source_set_description(s, path); +- + if (ret) + *ret = s; + TAKE_PTR(s); +@@ -2095,6 +2097,48 @@ _public_ int sd_event_add_inotify( + return 0; + } + ++_public_ int sd_event_add_inotify_fd( ++ sd_event *e, ++ sd_event_source **ret, ++ int fd, ++ uint32_t mask, ++ sd_event_inotify_handler_t callback, ++ void *userdata) { ++ ++ return event_add_inotify_fd_internal(e, ret, fd, /* donate= */ false, mask, callback, userdata); ++} ++ ++_public_ int sd_event_add_inotify( ++ sd_event *e, ++ sd_event_source **ret, ++ const char *path, ++ uint32_t mask, ++ sd_event_inotify_handler_t callback, ++ void *userdata) { ++ ++ sd_event_source *s; ++ int fd, r; ++ ++ assert_return(path, -EINVAL); ++ ++ fd = open(path, O_PATH|O_CLOEXEC| ++ (mask & IN_ONLYDIR ? O_DIRECTORY : 0)| ++ (mask & IN_DONT_FOLLOW ? O_NOFOLLOW : 0)); ++ if (fd < 0) ++ return -errno; ++ ++ r = event_add_inotify_fd_internal(e, &s, fd, /* donate= */ true, mask, callback, userdata); ++ if (r < 0) ++ return r; ++ ++ (void) sd_event_source_set_description(s, path); ++ ++ if (ret) ++ *ret = s; ++ ++ return r; ++} ++ + _public_ sd_event_source* sd_event_source_ref(sd_event_source *s) { + + if (!s) +diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h +index 960bea1ac4..48b053c127 100644 +--- a/src/systemd/sd-event.h ++++ b/src/systemd/sd-event.h +@@ -91,6 +91,7 @@ int sd_event_add_time_relative(sd_event *e, sd_event_source **s, clockid_t clock + int sd_event_add_signal(sd_event *e, sd_event_source **s, int sig, sd_event_signal_handler_t callback, void *userdata); + int sd_event_add_child(sd_event *e, sd_event_source **s, pid_t pid, int options, sd_event_child_handler_t callback, void *userdata); + int sd_event_add_inotify(sd_event *e, sd_event_source **s, const char *path, uint32_t mask, sd_event_inotify_handler_t callback, void *userdata); ++int sd_event_add_inotify_fd(sd_event *e, sd_event_source **s, int fd, uint32_t mask, sd_event_inotify_handler_t callback, void *userdata); + int sd_event_add_defer(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata); + int sd_event_add_post(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata); + int sd_event_add_exit(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata); diff --git a/0957-test-add-test-case-for-self-destroy-inotify-handler.patch b/0957-test-add-test-case-for-self-destroy-inotify-handler.patch new file mode 100644 index 0000000..c2e2cb3 --- /dev/null +++ b/0957-test-add-test-case-for-self-destroy-inotify-handler.patch @@ -0,0 +1,65 @@ +From 2fcb71007e5137e1be4a16fb24783ff329313ebf Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 9 Nov 2021 00:15:43 +0100 +Subject: [PATCH] test: add test case for self-destroy inotify handler + +(cherry picked from commit 035daf73fbfa05e5abf049bd9385fc0994ab5672) + +Related: #2211358 +--- + src/libsystemd/sd-event/test-event.c | 36 ++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/src/libsystemd/sd-event/test-event.c b/src/libsystemd/sd-event/test-event.c +index 9135b22839..df3de1bfb0 100644 +--- a/src/libsystemd/sd-event/test-event.c ++++ b/src/libsystemd/sd-event/test-event.c +@@ -588,6 +588,40 @@ static void test_ratelimit(void) { + assert_se(expired == 0); + } + ++static int inotify_self_destroy_handler(sd_event_source *s, const struct inotify_event *ev, void *userdata) { ++ sd_event_source **p = userdata; ++ ++ assert_se(ev); ++ assert_se(p); ++ assert_se(*p == s); ++ ++ assert_se(FLAGS_SET(ev->mask, IN_ATTRIB)); ++ ++ assert_se(sd_event_exit(sd_event_source_get_event(s), 0) >= 0); ++ ++ *p = sd_event_source_unref(*p); /* here's what we actually intend to test: we destroy the event ++ * source from inside the event source handler */ ++ return 1; ++} ++ ++static void test_inotify_self_destroy(void) { ++ _cleanup_(sd_event_source_unrefp) sd_event_source *s = NULL; ++ _cleanup_(sd_event_unrefp) sd_event *e = NULL; ++ char path[] = "/tmp/inotifyXXXXXX"; ++ _cleanup_close_ int fd = -1; ++ ++ /* Tests that destroying an inotify event source from its own handler is safe */ ++ ++ assert_se(sd_event_default(&e) >= 0); ++ ++ fd = mkostemp_safe(path); ++ assert_se(fd >= 0); ++ assert_se(sd_event_add_inotify_fd(e, &s, fd, IN_ATTRIB, inotify_self_destroy_handler, &s) >= 0); ++ fd = safe_close(fd); ++ assert_se(unlink(path) >= 0); /* This will trigger IN_ATTRIB because link count goes to zero */ ++ assert_se(sd_event_loop(e) >= 0); ++} ++ + int main(int argc, char *argv[]) { + + log_set_max_level(LOG_DEBUG); +@@ -602,5 +636,7 @@ int main(int argc, char *argv[]) { + + test_ratelimit(); + ++ test_inotify_self_destroy(); ++ + return 0; + } diff --git a/0958-doc-add-downstream-CONTRIBUTING-document.patch b/0958-doc-add-downstream-CONTRIBUTING-document.patch new file mode 100644 index 0000000..c221180 --- /dev/null +++ b/0958-doc-add-downstream-CONTRIBUTING-document.patch @@ -0,0 +1,86 @@ +From 322ef6cb5fe3c293c6b9a37fe2e58491e9a5100b Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Fri, 4 Aug 2023 13:09:46 +0200 +Subject: [PATCH] doc: add downstream CONTRIBUTING document + +rhel-only + +Related: #2179309 +--- + CONTRIBUTING.md | 67 +++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 67 insertions(+) + create mode 100644 CONTRIBUTING.md + +diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md +new file mode 100644 +index 0000000000..361366d899 +--- /dev/null ++++ b/CONTRIBUTING.md +@@ -0,0 +1,67 @@ ++# Contributing ++ ++Welcome to systemd source-git for CentOS Stream and RHEL. When contributing, please follow the guide below. ++ ++## Workflow ++ ++```mermaid ++flowchart LR ++ A(Issue) --> B{is fixed\nupstream} ++ B -->|YES| C(backport\nupstream patch) ++ B -->|NO| D(upstream\nsubmit issue or PR) ++ D --> E{accepted\nand fixed} ++ E -->|YES| C ++ E -->|NO| F(rhel-only patch) --> G ++ C --> G(submit PR) ++``` ++ ++## Filing issues ++ ++When you find an issue with systemd used in CentOS Stream or RHEL, please file an issue in [Jira ticket system](https://issues.redhat.com/secure/CreateIssue!default.jspa) (set Project to **RHEL** and Component to **systemd**). ++ ++GitHub Issues are not supported tracking system. If your issue is reproducible using the latest upstream version of systemd, please consider creating [upstream issue](https://github.com/systemd/systemd/issues/new/choose). ++ ++## Posting Pull Requests ++ ++Every Pull Request has to comply with the following rules: ++ ++- Each commit has to reference [upstream](https://github.com/systemd/systemd) commit. ++- Each commit has to reference the approved issue/tracker. ++- Pull requests have to pass mandatory CI validation and testing ++- Pull requests have to be approved by at least one systemd downstream maintainer ++ ++### Upstream reference ++ ++When doing a back-port of an upstream commit, always use `cherry-pick -x `. Consider proposing a change upstream first when an upstream commit doesn't exist. ++If the change isn't upstream relevant or accepted by upstream, mark the commit with the `rhel-only` string. ++ ++```md ++doc: Fix TYPO ++ ++rhel-only ++ ++Resolves: RHEL-678 ++``` ++ ++### Issue reference ++ ++Each commit has to reference the relevant approved systemd issue (see: [Filling issues section](#filing-issues)). For referencing issues, we use the following keywords: ++ ++- **Resolves** for commits that directly resolve issues described in a referenced tracker ++- **Related** for commits related to the referenced issue, but they don't fix it. Usually, tests and documentation. ++- **Reverts** for commits that reverts previously merged commit ++ ++When referencing issues, use following structure: `: `. See the example below: ++ ++```md ++doc: Fix TYPO ++ ++(cherry picked from commit c5afbac31bb33e7b1f4d59b253425af991a630a4) ++ ++Resolves: RHEL-678 ++``` ++ ++### Validation and testing ++ ++Each Pull Request has to pass all enabled tests that are automatically run using GitHub Actions, CentOS Stream CI, and others. ++If CI failure is unrelated to the change introduced in Pull Request, the downstream maintainer will set the `ci-waived` label and explain why CI was waived. diff --git a/0959-doc-use-link-with-prefilled-Jira-issue.patch b/0959-doc-use-link-with-prefilled-Jira-issue.patch new file mode 100644 index 0000000..d93e59e --- /dev/null +++ b/0959-doc-use-link-with-prefilled-Jira-issue.patch @@ -0,0 +1,25 @@ +From b50b19af7889a2d44e904fcb327b09130c9c96e7 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Tue, 8 Aug 2023 13:12:03 +0200 +Subject: [PATCH] doc: use link with prefilled Jira issue + +rhel-only + +Related: #2179309 +--- + CONTRIBUTING.md | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md +index 361366d899..1de2b88995 100644 +--- a/CONTRIBUTING.md ++++ b/CONTRIBUTING.md +@@ -17,7 +17,7 @@ flowchart LR + + ## Filing issues + +-When you find an issue with systemd used in CentOS Stream or RHEL, please file an issue in [Jira ticket system](https://issues.redhat.com/secure/CreateIssue!default.jspa) (set Project to **RHEL** and Component to **systemd**). ++When you find an issue with systemd used in CentOS Stream or RHEL, please file an issue in [Jira ticket system](https://issues.redhat.com/secure/CreateIssueDetails!init.jspa?pid=12332745&issuetype=1&components=12380515). + + GitHub Issues are not supported tracking system. If your issue is reproducible using the latest upstream version of systemd, please consider creating [upstream issue](https://github.com/systemd/systemd/issues/new/choose). + diff --git a/0960-docs-link-downstream-CONTRIBUTING-in-README.patch b/0960-docs-link-downstream-CONTRIBUTING-in-README.patch new file mode 100644 index 0000000..0d5de6b --- /dev/null +++ b/0960-docs-link-downstream-CONTRIBUTING-in-README.patch @@ -0,0 +1,52 @@ +From 380f7af4fb00d692132b38999813fd9023e14c81 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Thu, 10 Aug 2023 15:25:22 +0200 +Subject: [PATCH] docs: link downstream CONTRIBUTING in README + +This should increase the visibility of the downstream CONTRIBUTING. + +Also fix some wording and update links. + +rhel-only + +Related: #2179309 +--- + CONTRIBUTING.md | 4 ++-- + README.md | 2 +- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md +index 1de2b88995..bd17067be2 100644 +--- a/CONTRIBUTING.md ++++ b/CONTRIBUTING.md +@@ -17,7 +17,7 @@ flowchart LR + + ## Filing issues + +-When you find an issue with systemd used in CentOS Stream or RHEL, please file an issue in [Jira ticket system](https://issues.redhat.com/secure/CreateIssueDetails!init.jspa?pid=12332745&issuetype=1&components=12380515). ++When you find an issue with systemd used in **CentOS Stream** or **RHEL**, please file an issue in Red Hat [Jira ticket system](https://issues.redhat.com/secure/CreateIssueDetails!init.jspa?pid=12332745&issuetype=1&components=12380515&priority=10300). + + GitHub Issues are not supported tracking system. If your issue is reproducible using the latest upstream version of systemd, please consider creating [upstream issue](https://github.com/systemd/systemd/issues/new/choose). + +@@ -51,7 +51,7 @@ Each commit has to reference the relevant approved systemd issue (see: [Filling + - **Related** for commits related to the referenced issue, but they don't fix it. Usually, tests and documentation. + - **Reverts** for commits that reverts previously merged commit + +-When referencing issues, use following structure: `: `. See the example below: ++When referencing issues, use the following structure: `: `. See the example below: + + ```md + doc: Fix TYPO +diff --git a/README.md b/README.md +index a57566834c..2e02350299 100644 +--- a/README.md ++++ b/README.md +@@ -17,7 +17,7 @@ Consult our [NEWS file](../master/NEWS) for information about what's new in the + + Please see the [HACKING file](../master/doc/HACKING) for information how to hack on systemd and test your modifications. + +-Please see our [Contribution Guidelines](../master/.github/CONTRIBUTING.md) for more information about filing GitHub Issues and posting GitHub Pull Requests. ++Please see our [Contribution Guidelines](CONTRIBUTING.md) for more information about filing GitHub Issues and posting GitHub Pull Requests. + + When preparing patches for systemd, please follow our [Coding Style Guidelines](../master/doc/CODING_STYLE). + diff --git a/0961-unit-drop-in-Fix-ordering-of-special-type.d-drop-ins.patch b/0961-unit-drop-in-Fix-ordering-of-special-type.d-drop-ins.patch new file mode 100644 index 0000000..a346838 --- /dev/null +++ b/0961-unit-drop-in-Fix-ordering-of-special-type.d-drop-ins.patch @@ -0,0 +1,47 @@ +From e257d900b45df7db779fd34f01b251d4054f3685 Mon Sep 17 00:00:00 2001 +From: "Greg \"GothAck\" Miell" +Date: Fri, 27 Dec 2019 14:49:51 +0000 +Subject: [PATCH] unit drop-in: Fix ordering of special type.d drop-ins + +(cherry picked from commit e6627f2392cde12e21c40a7cfa96578c648c1f33) + +Related: #2156620 +--- + src/shared/dropin.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/shared/dropin.c b/src/shared/dropin.c +index 11ed4c7184..927107c508 100644 +--- a/src/shared/dropin.c ++++ b/src/shared/dropin.c +@@ -242,6 +242,10 @@ int unit_file_find_dropin_paths( + + assert(ret); + ++ SET_FOREACH(name, names, i) ++ STRV_FOREACH(p, lookup_path) ++ (void) unit_file_find_dirs(original_root, unit_path_cache, *p, name, dir_suffix, &dirs); ++ + /* All the names in the unit are of the same type so just grab one. */ + name = (char*) set_first(names); + if (name) { +@@ -253,7 +257,7 @@ int unit_file_find_dropin_paths( + "Failed to to derive unit type from unit name: %s", + name); + +- /* Special top level drop in for ".". Add this first as it's the most generic ++ /* Special top level drop in for ".". Add this last as it's the most generic + * and should be able to be overridden by more specific drop-ins. */ + STRV_FOREACH(p, lookup_path) + (void) unit_file_find_dirs(original_root, +@@ -264,10 +268,6 @@ int unit_file_find_dropin_paths( + &dirs); + } + +- SET_FOREACH(name, names, i) +- STRV_FOREACH(p, lookup_path) +- (void) unit_file_find_dirs(original_root, unit_path_cache, *p, name, dir_suffix, &dirs); +- + if (strv_isempty(dirs)) { + *ret = NULL; + return 0; diff --git a/0962-Add-failing-test-to-show-service.d-global-drop-in-do.patch b/0962-Add-failing-test-to-show-service.d-global-drop-in-do.patch new file mode 100644 index 0000000..1fbf0c3 --- /dev/null +++ b/0962-Add-failing-test-to-show-service.d-global-drop-in-do.patch @@ -0,0 +1,57 @@ +From 471f790115b2b0a56328cbf14a6e0f51c1176b62 Mon Sep 17 00:00:00 2001 +From: "Greg \"GothAck\" Miell" +Date: Fri, 27 Dec 2019 14:36:49 +0000 +Subject: [PATCH] Add failing test to show service.d global drop-in does not + get overridden by more specific dropins + +(cherry picked from commit f5dd6e50a781b83bc6b1d8e018783661142aabd0) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index 5419169f7b..a9d1ef0a10 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -118,6 +118,31 @@ EOF + clear_services a b c + } + ++test_hierarchical_dropins () { ++ echo "Testing hierarchical dropins..." ++ echo "*** test service.d/ top level drop-in" ++ create_services a-b-c ++ check_ko a-b-c ExecCondition "/bin/echo service.d" ++ check_ko a-b-c ExecCondition "/bin/echo a-.service.d" ++ check_ko a-b-c ExecCondition "/bin/echo a-b-.service.d" ++ check_ko a-b-c ExecCondition "/bin/echo a-b-c.service.d" ++ ++ for dropin in service.d a-.service.d a-b-.service.d a-b-c.service.d; do ++ mkdir -p /usr/lib/systemd/system/$dropin ++ echo " ++[Service] ++ExecCondition=/bin/echo $dropin ++ " >/usr/lib/systemd/system/$dropin/override.conf ++ systemctl daemon-reload ++ check_ok a-b-c ExecCondition "/bin/echo $dropin" ++ done ++ for dropin in service.d a-.service.d a-b-.service.d a-b-c.service.d; do ++ rm -rf /usr/lib/systemd/system/$dropin ++ done ++ ++ clear_services a-b-c ++} ++ + test_template_dropins () { + echo "Testing template dropins..." + +@@ -303,6 +328,7 @@ test_invalid_dropins () { + } + + test_basic_dropins ++test_hierarchical_dropins + test_template_dropins + test_alias_dropins + test_masked_dropins diff --git a/0963-test-set-indentation-to-4-spaces.patch b/0963-test-set-indentation-to-4-spaces.patch new file mode 100644 index 0000000..30a5591 --- /dev/null +++ b/0963-test-set-indentation-to-4-spaces.patch @@ -0,0 +1,522 @@ +From 3681938e3aa5d3580038011b4579ac39612df23e Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Thu, 13 Apr 2023 14:48:00 +0200 +Subject: [PATCH] test: set indentation to 4 spaces + +This is what upstream commit cc5549ca12616376a4e4ef04fd4e2fb53d6d098c +has done, but just for a single shell file. + +RHEL-only + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 448 ++++++++++++++--------------- + 1 file changed, 224 insertions(+), 224 deletions(-) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index a9d1ef0a10..64d8a98fc7 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -4,103 +4,103 @@ set -e + set -x + + _clear_service () { +- systemctl stop $1.service 2>/dev/null || : +- rm -f /{etc,run,usr/lib}/systemd/system/$1.service +- rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.d +- rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.{wants,requires} ++ systemctl stop $1.service 2>/dev/null || : ++ rm -f /{etc,run,usr/lib}/systemd/system/$1.service ++ rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.d ++ rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.{wants,requires} + } + + clear_services () { +- for u in $*; do +- _clear_service $u +- done +- systemctl daemon-reload ++ for u in $*; do ++ _clear_service $u ++ done ++ systemctl daemon-reload + } + + create_service () { +- clear_services $1 ++ clear_services $1 + +- cat >/etc/systemd/system/$1.service</etc/systemd/system/$1.service</usr/lib/systemd/system/a.service.d/override.conf </usr/lib/systemd/system/a.service.d/override.conf </usr/lib/systemd/system/a.service.d/wants-b.conf</usr/lib/systemd/system/a.service.d/wants-b.conf< +Date: Sat, 21 Mar 2020 16:30:27 +0100 +Subject: [PATCH] test/TEST-15: remove all created unit files + +We would miss anything created under a template instance. + +(cherry picked from commit 4e2ac45a83e5495a5c1d3ecac62a054e0cef7746) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index 64d8a98fc7..30f1e84954 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -8,6 +8,12 @@ _clear_service () { + rm -f /{etc,run,usr/lib}/systemd/system/$1.service + rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.d + rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.{wants,requires} ++ if [[ $1 == *@ ]]; then ++ systemctl stop $1*.service 2>/dev/null || : ++ rm -f /{etc,run,usr/lib}/systemd/system/$1*.service ++ rm -fr /{etc,run,usr/lib}/systemd/system/$1*.service.d ++ rm -fr /{etc,run,usr/lib}/systemd/system/$1*.service.{wants,requires} ++ fi + } + + clear_services () { diff --git a/0965-test-use-quotes-where-necessary.patch b/0965-test-use-quotes-where-necessary.patch new file mode 100644 index 0000000..03bf462 --- /dev/null +++ b/0965-test-use-quotes-where-necessary.patch @@ -0,0 +1,95 @@ +From 209b8c92f0c44644d0476349b4a65f4b9ad942de Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Fri, 9 Apr 2021 19:49:32 +0200 +Subject: [PATCH] test: use quotes where necessary + +to avoid possible word splitting. + +[dtardon: Dropped changes to other files.] + +(cherry picked from commit 38825267983a439f2cf8375463b1edc9ca2d3323) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 44 ++++++++++++++++-------------- + 1 file changed, 23 insertions(+), 21 deletions(-) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index 30f1e84954..a197989f72 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -4,51 +4,53 @@ set -e + set -x + + _clear_service () { +- systemctl stop $1.service 2>/dev/null || : +- rm -f /{etc,run,usr/lib}/systemd/system/$1.service +- rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.d +- rm -fr /{etc,run,usr/lib}/systemd/system/$1.service.{wants,requires} +- if [[ $1 == *@ ]]; then +- systemctl stop $1*.service 2>/dev/null || : +- rm -f /{etc,run,usr/lib}/systemd/system/$1*.service +- rm -fr /{etc,run,usr/lib}/systemd/system/$1*.service.d +- rm -fr /{etc,run,usr/lib}/systemd/system/$1*.service.{wants,requires} ++ local SERVICE_NAME="${1:?_clear_service: missing argument}" ++ systemctl stop "$SERVICE_NAME.service" 2>/dev/null || : ++ rm -f /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service.d ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service.{wants,requires} ++ if [[ $SERVICE_NAME == *@ ]]; then ++ systemctl stop "$SERVICE_NAME"*.service 2>/dev/null || : ++ rm -f /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service.d ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service.{wants,requires} + fi + } + + clear_services () { +- for u in $*; do +- _clear_service $u ++ for u in "$@"; do ++ _clear_service "$u" + done + systemctl daemon-reload + } + + create_service () { +- clear_services $1 ++ local SERVICE_NAME="${1:?create_service: missing argument}" ++ clear_services "$SERVICE_NAME" + +- cat >/etc/systemd/system/$1.service</etc/systemd/system/"$SERVICE_NAME".service < +Date: Wed, 4 May 2022 08:24:06 +0200 +Subject: [PATCH] tree-wide: drop manually-crafted message for missing + variables + +Bash will generate a very nice message for us: +/tmp/ff.sh: line 1: SOMEVAR: parameter null or not set + +Let's save some keystrokes by not replacing this with our own inferior +messages. + +[dtardon: Dropped changes to other files.] + +(cherry picked from commit d7ff52403902900b61f644f87b5222822fd4a69b) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index a197989f72..c2c96d9797 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -4,7 +4,7 @@ set -e + set -x + + _clear_service () { +- local SERVICE_NAME="${1:?_clear_service: missing argument}" ++ local SERVICE_NAME="${1:?}" + systemctl stop "$SERVICE_NAME.service" 2>/dev/null || : + rm -f /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service + rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service.d +@@ -25,7 +25,7 @@ clear_services () { + } + + create_service () { +- local SERVICE_NAME="${1:?create_service: missing argument}" ++ local SERVICE_NAME="${1:?}" + clear_services "$SERVICE_NAME" + + cat >/etc/systemd/system/"$SERVICE_NAME".service < +Date: Fri, 14 Oct 2022 14:40:24 +0200 +Subject: [PATCH] manager: reformat boolean expression in unit_is_pristine() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Not not IN_SET(…) is just too much for my poor brain. Let's invert +the expression to make it easier to undertand. + +(cherry picked from commit b146a7345b69de16e88347acadb3783ffeeaad9d) + +Related: #2156620 +--- + src/core/unit.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index 9be2a0c326..78666e73bf 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -4848,12 +4848,12 @@ bool unit_is_pristine(Unit *u) { + * are marked UNIT_LOADED even though nothing was actually + * loaded, as those unit types don't require a file on disk. */ + +- return !(!IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_LOADED) || +- u->fragment_path || +- u->source_path || +- !strv_isempty(u->dropin_paths) || +- u->job || +- u->merged_into); ++ return IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_LOADED) && ++ !u->fragment_path && ++ !u->source_path && ++ strv_isempty(u->dropin_paths) && ++ !u->job && ++ !u->merged_into; + } + + pid_t unit_control_pid(Unit *u) { diff --git a/0968-manager-allow-transient-units-to-have-drop-ins.patch b/0968-manager-allow-transient-units-to-have-drop-ins.patch new file mode 100644 index 0000000..c6826d1 --- /dev/null +++ b/0968-manager-allow-transient-units-to-have-drop-ins.patch @@ -0,0 +1,88 @@ +From fa8ed66b5ff48e0d8e02cfae28e90e65c70e52e3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 14 Oct 2022 15:02:20 +0200 +Subject: [PATCH] manager: allow transient units to have drop-ins + +In https://github.com/containers/podman/issues/16107, starting of a transient +slice unit fails because there's a "global" drop-in +/usr/lib/systemd/user/slice.d/10-oomd-per-slice-defaults.conf (provided by +systemd-oomd-defaults package to install some default oomd policy). This means +that the unit_is_pristine() check fails and starting of the unit is forbidden. + +It seems pretty clear to me that dropins at any other level then the unit +should be ignored in this check: we now have multiple layers of drop-ins +(for each level of the cgroup path, and also "global" ones for a specific +unit type). If we install a "global" drop-in, we wouldn't be able to start +any transient units of that type, which seems undesired. + +In principle we could reject dropins at the unit level, but I don't think that +is useful. The whole reason for drop-ins is that they are "add ons", and there +isn't any particular reason to disallow them for transient units. It would also +make things harder to implement and describe: one place for drop-ins is good, +but another is bad. (And as a corner case: for instanciated units, a drop-in +in the template would be acceptable, but a instance-specific drop-in bad?) + +Thus, $subject. + +While at it, adjust the message. All the conditions in unit_is_pristine() +essentially mean that it wasn't loaded (e.g. it might be in an error state), +and that it doesn't have a fragment path (now that drop-ins are acceptable). +If there's a job for it, it necessarilly must have been loaded. If it is +merged into another unit, it also was loaded and found to be an alias. +Based on the discussion in the bugs, it seems that the current message +is far from obvious ;) + +Fixes https://github.com/containers/podman/issues/16107, +https://bugzilla.redhat.com/show_bug.cgi?id=2133792. + +(cherry picked from commit 1f83244641f13a9cb28fdac7e3c17c5446242dfb) + +Resolves: #2156620 +--- + src/core/dbus-manager.c | 3 ++- + src/core/unit.c | 14 ++++++++------ + 2 files changed, 10 insertions(+), 7 deletions(-) + +diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c +index 8a41eda4a6..ea2f3e7f59 100644 +--- a/src/core/dbus-manager.c ++++ b/src/core/dbus-manager.c +@@ -892,7 +892,8 @@ static int transient_unit_from_message( + return r; + + if (!unit_is_pristine(u)) +- return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name); ++ return sd_bus_error_setf(error, BUS_ERROR_UNIT_EXISTS, ++ "Unit %s was already loaded or has a fragment file.", name); + + /* OK, the unit failed to load and is unreferenced, now let's + * fill in the transient data instead */ +diff --git a/src/core/unit.c b/src/core/unit.c +index 78666e73bf..76fb9f8075 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -4842,16 +4842,18 @@ int unit_fail_if_noncanonical(Unit *u, const char* where) { + bool unit_is_pristine(Unit *u) { + assert(u); + +- /* Check if the unit already exists or is already around, +- * in a number of different ways. Note that to cater for unit +- * types such as slice, we are generally fine with units that +- * are marked UNIT_LOADED even though nothing was actually +- * loaded, as those unit types don't require a file on disk. */ ++ /* Check if the unit already exists or is already around, in a number of different ways. Note that to ++ * cater for unit types such as slice, we are generally fine with units that are marked UNIT_LOADED ++ * even though nothing was actually loaded, as those unit types don't require a file on disk. ++ * ++ * Note that we don't check for drop-ins here, because we allow drop-ins for transient units ++ * identically to non-transient units, both unit-specific and hierarchical. E.g. for a-b-c.service: ++ * service.d/….conf, a-.service.d/….conf, a-b-.service.d/….conf, a-b-c.service.d/….conf. ++ */ + + return IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_LOADED) && + !u->fragment_path && + !u->source_path && +- strv_isempty(u->dropin_paths) && + !u->job && + !u->merged_into; + } diff --git a/0969-TEST-15-allow-helper-functions-to-accept-other-unit-.patch b/0969-TEST-15-allow-helper-functions-to-accept-other-unit-.patch new file mode 100644 index 0000000..79f29d0 --- /dev/null +++ b/0969-TEST-15-allow-helper-functions-to-accept-other-unit-.patch @@ -0,0 +1,135 @@ +From 8a85dd4af8e4948299b4c84df65c789999024d5f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sun, 16 Oct 2022 12:42:35 +0200 +Subject: [PATCH] TEST-15: allow helper functions to accept other unit types + +clear_services() is renamed to clear_units() and now takes a full +unit name including the suffix as an argument. + +_clear_service() is renamed to clear_unit() and changed likewise. +create_service() didn't have the same underscore prefix, and I don't think +it's useful or needed for a local function, so it is removed. + +No functional change. + +(cherry picked from commit 5731e1378ad6256e34f3da33ee993343f025c075) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 44 ++++++++++++++++-------------- + 1 file changed, 23 insertions(+), 21 deletions(-) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index c2c96d9797..bcd351360d 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -3,30 +3,32 @@ + set -e + set -x + +-_clear_service () { +- local SERVICE_NAME="${1:?}" +- systemctl stop "$SERVICE_NAME.service" 2>/dev/null || : +- rm -f /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service +- rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service.d +- rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME".service.{wants,requires} +- if [[ $SERVICE_NAME == *@ ]]; then +- systemctl stop "$SERVICE_NAME"*.service 2>/dev/null || : +- rm -f /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service +- rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service.d +- rm -fr /{etc,run,usr/lib}/systemd/system/"$SERVICE_NAME"*.service.{wants,requires} ++clear_unit () { ++ local UNIT_NAME="${1:?}" ++ systemctl stop "$UNIT_NAME" 2>/dev/null || : ++ rm -f /{etc,run,usr/lib}/systemd/system/"$UNIT_NAME" ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$UNIT_NAME".d ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$UNIT_NAME".{wants,requires} ++ if [[ $UNIT_NAME == *@ ]]; then ++ local base="${UNIT_NAME%@*}" ++ local suffix="${UNIT_NAME##*.}" ++ systemctl stop "$base@"*."$suffix" 2>/dev/null || : ++ rm -f /{etc,run,usr/lib}/systemd/system/"$base@"*."$suffix" ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$base@"*."$suffix".d ++ rm -fr /{etc,run,usr/lib}/systemd/system/"$base@"*."$suffix".{wants,requires} + fi + } + +-clear_services () { ++clear_units () { + for u in "$@"; do +- _clear_service "$u" ++ clear_unit "$u" + done + systemctl daemon-reload + } + + create_service () { + local SERVICE_NAME="${1:?}" +- clear_services "$SERVICE_NAME" ++ clear_units "${SERVICE_NAME}".service + + cat >/etc/systemd/system/"$SERVICE_NAME".service < +Date: Sun, 16 Oct 2022 12:54:34 +0200 +Subject: [PATCH] TEST-15: also test hierarchical drop-ins for slices + +Slices are worth testing too, because they don't need a fragment path so they +behave slightly differently than service units. I'm making this a separate +patch from the actual tests that I wanted to add later because it's complex +enough on its own. + +(cherry picked from commit f80c874af376052b6b81f47cbbc43d7fecd98cd6) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 37 +++++++++++++++++++++++++++--- + 1 file changed, 34 insertions(+), 3 deletions(-) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index bcd351360d..d46946fd77 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -128,8 +128,8 @@ EOF + clear_units {a,b,c}.service + } + +-test_hierarchical_dropins () { +- echo "Testing hierarchical dropins..." ++test_hierarchical_service_dropins () { ++ echo "Testing hierarchical service dropins..." + echo "*** test service.d/ top level drop-in" + create_services a-b-c + check_ko a-b-c ExecCondition "/bin/echo service.d" +@@ -153,6 +153,36 @@ ExecCondition=/bin/echo $dropin + clear_units a-b-c.service + } + ++test_hierarchical_slice_dropins () { ++ echo "Testing hierarchical slice dropins..." ++ echo "*** test slice.d/ top level drop-in" ++ # Slice units don't even need a fragment, so we test the defaults here ++ check_ok a-b-c.slice Description "a-b-c.slice" ++ check_ok a-b-c.slice MemoryMax "infinity" ++ ++ # Test drop-ins ++ for dropin in slice.d a-.slice.d a-b-.slice.d a-b-c.slice.d; do ++ mkdir -p /usr/lib/systemd/system/$dropin ++ echo " ++[Slice] ++MemoryMax=1000000000 ++ " >/usr/lib/systemd/system/$dropin/override.conf ++ systemctl daemon-reload ++ check_ok a-b-c.slice MemoryMax "1000000000" ++ rm /usr/lib/systemd/system/$dropin/override.conf ++ done ++ ++ # Test unit with a fragment ++ echo " ++[Slice] ++MemoryMax=1000000001 ++ " >/usr/lib/systemd/system/a-b-c.slice ++ systemctl daemon-reload ++ check_ok a-b-c.slice MemoryMax "1000000001" ++ ++ clear_units a-b-c.slice ++} ++ + test_template_dropins () { + echo "Testing template dropins..." + +@@ -338,7 +368,8 @@ test_invalid_dropins () { + } + + test_basic_dropins +-test_hierarchical_dropins ++test_hierarchical_service_dropins ++test_hierarchical_slice_dropins + test_template_dropins + test_alias_dropins + test_masked_dropins diff --git a/0971-TEST-15-add-test-for-transient-units-with-drop-ins.patch b/0971-TEST-15-add-test-for-transient-units-with-drop-ins.patch new file mode 100644 index 0000000..4d892e4 --- /dev/null +++ b/0971-TEST-15-add-test-for-transient-units-with-drop-ins.patch @@ -0,0 +1,109 @@ +From c4db01d0c3e1ff05286261971ba39839cc91c21a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sun, 16 Oct 2022 14:02:45 +0200 +Subject: [PATCH] TEST-15: add test for transient units with drop-ins + +We want to test four things: +- that the transient units are successfully started when drop-ins exist +- that the transient setings override the defaults +- the drop-ins override the transient settings (the same as for a normal unit) +- that things are the same before and after a reload + +To make things more fun, we start and stop units in two different ways: via +systemctl and via a direct busctl invocation. This gives us a bit more coverage +of different code paths. + +(cherry picked from commit 6854434cfb5dda10c07d95835c38b75e5e71c2b5) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 62 +++++++++++++++++++++++++++--- + 1 file changed, 56 insertions(+), 6 deletions(-) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index d46946fd77..5f061d3629 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -132,19 +132,40 @@ test_hierarchical_service_dropins () { + echo "Testing hierarchical service dropins..." + echo "*** test service.d/ top level drop-in" + create_services a-b-c +- check_ko a-b-c ExecCondition "/bin/echo service.d" +- check_ko a-b-c ExecCondition "/bin/echo a-.service.d" +- check_ko a-b-c ExecCondition "/bin/echo a-b-.service.d" +- check_ko a-b-c ExecCondition "/bin/echo a-b-c.service.d" ++ check_ko a-b-c ExecCondition "echo service.d" ++ check_ko a-b-c ExecCondition "echo a-.service.d" ++ check_ko a-b-c ExecCondition "echo a-b-.service.d" ++ check_ko a-b-c ExecCondition "echo a-b-c.service.d" + + for dropin in service.d a-.service.d a-b-.service.d a-b-c.service.d; do + mkdir -p /usr/lib/systemd/system/$dropin + echo " + [Service] +-ExecCondition=/bin/echo $dropin ++ExecCondition=echo $dropin + " >/usr/lib/systemd/system/$dropin/override.conf + systemctl daemon-reload +- check_ok a-b-c ExecCondition "/bin/echo $dropin" ++ check_ok a-b-c ExecCondition "echo $dropin" ++ ++ # Check that we can start a transient service in presence of the drop-ins ++ systemd-run --unit a-b-c2.service -p Description='sleepy' sleep infinity ++ ++ # The transient setting replaces the default ++ check_ok a-b-c2.service Description "sleepy" ++ ++ # The override takes precedence for ExecCondition ++ # (except the last iteration when it only applies to the other service) ++ if [ "$dropin" != "a-b-c.service.d" ]; then ++ check_ok a-b-c2.service ExecCondition "echo $dropin" ++ fi ++ ++ # Check that things are the same after a reload ++ systemctl daemon-reload ++ check_ok a-b-c2.service Description "sleepy" ++ if [ "$dropin" != "a-b-c.service.d" ]; then ++ check_ok a-b-c2.service ExecCondition "echo $dropin" ++ fi ++ ++ systemctl stop a-b-c2.service + done + for dropin in service.d a-.service.d a-b-.service.d a-b-c.service.d; do + rm -rf /usr/lib/systemd/system/$dropin +@@ -169,6 +190,35 @@ MemoryMax=1000000000 + " >/usr/lib/systemd/system/$dropin/override.conf + systemctl daemon-reload + check_ok a-b-c.slice MemoryMax "1000000000" ++ ++ busctl call \ ++ org.freedesktop.systemd1 \ ++ /org/freedesktop/systemd1 \ ++ org.freedesktop.systemd1.Manager \ ++ StartTransientUnit 'ssa(sv)a(sa(sv))' \ ++ 'a-b-c.slice' 'replace' \ ++ 2 \ ++ 'Description' s 'slice too' \ ++ 'MemoryMax' t 1000000002 \ ++ 0 ++ ++ # The override takes precedence for MemoryMax ++ check_ok a-b-c.slice MemoryMax "1000000000" ++ # The transient setting replaces the default ++ check_ok a-b-c.slice Description "slice too" ++ ++ # Check that things are the same after a reload ++ systemctl daemon-reload ++ check_ok a-b-c.slice MemoryMax "1000000000" ++ check_ok a-b-c.slice Description "slice too" ++ ++ busctl call \ ++ org.freedesktop.systemd1 \ ++ /org/freedesktop/systemd1 \ ++ org.freedesktop.systemd1.Manager \ ++ StopUnit 'ss' \ ++ 'a-b-c.slice' 'replace' ++ + rm /usr/lib/systemd/system/$dropin/override.conf + done + diff --git a/0972-TEST-15-add-one-more-test-for-drop-in-precedence.patch b/0972-TEST-15-add-one-more-test-for-drop-in-precedence.patch new file mode 100644 index 0000000..d27d06d --- /dev/null +++ b/0972-TEST-15-add-one-more-test-for-drop-in-precedence.patch @@ -0,0 +1,66 @@ +From 832ceb778409cac37c3b64294dc64312e86eedc6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sun, 16 Oct 2022 21:52:43 +0200 +Subject: [PATCH] TEST-15: add one more test for drop-in precedence + +(cherry picked from commit c3fa408dcc03bb6dbd11f180540fb9e684893c39) + +Related: #2156620 +--- + test/TEST-15-DROPIN/test-dropin.sh | 36 ++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/test/TEST-15-DROPIN/test-dropin.sh b/test/TEST-15-DROPIN/test-dropin.sh +index 5f061d3629..f6b3844630 100755 +--- a/test/TEST-15-DROPIN/test-dropin.sh ++++ b/test/TEST-15-DROPIN/test-dropin.sh +@@ -233,6 +233,41 @@ MemoryMax=1000000001 + clear_units a-b-c.slice + } + ++test_transient_service_dropins () { ++ echo "Testing dropins for a transient service..." ++ echo "*** test transient service drop-ins" ++ ++ mkdir -p /etc/systemd/system/service.d ++ mkdir -p /etc/systemd/system/a-.service.d ++ mkdir -p /etc/systemd/system/a-b-.service.d ++ mkdir -p /etc/systemd/system/a-b-c.service.d ++ ++ echo -e '[Service]\nStandardInputText=aaa' >/etc/systemd/system/service.d/drop1.conf ++ echo -e '[Service]\nStandardInputText=bbb' >/etc/systemd/system/a-.service.d/drop2.conf ++ echo -e '[Service]\nStandardInputText=ccc' >/etc/systemd/system/a-b-.service.d/drop3.conf ++ echo -e '[Service]\nStandardInputText=ddd' >/etc/systemd/system/a-b-c.service.d/drop4.conf ++ ++ # There's no fragment yet, so this fails ++ systemctl cat a-b-c.service && exit 1 ++ ++ # xxx → eHh4Cg== ++ systemd-run --unit a-b-c.service -p StandardInputData=eHh4Cg== sleep infinity ++ ++ data=$(systemctl show --value -p StandardInputData a-b-c.service) ++ # xxx\naaa\n\bbb\nccc\nddd\n → eHh4… ++ test "$data" = "eHh4CmFhYQpiYmIKY2NjCmRkZAo=" ++ ++ # Do a reload and check again ++ systemctl daemon-reload ++ data=$(systemctl show --value -p StandardInputData a-b-c.service) ++ test "$data" = "eHh4CmFhYQpiYmIKY2NjCmRkZAo=" ++ ++ clear_units a-b-c.service ++ rm /etc/systemd/system/service.d/drop1.conf \ ++ /etc/systemd/system/a-.service.d/drop2.conf \ ++ /etc/systemd/system/a-b-.service.d/drop3.conf ++} ++ + test_template_dropins () { + echo "Testing template dropins..." + +@@ -420,6 +455,7 @@ test_invalid_dropins () { + test_basic_dropins + test_hierarchical_service_dropins + test_hierarchical_slice_dropins ++test_transient_service_dropins + test_template_dropins + test_alias_dropins + test_masked_dropins diff --git a/0973-udev-net_id-introduce-naming-scheme-for-RHEL-8.9.patch b/0973-udev-net_id-introduce-naming-scheme-for-RHEL-8.9.patch new file mode 100644 index 0000000..a5e1176 --- /dev/null +++ b/0973-udev-net_id-introduce-naming-scheme-for-RHEL-8.9.patch @@ -0,0 +1,50 @@ +From 79e852a6c50ab2eae16761f128c52ef286c2956b Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Mon, 14 Aug 2023 15:58:02 +0200 +Subject: [PATCH] udev/net_id: introduce naming scheme for RHEL-8.9 + +rhel-only + +Resolves: #2231846 +--- + man/systemd.net-naming-scheme.xml | 6 ++++++ + src/udev/udev-builtin-net_id.c | 2 ++ + 2 files changed, 8 insertions(+) + +diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml +index 3cc7719e99..ddd41646ae 100644 +--- a/man/systemd.net-naming-scheme.xml ++++ b/man/systemd.net-naming-scheme.xml +@@ -334,6 +334,12 @@ + Same as naming scheme rhel-8.7. + + ++ ++ rhel-8.9 ++ ++ Same as naming scheme rhel-8.7. ++ ++ + Note that latest may be used to denote the latest scheme known to this + particular version of systemd. + +diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c +index ef2bb1b08e..0f42c1c007 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -142,6 +142,7 @@ typedef enum NamingSchemeFlags { + NAMING_RHEL_8_6 = NAMING_RHEL_8_4, + NAMING_RHEL_8_7 = NAMING_RHEL_8_4|NAMING_SLOT_FUNCTION_ID|NAMING_16BIT_INDEX, + NAMING_RHEL_8_8 = NAMING_RHEL_8_7, ++ NAMING_RHEL_8_9 = NAMING_RHEL_8_7, + + _NAMING_SCHEME_FLAGS_INVALID = -1, + } NamingSchemeFlags; +@@ -163,6 +164,7 @@ static const NamingScheme naming_schemes[] = { + { "rhel-8.6", NAMING_RHEL_8_6 }, + { "rhel-8.7", NAMING_RHEL_8_7 }, + { "rhel-8.8", NAMING_RHEL_8_8 }, ++ { "rhel-8.9", NAMING_RHEL_8_9 }, + /* … add more schemes here, as the logic to name devices is updated … */ + }; + diff --git a/0974-meson-remove-libdw-dependency-from-pstore.patch b/0974-meson-remove-libdw-dependency-from-pstore.patch new file mode 100644 index 0000000..87c5315 --- /dev/null +++ b/0974-meson-remove-libdw-dependency-from-pstore.patch @@ -0,0 +1,27 @@ +From e89c5274a75907bf24689859cdcdf8335df382cd Mon Sep 17 00:00:00 2001 +From: Luca Boccassi +Date: Wed, 24 Nov 2021 20:23:02 +0000 +Subject: [PATCH] meson: remove libdw dependency from pstore + +systemd-pstore does not use any symbol from libdw, and never did, +but the dependency was listed since the beginning + +(cherry picked from commit 5361f62d6d5b25c6545059f7d2513324be8d7a49) + +Related: #2211416 +--- + meson.build | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/meson.build b/meson.build +index d986dd24ac..d00d250444 100644 +--- a/meson.build ++++ b/meson.build +@@ -2161,7 +2161,6 @@ if conf.get('ENABLE_PSTORE') == 1 + link_with : [libshared], + dependencies : [threads, + libacl, +- libdw, + libxz, + liblz4], + install_rpath : rootlibexecdir, diff --git a/0975-pstore-introduce-tmpfiles.d-systemd-pstore.conf.patch b/0975-pstore-introduce-tmpfiles.d-systemd-pstore.conf.patch new file mode 100644 index 0000000..473087c --- /dev/null +++ b/0975-pstore-introduce-tmpfiles.d-systemd-pstore.conf.patch @@ -0,0 +1,113 @@ +From e7f656192ea399043947640a664bd94129e9549b Mon Sep 17 00:00:00 2001 +From: Eric DeVolder +Date: Mon, 13 Apr 2020 16:22:04 -0500 +Subject: [PATCH] pstore: introduce tmpfiles.d/systemd-pstore.conf + +The systemd pstore service archives the contents of /sys/fs/pstore +upon boot so that there is room for a subsequent dump. The issue is +that while the service is present, the kernel still needs to be +configured to write data into the pstore. The kernel has two +parameters, crash_kexec_post_notifiers and printk.always_kmsg_dump, +that control writes into pstore. + +The crash_kexec_post_notifiers parameter enables the kernel to write +dmesg (including stack trace) into pstore upon a panic, and +printk.always_kmsg_dump parameter enables the kernel to write dmesg +upon a shutdown (shutdown, reboot, halt). + +As it stands today, these parameters are not managed/manipulated by +the systemd pstore service, and are solely reliant upon the user [to +have the foresight] to set them on the kernel command line at boot, or +post boot via sysfs. Furthermore, the user would need to set these +parameters in a persistent fashion so that that they are enabled on +subsequent reboots. + +This patch introduces the setting of these two kernel parameters via +the systemd tmpfiles technique. + +(cherry picked from commit f00c36641a253f4ea659ec3def5d87ba1336eb3b) + +Resolves: #2211416 +--- + man/systemd-pstore.service.xml | 18 ++++++++++++++++++ + tmpfiles.d/meson.build | 1 + + tmpfiles.d/systemd-pstore.conf | 29 +++++++++++++++++++++++++++++ + 3 files changed, 48 insertions(+) + create mode 100644 tmpfiles.d/systemd-pstore.conf + +diff --git a/man/systemd-pstore.service.xml b/man/systemd-pstore.service.xml +index 47916da521..335a3b3d18 100644 +--- a/man/systemd-pstore.service.xml ++++ b/man/systemd-pstore.service.xml +@@ -81,6 +81,24 @@ + pstore.conf5. + + ++ ++ ++ Controlling kernel parameters ++ ++ The kernel has two parameters, ++ /sys/module/kernel/parameters/crash_kexec_post_notifiers and ++ /sys/module/printk/parameters/always_kmsg_dump, ++ that control writes into pstore. ++ The crash_kexec_post_notifiers parameter enables the kernel to write ++ dmesg (including stack trace) into pstore upon a panic or crash, and ++ printk.always_kmsg_dump parameter enables the kernel to write dmesg ++ upon a normal shutdown (shutdown, reboot, halt). These kernel ++ parameters are managed via the ++ tmpfiles.d5 ++ mechanism, specifically the file /usr/lib/tmpfiles/systemd-pstore.conf. ++ ++ ++ + + + +diff --git a/tmpfiles.d/meson.build b/tmpfiles.d/meson.build +index 35eea2be5c..5ebb8f432a 100644 +--- a/tmpfiles.d/meson.build ++++ b/tmpfiles.d/meson.build +@@ -7,6 +7,7 @@ tmpfiles = [['home.conf', ''], + ['systemd-nologin.conf', ''], + ['systemd-nspawn.conf', 'ENABLE_MACHINED'], + ['portables.conf', 'ENABLE_PORTABLED'], ++ ['systemd-pstore.conf', 'ENABLE_PSTORE'], + ['tmp.conf', ''], + ['x11.conf', ''], + ['legacy.conf', 'HAVE_SYSV_COMPAT'], +diff --git a/tmpfiles.d/systemd-pstore.conf b/tmpfiles.d/systemd-pstore.conf +new file mode 100644 +index 0000000000..cb600ec1ee +--- /dev/null ++++ b/tmpfiles.d/systemd-pstore.conf +@@ -0,0 +1,29 @@ ++# SPDX-License-Identifier: LGPL-2.1+ ++# ++# The systemd-pstore.service(1) archives the contents of /sys/fs/pstore ++# upon boot so that there is room for a subsequent dump. This service ++# is enabled with: ++# systemctl enable systemd-pstore ++# ++# With the service enabled, the kernel still needs to be configured ++# to write data into the pstore. The kernel has two parameters, ++# crash_kexec_post_notifiers and printk.always_kmsg_dump, that ++# control writes into pstore. ++# ++# The crash_kexec_post_notifiers parameter enables the kernel to write ++# dmesg (including stack trace) into pstore upon a panic, and ++# printk.always_kmsg_dump parameter enables the kernel to write dmesg ++# upon a normal shutdown (shutdown, reboot, halt). ++# ++# To configure the kernel parameters, uncomment the appropriate ++# line(s) below. The value written is either 'Y' to enable the ++# kernel parameter, or 'N' to disable the kernel parameter. ++# ++# After making a change to this file, do: ++# systemd-tmpfiles --create path/to/tmpfiles.d/systemd-pstore.conf ++# ++# These changes are automatically applied on future re-boots. ++ ++d /var/lib/systemd/pstore 0755 root root 14d ++#w /sys/module/printk/parameters/always_kmsg_dump - - - - Y ++w /sys/module/kernel/parameters/crash_kexec_post_notifiers - - - - Y diff --git a/0976-tmpfiles-don-t-complain-if-we-can-t-enable-pstore-in.patch b/0976-tmpfiles-don-t-complain-if-we-can-t-enable-pstore-in.patch new file mode 100644 index 0000000..4dec077 --- /dev/null +++ b/0976-tmpfiles-don-t-complain-if-we-can-t-enable-pstore-in.patch @@ -0,0 +1,25 @@ +From fec31cf3f20aa97b7dc8b381e64f30eea4d4c2d2 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 25 May 2020 16:11:51 +0200 +Subject: [PATCH] tmpfiles: don't complain if we can't enable pstore in + containers + +(cherry picked from commit 203c07c95b91b4ae3b0c1ae3c92accdb71fd5e13) + +Related: #2211416 +--- + tmpfiles.d/systemd-pstore.conf | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tmpfiles.d/systemd-pstore.conf b/tmpfiles.d/systemd-pstore.conf +index cb600ec1ee..8b6a1dafc3 100644 +--- a/tmpfiles.d/systemd-pstore.conf ++++ b/tmpfiles.d/systemd-pstore.conf +@@ -25,5 +25,5 @@ + # These changes are automatically applied on future re-boots. + + d /var/lib/systemd/pstore 0755 root root 14d +-#w /sys/module/printk/parameters/always_kmsg_dump - - - - Y +-w /sys/module/kernel/parameters/crash_kexec_post_notifiers - - - - Y ++#w- /sys/module/printk/parameters/always_kmsg_dump - - - - Y ++w- /sys/module/kernel/parameters/crash_kexec_post_notifiers - - - - Y diff --git a/0977-pstore-don-t-enable-crash_kexec_post_notifiers-by-de.patch b/0977-pstore-don-t-enable-crash_kexec_post_notifiers-by-de.patch new file mode 100644 index 0000000..1824a74 --- /dev/null +++ b/0977-pstore-don-t-enable-crash_kexec_post_notifiers-by-de.patch @@ -0,0 +1,66 @@ +From 21e0afbe2764476c98d7809af6634773835723d4 Mon Sep 17 00:00:00 2001 +From: Kairui Song +Date: Tue, 4 Aug 2020 17:30:51 +0800 +Subject: [PATCH] pstore: don't enable crash_kexec_post_notifiers by default + +commit f00c36641a253f4ea659ec3def5d87ba1336eb3b enabled +crash_kexec_post_notifiers by default regardless of whether pstore +is enabled or not. + +The original intention to enabled this option by default is that +it only affects kernel post-panic behavior, so should have no harm. +But this is not true if the user wants a reliable kdump. + +crash_kexec_post_notifiers is known to cause problem with kdump, +and it's documented in kernel. It's not easy to fix the problem +because of how kdump works. Kdump expects the crashed kernel to +jump to an pre-loaded crash kernel, so doing any extra job before +the jump will increase the risk. + +It depends on the user to choose between having a reliable kdump or +some other post-panic debug mechanic. + +So it's better to keep this config untouched by default, or it may put +kdump at higher risk of failing silently. User should enable it by +uncommenting the config line manually if pstore is always needed. + +Also add a inline comment inform user about the potential issue. + +Thanks to Dave Young for finding out this issue. + +Fixes #16661 + +Signed-off-by: Kairui Song +(cherry picked from commit edb8c98446e7dae54bcda90806bf6c068e1c6385) + +Related: #2211416 +--- + tmpfiles.d/systemd-pstore.conf | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/tmpfiles.d/systemd-pstore.conf b/tmpfiles.d/systemd-pstore.conf +index 8b6a1dafc3..e8e9ed48ae 100644 +--- a/tmpfiles.d/systemd-pstore.conf ++++ b/tmpfiles.d/systemd-pstore.conf +@@ -11,8 +11,13 @@ + # control writes into pstore. + # + # The crash_kexec_post_notifiers parameter enables the kernel to write +-# dmesg (including stack trace) into pstore upon a panic, and +-# printk.always_kmsg_dump parameter enables the kernel to write dmesg ++# dmesg (including stack trace) into pstore upon a panic even if kdump ++# is loaded, only needed if you want to use pstore with kdump. Without ++# this parameter, kdump could block writing to pstore for stability ++# reason. Note this increases the risk of kdump failure even if pstore ++# is not available. ++# ++# The printk.always_kmsg_dump parameter enables the kernel to write dmesg + # upon a normal shutdown (shutdown, reboot, halt). + # + # To configure the kernel parameters, uncomment the appropriate +@@ -26,4 +31,4 @@ + + d /var/lib/systemd/pstore 0755 root root 14d + #w- /sys/module/printk/parameters/always_kmsg_dump - - - - Y +-w- /sys/module/kernel/parameters/crash_kexec_post_notifiers - - - - Y ++#w- /sys/module/kernel/parameters/crash_kexec_post_notifiers - - - - Y diff --git a/0978-core-when-Delegate-yes-is-set-for-a-unit-run-ExecSta.patch b/0978-core-when-Delegate-yes-is-set-for-a-unit-run-ExecSta.patch new file mode 100644 index 0000000..cf88994 --- /dev/null +++ b/0978-core-when-Delegate-yes-is-set-for-a-unit-run-ExecSta.patch @@ -0,0 +1,217 @@ +From 44d19e4beb486969b25c07f7efdee2e8b8bcf986 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 16 Nov 2018 20:19:07 +0100 +Subject: [PATCH] core: when Delegate=yes is set for a unit, run ExecStartPre= + and friends in a subcgroup of the unit + +Otherwise we might conflict with the "no-processes-in-inner-cgroup" rule +of cgroupsv2. Consider nspawn starting up and initializing its cgroup +hierarchy with "supervisor/" and "payload/" as subcgroup, with itself +moved into the former and the payload into the latter. Now, if an +ExecStartPre= is run right after it cannot be placed in the main cgroup, +because that is now in inner cgroup with populated children. + +Hence, let's run these helpers in another sub-cgroup .control/ below it. + +This is somewhat ugly since it weakens the clear separation of +ownership, but given that this is an explicit contract, and double opt-in should be acceptable. + +Fixes: #10482 +(cherry picked from commit 78f93209fc7f61f15b12d7a5f74d712bd020b249) + +Resolves: #2215925 +--- + src/core/execute.c | 67 +++++++++++++++++++++++++++++++++++++++------- + src/core/execute.h | 9 ++++--- + src/core/service.c | 13 ++++----- + 3 files changed, 70 insertions(+), 19 deletions(-) + +diff --git a/src/core/execute.c b/src/core/execute.c +index b1d8dceb32..7e186c948c 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -2834,6 +2834,37 @@ bool exec_context_get_cpu_affinity_from_numa(const ExecContext *c) { + return c->cpu_affinity_from_numa; + } + ++static int exec_parameters_get_cgroup_path(const ExecParameters *params, char **ret) { ++ bool using_subcgroup; ++ char *p; ++ ++ assert(params); ++ assert(ret); ++ ++ if (!params->cgroup_path) ++ return -EINVAL; ++ ++ /* If we are called for a unit where cgroup delegation is on, and the payload created its own populated ++ * subcgroup (which we expect it to do, after all it asked for delegation), then we cannot place the control ++ * processes started after the main unit's process in the unit's main cgroup because it is now an inner one, ++ * and inner cgroups may not contain processes. Hence, if delegation is on, and this is a control process, ++ * let's use ".control" as subcgroup instead. Note that we do so only for ExecStartPost=, ExecReload=, ++ * ExecStop=, ExecStopPost=, i.e. for the commands where the main process is already forked. For ExecStartPre= ++ * this is not necessary, the cgroup is still empty. We distinguish these cases with the EXEC_CONTROL_CGROUP ++ * flag, which is only passed for the former statements, not for the latter. */ ++ ++ using_subcgroup = FLAGS_SET(params->flags, EXEC_CONTROL_CGROUP|EXEC_CGROUP_DELEGATE|EXEC_IS_CONTROL); ++ if (using_subcgroup) ++ p = strjoin(params->cgroup_path, "/.control"); ++ else ++ p = strdup(params->cgroup_path); ++ if (!p) ++ return -ENOMEM; ++ ++ *ret = p; ++ return using_subcgroup; ++} ++ + static int exec_child( + Unit *unit, + const ExecCommand *command, +@@ -3055,10 +3086,18 @@ static int exec_child( + } + + if (params->cgroup_path) { +- r = cg_attach_everywhere(params->cgroup_supported, params->cgroup_path, 0, NULL, NULL); ++ _cleanup_free_ char *p = NULL; ++ ++ r = exec_parameters_get_cgroup_path(params, &p); + if (r < 0) { + *exit_status = EXIT_CGROUP; +- return log_unit_error_errno(unit, r, "Failed to attach to cgroup %s: %m", params->cgroup_path); ++ return log_unit_error_errno(unit, r, "Failed to acquire cgroup path: %m"); ++ } ++ ++ r = cg_attach_everywhere(params->cgroup_supported, p, 0, NULL, NULL); ++ if (r < 0) { ++ *exit_status = EXIT_CGROUP; ++ return log_unit_error_errno(unit, r, "Failed to attach to cgroup %s: %m", p); + } + } + +@@ -3659,6 +3698,7 @@ int exec_spawn(Unit *unit, + DynamicCreds *dcreds, + pid_t *ret) { + ++ _cleanup_free_ char *subcgroup_path = NULL; + _cleanup_strv_free_ char **files_env = NULL; + int *fds = NULL; + size_t n_storage_fds = 0, n_socket_fds = 0; +@@ -3716,6 +3756,17 @@ int exec_spawn(Unit *unit, + LOG_UNIT_ID(unit), + LOG_UNIT_INVOCATION_ID(unit)); + ++ if (params->cgroup_path) { ++ r = exec_parameters_get_cgroup_path(params, &subcgroup_path); ++ if (r < 0) ++ return log_unit_error_errno(unit, r, "Failed to acquire subcgroup path: %m"); ++ if (r > 0) { /* We are using a child cgroup */ ++ r = cg_create(SYSTEMD_CGROUP_CONTROLLER, subcgroup_path); ++ if (r < 0) ++ return log_unit_error_errno(unit, r, "Failed to create control group '%s': %m", subcgroup_path); ++ } ++ } ++ + pid = fork(); + if (pid < 0) + return log_unit_error_errno(unit, errno, "Failed to fork: %m"); +@@ -3754,13 +3805,11 @@ int exec_spawn(Unit *unit, + + log_unit_debug(unit, "Forked %s as "PID_FMT, command->path, pid); + +- /* We add the new process to the cgroup both in the child (so +- * that we can be sure that no user code is ever executed +- * outside of the cgroup) and in the parent (so that we can be +- * sure that when we kill the cgroup the process will be +- * killed too). */ +- if (params->cgroup_path) +- (void) cg_attach(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, pid); ++ /* We add the new process to the cgroup both in the child (so that we can be sure that no user code is ever ++ * executed outside of the cgroup) and in the parent (so that we can be sure that when we kill the cgroup the ++ * process will be killed too). */ ++ if (subcgroup_path) ++ (void) cg_attach(SYSTEMD_CGROUP_CONTROLLER, subcgroup_path, pid); + + exec_status_start(&command->exec_status, pid); + +diff --git a/src/core/execute.h b/src/core/execute.h +index 62c6229621..f5bc180ece 100644 +--- a/src/core/execute.h ++++ b/src/core/execute.h +@@ -289,12 +289,13 @@ typedef enum ExecFlags { + EXEC_CHOWN_DIRECTORIES = 1 << 5, /* chown() the runtime/state/cache/log directories to the user we run as, under all conditions */ + EXEC_NSS_BYPASS_BUS = 1 << 6, /* Set the SYSTEMD_NSS_BYPASS_BUS environment variable, to disable nss-systemd for dbus */ + EXEC_CGROUP_DELEGATE = 1 << 7, ++ EXEC_IS_CONTROL = 1 << 8, ++ EXEC_CONTROL_CGROUP = 1 << 9, /* Place the process not in the indicated cgroup but in a subcgroup '/.control', but only EXEC_CGROUP_DELEGATE and EXEC_IS_CONTROL is set, too */ + + /* The following are not used by execute.c, but by consumers internally */ +- EXEC_PASS_FDS = 1 << 8, +- EXEC_IS_CONTROL = 1 << 9, +- EXEC_SETENV_RESULT = 1 << 10, +- EXEC_SET_WATCHDOG = 1 << 11, ++ EXEC_PASS_FDS = 1 << 10, ++ EXEC_SETENV_RESULT = 1 << 11, ++ EXEC_SET_WATCHDOG = 1 << 12, + } ExecFlags; + + struct ExecParameters { +diff --git a/src/core/service.c b/src/core/service.c +index e05d0e0514..0423f2c73e 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -1429,7 +1429,7 @@ static int service_spawn( + assert(c); + assert(_pid); + +- r = unit_prepare_exec(UNIT(s)); ++ r = unit_prepare_exec(UNIT(s)); /* This realizes the cgroup, among other things */ + if (r < 0) + return r; + +@@ -1798,7 +1798,7 @@ static void service_enter_stop_post(Service *s, ServiceResult f) { + r = service_spawn(s, + s->control_command, + s->timeout_stop_usec, +- EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN|EXEC_IS_CONTROL|EXEC_SETENV_RESULT, ++ EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN|EXEC_IS_CONTROL|EXEC_SETENV_RESULT|EXEC_CONTROL_CGROUP, + &s->control_pid); + if (r < 0) + goto fail; +@@ -1913,7 +1913,7 @@ static void service_enter_stop(Service *s, ServiceResult f) { + r = service_spawn(s, + s->control_command, + s->timeout_stop_usec, +- EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_SETENV_RESULT, ++ EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_SETENV_RESULT|EXEC_CONTROL_CGROUP, + &s->control_pid); + if (r < 0) + goto fail; +@@ -1991,7 +1991,7 @@ static void service_enter_start_post(Service *s) { + r = service_spawn(s, + s->control_command, + s->timeout_start_usec, +- EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL, ++ EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_CONTROL_CGROUP, + &s->control_pid); + if (r < 0) + goto fail; +@@ -2269,7 +2269,7 @@ static void service_enter_reload(Service *s) { + r = service_spawn(s, + s->control_command, + s->timeout_start_usec, +- EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL, ++ EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_CONTROL_CGROUP, + &s->control_pid); + if (r < 0) + goto fail; +@@ -2309,7 +2309,8 @@ static void service_run_next_control(Service *s) { + timeout, + EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL| + (IN_SET(s->control_command_id, SERVICE_EXEC_CONDITION, SERVICE_EXEC_START_PRE, SERVICE_EXEC_STOP_POST) ? EXEC_APPLY_TTY_STDIN : 0)| +- (IN_SET(s->control_command_id, SERVICE_EXEC_STOP, SERVICE_EXEC_STOP_POST) ? EXEC_SETENV_RESULT : 0), ++ (IN_SET(s->control_command_id, SERVICE_EXEC_STOP, SERVICE_EXEC_STOP_POST) ? EXEC_SETENV_RESULT : 0)| ++ (IN_SET(s->control_command_id, SERVICE_EXEC_START_POST, SERVICE_EXEC_RELOAD, SERVICE_EXEC_STOP, SERVICE_EXEC_STOP_POST) ? EXEC_CONTROL_CGROUP : 0), + &s->control_pid); + if (r < 0) + goto fail; diff --git a/0979-man-link-Delegate-documentation-up-with-the-markdown.patch b/0979-man-link-Delegate-documentation-up-with-the-markdown.patch new file mode 100644 index 0000000..a28e88d --- /dev/null +++ b/0979-man-link-Delegate-documentation-up-with-the-markdown.patch @@ -0,0 +1,26 @@ +From 0c1f96220f2a42c256a1e22e5f16d2ff8f4144df Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 16 Nov 2018 20:29:02 +0100 +Subject: [PATCH] man: link Delegate= documentation up with the markdown docs + +(cherry picked from commit 077c40bc5271dfc8d9cee179fbed27a27e741973) + +Related: #2215925 +--- + man/systemd.resource-control.xml | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/man/systemd.resource-control.xml b/man/systemd.resource-control.xml +index d3bff29169..36a622ebf0 100644 +--- a/man/systemd.resource-control.xml ++++ b/man/systemd.resource-control.xml +@@ -808,6 +808,9 @@ + specific to the unified hierarchy while others are specific to the legacy hierarchy. Also note that the + kernel might support further controllers, which aren't covered here yet as delegation is either not supported + at all for them or not defined cleanly. ++ ++ For further details on the delegation model consult Control Group APIs and Delegation. + + + diff --git a/systemd.spec b/systemd.spec index 1ddf849..25e87ae 100644 --- a/systemd.spec +++ b/systemd.spec @@ -13,7 +13,7 @@ Name: systemd Url: http://www.freedesktop.org/wiki/Software/systemd Version: 239 -Release: 77%{?dist} +Release: 78%{?dist} # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: System and Service Manager @@ -1000,6 +1000,35 @@ Patch0947: 0947-core-timer-Always-use-inactive_exit_timestamp-if-it-.patch Patch0948: 0948-timer-Use-dual_timestamp_is_set-in-one-more-place.patch Patch0949: 0949-ci-drop-systemd-stable-from-advanced-commit-linter-c.patch Patch0950: 0950-core-mount-escape-invalid-UTF8-char-in-dbus-reply.patch +Patch0951: 0951-login-add-a-missing-error-check-for-session_set_lead.patch +Patch0952: 0952-logind-reset-session-leader-if-we-know-for-a-fact-th.patch +Patch0953: 0953-test-login-skip-consistency-checks-when-logind-is-no.patch +Patch0954: 0954-sd-event-remove-dead-code-and-use-_cleanup_.patch +Patch0955: 0955-sd-event-don-t-destroy-inotify-data-structures-from-.patch +Patch0956: 0956-sd-event-add-sd_event_add_inotify_fd-call.patch +Patch0957: 0957-test-add-test-case-for-self-destroy-inotify-handler.patch +Patch0958: 0958-doc-add-downstream-CONTRIBUTING-document.patch +Patch0959: 0959-doc-use-link-with-prefilled-Jira-issue.patch +Patch0960: 0960-docs-link-downstream-CONTRIBUTING-in-README.patch +Patch0961: 0961-unit-drop-in-Fix-ordering-of-special-type.d-drop-ins.patch +Patch0962: 0962-Add-failing-test-to-show-service.d-global-drop-in-do.patch +Patch0963: 0963-test-set-indentation-to-4-spaces.patch +Patch0964: 0964-test-TEST-15-remove-all-created-unit-files.patch +Patch0965: 0965-test-use-quotes-where-necessary.patch +Patch0966: 0966-tree-wide-drop-manually-crafted-message-for-missing-.patch +Patch0967: 0967-manager-reformat-boolean-expression-in-unit_is_prist.patch +Patch0968: 0968-manager-allow-transient-units-to-have-drop-ins.patch +Patch0969: 0969-TEST-15-allow-helper-functions-to-accept-other-unit-.patch +Patch0970: 0970-TEST-15-also-test-hierarchical-drop-ins-for-slices.patch +Patch0971: 0971-TEST-15-add-test-for-transient-units-with-drop-ins.patch +Patch0972: 0972-TEST-15-add-one-more-test-for-drop-in-precedence.patch +Patch0973: 0973-udev-net_id-introduce-naming-scheme-for-RHEL-8.9.patch +Patch0974: 0974-meson-remove-libdw-dependency-from-pstore.patch +Patch0975: 0975-pstore-introduce-tmpfiles.d-systemd-pstore.conf.patch +Patch0976: 0976-tmpfiles-don-t-complain-if-we-can-t-enable-pstore-in.patch +Patch0977: 0977-pstore-don-t-enable-crash_kexec_post_notifiers-by-de.patch +Patch0978: 0978-core-when-Delegate-yes-is-set-for-a-unit-run-ExecSta.patch +Patch0979: 0979-man-link-Delegate-documentation-up-with-the-markdown.patch %ifarch %{ix86} x86_64 aarch64 %global have_gnu_efi 1 @@ -1630,6 +1659,37 @@ fi %files tests -f .file-list-tests %changelog +* Tue Aug 22 2023 systemd maintenance team - 239-78 +- login: add a missing error check for session_set_leader() (#2158167) +- logind: reset session leader if we know for a fact that it is gone (#2158167) +- test-login: skip consistency checks when logind is not active (#2223582) +- sd-event: remove dead code and use _cleanup_ (#2211358) +- sd-event: don't destroy inotify data structures from inotify event handler (#2211358) +- sd-event: add sd_event_add_inotify_fd() call (#2211358) +- test: add test case for self-destroy inotify handler (#2211358) +- doc: add downstream CONTRIBUTING document (#2179309) +- doc: use link with prefilled Jira issue (#2179309) +- docs: link downstream CONTRIBUTING in README (#2179309) +- unit drop-in: Fix ordering of special type.d drop-ins (#2156620) +- Add failing test to show service.d global drop-in does not get overridden by more specific dropins (#2156620) +- test: set indentation to 4 spaces (#2156620) +- test/TEST-15: remove all created unit files (#2156620) +- test: use quotes where necessary (#2156620) +- tree-wide: drop manually-crafted message for missing variables (#2156620) +- manager: reformat boolean expression in unit_is_pristine() (#2156620) +- manager: allow transient units to have drop-ins (#2156620) +- TEST-15: allow helper functions to accept other unit types (#2156620) +- TEST-15: also test hierarchical drop-ins for slices (#2156620) +- TEST-15: add test for transient units with drop-ins (#2156620) +- TEST-15: add one more test for drop-in precedence (#2156620) +- udev/net_id: introduce naming scheme for RHEL-8.9 (#2231846) +- meson: remove libdw dependency from pstore (#2211416) +- pstore: introduce tmpfiles.d/systemd-pstore.conf (#2211416) +- tmpfiles: don't complain if we can't enable pstore in containers (#2211416) +- pstore: don't enable crash_kexec_post_notifiers by default (#2211416) +- core: when Delegate=yes is set for a unit, run ExecStartPre= and friends in a subcgroup of the unit (#2215925) +- man: link Delegate= documentation up with the markdown docs (#2215925) + * Mon Jul 17 2023 systemd maintenance team - 239-77 - ci: update permissions for source-git automation workflows (#2179309) - sulogin: fix control lost of the current terminal when default.target is rescue.target (#2169932)