diff --git a/0657-sd-hwdb-allow-empty-properties.patch b/0637-sd-hwdb-allow-empty-properties.patch similarity index 94% rename from 0657-sd-hwdb-allow-empty-properties.patch rename to 0637-sd-hwdb-allow-empty-properties.patch index dde42396df7e6410b75cdc386e414e32ef00847e..57a0575e5a47244aec9a4f16071b302a5e394306 100644 --- a/0657-sd-hwdb-allow-empty-properties.patch +++ b/0637-sd-hwdb-allow-empty-properties.patch @@ -1,4 +1,4 @@ -From cd407514366a2ec2c32ebc7a5b405d37005456fd Mon Sep 17 00:00:00 2001 +From 2ab6e6ae9853e410310268efc0cea7f2276979ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 20 Oct 2020 17:12:42 +0200 Subject: [PATCH] sd-hwdb: allow empty properties @@ -9,7 +9,7 @@ override properties (back to the empty) value for specific cases. (cherry picked from commit afe87974dd57741f74dd87165b251886f24c859f) -Related: #1930568 +Related: #2005009 --- src/hwdb/hwdb.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/0658-Update-hwdb.patch b/0638-Update-hwdb.patch similarity index 99% rename from 0658-Update-hwdb.patch rename to 0638-Update-hwdb.patch index c95129753a66326ec51bb6fd0939c1f7985e32be..f189fab6bb3353c9148f001f6a95255b2f1ea2c4 100644 --- a/0658-Update-hwdb.patch +++ b/0638-Update-hwdb.patch @@ -1,9 +1,9 @@ -From a02798d09681906096cfb8f0f3997b535bb6a06d Mon Sep 17 00:00:00 2001 +From 793dc4d9e32baba27eac1f37283a7485b0889803 Mon Sep 17 00:00:00 2001 From: David Tardon Date: Thu, 19 Aug 2021 12:31:36 +0200 Subject: [PATCH] Update hwdb -Resolves: #1930568 +Resolves: #2005009 --- hwdb/20-OUI.hwdb | 26574 +++++++++++++++++- hwdb/20-acpi-vendor.hwdb | 257 +- diff --git a/0639-Disable-libpitc-to-fix-CentOS-Stream-CI.patch b/0639-Disable-libpitc-to-fix-CentOS-Stream-CI.patch new file mode 100644 index 0000000000000000000000000000000000000000..28f4c2434a7f8a1b2ef7909322dc4916c555bedf --- /dev/null +++ b/0639-Disable-libpitc-to-fix-CentOS-Stream-CI.patch @@ -0,0 +1,26 @@ +From b029865ef6d8b23ecdbfda4e277a3f75cb59ee94 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Mon, 25 Oct 2021 15:27:27 +0200 +Subject: [PATCH] Disable libpitc to fix CentOS Stream CI + +We have disabled it in our spec starting with 8.5.0, so let's follow +suit here. + +Related: #2017033 +--- + .github/workflows/unit_tests.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/unit_tests.sh b/.github/workflows/unit_tests.sh +index ad4584ec1d..def38bffe2 100755 +--- a/.github/workflows/unit_tests.sh ++++ b/.github/workflows/unit_tests.sh +@@ -50,7 +50,7 @@ CONFIGURE_OPTS=( + -Dgnutls=true + -Dmicrohttpd=true + -Dlibidn2=true +- -Dlibiptc=true ++ -Dlibiptc=false + -Dlibcurl=true + -Defi=true + -Dtpm=true diff --git a/0640-rpm-Fix-typo-in-_environmentdir.patch b/0640-rpm-Fix-typo-in-_environmentdir.patch new file mode 100644 index 0000000000000000000000000000000000000000..150dcd40adbf64fe10a052333f7954902bf79706 --- /dev/null +++ b/0640-rpm-Fix-typo-in-_environmentdir.patch @@ -0,0 +1,25 @@ +From 74cbe4b73a1dbb1113c822690561b8b41b2fb60a Mon Sep 17 00:00:00 2001 +From: Neal Gompa +Date: Mon, 25 Jun 2018 12:56:50 -0400 +Subject: [PATCH] rpm: Fix typo in %_environmentdir + +Signed-off-by: Neal Gompa +(cherry picked from commit 6ea4cb975f99cdfd447332ffa9631790a5975eea) +Resolves: #2018024 +--- + src/core/macros.systemd.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/macros.systemd.in b/src/core/macros.systemd.in +index f3b74f4273..a24d7bbe58 100644 +--- a/src/core/macros.systemd.in ++++ b/src/core/macros.systemd.in +@@ -18,7 +18,7 @@ + %_sysctldir @sysctldir@ + %_sysusersdir @sysusersdir@ + %_tmpfilesdir @tmpfilesdir@ +-%_environmnentdir @environmentdir@ ++%_environmentdir @environmentdir@ + %_modulesloaddir @modulesloaddir@ + %_modprobedir @modprobedir@ + %_systemdgeneratordir @systemgeneratordir@ diff --git a/0641-rpm-Add-misspelled-_environmentdir-macro-for-tempora.patch b/0641-rpm-Add-misspelled-_environmentdir-macro-for-tempora.patch new file mode 100644 index 0000000000000000000000000000000000000000..9c01b95a411e2b4476b7217eb1b885f415a3d975 --- /dev/null +++ b/0641-rpm-Add-misspelled-_environmentdir-macro-for-tempora.patch @@ -0,0 +1,30 @@ +From 7b2d5268cf43a4ed7847bdbed2328bccddd5a716 Mon Sep 17 00:00:00 2001 +From: Neal Gompa +Date: Tue, 26 Jun 2018 07:42:29 -0400 +Subject: [PATCH] rpm: Add misspelled %_environmentdir macro for temporary + compatibility + +This should be removed after systemd 240 is released. + +Signed-off-by: Neal Gompa +(cherry picked from commit a6bb5504583e3267d35fa385fe20f60fd998ca5d) +Related: #2018024 +--- + src/core/macros.systemd.in | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/src/core/macros.systemd.in b/src/core/macros.systemd.in +index a24d7bbe58..abbb42b22f 100644 +--- a/src/core/macros.systemd.in ++++ b/src/core/macros.systemd.in +@@ -26,6 +26,10 @@ + %_systemd_system_env_generator_dir @systemenvgeneratordir@ + %_systemd_user_env_generator_dir @userenvgeneratordir@ + ++# Because we had one release with a typo... ++# This is temporary (Remove after systemd 240 is released) ++%_environmnentdir %_environmentdir ++ + %systemd_requires \ + Requires(post): systemd \ + Requires(preun): systemd \ diff --git a/0642-rpm-emit-warning-when-macro-with-typo-is-used.patch b/0642-rpm-emit-warning-when-macro-with-typo-is-used.patch new file mode 100644 index 0000000000000000000000000000000000000000..beca14798ffa27fd0cbe03c5f972bb1b5d407fde --- /dev/null +++ b/0642-rpm-emit-warning-when-macro-with-typo-is-used.patch @@ -0,0 +1,32 @@ +From 4d994a262ec1ad3e33e197cb09aa5aeabb5835dd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 3 Jul 2018 15:40:53 +0200 +Subject: [PATCH] rpm: emit warning when macro with typo is used + +Follow-up for a6bb550458. Suggested by @ignatenkobrain. + +$ rpmbuild --eval %_environmentdir +/usr/lib/environment.d +$ rpmbuild --eval %_environmnentdir +warning: Use %_environmentdir instead +/usr/lib/environment.d + +(cherry picked from commit be9bf171bbf764997551f8a9b3c2aba5c6a875d3) +Related: #2018024 +--- + src/core/macros.systemd.in | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/macros.systemd.in b/src/core/macros.systemd.in +index abbb42b22f..fe7ca26a34 100644 +--- a/src/core/macros.systemd.in ++++ b/src/core/macros.systemd.in +@@ -28,7 +28,7 @@ + + # Because we had one release with a typo... + # This is temporary (Remove after systemd 240 is released) +-%_environmnentdir %_environmentdir ++%_environmnentdir %{warn:Use %%_environmentdir instead}%_environmentdir + + %systemd_requires \ + Requires(post): systemd \ diff --git a/0643-Remove-unintended-additions-to-systemd-analyze-man-p.patch b/0643-Remove-unintended-additions-to-systemd-analyze-man-p.patch new file mode 100644 index 0000000000000000000000000000000000000000..0021bdb2b9ab347f5e29f04894a5ae3a55719102 --- /dev/null +++ b/0643-Remove-unintended-additions-to-systemd-analyze-man-p.patch @@ -0,0 +1,75 @@ +From f29b7bcd85d4e8d824d36fecc130a0d74af718f8 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Tue, 12 Oct 2021 16:47:48 +0200 +Subject: [PATCH] Remove unintended additions to systemd-analyze man page + +These changes were introduced in commit +a2e00522971897909db2a81b4daf10e5700f453e . + +Resolves: #2004765 +--- + man/systemd-analyze.xml | 51 +---------------------------------------- + 1 file changed, 1 insertion(+), 50 deletions(-) + +diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml +index 7c873cbdd1..e17ff0cf90 100644 +--- a/man/systemd-analyze.xml ++++ b/man/systemd-analyze.xml +@@ -354,56 +354,7 @@ $ eog targets.svg + they elapse next. This takes the same input as the OnCalendar= setting in + systemd.timer5, + following the syntax described in +- systemd.time7. By +- default, only the next time the calendar expression will elapse is shown; use +- to show the specified number of next times the expression +- elapses. +- +- +- Show leap days in the near future +- +- $ systemd-analyze calendar --iterations=5 '*-2-29 0:0:0' +- Original form: *-2-29 0:0:0 +-Normalized form: *-02-29 00:00:00 +- Next elapse: Sat 2020-02-29 00:00:00 UTC +- From now: 11 months 15 days left +- Iter. #2: Thu 2024-02-29 00:00:00 UTC +- From now: 4 years 11 months left +- Iter. #3: Tue 2028-02-29 00:00:00 UTC +- From now: 8 years 11 months left +- Iter. #4: Sun 2032-02-29 00:00:00 UTC +- From now: 12 years 11 months left +- Iter. #5: Fri 2036-02-29 00:00:00 UTC +- From now: 16 years 11 months left +- +- +- +- +- +- <command>systemd-analyze timespan <replaceable>EXPRESSION</replaceable>...</command> +- +- This command parses a time span and outputs the normalized form and the equivalent value in +- microseconds. The time span should adhere to the same syntax documented in +- systemd.time7. +- Values without associated magnitudes are parsed as seconds. +- +- +- Show parsing of timespans +- +- $ systemd-analyze timespan 1s 300s '1year 0.000001s' +-Original: 1s +- μs: 1000000 +- Human: 1s +- +-Original: 300s +- μs: 300000000 +- Human: 5min +- +-Original: 1year 0.000001s +- μs: 31557600000001 +- Human: 1y 1us +- +- ++ systemd.time7. + + + diff --git a/0644-Disable-iptables-for-CI.patch b/0644-Disable-iptables-for-CI.patch new file mode 100644 index 0000000000000000000000000000000000000000..a479a5829637b3cb6e3539700f7327d8fb62dedc --- /dev/null +++ b/0644-Disable-iptables-for-CI.patch @@ -0,0 +1,21 @@ +From ffd20a699280a4732d0fe4cddafe12ee8010ddb6 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Wed, 13 Oct 2021 10:01:59 +0200 +Subject: [PATCH] Disable iptables for CI + +--- + .github/workflows/unit_tests.sh | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/.github/workflows/unit_tests.sh b/.github/workflows/unit_tests.sh +index def38bffe2..814870e7a0 100755 +--- a/.github/workflows/unit_tests.sh ++++ b/.github/workflows/unit_tests.sh +@@ -92,7 +92,6 @@ SYSTEMD_BUILD_DEPS=( + gnutls-devel + gobject-introspection-devel + gperf +- iptables-devel + kmod-devel + libacl-devel + libblkid-devel diff --git a/0645-core-fix-SIGABRT-on-empty-exec-command-argv.patch b/0645-core-fix-SIGABRT-on-empty-exec-command-argv.patch new file mode 100644 index 0000000000000000000000000000000000000000..4fead0e067139f13167f18ab6f7c5c56a75aad63 --- /dev/null +++ b/0645-core-fix-SIGABRT-on-empty-exec-command-argv.patch @@ -0,0 +1,103 @@ +From 8e322f5bc24547963978be071a8a2547abad875a Mon Sep 17 00:00:00 2001 +From: Henri Chain +Date: Tue, 5 Oct 2021 13:10:31 +0200 +Subject: [PATCH] core: fix SIGABRT on empty exec command argv + +This verifies that the argv part of any exec_command parameters that +are sent through dbus is not empty at deserialization time. + +There is an additional check in service.c service_verify() that again +checks if all exec_commands are correctly populated, after the service +has been loaded, whether through dbus or otherwise. + +Fixes #20933. + +(cherry picked from commit 29500cf8c47e6eb0518d171d62aa8213020c9152) + +Resolves: #2020239 +--- + src/core/dbus-execute.c | 4 ++++ + src/core/service.c | 12 +++++++++++ + test/TEST-23-TYPE-EXEC/testsuite.sh | 31 +++++++++++++++++++++++++++++ + 3 files changed, 47 insertions(+) + +diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c +index 8348663000..2e64f0baf4 100644 +--- a/src/core/dbus-execute.c ++++ b/src/core/dbus-execute.c +@@ -969,6 +969,10 @@ int bus_set_transient_exec_command( + if (r < 0) + return r; + ++ if (strv_isempty(argv)) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, ++ "\"%s\" argv cannot be empty", name); ++ + r = sd_bus_message_read(message, "b", &b); + if (r < 0) + return r; +diff --git a/src/core/service.c b/src/core/service.c +index 5e3e75b5ae..12adf89dd4 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -536,6 +536,18 @@ static int service_verify(Service *s) { + if (UNIT(s)->load_state != UNIT_LOADED) + return 0; + ++ for (ServiceExecCommand c = 0; c < _SERVICE_EXEC_COMMAND_MAX; c++) { ++ ExecCommand *command; ++ ++ LIST_FOREACH(command, command, s->exec_command[c]) ++ if (strv_isempty(command->argv)) { ++ log_unit_error(UNIT(s), ++ "Service has an empty argv in %s=. Refusing.", ++ service_exec_command_to_string(c)); ++ return -ENOEXEC; ++ } ++ } ++ + if (!s->exec_command[SERVICE_EXEC_START] && !s->exec_command[SERVICE_EXEC_STOP]) { + log_unit_error(UNIT(s), "Service lacks both ExecStart= and ExecStop= setting. Refusing."); + return -ENOEXEC; +diff --git a/test/TEST-23-TYPE-EXEC/testsuite.sh b/test/TEST-23-TYPE-EXEC/testsuite.sh +index 80734bbbdc..e0c34cfd04 100755 +--- a/test/TEST-23-TYPE-EXEC/testsuite.sh ++++ b/test/TEST-23-TYPE-EXEC/testsuite.sh +@@ -21,6 +21,37 @@ systemd-run --unit=four -p Type=exec /bin/sleep infinity + ! systemd-run --unit=five -p Type=exec -p User=idontexist /bin/sleep infinity + ! systemd-run --unit=six -p Type=exec /tmp/brokenbinary + ++# For issue #20933 ++ ++# Should work normally ++busctl call \ ++ org.freedesktop.systemd1 /org/freedesktop/systemd1 \ ++ org.freedesktop.systemd1.Manager StartTransientUnit \ ++ "ssa(sv)a(sa(sv))" test-20933-ok.service replace 1 \ ++ ExecStart "a(sasb)" 1 \ ++ /usr/bin/sleep 2 /usr/bin/sleep 1 true \ ++ 0 ++ ++# DBus call should fail but not crash systemd ++busctl call \ ++ org.freedesktop.systemd1 /org/freedesktop/systemd1 \ ++ org.freedesktop.systemd1.Manager StartTransientUnit \ ++ "ssa(sv)a(sa(sv))" test-20933-bad.service replace 1 \ ++ ExecStart "a(sasb)" 1 \ ++ /usr/bin/sleep 0 true \ ++ 0 && { echo 'unexpected success'; exit 1; } ++ ++# Same but with the empty argv in the middle ++busctl call \ ++ org.freedesktop.systemd1 /org/freedesktop/systemd1 \ ++ org.freedesktop.systemd1.Manager StartTransientUnit \ ++ "ssa(sv)a(sa(sv))" test-20933-bad-middle.service replace 1 \ ++ ExecStart "a(sasb)" 3 \ ++ /usr/bin/sleep 2 /usr/bin/sleep 1 true \ ++ /usr/bin/sleep 0 true \ ++ /usr/bin/sleep 2 /usr/bin/sleep 1 true \ ++ 0 && { echo 'unexpected success'; exit 1; } ++ + systemd-analyze set-log-level info + + echo OK > /testok diff --git a/0646-core-service-also-check-path-in-exec-commands.patch b/0646-core-service-also-check-path-in-exec-commands.patch new file mode 100644 index 0000000000000000000000000000000000000000..d887be68392be86dd81bf65e70debc5a0833c21e --- /dev/null +++ b/0646-core-service-also-check-path-in-exec-commands.patch @@ -0,0 +1,39 @@ +From 71ebbd2da606c9cb4da694bbcc925078f253f496 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 6 Oct 2021 00:19:41 +0900 +Subject: [PATCH] core/service: also check path in exec commands + +(cherry picked from commit 8688a389cabdff61efe187bb85cc1776de03c460) + +Related: #2020239 +--- + src/core/service.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/src/core/service.c b/src/core/service.c +index 12adf89dd4..ae31973774 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -539,13 +539,21 @@ static int service_verify(Service *s) { + for (ServiceExecCommand c = 0; c < _SERVICE_EXEC_COMMAND_MAX; c++) { + ExecCommand *command; + +- LIST_FOREACH(command, command, s->exec_command[c]) ++ LIST_FOREACH(command, command, s->exec_command[c]) { ++ if (!path_is_absolute(command->path) && !filename_is_valid(command->path)) { ++ log_unit_error(UNIT(s), ++ "Service %s= binary path \"%s\" is neither a valid executable name nor an absolute path. Refusing.", ++ command->path, ++ service_exec_command_to_string(c)); ++ return -ENOEXEC; ++ } + if (strv_isempty(command->argv)) { + log_unit_error(UNIT(s), + "Service has an empty argv in %s=. Refusing.", + service_exec_command_to_string(c)); + return -ENOEXEC; + } ++ } + } + + if (!s->exec_command[SERVICE_EXEC_START] && !s->exec_command[SERVICE_EXEC_STOP]) { diff --git a/0647-mount-util-fix-fd_is_mount_point-when-both-the-paren.patch b/0647-mount-util-fix-fd_is_mount_point-when-both-the-paren.patch new file mode 100644 index 0000000000000000000000000000000000000000..43206fe689d9d41e9ae4f640176f9a9c5a5ce11f --- /dev/null +++ b/0647-mount-util-fix-fd_is_mount_point-when-both-the-paren.patch @@ -0,0 +1,124 @@ +From 397aaad6da5c4bfb160adca7a68f865086f2ed0a Mon Sep 17 00:00:00 2001 +From: Franck Bui +Date: Thu, 30 Sep 2021 14:05:36 +0200 +Subject: [PATCH] mount-util: fix fd_is_mount_point() when both the parent and + directory are network fs + +The second call to name_to_handle_at_loop() didn't check for the specific +errors that can happen when the parent dir is mounted by nfs and instead of +falling back like it's done for the child dir, fd_is_mount_point() failed in +this case. + +(cherry picked from commit 964ccab8286a7e75d7e9107f574f5cb23752bd5d) + +Resolves: #2015057 +--- + src/basic/mount-util.c | 71 ++++++++++++++++++++++++------------------ + 1 file changed, 41 insertions(+), 30 deletions(-) + +diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c +index 45348bf878..0c709001be 100644 +--- a/src/basic/mount-util.c ++++ b/src/basic/mount-util.c +@@ -139,6 +139,19 @@ static int fd_fdinfo_mnt_id(int fd, const char *filename, int flags, int *mnt_id + return safe_atoi(p, mnt_id); + } + ++static bool is_name_to_handle_at_fatal_error(int err) { ++ /* name_to_handle_at() can return "acceptable" errors that are due to the context. For ++ * example the kernel does not support name_to_handle_at() at all (ENOSYS), or the syscall ++ * was blocked (EACCES/EPERM; maybe through seccomp, because we are running inside of a ++ * container), or the mount point is not triggered yet (EOVERFLOW, think nfs4), or some ++ * general name_to_handle_at() flakiness (EINVAL). However other errors are not supposed to ++ * happen and therefore are considered fatal ones. */ ++ ++ assert(err < 0); ++ ++ return !IN_SET(err, -EOPNOTSUPP, -ENOSYS, -EACCES, -EPERM, -EOVERFLOW, -EINVAL); ++} ++ + int fd_is_mount_point(int fd, const char *filename, int flags) { + _cleanup_free_ struct file_handle *h = NULL, *h_parent = NULL; + int mount_id = -1, mount_id_parent = -1; +@@ -173,42 +186,40 @@ int fd_is_mount_point(int fd, const char *filename, int flags) { + * real mounts of their own. */ + + r = name_to_handle_at_loop(fd, filename, &h, &mount_id, flags); +- if (IN_SET(r, -ENOSYS, -EACCES, -EPERM, -EOVERFLOW, -EINVAL)) +- /* This kernel does not support name_to_handle_at() at all (ENOSYS), or the syscall was blocked +- * (EACCES/EPERM; maybe through seccomp, because we are running inside of a container?), or the mount +- * point is not triggered yet (EOVERFLOW, think nfs4), or some general name_to_handle_at() flakiness +- * (EINVAL): fall back to simpler logic. */ +- goto fallback_fdinfo; +- else if (r == -EOPNOTSUPP) +- /* This kernel or file system does not support name_to_handle_at(), hence let's see if the upper fs +- * supports it (in which case it is a mount point), otherwise fallback to the traditional stat() +- * logic */ ++ if (r < 0) { ++ if (is_name_to_handle_at_fatal_error(r)) ++ return r; ++ if (r != -EOPNOTSUPP) ++ goto fallback_fdinfo; ++ ++ /* This kernel or file system does not support name_to_handle_at(), hence let's see ++ * if the upper fs supports it (in which case it is a mount point), otherwise fall ++ * back to the traditional stat() logic */ + nosupp = true; +- else if (r < 0) +- return r; ++ } + + r = name_to_handle_at_loop(fd, "", &h_parent, &mount_id_parent, AT_EMPTY_PATH); +- if (r == -EOPNOTSUPP) { ++ if (r < 0) { ++ if (is_name_to_handle_at_fatal_error(r)) ++ return r; ++ if (r != -EOPNOTSUPP) ++ goto fallback_fdinfo; + if (nosupp) +- /* Neither parent nor child do name_to_handle_at()? We have no choice but to fall back. */ ++ /* Both the parent and the directory can't do name_to_handle_at() */ + goto fallback_fdinfo; +- else +- /* The parent can't do name_to_handle_at() but the directory we are interested in can? If so, +- * it must be a mount point. */ +- return 1; +- } else if (r < 0) +- return r; + +- /* The parent can do name_to_handle_at() but the +- * directory we are interested in can't? If so, it +- * must be a mount point. */ ++ /* The parent can't do name_to_handle_at() but the directory we are ++ * interested in can? If so, it must be a mount point. */ ++ return 1; ++ } ++ ++ /* The parent can do name_to_handle_at() but the directory we are interested in can't? If ++ * so, it must be a mount point. */ + if (nosupp) + return 1; + +- /* If the file handle for the directory we are +- * interested in and its parent are identical, we +- * assume this is the root directory, which is a mount +- * point. */ ++ /* If the file handle for the directory we are interested in and its parent are identical, ++ * we assume this is the root directory, which is a mount point. */ + + if (h->handle_bytes == h_parent->handle_bytes && + h->handle_type == h_parent->handle_type && +@@ -300,10 +311,10 @@ int path_get_mnt_id(const char *path, int *ret) { + int r; + + r = name_to_handle_at_loop(AT_FDCWD, path, NULL, ret, 0); +- if (IN_SET(r, -EOPNOTSUPP, -ENOSYS, -EACCES, -EPERM, -EOVERFLOW, -EINVAL)) /* kernel/fs don't support this, or seccomp blocks access, or untriggered mount, or name_to_handle_at() is flaky */ +- return fd_fdinfo_mnt_id(AT_FDCWD, path, 0, ret); ++ if (r == 0 || is_name_to_handle_at_fatal_error(r)) ++ return r; + +- return r; ++ return fd_fdinfo_mnt_id(AT_FDCWD, path, 0, ret); + } + + int umount_recursive(const char *prefix, int flags) { diff --git a/0648-basic-add-vmware-hypervisor-detection-from-device-tr.patch b/0648-basic-add-vmware-hypervisor-detection-from-device-tr.patch new file mode 100644 index 0000000000000000000000000000000000000000..8685575773b59208e61e66b89cc0a80530748300 --- /dev/null +++ b/0648-basic-add-vmware-hypervisor-detection-from-device-tr.patch @@ -0,0 +1,28 @@ +From 537055fc407d7cff32ddd3414a6900ccff579c46 Mon Sep 17 00:00:00 2001 +From: Cyprien Laplace +Date: Thu, 14 Nov 2019 09:42:14 -0500 +Subject: [PATCH] basic: add vmware hypervisor detection from device-tree + +Allow ConditionVirtualization=vmware to work on ESXi on arm VMs +using device-tree. + +(cherry picked from commit 4d4ac92c928fcbc60b85fcbf8370af3883ee63db) + +Resolves: #1959150 +--- + src/basic/virt.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/basic/virt.c b/src/basic/virt.c +index 0b88005ed6..8d862b6d67 100644 +--- a/src/basic/virt.c ++++ b/src/basic/virt.c +@@ -122,6 +122,8 @@ static int detect_vm_device_tree(void) { + return VIRTUALIZATION_KVM; + else if (strstr(hvtype, "xen")) + return VIRTUALIZATION_XEN; ++ else if (strstr(hvtype, "vmware")) ++ return VIRTUALIZATION_VMWARE; + else + return VIRTUALIZATION_VM_OTHER; + #else diff --git a/0649-pam-do-not-require-a-non-expired-password-for-user-..patch b/0649-pam-do-not-require-a-non-expired-password-for-user-..patch new file mode 100644 index 0000000000000000000000000000000000000000..fdd68b2b3f30c79d1cbff412d49f16216d60dbc3 --- /dev/null +++ b/0649-pam-do-not-require-a-non-expired-password-for-user-..patch @@ -0,0 +1,45 @@ +From a677e477ef541d172ede2a5bd728a4ff1ffb312d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 1 Jun 2021 16:17:16 +0200 +Subject: [PATCH] pam: do not require a non-expired password for user@.service + +Without this parameter, we would allow user@ to start if the user +has no password (i.e. the password is "locked"). But when the user does have a password, +and it is marked as expired, we would refuse to start the service. +There are other authentication mechanisms and we should not tie this service to +the password state. + +The documented way to disable an *account* is to call 'chage -E0'. With a disabled +account, user@.service will still refuse to start: + +systemd[16598]: PAM failed: User account has expired +systemd[16598]: PAM failed: User account has expired +systemd[16598]: user@1005.service: Failed to set up PAM session: Operation not permitted +systemd[16598]: user@1005.service: Failed at step PAM spawning /usr/lib/systemd/systemd: Operation not permitted +systemd[1]: user@1005.service: Main process exited, code=exited, status=224/PAM +systemd[1]: user@1005.service: Failed with result 'exit-code'. +systemd[1]: Failed to start user@1005.service. +systemd[1]: Stopping user-runtime-dir@1005.service... + +Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1961746. + +(cherry picked from commit 71889176e4372b443018584c3520c1ff3efe2711) + +Resolves: #1961746 +--- + src/login/systemd-user.m4 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/login/systemd-user.m4 b/src/login/systemd-user.m4 +index 4f85b4b7fe..20c8999331 100644 +--- a/src/login/systemd-user.m4 ++++ b/src/login/systemd-user.m4 +@@ -2,7 +2,7 @@ + # + # Used by systemd --user instances. + +-account required pam_unix.so ++account sufficient pam_unix.so no_pass_expiry + m4_ifdef(`HAVE_SELINUX', + session required pam_selinux.so close + session required pam_selinux.so nottys open diff --git a/0650-udev-rules-add-rule-to-create-dev-ptp_hyperv.patch b/0650-udev-rules-add-rule-to-create-dev-ptp_hyperv.patch new file mode 100644 index 0000000000000000000000000000000000000000..75191914ede1835629cc103d66b6e2584f80dee0 --- /dev/null +++ b/0650-udev-rules-add-rule-to-create-dev-ptp_hyperv.patch @@ -0,0 +1,26 @@ +From c0e530dc95fa7842ec1a48fd5df98956a76ae26c Mon Sep 17 00:00:00 2001 +From: Luca Boccassi +Date: Fri, 26 Feb 2021 10:25:31 +0000 +Subject: [PATCH] udev rules: add rule to create /dev/ptp_hyperv + +As for the KVM case, necessary for network cards with +PTP devices when running a guest on HyperV + +(cherry picked from commit 32e868f058da8b90add00b2958c516241c532b70) + +Resolves: #1991834 +--- + rules/50-udev-default.rules.in | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/rules/50-udev-default.rules.in b/rules/50-udev-default.rules.in +index 191f56f42e..36657ce1a4 100644 +--- a/rules/50-udev-default.rules.in ++++ b/rules/50-udev-default.rules.in +@@ -83,4 +83,6 @@ KERNEL=="kvm", GROUP="kvm", MODE="@DEV_KVM_MODE@", OPTIONS+="static_node=kvm" + + SUBSYSTEM=="ptp", ATTR{clock_name}=="KVM virtual PTP", SYMLINK += "ptp_kvm" + ++SUBSYSTEM=="ptp", ATTR{clock_name}=="hyperv", SYMLINK += "ptp_hyperv" ++ + LABEL="default_end" diff --git a/0651-process-util-explicitly-handle-processes-lacking-par.patch b/0651-process-util-explicitly-handle-processes-lacking-par.patch new file mode 100644 index 0000000000000000000000000000000000000000..3dfb66a1c0ec5e27f6897633cc88dadd59a7e919 --- /dev/null +++ b/0651-process-util-explicitly-handle-processes-lacking-par.patch @@ -0,0 +1,223 @@ +From 9b30c003c8f80bf44f18168d07ea11c48e6d8864 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 7 Jul 2021 15:57:51 +0200 +Subject: [PATCH] process-util: explicitly handle processes lacking parents in + get_process_ppid() + +Let's make sure we signal out-of-band via an error message if a process +doesn't have a parent process whose PID we could return. Otherwise we'll +too likely hide errors, as we return an invalid PID 0, which in other +contexts has special meaning (i.e. usually "myself"). + +Replaces: #20153 + +This is based on work by @dtardon, but goes a different route, by +ensuring we propagate a proper error in this case. + +This modernizes the function in question a bit in other ways, i.e. +renames stuff and makes the return parameter optional. + +(cherry picked from commit 0c4d1e6d96a549054bfe0597d197f829838917f1) + +Resolves: #1977569 +--- + src/basic/process-util.c | 27 +++++++++++++------- + src/coredump/coredump.c | 23 +++++++++-------- + src/test/test-process-util.c | 48 +++++++++++++++++++++++++++++++++--- + 3 files changed, 74 insertions(+), 24 deletions(-) + +diff --git a/src/basic/process-util.c b/src/basic/process-util.c +index 0a4a747ba4..6016d83d41 100644 +--- a/src/basic/process-util.c ++++ b/src/basic/process-util.c +@@ -603,20 +603,23 @@ int get_process_environ(pid_t pid, char **env) { + return 0; + } + +-int get_process_ppid(pid_t pid, pid_t *_ppid) { +- int r; ++int get_process_ppid(pid_t pid, pid_t *ret) { + _cleanup_free_ char *line = NULL; + long unsigned ppid; + const char *p; ++ int r; + + assert(pid >= 0); +- assert(_ppid); + + if (pid == 0 || pid == getpid_cached()) { +- *_ppid = getppid(); ++ if (ret) ++ *ret = getppid(); + return 0; + } + ++ if (pid == 1) /* PID 1 has no parent, shortcut this case */ ++ return -EADDRNOTAVAIL; ++ + p = procfs_file_alloca(pid, "stat"); + r = read_one_line_file(p, &line); + if (r == -ENOENT) +@@ -624,9 +627,8 @@ int get_process_ppid(pid_t pid, pid_t *_ppid) { + if (r < 0) + return r; + +- /* Let's skip the pid and comm fields. The latter is enclosed +- * in () but does not escape any () in its value, so let's +- * skip over it manually */ ++ /* Let's skip the pid and comm fields. The latter is enclosed in () but does not escape any () in its ++ * value, so let's skip over it manually */ + + p = strrchr(line, ')'); + if (!p) +@@ -640,10 +642,17 @@ int get_process_ppid(pid_t pid, pid_t *_ppid) { + &ppid) != 1) + return -EIO; + +- if ((long unsigned) (pid_t) ppid != ppid) ++ /* If ppid is zero the process has no parent. Which might be the case for PID 1 but also for ++ * processes originating in other namespaces that are inserted into a pidns. Return a recognizable ++ * error in this case. */ ++ if (ppid == 0) ++ return -EADDRNOTAVAIL; ++ ++ if ((pid_t) ppid < 0 || (long unsigned) (pid_t) ppid != ppid) + return -ERANGE; + +- *_ppid = (pid_t) ppid; ++ if (ret) ++ *ret = (pid_t) ppid; + + return 0; + } +diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c +index 2a130e8838..fb3a6ecfe9 100644 +--- a/src/coredump/coredump.c ++++ b/src/coredump/coredump.c +@@ -591,8 +591,7 @@ static int get_process_ns(pid_t pid, const char *namespace, ino_t *ns) { + return 0; + } + +-static int get_mount_namespace_leader(pid_t pid, pid_t *container_pid) { +- pid_t cpid = pid, ppid = 0; ++static int get_mount_namespace_leader(pid_t pid, pid_t *ret) { + ino_t proc_mntns; + int r = 0; + +@@ -602,8 +601,12 @@ static int get_mount_namespace_leader(pid_t pid, pid_t *container_pid) { + + for (;;) { + ino_t parent_mntns; ++ pid_t ppid; + +- r = get_process_ppid(cpid, &ppid); ++ r = get_process_ppid(pid, &ppid); ++ if (r == -EADDRNOTAVAIL) /* Reached the top (i.e. typically PID 1, but could also be a process ++ * whose parent is not in our pidns) */ ++ return -ENOENT; + if (r < 0) + return r; + +@@ -611,17 +614,13 @@ static int get_mount_namespace_leader(pid_t pid, pid_t *container_pid) { + if (r < 0) + return r; + +- if (proc_mntns != parent_mntns) +- break; +- +- if (ppid == 1) +- return -ENOENT; ++ if (proc_mntns != parent_mntns) { ++ *ret = ppid; ++ return 0; ++ } + +- cpid = ppid; ++ pid = ppid; + } +- +- *container_pid = ppid; +- return 0; + } + + /* Returns 1 if the parent was found. +diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c +index 26e3247993..6b14ff592b 100644 +--- a/src/test/test-process-util.c ++++ b/src/test/test-process-util.c +@@ -19,6 +19,7 @@ + #include "macro.h" + #include "parse-util.h" + #include "process-util.h" ++#include "procfs-util.h" + #include "signal-util.h" + #include "stdio-util.h" + #include "string-util.h" +@@ -56,9 +57,12 @@ static void test_get_process_comm(pid_t pid) { + assert_se(get_process_cmdline(pid, 1, false, &d) >= 0); + log_info("PID"PID_FMT" cmdline truncated to 1: '%s'", pid, d); + +- assert_se(get_process_ppid(pid, &e) >= 0); +- log_info("PID"PID_FMT" PPID: "PID_FMT, pid, e); +- assert_se(pid == 1 ? e == 0 : e > 0); ++ r = get_process_ppid(pid, &e); ++ assert_se(pid == 1 ? r == -EADDRNOTAVAIL : r >= 0); ++ if (r >= 0) { ++ log_info("PID"PID_FMT" PPID: "PID_FMT, pid, e); ++ assert_se(e > 0); ++ } + + assert_se(is_kernel_thread(pid) == 0 || pid != 1); + +@@ -585,6 +589,43 @@ static void test_ioprio_class_from_to_string(void) { + test_ioprio_class_from_to_string_one("-1", -1); + } + ++static void test_get_process_ppid(void) { ++ uint64_t limit; ++ int r; ++ ++ log_info("/* %s */", __func__); ++ ++ assert_se(get_process_ppid(1, NULL) == -EADDRNOTAVAIL); ++ ++ /* the process with the PID above the global limit definitely doesn't exist. Verify that */ ++ assert_se(procfs_tasks_get_limit(&limit) >= 0); ++ assert_se(limit >= INT_MAX || get_process_ppid(limit+1, NULL) == -ESRCH); ++ ++ for (pid_t pid = 0;;) { ++ _cleanup_free_ char *c1 = NULL, *c2 = NULL; ++ pid_t ppid; ++ ++ r = get_process_ppid(pid, &ppid); ++ if (r == -EADDRNOTAVAIL) { ++ log_info("No further parent PID"); ++ break; ++ } ++ ++ assert_se(r >= 0); ++ ++ /* NOTE: The size is SIZE_MAX in the original commit, but it would require backporting a ++ * lot more stuff to support that (the current version of get_process_cmdline() just fails with ++ * ENOMEM). UINT16_MAX should be enough for practical purposes. ++ */ ++ assert_se(get_process_cmdline(pid, UINT16_MAX, true, &c1) >= 0); ++ assert_se(get_process_cmdline(ppid, UINT16_MAX, true, &c2) >= 0); ++ ++ log_info("Parent of " PID_FMT " (%s) is " PID_FMT " (%s).", pid, c1, ppid, c2); ++ ++ pid = ppid; ++ } ++} ++ + int main(int argc, char *argv[]) { + log_set_max_level(LOG_DEBUG); + log_parse_environment(); +@@ -614,6 +655,7 @@ int main(int argc, char *argv[]) { + test_safe_fork(); + test_pid_to_ptr(); + test_ioprio_class_from_to_string(); ++ test_get_process_ppid(); + + return 0; + } diff --git a/0652-errno-util-add-ERRNO_IS_PRIVILEGE-helper.patch b/0652-errno-util-add-ERRNO_IS_PRIVILEGE-helper.patch new file mode 100644 index 0000000000000000000000000000000000000000..b341839233322a0355c31bffc3bca03745ae450d --- /dev/null +++ b/0652-errno-util-add-ERRNO_IS_PRIVILEGE-helper.patch @@ -0,0 +1,30 @@ +From c078d4d4bc3a61d186a98e03afc699b11134e09f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 20 Nov 2019 12:22:40 +0100 +Subject: [PATCH] errno-util: add ERRNO_IS_PRIVILEGE() helper + +(cherry picked from commit e884e000714c2db006384058a63788ffcce8c8b8) + +Related: #1977569 +--- + src/basic/util.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/basic/util.h b/src/basic/util.h +index c70467f98c..76b76d7e91 100644 +--- a/src/basic/util.h ++++ b/src/basic/util.h +@@ -170,6 +170,13 @@ static inline int negative_errno(void) { + return -errno; + } + ++/* Two different errors for access problems */ ++static inline bool ERRNO_IS_PRIVILEGE(int r) { ++ return IN_SET(abs(r), ++ EACCES, ++ EPERM); ++} ++ + static inline unsigned u64log2(uint64_t n) { + #if __SIZEOF_LONG_LONG__ == 8 + return (n > 1) ? (unsigned) __builtin_clzll(n) ^ 63U : 0; diff --git a/0653-procfs-util-fix-confusion-wrt.-quantity-limit-and-ma.patch b/0653-procfs-util-fix-confusion-wrt.-quantity-limit-and-ma.patch new file mode 100644 index 0000000000000000000000000000000000000000..d85bfc5c090bfdc211ddb54c8f4652ef7372698e --- /dev/null +++ b/0653-procfs-util-fix-confusion-wrt.-quantity-limit-and-ma.patch @@ -0,0 +1,318 @@ +From 62678ec1aa02b53cb116b6f7dd72a54bf61153b7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 2 Nov 2021 18:18:21 +0100 +Subject: [PATCH] procfs-util: fix confusion wrt. quantity limit and maximum + value +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From packit/rawhide-arm64 logs: +Assertion 'limit >= INT_MAX || get_process_ppid(limit+1, NULL) == -ESRCH' failed at src/test/test-process-util.c:855, function test_get_process_ppid(). Aborting. +―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― + +The kernel has a few different limits. In particular kernel.threads-max can be +set to some lower value, and kernel.pid_max can be set to a higher value. This +is nice because it reduces PID reuse, even if the number of threads that is +allowed is limited. But the tests assumed that we cannot have a thread with +PID above MIN(kernel.threads-max, kernel.pid_max-1), which is not valid. + +So let's rework the whole thing: let's expose the helpers to read +kernel.threads-max and kernel.pid_max, and print what they return in tests. +procfs_tasks_get_limit() was something that is only used in tests, and wasn't +very well defined, so let's drop it. + +Fixes #21193. + +(cherry picked from commit c3dead53d50e334f2d072a2248256983d6dc9f8c) + +Related: #1977569 +--- + src/basic/procfs-util.c | 53 +++++++++--------------------------- + src/basic/procfs-util.h | 4 ++- + src/basic/util.c | 49 +++++++++++++++++++++++---------- + src/test/test-process-util.c | 10 +++++-- + src/test/test-procfs-util.c | 37 +++++++++++++++++++------ + 5 files changed, 88 insertions(+), 65 deletions(-) + +diff --git a/src/basic/procfs-util.c b/src/basic/procfs-util.c +index 7aaf95bfce..fa5671dd72 100644 +--- a/src/basic/procfs-util.c ++++ b/src/basic/procfs-util.c +@@ -12,54 +12,34 @@ + #include "stdio-util.h" + #include "string-util.h" + +-int procfs_tasks_get_limit(uint64_t *ret) { ++int procfs_get_pid_max(uint64_t *ret) { + _cleanup_free_ char *value = NULL; +- uint64_t pid_max, threads_max; + int r; + + assert(ret); + +- /* So there are two sysctl files that control the system limit of processes: +- * +- * 1. kernel.threads-max: this is probably the sysctl that makes more sense, as it directly puts a limit on +- * concurrent tasks. +- * +- * 2. kernel.pid_max: this limits the numeric range PIDs can take, and thus indirectly also limits the number +- * of concurrent threads. AFAICS it's primarily a compatibility concept: some crappy old code used a signed +- * 16bit type for PIDs, hence the kernel provides a way to ensure the PIDs never go beyond INT16_MAX by +- * default. +- * +- * By default #2 is set to much lower values than #1, hence the limit people come into contact with first, as +- * it's the lowest boundary they need to bump when they want higher number of processes. +- * +- * Also note the weird definition of #2: PIDs assigned will be kept below this value, which means the number of +- * tasks that can be created is one lower, as PID 0 is not a valid process ID. */ +- + r = read_one_line_file("/proc/sys/kernel/pid_max", &value); + if (r < 0) + return r; + +- r = safe_atou64(value, &pid_max); +- if (r < 0) +- return r; ++ return safe_atou64(value, ret); ++} + +- value = mfree(value); +- r = read_one_line_file("/proc/sys/kernel/threads-max", &value); +- if (r < 0) +- return r; ++int procfs_get_threads_max(uint64_t *ret) { ++ _cleanup_free_ char *value = NULL; ++ int r; + +- r = safe_atou64(value, &threads_max); ++ assert(ret); ++ ++ r = read_one_line_file("/proc/sys/kernel/threads-max", &value); + if (r < 0) + return r; + +- /* Subtract one from pid_max, since PID 0 is not a valid PID */ +- *ret = MIN(pid_max-1, threads_max); +- return 0; ++ return safe_atou64(value, ret); + } + + int procfs_tasks_set_limit(uint64_t limit) { + char buffer[DECIMAL_STR_MAX(uint64_t)+1]; +- _cleanup_free_ char *value = NULL; + uint64_t pid_max; + int r; + +@@ -74,10 +54,7 @@ int procfs_tasks_set_limit(uint64_t limit) { + * set it to the maximum. */ + limit = CLAMP(limit, 20U, TASKS_MAX); + +- r = read_one_line_file("/proc/sys/kernel/pid_max", &value); +- if (r < 0) +- return r; +- r = safe_atou64(value, &pid_max); ++ r = procfs_get_pid_max(&pid_max); + if (r < 0) + return r; + +@@ -98,14 +75,10 @@ int procfs_tasks_set_limit(uint64_t limit) { + /* Hmm, we couldn't write this? If so, maybe it was already set properly? In that case let's not + * generate an error */ + +- value = mfree(value); +- if (read_one_line_file("/proc/sys/kernel/threads-max", &value) < 0) +- return r; /* return original error */ +- +- if (safe_atou64(value, &threads_max) < 0) ++ if (procfs_get_threads_max(&threads_max) < 0) + return r; /* return original error */ + +- if (MIN(pid_max-1, threads_max) != limit) ++ if (MIN(pid_max - 1, threads_max) != limit) + return r; /* return original error */ + + /* Yay! Value set already matches what we were trying to set, hence consider this a success. */ +diff --git a/src/basic/procfs-util.h b/src/basic/procfs-util.h +index 5a44e9eff7..caaee8b0b6 100644 +--- a/src/basic/procfs-util.h ++++ b/src/basic/procfs-util.h +@@ -5,7 +5,9 @@ + + #include "time-util.h" + +-int procfs_tasks_get_limit(uint64_t *ret); ++int procfs_get_pid_max(uint64_t *ret); ++int procfs_get_threads_max(uint64_t *ret); ++ + int procfs_tasks_set_limit(uint64_t limit); + int procfs_tasks_get_current(uint64_t *ret); + +diff --git a/src/basic/util.c b/src/basic/util.c +index 609f8c2f33..548e3652cc 100644 +--- a/src/basic/util.c ++++ b/src/basic/util.c +@@ -527,23 +527,46 @@ uint64_t physical_memory_scale(uint64_t v, uint64_t max) { + } + + uint64_t system_tasks_max(void) { +- +- uint64_t a = TASKS_MAX, b = TASKS_MAX; ++ uint64_t a = TASKS_MAX, b = TASKS_MAX, c = TASKS_MAX; + _cleanup_free_ char *root = NULL; + int r; + +- /* Determine the maximum number of tasks that may run on this system. We check three sources to determine this +- * limit: ++ /* Determine the maximum number of tasks that may run on this system. We check three sources to ++ * determine this limit: ++ * ++ * a) kernel.threads-max sysctl: the maximum number of tasks (threads) the kernel allows. ++ * ++ * This puts a direct limit on the number of concurrent tasks. ++ * ++ * b) kernel.pid_max sysctl: the maximum PID value. ++ * ++ * This limits the numeric range PIDs can take, and thus indirectly also limits the number of ++ * concurrent threads. It's primarily a compatibility concept: some crappy old code used a signed ++ * 16bit type for PIDs, hence the kernel provides a way to ensure the PIDs never go beyond ++ * INT16_MAX by default. + * +- * a) the maximum tasks value the kernel allows on this architecture +- * b) the cgroups pids_max attribute for the system +- * c) the kernel's configured maximum PID value ++ * Also note the weird definition: PIDs assigned will be kept below this value, which means ++ * the number of tasks that can be created is one lower, as PID 0 is not a valid process ID. + * +- * And then pick the smallest of the three */ ++ * c) pids.max on the root cgroup: the kernel's configured maximum number of tasks. ++ * ++ * and then pick the smallest of the three. ++ * ++ * By default pid_max is set to much lower values than threads-max, hence the limit people come into ++ * contact with first, as it's the lowest boundary they need to bump when they want higher number of ++ * processes. ++ */ ++ ++ r = procfs_get_threads_max(&a); ++ if (r < 0) ++ log_debug_errno(r, "Failed to read kernel.threads-max, ignoring: %m"); + +- r = procfs_tasks_get_limit(&a); ++ r = procfs_get_pid_max(&b); + if (r < 0) +- log_debug_errno(r, "Failed to read maximum number of tasks from /proc, ignoring: %m"); ++ log_debug_errno(r, "Failed to read kernel.pid_max, ignoring: %m"); ++ else if (b > 0) ++ /* Subtract one from pid_max, since PID 0 is not a valid PID */ ++ b--; + + r = cg_get_root_path(&root); + if (r < 0) +@@ -555,15 +578,13 @@ uint64_t system_tasks_max(void) { + if (r < 0) + log_debug_errno(r, "Failed to read pids.max attribute of cgroup root, ignoring: %m"); + else if (!streq(value, "max")) { +- r = safe_atou64(value, &b); ++ r = safe_atou64(value, &c); + if (r < 0) + log_debug_errno(r, "Failed to parse pids.max attribute of cgroup root, ignoring: %m"); + } + } + +- return MIN3(TASKS_MAX, +- a <= 0 ? TASKS_MAX : a, +- b <= 0 ? TASKS_MAX : b); ++ return MIN3(a, b, c); + } + + uint64_t system_tasks_max_scale(uint64_t v, uint64_t max) { +diff --git a/src/test/test-process-util.c b/src/test/test-process-util.c +index 6b14ff592b..6295889b47 100644 +--- a/src/test/test-process-util.c ++++ b/src/test/test-process-util.c +@@ -598,8 +598,14 @@ static void test_get_process_ppid(void) { + assert_se(get_process_ppid(1, NULL) == -EADDRNOTAVAIL); + + /* the process with the PID above the global limit definitely doesn't exist. Verify that */ +- assert_se(procfs_tasks_get_limit(&limit) >= 0); +- assert_se(limit >= INT_MAX || get_process_ppid(limit+1, NULL) == -ESRCH); ++ assert_se(procfs_get_pid_max(&limit) >= 0); ++ log_debug("kernel.pid_max = %"PRIu64, limit); ++ ++ if (limit < INT_MAX) { ++ r = get_process_ppid(limit + 1, NULL); ++ log_debug_errno(r, "get_process_limit(%"PRIu64") → %d/%m", limit + 1, r); ++ assert(r == -ESRCH); ++ } + + for (pid_t pid = 0;;) { + _cleanup_free_ char *c1 = NULL, *c2 = NULL; +diff --git a/src/test/test-procfs-util.c b/src/test/test-procfs-util.c +index 1d0612985b..bb6943fed0 100644 +--- a/src/test/test-procfs-util.c ++++ b/src/test/test-procfs-util.c +@@ -5,11 +5,13 @@ + #include "log.h" + #include "parse-util.h" + #include "procfs-util.h" ++#include "process-util.h" ++#include "util.h" + + int main(int argc, char *argv[]) { + char buf[CONST_MAX(FORMAT_TIMESPAN_MAX, FORMAT_BYTES_MAX)]; + nsec_t nsec; +- uint64_t v; ++ uint64_t v, w; + int r; + + log_parse_environment(); +@@ -24,22 +26,41 @@ int main(int argc, char *argv[]) { + assert_se(procfs_tasks_get_current(&v) >= 0); + log_info("Current number of tasks: %" PRIu64, v); + +- assert_se(procfs_tasks_get_limit(&v) >= 0); ++ v = TASKS_MAX; ++ r = procfs_get_pid_max(&v); ++ assert(r >= 0 || r == -ENOENT || ERRNO_IS_PRIVILEGE(r)); ++ log_info("kernel.pid_max: %"PRIu64, v); ++ ++ w = TASKS_MAX; ++ r = procfs_get_threads_max(&w); ++ assert(r >= 0 || r == -ENOENT || ERRNO_IS_PRIVILEGE(r)); ++ log_info("kernel.threads-max: %"PRIu64, w); ++ ++ v = MIN(v - (v > 0), w); ++ ++ assert_se(r >= 0); + log_info("Limit of tasks: %" PRIu64, v); + assert_se(v > 0); +- assert_se(procfs_tasks_set_limit(v) >= 0); ++ r = procfs_tasks_set_limit(v); ++ if (r == -ENOENT || ERRNO_IS_PRIVILEGE(r)) { ++ log_notice_errno(r, "Skipping test: can't set task limits"); ++ return EXIT_TEST_SKIP; ++ } ++ assert(r >= 0); + + if (v > 100) { +- uint64_t w; ++ log_info("Reducing limit by one to %"PRIu64"…", v-1); ++ + r = procfs_tasks_set_limit(v-1); +- assert_se(IN_SET(r, 0, -EPERM, -EACCES, -EROFS)); ++ log_info_errno(r, "procfs_tasks_set_limit: %m"); ++ assert_se(r >= 0 || ERRNO_IS_PRIVILEGE(r)); + +- assert_se(procfs_tasks_get_limit(&w) >= 0); +- assert_se((r == 0 && w == v - 1) || (r < 0 && w == v)); ++ assert_se(procfs_get_threads_max(&w) >= 0); ++ assert_se(r >= 0 ? w == v - 1 : w == v); + + assert_se(procfs_tasks_set_limit(v) >= 0); + +- assert_se(procfs_tasks_get_limit(&w) >= 0); ++ assert_se(procfs_get_threads_max(&w) >= 0); + assert_se(v == w); + } + diff --git a/0654-test-process-util-also-add-EROFS-to-the-list-of-good.patch b/0654-test-process-util-also-add-EROFS-to-the-list-of-good.patch new file mode 100644 index 0000000000000000000000000000000000000000..8b756d2f2b4fe93322afe42835cb452675132b8b --- /dev/null +++ b/0654-test-process-util-also-add-EROFS-to-the-list-of-good.patch @@ -0,0 +1,31 @@ +From fe15b97e44beb69305d3970a3748624ae76f9f04 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 3 Nov 2021 09:39:16 +0100 +Subject: [PATCH] test-process-util: also add EROFS to the list of "good" + errors + +It is only added in the one place where we actually try to set the +setting to a new value. Before we were testing if we can set to it the +existing value, which was a noop. We could still get a permission error, +but this is the first place where we would propagate EROFS. + +(cherry picked from commit 6434a83d01d96e9f9a17ed9ce1f04a7d64859950) + +Related: #1977569 +--- + src/test/test-procfs-util.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/test/test-procfs-util.c b/src/test/test-procfs-util.c +index bb6943fed0..d656c4df4f 100644 +--- a/src/test/test-procfs-util.c ++++ b/src/test/test-procfs-util.c +@@ -53,7 +53,7 @@ int main(int argc, char *argv[]) { + + r = procfs_tasks_set_limit(v-1); + log_info_errno(r, "procfs_tasks_set_limit: %m"); +- assert_se(r >= 0 || ERRNO_IS_PRIVILEGE(r)); ++ assert_se(r >= 0 || ERRNO_IS_PRIVILEGE(r) || r == -EROFS); + + assert_se(procfs_get_threads_max(&w) >= 0); + assert_se(r >= 0 ? w == v - 1 : w == v); diff --git a/0655-journal-refresh-cached-credentials-of-stdout-streams.patch b/0655-journal-refresh-cached-credentials-of-stdout-streams.patch new file mode 100644 index 0000000000000000000000000000000000000000..7b1481dbd9fef7811e9b60d3f11aef0c461b46b5 --- /dev/null +++ b/0655-journal-refresh-cached-credentials-of-stdout-streams.patch @@ -0,0 +1,146 @@ +From a42cf9af339f48f633fa0b17a960e1e407b7450f Mon Sep 17 00:00:00 2001 +From: Lorenz Bauer +Date: Mon, 4 Nov 2019 16:35:46 +0000 +Subject: [PATCH] journal: refresh cached credentials of stdout streams + +journald assumes that getsockopt(SO_PEERCRED) correctly identifies the +process on the remote end of the socket. However, this is incorrect +according to man 7 socket: + + The returned credentials are those that were in effect at the + time of the call to connect(2) or socketpair(2). + +This becomes a problem when a new process inherits the stdout stream +from a parent. First, log messages from the child process will +be attributed to the parent. Second, the struct ucred used by journald +becomes invalid as soon as the parent exits. Further sendmsg calls then +fail with ENOENT. Logs for the child process then vanish from the journal. + +Fix this by using recvmsg on the stdout stream, and refreshing the cached +struct ucred if SCM_CREDENTIALS indicate a new process. + +Fixes #13708 + +(cherry picked from commit 09d0b46ab61bebafe5bdc1be95ee153dfb13d6bc) + +Resolves: #1931806 +--- + src/journal/journald-stream.c | 49 ++++++++++++++++++++++++++-- + test/TEST-04-JOURNAL/test-journal.sh | 13 ++++++++ + 2 files changed, 60 insertions(+), 2 deletions(-) + +diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c +index 6f8a4011ff..302a82d3d7 100644 +--- a/src/journal/journald-stream.c ++++ b/src/journal/journald-stream.c +@@ -484,11 +484,22 @@ static int stdout_stream_scan(StdoutStream *s, bool force_flush) { + } + + static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, void *userdata) { ++ uint8_t buf[CMSG_SPACE(sizeof(struct ucred))]; + StdoutStream *s = userdata; ++ struct ucred *ucred = NULL; ++ struct cmsghdr *cmsg; ++ struct iovec iovec; + size_t limit; + ssize_t l; + int r; + ++ struct msghdr msghdr = { ++ .msg_iov = &iovec, ++ .msg_iovlen = 1, ++ .msg_control = buf, ++ .msg_controllen = sizeof(buf), ++ }; ++ + assert(s); + + if ((revents|EPOLLIN|EPOLLHUP) != (EPOLLIN|EPOLLHUP)) { +@@ -508,20 +519,50 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, + * always leave room for a terminating NUL we might need to add. */ + limit = MIN(s->allocated - 1, s->server->line_max); + +- l = read(s->fd, s->buffer + s->length, limit - s->length); ++ iovec = IOVEC_MAKE(s->buffer + s->length, limit - s->length); ++ ++ l = recvmsg(s->fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); + if (l < 0) { +- if (errno == EAGAIN) ++ if (IN_SET(errno, EINTR, EAGAIN)) + return 0; + + log_warning_errno(errno, "Failed to read from stream: %m"); + goto terminate; + } ++ cmsg_close_all(&msghdr); + + if (l == 0) { + stdout_stream_scan(s, true); + goto terminate; + } + ++ CMSG_FOREACH(cmsg, &msghdr) ++ if (cmsg->cmsg_level == SOL_SOCKET && ++ cmsg->cmsg_type == SCM_CREDENTIALS && ++ cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) { ++ ucred = (struct ucred *)CMSG_DATA(cmsg); ++ break; ++ } ++ ++ /* Invalidate the context if the pid of the sender changed. ++ * This happens when a forked process inherits stdout / stderr ++ * from a parent. In this case getpeercred returns the ucred ++ * of the parent, which can be invalid if the parent has exited ++ * in the meantime. ++ */ ++ if (ucred && ucred->pid != s->ucred.pid) { ++ /* force out any previously half-written lines from a ++ * different process, before we switch to the new ucred ++ * structure for everything we just added */ ++ r = stdout_stream_scan(s, true); ++ if (r < 0) ++ goto terminate; ++ ++ s->ucred = *ucred; ++ client_context_release(s->server, s->context); ++ s->context = NULL; ++ } ++ + s->length += l; + r = stdout_stream_scan(s, false); + if (r < 0) +@@ -559,6 +600,10 @@ int stdout_stream_install(Server *s, int fd, StdoutStream **ret) { + if (r < 0) + return log_error_errno(r, "Failed to determine peer credentials: %m"); + ++ r = setsockopt_int(fd, SOL_SOCKET, SO_PASSCRED, true); ++ if (r < 0) ++ return log_error_errno(r, "SO_PASSCRED failed: %m"); ++ + if (mac_selinux_use()) { + r = getpeersec(fd, &stream->label); + if (r < 0 && r != -EOPNOTSUPP) +diff --git a/test/TEST-04-JOURNAL/test-journal.sh b/test/TEST-04-JOURNAL/test-journal.sh +index 260cae09ab..52a6ee84d1 100755 +--- a/test/TEST-04-JOURNAL/test-journal.sh ++++ b/test/TEST-04-JOURNAL/test-journal.sh +@@ -63,6 +63,19 @@ grep -q '^PRIORITY=6$' /output + ! grep -q '^FOO=' /output + ! grep -q '^SYSLOG_FACILITY=' /output + ++# https://github.com/systemd/systemd/issues/13708 ++ID=$(journalctl --new-id128 | sed -n 2p) ++systemd-cat -t "$ID" bash -c 'echo parent; (echo child) & wait' & ++PID=$! ++wait %% ++journalctl --sync ++# We can drop this grep when https://github.com/systemd/systemd/issues/13937 ++# has a fix. ++journalctl -b -o export -t "$ID" --output-fields=_PID | grep '^_PID=' >/output ++[[ `grep -c . /output` -eq 2 ]] ++grep -q "^_PID=$PID" /output ++grep -vq "^_PID=$PID" /output ++ + # Don't lose streams on restart + systemctl start forever-print-hola + sleep 3 diff --git a/0656-Fix-LGTM-build.patch b/0656-Fix-LGTM-build.patch deleted file mode 100644 index 81751bf0437075476d8cbd1d6437385f7fc75c01..0000000000000000000000000000000000000000 --- a/0656-Fix-LGTM-build.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 93c42f4da4563d225e3a2b9e72e8f9bb50d86bb1 Mon Sep 17 00:00:00 2001 -From: David Tardon -Date: Fri, 17 Sep 2021 15:10:03 +0200 -Subject: [PATCH] Fix LGTM build - -Related: #1850986 ---- - src/network/netdev/netdev.c | 2 +- - src/network/networkd-network.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c -index 82ce88402f..e97cc07028 100644 ---- a/src/network/netdev/netdev.c -+++ b/src/network/netdev/netdev.c -@@ -640,7 +640,7 @@ static int netdev_load_one(Manager *manager, const char *filename) { - netdev_raw->match_host, netdev_raw->match_virt, - netdev_raw->match_kernel_cmdline, netdev_raw->match_kernel_version, - netdev_raw->match_arch, -- NULL, NULL, NULL, NULL, NULL, NULL) <= 0) -+ NULL, NULL, NULL, NULL, NULL, NULL, NULL) <= 0) - return 0; - - if (netdev_raw->kind == _NETDEV_KIND_INVALID) { -diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c -index 429aac5e6c..7637d135a4 100644 ---- a/src/network/networkd-network.c -+++ b/src/network/networkd-network.c -@@ -479,7 +479,7 @@ int network_get(Manager *manager, struct udev_device *device, - network->match_virt, network->match_kernel_cmdline, - network->match_kernel_version, network->match_arch, - address, path, parent_driver, driver, -- devtype, ifname)) { -+ devtype, ifname, NULL)) { - if (network->match_name && device) { - const char *attr; - uint8_t name_assign_type = NET_NAME_UNKNOWN; diff --git a/0656-util-lib-introduce-HAS_FEATURE_ADDRESS_SANITIZER.patch b/0656-util-lib-introduce-HAS_FEATURE_ADDRESS_SANITIZER.patch new file mode 100644 index 0000000000000000000000000000000000000000..f51fced2388e5cee4a721e6848841de8b82f88c6 --- /dev/null +++ b/0656-util-lib-introduce-HAS_FEATURE_ADDRESS_SANITIZER.patch @@ -0,0 +1,35 @@ +From 39b10c9e7e4ad80adc0e8c43f7d1917edee515dd Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Sun, 2 Dec 2018 08:28:24 +0100 +Subject: [PATCH] util-lib: introduce HAS_FEATURE_ADDRESS_SANITIZER + +https://clang.llvm.org/docs/AddressSanitizer.html#conditional-compilation-with-has-feature-address-sanitizer +(cherry picked from commit 289acab951c5937fdf6d3a2666f411fd66dd20e5) + +Related: #2017033 +--- + src/basic/macro.h | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/src/basic/macro.h b/src/basic/macro.h +index 0fe6a62aa8..62f2359633 100644 +--- a/src/basic/macro.h ++++ b/src/basic/macro.h +@@ -55,6 +55,17 @@ + # endif + #endif + ++#if !defined(HAS_FEATURE_ADDRESS_SANITIZER) ++# if defined(__has_feature) ++# if __has_feature(address_sanitizer) ++# define HAS_FEATURE_ADDRESS_SANITIZER 1 ++# endif ++# endif ++# if !defined(HAS_FEATURE_ADDRESS_SANITIZER) ++# define HAS_FEATURE_ADDRESS_SANITIZER 0 ++# endif ++#endif ++ + /* Temporarily disable some warnings */ + #define DISABLE_WARNING_DECLARATION_AFTER_STATEMENT \ + _Pragma("GCC diagnostic push"); \ diff --git a/0657-ci-skip-test-execute-on-GH-Actions-under-ASan.patch b/0657-ci-skip-test-execute-on-GH-Actions-under-ASan.patch new file mode 100644 index 0000000000000000000000000000000000000000..1b64c95c19dc0a6207ffc7a276a01d828320cb35 --- /dev/null +++ b/0657-ci-skip-test-execute-on-GH-Actions-under-ASan.patch @@ -0,0 +1,34 @@ +From c0c7a5d73bd53375f90fbe70287512269bc8de16 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 12 Jan 2021 22:14:59 +0100 +Subject: [PATCH] ci: skip test-execute on GH Actions under ASan + +It seems to suffer from the same issue as on Travis CI, where the test +randomly fails due to timeouts in its subtests. + +See: https://github.com/systemd/systemd/issues/10696#issuecomment-758501797 +(cherry picked from commit f1a8fed286e3b9527b1837e9d5c6cb8d88bd2041) + +Related: #2017033 +--- + src/test/test-execute.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/src/test/test-execute.c b/src/test/test-execute.c +index 294f8fe7dd..5303652b93 100644 +--- a/src/test/test-execute.c ++++ b/src/test/test-execute.c +@@ -798,6 +798,13 @@ int main(int argc, char *argv[]) { + log_parse_environment(); + log_open(); + ++#if HAS_FEATURE_ADDRESS_SANITIZER ++ if (strstr_ptr(ci_environment(), "travis") || strstr_ptr(ci_environment(), "github-actions")) { ++ log_notice("Running on Travis CI/GH Actions under ASan, skipping, see https://github.com/systemd/systemd/issues/10696"); ++ return EXIT_TEST_SKIP; ++ } ++#endif ++ + (void) unsetenv("USER"); + (void) unsetenv("LOGNAME"); + (void) unsetenv("SHELL"); diff --git a/0658-test-seccomp-accept-ENOSYS-from-sysctl-2-too.patch b/0658-test-seccomp-accept-ENOSYS-from-sysctl-2-too.patch new file mode 100644 index 0000000000000000000000000000000000000000..a7a10ed8c8441dc2d187aa8fcc102a624234f7fa --- /dev/null +++ b/0658-test-seccomp-accept-ENOSYS-from-sysctl-2-too.patch @@ -0,0 +1,27 @@ +From 8c15742d1194e0db9a2555553e4d77ebb441b3dc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 22 Sep 2020 19:05:17 +0200 +Subject: [PATCH] test-seccomp: accept ENOSYS from sysctl(2) too + +It seems that kernel 5.9 started returning that. + +(cherry picked from commit 0af05e485a3a88f454c714901eb6109307dc893e) + +Related: #2017033 +--- + src/test/test-seccomp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c +index 5eb1c78b8b..6ec04c4c55 100644 +--- a/src/test/test-seccomp.c ++++ b/src/test/test-seccomp.c +@@ -239,7 +239,7 @@ static void test_protect_sysctl(void) { + if (pid == 0) { + #if defined __NR__sysctl && __NR__sysctl >= 0 + assert_se(syscall(__NR__sysctl, NULL) < 0); +- assert_se(errno == EFAULT); ++ assert_se(IN_SET(errno, EFAULT, ENOSYS)); + #endif + + assert_se(seccomp_protect_sysctl() >= 0); diff --git a/0659-test-accept-that-char-device-0-0-can-now-be-created-.patch b/0659-test-accept-that-char-device-0-0-can-now-be-created-.patch new file mode 100644 index 0000000000000000000000000000000000000000..ac082a499fc191aa4b5614bfb2fd8a4b262b3c30 --- /dev/null +++ b/0659-test-accept-that-char-device-0-0-can-now-be-created-.patch @@ -0,0 +1,51 @@ +From e61aa66a63bcfe9ce0d80f0db691ba40218b872a Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 14 Aug 2020 21:50:55 +0200 +Subject: [PATCH] test: accept that char device 0/0 can now be created witout + privileges + +Fixes: #16721 +(cherry picked from commit 5b5ce6298e5a1c09beacd5c963e2350979cbf94a) + +Related: #2017033 +--- + src/test/test-fs-util.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c +index e3338ea440..aa32629f62 100644 +--- a/src/test/test-fs-util.c ++++ b/src/test/test-fs-util.c +@@ -518,8 +518,8 @@ static void test_touch_file(void) { + assert_se(timespec_load(&st.st_mtim) == test_mtime); + + if (geteuid() == 0) { +- a = strjoina(p, "/cdev"); +- r = mknod(a, 0775 | S_IFCHR, makedev(0, 0)); ++ a = strjoina(p, "/bdev"); ++ r = mknod(a, 0775 | S_IFBLK, makedev(0, 0)); + if (r < 0 && errno == EPERM && detect_container() > 0) { + log_notice("Running in unprivileged container? Skipping remaining tests in %s", __func__); + return; +@@ -529,17 +529,17 @@ static void test_touch_file(void) { + assert_se(lstat(a, &st) >= 0); + assert_se(st.st_uid == test_uid); + assert_se(st.st_gid == test_gid); +- assert_se(S_ISCHR(st.st_mode)); ++ assert_se(S_ISBLK(st.st_mode)); + assert_se((st.st_mode & 0777) == 0640); + assert_se(timespec_load(&st.st_mtim) == test_mtime); + +- a = strjoina(p, "/bdev"); +- assert_se(mknod(a, 0775 | S_IFBLK, makedev(0, 0)) >= 0); ++ a = strjoina(p, "/cdev"); ++ assert_se(mknod(a, 0775 | S_IFCHR, makedev(0, 0)) >= 0); + assert_se(touch_file(a, false, test_mtime, test_uid, test_gid, 0640) >= 0); + assert_se(lstat(a, &st) >= 0); + assert_se(st.st_uid == test_uid); + assert_se(st.st_gid == test_gid); +- assert_se(S_ISBLK(st.st_mode)); ++ assert_se(S_ISCHR(st.st_mode)); + assert_se((st.st_mode & 0777) == 0640); + assert_se(timespec_load(&st.st_mtim) == test_mtime); + } diff --git a/0660-meson-do-not-fail-if-rsync-is-not-installed-with-mes.patch b/0660-meson-do-not-fail-if-rsync-is-not-installed-with-mes.patch new file mode 100644 index 0000000000000000000000000000000000000000..9f61ab98140e5e352406167234366fad84c44d6a --- /dev/null +++ b/0660-meson-do-not-fail-if-rsync-is-not-installed-with-mes.patch @@ -0,0 +1,54 @@ +From d5cefb7293d2999dcad81bd71933b319ca6c3590 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Mon, 12 Apr 2021 14:03:32 +0200 +Subject: [PATCH] meson: do not fail if rsync is not installed with meson + 0.57.2 + +https://github.com/mesonbuild/meson/issues/8641 + +Our CI started to fail. Even if the change is reverted in meson, +we need a quick workaround here. + +(cherry picked from commit 7c5fd25119a495009ea62f79e5daec34cc464628) + +Related: #2017033 +--- + man/meson.build | 25 ++++++++++++++----------- + 1 file changed, 14 insertions(+), 11 deletions(-) + +diff --git a/man/meson.build b/man/meson.build +index a953d34098..efc8836d0c 100644 +--- a/man/meson.build ++++ b/man/meson.build +@@ -178,17 +178,20 @@ html = custom_target( + depends : html_pages, + command : ['echo']) + +-run_target( +- 'doc-sync', +- depends : man_pages + html_pages, +- command : ['rsync', '-rlv', +- '--delete-excluded', +- '--include=man', +- '--include=*.html', +- '--exclude=*', +- '--omit-dir-times', +- meson.current_build_dir(), +- get_option('www-target')]) ++rsync = find_program('rsync', required : false) ++if rsync.found() ++ run_target( ++ 'doc-sync', ++ depends : man_pages + html_pages, ++ command : [rsync, '-rlv', ++ '--delete-excluded', ++ '--include=man', ++ '--include=*.html', ++ '--exclude=*', ++ '--omit-dir-times', ++ meson.current_build_dir(), ++ get_option('www-target')]) ++endif + + ############################################################ + diff --git a/0661-pid1-fix-free-of-uninitialized-pointer-in-unit_fail_.patch b/0661-pid1-fix-free-of-uninitialized-pointer-in-unit_fail_.patch new file mode 100644 index 0000000000000000000000000000000000000000..c260547b87d01f703abc2613a8eda198951ed704 --- /dev/null +++ b/0661-pid1-fix-free-of-uninitialized-pointer-in-unit_fail_.patch @@ -0,0 +1,27 @@ +From 30afbfdc82eb61f3bf47d6b1fa67a61d0ffcc4f2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 14 Dec 2018 08:16:31 +0100 +Subject: [PATCH] pid1: fix free of uninitialized pointer in + unit_fail_if_noncanonical() + +https://bugzilla.redhat.com/show_bug.cgi?id=1653068 +(cherry picked from commit 58d9d89b4b41189bdcea86c2ad5cf708b7d54aca) + +Related: #1970945 +--- + src/core/unit.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index 93c13e58d9..152a860d08 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -4785,7 +4785,7 @@ void unit_warn_if_dir_nonempty(Unit *u, const char* where) { + } + + int unit_fail_if_noncanonical(Unit *u, const char* where) { +- _cleanup_free_ char *canonical_where; ++ _cleanup_free_ char *canonical_where = NULL; + int r; + + assert(u); diff --git a/0662-sd-event-take-ref-on-event-loop-object-before-dispat.patch b/0662-sd-event-take-ref-on-event-loop-object-before-dispat.patch new file mode 100644 index 0000000000000000000000000000000000000000..afba787d9a8e8053cc7bcbb953509b5d7bcdd80b --- /dev/null +++ b/0662-sd-event-take-ref-on-event-loop-object-before-dispat.patch @@ -0,0 +1,32 @@ +From f025def77efc6bb1473b719e905fa70ed20b08d3 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 8 Sep 2021 15:42:11 +0200 +Subject: [PATCH] sd-event: take ref on event loop object before dispatching + event sources + +Idea is that all public APIs should take reference on objects that get +exposed to user-provided callbacks. We take the reference as a +protection from callbacks dropping it. We used to do this also here in +sd_event_loop(). However, in cleanup portion of f814c871e6 this was +accidentally dropped. + +(cherry picked from commit 9f6ef467818f902fe5369c8e37a39a3901bdcf4f) + +Related: #1970945 +--- + src/libsystemd/sd-event/sd-event.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index f78da00c3a..47cf93b3f4 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -3838,7 +3838,7 @@ _public_ int sd_event_loop(sd_event *e) { + assert_return(!event_pid_changed(e), -ECHILD); + assert_return(e->state == SD_EVENT_INITIAL, -EBUSY); + +- _unused_ _cleanup_(sd_event_unrefp) sd_event *ref = NULL; ++ _unused_ _cleanup_(sd_event_unrefp) sd_event *ref = sd_event_ref(e); + + while (e->state != SD_EVENT_FINISHED) { + r = sd_event_run(e, (uint64_t) -1); diff --git a/0663-core-consider-service-with-no-start-command-immediat.patch b/0663-core-consider-service-with-no-start-command-immediat.patch new file mode 100644 index 0000000000000000000000000000000000000000..c8eda89bf310235ebf5a5dd1ef519d698d4e0995 --- /dev/null +++ b/0663-core-consider-service-with-no-start-command-immediat.patch @@ -0,0 +1,33 @@ +From c667291303bb876707d86ac3ab9ca62355bae1b3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 16 Oct 2018 22:45:34 +0200 +Subject: [PATCH] core: consider service with no start command immediately + started + +The service would always be in state == SERVICE_INACTIVE, but it needs to go +through state == SERVICE_START so that SuccessAction/FailureAction are executed. + +(cherry picked from commit ef5ae8e71329e43c277e6d4f983f0c0793047b94) + +Related: #1860899 +--- + src/core/service.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/core/service.c b/src/core/service.c +index ae31973774..4da1c5accb 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -2055,6 +2055,12 @@ static void service_enter_start(Service *s) { + goto fail; + } + ++ /* We force a fake state transition here. Otherwise, the unit would go directly from ++ * SERVICE_DEAD to SERVICE_DEAD without SERVICE_ACTIVATING or SERVICE_ACTIVE ++ * inbetween. This way we can later trigger actions that depend on the state ++ * transition, including SuccessAction=. */ ++ service_set_state(s, SERVICE_START); ++ + service_enter_start_post(s); + return; + } diff --git a/0664-man-move-description-of-Action-modes-to-FailureActio.patch b/0664-man-move-description-of-Action-modes-to-FailureActio.patch new file mode 100644 index 0000000000000000000000000000000000000000..c0344421dc3bc257b62e878117bce4d4f057dce0 --- /dev/null +++ b/0664-man-move-description-of-Action-modes-to-FailureActio.patch @@ -0,0 +1,84 @@ +From 12ce6830c63b4a27bb6d5b7729d70a86079b108f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 16 Oct 2018 15:56:35 +0200 +Subject: [PATCH] man: move description of *Action= modes to + FailureAction=/SuccessAction= + +FailureAction=/SuccessAction= were added later then StartLimitAction=, so it +was easiest to refer to the existing description. But those two settings are +somewhat simpler (they just execute the action unconditionally) while +StartLimitAction= has additional timing and burst parameters, and they are +about to take on a more prominent role, so let's move the description of +allowed values. + +(cherry picked from commit 454dd6ce7adb744584ecae9aa0bd1acf3a00e9ed) + +Related: #1860899 +--- + man/systemd.unit.xml | 44 +++++++++++++++++++++++--------------------- + 1 file changed, 23 insertions(+), 21 deletions(-) + +diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml +index 7605c43375..802db453a4 100644 +--- a/man/systemd.unit.xml ++++ b/man/systemd.unit.xml +@@ -873,6 +873,24 @@ + + + ++ ++ FailureAction= ++ SuccessAction= ++ ++ Configure the action to take when the unit stops and enters a failed state or inactive ++ state. Takes one of , , , ++ , , or ++ . If is set, no action will be triggered. ++ causes a reboot following the normal shutdown procedure (i.e. equivalent to ++ systemctl reboot). causes a forced reboot which will ++ terminate all processes forcibly but should cause no dirty file systems on reboot (i.e. equivalent to ++ systemctl reboot -f) and causes immediate execution of the ++ reboot2 system call, which ++ might result in data loss. Similarly, , , ++ have the effect of powering down the system with similar semantics. Both ++ options default to . ++ ++ + + JobTimeoutSec= + JobRunningTimeoutSec= +@@ -929,29 +947,13 @@ + + StartLimitAction= + +- Configure the action to take if the rate limit configured with +- StartLimitIntervalSec= and StartLimitBurst= is hit. Takes one of +- , , , +- , , or +- . If is set, hitting the rate limit will trigger no +- action besides that the start will not be permitted. causes a reboot following the +- normal shutdown procedure (i.e. equivalent to systemctl reboot). +- causes a forced reboot which will terminate all processes forcibly but should +- cause no dirty file systems on reboot (i.e. equivalent to systemctl reboot -f) and +- causes immediate execution of the +- reboot2 system call, which +- might result in data loss. Similarly, , , +- have the effect of powering down the system with similar +- semantics. Defaults to . ++ Configure an additional action to take if the rate limit configured with ++ StartLimitIntervalSec= and StartLimitBurst= is hit. Takes the same ++ values as the setting FailureAction=/SuccessAction= settings and executes ++ the same actions. If is set, hitting the rate limit will trigger no action besides that ++ the start will not be permitted. Defaults to . + + +- +- FailureAction= +- SuccessAction= +- Configure the action to take when the unit stops and enters a failed state or inactive +- state. Takes the same values as the setting StartLimitAction= setting and executes the same +- actions. Both options default to . +- + + + RebootArgument= diff --git a/0665-core-define-exit-and-exit-force-actions-for-user-uni.patch b/0665-core-define-exit-and-exit-force-actions-for-user-uni.patch new file mode 100644 index 0000000000000000000000000000000000000000..1c9f492f08fb58db5499d082542795efcfc14542 --- /dev/null +++ b/0665-core-define-exit-and-exit-force-actions-for-user-uni.patch @@ -0,0 +1,361 @@ +From 19d91eef7f15b654cd96ad5350385e535fab9e2a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 16 Oct 2018 13:28:39 +0200 +Subject: [PATCH] core: define "exit" and "exit-force" actions for user units + and only accept that + +We would accept e.g. FailureAction=reboot-force in user units and then do an +exit in the user manager. Let's be stricter, and define "exit"/"exit-force" as +the only supported actions in user units. + +v2: +- rename 'exit' to 'exit-force' and add new 'exit' +- add test for the parsing function + +(cherry picked from commit 54fcb6192c618726d11404b24b1a1e9ec3169ee1) + +Related: #1860899 +--- + TODO | 4 +++ + man/systemd.unit.xml | 26 +++++++++------- + src/core/dbus-unit.c | 37 ++++++++++++++++++++++- + src/core/emergency-action.c | 47 ++++++++++++++++++++++------- + src/core/emergency-action.h | 5 ++++ + src/core/load-fragment.c | 42 +++++++++++++++++++++++++- + src/test/meson.build | 5 ++++ + src/test/test-emergency-action.c | 51 ++++++++++++++++++++++++++++++++ + 8 files changed, 195 insertions(+), 22 deletions(-) + create mode 100644 src/test/test-emergency-action.c + +diff --git a/TODO b/TODO +index 3100e067d6..0705b6b08e 100644 +--- a/TODO ++++ b/TODO +@@ -4,6 +4,10 @@ Bugfixes: + + * copy.c: set the right chattrs before copying files and others after + ++* Many manager configuration settings that are only applicable to user ++ manager or system manager can be always set. It would be better to reject ++ them when parsing config. ++ + External: + + * Fedora: add an rpmlint check that verifies that all unit files in the RPM are listed in %systemd_post macros. +diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml +index 802db453a4..5772a6684e 100644 +--- a/man/systemd.unit.xml ++++ b/man/systemd.unit.xml +@@ -877,18 +877,24 @@ + FailureAction= + SuccessAction= + +- Configure the action to take when the unit stops and enters a failed state or inactive +- state. Takes one of , , , +- , , or +- . If is set, no action will be triggered. +- causes a reboot following the normal shutdown procedure (i.e. equivalent to +- systemctl reboot). causes a forced reboot which will +- terminate all processes forcibly but should cause no dirty file systems on reboot (i.e. equivalent to +- systemctl reboot -f) and causes immediate execution of the ++ Configure the action to take when the unit stops and enters a failed state or inactive state. ++ Takes one of , , , ++ , , , ++ , , and . In system mode, ++ all options except and are allowed. In user mode, only ++ , , and are allowed. Both options default ++ to . ++ ++ If is set, no action will be triggered. causes a reboot ++ following the normal shutdown procedure (i.e. equivalent to systemctl reboot). ++ causes a forced reboot which will terminate all processes forcibly but should ++ cause no dirty file systems on reboot (i.e. equivalent to systemctl reboot -f) and ++ causes immediate execution of the + reboot2 system call, which + might result in data loss. Similarly, , , +- have the effect of powering down the system with similar semantics. Both +- options default to . ++ have the effect of powering down the system with similar ++ semantics. causes the user manager to exit following the normal shutdown procedure, and ++ causes it terminate without shutting down services. + + + +diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c +index 549a166abc..e7ea9db3ac 100644 +--- a/src/core/dbus-unit.c ++++ b/src/core/dbus-unit.c +@@ -1564,8 +1564,43 @@ static int bus_unit_set_live_property( + return 0; + } + ++static int bus_set_transient_emergency_action( ++ Unit *u, ++ const char *name, ++ EmergencyAction *p, ++ sd_bus_message *message, ++ UnitWriteFlags flags, ++ sd_bus_error *error) { ++ ++ const char *s; ++ EmergencyAction v; ++ int r; ++ bool system; ++ ++ assert(p); ++ ++ r = sd_bus_message_read(message, "s", &s); ++ if (r < 0) ++ return r; ++ ++ system = MANAGER_IS_SYSTEM(u->manager); ++ r = parse_emergency_action(s, system, &v); ++ if (v < 0) ++ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, ++ v == -EOPNOTSUPP ? "EmergencyAction setting invalid for manager type: %s" ++ : "Invalid %s setting: %s", ++ name, s); ++ ++ if (!UNIT_WRITE_FLAGS_NOOP(flags)) { ++ *p = v; ++ unit_write_settingf(u, flags, name, ++ "%s=%s", name, s); ++ } ++ ++ return 1; ++} ++ + static BUS_DEFINE_SET_TRANSIENT_PARSE(collect_mode, CollectMode, collect_mode_from_string); +-static BUS_DEFINE_SET_TRANSIENT_PARSE(emergency_action, EmergencyAction, emergency_action_from_string); + static BUS_DEFINE_SET_TRANSIENT_PARSE(job_mode, JobMode, job_mode_from_string); + + static int bus_set_transient_conditions( +diff --git a/src/core/emergency-action.c b/src/core/emergency-action.c +index 766a3b4d2b..00f5996317 100644 +--- a/src/core/emergency-action.c ++++ b/src/core/emergency-action.c +@@ -39,15 +39,6 @@ int emergency_action( + return -ECANCELED; + } + +- if (!MANAGER_IS_SYSTEM(m)) { +- /* Downgrade all options to simply exiting if we run +- * in user mode */ +- +- log_warning("Exiting: %s", reason); +- m->exit_code = MANAGER_EXIT; +- return -ECANCELED; +- } +- + switch (action) { + + case EMERGENCY_ACTION_REBOOT: +@@ -80,11 +71,26 @@ int emergency_action( + (void) reboot(RB_AUTOBOOT); + break; + ++ case EMERGENCY_ACTION_EXIT: ++ assert(MANAGER_IS_USER(m)); ++ ++ log_and_status(m, "Exiting", reason); ++ ++ (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_EXIT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL); ++ break; ++ + case EMERGENCY_ACTION_POWEROFF: + log_and_status(m, "Powering off", reason); + (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL); + break; + ++ case EMERGENCY_ACTION_EXIT_FORCE: ++ assert(MANAGER_IS_USER(m)); ++ ++ log_and_status(m, "Exiting immediately", reason); ++ m->exit_code = MANAGER_EXIT; ++ break; ++ + case EMERGENCY_ACTION_POWEROFF_FORCE: + log_and_status(m, "Forcibly powering off", reason); + m->exit_code = MANAGER_POWEROFF; +@@ -113,6 +119,27 @@ static const char* const emergency_action_table[_EMERGENCY_ACTION_MAX] = { + [EMERGENCY_ACTION_REBOOT_IMMEDIATE] = "reboot-immediate", + [EMERGENCY_ACTION_POWEROFF] = "poweroff", + [EMERGENCY_ACTION_POWEROFF_FORCE] = "poweroff-force", +- [EMERGENCY_ACTION_POWEROFF_IMMEDIATE] = "poweroff-immediate" ++ [EMERGENCY_ACTION_POWEROFF_IMMEDIATE] = "poweroff-immediate", ++ [EMERGENCY_ACTION_EXIT] = "exit", ++ [EMERGENCY_ACTION_EXIT_FORCE] = "exit-force", + }; + DEFINE_STRING_TABLE_LOOKUP(emergency_action, EmergencyAction); ++ ++int parse_emergency_action( ++ const char *value, ++ bool system, ++ EmergencyAction *ret) { ++ ++ EmergencyAction x; ++ ++ x = emergency_action_from_string(value); ++ if (x < 0) ++ return -EINVAL; ++ ++ if ((system && x >= _EMERGENCY_ACTION_FIRST_USER_ACTION) || ++ (!system && x != EMERGENCY_ACTION_NONE && x < _EMERGENCY_ACTION_FIRST_USER_ACTION)) ++ return -EOPNOTSUPP; ++ ++ *ret = x; ++ return 0; ++} +diff --git a/src/core/emergency-action.h b/src/core/emergency-action.h +index 61791f176f..646ccc4e6b 100644 +--- a/src/core/emergency-action.h ++++ b/src/core/emergency-action.h +@@ -13,6 +13,9 @@ typedef enum EmergencyAction { + EMERGENCY_ACTION_POWEROFF, + EMERGENCY_ACTION_POWEROFF_FORCE, + EMERGENCY_ACTION_POWEROFF_IMMEDIATE, ++ EMERGENCY_ACTION_EXIT, ++ _EMERGENCY_ACTION_FIRST_USER_ACTION = EMERGENCY_ACTION_EXIT, ++ EMERGENCY_ACTION_EXIT_FORCE, + _EMERGENCY_ACTION_MAX, + _EMERGENCY_ACTION_INVALID = -1 + } EmergencyAction; +@@ -24,3 +27,5 @@ int emergency_action(Manager *m, EmergencyAction action, const char *reboot_arg, + + const char* emergency_action_to_string(EmergencyAction i) _const_; + EmergencyAction emergency_action_from_string(const char *s) _pure_; ++ ++int parse_emergency_action(const char *value, bool system, EmergencyAction *ret); +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index e0d7b8f7f8..c102ffb9f0 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -77,7 +77,6 @@ DEFINE_CONFIG_PARSE(config_parse_socket_protocol, supported_socket_protocol_from + DEFINE_CONFIG_PARSE(config_parse_exec_secure_bits, secure_bits_from_string, "Failed to parse secure bits"); + DEFINE_CONFIG_PARSE_ENUM(config_parse_collect_mode, collect_mode, CollectMode, "Failed to parse garbage collection mode"); + DEFINE_CONFIG_PARSE_ENUM(config_parse_device_policy, cgroup_device_policy, CGroupDevicePolicy, "Failed to parse device policy"); +-DEFINE_CONFIG_PARSE_ENUM(config_parse_emergency_action, emergency_action, EmergencyAction, "Failed to parse failure action specifier"); + DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_keyring_mode, exec_keyring_mode, ExecKeyringMode, "Failed to parse keyring mode"); + DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_utmp_mode, exec_utmp_mode, ExecUtmpMode, "Failed to parse utmp mode"); + DEFINE_CONFIG_PARSE_ENUM(config_parse_job_mode, job_mode, JobMode, "Failed to parse job mode"); +@@ -4253,6 +4252,47 @@ int config_parse_job_running_timeout_sec( + return 0; + } + ++int config_parse_emergency_action( ++ const char* unit, ++ const char *filename, ++ unsigned line, ++ const char *section, ++ unsigned section_line, ++ const char *lvalue, ++ int ltype, ++ const char *rvalue, ++ void *data, ++ void *userdata) { ++ ++ Manager *m = NULL; ++ EmergencyAction *x = data; ++ int r; ++ ++ assert(filename); ++ assert(lvalue); ++ assert(rvalue); ++ assert(data); ++ ++ if (unit) ++ m = ((Unit*) userdata)->manager; ++ else ++ m = data; ++ ++ r = parse_emergency_action(rvalue, MANAGER_IS_SYSTEM(m), x); ++ if (r < 0) { ++ if (r == -EOPNOTSUPP) ++ log_syntax(unit, LOG_ERR, filename, line, r, ++ "%s= specified as %s mode action, ignoring: %s", ++ lvalue, MANAGER_IS_SYSTEM(m) ? "user" : "system", rvalue); ++ else ++ log_syntax(unit, LOG_ERR, filename, line, r, ++ "Failed to parse %s=, ignoring: %s", lvalue, rvalue); ++ return 0; ++ } ++ ++ return 0; ++} ++ + #define FOLLOW_MAX 8 + + static int open_follow(char **filename, FILE **_f, Set *names, char **_final) { +diff --git a/src/test/meson.build b/src/test/meson.build +index 7b310d4ec7..40cf56d73d 100644 +--- a/src/test/meson.build ++++ b/src/test/meson.build +@@ -65,6 +65,11 @@ tests += [ + libshared], + []], + ++ [['src/test/test-emergency-action.c'], ++ [libcore, ++ libshared], ++ []], ++ + [['src/test/test-job-type.c'], + [libcore, + libshared], +diff --git a/src/test/test-emergency-action.c b/src/test/test-emergency-action.c +new file mode 100644 +index 0000000000..493b23227e +--- /dev/null ++++ b/src/test/test-emergency-action.c +@@ -0,0 +1,51 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++#include "emergency-action.h" ++#include "tests.h" ++ ++static void test_parse_emergency_action(void) { ++ EmergencyAction x; ++ ++ log_info("/* %s */", __func__); ++ ++ assert_se(parse_emergency_action("none", false, &x) == 0); ++ assert_se(x == EMERGENCY_ACTION_NONE); ++ assert_se(parse_emergency_action("reboot", false, &x) == -EOPNOTSUPP); ++ assert_se(parse_emergency_action("reboot-force", false, &x) == -EOPNOTSUPP); ++ assert_se(parse_emergency_action("reboot-immediate", false, &x) == -EOPNOTSUPP); ++ assert_se(parse_emergency_action("poweroff", false, &x) == -EOPNOTSUPP); ++ assert_se(parse_emergency_action("poweroff-force", false, &x) == -EOPNOTSUPP); ++ assert_se(parse_emergency_action("poweroff-immediate", false, &x) == -EOPNOTSUPP); ++ assert_se(x == EMERGENCY_ACTION_NONE); ++ assert_se(parse_emergency_action("exit", false, &x) == 0); ++ assert_se(x == EMERGENCY_ACTION_EXIT); ++ assert_se(parse_emergency_action("exit-force", false, &x) == 0); ++ assert_se(x == EMERGENCY_ACTION_EXIT_FORCE); ++ assert_se(parse_emergency_action("exit-forcee", false, &x) == -EINVAL); ++ ++ assert_se(parse_emergency_action("none", true, &x) == 0); ++ assert_se(x == EMERGENCY_ACTION_NONE); ++ assert_se(parse_emergency_action("reboot", true, &x) == 0); ++ assert_se(x == EMERGENCY_ACTION_REBOOT); ++ assert_se(parse_emergency_action("reboot-force", true, &x) == 0); ++ assert_se(x == EMERGENCY_ACTION_REBOOT_FORCE); ++ assert_se(parse_emergency_action("reboot-immediate", true, &x) == 0); ++ assert_se(x == EMERGENCY_ACTION_REBOOT_IMMEDIATE); ++ assert_se(parse_emergency_action("poweroff", true, &x) == 0); ++ assert_se(x == EMERGENCY_ACTION_POWEROFF); ++ assert_se(parse_emergency_action("poweroff-force", true, &x) == 0); ++ assert_se(x == EMERGENCY_ACTION_POWEROFF_FORCE); ++ assert_se(parse_emergency_action("poweroff-immediate", true, &x) == 0); ++ assert_se(parse_emergency_action("exit", true, &x) == -EOPNOTSUPP); ++ assert_se(parse_emergency_action("exit-force", true, &x) == -EOPNOTSUPP); ++ assert_se(parse_emergency_action("exit-forcee", true, &x) == -EINVAL); ++ assert_se(x == EMERGENCY_ACTION_POWEROFF_IMMEDIATE); ++} ++ ++int main(int argc, char **argv) { ++ test_setup_logging(LOG_INFO); ++ ++ test_parse_emergency_action(); ++ ++ return EXIT_SUCCESS; ++} diff --git a/0666-core-accept-system-mode-emergency-action-specifiers-.patch b/0666-core-accept-system-mode-emergency-action-specifiers-.patch new file mode 100644 index 0000000000000000000000000000000000000000..b6753ab63c2eb3b7a17513f66c0c33115eb1ce06 --- /dev/null +++ b/0666-core-accept-system-mode-emergency-action-specifiers-.patch @@ -0,0 +1,40 @@ +From 9dbb6564826a0def39a77ad292aecde75537d164 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 16 Oct 2018 14:49:36 +0200 +Subject: [PATCH] core: accept system mode emergency action specifiers with a + warning + +Before we would only accept those "system" values, so there wasn't other +chocie. Let's provide backwards compatiblity in case somebody made use of +this functionality in user mode. + +v2: use 'exit-force' not 'exit' +v3: use error value in log_syntax +(cherry picked from commit 469f76f170db39c72578e869ec7c087bb43f9350) + +Related: #1860899 +--- + src/core/load-fragment.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index c102ffb9f0..c0b1fd4f91 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -4280,6 +4280,16 @@ int config_parse_emergency_action( + + r = parse_emergency_action(rvalue, MANAGER_IS_SYSTEM(m), x); + if (r < 0) { ++ if (r == -EOPNOTSUPP && MANAGER_IS_USER(m)) { ++ /* Compat mode: remove for systemd 241. */ ++ ++ log_syntax(unit, LOG_INFO, filename, line, r, ++ "%s= in user mode specified as \"%s\", using \"exit-force\" instead.", ++ lvalue, rvalue); ++ *x = EMERGENCY_ACTION_EXIT_FORCE; ++ return 0; ++ } ++ + if (r == -EOPNOTSUPP) + log_syntax(unit, LOG_ERR, filename, line, r, + "%s= specified as %s mode action, ignoring: %s", diff --git a/0667-core-allow-services-with-no-commands-but-SuccessActi.patch b/0667-core-allow-services-with-no-commands-but-SuccessActi.patch new file mode 100644 index 0000000000000000000000000000000000000000..8c081ebd7ed5aa6ab85e691e1f987f2ccd916bcd --- /dev/null +++ b/0667-core-allow-services-with-no-commands-but-SuccessActi.patch @@ -0,0 +1,43 @@ +From f97c6d921fb6b3d7ba88e064b03d3dd767df9ba1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 16 Oct 2018 15:07:42 +0200 +Subject: [PATCH] core: allow services with no commands but SuccessAction set + +(cherry picked from commit 3f00d379fa6221a4570c8cd955afd9b661787db9) + +Related: #1860899 +--- + src/core/service.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/src/core/service.c b/src/core/service.c +index 4da1c5accb..7969bbf071 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -556,8 +556,13 @@ static int service_verify(Service *s) { + } + } + +- if (!s->exec_command[SERVICE_EXEC_START] && !s->exec_command[SERVICE_EXEC_STOP]) { +- log_unit_error(UNIT(s), "Service lacks both ExecStart= and ExecStop= setting. Refusing."); ++ if (!s->exec_command[SERVICE_EXEC_START] && !s->exec_command[SERVICE_EXEC_STOP] ++ && UNIT(s)->success_action == EMERGENCY_ACTION_NONE) { ++ /* FailureAction= only makes sense if one of the start or stop commands is specified. ++ * SuccessAction= will be executed unconditionally if no commands are specified. Hence, ++ * either a command or SuccessAction= are required. */ ++ ++ log_unit_error(UNIT(s), "Service has no ExecStart=, ExecStop=, or SuccessAction=. Refusing."); + return -ENOEXEC; + } + +@@ -566,8 +571,8 @@ static int service_verify(Service *s) { + return -ENOEXEC; + } + +- if (!s->remain_after_exit && !s->exec_command[SERVICE_EXEC_START]) { +- log_unit_error(UNIT(s), "Service has no ExecStart= setting, which is only allowed for RemainAfterExit=yes services. Refusing."); ++ if (!s->remain_after_exit && !s->exec_command[SERVICE_EXEC_START] && UNIT(s)->success_action == EMERGENCY_ACTION_NONE) { ++ log_unit_error(UNIT(s), "Service has no ExecStart= and no SuccessAction= settings and does not have RemainAfterExit=yes set. Refusing."); + return -ENOEXEC; + } + diff --git a/0668-core-limit-service-watchdogs-no-to-actual-watchdog-c.patch b/0668-core-limit-service-watchdogs-no-to-actual-watchdog-c.patch new file mode 100644 index 0000000000000000000000000000000000000000..a32dcd7a340ddf4373046120359a061ad58c07db --- /dev/null +++ b/0668-core-limit-service-watchdogs-no-to-actual-watchdog-c.patch @@ -0,0 +1,120 @@ +From b8358d4edf1896a821c9370c9ba31c2bb07c277a Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 16 Oct 2018 15:24:44 +0200 +Subject: [PATCH] core: limit service-watchdogs=no to actual "watchdog" + commands + +The setting is now only looked at when considering an action for a job timeout +or unit start limit. It is ignored for ctrl-alt-del, SuccessAction, SuccessFailure. + +v2: turn the parameter into a flag field +v3: rename Options to Flags +(cherry picked from commit 1710d4beff6329cf6ae0767953cad09593517b2a) + +Related: #1860899 +--- + src/core/emergency-action.c | 3 ++- + src/core/emergency-action.h | 8 +++++++- + src/core/job.c | 3 ++- + src/core/manager.c | 2 +- + src/core/unit.c | 9 ++++++--- + 5 files changed, 18 insertions(+), 7 deletions(-) + +diff --git a/src/core/emergency-action.c b/src/core/emergency-action.c +index 00f5996317..e9e757dfa3 100644 +--- a/src/core/emergency-action.c ++++ b/src/core/emergency-action.c +@@ -24,6 +24,7 @@ static void log_and_status(Manager *m, const char *message, const char *reason) + int emergency_action( + Manager *m, + EmergencyAction action, ++ EmergencyActionFlags options, + const char *reboot_arg, + const char *reason) { + +@@ -34,7 +35,7 @@ int emergency_action( + if (action == EMERGENCY_ACTION_NONE) + return -ECANCELED; + +- if (!m->service_watchdogs) { ++ if (FLAGS_SET(options, EMERGENCY_ACTION_IS_WATCHDOG) && !m->service_watchdogs) { + log_warning("Watchdog disabled! Not acting on: %s", reason); + return -ECANCELED; + } +diff --git a/src/core/emergency-action.h b/src/core/emergency-action.h +index 646ccc4e6b..efbfaf6c6a 100644 +--- a/src/core/emergency-action.h ++++ b/src/core/emergency-action.h +@@ -20,10 +20,16 @@ typedef enum EmergencyAction { + _EMERGENCY_ACTION_INVALID = -1 + } EmergencyAction; + ++typedef enum EmergencyActionFlags { ++ EMERGENCY_ACTION_IS_WATCHDOG = 1 << 0, ++} EmergencyActionFlags; ++ + #include "macro.h" + #include "manager.h" + +-int emergency_action(Manager *m, EmergencyAction action, const char *reboot_arg, const char *reason); ++int emergency_action(Manager *m, ++ EmergencyAction action, EmergencyActionFlags options, ++ const char *reboot_arg, const char *reason); + + const char* emergency_action_to_string(EmergencyAction i) _const_; + EmergencyAction emergency_action_from_string(const char *s) _pure_; +diff --git a/src/core/job.c b/src/core/job.c +index 870ec0a387..d647aac42d 100644 +--- a/src/core/job.c ++++ b/src/core/job.c +@@ -1076,7 +1076,8 @@ static int job_dispatch_timer(sd_event_source *s, uint64_t monotonic, void *user + u = j->unit; + job_finish_and_invalidate(j, JOB_TIMEOUT, true, false); + +- emergency_action(u->manager, u->job_timeout_action, u->job_timeout_reboot_arg, "job timed out"); ++ emergency_action(u->manager, u->job_timeout_action, EMERGENCY_ACTION_IS_WATCHDOG, ++ u->job_timeout_reboot_arg, "job timed out"); + + return 0; + } +diff --git a/src/core/manager.c b/src/core/manager.c +index 3c44ad3dbc..ac1b198b21 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -2528,7 +2528,7 @@ static void manager_handle_ctrl_alt_del(Manager *m) { + if (ratelimit_below(&m->ctrl_alt_del_ratelimit) || m->cad_burst_action == EMERGENCY_ACTION_NONE) + manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE_IRREVERSIBLY); + else +- emergency_action(m, m->cad_burst_action, NULL, ++ emergency_action(m, m->cad_burst_action, 0, NULL, + "Ctrl-Alt-Del was pressed more than 7 times within 2s"); + } + +diff --git a/src/core/unit.c b/src/core/unit.c +index 152a860d08..dc5c89c195 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1669,7 +1669,8 @@ int unit_start_limit_test(Unit *u) { + log_unit_warning(u, "Start request repeated too quickly."); + u->start_limit_hit = true; + +- return emergency_action(u->manager, u->start_limit_action, u->reboot_arg, "unit failed"); ++ return emergency_action(u->manager, u->start_limit_action, EMERGENCY_ACTION_IS_WATCHDOG, ++ u->reboot_arg, "unit failed"); + } + + bool unit_shall_confirm_spawn(Unit *u) { +@@ -2469,9 +2470,11 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlag + unit_check_binds_to(u); + + if (os != UNIT_FAILED && ns == UNIT_FAILED) +- (void) emergency_action(u->manager, u->failure_action, u->reboot_arg, "unit failed"); ++ (void) emergency_action(u->manager, u->failure_action, 0, ++ u->reboot_arg, "unit failed"); + else if (!UNIT_IS_INACTIVE_OR_FAILED(os) && ns == UNIT_INACTIVE) +- (void) emergency_action(u->manager, u->success_action, u->reboot_arg, "unit succeeded"); ++ (void) emergency_action(u->manager, u->success_action, 0, ++ u->reboot_arg, "unit succeeded"); + } + + unit_add_to_dbus_queue(u); diff --git a/0669-units-use-SuccessAction-exit-force-in-systemd-exit.s.patch b/0669-units-use-SuccessAction-exit-force-in-systemd-exit.s.patch new file mode 100644 index 0000000000000000000000000000000000000000..564997ec990e7a819adb61baf3ab6bd2eb56e91e --- /dev/null +++ b/0669-units-use-SuccessAction-exit-force-in-systemd-exit.s.patch @@ -0,0 +1,56 @@ +From b0394ad25fd601b9ef29d26b87f12b0a0c17cda0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 16 Oct 2018 15:09:11 +0200 +Subject: [PATCH] units: use SuccessAction=exit-force in systemd-exit.service + +Fixes #10414. + +v2: +- rename .service.in to .service +- rename 'exit' to 'exit-force' + +(cherry picked from commit 631c9b7bf2dab5065d753a7b1cfaff5b100b3c90) + +Resolves: #1860899 +--- + units/user/meson.build | 2 +- + units/user/{systemd-exit.service.in => systemd-exit.service} | 5 +---- + 2 files changed, 2 insertions(+), 5 deletions(-) + rename units/user/{systemd-exit.service.in => systemd-exit.service} (87%) + +diff --git a/units/user/meson.build b/units/user/meson.build +index b1c2e95597..36341a42f5 100644 +--- a/units/user/meson.build ++++ b/units/user/meson.build +@@ -14,6 +14,7 @@ units = [ + 'sockets.target', + 'sound.target', + 'timers.target', ++ 'systemd-exit.service', + 'systemd-tmpfiles-clean.timer', + ] + +@@ -23,7 +24,6 @@ foreach file : units + endforeach + + in_units = [ +- 'systemd-exit.service', + 'systemd-tmpfiles-clean.service', + 'systemd-tmpfiles-setup.service', + ] +diff --git a/units/user/systemd-exit.service.in b/units/user/systemd-exit.service +similarity index 87% +rename from units/user/systemd-exit.service.in +rename to units/user/systemd-exit.service +index d69273f6b3..1d3b61e3ab 100644 +--- a/units/user/systemd-exit.service.in ++++ b/units/user/systemd-exit.service +@@ -13,7 +13,4 @@ Documentation=man:systemd.special(7) + DefaultDependencies=no + Requires=shutdown.target + After=shutdown.target +- +-[Service] +-Type=oneshot +-ExecStart=@SYSTEMCTL@ --user --force exit ++SuccessAction=exit-force diff --git a/0670-units-use-SuccessAction-reboot-force-in-systemd-rebo.patch b/0670-units-use-SuccessAction-reboot-force-in-systemd-rebo.patch new file mode 100644 index 0000000000000000000000000000000000000000..2b5e428ec34b79df51211de08122d8a7e139959c --- /dev/null +++ b/0670-units-use-SuccessAction-reboot-force-in-systemd-rebo.patch @@ -0,0 +1,51 @@ +From f531c34dd8ead33b9972bcd06017ac80ccedb757 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 16 Oct 2018 15:30:53 +0200 +Subject: [PATCH] units: use SuccessAction=reboot-force in + systemd-reboot.service + +(cherry picked from commit d85515edcf9700dc068201ab9f7103f04f3b25b2) + +Related: #1860899 +--- + units/meson.build | 2 +- + units/{systemd-reboot.service.in => systemd-reboot.service} | 5 +---- + 2 files changed, 2 insertions(+), 5 deletions(-) + rename units/{systemd-reboot.service.in => systemd-reboot.service} (89%) + +diff --git a/units/meson.build b/units/meson.build +index a1cd2524dc..b482431a10 100644 +--- a/units/meson.build ++++ b/units/meson.build +@@ -97,6 +97,7 @@ units = [ + 'sockets.target.wants/'], + ['systemd-networkd.socket', 'ENABLE_NETWORKD', + join_paths(pkgsysconfdir, 'system/sockets.target.wants/')], ++ ['systemd-reboot.service', ''], + ['systemd-rfkill.socket', 'ENABLE_RFKILL'], + ['systemd-tmpfiles-clean.timer', '', + 'timers.target.wants/'], +@@ -182,7 +183,6 @@ in_units = [ + ['systemd-quotacheck.service', 'ENABLE_QUOTACHECK'], + ['systemd-random-seed.service', 'ENABLE_RANDOMSEED', + 'sysinit.target.wants/'], +- ['systemd-reboot.service', ''], + ['systemd-remount-fs.service', '', + 'local-fs.target.wants/'], + ['systemd-resolved.service', 'ENABLE_RESOLVE', +diff --git a/units/systemd-reboot.service.in b/units/systemd-reboot.service +similarity index 89% +rename from units/systemd-reboot.service.in +rename to units/systemd-reboot.service +index 4763ccfdca..505f60aabf 100644 +--- a/units/systemd-reboot.service.in ++++ b/units/systemd-reboot.service +@@ -13,7 +13,4 @@ Documentation=man:systemd-halt.service(8) + DefaultDependencies=no + Requires=shutdown.target umount.target final.target + After=shutdown.target umount.target final.target +- +-[Service] +-Type=oneshot +-ExecStart=@SYSTEMCTL@ --force reboot ++SuccessAction=reboot-force diff --git a/0671-units-use-SuccessAction-poweroff-force-in-systemd-po.patch b/0671-units-use-SuccessAction-poweroff-force-in-systemd-po.patch new file mode 100644 index 0000000000000000000000000000000000000000..93be5d66a8f4b3e8ce83c434d2a8af662feba306 --- /dev/null +++ b/0671-units-use-SuccessAction-poweroff-force-in-systemd-po.patch @@ -0,0 +1,56 @@ +From 7e84234d9953f7ffacf7fff82679c9c9c3b78b7e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 16 Oct 2018 15:34:57 +0200 +Subject: [PATCH] units: use SuccessAction=poweroff-force in + systemd-poweroff.service + +Explicit systemctl calls remain in systemd-halt.service and the system +systemd-exit.service. To convert systemd-halt, we'd need to add +SuccessAction=halt-force. Halting doesn't make much sense, so let's just +leave that is. systemd-exit.service will be converted in the next commit. + +(cherry picked from commit afa6206583dfbc93e29981cb5d713841e4ca2865) + +Related: #1860899 +--- + units/meson.build | 2 +- + ...{systemd-poweroff.service.in => systemd-poweroff.service} | 5 +---- + 2 files changed, 2 insertions(+), 5 deletions(-) + rename units/{systemd-poweroff.service.in => systemd-poweroff.service} (89%) + +diff --git a/units/meson.build b/units/meson.build +index b482431a10..6fa804148b 100644 +--- a/units/meson.build ++++ b/units/meson.build +@@ -97,6 +97,7 @@ units = [ + 'sockets.target.wants/'], + ['systemd-networkd.socket', 'ENABLE_NETWORKD', + join_paths(pkgsysconfdir, 'system/sockets.target.wants/')], ++ ['systemd-poweroff.service', ''], + ['systemd-reboot.service', ''], + ['systemd-rfkill.socket', 'ENABLE_RFKILL'], + ['systemd-tmpfiles-clean.timer', '', +@@ -179,7 +180,6 @@ in_units = [ + ['systemd-nspawn@.service', ''], + ['systemd-portabled.service', 'ENABLE_PORTABLED', + 'dbus-org.freedesktop.portable1.service'], +- ['systemd-poweroff.service', ''], + ['systemd-quotacheck.service', 'ENABLE_QUOTACHECK'], + ['systemd-random-seed.service', 'ENABLE_RANDOMSEED', + 'sysinit.target.wants/'], +diff --git a/units/systemd-poweroff.service.in b/units/systemd-poweroff.service +similarity index 89% +rename from units/systemd-poweroff.service.in +rename to units/systemd-poweroff.service +index e9fd655508..8d1d54389b 100644 +--- a/units/systemd-poweroff.service.in ++++ b/units/systemd-poweroff.service +@@ -13,7 +13,4 @@ Documentation=man:systemd-halt.service(8) + DefaultDependencies=no + Requires=shutdown.target umount.target final.target + After=shutdown.target umount.target final.target +- +-[Service] +-Type=oneshot +-ExecStart=@SYSTEMCTL@ --force poweroff ++SuccessAction=poweroff-force diff --git a/0672-units-allow-and-use-SuccessAction-exit-force-in-syst.patch b/0672-units-allow-and-use-SuccessAction-exit-force-in-syst.patch new file mode 100644 index 0000000000000000000000000000000000000000..f57880214cd567a4e71e45520d3df17691849d5c --- /dev/null +++ b/0672-units-allow-and-use-SuccessAction-exit-force-in-syst.patch @@ -0,0 +1,164 @@ +From c0aa64901aa4d5d7c917fccf0993819fb1a1262f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 16 Oct 2018 16:34:45 +0200 +Subject: [PATCH] units: allow and use SuccessAction=exit-force in system + systemd-exit.service + +C.f. 287419c119ef961db487a281162ab037eba70c61: 'systemctl exit 42' can be +used to set an exit value and pulls in exit.target, which pulls in systemd-exit.service, +which calls org.fdo.Manager.Exit, which calls method_exit(), which sets the objective +to MANAGER_EXIT. Allow the same to happen through SuccessAction=exit. + +v2: update for 'exit' and 'exit-force' +(cherry picked from commit a400bd8c2a6285576edf8e2147e1d17aab129501) + +Related: #1860899 +--- + man/systemd.unit.xml | 7 +++-- + src/core/emergency-action.c | 27 +++++++++++-------- + src/test/test-emergency-action.c | 6 ++--- + units/meson.build | 2 +- + ...d-exit.service.in => systemd-exit.service} | 5 +--- + 5 files changed, 24 insertions(+), 23 deletions(-) + rename units/{systemd-exit.service.in => systemd-exit.service} (88%) + +diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml +index 5772a6684e..e80c760dd6 100644 +--- a/man/systemd.unit.xml ++++ b/man/systemd.unit.xml +@@ -881,9 +881,8 @@ + Takes one of , , , + , , , + , , and . In system mode, +- all options except and are allowed. In user mode, only +- , , and are allowed. Both options default +- to . ++ all options are allowed. In user mode, only , , and ++ are allowed. Both options default to . + + If is set, no action will be triggered. causes a reboot + following the normal shutdown procedure (i.e. equivalent to systemctl reboot). +@@ -893,7 +892,7 @@ + reboot2 system call, which + might result in data loss. Similarly, , , + have the effect of powering down the system with similar +- semantics. causes the user manager to exit following the normal shutdown procedure, and ++ semantics. causes the manager to exit following the normal shutdown procedure, and + causes it terminate without shutting down services. + + +diff --git a/src/core/emergency-action.c b/src/core/emergency-action.c +index e9e757dfa3..44b92ae6f8 100644 +--- a/src/core/emergency-action.c ++++ b/src/core/emergency-action.c +@@ -13,6 +13,7 @@ + #include "special.h" + #include "string-table.h" + #include "terminal-util.h" ++#include "virt.h" + + static void log_and_status(Manager *m, const char *message, const char *reason) { + log_warning("%s: %s", message, reason); +@@ -73,12 +74,14 @@ int emergency_action( + break; + + case EMERGENCY_ACTION_EXIT: +- assert(MANAGER_IS_USER(m)); +- +- log_and_status(m, "Exiting", reason); ++ if (MANAGER_IS_USER(m) || detect_container() > 0) { ++ log_and_status(m, "Exiting", reason); ++ (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_EXIT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL); ++ break; ++ } + +- (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_EXIT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL); +- break; ++ log_notice("Doing \"poweroff\" action instead of an \"exit\" emergency action."); ++ _fallthrough_; + + case EMERGENCY_ACTION_POWEROFF: + log_and_status(m, "Powering off", reason); +@@ -86,11 +89,14 @@ int emergency_action( + break; + + case EMERGENCY_ACTION_EXIT_FORCE: +- assert(MANAGER_IS_USER(m)); ++ if (MANAGER_IS_USER(m) || detect_container() > 0) { ++ log_and_status(m, "Exiting immediately", reason); ++ m->exit_code = MANAGER_EXIT; ++ break; ++ } + +- log_and_status(m, "Exiting immediately", reason); +- m->exit_code = MANAGER_EXIT; +- break; ++ log_notice("Doing \"poweroff-force\" action instead of an \"exit-force\" emergency action."); ++ _fallthrough_; + + case EMERGENCY_ACTION_POWEROFF_FORCE: + log_and_status(m, "Forcibly powering off", reason); +@@ -137,8 +143,7 @@ int parse_emergency_action( + if (x < 0) + return -EINVAL; + +- if ((system && x >= _EMERGENCY_ACTION_FIRST_USER_ACTION) || +- (!system && x != EMERGENCY_ACTION_NONE && x < _EMERGENCY_ACTION_FIRST_USER_ACTION)) ++ if (!system && x != EMERGENCY_ACTION_NONE && x < _EMERGENCY_ACTION_FIRST_USER_ACTION) + return -EOPNOTSUPP; + + *ret = x; +diff --git a/src/test/test-emergency-action.c b/src/test/test-emergency-action.c +index 493b23227e..8ce28ed9f5 100644 +--- a/src/test/test-emergency-action.c ++++ b/src/test/test-emergency-action.c +@@ -36,10 +36,10 @@ static void test_parse_emergency_action(void) { + assert_se(parse_emergency_action("poweroff-force", true, &x) == 0); + assert_se(x == EMERGENCY_ACTION_POWEROFF_FORCE); + assert_se(parse_emergency_action("poweroff-immediate", true, &x) == 0); +- assert_se(parse_emergency_action("exit", true, &x) == -EOPNOTSUPP); +- assert_se(parse_emergency_action("exit-force", true, &x) == -EOPNOTSUPP); ++ assert_se(parse_emergency_action("exit", true, &x) == 0); ++ assert_se(parse_emergency_action("exit-force", true, &x) == 0); + assert_se(parse_emergency_action("exit-forcee", true, &x) == -EINVAL); +- assert_se(x == EMERGENCY_ACTION_POWEROFF_IMMEDIATE); ++ assert_se(x == EMERGENCY_ACTION_EXIT_FORCE); + } + + int main(int argc, char **argv) { +diff --git a/units/meson.build b/units/meson.build +index 6fa804148b..a74fa95195 100644 +--- a/units/meson.build ++++ b/units/meson.build +@@ -86,6 +86,7 @@ units = [ + 'multi-user.target.wants/'], + ['systemd-coredump.socket', 'ENABLE_COREDUMP', + 'sockets.target.wants/'], ++ ['systemd-exit.service', ''], + ['systemd-initctl.socket', '', + 'sockets.target.wants/'], + ['systemd-journal-gatewayd.socket', 'ENABLE_REMOTE HAVE_MICROHTTPD'], +@@ -135,7 +136,6 @@ in_units = [ + ['systemd-binfmt.service', 'ENABLE_BINFMT', + 'sysinit.target.wants/'], + ['systemd-coredump@.service', 'ENABLE_COREDUMP'], +- ['systemd-exit.service', ''], + ['systemd-firstboot.service', 'ENABLE_FIRSTBOOT', + 'sysinit.target.wants/'], + ['systemd-fsck-root.service', ''], +diff --git a/units/systemd-exit.service.in b/units/systemd-exit.service +similarity index 88% +rename from units/systemd-exit.service.in +rename to units/systemd-exit.service +index 2fb6ebd767..6029b13a05 100644 +--- a/units/systemd-exit.service.in ++++ b/units/systemd-exit.service +@@ -13,7 +13,4 @@ Documentation=man:systemd.special(7) + DefaultDependencies=no + Requires=shutdown.target + After=shutdown.target +- +-[Service] +-Type=oneshot +-ExecStart=@SYSTEMCTL@ --force exit ++SuccessAction=exit diff --git a/0673-core-do-not-warn-about-mundane-emergency-actions.patch b/0673-core-do-not-warn-about-mundane-emergency-actions.patch new file mode 100644 index 0000000000000000000000000000000000000000..c00324c9c31b45680dfeeacb32b81224f7b14b82 --- /dev/null +++ b/0673-core-do-not-warn-about-mundane-emergency-actions.patch @@ -0,0 +1,174 @@ +From c8e9877d14c8742cc3732d305af2422f8a16f47d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 17 Oct 2018 17:27:20 +0200 +Subject: [PATCH] core: do not "warn" about mundane emergency actions + +For example in a container we'd log: +Oct 17 17:01:10 rawhide systemd[1]: Started Power-Off. +Oct 17 17:01:10 rawhide systemd[1]: Forcibly powering off: unit succeeded +Oct 17 17:01:10 rawhide systemd[1]: Reached target Power-Off. +Oct 17 17:01:10 rawhide systemd[1]: Shutting down. +and on the console we'd write (in red) +[ !! ] Forcibly powering off: unit succeeded + +This is not useful in any way, and the fact that we're calling an "emergency action" +is an internal implementation detail. Let's log about c-a-d and the watchdog actions +only. + +(cherry picked from commit c7adcb1af9946d0672c16bb4bb7eedf39b3d1fcb) + +Related: #1860899 +--- + src/core/emergency-action.c | 29 ++++++++++++++++------------- + src/core/emergency-action.h | 1 + + src/core/job.c | 3 ++- + src/core/manager.c | 2 +- + src/core/unit.c | 3 ++- + 5 files changed, 22 insertions(+), 16 deletions(-) + +diff --git a/src/core/emergency-action.c b/src/core/emergency-action.c +index 44b92ae6f8..fea1cb83db 100644 +--- a/src/core/emergency-action.c ++++ b/src/core/emergency-action.c +@@ -15,11 +15,12 @@ + #include "terminal-util.h" + #include "virt.h" + +-static void log_and_status(Manager *m, const char *message, const char *reason) { +- log_warning("%s: %s", message, reason); +- manager_status_printf(m, STATUS_TYPE_EMERGENCY, +- ANSI_HIGHLIGHT_RED " !! " ANSI_NORMAL, +- "%s: %s", message, reason); ++static void log_and_status(Manager *m, bool warn, const char *message, const char *reason) { ++ log_full(warn ? LOG_WARNING : LOG_DEBUG, "%s: %s", message, reason); ++ if (warn) ++ manager_status_printf(m, STATUS_TYPE_EMERGENCY, ++ ANSI_HIGHLIGHT_RED " !! " ANSI_NORMAL, ++ "%s: %s", message, reason); + } + + int emergency_action( +@@ -41,17 +42,19 @@ int emergency_action( + return -ECANCELED; + } + ++ bool warn = FLAGS_SET(options, EMERGENCY_ACTION_WARN); ++ + switch (action) { + + case EMERGENCY_ACTION_REBOOT: +- log_and_status(m, "Rebooting", reason); ++ log_and_status(m, warn, "Rebooting", reason); + + (void) update_reboot_parameter_and_warn(reboot_arg); + (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL); + break; + + case EMERGENCY_ACTION_REBOOT_FORCE: +- log_and_status(m, "Forcibly rebooting", reason); ++ log_and_status(m, warn, "Forcibly rebooting", reason); + + (void) update_reboot_parameter_and_warn(reboot_arg); + m->exit_code = MANAGER_REBOOT; +@@ -59,7 +62,7 @@ int emergency_action( + break; + + case EMERGENCY_ACTION_REBOOT_IMMEDIATE: +- log_and_status(m, "Rebooting immediately", reason); ++ log_and_status(m, warn, "Rebooting immediately", reason); + + sync(); + +@@ -75,7 +78,7 @@ int emergency_action( + + case EMERGENCY_ACTION_EXIT: + if (MANAGER_IS_USER(m) || detect_container() > 0) { +- log_and_status(m, "Exiting", reason); ++ log_and_status(m, warn, "Exiting", reason); + (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_EXIT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL); + break; + } +@@ -84,13 +87,13 @@ int emergency_action( + _fallthrough_; + + case EMERGENCY_ACTION_POWEROFF: +- log_and_status(m, "Powering off", reason); ++ log_and_status(m, warn, "Powering off", reason); + (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL, NULL); + break; + + case EMERGENCY_ACTION_EXIT_FORCE: + if (MANAGER_IS_USER(m) || detect_container() > 0) { +- log_and_status(m, "Exiting immediately", reason); ++ log_and_status(m, warn, "Exiting immediately", reason); + m->exit_code = MANAGER_EXIT; + break; + } +@@ -99,12 +102,12 @@ int emergency_action( + _fallthrough_; + + case EMERGENCY_ACTION_POWEROFF_FORCE: +- log_and_status(m, "Forcibly powering off", reason); ++ log_and_status(m, warn, "Forcibly powering off", reason); + m->exit_code = MANAGER_POWEROFF; + break; + + case EMERGENCY_ACTION_POWEROFF_IMMEDIATE: +- log_and_status(m, "Powering off immediately", reason); ++ log_and_status(m, warn, "Powering off immediately", reason); + + sync(); + +diff --git a/src/core/emergency-action.h b/src/core/emergency-action.h +index efbfaf6c6a..2aa1497118 100644 +--- a/src/core/emergency-action.h ++++ b/src/core/emergency-action.h +@@ -22,6 +22,7 @@ typedef enum EmergencyAction { + + typedef enum EmergencyActionFlags { + EMERGENCY_ACTION_IS_WATCHDOG = 1 << 0, ++ EMERGENCY_ACTION_WARN = 1 << 1, + } EmergencyActionFlags; + + #include "macro.h" +diff --git a/src/core/job.c b/src/core/job.c +index d647aac42d..43ab55ed18 100644 +--- a/src/core/job.c ++++ b/src/core/job.c +@@ -1076,7 +1076,8 @@ static int job_dispatch_timer(sd_event_source *s, uint64_t monotonic, void *user + u = j->unit; + job_finish_and_invalidate(j, JOB_TIMEOUT, true, false); + +- emergency_action(u->manager, u->job_timeout_action, EMERGENCY_ACTION_IS_WATCHDOG, ++ emergency_action(u->manager, u->job_timeout_action, ++ EMERGENCY_ACTION_IS_WATCHDOG|EMERGENCY_ACTION_WARN, + u->job_timeout_reboot_arg, "job timed out"); + + return 0; +diff --git a/src/core/manager.c b/src/core/manager.c +index ac1b198b21..ee976f70b3 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -2528,7 +2528,7 @@ static void manager_handle_ctrl_alt_del(Manager *m) { + if (ratelimit_below(&m->ctrl_alt_del_ratelimit) || m->cad_burst_action == EMERGENCY_ACTION_NONE) + manager_start_target(m, SPECIAL_CTRL_ALT_DEL_TARGET, JOB_REPLACE_IRREVERSIBLY); + else +- emergency_action(m, m->cad_burst_action, 0, NULL, ++ emergency_action(m, m->cad_burst_action, EMERGENCY_ACTION_WARN, NULL, + "Ctrl-Alt-Del was pressed more than 7 times within 2s"); + } + +diff --git a/src/core/unit.c b/src/core/unit.c +index dc5c89c195..23afa24c77 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1669,7 +1669,8 @@ int unit_start_limit_test(Unit *u) { + log_unit_warning(u, "Start request repeated too quickly."); + u->start_limit_hit = true; + +- return emergency_action(u->manager, u->start_limit_action, EMERGENCY_ACTION_IS_WATCHDOG, ++ return emergency_action(u->manager, u->start_limit_action, ++ EMERGENCY_ACTION_IS_WATCHDOG|EMERGENCY_ACTION_WARN, + u->reboot_arg, "unit failed"); + } + diff --git a/0674-core-return-true-from-cg_is_empty-on-ENOENT.patch b/0674-core-return-true-from-cg_is_empty-on-ENOENT.patch new file mode 100644 index 0000000000000000000000000000000000000000..09c30643438a8dc55ea016281abec2498c045b41 --- /dev/null +++ b/0674-core-return-true-from-cg_is_empty-on-ENOENT.patch @@ -0,0 +1,43 @@ +From 2aaa40e698f66fd10d0a7a71ca39637e24809e97 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 17 Oct 2018 17:48:35 +0200 +Subject: [PATCH] core: return true from cg_is_empty* on ENOENT + +(cherry picked from commit 1bcf3fc6c57d92927b96cad8c739099b4ceae236) + +Related: #1860899 +--- + src/basic/cgroup-util.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c +index 992b12811a..14abe6e014 100644 +--- a/src/basic/cgroup-util.c ++++ b/src/basic/cgroup-util.c +@@ -1177,7 +1177,7 @@ int cg_is_empty(const char *controller, const char *path) { + + r = cg_enumerate_processes(controller, path, &f); + if (r == -ENOENT) +- return 1; ++ return true; + if (r < 0) + return r; + +@@ -1207,6 +1207,8 @@ int cg_is_empty_recursive(const char *controller, const char *path) { + * via the "populated" attribute of "cgroup.events". */ + + r = cg_read_event(controller, path, "populated", &t); ++ if (r == -ENOENT) ++ return true; + if (r < 0) + return r; + +@@ -1221,7 +1223,7 @@ int cg_is_empty_recursive(const char *controller, const char *path) { + + r = cg_enumerate_subgroups(controller, path, &d); + if (r == -ENOENT) +- return 1; ++ return true; + if (r < 0) + return r; + diff --git a/0675-macro-define-HAS_FEATURE_ADDRESS_SANITIZER-also-on-g.patch b/0675-macro-define-HAS_FEATURE_ADDRESS_SANITIZER-also-on-g.patch new file mode 100644 index 0000000000000000000000000000000000000000..53b501655ed3a3176af5c644e21d205d247484d4 --- /dev/null +++ b/0675-macro-define-HAS_FEATURE_ADDRESS_SANITIZER-also-on-g.patch @@ -0,0 +1,29 @@ +From 01da36fadd365329cfd9e2c97eb419c63404b25f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 3 Dec 2018 17:30:19 +0100 +Subject: [PATCH] macro: define HAS_FEATURE_ADDRESS_SANITIZER also on gcc + +Let's make differences between compilers more minimal. + +(cherry picked from commit be5f77b26e22a806179c7b03e03d424682ed325c) + +Related: #2017033 +--- + src/basic/macro.h | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/basic/macro.h b/src/basic/macro.h +index 62f2359633..e87026882f 100644 +--- a/src/basic/macro.h ++++ b/src/basic/macro.h +@@ -56,7 +56,9 @@ + #endif + + #if !defined(HAS_FEATURE_ADDRESS_SANITIZER) +-# if defined(__has_feature) ++# ifdef __SANITIZE_ADDRESS__ ++# define HAS_FEATURE_ADDRESS_SANITIZER 1 ++# elif defined(__has_feature) + # if __has_feature(address_sanitizer) + # define HAS_FEATURE_ADDRESS_SANITIZER 1 + # endif diff --git a/0676-tests-add-helper-function-to-autodetect-CI-environme.patch b/0676-tests-add-helper-function-to-autodetect-CI-environme.patch new file mode 100644 index 0000000000000000000000000000000000000000..3d0cab932580cbfbf2a721091dcd8586f7cfa6a0 --- /dev/null +++ b/0676-tests-add-helper-function-to-autodetect-CI-environme.patch @@ -0,0 +1,104 @@ +From 6fbbf368f5a6d181b21f448255d5a4182dc2ab3a Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 29 Nov 2021 13:00:21 +0100 +Subject: [PATCH] tests: add helper function to autodetect CI environments + +Sadly there is no standarized way to check if we're running in some +CI environment. So let's try to gather the heuristics in one helper +function. + +Loosely cherry-picked from 4eb0c875f8825199a829ddc597874915fbee0a84. + +Related: #2017033 +--- + src/basic/string-util.h | 6 ++++++ + src/shared/tests.c | 42 +++++++++++++++++++++++++++++++++++++++++ + src/shared/tests.h | 3 +++ + 3 files changed, 51 insertions(+) + +diff --git a/src/basic/string-util.h b/src/basic/string-util.h +index 96a9260f93..742b566932 100644 +--- a/src/basic/string-util.h ++++ b/src/basic/string-util.h +@@ -32,6 +32,12 @@ static inline bool streq_ptr(const char *a, const char *b) { + return strcmp_ptr(a, b) == 0; + } + ++static inline char* strstr_ptr(const char *haystack, const char *needle) { ++ if (!haystack || !needle) ++ return NULL; ++ return strstr(haystack, needle); ++} ++ + static inline const char* strempty(const char *s) { + return s ?: ""; + } +diff --git a/src/shared/tests.c b/src/shared/tests.c +index 100b62b9b0..1da80d653f 100644 +--- a/src/shared/tests.c ++++ b/src/shared/tests.c +@@ -7,7 +7,9 @@ + #include + + #include "tests.h" ++#include "env-util.h" + #include "path-util.h" ++#include "strv.h" + + char* setup_fake_runtime_dir(void) { + char t[] = "/tmp/fake-xdg-runtime-XXXXXX", *p; +@@ -75,3 +77,43 @@ void test_setup_logging(int level) { + log_parse_environment(); + log_open(); + } ++ ++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 ++ * expected to use strstr on the returned value. */ ++ static const char *ans = (void*) UINTPTR_MAX; ++ const char *p; ++ int r; ++ ++ if (ans != (void*) UINTPTR_MAX) ++ return ans; ++ ++ /* We allow specifying the environment with $CITYPE. Nobody uses this so far, but we are ready. */ ++ p = getenv("CITYPE"); ++ if (!isempty(p)) ++ return (ans = p); ++ ++ if (getenv_bool("TRAVIS") > 0) ++ return (ans = "travis"); ++ if (getenv_bool("SEMAPHORE") > 0) ++ return (ans = "semaphore"); ++ if (getenv_bool("GITHUB_ACTIONS") > 0) ++ return (ans = "github-actions"); ++ if (getenv("AUTOPKGTEST_ARTIFACTS") || getenv("AUTOPKGTEST_TMP")) ++ return (ans = "autopkgtest"); ++ ++ FOREACH_STRING(p, "CI", "CONTINOUS_INTEGRATION") { ++ /* Those vars are booleans according to Semaphore and Travis docs: ++ * https://docs.travis-ci.com/user/environment-variables/#default-environment-variables ++ * https://docs.semaphoreci.com/ci-cd-environment/environment-variables/#ci ++ */ ++ r = getenv_bool(p); ++ if (r > 0) ++ return (ans = "unknown"); /* Some other unknown thing */ ++ if (r == 0) ++ return (ans = NULL); ++ } ++ ++ return (ans = NULL); ++} +diff --git a/src/shared/tests.h b/src/shared/tests.h +index 3d696d02fd..4f8f349097 100644 +--- a/src/shared/tests.h ++++ b/src/shared/tests.h +@@ -5,3 +5,6 @@ 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); ++ ++/* Provide a convenient way to check if we're running in CI. */ ++const char *ci_environment(void); diff --git a/0677-strv-rework-FOREACH_STRING-macro.patch b/0677-strv-rework-FOREACH_STRING-macro.patch new file mode 100644 index 0000000000000000000000000000000000000000..6ebdf7db86aa960ff7422d111ced0c4d6f7d9fd2 --- /dev/null +++ b/0677-strv-rework-FOREACH_STRING-macro.patch @@ -0,0 +1,48 @@ +From 3539a72c260063713e4ecba17966ba9a768d8af9 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 16 Jan 2019 00:13:38 +0100 +Subject: [PATCH] strv: rework FOREACH_STRING() macro + +So it's apparently problematic that we use STRV_MAKE() (i.e. a compound +initializer) outside of the {} block we use it in (and that includes +outside of the ({}) block, too). Hence, let's rework the macro to not +need that. + +This also makes the macro shorter, which is definitely a good and more +readable. Moreover, it will now complain if the iterator is a "char*" +instead of a "const char*", which is good too. + +Fixes: #11394 +(cherry picked from commit 66a64081f82dfad90f2f9394a477820a2e3e6510) + +Related: #2017033 +--- + src/basic/strv.h | 15 ++++----------- + 1 file changed, 4 insertions(+), 11 deletions(-) + +diff --git a/src/basic/strv.h b/src/basic/strv.h +index c1e4c973b6..a09d76706d 100644 +--- a/src/basic/strv.h ++++ b/src/basic/strv.h +@@ -148,17 +148,10 @@ void strv_print(char **l); + _found; \ + }) + +-#define FOREACH_STRING(x, ...) \ +- for (char **_l = ({ \ +- char **_ll = STRV_MAKE(__VA_ARGS__); \ +- x = _ll ? _ll[0] : NULL; \ +- _ll; \ +- }); \ +- _l && *_l; \ +- x = ({ \ +- _l ++; \ +- _l[0]; \ +- })) ++#define FOREACH_STRING(x, y, ...) \ ++ for (char **_l = STRV_MAKE(({ x = y; }), ##__VA_ARGS__); \ ++ x; \ ++ x = *(++_l)) + + char **strv_reverse(char **l); + char **strv_shell_escape(char **l, const char *bad); diff --git a/0678-test-systemctl-use-const-char-instead-of-char.patch b/0678-test-systemctl-use-const-char-instead-of-char.patch new file mode 100644 index 0000000000000000000000000000000000000000..866d5bb2b4ac5f57d5b822128f816cee3c22e063 --- /dev/null +++ b/0678-test-systemctl-use-const-char-instead-of-char.patch @@ -0,0 +1,45 @@ +From fdfff847313222eed3306ac605db46d8cbd23212 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 29 Nov 2021 13:47:24 +0100 +Subject: [PATCH] test,systemctl: use "const char*" instead of "char*" + +as iterator for FOREACH_STRING() + +The macro iterates through literal strings (i.e. constant strings), +hence it's more correct to have the iterator const too. + +Based on b2238e380e5f2fbcc129643b3fbd66f2828fd57c. + +Related: #2017033 +--- + src/systemctl/systemctl.c | 3 ++- + src/test/test-execute.c | 2 +- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c +index 3dd7c1522f..b967550b97 100644 +--- a/src/systemctl/systemctl.c ++++ b/src/systemctl/systemctl.c +@@ -7011,7 +7011,8 @@ static int run_editor(char **paths) { + if (r == 0) { + const char **args; + char *editor, **editor_args = NULL; +- char **tmp_path, **original_path, *p; ++ char **tmp_path, **original_path; ++ const char *p; + size_t n_editor_args = 0, i = 1; + size_t argc; + +diff --git a/src/test/test-execute.c b/src/test/test-execute.c +index 5303652b93..7581d5ed68 100644 +--- a/src/test/test-execute.c ++++ b/src/test/test-execute.c +@@ -146,7 +146,7 @@ invalid: + } + + static bool is_inaccessible_available(void) { +- char *p; ++ const char *p; + + FOREACH_STRING(p, + "/run/systemd/inaccessible/reg", diff --git a/0679-ci-pass-the-GITHUB_ACTIONS-variable-to-the-CentOS-co.patch b/0679-ci-pass-the-GITHUB_ACTIONS-variable-to-the-CentOS-co.patch new file mode 100644 index 0000000000000000000000000000000000000000..ef3751583bf6cdc1c72e873e5aa21b8eda39c5c4 --- /dev/null +++ b/0679-ci-pass-the-GITHUB_ACTIONS-variable-to-the-CentOS-co.patch @@ -0,0 +1,27 @@ +From a8fd8d157c832ddad34a9a3e372579c58261f7fb Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 29 Nov 2021 13:59:41 +0100 +Subject: [PATCH] ci: pass the $GITHUB_ACTIONS variable to the CentOS container + +so we can properly skip tests which are problematic when running in GH +Actions. + +Related: #2017033 +rhel-only +--- + .github/workflows/unit_tests.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/unit_tests.sh b/.github/workflows/unit_tests.sh +index 814870e7a0..c1311310fb 100755 +--- a/.github/workflows/unit_tests.sh ++++ b/.github/workflows/unit_tests.sh +@@ -131,7 +131,7 @@ for phase in "${PHASES[@]}"; do + # Pull a Docker image and start a new container + docker pull quay.io/centos/centos:$CENTOS_RELEASE + info "Starting container $CONT_NAME" +- $DOCKER_RUN -v $REPO_ROOT:/build:rw \ ++ $DOCKER_RUN -v $REPO_ROOT:/build:rw -e GITHUB_ACTIONS="$GITHUB_ACTIONS" \ + -w /build --privileged=true --name $CONT_NAME \ + -dit --net=host quay.io/centos/centos:$CENTOS_RELEASE /sbin/init + diff --git a/0680-lgtm-detect-uninitialized-variables-using-the-__clea.patch b/0680-lgtm-detect-uninitialized-variables-using-the-__clea.patch new file mode 100644 index 0000000000000000000000000000000000000000..d8f878eef780c13ba465062a7d9b75a99f5c9a93 --- /dev/null +++ b/0680-lgtm-detect-uninitialized-variables-using-the-__clea.patch @@ -0,0 +1,171 @@ +From cecb3cc06f6025835324c1837c03def1d9be8eb1 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Wed, 1 Dec 2021 21:31:43 +0100 +Subject: [PATCH] lgtm: detect uninitialized variables using the __cleanup__ + attribute + +This is a slightly modified version of the original +`cpp/uninitialized-local` CodeQL query which focuses only on variables +using the cleanup macros. Since this has proven to cause issues in the +past, let's panic on every uninitialized variable using any of the +cleanup macros (as long as they're written using the __cleanup__ +attribute). + +Some test results from a test I used when writing the query: + +``` + #define _cleanup_foo_ __attribute__((__cleanup__(foo))) + #define _cleanup_(x) __attribute__((__cleanup__(x))) + + static inline void freep(void *p) { + *(void**)p = mfree(*(void**) p); + } + + #define _cleanup_free_ _cleanup_(freep) + + static inline void foo(char **p) { + if (*p) + *p = free(*p); + } + + int main(void) { + __attribute__((__cleanup__(foo))) char *a; + char *b; + _cleanup_foo_ char *c; + char **d; + _cleanup_free_ char *e; + int r; + + r = fun(&e); + if (r < 0) + return 1; + + puts(a); + puts(b); + puts(c); + puts(*d); + puts(e); + + return 0; + } +``` + +``` ++| test.c:23:14:23:14 | e | The variable $@ may not be initialized here, but has a cleanup handler. | test.c:20:26:20:26 | e | e | ++| test.c:27:10:27:10 | a | The variable $@ may not be initialized here, but has a cleanup handler. | test.c:16:45:16:45 | a | a | ++| test.c:29:10:29:10 | c | The variable $@ may not be initialized here, but has a cleanup handler. | test.c:18:25:18:25 | c | c | +``` + +(cherry picked from commit 863bff75488d33f519deea6390988f3d9d72e6de) + +Related: #2017033 +--- + .../UninitializedVariableWithCleanup.ql | 99 +++++++++++++++++++ + 1 file changed, 99 insertions(+) + create mode 100644 .lgtm/cpp-queries/UninitializedVariableWithCleanup.ql + +diff --git a/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql b/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql +new file mode 100644 +index 0000000000..6bf0ae01eb +--- /dev/null ++++ b/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql +@@ -0,0 +1,99 @@ ++/** ++ * vi: sw=2 ts=2 et syntax=ql: ++ * ++ * Based on cpp/uninitialized-local. ++ * ++ * @name Potentially uninitialized local variable using the cleanup attribute ++ * @description Running the cleanup handler on a possibly uninitialized variable ++ * is generally a bad idea. ++ * @id cpp/uninitialized-local-with-cleanup ++ * @kind problem ++ * @problem.severity error ++ * @precision high ++ * @tags security ++ */ ++ ++import cpp ++import semmle.code.cpp.controlflow.StackVariableReachability ++ ++/** ++ * Auxiliary predicate: Types that don't require initialization ++ * before they are used, since they're stack-allocated. ++ */ ++predicate allocatedType(Type t) { ++ /* Arrays: "int foo[1]; foo[0] = 42;" is ok. */ ++ t instanceof ArrayType ++ or ++ /* Structs: "struct foo bar; bar.baz = 42" is ok. */ ++ t instanceof Class ++ or ++ /* Typedefs to other allocated types are fine. */ ++ allocatedType(t.(TypedefType).getUnderlyingType()) ++ or ++ /* Type specifiers don't affect whether or not a type is allocated. */ ++ allocatedType(t.getUnspecifiedType()) ++} ++ ++/** ++ * A declaration of a local variable using __attribute__((__cleanup__(x))) ++ * that leaves the variable uninitialized. ++ */ ++DeclStmt declWithNoInit(LocalVariable v) { ++ result.getADeclaration() = v and ++ not exists(v.getInitializer()) and ++ /* The variable has __attribute__((__cleanup__(...))) set */ ++ v.getAnAttribute().hasName("cleanup") and ++ /* The type of the variable is not stack-allocated. */ ++ exists(Type t | t = v.getType() | not allocatedType(t)) ++} ++ ++class UninitialisedLocalReachability extends StackVariableReachability { ++ UninitialisedLocalReachability() { this = "UninitialisedLocal" } ++ ++ override predicate isSource(ControlFlowNode node, StackVariable v) { node = declWithNoInit(v) } ++ ++ /* Note: _don't_ use the `useOfVarActual()` predicate here (and a couple of lines ++ * below), as it assumes that the callee always modifies the variable if ++ * it's passed to the function. ++ * ++ * i.e.: ++ * _cleanup_free char *x; ++ * fun(&x); ++ * puts(x); ++ * ++ * `useOfVarActual()` won't treat this an an uninitialized read even if the callee ++ * doesn't modify the argument, however, `useOfVar()` will ++ */ ++ override predicate isSink(ControlFlowNode node, StackVariable v) { useOfVar(v, node) } ++ ++ override predicate isBarrier(ControlFlowNode node, StackVariable v) { ++ // only report the _first_ possibly uninitialized use ++ useOfVar(v, node) or ++ definitionBarrier(v, node) ++ } ++} ++ ++pragma[noinline] ++predicate containsInlineAssembly(Function f) { exists(AsmStmt s | s.getEnclosingFunction() = f) } ++ ++/** ++ * Auxiliary predicate: List common exceptions or false positives ++ * for this check to exclude them. ++ */ ++VariableAccess commonException() { ++ // If the uninitialized use we've found is in a macro expansion, it's ++ // typically something like va_start(), and we don't want to complain. ++ result.getParent().isInMacroExpansion() ++ or ++ result.getParent() instanceof BuiltInOperation ++ or ++ // Finally, exclude functions that contain assembly blocks. It's ++ // anyone's guess what happens in those. ++ containsInlineAssembly(result.getEnclosingFunction()) ++} ++ ++from UninitialisedLocalReachability r, LocalVariable v, VariableAccess va ++where ++ r.reaches(_, v, va) and ++ not va = commonException() ++select va, "The variable $@ may not be initialized here, but has a cleanup handler.", v, v.getName() diff --git a/0681-lgtm-replace-the-query-used-for-looking-for-fgets-wi.patch b/0681-lgtm-replace-the-query-used-for-looking-for-fgets-wi.patch new file mode 100644 index 0000000000000000000000000000000000000000..acccb51592061f158d6ceaf033c572189bd830ff --- /dev/null +++ b/0681-lgtm-replace-the-query-used-for-looking-for-fgets-wi.patch @@ -0,0 +1,84 @@ +From c4a34b71d4f51f071f7a722059e36388b41d30e4 Mon Sep 17 00:00:00 2001 +From: Evgeny Vereshchagin +Date: Mon, 11 Mar 2019 21:05:13 +0100 +Subject: [PATCH] lgtm: replace the query used for looking for fgets with a + more general query + +to make it easier to comlain about `strtok` :-) + +Inspired by https://github.com/systemd/systemd/pull/11963, which, in turn, +was prompted by https://github.com/systemd/systemd/pull/11555. + +(cherry picked from commit 7ba5ded9dbd7737bc368521f5ea7c90e5b06ab3e) + +Related: #2017033 +--- + .../PotentiallyDangerousFunction.ql | 30 +++++++++++++++++++ + .lgtm/cpp-queries/fgets.ql | 21 ------------- + 2 files changed, 30 insertions(+), 21 deletions(-) + create mode 100644 .lgtm/cpp-queries/PotentiallyDangerousFunction.ql + delete mode 100644 .lgtm/cpp-queries/fgets.ql + +diff --git a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql +new file mode 100644 +index 0000000000..ba80f4ad8c +--- /dev/null ++++ b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql +@@ -0,0 +1,30 @@ ++/** ++ * @name Use of potentially dangerous function ++ * @description Certain standard library functions are dangerous to call. ++ * @kind problem ++ * @problem.severity error ++ * @precision high ++ * @id cpp/potentially-dangerous-function ++ * @tags reliability ++ * security ++ * ++ * Borrowed from ++ * https://github.com/Semmle/ql/blob/master/cpp/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.ql ++ */ ++import cpp ++ ++predicate potentiallyDangerousFunction(Function f, string message) { ++ ( ++ f.getQualifiedName() = "fgets" and ++ message = "Call to fgets is potentially dangerous. Use read_line() instead." ++ ) or ( ++ f.getQualifiedName() = "strtok" and ++ message = "Call to strtok is potentially dangerous. Use extract_first_word() instead." ++ ) ++} ++ ++from FunctionCall call, Function target, string message ++where ++ call.getTarget() = target and ++ potentiallyDangerousFunction(target, message) ++select call, message +diff --git a/.lgtm/cpp-queries/fgets.ql b/.lgtm/cpp-queries/fgets.ql +deleted file mode 100644 +index a4181e4f3d..0000000000 +--- a/.lgtm/cpp-queries/fgets.ql ++++ /dev/null +@@ -1,21 +0,0 @@ +-/** +- * @name Use of fgets() +- * @description fgets() is dangerous to call. Use read_line() instead. +- * @kind problem +- * @problem.severity error +- * @precision high +- * @id cpp/fgets +- * @tags reliability +- * security +- */ +-import cpp +- +-predicate dangerousFunction(Function function) { +- exists (string name | name = function.getQualifiedName() | +- name = "fgets") +-} +- +-from FunctionCall call, Function target +-where call.getTarget() = target +- and dangerousFunction(target) +-select call, target.getQualifiedName() + " is potentially dangerous" diff --git a/0682-lgtm-beef-up-list-of-dangerous-questionnable-API-cal.patch b/0682-lgtm-beef-up-list-of-dangerous-questionnable-API-cal.patch new file mode 100644 index 0000000000000000000000000000000000000000..03e39399a31648fd50c2639ac81df4c3b07e8c47 --- /dev/null +++ b/0682-lgtm-beef-up-list-of-dangerous-questionnable-API-cal.patch @@ -0,0 +1,48 @@ +From 8b60932555141e1fe61a343863eae7655c2449a9 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 2 Apr 2019 12:43:47 +0200 +Subject: [PATCH] lgtm: beef up list of dangerous/questionnable API calls not + to make + +(cherry picked from commit 9b4805421eb2a7319f6507a26febfb9d2cdc3a93) + +Related: #2017033 +--- + .../PotentiallyDangerousFunction.ql | 22 +++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +diff --git a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql +index ba80f4ad8c..cd0284b37a 100644 +--- a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql ++++ b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql +@@ -16,10 +16,28 @@ import cpp + predicate potentiallyDangerousFunction(Function f, string message) { + ( + f.getQualifiedName() = "fgets" and +- message = "Call to fgets is potentially dangerous. Use read_line() instead." ++ message = "Call to fgets() is potentially dangerous. Use read_line() instead." + ) or ( + f.getQualifiedName() = "strtok" and +- message = "Call to strtok is potentially dangerous. Use extract_first_word() instead." ++ message = "Call to strtok() is potentially dangerous. Use extract_first_word() instead." ++ ) or ( ++ f.getQualifiedName() = "strsep" and ++ message = "Call to strsep() is potentially dangerous. Use extract_first_word() instead." ++ ) or ( ++ f.getQualifiedName() = "dup" and ++ message = "Call to dup() is potentially dangerous. Use fcntl(fd, FD_DUPFD_CLOEXEC, 3) instead." ++ ) or ( ++ f.getQualifiedName() = "htonl" and ++ message = "Call to htonl() is confusing. Use htobe32() instead." ++ ) or ( ++ f.getQualifiedName() = "htons" and ++ message = "Call to htons() is confusing. Use htobe16() instead." ++ ) or ( ++ f.getQualifiedName() = "ntohl" and ++ message = "Call to ntohl() is confusing. Use be32toh() instead." ++ ) or ( ++ f.getQualifiedName() = "ntohs" and ++ message = "Call to ntohs() is confusing. Use be16toh() instead." + ) + } + diff --git a/0683-lgtm-warn-about-strerror-use.patch b/0683-lgtm-warn-about-strerror-use.patch new file mode 100644 index 0000000000000000000000000000000000000000..2661bfef769ac17b0000c8b57d24a982c73c0e73 --- /dev/null +++ b/0683-lgtm-warn-about-strerror-use.patch @@ -0,0 +1,26 @@ +From af6eac25456d4ca7e8233e00aec7531e640f17af Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 5 Apr 2019 15:31:34 +0200 +Subject: [PATCH] lgtm: warn about strerror() use + +(cherry picked from commit 9ff46eded2b99d244455467eb55c0ff3f51c5362) + +Related: #2017033 +--- + .lgtm/cpp-queries/PotentiallyDangerousFunction.ql | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql +index cd0284b37a..96712cf1c6 100644 +--- a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql ++++ b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql +@@ -38,6 +38,9 @@ predicate potentiallyDangerousFunction(Function f, string message) { + ) or ( + f.getQualifiedName() = "ntohs" and + message = "Call to ntohs() is confusing. Use be16toh() instead." ++ ) or ( ++ f.getQualifiedName() = "strerror" and ++ message = "Call to strerror() is not thread-safe. Use strerror_r() or printf()'s %m format string instead." + ) + } + diff --git a/0684-lgtm-complain-about-accept-people-should-use-accept4.patch b/0684-lgtm-complain-about-accept-people-should-use-accept4.patch new file mode 100644 index 0000000000000000000000000000000000000000..7c3b69c374e28e84a67d56c13d0e72daa71c4784 --- /dev/null +++ b/0684-lgtm-complain-about-accept-people-should-use-accept4.patch @@ -0,0 +1,27 @@ +From bfa090ce83f2b0734c526a4426a20f6f0f943aa0 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 10 Apr 2019 19:36:40 +0200 +Subject: [PATCH] lgtm: complain about accept() [people should use accept4() + instead, due to O_CLOEXEC] + +(cherry picked from commit e2d0fa6feb3797246c8bfda3db45a2f5b62e1b5b) + +Related: #2017033 +--- + .lgtm/cpp-queries/PotentiallyDangerousFunction.ql | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql +index 96712cf1c6..865330430d 100644 +--- a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql ++++ b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql +@@ -41,6 +41,9 @@ predicate potentiallyDangerousFunction(Function f, string message) { + ) or ( + f.getQualifiedName() = "strerror" and + message = "Call to strerror() is not thread-safe. Use strerror_r() or printf()'s %m format string instead." ++ ) or ( ++ f.getQualifiedName() = "accept" and ++ message = "Call to accept() is not O_CLOEXEC-safe. Use accept4() instead." + ) + } + diff --git a/0685-lgtm-don-t-treat-the-custom-note-as-a-list-of-tags.patch b/0685-lgtm-don-t-treat-the-custom-note-as-a-list-of-tags.patch new file mode 100644 index 0000000000000000000000000000000000000000..0eb213facf4c8eab5cb4726764f4d4729a56031b --- /dev/null +++ b/0685-lgtm-don-t-treat-the-custom-note-as-a-list-of-tags.patch @@ -0,0 +1,40 @@ +From 6eeaef95566e6d85e714280c412e5df347838e34 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Thu, 2 Dec 2021 16:55:17 +0100 +Subject: [PATCH] lgtm: don't treat the custom note as a list of tags + +Just a cosmetic change. + +(cherry picked from commit c7d70210fa45c3210b8b1eda51bc0f6d68bd8392) + +Related: #2017033 +--- + .lgtm/cpp-queries/PotentiallyDangerousFunction.ql | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql +index 865330430d..39e8dddd13 100644 +--- a/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql ++++ b/.lgtm/cpp-queries/PotentiallyDangerousFunction.ql +@@ -1,15 +1,17 @@ + /** ++ * vi: sw=2 ts=2 et syntax=ql: ++ * ++ * Borrowed from ++ * https://github.com/Semmle/ql/blob/master/cpp/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.ql ++ * + * @name Use of potentially dangerous function + * @description Certain standard library functions are dangerous to call. ++ * @id cpp/potentially-dangerous-function + * @kind problem + * @problem.severity error + * @precision high +- * @id cpp/potentially-dangerous-function + * @tags reliability + * security +- * +- * Borrowed from +- * https://github.com/Semmle/ql/blob/master/cpp/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.ql + */ + import cpp + diff --git a/0686-lgtm-ignore-certain-cleanup-functions.patch b/0686-lgtm-ignore-certain-cleanup-functions.patch new file mode 100644 index 0000000000000000000000000000000000000000..0793564a676598caed78f7407874d71aaf2fa540 --- /dev/null +++ b/0686-lgtm-ignore-certain-cleanup-functions.patch @@ -0,0 +1,42 @@ +From 42123e9614ea73c7f64c684c90e4dbb049ef67ef Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Sun, 5 Dec 2021 10:25:28 +0100 +Subject: [PATCH] lgtm: ignore certain cleanup functions + +as they don't do any illegal stuff even when used with an uninitialized +variable. + +(cherry picked from commit af1868213657b38b8d4008608976eb81546cfb8e) + +Related: #2017033 +--- + .lgtm/cpp-queries/UninitializedVariableWithCleanup.ql | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql b/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql +index 6bf0ae01eb..8c24b6d8f1 100644 +--- a/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql ++++ b/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql +@@ -34,6 +34,13 @@ predicate allocatedType(Type t) { + allocatedType(t.getUnspecifiedType()) + } + ++/** Auxiliary predicate: List cleanup functions we want to explicitly ignore ++ * since they don't do anything illegal even when the variable is uninitialized ++ */ ++predicate cleanupFunctionDenyList(string fun) { ++ fun = "erase_char" ++} ++ + /** + * A declaration of a local variable using __attribute__((__cleanup__(x))) + * that leaves the variable uninitialized. +@@ -43,6 +50,8 @@ DeclStmt declWithNoInit(LocalVariable v) { + not exists(v.getInitializer()) and + /* The variable has __attribute__((__cleanup__(...))) set */ + v.getAnAttribute().hasName("cleanup") and ++ /* Check if the cleanup function is not on a deny list */ ++ not exists(Attribute a | a = v.getAnAttribute() and a.getName() = "cleanup" | cleanupFunctionDenyList(a.getAnArgument().getValueText())) and + /* The type of the variable is not stack-allocated. */ + exists(Type t | t = v.getType() | not allocatedType(t)) + } diff --git a/0687-lgtm-detect-more-possible-problematic-scenarios.patch b/0687-lgtm-detect-more-possible-problematic-scenarios.patch new file mode 100644 index 0000000000000000000000000000000000000000..24edd31a5b72d8890fd0d697a20d630eb5d93cfa --- /dev/null +++ b/0687-lgtm-detect-more-possible-problematic-scenarios.patch @@ -0,0 +1,96 @@ +From f9b19c9d4caaf870b30cce8a3d6be79eda099c4e Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Sun, 5 Dec 2021 16:11:35 +0100 +Subject: [PATCH] lgtm: detect more possible problematic scenarios + +1) don't ignore stack-allocated variables, since they may hide + heap-allocated stuff (compound types) +2) check if there's a return between the variable declaration and its + initialization; if so, treat the variable as uninitialized +3) introduction of 2) increased the query runtime exponentially, so + introduce some optimizations to bring it back to some reasonable + values + +(cherry picked from commit c8fec8bf9b086f9fc7638db0f1a613a00d7c63a3) + +Related: #2017033 +--- + .../UninitializedVariableWithCleanup.ql | 48 ++++++++++--------- + 1 file changed, 25 insertions(+), 23 deletions(-) + +diff --git a/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql b/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql +index 8c24b6d8f1..6b3b62f8bc 100644 +--- a/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql ++++ b/.lgtm/cpp-queries/UninitializedVariableWithCleanup.ql +@@ -16,24 +16,6 @@ + import cpp + import semmle.code.cpp.controlflow.StackVariableReachability + +-/** +- * Auxiliary predicate: Types that don't require initialization +- * before they are used, since they're stack-allocated. +- */ +-predicate allocatedType(Type t) { +- /* Arrays: "int foo[1]; foo[0] = 42;" is ok. */ +- t instanceof ArrayType +- or +- /* Structs: "struct foo bar; bar.baz = 42" is ok. */ +- t instanceof Class +- or +- /* Typedefs to other allocated types are fine. */ +- allocatedType(t.(TypedefType).getUnderlyingType()) +- or +- /* Type specifiers don't affect whether or not a type is allocated. */ +- allocatedType(t.getUnspecifiedType()) +-} +- + /** Auxiliary predicate: List cleanup functions we want to explicitly ignore + * since they don't do anything illegal even when the variable is uninitialized + */ +@@ -47,13 +29,11 @@ predicate cleanupFunctionDenyList(string fun) { + */ + DeclStmt declWithNoInit(LocalVariable v) { + result.getADeclaration() = v and +- not exists(v.getInitializer()) and ++ not v.hasInitializer() and + /* The variable has __attribute__((__cleanup__(...))) set */ + v.getAnAttribute().hasName("cleanup") and + /* Check if the cleanup function is not on a deny list */ +- not exists(Attribute a | a = v.getAnAttribute() and a.getName() = "cleanup" | cleanupFunctionDenyList(a.getAnArgument().getValueText())) and +- /* The type of the variable is not stack-allocated. */ +- exists(Type t | t = v.getType() | not allocatedType(t)) ++ not cleanupFunctionDenyList(v.getAnAttribute().getAnArgument().getValueText()) + } + + class UninitialisedLocalReachability extends StackVariableReachability { +@@ -78,7 +58,29 @@ class UninitialisedLocalReachability extends StackVariableReachability { + override predicate isBarrier(ControlFlowNode node, StackVariable v) { + // only report the _first_ possibly uninitialized use + useOfVar(v, node) or +- definitionBarrier(v, node) ++ ( ++ /* If there's an return statement somewhere between the variable declaration ++ * and a possible definition, don't accept is as a valid initialization. ++ * ++ * E.g.: ++ * _cleanup_free_ char *x; ++ * ... ++ * if (...) ++ * return; ++ * ... ++ * x = malloc(...); ++ * ++ * is not a valid initialization, since we might return from the function ++ * _before_ the actual iniitialization (emphasis on _might_, since we ++ * don't know if the return statement might ever evaluate to true). ++ */ ++ definitionBarrier(v, node) and ++ not exists(ReturnStmt rs | ++ /* The attribute check is "just" a complexity optimization */ ++ v.getFunction() = rs.getEnclosingFunction() and v.getAnAttribute().hasName("cleanup") | ++ rs.getLocation().isBefore(node.getLocation()) ++ ) ++ ) + } + } + diff --git a/0688-lgtm-enable-more-and-potentially-useful-queries.patch b/0688-lgtm-enable-more-and-potentially-useful-queries.patch new file mode 100644 index 0000000000000000000000000000000000000000..784850e3d7312d6976185aab46139e4592fce7f7 --- /dev/null +++ b/0688-lgtm-enable-more-and-potentially-useful-queries.patch @@ -0,0 +1,48 @@ +From 842c676a36abab0d92f1e68de2c8881fd00fdf4b Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 30 Nov 2021 23:40:28 +0100 +Subject: [PATCH] lgtm: enable more (and potentially useful) queries + +Not all available queries on LGTM are enabled by default, but some of +the excluded ones might come in handy, hence let's enable them +explicitly. + +(cherry picked from commit 38f36b9f3443b4d2085799c772e901a402b84af3) + +Related: #2017033 +--- + .lgtm.yml | 24 ++++++++++++++++++++++++ + 1 file changed, 24 insertions(+) + +diff --git a/.lgtm.yml b/.lgtm.yml +index 5948d8c2bc..fe93957b67 100644 +--- a/.lgtm.yml ++++ b/.lgtm.yml +@@ -1,3 +1,27 @@ ++--- ++# vi: ts=2 sw=2 et: ++ ++# Explicitly enable certain checks which are hidden by default ++queries: ++ - include: cpp/bad-strncpy-size ++ - include: cpp/declaration-hides-variable ++ - include: cpp/inconsistent-null-check ++ - include: cpp/mistyped-function-arguments ++ - include: cpp/nested-loops-with-same-variable ++ - include: cpp/sizeof-side-effect ++ - include: cpp/suspicious-pointer-scaling ++ - include: cpp/suspicious-pointer-scaling-void ++ - include: cpp/suspicious-sizeof ++ - include: cpp/unsafe-strcat ++ - include: cpp/unsafe-strncat ++ - include: cpp/unsigned-difference-expression-compared-zero ++ - include: cpp/unused-local-variable ++ - include: ++ tags: ++ - "security" ++ - "correctness" ++ severity: "error" ++ + extraction: + cpp: + prepare: diff --git a/0689-meson-avoid-bogus-meson-warning.patch b/0689-meson-avoid-bogus-meson-warning.patch new file mode 100644 index 0000000000000000000000000000000000000000..3453c1f4487dfee959fce14b8a6af7ecbbae3915 --- /dev/null +++ b/0689-meson-avoid-bogus-meson-warning.patch @@ -0,0 +1,36 @@ +From 4433c31a80c4477b0a0c503c74e8faebc44f4453 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 7 Nov 2019 11:32:26 +0100 +Subject: [PATCH] meson: avoid bogus meson warning + +With meson-0.52.0-1.module_f31+6771+f5d842eb.noarch I get: +src/test/meson.build:19: WARNING: Overriding previous value of environment variable 'PATH' with a new one + +When we're using *prepend*, the whole point is to modify an existing variable, +so meson shouldn't warn. But let's set avoid the warning and shorten things by +setting the final value immediately. + +(cherry picked from commit cbe804947482998cc767bfb0c169e6263a6ef097) +--- + src/test/meson.build | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/src/test/meson.build b/src/test/meson.build +index 40cf56d73d..6eaa62e53f 100644 +--- a/src/test/meson.build ++++ b/src/test/meson.build +@@ -10,12 +10,11 @@ test_hashmap_ordered_c = custom_target( + + test_include_dir = include_directories('.') + +-path = run_command('sh', ['-c', 'echo "$PATH"']).stdout() ++path = run_command('sh', ['-c', 'echo "$PATH"']).stdout().strip() + test_env = environment() + test_env.set('SYSTEMD_KBD_MODEL_MAP', kbd_model_map) + test_env.set('SYSTEMD_LANGUAGE_FALLBACK_MAP', language_fallback_map) +-test_env.set('PATH', path) +-test_env.prepend('PATH', meson.build_root()) ++test_env.set('PATH', '@0@:@1@'.format(meson.build_root(), path)) + + ############################################################ + diff --git a/0690-test-make-TEST-47-less-racy.patch b/0690-test-make-TEST-47-less-racy.patch new file mode 100644 index 0000000000000000000000000000000000000000..4aa0371a4754448c4ed7fe6973bb2edca5c0646f --- /dev/null +++ b/0690-test-make-TEST-47-less-racy.patch @@ -0,0 +1,33 @@ +From de7125dcfe6d6c8af05262ab786f9fe7cbf15113 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Wed, 15 Dec 2021 12:15:19 +0100 +Subject: [PATCH] test: make TEST-47 less racy + +Based on: + - 2e7090e94d0c8b31d418555ab2f6a9b75318f6a4 + - e00e2e0b50bbd120290572c8d1242703fb98b34e + - 197298ff9fc930de450330095cc5b67d165d0801 + +Related: #2017033 +--- + test/TEST-47-ISSUE-14566/testsuite.sh | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/test/TEST-47-ISSUE-14566/testsuite.sh b/test/TEST-47-ISSUE-14566/testsuite.sh +index d917cf52ff..b12b50e96c 100755 +--- a/test/TEST-47-ISSUE-14566/testsuite.sh ++++ b/test/TEST-47-ISSUE-14566/testsuite.sh +@@ -6,11 +6,13 @@ systemd-analyze log-level debug + systemd-analyze log-target console + + systemctl start issue_14566_test ++sleep 4 + systemctl status issue_14566_test + + leaked_pid=$(cat /leakedtestpid) + + systemctl stop issue_14566_test ++sleep 4 + + # Leaked PID will still be around if we're buggy. + # I personally prefer to see 42. diff --git a/0691-core-rename-unit_-start_limit-condition-assert-_test.patch b/0691-core-rename-unit_-start_limit-condition-assert-_test.patch new file mode 100644 index 0000000000000000000000000000000000000000..2a254491affe9c5b90a2fcd86267c2ace787dc39 --- /dev/null +++ b/0691-core-rename-unit_-start_limit-condition-assert-_test.patch @@ -0,0 +1,179 @@ +From 894d307d0d149adb46e630550566e5a3f6ff8d2e Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 18 Mar 2019 12:21:27 +0100 +Subject: [PATCH] core: rename unit_{start_limit|condition|assert}_test() to + unit_test_xyz() + +Just some renaming, no change in behaviour. + +Background: I'd like to add more functions unit_test_xyz() that test +various things, hence let's streamline the naming a bit. + +(cherry picked from commit 97a3f4ee052e1b8a0ff03accfa478e352891a84f) + +Related: #2036608 +--- + src/core/automount.c | 2 +- + src/core/mount.c | 2 +- + src/core/path.c | 2 +- + src/core/service.c | 2 +- + src/core/socket.c | 2 +- + src/core/swap.c | 2 +- + src/core/timer.c | 2 +- + src/core/unit.c | 11 +++++------ + src/core/unit.h | 2 +- + 9 files changed, 13 insertions(+), 14 deletions(-) + +diff --git a/src/core/automount.c b/src/core/automount.c +index 76e70f4dac..2bc160cb07 100644 +--- a/src/core/automount.c ++++ b/src/core/automount.c +@@ -808,7 +808,7 @@ static int automount_start(Unit *u) { + return -ENOENT; + } + +- r = unit_start_limit_test(u); ++ r = unit_test_start_limit(u); + if (r < 0) { + automount_enter_dead(a, AUTOMOUNT_FAILURE_START_LIMIT_HIT); + return r; +diff --git a/src/core/mount.c b/src/core/mount.c +index 7e80a0c974..aa586d88cb 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1065,7 +1065,7 @@ static int mount_start(Unit *u) { + + assert(IN_SET(m->state, MOUNT_DEAD, MOUNT_FAILED)); + +- r = unit_start_limit_test(u); ++ r = unit_test_start_limit(u); + if (r < 0) { + mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT); + return r; +diff --git a/src/core/path.c b/src/core/path.c +index ed40bc6c19..4bccc0396b 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -565,7 +565,7 @@ static int path_start(Unit *u) { + return -ENOENT; + } + +- r = unit_start_limit_test(u); ++ r = unit_test_start_limit(u); + if (r < 0) { + path_enter_dead(p, PATH_FAILURE_START_LIMIT_HIT); + return r; +diff --git a/src/core/service.c b/src/core/service.c +index 7969bbf071..1a1de43d0d 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -2388,7 +2388,7 @@ static int service_start(Unit *u) { + assert(IN_SET(s->state, SERVICE_DEAD, SERVICE_FAILED)); + + /* Make sure we don't enter a busy loop of some kind. */ +- r = unit_start_limit_test(u); ++ r = unit_test_start_limit(u); + if (r < 0) { + service_enter_dead(s, SERVICE_FAILURE_START_LIMIT_HIT, false); + return r; +diff --git a/src/core/socket.c b/src/core/socket.c +index 50c32ed8f4..09491c6677 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -2469,7 +2469,7 @@ static int socket_start(Unit *u) { + + assert(IN_SET(s->state, SOCKET_DEAD, SOCKET_FAILED)); + +- r = unit_start_limit_test(u); ++ r = unit_test_start_limit(u); + if (r < 0) { + socket_enter_dead(s, SOCKET_FAILURE_START_LIMIT_HIT); + return r; +diff --git a/src/core/swap.c b/src/core/swap.c +index a8f127f660..823699699e 100644 +--- a/src/core/swap.c ++++ b/src/core/swap.c +@@ -851,7 +851,7 @@ static int swap_start(Unit *u) { + if (UNIT(other)->job && UNIT(other)->job->state == JOB_RUNNING) + return -EAGAIN; + +- r = unit_start_limit_test(u); ++ r = unit_test_start_limit(u); + if (r < 0) { + swap_enter_dead(s, SWAP_FAILURE_START_LIMIT_HIT); + return r; +diff --git a/src/core/timer.c b/src/core/timer.c +index 1718ffc5a5..be16321296 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -599,7 +599,7 @@ static int timer_start(Unit *u) { + return -ENOENT; + } + +- r = unit_start_limit_test(u); ++ r = unit_test_start_limit(u); + if (r < 0) { + timer_enter_dead(t, TIMER_FAILURE_START_LIMIT_HIT); + return r; +diff --git a/src/core/unit.c b/src/core/unit.c +index 23afa24c77..9013186d8a 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1633,7 +1633,7 @@ static bool unit_condition_test_list(Unit *u, Condition *first, const char *(*to + return triggered != 0; + } + +-static bool unit_condition_test(Unit *u) { ++static bool unit_test_condition(Unit *u) { + assert(u); + + dual_timestamp_get(&u->condition_timestamp); +@@ -1642,7 +1642,7 @@ static bool unit_condition_test(Unit *u) { + return u->condition_result; + } + +-static bool unit_assert_test(Unit *u) { ++static bool unit_test_assert(Unit *u) { + assert(u); + + dual_timestamp_get(&u->assert_timestamp); +@@ -1657,8 +1657,7 @@ void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg + REENABLE_WARNING; + } + +- +-int unit_start_limit_test(Unit *u) { ++int unit_test_start_limit(Unit *u) { + assert(u); + + if (ratelimit_below(&u->start_limit)) { +@@ -1750,14 +1749,14 @@ int unit_start(Unit *u) { + * speed up activation in case there is some hold-off time, + * but we don't want to recheck the condition in that case. */ + if (state != UNIT_ACTIVATING && +- !unit_condition_test(u)) { ++ !unit_test_condition(u)) { + log_unit_debug(u, "Starting requested but condition failed. Not starting unit."); + return -EALREADY; + } + + /* If the asserts failed, fail the entire job */ + if (state != UNIT_ACTIVATING && +- !unit_assert_test(u)) { ++ !unit_test_assert(u)) { + log_unit_notice(u, "Starting requested but asserts failed."); + return -EPROTO; + } +diff --git a/src/core/unit.h b/src/core/unit.h +index ec45b5fb48..a8bc350b66 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -786,7 +786,7 @@ static inline bool unit_supported(Unit *u) { + void unit_warn_if_dir_nonempty(Unit *u, const char* where); + int unit_fail_if_noncanonical(Unit *u, const char* where); + +-int unit_start_limit_test(Unit *u); ++int unit_test_start_limit(Unit *u); + + void unit_unref_uid(Unit *u, bool destroy_now); + int unit_ref_uid(Unit *u, uid_t uid, bool clean_ipc); diff --git a/0692-core-Check-unit-start-rate-limiting-earlier.patch b/0692-core-Check-unit-start-rate-limiting-earlier.patch new file mode 100644 index 0000000000000000000000000000000000000000..cbe1aacf3374c85c51ea1987b798fec1ca4d8f3e --- /dev/null +++ b/0692-core-Check-unit-start-rate-limiting-earlier.patch @@ -0,0 +1,400 @@ +From 471eda89a25a3ceac91a2d05e39a54aae78038ed Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Tue, 24 Aug 2021 16:46:47 +0100 +Subject: [PATCH] core: Check unit start rate limiting earlier + +Fixes #17433. Currently, if any of the validations we do before we +check start rate limiting fail, we can still enter a busy loop as +no rate limiting gets applied. A common occurence of this scenario +is path units triggering a service that fails a condition check. + +To fix the issue, we simply move up start rate limiting checks to +be the first thing we do when starting a unit. To achieve this, +we add a new method to the unit vtable and implement it for the +relevant unit types so that we can do the start rate limit checks +earlier on. + +(cherry picked from commit 9727f2427ff6b2e1f4ab927cc57ad8e888f04e95) + +Related: #2036608 + +[msekleta: I've deleted part of the original commit that adds test for +issue #17433. This was necessary because upstream commit assumes newer +organization of the test code which we don't have in RHEL-8 tree. As +a consequence we must add explicit test for this in the internal +test-suite.] +--- + src/core/automount.c | 23 +++++++++++++++++------ + src/core/mount.c | 23 +++++++++++++++++------ + src/core/path.c | 23 +++++++++++++++++------ + src/core/service.c | 25 ++++++++++++++++++------- + src/core/socket.c | 23 +++++++++++++++++------ + src/core/swap.c | 23 +++++++++++++++++------ + src/core/timer.c | 22 ++++++++++++++++------ + src/core/unit.c | 14 ++++++++++---- + src/core/unit.h | 4 ++++ + 9 files changed, 133 insertions(+), 47 deletions(-) + +diff --git a/src/core/automount.c b/src/core/automount.c +index 2bc160cb07..5e16adabb5 100644 +--- a/src/core/automount.c ++++ b/src/core/automount.c +@@ -808,12 +808,6 @@ static int automount_start(Unit *u) { + return -ENOENT; + } + +- r = unit_test_start_limit(u); +- if (r < 0) { +- automount_enter_dead(a, AUTOMOUNT_FAILURE_START_LIMIT_HIT); +- return r; +- } +- + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; +@@ -1077,6 +1071,21 @@ static bool automount_supported(void) { + return supported; + } + ++static int automount_test_start_limit(Unit *u) { ++ Automount *a = AUTOMOUNT(u); ++ int r; ++ ++ assert(a); ++ ++ r = unit_test_start_limit(u); ++ if (r < 0) { ++ automount_enter_dead(a, AUTOMOUNT_FAILURE_START_LIMIT_HIT); ++ return r; ++ } ++ ++ return 0; ++} ++ + static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = { + [AUTOMOUNT_SUCCESS] = "success", + [AUTOMOUNT_FAILURE_RESOURCES] = "resources", +@@ -1135,4 +1144,6 @@ const UnitVTable automount_vtable = { + [JOB_FAILED] = "Failed to unset automount %s.", + }, + }, ++ ++ .test_start_limit = automount_test_start_limit, + }; +diff --git a/src/core/mount.c b/src/core/mount.c +index aa586d88cb..22848847e5 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1065,12 +1065,6 @@ static int mount_start(Unit *u) { + + assert(IN_SET(m->state, MOUNT_DEAD, MOUNT_FAILED)); + +- r = unit_test_start_limit(u); +- if (r < 0) { +- mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT); +- return r; +- } +- + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; +@@ -1957,6 +1951,21 @@ static int mount_control_pid(Unit *u) { + return m->control_pid; + } + ++static int mount_test_start_limit(Unit *u) { ++ Mount *m = MOUNT(u); ++ int r; ++ ++ assert(m); ++ ++ r = unit_test_start_limit(u); ++ if (r < 0) { ++ mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT); ++ return r; ++ } ++ ++ return 0; ++} ++ + static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = { + [MOUNT_EXEC_MOUNT] = "ExecMount", + [MOUNT_EXEC_UNMOUNT] = "ExecUnmount", +@@ -2048,4 +2057,6 @@ const UnitVTable mount_vtable = { + [JOB_TIMEOUT] = "Timed out unmounting %s.", + }, + }, ++ ++ .test_start_limit = mount_test_start_limit, + }; +diff --git a/src/core/path.c b/src/core/path.c +index 4bccc0396b..1e69a1f05f 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -565,12 +565,6 @@ static int path_start(Unit *u) { + return -ENOENT; + } + +- r = unit_test_start_limit(u); +- if (r < 0) { +- path_enter_dead(p, PATH_FAILURE_START_LIMIT_HIT); +- return r; +- } +- + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; +@@ -730,6 +724,21 @@ static void path_reset_failed(Unit *u) { + p->result = PATH_SUCCESS; + } + ++static int path_test_start_limit(Unit *u) { ++ Path *p = PATH(u); ++ int r; ++ ++ assert(p); ++ ++ r = unit_test_start_limit(u); ++ if (r < 0) { ++ path_enter_dead(p, PATH_FAILURE_START_LIMIT_HIT); ++ return r; ++ } ++ ++ return 0; ++} ++ + static const char* const path_type_table[_PATH_TYPE_MAX] = { + [PATH_EXISTS] = "PathExists", + [PATH_EXISTS_GLOB] = "PathExistsGlob", +@@ -782,4 +791,6 @@ const UnitVTable path_vtable = { + + .bus_vtable = bus_path_vtable, + .bus_set_property = bus_path_set_property, ++ ++ .test_start_limit = path_test_start_limit, + }; +diff --git a/src/core/service.c b/src/core/service.c +index 1a1de43d0d..c5f408d817 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -2387,13 +2387,6 @@ static int service_start(Unit *u) { + + assert(IN_SET(s->state, SERVICE_DEAD, SERVICE_FAILED)); + +- /* Make sure we don't enter a busy loop of some kind. */ +- r = unit_test_start_limit(u); +- if (r < 0) { +- service_enter_dead(s, SERVICE_FAILURE_START_LIMIT_HIT, false); +- return r; +- } +- + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; +@@ -4081,6 +4074,22 @@ static bool service_needs_console(Unit *u) { + SERVICE_FINAL_SIGKILL); + } + ++static int service_test_start_limit(Unit *u) { ++ Service *s = SERVICE(u); ++ int r; ++ ++ assert(s); ++ ++ /* Make sure we don't enter a busy loop of some kind. */ ++ r = unit_test_start_limit(u); ++ if (r < 0) { ++ service_enter_dead(s, SERVICE_FAILURE_START_LIMIT_HIT, false); ++ return r; ++ } ++ ++ return 0; ++} ++ + static const char* const service_restart_table[_SERVICE_RESTART_MAX] = { + [SERVICE_RESTART_NO] = "no", + [SERVICE_RESTART_ON_SUCCESS] = "on-success", +@@ -4222,4 +4231,6 @@ const UnitVTable service_vtable = { + [JOB_FAILED] = "Stopped (with error) %s.", + }, + }, ++ ++ .test_start_limit = service_test_start_limit, + }; +diff --git a/src/core/socket.c b/src/core/socket.c +index 09491c6677..36d2e4f823 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -2469,12 +2469,6 @@ static int socket_start(Unit *u) { + + assert(IN_SET(s->state, SOCKET_DEAD, SOCKET_FAILED)); + +- r = unit_test_start_limit(u); +- if (r < 0) { +- socket_enter_dead(s, SOCKET_FAILURE_START_LIMIT_HIT); +- return r; +- } +- + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; +@@ -3267,6 +3261,21 @@ static int socket_control_pid(Unit *u) { + return s->control_pid; + } + ++static int socket_test_start_limit(Unit *u) { ++ Socket *s = SOCKET(u); ++ int r; ++ ++ assert(s); ++ ++ r = unit_test_start_limit(u); ++ if (r < 0) { ++ socket_enter_dead(s, SOCKET_FAILURE_START_LIMIT_HIT); ++ return r; ++ } ++ ++ return 0; ++} ++ + static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = { + [SOCKET_EXEC_START_PRE] = "ExecStartPre", + [SOCKET_EXEC_START_CHOWN] = "ExecStartChown", +@@ -3359,4 +3368,6 @@ const UnitVTable socket_vtable = { + [JOB_TIMEOUT] = "Timed out stopping %s.", + }, + }, ++ ++ .test_start_limit = socket_test_start_limit, + }; +diff --git a/src/core/swap.c b/src/core/swap.c +index 823699699e..90fcd69300 100644 +--- a/src/core/swap.c ++++ b/src/core/swap.c +@@ -851,12 +851,6 @@ static int swap_start(Unit *u) { + if (UNIT(other)->job && UNIT(other)->job->state == JOB_RUNNING) + return -EAGAIN; + +- r = unit_test_start_limit(u); +- if (r < 0) { +- swap_enter_dead(s, SWAP_FAILURE_START_LIMIT_HIT); +- return r; +- } +- + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; +@@ -1458,6 +1452,21 @@ static int swap_control_pid(Unit *u) { + return s->control_pid; + } + ++static int swap_test_start_limit(Unit *u) { ++ Swap *s = SWAP(u); ++ int r; ++ ++ assert(s); ++ ++ r = unit_test_start_limit(u); ++ if (r < 0) { ++ swap_enter_dead(s, SWAP_FAILURE_START_LIMIT_HIT); ++ return r; ++ } ++ ++ return 0; ++} ++ + static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = { + [SWAP_EXEC_ACTIVATE] = "ExecActivate", + [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate", +@@ -1547,4 +1556,6 @@ const UnitVTable swap_vtable = { + [JOB_TIMEOUT] = "Timed out deactivating swap %s.", + }, + }, ++ ++ .test_start_limit = swap_test_start_limit, + }; +diff --git a/src/core/timer.c b/src/core/timer.c +index be16321296..fb9ae17990 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -599,12 +599,6 @@ static int timer_start(Unit *u) { + return -ENOENT; + } + +- r = unit_test_start_limit(u); +- if (r < 0) { +- timer_enter_dead(t, TIMER_FAILURE_START_LIMIT_HIT); +- return r; +- } +- + r = unit_acquire_invocation_id(u); + if (r < 0) + return r; +@@ -829,6 +823,21 @@ static void timer_timezone_change(Unit *u) { + timer_enter_waiting(t, false); + } + ++static int timer_test_start_limit(Unit *u) { ++ Timer *t = TIMER(u); ++ int r; ++ ++ assert(t); ++ ++ r = unit_test_start_limit(u); ++ if (r < 0) { ++ timer_enter_dead(t, TIMER_FAILURE_START_LIMIT_HIT); ++ return r; ++ } ++ ++ return 0; ++} ++ + static const char* const timer_base_table[_TIMER_BASE_MAX] = { + [TIMER_ACTIVE] = "OnActiveSec", + [TIMER_BOOT] = "OnBootSec", +@@ -884,4 +893,5 @@ const UnitVTable timer_vtable = { + .bus_set_property = bus_timer_set_property, + + .can_transient = true, ++ .test_start_limit = timer_test_start_limit, + }; +diff --git a/src/core/unit.c b/src/core/unit.c +index 9013186d8a..f0df7452fa 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1728,10 +1728,16 @@ int unit_start(Unit *u) { + + assert(u); + +- /* If this is already started, then this will succeed. Note +- * that this will even succeed if this unit is not startable +- * by the user. This is relied on to detect when we need to +- * wait for units and when waiting is finished. */ ++ /* Check start rate limiting early so that failure conditions don't cause us to enter a busy loop. */ ++ if (UNIT_VTABLE(u)->test_start_limit) { ++ int r = UNIT_VTABLE(u)->test_start_limit(u); ++ if (r < 0) ++ return r; ++ } ++ ++ /* If this is already started, then this will succeed. Note that this will even succeed if this unit ++ * is not startable by the user. This is relied on to detect when we need to wait for units and when ++ * waiting is finished. */ + state = unit_active_state(u); + if (UNIT_IS_ACTIVE_OR_RELOADING(state)) + return -EALREADY; +diff --git a/src/core/unit.h b/src/core/unit.h +index a8bc350b66..9e6f1bcf81 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -567,6 +567,10 @@ typedef struct UnitVTable { + /* The bus vtable */ + const sd_bus_vtable *bus_vtable; + ++ /* If this function is set, it's invoked first as part of starting a unit to allow start rate ++ * limiting checks to occur before we do anything else. */ ++ int (*test_start_limit)(Unit *u); ++ + /* The strings to print in status messages */ + UnitStatusMessageFormats status_message_formats; + diff --git a/0693-sd-event-introduce-callback-invoked-when-event-sourc.patch b/0693-sd-event-introduce-callback-invoked-when-event-sourc.patch new file mode 100644 index 0000000000000000000000000000000000000000..42d59d7b9e40fadb23bba107bebb7fde44228c35 --- /dev/null +++ b/0693-sd-event-introduce-callback-invoked-when-event-sourc.patch @@ -0,0 +1,226 @@ +From 51210a849ea7f163a1760de989756206c01dd758 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 4 Oct 2021 19:44:06 +0200 +Subject: [PATCH] sd-event: introduce callback invoked when event source + ratelimit expires + +(cherry picked from commit fd69f2247520b0be3190ded96d646a415edc97b7) + +Related: #2036608 +--- + src/libsystemd/libsystemd.sym | 5 +++ + src/libsystemd/sd-event/sd-event.c | 61 +++++++++++++++++++++++----- + src/libsystemd/sd-event/test-event.c | 12 ++++++ + src/systemd/sd-event.h | 1 + + 4 files changed, 68 insertions(+), 11 deletions(-) + +diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym +index 149d2e7b82..f4a1426248 100644 +--- a/src/libsystemd/libsystemd.sym ++++ b/src/libsystemd/libsystemd.sym +@@ -579,3 +579,8 @@ global: + sd_event_source_get_ratelimit; + sd_event_source_is_ratelimited; + } LIBSYSTEMD_239; ++ ++LIBSYSTEMD_250 { ++global: ++ 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 47cf93b3f4..0adfdd9e1a 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -125,6 +125,7 @@ struct sd_event_source { + uint64_t prepare_iteration; + + sd_event_destroy_t destroy_callback; ++ sd_event_handler_t ratelimit_expire_callback; + + LIST_FIELDS(sd_event_source, sources); + +@@ -2734,7 +2735,7 @@ fail: + return r; + } + +-static int event_source_leave_ratelimit(sd_event_source *s) { ++static int event_source_leave_ratelimit(sd_event_source *s, bool run_callback) { + int r; + + assert(s); +@@ -2766,6 +2767,23 @@ static int event_source_leave_ratelimit(sd_event_source *s) { + ratelimit_reset(&s->rate_limit); + + log_debug("Event source %p (%s) left rate limit state.", s, strna(s->description)); ++ ++ if (run_callback && s->ratelimit_expire_callback) { ++ s->dispatching = true; ++ r = s->ratelimit_expire_callback(s, s->userdata); ++ s->dispatching = false; ++ ++ if (r < 0) { ++ log_debug_errno(r, "Ratelimit expiry callback of event source %s (type %s) returned error, disabling: %m", ++ strna(s->description), ++ event_source_type_to_string(s->type)); ++ ++ sd_event_source_set_enabled(s, SD_EVENT_OFF); ++ } ++ ++ return 1; ++ } ++ + return 0; + + fail: +@@ -2966,6 +2984,7 @@ static int process_timer( + struct clock_data *d) { + + sd_event_source *s; ++ bool callback_invoked = false; + int r; + + assert(e); +@@ -2981,9 +3000,11 @@ static int process_timer( + * again. */ + assert(s->ratelimited); + +- r = event_source_leave_ratelimit(s); ++ r = event_source_leave_ratelimit(s, /* run_callback */ true); + if (r < 0) + return r; ++ else if (r == 1) ++ callback_invoked = true; + + continue; + } +@@ -2998,7 +3019,7 @@ static int process_timer( + event_source_time_prioq_reshuffle(s); + } + +- return 0; ++ return callback_invoked; + } + + static int process_child(sd_event *e) { +@@ -3698,15 +3719,15 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) { + if (r < 0) + goto finish; + +- r = process_timer(e, e->timestamp.realtime, &e->realtime); ++ r = process_inotify(e); + if (r < 0) + goto finish; + +- r = process_timer(e, e->timestamp.boottime, &e->boottime); ++ r = process_timer(e, e->timestamp.realtime, &e->realtime); + if (r < 0) + goto finish; + +- r = process_timer(e, e->timestamp.monotonic, &e->monotonic); ++ r = process_timer(e, e->timestamp.boottime, &e->boottime); + if (r < 0) + goto finish; + +@@ -3718,16 +3739,27 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) { + if (r < 0) + goto finish; + ++ r = process_timer(e, e->timestamp.monotonic, &e->monotonic); ++ if (r < 0) ++ goto finish; ++ else if (r == 1) { ++ /* Ratelimit expiry callback was called. Let's postpone processing pending sources and ++ * put loop in the initial state in order to evaluate (in the next iteration) also sources ++ * there were potentially re-enabled by the callback. ++ * ++ * Wondering why we treat only this invocation of process_timer() differently? Once event ++ * source is ratelimited we essentially transform it into CLOCK_MONOTONIC timer hence ++ * ratelimit expiry callback is never called for any other timer type. */ ++ r = 0; ++ goto finish; ++ } ++ + if (e->need_process_child) { + r = process_child(e); + if (r < 0) + goto finish; + } + +- r = process_inotify(e); +- if (r < 0) +- goto finish; +- + if (event_next_pending(e)) { + e->state = SD_EVENT_PENDING; + +@@ -4054,7 +4086,7 @@ _public_ int sd_event_source_set_ratelimit(sd_event_source *s, uint64_t interval + + /* When ratelimiting is configured we'll always reset the rate limit state first and start fresh, + * non-ratelimited. */ +- r = event_source_leave_ratelimit(s); ++ r = event_source_leave_ratelimit(s, /* run_callback */ false); + if (r < 0) + return r; + +@@ -4062,6 +4094,13 @@ _public_ int sd_event_source_set_ratelimit(sd_event_source *s, uint64_t interval + return 0; + } + ++_public_ int sd_event_source_set_ratelimit_expire_callback(sd_event_source *s, sd_event_handler_t callback) { ++ assert_return(s, -EINVAL); ++ ++ s->ratelimit_expire_callback = callback; ++ return 0; ++} ++ + _public_ int sd_event_source_get_ratelimit(sd_event_source *s, uint64_t *ret_interval, unsigned *ret_burst) { + assert_return(s, -EINVAL); + +diff --git a/src/libsystemd/sd-event/test-event.c b/src/libsystemd/sd-event/test-event.c +index e3ee4cd5c3..9135b22839 100644 +--- a/src/libsystemd/sd-event/test-event.c ++++ b/src/libsystemd/sd-event/test-event.c +@@ -506,6 +506,11 @@ static int ratelimit_time_handler(sd_event_source *s, uint64_t usec, void *userd + return 0; + } + ++static int expired = -1; ++static int ratelimit_expired(sd_event_source *s, void *userdata) { ++ return ++expired; ++} ++ + static void test_ratelimit(void) { + _cleanup_close_pair_ int p[2] = {-1, -1}; + _cleanup_(sd_event_unrefp) sd_event *e = NULL; +@@ -568,12 +573,19 @@ static void test_ratelimit(void) { + + assert_se(sd_event_source_set_ratelimit(s, 1 * USEC_PER_SEC, 10) >= 0); + ++ /* Set callback that will be invoked when we leave rate limited state. */ ++ assert_se(sd_event_source_set_ratelimit_expire_callback(s, ratelimit_expired) >= 0); ++ + do { + assert_se(sd_event_run(e, UINT64_MAX) >= 0); + } while (!sd_event_source_is_ratelimited(s)); + + log_info("ratelimit_time_handler: called 10 more times, event source got ratelimited"); + assert_se(count == 20); ++ ++ /* Dispatch the event loop once more and check that ratelimit expiration callback got called */ ++ assert_se(sd_event_run(e, UINT64_MAX) >= 0); ++ assert_se(expired == 0); + } + + int main(int argc, char *argv[]) { +diff --git a/src/systemd/sd-event.h b/src/systemd/sd-event.h +index a17a9b3488..c2e9c9614d 100644 +--- a/src/systemd/sd-event.h ++++ b/src/systemd/sd-event.h +@@ -147,6 +147,7 @@ int sd_event_source_get_destroy_callback(sd_event_source *s, sd_event_destroy_t + int sd_event_source_set_ratelimit(sd_event_source *s, uint64_t interval_usec, unsigned burst); + int sd_event_source_get_ratelimit(sd_event_source *s, uint64_t *ret_interval_usec, unsigned *ret_burst); + int sd_event_source_is_ratelimited(sd_event_source *s); ++int sd_event_source_set_ratelimit_expire_callback(sd_event_source *s, sd_event_handler_t callback); + + /* Define helpers so that __attribute__((cleanup(sd_event_unrefp))) and similar may be used. */ + _SD_DEFINE_POINTER_CLEANUP_FUNC(sd_event, sd_event_unref); diff --git a/0694-core-rename-generalize-UNIT-u-test_start_limit-hook.patch b/0694-core-rename-generalize-UNIT-u-test_start_limit-hook.patch new file mode 100644 index 0000000000000000000000000000000000000000..4353eae5e77dbbee093949312a68e63b1c974d58 --- /dev/null +++ b/0694-core-rename-generalize-UNIT-u-test_start_limit-hook.patch @@ -0,0 +1,263 @@ +From 3674514b7220a136dcfd464c205d41609f0c99a7 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 4 Oct 2021 17:51:52 +0200 +Subject: [PATCH] core: rename/generalize UNIT(u)->test_start_limit() hook + +Up until now the main reason why we didn't proceed with starting the +unit was exceed start limit burst. However, for unit types like mounts +the other reason could be effective ratelimit on /proc/self/mountinfo +event source. That means our mount unit state may not reflect current +kernel state. Hence, we need to attempt to re-run the start job again +after ratelimit on event source expires. + +As we will be introducing another reason than start limit let's rename +the virtual function that implements the check. + +(cherry picked from commit 705578c3b9d794097233aa66010cf67b2a444716) + +Related: #2036608 +--- + src/core/automount.c | 6 +++--- + src/core/mount.c | 6 +++--- + src/core/path.c | 6 +++--- + src/core/service.c | 6 +++--- + src/core/socket.c | 6 +++--- + src/core/swap.c | 6 +++--- + src/core/timer.c | 6 +++--- + src/core/unit.c | 6 +++--- + src/core/unit.h | 2 +- + 9 files changed, 25 insertions(+), 25 deletions(-) + +diff --git a/src/core/automount.c b/src/core/automount.c +index 5e16adabb5..f212620c8f 100644 +--- a/src/core/automount.c ++++ b/src/core/automount.c +@@ -1071,7 +1071,7 @@ static bool automount_supported(void) { + return supported; + } + +-static int automount_test_start_limit(Unit *u) { ++static int automount_can_start(Unit *u) { + Automount *a = AUTOMOUNT(u); + int r; + +@@ -1083,7 +1083,7 @@ static int automount_test_start_limit(Unit *u) { + return r; + } + +- return 0; ++ return 1; + } + + static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = { +@@ -1145,5 +1145,5 @@ const UnitVTable automount_vtable = { + }, + }, + +- .test_start_limit = automount_test_start_limit, ++ .can_start = automount_can_start, + }; +diff --git a/src/core/mount.c b/src/core/mount.c +index 22848847e5..032a2ca156 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1951,7 +1951,7 @@ static int mount_control_pid(Unit *u) { + return m->control_pid; + } + +-static int mount_test_start_limit(Unit *u) { ++static int mount_can_start(Unit *u) { + Mount *m = MOUNT(u); + int r; + +@@ -1963,7 +1963,7 @@ static int mount_test_start_limit(Unit *u) { + return r; + } + +- return 0; ++ return 1; + } + + static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = { +@@ -2058,5 +2058,5 @@ const UnitVTable mount_vtable = { + }, + }, + +- .test_start_limit = mount_test_start_limit, ++ .can_start = mount_can_start, + }; +diff --git a/src/core/path.c b/src/core/path.c +index 1e69a1f05f..58f490589d 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -724,7 +724,7 @@ static void path_reset_failed(Unit *u) { + p->result = PATH_SUCCESS; + } + +-static int path_test_start_limit(Unit *u) { ++static int path_can_start(Unit *u) { + Path *p = PATH(u); + int r; + +@@ -736,7 +736,7 @@ static int path_test_start_limit(Unit *u) { + return r; + } + +- return 0; ++ return 1; + } + + static const char* const path_type_table[_PATH_TYPE_MAX] = { +@@ -792,5 +792,5 @@ const UnitVTable path_vtable = { + .bus_vtable = bus_path_vtable, + .bus_set_property = bus_path_set_property, + +- .test_start_limit = path_test_start_limit, ++ .can_start = path_can_start, + }; +diff --git a/src/core/service.c b/src/core/service.c +index c5f408d817..e8ae1a5772 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -4074,7 +4074,7 @@ static bool service_needs_console(Unit *u) { + SERVICE_FINAL_SIGKILL); + } + +-static int service_test_start_limit(Unit *u) { ++static int service_can_start(Unit *u) { + Service *s = SERVICE(u); + int r; + +@@ -4087,7 +4087,7 @@ static int service_test_start_limit(Unit *u) { + return r; + } + +- return 0; ++ return 1; + } + + static const char* const service_restart_table[_SERVICE_RESTART_MAX] = { +@@ -4232,5 +4232,5 @@ const UnitVTable service_vtable = { + }, + }, + +- .test_start_limit = service_test_start_limit, ++ .can_start = service_can_start, + }; +diff --git a/src/core/socket.c b/src/core/socket.c +index 36d2e4f823..3589300e68 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -3261,7 +3261,7 @@ static int socket_control_pid(Unit *u) { + return s->control_pid; + } + +-static int socket_test_start_limit(Unit *u) { ++static int socket_can_start(Unit *u) { + Socket *s = SOCKET(u); + int r; + +@@ -3273,7 +3273,7 @@ static int socket_test_start_limit(Unit *u) { + return r; + } + +- return 0; ++ return 1; + } + + static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = { +@@ -3369,5 +3369,5 @@ const UnitVTable socket_vtable = { + }, + }, + +- .test_start_limit = socket_test_start_limit, ++ .can_start = socket_can_start, + }; +diff --git a/src/core/swap.c b/src/core/swap.c +index 90fcd69300..498c5a6d69 100644 +--- a/src/core/swap.c ++++ b/src/core/swap.c +@@ -1452,7 +1452,7 @@ static int swap_control_pid(Unit *u) { + return s->control_pid; + } + +-static int swap_test_start_limit(Unit *u) { ++static int swap_can_start(Unit *u) { + Swap *s = SWAP(u); + int r; + +@@ -1464,7 +1464,7 @@ static int swap_test_start_limit(Unit *u) { + return r; + } + +- return 0; ++ return 1; + } + + static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = { +@@ -1557,5 +1557,5 @@ const UnitVTable swap_vtable = { + }, + }, + +- .test_start_limit = swap_test_start_limit, ++ .can_start = swap_can_start, + }; +diff --git a/src/core/timer.c b/src/core/timer.c +index fb9ae17990..684180bf99 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -823,7 +823,7 @@ static void timer_timezone_change(Unit *u) { + timer_enter_waiting(t, false); + } + +-static int timer_test_start_limit(Unit *u) { ++static int timer_can_start(Unit *u) { + Timer *t = TIMER(u); + int r; + +@@ -835,7 +835,7 @@ static int timer_test_start_limit(Unit *u) { + return r; + } + +- return 0; ++ return 1; + } + + static const char* const timer_base_table[_TIMER_BASE_MAX] = { +@@ -893,5 +893,5 @@ const UnitVTable timer_vtable = { + .bus_set_property = bus_timer_set_property, + + .can_transient = true, +- .test_start_limit = timer_test_start_limit, ++ .can_start = timer_can_start, + }; +diff --git a/src/core/unit.c b/src/core/unit.c +index f0df7452fa..4de218feac 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1728,9 +1728,9 @@ int unit_start(Unit *u) { + + assert(u); + +- /* Check start rate limiting early so that failure conditions don't cause us to enter a busy loop. */ +- if (UNIT_VTABLE(u)->test_start_limit) { +- int r = UNIT_VTABLE(u)->test_start_limit(u); ++ /* Check our ability to start early so that failure conditions don't cause us to enter a busy loop. */ ++ if (UNIT_VTABLE(u)->can_start) { ++ int r = UNIT_VTABLE(u)->can_start(u); + if (r < 0) + return r; + } +diff --git a/src/core/unit.h b/src/core/unit.h +index 9e6f1bcf81..0cd259411f 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -569,7 +569,7 @@ typedef struct UnitVTable { + + /* If this function is set, it's invoked first as part of starting a unit to allow start rate + * limiting checks to occur before we do anything else. */ +- int (*test_start_limit)(Unit *u); ++ int (*can_start)(Unit *u); + + /* The strings to print in status messages */ + UnitStatusMessageFormats status_message_formats; diff --git a/0695-mount-make-mount-units-start-jobs-not-runnable-if-p-.patch b/0695-mount-make-mount-units-start-jobs-not-runnable-if-p-.patch new file mode 100644 index 0000000000000000000000000000000000000000..cb7a006135ccd13ebb1378a3e75584d344d559e0 --- /dev/null +++ b/0695-mount-make-mount-units-start-jobs-not-runnable-if-p-.patch @@ -0,0 +1,27 @@ +From cb519c7d769851ee5e24c797fc04eaa13383c674 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 4 Oct 2021 19:41:34 +0200 +Subject: [PATCH] mount: make mount units start jobs not runnable if + /p/s/mountinfo ratelimit is in effect + +(cherry picked from commit a7c93dfe91e88a5a561341c523a45c7f8d71a588) + +Related: #2036608 +--- + src/core/mount.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/core/mount.c b/src/core/mount.c +index 032a2ca156..ab09e6fbb0 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1957,6 +1957,9 @@ static int mount_can_start(Unit *u) { + + assert(m); + ++ if (sd_event_source_is_ratelimited(u->manager->mount_event_source)) ++ return -EAGAIN; ++ + r = unit_test_start_limit(u); + if (r < 0) { + mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT); diff --git a/0696-mount-retrigger-run-queue-after-ratelimit-expired-to.patch b/0696-mount-retrigger-run-queue-after-ratelimit-expired-to.patch new file mode 100644 index 0000000000000000000000000000000000000000..c4909f6f7432e3df663df1337ec2ecc4c36ba073 --- /dev/null +++ b/0696-mount-retrigger-run-queue-after-ratelimit-expired-to.patch @@ -0,0 +1,54 @@ +From b0c226e9fd3e6bfa5388832cc2745d9ec935f3ec Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 4 Oct 2021 20:31:49 +0200 +Subject: [PATCH] mount: retrigger run queue after ratelimit expired to run + delayed mount start jobs + +Fixes #20329 + +(cherry picked from commit edc027b4f1cfaa49e8ecdde763eb8c623402d464) + +Related: #2036608 +--- + src/core/mount.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/src/core/mount.c b/src/core/mount.c +index ab09e6fbb0..bdba9e6884 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1710,6 +1710,21 @@ static bool mount_is_mounted(Mount *m) { + return UNIT(m)->perpetual || m->is_mounted; + } + ++static int mount_on_ratelimit_expire(sd_event_source *s, void *userdata) { ++ Manager *m = userdata; ++ int r; ++ ++ assert(m); ++ ++ /* By entering ratelimited state we made all mount start jobs not runnable, now rate limit is over so let's ++ * make sure we dispatch them in the next iteration. */ ++ r = sd_event_source_set_enabled(m->run_queue_event_source, SD_EVENT_ONESHOT); ++ if (r < 0) ++ log_debug_errno(r, "Failed to enable run queue event source, ignoring: %m"); ++ ++ return 0; ++} ++ + static void mount_enumerate(Manager *m) { + int r; + +@@ -1763,6 +1778,12 @@ static void mount_enumerate(Manager *m) { + goto fail; + } + ++ r = sd_event_source_set_ratelimit_expire_callback(m->mount_event_source, mount_on_ratelimit_expire); ++ if (r < 0) { ++ log_error_errno(r, "Failed to enable rate limit for mount events: %m"); ++ goto fail; ++ } ++ + (void) sd_event_source_set_description(m->mount_event_source, "mount-monitor-dispatch"); + } + diff --git a/0697-pid1-add-a-manager_trigger_run_queue-helper.patch b/0697-pid1-add-a-manager_trigger_run_queue-helper.patch new file mode 100644 index 0000000000000000000000000000000000000000..96b3351551d0c71801cb03dbb65cc494c98b3503 --- /dev/null +++ b/0697-pid1-add-a-manager_trigger_run_queue-helper.patch @@ -0,0 +1,98 @@ +From 5a218b6820be7ffaf21cd42cd4c96b47d18442ee Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 12 Nov 2021 09:43:07 +0100 +Subject: [PATCH] pid1: add a manager_trigger_run_queue() helper + +We have two different places where we re-trigger the run queue now. +let's unify it under a common function, that is part of the Manager +code. + +Follow-up for #20953 + +(cherry picked from commit b0c4b2824693fe6a27ea9439ec7a6328a0e23704) + +Related: #2036608 +--- + src/core/job.c | 5 ++--- + src/core/manager.c | 12 ++++++++++++ + src/core/manager.h | 2 ++ + src/core/mount.c | 9 +++------ + 4 files changed, 19 insertions(+), 9 deletions(-) + +diff --git a/src/core/job.c b/src/core/job.c +index 43ab55ed18..55f36b928f 100644 +--- a/src/core/job.c ++++ b/src/core/job.c +@@ -1139,11 +1139,10 @@ void job_add_to_run_queue(Job *j) { + if (j->in_run_queue) + return; + +- if (!j->manager->run_queue) +- sd_event_source_set_enabled(j->manager->run_queue_event_source, SD_EVENT_ONESHOT); +- + LIST_PREPEND(run_queue, j->manager->run_queue, j); + j->in_run_queue = true; ++ ++ manager_trigger_run_queue(j->manager); + } + + void job_add_to_dbus_queue(Job *j) { +diff --git a/src/core/manager.c b/src/core/manager.c +index ee976f70b3..845c26f498 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -2120,6 +2120,18 @@ static int manager_dispatch_run_queue(sd_event_source *source, void *userdata) { + return 1; + } + ++void manager_trigger_run_queue(Manager *m) { ++ int r; ++ ++ assert(m); ++ ++ r = sd_event_source_set_enabled( ++ m->run_queue_event_source, ++ m->run_queue ? SD_EVENT_ONESHOT: SD_EVENT_OFF); ++ if (r < 0) ++ log_warning_errno(r, "Failed to enable job run queue event source, ignoring: %m"); ++} ++ + static unsigned manager_dispatch_dbus_queue(Manager *m) { + unsigned n = 0, budget; + Unit *u; +diff --git a/src/core/manager.h b/src/core/manager.h +index c4b8e80093..7b572c8dfd 100644 +--- a/src/core/manager.h ++++ b/src/core/manager.h +@@ -416,6 +416,8 @@ unsigned manager_dispatch_load_queue(Manager *m); + int manager_environment_add(Manager *m, char **minus, char **plus); + int manager_set_default_rlimits(Manager *m, struct rlimit **default_rlimit); + ++void manager_trigger_run_queue(Manager *m); ++ + int manager_loop(Manager *m); + + int manager_open_serialization(Manager *m, FILE **_f); +diff --git a/src/core/mount.c b/src/core/mount.c +index bdba9e6884..c17154cde1 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1712,15 +1712,12 @@ static bool mount_is_mounted(Mount *m) { + + static int mount_on_ratelimit_expire(sd_event_source *s, void *userdata) { + Manager *m = userdata; +- int r; + + assert(m); + +- /* By entering ratelimited state we made all mount start jobs not runnable, now rate limit is over so let's +- * make sure we dispatch them in the next iteration. */ +- r = sd_event_source_set_enabled(m->run_queue_event_source, SD_EVENT_ONESHOT); +- if (r < 0) +- log_debug_errno(r, "Failed to enable run queue event source, ignoring: %m"); ++ /* By entering ratelimited state we made all mount start jobs not runnable, now rate limit is over so ++ * let's make sure we dispatch them in the next iteration. */ ++ manager_trigger_run_queue(m); + + return 0; + } diff --git a/0698-unit-add-jobs-that-were-skipped-because-of-ratelimit.patch b/0698-unit-add-jobs-that-were-skipped-because-of-ratelimit.patch new file mode 100644 index 0000000000000000000000000000000000000000..bc7fe062f9dfcff5b0ae4c87bfd48e6872210a77 --- /dev/null +++ b/0698-unit-add-jobs-that-were-skipped-because-of-ratelimit.patch @@ -0,0 +1,46 @@ +From dd662fc39a28655b89619a828a15e5e457bf6f4c Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Thu, 25 Nov 2021 18:28:25 +0100 +Subject: [PATCH] unit: add jobs that were skipped because of ratelimit back to + run_queue + +Assumption in edc027b was that job we first skipped because of active +ratelimit is still in run_queue. Hence we trigger the queue and dispatch +it in the next iteration. Actually we remove jobs from run_queue in +job_run_and_invalidate() before we call unit_start(). Hence if we want +to attempt to run the job again in the future we need to add it back +to run_queue. + +Fixes #21458 + +(cherry picked from commit c29e6a9530316823b0455cd83eb6d0bb8dd664f4) + +Related: #2036608 +--- + src/core/mount.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/core/mount.c b/src/core/mount.c +index c17154cde1..691b23ca74 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1712,9 +1712,19 @@ static bool mount_is_mounted(Mount *m) { + + static int mount_on_ratelimit_expire(sd_event_source *s, void *userdata) { + Manager *m = userdata; ++ Job *j; ++ Iterator i; + + assert(m); + ++ /* Let's enqueue all start jobs that were previously skipped because of active ratelimit. */ ++ HASHMAP_FOREACH(j, m->jobs, i) { ++ if (j->unit->type != UNIT_MOUNT) ++ continue; ++ ++ job_add_to_run_queue(j); ++ } ++ + /* By entering ratelimited state we made all mount start jobs not runnable, now rate limit is over so + * let's make sure we dispatch them in the next iteration. */ + manager_trigger_run_queue(m); diff --git a/0699-Revert-Revert-sysctl-Enable-ping-8-inside-rootless-P.patch b/0699-Revert-Revert-sysctl-Enable-ping-8-inside-rootless-P.patch new file mode 100644 index 0000000000000000000000000000000000000000..5f9f27b9c262a725eb90b02c278385901db465ff --- /dev/null +++ b/0699-Revert-Revert-sysctl-Enable-ping-8-inside-rootless-P.patch @@ -0,0 +1,37 @@ +From 54faef034bb2062ed8afa72e2c1be40ef7cc41c5 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 26 Jul 2019 09:25:09 +0200 +Subject: [PATCH] Revert "Revert "sysctl: Enable ping(8) inside rootless Podman + containers"" + +This reverts commit be74f51605b4c7cb74fec3a50cd13b67598a8ac1. + +Let's add this again. With the new sysctl "-" thing we can make this +work. + +Resolves: #2037807 + +(cherry picked from commit 0338934f4bcda6a96a5342449ae96b003de3378d) +--- + sysctl.d/50-default.conf | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/sysctl.d/50-default.conf b/sysctl.d/50-default.conf +index e0afc9c702..21ae1df13d 100644 +--- a/sysctl.d/50-default.conf ++++ b/sysctl.d/50-default.conf +@@ -33,6 +33,14 @@ net.ipv4.conf.all.accept_source_route = 0 + # Promote secondary addresses when the primary address is removed + net.ipv4.conf.all.promote_secondaries = 1 + ++# ping(8) without CAP_NET_ADMIN and CAP_NET_RAW ++# The upper limit is set to 2^31-1. Values greater than that get rejected by ++# the kernel because of this definition in linux/include/net/ping.h: ++# #define GID_T_MAX (((gid_t)~0U) >> 1) ++# That's not so bad because values between 2^31 and 2^32-1 are reserved on ++# systemd-based systems anyway: https://systemd.io/UIDS-GIDS.html#summary ++net.ipv4.ping_group_range = 0 2147483647 ++ + # Fair Queue CoDel packet scheduler to fight bufferbloat + net.core.default_qdisc = fq_codel + diff --git a/0700-sysctl-prefix-ping-port-range-setting-with-a-dash.patch b/0700-sysctl-prefix-ping-port-range-setting-with-a-dash.patch new file mode 100644 index 0000000000000000000000000000000000000000..4e2e5664b150f366d5cef8c57fbd5125b48c87ca --- /dev/null +++ b/0700-sysctl-prefix-ping-port-range-setting-with-a-dash.patch @@ -0,0 +1,27 @@ +From 41a32aeaf5d33f253f48bfbe8d00de9d160985f7 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 26 Jul 2019 09:26:07 +0200 +Subject: [PATCH] sysctl: prefix ping port range setting with a dash + +Fixes: #13177 + +Resolves: #2037807 + +(cherry picked from commit 000500c9d6347e0e2cdb92ec48fa10c0bb3ceca8) +--- + sysctl.d/50-default.conf | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sysctl.d/50-default.conf b/sysctl.d/50-default.conf +index 21ae1df13d..5156d55ca9 100644 +--- a/sysctl.d/50-default.conf ++++ b/sysctl.d/50-default.conf +@@ -39,7 +39,7 @@ net.ipv4.conf.all.promote_secondaries = 1 + # #define GID_T_MAX (((gid_t)~0U) >> 1) + # That's not so bad because values between 2^31 and 2^32-1 are reserved on + # systemd-based systems anyway: https://systemd.io/UIDS-GIDS.html#summary +-net.ipv4.ping_group_range = 0 2147483647 ++-net.ipv4.ping_group_range = 0 2147483647 + + # Fair Queue CoDel packet scheduler to fight bufferbloat + net.core.default_qdisc = fq_codel diff --git a/0701-mount-don-t-propagate-errors-from-mount_setup_unit-f.patch b/0701-mount-don-t-propagate-errors-from-mount_setup_unit-f.patch new file mode 100644 index 0000000000000000000000000000000000000000..adc7bd138cd3cb3a11f5d040c275feb1ee9b36fc --- /dev/null +++ b/0701-mount-don-t-propagate-errors-from-mount_setup_unit-f.patch @@ -0,0 +1,56 @@ +From c236734f95550747c4979fe318e3a890adaa0a94 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 28 Nov 2018 12:41:44 +0100 +Subject: [PATCH] mount: don't propagate errors from mount_setup_unit() further + up + +If we can't process a specific line in /proc/self/mountinfo we should +log about it (which we do), but this should not affect other lines, nor +further processing of mount units. Let's keep these failures local. + +Fixes: #10874 + +Cherry picked from commit ba0d56f55f2073164799be714b5bd1aad94d059a. +Trivial conflict in src/core/mount.c, function mount_load_proc_self_mountinfo, +due to local commit ca634baa10e. Also, due to the same commit, int k +is no longer used and is thus removed. + +Resolves: #2036853 + +Signed-off-by: Kir Kolyshkin +--- + src/core/mount.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/src/core/mount.c b/src/core/mount.c +index 691b23ca74..4e0a4f238a 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1615,12 +1615,10 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { + if (r < 0) + return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m"); + +- r = 0; + for (;;) { + struct libmnt_fs *fs; + const char *device, *path, *options, *fstype; + _cleanup_free_ char *d = NULL, *p = NULL; +- int k; + + r = mnt_table_next_fs(table, iter, &fs); + if (r == 1) +@@ -1644,12 +1642,10 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { + + device_found_node(m, d, DEVICE_FOUND_MOUNT, DEVICE_FOUND_MOUNT); + +- k = mount_setup_unit(m, d, p, options, fstype, set_flags); +- if (r == 0 && k < 0) +- r = k; ++ (void) mount_setup_unit(m, d, p, options, fstype, set_flags); + } + +- return r; ++ return 0; + } + + static void mount_shutdown(Manager *m) { diff --git a/0702-udev-net_id-introduce-naming-scheme-for-RHEL-8.5.patch b/0702-udev-net_id-introduce-naming-scheme-for-RHEL-8.5.patch new file mode 100644 index 0000000000000000000000000000000000000000..822fafcfdbf9671376843831d0ecd1d6f6017768 --- /dev/null +++ b/0702-udev-net_id-introduce-naming-scheme-for-RHEL-8.5.patch @@ -0,0 +1,50 @@ +From d45e0cc7a64648dc3ad082b512ff488537d3ebef Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 12 Jan 2022 15:35:19 +0100 +Subject: [PATCH] udev/net_id: introduce naming scheme for RHEL-8.5 + +RHEL-only + +Related: #2039797 +--- + 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 10e71dcb15..be969bc8d0 100644 +--- a/man/systemd.net-naming-scheme.xml ++++ b/man/systemd.net-naming-scheme.xml +@@ -301,6 +301,12 @@ + avoid possible naming conflict. + + ++ ++ rhel-8.5 ++ ++ Same as naming scheme rhel-8.4. ++ ++ + 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 7c153f0aef..81139e666b 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -134,6 +134,7 @@ typedef enum NamingSchemeFlags { + NAMING_RHEL_8_2 = NAMING_V239, + NAMING_RHEL_8_3 = NAMING_V239, + NAMING_RHEL_8_4 = NAMING_V239|NAMING_BRIDGE_NO_SLOT, ++ NAMING_RHEL_8_5 = NAMING_RHEL_8_4, + + _NAMING_SCHEME_FLAGS_INVALID = -1, + } NamingSchemeFlags; +@@ -151,6 +152,7 @@ static const NamingScheme naming_schemes[] = { + { "rhel-8.2", NAMING_RHEL_8_2 }, + { "rhel-8.3", NAMING_RHEL_8_3 }, + { "rhel-8.4", NAMING_RHEL_8_4 }, ++ { "rhel-8.5", NAMING_RHEL_8_5 }, + /* … add more schemes here, as the logic to name devices is updated … */ + }; + diff --git a/0703-udev-net_id-remove-extraneous-bracket.patch b/0703-udev-net_id-remove-extraneous-bracket.patch new file mode 100644 index 0000000000000000000000000000000000000000..6c3efb89d9effe4b32e6312bef873609e5cbb28e --- /dev/null +++ b/0703-udev-net_id-remove-extraneous-bracket.patch @@ -0,0 +1,25 @@ +From a967622c58e1ae76bb7e22e83389295c77d560df Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 12 Jan 2022 15:35:54 +0100 +Subject: [PATCH] udev/net_id: remove extraneous bracket + +RHEL-only + +Related: #2039797 +--- + man/systemd.net-naming-scheme.xml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/man/systemd.net-naming-scheme.xml b/man/systemd.net-naming-scheme.xml +index be969bc8d0..a65da5c6c1 100644 +--- a/man/systemd.net-naming-scheme.xml ++++ b/man/systemd.net-naming-scheme.xml +@@ -307,7 +307,7 @@ + Same as naming scheme rhel-8.4. + + +- Note that latest may be used to denote the latest scheme known (to this ++ Note that latest may be used to denote the latest scheme known to this + particular version of systemd. + + diff --git a/0704-udev-net_id-introduce-naming-scheme-for-RHEL-8.6.patch b/0704-udev-net_id-introduce-naming-scheme-for-RHEL-8.6.patch new file mode 100644 index 0000000000000000000000000000000000000000..a5f712f9a6ef5c939c79dcb8a599b1663b9b5427 --- /dev/null +++ b/0704-udev-net_id-introduce-naming-scheme-for-RHEL-8.6.patch @@ -0,0 +1,50 @@ +From 7ee6542c64103205d6520c1165894b3b6a40f2c9 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 12 Jan 2022 15:38:38 +0100 +Subject: [PATCH] udev/net_id: introduce naming scheme for RHEL-8.6 + +RHEL-only + +Related: #2039797 +--- + 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 a65da5c6c1..fe1aa4b654 100644 +--- a/man/systemd.net-naming-scheme.xml ++++ b/man/systemd.net-naming-scheme.xml +@@ -307,6 +307,12 @@ + Same as naming scheme rhel-8.4. + + ++ ++ rhel-8.6 ++ ++ Same as naming scheme rhel-8.4. ++ ++ + 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 81139e666b..eafcbb64c5 100644 +--- a/src/udev/udev-builtin-net_id.c ++++ b/src/udev/udev-builtin-net_id.c +@@ -135,6 +135,7 @@ typedef enum NamingSchemeFlags { + NAMING_RHEL_8_3 = NAMING_V239, + NAMING_RHEL_8_4 = NAMING_V239|NAMING_BRIDGE_NO_SLOT, + NAMING_RHEL_8_5 = NAMING_RHEL_8_4, ++ NAMING_RHEL_8_6 = NAMING_RHEL_8_4, + + _NAMING_SCHEME_FLAGS_INVALID = -1, + } NamingSchemeFlags; +@@ -153,6 +154,7 @@ static const NamingScheme naming_schemes[] = { + { "rhel-8.3", NAMING_RHEL_8_3 }, + { "rhel-8.4", NAMING_RHEL_8_4 }, + { "rhel-8.5", NAMING_RHEL_8_5 }, ++ { "rhel-8.6", NAMING_RHEL_8_6 }, + /* … add more schemes here, as the logic to name devices is updated … */ + }; + diff --git a/0637-define-newly-needed-constants.patch b/0705-define-newly-needed-constants.patch similarity index 93% rename from 0637-define-newly-needed-constants.patch rename to 0705-define-newly-needed-constants.patch index 7bbbbcf83e5cf6f03da9c992dbc32ddea1916412..9281b840c3ff24c1cb4185ab73014d4519cfd633 100644 --- a/0637-define-newly-needed-constants.patch +++ b/0705-define-newly-needed-constants.patch @@ -1,9 +1,9 @@ -From 81b23f487eeffbc0e217c4e57567cfb70842f668 Mon Sep 17 00:00:00 2001 +From 08c1e6e304108e8bc8beca126f50888be7575bd0 Mon Sep 17 00:00:00 2001 From: David Tardon Date: Thu, 26 Nov 2020 16:29:10 +0100 Subject: [PATCH] define newly needed constants -Related: #1850986 +Related: #2005008 --- src/basic/missing.h | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/0638-sd-netlink-support-IFLA_PROP_LIST-and-IFLA_ALT_IFNAM.patch b/0706-sd-netlink-support-IFLA_PROP_LIST-and-IFLA_ALT_IFNAM.patch similarity index 98% rename from 0638-sd-netlink-support-IFLA_PROP_LIST-and-IFLA_ALT_IFNAM.patch rename to 0706-sd-netlink-support-IFLA_PROP_LIST-and-IFLA_ALT_IFNAM.patch index 47667d64772898e1b3d72a32f78c3d0640f2c834..6b0e46b0de662463c963e7baf852a045f031b9bb 100644 --- a/0638-sd-netlink-support-IFLA_PROP_LIST-and-IFLA_ALT_IFNAM.patch +++ b/0706-sd-netlink-support-IFLA_PROP_LIST-and-IFLA_ALT_IFNAM.patch @@ -1,4 +1,4 @@ -From b0b98085bb0b95395b686efca43980d463749f3d Mon Sep 17 00:00:00 2001 +From 32e39fd249737c77248c32d064021426a2ec7a52 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 15 Dec 2019 20:57:51 +0900 Subject: [PATCH] sd-netlink: support IFLA_PROP_LIST and IFLA_ALT_IFNAME @@ -6,7 +6,7 @@ Subject: [PATCH] sd-netlink: support IFLA_PROP_LIST and IFLA_ALT_IFNAME (cherry picked from commit ffeb16f5d832b1c65b8c8a1dd9bdd028bd76fc72) -Related: #1850986 +Related: #2005008 --- src/libsystemd/sd-netlink/netlink-message.c | 2 +- src/libsystemd/sd-netlink/netlink-types.c | 13 +++++++++++++ diff --git a/0639-sd-netlink-introduce-sd_netlink_message_read_strv.patch b/0707-sd-netlink-introduce-sd_netlink_message_read_strv.patch similarity index 98% rename from 0639-sd-netlink-introduce-sd_netlink_message_read_strv.patch rename to 0707-sd-netlink-introduce-sd_netlink_message_read_strv.patch index f3866d5b8d9512e959f8b1b9480c14fa468a79be..ecf264ceefee3b32b18e8392f12cd1ad9c8ae273 100644 --- a/0639-sd-netlink-introduce-sd_netlink_message_read_strv.patch +++ b/0707-sd-netlink-introduce-sd_netlink_message_read_strv.patch @@ -1,4 +1,4 @@ -From 3c31ef05ba732e3ab5d23761c5f84768ca8de68e Mon Sep 17 00:00:00 2001 +From cd3b4c5345a3500f190941454fff03fc143c6f2e Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 15 Dec 2019 21:32:25 +0900 Subject: [PATCH] sd-netlink: introduce sd_netlink_message_read_strv() @@ -10,7 +10,7 @@ The function introduced here reads all matched attributes. (cherry picked from commit 8f3c1859669230c2c8458675f41de13e369b47e7) -Related: #1850986 +Related: #2005008 --- src/libsystemd/sd-netlink/netlink-message.c | 58 +++++++++++++++++++++ src/systemd/sd-netlink.h | 1 + diff --git a/0640-sd-netlink-introduce-sd_netlink_message_append_strv.patch b/0708-sd-netlink-introduce-sd_netlink_message_append_strv.patch similarity index 96% rename from 0640-sd-netlink-introduce-sd_netlink_message_append_strv.patch rename to 0708-sd-netlink-introduce-sd_netlink_message_append_strv.patch index d271edb5d46400a3edd656783b9049411ec56383..2f66c130fe926c878b46e0c31f3acdfb94edd461 100644 --- a/0640-sd-netlink-introduce-sd_netlink_message_append_strv.patch +++ b/0708-sd-netlink-introduce-sd_netlink_message_append_strv.patch @@ -1,11 +1,11 @@ -From 7888c8796197357f0214ea5fe17b11a8814fc313 Mon Sep 17 00:00:00 2001 +From bbfebb42c9023e36fb66f0e3b0bad132ab2fba55 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 15 Dec 2019 21:47:21 +0900 Subject: [PATCH] sd-netlink: introduce sd_netlink_message_append_strv() (cherry picked from commit 6d725977c4f98a8f5effc33f44aa646cc2b6a0b7) -Related: #1850986 +Related: #2005008 --- src/libsystemd/sd-netlink/netlink-message.c | 29 +++++++++++++++++++++ src/systemd/sd-netlink.h | 1 + diff --git a/0641-test-add-a-test-for-sd_netlink_message_-append-read-.patch b/0709-test-add-a-test-for-sd_netlink_message_-append-read-.patch similarity index 96% rename from 0641-test-add-a-test-for-sd_netlink_message_-append-read-.patch rename to 0709-test-add-a-test-for-sd_netlink_message_-append-read-.patch index d99ffe5e4a38855e8292ac813f090b7e1b5c8b37..082a4e3dd0c0aa7663efdfd2d3ebe1cfc45f47e3 100644 --- a/0641-test-add-a-test-for-sd_netlink_message_-append-read-.patch +++ b/0709-test-add-a-test-for-sd_netlink_message_-append-read-.patch @@ -1,11 +1,11 @@ -From aff5197c5f06617b1ca0291614a0fb02c0c2e948 Mon Sep 17 00:00:00 2001 +From 58d0d77ddda4c02943d1f03e4c142aec9c4930f5 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 15 Dec 2019 21:48:12 +0900 Subject: [PATCH] test: add a test for sd_netlink_message_{append,read}_strv() (cherry picked from commit d08d92d5ee508a80e35d6b95b962bd09527fb5f2) -Related: #1850986 +Related: #2005008 --- src/libsystemd/sd-netlink/test-netlink.c | 33 ++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/0642-util-introduce-ifname_valid_full.patch b/0710-util-introduce-ifname_valid_full.patch similarity index 96% rename from 0642-util-introduce-ifname_valid_full.patch rename to 0710-util-introduce-ifname_valid_full.patch index 6c877dc077659376f0095f2838a9588444a2d8bb..c04c9957a338edd13664d2ca73c21407ae4c974d 100644 --- a/0642-util-introduce-ifname_valid_full.patch +++ b/0710-util-introduce-ifname_valid_full.patch @@ -1,11 +1,11 @@ -From c50aab5f23535ea7f3ef004910465e7054931199 Mon Sep 17 00:00:00 2001 +From 1b12b8e9c0f6f230e12ca13bd70f27ef0a2fcfdd Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 15 Dec 2019 23:01:54 +0900 Subject: [PATCH] util: introduce ifname_valid_full() (cherry picked from commit 4252696aec9ec038ff312a164e25f039da25126f) -Related: #1850986 +Related: #2005008 --- src/basic/socket-util.c | 12 +++++++++--- src/basic/socket-util.h | 5 ++++- diff --git a/0643-rename-function.patch b/0711-rename-function.patch similarity index 98% rename from 0643-rename-function.patch rename to 0711-rename-function.patch index eb28e08e4589e03ee8ca5d8bd591e21204b11cbb..f256c15c72449842c3ee674047c139e35020fd22 100644 --- a/0643-rename-function.patch +++ b/0711-rename-function.patch @@ -1,4 +1,4 @@ -From 7fc7c2774e0836ace524215ced5c60db405a154a Mon Sep 17 00:00:00 2001 +From 3275093305c1305d163f26cb4e4d614a87f8ff43 Mon Sep 17 00:00:00 2001 From: David Tardon Date: Fri, 27 Nov 2020 10:25:12 +0100 Subject: [PATCH] rename function @@ -7,7 +7,7 @@ This happened upstream in commit 54a8423788ec3cc6240959ab9f5cdac40baf047a, but I don't want to backport the whole commit... -Related: #1850986 +Related: #2005008 --- src/libsystemd-network/network-internal.c | 2 +- src/libsystemd-network/network-internal.h | 2 +- diff --git a/0644-udev-support-AlternativeName-setting-in-.link-file.patch b/0712-udev-support-AlternativeName-setting-in-.link-file.patch similarity index 99% rename from 0644-udev-support-AlternativeName-setting-in-.link-file.patch rename to 0712-udev-support-AlternativeName-setting-in-.link-file.patch index 6f0700243bc607fc31e7a77dd5df4ddf3a5f33ce..d4fe837f24495b94572c6d59425e645163eb5581 100644 --- a/0644-udev-support-AlternativeName-setting-in-.link-file.patch +++ b/0712-udev-support-AlternativeName-setting-in-.link-file.patch @@ -1,11 +1,11 @@ -From b99b055ba975c1663beaf94dbfe8f5c5c7398996 Mon Sep 17 00:00:00 2001 +From a29790ac578540ccb4264367603aba9bc41d1bf7 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 15 Dec 2019 23:21:18 +0900 Subject: [PATCH] udev: support AlternativeName= setting in .link file (cherry picked from commit a5053a158b43c5ddee90f4915b9fc603e0191d6d) -Related: #1850986 +Related: #2005008 --- man/systemd.link.xml | 8 ++++ src/libsystemd/sd-netlink/netlink-util.c | 40 ++++++++++++++++ diff --git a/0645-network-make-Name-in-Match-support-alternative-names.patch b/0713-network-make-Name-in-Match-support-alternative-names.patch similarity index 73% rename from 0645-network-make-Name-in-Match-support-alternative-names.patch rename to 0713-network-make-Name-in-Match-support-alternative-names.patch index fe0a4c75fb22ae5cb39d60b9ddb92b7a6e5a6cd4..2783da9a167788d7a493855f15c6b699d0245f64 100644 --- a/0645-network-make-Name-in-Match-support-alternative-names.patch +++ b/0713-network-make-Name-in-Match-support-alternative-names.patch @@ -1,4 +1,4 @@ -From c76d050d8d61b4a63d4407bd03bd3f49cd9915ce Mon Sep 17 00:00:00 2001 +From 0c178bf442aebcd2b42f10a0e4d2382a15505bb6 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 15 Dec 2019 22:46:19 +0900 Subject: [PATCH] network: make Name= in [Match] support alternative names of @@ -7,13 +7,15 @@ Subject: [PATCH] network: make Name= in [Match] support alternative names of (cherry picked from commit 572b21d96cabd5860b0670e98440b6cb99a4b749 src/network bits have been left out.) -Related: #1850986 +Related: #2005008 --- man/systemd.network.xml | 7 +++---- src/libsystemd-network/network-internal.c | 20 ++++++++++++++++++-- src/libsystemd-network/network-internal.h | 3 ++- + src/network/netdev/netdev.c | 2 +- + src/network/networkd-network.c | 2 +- src/udev/net/link-config.c | 3 ++- - 4 files changed, 25 insertions(+), 8 deletions(-) + 6 files changed, 27 insertions(+), 10 deletions(-) diff --git a/man/systemd.network.xml b/man/systemd.network.xml index fc8e0aea68..8300540096 100644 @@ -99,6 +101,32 @@ index 9074758bbb..e1d098f3fe 100644 CONFIG_PARSER_PROTOTYPE(config_parse_net_condition); CONFIG_PARSER_PROTOTYPE(config_parse_hwaddr); +diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c +index 82ce88402f..e97cc07028 100644 +--- a/src/network/netdev/netdev.c ++++ b/src/network/netdev/netdev.c +@@ -640,7 +640,7 @@ static int netdev_load_one(Manager *manager, const char *filename) { + netdev_raw->match_host, netdev_raw->match_virt, + netdev_raw->match_kernel_cmdline, netdev_raw->match_kernel_version, + netdev_raw->match_arch, +- NULL, NULL, NULL, NULL, NULL, NULL) <= 0) ++ NULL, NULL, NULL, NULL, NULL, NULL, NULL) <= 0) + return 0; + + if (netdev_raw->kind == _NETDEV_KIND_INVALID) { +diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c +index 429aac5e6c..7637d135a4 100644 +--- a/src/network/networkd-network.c ++++ b/src/network/networkd-network.c +@@ -479,7 +479,7 @@ int network_get(Manager *manager, struct udev_device *device, + network->match_virt, network->match_kernel_cmdline, + network->match_kernel_version, network->match_arch, + address, path, parent_driver, driver, +- devtype, ifname)) { ++ devtype, ifname, NULL)) { + if (network->match_name && device) { + const char *attr; + uint8_t name_assign_type = NET_NAME_UNKNOWN; diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index d07a1a1874..e5052f8f29 100644 --- a/src/udev/net/link-config.c diff --git a/0646-udev-extend-the-length-of-ID_NET_NAME_XXX-to-ALTIFNA.patch b/0714-udev-extend-the-length-of-ID_NET_NAME_XXX-to-ALTIFNA.patch similarity index 91% rename from 0646-udev-extend-the-length-of-ID_NET_NAME_XXX-to-ALTIFNA.patch rename to 0714-udev-extend-the-length-of-ID_NET_NAME_XXX-to-ALTIFNA.patch index f8ed2ecef0f0c8e293d4738566a3263bf9e7dd87..191049a4b53cc303e81e008ae2709719f4d91171 100644 --- a/0646-udev-extend-the-length-of-ID_NET_NAME_XXX-to-ALTIFNA.patch +++ b/0714-udev-extend-the-length-of-ID_NET_NAME_XXX-to-ALTIFNA.patch @@ -1,11 +1,11 @@ -From 22dd44ae3cfd66e622e0b672af96728b6f505ad1 Mon Sep 17 00:00:00 2001 +From 9f59dca3868b1e934a2aac2d811c55ab33cca0eb Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 17 Dec 2019 11:01:35 +0900 Subject: [PATCH] udev: extend the length of ID_NET_NAME_XXX= to ALTIFNAMSIZ (cherry picked from commit 78f8849f84ca0939796edb840e878a9d2e124a4d) -Related: #1850986 +Related: #2005008 --- src/udev/net/link-config.c | 5 ++++- src/udev/udev-builtin-net_id.c | 33 +++++++++++++++++---------------- @@ -43,7 +43,7 @@ index e5052f8f29..4de8ee7d7e 100644 } diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c -index 7c153f0aef..0611c08234 100644 +index eafcbb64c5..386d74ca5e 100644 --- a/src/udev/udev-builtin-net_id.c +++ b/src/udev/udev-builtin-net_id.c @@ -90,6 +90,7 @@ @@ -54,7 +54,7 @@ index 7c153f0aef..0611c08234 100644 #include #include "dirent-util.h" -@@ -172,21 +173,21 @@ struct netnames { +@@ -176,21 +177,21 @@ struct netnames { bool mac_valid; struct udev_device *pcidev; @@ -85,7 +85,7 @@ index 7c153f0aef..0611c08234 100644 }; static const NamingScheme* naming_scheme_from_name(const char *name) { -@@ -883,7 +884,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool +@@ -887,7 +888,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool err = names_mac(dev, &names); if (err >= 0 && names.mac_valid) { @@ -94,7 +94,7 @@ index 7c153f0aef..0611c08234 100644 xsprintf(str, "%sx%02x%02x%02x%02x%02x%02x", prefix, names.mac[0], names.mac[1], names.mac[2], -@@ -896,7 +897,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool +@@ -900,7 +901,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool /* get path names for Linux on System z network devices */ err = names_ccw(dev, &names); if (err >= 0 && names.type == NET_CCW) { @@ -103,7 +103,7 @@ index 7c153f0aef..0611c08234 100644 if (snprintf_ok(str, sizeof str, "%s%s", prefix, names.ccw_busid)) udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str); -@@ -906,7 +907,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool +@@ -910,7 +911,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool /* get ibmveth/ibmvnic slot-based names. */ err = names_vio(dev, &names); if (err >= 0 && names.type == NET_VIO) { @@ -112,7 +112,7 @@ index 7c153f0aef..0611c08234 100644 if (snprintf_ok(str, sizeof str, "%s%s", prefix, names.vio_slot)) udev_builtin_add_property(dev, test, "ID_NET_NAME_SLOT", str); -@@ -916,7 +917,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool +@@ -920,7 +921,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool /* get ACPI path names for ARM64 platform devices */ err = names_platform(dev, &names, test); if (err >= 0 && names.type == NET_PLATFORM) { @@ -121,7 +121,7 @@ index 7c153f0aef..0611c08234 100644 if (snprintf_ok(str, sizeof str, "%s%s", prefix, names.platform_path)) udev_builtin_add_property(dev, test, "ID_NET_NAME_PATH", str); -@@ -930,7 +931,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool +@@ -934,7 +935,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool /* plain PCI device */ if (names.type == NET_PCI) { @@ -130,7 +130,7 @@ index 7c153f0aef..0611c08234 100644 if (names.pci_onboard[0] && snprintf_ok(str, sizeof str, "%s%s", prefix, names.pci_onboard)) -@@ -953,7 +954,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool +@@ -957,7 +958,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool /* USB device */ err = names_usb(dev, &names); if (err >= 0 && names.type == NET_USB) { @@ -139,7 +139,7 @@ index 7c153f0aef..0611c08234 100644 if (names.pci_path[0] && snprintf_ok(str, sizeof str, "%s%s%s", prefix, names.pci_path, names.usb_ports)) -@@ -968,7 +969,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool +@@ -972,7 +973,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool /* Broadcom bus */ err = names_bcma(dev, &names); if (err >= 0 && names.type == NET_BCMA) { diff --git a/0647-udev-do-not-fail-if-kernel-does-not-support-alternat.patch b/0715-udev-do-not-fail-if-kernel-does-not-support-alternat.patch similarity index 95% rename from 0647-udev-do-not-fail-if-kernel-does-not-support-alternat.patch rename to 0715-udev-do-not-fail-if-kernel-does-not-support-alternat.patch index 38ab61a3e50e8c8527610f8f1048f29e6deefbf7..29abb6843e8fadf3df6d2f67bedcea9cc05f8579 100644 --- a/0647-udev-do-not-fail-if-kernel-does-not-support-alternat.patch +++ b/0715-udev-do-not-fail-if-kernel-does-not-support-alternat.patch @@ -1,4 +1,4 @@ -From 42894fc33ae88f3be49aa01ac24dd1c3e96770f6 Mon Sep 17 00:00:00 2001 +From f0b11f5042489c85d5016eceff06647bb49d486a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 17 Dec 2019 15:32:22 +0900 Subject: [PATCH] udev: do not fail if kernel does not support alternative @@ -6,7 +6,7 @@ Subject: [PATCH] udev: do not fail if kernel does not support alternative (cherry picked from commit bb181dd4a664ca8e82a8f7194261fd6531e861d8) -Related: #1850986 +Related: #2005008 --- man/systemd.link.xml | 3 ++- src/udev/net/link-config.c | 4 +++- diff --git a/0648-udev-introduce-AlternativeNamesPolicy-setting.patch b/0716-udev-introduce-AlternativeNamesPolicy-setting.patch similarity index 99% rename from 0648-udev-introduce-AlternativeNamesPolicy-setting.patch rename to 0716-udev-introduce-AlternativeNamesPolicy-setting.patch index e22d7020eb3278cd9f41fb7cd129e2573883aa52..4b9087faf581619e23da6fe52c33dbf2e9188c8b 100644 --- a/0648-udev-introduce-AlternativeNamesPolicy-setting.patch +++ b/0716-udev-introduce-AlternativeNamesPolicy-setting.patch @@ -1,11 +1,11 @@ -From 4f47e35ee4026f24ee99a0bfa7ba5b2f24a92a02 Mon Sep 17 00:00:00 2001 +From 2faf160d0b8122e0dca603a441db68dc38c1bab6 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 16 Dec 2019 23:44:42 +0900 Subject: [PATCH] udev: introduce AlternativeNamesPolicy= setting (cherry picked from commit ef1d2c07f9567dfea8a4e012d8779a4ded2d9ae6) -Resolves: #1850986 +Related: #2005008 --- man/systemd.link.xml | 11 +++++ src/udev/net/link-config-gperf.gperf | 1 + diff --git a/0649-network-set-AlternativeNamesPolicy-in-99-default.lin.patch b/0717-network-set-AlternativeNamesPolicy-in-99-default.lin.patch similarity index 88% rename from 0649-network-set-AlternativeNamesPolicy-in-99-default.lin.patch rename to 0717-network-set-AlternativeNamesPolicy-in-99-default.lin.patch index 3effce6b09d69474b268a0227ebf5ca407568b8e..9f4a2161c4f8fd19464fd77e4439b1ded6792916 100644 --- a/0649-network-set-AlternativeNamesPolicy-in-99-default.lin.patch +++ b/0717-network-set-AlternativeNamesPolicy-in-99-default.lin.patch @@ -1,11 +1,11 @@ -From 433d85ac89baa0683290cf8b5a913e7c6d666ef1 Mon Sep 17 00:00:00 2001 +From 9a224b9480d218b782ac7bbacb3732672d0dad3f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 17 Dec 2019 00:30:38 +0900 Subject: [PATCH] network: set AlternativeNamesPolicy= in 99-default.link (cherry picked from commit 49f5cbe92484a6661bccc0ae6c547bc5767c83bf) -Related: #1850986 +Related: #2005008 --- network/99-default.link | 1 + 1 file changed, 1 insertion(+) diff --git a/0650-random-util-call-initialize_srand-after-fork.patch b/0718-random-util-call-initialize_srand-after-fork.patch similarity index 95% rename from 0650-random-util-call-initialize_srand-after-fork.patch rename to 0718-random-util-call-initialize_srand-after-fork.patch index 81796ab7f61400b0489df91f4ce2bf61c273d06c..f82e976a8b596897b7b2523d71b85cac1237b190 100644 --- a/0650-random-util-call-initialize_srand-after-fork.patch +++ b/0718-random-util-call-initialize_srand-after-fork.patch @@ -1,11 +1,11 @@ -From c4c771f2dc5c590990d1f9105886b833afa59852 Mon Sep 17 00:00:00 2001 +From 58cdc09af08e065c85b2f8834ee9848c010f5afe Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 16 Dec 2019 19:47:48 +0900 Subject: [PATCH] random-util: call initialize_srand() after fork() (cherry picked from commit a0f11d1d11a546f791855ec9c47c2ff830e6a5aa) -Related: #1850986 +Related: #2005008 --- src/basic/random-util.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/0651-sd-netlink-introduce-rtnl_resolve_link_alternative_n.patch b/0719-sd-netlink-introduce-rtnl_resolve_link_alternative_n.patch similarity index 97% rename from 0651-sd-netlink-introduce-rtnl_resolve_link_alternative_n.patch rename to 0719-sd-netlink-introduce-rtnl_resolve_link_alternative_n.patch index 94fecacf74d6f5d1f6fbea485115c64932f13341..4c80d6318e573f94fbb274f5497252794ed9165b 100644 --- a/0651-sd-netlink-introduce-rtnl_resolve_link_alternative_n.patch +++ b/0719-sd-netlink-introduce-rtnl_resolve_link_alternative_n.patch @@ -1,11 +1,11 @@ -From 8db22aec9bfd140855b64f2879b7ca6d1cba69c6 Mon Sep 17 00:00:00 2001 +From bb7c49cc95e9de877fafc5c2be06932bc21aa762 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 17 Dec 2019 18:28:36 +0900 Subject: [PATCH] sd-netlink: introduce rtnl_resolve_link_alternative_names() (cherry picked from commit b04c5e51da7a61d41d564e73a1e92bd8b29b0223) -Related: #1850986 +Related: #2005008 --- src/libsystemd/sd-netlink/netlink-types.c | 1 + src/libsystemd/sd-netlink/netlink-util.c | 29 +++++++++++++++++++++++ diff --git a/0652-udev-sort-alternative-names.patch b/0720-udev-sort-alternative-names.patch similarity index 91% rename from 0652-udev-sort-alternative-names.patch rename to 0720-udev-sort-alternative-names.patch index 896c8ab673f66188363f5bafcec8d7d12aa0dc3d..e3f0f9421912744fb9123c2867575573fbd9664e 100644 --- a/0652-udev-sort-alternative-names.patch +++ b/0720-udev-sort-alternative-names.patch @@ -1,4 +1,4 @@ -From eeea9a2f94b5defb97c20c62a23345a367a734aa Mon Sep 17 00:00:00 2001 +From f5d149095f95704fe7660069a493c0329ddbb5aa Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 17 Dec 2019 20:41:21 +0900 Subject: [PATCH] udev: sort alternative names @@ -8,7 +8,7 @@ visibility, let's sort the alternative names. (cherry picked from commit 4d016e965b13883cccc963a34a1299a0c4f900ca) -Related: #1850986 +Related: #2005008 --- src/udev/net/link-config.c | 1 + 1 file changed, 1 insertion(+) diff --git a/0653-netlink-introduce-rtnl_get-delete_link_alternative_n.patch b/0721-netlink-introduce-rtnl_get-delete_link_alternative_n.patch similarity index 98% rename from 0653-netlink-introduce-rtnl_get-delete_link_alternative_n.patch rename to 0721-netlink-introduce-rtnl_get-delete_link_alternative_n.patch index 8b99f33e26e758f60502cf5890c04723da0b3f71..0cc78fcac7acfbc9e6f622ef00afcd23aceec87c 100644 --- a/0653-netlink-introduce-rtnl_get-delete_link_alternative_n.patch +++ b/0721-netlink-introduce-rtnl_get-delete_link_alternative_n.patch @@ -1,11 +1,11 @@ -From 8f946da7ee9bbb6e52e99b452c1f4f6f76e7b3c2 Mon Sep 17 00:00:00 2001 +From c6b2c2fb577d20879b5b4c610c4c29bac259beab Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 17 Jul 2020 21:29:13 +0900 Subject: [PATCH] netlink: introduce rtnl_get/delete_link_alternative_names() (cherry picked from commit 14982526145de84201c7e3b4fc6be6aa5e9a08f7) -Related: #1850986 +Related: #2005008 --- src/libsystemd/sd-netlink/netlink-util.c | 45 ++++++++++++++++++++++-- src/libsystemd/sd-netlink/netlink-util.h | 2 ++ diff --git a/0654-netlink-do-not-fail-when-new-interface-name-is-alrea.patch b/0722-netlink-do-not-fail-when-new-interface-name-is-alrea.patch similarity index 97% rename from 0654-netlink-do-not-fail-when-new-interface-name-is-alrea.patch rename to 0722-netlink-do-not-fail-when-new-interface-name-is-alrea.patch index 3cf3b8b41025745bd27822e462244fcd415c7720..2774ac2a92ff4fef69349eb506d02c5bad76cd57 100644 --- a/0654-netlink-do-not-fail-when-new-interface-name-is-alrea.patch +++ b/0722-netlink-do-not-fail-when-new-interface-name-is-alrea.patch @@ -1,4 +1,4 @@ -From 6db267672de69d6bf4809f433cde106e11145ca8 Mon Sep 17 00:00:00 2001 +From 73ff88cdb6bd1991d75323c6c364bcc9bce7efda Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 17 Jul 2020 21:31:24 +0900 Subject: [PATCH] netlink: do not fail when new interface name is already used @@ -12,7 +12,7 @@ as an alternative name. (cherry picked from commit 434a34838034347f45fb9a47df55b1a36e5addfd) -Related: #1850986 +Related: #2005008 --- src/libsystemd/sd-netlink/netlink-util.c | 30 +++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/0655-udev-do-not-try-to-reassign-alternative-names.patch b/0723-udev-do-not-try-to-reassign-alternative-names.patch similarity index 95% rename from 0655-udev-do-not-try-to-reassign-alternative-names.patch rename to 0723-udev-do-not-try-to-reassign-alternative-names.patch index a203bf337fbdd0d06f2393c18aeec37d3b52b990..f707a3d83d50b1252424710e98b06393f6fd3474 100644 --- a/0655-udev-do-not-try-to-reassign-alternative-names.patch +++ b/0723-udev-do-not-try-to-reassign-alternative-names.patch @@ -1,4 +1,4 @@ -From 817a707daf1e9fa4f20eba04ce1c52af7518e355 Mon Sep 17 00:00:00 2001 +From aec8473f69877c353b9e788b2a7329e290ae14f9 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 17 Jul 2020 21:36:05 +0900 Subject: [PATCH] udev: do not try to reassign alternative names @@ -7,7 +7,7 @@ Setting alternative names may fail if some of them are already assigned. (cherry picked from commit 97fdae33dfe8e7e0a4e5230564f6cdebc4450eec) -Related: #1850986 +Related: #2005008 --- src/udev/net/link-config.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/0724-Do-not-fail-if-the-same-alt.-name-is-set-again.patch b/0724-Do-not-fail-if-the-same-alt.-name-is-set-again.patch new file mode 100644 index 0000000000000000000000000000000000000000..46d537cdb68f51593307b1ab04197ce3f22a4924 --- /dev/null +++ b/0724-Do-not-fail-if-the-same-alt.-name-is-set-again.patch @@ -0,0 +1,27 @@ +From 270e3f46d1fe474eb3b4cd6789520b36a740ef32 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Wed, 8 Dec 2021 09:49:24 +0100 +Subject: [PATCH] Do not fail if the same alt. name is set again + +This is a workaround for a kernel bug. + +RHEL-only + +Related: #2005008 +--- + src/udev/net/link-config.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c +index 5220f247f0..9046c5bd2a 100644 +--- a/src/udev/net/link-config.c ++++ b/src/udev/net/link-config.c +@@ -526,7 +526,7 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, + strv_uniq(altnames); + strv_sort(altnames); + r = rtnl_set_link_alternative_names(&ctx->rtnl, ifindex, altnames); +- if (r == -EOPNOTSUPP) ++ if (IN_SET(r, -EOPNOTSUPP, -EEXIST)) + log_debug_errno(r, "Could not set AlternativeName= or apply AlternativeNamesPolicy= on %s, ignoring: %m", old_name); + else if (r < 0) + return log_warning_errno(r, "Could not set AlternativeName= or apply AlternativeNamesPolicy= on %s: %m", old_name); diff --git a/0725-mount-do-not-update-exec-deps-on-mountinfo-changes.patch b/0725-mount-do-not-update-exec-deps-on-mountinfo-changes.patch new file mode 100644 index 0000000000000000000000000000000000000000..6a68cafb3b166615b908e03f546736e664e9cd0c --- /dev/null +++ b/0725-mount-do-not-update-exec-deps-on-mountinfo-changes.patch @@ -0,0 +1,87 @@ +From 21e4d155ac04bf3b999834cd42e4773ae01bf3b3 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 15 Nov 2019 14:00:54 +0100 +Subject: [PATCH] mount: do not update exec deps on mountinfo changes + +Fixes: #13978 +(cherry picked from commit bf7eedbf8f8c83d9e775c80275f98f506ec963c6) + +Related: #2008825 +--- + src/core/mount.c | 42 ++++++++++++++++++++++++++++-------------- + 1 file changed, 28 insertions(+), 14 deletions(-) + +diff --git a/src/core/mount.c b/src/core/mount.c +index 4e0a4f238a..73c0531158 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -535,6 +535,32 @@ static int mount_verify(Mount *m) { + return 0; + } + ++static int mount_add_non_exec_dependencies(Mount *m) { ++ int r; ++ assert(m); ++ ++ /* Adds in all dependencies directly responsible for ordering the mount, as opposed to dependencies ++ * resulting from the ExecContext and such. */ ++ ++ r = mount_add_device_dependencies(m); ++ if (r < 0) ++ return r; ++ ++ r = mount_add_mount_dependencies(m); ++ if (r < 0) ++ return r; ++ ++ r = mount_add_quota_dependencies(m); ++ if (r < 0) ++ return r; ++ ++ r = mount_add_default_dependencies(m); ++ if (r < 0) ++ return r; ++ ++ return 0; ++} ++ + static int mount_add_extras(Mount *m) { + Unit *u = UNIT(m); + int r; +@@ -558,18 +584,6 @@ static int mount_add_extras(Mount *m) { + return r; + } + +- r = mount_add_device_dependencies(m); +- if (r < 0) +- return r; +- +- r = mount_add_mount_dependencies(m); +- if (r < 0) +- return r; +- +- r = mount_add_quota_dependencies(m); +- if (r < 0) +- return r; +- + r = unit_patch_contexts(u); + if (r < 0) + return r; +@@ -582,7 +596,7 @@ static int mount_add_extras(Mount *m) { + if (r < 0) + return r; + +- r = mount_add_default_dependencies(m); ++ r = mount_add_non_exec_dependencies(m); + if (r < 0) + return r; + +@@ -1526,7 +1540,7 @@ static int mount_setup_existing_unit( + } + + if (load_extras) +- return mount_add_extras(MOUNT(u)); ++ return mount_add_non_exec_dependencies(MOUNT(u)); + + return 0; + } diff --git a/0726-core-mount-add-implicit-unit-dependencies-even-if-wh.patch b/0726-core-mount-add-implicit-unit-dependencies-even-if-wh.patch new file mode 100644 index 0000000000000000000000000000000000000000..538c8993be18ea8d2e2797ac08f756f9c3ade282 --- /dev/null +++ b/0726-core-mount-add-implicit-unit-dependencies-even-if-wh.patch @@ -0,0 +1,46 @@ +From 1fb992c50f7fc6a5c399e302ba79097d36a0cedf Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 29 Aug 2021 21:20:43 +0900 +Subject: [PATCH] core/mount: add implicit unit dependencies even if when mount + unit is generated from /proc/self/mountinfo + +Hopefully fixes #20566. + +(cherry picked from commit aebff2e7ce209fc2d75b894a3ae8b80f6f36ec11) + +Resolves: #2008825 +--- + src/core/mount.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/core/mount.c b/src/core/mount.c +index 73c0531158..9547cb9b29 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1437,6 +1437,7 @@ static int mount_setup_new_unit( + MountSetupFlags *flags) { + + MountParameters *p; ++ int r; + + assert(u); + assert(flags); +@@ -1458,7 +1459,6 @@ static int mount_setup_new_unit( + + if (!mount_is_extrinsic(MOUNT(u))) { + const char *target; +- int r; + + target = mount_is_network(p) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET; + r = unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true, UNIT_DEPENDENCY_MOUNTINFO_IMPLICIT); +@@ -1470,6 +1470,10 @@ static int mount_setup_new_unit( + return r; + } + ++ r = mount_add_non_exec_dependencies(MOUNT(u)); ++ if (r < 0) ++ return r; ++ + unit_add_to_load_queue(u); + flags->is_mounted = true; + flags->just_mounted = true; diff --git a/0727-core-fix-unfortunate-typo-in-unit_is_unneeded.patch b/0727-core-fix-unfortunate-typo-in-unit_is_unneeded.patch new file mode 100644 index 0000000000000000000000000000000000000000..bea7482403178fe109dc1e1b2cbf1f32067caf42 --- /dev/null +++ b/0727-core-fix-unfortunate-typo-in-unit_is_unneeded.patch @@ -0,0 +1,27 @@ +From 7b9b641a7721f013fb12ab4e2a03423b5ede08c6 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 9 Oct 2018 22:23:14 +0200 +Subject: [PATCH] core: fix unfortunate typo in unit_is_unneeded() + +Follow-up for a3c1168ac293f16d9343d248795bb4c246aaff4a. + +(cherry picked from commit 93d4cb09d56e670b0c203dd6ec6939e391a0df59) + +Resolves: #2040147 +--- + src/core/unit.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index 4de218feac..e2c61ce866 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1956,7 +1956,7 @@ bool unit_is_unneeded(Unit *u) { + * restart, then don't clean this one up. */ + + HASHMAP_FOREACH_KEY(v, other, u->dependencies[deps[j]], i) { +- if (u->job) ++ if (other->job) + return false; + + if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) diff --git a/0728-core-make-destructive-transaction-error-a-bit-more-u.patch b/0728-core-make-destructive-transaction-error-a-bit-more-u.patch new file mode 100644 index 0000000000000000000000000000000000000000..6694a5dcad50caf9c33512c8fbdd36d9477abb2d --- /dev/null +++ b/0728-core-make-destructive-transaction-error-a-bit-more-u.patch @@ -0,0 +1,27 @@ +From 8cb38e1557b81740f49dff43a297aef7bd676424 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 9 Oct 2018 22:22:52 +0200 +Subject: [PATCH] core: make destructive transaction error a bit more useful + +(cherry picked from commit cf99f8eacf1c864b19a6a02edea78c43f3185cb7) + +Related: #2040147 +--- + src/core/transaction.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/core/transaction.c b/src/core/transaction.c +index cdaaff4f55..ee5b39fef4 100644 +--- a/src/core/transaction.c ++++ b/src/core/transaction.c +@@ -526,7 +526,9 @@ static int transaction_is_destructive(Transaction *tr, JobMode mode, sd_bus_erro + if (j->unit->job && (mode == JOB_FAIL || j->unit->job->irreversible) && + job_type_is_conflicting(j->unit->job->type, j->type)) + return sd_bus_error_setf(e, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE, +- "Transaction is destructive."); ++ "Transaction for %s/%s is destructive (%s has '%s' job queued, but '%s' is included in transaction).", ++ tr->anchor_job->unit->id, job_type_to_string(tr->anchor_job->type), ++ j->unit->id, job_type_to_string(j->unit->job->type), job_type_to_string(j->type)); + } + + return 0; diff --git a/0729-tmpfiles-use-a-entry-in-hashmap-as-ItemArray-in-read.patch b/0729-tmpfiles-use-a-entry-in-hashmap-as-ItemArray-in-read.patch new file mode 100644 index 0000000000000000000000000000000000000000..0e22dbbf1f46d6409dc4fb931cab7b8c2f0dfc5a --- /dev/null +++ b/0729-tmpfiles-use-a-entry-in-hashmap-as-ItemArray-in-read.patch @@ -0,0 +1,89 @@ +From 81b967279f6e23474b1e7a0ea9b4ecf9405f87bb Mon Sep 17 00:00:00 2001 +From: Masahiro Matsuya +Date: Wed, 31 Mar 2021 11:44:24 +0900 +Subject: [PATCH] tmpfiles: use a entry in hashmap as ItemArray in + read_config_file() + +[zjs: squash commits and use size_t as appropriate. + +Bug seems to have been introduced in 811a15877825da9e53f9a2a8603da34589af6bbb. +Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1944468.] + +(cherry picked from commit bec890e3cd6dac249cb12ce9430fdb78b6cf546b) + +Resolves: #1944468 +--- + src/tmpfiles/tmpfiles.c | 47 +++++++++++++++++++++++------------------ + 1 file changed, 26 insertions(+), 21 deletions(-) + +diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c +index 927de35f32..1aeeed0d2e 100644 +--- a/src/tmpfiles/tmpfiles.c ++++ b/src/tmpfiles/tmpfiles.c +@@ -2646,7 +2646,7 @@ static int read_config_file(char **config_dirs, const char *fn, bool ignore_enoe + char line[LINE_MAX]; + Iterator iterator; + unsigned v = 0; +- Item *i; ++ ItemArray *ia; + int r = 0; + + assert(fn); +@@ -2692,32 +2692,37 @@ static int read_config_file(char **config_dirs, const char *fn, bool ignore_enoe + } + + /* we have to determine age parameter for each entry of type X */ +- ORDERED_HASHMAP_FOREACH(i, globs, iterator) { +- Iterator iter; +- Item *j, *candidate_item = NULL; ++ ORDERED_HASHMAP_FOREACH(ia, globs, iterator) ++ for (size_t ni = 0; ni < ia->count; ni++) { ++ Iterator iter; ++ ItemArray *ja; ++ Item *i = ia->items + ni, *candidate_item = NULL; + +- if (i->type != IGNORE_DIRECTORY_PATH) +- continue; +- +- ORDERED_HASHMAP_FOREACH(j, items, iter) { +- if (!IN_SET(j->type, CREATE_DIRECTORY, TRUNCATE_DIRECTORY, CREATE_SUBVOLUME, CREATE_SUBVOLUME_INHERIT_QUOTA, CREATE_SUBVOLUME_NEW_QUOTA)) ++ if (i->type != IGNORE_DIRECTORY_PATH) + continue; + +- if (path_equal(j->path, i->path)) { +- candidate_item = j; +- break; +- } ++ ORDERED_HASHMAP_FOREACH(ja, items, iter) ++ for (size_t nj = 0; nj < ja->count; nj++) { ++ Item *j = ja->items + nj; + +- if ((!candidate_item && path_startswith(i->path, j->path)) || +- (candidate_item && path_startswith(j->path, candidate_item->path) && (fnmatch(i->path, j->path, FNM_PATHNAME | FNM_PERIOD) == 0))) +- candidate_item = j; +- } ++ if (!IN_SET(j->type, CREATE_DIRECTORY, TRUNCATE_DIRECTORY, CREATE_SUBVOLUME, CREATE_SUBVOLUME_INHERIT_QUOTA, CREATE_SUBVOLUME_NEW_QUOTA)) ++ continue; + +- if (candidate_item && candidate_item->age_set) { +- i->age = candidate_item->age; +- i->age_set = true; ++ if (path_equal(j->path, i->path)) { ++ candidate_item = j; ++ break; ++ } ++ ++ if ((!candidate_item && path_startswith(i->path, j->path)) || ++ (candidate_item && path_startswith(j->path, candidate_item->path) && (fnmatch(i->path, j->path, FNM_PATHNAME | FNM_PERIOD) == 0))) ++ candidate_item = j; ++ } ++ ++ if (candidate_item && candidate_item->age_set) { ++ i->age = candidate_item->age; ++ i->age_set = true; ++ } + } +- } + + if (ferror(f)) { + log_error_errno(errno, "Failed to read from file %s: %m", fn); diff --git a/0730-tmpfiles-rework-condition-check.patch b/0730-tmpfiles-rework-condition-check.patch new file mode 100644 index 0000000000000000000000000000000000000000..03611e4409a8b65c695b92edb698224f1da8c688 --- /dev/null +++ b/0730-tmpfiles-rework-condition-check.patch @@ -0,0 +1,45 @@ +From 520ff5394187a0d6cb0cb40251f6e8e997ccdd0e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 7 Apr 2021 17:54:49 +0200 +Subject: [PATCH] tmpfiles: rework condition check + +(!a && b) || (a && c) is replaced by (a ? c : b). + +path_startswith() != NULL is need to avoid type warning. + +(cherry picked from commit 875e7b25d84a111755dab79241c9e64e44836910) + +Related: #1944468 +--- + src/tmpfiles/tmpfiles.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c +index 1aeeed0d2e..50fada99dd 100644 +--- a/src/tmpfiles/tmpfiles.c ++++ b/src/tmpfiles/tmpfiles.c +@@ -2705,7 +2705,11 @@ static int read_config_file(char **config_dirs, const char *fn, bool ignore_enoe + for (size_t nj = 0; nj < ja->count; nj++) { + Item *j = ja->items + nj; + +- if (!IN_SET(j->type, CREATE_DIRECTORY, TRUNCATE_DIRECTORY, CREATE_SUBVOLUME, CREATE_SUBVOLUME_INHERIT_QUOTA, CREATE_SUBVOLUME_NEW_QUOTA)) ++ if (!IN_SET(j->type, CREATE_DIRECTORY, ++ TRUNCATE_DIRECTORY, ++ CREATE_SUBVOLUME, ++ CREATE_SUBVOLUME_INHERIT_QUOTA, ++ CREATE_SUBVOLUME_NEW_QUOTA)) + continue; + + if (path_equal(j->path, i->path)) { +@@ -2713,8 +2717,9 @@ static int read_config_file(char **config_dirs, const char *fn, bool ignore_enoe + break; + } + +- if ((!candidate_item && path_startswith(i->path, j->path)) || +- (candidate_item && path_startswith(j->path, candidate_item->path) && (fnmatch(i->path, j->path, FNM_PATHNAME | FNM_PERIOD) == 0))) ++ if (candidate_item ++ ? (path_startswith(j->path, candidate_item->path) && fnmatch(i->path, j->path, FNM_PATHNAME | FNM_PERIOD) == 0) ++ : path_startswith(i->path, j->path) != NULL) + candidate_item = j; + } + diff --git a/0731-TEST-22-TMPFILES-add-reproducer-for-bug-with-X.patch b/0731-TEST-22-TMPFILES-add-reproducer-for-bug-with-X.patch new file mode 100644 index 0000000000000000000000000000000000000000..8234fed5aa0d79ab1679f1bdc3cd10ff12c3beb6 --- /dev/null +++ b/0731-TEST-22-TMPFILES-add-reproducer-for-bug-with-X.patch @@ -0,0 +1,160 @@ +From 4871d0807e4add56258633d3c3452b0ee5cc8f99 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Wed, 7 Apr 2021 22:35:19 +0200 +Subject: [PATCH] TEST-22-TMPFILES: add reproducer for bug with X + +(cherry picked from commit 1672be86021b5ae8e80d095409a4fffcba7cbb75) + +Related: #1944468 +--- + test/TEST-22-TMPFILES/test-11.sh | 141 +++++++++++++++++++++++++++++++ + 1 file changed, 141 insertions(+) + create mode 100755 test/TEST-22-TMPFILES/test-11.sh + +diff --git a/test/TEST-22-TMPFILES/test-11.sh b/test/TEST-22-TMPFILES/test-11.sh +new file mode 100755 +index 0000000000..21ef210cd1 +--- /dev/null ++++ b/test/TEST-22-TMPFILES/test-11.sh +@@ -0,0 +1,141 @@ ++#! /bin/bash ++ ++set -e ++set -x ++ ++rm -fr /tmp/x ++mkdir /tmp/x ++ ++# ++# 'x' ++# ++mkdir -p /tmp/x/{1,2} ++touch /tmp/x/1/{x1,x2} /tmp/x/2/{y1,y2} /tmp/x/{z1,z2} ++ ++systemd-tmpfiles --clean - < +Date: Wed, 22 Apr 2020 21:52:22 +0200 +Subject: [PATCH] core: make sure we don't get confused when setting TERM for a + tty fd + +Fixes: #15344 +(cherry picked from commit e8cf09b2a2ad0d48e5493050d54251d5f512d9b6) + +Resolves: #2045307 +--- + src/core/execute.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/src/core/execute.c b/src/core/execute.c +index d528d08830..a104294966 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -1709,12 +1709,13 @@ static int build_environment( + + tty_path = exec_context_tty_path(c); + +- /* If we are forked off PID 1 and we are supposed to operate on /dev/console, then let's try to inherit +- * the $TERM set for PID 1. This is useful for containers so that the $TERM the container manager +- * passes to PID 1 ends up all the way in the console login shown. */ ++ /* If we are forked off PID 1 and we are supposed to operate on /dev/console, then let's try ++ * to inherit the $TERM set for PID 1. This is useful for containers so that the $TERM the ++ * container manager passes to PID 1 ends up all the way in the console login shown. */ + +- if (path_equal(tty_path, "/dev/console") && getppid() == 1) ++ if (path_equal_ptr(tty_path, "/dev/console") && getppid() == 1) + term = getenv("TERM"); ++ + if (!term) + term = default_term_for_tty(tty_path); + diff --git a/0733-hash-funcs-introduce-macro-to-create-typesafe-hash_o.patch b/0733-hash-funcs-introduce-macro-to-create-typesafe-hash_o.patch new file mode 100644 index 0000000000000000000000000000000000000000..15bee3e751bcf6aa3938a92f62e93c4a3ce21ef1 --- /dev/null +++ b/0733-hash-funcs-introduce-macro-to-create-typesafe-hash_o.patch @@ -0,0 +1,37 @@ +From cfa7b3d0a1900b725e5489dfec2c39abb8569c29 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 28 Nov 2018 14:10:04 +0900 +Subject: [PATCH] hash-funcs: introduce macro to create typesafe hash_ops + +(cherry picked from commit d1005d1c0050d3dc3a24c054bac4c4916073cbba) + +Resolves: #2037807 +--- + src/basic/hash-funcs.h | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/src/basic/hash-funcs.h b/src/basic/hash-funcs.h +index 5e5989f021..2ff687e5f9 100644 +--- a/src/basic/hash-funcs.h ++++ b/src/basic/hash-funcs.h +@@ -13,6 +13,20 @@ struct hash_ops { + compare_func_t compare; + }; + ++#define _DEFINE_HASH_OPS(uq, name, type, hash_func, compare_func, scope) \ ++ _unused_ static void (* UNIQ_T(static_hash_wrapper, uq))(const type *, struct siphash *) = hash_func; \ ++ _unused_ static int (* UNIQ_T(static_compare_wrapper, uq))(const type *, const type *) = compare_func; \ ++ scope const struct hash_ops name = { \ ++ .hash = (hash_func_t) hash_func, \ ++ .compare = (compare_func_t) compare_func, \ ++ } ++ ++#define DEFINE_HASH_OPS(name, type, hash_func, compare_func) \ ++ _DEFINE_HASH_OPS(UNIQ, name, type, hash_func, compare_func,) ++ ++#define DEFINE_PRIVATE_HASH_OPS(name, type, hash_func, compare_func) \ ++ _DEFINE_HASH_OPS(UNIQ, name, type, hash_func, compare_func, static) ++ + void string_hash_func(const void *p, struct siphash *state); + int string_compare_func(const void *a, const void *b) _pure_; + extern const struct hash_ops string_hash_ops; diff --git a/0734-hash-func-add-destructors-for-key-and-value.patch b/0734-hash-func-add-destructors-for-key-and-value.patch new file mode 100644 index 0000000000000000000000000000000000000000..c2d90a45eab10db0ca066bac86c4d082c50e98d3 --- /dev/null +++ b/0734-hash-func-add-destructors-for-key-and-value.patch @@ -0,0 +1,369 @@ +From 3bee193141bdf3106732a2c925ffaf5ce48f0ecb Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 27 Nov 2018 22:25:40 +0900 +Subject: [PATCH] hash-func: add destructors for key and value + +If they are set, then they are called in hashmap_clear() or +hashmap_free(). + +(cherry picked from commit 59a5cda7b904cd7ef9853bda15b498bbc0577524) + +Resolves: #2037807 +--- + src/basic/hash-funcs.h | 54 ++++++++++++++++++++++++++--- + src/basic/hashmap.c | 76 +++++++++++------------------------------ + src/basic/hashmap.h | 50 ++++++++++++++++++--------- + src/basic/ordered-set.h | 6 ++-- + src/basic/set.h | 10 +++--- + 5 files changed, 109 insertions(+), 87 deletions(-) + +diff --git a/src/basic/hash-funcs.h b/src/basic/hash-funcs.h +index 2ff687e5f9..2d3125d0f9 100644 +--- a/src/basic/hash-funcs.h ++++ b/src/basic/hash-funcs.h +@@ -1,7 +1,7 @@ + /* SPDX-License-Identifier: LGPL-2.1+ */ + #pragma once + +- ++#include "alloc-util.h" + #include "macro.h" + #include "siphash24.h" + +@@ -11,21 +11,67 @@ typedef int (*compare_func_t)(const void *a, const void *b); + struct hash_ops { + hash_func_t hash; + compare_func_t compare; ++ free_func_t free_key; ++ free_func_t free_value; + }; + +-#define _DEFINE_HASH_OPS(uq, name, type, hash_func, compare_func, scope) \ ++#define _DEFINE_HASH_OPS(uq, name, type, hash_func, compare_func, free_key_func, free_value_func, scope) \ + _unused_ static void (* UNIQ_T(static_hash_wrapper, uq))(const type *, struct siphash *) = hash_func; \ + _unused_ static int (* UNIQ_T(static_compare_wrapper, uq))(const type *, const type *) = compare_func; \ + scope const struct hash_ops name = { \ + .hash = (hash_func_t) hash_func, \ + .compare = (compare_func_t) compare_func, \ ++ .free_key = free_key_func, \ ++ .free_value = free_value_func, \ ++ } ++ ++#define _DEFINE_FREE_FUNC(uq, type, wrapper_name, func) \ ++ /* Type-safe free function */ \ ++ static void UNIQ_T(wrapper_name, uq)(void *a) { \ ++ type *_a = a; \ ++ func(_a); \ + } + ++#define _DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(uq, name, type, hash_func, compare_func, free_func, scope) \ ++ _DEFINE_FREE_FUNC(uq, type, static_free_wrapper, free_func); \ ++ _DEFINE_HASH_OPS(uq, name, type, hash_func, compare_func, \ ++ UNIQ_T(static_free_wrapper, uq), NULL, scope) ++ ++#define _DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(uq, name, type, hash_func, compare_func, type_value, free_func, scope) \ ++ _DEFINE_FREE_FUNC(uq, type_value, static_free_wrapper, free_func); \ ++ _DEFINE_HASH_OPS(uq, name, type, hash_func, compare_func, \ ++ NULL, UNIQ_T(static_free_wrapper, uq), scope) ++ ++#define _DEFINE_HASH_OPS_FULL(uq, name, type, hash_func, compare_func, free_key_func, type_value, free_value_func, scope) \ ++ _DEFINE_FREE_FUNC(uq, type, static_free_key_wrapper, free_key_func); \ ++ _DEFINE_FREE_FUNC(uq, type_value, static_free_value_wrapper, free_value_func); \ ++ _DEFINE_HASH_OPS(uq, name, type, hash_func, compare_func, \ ++ UNIQ_T(static_free_key_wrapper, uq), \ ++ UNIQ_T(static_free_value_wrapper, uq), scope) ++ + #define DEFINE_HASH_OPS(name, type, hash_func, compare_func) \ +- _DEFINE_HASH_OPS(UNIQ, name, type, hash_func, compare_func,) ++ _DEFINE_HASH_OPS(UNIQ, name, type, hash_func, compare_func, NULL, NULL,) + + #define DEFINE_PRIVATE_HASH_OPS(name, type, hash_func, compare_func) \ +- _DEFINE_HASH_OPS(UNIQ, name, type, hash_func, compare_func, static) ++ _DEFINE_HASH_OPS(UNIQ, name, type, hash_func, compare_func, NULL, NULL, static) ++ ++#define DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(name, type, hash_func, compare_func, free_func) \ ++ _DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(UNIQ, name, type, hash_func, compare_func, free_func,) ++ ++#define DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(name, type, hash_func, compare_func, free_func) \ ++ _DEFINE_HASH_OPS_WITH_KEY_DESTRUCTOR(UNIQ, name, type, hash_func, compare_func, free_func, static) ++ ++#define DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(name, type, hash_func, compare_func, value_type, free_func) \ ++ _DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(UNIQ, name, type, hash_func, compare_func, value_type, free_func,) ++ ++#define DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(name, type, hash_func, compare_func, value_type, free_func) \ ++ _DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(UNIQ, name, type, hash_func, compare_func, value_type, free_func, static) ++ ++#define DEFINE_HASH_OPS_FULL(name, type, hash_func, compare_func, free_key_func, value_type, free_value_func) \ ++ _DEFINE_HASH_OPS_FULL(UNIQ, name, type, hash_func, compare_func, free_key_func, value_type, free_value_func,) ++ ++#define DEFINE_PRIVATE_HASH_OPS_FULL(name, type, hash_func, compare_func, free_key_func, value_type, free_value_func) \ ++ _DEFINE_HASH_OPS_FULL(UNIQ, name, type, hash_func, compare_func, free_key_func, value_type, free_value_func, static) + + void string_hash_func(const void *p, struct siphash *state); + int string_compare_func(const void *a, const void *b) _pure_; +diff --git a/src/basic/hashmap.c b/src/basic/hashmap.c +index 69a7d70b04..7c508086f0 100644 +--- a/src/basic/hashmap.c ++++ b/src/basic/hashmap.c +@@ -863,47 +863,38 @@ static void hashmap_free_no_clear(HashmapBase *h) { + free(h); + } + +-HashmapBase *internal_hashmap_free(HashmapBase *h) { +- +- /* Free the hashmap, but nothing in it */ +- ++HashmapBase *internal_hashmap_free(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value) { + if (h) { +- internal_hashmap_clear(h); ++ internal_hashmap_clear(h, default_free_key, default_free_value); + hashmap_free_no_clear(h); + } + + return NULL; + } + +-HashmapBase *internal_hashmap_free_free(HashmapBase *h) { ++void internal_hashmap_clear(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value) { ++ free_func_t free_key, free_value; ++ if (!h) ++ return; + +- /* Free the hashmap and all data objects in it, but not the +- * keys */ ++ free_key = h->hash_ops->free_key ?: default_free_key; ++ free_value = h->hash_ops->free_value ?: default_free_value; + +- if (h) { +- internal_hashmap_clear_free(h); +- hashmap_free_no_clear(h); +- } +- +- return NULL; +-} ++ if (free_key || free_value) { ++ unsigned idx; + +-Hashmap *hashmap_free_free_free(Hashmap *h) { ++ for (idx = skip_free_buckets(h, 0); idx != IDX_NIL; ++ idx = skip_free_buckets(h, idx + 1)) { ++ struct hashmap_base_entry *e = bucket_at(h, idx); + +- /* Free the hashmap and all data and key objects in it */ ++ if (free_key) ++ free_key((void *) e->key); + +- if (h) { +- hashmap_clear_free_free(h); +- hashmap_free_no_clear(HASHMAP_BASE(h)); ++ if (free_value) ++ free_value(entry_value(h, e)); ++ } + } + +- return NULL; +-} +- +-void internal_hashmap_clear(HashmapBase *h) { +- if (!h) +- return; +- + if (h->has_indirect) { + free(h->indirect.storage); + h->has_indirect = false; +@@ -920,35 +911,6 @@ void internal_hashmap_clear(HashmapBase *h) { + base_set_dirty(h); + } + +-void internal_hashmap_clear_free(HashmapBase *h) { +- unsigned idx; +- +- if (!h) +- return; +- +- for (idx = skip_free_buckets(h, 0); idx != IDX_NIL; +- idx = skip_free_buckets(h, idx + 1)) +- free(entry_value(h, bucket_at(h, idx))); +- +- internal_hashmap_clear(h); +-} +- +-void hashmap_clear_free_free(Hashmap *h) { +- unsigned idx; +- +- if (!h) +- return; +- +- for (idx = skip_free_buckets(HASHMAP_BASE(h), 0); idx != IDX_NIL; +- idx = skip_free_buckets(HASHMAP_BASE(h), idx + 1)) { +- struct plain_hashmap_entry *e = plain_bucket_at(h, idx); +- free((void*)e->b.key); +- free(e->value); +- } +- +- internal_hashmap_clear(HASHMAP_BASE(h)); +-} +- + static int resize_buckets(HashmapBase *h, unsigned entries_add); + + /* +@@ -1771,7 +1733,7 @@ HashmapBase *internal_hashmap_copy(HashmapBase *h) { + } + + if (r < 0) { +- internal_hashmap_free(copy); ++ internal_hashmap_free(copy, false, false); + return NULL; + } + +diff --git a/src/basic/hashmap.h b/src/basic/hashmap.h +index 5c70c102d7..9e4772b497 100644 +--- a/src/basic/hashmap.h ++++ b/src/basic/hashmap.h +@@ -23,6 +23,8 @@ + + #define HASH_KEY_SIZE 16 + ++typedef void* (*hashmap_destroy_t)(void *p); ++ + /* The base type for all hashmap and set types. Many functions in the + * implementation take (HashmapBase*) parameters and are run-time polymorphic, + * though the API is not meant to be polymorphic (do not call functions +@@ -88,25 +90,33 @@ OrderedHashmap *internal_ordered_hashmap_new(const struct hash_ops *hash_ops HA + #define hashmap_new(ops) internal_hashmap_new(ops HASHMAP_DEBUG_SRC_ARGS) + #define ordered_hashmap_new(ops) internal_ordered_hashmap_new(ops HASHMAP_DEBUG_SRC_ARGS) + +-HashmapBase *internal_hashmap_free(HashmapBase *h); ++HashmapBase *internal_hashmap_free(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value); + static inline Hashmap *hashmap_free(Hashmap *h) { +- return (void*)internal_hashmap_free(HASHMAP_BASE(h)); ++ return (void*) internal_hashmap_free(HASHMAP_BASE(h), NULL, NULL); + } + static inline OrderedHashmap *ordered_hashmap_free(OrderedHashmap *h) { +- return (void*)internal_hashmap_free(HASHMAP_BASE(h)); ++ return (void*) internal_hashmap_free(HASHMAP_BASE(h), NULL, NULL); + } + +-HashmapBase *internal_hashmap_free_free(HashmapBase *h); + static inline Hashmap *hashmap_free_free(Hashmap *h) { +- return (void*)internal_hashmap_free_free(HASHMAP_BASE(h)); ++ return (void*) internal_hashmap_free(HASHMAP_BASE(h), NULL, free); + } + static inline OrderedHashmap *ordered_hashmap_free_free(OrderedHashmap *h) { +- return (void*)internal_hashmap_free_free(HASHMAP_BASE(h)); ++ return (void*) internal_hashmap_free(HASHMAP_BASE(h), NULL, free); + } + +-Hashmap *hashmap_free_free_free(Hashmap *h); ++static inline Hashmap *hashmap_free_free_key(Hashmap *h) { ++ return (void*) internal_hashmap_free(HASHMAP_BASE(h), free, NULL); ++} ++static inline OrderedHashmap *ordered_hashmap_free_free_key(OrderedHashmap *h) { ++ return (void*) internal_hashmap_free(HASHMAP_BASE(h), free, NULL); ++} ++ ++static inline Hashmap *hashmap_free_free_free(Hashmap *h) { ++ return (void*) internal_hashmap_free(HASHMAP_BASE(h), free, free); ++} + static inline OrderedHashmap *ordered_hashmap_free_free_free(OrderedHashmap *h) { +- return (void*)hashmap_free_free_free(PLAIN_HASHMAP(h)); ++ return (void*) internal_hashmap_free(HASHMAP_BASE(h), free, free); + } + + IteratedCache *iterated_cache_free(IteratedCache *cache); +@@ -259,25 +269,33 @@ static inline bool ordered_hashmap_iterate(OrderedHashmap *h, Iterator *i, void + return internal_hashmap_iterate(HASHMAP_BASE(h), i, value, key); + } + +-void internal_hashmap_clear(HashmapBase *h); ++void internal_hashmap_clear(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value); + static inline void hashmap_clear(Hashmap *h) { +- internal_hashmap_clear(HASHMAP_BASE(h)); ++ internal_hashmap_clear(HASHMAP_BASE(h), NULL, NULL); + } + static inline void ordered_hashmap_clear(OrderedHashmap *h) { +- internal_hashmap_clear(HASHMAP_BASE(h)); ++ internal_hashmap_clear(HASHMAP_BASE(h), NULL, NULL); + } + +-void internal_hashmap_clear_free(HashmapBase *h); + static inline void hashmap_clear_free(Hashmap *h) { +- internal_hashmap_clear_free(HASHMAP_BASE(h)); ++ internal_hashmap_clear(HASHMAP_BASE(h), NULL, free); + } + static inline void ordered_hashmap_clear_free(OrderedHashmap *h) { +- internal_hashmap_clear_free(HASHMAP_BASE(h)); ++ internal_hashmap_clear(HASHMAP_BASE(h), NULL, free); + } + +-void hashmap_clear_free_free(Hashmap *h); ++static inline void hashmap_clear_free_key(Hashmap *h) { ++ internal_hashmap_clear(HASHMAP_BASE(h), free, NULL); ++} ++static inline void ordered_hashmap_clear_free_key(OrderedHashmap *h) { ++ internal_hashmap_clear(HASHMAP_BASE(h), free, NULL); ++} ++ ++static inline void hashmap_clear_free_free(Hashmap *h) { ++ internal_hashmap_clear(HASHMAP_BASE(h), free, free); ++} + static inline void ordered_hashmap_clear_free_free(OrderedHashmap *h) { +- hashmap_clear_free_free(PLAIN_HASHMAP(h)); ++ internal_hashmap_clear(HASHMAP_BASE(h), free, free); + } + + /* +diff --git a/src/basic/ordered-set.h b/src/basic/ordered-set.h +index e7c054d8e4..7cbb71819b 100644 +--- a/src/basic/ordered-set.h ++++ b/src/basic/ordered-set.h +@@ -21,13 +21,11 @@ static inline int ordered_set_ensure_allocated(OrderedSet **s, const struct hash + } + + static inline OrderedSet* ordered_set_free(OrderedSet *s) { +- ordered_hashmap_free((OrderedHashmap*) s); +- return NULL; ++ return (OrderedSet*) ordered_hashmap_free((OrderedHashmap*) s); + } + + static inline OrderedSet* ordered_set_free_free(OrderedSet *s) { +- ordered_hashmap_free_free((OrderedHashmap*) s); +- return NULL; ++ return (OrderedSet*) ordered_hashmap_free_free((OrderedHashmap*) s); + } + + static inline int ordered_set_put(OrderedSet *s, void *p) { +diff --git a/src/basic/set.h b/src/basic/set.h +index 664713810d..8e12670a6e 100644 +--- a/src/basic/set.h ++++ b/src/basic/set.h +@@ -9,13 +9,11 @@ Set *internal_set_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS); + #define set_new(ops) internal_set_new(ops HASHMAP_DEBUG_SRC_ARGS) + + static inline Set *set_free(Set *s) { +- internal_hashmap_free(HASHMAP_BASE(s)); +- return NULL; ++ return (Set*) internal_hashmap_free(HASHMAP_BASE(s), NULL, NULL); + } + + static inline Set *set_free_free(Set *s) { +- internal_hashmap_free_free(HASHMAP_BASE(s)); +- return NULL; ++ return (Set*) internal_hashmap_free(HASHMAP_BASE(s), free, NULL); + } + + /* no set_free_free_free */ +@@ -76,11 +74,11 @@ static inline unsigned set_buckets(Set *s) { + bool set_iterate(Set *s, Iterator *i, void **value); + + static inline void set_clear(Set *s) { +- internal_hashmap_clear(HASHMAP_BASE(s)); ++ internal_hashmap_clear(HASHMAP_BASE(s), NULL, NULL); + } + + static inline void set_clear_free(Set *s) { +- internal_hashmap_clear_free(HASHMAP_BASE(s)); ++ internal_hashmap_clear(HASHMAP_BASE(s), free, NULL); + } + + /* no set_clear_free_free */ diff --git a/0735-util-define-free_func_t.patch b/0735-util-define-free_func_t.patch new file mode 100644 index 0000000000000000000000000000000000000000..c32c6450875ed588379d3d265284306ade4cfcae --- /dev/null +++ b/0735-util-define-free_func_t.patch @@ -0,0 +1,25 @@ +From 8d596fa931a32e517323379dde6a73ee2a72506c Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 27 Nov 2018 16:33:28 +0900 +Subject: [PATCH] util: define free_func_t + +(cherry picked from commit e30f9c972b789152d67ff34fd3bda294d20d1f51) + +Resolves: #2037807 +--- + src/basic/alloc-util.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/basic/alloc-util.h b/src/basic/alloc-util.h +index ebe42889ea..f8294da68f 100644 +--- a/src/basic/alloc-util.h ++++ b/src/basic/alloc-util.h +@@ -8,6 +8,8 @@ + + #include "macro.h" + ++typedef void (*free_func_t)(void *p); ++ + #define new(t, n) ((t*) malloc_multiply(sizeof(t), (n))) + + #define new0(t, n) ((t*) calloc((n), sizeof(t))) diff --git a/0736-hash-funcs-make-basic-hash_ops-typesafe.patch b/0736-hash-funcs-make-basic-hash_ops-typesafe.patch new file mode 100644 index 0000000000000000000000000000000000000000..76d5aee9adec03b8c5f6eb92ab2b7df0253d0e15 --- /dev/null +++ b/0736-hash-funcs-make-basic-hash_ops-typesafe.patch @@ -0,0 +1,145 @@ +From 9d8948b3f8d37c4667a50f57ab2e357b1aeb4019 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 2 Dec 2018 07:46:33 +0100 +Subject: [PATCH] hash-funcs: make basic hash_ops typesafe + +(cherry picked from commit 25073e5012cdb4de13d815197815c33194ff7dc9) + +Resolves: #2037807 +--- + src/basic/hash-funcs.c | 49 +++++++++++------------------------------- + src/basic/hash-funcs.h | 16 +++++++------- + 2 files changed, 21 insertions(+), 44 deletions(-) + +diff --git a/src/basic/hash-funcs.c b/src/basic/hash-funcs.c +index db48437be7..0617536ea5 100644 +--- a/src/basic/hash-funcs.c ++++ b/src/basic/hash-funcs.c +@@ -5,21 +5,13 @@ + #include "hash-funcs.h" + #include "path-util.h" + +-void string_hash_func(const void *p, struct siphash *state) { ++void string_hash_func(const char *p, struct siphash *state) { + siphash24_compress(p, strlen(p) + 1, state); + } + +-int string_compare_func(const void *a, const void *b) { +- return strcmp(a, b); +-} +- +-const struct hash_ops string_hash_ops = { +- .hash = string_hash_func, +- .compare = string_compare_func +-}; ++DEFINE_HASH_OPS(string_hash_ops, char, string_hash_func, string_compare_func); + +-void path_hash_func(const void *p, struct siphash *state) { +- const char *q = p; ++void path_hash_func(const char *q, struct siphash *state) { + size_t n; + + assert(q); +@@ -57,14 +49,11 @@ void path_hash_func(const void *p, struct siphash *state) { + } + } + +-int path_compare_func(const void *a, const void *b) { ++int path_compare_func(const char *a, const char *b) { + return path_compare(a, b); + } + +-const struct hash_ops path_hash_ops = { +- .hash = path_hash_func, +- .compare = path_compare_func +-}; ++DEFINE_HASH_OPS(path_hash_ops, char, path_hash_func, path_compare_func); + + void trivial_hash_func(const void *p, struct siphash *state) { + siphash24_compress(&p, sizeof(p), state); +@@ -79,36 +68,24 @@ const struct hash_ops trivial_hash_ops = { + .compare = trivial_compare_func + }; + +-void uint64_hash_func(const void *p, struct siphash *state) { ++void uint64_hash_func(const uint64_t *p, struct siphash *state) { + siphash24_compress(p, sizeof(uint64_t), state); + } + +-int uint64_compare_func(const void *_a, const void *_b) { +- uint64_t a, b; +- a = *(const uint64_t*) _a; +- b = *(const uint64_t*) _b; +- return a < b ? -1 : (a > b ? 1 : 0); ++int uint64_compare_func(const uint64_t *a, const uint64_t *b) { ++ return CMP(*a, *b); + } + +-const struct hash_ops uint64_hash_ops = { +- .hash = uint64_hash_func, +- .compare = uint64_compare_func +-}; ++DEFINE_HASH_OPS(uint64_hash_ops, uint64_t, uint64_hash_func, uint64_compare_func); + + #if SIZEOF_DEV_T != 8 +-void devt_hash_func(const void *p, struct siphash *state) { ++void devt_hash_func(const dev_t *p, struct siphash *state) { + siphash24_compress(p, sizeof(dev_t), state); + } + +-int devt_compare_func(const void *_a, const void *_b) { +- dev_t a, b; +- a = *(const dev_t*) _a; +- b = *(const dev_t*) _b; +- return a < b ? -1 : (a > b ? 1 : 0); ++int devt_compare_func(const dev_t *a, const dev_t *b) { ++ return CMP(*a, *b); + } + +-const struct hash_ops devt_hash_ops = { +- .hash = devt_hash_func, +- .compare = devt_compare_func +-}; ++DEFINE_HASH_OPS(devt_hash_ops, dev_t, devt_hash_func, devt_compare_func); + #endif +diff --git a/src/basic/hash-funcs.h b/src/basic/hash-funcs.h +index 2d3125d0f9..3d2ae4b55e 100644 +--- a/src/basic/hash-funcs.h ++++ b/src/basic/hash-funcs.h +@@ -73,12 +73,12 @@ struct hash_ops { + #define DEFINE_PRIVATE_HASH_OPS_FULL(name, type, hash_func, compare_func, free_key_func, value_type, free_value_func) \ + _DEFINE_HASH_OPS_FULL(UNIQ, name, type, hash_func, compare_func, free_key_func, value_type, free_value_func, static) + +-void string_hash_func(const void *p, struct siphash *state); +-int string_compare_func(const void *a, const void *b) _pure_; ++void string_hash_func(const char *p, struct siphash *state); ++#define string_compare_func strcmp + extern const struct hash_ops string_hash_ops; + +-void path_hash_func(const void *p, struct siphash *state); +-int path_compare_func(const void *a, const void *b) _pure_; ++void path_hash_func(const char *p, struct siphash *state); ++int path_compare_func(const char *a, const char *b) _pure_; + extern const struct hash_ops path_hash_ops; + + /* This will compare the passed pointers directly, and will not dereference them. This is hence not useful for strings +@@ -89,15 +89,15 @@ extern const struct hash_ops trivial_hash_ops; + + /* 32bit values we can always just embed in the pointer itself, but in order to support 32bit archs we need store 64bit + * values indirectly, since they don't fit in a pointer. */ +-void uint64_hash_func(const void *p, struct siphash *state); +-int uint64_compare_func(const void *a, const void *b) _pure_; ++void uint64_hash_func(const uint64_t *p, struct siphash *state); ++int uint64_compare_func(const uint64_t *a, const uint64_t *b) _pure_; + extern const struct hash_ops uint64_hash_ops; + + /* On some archs dev_t is 32bit, and on others 64bit. And sometimes it's 64bit on 32bit archs, and sometimes 32bit on + * 64bit archs. Yuck! */ + #if SIZEOF_DEV_T != 8 +-void devt_hash_func(const void *p, struct siphash *state) _pure_; +-int devt_compare_func(const void *a, const void *b) _pure_; ++void devt_hash_func(const dev_t *p, struct siphash *state) _pure_; ++int devt_compare_func(const dev_t *a, const dev_t *b) _pure_; + extern const struct hash_ops devt_hash_ops; + #else + #define devt_hash_func uint64_hash_func diff --git a/0737-test-add-tests-for-destructors-of-hashmap-or-set.patch b/0737-test-add-tests-for-destructors-of-hashmap-or-set.patch new file mode 100644 index 0000000000000000000000000000000000000000..b7ecb4210c07596206364003a211c30b837115a4 --- /dev/null +++ b/0737-test-add-tests-for-destructors-of-hashmap-or-set.patch @@ -0,0 +1,105 @@ +From dcb475e97a48cddacab3ab5178fb351c702cdfb8 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 25 Nov 2018 21:54:44 +0900 +Subject: [PATCH] test: add tests for destructors of hashmap or set + +(cherry picked from commit 98233ee5e031cf39f5be73651a1f05c52927116b) + +Resolves: #2037807 +--- + src/test/test-hashmap-plain.c | 38 +++++++++++++++++++++++++++++++++++ + src/test/test-set.c | 19 ++++++++++++++++++ + 2 files changed, 57 insertions(+) + +diff --git a/src/test/test-hashmap-plain.c b/src/test/test-hashmap-plain.c +index b695d4ee35..a34de067fc 100644 +--- a/src/test/test-hashmap-plain.c ++++ b/src/test/test-hashmap-plain.c +@@ -867,6 +867,43 @@ static void test_hashmap_clear_free_free(void) { + + hashmap_clear_free_free(m); + assert_se(hashmap_isempty(m)); ++ ++ assert_se(hashmap_put(m, strdup("key 1"), strdup("value 1")) == 1); ++ assert_se(hashmap_put(m, strdup("key 2"), strdup("value 2")) == 1); ++ assert_se(hashmap_put(m, strdup("key 3"), strdup("value 3")) == 1); ++ ++ hashmap_clear_free_free(m); ++ assert_se(hashmap_isempty(m)); ++} ++ ++DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(test_hash_ops_key, char, string_hash_func, string_compare_func, free); ++DEFINE_PRIVATE_HASH_OPS_FULL(test_hash_ops_full, char, string_hash_func, string_compare_func, free, char, free); ++ ++static void test_hashmap_clear_free_with_destructor(void) { ++ _cleanup_hashmap_free_ Hashmap *m = NULL; ++ ++ log_info("%s", __func__); ++ ++ m = hashmap_new(&test_hash_ops_key); ++ assert_se(m); ++ ++ assert_se(hashmap_put(m, strdup("key 1"), NULL) == 1); ++ assert_se(hashmap_put(m, strdup("key 2"), NULL) == 1); ++ assert_se(hashmap_put(m, strdup("key 3"), NULL) == 1); ++ ++ hashmap_clear_free(m); ++ assert_se(hashmap_isempty(m)); ++ m = hashmap_free(m); ++ ++ m = hashmap_new(&test_hash_ops_full); ++ assert_se(m); ++ ++ assert_se(hashmap_put(m, strdup("key 1"), strdup("value 1")) == 1); ++ assert_se(hashmap_put(m, strdup("key 2"), strdup("value 2")) == 1); ++ assert_se(hashmap_put(m, strdup("key 3"), strdup("value 3")) == 1); ++ ++ hashmap_clear_free(m); ++ assert_se(hashmap_isempty(m)); + } + + static void test_hashmap_reserve(void) { +@@ -924,5 +961,6 @@ void test_hashmap_funcs(void) { + test_hashmap_steal_first_key(); + test_hashmap_steal_first(); + test_hashmap_clear_free_free(); ++ test_hashmap_clear_free_with_destructor(); + test_hashmap_reserve(); + } +diff --git a/src/test/test-set.c b/src/test/test-set.c +index 6307403e4c..340edeb65f 100644 +--- a/src/test/test-set.c ++++ b/src/test/test-set.c +@@ -45,6 +45,24 @@ static void test_set_free_with_destructor(void) { + assert_se(items[3].seen == 0); + } + ++DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(item_hash_ops, void, trivial_hash_func, trivial_compare_func, Item, item_seen); ++ ++static void test_set_free_with_hash_ops(void) { ++ Set *m; ++ struct Item items[4] = {}; ++ unsigned i; ++ ++ assert_se(m = set_new(&item_hash_ops)); ++ for (i = 0; i < ELEMENTSOF(items) - 1; i++) ++ assert_se(set_put(m, items + i) == 1); ++ ++ m = set_free(m); ++ assert_se(items[0].seen == 1); ++ assert_se(items[1].seen == 1); ++ assert_se(items[2].seen == 1); ++ assert_se(items[3].seen == 0); ++} ++ + static void test_set_put(void) { + _cleanup_set_free_ Set *m = NULL; + +@@ -64,6 +82,7 @@ static void test_set_put(void) { + int main(int argc, const char *argv[]) { + test_set_steal_first(); + test_set_free_with_destructor(); ++ test_set_free_with_hash_ops(); + test_set_put(); + + return 0; diff --git a/0738-man-document-the-new-sysctl.d-prefix.patch b/0738-man-document-the-new-sysctl.d-prefix.patch new file mode 100644 index 0000000000000000000000000000000000000000..d80ae9acc1abde1a3e51b7059529935a7c659db9 --- /dev/null +++ b/0738-man-document-the-new-sysctl.d-prefix.patch @@ -0,0 +1,27 @@ +From b1b5f4625bda683871e8120d2c7b4a59b3ad3951 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 26 Jul 2019 09:24:11 +0200 +Subject: [PATCH] man: document the new sysctl.d/ - prefix + +(cherry picked from commit e08be64937293e3aa8adb08048497520d58445c6) + +Related: #2037807 +--- + man/sysctl.d.xml | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/man/sysctl.d.xml b/man/sysctl.d.xml +index 7c8fde0dba..61820f2c4b 100644 +--- a/man/sysctl.d.xml ++++ b/man/sysctl.d.xml +@@ -60,6 +60,10 @@ + /proc/sys/net/ipv4/conf/enp3s0.200/forwarding. + + ++ If a variable assignment is prefixed with a single - character, any attempts to ++ set it that fail will be ignored (though are logged). Moreover, any access permission errors, and ++ attempts to write variables not defined on the local system are ignored (and logged) too. ++ + The settings configured with sysctl.d + files will be applied early on boot. The network + interface-specific options will also be applied individually for diff --git a/0739-sysctl-if-options-are-prefixed-with-ignore-write-err.patch b/0739-sysctl-if-options-are-prefixed-with-ignore-write-err.patch new file mode 100644 index 0000000000000000000000000000000000000000..a71c655509fcd668aba0fdc50b0a374efd110ccc --- /dev/null +++ b/0739-sysctl-if-options-are-prefixed-with-ignore-write-err.patch @@ -0,0 +1,196 @@ +From 516fc73142e803a7a6cbd126c338e1c3c73d6843 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Fri, 21 Jan 2022 12:10:45 +0100 +Subject: [PATCH] sysctl: if options are prefixed with "-" ignore write errors + +(cherry picked from commit dec02d6e1993d420a0a94c7fec294605df55e88e) + +Resolves: #2037807 +--- + src/sysctl/sysctl.c | 115 ++++++++++++++++++++++++++++++-------------- + 1 file changed, 80 insertions(+), 35 deletions(-) + +diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c +index 0151f7dabe..7b0528877c 100644 +--- a/src/sysctl/sysctl.c ++++ b/src/sysctl/sysctl.c +@@ -26,25 +26,71 @@ static char **arg_prefixes = NULL; + static bool arg_cat_config = false; + static bool arg_no_pager = false; + ++typedef struct Option { ++ char *key; ++ char *value; ++ bool ignore_failure; ++} Option; ++ ++static Option *option_free(Option *o) { ++ if (!o) ++ return NULL; ++ ++ free(o->key); ++ free(o->value); ++ ++ return mfree(o); ++} ++ ++DEFINE_TRIVIAL_CLEANUP_FUNC(Option*, option_free); ++DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(option_hash_ops, char, string_hash_func, string_compare_func, Option, option_free); ++ ++static Option *option_new( ++ const char *key, ++ const char *value, ++ bool ignore_failure) { ++ ++ _cleanup_(option_freep) Option *o = NULL; ++ ++ assert(key); ++ assert(value); ++ ++ o = new(Option, 1); ++ if (!o) ++ return NULL; ++ ++ *o = (Option) { ++ .key = strdup(key), ++ .value = strdup(value), ++ .ignore_failure = ignore_failure, ++ }; ++ ++ if (!o->key || !o->value) ++ return NULL; ++ ++ return TAKE_PTR(o); ++} ++ + static int apply_all(OrderedHashmap *sysctl_options) { +- char *property, *value; ++ Option *option; + Iterator i; + int r = 0; + +- ORDERED_HASHMAP_FOREACH_KEY(value, property, sysctl_options, i) { ++ ORDERED_HASHMAP_FOREACH(option, sysctl_options, i) { + int k; + +- k = sysctl_write(property, value); ++ k = sysctl_write(option->key, option->value); + if (k < 0) { +- /* If the sysctl is not available in the kernel or we are running with reduced privileges and +- * cannot write it, then log about the issue at LOG_NOTICE level, and proceed without +- * failing. (EROFS is treated as a permission problem here, since that's how container managers +- * usually protected their sysctls.) In all other cases log an error and make the tool fail. */ +- +- if (IN_SET(k, -EPERM, -EACCES, -EROFS, -ENOENT)) +- log_notice_errno(k, "Couldn't write '%s' to '%s', ignoring: %m", value, property); ++ /* If the sysctl is not available in the kernel or we are running with reduced ++ * privileges and cannot write it, then log about the issue at LOG_NOTICE level, and ++ * proceed without failing. (EROFS is treated as a permission problem here, since ++ * that's how container managers usually protected their sysctls.) In all other cases ++ * log an error and make the tool fail. */ ++ ++ if (IN_SET(k, -EPERM, -EACCES, -EROFS, -ENOENT) || option->ignore_failure) ++ log_notice_errno(k, "Couldn't write '%s' to '%s', ignoring: %m", option->value, option->key); + else { +- log_error_errno(k, "Couldn't write '%s' to '%s': %m", value, property); ++ log_error_errno(k, "Couldn't write '%s' to '%s': %m", option->value, option->key); + if (r == 0) + r = k; + } +@@ -90,9 +136,11 @@ static int parse_file(OrderedHashmap *sysctl_options, const char *path, bool ign + + log_debug("Parsing %s", path); + for (;;) { +- char *p, *value, *new_value, *property, *existing; ++ _cleanup_(option_freep) Option *new_option = NULL; + _cleanup_free_ char *l = NULL; +- void *v; ++ bool ignore_failure; ++ Option *existing; ++ char *p, *value; + int k; + + k = read_line(f, LONG_LINE_MAX, &l); +@@ -122,39 +170,37 @@ static int parse_file(OrderedHashmap *sysctl_options, const char *path, bool ign + *value = 0; + value++; + +- p = sysctl_normalize(strstrip(p)); ++ p = strstrip(p); ++ ignore_failure = p[0] == '-'; ++ if (ignore_failure) ++ p++; ++ ++ p = sysctl_normalize(p); + value = strstrip(value); + + if (!test_prefix(p)) + continue; + +- existing = ordered_hashmap_get2(sysctl_options, p, &v); ++ existing = ordered_hashmap_get(sysctl_options, p); + if (existing) { +- if (streq(value, existing)) ++ if (streq(value, existing->value)) { ++ existing->ignore_failure = existing->ignore_failure || ignore_failure; + continue; ++ } + + log_debug("Overwriting earlier assignment of %s at '%s:%u'.", p, path, c); +- free(ordered_hashmap_remove(sysctl_options, p)); +- free(v); ++ option_free(ordered_hashmap_remove(sysctl_options, p)); + } + +- property = strdup(p); +- if (!property) ++ new_option = option_new(p, value, ignore_failure); ++ if (!new_option) + return log_oom(); + +- new_value = strdup(value); +- if (!new_value) { +- free(property); +- return log_oom(); +- } ++ k = ordered_hashmap_put(sysctl_options, new_option->key, new_option); ++ if (k < 0) ++ return log_error_errno(k, "Failed to add sysctl variable %s to hashmap: %m", p); + +- k = ordered_hashmap_put(sysctl_options, property, new_value); +- if (k < 0) { +- log_error_errno(k, "Failed to add sysctl variable %s to hashmap: %m", property); +- free(property); +- free(new_value); +- return k; +- } ++ TAKE_PTR(new_option); + } + + return r; +@@ -251,7 +297,7 @@ static int parse_argv(int argc, char *argv[]) { + } + + int main(int argc, char *argv[]) { +- OrderedHashmap *sysctl_options = NULL; ++ _cleanup_(ordered_hashmap_freep) OrderedHashmap *sysctl_options = NULL; + int r = 0, k; + + r = parse_argv(argc, argv); +@@ -264,7 +310,7 @@ int main(int argc, char *argv[]) { + + umask(0022); + +- sysctl_options = ordered_hashmap_new(&path_hash_ops); ++ sysctl_options = ordered_hashmap_new(&option_hash_ops); + if (!sysctl_options) { + r = log_oom(); + goto finish; +@@ -311,7 +357,6 @@ int main(int argc, char *argv[]) { + finish: + pager_close(); + +- ordered_hashmap_free_free_free(sysctl_options); + strv_free(arg_prefixes); + + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; diff --git a/0740-sysctl-fix-segfault.patch b/0740-sysctl-fix-segfault.patch new file mode 100644 index 0000000000000000000000000000000000000000..6c5ec3d894222aa7504ced9cbf7b05f93f8baded --- /dev/null +++ b/0740-sysctl-fix-segfault.patch @@ -0,0 +1,27 @@ +From b30c37b500cbe0587656d5092a95fa695772cd0e Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Thu, 6 Feb 2020 19:13:11 +0900 +Subject: [PATCH] sysctl: fix segfault + +Fixes #14801. + +(cherry picked from commit db99904bc8482efe556bb010a8b203a3e60ee37f) + +Resolves: #2037807 +--- + src/sysctl/sysctl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c +index 7b0528877c..4c85d6887f 100644 +--- a/src/sysctl/sysctl.c ++++ b/src/sysctl/sysctl.c +@@ -183,7 +183,7 @@ static int parse_file(OrderedHashmap *sysctl_options, const char *path, bool ign + + existing = ordered_hashmap_get(sysctl_options, p); + if (existing) { +- if (streq(value, existing->value)) { ++ if (streq_ptr(value, existing->value)) { + existing->ignore_failure = existing->ignore_failure || ignore_failure; + continue; + } diff --git a/0741-ci-drop-CentOS-8-CI.patch b/0741-ci-drop-CentOS-8-CI.patch new file mode 100644 index 0000000000000000000000000000000000000000..cce92a887e45a76e76a382600f128f61da6c5c02 --- /dev/null +++ b/0741-ci-drop-CentOS-8-CI.patch @@ -0,0 +1,26 @@ +From 2347478a64329b2777ae0838be51c8b017a84960 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 8 Feb 2022 11:24:20 +0100 +Subject: [PATCH] ci: drop CentOS 8 CI + +since it went EOL and we should use only Stream 8 from now on. + +rhel-only +Related: #2017033 +--- + .github/workflows/unit_tests.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml +index b363118be8..87b162fa71 100644 +--- a/.github/workflows/unit_tests.yml ++++ b/.github/workflows/unit_tests.yml +@@ -10,7 +10,7 @@ jobs: + strategy: + fail-fast: false + matrix: +- image: [centos8, stream8] ++ image: [stream8] + phase: [GCC, GCC_ASAN] + env: + CONT_NAME: "systemd-centos8-ci" diff --git a/0742-test-adapt-to-the-new-capsh-format.patch b/0742-test-adapt-to-the-new-capsh-format.patch new file mode 100644 index 0000000000000000000000000000000000000000..aa43697157669aa490f95bdbc81e9342cd09f223 --- /dev/null +++ b/0742-test-adapt-to-the-new-capsh-format.patch @@ -0,0 +1,108 @@ +From 9070c6d48645b948d996f9c26bc590c07d46ca1f Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Tue, 4 Feb 2020 13:49:01 +0100 +Subject: [PATCH] test: adapt to the new capsh format + +Since libcap v2.29 the format of cap_to_text() has been changed which +makes certain `test-execute` subtest fail. Let's remove the offending +part of the output (dropped capabilities) to make it compatible with +both the old and the new libcap. + +(cherry picked from commit 9569e385036c05c0bf9fbccdbf3d131161398e2e) + +Related: #2017033 +--- + test/test-execute/exec-capabilityboundingset-invert.service | 3 ++- + .../exec-privatedevices-no-capability-mknod.service | 3 ++- + .../exec-privatedevices-no-capability-sys-rawio.service | 3 ++- + .../exec-privatedevices-yes-capability-mknod.service | 3 ++- + .../exec-privatedevices-yes-capability-sys-rawio.service | 3 ++- + .../exec-protectkernelmodules-no-capabilities.service | 3 ++- + .../exec-protectkernelmodules-yes-capabilities.service | 3 ++- + 7 files changed, 14 insertions(+), 7 deletions(-) + +diff --git a/test/test-execute/exec-capabilityboundingset-invert.service b/test/test-execute/exec-capabilityboundingset-invert.service +index 1abe390601..5f37427603 100644 +--- a/test/test-execute/exec-capabilityboundingset-invert.service ++++ b/test/test-execute/exec-capabilityboundingset-invert.service +@@ -2,6 +2,7 @@ + Description=Test for CapabilityBoundingSet + + [Service] +-ExecStart=/bin/sh -x -c '! capsh --print | grep "^Bounding set .*cap_chown"' ++# sed: remove dropped capabilities (cap_xxx-[epi]) from the output ++ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep "^Bounding set .*cap_chown"' + Type=oneshot + CapabilityBoundingSet=~CAP_CHOWN +diff --git a/test/test-execute/exec-privatedevices-no-capability-mknod.service b/test/test-execute/exec-privatedevices-no-capability-mknod.service +index 6d39469da8..4d61d9ffaa 100644 +--- a/test/test-execute/exec-privatedevices-no-capability-mknod.service ++++ b/test/test-execute/exec-privatedevices-no-capability-mknod.service +@@ -3,5 +3,6 @@ Description=Test CAP_MKNOD capability for PrivateDevices=no + + [Service] + PrivateDevices=no +-ExecStart=/bin/sh -x -c 'capsh --print | grep cap_mknod' ++# sed: remove dropped capabilities (cap_xxx-[epi]) from the output ++ExecStart=/bin/sh -x -c 'capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_mknod' + Type=oneshot +diff --git a/test/test-execute/exec-privatedevices-no-capability-sys-rawio.service b/test/test-execute/exec-privatedevices-no-capability-sys-rawio.service +index e7f529c44c..f7f7a16736 100644 +--- a/test/test-execute/exec-privatedevices-no-capability-sys-rawio.service ++++ b/test/test-execute/exec-privatedevices-no-capability-sys-rawio.service +@@ -3,5 +3,6 @@ Description=Test CAP_SYS_RAWIO capability for PrivateDevices=no + + [Service] + PrivateDevices=no +-ExecStart=/bin/sh -x -c 'capsh --print | grep cap_sys_rawio' ++# sed: remove dropped capabilities (cap_xxx-[epi]) from the output ++ExecStart=/bin/sh -x -c 'capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_rawio' + Type=oneshot +diff --git a/test/test-execute/exec-privatedevices-yes-capability-mknod.service b/test/test-execute/exec-privatedevices-yes-capability-mknod.service +index fb1fc2875a..5bcace0845 100644 +--- a/test/test-execute/exec-privatedevices-yes-capability-mknod.service ++++ b/test/test-execute/exec-privatedevices-yes-capability-mknod.service +@@ -3,5 +3,6 @@ Description=Test CAP_MKNOD capability for PrivateDevices=yes + + [Service] + PrivateDevices=yes +-ExecStart=/bin/sh -x -c '! capsh --print | grep cap_mknod' ++# sed: remove dropped capabilities (cap_xxx-[epi]) from the output ++ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_mknod' + Type=oneshot +diff --git a/test/test-execute/exec-privatedevices-yes-capability-sys-rawio.service b/test/test-execute/exec-privatedevices-yes-capability-sys-rawio.service +index cebc493a7a..a246f950c1 100644 +--- a/test/test-execute/exec-privatedevices-yes-capability-sys-rawio.service ++++ b/test/test-execute/exec-privatedevices-yes-capability-sys-rawio.service +@@ -3,5 +3,6 @@ Description=Test CAP_SYS_RAWIO capability for PrivateDevices=yes + + [Service] + PrivateDevices=yes +-ExecStart=/bin/sh -x -c '! capsh --print | grep cap_sys_rawio' ++# sed: remove dropped capabilities (cap_xxx-[epi]) from the output ++ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_rawio' + Type=oneshot +diff --git a/test/test-execute/exec-protectkernelmodules-no-capabilities.service b/test/test-execute/exec-protectkernelmodules-no-capabilities.service +index b2f2cd6b8a..8d7e2b52d4 100644 +--- a/test/test-execute/exec-protectkernelmodules-no-capabilities.service ++++ b/test/test-execute/exec-protectkernelmodules-no-capabilities.service +@@ -3,5 +3,6 @@ Description=Test CAP_SYS_MODULE ProtectKernelModules=no + + [Service] + ProtectKernelModules=no +-ExecStart=/bin/sh -x -c 'capsh --print | grep cap_sys_module' ++# sed: remove dropped capabilities (cap_xxx-[epi]) from the output ++ExecStart=/bin/sh -x -c 'capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_module' + Type=oneshot +diff --git a/test/test-execute/exec-protectkernelmodules-yes-capabilities.service b/test/test-execute/exec-protectkernelmodules-yes-capabilities.service +index 84bf39be56..fe2ae208dd 100644 +--- a/test/test-execute/exec-protectkernelmodules-yes-capabilities.service ++++ b/test/test-execute/exec-protectkernelmodules-yes-capabilities.service +@@ -3,5 +3,6 @@ Description=Test CAP_SYS_MODULE for ProtectKernelModules=yes + + [Service] + ProtectKernelModules=yes +-ExecStart=/bin/sh -x -c '! capsh --print | grep cap_sys_module' ++# sed: remove dropped capabilities (cap_xxx-[epi]) from the output ++ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_module' + Type=oneshot diff --git a/0743-test-ignore-IAB-capabilities-in-test-execute.patch b/0743-test-ignore-IAB-capabilities-in-test-execute.patch new file mode 100644 index 0000000000000000000000000000000000000000..36ebc9396f9de4f93dacb49cb0d38d7a4294c669 --- /dev/null +++ b/0743-test-ignore-IAB-capabilities-in-test-execute.patch @@ -0,0 +1,129 @@ +From 68c487956659bb0bc3e04be4c8f0687d46d23248 Mon Sep 17 00:00:00 2001 +From: Frantisek Sumsal +Date: Mon, 9 Mar 2020 11:00:58 +0100 +Subject: [PATCH] test: ignore IAB capabilities in `test-execute` + +libcap v2.33 introduces a new capability set called IAB[0] which is shown +in the output of `capsh --print` and interferes with the test checks. Let's +drop the IAB set from the output, for now, to mitigate this. + +This could be (and probably should be) replaced in the future by the +newly introduced testing options[1][2] in libcap v2.32, namely: + --has-p=xxx + --has-i=xxx + --has-a=xxx + +but this needs to wait until the respective libcap version gets a wider +adoption. Until then, let's stick with the relatively ugly sed. + +Fixes: #15046 + +[0] https://git.kernel.org/pub/scm/libs/libcap/libcap.git/commit/?id=943b011b5e53624eb9cab4e96c1985326e077cdd +[1] https://git.kernel.org/pub/scm/libs/libcap/libcap.git/commit/?id=588d0439cb6495b03f0ab9f213f0b6b339e7d4b7 +[2] https://git.kernel.org/pub/scm/libs/libcap/libcap.git/commit/?id=e7709bbc1c4712f2ddfc6e6f42892928a8a03782 + +(cherry picked from commit e9cdcbed77971da3cb0b98b3eb91081142c91eb7) + +Related: #2017033 +--- + test/test-execute/exec-capabilityboundingset-invert.service | 4 ++-- + .../exec-privatedevices-no-capability-mknod.service | 4 ++-- + .../exec-privatedevices-no-capability-sys-rawio.service | 4 ++-- + .../exec-privatedevices-yes-capability-mknod.service | 4 ++-- + .../exec-privatedevices-yes-capability-sys-rawio.service | 4 ++-- + .../exec-protectkernelmodules-no-capabilities.service | 4 ++-- + .../exec-protectkernelmodules-yes-capabilities.service | 4 ++-- + 7 files changed, 14 insertions(+), 14 deletions(-) + +diff --git a/test/test-execute/exec-capabilityboundingset-invert.service b/test/test-execute/exec-capabilityboundingset-invert.service +index 5f37427603..4486f6c25d 100644 +--- a/test/test-execute/exec-capabilityboundingset-invert.service ++++ b/test/test-execute/exec-capabilityboundingset-invert.service +@@ -2,7 +2,7 @@ + Description=Test for CapabilityBoundingSet + + [Service] +-# sed: remove dropped capabilities (cap_xxx-[epi]) from the output +-ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep "^Bounding set .*cap_chown"' ++# sed: remove dropped (cap_xxx-[epi]) and IAB capabilities from the output ++ExecStart=/bin/sh -x -c '! capsh --print | sed -re "s/[^ ]+?\-[epi]+//g" -e '/IAB/d' | grep "^Bounding set .*cap_chown"' + Type=oneshot + CapabilityBoundingSet=~CAP_CHOWN +diff --git a/test/test-execute/exec-privatedevices-no-capability-mknod.service b/test/test-execute/exec-privatedevices-no-capability-mknod.service +index 4d61d9ffaa..8f135be0b5 100644 +--- a/test/test-execute/exec-privatedevices-no-capability-mknod.service ++++ b/test/test-execute/exec-privatedevices-no-capability-mknod.service +@@ -3,6 +3,6 @@ Description=Test CAP_MKNOD capability for PrivateDevices=no + + [Service] + PrivateDevices=no +-# sed: remove dropped capabilities (cap_xxx-[epi]) from the output +-ExecStart=/bin/sh -x -c 'capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_mknod' ++# sed: remove dropped (cap_xxx-[epi]) and IAB capabilities from the output ++ExecStart=/bin/sh -x -c 'capsh --print | sed -re "s/[^ ]+?\-[epi]+//g" -e '/IAB/d' | grep cap_mknod' + Type=oneshot +diff --git a/test/test-execute/exec-privatedevices-no-capability-sys-rawio.service b/test/test-execute/exec-privatedevices-no-capability-sys-rawio.service +index f7f7a16736..30ce549254 100644 +--- a/test/test-execute/exec-privatedevices-no-capability-sys-rawio.service ++++ b/test/test-execute/exec-privatedevices-no-capability-sys-rawio.service +@@ -3,6 +3,6 @@ Description=Test CAP_SYS_RAWIO capability for PrivateDevices=no + + [Service] + PrivateDevices=no +-# sed: remove dropped capabilities (cap_xxx-[epi]) from the output +-ExecStart=/bin/sh -x -c 'capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_rawio' ++# sed: remove dropped (cap_xxx-[epi]) and IAB capabilities from the output ++ExecStart=/bin/sh -x -c 'capsh --print | sed -re "s/[^ ]+?\-[epi]+//g" -e '/IAB/d' | grep cap_sys_rawio' + Type=oneshot +diff --git a/test/test-execute/exec-privatedevices-yes-capability-mknod.service b/test/test-execute/exec-privatedevices-yes-capability-mknod.service +index 5bcace0845..b98cfb5c7e 100644 +--- a/test/test-execute/exec-privatedevices-yes-capability-mknod.service ++++ b/test/test-execute/exec-privatedevices-yes-capability-mknod.service +@@ -3,6 +3,6 @@ Description=Test CAP_MKNOD capability for PrivateDevices=yes + + [Service] + PrivateDevices=yes +-# sed: remove dropped capabilities (cap_xxx-[epi]) from the output +-ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_mknod' ++# sed: remove dropped (cap_xxx-[epi]) and IAB capabilities from the output ++ExecStart=/bin/sh -x -c '! capsh --print | sed -re "s/[^ ]+?\-[epi]+//g" -e '/IAB/d' | grep cap_mknod' + Type=oneshot +diff --git a/test/test-execute/exec-privatedevices-yes-capability-sys-rawio.service b/test/test-execute/exec-privatedevices-yes-capability-sys-rawio.service +index a246f950c1..5b0c0700f2 100644 +--- a/test/test-execute/exec-privatedevices-yes-capability-sys-rawio.service ++++ b/test/test-execute/exec-privatedevices-yes-capability-sys-rawio.service +@@ -3,6 +3,6 @@ Description=Test CAP_SYS_RAWIO capability for PrivateDevices=yes + + [Service] + PrivateDevices=yes +-# sed: remove dropped capabilities (cap_xxx-[epi]) from the output +-ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_rawio' ++# sed: remove dropped (cap_xxx-[epi]) and IAB capabilities from the output ++ExecStart=/bin/sh -x -c '! capsh --print | sed -re "s/[^ ]+?\-[epi]+//g" -e '/IAB/d' | grep cap_sys_rawio' + Type=oneshot +diff --git a/test/test-execute/exec-protectkernelmodules-no-capabilities.service b/test/test-execute/exec-protectkernelmodules-no-capabilities.service +index 8d7e2b52d4..1b73656305 100644 +--- a/test/test-execute/exec-protectkernelmodules-no-capabilities.service ++++ b/test/test-execute/exec-protectkernelmodules-no-capabilities.service +@@ -3,6 +3,6 @@ Description=Test CAP_SYS_MODULE ProtectKernelModules=no + + [Service] + ProtectKernelModules=no +-# sed: remove dropped capabilities (cap_xxx-[epi]) from the output +-ExecStart=/bin/sh -x -c 'capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_module' ++# sed: remove dropped (cap_xxx-[epi]) and IAB capabilities from the output ++ExecStart=/bin/sh -x -c 'capsh --print | sed -re "s/[^ ]+?\-[epi]+//g" -e '/IAB/d' | grep cap_sys_module' + Type=oneshot +diff --git a/test/test-execute/exec-protectkernelmodules-yes-capabilities.service b/test/test-execute/exec-protectkernelmodules-yes-capabilities.service +index fe2ae208dd..e43e72733c 100644 +--- a/test/test-execute/exec-protectkernelmodules-yes-capabilities.service ++++ b/test/test-execute/exec-protectkernelmodules-yes-capabilities.service +@@ -3,6 +3,6 @@ Description=Test CAP_SYS_MODULE for ProtectKernelModules=yes + + [Service] + ProtectKernelModules=yes +-# sed: remove dropped capabilities (cap_xxx-[epi]) from the output +-ExecStart=/bin/sh -x -c '! capsh --print | sed -r "s/[^ ]+?\-[epi]+//g" | grep cap_sys_module' ++# sed: remove dropped (cap_xxx-[epi]) and IAB capabilities from the output ++ExecStart=/bin/sh -x -c '! capsh --print | sed -re "s/[^ ]+?\-[epi]+//g" -e '/IAB/d' | grep cap_sys_module' + Type=oneshot diff --git a/0744-acpi-fpdt-mark-structures-as-packed.patch b/0744-acpi-fpdt-mark-structures-as-packed.patch new file mode 100644 index 0000000000000000000000000000000000000000..da3fe566930794c1446a02a89edd12a8dc4db5f6 --- /dev/null +++ b/0744-acpi-fpdt-mark-structures-as-packed.patch @@ -0,0 +1,51 @@ +From 96bc9caf3216b391a1da88b92ca507fa617177f7 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Thu, 23 Apr 2020 08:49:10 +0200 +Subject: [PATCH] acpi-fpdt: mark structures as packed + +Let's make sure the alignment doesn't matter. + +(cherry picked from commit 49490c1d353bc920cbf73f4c71e9c35d2e3eb8b1) + +Related: #2084052 +--- + src/shared/acpi-fpdt.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/shared/acpi-fpdt.c b/src/shared/acpi-fpdt.c +index d565ebd43e..38c464c912 100644 +--- a/src/shared/acpi-fpdt.c ++++ b/src/shared/acpi-fpdt.c +@@ -23,7 +23,7 @@ struct acpi_table_header { + uint32_t oem_revision; + char asl_compiler_id[4]; + uint32_t asl_compiler_revision; +-}; ++} _packed_; + + enum { + ACPI_FPDT_TYPE_BOOT = 0, +@@ -36,12 +36,12 @@ struct acpi_fpdt_header { + uint8_t revision; + uint8_t reserved[4]; + uint64_t ptr; +-}; ++} _packed_; + + struct acpi_fpdt_boot_header { + char signature[4]; + uint32_t length; +-}; ++} _packed_; + + enum { + ACPI_FPDT_S3PERF_RESUME_REC = 0, +@@ -59,7 +59,7 @@ struct acpi_fpdt_boot { + uint64_t startup_start; + uint64_t exit_services_entry; + uint64_t exit_services_exit; +-}; ++} _packed; + + int acpi_get_boot_usec(usec_t *loader_start, usec_t *loader_exit) { + _cleanup_free_ char *buf = NULL; diff --git a/0745-core-slice-make-slice_freezer_action-return-0-if-fre.patch b/0745-core-slice-make-slice_freezer_action-return-0-if-fre.patch new file mode 100644 index 0000000000000000000000000000000000000000..1d1fa6b06c9c21cae45a742f49b3a884fb5824c0 --- /dev/null +++ b/0745-core-slice-make-slice_freezer_action-return-0-if-fre.patch @@ -0,0 +1,46 @@ +From 9e3aefa21a631e7f47a8121097384a8b08ae8502 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Fri, 6 May 2022 14:01:22 +0900 +Subject: [PATCH] core/slice: make slice_freezer_action() return 0 if freezing + state is unchanged + +Fixes #23278. + +(cherry picked from commit d171e72e7afa11b238ba20758384d223b0c76e39) + +Related: #2084052 +--- + src/core/slice.c | 6 +----- + src/core/unit.c | 2 ++ + 2 files changed, 3 insertions(+), 5 deletions(-) + +diff --git a/src/core/slice.c b/src/core/slice.c +index c10e830917..34f3c84bf9 100644 +--- a/src/core/slice.c ++++ b/src/core/slice.c +@@ -395,11 +395,7 @@ static int slice_freezer_action(Unit *s, FreezerAction action) { + return r; + } + +- r = unit_cgroup_freezer_action(s, action); +- if (r < 0) +- return r; +- +- return 1; ++ return unit_cgroup_freezer_action(s, action); + } + + static int slice_freeze(Unit *s) { +diff --git a/src/core/unit.c b/src/core/unit.c +index e2c61ce866..bd79578255 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -5622,6 +5622,8 @@ static int unit_freezer_action(Unit *u, FreezerAction action) { + if (r <= 0) + return r; + ++ assert(IN_SET(u->freezer_state, FREEZER_FREEZING, FREEZER_THAWING)); ++ + return 1; + } + diff --git a/0746-core-unit-fix-use-after-free.patch b/0746-core-unit-fix-use-after-free.patch new file mode 100644 index 0000000000000000000000000000000000000000..ecd57f2da15f7d079350631d7ed3f274c8ba4e04 --- /dev/null +++ b/0746-core-unit-fix-use-after-free.patch @@ -0,0 +1,29 @@ +From 330e0ea2859db6107fae65bce982c0f2e2ababf5 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 9 May 2022 00:56:05 +0900 +Subject: [PATCH] core/unit: fix use-after-free + +Fixes #23312. + +(cherry picked from commit 734582830b58e000a26e18807ea277c18778573c) + +Related: #2084052 +--- + src/core/unit.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index bd79578255..68affa2c0e 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -580,8 +580,8 @@ void unit_free(Unit *u) { + + unit_dequeue_rewatch_pids(u); + +- sd_bus_slot_unref(u->match_bus_slot); +- sd_bus_track_unref(u->bus_track); ++ u->match_bus_slot = sd_bus_slot_unref(u->match_bus_slot); ++ u->bus_track = sd_bus_track_unref(u->bus_track); + u->deserialized_refs = strv_free(u->deserialized_refs); + u->pending_freezer_message = sd_bus_message_unref(u->pending_freezer_message); + diff --git a/0747-sd-bus-fix-reference-counter-to-be-incremented.patch b/0747-sd-bus-fix-reference-counter-to-be-incremented.patch new file mode 100644 index 0000000000000000000000000000000000000000..dde33df3473ee8f32f96df16b7de63d849283549 --- /dev/null +++ b/0747-sd-bus-fix-reference-counter-to-be-incremented.patch @@ -0,0 +1,58 @@ +From d3d0969d7c366d6bb2f66501e61cbcd11a60face Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 17 Apr 2022 07:05:07 +0900 +Subject: [PATCH] sd-bus: fix reference counter to be incremented + +Fixes #23097. + +(cherry picked from commit b21f237d996c8c18991a68e1204f060d07dc4745) + +[msekleta: This commit also contains the hunk from c2d7dd35d2 +(in sd_bus_track_remove_name). I've decided to not backport that commit +fully because of conflicts and because its was made largely irrelevant +by 7f40cb7c86] + +Related: #2084052 +--- + src/libsystemd/sd-bus/bus-track.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-track.c b/src/libsystemd/sd-bus/bus-track.c +index 16bf615f50..b1ec5ecbbb 100644 +--- a/src/libsystemd/sd-bus/bus-track.c ++++ b/src/libsystemd/sd-bus/bus-track.c +@@ -208,12 +208,12 @@ _public_ int sd_bus_track_add_name(sd_bus_track *track, const char *name) { + i = hashmap_get(track->names, name); + if (i) { + if (track->recursive) { +- unsigned k = track->n_ref + 1; ++ unsigned k = i->n_ref + 1; + +- if (k < track->n_ref) /* Check for overflow */ ++ if (k < i->n_ref) /* Check for overflow */ + return -EOVERFLOW; + +- track->n_ref = k; ++ i->n_ref = k; + } + + bus_track_remove_from_queue(track); +@@ -281,14 +281,13 @@ _public_ int sd_bus_track_remove_name(sd_bus_track *track, const char *name) { + i = hashmap_get(track->names, name); + if (!i) + return -EUNATCH; +- if (i->n_ref <= 0) +- return -EUNATCH; +- +- i->n_ref--; + +- if (i->n_ref <= 0) ++ assert(i->n_ref >=1); ++ if (i->n_ref <= 1) + return bus_track_remove_name_fully(track, name); + ++ i->n_ref--; ++ + return 1; + } + diff --git a/0748-sd-bus-do-not-read-unused-value.patch b/0748-sd-bus-do-not-read-unused-value.patch new file mode 100644 index 0000000000000000000000000000000000000000..c3daafcae808e8f254fe8d473110462ab7f9aca9 --- /dev/null +++ b/0748-sd-bus-do-not-read-unused-value.patch @@ -0,0 +1,32 @@ +From 6f8278097070d77e39d15e5f5d11e1c8b83871c2 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 17 Apr 2022 07:25:09 +0900 +Subject: [PATCH] sd-bus: do not read unused value + +(cherry picked from commit 6a7ca27740be4229b4c9f540cd610b205ca5752c) + +Related: #2084052 +--- + src/libsystemd/sd-bus/bus-track.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-track.c b/src/libsystemd/sd-bus/bus-track.c +index b1ec5ecbbb..b9965d9d64 100644 +--- a/src/libsystemd/sd-bus/bus-track.c ++++ b/src/libsystemd/sd-bus/bus-track.c +@@ -182,13 +182,13 @@ _public_ sd_bus_track* sd_bus_track_unref(sd_bus_track *track) { + + static int on_name_owner_changed(sd_bus_message *message, void *userdata, sd_bus_error *error) { + sd_bus_track *track = userdata; +- const char *name, *old, *new; ++ const char *name; + int r; + + assert(message); + assert(track); + +- r = sd_bus_message_read(message, "sss", &name, &old, &new); ++ r = sd_bus_message_read(message, "sss", &name, NULL, NULL); + if (r < 0) + return 0; + diff --git a/0749-sd-bus-do-not-return-negative-errno-when-unknown-nam.patch b/0749-sd-bus-do-not-return-negative-errno-when-unknown-nam.patch new file mode 100644 index 0000000000000000000000000000000000000000..5fb3f8cef5b5140978e39be5c6c39449716ce37a --- /dev/null +++ b/0749-sd-bus-do-not-return-negative-errno-when-unknown-nam.patch @@ -0,0 +1,35 @@ +From 3005733945670cc4a77920bb55e5cdda331cff4d Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Sun, 17 Apr 2022 07:29:24 +0900 +Subject: [PATCH] sd-bus: do not return negative errno when unknown name is + specified + +When 'recursive' is false, then sd_bus_track_remove_name() does not +return negative errno when unknown name is specified. Let's follow the +same pattern for the case that 'recursive' is true. + +(cherry picked from commit 55bfacc6c33eaf3475762e71172b2ef504be5af8) + +Related: #2084052 +--- + src/libsystemd/sd-bus/bus-track.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-track.c b/src/libsystemd/sd-bus/bus-track.c +index b9965d9d64..8893f190a1 100644 +--- a/src/libsystemd/sd-bus/bus-track.c ++++ b/src/libsystemd/sd-bus/bus-track.c +@@ -275,12 +275,9 @@ _public_ int sd_bus_track_remove_name(sd_bus_track *track, const char *name) { + if (!track) /* Treat a NULL track object as an empty track object */ + return 0; + +- if (!track->recursive) +- return bus_track_remove_name_fully(track, name); +- + i = hashmap_get(track->names, name); + if (!i) +- return -EUNATCH; ++ return 0; + + assert(i->n_ref >=1); + if (i->n_ref <= 1) diff --git a/0750-sd-bus-switch-to-a-manual-overflow-check-in-sd_bus_t.patch b/0750-sd-bus-switch-to-a-manual-overflow-check-in-sd_bus_t.patch new file mode 100644 index 0000000000000000000000000000000000000000..a280a406a98812528a854342dc80ca9e93cd0b69 --- /dev/null +++ b/0750-sd-bus-switch-to-a-manual-overflow-check-in-sd_bus_t.patch @@ -0,0 +1,48 @@ +From 78b5b6dbd0bb4e5644e798748d186cca88fc523d Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 20 Apr 2022 22:30:22 +0200 +Subject: [PATCH] sd-bus: switch to a manual overflow check in + sd_bus_track_add_name() + +This is generally used in a directly client controllable way, hence we +should handle ref count overflow gracefully, instead of hitting an +assert(). + +As discussed: + +https://github.com/systemd/systemd/pull/23099#discussion_r854341850 +(cherry picked from commit 7f40cb7c86b0fff3a82096a9499570bad9c19fd2) + +[msekleta: We've never switched to using track_item_ref/unref introduced +in c2d7dd35d2 hence we still had potential undefined behavior related to +overflow check and this commit fixes that.] + +Related: #2084052 +--- + src/libsystemd/sd-bus/bus-track.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-track.c b/src/libsystemd/sd-bus/bus-track.c +index 8893f190a1..b818e93bec 100644 +--- a/src/libsystemd/sd-bus/bus-track.c ++++ b/src/libsystemd/sd-bus/bus-track.c +@@ -208,12 +208,16 @@ _public_ int sd_bus_track_add_name(sd_bus_track *track, const char *name) { + i = hashmap_get(track->names, name); + if (i) { + if (track->recursive) { +- unsigned k = i->n_ref + 1; ++ assert(i->n_ref > 0); + +- if (k < i->n_ref) /* Check for overflow */ ++ /* Manual oveflow check (instead of a DEFINE_TRIVIAL_REF_FUNC() helper or so), so ++ * that we can return a proper error, given this is almost always called in a ++ * directly client controllable way, and thus better should never hit an assertion ++ * here. */ ++ if (i->n_ref >= UINT_MAX) + return -EOVERFLOW; + +- i->n_ref = k; ++ i->n_ref++; + } + + bus_track_remove_from_queue(track); diff --git a/0751-unit-don-t-emit-PropertiesChanged-signal-if-adding-a.patch b/0751-unit-don-t-emit-PropertiesChanged-signal-if-adding-a.patch new file mode 100644 index 0000000000000000000000000000000000000000..3c3679eabdc9ef57e3101e24ef6876d79b580535 --- /dev/null +++ b/0751-unit-don-t-emit-PropertiesChanged-signal-if-adding-a.patch @@ -0,0 +1,62 @@ +From 3dc25568b15bff0c79ae6e136a73ffd18a69f525 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Renaud=20M=C3=A9trich?= +Date: Fri, 2 Oct 2020 17:30:35 +0200 +Subject: [PATCH] unit: don't emit PropertiesChanged signal if adding a + dependency to a unit is a no-op + +(cherry picked from commit 5177cb0a9add4ae568cff6e6f7c2b3c77760c343) + +Resolves: #2091590 +--- + src/core/unit.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index 68affa2c0e..e3e534ea2e 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -2818,6 +2818,9 @@ int unit_add_dependency( + }; + Unit *original_u = u, *original_other = other; + int r; ++ /* Helper to know whether sending a notification is necessary or not: ++ * if the dependency is already there, no need to notify! */ ++ bool noop = true; + + assert(u); + assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX); +@@ -2842,24 +2845,33 @@ int unit_add_dependency( + r = unit_add_dependency_hashmap(u->dependencies + d, other, mask, 0); + if (r < 0) + return r; ++ else if (r > 0) ++ noop = false; + + if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID && inverse_table[d] != d) { + r = unit_add_dependency_hashmap(other->dependencies + inverse_table[d], u, 0, mask); + if (r < 0) + return r; ++ else if (r > 0) ++ noop = false; + } + + if (add_reference) { + r = unit_add_dependency_hashmap(u->dependencies + UNIT_REFERENCES, other, mask, 0); + if (r < 0) + return r; ++ else if (r > 0) ++ noop = false; + + r = unit_add_dependency_hashmap(other->dependencies + UNIT_REFERENCED_BY, u, 0, mask); + if (r < 0) + return r; ++ else if (r > 0) ++ noop = false; + } + +- unit_add_to_dbus_queue(u); ++ if (!noop) ++ unit_add_to_dbus_queue(u); + return 0; + } + diff --git a/0752-core-propagate-triggered-unit-in-more-load-states.patch b/0752-core-propagate-triggered-unit-in-more-load-states.patch new file mode 100644 index 0000000000000000000000000000000000000000..e4e8a2464ac8530755716a9a3892653bf912367b --- /dev/null +++ b/0752-core-propagate-triggered-unit-in-more-load-states.patch @@ -0,0 +1,122 @@ +From 336ec08378b901b0372b726ace8b354ef22dd13d Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 11 Sep 2020 19:49:33 +0200 +Subject: [PATCH] core: propagate triggered unit in more load states + +In 4c2ef3276735ad9f7fccf33f5bdcbe7d8751e7ec we enabled propagating +triggered unit state to the triggering unit for service units in more +load states, so that we don't accidentally stop tracking state +correctly. + +Do the same for our other triggering unit states: automounts, paths, and +timers. + +Also, make this an assertion rather than a simple test. After all it +should never happen that we get called for half-loaded units or units of +the wrong type. The load routines should already have made this +impossible. + +(cherry picked from commit 0377cd2936ae5cac0c9d76a4b58889f121c097c4) + +Related: #2086553 +--- + src/core/automount.c | 4 ++-- + src/core/path.c | 7 +++---- + src/core/socket.c | 4 ++-- + src/core/timer.c | 4 ++-- + src/core/transaction.c | 2 +- + src/core/unit.h | 4 ++++ + 6 files changed, 14 insertions(+), 11 deletions(-) + +diff --git a/src/core/automount.c b/src/core/automount.c +index f212620c8f..c1c513d4a5 100644 +--- a/src/core/automount.c ++++ b/src/core/automount.c +@@ -492,8 +492,8 @@ static void automount_trigger_notify(Unit *u, Unit *other) { + assert(other); + + /* Filter out invocations with bogus state */ +- if (other->load_state != UNIT_LOADED || other->type != UNIT_MOUNT) +- return; ++ assert(UNIT_IS_LOAD_COMPLETE(other->load_state)); ++ assert(other->type == UNIT_MOUNT); + + /* Don't propagate state changes from the mount if we are already down */ + if (!IN_SET(a->state, AUTOMOUNT_WAITING, AUTOMOUNT_RUNNING)) +diff --git a/src/core/path.c b/src/core/path.c +index 58f490589d..a7c2e0b7c1 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -696,11 +696,10 @@ static void path_trigger_notify(Unit *u, Unit *other) { + assert(u); + assert(other); + +- /* Invoked whenever the unit we trigger changes state or gains +- * or loses a job */ ++ /* Invoked whenever the unit we trigger changes state or gains or loses a job */ + +- if (other->load_state != UNIT_LOADED) +- return; ++ /* Filter out invocations with bogus state */ ++ assert(UNIT_IS_LOAD_COMPLETE(other->load_state)); + + if (p->state == PATH_RUNNING && + UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) { +diff --git a/src/core/socket.c b/src/core/socket.c +index 3589300e68..74c1cc70cb 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -3190,8 +3190,8 @@ static void socket_trigger_notify(Unit *u, Unit *other) { + assert(other); + + /* Filter out invocations with bogus state */ +- if (other->load_state != UNIT_LOADED || other->type != UNIT_SERVICE) +- return; ++ assert(UNIT_IS_LOAD_COMPLETE(other->load_state)); ++ assert(other->type == UNIT_SERVICE); + + /* Don't propagate state changes from the service if we are already down */ + if (!IN_SET(s->state, SOCKET_RUNNING, SOCKET_LISTENING)) +diff --git a/src/core/timer.c b/src/core/timer.c +index 684180bf99..990f05fee4 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -745,8 +745,8 @@ static void timer_trigger_notify(Unit *u, Unit *other) { + assert(u); + assert(other); + +- if (other->load_state != UNIT_LOADED) +- return; ++ /* Filter out invocations with bogus state */ ++ assert(UNIT_IS_LOAD_COMPLETE(other->load_state)); + + /* Reenable all timers that depend on unit state */ + LIST_FOREACH(value, v, t->values) +diff --git a/src/core/transaction.c b/src/core/transaction.c +index ee5b39fef4..8196aba927 100644 +--- a/src/core/transaction.c ++++ b/src/core/transaction.c +@@ -915,7 +915,7 @@ int transaction_add_job_and_dependencies( + + /* Safety check that the unit is a valid state, i.e. not in UNIT_STUB or UNIT_MERGED which should only be set + * temporarily. */ +- if (!IN_SET(unit->load_state, UNIT_LOADED, UNIT_ERROR, UNIT_NOT_FOUND, UNIT_BAD_SETTING, UNIT_MASKED)) ++ if (!UNIT_IS_LOAD_COMPLETE(unit->load_state)) + return sd_bus_error_setf(e, BUS_ERROR_LOAD_FAILED, "Unit %s is not loaded properly.", unit->id); + + if (type != JOB_STOP) { +diff --git a/src/core/unit.h b/src/core/unit.h +index 0cd259411f..b8b914711f 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -47,6 +47,10 @@ static inline bool UNIT_IS_INACTIVE_OR_FAILED(UnitActiveState t) { + return IN_SET(t, UNIT_INACTIVE, UNIT_FAILED); + } + ++static inline bool UNIT_IS_LOAD_COMPLETE(UnitLoadState t) { ++ return t >= 0 && t < _UNIT_LOAD_STATE_MAX && t != UNIT_STUB && t != UNIT_MERGED; ++} ++ + /* Stores the 'reason' a dependency was created as a bit mask, i.e. due to which configuration source it came to be. We + * use this so that we can selectively flush out parts of dependencies again. Note that the same dependency might be + * created as a result of multiple "reasons", hence the bitmask. */ diff --git a/0753-core-propagate-unit-start-limit-hit-state-to-trigger.patch b/0753-core-propagate-unit-start-limit-hit-state-to-trigger.patch new file mode 100644 index 0000000000000000000000000000000000000000..b5ba700e1c556507b5db638aafbf48798ac64ece --- /dev/null +++ b/0753-core-propagate-unit-start-limit-hit-state-to-trigger.patch @@ -0,0 +1,68 @@ +From 2ce14fcc879b0a24d29dc5f5d36db80c5c1f2653 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 11 Sep 2020 19:57:09 +0200 +Subject: [PATCH] core: propagate unit start limit hit state to triggering path + unit + +We already do this for socket and automount units, do it for path units +too: if the triggered service keeps hitting the start limit, then fail +the triggering unit too, so that we don#t busy loop forever. + +(Note that this leaves only timer units out in the cold for this kind of +protection, but it shouldn't matter there, as they are naturally +protected against busy loops: they are scheduled by time anyway). + +Fixes: #16669 +(cherry picked from commit 47ab8f73e3468b6e5a48218eacdb830e978d2cfd) + +Related: #2086553 +--- + src/core/path.c | 15 +++++++++++++++ + src/core/path.h | 1 + + 2 files changed, 16 insertions(+) + +diff --git a/src/core/path.c b/src/core/path.c +index a7c2e0b7c1..c2facf0b16 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -701,6 +701,20 @@ static void path_trigger_notify(Unit *u, Unit *other) { + /* Filter out invocations with bogus state */ + assert(UNIT_IS_LOAD_COMPLETE(other->load_state)); + ++ /* Don't propagate state changes from the triggered unit if we are already down */ ++ if (!IN_SET(p->state, PATH_WAITING, PATH_RUNNING)) ++ return; ++ ++ /* Propagate start limit hit state */ ++ if (other->start_limit_hit) { ++ path_enter_dead(p, PATH_FAILURE_UNIT_START_LIMIT_HIT); ++ return; ++ } ++ ++ /* Don't propagate anything if there's still a job queued */ ++ if (other->job) ++ return; ++ + if (p->state == PATH_RUNNING && + UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) { + log_unit_debug(UNIT(p), "Got notified about unit deactivation."); +@@ -752,6 +766,7 @@ static const char* const path_result_table[_PATH_RESULT_MAX] = { + [PATH_SUCCESS] = "success", + [PATH_FAILURE_RESOURCES] = "resources", + [PATH_FAILURE_START_LIMIT_HIT] = "start-limit-hit", ++ [PATH_FAILURE_UNIT_START_LIMIT_HIT] = "unit-start-limit-hit", + }; + + DEFINE_STRING_TABLE_LOOKUP(path_result, PathResult); +diff --git a/src/core/path.h b/src/core/path.h +index 4d4b6236c2..8a69f06c13 100644 +--- a/src/core/path.h ++++ b/src/core/path.h +@@ -45,6 +45,7 @@ typedef enum PathResult { + PATH_SUCCESS, + PATH_FAILURE_RESOURCES, + PATH_FAILURE_START_LIMIT_HIT, ++ PATH_FAILURE_UNIT_START_LIMIT_HIT, + _PATH_RESULT_MAX, + _PATH_RESULT_INVALID = -1 + } PathResult; diff --git a/0754-core-Move-r-variable-declaration-to-start-of-unit_st.patch b/0754-core-Move-r-variable-declaration-to-start-of-unit_st.patch new file mode 100644 index 0000000000000000000000000000000000000000..70960621e7d71e3437da11910a58b118aff488f2 --- /dev/null +++ b/0754-core-Move-r-variable-declaration-to-start-of-unit_st.patch @@ -0,0 +1,31 @@ +From 182d91dbf7f5242dfd390f5145ce342927c3bd50 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Sat, 30 Oct 2021 22:12:06 +0100 +Subject: [PATCH] core: Move 'r' variable declaration to start of unit_start() + +(cherry picked from commit 5f37c1a955e399756c4137d22f7f0f45a619f425) + +Related: #2086553 +--- + src/core/unit.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index e3e534ea2e..4fd9af87b7 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1725,12 +1725,13 @@ static bool unit_verify_deps(Unit *u) { + int unit_start(Unit *u) { + UnitActiveState state; + Unit *following; ++ int r; + + assert(u); + + /* Check our ability to start early so that failure conditions don't cause us to enter a busy loop. */ + if (UNIT_VTABLE(u)->can_start) { +- int r = UNIT_VTABLE(u)->can_start(u); ++ r = UNIT_VTABLE(u)->can_start(u); + if (r < 0) + return r; + } diff --git a/0755-core-Delay-start-rate-limit-check-when-starting-a-un.patch b/0755-core-Delay-start-rate-limit-check-when-starting-a-un.patch new file mode 100644 index 0000000000000000000000000000000000000000..7e0772f91163217ce57f399bb9f24d0a130f5eda --- /dev/null +++ b/0755-core-Delay-start-rate-limit-check-when-starting-a-un.patch @@ -0,0 +1,49 @@ +From aaeac7a33c8cc23cb890d2ad33b0b1542d5a9176 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Tue, 19 Oct 2021 10:45:48 +0100 +Subject: [PATCH] core: Delay start rate limit check when starting a unit + +Doing start rate limit checks before doing condition checks made +condition check failures count towards the start rate limit which +broke existing assumptions (see #21025). Run the rate limit checks +after the condition checks again to restore the previous behaviour. + +(cherry picked from commit ce2146f5256659c7fb53a7d5b9dc551252e27e7e) + +Related: #2086553 +--- + src/core/unit.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/src/core/unit.c b/src/core/unit.c +index 4fd9af87b7..b825e2418c 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1729,13 +1729,6 @@ int unit_start(Unit *u) { + + assert(u); + +- /* Check our ability to start early so that failure conditions don't cause us to enter a busy loop. */ +- if (UNIT_VTABLE(u)->can_start) { +- r = UNIT_VTABLE(u)->can_start(u); +- if (r < 0) +- return r; +- } +- + /* If this is already started, then this will succeed. Note that this will even succeed if this unit + * is not startable by the user. This is relied on to detect when we need to wait for units and when + * waiting is finished. */ +@@ -1790,6 +1783,13 @@ int unit_start(Unit *u) { + return unit_start(following); + } + ++ /* Check start rate limiting early so that failure conditions don't cause us to enter a busy loop. */ ++ if (UNIT_VTABLE(u)->can_start) { ++ r = UNIT_VTABLE(u)->can_start(u); ++ if (r < 0) ++ return r; ++ } ++ + /* If it is stopped, but we cannot start it, then fail */ + if (!UNIT_VTABLE(u)->start) + return -EBADR; diff --git a/0756-core-Propagate-condition-failed-state-to-triggering-.patch b/0756-core-Propagate-condition-failed-state-to-triggering-.patch new file mode 100644 index 0000000000000000000000000000000000000000..2622b69c46da2b227e19fbeaacde20c48b3e3bd9 --- /dev/null +++ b/0756-core-Propagate-condition-failed-state-to-triggering-.patch @@ -0,0 +1,258 @@ +From 42b7498556a3078906834772fec78e2e7303011e Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Mon, 18 Oct 2021 14:17:02 +0200 +Subject: [PATCH] core: Propagate condition failed state to triggering units. + +Alternative to https://github.com/systemd/systemd/pull/20531. + +Whenever a service triggered by another unit fails condition checks, +stop the triggering unit to prevent systemd busy looping trying to +start the triggered unit. + +(cherry picked from commit 12ab94a1e4961a39c32efb60b71866ab588d3ea2) + +Resolves: #2086553 +--- + src/core/automount.c | 14 ++++++++++---- + src/core/automount.h | 1 + + src/core/path.c | 16 +++++++++++----- + src/core/path.h | 1 + + src/core/socket.c | 28 +++++++++++++++++++--------- + src/core/socket.h | 1 + + src/core/timer.c | 12 +++++++++--- + src/core/timer.h | 1 + + src/core/unit.c | 10 ++++++++++ + src/core/unit.h | 2 ++ + 10 files changed, 65 insertions(+), 21 deletions(-) + +diff --git a/src/core/automount.c b/src/core/automount.c +index c1c513d4a5..bac3b2fab7 100644 +--- a/src/core/automount.c ++++ b/src/core/automount.c +@@ -776,6 +776,11 @@ static void automount_enter_running(Automount *a) { + goto fail; + } + ++ if (unit_has_failed_condition_or_assert(trigger)) { ++ automount_enter_dead(a, AUTOMOUNT_FAILURE_MOUNT_CONDITION_FAILED); ++ return; ++ } ++ + r = manager_add_job(UNIT(a)->manager, JOB_START, trigger, JOB_REPLACE, NULL, &error, NULL); + if (r < 0) { + log_unit_warning(UNIT(a), "Failed to queue mount startup job: %s", bus_error_message(&error, r)); +@@ -1087,10 +1092,11 @@ static int automount_can_start(Unit *u) { + } + + static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = { +- [AUTOMOUNT_SUCCESS] = "success", +- [AUTOMOUNT_FAILURE_RESOURCES] = "resources", +- [AUTOMOUNT_FAILURE_START_LIMIT_HIT] = "start-limit-hit", +- [AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT] = "mount-start-limit-hit", ++ [AUTOMOUNT_SUCCESS] = "success", ++ [AUTOMOUNT_FAILURE_RESOURCES] = "resources", ++ [AUTOMOUNT_FAILURE_START_LIMIT_HIT] = "start-limit-hit", ++ [AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT] = "mount-start-limit-hit", ++ [AUTOMOUNT_FAILURE_MOUNT_CONDITION_FAILED] = "mount-condition-failed", + }; + + DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult); +diff --git a/src/core/automount.h b/src/core/automount.h +index 21dd1c0774..a7417d195c 100644 +--- a/src/core/automount.h ++++ b/src/core/automount.h +@@ -10,6 +10,7 @@ typedef enum AutomountResult { + AUTOMOUNT_FAILURE_RESOURCES, + AUTOMOUNT_FAILURE_START_LIMIT_HIT, + AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT, ++ AUTOMOUNT_FAILURE_MOUNT_CONDITION_FAILED, + _AUTOMOUNT_RESULT_MAX, + _AUTOMOUNT_RESULT_INVALID = -1 + } AutomountResult; +diff --git a/src/core/path.c b/src/core/path.c +index c2facf0b16..bf7e1bf3c2 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -453,7 +453,7 @@ static void path_enter_dead(Path *p, PathResult f) { + else + unit_log_failure(UNIT(p), path_result_to_string(p->result)); + +- path_set_state(p, p->result != PATH_SUCCESS ? PATH_FAILED : PATH_DEAD); ++ path_set_state(p, p->result == PATH_SUCCESS ? PATH_DEAD : PATH_FAILED); + } + + static void path_enter_running(Path *p) { +@@ -711,6 +711,11 @@ static void path_trigger_notify(Unit *u, Unit *other) { + return; + } + ++ if (unit_has_failed_condition_or_assert(other)) { ++ path_enter_dead(p, PATH_FAILURE_UNIT_CONDITION_FAILED); ++ return; ++ } ++ + /* Don't propagate anything if there's still a job queued */ + if (other->job) + return; +@@ -763,10 +768,11 @@ static const char* const path_type_table[_PATH_TYPE_MAX] = { + DEFINE_STRING_TABLE_LOOKUP(path_type, PathType); + + static const char* const path_result_table[_PATH_RESULT_MAX] = { +- [PATH_SUCCESS] = "success", +- [PATH_FAILURE_RESOURCES] = "resources", +- [PATH_FAILURE_START_LIMIT_HIT] = "start-limit-hit", +- [PATH_FAILURE_UNIT_START_LIMIT_HIT] = "unit-start-limit-hit", ++ [PATH_SUCCESS] = "success", ++ [PATH_FAILURE_RESOURCES] = "resources", ++ [PATH_FAILURE_START_LIMIT_HIT] = "start-limit-hit", ++ [PATH_FAILURE_UNIT_START_LIMIT_HIT] = "unit-start-limit-hit", ++ [PATH_FAILURE_UNIT_CONDITION_FAILED] = "unit-condition-failed", + }; + + DEFINE_STRING_TABLE_LOOKUP(path_result, PathResult); +diff --git a/src/core/path.h b/src/core/path.h +index 8a69f06c13..0ad6bd12c6 100644 +--- a/src/core/path.h ++++ b/src/core/path.h +@@ -46,6 +46,7 @@ typedef enum PathResult { + PATH_FAILURE_RESOURCES, + PATH_FAILURE_START_LIMIT_HIT, + PATH_FAILURE_UNIT_START_LIMIT_HIT, ++ PATH_FAILURE_UNIT_CONDITION_FAILED, + _PATH_RESULT_MAX, + _PATH_RESULT_INVALID = -1 + } PathResult; +diff --git a/src/core/socket.c b/src/core/socket.c +index 74c1cc70cb..6f9a0f7575 100644 +--- a/src/core/socket.c ++++ b/src/core/socket.c +@@ -2272,6 +2272,15 @@ static void socket_enter_running(Socket *s, int cfd) { + goto refuse; + } + ++ if (UNIT_ISSET(s->service) && cfd < 0) { ++ Unit *service = UNIT_DEREF(s->service); ++ ++ if (unit_has_failed_condition_or_assert(service)) { ++ socket_enter_dead(s, SOCKET_FAILURE_SERVICE_CONDITION_FAILED); ++ return; ++ } ++ } ++ + if (cfd < 0) { + bool pending = false; + Unit *other; +@@ -3287,15 +3296,16 @@ static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = { + DEFINE_STRING_TABLE_LOOKUP(socket_exec_command, SocketExecCommand); + + static const char* const socket_result_table[_SOCKET_RESULT_MAX] = { +- [SOCKET_SUCCESS] = "success", +- [SOCKET_FAILURE_RESOURCES] = "resources", +- [SOCKET_FAILURE_TIMEOUT] = "timeout", +- [SOCKET_FAILURE_EXIT_CODE] = "exit-code", +- [SOCKET_FAILURE_SIGNAL] = "signal", +- [SOCKET_FAILURE_CORE_DUMP] = "core-dump", +- [SOCKET_FAILURE_START_LIMIT_HIT] = "start-limit-hit", +- [SOCKET_FAILURE_TRIGGER_LIMIT_HIT] = "trigger-limit-hit", +- [SOCKET_FAILURE_SERVICE_START_LIMIT_HIT] = "service-start-limit-hit" ++ [SOCKET_SUCCESS] = "success", ++ [SOCKET_FAILURE_RESOURCES] = "resources", ++ [SOCKET_FAILURE_TIMEOUT] = "timeout", ++ [SOCKET_FAILURE_EXIT_CODE] = "exit-code", ++ [SOCKET_FAILURE_SIGNAL] = "signal", ++ [SOCKET_FAILURE_CORE_DUMP] = "core-dump", ++ [SOCKET_FAILURE_START_LIMIT_HIT] = "start-limit-hit", ++ [SOCKET_FAILURE_TRIGGER_LIMIT_HIT] = "trigger-limit-hit", ++ [SOCKET_FAILURE_SERVICE_START_LIMIT_HIT] = "service-start-limit-hit", ++ [SOCKET_FAILURE_SERVICE_CONDITION_FAILED] = "service-condition-failed", + }; + + DEFINE_STRING_TABLE_LOOKUP(socket_result, SocketResult); +diff --git a/src/core/socket.h b/src/core/socket.h +index 2409dbf2a0..b171b94316 100644 +--- a/src/core/socket.h ++++ b/src/core/socket.h +@@ -39,6 +39,7 @@ typedef enum SocketResult { + SOCKET_FAILURE_START_LIMIT_HIT, + SOCKET_FAILURE_TRIGGER_LIMIT_HIT, + SOCKET_FAILURE_SERVICE_START_LIMIT_HIT, ++ SOCKET_FAILURE_SERVICE_CONDITION_FAILED, + _SOCKET_RESULT_MAX, + _SOCKET_RESULT_INVALID = -1 + } SocketResult; +diff --git a/src/core/timer.c b/src/core/timer.c +index 990f05fee4..3c8d89771d 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -567,6 +567,11 @@ static void timer_enter_running(Timer *t) { + return; + } + ++ if (unit_has_failed_condition_or_assert(trigger)) { ++ timer_enter_dead(t, TIMER_FAILURE_UNIT_CONDITION_FAILED); ++ return; ++ } ++ + r = manager_add_job(UNIT(t)->manager, JOB_START, trigger, JOB_REPLACE, NULL, &error, NULL); + if (r < 0) + goto fail; +@@ -850,9 +855,10 @@ static const char* const timer_base_table[_TIMER_BASE_MAX] = { + DEFINE_STRING_TABLE_LOOKUP(timer_base, TimerBase); + + static const char* const timer_result_table[_TIMER_RESULT_MAX] = { +- [TIMER_SUCCESS] = "success", +- [TIMER_FAILURE_RESOURCES] = "resources", +- [TIMER_FAILURE_START_LIMIT_HIT] = "start-limit-hit", ++ [TIMER_SUCCESS] = "success", ++ [TIMER_FAILURE_RESOURCES] = "resources", ++ [TIMER_FAILURE_START_LIMIT_HIT] = "start-limit-hit", ++ [TIMER_FAILURE_UNIT_CONDITION_FAILED] = "unit-condition-failed", + }; + + DEFINE_STRING_TABLE_LOOKUP(timer_result, TimerResult); +diff --git a/src/core/timer.h b/src/core/timer.h +index 833aadb0b8..d23e19d622 100644 +--- a/src/core/timer.h ++++ b/src/core/timer.h +@@ -32,6 +32,7 @@ typedef enum TimerResult { + TIMER_SUCCESS, + TIMER_FAILURE_RESOURCES, + TIMER_FAILURE_START_LIMIT_HIT, ++ TIMER_FAILURE_UNIT_CONDITION_FAILED, + _TIMER_RESULT_MAX, + _TIMER_RESULT_INVALID = -1 + } TimerResult; +diff --git a/src/core/unit.c b/src/core/unit.c +index b825e2418c..c00d30e837 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -5657,6 +5657,16 @@ int unit_thaw_vtable_common(Unit *u) { + return unit_cgroup_freezer_action(u, FREEZER_THAW); + } + ++bool unit_has_failed_condition_or_assert(Unit *u) { ++ if (dual_timestamp_is_set(&u->condition_timestamp) && !u->condition_result) ++ return true; ++ ++ if (dual_timestamp_is_set(&u->assert_timestamp) && !u->assert_result) ++ return true; ++ ++ return false; ++} ++ + static const char* const collect_mode_table[_COLLECT_MODE_MAX] = { + [COLLECT_INACTIVE] = "inactive", + [COLLECT_INACTIVE_OR_FAILED] = "inactive-or-failed", +diff --git a/src/core/unit.h b/src/core/unit.h +index b8b914711f..a924bd2e83 100644 +--- a/src/core/unit.h ++++ b/src/core/unit.h +@@ -847,6 +847,8 @@ void unit_thawed(Unit *u); + int unit_freeze_vtable_common(Unit *u); + int unit_thaw_vtable_common(Unit *u); + ++bool unit_has_failed_condition_or_assert(Unit *u); ++ + /* Macros which append UNIT= or USER_UNIT= to the message */ + + #define log_unit_full(unit, level, error, ...) \ diff --git a/0757-unit-check-for-mount-rate-limiting-before-checking-a.patch b/0757-unit-check-for-mount-rate-limiting-before-checking-a.patch new file mode 100644 index 0000000000000000000000000000000000000000..bd5dddfa0ebb3de18a9c592a00205311539c904b --- /dev/null +++ b/0757-unit-check-for-mount-rate-limiting-before-checking-a.patch @@ -0,0 +1,52 @@ +From 38e66bd347619efaa42118ebec55b43a87fe02c6 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Mon, 30 May 2022 11:55:41 +0200 +Subject: [PATCH] unit: check for mount rate limiting before checking active + state + +Having this check as part of mount_can_start() is too late because +UNIT(u)->can_start() virtual method is called after checking the active +state of unit in unit_start(). + +We need to hold off running mount start jobs when /p/s/mountinfo monitor +is rate limited even when given mount unit is already active. + +Fixes #20329 + +(cherry picked from commit b161bc394b2cc8b271dda9208e310cc2af0cc29d) + +Resolves: #2097336 +--- + src/core/mount.c | 3 --- + src/core/unit.c | 4 ++++ + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/core/mount.c b/src/core/mount.c +index 9547cb9b29..d37b5731f8 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1999,9 +1999,6 @@ static int mount_can_start(Unit *u) { + + assert(m); + +- if (sd_event_source_is_ratelimited(u->manager->mount_event_source)) +- return -EAGAIN; +- + r = unit_test_start_limit(u); + if (r < 0) { + mount_enter_dead(m, MOUNT_FAILURE_START_LIMIT_HIT); +diff --git a/src/core/unit.c b/src/core/unit.c +index c00d30e837..0810bf5a58 100644 +--- a/src/core/unit.c ++++ b/src/core/unit.c +@@ -1729,6 +1729,10 @@ int unit_start(Unit *u) { + + assert(u); + ++ /* Let's hold off running start jobs for mount units when /proc/self/mountinfo monitor is rate limited. */ ++ if (u->type == UNIT_MOUNT && sd_event_source_is_ratelimited(u->manager->mount_event_source)) ++ return -EAGAIN; ++ + /* If this is already started, then this will succeed. Note that this will even succeed if this unit + * is not startable by the user. This is relied on to detect when we need to wait for units and when + * waiting is finished. */ diff --git a/0758-sd-event-don-t-invalidate-source-type-on-disconnect.patch b/0758-sd-event-don-t-invalidate-source-type-on-disconnect.patch new file mode 100644 index 0000000000000000000000000000000000000000..e10016bdba18eeaf2f0e130349e93f0371ad9906 --- /dev/null +++ b/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/0759-test-procfs-util-skip-test-on-certain-errors.patch b/0759-test-procfs-util-skip-test-on-certain-errors.patch new file mode 100644 index 0000000000000000000000000000000000000000..49398db47d24e57b2cfe3fbcc8eb77b848fac632 --- /dev/null +++ b/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/0760-Try-stopping-MD-RAID-devices-in-shutdown-too.patch b/0760-Try-stopping-MD-RAID-devices-in-shutdown-too.patch new file mode 100644 index 0000000000000000000000000000000000000000..2275b8dec99b536d95dbd6822573390b691e93d9 --- /dev/null +++ b/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/0761-shutdown-get-only-active-md-arrays.patch b/0761-shutdown-get-only-active-md-arrays.patch new file mode 100644 index 0000000000000000000000000000000000000000..656bea740773c9f7f93a27ced72c60c6764ac17a --- /dev/null +++ b/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/9000-resolved-pin-stream-while-calling-callbacks-for-it.patch b/9000-resolved-pin-stream-while-calling-callbacks-for-it.patch new file mode 100644 index 0000000000000000000000000000000000000000..9b82d08a134fe33b5c1f2c666a2d86b273236b16 --- /dev/null +++ b/9000-resolved-pin-stream-while-calling-callbacks-for-it.patch @@ -0,0 +1,42 @@ +From a4f08c798cabd5c43f2578a9e2b048fa1ad4a52c Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 4 Dec 2018 22:13:39 +0100 +Subject: [PATCH] resolved: pin stream while calling callbacks for it + +These callbacks might unref the stream, but we still have to access it, +let's hence ref it explicitly. + +Maybe fixes: #10725 + +(cherry picked from commit d973d94dec349fb676fdd844f6fe2ada3538f27c) + +Resolves: #2110548 +--- + src/resolve/resolved-dns-stream.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/resolve/resolved-dns-stream.c b/src/resolve/resolved-dns-stream.c +index 066daef96e..2d0162483a 100644 +--- a/src/resolve/resolved-dns-stream.c ++++ b/src/resolve/resolved-dns-stream.c +@@ -42,6 +42,8 @@ static int dns_stream_update_io(DnsStream *s) { + } + + static int dns_stream_complete(DnsStream *s, int error) { ++ _cleanup_(dns_stream_unrefp) _unused_ DnsStream *ref = dns_stream_ref(s); /* Protect stream while we process it */ ++ + assert(s); + + #if ENABLE_DNS_OVER_TLS +@@ -315,7 +317,7 @@ static int on_stream_timeout(sd_event_source *es, usec_t usec, void *userdata) { + } + + static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *userdata) { +- DnsStream *s = userdata; ++ _cleanup_(dns_stream_unrefp) DnsStream *s = dns_stream_ref(userdata); /* Protect stream while we process it */ + int r; + + assert(s); +-- +2.37.1 + diff --git a/dist b/dist new file mode 100644 index 0000000000000000000000000000000000000000..0ee7539a2292be885eb3a6caf1a4ee4666e5e99f --- /dev/null +++ b/dist @@ -0,0 +1 @@ +an8_6 diff --git a/download b/download new file mode 100644 index 0000000000000000000000000000000000000000..284fce8df2d40d11b3b6b630a0e0c374bfcb6eef --- /dev/null +++ b/download @@ -0,0 +1 @@ +6137e3f50390391cf34521d071a1a078 systemd-239.tar.gz diff --git a/systemd-239.tar.gz b/systemd-239.tar.gz deleted file mode 100644 index 156a7658f66553d2dbebcbe016f6f3c90e4b9765..0000000000000000000000000000000000000000 Binary files a/systemd-239.tar.gz and /dev/null differ diff --git a/systemd.spec b/systemd.spec index 580ef822e9146c657518f3f293fa0aea07c7e328..605bd40bad8008d6c2ae1f91e5ca8b25bd43ce76 100644 --- a/systemd.spec +++ b/systemd.spec @@ -13,7 +13,7 @@ Name: systemd Url: http://www.freedesktop.org/wiki/Software/systemd Version: 239 -Release: 51%{?dist} +Release: 58%{?dist}.7 # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: System and Service Manager @@ -686,29 +686,133 @@ Patch0633: 0633-logind-improve-error-propagation-of-user_check_linge.patch Patch0634: 0634-logind-automatically-GC-lingering-users-for-who-now-.patch Patch0635: 0635-pam_systemd-simplify-code-which-with-we-set-environm.patch Patch0636: 0636-logind-validate-run-user-1000-before-we-set-it.patch -Patch0637: 0637-define-newly-needed-constants.patch -Patch0638: 0638-sd-netlink-support-IFLA_PROP_LIST-and-IFLA_ALT_IFNAM.patch -Patch0639: 0639-sd-netlink-introduce-sd_netlink_message_read_strv.patch -Patch0640: 0640-sd-netlink-introduce-sd_netlink_message_append_strv.patch -Patch0641: 0641-test-add-a-test-for-sd_netlink_message_-append-read-.patch -Patch0642: 0642-util-introduce-ifname_valid_full.patch -Patch0643: 0643-rename-function.patch -Patch0644: 0644-udev-support-AlternativeName-setting-in-.link-file.patch -Patch0645: 0645-network-make-Name-in-Match-support-alternative-names.patch -Patch0646: 0646-udev-extend-the-length-of-ID_NET_NAME_XXX-to-ALTIFNA.patch -Patch0647: 0647-udev-do-not-fail-if-kernel-does-not-support-alternat.patch -Patch0648: 0648-udev-introduce-AlternativeNamesPolicy-setting.patch -Patch0649: 0649-network-set-AlternativeNamesPolicy-in-99-default.lin.patch -Patch0650: 0650-random-util-call-initialize_srand-after-fork.patch -Patch0651: 0651-sd-netlink-introduce-rtnl_resolve_link_alternative_n.patch -Patch0652: 0652-udev-sort-alternative-names.patch -Patch0653: 0653-netlink-introduce-rtnl_get-delete_link_alternative_n.patch -Patch0654: 0654-netlink-do-not-fail-when-new-interface-name-is-alrea.patch -Patch0655: 0655-udev-do-not-try-to-reassign-alternative-names.patch -Patch0656: 0656-Fix-LGTM-build.patch -Patch0657: 0657-sd-hwdb-allow-empty-properties.patch -Patch0658: 0658-Update-hwdb.patch - +Patch0637: 0637-sd-hwdb-allow-empty-properties.patch +Patch0638: 0638-Update-hwdb.patch +Patch0639: 0639-Disable-libpitc-to-fix-CentOS-Stream-CI.patch +Patch0640: 0640-rpm-Fix-typo-in-_environmentdir.patch +Patch0641: 0641-rpm-Add-misspelled-_environmentdir-macro-for-tempora.patch +Patch0642: 0642-rpm-emit-warning-when-macro-with-typo-is-used.patch +Patch0643: 0643-Remove-unintended-additions-to-systemd-analyze-man-p.patch +Patch0644: 0644-Disable-iptables-for-CI.patch +Patch0645: 0645-core-fix-SIGABRT-on-empty-exec-command-argv.patch +Patch0646: 0646-core-service-also-check-path-in-exec-commands.patch +Patch0647: 0647-mount-util-fix-fd_is_mount_point-when-both-the-paren.patch +Patch0648: 0648-basic-add-vmware-hypervisor-detection-from-device-tr.patch +Patch0649: 0649-pam-do-not-require-a-non-expired-password-for-user-..patch +Patch0650: 0650-udev-rules-add-rule-to-create-dev-ptp_hyperv.patch +Patch0651: 0651-process-util-explicitly-handle-processes-lacking-par.patch +Patch0652: 0652-errno-util-add-ERRNO_IS_PRIVILEGE-helper.patch +Patch0653: 0653-procfs-util-fix-confusion-wrt.-quantity-limit-and-ma.patch +Patch0654: 0654-test-process-util-also-add-EROFS-to-the-list-of-good.patch +Patch0655: 0655-journal-refresh-cached-credentials-of-stdout-streams.patch +Patch0656: 0656-util-lib-introduce-HAS_FEATURE_ADDRESS_SANITIZER.patch +Patch0657: 0657-ci-skip-test-execute-on-GH-Actions-under-ASan.patch +Patch0658: 0658-test-seccomp-accept-ENOSYS-from-sysctl-2-too.patch +Patch0659: 0659-test-accept-that-char-device-0-0-can-now-be-created-.patch +Patch0660: 0660-meson-do-not-fail-if-rsync-is-not-installed-with-mes.patch +Patch0661: 0661-pid1-fix-free-of-uninitialized-pointer-in-unit_fail_.patch +Patch0662: 0662-sd-event-take-ref-on-event-loop-object-before-dispat.patch +Patch0663: 0663-core-consider-service-with-no-start-command-immediat.patch +Patch0664: 0664-man-move-description-of-Action-modes-to-FailureActio.patch +Patch0665: 0665-core-define-exit-and-exit-force-actions-for-user-uni.patch +Patch0666: 0666-core-accept-system-mode-emergency-action-specifiers-.patch +Patch0667: 0667-core-allow-services-with-no-commands-but-SuccessActi.patch +Patch0668: 0668-core-limit-service-watchdogs-no-to-actual-watchdog-c.patch +Patch0669: 0669-units-use-SuccessAction-exit-force-in-systemd-exit.s.patch +Patch0670: 0670-units-use-SuccessAction-reboot-force-in-systemd-rebo.patch +Patch0671: 0671-units-use-SuccessAction-poweroff-force-in-systemd-po.patch +Patch0672: 0672-units-allow-and-use-SuccessAction-exit-force-in-syst.patch +Patch0673: 0673-core-do-not-warn-about-mundane-emergency-actions.patch +Patch0674: 0674-core-return-true-from-cg_is_empty-on-ENOENT.patch +Patch0675: 0675-macro-define-HAS_FEATURE_ADDRESS_SANITIZER-also-on-g.patch +Patch0676: 0676-tests-add-helper-function-to-autodetect-CI-environme.patch +Patch0677: 0677-strv-rework-FOREACH_STRING-macro.patch +Patch0678: 0678-test-systemctl-use-const-char-instead-of-char.patch +Patch0679: 0679-ci-pass-the-GITHUB_ACTIONS-variable-to-the-CentOS-co.patch +Patch0680: 0680-lgtm-detect-uninitialized-variables-using-the-__clea.patch +Patch0681: 0681-lgtm-replace-the-query-used-for-looking-for-fgets-wi.patch +Patch0682: 0682-lgtm-beef-up-list-of-dangerous-questionnable-API-cal.patch +Patch0683: 0683-lgtm-warn-about-strerror-use.patch +Patch0684: 0684-lgtm-complain-about-accept-people-should-use-accept4.patch +Patch0685: 0685-lgtm-don-t-treat-the-custom-note-as-a-list-of-tags.patch +Patch0686: 0686-lgtm-ignore-certain-cleanup-functions.patch +Patch0687: 0687-lgtm-detect-more-possible-problematic-scenarios.patch +Patch0688: 0688-lgtm-enable-more-and-potentially-useful-queries.patch +Patch0689: 0689-meson-avoid-bogus-meson-warning.patch +Patch0690: 0690-test-make-TEST-47-less-racy.patch +Patch0691: 0691-core-rename-unit_-start_limit-condition-assert-_test.patch +Patch0692: 0692-core-Check-unit-start-rate-limiting-earlier.patch +Patch0693: 0693-sd-event-introduce-callback-invoked-when-event-sourc.patch +Patch0694: 0694-core-rename-generalize-UNIT-u-test_start_limit-hook.patch +Patch0695: 0695-mount-make-mount-units-start-jobs-not-runnable-if-p-.patch +Patch0696: 0696-mount-retrigger-run-queue-after-ratelimit-expired-to.patch +Patch0697: 0697-pid1-add-a-manager_trigger_run_queue-helper.patch +Patch0698: 0698-unit-add-jobs-that-were-skipped-because-of-ratelimit.patch +Patch0699: 0699-Revert-Revert-sysctl-Enable-ping-8-inside-rootless-P.patch +Patch0700: 0700-sysctl-prefix-ping-port-range-setting-with-a-dash.patch +Patch0701: 0701-mount-don-t-propagate-errors-from-mount_setup_unit-f.patch +Patch0702: 0702-udev-net_id-introduce-naming-scheme-for-RHEL-8.5.patch +Patch0703: 0703-udev-net_id-remove-extraneous-bracket.patch +Patch0704: 0704-udev-net_id-introduce-naming-scheme-for-RHEL-8.6.patch +Patch0705: 0705-define-newly-needed-constants.patch +Patch0706: 0706-sd-netlink-support-IFLA_PROP_LIST-and-IFLA_ALT_IFNAM.patch +Patch0707: 0707-sd-netlink-introduce-sd_netlink_message_read_strv.patch +Patch0708: 0708-sd-netlink-introduce-sd_netlink_message_append_strv.patch +Patch0709: 0709-test-add-a-test-for-sd_netlink_message_-append-read-.patch +Patch0710: 0710-util-introduce-ifname_valid_full.patch +Patch0711: 0711-rename-function.patch +Patch0712: 0712-udev-support-AlternativeName-setting-in-.link-file.patch +Patch0713: 0713-network-make-Name-in-Match-support-alternative-names.patch +Patch0714: 0714-udev-extend-the-length-of-ID_NET_NAME_XXX-to-ALTIFNA.patch +Patch0715: 0715-udev-do-not-fail-if-kernel-does-not-support-alternat.patch +Patch0716: 0716-udev-introduce-AlternativeNamesPolicy-setting.patch +Patch0717: 0717-network-set-AlternativeNamesPolicy-in-99-default.lin.patch +Patch0718: 0718-random-util-call-initialize_srand-after-fork.patch +Patch0719: 0719-sd-netlink-introduce-rtnl_resolve_link_alternative_n.patch +Patch0720: 0720-udev-sort-alternative-names.patch +Patch0721: 0721-netlink-introduce-rtnl_get-delete_link_alternative_n.patch +Patch0722: 0722-netlink-do-not-fail-when-new-interface-name-is-alrea.patch +Patch0723: 0723-udev-do-not-try-to-reassign-alternative-names.patch +Patch0724: 0724-Do-not-fail-if-the-same-alt.-name-is-set-again.patch +Patch0725: 0725-mount-do-not-update-exec-deps-on-mountinfo-changes.patch +Patch0726: 0726-core-mount-add-implicit-unit-dependencies-even-if-wh.patch +Patch0727: 0727-core-fix-unfortunate-typo-in-unit_is_unneeded.patch +Patch0728: 0728-core-make-destructive-transaction-error-a-bit-more-u.patch +Patch0729: 0729-tmpfiles-use-a-entry-in-hashmap-as-ItemArray-in-read.patch +Patch0730: 0730-tmpfiles-rework-condition-check.patch +Patch0731: 0731-TEST-22-TMPFILES-add-reproducer-for-bug-with-X.patch +Patch0732: 0732-core-make-sure-we-don-t-get-confused-when-setting-TE.patch +Patch0733: 0733-hash-funcs-introduce-macro-to-create-typesafe-hash_o.patch +Patch0734: 0734-hash-func-add-destructors-for-key-and-value.patch +Patch0735: 0735-util-define-free_func_t.patch +Patch0736: 0736-hash-funcs-make-basic-hash_ops-typesafe.patch +Patch0737: 0737-test-add-tests-for-destructors-of-hashmap-or-set.patch +Patch0738: 0738-man-document-the-new-sysctl.d-prefix.patch +Patch0739: 0739-sysctl-if-options-are-prefixed-with-ignore-write-err.patch +Patch0740: 0740-sysctl-fix-segfault.patch +Patch0741: 0741-ci-drop-CentOS-8-CI.patch +Patch0742: 0742-test-adapt-to-the-new-capsh-format.patch +Patch0743: 0743-test-ignore-IAB-capabilities-in-test-execute.patch +Patch0744: 0744-acpi-fpdt-mark-structures-as-packed.patch +Patch0745: 0745-core-slice-make-slice_freezer_action-return-0-if-fre.patch +Patch0746: 0746-core-unit-fix-use-after-free.patch +Patch0747: 0747-sd-bus-fix-reference-counter-to-be-incremented.patch +Patch0748: 0748-sd-bus-do-not-read-unused-value.patch +Patch0749: 0749-sd-bus-do-not-return-negative-errno-when-unknown-nam.patch +Patch0750: 0750-sd-bus-switch-to-a-manual-overflow-check-in-sd_bus_t.patch +Patch0751: 0751-unit-don-t-emit-PropertiesChanged-signal-if-adding-a.patch +Patch0752: 0752-core-propagate-triggered-unit-in-more-load-states.patch +Patch0753: 0753-core-propagate-unit-start-limit-hit-state-to-trigger.patch +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 %ifarch %{ix86} x86_64 aarch64 %global have_gnu_efi 1 @@ -1014,6 +1118,8 @@ mkdir -p %{buildroot}%{system_unit_dir}/dbus.target.wants mkdir -p %{buildroot}%{system_unit_dir}/syslog.target.wants mkdir -p %{buildroot}%{_localstatedir}/run mkdir -p %{buildroot}%{_localstatedir}/log +touch %{buildroot}%{_localstatedir}/log/lastlog +chmod 0664 %{buildroot}%{_localstatedir}/log/lastlog touch %{buildroot}%{_localstatedir}/run/utmp touch %{buildroot}%{_localstatedir}/log/{w,b}tmp @@ -1098,6 +1204,7 @@ python3 %{SOURCE2} %buildroot < - 239-51 -- define newly needed constants (#1850986) -- sd-netlink: support IFLA_PROP_LIST and IFLA_ALT_IFNAME attributes (#1850986) -- sd-netlink: introduce sd_netlink_message_read_strv() (#1850986) -- sd-netlink: introduce sd_netlink_message_append_strv() (#1850986) -- test: add a test for sd_netlink_message_{append,read}_strv() (#1850986) -- util: introduce ifname_valid_full() (#1850986) -- rename function (#1850986) -- udev: support AlternativeName= setting in .link file (#1850986) -- network: make Name= in [Match] support alternative names of interfaces (#1850986) -- udev: extend the length of ID_NET_NAME_XXX= to ALTIFNAMSIZ (#1850986) -- udev: do not fail if kernel does not support alternative names (#1850986) -- udev: introduce AlternativeNamesPolicy= setting (#1850986) -- network: set AlternativeNamesPolicy= in 99-default.link (#1850986) -- random-util: call initialize_srand() after fork() (#1850986) -- sd-netlink: introduce rtnl_resolve_link_alternative_names() (#1850986) -- udev: sort alternative names (#1850986) -- netlink: introduce rtnl_get/delete_link_alternative_names() (#1850986) -- netlink: do not fail when new interface name is already used as an alternative name (#1850986) -- udev: do not try to reassign alternative names (#1850986) -- Fix LGTM build (#1850986) -- sd-hwdb: allow empty properties (#1930568) -- Update hwdb (#1930568) +* 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) + +* Thu Jun 23 2022 systemd maintenance team - 239-58.3 +- unit: check for mount rate limiting before checking active state (#2097336) + +* Thu Jun 09 2022 systemd maintenance team - 239-58.2 +- unit: don't emit PropertiesChanged signal if adding a dependency to a unit is a no-op (#2091590) +- core: propagate triggered unit in more load states (#2086553) +- core: propagate unit start limit hit state to triggering path unit (#2086553) +- core: Move 'r' variable declaration to start of unit_start() (#2086553) +- core: Delay start rate limit check when starting a unit (#2086553) +- core: Propagate condition failed state to triggering units. (#2086553) + +* Wed May 11 2022 systemd maintenance team - 239-58.1 +- acpi-fpdt: mark structures as packed (#2084052) +- core/slice: make slice_freezer_action() return 0 if freezing state is unchanged (#2084052) +- core/unit: fix use-after-free (#2084052) +- sd-bus: fix reference counter to be incremented (#2084052) +- sd-bus: do not read unused value (#2084052) +- sd-bus: do not return negative errno when unknown name is specified (#2084052) +- sd-bus: switch to a manual overflow check in sd_bus_track_add_name() (#2084052) + +* Tue Feb 08 2022 systemd maintenance team - 239-58 +- ci: drop CentOS 8 CI (#2017033) +- test: adapt to the new capsh format (#2017033) +- test: ignore IAB capabilities in `test-execute` (#2017033) + +* Mon Feb 07 2022 systemd maintenance team - 239-57 +- udev/net_id: introduce naming scheme for RHEL-8.5 (#2039797) +- udev/net_id: remove extraneous bracket (#2039797) +- udev/net_id: introduce naming scheme for RHEL-8.6 (#2039797) +- define newly needed constants (#2005008) +- sd-netlink: support IFLA_PROP_LIST and IFLA_ALT_IFNAME attributes (#2005008) +- sd-netlink: introduce sd_netlink_message_read_strv() (#2005008) +- sd-netlink: introduce sd_netlink_message_append_strv() (#2005008) +- test: add a test for sd_netlink_message_{append,read}_strv() (#2005008) +- util: introduce ifname_valid_full() (#2005008) +- rename function (#2005008) +- udev: support AlternativeName= setting in .link file (#2005008) +- network: make Name= in [Match] support alternative names of interfaces (#2005008) +- udev: extend the length of ID_NET_NAME_XXX= to ALTIFNAMSIZ (#2005008) +- udev: do not fail if kernel does not support alternative names (#2005008) +- udev: introduce AlternativeNamesPolicy= setting (#2005008) +- network: set AlternativeNamesPolicy= in 99-default.link (#2005008) +- random-util: call initialize_srand() after fork() (#2005008) +- sd-netlink: introduce rtnl_resolve_link_alternative_names() (#2005008) +- udev: sort alternative names (#2005008) +- netlink: introduce rtnl_get/delete_link_alternative_names() (#2005008) +- netlink: do not fail when new interface name is already used as an alternative name (#2005008) +- udev: do not try to reassign alternative names (#2005008) +- Do not fail if the same alt. name is set again (#2005008) +- mount: do not update exec deps on mountinfo changes (#2008825) +- core/mount: add implicit unit dependencies even if when mount unit is generated from /proc/self/mountinfo (#2008825) +- core: fix unfortunate typo in unit_is_unneeded() (#2040147) +- core: make destructive transaction error a bit more useful (#2040147) +- tmpfiles: use a entry in hashmap as ItemArray in read_config_file() (#1944468) +- tmpfiles: rework condition check (#1944468) +- TEST-22-TMPFILES: add reproducer for bug with X (#1944468) +- core: make sure we don't get confused when setting TERM for a tty fd (#2045307) +- hash-funcs: introduce macro to create typesafe hash_ops (#2037807) +- hash-func: add destructors for key and value (#2037807) +- util: define free_func_t (#2037807) +- hash-funcs: make basic hash_ops typesafe (#2037807) +- test: add tests for destructors of hashmap or set (#2037807) +- man: document the new sysctl.d/ - prefix (#2037807) +- sysctl: if options are prefixed with "-" ignore write errors (#2037807) +- sysctl: fix segfault (#2037807) + +* Tue Jan 25 2022 systemd maintenance team - 239-56 +- Take ghost ownership of /var/log/lastlog (#1798685) + +* Mon Jan 10 2022 systemd maintenance team - 239-55 +- lgtm: detect uninitialized variables using the __cleanup__ attribute (#2017033) +- lgtm: replace the query used for looking for fgets with a more general query (#2017033) +- lgtm: beef up list of dangerous/questionnable API calls not to make (#2017033) +- lgtm: warn about strerror() use (#2017033) +- lgtm: complain about accept() [people should use accept4() instead, due to O_CLOEXEC] (#2017033) +- lgtm: don't treat the custom note as a list of tags (#2017033) +- lgtm: ignore certain cleanup functions (#2017033) +- lgtm: detect more possible problematic scenarios (#2017033) +- lgtm: enable more (and potentially useful) queries (#2017033) +- test: make TEST-47 less racy (#2017033) +- core: rename unit_{start_limit|condition|assert}_test() to unit_test_xyz() (#2036608) +- core: Check unit start rate limiting earlier (#2036608) +- sd-event: introduce callback invoked when event source ratelimit expires (#2036608) +- core: rename/generalize UNIT(u)->test_start_limit() hook (#2036608) +- mount: make mount units start jobs not runnable if /p/s/mountinfo ratelimit is in effect (#2036608) +- mount: retrigger run queue after ratelimit expired to run delayed mount start jobs (#2036608) +- pid1: add a manager_trigger_run_queue() helper (#2036608) +- unit: add jobs that were skipped because of ratelimit back to run_queue (#2036608) +- Revert "Revert "sysctl: Enable ping(8) inside rootless Podman containers"" (#2037807) +- sysctl: prefix ping port range setting with a dash (#2037807) +- mount: don't propagate errors from mount_setup_unit() further up (#2036853) + +* Wed Dec 01 2021 systemd maintenance team - 239-54 +- core: consider service with no start command immediately started (#1860899) +- man: move description of *Action= modes to FailureAction=/SuccessAction= (#1860899) +- core: define "exit" and "exit-force" actions for user units and only accept that (#1860899) +- core: accept system mode emergency action specifiers with a warning (#1860899) +- core: allow services with no commands but SuccessAction set (#1860899) +- core: limit service-watchdogs=no to actual "watchdog" commands (#1860899) +- units: use SuccessAction=exit-force in systemd-exit.service (#1860899) +- units: use SuccessAction=reboot-force in systemd-reboot.service (#1860899) +- units: use SuccessAction=poweroff-force in systemd-poweroff.service (#1860899) +- units: allow and use SuccessAction=exit-force in system systemd-exit.service (#1860899) +- core: do not "warn" about mundane emergency actions (#1860899) +- core: return true from cg_is_empty* on ENOENT (#1860899) +- macro: define HAS_FEATURE_ADDRESS_SANITIZER also on gcc (#2017033) +- tests: add helper function to autodetect CI environments (#2017033) +- strv: rework FOREACH_STRING() macro (#2017033) +- test,systemctl: use "const char*" instead of "char*" (#2017033) +- ci: pass the $GITHUB_ACTIONS variable to the CentOS container (#2017033) + +* Wed Nov 24 2021 systemd maintenance team - 239-53 +- sd-hwdb: allow empty properties (#2005009) +- Update hwdb (#2005009) +- Disable libpitc to fix CentOS Stream CI (#2017033) +- rpm: Fix typo in %_environmentdir (#2018024) +- rpm: Add misspelled %_environmentdir macro for temporary compatibility (#2018024) +- rpm: emit warning when macro with typo is used (#2018024) +- Remove unintended additions to systemd-analyze man page (#2004765) +- core: fix SIGABRT on empty exec command argv (#2020239) +- core/service: also check path in exec commands (#2020239) +- mount-util: fix fd_is_mount_point() when both the parent and directory are network fs (#2015057) +- basic: add vmware hypervisor detection from device-tree (#1959150) +- pam: do not require a non-expired password for user@.service (#1961746) +- udev rules: add rule to create /dev/ptp_hyperv (#1991834) +- process-util: explicitly handle processes lacking parents in get_process_ppid() (#1977569) +- errno-util: add ERRNO_IS_PRIVILEGE() helper (#1977569) +- procfs-util: fix confusion wrt. quantity limit and maximum value (#1977569) +- test-process-util: also add EROFS to the list of "good" errors (#1977569) +- journal: refresh cached credentials of stdout streams (#1931806) +- util-lib: introduce HAS_FEATURE_ADDRESS_SANITIZER (#2017033) +- ci: skip test-execute on GH Actions under ASan (#2017033) +- test-seccomp: accept ENOSYS from sysctl(2) too (#2017033) +- test: accept that char device 0/0 can now be created witout privileges (#2017033) +- meson: do not fail if rsync is not installed with meson 0.57.2 (#2017033) +- pid1: fix free of uninitialized pointer in unit_fail_if_noncanonical() (#1970945) +- sd-event: take ref on event loop object before dispatching event sources (#1970945) * Fri Aug 27 2021 systemd maintenance team - 239-50 - Added option --check-inhibitors for non-tty usage (#1269726)