diff --git a/0920-ci-update-permissions-for-source-git-automation-work.patch b/0920-ci-update-permissions-for-source-git-automation-work.patch new file mode 100644 index 0000000..2b123bb --- /dev/null +++ b/0920-ci-update-permissions-for-source-git-automation-work.patch @@ -0,0 +1,29 @@ +From ab5a221daca2783b73fd286f5410dbec905cabfa Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Fri, 19 May 2023 16:42:03 +0200 +Subject: [PATCH] ci: update permissions for source-git automation workflows + +The new version of `redhat-plumbers-in-action/advanced-commit-linter` requires new permission: `checks: write`. + +https://github.com/redhat-plumbers-in-action/advanced-commit-linter/commit/f1bb35fcdeff83d40eb67b5e7c58baad6be689b2 + +rhel-only + +Related: #2179309 +--- + .github/workflows/source-git-automation.yml | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/.github/workflows/source-git-automation.yml b/.github/workflows/source-git-automation.yml +index 140f21b116..e653e28a7f 100644 +--- a/.github/workflows/source-git-automation.yml ++++ b/.github/workflows/source-git-automation.yml +@@ -33,7 +33,7 @@ jobs: + validated-pr-metadata: ${{ steps.commit-linter.outputs.validated-pr-metadata }} + + permissions: +- statuses: write ++ checks: write + pull-requests: write + + steps: diff --git a/0921-sulogin-fix-control-lost-of-the-current-terminal-whe.patch b/0921-sulogin-fix-control-lost-of-the-current-terminal-whe.patch new file mode 100644 index 0000000..fa60f26 --- /dev/null +++ b/0921-sulogin-fix-control-lost-of-the-current-terminal-whe.patch @@ -0,0 +1,130 @@ +From 30cbb55a8d9fedf07d5c9d792849b723b856cd62 Mon Sep 17 00:00:00 2001 +From: HATAYAMA Daisuke +Date: Sun, 12 Feb 2023 12:15:08 +0000 +Subject: [PATCH] sulogin: fix control lost of the current terminal when + default.target is rescue.target + +When default.target is rescue.target, exiting from the single-user shell +results in lost of the control of the current terminal. This is because the +operation performed to continue to boot is systemctl default but default.target +is now rescue.target and it is already active. Hence, no new process that +controls the current terminal is created. Users need to make hardware reset to +recover the situation. + +This sounds like a bit corner case issue and some might feel configuring +default.target as rescue.target is odd because there are several other ways to +transition to rescue.mode without configuring default.target to rescue.target +such as systemctl rescue or systemd.unit=rescue.target something like +that. However, users unfamiliar with systemd operations tend to come up with +systemctl set-default rescue.target. + +To fix this issue, let's transition to default.target only when default.target +is inactive. Otherwise, invoke the single-user shell again to keep control of +the current terminal for users. + +This new logic depends on whether D-Bus working well. Exiting without any check +of result of systemctl default could lead to again the control lost of the +current terminal. Hence, add checking results of each D-Bus operations +including systemctl default and invoke the single-user shell if they fail. + +(cherry picked from commit 937ca8330d11e406b8ef343bead6f4f6244e39c7) + +Resolves: #2169932 +--- + src/sulogin-shell/sulogin-shell.c | 60 +++++++++++++++++++++++++------ + 1 file changed, 50 insertions(+), 10 deletions(-) + +diff --git a/src/sulogin-shell/sulogin-shell.c b/src/sulogin-shell/sulogin-shell.c +index a1ea2333de..8f14ee11bb 100644 +--- a/src/sulogin-shell/sulogin-shell.c ++++ b/src/sulogin-shell/sulogin-shell.c +@@ -14,6 +14,8 @@ + #include "process-util.h" + #include "sd-bus.h" + #include "signal-util.h" ++#include "special.h" ++#include "unit-def.h" + + static int reload_manager(sd_bus *bus) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; +@@ -43,6 +45,28 @@ static int reload_manager(sd_bus *bus) { + return 0; + } + ++static int default_target_is_inactive(sd_bus *bus) { ++ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; ++ _cleanup_free_ char *path = NULL, *state = NULL; ++ int r; ++ ++ path = unit_dbus_path_from_name(SPECIAL_DEFAULT_TARGET); ++ if (!path) ++ return log_oom(); ++ ++ r = sd_bus_get_property_string(bus, ++ "org.freedesktop.systemd1", ++ path, ++ "org.freedesktop.systemd1.Unit", ++ "ActiveState", ++ &error, ++ &state); ++ if (r < 0) ++ return log_error_errno(r, "Failed to retrieve unit state: %s", bus_error_message(&error, r)); ++ ++ return streq_ptr(state, "inactive"); ++} ++ + static int start_default_target(sd_bus *bus) { + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + int r; +@@ -95,7 +119,6 @@ int main(int argc, char *argv[]) { + NULL, /* --force */ + NULL + }; +- _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; + int r; + + log_set_target(LOG_TARGET_AUTO); +@@ -108,17 +131,34 @@ int main(int argc, char *argv[]) { + /* allows passwordless logins if root account is locked. */ + sulogin_cmdline[1] = "--force"; + +- (void) fork_wait(sulogin_cmdline); ++ for (;;) { ++ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL; ++ ++ (void) fork_wait(sulogin_cmdline); ++ ++ r = bus_connect_system_systemd(&bus); ++ if (r < 0) { ++ log_warning_errno(r, "Failed to get D-Bus connection: %m"); ++ goto fallback; ++ } + +- r = bus_connect_system_systemd(&bus); +- if (r < 0) { +- log_warning_errno(r, "Failed to get D-Bus connection: %m"); +- r = 0; +- } else { +- (void) reload_manager(bus); ++ if (reload_manager(bus) < 0) ++ goto fallback; + +- r = start_default_target(bus); ++ r = default_target_is_inactive(bus); ++ if (r < 0) ++ goto fallback; ++ if (!r) { ++ log_warning(SPECIAL_DEFAULT_TARGET" is not inactive. Please review the "SPECIAL_DEFAULT_TARGET" setting.\n"); ++ goto fallback; ++ } ++ ++ if (start_default_target(bus) >= 0) ++ break; ++ ++ fallback: ++ log_warning("Fallback to the single-user shell.\n"); + } + +- return r >= 0 ? EXIT_SUCCESS : EXIT_FAILURE; ++ return 0; + } diff --git a/0922-parse-util-in-parse_permille-check-negative-earlier.patch b/0922-parse-util-in-parse_permille-check-negative-earlier.patch new file mode 100644 index 0000000..2e1065e --- /dev/null +++ b/0922-parse-util-in-parse_permille-check-negative-earlier.patch @@ -0,0 +1,49 @@ +From cb99c3e54af1ba7c6cf1cd99d61546f5aa9423cb Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 2 Jul 2018 18:50:25 +0200 +Subject: [PATCH] parse-util: in parse_permille() check negative earlier + +If 'v' is negative, it's wrong to add the decimal to it, as we'd +actually need to subtract it in this case. But given that we don't want +to allow negative vaues anyway, simply check earlier whether what we +have parsed so far was negative, and react to that before adding the +decimal to it. + +(cherry picked from commit 8cbc92d5975b603002c3141364a7709a9c66e23a) + +Related: #2178179 +--- + src/basic/parse-util.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/src/basic/parse-util.c b/src/basic/parse-util.c +index 992ea3605b..2ab8e88451 100644 +--- a/src/basic/parse-util.c ++++ b/src/basic/parse-util.c +@@ -728,6 +728,8 @@ int parse_permille_unbounded(const char *p) { + r = safe_atoi(n, &v); + if (r < 0) + return r; ++ if (v < 0) ++ return -ERANGE; + } else { + pc = endswith(p, "%"); + if (!pc) +@@ -748,15 +750,14 @@ int parse_permille_unbounded(const char *p) { + r = safe_atoi(n, &v); + if (r < 0) + return r; ++ if (v < 0) ++ return -ERANGE; + if (v > (INT_MAX - q) / 10) + return -ERANGE; + + v = v * 10 + q; + } + +- if (v < 0) +- return -ERANGE; +- + return v; + } + diff --git a/0923-tree-wide-increase-granularity-of-percent-specificat.patch b/0923-tree-wide-increase-granularity-of-percent-specificat.patch new file mode 100644 index 0000000..5e53d2a --- /dev/null +++ b/0923-tree-wide-increase-granularity-of-percent-specificat.patch @@ -0,0 +1,165 @@ +From 30343fc0ba66dd7a513de736c7708702ec5400be Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 2 Jul 2018 18:52:42 +0200 +Subject: [PATCH] tree-wide: increase granularity of percent specifications all + over the place to permille + +We so far had various placed we'd parse percentages with +parse_percent(). Let's make them use parse_permille() instead, which is +downward compatible (as it also parses percent values), and increases +the granularity a bit. Given that on the wire we usually normalize +relative specifications to something like UINT32_MAX anyway changing +from base-100 to base-1000 calculations can be done easily without +breaking compat. + +This commit doesn't document this change in the man pages. While +allowing more precise specifcations permille is not as commonly +understood as perent I guess, hence let's keep this out of the docs for +now. + +(cherry picked from commit f806dfd34595dac8632ba777250323a4735568dc) + +Resolves: #2178179 +--- + src/core/load-fragment.c | 12 ++++++------ + src/login/logind-user.c | 6 +++--- + src/login/pam_systemd.c | 4 ++-- + src/shared/bus-unit-util.c | 22 ++++++++++++---------- + 4 files changed, 23 insertions(+), 21 deletions(-) + +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index 53de7ff5e9..f6505cf83c 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -2991,13 +2991,13 @@ int config_parse_cpu_quota( + return 0; + } + +- r = parse_percent_unbounded(rvalue); ++ r = parse_permille_unbounded(rvalue); + if (r <= 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Invalid CPU quota '%s', ignoring.", rvalue); + return 0; + } + +- c->cpu_quota_per_sec_usec = ((usec_t) r * USEC_PER_SEC) / 100U; ++ c->cpu_quota_per_sec_usec = ((usec_t) r * USEC_PER_SEC) / 1000U; + return 0; + } + +@@ -3057,7 +3057,7 @@ int config_parse_memory_limit( + + if (!isempty(rvalue) && !streq(rvalue, "infinity")) { + +- r = parse_percent(rvalue); ++ r = parse_permille(rvalue); + if (r < 0) { + r = parse_size(rvalue, 1024, &bytes); + if (r < 0) { +@@ -3065,7 +3065,7 @@ int config_parse_memory_limit( + return 0; + } + } else +- bytes = physical_memory_scale(r, 100U); ++ bytes = physical_memory_scale(r, 1000U); + + if (bytes >= UINT64_MAX || + (bytes <= 0 && !STR_IN_SET(lvalue, "MemorySwapMax", "MemoryLow", "MemoryMin", "DefaultMemoryLow", "DefaultMemoryMin"))) { +@@ -3132,7 +3132,7 @@ int config_parse_tasks_max( + return 0; + } + +- r = parse_percent(rvalue); ++ r = parse_permille(rvalue); + if (r < 0) { + r = safe_atou64(rvalue, &v); + if (r < 0) { +@@ -3140,7 +3140,7 @@ int config_parse_tasks_max( + return 0; + } + } else +- v = system_tasks_max_scale(r, 100U); ++ v = system_tasks_max_scale(r, 1000U); + + if (v <= 0 || v >= UINT64_MAX) { + log_syntax(unit, LOG_ERR, filename, line, 0, "Maximum tasks value '%s' out of range, ignoring.", rvalue); +diff --git a/src/login/logind-user.c b/src/login/logind-user.c +index bba3158d1a..00d25d5876 100644 +--- a/src/login/logind-user.c ++++ b/src/login/logind-user.c +@@ -794,9 +794,9 @@ int config_parse_tmpfs_size( + assert(data); + + /* First, try to parse as percentage */ +- r = parse_percent(rvalue); +- if (r > 0 && r < 100) +- *sz = physical_memory_scale(r, 100U); ++ r = parse_permille(rvalue); ++ if (r > 0 && r < 1000) ++ *sz = physical_memory_scale(r, 1000U); + else { + uint64_t k; + +diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c +index c87e980b18..7a551a41bb 100644 +--- a/src/login/pam_systemd.c ++++ b/src/login/pam_systemd.c +@@ -208,9 +208,9 @@ static int append_session_memory_max(pam_handle_t *handle, sd_bus_message *m, co + return r; + } + } else { +- r = parse_percent(limit); ++ r = parse_permille(limit); + if (r >= 0) { +- r = sd_bus_message_append(m, "(sv)", "MemoryMaxScale", "u", (uint32_t) (((uint64_t) UINT32_MAX * r) / 100U)); ++ r = sd_bus_message_append(m, "(sv)", "MemoryMaxScale", "u", (uint32_t) (((uint64_t) r * UINT32_MAX) / 1000U)); + if (r < 0) { + pam_syslog(handle, LOG_ERR, "Failed to append to bus message: %s", strerror(-r)); + return r; +diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c +index c475bbafe0..aa4286ab6e 100644 +--- a/src/shared/bus-unit-util.c ++++ b/src/shared/bus-unit-util.c +@@ -440,16 +440,16 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons + return 1; + } + +- r = parse_percent(eq); ++ r = parse_permille(eq); + if (r >= 0) { + char *n; + +- /* When this is a percentage we'll convert this into a relative value in the range +- * 0…UINT32_MAX and pass it in the MemoryLowScale property (and related +- * ones). This way the physical memory size can be determined server-side */ ++ /* When this is a percentage we'll convert this into a relative value in the range 0…UINT32_MAX ++ * and pass it in the MemoryLowScale property (and related ones). This way the physical memory ++ * size can be determined server-side. */ + + n = strjoina(field, "Scale"); +- r = sd_bus_message_append(m, "(sv)", n, "u", (uint32_t) (((uint64_t) UINT32_MAX * r) / 100U)); ++ r = sd_bus_message_append(m, "(sv)", n, "u", (uint32_t) (((uint64_t) r * UINT32_MAX) / 1000U)); + if (r < 0) + return bus_log_create_error(r); + +@@ -467,13 +467,15 @@ static int bus_append_cgroup_property(sd_bus_message *m, const char *field, cons + if (isempty(eq)) + r = sd_bus_message_append(m, "(sv)", "CPUQuotaPerSecUSec", "t", USEC_INFINITY); + else { +- r = parse_percent_unbounded(eq); +- if (r <= 0) { +- log_error_errno(r, "CPU quota '%s' invalid.", eq); +- return -EINVAL; ++ r = parse_permille_unbounded(eq); ++ if (r == 0) { ++ log_error("CPU quota too small."); ++ return -ERANGE; + } ++ if (r < 0) ++ return log_error_errno(r, "CPU quota '%s' invalid.", eq); + +- r = sd_bus_message_append(m, "(sv)", "CPUQuotaPerSecUSec", "t", (usec_t) r * USEC_PER_SEC / 100U); ++ r = sd_bus_message_append(m, "(sv)", "CPUQuotaPerSecUSec", "t", (((uint64_t) r * USEC_PER_SEC) / 1000U)); + } + + if (r < 0) diff --git a/0924-errno-util-introduce-ERRNO_IS_TRANSIENT.patch b/0924-errno-util-introduce-ERRNO_IS_TRANSIENT.patch new file mode 100644 index 0000000..abed63e --- /dev/null +++ b/0924-errno-util-introduce-ERRNO_IS_TRANSIENT.patch @@ -0,0 +1,31 @@ +From 5a1d30b9a775a7bbac55752abdc10ed5383d209f Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 30 Nov 2021 03:39:35 +0900 +Subject: [PATCH] errno-util: introduce ERRNO_IS_TRANSIENT() + +(cherry picked from commit 7aad83580fccee926d903bdb1a2a6af2c40ef0fc) + +Related: #2172846 +--- + src/basic/util.h | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/src/basic/util.h b/src/basic/util.h +index 195f02cf5f..48beb88bac 100644 +--- a/src/basic/util.h ++++ b/src/basic/util.h +@@ -180,6 +180,14 @@ static inline int negative_errno(void) { + return -errno; + } + ++ ++/* For send()/recv() or read()/write(). */ ++static inline bool ERRNO_IS_TRANSIENT(int r) { ++ return IN_SET(abs(r), ++ EAGAIN, ++ EINTR); ++} ++ + /* Two different errors for access problems */ + static inline bool ERRNO_IS_PRIVILEGE(int r) { + return IN_SET(abs(r), diff --git a/0925-tree-wide-use-ERRNO_IS_TRANSIENT.patch b/0925-tree-wide-use-ERRNO_IS_TRANSIENT.patch new file mode 100644 index 0000000..2c0b3b1 --- /dev/null +++ b/0925-tree-wide-use-ERRNO_IS_TRANSIENT.patch @@ -0,0 +1,545 @@ +From da79f303ec02fdb9a1c07e0fe48e0aaf4bd09e1b Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 30 Nov 2021 04:07:24 +0900 +Subject: [PATCH] tree-wide: use ERRNO_IS_TRANSIENT() + +(cherry picked from commit 8add30a03cb19e4a2722fa5a0fc08c277aaf67fd) + +Related: #2172846 +--- + src/basic/barrier.c | 7 ++++--- + src/basic/terminal-util.c | 2 +- + src/core/cgroup.c | 2 +- + src/core/manager.c | 17 ++++++++--------- + src/core/path.c | 2 +- + src/import/importd.c | 2 +- + src/journal/journald-kmsg.c | 2 +- + src/journal/journald-server.c | 2 +- + src/journal/journald-stream.c | 2 +- + src/journal/sd-journal.c | 2 +- + src/libsystemd-network/icmp6-util.c | 2 +- + src/libsystemd-network/sd-dhcp-client.c | 4 ++-- + src/libsystemd-network/sd-dhcp-server.c | 2 +- + src/libsystemd-network/sd-dhcp6-client.c | 2 +- + src/libsystemd-network/sd-ipv4acd.c | 2 +- + src/libsystemd-network/sd-lldp.c | 2 +- + src/libsystemd/sd-event/sd-event.c | 6 +++--- + src/libsystemd/sd-netlink/netlink-socket.c | 4 ++-- + src/libsystemd/sd-network/sd-network.c | 2 +- + src/nspawn/nspawn.c | 2 +- + src/resolve/resolved-dns-stream.c | 6 +++--- + src/resolve/resolved-dns-stub.c | 2 +- + src/resolve/resolved-manager.c | 2 +- + src/shared/ask-password-api.c | 6 +++--- + src/socket-proxy/socket-proxyd.c | 4 ++-- + src/time-wait-sync/time-wait-sync.c | 2 +- + .../tty-ask-password-agent.c | 2 +- + src/udev/udevd.c | 2 +- + 28 files changed, 47 insertions(+), 47 deletions(-) + +diff --git a/src/basic/barrier.c b/src/basic/barrier.c +index 587852aac8..d36c6c6f88 100644 +--- a/src/basic/barrier.c ++++ b/src/basic/barrier.c +@@ -13,6 +13,7 @@ + #include "barrier.h" + #include "fd-util.h" + #include "macro.h" ++#include "util.h" + + /** + * Barriers +@@ -181,7 +182,7 @@ static bool barrier_write(Barrier *b, uint64_t buf) { + assert(b->me >= 0); + do { + len = write(b->me, &buf, sizeof(buf)); +- } while (len < 0 && IN_SET(errno, EAGAIN, EINTR)); ++ } while (len < 0 && ERRNO_IS_TRANSIENT(errno)); + + if (len != sizeof(buf)) + goto error; +@@ -223,7 +224,7 @@ static bool barrier_read(Barrier *b, int64_t comp) { + int r; + + r = poll(pfd, 2, -1); +- if (r < 0 && IN_SET(errno, EAGAIN, EINTR)) ++ if (r < 0 && ERRNO_IS_TRANSIENT(errno)) + continue; + else if (r < 0) + goto error; +@@ -233,7 +234,7 @@ static bool barrier_read(Barrier *b, int64_t comp) { + + /* events on @them signal new data for us */ + len = read(b->them, &buf, sizeof(buf)); +- if (len < 0 && IN_SET(errno, EAGAIN, EINTR)) ++ if (len < 0 && ERRNO_IS_TRANSIENT(errno)) + continue; + + if (len != sizeof(buf)) +diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c +index e2bbe8187d..18176cfe17 100644 +--- a/src/basic/terminal-util.c ++++ b/src/basic/terminal-util.c +@@ -460,7 +460,7 @@ int acquire_terminal( + + l = read(notify, &buffer, sizeof(buffer)); + if (l < 0) { +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (ERRNO_IS_TRANSIENT(errno)) + continue; + + return -errno; +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index f89bce3d61..0c8a66edd1 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -2356,7 +2356,7 @@ static int on_cgroup_inotify_event(sd_event_source *s, int fd, uint32_t revents, + + l = read(fd, &buffer, sizeof(buffer)); + if (l < 0) { +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return log_error_errno(errno, "Failed to read control group inotify events: %m"); +diff --git a/src/core/manager.c b/src/core/manager.c +index 4a9f9bfcf9..e09227d5ac 100644 +--- a/src/core/manager.c ++++ b/src/core/manager.c +@@ -2331,7 +2331,7 @@ static int manager_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t + + n = recvmsg(m->notify_fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC|MSG_TRUNC); + if (n < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(n)) + return 0; /* Spurious wakeup, try again */ + + /* If this is any other, real error, then let's stop processing this socket. This of course means we +@@ -2573,19 +2573,18 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t + } + + n = read(m->signal_fd, &sfsi, sizeof(sfsi)); +- if (n != sizeof(sfsi)) { +- if (n >= 0) { +- log_warning("Truncated read from signal fd (%zu bytes), ignoring!", n); +- return 0; +- } +- +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (n < 0) { ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + /* We return an error here, which will kill this handler, + * to avoid a busy loop on read error. */ + return log_error_errno(errno, "Reading from signal fd failed: %m"); + } ++ if (n != sizeof(sfsi)) { ++ log_warning("Truncated read from signal fd (%zu bytes), ignoring!", n); ++ return 0; ++ } + + log_received_signal(sfsi.ssi_signo == SIGCHLD || + (sfsi.ssi_signo == SIGTERM && MANAGER_IS_USER(m)) +@@ -4453,7 +4452,7 @@ int manager_dispatch_user_lookup_fd(sd_event_source *source, int fd, uint32_t re + + l = recv(fd, &buffer, sizeof(buffer), MSG_DONTWAIT); + if (l < 0) { +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return log_error_errno(errno, "Failed to read from user lookup fd: %m"); +diff --git a/src/core/path.c b/src/core/path.c +index b899bde0de..dfa63d5102 100644 +--- a/src/core/path.c ++++ b/src/core/path.c +@@ -152,7 +152,7 @@ int path_spec_fd_event(PathSpec *s, uint32_t revents) { + + l = read(s->inotify_fd, &buffer, sizeof(buffer)); + if (l < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return log_error_errno(errno, "Failed to read inotify event: %m"); +diff --git a/src/import/importd.c b/src/import/importd.c +index 04563fb098..5463bd7146 100644 +--- a/src/import/importd.c ++++ b/src/import/importd.c +@@ -519,7 +519,7 @@ static int manager_on_notify(sd_event_source *s, int fd, uint32_t revents, void + + n = recvmsg(fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); + if (n < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(n)) + return 0; + + return -errno; +diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c +index 726c006ce1..a49cc5c4c5 100644 +--- a/src/journal/journald-kmsg.c ++++ b/src/journal/journald-kmsg.c +@@ -321,7 +321,7 @@ static int server_read_dev_kmsg(Server *s) { + return 0; + } + +- if (IN_SET(errno, EAGAIN, EINTR, EPIPE)) ++ if (ERRNO_IS_TRANSIENT(errno) || errno == EPIPE) + return 0; + + return log_error_errno(errno, "Failed to read from kernel: %m"); +diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c +index 4788ff78bb..1e00e4b4bd 100644 +--- a/src/journal/journald-server.c ++++ b/src/journal/journald-server.c +@@ -1131,7 +1131,7 @@ int server_process_datagram(sd_event_source *es, int fd, uint32_t revents, void + + n = recvmsg(fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); + if (n < 0) { +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (ERRNO_IS_TRANSIENT(n)) + return 0; + + return log_error_errno(errno, "recvmsg() failed: %m"); +diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c +index 5be5b0939c..470d2e2661 100644 +--- a/src/journal/journald-stream.c ++++ b/src/journal/journald-stream.c +@@ -556,7 +556,7 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, + + l = recvmsg(s->fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); + if (l < 0) { +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + log_warning_errno(errno, "Failed to read from stream: %m"); +diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c +index 4c502978de..ca083da161 100644 +--- a/src/journal/sd-journal.c ++++ b/src/journal/sd-journal.c +@@ -2563,7 +2563,7 @@ _public_ int sd_journal_process(sd_journal *j) { + + l = read(j->inotify_fd, &buffer, sizeof(buffer)); + if (l < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return got_something ? determine_change(j) : SD_JOURNAL_NOP; + + return -errno; +diff --git a/src/libsystemd-network/icmp6-util.c b/src/libsystemd-network/icmp6-util.c +index 736df222f0..17d4d1faf2 100644 +--- a/src/libsystemd-network/icmp6-util.c ++++ b/src/libsystemd-network/icmp6-util.c +@@ -175,7 +175,7 @@ int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst, + + len = recvmsg(fd, &msg, MSG_DONTWAIT); + if (len < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return -errno; +diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c +index ff434f8ce7..8a8d806b3f 100644 +--- a/src/libsystemd-network/sd-dhcp-client.c ++++ b/src/libsystemd-network/sd-dhcp-client.c +@@ -1720,7 +1720,7 @@ static int client_receive_message_udp( + + len = recv(fd, message, buflen, 0); + if (len < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return log_dhcp_client_errno(client, errno, +@@ -1814,7 +1814,7 @@ static int client_receive_message_raw( + + len = recvmsg(fd, &msg, 0); + if (len < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return log_dhcp_client_errno(client, errno, +diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c +index 5ca46b3502..c964b73da1 100644 +--- a/src/libsystemd-network/sd-dhcp-server.c ++++ b/src/libsystemd-network/sd-dhcp-server.c +@@ -962,7 +962,7 @@ static int server_receive_message(sd_event_source *s, int fd, + + len = recvmsg(fd, &msg, 0); + if (len < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(len)) + return 0; + + return -errno; +diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c +index b3bc259280..67257f2e03 100644 +--- a/src/libsystemd-network/sd-dhcp6-client.c ++++ b/src/libsystemd-network/sd-dhcp6-client.c +@@ -1055,7 +1055,7 @@ static int client_receive_message( + + len = recv(fd, message, buflen, 0); + if (len < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(len)) + return 0; + + return log_dhcp6_client_errno(client, errno, "Could not receive message from UDP socket: %m"); +diff --git a/src/libsystemd-network/sd-ipv4acd.c b/src/libsystemd-network/sd-ipv4acd.c +index a40d40db90..f69810c6f5 100644 +--- a/src/libsystemd-network/sd-ipv4acd.c ++++ b/src/libsystemd-network/sd-ipv4acd.c +@@ -336,7 +336,7 @@ static int ipv4acd_on_packet( + + n = recv(fd, &packet, sizeof(struct ether_arp), 0); + if (n < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + log_ipv4acd_errno(acd, errno, "Failed to read ARP packet: %m"); +diff --git a/src/libsystemd-network/sd-lldp.c b/src/libsystemd-network/sd-lldp.c +index c75d6079e1..bf15029027 100644 +--- a/src/libsystemd-network/sd-lldp.c ++++ b/src/libsystemd-network/sd-lldp.c +@@ -200,7 +200,7 @@ static int lldp_receive_datagram(sd_event_source *s, int fd, uint32_t revents, v + + length = recv(fd, LLDP_NEIGHBOR_RAW(n), n->raw_size, MSG_DONTWAIT); + if (length < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return log_lldp_errno(errno, "Failed to read LLDP datagram: %m"); +diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c +index 2c9d331bf2..549103bc6f 100644 +--- a/src/libsystemd/sd-event/sd-event.c ++++ b/src/libsystemd/sd-event/sd-event.c +@@ -3007,7 +3007,7 @@ static int flush_timer(sd_event *e, int fd, uint32_t events, usec_t *next) { + + ss = read(fd, &x, sizeof(x)); + if (ss < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return -errno; +@@ -3161,7 +3161,7 @@ static int process_signal(sd_event *e, struct signal_data *d, uint32_t events) { + + n = read(d->fd, &si, sizeof(si)); + if (n < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return read_one; + + return -errno; +@@ -3210,7 +3210,7 @@ static int event_inotify_data_read(sd_event *e, struct inotify_data *d, uint32_t + + n = read(d->fd, &d->buffer, sizeof(d->buffer)); + if (n < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return -errno; +diff --git a/src/libsystemd/sd-netlink/netlink-socket.c b/src/libsystemd/sd-netlink/netlink-socket.c +index f103cbedea..5fe91450a7 100644 +--- a/src/libsystemd/sd-netlink/netlink-socket.c ++++ b/src/libsystemd/sd-netlink/netlink-socket.c +@@ -265,7 +265,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool + else if (errno == EAGAIN) + log_debug("rtnl: no data in socket"); + +- return IN_SET(errno, EAGAIN, EINTR) ? 0 : -errno; ++ return ERRNO_IS_TRANSIENT(errno) ? 0 : -errno; + } + + if (sender.nl.nl_pid != 0) { +@@ -276,7 +276,7 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool + /* drop the message */ + n = recvmsg(fd, &msg, 0); + if (n < 0) +- return IN_SET(errno, EAGAIN, EINTR) ? 0 : -errno; ++ return ERRNO_IS_TRANSIENT(errno) ? 0 : -errno; + } + + return 0; +diff --git a/src/libsystemd/sd-network/sd-network.c b/src/libsystemd/sd-network/sd-network.c +index 3b8ce935b0..09d3b86e14 100644 +--- a/src/libsystemd/sd-network/sd-network.c ++++ b/src/libsystemd/sd-network/sd-network.c +@@ -338,7 +338,7 @@ _public_ int sd_network_monitor_flush(sd_network_monitor *m) { + + l = read(fd, &buffer, sizeof(buffer)); + if (l < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return -errno; +diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c +index 8cb7591f0e..025a513def 100644 +--- a/src/nspawn/nspawn.c ++++ b/src/nspawn/nspawn.c +@@ -3252,7 +3252,7 @@ static int nspawn_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t r + + n = recvmsg(fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC); + if (n < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(n)) + return 0; + + return log_warning_errno(errno, "Couldn't read notification socket: %m"); +diff --git a/src/resolve/resolved-dns-stream.c b/src/resolve/resolved-dns-stream.c +index ca0313d1d7..cebaba4207 100644 +--- a/src/resolve/resolved-dns-stream.c ++++ b/src/resolve/resolved-dns-stream.c +@@ -380,7 +380,7 @@ static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *use + + ss = dns_stream_writev(s, iov, 2, 0); + if (ss < 0) { +- if (!IN_SET(-ss, EINTR, EAGAIN)) ++ if (!ERRNO_IS_TRANSIENT(ss)) + return dns_stream_complete(s, -ss); + } else + s->n_written += ss; +@@ -402,7 +402,7 @@ static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *use + + ss = dns_stream_read(s, (uint8_t*) &s->read_size + s->n_read, sizeof(s->read_size) - s->n_read); + if (ss < 0) { +- if (!IN_SET(-ss, EINTR, EAGAIN)) ++ if (!ERRNO_IS_TRANSIENT(ss)) + return dns_stream_complete(s, -ss); + } else if (ss == 0) + return dns_stream_complete(s, ECONNRESET); +@@ -452,7 +452,7 @@ static int on_stream_io(sd_event_source *es, int fd, uint32_t revents, void *use + (uint8_t*) DNS_PACKET_DATA(s->read_packet) + s->n_read - sizeof(s->read_size), + sizeof(s->read_size) + be16toh(s->read_size) - s->n_read); + if (ss < 0) { +- if (!IN_SET(errno, EINTR, EAGAIN)) ++ if (!ERRNO_IS_TRANSIENT(errno)) + return dns_stream_complete(s, errno); + } else if (ss == 0) + return dns_stream_complete(s, ECONNRESET); +diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c +index 5ddf13081e..1b80c42174 100644 +--- a/src/resolve/resolved-dns-stub.c ++++ b/src/resolve/resolved-dns-stub.c +@@ -458,7 +458,7 @@ static int on_dns_stub_stream(sd_event_source *s, int fd, uint32_t revents, void + + cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC); + if (cfd < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return -errno; +diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c +index 01372fc66b..2a23c387a6 100644 +--- a/src/resolve/resolved-manager.c ++++ b/src/resolve/resolved-manager.c +@@ -755,7 +755,7 @@ int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) { + if (l == 0) + return 0; + if (l < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return -errno; +diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c +index 764ebd08e1..062db31bbd 100644 +--- a/src/shared/ask-password-api.c ++++ b/src/shared/ask-password-api.c +@@ -332,7 +332,7 @@ int ask_password_tty( + + n = read(ttyfd >= 0 ? ttyfd : STDIN_FILENO, &c, 1); + if (n < 0) { +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (ERRNO_IS_TRANSIENT(errno)) + continue; + + r = -errno; +@@ -652,7 +652,7 @@ int ask_password_agent( + + n = recvmsg(socket_fd, &msghdr, 0); + if (n < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + continue; + + r = -errno; +@@ -661,7 +661,7 @@ int ask_password_agent( + + cmsg_close_all(&msghdr); + +- if (n <= 0) { ++ if (n == 0) { + log_debug("Message too short"); + continue; + } +diff --git a/src/socket-proxy/socket-proxyd.c b/src/socket-proxy/socket-proxyd.c +index 3d07483eb4..155631f1e7 100644 +--- a/src/socket-proxy/socket-proxyd.c ++++ b/src/socket-proxy/socket-proxyd.c +@@ -144,7 +144,7 @@ static int connection_shovel( + } else if (z == 0 || IN_SET(errno, EPIPE, ECONNRESET)) { + *from_source = sd_event_source_unref(*from_source); + *from = safe_close(*from); +- } else if (!IN_SET(errno, EAGAIN, EINTR)) ++ } else if (!ERRNO_IS_TRANSIENT(errno)) + return log_error_errno(errno, "Failed to splice: %m"); + } + +@@ -156,7 +156,7 @@ static int connection_shovel( + } else if (z == 0 || IN_SET(errno, EPIPE, ECONNRESET)) { + *to_source = sd_event_source_unref(*to_source); + *to = safe_close(*to); +- } else if (!IN_SET(errno, EAGAIN, EINTR)) ++ } else if (!ERRNO_IS_TRANSIENT(errno)) + return log_error_errno(errno, "Failed to splice: %m"); + } + } while (shoveled); +diff --git a/src/time-wait-sync/time-wait-sync.c b/src/time-wait-sync/time-wait-sync.c +index d268fb0c5a..2071cb2759 100644 +--- a/src/time-wait-sync/time-wait-sync.c ++++ b/src/time-wait-sync/time-wait-sync.c +@@ -94,7 +94,7 @@ static int inotify_handler(sd_event_source *s, + + l = read(fd, &buffer, sizeof(buffer)); + if (l < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return log_warning_errno(errno, "Lost access to inotify: %m"); +diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c +index 40d594896b..3a20a381c9 100644 +--- a/src/tty-ask-password-agent/tty-ask-password-agent.c ++++ b/src/tty-ask-password-agent/tty-ask-password-agent.c +@@ -150,7 +150,7 @@ static int ask_password_plymouth( + + k = read(fd, buffer + p, sizeof(buffer) - p); + if (k < 0) { +- if (IN_SET(errno, EINTR, EAGAIN)) ++ if (ERRNO_IS_TRANSIENT(errno)) + continue; + + r = -errno; +diff --git a/src/udev/udevd.c b/src/udev/udevd.c +index 34f6a95503..172d21018e 100644 +--- a/src/udev/udevd.c ++++ b/src/udev/udevd.c +@@ -1119,7 +1119,7 @@ static int on_inotify(sd_event_source *s, int fd, uint32_t revents, void *userda + + l = read(fd, &buffer, sizeof(buffer)); + if (l < 0) { +- if (IN_SET(errno, EAGAIN, EINTR)) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 1; + + return log_error_errno(errno, "Failed to read inotify fd: %m"); diff --git a/0926-libsystemd-ignore-both-EINTR-and-EAGAIN.patch b/0926-libsystemd-ignore-both-EINTR-and-EAGAIN.patch new file mode 100644 index 0000000..b24f961 --- /dev/null +++ b/0926-libsystemd-ignore-both-EINTR-and-EAGAIN.patch @@ -0,0 +1,75 @@ +From 4cbf11180cc6c6792f541a861f3309c34c156f4b Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 30 Nov 2021 03:33:55 +0900 +Subject: [PATCH] libsystemd: ignore both EINTR and EAGAIN + +(cherry picked from commit b3d06b9226db96fddb6bb45a4708e2e8d413d91d) + +Related: #2172846 +--- + src/libsystemd/sd-bus/bus-socket.c | 8 ++++---- + src/libsystemd/sd-resolve/sd-resolve.c | 4 ++-- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c +index 8813dd5efd..c6e1a1624f 100644 +--- a/src/libsystemd/sd-bus/bus-socket.c ++++ b/src/libsystemd/sd-bus/bus-socket.c +@@ -155,7 +155,7 @@ static int bus_socket_write_auth(sd_bus *b) { + } + + if (k < 0) +- return errno == EAGAIN ? 0 : -errno; ++ return ERRNO_IS_TRANSIENT(errno) ? 0 : -errno; + + iovec_advance(b->auth_iovec, &b->auth_index, (size_t) k); + return 1; +@@ -573,7 +573,7 @@ static int bus_socket_read_auth(sd_bus *b) { + handle_cmsg = true; + } + if (k < 0) +- return errno == EAGAIN ? 0 : -errno; ++ return ERRNO_IS_TRANSIENT(errno) ? 0 : -errno; + if (k == 0) + return -ECONNRESET; + +@@ -1051,7 +1051,7 @@ int bus_socket_write_message(sd_bus *bus, sd_bus_message *m, size_t *idx) { + } + + if (k < 0) +- return errno == EAGAIN ? 0 : -errno; ++ return ERRNO_IS_TRANSIENT(errno) ? 0 : -errno; + + *idx += (size_t) k; + return 1; +@@ -1205,7 +1205,7 @@ int bus_socket_read_message(sd_bus *bus) { + handle_cmsg = true; + } + if (k < 0) +- return errno == EAGAIN ? 0 : -errno; ++ return ERRNO_IS_TRANSIENT(errno) ? 0 : -errno; + if (k == 0) + return -ECONNRESET; + +diff --git a/src/libsystemd/sd-resolve/sd-resolve.c b/src/libsystemd/sd-resolve/sd-resolve.c +index a189f140f8..99ecb6a467 100644 +--- a/src/libsystemd/sd-resolve/sd-resolve.c ++++ b/src/libsystemd/sd-resolve/sd-resolve.c +@@ -402,7 +402,7 @@ static void* thread_worker(void *p) { + + length = recv(resolve->fds[REQUEST_RECV_FD], &buf, sizeof buf, 0); + if (length < 0) { +- if (errno == EINTR) ++ if (ERRNO_IS_TRANSIENT(errno)) + continue; + + break; +@@ -850,7 +850,7 @@ _public_ int sd_resolve_process(sd_resolve *resolve) { + + l = recv(resolve->fds[RESPONSE_RECV_FD], &buf, sizeof buf, 0); + if (l < 0) { +- if (errno == EAGAIN) ++ if (ERRNO_IS_TRANSIENT(errno)) + return 0; + + return -errno; diff --git a/0927-sd-bus-handle-EINTR-return-from-bus_poll.patch b/0927-sd-bus-handle-EINTR-return-from-bus_poll.patch new file mode 100644 index 0000000..160c031 --- /dev/null +++ b/0927-sd-bus-handle-EINTR-return-from-bus_poll.patch @@ -0,0 +1,90 @@ +From b1075e8b3ecb9e0770dd46331ce8517ea152e1ca Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 21 Nov 2022 17:42:04 +0100 +Subject: [PATCH] sd-bus: handle -EINTR return from bus_poll() + +In sd_bus_wait(), let's convert EINTR to a return code of 0, thus asking +the caller do loop again and enter sd_bus_process() again (which will +not find any queued events). This way we'll not return an error on +something that isn't really an error. This should typically make sure +things are properly handled by the caller, magically, without eating up +the event entirely, and still giving the caller time to run some code if +they want. + +(cherry picked from commit 3022916b4d2483452c3ddbbac9ee7c4372b1cb46) + +Resolves: #2172846 +--- + src/libsystemd/sd-bus/bus-socket.c | 5 ++++- + src/libsystemd/sd-bus/sd-bus.c | 18 +++++++++++++++--- + 2 files changed, 19 insertions(+), 4 deletions(-) + +diff --git a/src/libsystemd/sd-bus/bus-socket.c b/src/libsystemd/sd-bus/bus-socket.c +index c6e1a1624f..a5c750fc69 100644 +--- a/src/libsystemd/sd-bus/bus-socket.c ++++ b/src/libsystemd/sd-bus/bus-socket.c +@@ -1266,8 +1266,11 @@ int bus_socket_process_opening(sd_bus *b) { + assert(b->state == BUS_OPENING); + + r = poll(&p, 1, 0); +- if (r < 0) ++ if (r < 0) { ++ if (ERRNO_IS_TRANSIENT(errno)) ++ return 0; + return -errno; ++ } + + if (!(p.revents & (POLLOUT|POLLERR|POLLHUP))) + return 0; +diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c +index 21e54591f7..5d934cbf73 100644 +--- a/src/libsystemd/sd-bus/sd-bus.c ++++ b/src/libsystemd/sd-bus/sd-bus.c +@@ -2209,8 +2209,11 @@ _public_ int sd_bus_call( + left = (uint64_t) -1; + + r = bus_poll(bus, true, left); +- if (r < 0) ++ if (r < 0) { ++ if (ERRNO_IS_TRANSIENT(r)) ++ continue; + goto fail; ++ } + if (r == 0) { + r = -ETIMEDOUT; + goto fail; +@@ -3069,6 +3072,7 @@ static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec) { + } + + _public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) { ++ int r; + + assert_return(bus, -EINVAL); + assert_return(bus = bus_resolve(bus), -ENOPKG); +@@ -3083,7 +3087,11 @@ _public_ int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec) { + if (bus->rqueue_size > 0) + return 0; + +- return bus_poll(bus, false, timeout_usec); ++ r = bus_poll(bus, false, timeout_usec); ++ if (r < 0 && ERRNO_IS_TRANSIENT(r)) ++ return 1; /* treat EINTR as success, but let's exit, so that the caller will call back into us soon. */ ++ ++ return r; + } + + _public_ int sd_bus_flush(sd_bus *bus) { +@@ -3125,8 +3133,12 @@ _public_ int sd_bus_flush(sd_bus *bus) { + return 0; + + r = bus_poll(bus, false, (uint64_t) -1); +- if (r < 0) ++ if (r < 0) { ++ if (ERRNO_IS_TRANSIENT(r)) ++ continue; ++ + return r; ++ } + } + } + diff --git a/0928-stdio-bridge-don-t-be-bothered-with-EINTR.patch b/0928-stdio-bridge-don-t-be-bothered-with-EINTR.patch new file mode 100644 index 0000000..2bc16f7 --- /dev/null +++ b/0928-stdio-bridge-don-t-be-bothered-with-EINTR.patch @@ -0,0 +1,28 @@ +From 9ddb41dd9dc3bac57d6c3e05700485ee98df3e17 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 22 Nov 2022 12:18:07 +0100 +Subject: [PATCH] stdio-bridge: don't be bothered with EINTR + +We handle signals via signal handlers, hence no need to be concerned +about EINTR. + +(cherry picked from commit 7c75f34131772781f690860de797d3e35fd0bed9) + +Related: #2172846 +--- + src/stdio-bridge/stdio-bridge.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/stdio-bridge/stdio-bridge.c b/src/stdio-bridge/stdio-bridge.c +index 519a92a094..493117ef95 100644 +--- a/src/stdio-bridge/stdio-bridge.c ++++ b/src/stdio-bridge/stdio-bridge.c +@@ -276,6 +276,8 @@ int main(int argc, char *argv[]) { + r = ppoll(p, ELEMENTSOF(p), ts, NULL); + } + if (r < 0) { ++ if (ERRNO_IS_TRANSIENT(r)) /* don't be bothered by signals, i.e. EINTR */ ++ continue; + log_error_errno(errno, "ppoll() failed: %m"); + goto finish; + } diff --git a/0929-sd-netlink-handle-EINTR-from-poll-gracefully-as-succ.patch b/0929-sd-netlink-handle-EINTR-from-poll-gracefully-as-succ.patch new file mode 100644 index 0000000..94f1ebb --- /dev/null +++ b/0929-sd-netlink-handle-EINTR-from-poll-gracefully-as-succ.patch @@ -0,0 +1,36 @@ +From da367d5c87c039f4d1250c12097a5fb16f179a70 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 22 Nov 2022 13:00:48 +0100 +Subject: [PATCH] sd-netlink: handle EINTR from poll() gracefully, as success + +(cherry picked from commit 69858785335afffc51bc03127beb53332c0fb983) + +Related: #2172846 +--- + src/libsystemd/sd-netlink/sd-netlink.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c +index a177f220ab..09900d577b 100644 +--- a/src/libsystemd/sd-netlink/sd-netlink.c ++++ b/src/libsystemd/sd-netlink/sd-netlink.c +@@ -488,13 +488,18 @@ static int rtnl_poll(sd_netlink *rtnl, bool need_more, uint64_t timeout_usec) { + } + + int sd_netlink_wait(sd_netlink *nl, uint64_t timeout_usec) { ++ int r; ++ + assert_return(nl, -EINVAL); + assert_return(!rtnl_pid_changed(nl), -ECHILD); + + if (nl->rqueue_size > 0) + return 0; + +- return rtnl_poll(nl, false, timeout_usec); ++ r = rtnl_poll(nl, false, timeout_usec); ++ if (r < 0 && ERRNO_IS_TRANSIENT(r)) /* Convert EINTR to "something happened" and give user a chance to run some code before calling back into us */ ++ return 1; ++ return r; + } + + static int timeout_compare(const void *a, const void *b) { diff --git a/0930-resolved-handle-EINTR-returned-from-fd_wait_for_even.patch b/0930-resolved-handle-EINTR-returned-from-fd_wait_for_even.patch new file mode 100644 index 0000000..381f651 --- /dev/null +++ b/0930-resolved-handle-EINTR-returned-from-fd_wait_for_even.patch @@ -0,0 +1,79 @@ +From 1316ec49f209e31799d42d114bd7f35d5acbe097 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 22 Nov 2022 12:28:19 +0100 +Subject: [PATCH] resolved: handle -EINTR returned from fd_wait_for_event() + better + +We might get signals for various reasons (for example, somebody asking +us to reload caches via a signal), hence let's handle this gracefully. + +(cherry picked from commit 6d66a221685c15798e796d9738f73fdb1fdccdb2) + +Related: #2172846 +--- + src/resolve/resolved-manager.c | 20 ++++++++++++++++---- + 1 file changed, 16 insertions(+), 4 deletions(-) + +diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c +index 2a23c387a6..5583d63527 100644 +--- a/src/resolve/resolved-manager.c ++++ b/src/resolve/resolved-manager.c +@@ -842,11 +842,14 @@ int manager_recv(Manager *m, int fd, DnsProtocol protocol, DnsPacket **ret) { + } + + static int sendmsg_loop(int fd, struct msghdr *mh, int flags) { ++ usec_t end; + int r; + + assert(fd >= 0); + assert(mh); + ++ end = usec_add(now(CLOCK_MONOTONIC), SEND_TIMEOUT_USEC); ++ + for (;;) { + if (sendmsg(fd, mh, flags) >= 0) + return 0; +@@ -857,20 +860,26 @@ static int sendmsg_loop(int fd, struct msghdr *mh, int flags) { + if (errno != EAGAIN) + return -errno; + +- r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC); +- if (r < 0) ++ r = fd_wait_for_event(fd, POLLOUT, LESS_BY(end, now(CLOCK_MONOTONIC))); ++ if (r < 0) { ++ if (ERRNO_IS_TRANSIENT(r)) ++ continue; + return r; ++ } + if (r == 0) + return -ETIMEDOUT; + } + } + + static int write_loop(int fd, void *message, size_t length) { ++ usec_t end; + int r; + + assert(fd >= 0); + assert(message); + ++ end = usec_add(now(CLOCK_MONOTONIC), SEND_TIMEOUT_USEC); ++ + for (;;) { + if (write(fd, message, length) >= 0) + return 0; +@@ -881,9 +890,12 @@ static int write_loop(int fd, void *message, size_t length) { + if (errno != EAGAIN) + return -errno; + +- r = fd_wait_for_event(fd, POLLOUT, SEND_TIMEOUT_USEC); +- if (r < 0) ++ r = fd_wait_for_event(fd, POLLOUT, LESS_BY(end, now(CLOCK_MONOTONIC))); ++ if (r < 0) { ++ if (ERRNO_IS_TRANSIENT(r)) ++ continue; + return r; ++ } + if (r == 0) + return -ETIMEDOUT; + } diff --git a/0931-utmp-wtmp-fix-error-in-case-isatty-fails.patch b/0931-utmp-wtmp-fix-error-in-case-isatty-fails.patch new file mode 100644 index 0000000..2d80680 --- /dev/null +++ b/0931-utmp-wtmp-fix-error-in-case-isatty-fails.patch @@ -0,0 +1,28 @@ +From c57daab191c6551ac757576fcf7df45fd9790b6b Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 22 Nov 2022 12:56:38 +0100 +Subject: [PATCH] utmp-wtmp: fix error in case isatty() fails + +(cherry picked from commit 80b780ba178a84b248ecee47eef82358480c9492) + +Related: #2172846 +--- + src/shared/utmp-wtmp.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/shared/utmp-wtmp.c b/src/shared/utmp-wtmp.c +index ef9427fa7b..743b784489 100644 +--- a/src/shared/utmp-wtmp.c ++++ b/src/shared/utmp-wtmp.c +@@ -312,8 +312,10 @@ static int write_to_terminal(const char *tty, const char *message) { + assert(message); + + fd = open(tty, O_WRONLY|O_NONBLOCK|O_NOCTTY|O_CLOEXEC); +- if (fd < 0 || !isatty(fd)) ++ if (fd < 0) + return -errno; ++ if (!isatty(fd)) ++ return -ENOTTY; + + p = message; + left = strlen(message); diff --git a/0932-utmp-wtmp-handle-EINTR-gracefully-when-waiting-to-wr.patch b/0932-utmp-wtmp-handle-EINTR-gracefully-when-waiting-to-wr.patch new file mode 100644 index 0000000..6cff781 --- /dev/null +++ b/0932-utmp-wtmp-handle-EINTR-gracefully-when-waiting-to-wr.patch @@ -0,0 +1,52 @@ +From 3590a9c5ce038bc56cdded426156cbd278903c86 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 22 Nov 2022 12:56:55 +0100 +Subject: [PATCH] utmp-wtmp: handle EINTR gracefully when waiting to write to + tty + +(cherry picked from commit 22ecfa83123dbfa2322346ac4e25ad2193a3b10c) + +Related: #2172846 +--- + src/shared/utmp-wtmp.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/src/shared/utmp-wtmp.c b/src/shared/utmp-wtmp.c +index 743b784489..7358ece75d 100644 +--- a/src/shared/utmp-wtmp.c ++++ b/src/shared/utmp-wtmp.c +@@ -320,7 +320,7 @@ static int write_to_terminal(const char *tty, const char *message) { + p = message; + left = strlen(message); + +- end = now(CLOCK_MONOTONIC) + TIMEOUT_MSEC*USEC_PER_MSEC; ++ end = usec_add(now(CLOCK_MONOTONIC), TIMEOUT_MSEC*USEC_PER_MSEC); + + while (left > 0) { + ssize_t n; +@@ -332,20 +332,22 @@ static int write_to_terminal(const char *tty, const char *message) { + int k; + + t = now(CLOCK_MONOTONIC); +- + if (t >= end) + return -ETIME; + + k = poll(&pollfd, 1, (end - t) / USEC_PER_MSEC); +- if (k < 0) ++ if (k < 0) { ++ if (ERRNO_IS_TRANSIENT(k)) ++ continue; + return -errno; + ++ } + if (k == 0) + return -ETIME; + + n = write(fd, p, left); + if (n < 0) { +- if (errno == EAGAIN) ++ if (ERRNO_IS_TRANSIENT(errno)) + continue; + + return -errno; diff --git a/0933-journal-vacuum-count-size-of-all-journal-files.patch b/0933-journal-vacuum-count-size-of-all-journal-files.patch new file mode 100644 index 0000000..48c4403 --- /dev/null +++ b/0933-journal-vacuum-count-size-of-all-journal-files.patch @@ -0,0 +1,90 @@ +From 947296a00d17ef115f4097aa86a8c6f1bfc8bf58 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Wed, 22 Mar 2023 12:36:54 +0100 +Subject: [PATCH] journal-vacuum: count size of all journal files + +Currently, active journal files are excluded, which means that vacuuming +may not remove anything even if *MaxUse= has been exceeded. + +(cherry picked from commit 9ea46af4f2368b41d57705bac09774778126507f) + +Resolves: #2180380 +--- + src/journal/journal-vacuum.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/src/journal/journal-vacuum.c b/src/journal/journal-vacuum.c +index 8d3ae71440..dd21f40966 100644 +--- a/src/journal/journal-vacuum.c ++++ b/src/journal/journal-vacuum.c +@@ -179,6 +179,8 @@ int journal_directory_vacuum( + if (!S_ISREG(st.st_mode)) + continue; + ++ size = 512UL * (uint64_t) st.st_blocks; ++ + q = strlen(de->d_name); + + if (endswith(de->d_name, ".journal")) { +@@ -188,6 +190,7 @@ int journal_directory_vacuum( + + if (q < 1 + 32 + 1 + 16 + 1 + 16 + 8) { + n_active_files++; ++ sum += size; + continue; + } + +@@ -195,6 +198,7 @@ int journal_directory_vacuum( + de->d_name[q-8-16-1-16-1] != '-' || + de->d_name[q-8-16-1-16-1-32-1] != '@') { + n_active_files++; ++ sum += size; + continue; + } + +@@ -207,11 +211,13 @@ int journal_directory_vacuum( + de->d_name[q-8-16-1-16-1] = 0; + if (sd_id128_from_string(de->d_name + q-8-16-1-16-1-32, &seqnum_id) < 0) { + n_active_files++; ++ sum += size; + continue; + } + + if (sscanf(de->d_name + q-8-16-1-16, "%16llx-%16llx.journal", &seqnum, &realtime) != 2) { + n_active_files++; ++ sum += size; + continue; + } + +@@ -224,12 +230,14 @@ int journal_directory_vacuum( + + if (q < 1 + 16 + 1 + 16 + 8 + 1) { + n_active_files++; ++ sum += size; + continue; + } + + if (de->d_name[q-1-8-16-1] != '-' || + de->d_name[q-1-8-16-1-16-1] != '@') { + n_active_files++; ++ sum += size; + continue; + } + +@@ -241,6 +249,7 @@ int journal_directory_vacuum( + + if (sscanf(de->d_name + q-1-8-16-1-16, "%16llx-%16llx.journal~", &realtime, &tmp) != 2) { + n_active_files++; ++ sum += size; + continue; + } + +@@ -251,8 +260,6 @@ int journal_directory_vacuum( + continue; + } + +- size = 512UL * (uint64_t) st.st_blocks; +- + r = journal_file_empty(dirfd(d), p); + if (r < 0) { + log_debug_errno(r, "Failed check if %s is empty, ignoring: %m", p); diff --git a/0934-resolved-instead-of-closing-DNS-UDP-transaction-fds-.patch b/0934-resolved-instead-of-closing-DNS-UDP-transaction-fds-.patch new file mode 100644 index 0000000..3a51892 --- /dev/null +++ b/0934-resolved-instead-of-closing-DNS-UDP-transaction-fds-.patch @@ -0,0 +1,365 @@ +From fc8959efebc662f4050700cc1ed2798750b15b73 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 6 Nov 2020 13:32:53 +0100 +Subject: [PATCH] resolved: instead of closing DNS UDP transaction fds + right-away, add them to a socket "graveyard" + +The "socket graveyard" shall contain sockets we have sent a question out +of, but not received a reply. If we'd close thus sockets immediately +when we are not interested anymore, we'd trigger ICMP port unreachable +messages once we after all *do* get a reply. Let's avoid that, by +leaving the fds open for a bit longer, until a timeout is reached or a +reply datagram received. + +Fixes: #17421 +(cherry picked from commit 80710ade03d971a8877fde8ce9d42eb2b07f4c47) + +Resolves: #2156751 +--- + src/resolve/meson.build | 2 + + src/resolve/resolved-dns-transaction.c | 44 ++++++-- + src/resolve/resolved-manager.c | 2 + + src/resolve/resolved-manager.h | 5 + + src/resolve/resolved-socket-graveyard.c | 133 ++++++++++++++++++++++++ + src/resolve/resolved-socket-graveyard.h | 18 ++++ + 6 files changed, 194 insertions(+), 10 deletions(-) + create mode 100644 src/resolve/resolved-socket-graveyard.c + create mode 100644 src/resolve/resolved-socket-graveyard.h + +diff --git a/src/resolve/meson.build b/src/resolve/meson.build +index 15f3835d55..a975e58242 100644 +--- a/src/resolve/meson.build ++++ b/src/resolve/meson.build +@@ -63,6 +63,8 @@ systemd_resolved_sources = files(''' + resolved-dns-stub.c + resolved-etc-hosts.h + resolved-etc-hosts.c ++ resolved-socket-graveyard.c ++ resolved-socket-graveyard.h + '''.split()) + + resolvectl_sources = files(''' +diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c +index c60b8215a6..95aea21134 100644 +--- a/src/resolve/resolved-dns-transaction.c ++++ b/src/resolve/resolved-dns-transaction.c +@@ -48,7 +48,14 @@ static void dns_transaction_flush_dnssec_transactions(DnsTransaction *t) { + } + } + +-static void dns_transaction_close_connection(DnsTransaction *t) { ++static void dns_transaction_close_connection( ++ DnsTransaction *t, ++ bool use_graveyard) { /* Set use_graveyard = false when you know the connection is already ++ * dead, for example because you got a connection error back from the ++ * kernel. In that case there's no point in keeping the fd around, ++ * hence don't. */ ++ int r; ++ + assert(t); + + if (t->stream) { +@@ -62,6 +69,20 @@ static void dns_transaction_close_connection(DnsTransaction *t) { + } + + t->dns_udp_event_source = sd_event_source_unref(t->dns_udp_event_source); ++ ++ /* If we have an UDP socket where we sent a packet, but never received one, then add it to the socket ++ * graveyard, instead of closing it right away. That way it will stick around for a moment longer, ++ * and the reply we might still get from the server will be eaten up instead of resulting in an ICMP ++ * port unreachable error message. */ ++ ++ if (use_graveyard && t->dns_udp_fd >= 0 && t->sent && !t->received) { ++ r = manager_add_socket_to_graveyard(t->scope->manager, t->dns_udp_fd); ++ if (r < 0) ++ log_debug_errno(r, "Failed to add UDP socket to graveyard, closing immediately: %m"); ++ else ++ TAKE_FD(t->dns_udp_fd); ++ } ++ + t->dns_udp_fd = safe_close(t->dns_udp_fd); + } + +@@ -81,7 +102,7 @@ DnsTransaction* dns_transaction_free(DnsTransaction *t) { + + log_debug("Freeing transaction %" PRIu16 ".", t->id); + +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); + dns_transaction_stop_timeout(t); + + dns_packet_unref(t->sent); +@@ -341,7 +362,7 @@ void dns_transaction_complete(DnsTransaction *t, DnsTransactionState state) { + + t->state = state; + +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); + dns_transaction_stop_timeout(t); + + /* Notify all queries that are interested, but make sure the +@@ -455,7 +476,7 @@ static int dns_transaction_maybe_restart(DnsTransaction *t) { + static void on_transaction_stream_error(DnsTransaction *t, int error) { + assert(t); + +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); + + if (ERRNO_IS_DISCONNECT(error)) { + if (t->scope->protocol == DNS_PROTOCOL_LLMNR) { +@@ -478,7 +499,7 @@ static int dns_transaction_on_stream_packet(DnsTransaction *t, DnsPacket *p) { + assert(t); + assert(p); + +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); + + if (dns_packet_validate_reply(p) <= 0) { + log_debug("Invalid TCP reply packet."); +@@ -583,7 +604,7 @@ static int dns_transaction_emit_tcp(DnsTransaction *t) { + + assert(t); + +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); + + switch (t->scope->protocol) { + +@@ -692,7 +713,7 @@ static int dns_transaction_emit_tcp(DnsTransaction *t) { + + r = dns_stream_write_packet(t->stream, t->sent); + if (r < 0) { +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, /* use_graveyard= */ false); + return r; + } + +@@ -1196,7 +1217,7 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) { + if (r > 0) { + /* There are DNSSEC transactions pending now. Update the state accordingly. */ + t->state = DNS_TRANSACTION_VALIDATING; +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); + dns_transaction_stop_timeout(t); + return; + } +@@ -1277,7 +1298,10 @@ static int dns_transaction_emit_udp(DnsTransaction *t) { + if (r > 0 || t->dns_udp_fd < 0) { /* Server changed, or no connection yet. */ + int fd; + +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); ++ ++ /* Before we allocate a new UDP socket, let's process the graveyard a bit to free some fds */ ++ manager_socket_graveyard_process(t->scope->manager); + + fd = dns_scope_socket_udp(t->scope, t->server, 53); + if (fd < 0) +@@ -1297,7 +1321,7 @@ static int dns_transaction_emit_udp(DnsTransaction *t) { + if (r < 0) + return r; + } else +- dns_transaction_close_connection(t); ++ dns_transaction_close_connection(t, true); + + r = dns_scope_emit_udp(t->scope, t->dns_udp_fd, t->sent); + if (r < 0) +diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c +index 5583d63527..5feb92a676 100644 +--- a/src/resolve/resolved-manager.c ++++ b/src/resolve/resolved-manager.c +@@ -683,6 +683,8 @@ Manager *manager_free(Manager *m) { + manager_mdns_stop(m); + manager_dns_stub_stop(m); + ++ manager_socket_graveyard_clear(m); ++ + sd_bus_slot_unref(m->prepare_for_sleep_slot); + sd_bus_unref(m->bus); + +diff --git a/src/resolve/resolved-manager.h b/src/resolve/resolved-manager.h +index d94b2888ab..80119bfcb3 100644 +--- a/src/resolve/resolved-manager.h ++++ b/src/resolve/resolved-manager.h +@@ -20,6 +20,7 @@ typedef struct Manager Manager; + #include "resolved-dns-stream.h" + #include "resolved-dns-trust-anchor.h" + #include "resolved-link.h" ++#include "resolved-socket-graveyard.h" + + #define MANAGER_SEARCH_DOMAINS_MAX 32 + #define MANAGER_DNS_SERVERS_MAX 32 +@@ -130,6 +131,10 @@ struct Manager { + sd_event_source *dns_stub_tcp_event_source; + + Hashmap *polkit_registry; ++ ++ LIST_HEAD(SocketGraveyard, socket_graveyard); ++ SocketGraveyard *socket_graveyard_oldest; ++ size_t n_socket_graveyard; + }; + + /* Manager */ +diff --git a/src/resolve/resolved-socket-graveyard.c b/src/resolve/resolved-socket-graveyard.c +new file mode 100644 +index 0000000000..067cb666d4 +--- /dev/null ++++ b/src/resolve/resolved-socket-graveyard.c +@@ -0,0 +1,133 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++ ++#include "resolved-socket-graveyard.h" ++ ++#define SOCKET_GRAVEYARD_USEC (5 * USEC_PER_SEC) ++#define SOCKET_GRAVEYARD_MAX 100 ++ ++/* This implements a socket "graveyard" for UDP sockets. If a socket fd is added to the graveyard it is kept ++ * open for a couple of more seconds, expecting one reply. Once the reply is received the fd is closed ++ * immediately, or if none is received it is closed after the timeout. Why all this? So that if we contact a ++ * DNS server, and it doesn't reply instantly, and we lose interest in the response and thus close the fd, we ++ * don't end up sending back an ICMP error once the server responds but we aren't listening anymore. (See ++ * https://github.com/systemd/systemd/issues/17421 for further information.) ++ * ++ * Note that we don't allocate any timer event source to clear up the graveyard once the socket's timeout is ++ * reached. Instead we operate lazily: we close old entries when adding a new fd to the graveyard, or ++ * whenever any code runs manager_socket_graveyard_process() — which the DNS transaction code does right ++ * before allocating a new UDP socket. */ ++ ++static SocketGraveyard* socket_graveyard_free(SocketGraveyard *g) { ++ if (!g) ++ return NULL; ++ ++ if (g->manager) { ++ assert(g->manager->n_socket_graveyard > 0); ++ g->manager->n_socket_graveyard--; ++ ++ if (g->manager->socket_graveyard_oldest == g) ++ g->manager->socket_graveyard_oldest = g->graveyard_prev; ++ ++ LIST_REMOVE(graveyard, g->manager->socket_graveyard, g); ++ ++ assert((g->manager->n_socket_graveyard > 0) == !!g->manager->socket_graveyard); ++ assert((g->manager->n_socket_graveyard > 0) == !!g->manager->socket_graveyard_oldest); ++ } ++ ++ if (g->io_event_source) { ++ log_debug("Closing graveyard socket fd %i", sd_event_source_get_io_fd(g->io_event_source)); ++ sd_event_source_unref(g->io_event_source); ++ } ++ ++ return mfree(g); ++} ++ ++DEFINE_TRIVIAL_CLEANUP_FUNC(SocketGraveyard*, socket_graveyard_free); ++ ++void manager_socket_graveyard_process(Manager *m) { ++ usec_t n = USEC_INFINITY; ++ ++ assert(m); ++ ++ while (m->socket_graveyard_oldest) { ++ SocketGraveyard *g = m->socket_graveyard_oldest; ++ ++ if (n == USEC_INFINITY) ++ assert_se(sd_event_now(m->event, clock_boottime_or_monotonic(), &n) >= 0); ++ ++ if (g->deadline > n) ++ break; ++ ++ socket_graveyard_free(g); ++ } ++} ++ ++void manager_socket_graveyard_clear(Manager *m) { ++ assert(m); ++ ++ while (m->socket_graveyard) ++ socket_graveyard_free(m->socket_graveyard); ++} ++ ++static int on_io_event(sd_event_source *s, int fd, uint32_t revents, void *userdata) { ++ SocketGraveyard *g = userdata; ++ ++ assert(g); ++ ++ /* An IO event happened on the graveyard fd. We don't actually care which event that is, and we don't ++ * read any incoming packet off the socket. We just close the fd, that's enough to not trigger the ++ * ICMP unreachable port event */ ++ ++ socket_graveyard_free(g); ++ return 0; ++} ++ ++static void manager_socket_graveyard_make_room(Manager *m) { ++ assert(m); ++ ++ while (m->n_socket_graveyard >= SOCKET_GRAVEYARD_MAX) ++ socket_graveyard_free(m->socket_graveyard_oldest); ++} ++ ++int manager_add_socket_to_graveyard(Manager *m, int fd) { ++ _cleanup_(socket_graveyard_freep) SocketGraveyard *g = NULL; ++ int r; ++ ++ assert(m); ++ assert(fd >= 0); ++ ++ manager_socket_graveyard_process(m); ++ manager_socket_graveyard_make_room(m); ++ ++ g = new(SocketGraveyard, 1); ++ if (!g) ++ return log_oom(); ++ ++ *g = (SocketGraveyard) { ++ .manager = m, ++ }; ++ ++ LIST_PREPEND(graveyard, m->socket_graveyard, g); ++ if (!m->socket_graveyard_oldest) ++ m->socket_graveyard_oldest = g; ++ ++ m->n_socket_graveyard++; ++ ++ assert_se(sd_event_now(m->event, clock_boottime_or_monotonic(), &g->deadline) >= 0); ++ g->deadline += SOCKET_GRAVEYARD_USEC; ++ ++ r = sd_event_add_io(m->event, &g->io_event_source, fd, EPOLLIN, on_io_event, g); ++ if (r < 0) ++ return log_error_errno(r, "Failed to create graveyard IO source: %m"); ++ ++ r = sd_event_source_set_io_fd_own(g->io_event_source, true); ++ if (r < 0) ++ return log_error_errno(r, "Failed to enable graveyard IO source fd ownership: %m"); ++ ++ (void) sd_event_source_set_description(g->io_event_source, "graveyard"); ++ ++ log_debug("Added socket %i to graveyard", fd); ++ ++ TAKE_PTR(g); ++ return 0; ++} +diff --git a/src/resolve/resolved-socket-graveyard.h b/src/resolve/resolved-socket-graveyard.h +new file mode 100644 +index 0000000000..9b13bb0482 +--- /dev/null ++++ b/src/resolve/resolved-socket-graveyard.h +@@ -0,0 +1,18 @@ ++/* SPDX-License-Identifier: LGPL-2.1+ */ ++#pragma once ++ ++typedef struct SocketGraveyard SocketGraveyard; ++ ++#include "resolved-manager.h" ++ ++struct SocketGraveyard { ++ Manager *manager; ++ usec_t deadline; ++ sd_event_source *io_event_source; ++ LIST_FIELDS(SocketGraveyard, graveyard); ++}; ++ ++void manager_socket_graveyard_process(Manager *m); ++void manager_socket_graveyard_clear(Manager *m); ++ ++int manager_add_socket_to_graveyard(Manager *m, int fd); diff --git a/0935-resolved-close-UDP-socket-when-we-received-a-network.patch b/0935-resolved-close-UDP-socket-when-we-received-a-network.patch new file mode 100644 index 0000000..25c1692 --- /dev/null +++ b/0935-resolved-close-UDP-socket-when-we-received-a-network.patch @@ -0,0 +1,26 @@ +From 648fe0097229c7ae46a6b5911521cef27a726cbe Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 6 Nov 2020 14:31:56 +0100 +Subject: [PATCH] resolved: close UDP socket when we received a network error + on it + +(cherry picked from commit d68dbb37d7408c025e736181f294152e2a515bf1) + +Related: #2156751 +--- + src/resolve/resolved-dns-transaction.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c +index 95aea21134..c975215468 100644 +--- a/src/resolve/resolved-dns-transaction.c ++++ b/src/resolve/resolved-dns-transaction.c +@@ -1250,6 +1250,8 @@ static int on_dns_packet(sd_event_source *s, int fd, uint32_t revents, void *use + assert_se(sd_event_now(t->scope->manager->event, clock_boottime_or_monotonic(), &usec) >= 0); + dns_server_packet_lost(t->server, IPPROTO_UDP, t->current_feature_level); + ++ dns_transaction_close_connection(t, /* use_graveyard = */ false); ++ + dns_transaction_retry(t, true); + return 0; + } diff --git a/0936-ci-allow-RHEL-only-labels-to-mark-downstream-only-co.patch b/0936-ci-allow-RHEL-only-labels-to-mark-downstream-only-co.patch new file mode 100644 index 0000000..342a153 --- /dev/null +++ b/0936-ci-allow-RHEL-only-labels-to-mark-downstream-only-co.patch @@ -0,0 +1,24 @@ +From 950cc2c5109f269561d3c0fdd020c6bf7cb561e1 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Mon, 10 Jul 2023 12:38:05 +0200 +Subject: [PATCH] ci: allow RHEL-only labels to mark downstream-only commits + +RHEL-only + +Related: #2179309 +--- + .github/advanced-commit-linter.yml | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/.github/advanced-commit-linter.yml b/.github/advanced-commit-linter.yml +index 491836abbb..327af0467a 100644 +--- a/.github/advanced-commit-linter.yml ++++ b/.github/advanced-commit-linter.yml +@@ -6,6 +6,7 @@ policy: + exception: + note: + - rhel-only ++ - RHEL-only + tracker: + - keyword: + - 'Resolves: #?' diff --git a/0937-man-tweak-markup-in-systemd-pstore.service-8.patch b/0937-man-tweak-markup-in-systemd-pstore.service-8.patch new file mode 100644 index 0000000..eec7298 --- /dev/null +++ b/0937-man-tweak-markup-in-systemd-pstore.service-8.patch @@ -0,0 +1,39 @@ +From e3d4d6b36c111c5273ce5da124116f1c98b10d9d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 29 Feb 2020 09:48:44 +0100 +Subject: [PATCH] man: tweak markup in systemd-pstore.service(8) + +(cherry picked from commit e3b192626e24cbd3a4dc2c7d5fb9a3b3fd136e24) + +Related: #2217786 +--- + man/systemd-pstore.xml | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/man/systemd-pstore.xml b/man/systemd-pstore.xml +index dd1aa5e83b..8726071cf0 100644 +--- a/man/systemd-pstore.xml ++++ b/man/systemd-pstore.xml +@@ -49,8 +49,8 @@ + + The pstore service is independent of the kdump service. In cloud environments + specifically, host and guest filesystems are on remote filesystems (eg. iSCSI +- or NFS), thus kdump relies [implicitly and/or explicitly] upon proper operation +- of networking software *and* hardware *and* infrastructure. Thus it may not be ++ or NFS), thus kdump relies (implicitly and/or explicitly) upon proper operation ++ of networking software *and* hardware *and* infrastructure. Thus it may not be + possible to capture a kernel coredump to a file since writes over the network + may not be possible. + +@@ -59,9 +59,9 @@ + debugging. + + The systemd-pstore executable does the actual work. Upon starting, +- the pstore.conf is read to obtain options, then the /sys/fs/pstore ++ the pstore.conf file is read and the /sys/fs/pstore + directory contents are processed according to the options. Pstore files are written to the +- journal, and optionally saved into /var/lib/systemd/pstore. ++ journal, and optionally saved into /var/lib/systemd/pstore. + + + diff --git a/0938-man-add-.service-suffix-to-systemd-pstore-8.patch b/0938-man-add-.service-suffix-to-systemd-pstore-8.patch new file mode 100644 index 0000000..2a4f140 --- /dev/null +++ b/0938-man-add-.service-suffix-to-systemd-pstore-8.patch @@ -0,0 +1,61 @@ +From ff17baae0631f42f59be6e425943c7181c6c5c18 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 29 Feb 2020 09:57:06 +0100 +Subject: [PATCH] man: add .service suffix to systemd-pstore(8) + +That is the pattern that we always use with executables not in +$PATH. + +(cherry picked from commit aa07dc70932837bfeda982affe53f01d36ec6efe) + +Related: #2217786 +--- + man/rules/meson.build | 2 +- + man/{systemd-pstore.xml => systemd-pstore.service.xml} | 8 ++++---- + 2 files changed, 5 insertions(+), 5 deletions(-) + rename man/{systemd-pstore.xml => systemd-pstore.service.xml} (95%) + +diff --git a/man/rules/meson.build b/man/rules/meson.build +index 6295330c5e..05eb0a1604 100644 +--- a/man/rules/meson.build ++++ b/man/rules/meson.build +@@ -634,7 +634,7 @@ manpages = [ + ['systemd-nspawn', '1', [], ''], + ['systemd-path', '1', [], ''], + ['systemd-portabled.service', '8', ['systemd-portabled'], 'ENABLE_PORTABLED'], +- ['systemd-pstore', '8', ['systemd-pstore.service'], 'ENABLE_PSTORE'], ++ ['systemd-pstore.service', '8', ['systemd-pstore'], 'ENABLE_PSTORE'], + ['systemd-quotacheck.service', + '8', + ['systemd-quotacheck'], +diff --git a/man/systemd-pstore.xml b/man/systemd-pstore.service.xml +similarity index 95% +rename from man/systemd-pstore.xml +rename to man/systemd-pstore.service.xml +index 8726071cf0..47916da521 100644 +--- a/man/systemd-pstore.xml ++++ b/man/systemd-pstore.service.xml +@@ -7,19 +7,19 @@ + xmlns:xi="http://www.w3.org/2001/XInclude"> + + +- systemd-pstore ++ systemd-pstore.service + systemd + + + +- systemd-pstore ++ systemd-pstore.service + 8 + + + +- systemd-pstore + systemd-pstore.service +- Tool to archive contents of the persistent storage filesytem ++ systemd-pstore ++ A service to archive contents of pstore + + + diff --git a/0939-presets-enable-systemd-pstore.service-by-default.patch b/0939-presets-enable-systemd-pstore.service-by-default.patch new file mode 100644 index 0000000..0999eb3 --- /dev/null +++ b/0939-presets-enable-systemd-pstore.service-by-default.patch @@ -0,0 +1,26 @@ +From 36d9a1a50f80322b24ff5756b8fb89a07363dfd7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sat, 29 Feb 2020 10:01:39 +0100 +Subject: [PATCH] presets: enable systemd-pstore.service by default + +It has no effect is the pstore is not used, and prevents the non-volatile +storage from filling up if is used by the kernel. + +https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=952767 +(cherry picked from commit 5926ea0a6860095eaa83403417cbbf345db864f6) + +Resolves: #2217786 +--- + presets/90-systemd.preset | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/presets/90-systemd.preset b/presets/90-systemd.preset +index 11960e5423..b8edc23d48 100644 +--- a/presets/90-systemd.preset ++++ b/presets/90-systemd.preset +@@ -34,3 +34,5 @@ disable syslog.socket + disable systemd-journal-gatewayd.* + disable systemd-journal-remote.* + disable systemd-journal-upload.* ++ ++enable systemd-pstore.service diff --git a/0940-logind-simplify-code.patch b/0940-logind-simplify-code.patch new file mode 100644 index 0000000..b1a4a25 --- /dev/null +++ b/0940-logind-simplify-code.patch @@ -0,0 +1,54 @@ +From bf5b87db9785b86fadbd2b5e97e4883cbe51797d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Thu, 23 Jun 2022 09:56:33 +0200 +Subject: [PATCH] logind: simplify code + +Follow-up for 4885d7490b23e08d8444e5a68927ce9ce8727e5a. + +(cherry picked from commit e5c09aad375551b9db499703ab7eb123d408ba16) + +Resolves: #2209328 +--- + src/login/logind-session.c | 10 +++------- + 1 file changed, 3 insertions(+), 7 deletions(-) + +diff --git a/src/login/logind-session.c b/src/login/logind-session.c +index 916202a65a..fabf680b61 100644 +--- a/src/login/logind-session.c ++++ b/src/login/logind-session.c +@@ -349,12 +349,11 @@ fail: + } + + static int session_load_devices(Session *s, const char *devices) { +- const char *p; + int r = 0; + + assert(s); + +- for (p = devices;;) { ++ for (const char *p = devices;;) { + _cleanup_free_ char *word = NULL; + SessionDevice *sd; + dev_t dev; +@@ -531,7 +530,7 @@ int session_load(Session *s) { + s->class = c; + } + +- if (state && streq(state, "closing")) ++ if (streq_ptr(state, "closing")) + s->stopping = true; + + if (s->fifo_path) { +@@ -1073,11 +1072,8 @@ int session_set_display(Session *s, const char *display) { + assert(s); + assert(display); + +- if (streq(s->display, display)) +- return 0; +- + r = free_and_strdup(&s->display, display); +- if (r < 0) ++ if (r <= 0) /* 0 means the strings were equal */ + return r; + + session_save(s); diff --git a/0941-format-table-add-TABLE_TIMESTAMP_UTC-and-_RELATIVE.patch b/0941-format-table-add-TABLE_TIMESTAMP_UTC-and-_RELATIVE.patch new file mode 100644 index 0000000..5b62383 --- /dev/null +++ b/0941-format-table-add-TABLE_TIMESTAMP_UTC-and-_RELATIVE.patch @@ -0,0 +1,89 @@ +From 2fb7d36caf560e4ce57265673da7a518d7a5348f Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 16 Jul 2019 00:44:14 +0900 +Subject: [PATCH] format-table: add TABLE_TIMESTAMP_UTC and _RELATIVE + +(cherry picked from commit c5bbb2b5be079852d92d16ebc0d0840929ed82e1) + +Related: #2156786 +--- + src/basic/format-table.c | 25 ++++++++++++++++++------- + src/basic/format-table.h | 2 ++ + 2 files changed, 20 insertions(+), 7 deletions(-) + +diff --git a/src/basic/format-table.c b/src/basic/format-table.c +index c541e92b3c..5f2e5e3d73 100644 +--- a/src/basic/format-table.c ++++ b/src/basic/format-table.c +@@ -236,6 +236,8 @@ static size_t table_data_size(TableDataType type, const void *data) { + return sizeof(bool); + + case TABLE_TIMESTAMP: ++ case TABLE_TIMESTAMP_UTC: ++ case TABLE_TIMESTAMP_RELATIVE: + case TABLE_TIMESPAN: + return sizeof(usec_t); + +@@ -700,6 +702,8 @@ int table_add_many_internal(Table *t, TableDataType first_type, ...) { + break; + + case TABLE_TIMESTAMP: ++ case TABLE_TIMESTAMP_UTC: ++ case TABLE_TIMESTAMP_RELATIVE: + case TABLE_TIMESPAN: + buffer.usec = va_arg(ap, usec_t); + data = &buffer.usec; +@@ -837,11 +841,9 @@ static int cell_data_compare(TableData *a, size_t index_a, TableData *b, size_t + return 0; + + case TABLE_TIMESTAMP: +- if (a->timestamp < b->timestamp) +- return -1; +- if (a->timestamp > b->timestamp) +- return 1; +- return 0; ++ case TABLE_TIMESTAMP_UTC: ++ case TABLE_TIMESTAMP_RELATIVE: ++ return CMP(a->timestamp, b->timestamp); + + case TABLE_TIMESPAN: + if (a->timespan < b->timespan) +@@ -952,14 +954,23 @@ static const char *table_data_format(TableData *d) { + case TABLE_BOOLEAN: + return yes_no(d->boolean); + +- case TABLE_TIMESTAMP: { ++ case TABLE_TIMESTAMP: ++ case TABLE_TIMESTAMP_UTC: ++ case TABLE_TIMESTAMP_RELATIVE: { + _cleanup_free_ char *p; ++ char *ret; + + p = new(char, FORMAT_TIMESTAMP_MAX); + if (!p) + return NULL; + +- if (!format_timestamp(p, FORMAT_TIMESTAMP_MAX, d->timestamp)) ++ if (d->type == TABLE_TIMESTAMP) ++ ret = format_timestamp(p, FORMAT_TIMESTAMP_MAX, d->timestamp); ++ else if (d->type == TABLE_TIMESTAMP_UTC) ++ ret = format_timestamp_utc(p, FORMAT_TIMESTAMP_MAX, d->timestamp); ++ else ++ ret = format_timestamp_relative(p, FORMAT_TIMESTAMP_MAX, d->timestamp); ++ if (!ret) + return "n/a"; + + d->formatted = TAKE_PTR(p); +diff --git a/src/basic/format-table.h b/src/basic/format-table.h +index 5a076b5383..1c8ab5436d 100644 +--- a/src/basic/format-table.h ++++ b/src/basic/format-table.h +@@ -12,6 +12,8 @@ typedef enum TableDataType { + TABLE_STRING, + TABLE_BOOLEAN, + TABLE_TIMESTAMP, ++ TABLE_TIMESTAMP_UTC, ++ TABLE_TIMESTAMP_RELATIVE, + TABLE_TIMESPAN, + TABLE_SIZE, + TABLE_UINT32, diff --git a/0942-loginctl-shorten-variable-name.patch b/0942-loginctl-shorten-variable-name.patch new file mode 100644 index 0000000..e959206 --- /dev/null +++ b/0942-loginctl-shorten-variable-name.patch @@ -0,0 +1,39 @@ +From c88514d4de20ceeeea2028917087e2710ea419b2 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Tue, 23 May 2023 10:48:15 +0200 +Subject: [PATCH] loginctl: shorten variable name + +(cherry picked from commit 86f128558d57586bd28c55eb63968eab3dc4b36e) + +Related: #2156786 +--- + src/login/loginctl.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/login/loginctl.c b/src/login/loginctl.c +index 9b3fed928b..079c0e2b17 100644 +--- a/src/login/loginctl.c ++++ b/src/login/loginctl.c +@@ -147,7 +147,7 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + (void) table_set_align_percent(table, TABLE_HEADER_CELL(1), 100); + + for (;;) { +- _cleanup_(sd_bus_error_free) sd_bus_error error_tty = SD_BUS_ERROR_NULL; ++ _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply_tty = NULL; + const char *id, *user, *seat, *object, *tty = NULL; + uint32_t uid; +@@ -164,11 +164,11 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + object, + "org.freedesktop.login1.Session", + "TTY", +- &error_tty, ++ &e, + &reply_tty, + "s"); + if (r < 0) +- log_warning_errno(r, "Failed to get TTY for session %s: %s", id, bus_error_message(&error_tty, r)); ++ log_warning_errno(r, "Failed to get TTY for session %s: %s", id, bus_error_message(&e, r)); + else { + r = sd_bus_message_read(reply_tty, "s", &tty); + if (r < 0) diff --git a/0943-loginctl-use-bus_map_all_properties.patch b/0943-loginctl-use-bus_map_all_properties.patch new file mode 100644 index 0000000..3786b5c --- /dev/null +++ b/0943-loginctl-use-bus_map_all_properties.patch @@ -0,0 +1,137 @@ +From 5d2f49451c5e697d6e3548cfc9087ef3c16aa969 Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Fri, 19 May 2023 13:33:58 +0200 +Subject: [PATCH] loginctl: use bus_map_all_properties + +(cherry picked from commit 5b7d1536d0c2ccf0b7688490f31c92c1e766ea44) + +Related: #2156786 +--- + src/login/loginctl.c | 78 ++++++++++++++++++++++---------------------- + 1 file changed, 39 insertions(+), 39 deletions(-) + +diff --git a/src/login/loginctl.c b/src/login/loginctl.c +index 079c0e2b17..9e4c710062 100644 +--- a/src/login/loginctl.c ++++ b/src/login/loginctl.c +@@ -47,6 +47,27 @@ static bool arg_ask_password = true; + static unsigned arg_lines = 10; + static OutputMode arg_output = OUTPUT_SHORT; + ++typedef struct SessionStatusInfo { ++ const char *id; ++ uid_t uid; ++ const char *name; ++ struct dual_timestamp timestamp; ++ unsigned int vtnr; ++ const char *seat; ++ const char *tty; ++ const char *display; ++ bool remote; ++ const char *remote_host; ++ const char *remote_user; ++ const char *service; ++ pid_t leader; ++ const char *type; ++ const char *class; ++ const char *state; ++ const char *scope; ++ const char *desktop; ++} SessionStatusInfo; ++ + static OutputFlags get_output_flags(void) { + + return +@@ -112,6 +133,12 @@ static int show_table(Table *table, const char *word) { + } + + static int list_sessions(int argc, char *argv[], void *userdata) { ++ ++ static const struct bus_properties_map map[] = { ++ { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) }, ++ {}, ++ }; ++ + _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; + _cleanup_(table_unrefp) Table *table = NULL; +@@ -148,9 +175,10 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + + for (;;) { + _cleanup_(sd_bus_error_free) sd_bus_error e = SD_BUS_ERROR_NULL; +- _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply_tty = NULL; +- const char *id, *user, *seat, *object, *tty = NULL; ++ const char *id, *user, *seat, *object; + uint32_t uid; ++ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; ++ SessionStatusInfo i = {}; + + r = sd_bus_message_read(reply, "(susso)", &id, &uid, &user, &seat, &object); + if (r < 0) +@@ -158,21 +186,14 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + if (r == 0) + break; + +- r = sd_bus_get_property( +- bus, +- "org.freedesktop.login1", +- object, +- "org.freedesktop.login1.Session", +- "TTY", +- &e, +- &reply_tty, +- "s"); +- if (r < 0) +- log_warning_errno(r, "Failed to get TTY for session %s: %s", id, bus_error_message(&e, r)); +- else { +- r = sd_bus_message_read(reply_tty, "s", &tty); +- if (r < 0) +- return bus_log_parse_error(r); ++ r = bus_map_all_properties(bus, "org.freedesktop.login1", object, map, BUS_MAP_BOOLEAN_AS_BOOL, &e, &m, &i); ++ if (r < 0) { ++ if (sd_bus_error_has_name(&e, SD_BUS_ERROR_UNKNOWN_OBJECT)) ++ /* The session is already closed when we're querying the property */ ++ continue; ++ ++ log_warning_errno(r, "Failed to get properties of session %s, ignoring: %s", ++ id, bus_error_message(&e, r)); + } + + r = table_add_many(table, +@@ -180,7 +201,7 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + TABLE_UINT32, uid, + TABLE_STRING, user, + TABLE_STRING, seat, +- TABLE_STRING, strna(tty)); ++ TABLE_STRING, strna(i.tty)); + if (r < 0) + return log_error_errno(r, "Failed to add row to table: %m"); + } +@@ -341,27 +362,6 @@ static int show_unit_cgroup(sd_bus *bus, const char *interface, const char *unit + return 0; + } + +-typedef struct SessionStatusInfo { +- const char *id; +- uid_t uid; +- const char *name; +- struct dual_timestamp timestamp; +- unsigned int vtnr; +- const char *seat; +- const char *tty; +- const char *display; +- bool remote; +- const char *remote_host; +- const char *remote_user; +- const char *service; +- pid_t leader; +- const char *type; +- const char *class; +- const char *state; +- const char *scope; +- const char *desktop; +-} SessionStatusInfo; +- + typedef struct UserStatusInfo { + uid_t uid; + bool linger; diff --git a/0944-loginctl-show-session-idle-status-in-list-sessions.patch b/0944-loginctl-show-session-idle-status-in-list-sessions.patch new file mode 100644 index 0000000..1edd5e2 --- /dev/null +++ b/0944-loginctl-show-session-idle-status-in-list-sessions.patch @@ -0,0 +1,80 @@ +From 0d1082f3cf9d4028ac69c22e9dad2adb51ee910d Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Fri, 19 May 2023 14:03:09 +0200 +Subject: [PATCH] loginctl: show session idle status in list-sessions + +(cherry picked from commit 556723e738b96a5c2b2d45a96b87b7b80e0c5664) + +Resolves: #2156786 +--- + src/login/loginctl.c | 29 ++++++++++++++++++++--------- + 1 file changed, 20 insertions(+), 9 deletions(-) + +diff --git a/src/login/loginctl.c b/src/login/loginctl.c +index 9e4c710062..65fe182195 100644 +--- a/src/login/loginctl.c ++++ b/src/login/loginctl.c +@@ -66,6 +66,8 @@ typedef struct SessionStatusInfo { + const char *state; + const char *scope; + const char *desktop; ++ bool idle_hint; ++ dual_timestamp idle_hint_timestamp; + } SessionStatusInfo; + + static OutputFlags get_output_flags(void) { +@@ -135,7 +137,9 @@ static int show_table(Table *table, const char *word) { + static int list_sessions(int argc, char *argv[], void *userdata) { + + static const struct bus_properties_map map[] = { +- { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) }, ++ { "IdleHint", "b", NULL, offsetof(SessionStatusInfo, idle_hint) }, ++ { "IdleSinceHintMonotonic", "t", NULL, offsetof(SessionStatusInfo, idle_hint_timestamp.monotonic) }, ++ { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) }, + {}, + }; + +@@ -165,7 +169,7 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + if (r < 0) + return bus_log_parse_error(r); + +- table = table_new("SESSION", "UID", "USER", "SEAT", "TTY"); ++ table = table_new("SESSION", "UID", "USER", "SEAT", "TTY", "IDLE", "SINCE"); + if (!table) + return log_oom(); + +@@ -188,12 +192,11 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + + r = bus_map_all_properties(bus, "org.freedesktop.login1", object, map, BUS_MAP_BOOLEAN_AS_BOOL, &e, &m, &i); + if (r < 0) { +- if (sd_bus_error_has_name(&e, SD_BUS_ERROR_UNKNOWN_OBJECT)) +- /* The session is already closed when we're querying the property */ +- continue; +- +- log_warning_errno(r, "Failed to get properties of session %s, ignoring: %s", +- id, bus_error_message(&e, r)); ++ log_full_errno(sd_bus_error_has_name(&e, SD_BUS_ERROR_UNKNOWN_OBJECT) ? LOG_DEBUG : LOG_WARNING, ++ r, ++ "Failed to get properties of session %s, ignoring: %s", ++ id, bus_error_message(&e, r)); ++ continue; + } + + r = table_add_many(table, +@@ -201,7 +204,15 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + TABLE_UINT32, uid, + TABLE_STRING, user, + TABLE_STRING, seat, +- TABLE_STRING, strna(i.tty)); ++ TABLE_STRING, strna(i.tty), ++ TABLE_BOOLEAN, i.idle_hint); ++ if (r < 0) ++ return log_error_errno(r, "Failed to add row to table: %m"); ++ ++ if (i.idle_hint) ++ r = table_add_cell(table, NULL, TABLE_TIMESTAMP_RELATIVE, &i.idle_hint_timestamp.monotonic); ++ else ++ r = table_add_cell(table, NULL, TABLE_EMPTY, NULL); + if (r < 0) + return log_error_errno(r, "Failed to add row to table: %m"); + } diff --git a/0945-loginctl-list-sessions-fix-timestamp-for-idle-hint.patch b/0945-loginctl-list-sessions-fix-timestamp-for-idle-hint.patch new file mode 100644 index 0000000..93a96b5 --- /dev/null +++ b/0945-loginctl-list-sessions-fix-timestamp-for-idle-hint.patch @@ -0,0 +1,53 @@ +From ea3d85221a7ba83ff1d9612d29cc8ca3e054f2fa Mon Sep 17 00:00:00 2001 +From: Mike Yuan +Date: Thu, 25 May 2023 01:20:45 +0800 +Subject: [PATCH] loginctl: list-sessions: fix timestamp for idle hint + +Follow-up for 556723e738b96a5c2b2d45a96b87b7b80e0c5664 + +TABLE_TIMESTAMP_RELATIVE takes a realtime timestamp. + +(cherry picked from commit be88af3d9646c8bd1aaea3d4a00520e97ee8674d) + +Related: #2156786 +--- + src/login/loginctl.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/login/loginctl.c b/src/login/loginctl.c +index 65fe182195..1131267015 100644 +--- a/src/login/loginctl.c ++++ b/src/login/loginctl.c +@@ -67,7 +67,7 @@ typedef struct SessionStatusInfo { + const char *scope; + const char *desktop; + bool idle_hint; +- dual_timestamp idle_hint_timestamp; ++ usec_t idle_hint_timestamp; + } SessionStatusInfo; + + static OutputFlags get_output_flags(void) { +@@ -136,10 +136,10 @@ static int show_table(Table *table, const char *word) { + + static int list_sessions(int argc, char *argv[], void *userdata) { + +- static const struct bus_properties_map map[] = { +- { "IdleHint", "b", NULL, offsetof(SessionStatusInfo, idle_hint) }, +- { "IdleSinceHintMonotonic", "t", NULL, offsetof(SessionStatusInfo, idle_hint_timestamp.monotonic) }, +- { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) }, ++ static const struct bus_properties_map map[] = { ++ { "IdleHint", "b", NULL, offsetof(SessionStatusInfo, idle_hint) }, ++ { "IdleSinceHint", "t", NULL, offsetof(SessionStatusInfo, idle_hint_timestamp) }, ++ { "TTY", "s", NULL, offsetof(SessionStatusInfo, tty) }, + {}, + }; + +@@ -210,7 +210,7 @@ static int list_sessions(int argc, char *argv[], void *userdata) { + return log_error_errno(r, "Failed to add row to table: %m"); + + if (i.idle_hint) +- r = table_add_cell(table, NULL, TABLE_TIMESTAMP_RELATIVE, &i.idle_hint_timestamp.monotonic); ++ r = table_add_cell(table, NULL, TABLE_TIMESTAMP_RELATIVE, &i.idle_hint_timestamp); + else + r = table_add_cell(table, NULL, TABLE_EMPTY, NULL); + if (r < 0) diff --git a/0946-loginctl-also-show-idle-hint-in-session-status.patch b/0946-loginctl-also-show-idle-hint-in-session-status.patch new file mode 100644 index 0000000..f69b6fa --- /dev/null +++ b/0946-loginctl-also-show-idle-hint-in-session-status.patch @@ -0,0 +1,40 @@ +From 0d3f481f791d918380a1b5587529cb8642d3e407 Mon Sep 17 00:00:00 2001 +From: Mike Yuan +Date: Tue, 23 May 2023 18:54:30 +0800 +Subject: [PATCH] loginctl: also show idle hint in session-status + +(cherry picked from commit 82449055af97cf92466dbe132a89c9d889440c3d) + +Related: #2156786 +--- + src/login/loginctl.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/login/loginctl.c b/src/login/loginctl.c +index 1131267015..80d0a302d3 100644 +--- a/src/login/loginctl.c ++++ b/src/login/loginctl.c +@@ -473,6 +473,8 @@ static int print_session_status_info(sd_bus *bus, const char *path, bool *new_li + { "Remote", "b", NULL, offsetof(SessionStatusInfo, remote) }, + { "Timestamp", "t", NULL, offsetof(SessionStatusInfo, timestamp.realtime) }, + { "TimestampMonotonic", "t", NULL, offsetof(SessionStatusInfo, timestamp.monotonic) }, ++ { "IdleHint", "b", NULL, offsetof(SessionStatusInfo, idle_hint) }, ++ { "IdleSinceHint", "t", NULL, offsetof(SessionStatusInfo, idle_hint_timestamp) }, + { "User", "(uo)", prop_map_first_of_struct, offsetof(SessionStatusInfo, uid) }, + { "Seat", "(so)", prop_map_first_of_struct, offsetof(SessionStatusInfo, seat) }, + {} +@@ -571,6 +573,14 @@ static int print_session_status_info(sd_bus *bus, const char *path, bool *new_li + if (i.state) + printf("\t State: %s\n", i.state); + ++ if (i.idle_hint && i.idle_hint_timestamp > 0) { ++ s1 = format_timestamp_relative(since1, sizeof(since1), i.idle_hint_timestamp); ++ s2 = format_timestamp(since2, sizeof(since2), i.idle_hint_timestamp); ++ ++ printf("\t Idle: %s since %s (%s)\n", yes_no(i.idle_hint), s2, s1); ++ } else ++ printf("\t Idle: %s\n", yes_no(i.idle_hint)); ++ + if (i.scope) { + printf("\t Unit: %s\n", i.scope); + show_unit_cgroup(bus, "org.freedesktop.systemd1.Scope", i.scope, i.leader); diff --git a/0947-core-timer-Always-use-inactive_exit_timestamp-if-it-.patch b/0947-core-timer-Always-use-inactive_exit_timestamp-if-it-.patch new file mode 100644 index 0000000..cc9bb1a --- /dev/null +++ b/0947-core-timer-Always-use-inactive_exit_timestamp-if-it-.patch @@ -0,0 +1,46 @@ +From a741d3b8bc23b4be1b83e393ca864983558a730c Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Tue, 23 May 2023 16:24:47 +0200 +Subject: [PATCH] core/timer: Always use inactive_exit_timestamp if it is set + +If we're doing a daemon-reload, we'll be going from TIMER_DEAD => TIMER_WAITING, +so we won't use inactive_exit_timestamp because TIMER_DEAD != UNIT_ACTIVE, even +though inactive_exit_timestamp is serialized/deserialized and will be valid after +the daemon-reload. + +This issue can lead to timers never firing as we'll always calculate the next +elapse based on the current realtime on daemon-reload, so if daemon-reload happens +often enough, the elapse interval will be moved into the future every time, which +means the timer will never trigger. + +To fix the issue, let's always use inactive_exit_timestamp if it is set, and only +fall back to the current realtime if it is not set. + +(cherry picked from commit 6546045fa0bf84737bd8b2e1e8bf7dd3941d8352) + +Resolves: #1719364 +--- + src/core/timer.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/src/core/timer.c b/src/core/timer.c +index 990f05fee4..b80f6d714c 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -368,12 +368,10 @@ static void timer_enter_waiting(Timer *t, bool time_change) { + + if (t->last_trigger.realtime > 0) + b = t->last_trigger.realtime; +- else { +- if (state_translation_table[t->state] == UNIT_ACTIVE) +- b = UNIT(t)->inactive_exit_timestamp.realtime; +- else +- b = ts.realtime; +- } ++ else if (dual_timestamp_is_set(&UNIT(t)->inactive_exit_timestamp)) ++ b = UNIT(t)->inactive_exit_timestamp.realtime; ++ else ++ b = ts.realtime; + + r = calendar_spec_next_usec(v->calendar_spec, b, &v->next_elapse); + if (r < 0) diff --git a/0948-timer-Use-dual_timestamp_is_set-in-one-more-place.patch b/0948-timer-Use-dual_timestamp_is_set-in-one-more-place.patch new file mode 100644 index 0000000..e7518ab --- /dev/null +++ b/0948-timer-Use-dual_timestamp_is_set-in-one-more-place.patch @@ -0,0 +1,25 @@ +From e7c06a10a106068e5bd9f092edbfcc937954a959 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Wed, 24 May 2023 11:41:37 +0200 +Subject: [PATCH] timer: Use dual_timestamp_is_set() in one more place + +(cherry picked from commit e21f75afcd95a46261a36a2614712eff6bc119f4) + +Related: #1719364 +--- + src/core/timer.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/timer.c b/src/core/timer.c +index b80f6d714c..81468d4ca6 100644 +--- a/src/core/timer.c ++++ b/src/core/timer.c +@@ -366,7 +366,7 @@ static void timer_enter_waiting(Timer *t, bool time_change) { + * to that. If we don't, just start from + * the activation time. */ + +- if (t->last_trigger.realtime > 0) ++ if (dual_timestamp_is_set(&t->last_trigger)) + b = t->last_trigger.realtime; + else if (dual_timestamp_is_set(&UNIT(t)->inactive_exit_timestamp)) + b = UNIT(t)->inactive_exit_timestamp.realtime; diff --git a/0949-ci-drop-systemd-stable-from-advanced-commit-linter-c.patch b/0949-ci-drop-systemd-stable-from-advanced-commit-linter-c.patch new file mode 100644 index 0000000..0900c1b --- /dev/null +++ b/0949-ci-drop-systemd-stable-from-advanced-commit-linter-c.patch @@ -0,0 +1,28 @@ +From d55687b7489127b4b6be953c54719f3219e852f6 Mon Sep 17 00:00:00 2001 +From: Jan Macku +Date: Thu, 13 Jul 2023 14:23:51 +0200 +Subject: [PATCH] ci: drop systemd-stable from advanced-commit-linter config + +It's sufficient enough to check only the `systemd/systemd` repo. + +Related to https://github.com/redhat-plumbers-in-action/advanced-commit-linter/issues/62 + +rhel-only + +Related: #2179309 +--- + .github/advanced-commit-linter.yml | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/.github/advanced-commit-linter.yml b/.github/advanced-commit-linter.yml +index 327af0467a..0fb74a9dc8 100644 +--- a/.github/advanced-commit-linter.yml ++++ b/.github/advanced-commit-linter.yml +@@ -2,7 +2,6 @@ policy: + cherry-pick: + upstream: + - github: systemd/systemd +- - github: systemd/systemd-stable + exception: + note: + - rhel-only diff --git a/0950-core-mount-escape-invalid-UTF8-char-in-dbus-reply.patch b/0950-core-mount-escape-invalid-UTF8-char-in-dbus-reply.patch new file mode 100644 index 0000000..c7d466c --- /dev/null +++ b/0950-core-mount-escape-invalid-UTF8-char-in-dbus-reply.patch @@ -0,0 +1,108 @@ +From 048c335acdaaba173574305c9b03677b3fde999f Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Thu, 11 May 2023 19:21:57 +0900 +Subject: [PATCH] core/mount: escape invalid UTF8 char in dbus reply + +When What= or Options= may contain invalid UTF8 chars. + +Replaces aaf7b0e41105d7b7cf30912cdac32820f011a219 (#27541). + +(cherry picked from commit 4804da58536ab7ad46178a03f4d2da49fd8e4ba2) + +Resolves: #2158724 +--- + src/core/dbus-mount.c | 69 +++++++++++++++++++++++++++++++++++-------- + 1 file changed, 57 insertions(+), 12 deletions(-) + +diff --git a/src/core/dbus-mount.c b/src/core/dbus-mount.c +index 3f98d3ecf0..a089b37e04 100644 +--- a/src/core/dbus-mount.c ++++ b/src/core/dbus-mount.c +@@ -9,21 +9,68 @@ + #include "mount.h" + #include "string-util.h" + #include "unit.h" ++#include "utf8.h" ++ ++static int property_get_what( ++ sd_bus *bus, ++ const char *path, ++ const char *interface, ++ const char *property, ++ sd_bus_message *reply, ++ void *userdata, ++ sd_bus_error *error) { ++ ++ _cleanup_free_ char *escaped = NULL; ++ Mount *m = userdata; ++ const char *s = NULL; ++ ++ assert(bus); ++ assert(reply); ++ assert(m); + +-static const char *mount_get_what(const Mount *m) { + if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.what) +- return m->parameters_proc_self_mountinfo.what; +- if (m->from_fragment && m->parameters_fragment.what) +- return m->parameters_fragment.what; +- return NULL; ++ s = m->parameters_proc_self_mountinfo.what; ++ else if (m->from_fragment && m->parameters_fragment.what) ++ s = m->parameters_fragment.what; ++ ++ if (s) { ++ escaped = utf8_escape_invalid(s); ++ if (!escaped) ++ return -ENOMEM; ++ } ++ ++ return sd_bus_message_append_basic(reply, 's', escaped); + } + +-static const char *mount_get_options(const Mount *m) { ++static int property_get_options( ++ sd_bus *bus, ++ const char *path, ++ const char *interface, ++ const char *property, ++ sd_bus_message *reply, ++ void *userdata, ++ sd_bus_error *error) { ++ ++ _cleanup_free_ char *escaped = NULL; ++ Mount *m = userdata; ++ const char *s = NULL; ++ ++ assert(bus); ++ assert(reply); ++ assert(m); ++ + if (m->from_proc_self_mountinfo && m->parameters_proc_self_mountinfo.options) +- return m->parameters_proc_self_mountinfo.options; +- if (m->from_fragment && m->parameters_fragment.options) +- return m->parameters_fragment.options; +- return NULL; ++ s = m->parameters_proc_self_mountinfo.options; ++ else if (m->from_fragment && m->parameters_fragment.options) ++ s = m->parameters_fragment.options; ++ ++ if (s) { ++ escaped = utf8_escape_invalid(s); ++ if (!escaped) ++ return -ENOMEM; ++ } ++ ++ return sd_bus_message_append_basic(reply, 's', escaped); + } + + static const char *mount_get_fstype(const Mount *m) { +@@ -34,8 +81,6 @@ static const char *mount_get_fstype(const Mount *m) { + return NULL; + } + +-static BUS_DEFINE_PROPERTY_GET(property_get_what, "s", Mount, mount_get_what); +-static BUS_DEFINE_PROPERTY_GET(property_get_options, "s", Mount, mount_get_options); + static BUS_DEFINE_PROPERTY_GET(property_get_type, "s", Mount, mount_get_fstype); + static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, mount_result, MountResult); + diff --git a/systemd.spec b/systemd.spec index 65e229b..ff01e9d 100644 --- a/systemd.spec +++ b/systemd.spec @@ -13,7 +13,7 @@ Name: systemd Url: http://www.freedesktop.org/wiki/Software/systemd Version: 239 -Release: 76%{?dist} +Release: 77%{?dist} # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: System and Service Manager @@ -969,6 +969,37 @@ Patch0916: 0916-test-Disable-LUKS-devices-from-initramfs-in-QEMU-tes.patch Patch0917: 0917-pstore-explicitly-set-the-base-when-converting-recor.patch Patch0918: 0918-pstore-avoid-opening-the-dmesg.txt-file-if-not-reque.patch Patch0919: 0919-test-add-a-couple-of-tests-for-systemd-pstore.patch +Patch0920: 0920-ci-update-permissions-for-source-git-automation-work.patch +Patch0921: 0921-sulogin-fix-control-lost-of-the-current-terminal-whe.patch +Patch0922: 0922-parse-util-in-parse_permille-check-negative-earlier.patch +Patch0923: 0923-tree-wide-increase-granularity-of-percent-specificat.patch +Patch0924: 0924-errno-util-introduce-ERRNO_IS_TRANSIENT.patch +Patch0925: 0925-tree-wide-use-ERRNO_IS_TRANSIENT.patch +Patch0926: 0926-libsystemd-ignore-both-EINTR-and-EAGAIN.patch +Patch0927: 0927-sd-bus-handle-EINTR-return-from-bus_poll.patch +Patch0928: 0928-stdio-bridge-don-t-be-bothered-with-EINTR.patch +Patch0929: 0929-sd-netlink-handle-EINTR-from-poll-gracefully-as-succ.patch +Patch0930: 0930-resolved-handle-EINTR-returned-from-fd_wait_for_even.patch +Patch0931: 0931-utmp-wtmp-fix-error-in-case-isatty-fails.patch +Patch0932: 0932-utmp-wtmp-handle-EINTR-gracefully-when-waiting-to-wr.patch +Patch0933: 0933-journal-vacuum-count-size-of-all-journal-files.patch +Patch0934: 0934-resolved-instead-of-closing-DNS-UDP-transaction-fds-.patch +Patch0935: 0935-resolved-close-UDP-socket-when-we-received-a-network.patch +Patch0936: 0936-ci-allow-RHEL-only-labels-to-mark-downstream-only-co.patch +Patch0937: 0937-man-tweak-markup-in-systemd-pstore.service-8.patch +Patch0938: 0938-man-add-.service-suffix-to-systemd-pstore-8.patch +Patch0939: 0939-presets-enable-systemd-pstore.service-by-default.patch +Patch0940: 0940-logind-simplify-code.patch +Patch0941: 0941-format-table-add-TABLE_TIMESTAMP_UTC-and-_RELATIVE.patch +Patch0942: 0942-loginctl-shorten-variable-name.patch +Patch0943: 0943-loginctl-use-bus_map_all_properties.patch +Patch0944: 0944-loginctl-show-session-idle-status-in-list-sessions.patch +Patch0945: 0945-loginctl-list-sessions-fix-timestamp-for-idle-hint.patch +Patch0946: 0946-loginctl-also-show-idle-hint-in-session-status.patch +Patch0947: 0947-core-timer-Always-use-inactive_exit_timestamp-if-it-.patch +Patch0948: 0948-timer-Use-dual_timestamp_is_set-in-one-more-place.patch +Patch0949: 0949-ci-drop-systemd-stable-from-advanced-commit-linter-c.patch +Patch0950: 0950-core-mount-escape-invalid-UTF8-char-in-dbus-reply.patch %ifarch %{ix86} x86_64 aarch64 %global have_gnu_efi 1 @@ -1599,6 +1630,39 @@ fi %files tests -f .file-list-tests %changelog +* Mon Jul 17 2023 systemd maintenance team - 239-77 +- ci: update permissions for source-git automation workflows (#2179309) +- sulogin: fix control lost of the current terminal when default.target is rescue.target (#2169932) +- parse-util: in parse_permille() check negative earlier (#2178179) +- tree-wide: increase granularity of percent specifications all over the place to permille (#2178179) +- errno-util: introduce ERRNO_IS_TRANSIENT() (#2172846) +- tree-wide: use ERRNO_IS_TRANSIENT() (#2172846) +- libsystemd: ignore both EINTR and EAGAIN (#2172846) +- sd-bus: handle -EINTR return from bus_poll() (#2172846) +- stdio-bridge: don't be bothered with EINTR (#2172846) +- sd-netlink: handle EINTR from poll() gracefully, as success (#2172846) +- resolved: handle -EINTR returned from fd_wait_for_event() better (#2172846) +- utmp-wtmp: fix error in case isatty() fails (#2172846) +- utmp-wtmp: handle EINTR gracefully when waiting to write to tty (#2172846) +- journal-vacuum: count size of all journal files (#2180380) +- resolved: instead of closing DNS UDP transaction fds right-away, add them to a socket "graveyard" (#2156751) +- resolved: close UDP socket when we received a network error on it (#2156751) +- ci: allow RHEL-only labels to mark downstream-only commits (#2179309) +- man: tweak markup in systemd-pstore.service(8) (#2217786) +- man: add .service suffix to systemd-pstore(8) (#2217786) +- presets: enable systemd-pstore.service by default (#2217786) +- logind: simplify code (#2209328) +- format-table: add TABLE_TIMESTAMP_UTC and _RELATIVE (#2156786) +- loginctl: shorten variable name (#2156786) +- loginctl: use bus_map_all_properties (#2156786) +- loginctl: show session idle status in list-sessions (#2156786) +- loginctl: list-sessions: fix timestamp for idle hint (#2156786) +- loginctl: also show idle hint in session-status (#2156786) +- core/timer: Always use inactive_exit_timestamp if it is set (#1719364) +- timer: Use dual_timestamp_is_set() in one more place (#1719364) +- ci: drop systemd-stable from advanced-commit-linter config (#2179309) +- core/mount: escape invalid UTF8 char in dbus reply (#2158724) + * Thu May 18 2023 systemd maintenance team - 239-76 - ci(Mergify): drop requirements on linting workflows (#2179309) - ci: workflow for gathering metadata for source-git automation (#2179309)