From 4262b837d63cf58414bca94ff92443dc11347cde Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Sep 13 2022 07:41:26 +0000 Subject: import systemd-239-58.el8_6.7 --- diff --git a/SOURCES/0758-sd-event-don-t-invalidate-source-type-on-disconnect.patch b/SOURCES/0758-sd-event-don-t-invalidate-source-type-on-disconnect.patch new file mode 100644 index 0000000..e10016b --- /dev/null +++ b/SOURCES/0758-sd-event-don-t-invalidate-source-type-on-disconnect.patch @@ -0,0 +1,33 @@ +From 42c620347c8252675def5a2ce96dc8f5d090f0c7 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 30 Oct 2019 16:37:42 +0100 +Subject: [PATCH] sd-event: don't invalidate source type on disconnect + +This fixes fd closing if fd ownership is requested. + +(cherry picked from commit f59825595182d70b9ead238d1e885d0db99cc201) + +Resolves: #2116892 +--- + src/libsystemd/sd-event/sd-event.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 0adfdd9e1a..09d4584bf9 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -1104,11 +1104,13 @@ static void source_disconnect(sd_event_source *s) { + + event = s->event; + +- s->type = _SOURCE_EVENT_SOURCE_TYPE_INVALID; + s->event = NULL; + LIST_REMOVE(sources, event->sources, s); + event->n_sources--; + ++ /* Note that we don't invalidate the type here, since we still need it in order to close the fd or ++ * pidfd associated with this event source, which we'll do only on source_free(). */ ++ + if (!s->floating) + sd_event_unref(event); + } diff --git a/SOURCES/0759-test-procfs-util-skip-test-on-certain-errors.patch b/SOURCES/0759-test-procfs-util-skip-test-on-certain-errors.patch new file mode 100644 index 0000000..49398db --- /dev/null +++ b/SOURCES/0759-test-procfs-util-skip-test-on-certain-errors.patch @@ -0,0 +1,77 @@ +From 1521040d1e77aeed7f9d3a3ececf271ca1a5f1b5 Mon Sep 17 00:00:00 2001 +From: Lukas Nykryn +Date: Thu, 18 Aug 2022 16:35:23 +0200 +Subject: [PATCH] test-procfs-util: skip test on certain errors + +Inspired by upstream bf47f71c1c + +(cherry picked from commit 33305c6801c10b741b11a3f329dc339d2e8c5514) + +RHEL-only +Related: #2087152 +--- + src/shared/tests.c | 12 ++++++++++++ + src/shared/tests.h | 2 ++ + src/test/test-procfs-util.c | 6 ++++-- + 3 files changed, 18 insertions(+), 2 deletions(-) + +diff --git a/src/shared/tests.c b/src/shared/tests.c +index 1da80d653f..b1c71b992f 100644 +--- a/src/shared/tests.c ++++ b/src/shared/tests.c +@@ -78,6 +78,18 @@ void test_setup_logging(int level) { + log_open(); + } + ++int log_tests_skipped(const char *message) { ++ log_notice("%s: %s, skipping tests.", ++ program_invocation_short_name, message); ++ return EXIT_TEST_SKIP; ++} ++ ++int log_tests_skipped_errno(int r, const char *message) { ++ log_notice_errno(r, "%s: %s, skipping tests: %m", ++ program_invocation_short_name, message); ++ return EXIT_TEST_SKIP; ++} ++ + const char *ci_environment(void) { + /* We return a string because we might want to provide multiple bits of information later on: not + * just the general CI environment type, but also whether we're sanitizing or not, etc. The caller is +diff --git a/src/shared/tests.h b/src/shared/tests.h +index 4f8f349097..d50711338c 100644 +--- a/src/shared/tests.h ++++ b/src/shared/tests.h +@@ -5,6 +5,8 @@ char* setup_fake_runtime_dir(void); + bool test_is_running_from_builddir(char **exedir); + const char* get_testdata_dir(void); + void test_setup_logging(int level); ++int log_tests_skipped(const char *message); ++int log_tests_skipped_errno(int r, const char *message); + + /* Provide a convenient way to check if we're running in CI. */ + const char *ci_environment(void); +diff --git a/src/test/test-procfs-util.c b/src/test/test-procfs-util.c +index d656c4df4f..aba5692e54 100644 +--- a/src/test/test-procfs-util.c ++++ b/src/test/test-procfs-util.c +@@ -7,6 +7,7 @@ + #include "procfs-util.h" + #include "process-util.h" + #include "util.h" ++#include "tests.h" + + int main(int argc, char *argv[]) { + char buf[CONST_MAX(FORMAT_TIMESPAN_MAX, FORMAT_BYTES_MAX)]; +@@ -52,8 +53,9 @@ int main(int argc, char *argv[]) { + log_info("Reducing limit by one to %"PRIu64"…", v-1); + + r = procfs_tasks_set_limit(v-1); +- log_info_errno(r, "procfs_tasks_set_limit: %m"); +- assert_se(r >= 0 || ERRNO_IS_PRIVILEGE(r) || r == -EROFS); ++ if (IN_SET(r, -ENOENT, -EROFS) || ERRNO_IS_PRIVILEGE(r)) ++ return log_tests_skipped_errno(r, "can't set tasks limit"); ++ assert_se(r >= 0); + + assert_se(procfs_get_threads_max(&w) >= 0); + assert_se(r >= 0 ? w == v - 1 : w == v); diff --git a/SOURCES/0760-Try-stopping-MD-RAID-devices-in-shutdown-too.patch b/SOURCES/0760-Try-stopping-MD-RAID-devices-in-shutdown-too.patch new file mode 100644 index 0000000..2275b8d --- /dev/null +++ b/SOURCES/0760-Try-stopping-MD-RAID-devices-in-shutdown-too.patch @@ -0,0 +1,292 @@ +From 53d80a42f7077a087b976f7dfcdb34f107f2ce69 Mon Sep 17 00:00:00 2001 +From: Hubert Kario +Date: Sun, 20 Sep 2020 18:59:58 +0200 +Subject: [PATCH] Try stopping MD RAID devices in shutdown too + +Currently the systemd-shutdown command attempts to stop swaps, DM +(crypt, LVM2) and loop devices, but it doesn't attempt to stop MD +RAID devices, which means that if the RAID is set up on crypt, +loop, etc. device, it won't be able to stop those underlying devices. + +This code extends the shutdown application to also attempt stopping +the MD RAID devices. + +Signed-off-by: Hubert Kario +(cherry picked from commit 0b220a5f2a31844eaa1f5426bab02d41d54f471c) + +Resolves: #2120608 +--- + src/core/shutdown.c | 37 +++++++++---- + src/core/umount.c | 125 ++++++++++++++++++++++++++++++++++++++++++++ + src/core/umount.h | 2 + + 3 files changed, 154 insertions(+), 10 deletions(-) + +diff --git a/src/core/shutdown.c b/src/core/shutdown.c +index 038345b752..b8a983986a 100644 +--- a/src/core/shutdown.c ++++ b/src/core/shutdown.c +@@ -251,7 +251,7 @@ static void sync_with_progress(void) { + } + + int main(int argc, char *argv[]) { +- bool need_umount, need_swapoff, need_loop_detach, need_dm_detach; ++ bool need_umount, need_swapoff, need_loop_detach, need_dm_detach, need_md_detach; + bool in_container, use_watchdog = false, can_initrd; + _cleanup_free_ char *cgroup = NULL; + char *arguments[3]; +@@ -331,6 +331,7 @@ int main(int argc, char *argv[]) { + need_swapoff = !in_container; + need_loop_detach = !in_container; + need_dm_detach = !in_container; ++ need_md_detach = !in_container; + can_initrd = !in_container && !in_initrd() && access("/run/initramfs/shutdown", X_OK) == 0; + + /* Unmount all mountpoints, swaps, and loopback devices */ +@@ -383,6 +384,18 @@ int main(int argc, char *argv[]) { + log_error_errno(r, "Failed to detach loop devices: %m"); + } + ++ if (need_md_detach) { ++ log_info("Stopping MD devices."); ++ r = md_detach_all(&changed, umount_log_level); ++ if (r == 0) { ++ need_md_detach = false; ++ log_info("All MD devices stopped."); ++ } else if (r > 0) ++ log_info("Not all MD devices stopped, %d left.", r); ++ else ++ log_error_errno(r, "Failed to stop MD devices: %m"); ++ } ++ + if (need_dm_detach) { + log_info("Detaching DM devices."); + r = dm_detach_all(&changed, umount_log_level); +@@ -395,8 +408,9 @@ int main(int argc, char *argv[]) { + log_error_errno(r, "Failed to detach DM devices: %m"); + } + +- if (!need_umount && !need_swapoff && !need_loop_detach && !need_dm_detach) { +- log_info("All filesystems, swaps, loop devices and DM devices detached."); ++ if (!need_umount && !need_swapoff && !need_loop_detach && !need_dm_detach ++ && !need_md_detach) { ++ log_info("All filesystems, swaps, loop devices, MD devices and DM devices detached."); + /* Yay, done */ + break; + } +@@ -414,19 +428,21 @@ int main(int argc, char *argv[]) { + /* If in this iteration we didn't manage to + * unmount/deactivate anything, we simply give up */ + if (!changed) { +- log_info("Cannot finalize remaining%s%s%s%s continuing.", ++ log_info("Cannot finalize remaining%s%s%s%s%s continuing.", + need_umount ? " file systems," : "", + need_swapoff ? " swap devices," : "", + need_loop_detach ? " loop devices," : "", +- need_dm_detach ? " DM devices," : ""); ++ need_dm_detach ? " DM devices," : "", ++ need_md_detach ? " MD devices," : ""); + break; + } + +- log_debug("Couldn't finalize remaining %s%s%s%s trying again.", ++ log_debug("Couldn't finalize remaining %s%s%s%s%s trying again.", + need_umount ? " file systems," : "", + need_swapoff ? " swap devices," : "", + need_loop_detach ? " loop devices," : "", +- need_dm_detach ? " DM devices," : ""); ++ need_dm_detach ? " DM devices," : "", ++ need_md_detach ? " MD devices," : ""); + } + + /* We're done with the watchdog. */ +@@ -455,12 +471,13 @@ int main(int argc, char *argv[]) { + + } + +- if (need_umount || need_swapoff || need_loop_detach || need_dm_detach) +- log_error("Failed to finalize %s%s%s%s ignoring", ++ if (need_umount || need_swapoff || need_loop_detach || need_dm_detach || need_md_detach) ++ log_error("Failed to finalize%s%s%s%s%s ignoring.", + need_umount ? " file systems," : "", + need_swapoff ? " swap devices," : "", + need_loop_detach ? " loop devices," : "", +- need_dm_detach ? " DM devices," : ""); ++ need_dm_detach ? " DM devices," : "", ++ need_md_detach ? " MD devices," : ""); + + /* The kernel will automatically flush ATA disks and suchlike on reboot(), but the file systems need to be + * sync'ed explicitly in advance. So let's do this here, but not needlessly slow down containers. Note that we +diff --git a/src/core/umount.c b/src/core/umount.c +index 3f02bf141a..ed90c6b1fc 100644 +--- a/src/core/umount.c ++++ b/src/core/umount.c +@@ -5,6 +5,8 @@ + + #include + #include ++#include ++#include + #include + #include + #include +@@ -332,6 +334,66 @@ static int dm_list_get(MountPoint **head) { + return 0; + } + ++static int md_list_get(MountPoint **head) { ++ _cleanup_(udev_enumerate_unrefp) struct udev_enumerate *e = NULL; ++ struct udev_list_entry *item = NULL, *first = NULL; ++ _cleanup_(udev_unrefp) struct udev *udev = NULL; ++ int r; ++ ++ assert(head); ++ ++ udev = udev_new(); ++ if (!udev) ++ return -ENOMEM; ++ ++ e = udev_enumerate_new(udev); ++ if (!e) ++ return -ENOMEM; ++ ++ r = udev_enumerate_add_match_subsystem(e, "block"); ++ if (r < 0) ++ return r; ++ ++ r = udev_enumerate_add_match_sysname(e, "md*"); ++ if (r < 0) ++ return r; ++ ++ first = udev_enumerate_get_list_entry(e); ++ udev_list_entry_foreach(item, first) { ++ _cleanup_(udev_device_unrefp) struct udev_device *d; ++ _cleanup_free_ char *p = NULL; ++ const char *dn; ++ MountPoint *m; ++ dev_t devnum; ++ ++ d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)); ++ if (!d) ++ return -ENOMEM; ++ ++ devnum = udev_device_get_devnum(d); ++ dn = udev_device_get_devnode(d); ++ if (major(devnum) == 0 || !dn) ++ continue; ++ ++ p = strdup(dn); ++ if (!p) ++ return -ENOMEM; ++ ++ m = new(MountPoint, 1); ++ if (!m) ++ return -ENOMEM; ++ ++ *m = (MountPoint) { ++ .path = TAKE_PTR(p), ++ .devnum = devnum, ++ }; ++ ++ LIST_PREPEND(mount_point, *head, m); ++ } ++ ++ return 0; ++} ++ + static int delete_loopback(const char *device) { + _cleanup_close_ int fd = -1; + int r; +@@ -379,6 +441,23 @@ static int delete_dm(dev_t devnum) { + return 0; + } + ++static int delete_md(MountPoint *m) { ++ ++ _cleanup_close_ int fd = -1; ++ ++ assert(major(m->devnum) != 0); ++ assert(m->path != 0); ++ ++ fd = open(m->path, O_RDONLY|O_CLOEXEC|O_EXCL); ++ if (fd < 0) ++ return -errno; ++ ++ if (ioctl(fd, STOP_ARRAY, NULL) < 0) ++ return -errno; ++ ++ return 0; ++} ++ + static bool nonunmountable_path(const char *path) { + return path_equal(path, "/") + #if ! HAVE_SPLIT_USR +@@ -618,6 +697,37 @@ static int dm_points_list_detach(MountPoint **head, bool *changed, int umount_lo + return n_failed; + } + ++static int md_points_list_detach(MountPoint **head, bool *changed, int umount_log_level) { ++ MountPoint *m, *n; ++ int n_failed = 0, r; ++ dev_t rootdev = 0; ++ ++ assert(head); ++ assert(changed); ++ ++ (void) get_block_device("/", &rootdev); ++ ++ LIST_FOREACH_SAFE(mount_point, m, n, *head) { ++ if (major(rootdev) != 0 && rootdev == m->devnum) { ++ n_failed ++; ++ continue; ++ } ++ ++ log_info("Stopping MD %s (%u:%u).", m->path, major(m->devnum), minor(m->devnum)); ++ r = delete_md(m); ++ if (r < 0) { ++ log_full_errno(umount_log_level, r, "Could not stop MD %s: %m", m->path); ++ n_failed++; ++ continue; ++ } ++ ++ *changed = true; ++ mount_point_free(head, m); ++ } ++ ++ return n_failed; ++} ++ + static int umount_all_once(bool *changed, int umount_log_level) { + int r; + _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, mp_list_head); +@@ -696,3 +806,18 @@ int dm_detach_all(bool *changed, int umount_log_level) { + + return dm_points_list_detach(&dm_list_head, changed, umount_log_level); + } ++ ++int md_detach_all(bool *changed, int umount_log_level) { ++ _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, md_list_head); ++ int r; ++ ++ assert(changed); ++ ++ LIST_HEAD_INIT(md_list_head); ++ ++ r = md_list_get(&md_list_head); ++ if (r < 0) ++ return r; ++ ++ return md_points_list_detach(&md_list_head, changed, umount_log_level); ++} +diff --git a/src/core/umount.h b/src/core/umount.h +index 6f2b24d195..b01062484f 100644 +--- a/src/core/umount.h ++++ b/src/core/umount.h +@@ -15,6 +15,8 @@ int loopback_detach_all(bool *changed, int umount_log_level); + + int dm_detach_all(bool *changed, int umount_log_level); + ++int md_detach_all(bool *changed, int umount_log_level); ++ + /* This is exported just for testing */ + typedef struct MountPoint { + char *path; diff --git a/SOURCES/0761-shutdown-get-only-active-md-arrays.patch b/SOURCES/0761-shutdown-get-only-active-md-arrays.patch new file mode 100644 index 0000000..656bea7 --- /dev/null +++ b/SOURCES/0761-shutdown-get-only-active-md-arrays.patch @@ -0,0 +1,70 @@ +From e95632fbed66da97cbca7e9d4ee60fd60387c5dd Mon Sep 17 00:00:00 2001 +From: Mariusz Tkaczyk +Date: Tue, 29 Mar 2022 12:49:54 +0200 +Subject: [PATCH] shutdown: get only active md arrays. + +Current md_list_get() implementation filters all block devices, started from +"md*". This is ambiguous because list could contain: +- partitions created upon md device (mdXpY) +- external metadata container- specific type of md array. + +For partitions there is no issue, because they aren't handle STOP_ARRAY +ioctl sent later. It generates misleading errors only. + +Second case is more problematic because containers are not locked in kernel. +They are stopped even if container member array is active. For that reason +reboot or shutdown flow could be blocked because metadata manager cannot be +restarted after switch root on shutdown. + +Add filters to remove partitions and containers from md_list. Partitions +can be excluded by DEVTYPE. Containers are determined by MD_LEVEL +property, we are excluding all with "container" value. + +Signed-off-by: Mariusz Tkaczyk +(cherry picked from commit 3a3b022d2cc112803ea7b9beea98bbcad110368a) + +Related: #2120608 +--- + src/core/umount.c | 18 +++++++++++++++++- + 1 file changed, 17 insertions(+), 1 deletion(-) + +diff --git a/src/core/umount.c b/src/core/umount.c +index ed90c6b1fc..b513e91c4d 100644 +--- a/src/core/umount.c ++++ b/src/core/umount.c +@@ -358,11 +358,16 @@ static int md_list_get(MountPoint **head) { + if (r < 0) + return r; + ++ /* Filter out partitions. */ ++ r = udev_enumerate_add_match_property(e, "DEVTYPE", "disk"); ++ if (r < 0) ++ return r; ++ + first = udev_enumerate_get_list_entry(e); + udev_list_entry_foreach(item, first) { + _cleanup_(udev_device_unrefp) struct udev_device *d; + _cleanup_free_ char *p = NULL; +- const char *dn; ++ const char *dn, *md_level; + MountPoint *m; + dev_t devnum; + +@@ -375,6 +380,17 @@ static int md_list_get(MountPoint **head) { + if (major(devnum) == 0 || !dn) + continue; + ++ md_level = udev_device_get_property_value(d, "MD_LEVEL"); ++ if (!m) { ++ log_warning("Failed to get MD_LEVEL property for %s, ignoring", dn); ++ continue; ++ } ++ ++ /* MD "containers" are a special type of MD devices, used for external metadata. ++ * Since it doesn't provide RAID functionality in itself we don't need to stop it. */ ++ if (streq(md_level, "container")) ++ continue; ++ + p = strdup(dn); + if (!p) + return -ENOMEM; diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec index 9c08bb1..605bd40 100644 --- a/SPECS/systemd.spec +++ b/SPECS/systemd.spec @@ -13,7 +13,7 @@ Name: systemd Url: http://www.freedesktop.org/wiki/Software/systemd Version: 239 -Release: 58%{?dist}.4 +Release: 58%{?dist}.7 # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: System and Service Manager @@ -807,6 +807,10 @@ Patch0754: 0754-core-Move-r-variable-declaration-to-start-of-unit_st.patch Patch0755: 0755-core-Delay-start-rate-limit-check-when-starting-a-un.patch Patch0756: 0756-core-Propagate-condition-failed-state-to-triggering-.patch Patch0757: 0757-unit-check-for-mount-rate-limiting-before-checking-a.patch +Patch0758: 0758-sd-event-don-t-invalidate-source-type-on-disconnect.patch +Patch0759: 0759-test-procfs-util-skip-test-on-certain-errors.patch +Patch0760: 0760-Try-stopping-MD-RAID-devices-in-shutdown-too.patch +Patch0761: 0761-shutdown-get-only-active-md-arrays.patch Patch9000: 9000-resolved-pin-stream-while-calling-callbacks-for-it.patch @@ -1438,6 +1442,12 @@ fi %files tests -f .file-list-tests %changelog +* Thu Aug 25 2022 systemd maintenance team - 239-58.7 +- sd-event: don't invalidate source type on disconnect (#2116892) +- test-procfs-util: skip test on certain errors (#2087152) +- Try stopping MD RAID devices in shutdown too (#2120608) +- shutdown: get only active md arrays. (#2120608) + * Wed Aug 03 2022 systemd maintenance team - 239-58.4 - resolved: pin stream while calling callbacks for it (#2110548)