systemd-239-77

Resolves: #1719364,#2156751,#2156786,#2158724,#2169932,#2172846,#2178179,#2179309,#2180380,#2209328,#2217786
This commit is contained in:
Jan Macku 2023-07-17 10:29:16 +02:00
parent 577d68e7cb
commit a0e2ca72a7
32 changed files with 2732 additions and 1 deletions

View File

@ -0,0 +1,29 @@
From ab5a221daca2783b73fd286f5410dbec905cabfa Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
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:

View File

@ -0,0 +1,130 @@
From 30cbb55a8d9fedf07d5c9d792849b723b856cd62 Mon Sep 17 00:00:00 2001
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
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;
}

View File

@ -0,0 +1,49 @@
From cb99c3e54af1ba7c6cf1cd99d61546f5aa9423cb Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
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;
}

View File

@ -0,0 +1,165 @@
From 30343fc0ba66dd7a513de736c7708702ec5400be Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
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)

View File

@ -0,0 +1,31 @@
From 5a1d30b9a775a7bbac55752abdc10ed5383d209f Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
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),

View File

@ -0,0 +1,545 @@
From da79f303ec02fdb9a1c07e0fe48e0aaf4bd09e1b Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
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");

View File

@ -0,0 +1,75 @@
From 4cbf11180cc6c6792f541a861f3309c34c156f4b Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
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;

View File

@ -0,0 +1,90 @@
From b1075e8b3ecb9e0770dd46331ce8517ea152e1ca Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
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;
+ }
}
}

View File

@ -0,0 +1,28 @@
From 9ddb41dd9dc3bac57d6c3e05700485ee98df3e17 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
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;
}

View File

@ -0,0 +1,36 @@
From da367d5c87c039f4d1250c12097a5fb16f179a70 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
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) {

View File

@ -0,0 +1,79 @@
From 1316ec49f209e31799d42d114bd7f35d5acbe097 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
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;
}

View File

@ -0,0 +1,28 @@
From c57daab191c6551ac757576fcf7df45fd9790b6b Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
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);

View File

@ -0,0 +1,52 @@
From 3590a9c5ce038bc56cdded426156cbd278903c86 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
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;

View File

@ -0,0 +1,90 @@
From 947296a00d17ef115f4097aa86a8c6f1bfc8bf58 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
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);

View File

@ -0,0 +1,365 @@
From fc8959efebc662f4050700cc1ed2798750b15b73 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
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);

View File

@ -0,0 +1,26 @@
From 648fe0097229c7ae46a6b5911521cef27a726cbe Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
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;
}

View File

@ -0,0 +1,24 @@
From 950cc2c5109f269561d3c0fdd020c6bf7cb561e1 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
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: #?'

View File

@ -0,0 +1,39 @@
From e3d4d6b36c111c5273ce5da124116f1c98b10d9d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
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 @@
<para>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.</para>
@@ -59,9 +59,9 @@
debugging.</para>
<para>The <command>systemd-pstore</command> executable does the actual work. Upon starting,
- the <filename>pstore.conf</filename> is read to obtain options, then the /sys/fs/pstore
+ the <filename>pstore.conf</filename> file is read and the <filename>/sys/fs/pstore</filename>
directory contents are processed according to the options. Pstore files are written to the
- journal, and optionally saved into /var/lib/systemd/pstore.</para>
+ journal, and optionally saved into <filename>/var/lib/systemd/pstore</filename>.</para>
</refsect1>
<refsect1>

View File

@ -0,0 +1,61 @@
From ff17baae0631f42f59be6e425943c7181c6c5c18 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
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">
<refentryinfo>
- <title>systemd-pstore</title>
+ <title>systemd-pstore.service</title>
<productname>systemd</productname>
</refentryinfo>
<refmeta>
- <refentrytitle>systemd-pstore</refentrytitle>
+ <refentrytitle>systemd-pstore.service</refentrytitle>
<manvolnum>8</manvolnum>
</refmeta>
<refnamediv>
- <refname>systemd-pstore</refname>
<refname>systemd-pstore.service</refname>
- <refpurpose>Tool to archive contents of the persistent storage filesytem</refpurpose>
+ <refname>systemd-pstore</refname>
+ <refpurpose>A service to archive contents of pstore</refpurpose>
</refnamediv>
<refsynopsisdiv>

View File

@ -0,0 +1,26 @@
From 36d9a1a50f80322b24ff5756b8fb89a07363dfd7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
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

View File

@ -0,0 +1,54 @@
From bf5b87db9785b86fadbd2b5e97e4883cbe51797d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
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);

View File

@ -0,0 +1,89 @@
From 2fb7d36caf560e4ce57265673da7a518d7a5348f Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
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,

View File

@ -0,0 +1,39 @@
From c88514d4de20ceeeea2028917087e2710ea419b2 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
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)

View File

@ -0,0 +1,137 @@
From 5d2f49451c5e697d6e3548cfc9087ef3c16aa969 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
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;

View File

@ -0,0 +1,80 @@
From 0d1082f3cf9d4028ac69c22e9dad2adb51ee910d Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
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");
}

View File

@ -0,0 +1,53 @@
From ea3d85221a7ba83ff1d9612d29cc8ca3e054f2fa Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
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)

View File

@ -0,0 +1,40 @@
From 0d3f481f791d918380a1b5587529cb8642d3e407 Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
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);

View File

@ -0,0 +1,46 @@
From a741d3b8bc23b4be1b83e393ca864983558a730c Mon Sep 17 00:00:00 2001
From: Daan De Meyer <daan.j.demeyer@gmail.com>
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)

View File

@ -0,0 +1,25 @@
From e7c06a10a106068e5bd9f092edbfcc937954a959 Mon Sep 17 00:00:00 2001
From: Daan De Meyer <daan.j.demeyer@gmail.com>
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;

View File

@ -0,0 +1,28 @@
From d55687b7489127b4b6be953c54719f3219e852f6 Mon Sep 17 00:00:00 2001
From: Jan Macku <jamacku@redhat.com>
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

View File

@ -0,0 +1,108 @@
From 048c335acdaaba173574305c9b03677b3fde999f Mon Sep 17 00:00:00 2001
From: Yu Watanabe <watanabe.yu+github@gmail.com>
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);

View File

@ -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 <systemd-maint@redhat.com> - 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 <systemd-maint@redhat.com> - 239-76
- ci(Mergify): drop requirements on linting workflows (#2179309)
- ci: workflow for gathering metadata for source-git automation (#2179309)