Version 248-rc4

This commit is contained in:
Yu Watanabe 2021-03-18 23:04:02 +09:00 committed by Yu Watanabe
parent 22e7d02418
commit 45fafe9791
10 changed files with 8 additions and 1746 deletions

View File

@ -1,123 +0,0 @@
From 3552ac862497bdb5ea73639851bbfd114b795fa2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Thu, 11 Mar 2021 20:41:36 +0100
Subject: [PATCH] Revert "sd-event: make use of epoll_pwait2() for greater time
accuracy"
This reverts commit 798445ab84cff51bde7fcf936f0fb19c37cf858c.
Unfortunately this causes test-event to hang. 32 bit architectures seem
affected: i686 and arm32 in fedora koji. 32 bit build of test-event hangs
reliably under valgrind:
$ PKG_CONFIG_LIBDIR=/usr/lib/pkgconfig meson build-32 -Dc_args=-m32 -Dc_link_args=-m32 -Dcpp_args=-m32 -Dcpp_link_args=-m32 && ninja -C build-32 test-event && valgrind build/test-event
---
src/libsystemd/sd-event/sd-event.c | 73 ++++++------------------------
1 file changed, 14 insertions(+), 59 deletions(-)
diff --git a/src/libsystemd/sd-event/sd-event.c b/src/libsystemd/sd-event/sd-event.c
index 8ab9d419af..69d9c5e780 100644
--- a/src/libsystemd/sd-event/sd-event.c
+++ b/src/libsystemd/sd-event/sd-event.c
@@ -3781,59 +3781,9 @@ pending:
return r;
}
-static int epoll_wait_usec(
- int fd,
- struct epoll_event *events,
- int maxevents,
- usec_t timeout) {
-
- static bool epoll_pwait2_absent = false;
- int r, msec;
-
- /* A wrapper that uses epoll_pwait2() if available, and falls back to epoll_wait() if not */
-
- if (!epoll_pwait2_absent && timeout != USEC_INFINITY) {
- struct timespec ts;
-
- r = epoll_pwait2(fd,
- events,
- maxevents,
- timespec_store(&ts, timeout),
- NULL);
- if (r >= 0)
- return r;
- if (!ERRNO_IS_NOT_SUPPORTED(r) && !ERRNO_IS_PRIVILEGE(r))
- return -errno; /* Only fallback to old epoll_wait() if the syscall is masked or not
- * supported. */
-
- epoll_pwait2_absent = true;
- }
-
- if (timeout == USEC_INFINITY)
- msec = -1;
- else {
- usec_t k;
-
- k = DIV_ROUND_UP(timeout, USEC_PER_MSEC);
- if (k >= INT_MAX)
- msec = INT_MAX; /* Saturate */
- else
- msec = (int) k;
- }
-
- r = epoll_wait(fd,
- events,
- maxevents,
- msec);
- if (r < 0)
- return -errno;
-
- return r;
-}
-
_public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
size_t n_event_queue, m;
- int r;
+ int r, msec;
assert_return(e, -EINVAL);
assert_return(e = event_resolve(e), -ENOPKG);
@@ -3852,16 +3802,21 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
/* If we still have inotify data buffered, then query the other fds, but don't wait on it */
if (e->inotify_data_buffered)
- timeout = 0;
+ msec = 0;
+ else
+ msec = timeout == (uint64_t) -1 ? -1 : (int) DIV_ROUND_UP(timeout, USEC_PER_MSEC);
for (;;) {
- r = epoll_wait_usec(e->epoll_fd, e->event_queue, e->event_queue_allocated, timeout);
- if (r == -EINTR) {
- e->state = SD_EVENT_PENDING;
- return 1;
- }
- if (r < 0)
+ r = epoll_wait(e->epoll_fd, e->event_queue, e->event_queue_allocated, msec);
+ if (r < 0) {
+ if (errno == EINTR) {
+ e->state = SD_EVENT_PENDING;
+ return 1;
+ }
+
+ r = -errno;
goto finish;
+ }
m = (size_t) r;
@@ -3874,7 +3829,7 @@ _public_ int sd_event_wait(sd_event *e, uint64_t timeout) {
if (!GREEDY_REALLOC(e->event_queue, e->event_queue_allocated, e->event_queue_allocated + n_event_queue))
return -ENOMEM;
- timeout = 0;
+ msec = 0;
}
triple_timestamp_get(&e->timestamp);
--
2.30.1

View File

@ -1,169 +0,0 @@
From aee1d734a5034d47005a339ec5b2b39583795039 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Wed, 16 Dec 2020 15:56:44 +0100
Subject: [PATCH] test-login: skip consistency checks when logind is not active
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
There are two ways in swich sd_login_* functions acquire data:
some are derived from the cgroup path, but others use the data serialized
by logind.
When the tests are executed under Fedora's mock, without systemd-spawn
but instead in a traditional chroot, test-login gets confused:
the "outside" cgroup path is visible, so sd_pid_get_unit() and
sd_pid_get_session() work, but sd_session_is_active() and other functions
that need logind data fail.
Such a buildroot setup is fairly bad, but it can be encountered in the wild, so
let's just skip the tests in that case.
/* Information printed is from the live system */
sd_pid_get_unit(0, …) → "session-237.scope"
sd_pid_get_user_unit(0, …) → "n/a"
sd_pid_get_slice(0, …) → "user-1000.slice"
sd_pid_get_session(0, …) → "237"
sd_pid_get_owner_uid(0, …) → 1000
sd_pid_get_cgroup(0, …) → "/user.slice/user-1000.slice/session-237.scope"
sd_uid_get_display(1000, …) → "(null)"
sd_uid_get_sessions(1000, …) → [0] ""
sd_uid_get_seats(1000, …) → [0] ""
Assertion 'r >= 0' failed at src/libsystemd/sd-login/test-login.c:104, function test_login(). Aborting.
---
src/libsystemd/sd-login/test-login.c | 98 +++++++++++++++-------------
1 file changed, 52 insertions(+), 46 deletions(-)
diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c
index 5b2ff93e1c..f762b8475b 100644
--- a/src/libsystemd/sd-login/test-login.c
+++ b/src/libsystemd/sd-login/test-login.c
@@ -112,68 +112,74 @@ static void test_login(void) {
if (session) {
r = sd_session_is_active(session);
- assert_se(r >= 0);
- log_info("sd_session_is_active(\"%s\") → %s", session, yes_no(r));
+ if (r == -ENXIO)
+ log_notice("sd_session_is_active failed with ENXIO, it seems logind is not running.");
+ else {
+ /* All those tests will fail with ENXIO, so let's skip them. */
- r = sd_session_is_remote(session);
- assert_se(r >= 0);
- log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r));
+ assert_se(r >= 0);
+ log_info("sd_session_is_active(\"%s\") → %s", session, yes_no(r));
- r = sd_session_get_state(session, &state);
- assert_se(r == 0);
- log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state);
+ r = sd_session_is_remote(session);
+ assert_se(r >= 0);
+ log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r));
- assert_se(sd_session_get_uid(session, &u) >= 0);
- log_info("sd_session_get_uid(\"%s\") → "UID_FMT, session, u);
- assert_se(u == u2);
+ r = sd_session_get_state(session, &state);
+ assert_se(r == 0);
+ log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state);
- assert_se(sd_session_get_type(session, &type) >= 0);
- log_info("sd_session_get_type(\"%s\") → \"%s\"", session, type);
+ assert_se(sd_session_get_uid(session, &u) >= 0);
+ log_info("sd_session_get_uid(\"%s\") → "UID_FMT, session, u);
+ assert_se(u == u2);
- assert_se(sd_session_get_class(session, &class) >= 0);
- log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class);
+ assert_se(sd_session_get_type(session, &type) >= 0);
+ log_info("sd_session_get_type(\"%s\") → \"%s\"", session, type);
- r = sd_session_get_display(session, &display);
- assert_se(IN_SET(r, 0, -ENODATA));
- log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display));
+ assert_se(sd_session_get_class(session, &class) >= 0);
+ log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class);
- r = sd_session_get_remote_user(session, &remote_user);
- assert_se(IN_SET(r, 0, -ENODATA));
- log_info("sd_session_get_remote_user(\"%s\") → \"%s\"",
- session, strna(remote_user));
+ r = sd_session_get_display(session, &display);
+ assert_se(IN_SET(r, 0, -ENODATA));
+ log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display));
- r = sd_session_get_remote_host(session, &remote_host);
- assert_se(IN_SET(r, 0, -ENODATA));
- log_info("sd_session_get_remote_host(\"%s\") → \"%s\"",
- session, strna(remote_host));
+ r = sd_session_get_remote_user(session, &remote_user);
+ assert_se(IN_SET(r, 0, -ENODATA));
+ log_info("sd_session_get_remote_user(\"%s\") → \"%s\"",
+ session, strna(remote_user));
- r = sd_session_get_seat(session, &seat);
- if (r >= 0) {
- assert_se(seat);
+ r = sd_session_get_remote_host(session, &remote_host);
+ assert_se(IN_SET(r, 0, -ENODATA));
+ log_info("sd_session_get_remote_host(\"%s\") → \"%s\"",
+ session, strna(remote_host));
- log_info("sd_session_get_seat(\"%s\") → \"%s\"", session, seat);
+ r = sd_session_get_seat(session, &seat);
+ if (r >= 0) {
+ assert_se(seat);
+
+ log_info("sd_session_get_seat(\"%s\") → \"%s\"", session, seat);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
- r = sd_seat_can_multi_session(seat);
+ r = sd_seat_can_multi_session(seat);
#pragma GCC diagnostic pop
- assert_se(r == 1);
- log_info("sd_session_can_multi_seat(\"%s\") → %s", seat, yes_no(r));
+ assert_se(r == 1);
+ log_info("sd_session_can_multi_seat(\"%s\") → %s", seat, yes_no(r));
- r = sd_seat_can_tty(seat);
- assert_se(r >= 0);
- log_info("sd_session_can_tty(\"%s\") → %s", seat, yes_no(r));
+ r = sd_seat_can_tty(seat);
+ assert_se(r >= 0);
+ log_info("sd_session_can_tty(\"%s\") → %s", seat, yes_no(r));
- r = sd_seat_can_graphical(seat);
- assert_se(r >= 0);
- log_info("sd_session_can_graphical(\"%s\") → %s", seat, yes_no(r));
- } else {
- log_info_errno(r, "sd_session_get_seat(\"%s\"): %m", session);
- assert_se(r == -ENODATA);
+ r = sd_seat_can_graphical(seat);
+ assert_se(r >= 0);
+ log_info("sd_session_can_graphical(\"%s\") → %s", seat, yes_no(r));
+ } else {
+ log_info_errno(r, "sd_session_get_seat(\"%s\"): %m", session);
+ assert_se(r == -ENODATA);
+ }
+
+ assert_se(sd_uid_get_state(u, &state2) == 0);
+ log_info("sd_uid_get_state("UID_FMT", …) → %s", u, state2);
}
-
- assert_se(sd_uid_get_state(u, &state2) == 0);
- log_info("sd_uid_get_state("UID_FMT", …) → %s", u, state2);
}
if (seat) {
@@ -214,7 +220,7 @@ static void test_login(void) {
assert_se(sd_get_seats(NULL) == r);
r = sd_seat_get_active(NULL, &t, NULL);
- assert_se(IN_SET(r, 0, -ENODATA));
+ assert_se(IN_SET(r, 0, -ENODATA, -ENXIO));
log_info("sd_seat_get_active(NULL, …) (active session on current seat) → %s / \"%s\"", e(r), strnull(t));
free(t);

View File

@ -1,70 +0,0 @@
From 2e9d763e7cbeb33954bbe3f96fd94de2cd62edf7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Thu, 12 Nov 2020 14:28:24 +0100
Subject: [PATCH] test-path-util: do not fail if the fd_is_mount_point check
fails
This test fails on i686 and ppc64le in koji:
/* test_path */
Assertion 'fd_is_mount_point(fd, "/", 0) > 0' failed at src/test/test-path-util.c:85, function test_path(). Aborting.
I guess some permission error is the most likely.
---
src/test/test-path-util.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c
index f4f8d0550b..be428334f3 100644
--- a/src/test/test-path-util.c
+++ b/src/test/test-path-util.c
@@ -40,8 +40,6 @@ static void test_path_simplify(const char *in, const char *out, const char *out_
}
static void test_path(void) {
- _cleanup_close_ int fd = -1;
-
log_info("/* %s */", __func__);
test_path_compare("/goo", "/goo", 0);
@@ -80,10 +78,6 @@ static void test_path(void) {
assert_se(streq(basename("/aa///file..."), "file..."));
assert_se(streq(basename("file.../"), ""));
- fd = open("/", O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY);
- assert_se(fd >= 0);
- assert_se(fd_is_mount_point(fd, "/", 0) > 0);
-
test_path_simplify("aaa/bbb////ccc", "aaa/bbb/ccc", "aaa/bbb/ccc");
test_path_simplify("//aaa/.////ccc", "/aaa/./ccc", "/aaa/ccc");
test_path_simplify("///", "/", "/");
@@ -120,6 +114,22 @@ static void test_path(void) {
assert_se(!path_equal_ptr(NULL, "/a"));
}
+static void test_path_is_mountpoint(void) {
+ _cleanup_close_ int fd = -1;
+ int r;
+
+ log_info("/* %s */", __func__);
+
+ fd = open("/", O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY);
+ assert_se(fd >= 0);
+
+ r = fd_is_mount_point(fd, "/", 0);
+ if (r < 0)
+ log_warning_errno(r, "Failed to check if / is a mount point, ignoring: %m");
+ else
+ assert_se(r == 1);
+}
+
static void test_path_equal_root(void) {
/* Nail down the details of how path_equal("/", ...) works. */
@@ -714,6 +724,7 @@ int main(int argc, char **argv) {
test_print_paths();
test_path();
+ test_path_is_mountpoint();
test_path_equal_root();
test_find_executable_full();
test_find_executable(argv[0]);

View File

@ -1,33 +0,0 @@
From e8bca4ba55f855260eda684a16e8feb5f20b1deb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Thu, 12 Nov 2020 15:06:12 +0100
Subject: [PATCH] test-path-util: ignore test failure
---
src/test/test-path-util.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/src/test/test-path-util.c b/src/test/test-path-util.c
index be428334f3..207c659b8b 100644
--- a/src/test/test-path-util.c
+++ b/src/test/test-path-util.c
@@ -120,14 +120,17 @@ static void test_path_is_mountpoint(void) {
log_info("/* %s */", __func__);
+ (void) system("uname -a");
+ (void) system("mountpoint /");
+
fd = open("/", O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY);
assert_se(fd >= 0);
r = fd_is_mount_point(fd, "/", 0);
if (r < 0)
log_warning_errno(r, "Failed to check if / is a mount point, ignoring: %m");
- else
- assert_se(r == 1);
+ else if (r == 0)
+ log_warning("/ is not a mountpoint?");
}
static void test_path_equal_root(void) {

View File

@ -1,495 +0,0 @@
From e0ae456a554d0fce250f9a009c561b97f20c41f8 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 5 Mar 2021 17:47:45 +0100
Subject: [PATCH 1/6] dns-query: export CNAME_MAX, so that we can use it in
other files, too
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Let's rename it a bit, to be more explanatory while exporting it.
(And let's bump the CNAME limit to 16 — 8 just sounded so little)
---
src/resolve/resolved-dns-query.c | 3 +--
src/resolve/resolved-dns-query.h | 2 ++
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c
index 7554d1e82f4..aa9d65d4a82 100644
--- a/src/resolve/resolved-dns-query.c
+++ b/src/resolve/resolved-dns-query.c
@@ -10,7 +10,6 @@
#include "resolved-etc-hosts.h"
#include "string-util.h"
-#define CNAME_MAX 8
#define QUERIES_MAX 2048
#define AUXILIARY_QUERIES_MAX 64
@@ -977,7 +976,7 @@ static int dns_query_cname_redirect(DnsQuery *q, const DnsResourceRecord *cname)
assert(q);
q->n_cname_redirects++;
- if (q->n_cname_redirects > CNAME_MAX)
+ if (q->n_cname_redirects > CNAME_REDIRECT_MAX)
return -ELOOP;
r = dns_question_cname_redirect(q->question_idna, cname, &nq_idna);
diff --git a/src/resolve/resolved-dns-query.h b/src/resolve/resolved-dns-query.h
index ea296167b61..5d12171b0a1 100644
--- a/src/resolve/resolved-dns-query.h
+++ b/src/resolve/resolved-dns-query.h
@@ -145,3 +145,5 @@ static inline uint64_t dns_query_reply_flags_make(DnsQuery *q) {
dns_query_fully_confidential(q)) |
(q->answer_query_flags & (SD_RESOLVED_FROM_MASK|SD_RESOLVED_SYNTHETIC));
}
+
+#define CNAME_REDIRECT_MAX 16
From d29958261a3df80f5cf0e98b1cd307790a92b13b Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 5 Mar 2021 17:48:43 +0100
Subject: [PATCH 2/6] resolved: tighten checks in
dns_resource_record_get_cname_target()
Let's refuse to consider CNAME/DNAME replies matching for RR types where
that is not really conceptually allow (i.e. on CNAME/DNAME lookups
themselves).
(And add a similar check to dns_resource_key_match_cname_or_dname() too,
which implements a smilar match)
---
src/resolve/resolved-dns-rr.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/src/resolve/resolved-dns-rr.c b/src/resolve/resolved-dns-rr.c
index 823117e5c92..7e76e0c6cc0 100644
--- a/src/resolve/resolved-dns-rr.c
+++ b/src/resolve/resolved-dns-rr.c
@@ -244,6 +244,9 @@ int dns_resource_key_match_cname_or_dname(const DnsResourceKey *key, const DnsRe
if (cname->class != key->class && key->class != DNS_CLASS_ANY)
return 0;
+ if (!dns_type_may_redirect(key->type))
+ return 0;
+
if (cname->type == DNS_TYPE_CNAME)
r = dns_name_equal(dns_resource_key_name(key), dns_resource_key_name(cname));
else if (cname->type == DNS_TYPE_DNAME)
@@ -1743,9 +1746,16 @@ int dns_resource_record_get_cname_target(DnsResourceKey *key, DnsResourceRecord
assert(key);
assert(cname);
+ /* Checks if the RR `cname` is a CNAME/DNAME RR that matches the specified `key`. If so, returns the
+ * target domain. If not, returns -EUNATCH */
+
if (key->class != cname->key->class && key->class != DNS_CLASS_ANY)
return -EUNATCH;
+ if (!dns_type_may_redirect(key->type)) /* This key type is not subject to CNAME/DNAME redirection?
+ * Then let's refuse right-away */
+ return -EUNATCH;
+
if (cname->key->type == DNS_TYPE_CNAME) {
r = dns_name_equal(dns_resource_key_name(key),
dns_resource_key_name(cname->key));
From 4838dc4f2be1d29da9ce9a930c48717a4491d70e Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 5 Mar 2021 17:53:31 +0100
Subject: [PATCH 3/6] resolved: handle multiple CNAME redirects in a single
reply from upstream
www.netflix.com responds with a chain of CNAMEs in the same packet.
Let's handle that properly (so far we only followed CNAMEs a single step
when in the same packet)
Fixes: #18819
---
src/resolve/resolved-dns-stub.c | 105 +++++++++++++++++---------------
1 file changed, 57 insertions(+), 48 deletions(-)
diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c
index c2734e57b9b..c3a28d390a4 100644
--- a/src/resolve/resolved-dns-stub.c
+++ b/src/resolve/resolved-dns-stub.c
@@ -162,79 +162,88 @@ static int dns_stub_collect_answer_by_question(
bool with_rrsig) { /* Add RRSIG RR matching each RR */
_cleanup_(dns_resource_key_unrefp) DnsResourceKey *redirected_key = NULL;
+ unsigned n_cname_redirects = 0;
DnsAnswerItem *item;
int r;
assert(reply);
- /* Copies all RRs from 'answer' into 'reply', if they match 'question'. */
+ /* Copies all RRs from 'answer' into 'reply', if they match 'question'. There might be direct and
+ * indirect matches (i.e. via CNAME/DNAME). If they have an indirect one, remember where we need to
+ * go, and restart the loop */
+
+ for (;;) {
+ _cleanup_(dns_resource_key_unrefp) DnsResourceKey *next_redirected_key = NULL;
+
+ DNS_ANSWER_FOREACH_ITEM(item, answer) {
+ DnsResourceKey *k = NULL;
+
+ if (redirected_key) {
+ /* There was a redirect in this packet, let's collect all matching RRs for the redirect */
+ r = dns_resource_key_match_rr(redirected_key, item->rr, NULL);
+ if (r < 0)
+ return r;
+
+ k = redirected_key;
+ } else if (question) {
+ /* We have a question, let's see if this RR matches it */
+ r = dns_question_matches_rr(question, item->rr, NULL);
+ if (r < 0)
+ return r;
+
+ k = question->keys[0];
+ } else
+ r = 1; /* No question, everything matches */
- DNS_ANSWER_FOREACH_ITEM(item, answer) {
- if (question) {
- r = dns_question_matches_rr(question, item->rr, NULL);
- if (r < 0)
- return r;
if (r == 0) {
_cleanup_free_ char *target = NULL;
/* OK, so the RR doesn't directly match. Let's see if the RR is a matching
* CNAME or DNAME */
- r = dns_resource_record_get_cname_target(
- question->keys[0],
- item->rr,
- &target);
+ assert(k);
+
+ r = dns_resource_record_get_cname_target(k, item->rr, &target);
if (r == -EUNATCH)
continue; /* Not a CNAME/DNAME or doesn't match */
if (r < 0)
return r;
- dns_resource_key_unref(redirected_key);
+ /* Oh, wow, this is a redirect. Let's remember where this points, and store
+ * it in 'next_redirected_key'. Once we finished iterating through the rest
+ * of the RR's we'll start again, with the redirected RR key. */
+
+ n_cname_redirects++;
+ if (n_cname_redirects > CNAME_REDIRECT_MAX) /* don't loop forever */
+ return -ELOOP;
+
+ dns_resource_key_unref(next_redirected_key);
/* There can only be one CNAME per name, hence no point in storing more than one here */
- redirected_key = dns_resource_key_new(question->keys[0]->class, question->keys[0]->type, target);
- if (!redirected_key)
+ next_redirected_key = dns_resource_key_new(k->class, k->type, target);
+ if (!next_redirected_key)
return -ENOMEM;
}
- }
- /* Mask the section info, we want the primary answers to always go without section info, so
- * that it is added to the answer section when we synthesize a reply. */
+ /* Mask the section info, we want the primary answers to always go without section info, so
+ * that it is added to the answer section when we synthesize a reply. */
- r = reply_add_with_rrsig(
- reply,
- item->rr,
- item->ifindex,
- item->flags & ~DNS_ANSWER_MASK_SECTIONS,
- item->rrsig,
- with_rrsig);
- if (r < 0)
- return r;
- }
-
- if (!redirected_key)
- return 0;
-
- /* This is a CNAME/DNAME answer. In this case also append where the redirections point to to the main
- * answer section */
-
- DNS_ANSWER_FOREACH_ITEM(item, answer) {
+ r = reply_add_with_rrsig(
+ reply,
+ item->rr,
+ item->ifindex,
+ item->flags & ~DNS_ANSWER_MASK_SECTIONS,
+ item->rrsig,
+ with_rrsig);
+ if (r < 0)
+ return r;
+ }
- r = dns_resource_key_match_rr(redirected_key, item->rr, NULL);
- if (r < 0)
- return r;
- if (r == 0)
- continue;
+ if (!next_redirected_key)
+ break;
- r = reply_add_with_rrsig(
- reply,
- item->rr,
- item->ifindex,
- item->flags & ~DNS_ANSWER_MASK_SECTIONS,
- item->rrsig,
- with_rrsig);
- if (r < 0)
- return r;
+ dns_resource_key_unref(redirected_key);
+ redirected_key = TAKE_PTR(next_redirected_key);
}
return 0;
From 39005e187095062718621880e5d8ad707ac8fe8f Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 5 Mar 2021 18:01:27 +0100
Subject: [PATCH 4/6] resolved: split out helper that checks whether we shall
reply with EDNS0 DO
Just some refactoring, no actual code changes.
---
src/resolve/resolved-dns-stub.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c
index c3a28d390a4..b4df5837aad 100644
--- a/src/resolve/resolved-dns-stub.c
+++ b/src/resolve/resolved-dns-stub.c
@@ -561,6 +561,19 @@ static int dns_stub_send(
return 0;
}
+static int dns_stub_reply_with_edns0_do(DnsQuery *q) {
+ assert(q);
+
+ /* Reply with DNSSEC DO set? Only if client supports it; and we did any DNSSEC verification
+ * ourselves, or consider the data fully authenticated because we generated it locally, or the client
+ * set cd */
+
+ return DNS_PACKET_DO(q->request_packet) &&
+ (q->answer_dnssec_result >= 0 || /* we did proper DNSSEC validation … */
+ dns_query_fully_authenticated(q) || /* … or we considered it authentic otherwise … */
+ DNS_PACKET_CD(q->request_packet)); /* … or client set CD */
+}
+
static int dns_stub_send_reply(
DnsQuery *q,
int rcode) {
@@ -571,14 +584,7 @@ static int dns_stub_send_reply(
assert(q);
- /* Reply with DNSSEC DO set? Only if client supports it; and we did any DNSSEC verification
- * ourselves, or consider the data fully authenticated because we generated it locally, or
- * the client set cd */
- edns0_do =
- DNS_PACKET_DO(q->request_packet) &&
- (q->answer_dnssec_result >= 0 || /* we did proper DNSSEC validation … */
- dns_query_fully_authenticated(q) || /* … or we considered it authentic otherwise … */
- DNS_PACKET_CD(q->request_packet)); /* … or client set CD */
+ edns0_do = dns_stub_reply_with_edns0_do(q); /* let's check if we shall reply with EDNS0 DO? */
r = dns_stub_assign_sections(
q,
From b97fc57178932689bdcb9030e1e2bf299d49ce0b Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 5 Mar 2021 16:50:04 +0100
Subject: [PATCH 5/6] resolved: fully follow CNAMEs in the DNS stub after all
In 2f4d8e577ca7bc51fb054b8c2c8dd57c2e188a41 I argued that following
CNAMEs in the stub is not necessary anymore. However, I think it' better
to revert to the status quo ante and follow it after all, given it is
easy for us and makes sure our D-Bus/varlink replies are more similar to
our DNS stub replies that way, and we save clients potential roundtrips.
Hence, whenever we hit a CNAME/DNAME redirect, let's restart the query
like we do for the D-Bus/Varlink case, and collect replies as we go.
---
src/resolve/resolved-dns-stub.c | 38 +++++++++++++++++++++++----------
1 file changed, 27 insertions(+), 11 deletions(-)
diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c
index b4df5837aad..85c4eda469c 100644
--- a/src/resolve/resolved-dns-stub.c
+++ b/src/resolve/resolved-dns-stub.c
@@ -586,13 +586,6 @@ static int dns_stub_send_reply(
edns0_do = dns_stub_reply_with_edns0_do(q); /* let's check if we shall reply with EDNS0 DO? */
- r = dns_stub_assign_sections(
- q,
- q->request_packet->question,
- edns0_do);
- if (r < 0)
- return log_debug_errno(r, "Failed to assign sections: %m");
-
r = dns_stub_make_reply_packet(
&reply,
DNS_PACKET_PAYLOAD_SIZE_MAX(q->request_packet),
@@ -743,13 +736,37 @@ static void dns_stub_query_complete(DnsQuery *q) {
}
}
- /* Note that we don't bother with following CNAMEs here. We propagate the authoritative/additional
- * sections from the upstream answer however, hence if the upstream server collected that information
- * already we don't have to collect it ourselves anymore. */
+ /* Take all data from the current reply, and merge it into the three reply sections we are building
+ * up. We do this before processing CNAME redirects, so that we gradually build up our sections, and
+ * and keep adding all RRs in the CNAME chain. */
+ r = dns_stub_assign_sections(
+ q,
+ q->request_packet->question,
+ dns_stub_reply_with_edns0_do(q));
+ if (r < 0) {
+ log_debug_errno(r, "Failed to assign sections: %m");
+ dns_query_free(q);
+ return;
+ }
switch (q->state) {
case DNS_TRANSACTION_SUCCESS:
+ r = dns_query_process_cname(q);
+ if (r == -ELOOP) { /* CNAME loop, let's send what we already have */
+ log_debug_errno(r, "Detected CNAME loop, returning what we already have.");
+ (void) dns_stub_send_reply(q, q->answer_rcode);
+ break;
+ }
+ if (r < 0) {
+ log_debug_errno(r, "Failed to process CNAME: %m");
+ break;
+ }
+ if (r == DNS_QUERY_RESTARTED)
+ return;
+
+ _fallthrough_;
+
case DNS_TRANSACTION_RCODE_FAILURE:
(void) dns_stub_send_reply(q, q->answer_rcode);
break;
@@ -888,7 +905,6 @@ static void dns_stub_process_query(Manager *m, DnsStubListenerExtra *l, DnsStrea
r = dns_query_new(m, &q, p->question, p->question, NULL, 0,
SD_RESOLVED_PROTOCOLS_ALL|
SD_RESOLVED_NO_SEARCH|
- SD_RESOLVED_NO_CNAME|
(DNS_PACKET_DO(p) ? SD_RESOLVED_REQUIRE_PRIMARY : 0)|
SD_RESOLVED_CLAMP_TTL);
if (r < 0) {
From 5d7da51ee1d27e86a0487a4b2abc3cfb0ed44c23 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Fri, 5 Mar 2021 18:20:59 +0100
Subject: [PATCH 6/6] resolved: when synthesizing stub replies from multiple
upstream packet, let's avoid RR duplicates
If we synthesize a stub reply from multiple upstream packet (i.e. a
series of CNAME/DNAME redirects), it might happen that we add the same
RR to a different reply section at a different CNAME/DNAME redirect
chain element. Let's clean this up once we are about to send the reply
message to the client: let's remove sections from "lower-priority"
sections when they are already listed in a "higher-priority" section.
---
src/resolve/resolved-dns-answer.c | 25 +++++++++++++++++++++++++
src/resolve/resolved-dns-answer.h | 1 +
src/resolve/resolved-dns-stub.c | 20 ++++++++++++++++++++
3 files changed, 46 insertions(+)
diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c
index ce3cbce308d..a667ab5ede4 100644
--- a/src/resolve/resolved-dns-answer.c
+++ b/src/resolve/resolved-dns-answer.c
@@ -640,6 +640,31 @@ int dns_answer_remove_by_rr(DnsAnswer **a, DnsResourceRecord *rm) {
return 1;
}
+int dns_answer_remove_by_answer_keys(DnsAnswer **a, DnsAnswer *b) {
+ _cleanup_(dns_resource_key_unrefp) DnsResourceKey *prev = NULL;
+ DnsAnswerItem *item;
+ int r;
+
+ /* Removes all items from '*a' that have a matching key in 'b' */
+
+ DNS_ANSWER_FOREACH_ITEM(item, b) {
+
+ if (prev && dns_resource_key_equal(item->rr->key, prev)) /* Skip this one, we already looked at it */
+ continue;
+
+ r = dns_answer_remove_by_key(a, item->rr->key);
+ if (r < 0)
+ return r;
+
+ /* Let's remember this entry's RR key, to optimize the loop a bit: if we have an RRset with
+ * more than one item then we don't need to remove the key multiple times */
+ dns_resource_key_unref(prev);
+ prev = dns_resource_key_ref(item->rr->key);
+ }
+
+ return 0;
+}
+
int dns_answer_copy_by_key(
DnsAnswer **a,
DnsAnswer *source,
diff --git a/src/resolve/resolved-dns-answer.h b/src/resolve/resolved-dns-answer.h
index c2fd0c078f4..7d19eee4e2b 100644
--- a/src/resolve/resolved-dns-answer.h
+++ b/src/resolve/resolved-dns-answer.h
@@ -68,6 +68,7 @@ int dns_answer_reserve_or_clone(DnsAnswer **a, size_t n_free);
int dns_answer_remove_by_key(DnsAnswer **a, const DnsResourceKey *key);
int dns_answer_remove_by_rr(DnsAnswer **a, DnsResourceRecord *rr);
+int dns_answer_remove_by_answer_keys(DnsAnswer **a, DnsAnswer *b);
int dns_answer_copy_by_key(DnsAnswer **a, DnsAnswer *source, const DnsResourceKey *key, DnsAnswerFlags or_flags, DnsResourceRecord *rrsig);
int dns_answer_move_by_key(DnsAnswer **to, DnsAnswer **from, const DnsResourceKey *key, DnsAnswerFlags or_flags, DnsResourceRecord *rrsig);
diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c
index 85c4eda469c..8e781dd7389 100644
--- a/src/resolve/resolved-dns-stub.c
+++ b/src/resolve/resolved-dns-stub.c
@@ -574,6 +574,24 @@ static int dns_stub_reply_with_edns0_do(DnsQuery *q) {
DNS_PACKET_CD(q->request_packet)); /* … or client set CD */
}
+static void dns_stub_suppress_duplicate_section_rrs(DnsQuery *q) {
+ /* If we follow a CNAME/DNAME chain we might end up populating our sections with redundant RRs
+ * because we built up the sections from multiple reply packets (one from each CNAME/DNAME chain
+ * element). E.g. it could be that an RR that was included in the first reply's additional section
+ * ends up being relevant as main answer in a subsequent reply in the chain. Let's clean this up, and
+ * remove everything in the "higher priority" sections from the "lower priority" sections.
+ *
+ * Note that this removal matches by RR keys instead of the full RRs. This is because RRsets should
+ * always end up in one section fully or not at all, but never be split among sections.
+ *
+ * Specifically: we remove ANSWER section RRs from the AUTHORITATIVE and ADDITIONAL sections, as well
+ * as AUTHORITATIVE section RRs from the ADDITIONAL section. */
+
+ dns_answer_remove_by_answer_keys(&q->reply_authoritative, q->reply_answer);
+ dns_answer_remove_by_answer_keys(&q->reply_additional, q->reply_answer);
+ dns_answer_remove_by_answer_keys(&q->reply_additional, q->reply_authoritative);
+}
+
static int dns_stub_send_reply(
DnsQuery *q,
int rcode) {
@@ -594,6 +612,8 @@ static int dns_stub_send_reply(
if (r < 0)
return log_debug_errno(r, "Failed to build reply packet: %m");
+ dns_stub_suppress_duplicate_section_rrs(q);
+
r = dns_stub_add_reply_packet_body(
reply,
q->reply_answer,

View File

@ -1,154 +0,0 @@
From 8b0f54c9290564e8c27c9c8ac464cdcc2c659ad5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Sat, 6 Mar 2021 19:06:08 +0100
Subject: [PATCH 1/3] pid1: return varlink error on the right connection
---
src/core/core-varlink.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/core/core-varlink.c b/src/core/core-varlink.c
index d695106658b..b3df8cd893c 100644
--- a/src/core/core-varlink.c
+++ b/src/core/core-varlink.c
@@ -142,7 +142,7 @@ static int vl_method_subscribe_managed_oom_cgroups(
/* We only take one subscriber for this method so return an error if there's already an existing one.
* This shouldn't happen since systemd-oomd is the only client of this method. */
if (FLAGS_SET(flags, VARLINK_METHOD_MORE) && m->managed_oom_varlink_request)
- return varlink_error(m->managed_oom_varlink_request, VARLINK_ERROR_SUBSCRIPTION_TAKEN, NULL);
+ return varlink_error(link, VARLINK_ERROR_SUBSCRIPTION_TAKEN, NULL);
r = json_build(&arr, JSON_BUILD_EMPTY_ARRAY);
if (r < 0)
@@ -188,6 +188,7 @@ static int vl_method_subscribe_managed_oom_cgroups(
if (!FLAGS_SET(flags, VARLINK_METHOD_MORE))
return varlink_reply(link, v);
+ assert(!m->managed_oom_varlink_request);
m->managed_oom_varlink_request = varlink_ref(link);
return varlink_notify(m->managed_oom_varlink_request, v);
}
@@ -475,8 +476,7 @@ void manager_varlink_done(Manager *m) {
assert(m);
/* Send the final message if we still have a subscribe request open. */
- if (m->managed_oom_varlink_request)
- m->managed_oom_varlink_request = varlink_close_unref(m->managed_oom_varlink_request);
+ m->managed_oom_varlink_request = varlink_close_unref(m->managed_oom_varlink_request);
m->varlink_server = varlink_server_unref(m->varlink_server);
}
From 39ad3f1c092b5dffcbb4b1d12eb9ca407f010a3c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Sun, 7 Mar 2021 16:42:35 +0100
Subject: [PATCH 2/3] varlink: avoid using dangling ref in
varlink_close_unref()
Fixes #18025, https://bugzilla.redhat.com/show_bug.cgi?id=1931034.
We drop the reference stored in Manager.managed_oom_varlink_request in two code paths:
vl_disconnect() which is installed as a disconnect callback, and in manager_varlink_done().
But we also make a disconnect from manager_varlink_done(). So we end up with the following
call stack:
(gdb) bt
0 vl_disconnect (s=0x112c7b0, link=0xea0070, userdata=0xe9bcc0) at ../src/core/core-varlink.c:414
1 0x00007f1366e9d5ac in varlink_detach_server (v=0xea0070) at ../src/shared/varlink.c:1210
2 0x00007f1366e9d664 in varlink_close (v=0xea0070) at ../src/shared/varlink.c:1228
3 0x00007f1366e9d6b5 in varlink_close_unref (v=0xea0070) at ../src/shared/varlink.c:1240
4 0x0000000000524629 in manager_varlink_done (m=0xe9bcc0) at ../src/core/core-varlink.c:479
5 0x000000000048ef7b in manager_free (m=0xe9bcc0) at ../src/core/manager.c:1357
6 0x000000000042602c in main (argc=5, argv=0x7fff439c43d8) at ../src/core/main.c:2909
When we enter vl_disconnect(), m->managed_oom_varlink_request.n_ref==1.
When we exit from vl_discconect(), m->managed_oom_varlink_request==NULL. But
varlink_close_unref() has a copy of the pointer in *v. When we continue executing
varlink_close_unref(), this pointer is dangling, and the call to varlink_unref()
is done with an invalid pointer.
---
src/shared/varlink.c | 33 +++++++++++++++++++++++++--------
1 file changed, 25 insertions(+), 8 deletions(-)
diff --git a/src/shared/varlink.c b/src/shared/varlink.c
index 31128e02e06..6ed72075ba5 100644
--- a/src/shared/varlink.c
+++ b/src/shared/varlink.c
@@ -1206,8 +1206,9 @@ int varlink_close(Varlink *v) {
varlink_set_state(v, VARLINK_DISCONNECTED);
- /* Let's take a reference first, since varlink_detach_server() might drop the final (dangling) ref
- * which would destroy us before we can call varlink_clear() */
+ /* Let's take a reference first, since varlink_detach_server() might drop the final ref from the
+ * disconnect callback, which would invalidate the pointer we are holding before we can call
+ * varlink_clear(). */
varlink_ref(v);
varlink_detach_server(v);
varlink_clear(v);
@@ -1220,17 +1221,33 @@ Varlink* varlink_close_unref(Varlink *v) {
if (!v)
return NULL;
- (void) varlink_close(v);
+ /* A reference is given to us to be destroyed. But when calling varlink_close(), a callback might
+ * also drop a reference. We allow this, and will hold a temporary reference to the object to make
+ * sure that the object still exists when control returns to us. If there's just one reference
+ * remaining after varlink_close(), even though there were at least two right before, we'll handle
+ * that gracefully instead of crashing.
+ *
+ * In other words, this call drops the donated reference, but if the internal call to varlink_close()
+ * dropped a reference to, we don't drop the reference afain. This allows the caller to say:
+ * global_object->varlink = varlink_close_unref(global_object->varlink);
+ * even though there is some callback which has access to global_object and may drop the reference
+ * stored in global_object->varlink. Without this step, the same code would have to be written as:
+ * Varlink *t = TAKE_PTR(global_object->varlink);
+ * varlink_close_unref(t);
+ */
+ /* n_ref >= 1 */
+ varlink_ref(v); /* n_ref >= 2 */
+ varlink_close(v); /* n_ref >= 1 */
+ if (v->n_ref > 1)
+ v->n_ref--; /* n_ref >= 1 */
return varlink_unref(v);
}
Varlink* varlink_flush_close_unref(Varlink *v) {
- if (!v)
- return NULL;
+ if (v)
+ varlink_flush(v);
- (void) varlink_flush(v);
- (void) varlink_close(v);
- return varlink_unref(v);
+ return varlink_close_unref(v);
}
static int varlink_enqueue_json(Varlink *v, JsonVariant *m) {
From a19c1a4baaa1dadc80885e3ad41f19a6c6c450fd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Mon, 8 Mar 2021 09:21:25 +0100
Subject: [PATCH 3/3] oomd: "downgrade" level of message
PID1 already logs about the service being started, so this line isn't necessary
in normal use. Also, by the time it is emitted, the service has already
signalled readiness, so let's not say "starting" but "started".
---
src/oom/oomd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/oom/oomd.c b/src/oom/oomd.c
index 674d53fdcfe..6e2a5889d1e 100644
--- a/src/oom/oomd.c
+++ b/src/oom/oomd.c
@@ -170,7 +170,7 @@ static int run(int argc, char *argv[]) {
notify_msg = notify_start(NOTIFY_READY, NOTIFY_STOPPING);
- log_info("systemd-oomd starting%s!", arg_dry_run ? " in dry run mode" : "");
+ log_debug("systemd-oomd started%s.", arg_dry_run ? " in dry run mode" : "");
r = sd_event_loop(m->event);
if (r < 0)

View File

@ -1,593 +0,0 @@
From 1499a0a99a0765b4b1b56f56d6712324e740911f Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 15 Mar 2021 20:47:28 +0100
Subject: [PATCH 01/12] resolved: add new helper dns_answer_min_ttl()
---
src/resolve/resolved-dns-answer.c | 19 +++++++++++++++++++
src/resolve/resolved-dns-answer.h | 2 ++
2 files changed, 21 insertions(+)
diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c
index a667ab5ede4..5fbff81c255 100644
--- a/src/resolve/resolved-dns-answer.c
+++ b/src/resolve/resolved-dns-answer.c
@@ -963,3 +963,22 @@ void dns_answer_randomize(DnsAnswer *a) {
SWAP_TWO(a->items[i], a->items[k]);
}
}
+
+uint32_t dns_answer_min_ttl(DnsAnswer *a) {
+ uint32_t ttl = UINT32_MAX;
+ DnsResourceRecord *rr;
+
+ /* Return the smallest TTL of all RRs in this answer */
+
+ DNS_ANSWER_FOREACH(rr, a) {
+ /* Don't consider OPT (where the TTL field is used for other purposes than an actual TTL) */
+
+ if (dns_type_is_pseudo(rr->key->type) ||
+ dns_class_is_pseudo(rr->key->class))
+ continue;
+
+ ttl = MIN(ttl, rr->ttl);
+ }
+
+ return ttl;
+}
diff --git a/src/resolve/resolved-dns-answer.h b/src/resolve/resolved-dns-answer.h
index 7d19eee4e2b..447da5d6cc3 100644
--- a/src/resolve/resolved-dns-answer.h
+++ b/src/resolve/resolved-dns-answer.h
@@ -87,6 +87,8 @@ void dns_answer_dump(DnsAnswer *answer, FILE *f);
void dns_answer_randomize(DnsAnswer *a);
+uint32_t dns_answer_min_ttl(DnsAnswer *a);
+
DEFINE_TRIVIAL_CLEANUP_FUNC(DnsAnswer*, dns_answer_unref);
#define _DNS_ANSWER_FOREACH(q, kk, a) \
From 3b7006cb44dd2860cb1b2e652e318d196dddf312 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 15 Mar 2021 20:47:53 +0100
Subject: [PATCH 02/12] resolved: rebreak a few comments
---
src/resolve/resolved-dns-cache.c | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
index 0bf320df880..23612a5c353 100644
--- a/src/resolve/resolved-dns-cache.c
+++ b/src/resolve/resolved-dns-cache.c
@@ -320,11 +320,9 @@ static usec_t calculate_until(DnsResourceRecord *rr, uint32_t nsec_ttl, usec_t t
ttl = MIN(rr->ttl, nsec_ttl);
if (rr->key->type == DNS_TYPE_SOA && use_soa_minimum) {
- /* If this is a SOA RR, and it is requested, clamp to
- * the SOA's minimum field. This is used when we do
- * negative caching, to determine the TTL for the
- * negative caching entry. See RFC 2308, Section
- * 5. */
+ /* If this is a SOA RR, and it is requested, clamp to the SOA's minimum field. This is used
+ * when we do negative caching, to determine the TTL for the negative caching entry. See RFC
+ * 2308, Section 5. */
if (ttl > rr->soa.minimum)
ttl = rr->soa.minimum;
@@ -337,8 +335,7 @@ static usec_t calculate_until(DnsResourceRecord *rr, uint32_t nsec_ttl, usec_t t
if (rr->expiry != USEC_INFINITY) {
usec_t left;
- /* Make use of the DNSSEC RRSIG expiry info, if we
- * have it */
+ /* Make use of the DNSSEC RRSIG expiry info, if we have it */
left = LESS_BY(rr->expiry, now(CLOCK_REALTIME));
if (u > left)
@@ -785,9 +782,8 @@ int dns_cache_put(
if (r > 0)
return 0;
- /* But not if it has a matching CNAME/DNAME (the negative
- * caching will be done on the canonical name, not on the
- * alias) */
+ /* But not if it has a matching CNAME/DNAME (the negative caching will be done on the canonical name,
+ * not on the alias) */
r = dns_answer_find_cname_or_dname(answer, key, NULL, NULL);
if (r < 0)
goto fail;
@@ -803,8 +799,7 @@ int dns_cache_put(
if (r == 0 && !weird_rcode)
return 0;
if (r > 0) {
- /* Refuse using the SOA data if it is unsigned, but the key is
- * signed */
+ /* Refuse using the SOA data if it is unsigned, but the key is signed */
if (FLAGS_SET(query_flags, SD_RESOLVED_AUTHENTICATED) &&
(flags & DNS_ANSWER_AUTHENTICATED) == 0)
return 0;
From 77db3caee36d0241bf2153f56579a9fb952962f1 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 15 Mar 2021 20:48:18 +0100
Subject: [PATCH 03/12] resolved: use dns_answer_isempty() where appropriate
---
src/resolve/resolved-dns-cache.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
index 23612a5c353..8edbd5fee94 100644
--- a/src/resolve/resolved-dns-cache.c
+++ b/src/resolve/resolved-dns-cache.c
@@ -693,7 +693,7 @@ int dns_cache_put(
* short time.) */
if (IN_SET(rcode, DNS_RCODE_SUCCESS, DNS_RCODE_NXDOMAIN)) {
- if (dns_answer_size(answer) <= 0) {
+ if (dns_answer_isempty(answer)) {
if (key) {
char key_str[DNS_RESOURCE_KEY_STRING_MAX];
From b12058e8f96a9b490e2b1ce98f81ced182add577 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 15 Mar 2021 20:48:35 +0100
Subject: [PATCH 04/12] resolved: fix indentation
---
src/resolve/resolved-dns-cache.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
index 8edbd5fee94..09fb8e2c883 100644
--- a/src/resolve/resolved-dns-cache.c
+++ b/src/resolve/resolved-dns-cache.c
@@ -808,7 +808,7 @@ int dns_cache_put(
if (cache_mode == DNS_CACHE_MODE_NO_NEGATIVE) {
char key_str[DNS_RESOURCE_KEY_STRING_MAX];
log_debug("Not caching negative entry for: %s, cache mode set to no-negative",
- dns_resource_key_to_string(key, key_str, sizeof key_str));
+ dns_resource_key_to_string(key, key_str, sizeof key_str));
return 0;
}
From f6d80c361d6a51972d4df264a190bf01ef7af624 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 15 Mar 2021 21:15:30 +0100
Subject: [PATCH 05/12] resolved: drop unnecessary local variable
---
src/resolve/resolved-dns-cache.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
index 09fb8e2c883..0f40e0e40f4 100644
--- a/src/resolve/resolved-dns-cache.c
+++ b/src/resolve/resolved-dns-cache.c
@@ -416,7 +416,7 @@ static int dns_cache_put_positive(
_cleanup_(dns_cache_item_freep) DnsCacheItem *i = NULL;
DnsCacheItem *existing;
char key_str[DNS_RESOURCE_KEY_STRING_MAX];
- int r, k;
+ int r;
assert(c);
assert(rr);
@@ -430,9 +430,9 @@ static int dns_cache_put_positive(
/* New TTL is 0? Delete this specific entry... */
if (rr->ttl <= 0) {
- k = dns_cache_remove_by_rr(c, rr);
+ r = dns_cache_remove_by_rr(c, rr);
log_debug("%s: %s",
- k > 0 ? "Removed zero TTL entry from cache" : "Not caching zero TTL cache entry",
+ r > 0 ? "Removed zero TTL entry from cache" : "Not caching zero TTL cache entry",
dns_resource_key_to_string(rr->key, key_str, sizeof key_str));
return 0;
}
From b974211acbe419170fc56a317a1d55d07c7cb686 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 15 Mar 2021 21:18:32 +0100
Subject: [PATCH 06/12] resolved: take shortest TTL of all of RRs in answer as
cache lifetime
We nowadays cache full answer RRset combinations instead of just the
exact matching rrset. This means we should not cache RRs that are not
immediate answers to our question for longer then their own RRs. Or in
other words: let's determine the shortest TTL of all RRs in the whole
answer, and use that as cache lifetime.
---
src/resolve/resolved-dns-cache.c | 60 +++++++++++++++++++++++---------
1 file changed, 44 insertions(+), 16 deletions(-)
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
index 0f40e0e40f4..db2361ae363 100644
--- a/src/resolve/resolved-dns-cache.c
+++ b/src/resolve/resolved-dns-cache.c
@@ -312,13 +312,19 @@ static DnsCacheItem* dns_cache_get(DnsCache *c, DnsResourceRecord *rr) {
return NULL;
}
-static usec_t calculate_until(DnsResourceRecord *rr, uint32_t nsec_ttl, usec_t timestamp, bool use_soa_minimum) {
+static usec_t calculate_until(
+ DnsResourceRecord *rr,
+ uint32_t min_ttl,
+ uint32_t nsec_ttl,
+ usec_t timestamp,
+ bool use_soa_minimum) {
+
uint32_t ttl;
usec_t u;
assert(rr);
- ttl = MIN(rr->ttl, nsec_ttl);
+ ttl = MIN(min_ttl, nsec_ttl);
if (rr->key->type == DNS_TYPE_SOA && use_soa_minimum) {
/* If this is a SOA RR, and it is requested, clamp to the SOA's minimum field. This is used
* when we do negative caching, to determine the TTL for the negative caching entry. See RFC
@@ -351,6 +357,7 @@ static void dns_cache_item_update_positive(
DnsResourceRecord *rr,
DnsAnswer *answer,
DnsPacket *full_packet,
+ uint32_t min_ttl,
uint64_t query_flags,
bool shared_owner,
DnssecResult dnssec_result,
@@ -387,7 +394,7 @@ static void dns_cache_item_update_positive(
dns_packet_unref(i->full_packet);
i->full_packet = full_packet;
- i->until = calculate_until(rr, UINT32_MAX, timestamp, false);
+ i->until = calculate_until(rr, min_ttl, UINT32_MAX, timestamp, false);
i->query_flags = query_flags & CACHEABLE_QUERY_FLAGS;
i->shared_owner = shared_owner;
i->dnssec_result = dnssec_result;
@@ -414,8 +421,9 @@ static int dns_cache_put_positive(
const union in_addr_union *owner_address) {
_cleanup_(dns_cache_item_freep) DnsCacheItem *i = NULL;
- DnsCacheItem *existing;
char key_str[DNS_RESOURCE_KEY_STRING_MAX];
+ DnsCacheItem *existing;
+ uint32_t min_ttl;
int r;
assert(c);
@@ -428,8 +436,15 @@ static int dns_cache_put_positive(
if (dns_type_is_pseudo(rr->key->type))
return 0;
+ /* Determine the minimal TTL of all RRs in the answer plus the one by the main RR we are supposed to
+ * cache. Since we cache whole answers to questions we should never return answers where only some
+ * RRs are still valid, hence find the lowest here */
+ min_ttl = dns_answer_min_ttl(answer);
+ if (rr)
+ min_ttl = MIN(min_ttl, rr->ttl);
+
/* New TTL is 0? Delete this specific entry... */
- if (rr->ttl <= 0) {
+ if (min_ttl <= 0) {
r = dns_cache_remove_by_rr(c, rr);
log_debug("%s: %s",
r > 0 ? "Removed zero TTL entry from cache" : "Not caching zero TTL cache entry",
@@ -446,6 +461,7 @@ static int dns_cache_put_positive(
rr,
answer,
full_packet,
+ min_ttl,
query_flags,
shared_owner,
dnssec_result,
@@ -473,7 +489,7 @@ static int dns_cache_put_positive(
.rr = dns_resource_record_ref(rr),
.answer = dns_answer_ref(answer),
.full_packet = dns_packet_ref(full_packet),
- .until = calculate_until(rr, UINT32_MAX, timestamp, false),
+ .until = calculate_until(rr, min_ttl, UINT32_MAX, timestamp, false),
.query_flags = query_flags & CACHEABLE_QUERY_FLAGS,
.shared_owner = shared_owner,
.dnssec_result = dnssec_result,
@@ -575,9 +591,12 @@ static int dns_cache_put_negative(
.full_packet = dns_packet_ref(full_packet),
};
+ /* Determine how long to cache this entry. In case we have some RRs in the answer use the lowest TTL
+ * of any of them. Typically that's the SOA's TTL, which is OK, but could possibly be lower because
+ * of some other RR. Let's better take the lowest option here than a needlessly high one */
i->until =
i->type == DNS_CACHE_RCODE ? timestamp + CACHE_TTL_STRANGE_RCODE_USEC :
- calculate_until(soa, nsec_ttl, timestamp, true);
+ calculate_until(soa, dns_answer_min_ttl(answer), nsec_ttl, timestamp, true);
if (i->type == DNS_CACHE_NXDOMAIN) {
/* NXDOMAIN entries should apply equally to all types, so we use ANY as
@@ -1046,21 +1065,30 @@ int dns_cache_lookup(
DnsAnswerItem *item;
DNS_ANSWER_FOREACH_ITEM(item, j->answer) {
- r = answer_add_clamp_ttl(&answer, item->rr, item->ifindex, item->flags, item->rrsig, query_flags, j->until, current);
+ r = answer_add_clamp_ttl(
+ &answer,
+ item->rr,
+ item->ifindex,
+ item->flags,
+ item->rrsig,
+ query_flags,
+ j->until,
+ current);
if (r < 0)
return r;
}
}
} else if (j->rr) {
- r = answer_add_clamp_ttl(&answer,
- j->rr,
- j->ifindex,
- FLAGS_SET(j->query_flags, SD_RESOLVED_AUTHENTICATED) ? DNS_ANSWER_AUTHENTICATED : 0,
- NULL,
- query_flags,
- j->until,
- current);
+ r = answer_add_clamp_ttl(
+ &answer,
+ j->rr,
+ j->ifindex,
+ FLAGS_SET(j->query_flags, SD_RESOLVED_AUTHENTICATED) ? DNS_ANSWER_AUTHENTICATED : 0,
+ NULL,
+ query_flags,
+ j->until,
+ current);
if (r < 0)
return r;
}
From a1acc6e332b05f6a5167bf9d0bc0657794e1342c Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 15 Mar 2021 21:18:52 +0100
Subject: [PATCH 07/12] resolved: let's tweak how we calculate TTL left
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When responding from DNS cache, let's slightly tweak how the TTL is
lowered: as before let's round down when converting from our internal µs
to the external seconds. (This is preferable, since records should
better be cached too short instead of too long.) Let's avoid rounding
down to zero though, since that has special semantics in many cases (in
particular mDNS). Let's just use 1s in that case.
---
src/resolve/resolved-dns-cache.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/src/resolve/resolved-dns-cache.c b/src/resolve/resolved-dns-cache.c
index db2361ae363..9b2e7115c0a 100644
--- a/src/resolve/resolved-dns-cache.c
+++ b/src/resolve/resolved-dns-cache.c
@@ -937,9 +937,18 @@ static int answer_add_clamp_ttl(
assert(rr);
if (FLAGS_SET(query_flags, SD_RESOLVED_CLAMP_TTL)) {
+ uint32_t left_ttl;
+
+ /* Let's determine how much time is left for this cache entry. Note that we round down, but
+ * clamp this to be 1s at minimum, since we usually want records to remain cached better too
+ * short a time than too long a time, but otoh don't want to return 0 ever, since that has
+ * special semantics in various contexts — in particular in mDNS */
+
+ left_ttl = MAX(1U, LESS_BY(until, current) / USEC_PER_SEC);
+
patched = dns_resource_record_ref(rr);
- r = dns_resource_record_clamp_ttl(&patched, LESS_BY(until, current) / USEC_PER_SEC);
+ r = dns_resource_record_clamp_ttl(&patched, left_ttl);
if (r < 0)
return r;
@@ -947,7 +956,7 @@ static int answer_add_clamp_ttl(
if (rrsig) {
patched_rrsig = dns_resource_record_ref(rrsig);
- r = dns_resource_record_clamp_ttl(&patched_rrsig, LESS_BY(until, current) / USEC_PER_SEC);
+ r = dns_resource_record_clamp_ttl(&patched_rrsig, left_ttl);
if (r < 0)
return r;
From c4d98c3acc5901fad4a9a8e2ecd7cf9ad7b8ecb0 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 15 Mar 2021 21:36:42 +0100
Subject: [PATCH 08/12] resolved: use DNS_ANSWER_MASK_SECTIONS where
appropriate
---
src/resolve/resolved-dns-stub.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c
index 8e781dd7389..f8d4767e536 100644
--- a/src/resolve/resolved-dns-stub.c
+++ b/src/resolve/resolved-dns-stub.c
@@ -275,7 +275,7 @@ static int dns_stub_collect_answer_by_section(
dns_type_is_dnssec(item->rr->key->type))
continue;
- if (((item->flags ^ section) & (DNS_ANSWER_SECTION_ANSWER|DNS_ANSWER_SECTION_AUTHORITY|DNS_ANSWER_SECTION_ADDITIONAL)) != 0)
+ if (((item->flags ^ section) & DNS_ANSWER_MASK_SECTIONS) != 0)
continue;
r = reply_add_with_rrsig(
From 567aa5c87b4a177cd4a6ef3ed8d6814839a4ffd8 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 15 Mar 2021 22:14:43 +0100
Subject: [PATCH 09/12] resolved: show TTLs in answer dump
---
src/resolve/resolved-dns-answer.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c
index 5fbff81c255..a032ac157e0 100644
--- a/src/resolve/resolved-dns-answer.c
+++ b/src/resolve/resolved-dns-answer.c
@@ -879,9 +879,8 @@ void dns_answer_dump(DnsAnswer *answer, FILE *f) {
}
fputs(t, f);
-
- if (item->ifindex != 0 || item->rrsig || item->flags != 0)
- fputs("\t;", f);
+ fputs("\t;", f);
+ fprintf(f, " ttl=%" PRIu32, item->rr->ttl);
if (item->ifindex != 0)
fprintf(f, " ifindex=%i", item->ifindex);
From 1414b67e0d9515c23221cecbb5323d45ea2020b1 Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 15 Mar 2021 22:15:06 +0100
Subject: [PATCH 10/12] resolved: add helper for dumping DnsQuestion, similar
to what we have for DnsAnswer
---
src/resolve/resolved-dns-question.c | 18 ++++++++++++++++++
src/resolve/resolved-dns-question.h | 2 ++
2 files changed, 20 insertions(+)
diff --git a/src/resolve/resolved-dns-question.c b/src/resolve/resolved-dns-question.c
index 047170899db..ef409326304 100644
--- a/src/resolve/resolved-dns-question.c
+++ b/src/resolve/resolved-dns-question.c
@@ -445,3 +445,21 @@ int dns_question_new_service(
return 0;
}
+
+/*
+ * This function is not used in the code base, but is useful when debugging. Do not delete.
+ */
+void dns_question_dump(DnsQuestion *question, FILE *f) {
+ DnsResourceKey *k;
+
+ if (!f)
+ f = stdout;
+
+ DNS_QUESTION_FOREACH(k, question) {
+ char buf[DNS_RESOURCE_KEY_STRING_MAX];
+
+ fputc('\t', f);
+ fputs(dns_resource_key_to_string(k, buf, sizeof(buf)), f);
+ fputc('\n', f);
+ }
+}
diff --git a/src/resolve/resolved-dns-question.h b/src/resolve/resolved-dns-question.h
index a6444b0baf9..8f9a84c82d9 100644
--- a/src/resolve/resolved-dns-question.h
+++ b/src/resolve/resolved-dns-question.h
@@ -33,6 +33,8 @@ int dns_question_is_equal(DnsQuestion *a, DnsQuestion *b);
int dns_question_cname_redirect(DnsQuestion *q, const DnsResourceRecord *cname, DnsQuestion **ret);
+void dns_question_dump(DnsQuestion *q, FILE *f);
+
const char *dns_question_first_name(DnsQuestion *q);
static inline size_t dns_question_size(DnsQuestion *q) {
From a7c0291c104cdd9d5ae2fe3c5855273bbadae13e Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 15 Mar 2021 22:15:18 +0100
Subject: [PATCH 11/12] resolved: match CNAME replies to right question
Previously by mistake we'd always match every single reply we get in a
CNAME chain to the original question from the stub client. That's
broken, we need to test it against the CNAME query we are currently
looking at.
The effect of this incorrect matching was that we'd assign the RRs to
the wrong section since we'd assume they'd be auxiliary answers instead
of primary answers.
Fixes: #18972
---
src/resolve/resolved-dns-stub.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/resolve/resolved-dns-stub.c b/src/resolve/resolved-dns-stub.c
index f8d4767e536..b6d14b9305e 100644
--- a/src/resolve/resolved-dns-stub.c
+++ b/src/resolve/resolved-dns-stub.c
@@ -761,7 +761,7 @@ static void dns_stub_query_complete(DnsQuery *q) {
* and keep adding all RRs in the CNAME chain. */
r = dns_stub_assign_sections(
q,
- q->request_packet->question,
+ dns_query_question_for_protocol(q, DNS_PROTOCOL_DNS),
dns_stub_reply_with_edns0_do(q));
if (r < 0) {
log_debug_errno(r, "Failed to assign sections: %m");
From b1eea703e01da1e280e179fb119449436a0c9b8e Mon Sep 17 00:00:00 2001
From: Lennart Poettering <lennart@poettering.net>
Date: Mon, 15 Mar 2021 23:26:46 +0100
Subject: [PATCH 12/12] resolved: don't flush answer RRs on CNAME redirect too
early
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When doing a CNAME/DNAME redirect let's first check if the answer we
already have fully answers the redirected question already. If so, let's
use that. If not, let's properly restart things.
This simply removes one call to dns_answer_reset() that was placed too
early: instead of resetting when we detect a CNAME/DNAME redirect, do so
only after checking if the answer we already have doesn't match the
reply, and then decide to *actually* follow it. Or in other words: rely
on the dns_answer_reset() call in dns_query_go() which we'll call to
actually begin with the redirected question.
This fixes an optimization path which was broken back in 7820b320eaa608748f66f8105621640cf80e483a.
(This doesn't really matter as much as one might think, since our cache
stepped in anyway and answered the questions before going back to the
network. However, this adds noise if RRs with very short TTLs are cached
which some CDNs do and is of course relavant when people turn off
the local cache.)
---
src/resolve/resolved-dns-query.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/resolve/resolved-dns-query.c b/src/resolve/resolved-dns-query.c
index aa9d65d4a82..e4386c402ac 100644
--- a/src/resolve/resolved-dns-query.c
+++ b/src/resolve/resolved-dns-query.c
@@ -1019,7 +1019,9 @@ static int dns_query_cname_redirect(DnsQuery *q, const DnsResourceRecord *cname)
q->question_utf8 = TAKE_PTR(nq_utf8);
dns_query_unref_candidates(q);
- dns_query_reset_answer(q);
+
+ /* Note that we do *not* reset the answer here, because the answer we previously got might already
+ * include everything we need, let's check that first */
q->state = DNS_TRANSACTION_NULL;
@@ -1069,8 +1071,7 @@ int dns_query_process_cname(DnsQuery *q) {
if (r < 0)
return r;
- /* Let's see if the answer can already answer the new
- * redirected question */
+ /* Let's see if the answer can already answer the new redirected question */
r = dns_query_process_cname(q);
if (r != DNS_QUERY_NOMATCH)
return r;

View File

@ -1,102 +0,0 @@
From 9cc6a94790eecfc808335b759355a4005d66f6e3 Mon Sep 17 00:00:00 2001
From: "Jonathan G. Underwood" <jonathan.underwood@gmail.com>
Date: Tue, 22 Dec 2020 20:04:52 +0000
Subject: [PATCH] cryptsetup: add support for workqueue options
This commit adds support for disabling the read and write
workqueues with the new crypttab options no-read-workqueue
and no-write-workqueue. These correspond to the cryptsetup
options --perf-no_read_workqueue and --perf-no_write_workqueue
respectively.
---
man/crypttab.xml | 19 +++++++++++++++++++
src/cryptsetup/cryptsetup.c | 12 ++++++++++++
src/shared/cryptsetup-util.h | 8 ++++++++
3 files changed, 39 insertions(+)
diff --git a/man/crypttab.xml b/man/crypttab.xml
index 2062a5b8e70..72fe2e692da 100644
--- a/man/crypttab.xml
+++ b/man/crypttab.xml
@@ -342,6 +342,25 @@
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>no-read-workqueue</option></term>
+
+ <listitem><para>Bypass dm-crypt internal workqueue and process read requests synchronously. The
+ default is to queue these requests and process them asynchronously.</para>
+
+ <para>This requires kernel 5.9 or newer.</para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><option>no-write-workqueue</option></term>
+
+ <listitem><para>Bypass dm-crypt internal workqueue and process write requests synchronously. The
+ default is to queue these requests and process them asynchronously.</para>
+
+ <para>This requires kernel 5.9 or newer.</para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><option>skip=</option></term>
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
index 7b21a7457a1..65cbd1aec83 100644
--- a/src/cryptsetup/cryptsetup.c
+++ b/src/cryptsetup/cryptsetup.c
@@ -60,6 +60,8 @@ static bool arg_verify = false;
static bool arg_discards = false;
static bool arg_same_cpu_crypt = false;
static bool arg_submit_from_crypt_cpus = false;
+static bool arg_no_read_workqueue = false;
+static bool arg_no_write_workqueue = false;
static bool arg_tcrypt_hidden = false;
static bool arg_tcrypt_system = false;
static bool arg_tcrypt_veracrypt = false;
@@ -236,6 +238,10 @@ static int parse_one_option(const char *option) {
arg_same_cpu_crypt = true;
else if (streq(option, "submit-from-crypt-cpus"))
arg_submit_from_crypt_cpus = true;
+ else if (streq(option, "no-read-workqueue"))
+ arg_no_read_workqueue = true;
+ else if (streq(option, "no-write-workqueue"))
+ arg_no_write_workqueue = true;
else if (streq(option, "luks"))
arg_type = ANY_LUKS;
/* since cryptsetup 2.3.0 (Feb 2020) */
@@ -1352,6 +1358,12 @@ static uint32_t determine_flags(void) {
if (arg_submit_from_crypt_cpus)
flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS;
+ if (arg_no_read_workqueue)
+ flags |= CRYPT_ACTIVATE_NO_READ_WORKQUEUE;
+
+ if (arg_no_write_workqueue)
+ flags |= CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE;
+
#ifdef CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF
/* Try to decrease the risk of OOM event if memory hard key derivation function is in use */
/* https://gitlab.com/cryptsetup/cryptsetup/issues/446/ */
diff --git a/src/shared/cryptsetup-util.h b/src/shared/cryptsetup-util.h
index fa2d2f65f3c..afac5cd46bd 100644
--- a/src/shared/cryptsetup-util.h
+++ b/src/shared/cryptsetup-util.h
@@ -7,6 +7,14 @@
#if HAVE_LIBCRYPTSETUP
#include <libcryptsetup.h>
+/* These next two are defined in libcryptsetup.h from cryptsetup version 2.3.4 forwards. */
+#ifndef CRYPT_ACTIVATE_NO_READ_WORKQUEUE
+#define CRYPT_ACTIVATE_NO_READ_WORKQUEUE (1 << 24)
+#endif
+#ifndef CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE
+#define CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE (1 << 25)
+#endif
+
extern int (*sym_crypt_activate_by_passphrase)(struct crypt_device *cd, const char *name, int keyslot, const char *passphrase, size_t passphrase_size, uint32_t flags);
#if HAVE_CRYPT_ACTIVATE_BY_SIGNED_KEY
extern int (*sym_crypt_activate_by_signed_key)(struct crypt_device *cd, const char *name, const char *volume_key, size_t volume_key_size, const char *signature, size_t signature_size, uint32_t flags);

View File

@ -1 +1 @@
SHA512 (systemd-248-rc3.tar.gz) = f9c2f47a6ee817a47c7efb7d3de5330e245e144ae1bf488722807888c884179c44f4fefd031cf2963678f1d752568876de057db53acfe874674de4072f78d084
SHA512 (systemd-248-rc4.tar.gz) = 022e8aabdc84c45ea06928c7b373c13f99d78fd808d9c07d3cd79dae5a2356f70d012eafbc749a588ddfcc2b1d0155f65f33ee240c4f15190d16f784803ffeac

View File

@ -20,8 +20,8 @@
Name: systemd
Url: https://www.freedesktop.org/wiki/Software/systemd
Version: 248~rc3
Release: 2%{?dist}
Version: 248~rc4
Release: 1%{?dist}
# For a breakdown of the licensing, see README
License: LGPLv2+ and MIT and GPLv2+
Summary: System and Service Manager
@ -71,10 +71,6 @@ GIT_DIR=../../src/systemd/.git git diffab -M v233..master@{2017-06-15} -- hwdb/[
%endif
# Backports of patches from upstream (00000499)
Patch0001: 0001-Revert-sd-event-make-use-of-epoll_pwait2-for-greater.patch
# https://github.com/systemd/systemd/pull/19009
# Fixes more CNAME issues in stub resolver (#1933433)
Patch0002: 19009.patch
# Downstream-only patches (50009999)
# https://bugzilla.redhat.com/show_bug.cgi?id=1738828
@ -950,6 +946,11 @@ getent passwd systemd-network &>/dev/null || useradd -r -u 192 -l -g systemd-net
%files standalone-sysusers -f .file-list-standalone-sysusers
%changelog
* Thu Mar 18 2021 Yu Watanabe <yuwatana@redhat.com> - 248~rc4-1
- Latest upstream prerelease, see
https://github.com/systemd/systemd/blob/v248-rc4/NEWS.
- A bunch of documentation updates, and correctness fixes.
* Tue Mar 16 2021 Adam Williamson <awilliam@redhat.com> - 248~rc3-2
- Backport PR #19009 to fix CNAME redirect resolving some more (#1933433)