import systemd-239-21.el8
This commit is contained in:
parent
2aad85c23d
commit
22bbbfe74c
87
SOURCES/0201-sd-bus-deal-with-cookie-overruns.patch
Normal file
87
SOURCES/0201-sd-bus-deal-with-cookie-overruns.patch
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
From 980418c331293aeb8595fcc95cbc4a9e1a485eda Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Mon, 25 Feb 2019 11:02:46 +0100
|
||||||
|
Subject: [PATCH] sd-bus: deal with cookie overruns
|
||||||
|
|
||||||
|
Apparently this happens IRL. Let's carefully deal with issues like this:
|
||||||
|
when we overrun, let's not go back to zero but instead leave the highest
|
||||||
|
cookie bit set. We use that as indication that we are in "overrun
|
||||||
|
territory", and then are particularly careful with checking cookies,
|
||||||
|
i.e. that they haven't been used for still outstanding replies yet. This
|
||||||
|
should retain the quick cookie generation behaviour we used to have, but
|
||||||
|
permits dealing with overruns.
|
||||||
|
|
||||||
|
Replaces: #11804
|
||||||
|
Fixes: #11809
|
||||||
|
(cherry picked from commit 1f82f5bb4237ed5f015daf93f818e9db95e764b8)
|
||||||
|
|
||||||
|
Resolves: #1694999
|
||||||
|
---
|
||||||
|
src/libsystemd/sd-bus/sd-bus.c | 47 +++++++++++++++++++++++++++++++++-
|
||||||
|
1 file changed, 46 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
|
||||||
|
index f53a98d6bf..3583e24e64 100644
|
||||||
|
--- a/src/libsystemd/sd-bus/sd-bus.c
|
||||||
|
+++ b/src/libsystemd/sd-bus/sd-bus.c
|
||||||
|
@@ -1597,6 +1597,47 @@ _public_ int sd_bus_get_bus_id(sd_bus *bus, sd_id128_t *id) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+#define COOKIE_CYCLED (UINT32_C(1) << 31)
|
||||||
|
+
|
||||||
|
+static uint64_t cookie_inc(uint64_t cookie) {
|
||||||
|
+
|
||||||
|
+ /* Stay within the 32bit range, since classic D-Bus can't deal with more */
|
||||||
|
+ if (cookie >= UINT32_MAX)
|
||||||
|
+ return COOKIE_CYCLED; /* Don't go back to zero, but use the highest bit for checking
|
||||||
|
+ * whether we are looping. */
|
||||||
|
+
|
||||||
|
+ return cookie + 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int next_cookie(sd_bus *b) {
|
||||||
|
+ uint64_t new_cookie;
|
||||||
|
+
|
||||||
|
+ assert(b);
|
||||||
|
+
|
||||||
|
+ new_cookie = cookie_inc(b->cookie);
|
||||||
|
+
|
||||||
|
+ /* Small optimization: don't bother with checking for cookie reuse until we overran cookiespace at
|
||||||
|
+ * least once, but then do it thorougly. */
|
||||||
|
+ if (FLAGS_SET(new_cookie, COOKIE_CYCLED)) {
|
||||||
|
+ uint32_t i;
|
||||||
|
+
|
||||||
|
+ /* Check if the cookie is currently in use. If so, pick the next one */
|
||||||
|
+ for (i = 0; i < COOKIE_CYCLED; i++) {
|
||||||
|
+ if (!ordered_hashmap_contains(b->reply_callbacks, &new_cookie))
|
||||||
|
+ goto good;
|
||||||
|
+
|
||||||
|
+ new_cookie = cookie_inc(new_cookie);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Can't fulfill request */
|
||||||
|
+ return -EBUSY;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+good:
|
||||||
|
+ b->cookie = new_cookie;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
@@ -1620,7 +1661,11 @@ static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
- return sd_bus_message_seal(m, ++b->cookie, timeout);
|
||||||
|
+ r = next_cookie(b);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ return sd_bus_message_seal(m, b->cookie, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int bus_remarshal_message(sd_bus *b, sd_bus_message **m) {
|
@ -0,0 +1,77 @@
|
|||||||
|
From f551c05e4799386508e10f0f007251e426493a67 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Mon, 11 Mar 2019 12:27:18 +0900
|
||||||
|
Subject: [PATCH] journal-remote: do not request Content-Length if
|
||||||
|
Transfer-Encoding is chunked
|
||||||
|
|
||||||
|
This fixes a bug introduced by 7fdb237f5473cb8fc2129e57e8a0039526dcb4fd.
|
||||||
|
|
||||||
|
Closes #11571.
|
||||||
|
|
||||||
|
(cherry picked from commit a289dfd69b3ff4bccdde93e84b67c947bafa27e1)
|
||||||
|
|
||||||
|
Resolves: #1708849
|
||||||
|
---
|
||||||
|
src/journal-remote/journal-remote-main.c | 41 ++++++++++++++++--------
|
||||||
|
1 file changed, 27 insertions(+), 14 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c
|
||||||
|
index 5b0bbba310..47fe9d7433 100644
|
||||||
|
--- a/src/journal-remote/journal-remote-main.c
|
||||||
|
+++ b/src/journal-remote/journal-remote-main.c
|
||||||
|
@@ -254,6 +254,7 @@ static int request_handler(
|
||||||
|
const char *header;
|
||||||
|
int r, code, fd;
|
||||||
|
_cleanup_free_ char *hostname = NULL;
|
||||||
|
+ bool chunked = false;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
assert(connection);
|
||||||
|
@@ -279,21 +280,33 @@ static int request_handler(
|
||||||
|
return mhd_respond(connection, MHD_HTTP_UNSUPPORTED_MEDIA_TYPE,
|
||||||
|
"Content-Type: application/vnd.fdo.journal is required.");
|
||||||
|
|
||||||
|
+ header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Transfer-Encoding");
|
||||||
|
+ if (header) {
|
||||||
|
+ if (!strcaseeq(header, "chunked"))
|
||||||
|
+ return mhd_respondf(connection, 0, MHD_HTTP_BAD_REQUEST,
|
||||||
|
+ "Unsupported Transfer-Encoding type: %s", header);
|
||||||
|
+
|
||||||
|
+ chunked = true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Content-Length");
|
||||||
|
- if (!header)
|
||||||
|
- return mhd_respond(connection, MHD_HTTP_LENGTH_REQUIRED,
|
||||||
|
- "Content-Length header is required.");
|
||||||
|
- r = safe_atozu(header, &len);
|
||||||
|
- if (r < 0)
|
||||||
|
- return mhd_respondf(connection, r, MHD_HTTP_LENGTH_REQUIRED,
|
||||||
|
- "Content-Length: %s cannot be parsed: %m", header);
|
||||||
|
-
|
||||||
|
- if (len > ENTRY_SIZE_MAX)
|
||||||
|
- /* When serialized, an entry of maximum size might be slightly larger,
|
||||||
|
- * so this does not correspond exactly to the limit in journald. Oh well.
|
||||||
|
- */
|
||||||
|
- return mhd_respondf(connection, 0, MHD_HTTP_PAYLOAD_TOO_LARGE,
|
||||||
|
- "Payload larger than maximum size of %u bytes", ENTRY_SIZE_MAX);
|
||||||
|
+ if (header) {
|
||||||
|
+ if (chunked)
|
||||||
|
+ return mhd_respond(connection, MHD_HTTP_BAD_REQUEST,
|
||||||
|
+ "Content-Length must not specified when Transfer-Encoding type is 'chuncked'");
|
||||||
|
+
|
||||||
|
+ r = safe_atozu(header, &len);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return mhd_respondf(connection, r, MHD_HTTP_LENGTH_REQUIRED,
|
||||||
|
+ "Content-Length: %s cannot be parsed: %m", header);
|
||||||
|
+
|
||||||
|
+ if (len > ENTRY_SIZE_MAX)
|
||||||
|
+ /* When serialized, an entry of maximum size might be slightly larger,
|
||||||
|
+ * so this does not correspond exactly to the limit in journald. Oh well.
|
||||||
|
+ */
|
||||||
|
+ return mhd_respondf(connection, 0, MHD_HTTP_PAYLOAD_TOO_LARGE,
|
||||||
|
+ "Payload larger than maximum size of %u bytes", ENTRY_SIZE_MAX);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
{
|
||||||
|
const union MHD_ConnectionInfo *ci;
|
@ -0,0 +1,79 @@
|
|||||||
|
From fffbf1f90be5236b310bc0b10034815b1051f0ac Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Fri, 10 Aug 2018 11:07:54 +0900
|
||||||
|
Subject: [PATCH] journal: do not remove multiple spaces after identifier in
|
||||||
|
syslog message
|
||||||
|
|
||||||
|
Single space is used as separator.
|
||||||
|
C.f. discussions in #156.
|
||||||
|
|
||||||
|
Fixes #9839 introduced by a6aadf4ae0bae185dc4c414d492a4a781c80ffe5.
|
||||||
|
|
||||||
|
(cherry picked from commit 8595102d3ddde6d25c282f965573a6de34ab4421)
|
||||||
|
|
||||||
|
Resolves: #1691817
|
||||||
|
---
|
||||||
|
src/journal/journald-syslog.c | 4 +++-
|
||||||
|
src/journal/test-journal-syslog.c | 24 ++++++++++++++----------
|
||||||
|
2 files changed, 17 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
|
||||||
|
index 97711ac7a3..e0b55cc566 100644
|
||||||
|
--- a/src/journal/journald-syslog.c
|
||||||
|
+++ b/src/journal/journald-syslog.c
|
||||||
|
@@ -219,7 +219,9 @@ size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid)
|
||||||
|
if (t)
|
||||||
|
*identifier = t;
|
||||||
|
|
||||||
|
- e += strspn(p + e, WHITESPACE);
|
||||||
|
+ /* Single space is used as separator */
|
||||||
|
+ if (p[e] != '\0' && strchr(WHITESPACE, p[e]))
|
||||||
|
+ e++;
|
||||||
|
|
||||||
|
*buf = p + e;
|
||||||
|
return e;
|
||||||
|
diff --git a/src/journal/test-journal-syslog.c b/src/journal/test-journal-syslog.c
|
||||||
|
index 05f759817e..7294cde032 100644
|
||||||
|
--- a/src/journal/test-journal-syslog.c
|
||||||
|
+++ b/src/journal/test-journal-syslog.c
|
||||||
|
@@ -6,7 +6,7 @@
|
||||||
|
#include "string-util.h"
|
||||||
|
|
||||||
|
static void test_syslog_parse_identifier(const char *str,
|
||||||
|
- const char *ident, const char *pid, int ret) {
|
||||||
|
+ const char *ident, const char *pid, const char *rest, int ret) {
|
||||||
|
const char *buf = str;
|
||||||
|
_cleanup_free_ char *ident2 = NULL, *pid2 = NULL;
|
||||||
|
int ret2;
|
||||||
|
@@ -16,18 +16,22 @@ static void test_syslog_parse_identifier(const char *str,
|
||||||
|
assert_se(ret == ret2);
|
||||||
|
assert_se(ident == ident2 || streq_ptr(ident, ident2));
|
||||||
|
assert_se(pid == pid2 || streq_ptr(pid, pid2));
|
||||||
|
+ assert_se(streq(buf, rest));
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
- test_syslog_parse_identifier("pidu[111]: xxx", "pidu", "111", 11);
|
||||||
|
- test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, 6);
|
||||||
|
- test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, 7);
|
||||||
|
- test_syslog_parse_identifier("pidu xxx", NULL, NULL, 0);
|
||||||
|
- test_syslog_parse_identifier(":", "", NULL, 1);
|
||||||
|
- test_syslog_parse_identifier(": ", "", NULL, 3);
|
||||||
|
- test_syslog_parse_identifier("pidu:", "pidu", NULL, 5);
|
||||||
|
- test_syslog_parse_identifier("pidu: ", "pidu", NULL, 6);
|
||||||
|
- test_syslog_parse_identifier("pidu : ", NULL, NULL, 0);
|
||||||
|
+ test_syslog_parse_identifier("pidu[111]: xxx", "pidu", "111", "xxx", 11);
|
||||||
|
+ test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, "xxx", 6);
|
||||||
|
+ test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, " xxx", 6);
|
||||||
|
+ test_syslog_parse_identifier("pidu xxx", NULL, NULL, "pidu xxx", 0);
|
||||||
|
+ test_syslog_parse_identifier(" pidu xxx", NULL, NULL, " pidu xxx", 0);
|
||||||
|
+ test_syslog_parse_identifier("", NULL, NULL, "", 0);
|
||||||
|
+ test_syslog_parse_identifier(" ", NULL, NULL, " ", 0);
|
||||||
|
+ test_syslog_parse_identifier(":", "", NULL, "", 1);
|
||||||
|
+ test_syslog_parse_identifier(": ", "", NULL, " ", 2);
|
||||||
|
+ test_syslog_parse_identifier("pidu:", "pidu", NULL, "", 5);
|
||||||
|
+ test_syslog_parse_identifier("pidu: ", "pidu", NULL, "", 6);
|
||||||
|
+ test_syslog_parse_identifier("pidu : ", NULL, NULL, "pidu : ", 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
From 4f9d00380ea41f5a4eb1610ae5c354a8f749cc98 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Milan Broz <gmazyland@gmail.com>
|
||||||
|
Date: Mon, 27 May 2019 09:27:54 +0200
|
||||||
|
Subject: [PATCH] cryptsetup: Do not fallback to PLAIN mapping if LUKS data
|
||||||
|
device set fails.
|
||||||
|
|
||||||
|
If crypt_load() for LUKS succeeds, we know that it is a LUKS device.
|
||||||
|
Failure of data device setting should fail in this case; remapping
|
||||||
|
as a PLAIN device late could mean data corruption.
|
||||||
|
|
||||||
|
(If a user wants to map PLAIN device over a device with LUKS header,
|
||||||
|
it should be said explicitly with "plain" argument type.)
|
||||||
|
|
||||||
|
Also, if there is no explicit PLAIN type requested and crypt device
|
||||||
|
is already initialized (crypt_data_type() is set), do not run
|
||||||
|
the initialization again.
|
||||||
|
|
||||||
|
(cherry picked from commit 2e4beb875bcb24e7d7d4339cc202b0b3f2953f71)
|
||||||
|
|
||||||
|
Related: #1719153
|
||||||
|
---
|
||||||
|
src/cryptsetup/cryptsetup.c | 12 +++++++-----
|
||||||
|
1 file changed, 7 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
|
||||||
|
index abeba44ee8..5be1469d69 100644
|
||||||
|
--- a/src/cryptsetup/cryptsetup.c
|
||||||
|
+++ b/src/cryptsetup/cryptsetup.c
|
||||||
|
@@ -492,11 +492,14 @@ static int attach_luks_or_plain(struct crypt_device *cd,
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (data_device)
|
||||||
|
+ if (data_device) {
|
||||||
|
r = crypt_set_data_device(cd, data_device);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_error_errno(r, "Failed to set LUKS data device %s: %m", data_device);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
- if ((!arg_type && r < 0) || streq_ptr(arg_type, CRYPT_PLAIN)) {
|
||||||
|
+ if ((!arg_type && !crypt_get_type(cd)) || streq_ptr(arg_type, CRYPT_PLAIN)) {
|
||||||
|
struct crypt_params_plain params = {
|
||||||
|
.offset = arg_offset,
|
||||||
|
.skip = arg_skip,
|
||||||
|
@@ -543,14 +546,13 @@ static int attach_luks_or_plain(struct crypt_device *cd,
|
||||||
|
* parameters when used for plain
|
||||||
|
* mode. */
|
||||||
|
r = crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, arg_keyfile_size, ¶ms);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_error_errno(r, "Loading of cryptographic parameters failed: %m");
|
||||||
|
|
||||||
|
/* hash == NULL implies the user passed "plain" */
|
||||||
|
pass_volume_key = (params.hash == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (r < 0)
|
||||||
|
- return log_error_errno(r, "Loading of cryptographic parameters failed: %m");
|
||||||
|
-
|
||||||
|
log_info("Set cipher %s, mode %s, key size %i bits for device %s.",
|
||||||
|
crypt_get_cipher(cd),
|
||||||
|
crypt_get_cipher_mode(cd),
|
@ -0,0 +1,79 @@
|
|||||||
|
From 788fb775f7deb8c456868362454e2a5f50c6068f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Milan Broz <gmazyland@gmail.com>
|
||||||
|
Date: Mon, 27 May 2019 09:43:03 +0200
|
||||||
|
Subject: [PATCH] cryptsetup: call crypt_load() for LUKS only once
|
||||||
|
|
||||||
|
The crypt_load() for LUKS2 can read a quite big area of disk
|
||||||
|
(metadata area size is configurable and can increase up to megabytes).
|
||||||
|
|
||||||
|
This initialization is not needed to be repeated, just use the existing context.
|
||||||
|
|
||||||
|
(This patch is also required for the following change.)
|
||||||
|
|
||||||
|
(cherry picked from commit ea9a9d49e4af31c49e5c216e7e5e2f533e727579)
|
||||||
|
|
||||||
|
Related: #1719153
|
||||||
|
---
|
||||||
|
src/cryptsetup/cryptsetup.c | 28 ++++++++++++----------------
|
||||||
|
1 file changed, 12 insertions(+), 16 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
|
||||||
|
index 5be1469d69..a0bd80ea65 100644
|
||||||
|
--- a/src/cryptsetup/cryptsetup.c
|
||||||
|
+++ b/src/cryptsetup/cryptsetup.c
|
||||||
|
@@ -475,7 +475,6 @@ static int attach_tcrypt(
|
||||||
|
static int attach_luks_or_plain(struct crypt_device *cd,
|
||||||
|
const char *name,
|
||||||
|
const char *key_file,
|
||||||
|
- const char *data_device,
|
||||||
|
char **passwords,
|
||||||
|
uint32_t flags) {
|
||||||
|
int r = 0;
|
||||||
|
@@ -485,20 +484,6 @@ static int attach_luks_or_plain(struct crypt_device *cd,
|
||||||
|
assert(name);
|
||||||
|
assert(key_file || passwords);
|
||||||
|
|
||||||
|
- if (!arg_type || STR_IN_SET(arg_type, ANY_LUKS, CRYPT_LUKS1)) {
|
||||||
|
- r = crypt_load(cd, CRYPT_LUKS, NULL);
|
||||||
|
- if (r < 0) {
|
||||||
|
- log_error("crypt_load() failed on device %s.\n", crypt_get_device_name(cd));
|
||||||
|
- return r;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (data_device) {
|
||||||
|
- r = crypt_set_data_device(cd, data_device);
|
||||||
|
- if (r < 0)
|
||||||
|
- return log_error_errno(r, "Failed to set LUKS data device %s: %m", data_device);
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
if ((!arg_type && !crypt_get_type(cd)) || streq_ptr(arg_type, CRYPT_PLAIN)) {
|
||||||
|
struct crypt_params_plain params = {
|
||||||
|
.offset = arg_offset,
|
||||||
|
@@ -687,6 +672,18 @@ int main(int argc, char *argv[]) {
|
||||||
|
log_warning("Key file %s is world-readable. This is not a good idea!", key_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (!arg_type || STR_IN_SET(arg_type, ANY_LUKS, CRYPT_LUKS1)) {
|
||||||
|
+ r = crypt_load(cd, CRYPT_LUKS, NULL);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_error_errno(r, "Failed to load LUKS superblock on device %s: %m", crypt_get_device_name(cd));
|
||||||
|
+
|
||||||
|
+ if (arg_header) {
|
||||||
|
+ r = crypt_set_data_device(cd, argv[3]);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_error_errno(r, "Failed to set LUKS data device %s: %m", argv[3]);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
for (tries = 0; arg_tries == 0 || tries < arg_tries; tries++) {
|
||||||
|
_cleanup_strv_free_erase_ char **passwords = NULL;
|
||||||
|
|
||||||
|
@@ -704,7 +701,6 @@ int main(int argc, char *argv[]) {
|
||||||
|
r = attach_luks_or_plain(cd,
|
||||||
|
argv[2],
|
||||||
|
key_file,
|
||||||
|
- arg_header ? argv[3] : NULL,
|
||||||
|
passwords,
|
||||||
|
flags);
|
||||||
|
if (r >= 0)
|
45
SOURCES/0206-cryptsetup-Add-LUKS2-token-support.patch
Normal file
45
SOURCES/0206-cryptsetup-Add-LUKS2-token-support.patch
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
From 7a597a091de83a861d81166b0e863bf2977c829c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Milan Broz <gmazyland@gmail.com>
|
||||||
|
Date: Mon, 27 May 2019 09:44:14 +0200
|
||||||
|
Subject: [PATCH] cryptsetup: Add LUKS2 token support.
|
||||||
|
|
||||||
|
LUKS2 supports so-called tokens. The libcryptsetup internally
|
||||||
|
support keyring token (it tries to open device using specified
|
||||||
|
keyring entry).
|
||||||
|
Only if all token fails (or are not available), it uses a passphrase.
|
||||||
|
|
||||||
|
This patch aligns the functionality with the cryptsetup utility
|
||||||
|
(cryptsetup luksOpen tries tokens first) but does not replace
|
||||||
|
the systemd native ask-password function (can be used the same in
|
||||||
|
combination with this patch).
|
||||||
|
|
||||||
|
(cherry picked from commit 894bb3ca4c730cc9e9d46ef5004ba4ca5e201d8d)
|
||||||
|
|
||||||
|
Resolves: #1719153
|
||||||
|
---
|
||||||
|
src/cryptsetup/cryptsetup.c | 12 ++++++++++++
|
||||||
|
1 file changed, 12 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
|
||||||
|
index a0bd80ea65..4e1b3eff19 100644
|
||||||
|
--- a/src/cryptsetup/cryptsetup.c
|
||||||
|
+++ b/src/cryptsetup/cryptsetup.c
|
||||||
|
@@ -682,6 +682,18 @@ int main(int argc, char *argv[]) {
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to set LUKS data device %s: %m", argv[3]);
|
||||||
|
}
|
||||||
|
+#ifdef CRYPT_ANY_TOKEN
|
||||||
|
+ /* Tokens are available in LUKS2 only, but it is ok to call (and fail) with LUKS1. */
|
||||||
|
+ if (!key_file) {
|
||||||
|
+ r = crypt_activate_by_token(cd, argv[2], CRYPT_ANY_TOKEN, NULL, flags);
|
||||||
|
+ if (r >= 0) {
|
||||||
|
+ log_debug("Volume %s activated with LUKS token id %i.", argv[2], r);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ log_debug_errno(r, "Token activation unsuccessful for device %s: %m", crypt_get_device_name(cd));
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
for (tries = 0; arg_tries == 0 || tries < arg_tries; tries++) {
|
@ -0,0 +1,30 @@
|
|||||||
|
From 7b3ef169e3142fb471c48f265881b371380d77e0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Zhang Xianwei <zhang.xianwei8@zte.com.cn>
|
||||||
|
Date: Mon, 13 May 2019 18:41:55 +0800
|
||||||
|
Subject: [PATCH] udev/scsi_id: fix incorrect page length when get device
|
||||||
|
identification VPD page
|
||||||
|
|
||||||
|
The length of device identification VPD page is filled with two bytes,
|
||||||
|
but scsi_id only gets the low byte. Fix it.
|
||||||
|
|
||||||
|
Signed-off-by: Zhang Xianwei <zhang.xianwei8@zte.com.cn>
|
||||||
|
(cherry picked from commit 1f7b6872dbe8ccae1f3bda9aa6aeb87c9b42e01e)
|
||||||
|
|
||||||
|
Resolves: #1713227
|
||||||
|
---
|
||||||
|
src/udev/scsi_id/scsi_serial.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/udev/scsi_id/scsi_serial.c b/src/udev/scsi_id/scsi_serial.c
|
||||||
|
index fd91657a32..fb6055395d 100644
|
||||||
|
--- a/src/udev/scsi_id/scsi_serial.c
|
||||||
|
+++ b/src/udev/scsi_id/scsi_serial.c
|
||||||
|
@@ -661,7 +661,7 @@ static int do_scsi_page83_inquiry(struct udev *udev,
|
||||||
|
* Examine each descriptor returned. There is normally only
|
||||||
|
* one or a small number of descriptors.
|
||||||
|
*/
|
||||||
|
- for (j = 4; j <= (unsigned int)page_83[3] + 3; j += page_83[j + 3] + 4) {
|
||||||
|
+ for (j = 4; j <= ((unsigned)page_83[2] << 8) + (unsigned)page_83[3] + 3; j += page_83[j + 3] + 4) {
|
||||||
|
retval = check_fill_0x83_id(udev,
|
||||||
|
dev_scsi, &page_83[j],
|
||||||
|
&id_search_list[id_ind],
|
@ -0,0 +1,55 @@
|
|||||||
|
From d70e1c2eb596b8144197192e2324abbb45f547a6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jonathon Kowalski <bl0pbl33p@gmail.com>
|
||||||
|
Date: Thu, 17 Jan 2019 17:08:00 +0000
|
||||||
|
Subject: [PATCH] Change job mode of manager triggered restarts to JOB_REPLACE
|
||||||
|
|
||||||
|
Fixes: #11305
|
||||||
|
Fixes: #3260
|
||||||
|
Related: #11456
|
||||||
|
|
||||||
|
So, here's what happens in the described scenario in #11305. A unit goes
|
||||||
|
down, and that triggeres stop jobs for the other two units as they were
|
||||||
|
bound to it. Now, the timer for manager triggered restarts kicks in and
|
||||||
|
schedules a restart job with the JOB_FAIL job mode. This means there is
|
||||||
|
a stop job installed on those units, and now due to them being bound to
|
||||||
|
us they also get a restart job enqueued. This however is a conflicts, as
|
||||||
|
neither stop can merge into restart, nor restart into stop. However,
|
||||||
|
restart should be able to replace stop in any case. If the stop
|
||||||
|
procedure is ongoing, it can cancel the stop job, install itself, and
|
||||||
|
then after reaching dead finish and convert itself to a start job.
|
||||||
|
However, if we increase the timer, then it can always take those units
|
||||||
|
from inactive -> auto-restart.
|
||||||
|
|
||||||
|
We change the job mode to JOB_REPLACE so the restart job cancels the
|
||||||
|
stop job and installs itself.
|
||||||
|
|
||||||
|
Also, the original bug could be worked around by bumping RestartSec= to
|
||||||
|
avoid the conflicting.
|
||||||
|
|
||||||
|
This doesn't seem to be something that is going to break uses. That is
|
||||||
|
because for those who already had it working, there must have never been
|
||||||
|
conflicting jobs, as that would result in a desctructive transaction by
|
||||||
|
virtue of the job mode used.
|
||||||
|
|
||||||
|
After this change, the test case is able to work nicely without issues.
|
||||||
|
|
||||||
|
(cherry picked from commit 03ff2dc71ecb09272d728d458498b44f7f132f51)
|
||||||
|
|
||||||
|
Resolves: #1712524
|
||||||
|
---
|
||||||
|
src/core/service.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/service.c b/src/core/service.c
|
||||||
|
index 3eab749362..8342c131c8 100644
|
||||||
|
--- a/src/core/service.c
|
||||||
|
+++ b/src/core/service.c
|
||||||
|
@@ -2133,7 +2133,7 @@ static void service_enter_restart(Service *s) {
|
||||||
|
* restarted. We use JOB_RESTART (instead of the more obvious
|
||||||
|
* JOB_START) here so that those dependency jobs will be added
|
||||||
|
* as well. */
|
||||||
|
- r = manager_add_job(UNIT(s)->manager, JOB_RESTART, UNIT(s), JOB_FAIL, &error, NULL);
|
||||||
|
+ r = manager_add_job(UNIT(s)->manager, JOB_RESTART, UNIT(s), JOB_REPLACE, &error, NULL);
|
||||||
|
if (r < 0)
|
||||||
|
goto fail;
|
||||||
|
|
58
SOURCES/0209-bash-completion-analyze-support-security.patch
Normal file
58
SOURCES/0209-bash-completion-analyze-support-security.patch
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
From 8d1a8f099dbf79d0e18e055721228192a637a759 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Thu, 6 Dec 2018 18:51:56 +0100
|
||||||
|
Subject: [PATCH] bash-completion: analyze: support 'security'
|
||||||
|
|
||||||
|
(cherry picked from commit 83da42c3bf86e8787cfec2c7fb6ca379dfec3632)
|
||||||
|
|
||||||
|
Resolves: #1733395
|
||||||
|
---
|
||||||
|
shell-completion/bash/systemd-analyze | 20 +++++++++++++++++++-
|
||||||
|
1 file changed, 19 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/shell-completion/bash/systemd-analyze b/shell-completion/bash/systemd-analyze
|
||||||
|
index 21d0fcf1b8..b4fcfc6492 100644
|
||||||
|
--- a/shell-completion/bash/systemd-analyze
|
||||||
|
+++ b/shell-completion/bash/systemd-analyze
|
||||||
|
@@ -31,8 +31,13 @@ __get_machines() {
|
||||||
|
machinectl list --no-legend --no-pager | { while read a b; do echo " $a"; done; };
|
||||||
|
}
|
||||||
|
|
||||||
|
+__get_services() {
|
||||||
|
+ systemctl list-units --no-legend --no-pager -t service --all $1 | \
|
||||||
|
+ { while read -r a b c; do [[ $b == "loaded" ]]; echo " $a"; done }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
_systemd_analyze() {
|
||||||
|
- local i verb comps
|
||||||
|
+ local i verb comps mode
|
||||||
|
local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||||
|
|
||||||
|
local -A OPTS=(
|
||||||
|
@@ -51,6 +56,7 @@ _systemd_analyze() {
|
||||||
|
[SECCOMP_FILTER]='syscall-filter'
|
||||||
|
[SERVICE_WATCHDOGS]='service-watchdogs'
|
||||||
|
[CAT_CONFIG]='cat-config'
|
||||||
|
+ [SECURITY]='security'
|
||||||
|
)
|
||||||
|
|
||||||
|
local CONFIGS='systemd/bootchart.conf systemd/coredump.conf systemd/journald.conf
|
||||||
|
@@ -149,6 +155,18 @@ _systemd_analyze() {
|
||||||
|
comps="$CONFIGS $( compgen -A file -- "$cur" )"
|
||||||
|
compopt -o filenames
|
||||||
|
fi
|
||||||
|
+
|
||||||
|
+ elif __contains_word "$verb" ${VERBS[SECURITY]}; then
|
||||||
|
+ if [[ $cur = -* ]]; then
|
||||||
|
+ comps='--help --version --no-pager --system --user -H --host -M --machine'
|
||||||
|
+ else
|
||||||
|
+ if __contains_word "--user" ${COMP_WORDS[*]}; then
|
||||||
|
+ mode=--user
|
||||||
|
+ else
|
||||||
|
+ mode=--system
|
||||||
|
+ fi
|
||||||
|
+ comps=$( __get_services $mode )
|
||||||
|
+ fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
COMPREPLY=( $(compgen -W '$comps' -- "$cur") )
|
@ -0,0 +1,28 @@
|
|||||||
|
From 705a67a53a8a1b836ef17f048366bbf33357afc1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Synacek <jsynacek@redhat.com>
|
||||||
|
Date: Tue, 14 May 2019 10:45:08 +0200
|
||||||
|
Subject: [PATCH] man: note that journal does not validate syslog fields
|
||||||
|
|
||||||
|
(cherry picked from commit 63ea8032f28052f7cda860e5324c0a83dee7ed23)
|
||||||
|
|
||||||
|
Resolves: #1707175
|
||||||
|
---
|
||||||
|
man/systemd.journal-fields.xml | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/man/systemd.journal-fields.xml b/man/systemd.journal-fields.xml
|
||||||
|
index c079274c32..0c95c4cd95 100644
|
||||||
|
--- a/man/systemd.journal-fields.xml
|
||||||
|
+++ b/man/systemd.journal-fields.xml
|
||||||
|
@@ -111,6 +111,11 @@
|
||||||
|
<varname>program_invocation_short_name</varname> variable,
|
||||||
|
see
|
||||||
|
<citerefentry project='die-net'><refentrytitle>program_invocation_short_name</refentrytitle><manvolnum>3</manvolnum></citerefentry>.)</para>
|
||||||
|
+ <para>Note that the journal service does not validate the values of any structured
|
||||||
|
+ journal fields whose name is not prefixed with an underscore, and this includes any
|
||||||
|
+ syslog related fields such as these. Hence, applications that supply a facility, PID,
|
||||||
|
+ or log level are expected to do so properly formatted, i.e. as numeric integers formatted
|
||||||
|
+ as decimal strings.</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
</varlistentry>
|
22
SOURCES/0211-rules-skip-memory-hotplug-on-ppc64.patch
Normal file
22
SOURCES/0211-rules-skip-memory-hotplug-on-ppc64.patch
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
From 72dd8d8cd1a7417805009050f859d502b1c6cf3e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Synacek <jsynacek@redhat.com>
|
||||||
|
Date: Thu, 6 Jun 2019 09:35:27 +0200
|
||||||
|
Subject: [PATCH] rules: skip memory hotplug on ppc64
|
||||||
|
|
||||||
|
Resolves (#1713159)
|
||||||
|
---
|
||||||
|
rules/40-redhat.rules | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
|
||||||
|
index 17b33682bd..fadc6e59f1 100644
|
||||||
|
--- a/rules/40-redhat.rules
|
||||||
|
+++ b/rules/40-redhat.rules
|
||||||
|
@@ -7,6 +7,7 @@ SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}
|
||||||
|
SUBSYSTEM!="memory", GOTO="memory_hotplug_end"
|
||||||
|
ACTION!="add", GOTO="memory_hotplug_end"
|
||||||
|
PROGRAM="/bin/uname -p", RESULT=="s390*", GOTO="memory_hotplug_end"
|
||||||
|
+PROGRAM="/bin/uname -p", RESULT=="ppc64*", GOTO="memory_hotplug_end"
|
||||||
|
|
||||||
|
ENV{.state}="online"
|
||||||
|
PROGRAM="/bin/systemd-detect-virt", RESULT=="none", ENV{.state}="online_movable"
|
@ -0,0 +1,86 @@
|
|||||||
|
From daf63a3c6c6cd241017bdf9a26c7b1caf744e69b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Wed, 17 Jul 2019 14:53:07 +0200
|
||||||
|
Subject: [PATCH] mount: simplify /proc/self/mountinfo handler
|
||||||
|
|
||||||
|
Our IO handler is only installed for one fd, hence there's no reason to
|
||||||
|
conditionalize on it again.
|
||||||
|
|
||||||
|
Also, split out the draining into a helper function of its own.
|
||||||
|
|
||||||
|
(cherry picked from commit fcd8e119c28be19ffbc5227089cf4d3b8ba60238)
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
src/core/mount.c
|
||||||
|
|
||||||
|
Related: #1696178
|
||||||
|
---
|
||||||
|
src/core/mount.c | 48 ++++++++++++++++++++++++++----------------------
|
||||||
|
1 file changed, 26 insertions(+), 22 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/mount.c b/src/core/mount.c
|
||||||
|
index 16229d4af1..85b07375e2 100644
|
||||||
|
--- a/src/core/mount.c
|
||||||
|
+++ b/src/core/mount.c
|
||||||
|
@@ -1758,6 +1758,29 @@ fail:
|
||||||
|
mount_shutdown(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int drain_libmount(Manager *m) {
|
||||||
|
+ bool rescan = false;
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ assert(m);
|
||||||
|
+
|
||||||
|
+ /* Drain all events and verify that the event is valid.
|
||||||
|
+ *
|
||||||
|
+ * Note that libmount also monitors /run/mount mkdir if the directory does not exist yet. The mkdir
|
||||||
|
+ * may generate event which is irrelevant for us.
|
||||||
|
+ *
|
||||||
|
+ * error: r < 0; valid: r == 0, false positive: r == 1 */
|
||||||
|
+ do {
|
||||||
|
+ r = mnt_monitor_next_change(m->mount_monitor, NULL, NULL);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_error_errno(r, "Failed to drain libmount events: %m");
|
||||||
|
+ if (r == 0)
|
||||||
|
+ rescan = true;
|
||||||
|
+ } while (r == 0);
|
||||||
|
+
|
||||||
|
+ return rescan;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
|
||||||
|
_cleanup_set_free_ Set *around = NULL, *gone = NULL;
|
||||||
|
Manager *m = userdata;
|
||||||
|
@@ -1769,28 +1792,9 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
|
||||||
|
assert(m);
|
||||||
|
assert(revents & EPOLLIN);
|
||||||
|
|
||||||
|
- if (fd == mnt_monitor_get_fd(m->mount_monitor)) {
|
||||||
|
- bool rescan = false;
|
||||||
|
-
|
||||||
|
- /* Drain all events and verify that the event is valid.
|
||||||
|
- *
|
||||||
|
- * Note that libmount also monitors /run/mount mkdir if the
|
||||||
|
- * directory does not exist yet. The mkdir may generate event
|
||||||
|
- * which is irrelevant for us.
|
||||||
|
- *
|
||||||
|
- * error: r < 0; valid: r == 0, false positive: rc == 1 */
|
||||||
|
- do {
|
||||||
|
- r = mnt_monitor_next_change(m->mount_monitor, NULL, NULL);
|
||||||
|
- if (r == 0)
|
||||||
|
- rescan = true;
|
||||||
|
- else if (r < 0)
|
||||||
|
- return log_error_errno(r, "Failed to drain libmount events");
|
||||||
|
- } while (r == 0);
|
||||||
|
-
|
||||||
|
- log_debug("libmount event [rescan: %s]", yes_no(rescan));
|
||||||
|
- if (!rescan)
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
+ r = drain_libmount(m);
|
||||||
|
+ if (r <= 0)
|
||||||
|
+ return r;
|
||||||
|
|
||||||
|
r = mount_load_proc_self_mountinfo(m, true);
|
||||||
|
if (r < 0) {
|
@ -0,0 +1,90 @@
|
|||||||
|
From 4bc21bbc61acd1ce114da381a9742f6bcd4ffde8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Wed, 17 Jul 2019 18:57:13 +0200
|
||||||
|
Subject: [PATCH] mount: rescan /proc/self/mountinfo before processing waitid()
|
||||||
|
results
|
||||||
|
|
||||||
|
(The interesting bits about the what and why are in a comment in the
|
||||||
|
patch, please have a look there instead of looking here in the commit
|
||||||
|
msg).
|
||||||
|
|
||||||
|
Fixes: #10872
|
||||||
|
(cherry picked from commit 350804867dbcc9b7ccabae1187d730d37e2d8a21)
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
src/core/mount.c
|
||||||
|
|
||||||
|
Resolves: #1696178
|
||||||
|
---
|
||||||
|
src/core/mount.c | 30 +++++++++++++++++++++++++++---
|
||||||
|
1 file changed, 27 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/mount.c b/src/core/mount.c
|
||||||
|
index 85b07375e2..2ac04e3874 100644
|
||||||
|
--- a/src/core/mount.c
|
||||||
|
+++ b/src/core/mount.c
|
||||||
|
@@ -53,6 +53,7 @@ static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = {
|
||||||
|
|
||||||
|
static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
|
||||||
|
static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
|
||||||
|
+static int mount_process_proc_self_mountinfo(Manager *m);
|
||||||
|
|
||||||
|
static bool MOUNT_STATE_WITH_PROCESS(MountState state) {
|
||||||
|
return IN_SET(state,
|
||||||
|
@@ -1241,6 +1242,22 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||||
|
if (pid != m->control_pid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
+ /* So here's the thing, we really want to know before /usr/bin/mount or /usr/bin/umount exit whether
|
||||||
|
+ * they established/remove a mount. This is important when mounting, but even more so when unmounting
|
||||||
|
+ * since we need to deal with nested mounts and otherwise cannot safely determine whether to repeat
|
||||||
|
+ * the unmounts. In theory, the kernel fires /proc/self/mountinfo changes off before returning from
|
||||||
|
+ * the mount() or umount() syscalls, and thus we should see the changes to the proc file before we
|
||||||
|
+ * process the waitid() for the /usr/bin/(u)mount processes. However, this is unfortunately racy: we
|
||||||
|
+ * have to waitid() for processes using P_ALL (since we need to reap unexpected children that got
|
||||||
|
+ * reparented to PID 1), but when using P_ALL we might end up reaping processes that terminated just
|
||||||
|
+ * instants ago, i.e. already after our last event loop iteration (i.e. after the last point we might
|
||||||
|
+ * have noticed /proc/self/mountinfo events via epoll). This means event loop priorities for
|
||||||
|
+ * processing SIGCHLD vs. /proc/self/mountinfo IO events are not as relevant as we want. To fix that
|
||||||
|
+ * race, let's explicitly scan /proc/self/mountinfo before we start processing /usr/bin/(u)mount
|
||||||
|
+ * dying. It's ugly, but it makes our ordering systematic again, and makes sure we always see
|
||||||
|
+ * /proc/self/mountinfo changes before our mount/umount exits. */
|
||||||
|
+ (void) mount_process_proc_self_mountinfo(u->manager);
|
||||||
|
+
|
||||||
|
m->control_pid = 0;
|
||||||
|
|
||||||
|
if (is_clean_exit(code, status, EXIT_CLEAN_COMMAND, NULL))
|
||||||
|
@@ -1781,16 +1798,14 @@ static int drain_libmount(Manager *m) {
|
||||||
|
return rescan;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
|
||||||
|
+static int mount_process_proc_self_mountinfo(Manager *m) {
|
||||||
|
_cleanup_set_free_ Set *around = NULL, *gone = NULL;
|
||||||
|
- Manager *m = userdata;
|
||||||
|
const char *what;
|
||||||
|
Iterator i;
|
||||||
|
Unit *u;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(m);
|
||||||
|
- assert(revents & EPOLLIN);
|
||||||
|
|
||||||
|
r = drain_libmount(m);
|
||||||
|
if (r <= 0)
|
||||||
|
@@ -1898,6 +1913,15 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
|
||||||
|
+ Manager *m = userdata;
|
||||||
|
+
|
||||||
|
+ assert(m);
|
||||||
|
+ assert(revents & EPOLLIN);
|
||||||
|
+
|
||||||
|
+ return mount_process_proc_self_mountinfo(m);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void mount_reset_failed(Unit *u) {
|
||||||
|
Mount *m = MOUNT(u);
|
||||||
|
|
@ -0,0 +1,69 @@
|
|||||||
|
From a0c135f7771dbe3a6cd3da2aaa106900be0f4470 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Wed, 17 Jul 2019 18:58:44 +0200
|
||||||
|
Subject: [PATCH] swap: scan /proc/swaps before processing waitid() results
|
||||||
|
|
||||||
|
Similar to the previous commit, but for /proc/swaps, where the same
|
||||||
|
logic and rationale applies.
|
||||||
|
|
||||||
|
(cherry picked from commit bcce581d65de68cca01c73e1c890e261e72d20af)
|
||||||
|
|
||||||
|
Related: #1696178
|
||||||
|
---
|
||||||
|
src/core/swap.c | 18 +++++++++++++++---
|
||||||
|
1 file changed, 15 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/swap.c b/src/core/swap.c
|
||||||
|
index e01e61e56d..b644753a1c 100644
|
||||||
|
--- a/src/core/swap.c
|
||||||
|
+++ b/src/core/swap.c
|
||||||
|
@@ -40,6 +40,7 @@ static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = {
|
||||||
|
|
||||||
|
static int swap_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
|
||||||
|
static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
|
||||||
|
+static int swap_process_proc_swaps(Manager *m);
|
||||||
|
|
||||||
|
static bool SWAP_STATE_WITH_PROCESS(SwapState state) {
|
||||||
|
return IN_SET(state,
|
||||||
|
@@ -990,6 +991,10 @@ static void swap_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||||
|
if (pid != s->control_pid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
+ /* Let's scan /proc/swaps before we process SIGCHLD. For the reasoning see the similar code in
|
||||||
|
+ * mount.c */
|
||||||
|
+ (void) swap_process_proc_swaps(u->manager);
|
||||||
|
+
|
||||||
|
s->control_pid = 0;
|
||||||
|
|
||||||
|
if (is_clean_exit(code, status, EXIT_CLEAN_COMMAND, NULL))
|
||||||
|
@@ -1125,13 +1130,11 @@ static int swap_load_proc_swaps(Manager *m, bool set_flags) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
|
||||||
|
- Manager *m = userdata;
|
||||||
|
+static int swap_process_proc_swaps(Manager *m) {
|
||||||
|
Unit *u;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(m);
|
||||||
|
- assert(revents & EPOLLPRI);
|
||||||
|
|
||||||
|
r = swap_load_proc_swaps(m, true);
|
||||||
|
if (r < 0) {
|
||||||
|
@@ -1205,6 +1208,15 @@ static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, v
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int swap_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
|
||||||
|
+ Manager *m = userdata;
|
||||||
|
+
|
||||||
|
+ assert(m);
|
||||||
|
+ assert(revents & EPOLLPRI);
|
||||||
|
+
|
||||||
|
+ return swap_process_proc_swaps(m);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static Unit *swap_following(Unit *u) {
|
||||||
|
Swap *s = SWAP(u);
|
||||||
|
Swap *other, *first = NULL;
|
@ -0,0 +1,25 @@
|
|||||||
|
From ebe93460ef5ae3744c4b627361f4dc5815cffc13 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Synacek <jsynacek@redhat.com>
|
||||||
|
Date: Wed, 31 Jul 2019 09:13:41 +0200
|
||||||
|
Subject: [PATCH] analyze-security: fix potential division by zero
|
||||||
|
|
||||||
|
Upstream PR: https://github.com/systemd/systemd/pull/13238
|
||||||
|
|
||||||
|
Resolves: #1734400
|
||||||
|
---
|
||||||
|
src/analyze/analyze-security.c | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/analyze/analyze-security.c b/src/analyze/analyze-security.c
|
||||||
|
index 541fc0d97a..eec040d5c3 100644
|
||||||
|
--- a/src/analyze/analyze-security.c
|
||||||
|
+++ b/src/analyze/analyze-security.c
|
||||||
|
@@ -1494,6 +1494,8 @@ static int assess(const struct security_info *info, Table *overview_table, Analy
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ assert(weight_sum > 0);
|
||||||
|
+
|
||||||
|
if (details_table) {
|
||||||
|
size_t row;
|
||||||
|
|
@ -0,0 +1,26 @@
|
|||||||
|
From cffe5d0e781f6fa7f2275b94d2dcc26e00859a78 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Wed, 17 Jul 2019 19:16:33 +0200
|
||||||
|
Subject: [PATCH] core: never propagate reload failure to service result
|
||||||
|
|
||||||
|
Fixes: #11238
|
||||||
|
(cherry picked from commit d611cfa748aaf600832160132774074e808c82c7)
|
||||||
|
|
||||||
|
Resolves: #1735787
|
||||||
|
---
|
||||||
|
src/core/service.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/service.c b/src/core/service.c
|
||||||
|
index 8342c131c8..24f167572a 100644
|
||||||
|
--- a/src/core/service.c
|
||||||
|
+++ b/src/core/service.c
|
||||||
|
@@ -3310,7 +3310,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||||
|
"Control process exited, code=%s status=%i",
|
||||||
|
sigchld_code_to_string(code), status);
|
||||||
|
|
||||||
|
- if (s->result == SERVICE_SUCCESS)
|
||||||
|
+ if (s->state != SERVICE_RELOAD && s->result == SERVICE_SUCCESS)
|
||||||
|
s->result = f;
|
||||||
|
|
||||||
|
if (s->control_command &&
|
59
SOURCES/0217-man-document-systemd-analyze-security.patch
Normal file
59
SOURCES/0217-man-document-systemd-analyze-security.patch
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
From d11fdacaf3c804b60dfe8371062f34ac2b624ac9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Synacek <jsynacek@redhat.com>
|
||||||
|
Date: Fri, 13 Sep 2019 09:23:32 +0200
|
||||||
|
Subject: [PATCH] man: document systemd-analyze security
|
||||||
|
|
||||||
|
(cherry-picked from commit ee93c1e664a7bbc59f1578e285c871999507b14d)
|
||||||
|
|
||||||
|
Resolves: #1750343
|
||||||
|
---
|
||||||
|
man/systemd-analyze.xml | 29 +++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 29 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml
|
||||||
|
index 7aa10fc68e..f3b595880f 100644
|
||||||
|
--- a/man/systemd-analyze.xml
|
||||||
|
+++ b/man/systemd-analyze.xml
|
||||||
|
@@ -106,6 +106,12 @@
|
||||||
|
<arg choice="plain">service-watchdogs</arg>
|
||||||
|
<arg choice="opt"><replaceable>BOOL</replaceable></arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
+ <cmdsynopsis>
|
||||||
|
+ <command>systemd-analyze</command>
|
||||||
|
+ <arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||||
|
+ <arg choice="plain">security</arg>
|
||||||
|
+ <arg choice="plain" rep="repeat"><replaceable>UNIT</replaceable></arg>
|
||||||
|
+ </cmdsynopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
@@ -253,6 +259,29 @@ NAutoVTs=8
|
||||||
|
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||||
|
The hardware watchdog is not affected by this setting.</para>
|
||||||
|
|
||||||
|
+ <para><command>systemd-analyze security</command> analyzes the security and sandboxing settings of one or more
|
||||||
|
+ specified service units. If at least one unit name is specified the security settings of the specified service
|
||||||
|
+ units are inspected and a detailed analysis is shown. If no unit name is specified, all currently loaded,
|
||||||
|
+ long-running service units are inspected and a terse table with results shown. The command checks for various
|
||||||
|
+ security-related service settings, assigning each a numeric "exposure level" value, depending on how important a
|
||||||
|
+ setting is. It then calculates an overall exposure level for the whole unit, which is an estimation in the range
|
||||||
|
+ 0.0…10.0 indicating how exposed a service is security-wise. High exposure levels indicate very little applied
|
||||||
|
+ sandboxing. Low exposure levels indicate tight sandboxing and strongest security restrictions. Note that this only
|
||||||
|
+ analyzes the per-service security features systemd itself implements. This means that any additional security
|
||||||
|
+ mechanisms applied by the service code itself are not accounted for. The exposure level determined this way should
|
||||||
|
+ not be misunderstood: a high exposure level neither means that there is no effective sandboxing applied by the
|
||||||
|
+ service code itself, nor that the service is actually vulnerable to remote or local attacks. High exposure levels
|
||||||
|
+ do indicate however that most likely the service might benefit from additional settings applied to them. Please
|
||||||
|
+ note that many of the security and sandboxing settings individually can be circumvented — unless combined with
|
||||||
|
+ others. For example, if a service retains the privilege to establish or undo mount points many of the sandboxing
|
||||||
|
+ options can be undone by the service code itself. Due to that is essential that each service uses the most
|
||||||
|
+ comprehensive and strict sandboxing and security settings possible. The tool will take into account some of these
|
||||||
|
+ combinations and relationships between the settings, but not all. Also note that the security and sandboxing
|
||||||
|
+ settings analyzed here only apply to the operations executed by the service code itself. If a service has access to
|
||||||
|
+ an IPC system (such as D-Bus) it might request operations from other services that are not subject to the same
|
||||||
|
+ restrictions. Any comprehensive security and sandboxing analysis is hence incomplete if the IPC access policy is
|
||||||
|
+ not validated too.</para>
|
||||||
|
+
|
||||||
|
<para>If no command is passed, <command>systemd-analyze
|
||||||
|
time</command> is implied.</para>
|
||||||
|
|
@ -0,0 +1,772 @@
|
|||||||
|
From a2e00522971897909db2a81b4daf10e5700f453e Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Fri, 15 Mar 2019 10:13:55 +0100
|
||||||
|
Subject: [PATCH] man: reorder and add examples to systemd-analyze(1)
|
||||||
|
|
||||||
|
The number of verbs supported by systemd-analyze has grown quite a bit, and the
|
||||||
|
man page has become an unreadable wall of text. Let's put each verb in a
|
||||||
|
separate subsection, grouping similar verbs together, and add a lot of examples
|
||||||
|
to guide the user.
|
||||||
|
|
||||||
|
(cherry picked from commit d323a99001c1f7625e8ac902e18deb514a4ca18d)
|
||||||
|
|
||||||
|
Related: #1750343
|
||||||
|
---
|
||||||
|
man/systemd-analyze.xml | 678 +++++++++++++++++++++++++---------------
|
||||||
|
1 file changed, 429 insertions(+), 249 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml
|
||||||
|
index f3b595880f..7c873cbdd1 100644
|
||||||
|
--- a/man/systemd-analyze.xml
|
||||||
|
+++ b/man/systemd-analyze.xml
|
||||||
|
@@ -41,46 +41,50 @@
|
||||||
|
<arg choice="plain">critical-chain</arg>
|
||||||
|
<arg choice="opt" rep="repeat"><replaceable>UNIT</replaceable></arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
+
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>systemd-analyze</command>
|
||||||
|
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||||
|
- <arg choice="plain">plot</arg>
|
||||||
|
- <arg choice="opt">> file.svg</arg>
|
||||||
|
+ <arg choice="plain">log-level</arg>
|
||||||
|
+ <arg choice="opt"><replaceable>LEVEL</replaceable></arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>systemd-analyze</command>
|
||||||
|
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||||
|
- <arg choice="plain">dot</arg>
|
||||||
|
- <arg choice="opt" rep="repeat"><replaceable>PATTERN</replaceable></arg>
|
||||||
|
- <arg choice="opt">> file.dot</arg>
|
||||||
|
+ <arg choice="plain">log-target</arg>
|
||||||
|
+ <arg choice="opt"><replaceable>TARGET</replaceable></arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>systemd-analyze</command>
|
||||||
|
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||||
|
- <arg choice="plain">dump</arg>
|
||||||
|
+ <arg choice="plain">service-watchdogs</arg>
|
||||||
|
+ <arg choice="opt"><replaceable>BOOL</replaceable></arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
+
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>systemd-analyze</command>
|
||||||
|
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||||
|
- <arg choice="plain">cat-config</arg>
|
||||||
|
- <arg choice="plain" rep="repeat"><replaceable>NAME</replaceable>|<replaceable>PATH</replaceable></arg>
|
||||||
|
+ <arg choice="plain">dump</arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
+
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>systemd-analyze</command>
|
||||||
|
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||||
|
- <arg choice="plain">unit-paths</arg>
|
||||||
|
+ <arg choice="plain">plot</arg>
|
||||||
|
+ <arg choice="opt">>file.svg</arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>systemd-analyze</command>
|
||||||
|
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||||
|
- <arg choice="plain">log-level</arg>
|
||||||
|
- <arg choice="opt"><replaceable>LEVEL</replaceable></arg>
|
||||||
|
+ <arg choice="plain">dot</arg>
|
||||||
|
+ <arg choice="opt" rep="repeat"><replaceable>PATTERN</replaceable></arg>
|
||||||
|
+ <arg choice="opt">>file.dot</arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
+
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>systemd-analyze</command>
|
||||||
|
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||||
|
- <arg choice="plain">log-target</arg>
|
||||||
|
- <arg choice="opt"><replaceable>TARGET</replaceable></arg>
|
||||||
|
+ <arg choice="plain">unit-paths</arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>systemd-analyze</command>
|
||||||
|
@@ -91,20 +95,20 @@
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>systemd-analyze</command>
|
||||||
|
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||||
|
- <arg choice="plain">verify</arg>
|
||||||
|
- <arg choice="opt" rep="repeat"><replaceable>FILES</replaceable></arg>
|
||||||
|
+ <arg choice="plain">calendar</arg>
|
||||||
|
+ <arg choice="plain" rep="repeat"><replaceable>SPECS</replaceable></arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>systemd-analyze</command>
|
||||||
|
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||||
|
- <arg choice="plain">calendar</arg>
|
||||||
|
- <arg choice="plain" rep="repeat"><replaceable>SPECS</replaceable></arg>
|
||||||
|
+ <arg choice="plain">timespan</arg>
|
||||||
|
+ <arg choice="plain" rep="repeat"><replaceable>SPAN</replaceable></arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>systemd-analyze</command>
|
||||||
|
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||||
|
- <arg choice="plain">service-watchdogs</arg>
|
||||||
|
- <arg choice="opt"><replaceable>BOOL</replaceable></arg>
|
||||||
|
+ <arg choice="plain">cat-config</arg>
|
||||||
|
+ <arg choice="plain" rep="repeat"><replaceable>NAME</replaceable>|<replaceable>PATH</replaceable></arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>systemd-analyze</command>
|
||||||
|
@@ -123,73 +127,299 @@
|
||||||
|
verify the correctness of unit files. It is also used to access
|
||||||
|
special functions useful for advanced system manager debugging.</para>
|
||||||
|
|
||||||
|
- <para><command>systemd-analyze time</command> prints the time
|
||||||
|
- spent in the kernel before userspace has been reached, the time
|
||||||
|
- spent in the initial RAM disk (initrd) before normal system
|
||||||
|
- userspace has been reached, and the time normal system userspace
|
||||||
|
- took to initialize. Note that these measurements simply measure
|
||||||
|
- the time passed up to the point where all system services have
|
||||||
|
- been spawned, but not necessarily until they fully finished
|
||||||
|
- initialization or the disk is idle.</para>
|
||||||
|
-
|
||||||
|
- <para><command>systemd-analyze blame</command> prints a list of
|
||||||
|
- all running units, ordered by the time they took to initialize.
|
||||||
|
- This information may be used to optimize boot-up times. Note that
|
||||||
|
- the output might be misleading as the initialization of one
|
||||||
|
- service might be slow simply because it waits for the
|
||||||
|
- initialization of another service to complete.
|
||||||
|
- Also note: <command>systemd-analyze blame</command> doesn't display
|
||||||
|
- results for services with <varname>Type=simple</varname>,
|
||||||
|
- because systemd considers such services to be started immediately,
|
||||||
|
- hence no measurement of the initialization delays can be done.</para>
|
||||||
|
-
|
||||||
|
- <para><command>systemd-analyze critical-chain
|
||||||
|
- [<replaceable>UNIT…</replaceable>]</command> prints a tree of
|
||||||
|
- the time-critical chain of units (for each of the specified
|
||||||
|
- <replaceable>UNIT</replaceable>s or for the default target
|
||||||
|
- otherwise). The time after the unit is active or started is
|
||||||
|
- printed after the "@" character. The time the unit takes to start
|
||||||
|
- is printed after the "+" character. Note that the output might be
|
||||||
|
- misleading as the initialization of one service might depend on
|
||||||
|
- socket activation and because of the parallel execution of
|
||||||
|
- units.</para>
|
||||||
|
-
|
||||||
|
- <para><command>systemd-analyze plot</command> prints an SVG
|
||||||
|
- graphic detailing which system services have been started at what
|
||||||
|
- time, highlighting the time they spent on initialization.</para>
|
||||||
|
-
|
||||||
|
- <para><command>systemd-analyze dot</command> generates textual
|
||||||
|
- dependency graph description in dot format for further processing
|
||||||
|
- with the GraphViz
|
||||||
|
- <citerefentry project='die-net'><refentrytitle>dot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||||
|
- tool. Use a command line like <command>systemd-analyze dot | dot
|
||||||
|
- -Tsvg > systemd.svg</command> to generate a graphical dependency
|
||||||
|
- tree. Unless <option>--order</option> or
|
||||||
|
- <option>--require</option> is passed, the generated graph will
|
||||||
|
- show both ordering and requirement dependencies. Optional pattern
|
||||||
|
- globbing style specifications (e.g. <filename>*.target</filename>)
|
||||||
|
- may be given at the end. A unit dependency is included in the
|
||||||
|
- graph if any of these patterns match either the origin or
|
||||||
|
- destination node.</para>
|
||||||
|
-
|
||||||
|
- <para><command>systemd-analyze dump</command> outputs a (usually
|
||||||
|
- very long) human-readable serialization of the complete server
|
||||||
|
- state. Its format is subject to change without notice and should
|
||||||
|
- not be parsed by applications.</para>
|
||||||
|
-
|
||||||
|
- <para><command>systemd-analyze cat-config</command> is similar
|
||||||
|
- to <command>systemctl cat</command>, but operates on config files.
|
||||||
|
- It will copy the contents of a config file and any drop-ins to standard
|
||||||
|
- output, using the usual systemd set of directories and rules for
|
||||||
|
- precedence. Each argument must be either an absolute path including
|
||||||
|
- the prefix (such as <filename>/etc/systemd/logind.conf</filename> or
|
||||||
|
- <filename>/usr/lib/systemd/logind.conf</filename>), or a name
|
||||||
|
- relative to the prefix (such as <filename>systemd/logind.conf</filename>).
|
||||||
|
- </para>
|
||||||
|
+ <para>If no command is passed, <command>systemd-analyze
|
||||||
|
+ time</command> is implied.</para>
|
||||||
|
+
|
||||||
|
+ <refsect2>
|
||||||
|
+ <title><command>systemd-analyze time</command></title>
|
||||||
|
+
|
||||||
|
+ <para>This command prints the time spent in the kernel before userspace has been reached, the time
|
||||||
|
+ spent in the initial RAM disk (initrd) before normal system userspace has been reached, and the time
|
||||||
|
+ normal system userspace took to initialize. Note that these measurements simply measure the time passed
|
||||||
|
+ up to the point where all system services have been spawned, but not necessarily until they fully
|
||||||
|
+ finished initialization or the disk is idle.</para>
|
||||||
|
+
|
||||||
|
+ <example>
|
||||||
|
+ <title><command>Show how long the boot took</command></title>
|
||||||
|
+
|
||||||
|
+ <programlisting># in a container
|
||||||
|
+$ systemd-analyze time
|
||||||
|
+Startup finished in 296ms (userspace)
|
||||||
|
+multi-user.target reached after 275ms in userspace
|
||||||
|
+
|
||||||
|
+# on a real machine
|
||||||
|
+$ systemd-analyze time
|
||||||
|
+Startup finished in 2.584s (kernel) + 19.176s (initrd) + 47.847s (userspace) = 1min 9.608s
|
||||||
|
+multi-user.target reached after 47.820s in userspace
|
||||||
|
+</programlisting>
|
||||||
|
+ </example>
|
||||||
|
+ </refsect2>
|
||||||
|
+
|
||||||
|
+ <refsect2>
|
||||||
|
+ <title><command>systemd-analyze blame</command></title>
|
||||||
|
+
|
||||||
|
+ <para>This command prints a list of all running units, ordered by the time they took to initialize.
|
||||||
|
+ This information may be used to optimize boot-up times. Note that the output might be misleading as the
|
||||||
|
+ initialization of one service might be slow simply because it waits for the initialization of another
|
||||||
|
+ service to complete. Also note: <command>systemd-analyze blame</command> doesn't display results for
|
||||||
|
+ services with <varname>Type=simple</varname>, because systemd considers such services to be started
|
||||||
|
+ immediately, hence no measurement of the initialization delays can be done.</para>
|
||||||
|
+
|
||||||
|
+ <example>
|
||||||
|
+ <title><command>Show which units took the most time during boot</command></title>
|
||||||
|
+
|
||||||
|
+ <programlisting>$ systemd-analyze blame
|
||||||
|
+ 32.875s pmlogger.service
|
||||||
|
+ 20.905s systemd-networkd-wait-online.service
|
||||||
|
+ 13.299s dev-vda1.device
|
||||||
|
+ ...
|
||||||
|
+ 23ms sysroot.mount
|
||||||
|
+ 11ms initrd-udevadm-cleanup-db.service
|
||||||
|
+ 3ms sys-kernel-config.mount
|
||||||
|
+ </programlisting>
|
||||||
|
+ </example>
|
||||||
|
+ </refsect2>
|
||||||
|
+
|
||||||
|
+ <refsect2>
|
||||||
|
+ <title><command>systemd-analyze critical-chain <optional><replaceable>UNIT</replaceable>...</optional></command></title>
|
||||||
|
+
|
||||||
|
+ <para>This command prints a tree of the time-critical chain of units (for each of the specified
|
||||||
|
+ <replaceable>UNIT</replaceable>s or for the default target otherwise). The time after the unit is
|
||||||
|
+ active or started is printed after the "@" character. The time the unit takes to start is printed after
|
||||||
|
+ the "+" character. Note that the output might be misleading as the initialization of services might
|
||||||
|
+ depend on socket activation and because of the parallel execution of units.</para>
|
||||||
|
+
|
||||||
|
+ <example>
|
||||||
|
+ <title><command>systemd-analyze time</command></title>
|
||||||
|
+
|
||||||
|
+ <programlisting>$ systemd-analyze critical-chain
|
||||||
|
+multi-user.target @47.820s
|
||||||
|
+└─pmie.service @35.968s +548ms
|
||||||
|
+ └─pmcd.service @33.715s +2.247s
|
||||||
|
+ └─network-online.target @33.712s
|
||||||
|
+ └─systemd-networkd-wait-online.service @12.804s +20.905s
|
||||||
|
+ └─systemd-networkd.service @11.109s +1.690s
|
||||||
|
+ └─systemd-udevd.service @9.201s +1.904s
|
||||||
|
+ └─systemd-tmpfiles-setup-dev.service @7.306s +1.776s
|
||||||
|
+ └─kmod-static-nodes.service @6.976s +177ms
|
||||||
|
+ └─systemd-journald.socket
|
||||||
|
+ └─system.slice
|
||||||
|
+ └─-.slice
|
||||||
|
+</programlisting>
|
||||||
|
+ </example>
|
||||||
|
+ </refsect2>
|
||||||
|
+
|
||||||
|
+ <refsect2>
|
||||||
|
+ <title><command>systemd-analyze log-level [<replaceable>LEVEL</replaceable>]</command></title>
|
||||||
|
+
|
||||||
|
+ <para><command>systemd-analyze log-level</command> prints the current log level of the
|
||||||
|
+ <command>systemd</command> daemon. If an optional argument <replaceable>LEVEL</replaceable> is
|
||||||
|
+ provided, then the command changes the current log level of the <command>systemd</command> daemon to
|
||||||
|
+ <replaceable>LEVEL</replaceable> (accepts the same values as <option>--log-level=</option> described in
|
||||||
|
+ <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>).</para>
|
||||||
|
+ </refsect2>
|
||||||
|
+
|
||||||
|
+ <refsect2>
|
||||||
|
+ <title><command>systemd-analyze log-target [<replaceable>TARGET</replaceable>]</command></title>
|
||||||
|
+
|
||||||
|
+ <para><command>systemd-analyze log-target</command> prints the current log target of the
|
||||||
|
+ <command>systemd</command> daemon. If an optional argument <replaceable>TARGET</replaceable> is
|
||||||
|
+ provided, then the command changes the current log target of the <command>systemd</command> daemon to
|
||||||
|
+ <replaceable>TARGET</replaceable> (accepts the same values as <option>--log-target=</option>, described
|
||||||
|
+ in <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>).</para>
|
||||||
|
+ </refsect2>
|
||||||
|
+
|
||||||
|
+ <refsect2>
|
||||||
|
+ <title><command>systemd-analyze service-watchdogs [yes|no]</command></title>
|
||||||
|
+
|
||||||
|
+ <para><command>systemd-analyze service-watchdogs</command> prints the current state of service runtime
|
||||||
|
+ watchdogs of the <command>systemd</command> daemon. If an optional boolean argument is provided, then
|
||||||
|
+ globally enables or disables the service runtime watchdogs (<option>WatchdogSec=</option>) and
|
||||||
|
+ emergency actions (e.g. <option>OnFailure=</option> or <option>StartLimitAction=</option>); see
|
||||||
|
+ <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||||
|
+ The hardware watchdog is not affected by this setting.</para>
|
||||||
|
+ </refsect2>
|
||||||
|
+
|
||||||
|
+ <refsect2>
|
||||||
|
+ <title><command>systemd-analyze dump</command></title>
|
||||||
|
+
|
||||||
|
+ <para>This command outputs a (usually very long) human-readable serialization of the complete server
|
||||||
|
+ state. Its format is subject to change without notice and should not be parsed by applications.</para>
|
||||||
|
+
|
||||||
|
+ <example>
|
||||||
|
+ <title>Show the internal state of user manager</title>
|
||||||
|
+
|
||||||
|
+ <programlisting>$ systemd-analyze --user dump
|
||||||
|
+Timestamp userspace: Thu 2019-03-14 23:28:07 CET
|
||||||
|
+Timestamp finish: Thu 2019-03-14 23:28:07 CET
|
||||||
|
+Timestamp generators-start: Thu 2019-03-14 23:28:07 CET
|
||||||
|
+Timestamp generators-finish: Thu 2019-03-14 23:28:07 CET
|
||||||
|
+Timestamp units-load-start: Thu 2019-03-14 23:28:07 CET
|
||||||
|
+Timestamp units-load-finish: Thu 2019-03-14 23:28:07 CET
|
||||||
|
+-> Unit proc-timer_list.mount:
|
||||||
|
+ Description: /proc/timer_list
|
||||||
|
+ ...
|
||||||
|
+-> Unit default.target:
|
||||||
|
+ Description: Main user target
|
||||||
|
+...
|
||||||
|
+</programlisting>
|
||||||
|
+ </example>
|
||||||
|
+ </refsect2>
|
||||||
|
+
|
||||||
|
+ <refsect2>
|
||||||
|
+ <title><command>systemd-analyze plot</command></title>
|
||||||
|
+
|
||||||
|
+ <para>This command prints an SVG graphic detailing which system services have been started at what
|
||||||
|
+ time, highlighting the time they spent on initialization.</para>
|
||||||
|
+
|
||||||
|
+ <example>
|
||||||
|
+ <title><command>Plot a bootchart</command></title>
|
||||||
|
+
|
||||||
|
+ <programlisting>$ systemd-analyze plot >bootup.svg
|
||||||
|
+$ eog bootup.svg&
|
||||||
|
+</programlisting>
|
||||||
|
+ </example>
|
||||||
|
+ </refsect2>
|
||||||
|
+
|
||||||
|
+ <refsect2>
|
||||||
|
+ <title><command>systemd-analyze dot [<replaceable>pattern</replaceable>...]</command></title>
|
||||||
|
+
|
||||||
|
+ <para>This command generates textual dependency graph description in dot format for further processing
|
||||||
|
+ with the GraphViz
|
||||||
|
+ <citerefentry project='die-net'><refentrytitle>dot</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||||
|
+ tool. Use a command line like <command>systemd-analyze dot | dot -Tsvg >systemd.svg</command> to
|
||||||
|
+ generate a graphical dependency tree. Unless <option>--order</option> or <option>--require</option> is
|
||||||
|
+ passed, the generated graph will show both ordering and requirement dependencies. Optional pattern
|
||||||
|
+ globbing style specifications (e.g. <filename>*.target</filename>) may be given at the end. A unit
|
||||||
|
+ dependency is included in the graph if any of these patterns match either the origin or destination
|
||||||
|
+ node.</para>
|
||||||
|
+
|
||||||
|
+ <example>
|
||||||
|
+ <title>Plot all dependencies of any unit whose name starts with <literal>avahi-daemon</literal>
|
||||||
|
+ </title>
|
||||||
|
+
|
||||||
|
+ <programlisting>$ systemd-analyze dot 'avahi-daemon.*' | dot -Tsvg >avahi.svg
|
||||||
|
+$ eog avahi.svg</programlisting>
|
||||||
|
+ </example>
|
||||||
|
+
|
||||||
|
+ <example>
|
||||||
|
+ <title>Plot the dependencies between all known target units</title>
|
||||||
|
|
||||||
|
- <example>
|
||||||
|
- <title>Showing logind configuration</title>
|
||||||
|
- <programlisting>$ systemd-analyze cat-config systemd/logind.conf
|
||||||
|
+ <programlisting>$ systemd-analyze dot --to-pattern='*.target' --from-pattern='*.target' \
|
||||||
|
+ | dot -Tsvg >targets.svg
|
||||||
|
+$ eog targets.svg</programlisting>
|
||||||
|
+ </example>
|
||||||
|
+ </refsect2>
|
||||||
|
+
|
||||||
|
+ <refsect2>
|
||||||
|
+ <title><command>systemd-analyze unit-paths</command></title>
|
||||||
|
+
|
||||||
|
+ <para>This command outputs a list of all directories from which unit files, <filename>.d</filename>
|
||||||
|
+ overrides, and <filename>.wants</filename>, <filename>.requires</filename> symlinks may be
|
||||||
|
+ loaded. Combine with <option>--user</option> to retrieve the list for the user manager instance, and
|
||||||
|
+ <option>--global</option> for the global configuration of user manager instances.</para>
|
||||||
|
+
|
||||||
|
+ <example>
|
||||||
|
+ <title><command>Show all paths for generated units</command></title>
|
||||||
|
+
|
||||||
|
+ <programlisting>$ systemd-analyze unit-paths | grep '^/run'
|
||||||
|
+/run/systemd/system.control
|
||||||
|
+/run/systemd/transient
|
||||||
|
+/run/systemd/generator.early
|
||||||
|
+/run/systemd/system
|
||||||
|
+/run/systemd/system.attached
|
||||||
|
+/run/systemd/generator
|
||||||
|
+/run/systemd/generator.late
|
||||||
|
+</programlisting>
|
||||||
|
+ </example>
|
||||||
|
+
|
||||||
|
+ <para>Note that this verb prints the list that is compiled into <command>systemd-analyze</command>
|
||||||
|
+ itself, and does not comunicate with the running manager. Use
|
||||||
|
+ <programlisting>systemctl [--user] [--global] show -p UnitPath --value</programlisting>
|
||||||
|
+ to retrieve the actual list that the manager uses, with any empty directories omitted.</para>
|
||||||
|
+ </refsect2>
|
||||||
|
+
|
||||||
|
+ <refsect2>
|
||||||
|
+ <title><command>systemd-analyze syscall-filter <optional><replaceable>SET</replaceable>...</optional></command></title>
|
||||||
|
+
|
||||||
|
+ <para>This command will list system calls contained in the specified system call set
|
||||||
|
+ <replaceable>SET</replaceable>, or all known sets if no sets are specified. Argument
|
||||||
|
+ <replaceable>SET</replaceable> must include the <literal>@</literal> prefix.</para>
|
||||||
|
+ </refsect2>
|
||||||
|
+
|
||||||
|
+ <refsect2>
|
||||||
|
+ <title><command>systemd-analyze calendar <replaceable>EXPRESSION</replaceable>...</command></title>
|
||||||
|
+
|
||||||
|
+ <para>This command will parse and normalize repetitive calendar time events, and will calculate when
|
||||||
|
+ they elapse next. This takes the same input as the <varname>OnCalendar=</varname> setting in
|
||||||
|
+ <citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||||
|
+ following the syntax described in
|
||||||
|
+ <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>. By
|
||||||
|
+ default, only the next time the calendar expression will elapse is shown; use
|
||||||
|
+ <option>--iterations=</option> to show the specified number of next times the expression
|
||||||
|
+ elapses.</para>
|
||||||
|
+
|
||||||
|
+ <example>
|
||||||
|
+ <title>Show leap days in the near future</title>
|
||||||
|
+
|
||||||
|
+ <programlisting>$ systemd-analyze calendar --iterations=5 '*-2-29 0:0:0'
|
||||||
|
+ Original form: *-2-29 0:0:0
|
||||||
|
+Normalized form: *-02-29 00:00:00
|
||||||
|
+ Next elapse: Sat 2020-02-29 00:00:00 UTC
|
||||||
|
+ From now: 11 months 15 days left
|
||||||
|
+ Iter. #2: Thu 2024-02-29 00:00:00 UTC
|
||||||
|
+ From now: 4 years 11 months left
|
||||||
|
+ Iter. #3: Tue 2028-02-29 00:00:00 UTC
|
||||||
|
+ From now: 8 years 11 months left
|
||||||
|
+ Iter. #4: Sun 2032-02-29 00:00:00 UTC
|
||||||
|
+ From now: 12 years 11 months left
|
||||||
|
+ Iter. #5: Fri 2036-02-29 00:00:00 UTC
|
||||||
|
+ From now: 16 years 11 months left
|
||||||
|
+</programlisting>
|
||||||
|
+ </example>
|
||||||
|
+ </refsect2>
|
||||||
|
+
|
||||||
|
+ <refsect2>
|
||||||
|
+ <title><command>systemd-analyze timespan <replaceable>EXPRESSION</replaceable>...</command></title>
|
||||||
|
+
|
||||||
|
+ <para>This command parses a time span and outputs the normalized form and the equivalent value in
|
||||||
|
+ microseconds. The time span should adhere to the same syntax documented in
|
||||||
|
+ <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
|
||||||
|
+ Values without associated magnitudes are parsed as seconds.</para>
|
||||||
|
+
|
||||||
|
+ <example>
|
||||||
|
+ <title>Show parsing of timespans</title>
|
||||||
|
+
|
||||||
|
+ <programlisting>$ systemd-analyze timespan 1s 300s '1year 0.000001s'
|
||||||
|
+Original: 1s
|
||||||
|
+ μs: 1000000
|
||||||
|
+ Human: 1s
|
||||||
|
+
|
||||||
|
+Original: 300s
|
||||||
|
+ μs: 300000000
|
||||||
|
+ Human: 5min
|
||||||
|
+
|
||||||
|
+Original: 1year 0.000001s
|
||||||
|
+ μs: 31557600000001
|
||||||
|
+ Human: 1y 1us
|
||||||
|
+</programlisting>
|
||||||
|
+ </example>
|
||||||
|
+ </refsect2>
|
||||||
|
+
|
||||||
|
+ <refsect2>
|
||||||
|
+ <title><command>systemd-analyze cat-config</command>
|
||||||
|
+ <replaceable>NAME</replaceable>|<replaceable>PATH</replaceable>...</title>
|
||||||
|
+
|
||||||
|
+ <para>This command is similar to <command>systemctl cat</command>, but operates on config files. It
|
||||||
|
+ will copy the contents of a config file and any drop-ins to standard output, using the usual systemd
|
||||||
|
+ set of directories and rules for precedence. Each argument must be either an absolute path including
|
||||||
|
+ the prefix (such as <filename>/etc/systemd/logind.conf</filename> or
|
||||||
|
+ <filename>/usr/lib/systemd/logind.conf</filename>), or a name relative to the prefix (such as
|
||||||
|
+ <filename>systemd/logind.conf</filename>).</para>
|
||||||
|
+
|
||||||
|
+ <example>
|
||||||
|
+ <title>Showing logind configuration</title>
|
||||||
|
+ <programlisting>$ systemd-analyze cat-config systemd/logind.conf
|
||||||
|
# /etc/systemd/logind.conf
|
||||||
|
...
|
||||||
|
[Login]
|
||||||
|
@@ -201,90 +431,122 @@ NAutoVTs=8
|
||||||
|
|
||||||
|
# /etc/systemd/logind.conf.d/50-override.conf
|
||||||
|
... some administrator override
|
||||||
|
- </programlisting>
|
||||||
|
- </example>
|
||||||
|
-
|
||||||
|
- <para><command>systemd-analyze unit-paths</command> outputs a list of all
|
||||||
|
- directories from which unit files, <filename>.d</filename> overrides, and
|
||||||
|
- <filename>.wants</filename>, <filename>.requires</filename> symlinks may be
|
||||||
|
- loaded. Combine with <option>--user</option> to retrieve the list for the user
|
||||||
|
- manager instance, and <option>--global</option> for the global configuration of
|
||||||
|
- user manager instances. Note that this verb prints the list that is compiled into
|
||||||
|
- <command>systemd-analyze</command> itself, and does not comunicate with the
|
||||||
|
- running manager. Use
|
||||||
|
- <programlisting>systemctl [--user] [--global] show -p UnitPath --value</programlisting>
|
||||||
|
- to retrieve the actual list that the manager uses, with any empty directories
|
||||||
|
- omitted.</para>
|
||||||
|
-
|
||||||
|
- <para><command>systemd-analyze log-level</command>
|
||||||
|
- prints the current log level of the <command>systemd</command> daemon.
|
||||||
|
- If an optional argument <replaceable>LEVEL</replaceable> is provided, then the command changes the current log
|
||||||
|
- level of the <command>systemd</command> daemon to <replaceable>LEVEL</replaceable> (accepts the same values as
|
||||||
|
- <option>--log-level=</option> described in
|
||||||
|
- <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>).</para>
|
||||||
|
-
|
||||||
|
- <para><command>systemd-analyze log-target</command>
|
||||||
|
- prints the current log target of the <command>systemd</command> daemon.
|
||||||
|
- If an optional argument <replaceable>TARGET</replaceable> is provided, then the command changes the current log
|
||||||
|
- target of the <command>systemd</command> daemon to <replaceable>TARGET</replaceable> (accepts the same values as
|
||||||
|
- <option>--log-target=</option>, described in
|
||||||
|
- <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>).</para>
|
||||||
|
-
|
||||||
|
- <para><command>systemd-analyze syscall-filter <optional><replaceable>SET</replaceable>…</optional></command>
|
||||||
|
- will list system calls contained in the specified system call set <replaceable>SET</replaceable>,
|
||||||
|
- or all known sets if no sets are specified. Argument <replaceable>SET</replaceable> must include
|
||||||
|
- the <literal>@</literal> prefix.</para>
|
||||||
|
-
|
||||||
|
- <para><command>systemd-analyze verify</command> will load unit files and print
|
||||||
|
- warnings if any errors are detected. Files specified on the command line will be
|
||||||
|
- loaded, but also any other units referenced by them. The full unit search path is
|
||||||
|
- formed by combining the directories for all command line arguments, and the usual unit
|
||||||
|
- load paths (variable <varname>$SYSTEMD_UNIT_PATH</varname> is supported, and may be
|
||||||
|
- used to replace or augment the compiled in set of unit load paths; see
|
||||||
|
- <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
|
||||||
|
- All units files present in the directories containing the command line arguments will
|
||||||
|
- be used in preference to the other paths.</para>
|
||||||
|
-
|
||||||
|
- <para><command>systemd-analyze calendar</command> will parse and normalize repetitive calendar time events, and
|
||||||
|
- will calculate when they will elapse next. This takes the same input as the <varname>OnCalendar=</varname> setting
|
||||||
|
- in <citerefentry><refentrytitle>systemd.timer</refentrytitle><manvolnum>5</manvolnum></citerefentry>, following the
|
||||||
|
- syntax described in
|
||||||
|
- <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
|
||||||
|
-
|
||||||
|
- <para><command>systemd-analyze service-watchdogs</command>
|
||||||
|
- prints the current state of service runtime watchdogs of the <command>systemd</command> daemon.
|
||||||
|
- If an optional boolean argument is provided, then globally enables or disables the service
|
||||||
|
- runtime watchdogs (<option>WatchdogSec=</option>) and emergency actions (e.g.
|
||||||
|
- <option>OnFailure=</option> or <option>StartLimitAction=</option>); see
|
||||||
|
- <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||||
|
- The hardware watchdog is not affected by this setting.</para>
|
||||||
|
-
|
||||||
|
- <para><command>systemd-analyze security</command> analyzes the security and sandboxing settings of one or more
|
||||||
|
- specified service units. If at least one unit name is specified the security settings of the specified service
|
||||||
|
- units are inspected and a detailed analysis is shown. If no unit name is specified, all currently loaded,
|
||||||
|
- long-running service units are inspected and a terse table with results shown. The command checks for various
|
||||||
|
- security-related service settings, assigning each a numeric "exposure level" value, depending on how important a
|
||||||
|
- setting is. It then calculates an overall exposure level for the whole unit, which is an estimation in the range
|
||||||
|
- 0.0…10.0 indicating how exposed a service is security-wise. High exposure levels indicate very little applied
|
||||||
|
- sandboxing. Low exposure levels indicate tight sandboxing and strongest security restrictions. Note that this only
|
||||||
|
- analyzes the per-service security features systemd itself implements. This means that any additional security
|
||||||
|
- mechanisms applied by the service code itself are not accounted for. The exposure level determined this way should
|
||||||
|
- not be misunderstood: a high exposure level neither means that there is no effective sandboxing applied by the
|
||||||
|
- service code itself, nor that the service is actually vulnerable to remote or local attacks. High exposure levels
|
||||||
|
- do indicate however that most likely the service might benefit from additional settings applied to them. Please
|
||||||
|
- note that many of the security and sandboxing settings individually can be circumvented — unless combined with
|
||||||
|
- others. For example, if a service retains the privilege to establish or undo mount points many of the sandboxing
|
||||||
|
- options can be undone by the service code itself. Due to that is essential that each service uses the most
|
||||||
|
- comprehensive and strict sandboxing and security settings possible. The tool will take into account some of these
|
||||||
|
- combinations and relationships between the settings, but not all. Also note that the security and sandboxing
|
||||||
|
- settings analyzed here only apply to the operations executed by the service code itself. If a service has access to
|
||||||
|
- an IPC system (such as D-Bus) it might request operations from other services that are not subject to the same
|
||||||
|
- restrictions. Any comprehensive security and sandboxing analysis is hence incomplete if the IPC access policy is
|
||||||
|
- not validated too.</para>
|
||||||
|
+ </programlisting>
|
||||||
|
+ </example>
|
||||||
|
+ </refsect2>
|
||||||
|
|
||||||
|
- <para>If no command is passed, <command>systemd-analyze
|
||||||
|
- time</command> is implied.</para>
|
||||||
|
+ <refsect2>
|
||||||
|
+ <title><command>systemd-analyze verify <replaceable>FILE</replaceable>...</command></title>
|
||||||
|
+
|
||||||
|
+ <para>This command will load unit files and print warnings if any errors are detected. Files specified
|
||||||
|
+ on the command line will be loaded, but also any other units referenced by them. The full unit search
|
||||||
|
+ path is formed by combining the directories for all command line arguments, and the usual unit load
|
||||||
|
+ paths (variable <varname>$SYSTEMD_UNIT_PATH</varname> is supported, and may be used to replace or
|
||||||
|
+ augment the compiled in set of unit load paths; see
|
||||||
|
+ <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>). All
|
||||||
|
+ units files present in the directories containing the command line arguments will be used in preference
|
||||||
|
+ to the other paths.</para>
|
||||||
|
+
|
||||||
|
+ <para>The following errors are currently detected:</para>
|
||||||
|
+ <itemizedlist>
|
||||||
|
+ <listitem><para>unknown sections and directives,</para></listitem>
|
||||||
|
+
|
||||||
|
+ <listitem><para>missing dependencies which are required to start the given unit,</para></listitem>
|
||||||
|
+
|
||||||
|
+ <listitem><para>man pages listed in <varname>Documentation=</varname> which are not found in the
|
||||||
|
+ system,</para></listitem>
|
||||||
|
+
|
||||||
|
+ <listitem><para>commands listed in <varname>ExecStart=</varname> and similar which are not found in
|
||||||
|
+ the system or not executable.</para></listitem>
|
||||||
|
+ </itemizedlist>
|
||||||
|
|
||||||
|
+ <example>
|
||||||
|
+ <title>Misspelt directives</title>
|
||||||
|
+
|
||||||
|
+ <programlisting>$ cat ./user.slice
|
||||||
|
+[Unit]
|
||||||
|
+WhatIsThis=11
|
||||||
|
+Documentation=man:nosuchfile(1)
|
||||||
|
+Requires=different.service
|
||||||
|
+
|
||||||
|
+[Service]
|
||||||
|
+Description=x
|
||||||
|
+
|
||||||
|
+$ systemd-analyze verify ./user.slice
|
||||||
|
+[./user.slice:9] Unknown lvalue 'WhatIsThis' in section 'Unit'
|
||||||
|
+[./user.slice:13] Unknown section 'Service'. Ignoring.
|
||||||
|
+Error: org.freedesktop.systemd1.LoadFailed:
|
||||||
|
+ Unit different.service failed to load:
|
||||||
|
+ No such file or directory.
|
||||||
|
+Failed to create user.slice/start: Invalid argument
|
||||||
|
+user.slice: man nosuchfile(1) command failed with code 16
|
||||||
|
+ </programlisting>
|
||||||
|
+ </example>
|
||||||
|
+
|
||||||
|
+ <example>
|
||||||
|
+ <title>Missing service units</title>
|
||||||
|
+
|
||||||
|
+ <programlisting>$ tail ./a.socket ./b.socket
|
||||||
|
+==> ./a.socket <==
|
||||||
|
+[Socket]
|
||||||
|
+ListenStream=100
|
||||||
|
+
|
||||||
|
+==> ./b.socket <==
|
||||||
|
+[Socket]
|
||||||
|
+ListenStream=100
|
||||||
|
+Accept=yes
|
||||||
|
+
|
||||||
|
+$ systemd-analyze verify ./a.socket ./b.socket
|
||||||
|
+Service a.service not loaded, a.socket cannot be started.
|
||||||
|
+Service b@0.service not loaded, b.socket cannot be started.
|
||||||
|
+ </programlisting>
|
||||||
|
+ </example>
|
||||||
|
+ </refsect2>
|
||||||
|
+
|
||||||
|
+ <refsect2>
|
||||||
|
+ <title><command>systemd-analyze security <optional><replaceable>UNIT</replaceable>...</optional></command></title>
|
||||||
|
+
|
||||||
|
+ <para>This command analyzes the security and sandboxing settings of one or more specified service
|
||||||
|
+ units. If at least one unit name is specified the security settings of the specified service units are
|
||||||
|
+ inspected and a detailed analysis is shown. If no unit name is specified, all currently loaded,
|
||||||
|
+ long-running service units are inspected and a terse table with results shown. The command checks for
|
||||||
|
+ various security-related service settings, assigning each a numeric "exposure level" value, depending
|
||||||
|
+ on how important a setting is. It then calculates an overall exposure level for the whole unit, which
|
||||||
|
+ is an estimation in the range 0.0…10.0 indicating how exposed a service is security-wise. High exposure
|
||||||
|
+ levels indicate very little applied sandboxing. Low exposure levels indicate tight sandboxing and
|
||||||
|
+ strongest security restrictions. Note that this only analyzes the per-service security features systemd
|
||||||
|
+ itself implements. This means that any additional security mechanisms applied by the service code
|
||||||
|
+ itself are not accounted for. The exposure level determined this way should not be misunderstood: a
|
||||||
|
+ high exposure level neither means that there is no effective sandboxing applied by the service code
|
||||||
|
+ itself, nor that the service is actually vulnerable to remote or local attacks. High exposure levels do
|
||||||
|
+ indicate however that most likely the service might benefit from additional settings applied to
|
||||||
|
+ them.</para>
|
||||||
|
+
|
||||||
|
+ <para>Please note that many of the security and sandboxing settings individually can be circumvented —
|
||||||
|
+ unless combined with others. For example, if a service retains the privilege to establish or undo mount
|
||||||
|
+ points many of the sandboxing options can be undone by the service code itself. Due to that is
|
||||||
|
+ essential that each service uses the most comprehensive and strict sandboxing and security settings
|
||||||
|
+ possible. The tool will take into account some of these combinations and relationships between the
|
||||||
|
+ settings, but not all. Also note that the security and sandboxing settings analyzed here only apply to
|
||||||
|
+ the operations executed by the service code itself. If a service has access to an IPC system (such as
|
||||||
|
+ D-Bus) it might request operations from other services that are not subject to the same
|
||||||
|
+ restrictions. Any comprehensive security and sandboxing analysis is hence incomplete if the IPC access
|
||||||
|
+ policy is not validated too.</para>
|
||||||
|
+
|
||||||
|
+ <example>
|
||||||
|
+ <title>Analyze <filename noindex="true">systemd-logind.service</filename></title>
|
||||||
|
+
|
||||||
|
+ <programlisting>$ systemd-analyze security --no-pager systemd-logind.service
|
||||||
|
+ NAME DESCRIPTION EXPOSURE
|
||||||
|
+✗ PrivateNetwork= Service has access to the host's network 0.5
|
||||||
|
+✗ User=/DynamicUser= Service runs as root user 0.4
|
||||||
|
+✗ DeviceAllow= Service has no device ACL 0.2
|
||||||
|
+✓ IPAddressDeny= Service blocks all IP address ranges
|
||||||
|
+...
|
||||||
|
+→ Overall exposure level for systemd-logind.service: 4.1 OK 🙂
|
||||||
|
+</programlisting>
|
||||||
|
+ </example>
|
||||||
|
+ </refsect2>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
@@ -408,88 +670,6 @@ NAutoVTs=8
|
||||||
|
otherwise.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
- <refsect1>
|
||||||
|
- <title>Examples for <command>dot</command></title>
|
||||||
|
-
|
||||||
|
- <example>
|
||||||
|
- <title>Plots all dependencies of any unit whose name starts with
|
||||||
|
- <literal>avahi-daemon</literal></title>
|
||||||
|
-
|
||||||
|
- <programlisting>$ systemd-analyze dot 'avahi-daemon.*' | dot -Tsvg > avahi.svg
|
||||||
|
-$ eog avahi.svg</programlisting>
|
||||||
|
- </example>
|
||||||
|
-
|
||||||
|
- <example>
|
||||||
|
- <title>Plots the dependencies between all known target units</title>
|
||||||
|
-
|
||||||
|
- <programlisting>$ systemd-analyze dot --to-pattern='*.target' --from-pattern='*.target' | dot -Tsvg > targets.svg
|
||||||
|
-$ eog targets.svg</programlisting>
|
||||||
|
- </example>
|
||||||
|
- </refsect1>
|
||||||
|
-
|
||||||
|
- <refsect1>
|
||||||
|
- <title>Examples for <command>verify</command></title>
|
||||||
|
-
|
||||||
|
- <para>The following errors are currently detected:</para>
|
||||||
|
- <itemizedlist>
|
||||||
|
- <listitem><para>unknown sections and directives,
|
||||||
|
- </para></listitem>
|
||||||
|
-
|
||||||
|
- <listitem><para>missing dependencies which are required to start
|
||||||
|
- the given unit,</para></listitem>
|
||||||
|
-
|
||||||
|
- <listitem><para>man pages listed in
|
||||||
|
- <varname>Documentation=</varname> which are not found in the
|
||||||
|
- system,</para></listitem>
|
||||||
|
-
|
||||||
|
- <listitem><para>commands listed in <varname>ExecStart=</varname>
|
||||||
|
- and similar which are not found in the system or not
|
||||||
|
- executable.</para></listitem>
|
||||||
|
- </itemizedlist>
|
||||||
|
-
|
||||||
|
- <example>
|
||||||
|
- <title>Misspelt directives</title>
|
||||||
|
-
|
||||||
|
- <programlisting>$ cat ./user.slice
|
||||||
|
-[Unit]
|
||||||
|
-WhatIsThis=11
|
||||||
|
-Documentation=man:nosuchfile(1)
|
||||||
|
-Requires=different.service
|
||||||
|
-
|
||||||
|
-[Service]
|
||||||
|
-Description=x
|
||||||
|
-
|
||||||
|
-$ systemd-analyze verify ./user.slice
|
||||||
|
-[./user.slice:9] Unknown lvalue 'WhatIsThis' in section 'Unit'
|
||||||
|
-[./user.slice:13] Unknown section 'Service'. Ignoring.
|
||||||
|
-Error: org.freedesktop.systemd1.LoadFailed:
|
||||||
|
- Unit different.service failed to load:
|
||||||
|
- No such file or directory.
|
||||||
|
-Failed to create user.slice/start: Invalid argument
|
||||||
|
-user.slice: man nosuchfile(1) command failed with code 16
|
||||||
|
- </programlisting>
|
||||||
|
- </example>
|
||||||
|
-
|
||||||
|
- <example>
|
||||||
|
- <title>Missing service units</title>
|
||||||
|
-
|
||||||
|
- <programlisting>$ tail ./a.socket ./b.socket
|
||||||
|
-==> ./a.socket <==
|
||||||
|
-[Socket]
|
||||||
|
-ListenStream=100
|
||||||
|
-
|
||||||
|
-==> ./b.socket <==
|
||||||
|
-[Socket]
|
||||||
|
-ListenStream=100
|
||||||
|
-Accept=yes
|
||||||
|
-
|
||||||
|
-$ systemd-analyze verify ./a.socket ./b.socket
|
||||||
|
-Service a.service not loaded, a.socket cannot be started.
|
||||||
|
-Service b@0.service not loaded, b.socket cannot be started.
|
||||||
|
- </programlisting>
|
||||||
|
- </example>
|
||||||
|
- </refsect1>
|
||||||
|
-
|
||||||
|
<xi:include href="less-variables.xml" />
|
||||||
|
|
||||||
|
<refsect1>
|
132
SOURCES/0219-travis-move-to-CentOS-8-docker-images.patch
Normal file
132
SOURCES/0219-travis-move-to-CentOS-8-docker-images.patch
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
From ac7db0c5b48f1090f77dbcfa0a1e0dc08d5c471e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frantisek Sumsal <fsumsal@redhat.com>
|
||||||
|
Date: Mon, 14 Oct 2019 15:26:48 +0200
|
||||||
|
Subject: [PATCH] travis: move to CentOS 8 docker images
|
||||||
|
|
||||||
|
As the CentOS 8 Docker images is finally out, we can use it and drop the
|
||||||
|
plethora of workarounds we had to implement to compile RHEL8 systemd on
|
||||||
|
CentOS 7.
|
||||||
|
|
||||||
|
Resolves: #1761519
|
||||||
|
---
|
||||||
|
.travis.yml | 22 ++++++++++------------
|
||||||
|
ci/travis-centos-rhel8.sh | 32 +++++++++-----------------------
|
||||||
|
2 files changed, 19 insertions(+), 35 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/.travis.yml b/.travis.yml
|
||||||
|
index 0010da5784..70c60cf24e 100644
|
||||||
|
--- a/.travis.yml
|
||||||
|
+++ b/.travis.yml
|
||||||
|
@@ -9,42 +9,40 @@ env:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
include:
|
||||||
|
- - name: CentOS 7
|
||||||
|
+ - name: CentOS 8
|
||||||
|
language: bash
|
||||||
|
env:
|
||||||
|
- - CENTOS_RELEASE="centos7"
|
||||||
|
+ - CENTOS_RELEASE="centos8"
|
||||||
|
- CONT_NAME="systemd-centos-$CENTOS_RELEASE"
|
||||||
|
- DOCKER_EXEC="docker exec -ti $CONT_NAME"
|
||||||
|
before_install:
|
||||||
|
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
|
||||||
|
- docker --version
|
||||||
|
install:
|
||||||
|
- - if [ -f meson.build ]; then RHEL_VERSION=rhel8; else RHEL_VERSION=rhel7; fi
|
||||||
|
- - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh SETUP
|
||||||
|
+ - $CI_ROOT/travis-centos-rhel8.sh SETUP
|
||||||
|
script:
|
||||||
|
- set -e
|
||||||
|
# Build systemd
|
||||||
|
- - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh RUN
|
||||||
|
+ - $CI_ROOT/travis-centos-rhel8.sh RUN
|
||||||
|
- set +e
|
||||||
|
after_script:
|
||||||
|
- - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh CLEANUP
|
||||||
|
+ - $CI_ROOT/travis-centos-rhel8.sh CLEANUP
|
||||||
|
|
||||||
|
- - name: CentOS 7 (ASan+UBSan)
|
||||||
|
+ - name: CentOS 8 (ASan+UBSan)
|
||||||
|
language: bash
|
||||||
|
env:
|
||||||
|
- - CENTOS_RELEASE="centos7"
|
||||||
|
+ - CENTOS_RELEASE="centos8"
|
||||||
|
- CONT_NAME="systemd-centos-$CENTOS_RELEASE"
|
||||||
|
- DOCKER_EXEC="docker exec -ti $CONT_NAME"
|
||||||
|
before_install:
|
||||||
|
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
|
||||||
|
- docker --version
|
||||||
|
install:
|
||||||
|
- - if [ -f meson.build ]; then RHEL_VERSION=rhel8; else RHEL_VERSION=rhel7; fi
|
||||||
|
- - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh SETUP
|
||||||
|
+ - $CI_ROOT/travis-centos-rhel8.sh SETUP
|
||||||
|
script:
|
||||||
|
- set -e
|
||||||
|
# Build systemd
|
||||||
|
- - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh RUN_ASAN
|
||||||
|
+ - $CI_ROOT/travis-centos-rhel8.sh RUN_ASAN
|
||||||
|
- set +e
|
||||||
|
after_script:
|
||||||
|
- - $CI_ROOT/travis-centos-${RHEL_VERSION}.sh CLEANUP
|
||||||
|
+ - $CI_ROOT/travis-centos-rhel8.sh CLEANUP
|
||||||
|
diff --git a/ci/travis-centos-rhel8.sh b/ci/travis-centos-rhel8.sh
|
||||||
|
index c3d1018682..ade44a0413 100755
|
||||||
|
--- a/ci/travis-centos-rhel8.sh
|
||||||
|
+++ b/ci/travis-centos-rhel8.sh
|
||||||
|
@@ -15,10 +15,7 @@ CONT_NAME="${CONT_NAME:-centos-$CENTOS_RELEASE-$RANDOM}"
|
||||||
|
DOCKER_EXEC="${DOCKER_EXEC:-docker exec -it $CONT_NAME}"
|
||||||
|
DOCKER_RUN="${DOCKER_RUN:-docker run}"
|
||||||
|
REPO_ROOT="${REPO_ROOT:-$PWD}"
|
||||||
|
-ADDITIONAL_DEPS=(systemd-ci-environment libidn2-devel python-lxml python36 ninja-build libasan net-tools strace nc busybox e2fsprogs quota dnsmasq)
|
||||||
|
-# Repo with additional depencencies to compile newer systemd on CentOS 7
|
||||||
|
-COPR_REPO="https://copr.fedorainfracloud.org/coprs/mrc0mmand/systemd-centos-ci/repo/epel-7/mrc0mmand-systemd-centos-ci-epel-7.repo"
|
||||||
|
-COPR_REPO_PATH="/etc/yum.repos.d/${COPR_REPO##*/}"
|
||||||
|
+ADDITIONAL_DEPS=(libasan libubsan net-tools strace nc e2fsprogs quota dnsmasq)
|
||||||
|
# RHEL8 options
|
||||||
|
CONFIGURE_OPTS=(
|
||||||
|
-Dsysvinit-path=/etc/rc.d/init.d
|
||||||
|
@@ -95,18 +92,14 @@ for phase in "${PHASES[@]}"; do
|
||||||
|
-dit --net=host centos:$CENTOS_RELEASE /sbin/init
|
||||||
|
# Beautiful workaround for Fedora's version of Docker
|
||||||
|
sleep 1
|
||||||
|
- $DOCKER_EXEC yum makecache
|
||||||
|
- $DOCKER_EXEC curl "$COPR_REPO" -o "$COPR_REPO_PATH"
|
||||||
|
- $DOCKER_EXEC yum -q -y install epel-release yum-utils
|
||||||
|
- $DOCKER_EXEC yum-config-manager -q --enable epel
|
||||||
|
- $DOCKER_EXEC yum -y upgrade
|
||||||
|
- # Install necessary build/test requirements
|
||||||
|
- $DOCKER_EXEC yum -y install "${ADDITIONAL_DEPS[@]}"
|
||||||
|
- $DOCKER_EXEC python3.6 -m ensurepip
|
||||||
|
- $DOCKER_EXEC python3.6 -m pip install meson
|
||||||
|
- # Create necessary symlinks
|
||||||
|
- $DOCKER_EXEC ln --force -s /usr/bin/python3.6 /usr/bin/python3
|
||||||
|
- $DOCKER_EXEC ln --force -s /usr/bin/ninja-build /usr/bin/ninja
|
||||||
|
+ $DOCKER_EXEC dnf makecache
|
||||||
|
+ # Install and enable EPEL
|
||||||
|
+ $DOCKER_EXEC dnf -q -y install epel-release dnf-utils "${ADDITIONAL_DEPS[@]}"
|
||||||
|
+ $DOCKER_EXEC dnf config-manager -q --enable epel
|
||||||
|
+ # Upgrade the container to get the most recent environment
|
||||||
|
+ $DOCKER_EXEC dnf -y upgrade
|
||||||
|
+ # Install systemd's build dependencies
|
||||||
|
+ $DOCKER_EXEC dnf -q -y --enablerepo "PowerTools" builddep systemd
|
||||||
|
;;
|
||||||
|
RUN)
|
||||||
|
info "Run phase"
|
||||||
|
@@ -117,16 +110,9 @@ for phase in "${PHASES[@]}"; do
|
||||||
|
# unexpected fails due to incompatibilities with older systemd
|
||||||
|
$DOCKER_EXEC ninja -C build install
|
||||||
|
docker restart $CONT_NAME
|
||||||
|
- # "Mask" the udev-test.pl, as it requires newer version of systemd-detect-virt
|
||||||
|
- # and it's pointless to run it on a VM in a Docker container...
|
||||||
|
- echo -ne "#!/usr/bin/perl\nexit(0);\n" > "test/udev-test.pl"
|
||||||
|
$DOCKER_EXEC ninja -C build test
|
||||||
|
;;
|
||||||
|
RUN_ASAN|RUN_CLANG_ASAN)
|
||||||
|
- # Let's install newer gcc for proper ASan/UBSan support
|
||||||
|
- $DOCKER_EXEC yum -y install centos-release-scl
|
||||||
|
- $DOCKER_EXEC yum -y install devtoolset-8 devtoolset-8-libasan-devel libasan5 devtoolset-8-libubsan-devel libubsan1
|
||||||
|
- $DOCKER_EXEC bash -c "echo 'source scl_source enable devtoolset-8' >> /root/.bashrc"
|
||||||
|
# Note to my future frustrated self: docker exec runs the given command
|
||||||
|
# as sh -c 'command' - which means both .bash_profile and .bashrc will
|
||||||
|
# be ignored. That's because .bash_profile is sourced for LOGIN shells (i.e.
|
50
SOURCES/0220-travis-drop-SCL-remains.patch
Normal file
50
SOURCES/0220-travis-drop-SCL-remains.patch
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
From 5b14988845b591f6fa2fc1e032618fe882827f4a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frantisek Sumsal <fsumsal@redhat.com>
|
||||||
|
Date: Mon, 14 Oct 2019 16:22:51 +0200
|
||||||
|
Subject: [PATCH] travis: drop SCL remains
|
||||||
|
|
||||||
|
The `bash -ic` wrapper existed solely to make SCL work as expected
|
||||||
|
|
||||||
|
Resolves: #1761519
|
||||||
|
---
|
||||||
|
ci/travis-centos-rhel8.sh | 16 +++-------------
|
||||||
|
1 file changed, 3 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ci/travis-centos-rhel8.sh b/ci/travis-centos-rhel8.sh
|
||||||
|
index ade44a0413..da131c726b 100755
|
||||||
|
--- a/ci/travis-centos-rhel8.sh
|
||||||
|
+++ b/ci/travis-centos-rhel8.sh
|
||||||
|
@@ -113,22 +113,12 @@ for phase in "${PHASES[@]}"; do
|
||||||
|
$DOCKER_EXEC ninja -C build test
|
||||||
|
;;
|
||||||
|
RUN_ASAN|RUN_CLANG_ASAN)
|
||||||
|
- # Note to my future frustrated self: docker exec runs the given command
|
||||||
|
- # as sh -c 'command' - which means both .bash_profile and .bashrc will
|
||||||
|
- # be ignored. That's because .bash_profile is sourced for LOGIN shells (i.e.
|
||||||
|
- # sh -l), whereas .bashrc is sourced for NON-LOGIN INTERACTIVE shells
|
||||||
|
- # (i.e. sh -i).
|
||||||
|
- # As the default docker exec command lacks either of those options,
|
||||||
|
- # we need to use a wrapper command which runs the wanted command
|
||||||
|
- # under an explicit bash -i, so the SCL source above works properly.
|
||||||
|
- docker exec -it $CONT_NAME bash -ic 'gcc --version'
|
||||||
|
-
|
||||||
|
if [[ "$phase" = "RUN_CLANG_ASAN" ]]; then
|
||||||
|
ENV_VARS="-e CC=clang -e CXX=clang++"
|
||||||
|
MESON_ARGS="-Db_lundef=false" # See https://github.com/mesonbuild/meson/issues/764
|
||||||
|
fi
|
||||||
|
- docker exec $ENV_VARS -it $CONT_NAME bash -ic "meson build --werror -Dtests=unsafe -Db_sanitize=address,undefined $MESON_ARGS ${CONFIGURE_OPTS[@]}"
|
||||||
|
- docker exec -it $CONT_NAME bash -ic 'ninja -v -C build'
|
||||||
|
+ docker exec $ENV_VARS -it $CONT_NAME meson build --werror -Dtests=unsafe -Db_sanitize=address,undefined $MESON_ARGS ${CONFIGURE_OPTS[@]}
|
||||||
|
+ docker exec -it $CONT_NAME ninja -v -C build
|
||||||
|
|
||||||
|
# Never remove halt_on_error from UBSAN_OPTIONS. See https://github.com/systemd/systemd/commit/2614d83aa06592aedb.
|
||||||
|
travis_wait docker exec --interactive=false \
|
||||||
|
@@ -136,7 +126,7 @@ for phase in "${PHASES[@]}"; do
|
||||||
|
-e ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1 \
|
||||||
|
-e "TRAVIS=$TRAVIS" \
|
||||||
|
-t $CONT_NAME \
|
||||||
|
- bash -ic 'meson test --timeout-multiplier=3 -C ./build/ --print-errorlogs'
|
||||||
|
+ meson test --timeout-multiplier=3 -C ./build/ --print-errorlogs
|
||||||
|
;;
|
||||||
|
CLEANUP)
|
||||||
|
info "Cleanup phase"
|
110
SOURCES/0221-syslog-fix-segfault-in-syslog_parse_priority.patch
Normal file
110
SOURCES/0221-syslog-fix-segfault-in-syslog_parse_priority.patch
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
From 8bd791fb3a8e85063e297204bdef8004aacd22b1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Wed, 8 Aug 2018 18:27:15 +0900
|
||||||
|
Subject: [PATCH] syslog: fix segfault in syslog_parse_priority()
|
||||||
|
|
||||||
|
(cherry picked from commit a5ee33b951cfa22db53d0274c9c6c0d9d4dae39d)
|
||||||
|
|
||||||
|
Resolves: #1761519
|
||||||
|
---
|
||||||
|
src/basic/syslog-util.c | 20 +++++++++++---------
|
||||||
|
src/journal/test-journal-syslog.c | 20 ++++++++++++++++++++
|
||||||
|
2 files changed, 31 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/syslog-util.c b/src/basic/syslog-util.c
|
||||||
|
index 21461fa581..fe129482f3 100644
|
||||||
|
--- a/src/basic/syslog-util.c
|
||||||
|
+++ b/src/basic/syslog-util.c
|
||||||
|
@@ -10,7 +10,8 @@
|
||||||
|
|
||||||
|
int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
|
||||||
|
int a = 0, b = 0, c = 0;
|
||||||
|
- int k;
|
||||||
|
+ const char *end;
|
||||||
|
+ size_t k;
|
||||||
|
|
||||||
|
assert(p);
|
||||||
|
assert(*p);
|
||||||
|
@@ -19,21 +20,22 @@ int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
|
||||||
|
if ((*p)[0] != '<')
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- if (!strchr(*p, '>'))
|
||||||
|
+ end = strchr(*p, '>');
|
||||||
|
+ if (!end)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- if ((*p)[2] == '>') {
|
||||||
|
+ k = end - *p;
|
||||||
|
+ assert(k > 0);
|
||||||
|
+
|
||||||
|
+ if (k == 2)
|
||||||
|
c = undecchar((*p)[1]);
|
||||||
|
- k = 3;
|
||||||
|
- } else if ((*p)[3] == '>') {
|
||||||
|
+ else if (k == 3) {
|
||||||
|
b = undecchar((*p)[1]);
|
||||||
|
c = undecchar((*p)[2]);
|
||||||
|
- k = 4;
|
||||||
|
- } else if ((*p)[4] == '>') {
|
||||||
|
+ } else if (k == 4) {
|
||||||
|
a = undecchar((*p)[1]);
|
||||||
|
b = undecchar((*p)[2]);
|
||||||
|
c = undecchar((*p)[3]);
|
||||||
|
- k = 5;
|
||||||
|
} else
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
@@ -46,7 +48,7 @@ int syslog_parse_priority(const char **p, int *priority, bool with_facility) {
|
||||||
|
else
|
||||||
|
*priority = (*priority & LOG_FACMASK) | c;
|
||||||
|
|
||||||
|
- *p += k;
|
||||||
|
+ *p += k + 1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/journal/test-journal-syslog.c b/src/journal/test-journal-syslog.c
|
||||||
|
index 7294cde032..120477cc9f 100644
|
||||||
|
--- a/src/journal/test-journal-syslog.c
|
||||||
|
+++ b/src/journal/test-journal-syslog.c
|
||||||
|
@@ -4,6 +4,7 @@
|
||||||
|
#include "journald-syslog.h"
|
||||||
|
#include "macro.h"
|
||||||
|
#include "string-util.h"
|
||||||
|
+#include "syslog-util.h"
|
||||||
|
|
||||||
|
static void test_syslog_parse_identifier(const char *str,
|
||||||
|
const char *ident, const char *pid, const char *rest, int ret) {
|
||||||
|
@@ -19,6 +20,17 @@ static void test_syslog_parse_identifier(const char *str,
|
||||||
|
assert_se(streq(buf, rest));
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void test_syslog_parse_priority(const char *str, int priority, int ret) {
|
||||||
|
+ const char *buf = str;
|
||||||
|
+ int priority2, ret2;
|
||||||
|
+
|
||||||
|
+ ret2 = syslog_parse_priority(&buf, &priority2, false);
|
||||||
|
+
|
||||||
|
+ assert_se(ret == ret2);
|
||||||
|
+ if (ret2 == 1)
|
||||||
|
+ assert_se(priority == priority2);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int main(void) {
|
||||||
|
test_syslog_parse_identifier("pidu[111]: xxx", "pidu", "111", "xxx", 11);
|
||||||
|
test_syslog_parse_identifier("pidu: xxx", "pidu", NULL, "xxx", 6);
|
||||||
|
@@ -33,5 +45,13 @@ int main(void) {
|
||||||
|
test_syslog_parse_identifier("pidu: ", "pidu", NULL, "", 6);
|
||||||
|
test_syslog_parse_identifier("pidu : ", NULL, NULL, "pidu : ", 0);
|
||||||
|
|
||||||
|
+ test_syslog_parse_priority("<>", 0, 0);
|
||||||
|
+ test_syslog_parse_priority("<>aaa", 0, 0);
|
||||||
|
+ test_syslog_parse_priority("<aaaa>", 0, 0);
|
||||||
|
+ test_syslog_parse_priority("<aaaa>aaa", 0, 0);
|
||||||
|
+ test_syslog_parse_priority(" <aaaa>", 0, 0);
|
||||||
|
+ test_syslog_parse_priority(" <aaaa>aaa", 0, 0);
|
||||||
|
+ /* TODO: add test cases of valid priorities */
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
45
SOURCES/0222-sd-bus-make-strict-asan-shut-up.patch
Normal file
45
SOURCES/0222-sd-bus-make-strict-asan-shut-up.patch
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
From fbe5fa22f5b99d4e444db54aadb661e9c932eb6c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Fri, 16 Nov 2018 13:00:40 +0100
|
||||||
|
Subject: [PATCH] sd-bus: make strict asan shut up
|
||||||
|
|
||||||
|
asan doesn't like it if we use strndup() (i.e. a string function) on a
|
||||||
|
non-NULL terminated buffer (i.e. something that isn't really a string).
|
||||||
|
|
||||||
|
Let's hence use memdup_suffix0() instead of strndup(), which is more
|
||||||
|
appropriate for binary data that is to become a string.
|
||||||
|
|
||||||
|
Fixes: #10385
|
||||||
|
(cherry picked from commit ac0a94f7438b49a0890d9806db1fa211a5bca10a)
|
||||||
|
|
||||||
|
Resolves: #1761519
|
||||||
|
---
|
||||||
|
src/libsystemd/sd-bus/bus-message.c | 7 +++++--
|
||||||
|
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c
|
||||||
|
index 53cbd675b7..19cb2b9a97 100644
|
||||||
|
--- a/src/libsystemd/sd-bus/bus-message.c
|
||||||
|
+++ b/src/libsystemd/sd-bus/bus-message.c
|
||||||
|
@@ -5101,6 +5101,7 @@ int bus_message_parse_fields(sd_bus_message *m) {
|
||||||
|
return -EBADMSG;
|
||||||
|
|
||||||
|
if (*p == 0) {
|
||||||
|
+ char *k;
|
||||||
|
size_t l;
|
||||||
|
|
||||||
|
/* We found the beginning of the signature
|
||||||
|
@@ -5114,9 +5115,11 @@ int bus_message_parse_fields(sd_bus_message *m) {
|
||||||
|
p[1 + l - 1] != SD_BUS_TYPE_STRUCT_END)
|
||||||
|
return -EBADMSG;
|
||||||
|
|
||||||
|
- if (free_and_strndup(&m->root_container.signature,
|
||||||
|
- p + 1 + 1, l - 2) < 0)
|
||||||
|
+ k = memdup_suffix0(p + 1 + 1, l - 2);
|
||||||
|
+ if (!k)
|
||||||
|
return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ free_and_replace(m->root_container.signature, k);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
|||||||
|
From 2f44943836b69455792a5422673f8a69bc9705ba Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frantisek Sumsal <fsumsal@redhat.com>
|
||||||
|
Date: Mon, 14 Oct 2019 17:14:35 +0200
|
||||||
|
Subject: [PATCH] travis: don't run slow tests under ASan/UBSan
|
||||||
|
|
||||||
|
Resolves: #1761519
|
||||||
|
---
|
||||||
|
ci/travis-centos-rhel8.sh | 8 ++------
|
||||||
|
1 file changed, 2 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/ci/travis-centos-rhel8.sh b/ci/travis-centos-rhel8.sh
|
||||||
|
index da131c726b..a1502e15ee 100755
|
||||||
|
--- a/ci/travis-centos-rhel8.sh
|
||||||
|
+++ b/ci/travis-centos-rhel8.sh
|
||||||
|
@@ -65,10 +65,6 @@ CONFIGURE_OPTS=(
|
||||||
|
-Dnetworkd=false
|
||||||
|
-Dtimesyncd=false
|
||||||
|
-Ddefault-hierarchy=legacy
|
||||||
|
- # Custom options
|
||||||
|
- -Dslow-tests=true
|
||||||
|
- -Dtests=unsafe
|
||||||
|
- -Dinstall-tests=true
|
||||||
|
)
|
||||||
|
|
||||||
|
function info() {
|
||||||
|
@@ -104,7 +100,7 @@ for phase in "${PHASES[@]}"; do
|
||||||
|
RUN)
|
||||||
|
info "Run phase"
|
||||||
|
# Build systemd
|
||||||
|
- docker exec -it -e CFLAGS='-g -O0 -ftrapv' $CONT_NAME meson build "${CONFIGURE_OPTS[@]}"
|
||||||
|
+ docker exec -it -e CFLAGS='-g -O0 -ftrapv' $CONT_NAME meson build -Dtests=unsafe -Dslow-tests=true "${CONFIGURE_OPTS[@]}"
|
||||||
|
$DOCKER_EXEC ninja -v -C build
|
||||||
|
# Let's install the new systemd and "reboot" the container to avoid
|
||||||
|
# unexpected fails due to incompatibilities with older systemd
|
||||||
|
@@ -117,7 +113,7 @@ for phase in "${PHASES[@]}"; do
|
||||||
|
ENV_VARS="-e CC=clang -e CXX=clang++"
|
||||||
|
MESON_ARGS="-Db_lundef=false" # See https://github.com/mesonbuild/meson/issues/764
|
||||||
|
fi
|
||||||
|
- docker exec $ENV_VARS -it $CONT_NAME meson build --werror -Dtests=unsafe -Db_sanitize=address,undefined $MESON_ARGS ${CONFIGURE_OPTS[@]}
|
||||||
|
+ docker exec $ENV_VARS -it $CONT_NAME meson build --werror -Dtests=unsafe -Db_sanitize=address,undefined $MESON_ARGS "${CONFIGURE_OPTS[@]}"
|
||||||
|
docker exec -it $CONT_NAME ninja -v -C build
|
||||||
|
|
||||||
|
# Never remove halt_on_error from UBSAN_OPTIONS. See https://github.com/systemd/systemd/commit/2614d83aa06592aedb.
|
@ -0,0 +1,67 @@
|
|||||||
|
From 6240d78097c6f828aa2ca3b50ac322b41dc41fd1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Fri, 23 Aug 2019 11:34:45 +0200
|
||||||
|
Subject: [PATCH] kernel-install: do not require non-empty kernel cmdline
|
||||||
|
|
||||||
|
When booting with Fedora-Server-dvd-x86_64-30-20190411.n.0.iso,
|
||||||
|
/proc/cmdline is empty (libvirt, qemu host with bios, not sure if that
|
||||||
|
matters), after installation to disk, anaconda would "crash" in kernel-core
|
||||||
|
%posttrans, after calling kernel-install, because dracut would fail
|
||||||
|
with
|
||||||
|
|
||||||
|
> Could not determine the kernel command line parameters.
|
||||||
|
> Please specify the kernel command line in /etc/kernel/cmdline!
|
||||||
|
|
||||||
|
I guess it's legitimate, even if unusual, to have no cmdline parameters.
|
||||||
|
Two changes are done in this patch:
|
||||||
|
|
||||||
|
1. do not fail if the cmdline is empty.
|
||||||
|
2. if /usr/lib/kernel/cmdline or /etc/kernel/cmdline are present, but
|
||||||
|
empty, ignore /proc/cmdline. If there's explicit configuration to
|
||||||
|
have empty cmdline, don't ignore it.
|
||||||
|
|
||||||
|
The same change was done in dracut:
|
||||||
|
https://github.com/dracutdevs/dracut/pull/561.
|
||||||
|
|
||||||
|
(cherry picked from commit 88e1306af6380794842fb31108ba67895799fab4)
|
||||||
|
|
||||||
|
Resolves: #1701454
|
||||||
|
---
|
||||||
|
src/kernel-install/90-loaderentry.install | 14 ++++----------
|
||||||
|
1 file changed, 4 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/kernel-install/90-loaderentry.install b/src/kernel-install/90-loaderentry.install
|
||||||
|
index a271cdb8a0..1619301536 100644
|
||||||
|
--- a/src/kernel-install/90-loaderentry.install
|
||||||
|
+++ b/src/kernel-install/90-loaderentry.install
|
||||||
|
@@ -43,13 +43,13 @@ if ! [[ $PRETTY_NAME ]]; then
|
||||||
|
PRETTY_NAME="Linux $KERNEL_VERSION"
|
||||||
|
fi
|
||||||
|
|
||||||
|
-declare -a BOOT_OPTIONS
|
||||||
|
-
|
||||||
|
if [[ -f /etc/kernel/cmdline ]]; then
|
||||||
|
read -r -d '' -a BOOT_OPTIONS < /etc/kernel/cmdline
|
||||||
|
-fi
|
||||||
|
+elif [[ -f /usr/lib/kernel/cmdline ]]; then
|
||||||
|
+ read -r -d '' -a BOOT_OPTIONS < /usr/lib/kernel/cmdline
|
||||||
|
+else
|
||||||
|
+ declare -a BOOT_OPTIONS
|
||||||
|
|
||||||
|
-if ! [[ ${BOOT_OPTIONS[*]} ]]; then
|
||||||
|
read -r -d '' -a line < /proc/cmdline
|
||||||
|
for i in "${line[@]}"; do
|
||||||
|
[[ "${i#initrd=*}" != "$i" ]] && continue
|
||||||
|
@@ -57,12 +57,6 @@ if ! [[ ${BOOT_OPTIONS[*]} ]]; then
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
-if ! [[ ${BOOT_OPTIONS[*]} ]]; then
|
||||||
|
- echo "Could not determine the kernel command line parameters." >&2
|
||||||
|
- echo "Please specify the kernel command line in /etc/kernel/cmdline!" >&2
|
||||||
|
- exit 1
|
||||||
|
-fi
|
||||||
|
-
|
||||||
|
cp "$KERNEL_IMAGE" "$BOOT_DIR_ABS/linux" &&
|
||||||
|
chown root:root "$BOOT_DIR_ABS/linux" &&
|
||||||
|
chmod 0644 "$BOOT_DIR_ABS/linux" || {
|
@ -0,0 +1,36 @@
|
|||||||
|
From c6c8e0d097d6ba12471c6112c3fd339ea40329d5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
|
||||||
|
Date: Mon, 13 May 2019 16:58:01 -0300
|
||||||
|
Subject: [PATCH] ask-password: prevent buffer overrow when reading from
|
||||||
|
keyring
|
||||||
|
|
||||||
|
When we read from keyring, a temporary buffer is allocated in order to
|
||||||
|
determine the size needed for the entire data. However, when zeroing that area,
|
||||||
|
we use the data size returned by the read instead of the lesser size allocate
|
||||||
|
for the buffer.
|
||||||
|
|
||||||
|
That will cause memory corruption that causes systemd-cryptsetup to crash
|
||||||
|
either when a single large password is used or when multiple passwords have
|
||||||
|
already been pushed to the keyring.
|
||||||
|
|
||||||
|
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
|
||||||
|
(cherry picked from commit 59c55e73eaee345e1ee67c23eace8895ed499693)
|
||||||
|
|
||||||
|
Resolves: #1752050
|
||||||
|
---
|
||||||
|
src/shared/ask-password-api.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c
|
||||||
|
index 682dc754fc..764ebd08e1 100644
|
||||||
|
--- a/src/shared/ask-password-api.c
|
||||||
|
+++ b/src/shared/ask-password-api.c
|
||||||
|
@@ -79,7 +79,7 @@ static int retrieve_key(key_serial_t serial, char ***ret) {
|
||||||
|
if (n < m)
|
||||||
|
break;
|
||||||
|
|
||||||
|
- explicit_bzero(p, n);
|
||||||
|
+ explicit_bzero(p, m);
|
||||||
|
free(p);
|
||||||
|
m *= 2;
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
From 985837dab9c892858a92ae50043843307f5e0714 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Fri, 19 Jul 2019 18:29:11 +0200
|
||||||
|
Subject: [PATCH] core: try to reopen /dev/kmsg again right after mounting /dev
|
||||||
|
|
||||||
|
I was debugging stuff during early boot, and was confused that I never
|
||||||
|
found the logs for it in kmsg. The reason for that was that /proc is
|
||||||
|
generally not mounted the first time we do log_open() and hence
|
||||||
|
log_set_target(LOG_TARGET_KMSG) we do when running as PID 1 had not
|
||||||
|
effect. A lot later during start-up we call log_open() again where this
|
||||||
|
is fixed (after the point where we close all remaining fds still open),
|
||||||
|
but in the meantime no logs every got written to kmsg. This patch fixes
|
||||||
|
that.
|
||||||
|
|
||||||
|
(cherry picked from commit 0a2eef1ee1fef74be9d12f7dc4d0006b645b579c)
|
||||||
|
|
||||||
|
Resolves: #1749212
|
||||||
|
---
|
||||||
|
src/core/main.c | 5 +++++
|
||||||
|
1 file changed, 5 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/core/main.c b/src/core/main.c
|
||||||
|
index 44dd8348be..af7b26d6f1 100644
|
||||||
|
--- a/src/core/main.c
|
||||||
|
+++ b/src/core/main.c
|
||||||
|
@@ -2215,6 +2215,11 @@ int main(int argc, char *argv[]) {
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* Let's open the log backend a second time, in case the first time didn't
|
||||||
|
+ * work. Quite possibly we have mounted /dev just now, so /dev/kmsg became
|
||||||
|
+ * available, and it previously wasn't. */
|
||||||
|
+ log_open();
|
||||||
|
+
|
||||||
|
r = initialize_security(
|
||||||
|
&loaded_policy,
|
||||||
|
&security_start_timestamp,
|
@ -0,0 +1,29 @@
|
|||||||
|
From 9f259b46b760b2aa08ac1fe76fe61df514e2768f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Sekletar <msekleta@redhat.com>
|
||||||
|
Date: Tue, 3 Sep 2019 10:05:42 +0200
|
||||||
|
Subject: [PATCH] buildsys: don't garbage collect sections while linking
|
||||||
|
|
||||||
|
gc-sections is actually very aggressive and garbage collects ELF
|
||||||
|
sections used by annobin gcc plugin and annocheck then reports gaps in
|
||||||
|
coverage. Let's drop that linker flag.
|
||||||
|
|
||||||
|
RHEL-only
|
||||||
|
|
||||||
|
Resolves: #1748258
|
||||||
|
---
|
||||||
|
meson.build | 2 --
|
||||||
|
1 file changed, 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index 04b461dcd4..613a5133b6 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -357,8 +357,6 @@ if get_option('buildtype') != 'debug'
|
||||||
|
'-ffunction-sections',
|
||||||
|
'-fdata-sections',
|
||||||
|
]
|
||||||
|
-
|
||||||
|
- possible_link_flags += '-Wl,--gc-sections'
|
||||||
|
endif
|
||||||
|
|
||||||
|
add_project_arguments(cc.get_supported_arguments(possible_cc_flags), language : 'c')
|
186
SOURCES/0228-udev-introduce-CONST-key-name.patch
Normal file
186
SOURCES/0228-udev-introduce-CONST-key-name.patch
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
From d6210c3d053d70175d72ed1d1719497eed76000b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Synacek <jsynacek@redhat.com>
|
||||||
|
Date: Thu, 17 Oct 2019 09:37:35 +0200
|
||||||
|
Subject: [PATCH] udev: introduce CONST key name
|
||||||
|
|
||||||
|
Currently, there is no way to match against system-wide constants, such
|
||||||
|
as architecture or virtualization type, without forking helper binaries.
|
||||||
|
That potentially results in a huge number of spawned processes which
|
||||||
|
output always the same answer.
|
||||||
|
|
||||||
|
This patch introduces a special CONST keyword which takes a hard-coded
|
||||||
|
string as its key and returns a value assigned to that key. Currently
|
||||||
|
implemented are CONST{arch} and CONST{virt}, which can be used to match
|
||||||
|
against the system's architecture and virtualization type.
|
||||||
|
|
||||||
|
(based on commit 4801d8afe2ff1c1c075c9f0bc5631612172e0bb7)
|
||||||
|
|
||||||
|
Resolves: #1762679
|
||||||
|
---
|
||||||
|
man/udev.xml | 26 ++++++++++++++++++++++++++
|
||||||
|
rules/40-redhat.rules | 6 +++---
|
||||||
|
src/udev/udev-rules.c | 32 ++++++++++++++++++++++++++++++++
|
||||||
|
test/rule-syntax-check.py | 2 +-
|
||||||
|
4 files changed, 62 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/udev.xml b/man/udev.xml
|
||||||
|
index bdf901a8f0..8c1eb41787 100644
|
||||||
|
--- a/man/udev.xml
|
||||||
|
+++ b/man/udev.xml
|
||||||
|
@@ -236,6 +236,32 @@
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><varname>CONST{<replaceable>key</replaceable>}</varname></term>
|
||||||
|
+ <listitem>
|
||||||
|
+ <para>Match against a system-wide constant. Supported keys are:</para>
|
||||||
|
+ <variablelist>
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><literal>arch</literal></term>
|
||||||
|
+ <listitem>
|
||||||
|
+ <para>System's architecture. See <option>ConditionArchitecture=</option> in
|
||||||
|
+ <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||||
|
+ for possible values.</para>
|
||||||
|
+ </listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><literal>virt</literal></term>
|
||||||
|
+ <listitem>
|
||||||
|
+ <para>System's virtualization environment. See
|
||||||
|
+ <citerefentry><refentrytitle>systemd-detect-virt</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||||
|
+ for possible values.</para>
|
||||||
|
+ </listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+ </variablelist>
|
||||||
|
+ <para>Unknown keys will never match.</para>
|
||||||
|
+ </listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>TAG</varname></term>
|
||||||
|
<listitem>
|
||||||
|
diff --git a/rules/40-redhat.rules b/rules/40-redhat.rules
|
||||||
|
index fadc6e59f1..3c95cd2df0 100644
|
||||||
|
--- a/rules/40-redhat.rules
|
||||||
|
+++ b/rules/40-redhat.rules
|
||||||
|
@@ -6,11 +6,11 @@ SUBSYSTEM=="cpu", ACTION=="add", TEST=="online", ATTR{online}=="0", ATTR{online}
|
||||||
|
# Memory hotadd request
|
||||||
|
SUBSYSTEM!="memory", GOTO="memory_hotplug_end"
|
||||||
|
ACTION!="add", GOTO="memory_hotplug_end"
|
||||||
|
-PROGRAM="/bin/uname -p", RESULT=="s390*", GOTO="memory_hotplug_end"
|
||||||
|
-PROGRAM="/bin/uname -p", RESULT=="ppc64*", GOTO="memory_hotplug_end"
|
||||||
|
+CONST{arch}=="s390*", GOTO="memory_hotplug_end"
|
||||||
|
+CONST{arch}=="ppc64*", GOTO="memory_hotplug_end"
|
||||||
|
|
||||||
|
ENV{.state}="online"
|
||||||
|
-PROGRAM="/bin/systemd-detect-virt", RESULT=="none", ENV{.state}="online_movable"
|
||||||
|
+CONST{virt}=="none", ENV{.state}="online_movable"
|
||||||
|
ATTR{state}=="offline", ATTR{state}="$env{.state}"
|
||||||
|
|
||||||
|
LABEL="memory_hotplug_end"
|
||||||
|
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
|
||||||
|
index 58af863f3d..a246cbe67e 100644
|
||||||
|
--- a/src/udev/udev-rules.c
|
||||||
|
+++ b/src/udev/udev-rules.c
|
||||||
|
@@ -17,6 +17,7 @@
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "alloc-util.h"
|
||||||
|
+#include "architecture.h"
|
||||||
|
#include "conf-files.h"
|
||||||
|
#include "dirent-util.h"
|
||||||
|
#include "escape.h"
|
||||||
|
@@ -34,6 +35,7 @@
|
||||||
|
#include "udev.h"
|
||||||
|
#include "user-util.h"
|
||||||
|
#include "util.h"
|
||||||
|
+#include "virt.h"
|
||||||
|
|
||||||
|
#define PREALLOC_TOKEN 2048
|
||||||
|
|
||||||
|
@@ -123,6 +125,7 @@ enum token_type {
|
||||||
|
TK_M_DEVLINK, /* val */
|
||||||
|
TK_M_NAME, /* val */
|
||||||
|
TK_M_ENV, /* val, attr */
|
||||||
|
+ TK_M_CONST, /* val, attr */
|
||||||
|
TK_M_TAG, /* val */
|
||||||
|
TK_M_SUBSYSTEM, /* val */
|
||||||
|
TK_M_DRIVER, /* val */
|
||||||
|
@@ -259,6 +262,7 @@ static const char *token_str(enum token_type type) {
|
||||||
|
[TK_M_DEVLINK] = "M DEVLINK",
|
||||||
|
[TK_M_NAME] = "M NAME",
|
||||||
|
[TK_M_ENV] = "M ENV",
|
||||||
|
+ [TK_M_CONST] = "M CONST",
|
||||||
|
[TK_M_TAG] = "M TAG",
|
||||||
|
[TK_M_SUBSYSTEM] = "M SUBSYSTEM",
|
||||||
|
[TK_M_DRIVER] = "M DRIVER",
|
||||||
|
@@ -370,6 +374,7 @@ static void dump_token(struct udev_rules *rules, struct token *token) {
|
||||||
|
case TK_M_SYSCTL:
|
||||||
|
case TK_M_ATTRS:
|
||||||
|
case TK_M_ENV:
|
||||||
|
+ case TK_M_CONST:
|
||||||
|
case TK_A_ATTR:
|
||||||
|
case TK_A_SYSCTL:
|
||||||
|
case TK_A_ENV:
|
||||||
|
@@ -903,6 +908,7 @@ static void rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
|
||||||
|
token->key.builtin_cmd = *(enum udev_builtin_cmd *)data;
|
||||||
|
break;
|
||||||
|
case TK_M_ENV:
|
||||||
|
+ case TK_M_CONST:
|
||||||
|
case TK_M_ATTR:
|
||||||
|
case TK_M_SYSCTL:
|
||||||
|
case TK_M_ATTRS:
|
||||||
|
@@ -1226,6 +1232,17 @@ static void add_rule(struct udev_rules *rules, char *line,
|
||||||
|
rule_add_key(&rule_tmp, TK_A_ENV, op, value, attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ } else if (startswith(key, "CONST{")) {
|
||||||
|
+ attr = get_key_attribute(rules->udev, key + STRLEN("CONST"));
|
||||||
|
+ if (attr == NULL || !STR_IN_SET(attr, "arch", "virt"))
|
||||||
|
+ LOG_AND_RETURN("error parsing %s attribute", "CONST");
|
||||||
|
+
|
||||||
|
+ if (op == OP_REMOVE)
|
||||||
|
+ LOG_AND_RETURN("invalid %s operation", "CONST");
|
||||||
|
+
|
||||||
|
+ if (op < OP_MATCH_MAX)
|
||||||
|
+ rule_add_key(&rule_tmp, TK_M_CONST, op, value, attr);
|
||||||
|
+
|
||||||
|
} else if (streq(key, "TAG")) {
|
||||||
|
if (op < OP_MATCH_MAX)
|
||||||
|
rule_add_key(&rule_tmp, TK_M_TAG, op, value, NULL);
|
||||||
|
@@ -1855,6 +1872,21 @@ void udev_rules_apply_to_event(struct udev_rules *rules,
|
||||||
|
goto nomatch;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
+ case TK_M_CONST: {
|
||||||
|
+ const char *key_name = rules_str(rules, cur->key.attr_off);
|
||||||
|
+ const char *value = NULL;
|
||||||
|
+
|
||||||
|
+ if (streq(key_name, "arch")) {
|
||||||
|
+ value = architecture_to_string(uname_architecture());
|
||||||
|
+ } else if (streq(key_name, "virt")) {
|
||||||
|
+ value = virtualization_to_string(detect_virtualization());
|
||||||
|
+ } else
|
||||||
|
+ assert_not_reached("Invalid CONST key");
|
||||||
|
+
|
||||||
|
+ if (match_key(rules, cur, value))
|
||||||
|
+ goto nomatch;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
case TK_M_TAG: {
|
||||||
|
struct udev_list_entry *list_entry;
|
||||||
|
bool match = false;
|
||||||
|
diff --git a/test/rule-syntax-check.py b/test/rule-syntax-check.py
|
||||||
|
index c7c0a1a656..6e59f421f5 100755
|
||||||
|
--- a/test/rule-syntax-check.py
|
||||||
|
+++ b/test/rule-syntax-check.py
|
||||||
|
@@ -19,7 +19,7 @@ quoted_string_re = r'"(?:[^\\"]|\\.)*"'
|
||||||
|
no_args_tests = re.compile(r'(ACTION|DEVPATH|KERNELS?|NAME|SYMLINK|SUBSYSTEMS?|DRIVERS?|TAG|PROGRAM|RESULT|TEST)\s*(?:=|!)=\s*' + quoted_string_re + '$')
|
||||||
|
# PROGRAM can also be specified as an assignment.
|
||||||
|
program_assign = re.compile(r'PROGRAM\s*=\s*' + quoted_string_re + '$')
|
||||||
|
-args_tests = re.compile(r'(ATTRS?|ENV|TEST){([a-zA-Z0-9/_.*%-]+)}\s*(?:=|!)=\s*' + quoted_string_re + '$')
|
||||||
|
+args_tests = re.compile(r'(ATTRS?|ENV|CONST|TEST){([a-zA-Z0-9/_.*%-]+)}\s*(?:=|!)=\s*' + quoted_string_re + '$')
|
||||||
|
no_args_assign = re.compile(r'(NAME|SYMLINK|OWNER|GROUP|MODE|TAG|RUN|LABEL|GOTO|WAIT_FOR|OPTIONS|IMPORT)\s*(?:\+=|:=|=)\s*' + quoted_string_re + '$')
|
||||||
|
args_assign = re.compile(r'(ATTR|ENV|IMPORT|RUN){([a-zA-Z0-9/_.*%-]+)}\s*(=|\+=)\s*' + quoted_string_re + '$')
|
||||||
|
# Find comma-separated groups, but allow commas that are inside quoted strings.
|
@ -0,0 +1,50 @@
|
|||||||
|
From e1bd03e75860fb349a6de589bbb1274acc454aef Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Renaud=20M=C3=A9trich?= <rmetrich@redhat.com>
|
||||||
|
Date: Fri, 13 Sep 2019 11:18:18 +0200
|
||||||
|
Subject: [PATCH] Call getgroups() to know size of supplementary groups array
|
||||||
|
to allocate
|
||||||
|
|
||||||
|
Resolves RHBZ #1743230 - journalctl dumps core when stack limit is reduced to 256 KB
|
||||||
|
|
||||||
|
(cherry picked from commit f5e0b942af1e86993c21f4e5c84342bb10403dac)
|
||||||
|
|
||||||
|
Resolves: #1743235
|
||||||
|
---
|
||||||
|
src/basic/user-util.c | 14 ++++++++------
|
||||||
|
1 file changed, 8 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/user-util.c b/src/basic/user-util.c
|
||||||
|
index a562a397c7..c533f67025 100644
|
||||||
|
--- a/src/basic/user-util.c
|
||||||
|
+++ b/src/basic/user-util.c
|
||||||
|
@@ -358,9 +358,8 @@ char* gid_to_name(gid_t gid) {
|
||||||
|
}
|
||||||
|
|
||||||
|
int in_gid(gid_t gid) {
|
||||||
|
- long ngroups_max;
|
||||||
|
gid_t *gids;
|
||||||
|
- int r, i;
|
||||||
|
+ int ngroups, r, i;
|
||||||
|
|
||||||
|
if (getgid() == gid)
|
||||||
|
return 1;
|
||||||
|
@@ -371,12 +370,15 @@ int in_gid(gid_t gid) {
|
||||||
|
if (!gid_is_valid(gid))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
- ngroups_max = sysconf(_SC_NGROUPS_MAX);
|
||||||
|
- assert(ngroups_max > 0);
|
||||||
|
+ ngroups = getgroups(0, NULL);
|
||||||
|
+ if (ngroups < 0)
|
||||||
|
+ return -errno;
|
||||||
|
+ if (ngroups == 0)
|
||||||
|
+ return 0;
|
||||||
|
|
||||||
|
- gids = newa(gid_t, ngroups_max);
|
||||||
|
+ gids = newa(gid_t, ngroups);
|
||||||
|
|
||||||
|
- r = getgroups(ngroups_max, gids);
|
||||||
|
+ r = getgroups(ngroups, gids);
|
||||||
|
if (r < 0)
|
||||||
|
return -errno;
|
||||||
|
|
30
SOURCES/0230-Consider-smb3-as-remote-filesystem.patch
Normal file
30
SOURCES/0230-Consider-smb3-as-remote-filesystem.patch
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
From 1bf923686a6842f222b1ef5f5174511340c75685 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Synacek <jsynacek@redhat.com>
|
||||||
|
Date: Tue, 1 Oct 2019 08:45:08 +0200
|
||||||
|
Subject: [PATCH] Consider smb3 as remote filesystem
|
||||||
|
|
||||||
|
Currently systemd will treat smb3 as local filesystem and cause
|
||||||
|
can't boot failures. Add smb3 to the list of remote filesystems
|
||||||
|
to fix this issue.
|
||||||
|
|
||||||
|
Signed-off-by: Kenneth D'souza <kdsouza@redhat.com>
|
||||||
|
|
||||||
|
(cherry picked from commit ff7d6a740b0c6fa3be63d3908a0858730a0837c5)
|
||||||
|
|
||||||
|
Resolves: #1757257
|
||||||
|
---
|
||||||
|
src/basic/mount-util.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c
|
||||||
|
index 3670b7f591..5b04e21f34 100644
|
||||||
|
--- a/src/basic/mount-util.c
|
||||||
|
+++ b/src/basic/mount-util.c
|
||||||
|
@@ -603,6 +603,7 @@ bool fstype_is_network(const char *fstype) {
|
||||||
|
return STR_IN_SET(fstype,
|
||||||
|
"afs",
|
||||||
|
"cifs",
|
||||||
|
+ "smb3",
|
||||||
|
"smbfs",
|
||||||
|
"sshfs",
|
||||||
|
"ncpfs",
|
114
SOURCES/0231-process-util-introduce-pid_is_my_child-helper.patch
Normal file
114
SOURCES/0231-process-util-introduce-pid_is_my_child-helper.patch
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
From f057aa6bb604845fa10ad569bca306e5e1e8fe0d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Franck Bui <fbui@suse.com>
|
||||||
|
Date: Mon, 18 Mar 2019 11:48:34 +0100
|
||||||
|
Subject: [PATCH] process-util: introduce pid_is_my_child() helper
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
No functional changes.
|
||||||
|
|
||||||
|
Thanks Renaud Métrich for backporting this to RHEL.
|
||||||
|
Resolves: #1744972
|
||||||
|
---
|
||||||
|
src/basic/process-util.c | 14 ++++++++++++++
|
||||||
|
src/basic/process-util.h | 1 +
|
||||||
|
src/core/cgroup.c | 7 ++-----
|
||||||
|
src/core/service.c | 8 ++------
|
||||||
|
4 files changed, 19 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
|
||||||
|
index aa3eff779a..6dbeee9dda 100644
|
||||||
|
--- a/src/basic/process-util.c
|
||||||
|
+++ b/src/basic/process-util.c
|
||||||
|
@@ -903,6 +903,20 @@ int getenv_for_pid(pid_t pid, const char *field, char **ret) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int pid_is_my_child(pid_t pid) {
|
||||||
|
+ pid_t ppid;
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ if (pid <= 1)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ r = get_process_ppid(pid, &ppid);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ return ppid == getpid_cached();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
bool pid_is_unwaited(pid_t pid) {
|
||||||
|
/* Checks whether a PID is still valid at all, including a zombie */
|
||||||
|
|
||||||
|
diff --git a/src/basic/process-util.h b/src/basic/process-util.h
|
||||||
|
index a5bb072b25..a3bd2851b4 100644
|
||||||
|
--- a/src/basic/process-util.h
|
||||||
|
+++ b/src/basic/process-util.h
|
||||||
|
@@ -68,6 +68,7 @@ int getenv_for_pid(pid_t pid, const char *field, char **_value);
|
||||||
|
|
||||||
|
bool pid_is_alive(pid_t pid);
|
||||||
|
bool pid_is_unwaited(pid_t pid);
|
||||||
|
+int pid_is_my_child(pid_t pid);
|
||||||
|
int pid_from_same_root_fs(pid_t pid);
|
||||||
|
|
||||||
|
bool is_main_thread(void);
|
||||||
|
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
|
||||||
|
index 62ab41a288..b7ed07e65b 100644
|
||||||
|
--- a/src/core/cgroup.c
|
||||||
|
+++ b/src/core/cgroup.c
|
||||||
|
@@ -1876,7 +1876,7 @@ void unit_prune_cgroup(Unit *u) {
|
||||||
|
|
||||||
|
int unit_search_main_pid(Unit *u, pid_t *ret) {
|
||||||
|
_cleanup_fclose_ FILE *f = NULL;
|
||||||
|
- pid_t pid = 0, npid, mypid;
|
||||||
|
+ pid_t pid = 0, npid;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(u);
|
||||||
|
@@ -1889,15 +1889,12 @@ int unit_search_main_pid(Unit *u, pid_t *ret) {
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
- mypid = getpid_cached();
|
||||||
|
while (cg_read_pid(f, &npid) > 0) {
|
||||||
|
- pid_t ppid;
|
||||||
|
|
||||||
|
if (npid == pid)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
- /* Ignore processes that aren't our kids */
|
||||||
|
- if (get_process_ppid(npid, &ppid) >= 0 && ppid != mypid)
|
||||||
|
+ if (pid_is_my_child(npid) == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (pid != 0)
|
||||||
|
diff --git a/src/core/service.c b/src/core/service.c
|
||||||
|
index 24f167572a..614ba05d89 100644
|
||||||
|
--- a/src/core/service.c
|
||||||
|
+++ b/src/core/service.c
|
||||||
|
@@ -139,8 +139,6 @@ static void service_unwatch_pid_file(Service *s) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static int service_set_main_pid(Service *s, pid_t pid) {
|
||||||
|
- pid_t ppid;
|
||||||
|
-
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
if (pid <= 1)
|
||||||
|
@@ -159,12 +157,10 @@ static int service_set_main_pid(Service *s, pid_t pid) {
|
||||||
|
|
||||||
|
s->main_pid = pid;
|
||||||
|
s->main_pid_known = true;
|
||||||
|
+ s->main_pid_alien = pid_is_my_child(pid) == 0;
|
||||||
|
|
||||||
|
- if (get_process_ppid(pid, &ppid) >= 0 && ppid != getpid_cached()) {
|
||||||
|
+ if (s->main_pid_alien)
|
||||||
|
log_unit_warning(UNIT(s), "Supervising process "PID_FMT" which is not our child. We'll most likely not notice when it exits.", pid);
|
||||||
|
- s->main_pid_alien = true;
|
||||||
|
- } else
|
||||||
|
- s->main_pid_alien = false;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,323 @@
|
|||||||
|
From 79e9566ec0a61d887ab63f17192dbd71aae36ee0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Franck Bui <fbui@suse.com>
|
||||||
|
Date: Mon, 18 Mar 2019 20:59:36 +0100
|
||||||
|
Subject: [PATCH] core: reduce the number of stalled PIDs from the watched
|
||||||
|
processes list when possible
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Some PIDs can remain in the watched list even though their processes have
|
||||||
|
exited since a long time. It can easily happen if the main process of a forking
|
||||||
|
service manages to spawn a child before the control process exits for example.
|
||||||
|
|
||||||
|
However when a pid is about to be mapped to a unit by calling unit_watch_pid(),
|
||||||
|
the caller usually knows if the pid should belong to this unit exclusively: if
|
||||||
|
we just forked() off a child, then we can be sure that its PID is otherwise
|
||||||
|
unused. In this case we take this opportunity to remove any stalled PIDs from
|
||||||
|
the watched process list.
|
||||||
|
|
||||||
|
If we learnt about a PID in any other form (for example via PID file, via
|
||||||
|
searching, MAINPID= and so on), then we can't assume anything.
|
||||||
|
|
||||||
|
Thanks Renaud Métrich for backporting this to RHEL.
|
||||||
|
Resolves: #1744972
|
||||||
|
---
|
||||||
|
src/core/cgroup.c | 2 +-
|
||||||
|
src/core/dbus-scope.c | 2 +-
|
||||||
|
src/core/manager.c | 10 ++++++++++
|
||||||
|
src/core/manager.h | 2 ++
|
||||||
|
src/core/mount.c | 5 ++---
|
||||||
|
src/core/service.c | 16 ++++++++--------
|
||||||
|
src/core/socket.c | 7 +++----
|
||||||
|
src/core/swap.c | 5 ++---
|
||||||
|
src/core/unit.c | 8 +++++++-
|
||||||
|
src/core/unit.h | 2 +-
|
||||||
|
src/test/test-watch-pid.c | 12 ++++++------
|
||||||
|
11 files changed, 43 insertions(+), 28 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
|
||||||
|
index b7ed07e65b..76eafdc082 100644
|
||||||
|
--- a/src/core/cgroup.c
|
||||||
|
+++ b/src/core/cgroup.c
|
||||||
|
@@ -1926,7 +1926,7 @@ static int unit_watch_pids_in_path(Unit *u, const char *path) {
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
while ((r = cg_read_pid(f, &pid)) > 0) {
|
||||||
|
- r = unit_watch_pid(u, pid);
|
||||||
|
+ r = unit_watch_pid(u, pid, false);
|
||||||
|
if (r < 0 && ret >= 0)
|
||||||
|
ret = r;
|
||||||
|
}
|
||||||
|
diff --git a/src/core/dbus-scope.c b/src/core/dbus-scope.c
|
||||||
|
index 6725f62794..0bbf64fff1 100644
|
||||||
|
--- a/src/core/dbus-scope.c
|
||||||
|
+++ b/src/core/dbus-scope.c
|
||||||
|
@@ -106,7 +106,7 @@ static int bus_scope_set_transient_property(
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||||
|
- r = unit_watch_pid(UNIT(s), pid);
|
||||||
|
+ r = unit_watch_pid(UNIT(s), pid, false);
|
||||||
|
if (r < 0 && r != -EEXIST)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
diff --git a/src/core/manager.c b/src/core/manager.c
|
||||||
|
index c83e296cf3..0eae7d46fb 100644
|
||||||
|
--- a/src/core/manager.c
|
||||||
|
+++ b/src/core/manager.c
|
||||||
|
@@ -2044,6 +2044,16 @@ void manager_clear_jobs(Manager *m) {
|
||||||
|
job_finish_and_invalidate(j, JOB_CANCELED, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void manager_unwatch_pid(Manager *m, pid_t pid) {
|
||||||
|
+ assert(m);
|
||||||
|
+
|
||||||
|
+ /* First let's drop the unit keyed as "pid". */
|
||||||
|
+ (void) hashmap_remove(m->watch_pids, PID_TO_PTR(pid));
|
||||||
|
+
|
||||||
|
+ /* Then, let's also drop the array keyed by -pid. */
|
||||||
|
+ free(hashmap_remove(m->watch_pids, PID_TO_PTR(-pid)));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int manager_dispatch_run_queue(sd_event_source *source, void *userdata) {
|
||||||
|
Manager *m = userdata;
|
||||||
|
Job *j;
|
||||||
|
diff --git a/src/core/manager.h b/src/core/manager.h
|
||||||
|
index c7f4d66ecd..fa47952d24 100644
|
||||||
|
--- a/src/core/manager.h
|
||||||
|
+++ b/src/core/manager.h
|
||||||
|
@@ -406,6 +406,8 @@ int manager_get_dump_string(Manager *m, char **ret);
|
||||||
|
|
||||||
|
void manager_clear_jobs(Manager *m);
|
||||||
|
|
||||||
|
+void manager_unwatch_pid(Manager *m, pid_t pid);
|
||||||
|
+
|
||||||
|
unsigned manager_dispatch_load_queue(Manager *m);
|
||||||
|
|
||||||
|
int manager_environment_add(Manager *m, char **minus, char **plus);
|
||||||
|
diff --git a/src/core/mount.c b/src/core/mount.c
|
||||||
|
index 2ac04e3874..5878814b1b 100644
|
||||||
|
--- a/src/core/mount.c
|
||||||
|
+++ b/src/core/mount.c
|
||||||
|
@@ -677,7 +677,7 @@ static int mount_coldplug(Unit *u) {
|
||||||
|
pid_is_unwaited(m->control_pid) &&
|
||||||
|
MOUNT_STATE_WITH_PROCESS(new_state)) {
|
||||||
|
|
||||||
|
- r = unit_watch_pid(UNIT(m), m->control_pid);
|
||||||
|
+ r = unit_watch_pid(UNIT(m), m->control_pid, false);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
@@ -781,9 +781,8 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
- r = unit_watch_pid(UNIT(m), pid);
|
||||||
|
+ r = unit_watch_pid(UNIT(m), pid, true);
|
||||||
|
if (r < 0)
|
||||||
|
- /* FIXME: we need to do something here */
|
||||||
|
return r;
|
||||||
|
|
||||||
|
*_pid = pid;
|
||||||
|
diff --git a/src/core/service.c b/src/core/service.c
|
||||||
|
index 614ba05d89..310838a5f6 100644
|
||||||
|
--- a/src/core/service.c
|
||||||
|
+++ b/src/core/service.c
|
||||||
|
@@ -974,7 +974,7 @@ static int service_load_pid_file(Service *s, bool may_warn) {
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
- r = unit_watch_pid(UNIT(s), pid);
|
||||||
|
+ r = unit_watch_pid(UNIT(s), pid, false);
|
||||||
|
if (r < 0) /* FIXME: we need to do something here */
|
||||||
|
return log_unit_warning_errno(UNIT(s), r, "Failed to watch PID "PID_FMT" for service: %m", pid);
|
||||||
|
|
||||||
|
@@ -1004,7 +1004,7 @@ static void service_search_main_pid(Service *s) {
|
||||||
|
if (service_set_main_pid(s, pid) < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- r = unit_watch_pid(UNIT(s), pid);
|
||||||
|
+ r = unit_watch_pid(UNIT(s), pid, false);
|
||||||
|
if (r < 0)
|
||||||
|
/* FIXME: we need to do something here */
|
||||||
|
log_unit_warning_errno(UNIT(s), r, "Failed to watch PID "PID_FMT" from: %m", pid);
|
||||||
|
@@ -1135,7 +1135,7 @@ static int service_coldplug(Unit *u) {
|
||||||
|
SERVICE_RUNNING, SERVICE_RELOAD,
|
||||||
|
SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
|
||||||
|
SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL))) {
|
||||||
|
- r = unit_watch_pid(UNIT(s), s->main_pid);
|
||||||
|
+ r = unit_watch_pid(UNIT(s), s->main_pid, false);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
@@ -1147,7 +1147,7 @@ static int service_coldplug(Unit *u) {
|
||||||
|
SERVICE_RELOAD,
|
||||||
|
SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
|
||||||
|
SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) {
|
||||||
|
- r = unit_watch_pid(UNIT(s), s->control_pid);
|
||||||
|
+ r = unit_watch_pid(UNIT(s), s->control_pid, false);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
@@ -1545,8 +1545,8 @@ static int service_spawn(
|
||||||
|
s->exec_fd_event_source = TAKE_PTR(exec_fd_source);
|
||||||
|
s->exec_fd_hot = false;
|
||||||
|
|
||||||
|
- r = unit_watch_pid(UNIT(s), pid);
|
||||||
|
- if (r < 0) /* FIXME: we need to do something here */
|
||||||
|
+ r = unit_watch_pid(UNIT(s), pid, true);
|
||||||
|
+ if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
*_pid = pid;
|
||||||
|
@@ -3643,7 +3643,7 @@ static void service_notify_message(
|
||||||
|
}
|
||||||
|
if (r > 0) {
|
||||||
|
service_set_main_pid(s, new_main_pid);
|
||||||
|
- unit_watch_pid(UNIT(s), new_main_pid);
|
||||||
|
+ unit_watch_pid(UNIT(s), new_main_pid, false);
|
||||||
|
notify_dbus = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -3858,7 +3858,7 @@ static void service_bus_name_owner_change(
|
||||||
|
log_unit_debug(u, "D-Bus name %s is now owned by process " PID_FMT, name, pid);
|
||||||
|
|
||||||
|
service_set_main_pid(s, pid);
|
||||||
|
- unit_watch_pid(UNIT(s), pid);
|
||||||
|
+ unit_watch_pid(UNIT(s), pid, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/src/core/socket.c b/src/core/socket.c
|
||||||
|
index d488c64e91..b034549634 100644
|
||||||
|
--- a/src/core/socket.c
|
||||||
|
+++ b/src/core/socket.c
|
||||||
|
@@ -1816,7 +1816,7 @@ static int socket_coldplug(Unit *u) {
|
||||||
|
SOCKET_FINAL_SIGTERM,
|
||||||
|
SOCKET_FINAL_SIGKILL)) {
|
||||||
|
|
||||||
|
- r = unit_watch_pid(UNIT(s), s->control_pid);
|
||||||
|
+ r = unit_watch_pid(UNIT(s), s->control_pid, false);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
@@ -1902,9 +1902,8 @@ static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
- r = unit_watch_pid(UNIT(s), pid);
|
||||||
|
+ r = unit_watch_pid(UNIT(s), pid, true);
|
||||||
|
if (r < 0)
|
||||||
|
- /* FIXME: we need to do something here */
|
||||||
|
return r;
|
||||||
|
|
||||||
|
*_pid = pid;
|
||||||
|
@@ -1973,7 +1972,7 @@ static int socket_chown(Socket *s, pid_t *_pid) {
|
||||||
|
_exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
- r = unit_watch_pid(UNIT(s), pid);
|
||||||
|
+ r = unit_watch_pid(UNIT(s), pid, true);
|
||||||
|
if (r < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
diff --git a/src/core/swap.c b/src/core/swap.c
|
||||||
|
index b644753a1c..e717dbb54a 100644
|
||||||
|
--- a/src/core/swap.c
|
||||||
|
+++ b/src/core/swap.c
|
||||||
|
@@ -531,7 +531,7 @@ static int swap_coldplug(Unit *u) {
|
||||||
|
pid_is_unwaited(s->control_pid) &&
|
||||||
|
SWAP_STATE_WITH_PROCESS(new_state)) {
|
||||||
|
|
||||||
|
- r = unit_watch_pid(UNIT(s), s->control_pid);
|
||||||
|
+ r = unit_watch_pid(UNIT(s), s->control_pid, false);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
@@ -636,9 +636,8 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
|
||||||
|
if (r < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
- r = unit_watch_pid(UNIT(s), pid);
|
||||||
|
+ r = unit_watch_pid(UNIT(s), pid, true);
|
||||||
|
if (r < 0)
|
||||||
|
- /* FIXME: we need to do something here */
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
*_pid = pid;
|
||||||
|
diff --git a/src/core/unit.c b/src/core/unit.c
|
||||||
|
index d298afb0d4..b0b1c77ef7 100644
|
||||||
|
--- a/src/core/unit.c
|
||||||
|
+++ b/src/core/unit.c
|
||||||
|
@@ -2500,7 +2500,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlag
|
||||||
|
unit_add_to_gc_queue(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
-int unit_watch_pid(Unit *u, pid_t pid) {
|
||||||
|
+int unit_watch_pid(Unit *u, pid_t pid, bool exclusive) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(u);
|
||||||
|
@@ -2508,6 +2508,12 @@ int unit_watch_pid(Unit *u, pid_t pid) {
|
||||||
|
|
||||||
|
/* Watch a specific PID */
|
||||||
|
|
||||||
|
+ /* Caller might be sure that this PID belongs to this unit only. Let's take this
|
||||||
|
+ * opportunity to remove any stalled references to this PID as they can be created
|
||||||
|
+ * easily (when watching a process which is not our direct child). */
|
||||||
|
+ if (exclusive)
|
||||||
|
+ manager_unwatch_pid(u->manager, pid);
|
||||||
|
+
|
||||||
|
r = set_ensure_allocated(&u->pids, NULL);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
diff --git a/src/core/unit.h b/src/core/unit.h
|
||||||
|
index e1a60da244..68cc1869e4 100644
|
||||||
|
--- a/src/core/unit.h
|
||||||
|
+++ b/src/core/unit.h
|
||||||
|
@@ -655,7 +655,7 @@ typedef enum UnitNotifyFlags {
|
||||||
|
|
||||||
|
void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, UnitNotifyFlags flags);
|
||||||
|
|
||||||
|
-int unit_watch_pid(Unit *u, pid_t pid);
|
||||||
|
+int unit_watch_pid(Unit *u, pid_t pid, bool exclusive);
|
||||||
|
void unit_unwatch_pid(Unit *u, pid_t pid);
|
||||||
|
void unit_unwatch_all_pids(Unit *u);
|
||||||
|
|
||||||
|
diff --git a/src/test/test-watch-pid.c b/src/test/test-watch-pid.c
|
||||||
|
index cb43b35bc5..8c70175aed 100644
|
||||||
|
--- a/src/test/test-watch-pid.c
|
||||||
|
+++ b/src/test/test-watch-pid.c
|
||||||
|
@@ -49,25 +49,25 @@ int main(int argc, char *argv[]) {
|
||||||
|
assert_se(hashmap_isempty(m->watch_pids));
|
||||||
|
assert_se(manager_get_unit_by_pid(m, 4711) == NULL);
|
||||||
|
|
||||||
|
- assert_se(unit_watch_pid(a, 4711) >= 0);
|
||||||
|
+ assert_se(unit_watch_pid(a, 4711, false) >= 0);
|
||||||
|
assert_se(manager_get_unit_by_pid(m, 4711) == a);
|
||||||
|
|
||||||
|
- assert_se(unit_watch_pid(a, 4711) >= 0);
|
||||||
|
+ assert_se(unit_watch_pid(a, 4711, false) >= 0);
|
||||||
|
assert_se(manager_get_unit_by_pid(m, 4711) == a);
|
||||||
|
|
||||||
|
- assert_se(unit_watch_pid(b, 4711) >= 0);
|
||||||
|
+ assert_se(unit_watch_pid(b, 4711, false) >= 0);
|
||||||
|
u = manager_get_unit_by_pid(m, 4711);
|
||||||
|
assert_se(u == a || u == b);
|
||||||
|
|
||||||
|
- assert_se(unit_watch_pid(b, 4711) >= 0);
|
||||||
|
+ assert_se(unit_watch_pid(b, 4711, false) >= 0);
|
||||||
|
u = manager_get_unit_by_pid(m, 4711);
|
||||||
|
assert_se(u == a || u == b);
|
||||||
|
|
||||||
|
- assert_se(unit_watch_pid(c, 4711) >= 0);
|
||||||
|
+ assert_se(unit_watch_pid(c, 4711, false) >= 0);
|
||||||
|
u = manager_get_unit_by_pid(m, 4711);
|
||||||
|
assert_se(u == a || u == b || u == c);
|
||||||
|
|
||||||
|
- assert_se(unit_watch_pid(c, 4711) >= 0);
|
||||||
|
+ assert_se(unit_watch_pid(c, 4711, false) >= 0);
|
||||||
|
u = manager_get_unit_by_pid(m, 4711);
|
||||||
|
assert_se(u == a || u == b || u == c);
|
||||||
|
|
@ -0,0 +1,55 @@
|
|||||||
|
From 25b93538eba0275d35ef4b0792c2cd63d63d5e8d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Franck Bui <fbui@suse.com>
|
||||||
|
Date: Tue, 19 Mar 2019 10:59:26 +0100
|
||||||
|
Subject: [PATCH] core: only watch processes when it's really necessary
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
If we know that main pid is our child then it's unnecessary to watch all
|
||||||
|
other processes of a unit since in this case we will get SIGCHLD when the main
|
||||||
|
process will exit and will act upon accordingly.
|
||||||
|
|
||||||
|
So let's watch all processes only if the main process is not our child since in
|
||||||
|
this case we need to detect when the cgroup will become empty in order to
|
||||||
|
figure out when the service becomes dead. This is only needed by cgroupv1.
|
||||||
|
|
||||||
|
Thanks Renaud Métrich for backporting this to RHEL.
|
||||||
|
Resolves: #1744972
|
||||||
|
---
|
||||||
|
src/core/service.c | 15 +++++++++------
|
||||||
|
1 file changed, 9 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/service.c b/src/core/service.c
|
||||||
|
index 310838a5f6..b1ec52d220 100644
|
||||||
|
--- a/src/core/service.c
|
||||||
|
+++ b/src/core/service.c
|
||||||
|
@@ -3410,8 +3410,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||||
|
if (main_pid_good(s) <= 0)
|
||||||
|
service_enter_stop_post(s, f);
|
||||||
|
|
||||||
|
- /* If there is still a service
|
||||||
|
- * process around, wait until
|
||||||
|
+ /* If there is still a service process around, wait until
|
||||||
|
* that one quit, too */
|
||||||
|
break;
|
||||||
|
|
||||||
|
@@ -3433,10 +3432,14 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||||
|
if (notify_dbus)
|
||||||
|
unit_add_to_dbus_queue(u);
|
||||||
|
|
||||||
|
- /* If we get a SIGCHLD event for one of the processes we were interested in, then we look for others to watch,
|
||||||
|
- * under the assumption that we'll sooner or later get a SIGCHLD for them, as the original process we watched
|
||||||
|
- * was probably the parent of them, and they are hence now our children. */
|
||||||
|
- (void) unit_enqueue_rewatch_pids(u);
|
||||||
|
+ /* We watch the main/control process otherwise we can't retrieve the unit they
|
||||||
|
+ * belong to with cgroupv1. But if they are not our direct child, we won't get a
|
||||||
|
+ * SIGCHLD for them. Therefore we need to look for others to watch so we can
|
||||||
|
+ * detect when the cgroup becomes empty. Note that the control process is always
|
||||||
|
+ * our child so it's pointless to watch all other processes. */
|
||||||
|
+ if (!control_pid_good(s))
|
||||||
|
+ if (!s->main_pid_known || s->main_pid_alien)
|
||||||
|
+ (void) unit_enqueue_rewatch_pids(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
|
641
SOURCES/0234-core-implement-per-unit-journal-rate-limiting.patch
Normal file
641
SOURCES/0234-core-implement-per-unit-journal-rate-limiting.patch
Normal file
@ -0,0 +1,641 @@
|
|||||||
|
From a26f2b2732733aa361fec0a3a8f0ba377f48e75c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Anita Zhang <anitzhang@gmail.com>
|
||||||
|
Date: Sun, 7 Oct 2018 20:28:36 -0700
|
||||||
|
Subject: [PATCH] core: implement per unit journal rate limiting
|
||||||
|
|
||||||
|
Add LogRateLimitIntervalSec= and LogRateLimitBurst= options for
|
||||||
|
services. If provided, these values get passed to the journald
|
||||||
|
client context, and those values are used in the rate limiting
|
||||||
|
function in the journal over the the journald.conf values.
|
||||||
|
|
||||||
|
Part of #10230
|
||||||
|
|
||||||
|
(cherry picked from commit 90fc172e191f44979005a524521112f2bd1ff21b)
|
||||||
|
|
||||||
|
Resolves: #1719577
|
||||||
|
---
|
||||||
|
catalog/systemd.catalog.in | 3 +-
|
||||||
|
doc/TRANSIENT-SETTINGS.md | 2 +
|
||||||
|
man/journald.conf.xml | 8 +-
|
||||||
|
man/systemd.exec.xml | 16 ++++
|
||||||
|
src/core/dbus-execute.c | 8 ++
|
||||||
|
src/core/execute.c | 14 ++++
|
||||||
|
src/core/execute.h | 3 +
|
||||||
|
src/core/load-fragment-gperf.gperf.m4 | 2 +
|
||||||
|
src/core/unit.c | 92 +++++++++++++++++++++
|
||||||
|
src/core/unit.h | 2 +
|
||||||
|
src/journal/journald-context.c | 50 ++++++++++-
|
||||||
|
src/journal/journald-context.h | 3 +
|
||||||
|
src/journal/journald-rate-limit.c | 38 ++++-----
|
||||||
|
src/journal/journald-rate-limit.h | 4 +-
|
||||||
|
src/journal/journald-server.c | 4 +-
|
||||||
|
src/shared/bus-unit-util.c | 8 ++
|
||||||
|
test/fuzz/fuzz-unit-file/directives.service | 2 +
|
||||||
|
17 files changed, 231 insertions(+), 28 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/catalog/systemd.catalog.in b/catalog/systemd.catalog.in
|
||||||
|
index f1bddc6f7d..8234e387cf 100644
|
||||||
|
--- a/catalog/systemd.catalog.in
|
||||||
|
+++ b/catalog/systemd.catalog.in
|
||||||
|
@@ -52,7 +52,8 @@ dropped, other services' messages are unaffected.
|
||||||
|
|
||||||
|
The limits controlling when messages are dropped may be configured
|
||||||
|
with RateLimitIntervalSec= and RateLimitBurst= in
|
||||||
|
-/etc/systemd/journald.conf. See journald.conf(5) for details.
|
||||||
|
+/etc/systemd/journald.conf or LogRateLimitIntervalSec= and LogRateLimitBurst=
|
||||||
|
+in the unit file. See journald.conf(5) and systemd.exec(5) for details.
|
||||||
|
|
||||||
|
-- e9bf28e6e834481bb6f48f548ad13606
|
||||||
|
Subject: Journal messages have been missed
|
||||||
|
diff --git a/doc/TRANSIENT-SETTINGS.md b/doc/TRANSIENT-SETTINGS.md
|
||||||
|
index ca9e8387b7..0ea444b133 100644
|
||||||
|
--- a/doc/TRANSIENT-SETTINGS.md
|
||||||
|
+++ b/doc/TRANSIENT-SETTINGS.md
|
||||||
|
@@ -135,6 +135,8 @@ All execution-related settings are available for transient units.
|
||||||
|
✓ SyslogLevelPrefix=
|
||||||
|
✓ LogLevelMax=
|
||||||
|
✓ LogExtraFields=
|
||||||
|
+✓ LogRateLimitIntervalSec=
|
||||||
|
+✓ LogRateLimitBurst=
|
||||||
|
✓ SecureBits=
|
||||||
|
✓ CapabilityBoundingSet=
|
||||||
|
✓ AmbientCapabilities=
|
||||||
|
diff --git a/man/journald.conf.xml b/man/journald.conf.xml
|
||||||
|
index ee8e8b7faf..b57a244b22 100644
|
||||||
|
--- a/man/journald.conf.xml
|
||||||
|
+++ b/man/journald.conf.xml
|
||||||
|
@@ -140,7 +140,13 @@
|
||||||
|
following units: <literal>s</literal>, <literal>min</literal>,
|
||||||
|
<literal>h</literal>, <literal>ms</literal>,
|
||||||
|
<literal>us</literal>. To turn off any kind of rate limiting,
|
||||||
|
- set either value to 0.</para></listitem>
|
||||||
|
+ set either value to 0.</para>
|
||||||
|
+
|
||||||
|
+ <para>If a service provides rate limits for itself through
|
||||||
|
+ <varname>LogRateLimitIntervalSec=</varname> and/or <varname>LogRateLimitBurst=</varname>
|
||||||
|
+ in <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||||
|
+ those values will override the settings specified here.</para>
|
||||||
|
+ </listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
|
||||||
|
index 3bd790b485..737c52bcc4 100644
|
||||||
|
--- a/man/systemd.exec.xml
|
||||||
|
+++ b/man/systemd.exec.xml
|
||||||
|
@@ -1905,6 +1905,22 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy
|
||||||
|
matching. Assign an empty string to reset the list.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><varname>LogRateLimitIntervalSec=</varname></term>
|
||||||
|
+ <term><varname>LogRateLimitBurst=</varname></term>
|
||||||
|
+
|
||||||
|
+ <listitem><para>Configures the rate limiting that is applied to messages generated by this unit. If, in the
|
||||||
|
+ time interval defined by <varname>LogRateLimitIntervalSec=</varname>, more messages than specified in
|
||||||
|
+ <varname>LogRateLimitBurst=</varname> are logged by a service, all further messages within the interval are
|
||||||
|
+ dropped until the interval is over. A message about the number of dropped messages is generated. The time
|
||||||
|
+ specification for <varname>LogRateLimitIntervalSec=</varname> may be specified in the following units: "s",
|
||||||
|
+ "min", "h", "ms", "us" (see
|
||||||
|
+ <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry> for details).
|
||||||
|
+ The default settings are set by <varname>RateLimitIntervalSec=</varname> and <varname>RateLimitBurst=</varname>
|
||||||
|
+ configured in <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||||
|
+ </para></listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>SyslogIdentifier=</varname></term>
|
||||||
|
|
||||||
|
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
|
||||||
|
index c44970c10c..33a91c012e 100644
|
||||||
|
--- a/src/core/dbus-execute.c
|
||||||
|
+++ b/src/core/dbus-execute.c
|
||||||
|
@@ -718,6 +718,8 @@ const sd_bus_vtable bus_exec_vtable[] = {
|
||||||
|
SD_BUS_PROPERTY("SyslogLevel", "i", property_get_syslog_level, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
SD_BUS_PROPERTY("SyslogFacility", "i", property_get_syslog_facility, offsetof(ExecContext, syslog_priority), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
SD_BUS_PROPERTY("LogLevelMax", "i", bus_property_get_int, offsetof(ExecContext, log_level_max), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
+ SD_BUS_PROPERTY("LogRateLimitIntervalUSec", "t", bus_property_get_usec, offsetof(ExecContext, log_rate_limit_interval_usec), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
+ SD_BUS_PROPERTY("LogRateLimitBurst", "u", bus_property_get_unsigned, offsetof(ExecContext, log_rate_limit_burst), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
SD_BUS_PROPERTY("LogExtraFields", "aay", property_get_log_extra_fields, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
SD_BUS_PROPERTY("SecureBits", "i", bus_property_get_int, offsetof(ExecContext, secure_bits), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
SD_BUS_PROPERTY("CapabilityBoundingSet", "t", NULL, offsetof(ExecContext, capability_bounding_set), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
@@ -1073,6 +1075,12 @@ int bus_exec_context_set_transient_property(
|
||||||
|
if (streq(name, "CPUSchedulingPriority"))
|
||||||
|
return bus_set_transient_sched_priority(u, name, &c->cpu_sched_priority, message, flags, error);
|
||||||
|
|
||||||
|
+ if (streq(name, "LogRateLimitIntervalUSec"))
|
||||||
|
+ return bus_set_transient_usec(u, name, &c->log_rate_limit_interval_usec, message, flags, error);
|
||||||
|
+
|
||||||
|
+ if (streq(name, "LogRateLimitBurst"))
|
||||||
|
+ return bus_set_transient_unsigned(u, name, &c->log_rate_limit_burst, message, flags, error);
|
||||||
|
+
|
||||||
|
if (streq(name, "Personality"))
|
||||||
|
return bus_set_transient_personality(u, name, &c->personality, message, flags, error);
|
||||||
|
|
||||||
|
diff --git a/src/core/execute.c b/src/core/execute.c
|
||||||
|
index c62f3cf849..8293c522bc 100644
|
||||||
|
--- a/src/core/execute.c
|
||||||
|
+++ b/src/core/execute.c
|
||||||
|
@@ -3693,6 +3693,9 @@ void exec_context_done(ExecContext *c) {
|
||||||
|
|
||||||
|
exec_context_free_log_extra_fields(c);
|
||||||
|
|
||||||
|
+ c->log_rate_limit_interval_usec = 0;
|
||||||
|
+ c->log_rate_limit_burst = 0;
|
||||||
|
+
|
||||||
|
c->stdin_data = mfree(c->stdin_data);
|
||||||
|
c->stdin_data_size = 0;
|
||||||
|
}
|
||||||
|
@@ -4153,6 +4156,17 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
|
||||||
|
fprintf(f, "%sLogLevelMax: %s\n", prefix, strna(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (c->log_rate_limit_interval_usec > 0) {
|
||||||
|
+ char buf_timespan[FORMAT_TIMESPAN_MAX];
|
||||||
|
+
|
||||||
|
+ fprintf(f,
|
||||||
|
+ "%sLogRateLimitIntervalSec: %s\n",
|
||||||
|
+ prefix, format_timespan(buf_timespan, sizeof(buf_timespan), c->log_rate_limit_interval_usec, USEC_PER_SEC));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (c->log_rate_limit_burst > 0)
|
||||||
|
+ fprintf(f, "%sLogRateLimitBurst: %u\n", prefix, c->log_rate_limit_burst);
|
||||||
|
+
|
||||||
|
if (c->n_log_extra_fields > 0) {
|
||||||
|
size_t j;
|
||||||
|
|
||||||
|
diff --git a/src/core/execute.h b/src/core/execute.h
|
||||||
|
index bff1634b88..8c91636adc 100644
|
||||||
|
--- a/src/core/execute.h
|
||||||
|
+++ b/src/core/execute.h
|
||||||
|
@@ -216,6 +216,9 @@ struct ExecContext {
|
||||||
|
struct iovec* log_extra_fields;
|
||||||
|
size_t n_log_extra_fields;
|
||||||
|
|
||||||
|
+ usec_t log_rate_limit_interval_usec;
|
||||||
|
+ unsigned log_rate_limit_burst;
|
||||||
|
+
|
||||||
|
bool cpu_sched_reset_on_fork;
|
||||||
|
bool non_blocking;
|
||||||
|
bool private_tmp;
|
||||||
|
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
|
||||||
|
index 15fb47838c..1066bcfb8f 100644
|
||||||
|
--- a/src/core/load-fragment-gperf.gperf.m4
|
||||||
|
+++ b/src/core/load-fragment-gperf.gperf.m4
|
||||||
|
@@ -57,6 +57,8 @@ $1.SyslogFacility, config_parse_log_facility, 0,
|
||||||
|
$1.SyslogLevel, config_parse_log_level, 0, offsetof($1, exec_context.syslog_priority)
|
||||||
|
$1.SyslogLevelPrefix, config_parse_bool, 0, offsetof($1, exec_context.syslog_level_prefix)
|
||||||
|
$1.LogLevelMax, config_parse_log_level, 0, offsetof($1, exec_context.log_level_max)
|
||||||
|
+$1.LogRateLimitIntervalSec, config_parse_sec, 0, offsetof($1, exec_context.log_rate_limit_interval_usec)
|
||||||
|
+$1.LogRateLimitBurst, config_parse_unsigned, 0, offsetof($1, exec_context.log_rate_limit_burst)
|
||||||
|
$1.LogExtraFields, config_parse_log_extra_fields, 0, offsetof($1, exec_context)
|
||||||
|
$1.Capabilities, config_parse_warn_compat, DISABLED_LEGACY, offsetof($1, exec_context)
|
||||||
|
$1.SecureBits, config_parse_exec_secure_bits, 0, offsetof($1, exec_context.secure_bits)
|
||||||
|
diff --git a/src/core/unit.c b/src/core/unit.c
|
||||||
|
index b0b1c77ef7..115739f4c6 100644
|
||||||
|
--- a/src/core/unit.c
|
||||||
|
+++ b/src/core/unit.c
|
||||||
|
@@ -3245,6 +3245,8 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds, bool serialize_jobs) {
|
||||||
|
unit_serialize_item(u, f, "exported-invocation-id", yes_no(u->exported_invocation_id));
|
||||||
|
unit_serialize_item(u, f, "exported-log-level-max", yes_no(u->exported_log_level_max));
|
||||||
|
unit_serialize_item(u, f, "exported-log-extra-fields", yes_no(u->exported_log_extra_fields));
|
||||||
|
+ unit_serialize_item(u, f, "exported-log-rate-limit-interval", yes_no(u->exported_log_rate_limit_interval));
|
||||||
|
+ unit_serialize_item(u, f, "exported-log-rate-limit-burst", yes_no(u->exported_log_rate_limit_burst));
|
||||||
|
|
||||||
|
unit_serialize_item_format(u, f, "cpu-usage-base", "%" PRIu64, u->cpu_usage_base);
|
||||||
|
if (u->cpu_usage_last != NSEC_INFINITY)
|
||||||
|
@@ -3508,6 +3510,26 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
|
||||||
|
|
||||||
|
continue;
|
||||||
|
|
||||||
|
+ } else if (streq(l, "exported-log-rate-limit-interval")) {
|
||||||
|
+
|
||||||
|
+ r = parse_boolean(v);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ log_unit_debug(u, "Failed to parse exported log rate limit interval %s, ignoring.", v);
|
||||||
|
+ else
|
||||||
|
+ u->exported_log_rate_limit_interval = r;
|
||||||
|
+
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ } else if (streq(l, "exported-log-rate-limit-burst")) {
|
||||||
|
+
|
||||||
|
+ r = parse_boolean(v);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ log_unit_debug(u, "Failed to parse exported log rate limit burst %s, ignoring.", v);
|
||||||
|
+ else
|
||||||
|
+ u->exported_log_rate_limit_burst = r;
|
||||||
|
+
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
} else if (STR_IN_SET(l, "cpu-usage-base", "cpuacct-usage-base")) {
|
||||||
|
|
||||||
|
r = safe_atou64(v, &u->cpu_usage_base);
|
||||||
|
@@ -5241,6 +5263,60 @@ fail:
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int unit_export_log_rate_limit_interval(Unit *u, const ExecContext *c) {
|
||||||
|
+ _cleanup_free_ char *buf = NULL;
|
||||||
|
+ const char *p;
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ assert(u);
|
||||||
|
+ assert(c);
|
||||||
|
+
|
||||||
|
+ if (u->exported_log_rate_limit_interval)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ if (c->log_rate_limit_interval_usec == 0)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ p = strjoina("/run/systemd/units/log-rate-limit-interval:", u->id);
|
||||||
|
+
|
||||||
|
+ if (asprintf(&buf, "%" PRIu64, c->log_rate_limit_interval_usec) < 0)
|
||||||
|
+ return log_oom();
|
||||||
|
+
|
||||||
|
+ r = symlink_atomic(buf, p);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_unit_debug_errno(u, r, "Failed to create log rate limit interval symlink %s: %m", p);
|
||||||
|
+
|
||||||
|
+ u->exported_log_rate_limit_interval = true;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int unit_export_log_rate_limit_burst(Unit *u, const ExecContext *c) {
|
||||||
|
+ _cleanup_free_ char *buf = NULL;
|
||||||
|
+ const char *p;
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ assert(u);
|
||||||
|
+ assert(c);
|
||||||
|
+
|
||||||
|
+ if (u->exported_log_rate_limit_burst)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ if (c->log_rate_limit_burst == 0)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ p = strjoina("/run/systemd/units/log-rate-limit-burst:", u->id);
|
||||||
|
+
|
||||||
|
+ if (asprintf(&buf, "%u", c->log_rate_limit_burst) < 0)
|
||||||
|
+ return log_oom();
|
||||||
|
+
|
||||||
|
+ r = symlink_atomic(buf, p);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_unit_debug_errno(u, r, "Failed to create log rate limit burst symlink %s: %m", p);
|
||||||
|
+
|
||||||
|
+ u->exported_log_rate_limit_burst = true;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void unit_export_state_files(Unit *u) {
|
||||||
|
const ExecContext *c;
|
||||||
|
|
||||||
|
@@ -5274,6 +5350,8 @@ void unit_export_state_files(Unit *u) {
|
||||||
|
if (c) {
|
||||||
|
(void) unit_export_log_level_max(u, c);
|
||||||
|
(void) unit_export_log_extra_fields(u, c);
|
||||||
|
+ (void) unit_export_log_rate_limit_interval(u, c);
|
||||||
|
+ (void) unit_export_log_rate_limit_burst(u, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -5310,6 +5388,20 @@ void unit_unlink_state_files(Unit *u) {
|
||||||
|
|
||||||
|
u->exported_log_extra_fields = false;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (u->exported_log_rate_limit_interval) {
|
||||||
|
+ p = strjoina("/run/systemd/units/log-rate-limit-interval:", u->id);
|
||||||
|
+ (void) unlink(p);
|
||||||
|
+
|
||||||
|
+ u->exported_log_rate_limit_interval = false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (u->exported_log_rate_limit_burst) {
|
||||||
|
+ p = strjoina("/run/systemd/units/log-rate-limit-burst:", u->id);
|
||||||
|
+ (void) unlink(p);
|
||||||
|
+
|
||||||
|
+ u->exported_log_rate_limit_burst = false;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
int unit_prepare_exec(Unit *u) {
|
||||||
|
diff --git a/src/core/unit.h b/src/core/unit.h
|
||||||
|
index 68cc1869e4..99755823eb 100644
|
||||||
|
--- a/src/core/unit.h
|
||||||
|
+++ b/src/core/unit.h
|
||||||
|
@@ -349,6 +349,8 @@ typedef struct Unit {
|
||||||
|
bool exported_invocation_id:1;
|
||||||
|
bool exported_log_level_max:1;
|
||||||
|
bool exported_log_extra_fields:1;
|
||||||
|
+ bool exported_log_rate_limit_interval:1;
|
||||||
|
+ bool exported_log_rate_limit_burst:1;
|
||||||
|
|
||||||
|
/* When writing transient unit files, stores which section we stored last. If < 0, we didn't write any yet. If
|
||||||
|
* == 0 we are in the [Unit] section, if > 0 we are in the unit type-specific section. */
|
||||||
|
diff --git a/src/journal/journald-context.c b/src/journal/journald-context.c
|
||||||
|
index dba3525ed8..c8e97e16de 100644
|
||||||
|
--- a/src/journal/journald-context.c
|
||||||
|
+++ b/src/journal/journald-context.c
|
||||||
|
@@ -140,6 +140,8 @@ static int client_context_new(Server *s, pid_t pid, ClientContext **ret) {
|
||||||
|
c->timestamp = USEC_INFINITY;
|
||||||
|
c->extra_fields_mtime = NSEC_INFINITY;
|
||||||
|
c->log_level_max = -1;
|
||||||
|
+ c->log_rate_limit_interval = s->rate_limit_interval;
|
||||||
|
+ c->log_rate_limit_burst = s->rate_limit_burst;
|
||||||
|
|
||||||
|
r = hashmap_put(s->client_contexts, PID_TO_PTR(pid), c);
|
||||||
|
if (r < 0) {
|
||||||
|
@@ -151,7 +153,8 @@ static int client_context_new(Server *s, pid_t pid, ClientContext **ret) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void client_context_reset(ClientContext *c) {
|
||||||
|
+static void client_context_reset(Server *s, ClientContext *c) {
|
||||||
|
+ assert(s);
|
||||||
|
assert(c);
|
||||||
|
|
||||||
|
c->timestamp = USEC_INFINITY;
|
||||||
|
@@ -186,6 +189,9 @@ static void client_context_reset(ClientContext *c) {
|
||||||
|
c->extra_fields_mtime = NSEC_INFINITY;
|
||||||
|
|
||||||
|
c->log_level_max = -1;
|
||||||
|
+
|
||||||
|
+ c->log_rate_limit_interval = s->rate_limit_interval;
|
||||||
|
+ c->log_rate_limit_burst = s->rate_limit_burst;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ClientContext* client_context_free(Server *s, ClientContext *c) {
|
||||||
|
@@ -199,7 +205,7 @@ static ClientContext* client_context_free(Server *s, ClientContext *c) {
|
||||||
|
if (c->in_lru)
|
||||||
|
assert_se(prioq_remove(s->client_contexts_lru, c, &c->lru_index) >= 0);
|
||||||
|
|
||||||
|
- client_context_reset(c);
|
||||||
|
+ client_context_reset(s, c);
|
||||||
|
|
||||||
|
return mfree(c);
|
||||||
|
}
|
||||||
|
@@ -464,6 +470,42 @@ static int client_context_read_extra_fields(
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int client_context_read_log_rate_limit_interval(ClientContext *c) {
|
||||||
|
+ _cleanup_free_ char *value = NULL;
|
||||||
|
+ const char *p;
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ assert(c);
|
||||||
|
+
|
||||||
|
+ if (!c->unit)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ p = strjoina("/run/systemd/units/log-rate-limit-interval:", c->unit);
|
||||||
|
+ r = readlink_malloc(p, &value);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ return safe_atou64(value, &c->log_rate_limit_interval);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int client_context_read_log_rate_limit_burst(ClientContext *c) {
|
||||||
|
+ _cleanup_free_ char *value = NULL;
|
||||||
|
+ const char *p;
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ assert(c);
|
||||||
|
+
|
||||||
|
+ if (!c->unit)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ p = strjoina("/run/systemd/units/log-rate-limit-burst:", c->unit);
|
||||||
|
+ r = readlink_malloc(p, &value);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ return safe_atou(value, &c->log_rate_limit_burst);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void client_context_really_refresh(
|
||||||
|
Server *s,
|
||||||
|
ClientContext *c,
|
||||||
|
@@ -490,6 +532,8 @@ static void client_context_really_refresh(
|
||||||
|
(void) client_context_read_invocation_id(s, c);
|
||||||
|
(void) client_context_read_log_level_max(s, c);
|
||||||
|
(void) client_context_read_extra_fields(s, c);
|
||||||
|
+ (void) client_context_read_log_rate_limit_interval(c);
|
||||||
|
+ (void) client_context_read_log_rate_limit_burst(c);
|
||||||
|
|
||||||
|
c->timestamp = timestamp;
|
||||||
|
|
||||||
|
@@ -520,7 +564,7 @@ void client_context_maybe_refresh(
|
||||||
|
/* If the data isn't pinned and if the cashed data is older than the upper limit, we flush it out
|
||||||
|
* entirely. This follows the logic that as long as an entry is pinned the PID reuse is unlikely. */
|
||||||
|
if (c->n_ref == 0 && c->timestamp + MAX_USEC < timestamp) {
|
||||||
|
- client_context_reset(c);
|
||||||
|
+ client_context_reset(s, c);
|
||||||
|
goto refresh;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/journal/journald-context.h b/src/journal/journald-context.h
|
||||||
|
index 9df3a38eff..5e19c71f14 100644
|
||||||
|
--- a/src/journal/journald-context.h
|
||||||
|
+++ b/src/journal/journald-context.h
|
||||||
|
@@ -49,6 +49,9 @@ struct ClientContext {
|
||||||
|
size_t extra_fields_n_iovec;
|
||||||
|
void *extra_fields_data;
|
||||||
|
nsec_t extra_fields_mtime;
|
||||||
|
+
|
||||||
|
+ usec_t log_rate_limit_interval;
|
||||||
|
+ unsigned log_rate_limit_burst;
|
||||||
|
};
|
||||||
|
|
||||||
|
int client_context_get(
|
||||||
|
diff --git a/src/journal/journald-rate-limit.c b/src/journal/journald-rate-limit.c
|
||||||
|
index 6a8a36a736..539efb8669 100644
|
||||||
|
--- a/src/journal/journald-rate-limit.c
|
||||||
|
+++ b/src/journal/journald-rate-limit.c
|
||||||
|
@@ -39,6 +39,10 @@ struct JournalRateLimitGroup {
|
||||||
|
JournalRateLimit *parent;
|
||||||
|
|
||||||
|
char *id;
|
||||||
|
+
|
||||||
|
+ /* Interval is stored to keep track of when the group expires */
|
||||||
|
+ usec_t interval;
|
||||||
|
+
|
||||||
|
JournalRateLimitPool pools[POOLS_MAX];
|
||||||
|
uint64_t hash;
|
||||||
|
|
||||||
|
@@ -47,8 +51,6 @@ struct JournalRateLimitGroup {
|
||||||
|
};
|
||||||
|
|
||||||
|
struct JournalRateLimit {
|
||||||
|
- usec_t interval;
|
||||||
|
- unsigned burst;
|
||||||
|
|
||||||
|
JournalRateLimitGroup* buckets[BUCKETS_MAX];
|
||||||
|
JournalRateLimitGroup *lru, *lru_tail;
|
||||||
|
@@ -58,18 +60,13 @@ struct JournalRateLimit {
|
||||||
|
uint8_t hash_key[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
-JournalRateLimit *journal_rate_limit_new(usec_t interval, unsigned burst) {
|
||||||
|
+JournalRateLimit *journal_rate_limit_new(void) {
|
||||||
|
JournalRateLimit *r;
|
||||||
|
|
||||||
|
- assert(interval > 0 || burst == 0);
|
||||||
|
-
|
||||||
|
r = new0(JournalRateLimit, 1);
|
||||||
|
if (!r)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
- r->interval = interval;
|
||||||
|
- r->burst = burst;
|
||||||
|
-
|
||||||
|
random_bytes(r->hash_key, sizeof(r->hash_key));
|
||||||
|
|
||||||
|
return r;
|
||||||
|
@@ -109,7 +106,7 @@ _pure_ static bool journal_rate_limit_group_expired(JournalRateLimitGroup *g, us
|
||||||
|
assert(g);
|
||||||
|
|
||||||
|
for (i = 0; i < POOLS_MAX; i++)
|
||||||
|
- if (g->pools[i].begin + g->parent->interval >= ts)
|
||||||
|
+ if (g->pools[i].begin + g->interval >= ts)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
@@ -126,7 +123,7 @@ static void journal_rate_limit_vacuum(JournalRateLimit *r, usec_t ts) {
|
||||||
|
journal_rate_limit_group_free(r->lru_tail);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r, const char *id, usec_t ts) {
|
||||||
|
+static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r, const char *id, usec_t interval, usec_t ts) {
|
||||||
|
JournalRateLimitGroup *g;
|
||||||
|
struct siphash state;
|
||||||
|
|
||||||
|
@@ -145,6 +142,8 @@ static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r,
|
||||||
|
string_hash_func(g->id, &state);
|
||||||
|
g->hash = siphash24_finalize(&state);
|
||||||
|
|
||||||
|
+ g->interval = interval;
|
||||||
|
+
|
||||||
|
journal_rate_limit_vacuum(r, ts);
|
||||||
|
|
||||||
|
LIST_PREPEND(bucket, r->buckets[g->hash % BUCKETS_MAX], g);
|
||||||
|
@@ -189,7 +188,7 @@ static unsigned burst_modulate(unsigned burst, uint64_t available) {
|
||||||
|
return burst;
|
||||||
|
}
|
||||||
|
|
||||||
|
-int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, uint64_t available) {
|
||||||
|
+int journal_rate_limit_test(JournalRateLimit *r, const char *id, usec_t rl_interval, unsigned rl_burst, int priority, uint64_t available) {
|
||||||
|
uint64_t h;
|
||||||
|
JournalRateLimitGroup *g;
|
||||||
|
JournalRateLimitPool *p;
|
||||||
|
@@ -209,11 +208,6 @@ int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, u
|
||||||
|
if (!r)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
- if (r->interval == 0 || r->burst == 0)
|
||||||
|
- return 1;
|
||||||
|
-
|
||||||
|
- burst = burst_modulate(r->burst, available);
|
||||||
|
-
|
||||||
|
ts = now(CLOCK_MONOTONIC);
|
||||||
|
|
||||||
|
siphash24_init(&state, r->hash_key);
|
||||||
|
@@ -226,10 +220,16 @@ int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, u
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!g) {
|
||||||
|
- g = journal_rate_limit_group_new(r, id, ts);
|
||||||
|
+ g = journal_rate_limit_group_new(r, id, rl_interval, ts);
|
||||||
|
if (!g)
|
||||||
|
return -ENOMEM;
|
||||||
|
- }
|
||||||
|
+ } else
|
||||||
|
+ g->interval = rl_interval;
|
||||||
|
+
|
||||||
|
+ if (rl_interval == 0 || rl_burst == 0)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ burst = burst_modulate(rl_burst, available);
|
||||||
|
|
||||||
|
p = &g->pools[priority_map[priority]];
|
||||||
|
|
||||||
|
@@ -240,7 +240,7 @@ int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, u
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (p->begin + r->interval < ts) {
|
||||||
|
+ if (p->begin + rl_interval < ts) {
|
||||||
|
unsigned s;
|
||||||
|
|
||||||
|
s = p->suppressed;
|
||||||
|
diff --git a/src/journal/journald-rate-limit.h b/src/journal/journald-rate-limit.h
|
||||||
|
index 3a7f106de0..a2992800fe 100644
|
||||||
|
--- a/src/journal/journald-rate-limit.h
|
||||||
|
+++ b/src/journal/journald-rate-limit.h
|
||||||
|
@@ -5,6 +5,6 @@
|
||||||
|
|
||||||
|
typedef struct JournalRateLimit JournalRateLimit;
|
||||||
|
|
||||||
|
-JournalRateLimit *journal_rate_limit_new(usec_t interval, unsigned burst);
|
||||||
|
+JournalRateLimit *journal_rate_limit_new(void);
|
||||||
|
void journal_rate_limit_free(JournalRateLimit *r);
|
||||||
|
-int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, uint64_t available);
|
||||||
|
+int journal_rate_limit_test(JournalRateLimit *r, const char *id, usec_t rl_interval, unsigned rl_burst, int priority, uint64_t available);
|
||||||
|
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
|
||||||
|
index 8de45552f6..0c983e102a 100644
|
||||||
|
--- a/src/journal/journald-server.c
|
||||||
|
+++ b/src/journal/journald-server.c
|
||||||
|
@@ -943,7 +943,7 @@ void server_dispatch_message(
|
||||||
|
if (c && c->unit) {
|
||||||
|
(void) determine_space(s, &available, NULL);
|
||||||
|
|
||||||
|
- rl = journal_rate_limit_test(s->rate_limit, c->unit, priority & LOG_PRIMASK, available);
|
||||||
|
+ rl = journal_rate_limit_test(s->rate_limit, c->unit, c->log_rate_limit_interval, c->log_rate_limit_burst, priority & LOG_PRIMASK, available);
|
||||||
|
if (rl == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
@@ -1852,7 +1852,7 @@ int server_init(Server *s) {
|
||||||
|
if (!s->udev)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
- s->rate_limit = journal_rate_limit_new(s->rate_limit_interval, s->rate_limit_burst);
|
||||||
|
+ s->rate_limit = journal_rate_limit_new();
|
||||||
|
if (!s->rate_limit)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
|
||||||
|
index 3238b442c0..271cc054da 100644
|
||||||
|
--- a/src/shared/bus-unit-util.c
|
||||||
|
+++ b/src/shared/bus-unit-util.c
|
||||||
|
@@ -755,6 +755,14 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
|
||||||
|
|
||||||
|
return bus_append_parse_nsec(m, field, eq);
|
||||||
|
|
||||||
|
+ if (STR_IN_SET(field, "LogRateLimitIntervalSec"))
|
||||||
|
+
|
||||||
|
+ return bus_append_parse_sec_rename(m, field, eq);
|
||||||
|
+
|
||||||
|
+ if (streq(field, "LogRateLimitBurst"))
|
||||||
|
+
|
||||||
|
+ return bus_append_safe_atou(m, field, eq);
|
||||||
|
+
|
||||||
|
if (streq(field, "MountFlags"))
|
||||||
|
|
||||||
|
return bus_append_mount_propagation_flags_from_string(m, field, eq);
|
||||||
|
diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service
|
||||||
|
index c2334d3b19..d8d1fc68b8 100644
|
||||||
|
--- a/test/fuzz/fuzz-unit-file/directives.service
|
||||||
|
+++ b/test/fuzz/fuzz-unit-file/directives.service
|
||||||
|
@@ -792,6 +792,8 @@ LineMax=
|
||||||
|
LockPersonality=
|
||||||
|
LogExtraFields=
|
||||||
|
LogLevelMax=
|
||||||
|
+LogRateLimitIntervalSec=
|
||||||
|
+LogRateLimitBurst=
|
||||||
|
LogsDirectory=
|
||||||
|
LogsDirectoryMode=
|
||||||
|
MACVLAN=
|
@ -0,0 +1,35 @@
|
|||||||
|
From 55d9d6dfb731d2f1c8c940fb8a7ea0af6c498c4c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Sekletar <msekleta@redhat.com>
|
||||||
|
Date: Mon, 9 Sep 2019 14:38:35 +0200
|
||||||
|
Subject: [PATCH] path: stop watching path specs once we triggered the target
|
||||||
|
unit
|
||||||
|
|
||||||
|
We start watching them again once we get a notification that triggered
|
||||||
|
unit entered inactive or failed state.
|
||||||
|
|
||||||
|
Fixes: #10503
|
||||||
|
(cherry picked from commit 8fca6944c2ee20c63d62154c8badddc77170b176)
|
||||||
|
|
||||||
|
Resolves: #1763161
|
||||||
|
---
|
||||||
|
src/core/path.c | 6 ++----
|
||||||
|
1 file changed, 2 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/path.c b/src/core/path.c
|
||||||
|
index 68b13b610a..5ef178a46b 100644
|
||||||
|
--- a/src/core/path.c
|
||||||
|
+++ b/src/core/path.c
|
||||||
|
@@ -478,11 +478,9 @@ static void path_enter_running(Path *p) {
|
||||||
|
|
||||||
|
p->inotify_triggered = false;
|
||||||
|
|
||||||
|
- r = path_watch(p);
|
||||||
|
- if (r < 0)
|
||||||
|
- goto fail;
|
||||||
|
-
|
||||||
|
path_set_state(p, PATH_RUNNING);
|
||||||
|
+ path_unwatch(p);
|
||||||
|
+
|
||||||
|
return;
|
||||||
|
|
||||||
|
fail:
|
@ -0,0 +1,28 @@
|
|||||||
|
From 33aa231f5bf3335cdacfb38ffba757865019ce4d Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Renaud=20M=C3=A9trich?=
|
||||||
|
<1163635+rmetrich@users.noreply.github.com>
|
||||||
|
Date: Mon, 3 Sep 2018 05:42:39 +0200
|
||||||
|
Subject: [PATCH] journald: fixed assertion failure when system journal
|
||||||
|
rotation fails (#9893)
|
||||||
|
|
||||||
|
(cherry picked from commit fd790d6f09b10a87b007b71403cb018f18ff91c9)
|
||||||
|
|
||||||
|
Resolves: #1763619
|
||||||
|
---
|
||||||
|
src/journal/journald-server.c | 3 ++-
|
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
|
||||||
|
index 0c983e102a..6aecb67d6c 100644
|
||||||
|
--- a/src/journal/journald-server.c
|
||||||
|
+++ b/src/journal/journald-server.c
|
||||||
|
@@ -1041,7 +1041,8 @@ int server_flush_to_var(Server *s, bool require_flag_file) {
|
||||||
|
r = 0;
|
||||||
|
|
||||||
|
finish:
|
||||||
|
- journal_file_post_change(s->system_journal);
|
||||||
|
+ if (s->system_journal)
|
||||||
|
+ journal_file_post_change(s->system_journal);
|
||||||
|
|
||||||
|
s->runtime_journal = journal_file_close(s->runtime_journal);
|
||||||
|
|
@ -0,0 +1,29 @@
|
|||||||
|
From a7f18f9ef4abc7e0732d1710ead2a18a38c3ec6d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||||
|
Date: Fri, 15 Mar 2019 10:05:33 +0100
|
||||||
|
Subject: [PATCH] test: use PBKDF2 instead of Argon2 in cryptsetup...
|
||||||
|
|
||||||
|
to reduce memory requirements for volume manipulation. Also,
|
||||||
|
to further improve the test performance, reduce number of PBKDF
|
||||||
|
iterations to 1000 (allowed minimum).
|
||||||
|
|
||||||
|
(cherry picked from commit 5b69d297c153478f6f5e74ba66e1f4e5b6422baf)
|
||||||
|
|
||||||
|
Related: #1761519
|
||||||
|
---
|
||||||
|
test/TEST-02-CRYPTSETUP/test.sh | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/test/TEST-02-CRYPTSETUP/test.sh b/test/TEST-02-CRYPTSETUP/test.sh
|
||||||
|
index 545602e17a..c38e56f72e 100755
|
||||||
|
--- a/test/TEST-02-CRYPTSETUP/test.sh
|
||||||
|
+++ b/test/TEST-02-CRYPTSETUP/test.sh
|
||||||
|
@@ -29,7 +29,7 @@ check_result_qemu() {
|
||||||
|
test_setup() {
|
||||||
|
create_empty_image
|
||||||
|
echo -n test >$TESTDIR/keyfile
|
||||||
|
- cryptsetup -q luksFormat ${LOOPDEV}p2 $TESTDIR/keyfile
|
||||||
|
+ cryptsetup -q luksFormat --pbkdf pbkdf2 --pbkdf-force-iterations 1000 ${LOOPDEV}p2 $TESTDIR/keyfile
|
||||||
|
cryptsetup luksOpen ${LOOPDEV}p2 varcrypt <$TESTDIR/keyfile
|
||||||
|
mkfs.ext4 -L var /dev/mapper/varcrypt
|
||||||
|
mkdir -p $TESTDIR/root
|
252
SOURCES/0238-test-mask-several-unnecessary-services.patch
Normal file
252
SOURCES/0238-test-mask-several-unnecessary-services.patch
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
From c748b95f5a00b6d9c46026c3d251c40437e6b64a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Thu, 1 Nov 2018 17:26:36 +0900
|
||||||
|
Subject: [PATCH] test: mask several unnecessary services
|
||||||
|
|
||||||
|
This may make CIs run faster.
|
||||||
|
|
||||||
|
(cherry picked from commit 056ae88152a722bdbea54ff33db815d585c8b9c6)
|
||||||
|
|
||||||
|
Related: #1761519
|
||||||
|
---
|
||||||
|
test/TEST-02-CRYPTSETUP/test.sh | 8 ++++++++
|
||||||
|
test/TEST-03-JOBS/test.sh | 8 ++++++++
|
||||||
|
test/TEST-04-JOURNAL/test.sh | 8 ++++++++
|
||||||
|
test/TEST-05-RLIMITS/test.sh | 8 ++++++++
|
||||||
|
test/TEST-07-ISSUE-1981/test.sh | 8 ++++++++
|
||||||
|
test/TEST-11-ISSUE-3166/test.sh | 8 ++++++++
|
||||||
|
test/TEST-12-ISSUE-3171/test.sh | 8 ++++++++
|
||||||
|
test/TEST-13-NSPAWN-SMOKE/test.sh | 8 ++++++++
|
||||||
|
test/TEST-18-FAILUREACTION/test.sh | 7 +++++++
|
||||||
|
test/TEST-19-DELEGATE/test.sh | 8 ++++++++
|
||||||
|
test/TEST-20-MAINPIDGAMES/test.sh | 8 ++++++++
|
||||||
|
test/TEST-23-TYPE-EXEC/test.sh | 8 ++++++++
|
||||||
|
12 files changed, 95 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/test/TEST-02-CRYPTSETUP/test.sh b/test/TEST-02-CRYPTSETUP/test.sh
|
||||||
|
index c38e56f72e..97eb2f409e 100755
|
||||||
|
--- a/test/TEST-02-CRYPTSETUP/test.sh
|
||||||
|
+++ b/test/TEST-02-CRYPTSETUP/test.sh
|
||||||
|
@@ -45,6 +45,14 @@ test_setup() {
|
||||||
|
|
||||||
|
setup_basic_environment
|
||||||
|
|
||||||
|
+ # mask some services that we do not want to run in these tests
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
|
||||||
|
+
|
||||||
|
# setup the testsuite service
|
||||||
|
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
|
||||||
|
[Unit]
|
||||||
|
diff --git a/test/TEST-03-JOBS/test.sh b/test/TEST-03-JOBS/test.sh
|
||||||
|
index 08e5cfe6c8..93a387df59 100755
|
||||||
|
--- a/test/TEST-03-JOBS/test.sh
|
||||||
|
+++ b/test/TEST-03-JOBS/test.sh
|
||||||
|
@@ -19,6 +19,14 @@ test_setup() {
|
||||||
|
|
||||||
|
setup_basic_environment
|
||||||
|
|
||||||
|
+ # mask some services that we do not want to run in these tests
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
|
||||||
|
+
|
||||||
|
# setup the testsuite service
|
||||||
|
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
|
||||||
|
[Unit]
|
||||||
|
diff --git a/test/TEST-04-JOURNAL/test.sh b/test/TEST-04-JOURNAL/test.sh
|
||||||
|
index 30e7b181b2..80e5fb0a73 100755
|
||||||
|
--- a/test/TEST-04-JOURNAL/test.sh
|
||||||
|
+++ b/test/TEST-04-JOURNAL/test.sh
|
||||||
|
@@ -18,6 +18,14 @@ test_setup() {
|
||||||
|
|
||||||
|
setup_basic_environment
|
||||||
|
|
||||||
|
+ # mask some services that we do not want to run in these tests
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
|
||||||
|
+
|
||||||
|
# setup the testsuite service
|
||||||
|
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
|
||||||
|
[Unit]
|
||||||
|
diff --git a/test/TEST-05-RLIMITS/test.sh b/test/TEST-05-RLIMITS/test.sh
|
||||||
|
index a1b855c5fb..711f87f585 100755
|
||||||
|
--- a/test/TEST-05-RLIMITS/test.sh
|
||||||
|
+++ b/test/TEST-05-RLIMITS/test.sh
|
||||||
|
@@ -18,6 +18,14 @@ test_setup() {
|
||||||
|
|
||||||
|
setup_basic_environment
|
||||||
|
|
||||||
|
+ # mask some services that we do not want to run in these tests
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
|
||||||
|
+
|
||||||
|
cat >$initdir/etc/systemd/system.conf <<EOF
|
||||||
|
[Manager]
|
||||||
|
DefaultLimitNOFILE=10000:16384
|
||||||
|
diff --git a/test/TEST-07-ISSUE-1981/test.sh b/test/TEST-07-ISSUE-1981/test.sh
|
||||||
|
index 88d143e479..8d3ed04712 100755
|
||||||
|
--- a/test/TEST-07-ISSUE-1981/test.sh
|
||||||
|
+++ b/test/TEST-07-ISSUE-1981/test.sh
|
||||||
|
@@ -21,6 +21,14 @@ test_setup() {
|
||||||
|
|
||||||
|
setup_basic_environment
|
||||||
|
|
||||||
|
+ # mask some services that we do not want to run in these tests
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
|
||||||
|
+
|
||||||
|
# setup the testsuite service
|
||||||
|
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
|
||||||
|
[Unit]
|
||||||
|
diff --git a/test/TEST-11-ISSUE-3166/test.sh b/test/TEST-11-ISSUE-3166/test.sh
|
||||||
|
index 8aae4d5ed9..e6e96101aa 100755
|
||||||
|
--- a/test/TEST-11-ISSUE-3166/test.sh
|
||||||
|
+++ b/test/TEST-11-ISSUE-3166/test.sh
|
||||||
|
@@ -20,6 +20,14 @@ test_setup() {
|
||||||
|
setup_basic_environment
|
||||||
|
dracut_install false touch
|
||||||
|
|
||||||
|
+ # mask some services that we do not want to run in these tests
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
|
||||||
|
+
|
||||||
|
# setup the testsuite service
|
||||||
|
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
|
||||||
|
[Unit]
|
||||||
|
diff --git a/test/TEST-12-ISSUE-3171/test.sh b/test/TEST-12-ISSUE-3171/test.sh
|
||||||
|
index 559fa469cd..915cc21cd8 100755
|
||||||
|
--- a/test/TEST-12-ISSUE-3171/test.sh
|
||||||
|
+++ b/test/TEST-12-ISSUE-3171/test.sh
|
||||||
|
@@ -20,6 +20,14 @@ test_setup() {
|
||||||
|
setup_basic_environment
|
||||||
|
dracut_install cat mv stat nc
|
||||||
|
|
||||||
|
+ # mask some services that we do not want to run in these tests
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
|
||||||
|
+
|
||||||
|
# setup the testsuite service
|
||||||
|
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
|
||||||
|
[Unit]
|
||||||
|
diff --git a/test/TEST-13-NSPAWN-SMOKE/test.sh b/test/TEST-13-NSPAWN-SMOKE/test.sh
|
||||||
|
index a676384bfc..cec59fa24d 100755
|
||||||
|
--- a/test/TEST-13-NSPAWN-SMOKE/test.sh
|
||||||
|
+++ b/test/TEST-13-NSPAWN-SMOKE/test.sh
|
||||||
|
@@ -20,6 +20,14 @@ test_setup() {
|
||||||
|
setup_basic_environment
|
||||||
|
dracut_install busybox chmod rmdir unshare ip sysctl
|
||||||
|
|
||||||
|
+ # mask some services that we do not want to run in these tests
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
|
||||||
|
+
|
||||||
|
cp create-busybox-container $initdir/
|
||||||
|
|
||||||
|
./create-busybox-container $initdir/nc-container
|
||||||
|
diff --git a/test/TEST-18-FAILUREACTION/test.sh b/test/TEST-18-FAILUREACTION/test.sh
|
||||||
|
index e48ba9bac3..783b3aac6e 100755
|
||||||
|
--- a/test/TEST-18-FAILUREACTION/test.sh
|
||||||
|
+++ b/test/TEST-18-FAILUREACTION/test.sh
|
||||||
|
@@ -35,6 +35,13 @@ EOF
|
||||||
|
) || return 1
|
||||||
|
setup_nspawn_root
|
||||||
|
|
||||||
|
+ # mask some services that we do not want to run in these tests
|
||||||
|
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
|
||||||
|
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
|
||||||
|
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.service
|
||||||
|
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
|
||||||
|
+ ln -s /dev/null $initdir/etc/systemd/system/systemd-resolved.service
|
||||||
|
+
|
||||||
|
ddebug "umount $TESTDIR/root"
|
||||||
|
umount $TESTDIR/root
|
||||||
|
}
|
||||||
|
diff --git a/test/TEST-19-DELEGATE/test.sh b/test/TEST-19-DELEGATE/test.sh
|
||||||
|
index 841a29c06f..ef1d99932a 100755
|
||||||
|
--- a/test/TEST-19-DELEGATE/test.sh
|
||||||
|
+++ b/test/TEST-19-DELEGATE/test.sh
|
||||||
|
@@ -20,6 +20,14 @@ test_setup() {
|
||||||
|
|
||||||
|
setup_basic_environment
|
||||||
|
|
||||||
|
+ # mask some services that we do not want to run in these tests
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
|
||||||
|
+
|
||||||
|
# setup the testsuite service
|
||||||
|
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
|
||||||
|
[Unit]
|
||||||
|
diff --git a/test/TEST-20-MAINPIDGAMES/test.sh b/test/TEST-20-MAINPIDGAMES/test.sh
|
||||||
|
index b14083a256..4ec8081478 100755
|
||||||
|
--- a/test/TEST-20-MAINPIDGAMES/test.sh
|
||||||
|
+++ b/test/TEST-20-MAINPIDGAMES/test.sh
|
||||||
|
@@ -17,6 +17,14 @@ test_setup() {
|
||||||
|
|
||||||
|
setup_basic_environment
|
||||||
|
|
||||||
|
+ # mask some services that we do not want to run in these tests
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
|
||||||
|
+
|
||||||
|
# setup the testsuite service
|
||||||
|
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
|
||||||
|
[Unit]
|
||||||
|
diff --git a/test/TEST-23-TYPE-EXEC/test.sh b/test/TEST-23-TYPE-EXEC/test.sh
|
||||||
|
index bdcea239a7..2e76451f5b 100755
|
||||||
|
--- a/test/TEST-23-TYPE-EXEC/test.sh
|
||||||
|
+++ b/test/TEST-23-TYPE-EXEC/test.sh
|
||||||
|
@@ -17,6 +17,14 @@ test_setup() {
|
||||||
|
|
||||||
|
setup_basic_environment
|
||||||
|
|
||||||
|
+ # mask some services that we do not want to run in these tests
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service
|
||||||
|
+ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service
|
||||||
|
+
|
||||||
|
# setup the testsuite service
|
||||||
|
cat >$initdir/etc/systemd/system/testsuite.service <<EOF
|
||||||
|
[Unit]
|
@ -0,0 +1,30 @@
|
|||||||
|
From 27d1acaa1d4c9299db461f0f1922c573be6a52c0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Frantisek Sumsal <fsumsal@redhat.com>
|
||||||
|
Date: Mon, 21 Oct 2019 18:39:39 +0200
|
||||||
|
Subject: [PATCH] test: bump the second partition's size to 50M
|
||||||
|
|
||||||
|
The former size (10M) caused systemd-journald to crash with SIGABRT when
|
||||||
|
used on a LUKS2 partition, as the LUKS2 metadata consume a significant
|
||||||
|
part of the 10M partition, thus leaving no space for the journal file
|
||||||
|
itself (relevant for TEST-02-CRYPTSETUP). This change has been present
|
||||||
|
in upstream for a while anyway.
|
||||||
|
|
||||||
|
Related: #1761519
|
||||||
|
rhel-only
|
||||||
|
---
|
||||||
|
test/test-functions | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/test/test-functions b/test/test-functions
|
||||||
|
index af9d16140f..fe25a501da 100644
|
||||||
|
--- a/test/test-functions
|
||||||
|
+++ b/test/test-functions
|
||||||
|
@@ -433,7 +433,7 @@ create_empty_image() {
|
||||||
|
[ -b "$LOOPDEV" ] || return 1
|
||||||
|
echo "LOOPDEV=$LOOPDEV" >> $STATEFILE
|
||||||
|
sfdisk "$LOOPDEV" <<EOF
|
||||||
|
-,390M
|
||||||
|
+,350M
|
||||||
|
,
|
||||||
|
EOF
|
||||||
|
|
@ -0,0 +1,51 @@
|
|||||||
|
From 069cf14150b55e6580cf1d482709a0e48c36ee84 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andrew Jorgensen <ajorgens@amazon.com>
|
||||||
|
Date: Wed, 25 Jul 2018 08:06:57 -0700
|
||||||
|
Subject: [PATCH] shared/sleep-config: exclude zram devices from hibernation
|
||||||
|
candidates
|
||||||
|
|
||||||
|
On a host with sufficiently large zram but with no actual swap, logind will
|
||||||
|
respond to CanHibernate() with yes. With this patch, it will correctly respond
|
||||||
|
no, unless there are other swap devices to consider.
|
||||||
|
|
||||||
|
(cherry picked from commit 411ae92b407bd7b4549b205ad754bcd0e3dfd81f)
|
||||||
|
|
||||||
|
Resolves: #1763617
|
||||||
|
---
|
||||||
|
src/shared/sleep-config.c | 16 +++++++++++++---
|
||||||
|
1 file changed, 13 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c
|
||||||
|
index 9e4ce183d3..a1523e3f21 100644
|
||||||
|
--- a/src/shared/sleep-config.c
|
||||||
|
+++ b/src/shared/sleep-config.c
|
||||||
|
@@ -21,6 +21,7 @@
|
||||||
|
#include "log.h"
|
||||||
|
#include "macro.h"
|
||||||
|
#include "parse-util.h"
|
||||||
|
+#include "path-util.h"
|
||||||
|
#include "sleep-config.h"
|
||||||
|
#include "string-util.h"
|
||||||
|
#include "strv.h"
|
||||||
|
@@ -201,9 +202,18 @@ int find_hibernate_location(char **device, char **type, size_t *size, size_t *us
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (streq(type_field, "partition") && endswith(dev_field, "\\040(deleted)")) {
|
||||||
|
- log_warning("Ignoring deleted swapfile '%s'.", dev_field);
|
||||||
|
- continue;
|
||||||
|
+ if (streq(type_field, "partition")) {
|
||||||
|
+ if (endswith(dev_field, "\\040(deleted)")) {
|
||||||
|
+ log_warning("Ignoring deleted swapfile '%s'.", dev_field);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ const char *fn;
|
||||||
|
+ fn = path_startswith(dev_field, "/dev/");
|
||||||
|
+ if (fn && startswith(fn, "zram")) {
|
||||||
|
+ log_debug("Ignoring compressed ram swap device '%s'.", dev_field);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
if (device)
|
||||||
|
*device = TAKE_PTR(dev_field);
|
@ -0,0 +1,45 @@
|
|||||||
|
From cc3c020a5f4fc577dbd2da769c22b77e37ae4e30 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Sekletar <msekleta@redhat.com>
|
||||||
|
Date: Tue, 26 Feb 2019 17:33:27 +0100
|
||||||
|
Subject: [PATCH] selinux: don't log SELINUX_INFO and SELINUX_WARNING messages
|
||||||
|
to audit
|
||||||
|
|
||||||
|
Previously we logged even info message from libselinux as USER_AVC's to
|
||||||
|
audit. For example, setting SELinux to permissive mode generated
|
||||||
|
following audit message,
|
||||||
|
|
||||||
|
time->Tue Feb 26 11:29:29 2019
|
||||||
|
type=USER_AVC msg=audit(1551198569.423:334): pid=1 uid=0 auid=4294967295 ses=4294967295 subj=system_u:system_r:init_t:s0 msg='avc: received setenforce notice (enforcing=0) exe="/usr/lib/systemd/systemd" sauid=0 hostname=? addr=? terminal=?'
|
||||||
|
|
||||||
|
This is unnecessary and wrong at the same time. First, kernel already
|
||||||
|
records audit event that SELinux was switched to permissive mode, also
|
||||||
|
the type of the message really shouldn't be USER_AVC.
|
||||||
|
|
||||||
|
Let's ignore SELINUX_WARNING and SELINUX_INFO and forward to audit only
|
||||||
|
USER_AVC's and errors as these two libselinux message types have clear
|
||||||
|
mapping to audit message types.
|
||||||
|
|
||||||
|
(cherry picked from commit 6227fc14c48c4c17daed4b91f61cdd4aa375790a)
|
||||||
|
|
||||||
|
Resolves: #1763612
|
||||||
|
---
|
||||||
|
src/core/selinux-access.c | 6 +++++-
|
||||||
|
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/selinux-access.c b/src/core/selinux-access.c
|
||||||
|
index 39e994afd7..ada4f8705c 100644
|
||||||
|
--- a/src/core/selinux-access.c
|
||||||
|
+++ b/src/core/selinux-access.c
|
||||||
|
@@ -112,7 +112,11 @@ _printf_(2, 3) static int log_callback(int type, const char *fmt, ...) {
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
if (r >= 0) {
|
||||||
|
- audit_log_user_avc_message(fd, AUDIT_USER_AVC, buf, NULL, NULL, NULL, 0);
|
||||||
|
+ if (type == SELINUX_AVC)
|
||||||
|
+ audit_log_user_avc_message(get_audit_fd(), AUDIT_USER_AVC, buf, NULL, NULL, NULL, 0);
|
||||||
|
+ else if (type == SELINUX_ERROR)
|
||||||
|
+ audit_log_user_avc_message(get_audit_fd(), AUDIT_USER_SELINUX_ERR, buf, NULL, NULL, NULL, 0);
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
47
SOURCES/0242-sd-device-introduce-log_device_-macros.patch
Normal file
47
SOURCES/0242-sd-device-introduce-log_device_-macros.patch
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
From 0160499e86642f159a972be0196bf7c8a1d19ea8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||||
|
Date: Mon, 22 Oct 2018 12:04:13 +0900
|
||||||
|
Subject: [PATCH] sd-device: introduce log_device_*() macros
|
||||||
|
|
||||||
|
(cherry picked from commit b0cba0ca526ed2d86e283a0fcfebdf0a4d4bea9b)
|
||||||
|
|
||||||
|
Related: #1753369
|
||||||
|
---
|
||||||
|
src/libsystemd/sd-device/device-util.h | 27 ++++++++++++++++++++++++++
|
||||||
|
1 file changed, 27 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/libsystemd/sd-device/device-util.h b/src/libsystemd/sd-device/device-util.h
|
||||||
|
index 6dcd2645e6..448dfc63d7 100644
|
||||||
|
--- a/src/libsystemd/sd-device/device-util.h
|
||||||
|
+++ b/src/libsystemd/sd-device/device-util.h
|
||||||
|
@@ -33,3 +33,30 @@
|
||||||
|
for (device = sd_device_enumerator_get_subsystem_first(enumerator); \
|
||||||
|
device; \
|
||||||
|
device = sd_device_enumerator_get_subsystem_next(enumerator))
|
||||||
|
+
|
||||||
|
+#define log_device_full(device, level, error, ...) \
|
||||||
|
+ ({ \
|
||||||
|
+ const char *_sysname = NULL, *_subsystem = NULL; \
|
||||||
|
+ sd_device *_d = (device); \
|
||||||
|
+ int _level = (level), _error = (error); \
|
||||||
|
+ \
|
||||||
|
+ if (_d && _unlikely_(log_get_max_level() >= _level)) { \
|
||||||
|
+ (void) sd_device_get_sysname(_d, &_sysname); \
|
||||||
|
+ (void) sd_device_get_subsystem(_d, &_subsystem); \
|
||||||
|
+ } \
|
||||||
|
+ log_object_internal(_level, _error, __FILE__, __LINE__, __func__, \
|
||||||
|
+ _sysname ? "DEVICE=" : NULL, _sysname, \
|
||||||
|
+ _subsystem ? "SUBSYSTEM=" : NULL, _subsystem, ##__VA_ARGS__); \
|
||||||
|
+ })
|
||||||
|
+
|
||||||
|
+#define log_device_debug(link, ...) log_device_full(link, LOG_DEBUG, 0, ##__VA_ARGS__)
|
||||||
|
+#define log_device_info(link, ...) log_device_full(link, LOG_INFO, 0, ##__VA_ARGS__)
|
||||||
|
+#define log_device_notice(link, ...) log_device_full(link, LOG_NOTICE, 0, ##__VA_ARGS__)
|
||||||
|
+#define log_device_warning(link, ...) log_device_full(link, LOG_WARNING, 0, ##__VA_ARGS__)
|
||||||
|
+#define log_device_error(link, ...) log_device_full(link, LOG_ERR, 0, ##__VA_ARGS__)
|
||||||
|
+
|
||||||
|
+#define log_device_debug_errno(link, error, ...) log_device_full(link, LOG_DEBUG, error, ##__VA_ARGS__)
|
||||||
|
+#define log_device_info_errno(link, error, ...) log_device_full(link, LOG_INFO, error, ##__VA_ARGS__)
|
||||||
|
+#define log_device_notice_errno(link, error, ...) log_device_full(link, LOG_NOTICE, error, ##__VA_ARGS__)
|
||||||
|
+#define log_device_warning_errno(link, error, ...) log_device_full(link, LOG_WARNING, error, ##__VA_ARGS__)
|
||||||
|
+#define log_device_error_errno(link, error, ...) log_device_full(link, LOG_ERR, error, ##__VA_ARGS__)
|
@ -0,0 +1,505 @@
|
|||||||
|
From 080d3b14470f6ac59f4cfb97a4200ed18df5c260 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Fabian Henneke <fabian@henneke.me>
|
||||||
|
Date: Wed, 21 Aug 2019 11:17:59 +0200
|
||||||
|
Subject: [PATCH] udev: Add id program and rule for FIDO security tokens
|
||||||
|
|
||||||
|
Add a fido_id program meant to be run for devices in the hidraw
|
||||||
|
subsystem via an IMPORT directive. The program parses the HID report
|
||||||
|
descriptor and assigns the ID_SECURITY_TOKEN environment variable if a
|
||||||
|
declared usage matches the FIDO_CTAPHID_USAGE declared in the FIDO CTAP
|
||||||
|
specification. This replaces the previous approach of whitelisting all
|
||||||
|
known security token models manually.
|
||||||
|
|
||||||
|
This commit is accompanied by a test suite and a fuzzer target for the
|
||||||
|
descriptor parsing routine.
|
||||||
|
|
||||||
|
Fixes: #11996.
|
||||||
|
(cherry picked from commit d45ee2f31a8358db0accde2e7c81777cedadc3c2)
|
||||||
|
|
||||||
|
Resolves: #1753369
|
||||||
|
---
|
||||||
|
rules/60-fido-id.rules | 7 ++
|
||||||
|
rules/meson.build | 1 +
|
||||||
|
src/fuzz/fuzz-fido-id-desc.c | 23 +++++++
|
||||||
|
src/fuzz/fuzz-fido-id-desc.dict | 6 ++
|
||||||
|
src/fuzz/meson.build | 4 ++
|
||||||
|
src/test/meson.build | 4 ++
|
||||||
|
src/test/test-fido-id-desc.c | 85 +++++++++++++++++++++++
|
||||||
|
src/udev/fido_id/fido_id.c | 103 ++++++++++++++++++++++++++++
|
||||||
|
src/udev/fido_id/fido_id_desc.c | 92 +++++++++++++++++++++++++
|
||||||
|
src/udev/fido_id/fido_id_desc.h | 8 +++
|
||||||
|
src/udev/meson.build | 3 +
|
||||||
|
test/fuzz/fuzz-fido-id-desc/crash0 | 1 +
|
||||||
|
test/fuzz/fuzz-fido-id-desc/crash1 | 1 +
|
||||||
|
test/fuzz/fuzz-fido-id-desc/report0 | Bin 0 -> 71 bytes
|
||||||
|
test/fuzz/fuzz-fido-id-desc/report1 | Bin 0 -> 34 bytes
|
||||||
|
15 files changed, 338 insertions(+)
|
||||||
|
create mode 100644 rules/60-fido-id.rules
|
||||||
|
create mode 100644 src/fuzz/fuzz-fido-id-desc.c
|
||||||
|
create mode 100644 src/fuzz/fuzz-fido-id-desc.dict
|
||||||
|
create mode 100644 src/test/test-fido-id-desc.c
|
||||||
|
create mode 100644 src/udev/fido_id/fido_id.c
|
||||||
|
create mode 100644 src/udev/fido_id/fido_id_desc.c
|
||||||
|
create mode 100644 src/udev/fido_id/fido_id_desc.h
|
||||||
|
create mode 100644 test/fuzz/fuzz-fido-id-desc/crash0
|
||||||
|
create mode 100644 test/fuzz/fuzz-fido-id-desc/crash1
|
||||||
|
create mode 100644 test/fuzz/fuzz-fido-id-desc/report0
|
||||||
|
create mode 100644 test/fuzz/fuzz-fido-id-desc/report1
|
||||||
|
|
||||||
|
diff --git a/rules/60-fido-id.rules b/rules/60-fido-id.rules
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..fcf5079704
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/rules/60-fido-id.rules
|
||||||
|
@@ -0,0 +1,7 @@
|
||||||
|
+# do not edit this file, it will be overwritten on update
|
||||||
|
+
|
||||||
|
+ACTION=="remove", GOTO="fido_id_end"
|
||||||
|
+
|
||||||
|
+SUBSYSTEM=="hidraw", IMPORT{program}="fido_id"
|
||||||
|
+
|
||||||
|
+LABEL="fido_id_end"
|
||||||
|
diff --git a/rules/meson.build b/rules/meson.build
|
||||||
|
index b6aae596b6..6363f8bf2e 100644
|
||||||
|
--- a/rules/meson.build
|
||||||
|
+++ b/rules/meson.build
|
||||||
|
@@ -7,6 +7,7 @@ rules = files('''
|
||||||
|
60-cdrom_id.rules
|
||||||
|
60-drm.rules
|
||||||
|
60-evdev.rules
|
||||||
|
+ 60-fido-id.rules
|
||||||
|
60-input-id.rules
|
||||||
|
60-persistent-alsa.rules
|
||||||
|
60-persistent-input.rules
|
||||||
|
diff --git a/src/fuzz/fuzz-fido-id-desc.c b/src/fuzz/fuzz-fido-id-desc.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..cf98dee044
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/fuzz/fuzz-fido-id-desc.c
|
||||||
|
@@ -0,0 +1,23 @@
|
||||||
|
+/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
+
|
||||||
|
+#include <linux/hid.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+#include <stdint.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+
|
||||||
|
+#include "fido_id/fido_id_desc.h"
|
||||||
|
+#include "fuzz.h"
|
||||||
|
+#include "log.h"
|
||||||
|
+
|
||||||
|
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
|
+ /* We don't want to fill the logs with messages about parse errors.
|
||||||
|
+ * Disable most logging if not running standalone */
|
||||||
|
+ if (!getenv("SYSTEMD_LOG_LEVEL"))
|
||||||
|
+ log_set_max_level(LOG_CRIT);
|
||||||
|
+
|
||||||
|
+ if (size > HID_MAX_DESCRIPTOR_SIZE)
|
||||||
|
+ return 0;
|
||||||
|
+ (void) is_fido_security_token_desc(data, size);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/src/fuzz/fuzz-fido-id-desc.dict b/src/fuzz/fuzz-fido-id-desc.dict
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..d2d2679e18
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/fuzz/fuzz-fido-id-desc.dict
|
||||||
|
@@ -0,0 +1,6 @@
|
||||||
|
+"\xfe"
|
||||||
|
+"\x00"
|
||||||
|
+"\x01"
|
||||||
|
+"\xf1"
|
||||||
|
+"\xd0"
|
||||||
|
+"\xf1\xd0\x00\x01"
|
||||||
|
diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build
|
||||||
|
index 1dbe28e57e..483a952421 100644
|
||||||
|
--- a/src/fuzz/meson.build
|
||||||
|
+++ b/src/fuzz/meson.build
|
||||||
|
@@ -47,4 +47,8 @@ fuzzers += [
|
||||||
|
[libsystemd_journal_remote,
|
||||||
|
libshared],
|
||||||
|
[]],
|
||||||
|
+ [['src/fuzz/fuzz-fido-id-desc.c',
|
||||||
|
+ 'src/udev/fido_id/fido_id_desc.c'],
|
||||||
|
+ [],
|
||||||
|
+ []]
|
||||||
|
]
|
||||||
|
diff --git a/src/test/meson.build b/src/test/meson.build
|
||||||
|
index 0998f59897..4259421f98 100644
|
||||||
|
--- a/src/test/meson.build
|
||||||
|
+++ b/src/test/meson.build
|
||||||
|
@@ -663,6 +663,10 @@ tests += [
|
||||||
|
[['src/test/test-bus-util.c'],
|
||||||
|
[],
|
||||||
|
[]],
|
||||||
|
+ [['src/test/test-fido-id-desc.c',
|
||||||
|
+ 'src/udev/fido_id/fido_id_desc.c'],
|
||||||
|
+ [],
|
||||||
|
+ []],
|
||||||
|
]
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
diff --git a/src/test/test-fido-id-desc.c b/src/test/test-fido-id-desc.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..cf55dd3266
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/test/test-fido-id-desc.c
|
||||||
|
@@ -0,0 +1,85 @@
|
||||||
|
+/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
+
|
||||||
|
+#include <stdint.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+
|
||||||
|
+#include "fido_id/fido_id_desc.h"
|
||||||
|
+#include "macro.h"
|
||||||
|
+
|
||||||
|
+static void test_is_fido_security_token_desc__fido(void) {
|
||||||
|
+ static const uint8_t FIDO_HID_DESC_1[] = {
|
||||||
|
+ 0x06, 0xd0, 0xf1, 0x09, 0x01, 0xa1, 0x01, 0x09, 0x20, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75,
|
||||||
|
+ 0x08, 0x95, 0x40, 0x81, 0x02, 0x09, 0x21, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95,
|
||||||
|
+ 0x40, 0x91, 0x02, 0xc0,
|
||||||
|
+ };
|
||||||
|
+ assert_se(is_fido_security_token_desc(FIDO_HID_DESC_1, sizeof(FIDO_HID_DESC_1)) > 0);
|
||||||
|
+
|
||||||
|
+ static const uint8_t FIDO_HID_DESC_2[] = {
|
||||||
|
+ 0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x05, 0x07, 0x19, 0xe0, 0x29, 0xe7, 0x15, 0x00, 0x25,
|
||||||
|
+ 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, 0x95, 0x01, 0x75, 0x08, 0x81, 0x01, 0x95, 0x05,
|
||||||
|
+ 0x75, 0x01, 0x05, 0x08, 0x19, 0x01, 0x29, 0x05, 0x91, 0x02, 0x95, 0x01, 0x75, 0x03, 0x91,
|
||||||
|
+ 0x01, 0x95, 0x06, 0x75, 0x08, 0x15, 0x00, 0x25, 0x65, 0x05, 0x07, 0x19, 0x00, 0x29, 0x65,
|
||||||
|
+ 0x81, 0x00, 0x09, 0x03, 0x75, 0x08, 0x95, 0x08, 0xb1, 0x02, 0xc0,
|
||||||
|
+ 0x06, 0xd0, 0xf1, 0x09, 0x01, 0xa1, 0x01, 0x09, 0x20, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75,
|
||||||
|
+ 0x08, 0x95, 0x40, 0x81, 0x02, 0x09, 0x21, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95,
|
||||||
|
+ 0x40, 0x91, 0x02, 0xc0,
|
||||||
|
+ };
|
||||||
|
+ assert_se(is_fido_security_token_desc(FIDO_HID_DESC_2, sizeof(FIDO_HID_DESC_2)) > 0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void test_is_fido_security_token_desc__non_fido(void) {
|
||||||
|
+ /* Wrong usage page */
|
||||||
|
+ static const uint8_t NON_FIDO_HID_DESC_1[] = {
|
||||||
|
+ 0x06, 0xd0, 0xf0, 0x09, 0x01, 0xa1, 0x01, 0x09, 0x20, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75,
|
||||||
|
+ 0x08, 0x95, 0x40, 0x81, 0x02, 0x09, 0x21, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95,
|
||||||
|
+ 0x40, 0x91, 0x02, 0xc0,
|
||||||
|
+ };
|
||||||
|
+ assert_se(is_fido_security_token_desc(NON_FIDO_HID_DESC_1, sizeof(NON_FIDO_HID_DESC_1)) == 0);
|
||||||
|
+
|
||||||
|
+ /* Wrong usage */
|
||||||
|
+ static const uint8_t NON_FIDO_HID_DESC_2[] = {
|
||||||
|
+ 0x06, 0xd0, 0xf1, 0x09, 0x02, 0xa1, 0x01, 0x09, 0x20, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75,
|
||||||
|
+ 0x08, 0x95, 0x40, 0x81, 0x02, 0x09, 0x21, 0x15, 0x00, 0x26, 0xff, 0x00, 0x75, 0x08, 0x95,
|
||||||
|
+ 0x40, 0x91, 0x02, 0xc0,
|
||||||
|
+ };
|
||||||
|
+ assert_se(is_fido_security_token_desc(NON_FIDO_HID_DESC_2, sizeof(NON_FIDO_HID_DESC_2)) == 0);
|
||||||
|
+
|
||||||
|
+ static const uint8_t NON_FIDO_HID_DESC_3[] = {
|
||||||
|
+ 0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x05, 0x07, 0x19, 0xe0, 0x29, 0xe7, 0x15, 0x00, 0x25,
|
||||||
|
+ 0x01, 0x75, 0x01, 0x95, 0x08, 0x81, 0x02, 0x95, 0x01, 0x75, 0x08, 0x81, 0x01, 0x95, 0x05,
|
||||||
|
+ 0x75, 0x01, 0x05, 0x08, 0x19, 0x01, 0x29, 0x05, 0x91, 0x02, 0x95, 0x01, 0x75, 0x03, 0x91,
|
||||||
|
+ 0x01, 0x95, 0x06, 0x75, 0x08, 0x15, 0x00, 0x25, 0x65, 0x05, 0x07, 0x19, 0x00, 0x29, 0x65,
|
||||||
|
+ 0x81, 0x00, 0x09, 0x03, 0x75, 0x08, 0x95, 0x08, 0xb1, 0x02, 0xc0,
|
||||||
|
+ };
|
||||||
|
+ assert_se(is_fido_security_token_desc(NON_FIDO_HID_DESC_3, sizeof(NON_FIDO_HID_DESC_3)) == 0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void test_is_fido_security_token_desc__invalid(void) {
|
||||||
|
+ /* Size coded on 1 byte, but no byte given */
|
||||||
|
+ static const uint8_t INVALID_HID_DESC_1[] = { 0x01 };
|
||||||
|
+ assert_se(is_fido_security_token_desc(INVALID_HID_DESC_1, sizeof(INVALID_HID_DESC_1)) < 0);
|
||||||
|
+
|
||||||
|
+ /* Size coded on 2 bytes, but only 1 byte given */
|
||||||
|
+ static const uint8_t INVALID_HID_DESC_2[] = { 0x02, 0x01 };
|
||||||
|
+ assert_se(is_fido_security_token_desc(INVALID_HID_DESC_2, sizeof(INVALID_HID_DESC_2)) < 0);
|
||||||
|
+
|
||||||
|
+ /* Size coded on 4 bytes, but only 3 bytes given */
|
||||||
|
+ static const uint8_t INVALID_HID_DESC_3[] = { 0x03, 0x01, 0x02, 0x03 };
|
||||||
|
+ assert_se(is_fido_security_token_desc(INVALID_HID_DESC_3, sizeof(INVALID_HID_DESC_3)) < 0);
|
||||||
|
+
|
||||||
|
+ /* Long item without a size byte */
|
||||||
|
+ static const uint8_t INVALID_HID_DESC_4[] = { 0xfe };
|
||||||
|
+ assert_se(is_fido_security_token_desc(INVALID_HID_DESC_4, sizeof(INVALID_HID_DESC_4)) < 0);
|
||||||
|
+
|
||||||
|
+ /* Usage pages are coded on at most 2 bytes */
|
||||||
|
+ static const uint8_t INVALID_HID_DESC_5[] = { 0x07, 0x01, 0x02, 0x03, 0x04 };
|
||||||
|
+ assert_se(is_fido_security_token_desc(INVALID_HID_DESC_5, sizeof(INVALID_HID_DESC_5)) < 0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int main(int argc, char *argv[]) {
|
||||||
|
+ test_is_fido_security_token_desc__fido();
|
||||||
|
+ test_is_fido_security_token_desc__non_fido();
|
||||||
|
+ test_is_fido_security_token_desc__invalid();
|
||||||
|
+
|
||||||
|
+ return EXIT_SUCCESS;
|
||||||
|
+}
|
||||||
|
diff --git a/src/udev/fido_id/fido_id.c b/src/udev/fido_id/fido_id.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..7e1cc804f2
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/udev/fido_id/fido_id.c
|
||||||
|
@@ -0,0 +1,103 @@
|
||||||
|
+/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
+/*
|
||||||
|
+ * Identifies FIDO CTAP1 ("U2F")/CTAP2 security tokens based on the usage declared in their report
|
||||||
|
+ * descriptor and outputs suitable environment variables.
|
||||||
|
+ *
|
||||||
|
+ * Inspired by Andrew Lutomirski's 'u2f-hidraw-policy.c'
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <fcntl.h>
|
||||||
|
+#include <linux/hid.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <sys/types.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+
|
||||||
|
+#include "sd-device.h"
|
||||||
|
+
|
||||||
|
+#include "device-internal.h"
|
||||||
|
+#include "device-private.h"
|
||||||
|
+#include "device-util.h"
|
||||||
|
+#include "fd-util.h"
|
||||||
|
+#include "fido_id_desc.h"
|
||||||
|
+#include "log.h"
|
||||||
|
+#include "macro.h"
|
||||||
|
+#include "path-util.h"
|
||||||
|
+#include "string-util.h"
|
||||||
|
+#include "udev-util.h"
|
||||||
|
+
|
||||||
|
+static int run(int argc, char **argv) {
|
||||||
|
+ _cleanup_(sd_device_unrefp) struct sd_device *device = NULL;
|
||||||
|
+ _cleanup_free_ char *desc_path = NULL;
|
||||||
|
+ _cleanup_close_ int fd = -1;
|
||||||
|
+
|
||||||
|
+ struct sd_device *hid_device;
|
||||||
|
+ const char *sys_path;
|
||||||
|
+ uint8_t desc[HID_MAX_DESCRIPTOR_SIZE];
|
||||||
|
+ ssize_t desc_len;
|
||||||
|
+
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ log_set_target(LOG_TARGET_AUTO);
|
||||||
|
+ udev_parse_config();
|
||||||
|
+ log_parse_environment();
|
||||||
|
+ log_open();
|
||||||
|
+
|
||||||
|
+ if (argc > 2)
|
||||||
|
+ return log_error_errno(EINVAL, "Usage: %s [SYSFS_PATH]", program_invocation_short_name);
|
||||||
|
+
|
||||||
|
+ if (argc == 1) {
|
||||||
|
+ r = device_new_from_strv(&device, environ);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_error_errno(r, "Failed to get current device from environment: %m");
|
||||||
|
+ } else {
|
||||||
|
+ r = sd_device_new_from_syspath(&device, argv[1]);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_error_errno(r, "Failed to get device from syspath: %m");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ r = sd_device_get_parent(device, &hid_device);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_device_error_errno(device, r, "Failed to get parent HID device: %m");
|
||||||
|
+
|
||||||
|
+ r = sd_device_get_syspath(hid_device, &sys_path);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_device_error_errno(hid_device, r, "Failed to get syspath for HID device: %m");
|
||||||
|
+
|
||||||
|
+ desc_path = path_join(NULL, sys_path, "report_descriptor");
|
||||||
|
+ if (!desc_path)
|
||||||
|
+ return log_oom();
|
||||||
|
+
|
||||||
|
+ fd = open(desc_path, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
|
||||||
|
+ if (fd < 0)
|
||||||
|
+ return log_device_error_errno(hid_device, errno,
|
||||||
|
+ "Failed to open report descriptor at '%s': %m", desc_path);
|
||||||
|
+
|
||||||
|
+ desc_len = read(fd, desc, sizeof(desc));
|
||||||
|
+ if (desc_len < 0)
|
||||||
|
+ return log_device_error_errno(hid_device, errno,
|
||||||
|
+ "Failed to read report descriptor at '%s': %m", desc_path);
|
||||||
|
+ if (desc_len == 0)
|
||||||
|
+ return log_device_debug_errno(hid_device, EINVAL,
|
||||||
|
+ "Empty report descriptor at '%s'.", desc_path);
|
||||||
|
+
|
||||||
|
+ r = is_fido_security_token_desc(desc, desc_len);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_device_debug_errno(hid_device, r,
|
||||||
|
+ "Failed to parse report descriptor at '%s'.", desc_path);
|
||||||
|
+ if (r > 0) {
|
||||||
|
+ printf("ID_FIDO_TOKEN=1\n");
|
||||||
|
+ printf("ID_SECURITY_TOKEN=1\n");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int main(int argc, char *argv[]) {
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ r = run(argc, argv);
|
||||||
|
+
|
||||||
|
+ return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||||
|
+}
|
||||||
|
diff --git a/src/udev/fido_id/fido_id_desc.c b/src/udev/fido_id/fido_id_desc.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..bbfcf93709
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/udev/fido_id/fido_id_desc.c
|
||||||
|
@@ -0,0 +1,92 @@
|
||||||
|
+/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
+/* Inspired by Andrew Lutomirski's 'u2f-hidraw-policy.c' */
|
||||||
|
+
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+#include <stddef.h>
|
||||||
|
+#include <stdint.h>
|
||||||
|
+
|
||||||
|
+#include "fido_id_desc.h"
|
||||||
|
+
|
||||||
|
+#define HID_RPTDESC_FIRST_BYTE_LONG_ITEM 0xfeu
|
||||||
|
+#define HID_RPTDESC_TYPE_GLOBAL 0x1u
|
||||||
|
+#define HID_RPTDESC_TYPE_LOCAL 0x2u
|
||||||
|
+#define HID_RPTDESC_TAG_USAGE_PAGE 0x0u
|
||||||
|
+#define HID_RPTDESC_TAG_USAGE 0x0u
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * HID usage for FIDO CTAP1 ("U2F") and CTAP2 security tokens.
|
||||||
|
+ * https://fidoalliance.org/specs/fido-u2f-v1.0-ps-20141009/fido-u2f-u2f_hid.h-v1.0-ps-20141009.txt
|
||||||
|
+ * https://fidoalliance.org/specs/fido-v2.0-ps-20190130/fido-client-to-authenticator-protocol-v2.0-ps-20190130.html#usb-discovery
|
||||||
|
+ * https://www.usb.org/sites/default/files/hutrr48.pdf
|
||||||
|
+ */
|
||||||
|
+#define FIDO_FULL_USAGE_CTAPHID 0xf1d00001u
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Parses a HID report descriptor and identifies FIDO CTAP1 ("U2F")/CTAP2 security tokens based on their
|
||||||
|
+ * declared usage.
|
||||||
|
+ * A positive return value indicates that the report descriptor belongs to a FIDO security token.
|
||||||
|
+ * https://www.usb.org/sites/default/files/documents/hid1_11.pdf (Section 6.2.2)
|
||||||
|
+ */
|
||||||
|
+int is_fido_security_token_desc(const uint8_t *desc, size_t desc_len) {
|
||||||
|
+ uint32_t usage = 0;
|
||||||
|
+
|
||||||
|
+ for (size_t pos = 0; pos < desc_len; ) {
|
||||||
|
+ uint8_t tag, type, size_code;
|
||||||
|
+ size_t size;
|
||||||
|
+ uint32_t value;
|
||||||
|
+
|
||||||
|
+ /* Report descriptors consists of short items (1-5 bytes) and long items (3-258 bytes). */
|
||||||
|
+ if (desc[pos] == HID_RPTDESC_FIRST_BYTE_LONG_ITEM) {
|
||||||
|
+ /* No long items are defined in the spec; skip them.
|
||||||
|
+ * The length of the data in a long item is contained in the byte after the long
|
||||||
|
+ * item tag. The header consists of three bytes: special long item tag, length,
|
||||||
|
+ * actual tag. */
|
||||||
|
+ if (pos + 1 >= desc_len)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ pos += desc[pos + 1] + 3;
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* The first byte of a short item encodes tag, type and size. */
|
||||||
|
+ tag = desc[pos] >> 4; /* Bits 7 to 4 */
|
||||||
|
+ type = (desc[pos] >> 2) & 0x3; /* Bits 3 and 2 */
|
||||||
|
+ size_code = desc[pos] & 0x3; /* Bits 1 and 0 */
|
||||||
|
+ /* Size is coded as follows:
|
||||||
|
+ * 0 -> 0 bytes, 1 -> 1 byte, 2 -> 2 bytes, 3 -> 4 bytes
|
||||||
|
+ */
|
||||||
|
+ size = size_code < 3 ? size_code : 4;
|
||||||
|
+ /* Consume header byte. */
|
||||||
|
+ pos++;
|
||||||
|
+
|
||||||
|
+ /* Extract the item value coded on size bytes. */
|
||||||
|
+ if (pos + size > desc_len)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ value = 0;
|
||||||
|
+ for (size_t i = 0; i < size; i++)
|
||||||
|
+ value |= (uint32_t) desc[pos + i] << (8 * i);
|
||||||
|
+ /* Consume value bytes. */
|
||||||
|
+ pos += size;
|
||||||
|
+
|
||||||
|
+ if (type == HID_RPTDESC_TYPE_GLOBAL && tag == HID_RPTDESC_TAG_USAGE_PAGE) {
|
||||||
|
+ /* A usage page is a 16 bit value coded on at most 16 bits. */
|
||||||
|
+ if (size > 2)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ /* A usage page sets the upper 16 bits of a following usage. */
|
||||||
|
+ usage = (value & 0x0000ffffu) << 16;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (type == HID_RPTDESC_TYPE_LOCAL && tag == HID_RPTDESC_TAG_USAGE) {
|
||||||
|
+ /* A usage is a 32 bit value, but is prepended with the current usage page if
|
||||||
|
+ * coded on less than 4 bytes (that is, at most 2 bytes). */
|
||||||
|
+ if (size == 4)
|
||||||
|
+ usage = value;
|
||||||
|
+ else
|
||||||
|
+ usage = (usage & 0xffff0000u) | (value & 0x0000ffffu);
|
||||||
|
+ if (usage == FIDO_FULL_USAGE_CTAPHID)
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/src/udev/fido_id/fido_id_desc.h b/src/udev/fido_id/fido_id_desc.h
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..c813a3a454
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/udev/fido_id/fido_id_desc.h
|
||||||
|
@@ -0,0 +1,8 @@
|
||||||
|
+/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
+
|
||||||
|
+#pragma once
|
||||||
|
+
|
||||||
|
+#include <stddef.h>
|
||||||
|
+#include <stdint.h>
|
||||||
|
+
|
||||||
|
+int is_fido_security_token_desc(const uint8_t *desc, size_t desc_len);
|
||||||
|
diff --git a/src/udev/meson.build b/src/udev/meson.build
|
||||||
|
index 3bcd2bd3d7..5931a6da7d 100644
|
||||||
|
--- a/src/udev/meson.build
|
||||||
|
+++ b/src/udev/meson.build
|
||||||
|
@@ -160,6 +160,9 @@ libudev_core = static_library(
|
||||||
|
foreach prog : [['ata_id/ata_id.c'],
|
||||||
|
['cdrom_id/cdrom_id.c'],
|
||||||
|
['collect/collect.c'],
|
||||||
|
+ ['fido_id/fido_id.c',
|
||||||
|
+ 'fido_id/fido_id_desc.c',
|
||||||
|
+ 'fido_id/fido_id_desc.h'],
|
||||||
|
['scsi_id/scsi_id.c',
|
||||||
|
'scsi_id/scsi_id.h',
|
||||||
|
'scsi_id/scsi_serial.c',
|
||||||
|
diff --git a/test/fuzz/fuzz-fido-id-desc/crash0 b/test/fuzz/fuzz-fido-id-desc/crash0
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..e066656502
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/fuzz/fuzz-fido-id-desc/crash0
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+Ì
|
||||||
|
\ No newline at end of file
|
||||||
|
diff --git a/test/fuzz/fuzz-fido-id-desc/crash1 b/test/fuzz/fuzz-fido-id-desc/crash1
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..aef3e18335
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/fuzz/fuzz-fido-id-desc/crash1
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+øûøûûÜ
|
||||||
|
\ No newline at end of file
|
||||||
|
diff --git a/test/fuzz/fuzz-fido-id-desc/report0 b/test/fuzz/fuzz-fido-id-desc/report0
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..48757cba682ffddd5a1ddd8988bb8bcdc7db0a7a
|
||||||
|
GIT binary patch
|
||||||
|
literal 71
|
||||||
|
zcmZQ&<YZgO$jUDHK=ZjMgDPVw<5Z4Drm2jj9F2@qSxXsNIV2f1Sto)-m?tt$Wh><X
|
||||||
|
Xs!9c_XV6S-WZ+~j<(SH`k?8;c6l@Pq
|
||||||
|
|
||||||
|
literal 0
|
||||||
|
HcmV?d00001
|
||||||
|
|
||||||
|
diff --git a/test/fuzz/fuzz-fido-id-desc/report1 b/test/fuzz/fuzz-fido-id-desc/report1
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..b70b7fb871aeccf4074ccbd20e3cdbaca42e23b3
|
||||||
|
GIT binary patch
|
||||||
|
literal 34
|
||||||
|
icmZR(@R5^oAtR@PD1+L6hEk5H4vkElig3<ErUL+_0SUDL
|
||||||
|
|
||||||
|
literal 0
|
||||||
|
HcmV?d00001
|
||||||
|
|
@ -0,0 +1,33 @@
|
|||||||
|
From c3be943b30689f77ded9f431fdafb666769aea89 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Tue, 27 Aug 2019 19:00:34 +0200
|
||||||
|
Subject: [PATCH] shared/but-util: drop trusted annotation from
|
||||||
|
bus_open_system_watch_bind_with_description()
|
||||||
|
|
||||||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1746057
|
||||||
|
|
||||||
|
This only affects systemd-resolved. bus_open_system_watch_bind_with_description()
|
||||||
|
is also used in timesyncd, but it has no methods, only read-only properties, and
|
||||||
|
in networkd, but it annotates all methods with SD_BUS_VTABLE_UNPRIVILEGED and does
|
||||||
|
polkit checks.
|
||||||
|
|
||||||
|
Resolves: #1746857
|
||||||
|
---
|
||||||
|
src/shared/bus-util.c | 4 ----
|
||||||
|
1 file changed, 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
|
||||||
|
index a4f2deba31..302dbb4c2e 100644
|
||||||
|
--- a/src/shared/bus-util.c
|
||||||
|
+++ b/src/shared/bus-util.c
|
||||||
|
@@ -1699,10 +1699,6 @@ int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *descri
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
- r = sd_bus_set_trusted(bus, true);
|
||||||
|
- if (r < 0)
|
||||||
|
- return r;
|
||||||
|
-
|
||||||
|
r = sd_bus_negotiate_creds(bus, true, SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_EFFECTIVE_CAPS);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
50
SOURCES/0245-sd-bus-adjust-indentation-of-comments.patch
Normal file
50
SOURCES/0245-sd-bus-adjust-indentation-of-comments.patch
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
From 7e0f9a0cd4053fcc713a99ada3d0d50793b83564 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Tue, 27 Aug 2019 19:00:50 +0200
|
||||||
|
Subject: [PATCH] sd-bus: adjust indentation of comments
|
||||||
|
|
||||||
|
Related: #1746857
|
||||||
|
---
|
||||||
|
src/libsystemd/sd-bus/sd-bus.c | 3 +--
|
||||||
|
src/shared/bus-util.c | 7 ++++---
|
||||||
|
2 files changed, 5 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c
|
||||||
|
index 3583e24e64..1c9e967ae0 100644
|
||||||
|
--- a/src/libsystemd/sd-bus/sd-bus.c
|
||||||
|
+++ b/src/libsystemd/sd-bus/sd-bus.c
|
||||||
|
@@ -1341,8 +1341,7 @@ _public_ int sd_bus_open_user_with_description(sd_bus **ret, const char *descrip
|
||||||
|
b->bus_client = true;
|
||||||
|
b->is_user = true;
|
||||||
|
|
||||||
|
- /* We don't do any per-method access control on the user
|
||||||
|
- * bus. */
|
||||||
|
+ /* We don't do any per-method access control on the user bus. */
|
||||||
|
b->trusted = true;
|
||||||
|
b->is_local = true;
|
||||||
|
|
||||||
|
diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c
|
||||||
|
index 302dbb4c2e..2d908eb45c 100644
|
||||||
|
--- a/src/shared/bus-util.c
|
||||||
|
+++ b/src/shared/bus-util.c
|
||||||
|
@@ -1675,7 +1675,8 @@ int bus_open_system_watch_bind_with_description(sd_bus **ret, const char *descri
|
||||||
|
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
- /* Match like sd_bus_open_system(), but with the "watch_bind" feature and the Connected() signal turned on. */
|
||||||
|
+ /* Match like sd_bus_open_system(), but with the "watch_bind" feature and the Connected() signal
|
||||||
|
+ * turned on. */
|
||||||
|
|
||||||
|
r = sd_bus_new(&bus);
|
||||||
|
if (r < 0)
|
||||||
|
@@ -1890,8 +1891,8 @@ int bus_reply_pair_array(sd_bus_message *m, char **l) {
|
||||||
|
|
||||||
|
assert(m);
|
||||||
|
|
||||||
|
- /* Reply to the specified message with a message containing a dictionary put together from the specified
|
||||||
|
- * strv */
|
||||||
|
+ /* Reply to the specified message with a message containing a dictionary put together from the
|
||||||
|
+ * specified strv */
|
||||||
|
|
||||||
|
r = sd_bus_message_new_method_return(m, &reply);
|
||||||
|
if (r < 0)
|
46
SOURCES/0246-resolved-do-not-run-loop-twice.patch
Normal file
46
SOURCES/0246-resolved-do-not-run-loop-twice.patch
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
From d95afbca80cf52f0bc84b2e1b4af6aadda007138 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Tue, 27 Aug 2019 19:02:53 +0200
|
||||||
|
Subject: [PATCH] resolved: do not run loop twice
|
||||||
|
|
||||||
|
This doesn't matter much, but let's just do the loop once and allocate
|
||||||
|
the populate the result set on the fly. If we find an error, it'll get
|
||||||
|
cleaned up automatically.
|
||||||
|
|
||||||
|
Related: #1746857
|
||||||
|
---
|
||||||
|
src/resolve/resolved-link-bus.c | 13 ++++++-------
|
||||||
|
1 file changed, 6 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/resolve/resolved-link-bus.c b/src/resolve/resolved-link-bus.c
|
||||||
|
index b1581740d8..46d2b11636 100644
|
||||||
|
--- a/src/resolve/resolved-link-bus.c
|
||||||
|
+++ b/src/resolve/resolved-link-bus.c
|
||||||
|
@@ -492,6 +492,10 @@ int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, v
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
+ ns = set_new(&dns_name_hash_ops);
|
||||||
|
+ if (!ns)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
r = sd_bus_message_read_strv(message, &ntas);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
@@ -501,14 +505,9 @@ int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, v
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
if (r == 0)
|
||||||
|
- return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid negative trust anchor domain: %s", *i);
|
||||||
|
- }
|
||||||
|
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS,
|
||||||
|
+ "Invalid negative trust anchor domain: %s", *i);
|
||||||
|
|
||||||
|
- ns = set_new(&dns_name_hash_ops);
|
||||||
|
- if (!ns)
|
||||||
|
- return -ENOMEM;
|
||||||
|
-
|
||||||
|
- STRV_FOREACH(i, ntas) {
|
||||||
|
r = set_put_strdup(ns, *i);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
@ -0,0 +1,347 @@
|
|||||||
|
From ddd08e75b1e7fa1f6dfef3d30a0c1ef8c63e4d07 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Tue, 27 Aug 2019 19:25:05 +0200
|
||||||
|
Subject: [PATCH] resolved: allow access to Set*Link and Revert methods through
|
||||||
|
polkit
|
||||||
|
|
||||||
|
This matches what is done in networkd very closely. In fact even the
|
||||||
|
policy descriptions are all identical (with s/network/resolve), except
|
||||||
|
for the last one:
|
||||||
|
resolved has org.freedesktop.resolve1.revert while
|
||||||
|
networkd has org.freedesktop.network1.revert-ntp and
|
||||||
|
org.freedesktop.network1.revert-dns so the description is a bit different.
|
||||||
|
|
||||||
|
Conflicts:
|
||||||
|
src/resolve/resolved-bus.c
|
||||||
|
src/resolve/resolved-link-bus.c
|
||||||
|
|
||||||
|
Related: #1746857
|
||||||
|
---
|
||||||
|
src/resolve/org.freedesktop.resolve1.policy | 99 +++++++++++++++++++++
|
||||||
|
src/resolve/resolved-bus.c | 22 ++---
|
||||||
|
src/resolve/resolved-link-bus.c | 97 +++++++++++++++++---
|
||||||
|
3 files changed, 197 insertions(+), 21 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/resolve/org.freedesktop.resolve1.policy b/src/resolve/org.freedesktop.resolve1.policy
|
||||||
|
index b65ba3e56a..592c4eb8b0 100644
|
||||||
|
--- a/src/resolve/org.freedesktop.resolve1.policy
|
||||||
|
+++ b/src/resolve/org.freedesktop.resolve1.policy
|
||||||
|
@@ -40,4 +40,103 @@
|
||||||
|
<annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
|
||||||
|
</action>
|
||||||
|
|
||||||
|
+ <action id="org.freedesktop.resolve1.set-dns-servers">
|
||||||
|
+ <description gettext-domain="systemd">Set DNS servers</description>
|
||||||
|
+ <message gettext-domain="systemd">Authentication is required to set DNS servers.</message>
|
||||||
|
+ <defaults>
|
||||||
|
+ <allow_any>auth_admin</allow_any>
|
||||||
|
+ <allow_inactive>auth_admin</allow_inactive>
|
||||||
|
+ <allow_active>auth_admin_keep</allow_active>
|
||||||
|
+ </defaults>
|
||||||
|
+ <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
|
||||||
|
+ </action>
|
||||||
|
+
|
||||||
|
+ <action id="org.freedesktop.resolve1.set-domains">
|
||||||
|
+ <description gettext-domain="systemd">Set domains</description>
|
||||||
|
+ <message gettext-domain="systemd">Authentication is required to set domains.</message>
|
||||||
|
+ <defaults>
|
||||||
|
+ <allow_any>auth_admin</allow_any>
|
||||||
|
+ <allow_inactive>auth_admin</allow_inactive>
|
||||||
|
+ <allow_active>auth_admin_keep</allow_active>
|
||||||
|
+ </defaults>
|
||||||
|
+ <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
|
||||||
|
+ </action>
|
||||||
|
+
|
||||||
|
+ <action id="org.freedesktop.resolve1.set-default-route">
|
||||||
|
+ <description gettext-domain="systemd">Set default route</description>
|
||||||
|
+ <message gettext-domain="systemd">Authentication is required to set default route.</message>
|
||||||
|
+ <defaults>
|
||||||
|
+ <allow_any>auth_admin</allow_any>
|
||||||
|
+ <allow_inactive>auth_admin</allow_inactive>
|
||||||
|
+ <allow_active>auth_admin_keep</allow_active>
|
||||||
|
+ </defaults>
|
||||||
|
+ <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
|
||||||
|
+ </action>
|
||||||
|
+
|
||||||
|
+ <action id="org.freedesktop.resolve1.set-llmnr">
|
||||||
|
+ <description gettext-domain="systemd">Enable/disable LLMNR</description>
|
||||||
|
+ <message gettext-domain="systemd">Authentication is required to enable or disable LLMNR.</message>
|
||||||
|
+ <defaults>
|
||||||
|
+ <allow_any>auth_admin</allow_any>
|
||||||
|
+ <allow_inactive>auth_admin</allow_inactive>
|
||||||
|
+ <allow_active>auth_admin_keep</allow_active>
|
||||||
|
+ </defaults>
|
||||||
|
+ <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
|
||||||
|
+ </action>
|
||||||
|
+
|
||||||
|
+ <action id="org.freedesktop.resolve1.set-mdns">
|
||||||
|
+ <description gettext-domain="systemd">Enable/disable multicast DNS</description>
|
||||||
|
+ <message gettext-domain="systemd">Authentication is required to enable or disable multicast DNS.</message>
|
||||||
|
+ <defaults>
|
||||||
|
+ <allow_any>auth_admin</allow_any>
|
||||||
|
+ <allow_inactive>auth_admin</allow_inactive>
|
||||||
|
+ <allow_active>auth_admin_keep</allow_active>
|
||||||
|
+ </defaults>
|
||||||
|
+ <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
|
||||||
|
+ </action>
|
||||||
|
+
|
||||||
|
+ <action id="org.freedesktop.resolve1.set-dns-over-tls">
|
||||||
|
+ <description gettext-domain="systemd">Enable/disable DNS over TLS</description>
|
||||||
|
+ <message gettext-domain="systemd">Authentication is required to enable or disable DNS over TLS.</message>
|
||||||
|
+ <defaults>
|
||||||
|
+ <allow_any>auth_admin</allow_any>
|
||||||
|
+ <allow_inactive>auth_admin</allow_inactive>
|
||||||
|
+ <allow_active>auth_admin_keep</allow_active>
|
||||||
|
+ </defaults>
|
||||||
|
+ <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
|
||||||
|
+ </action>
|
||||||
|
+
|
||||||
|
+ <action id="org.freedesktop.resolve1.set-dnssec">
|
||||||
|
+ <description gettext-domain="systemd">Enable/disable DNSSEC</description>
|
||||||
|
+ <message gettext-domain="systemd">Authentication is required to enable or disable DNSSEC.</message>
|
||||||
|
+ <defaults>
|
||||||
|
+ <allow_any>auth_admin</allow_any>
|
||||||
|
+ <allow_inactive>auth_admin</allow_inactive>
|
||||||
|
+ <allow_active>auth_admin_keep</allow_active>
|
||||||
|
+ </defaults>
|
||||||
|
+ <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
|
||||||
|
+ </action>
|
||||||
|
+
|
||||||
|
+ <action id="org.freedesktop.resolve1.set-dnssec-negative-trust-anchors">
|
||||||
|
+ <description gettext-domain="systemd">Set DNSSEC Negative Trust Anchors</description>
|
||||||
|
+ <message gettext-domain="systemd">Authentication is required to set DNSSEC Negative Trust Anchros.</message>
|
||||||
|
+ <defaults>
|
||||||
|
+ <allow_any>auth_admin</allow_any>
|
||||||
|
+ <allow_inactive>auth_admin</allow_inactive>
|
||||||
|
+ <allow_active>auth_admin_keep</allow_active>
|
||||||
|
+ </defaults>
|
||||||
|
+ <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
|
||||||
|
+ </action>
|
||||||
|
+
|
||||||
|
+ <action id="org.freedesktop.resolve1.revert">
|
||||||
|
+ <description gettext-domain="systemd">Revert name resolution settings</description>
|
||||||
|
+ <message gettext-domain="systemd">Authentication is required to revert name resolution settings.</message>
|
||||||
|
+ <defaults>
|
||||||
|
+ <allow_any>auth_admin</allow_any>
|
||||||
|
+ <allow_inactive>auth_admin</allow_inactive>
|
||||||
|
+ <allow_active>auth_admin_keep</allow_active>
|
||||||
|
+ </defaults>
|
||||||
|
+ <annotate key="org.freedesktop.policykit.owner">unix-user:systemd-resolve</annotate>
|
||||||
|
+ </action>
|
||||||
|
+
|
||||||
|
</policyconfig>
|
||||||
|
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
|
||||||
|
index da0a909dd6..4d6cc4fd48 100644
|
||||||
|
--- a/src/resolve/resolved-bus.c
|
||||||
|
+++ b/src/resolve/resolved-bus.c
|
||||||
|
@@ -1848,18 +1848,18 @@ static const sd_bus_vtable resolve_vtable[] = {
|
||||||
|
SD_BUS_METHOD("ResolveAddress", "iiayt", "a(is)t", bus_method_resolve_address, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
SD_BUS_METHOD("ResolveRecord", "isqqt", "a(iqqay)t", bus_method_resolve_record, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
SD_BUS_METHOD("ResolveService", "isssit", "a(qqqsa(iiay)s)aayssst", bus_method_resolve_service, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
- SD_BUS_METHOD("ResetStatistics", NULL, NULL, bus_method_reset_statistics, 0),
|
||||||
|
- SD_BUS_METHOD("FlushCaches", NULL, NULL, bus_method_flush_caches, 0),
|
||||||
|
- SD_BUS_METHOD("ResetServerFeatures", NULL, NULL, bus_method_reset_server_features, 0),
|
||||||
|
+ SD_BUS_METHOD("ResetStatistics", NULL, NULL, bus_method_reset_statistics, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
+ SD_BUS_METHOD("FlushCaches", NULL, NULL, bus_method_flush_caches, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
+ SD_BUS_METHOD("ResetServerFeatures", NULL, NULL, bus_method_reset_server_features, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
SD_BUS_METHOD("GetLink", "i", "o", bus_method_get_link, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
- SD_BUS_METHOD("SetLinkDNS", "ia(iay)", NULL, bus_method_set_link_dns_servers, 0),
|
||||||
|
- SD_BUS_METHOD("SetLinkDomains", "ia(sb)", NULL, bus_method_set_link_domains, 0),
|
||||||
|
- SD_BUS_METHOD("SetLinkLLMNR", "is", NULL, bus_method_set_link_llmnr, 0),
|
||||||
|
- SD_BUS_METHOD("SetLinkMulticastDNS", "is", NULL, bus_method_set_link_mdns, 0),
|
||||||
|
- SD_BUS_METHOD("SetLinkDNSOverTLS", "is", NULL, bus_method_set_link_dns_over_tls, 0),
|
||||||
|
- SD_BUS_METHOD("SetLinkDNSSEC", "is", NULL, bus_method_set_link_dnssec, 0),
|
||||||
|
- SD_BUS_METHOD("SetLinkDNSSECNegativeTrustAnchors", "ias", NULL, bus_method_set_link_dnssec_negative_trust_anchors, 0),
|
||||||
|
- SD_BUS_METHOD("RevertLink", "i", NULL, bus_method_revert_link, 0),
|
||||||
|
+ SD_BUS_METHOD("SetLinkDNS", "ia(iay)", NULL, bus_method_set_link_dns_servers, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
+ SD_BUS_METHOD("SetLinkDomains", "ia(sb)", NULL, bus_method_set_link_domains, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
+ SD_BUS_METHOD("SetLinkLLMNR", "is", NULL, bus_method_set_link_llmnr, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
+ SD_BUS_METHOD("SetLinkMulticastDNS", "is", NULL, bus_method_set_link_mdns, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
+ SD_BUS_METHOD("SetLinkDNSOverTLS", "is", NULL, bus_method_set_link_dns_over_tls, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
+ SD_BUS_METHOD("SetLinkDNSSEC", "is", NULL, bus_method_set_link_dnssec, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
+ SD_BUS_METHOD("SetLinkDNSSECNegativeTrustAnchors", "ias", NULL, bus_method_set_link_dnssec_negative_trust_anchors, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
+ SD_BUS_METHOD("RevertLink", "i", NULL, bus_method_revert_link, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
|
||||||
|
SD_BUS_METHOD("RegisterService", "sssqqqaa{say}", "o", bus_method_register_service, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
SD_BUS_METHOD("UnregisterService", "o", NULL, bus_method_unregister_service, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
diff --git a/src/resolve/resolved-link-bus.c b/src/resolve/resolved-link-bus.c
|
||||||
|
index 46d2b11636..bf3e42264e 100644
|
||||||
|
--- a/src/resolve/resolved-link-bus.c
|
||||||
|
+++ b/src/resolve/resolved-link-bus.c
|
||||||
|
@@ -1,5 +1,9 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
|
||||||
|
+#include <net/if.h>
|
||||||
|
+#include <netinet/in.h>
|
||||||
|
+#include <sys/capability.h>
|
||||||
|
+
|
||||||
|
#include "alloc-util.h"
|
||||||
|
#include "bus-common-errors.h"
|
||||||
|
#include "bus-util.h"
|
||||||
|
@@ -9,6 +13,7 @@
|
||||||
|
#include "resolved-link-bus.h"
|
||||||
|
#include "resolved-resolv-conf.h"
|
||||||
|
#include "strv.h"
|
||||||
|
+#include "user-util.h"
|
||||||
|
|
||||||
|
static BUS_DEFINE_PROPERTY_GET(property_get_dnssec_supported, "b", Link, link_dnssec_supported);
|
||||||
|
static BUS_DEFINE_PROPERTY_GET2(property_get_dnssec_mode, "s", Link, link_get_dnssec_mode, dnssec_mode_to_string);
|
||||||
|
@@ -235,6 +240,15 @@ int bus_link_method_set_dns_servers(sd_bus_message *message, void *userdata, sd_
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
+ r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
|
||||||
|
+ "org.freedesktop.resolve1.set-dns-servers",
|
||||||
|
+ NULL, true, UID_INVALID,
|
||||||
|
+ &l->manager->polkit_registry, error);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+ if (r == 0)
|
||||||
|
+ return 1; /* Polkit will call us back */
|
||||||
|
+
|
||||||
|
dns_server_mark_all(l->dns_servers);
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
@@ -298,12 +312,21 @@ int bus_link_method_set_domains(sd_bus_message *message, void *userdata, sd_bus_
|
||||||
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Root domain is not suitable as search domain");
|
||||||
|
}
|
||||||
|
|
||||||
|
- dns_search_domain_mark_all(l->search_domains);
|
||||||
|
-
|
||||||
|
r = sd_bus_message_rewind(message, false);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
+ r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
|
||||||
|
+ "org.freedesktop.resolve1.set-domains",
|
||||||
|
+ NULL, true, UID_INVALID,
|
||||||
|
+ &l->manager->polkit_registry, error);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+ if (r == 0)
|
||||||
|
+ return 1; /* Polkit will call us back */
|
||||||
|
+
|
||||||
|
+ dns_search_domain_mark_all(l->search_domains);
|
||||||
|
+
|
||||||
|
for (;;) {
|
||||||
|
DnsSearchDomain *d;
|
||||||
|
const char *name;
|
||||||
|
@@ -371,6 +394,15 @@ int bus_link_method_set_llmnr(sd_bus_message *message, void *userdata, sd_bus_er
|
||||||
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid LLMNR setting: %s", llmnr);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
|
||||||
|
+ "org.freedesktop.resolve1.set-llmnr",
|
||||||
|
+ NULL, true, UID_INVALID,
|
||||||
|
+ &l->manager->polkit_registry, error);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+ if (r == 0)
|
||||||
|
+ return 1; /* Polkit will call us back */
|
||||||
|
+
|
||||||
|
l->llmnr_support = mode;
|
||||||
|
link_allocate_scopes(l);
|
||||||
|
link_add_rrs(l, false);
|
||||||
|
@@ -405,6 +437,15 @@ int bus_link_method_set_mdns(sd_bus_message *message, void *userdata, sd_bus_err
|
||||||
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid MulticastDNS setting: %s", mdns);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
|
||||||
|
+ "org.freedesktop.resolve1.set-mdns",
|
||||||
|
+ NULL, true, UID_INVALID,
|
||||||
|
+ &l->manager->polkit_registry, error);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+ if (r == 0)
|
||||||
|
+ return 1; /* Polkit will call us back */
|
||||||
|
+
|
||||||
|
l->mdns_support = mode;
|
||||||
|
link_allocate_scopes(l);
|
||||||
|
link_add_rrs(l, false);
|
||||||
|
@@ -439,6 +480,15 @@ int bus_link_method_set_dns_over_tls(sd_bus_message *message, void *userdata, sd
|
||||||
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNSOverTLS setting: %s", dns_over_tls);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
|
||||||
|
+ "org.freedesktop.resolve1.set-dns-over-tls",
|
||||||
|
+ NULL, true, UID_INVALID,
|
||||||
|
+ &l->manager->polkit_registry, error);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+ if (r == 0)
|
||||||
|
+ return 1; /* Polkit will call us back */
|
||||||
|
+
|
||||||
|
link_set_dns_over_tls_mode(l, mode);
|
||||||
|
|
||||||
|
(void) link_save_user(l);
|
||||||
|
@@ -471,6 +521,15 @@ int bus_link_method_set_dnssec(sd_bus_message *message, void *userdata, sd_bus_e
|
||||||
|
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNSSEC setting: %s", dnssec);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
|
||||||
|
+ "org.freedesktop.resolve1.set-dnssec",
|
||||||
|
+ NULL, true, UID_INVALID,
|
||||||
|
+ &l->manager->polkit_registry, error);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+ if (r == 0)
|
||||||
|
+ return 1; /* Polkit will call us back */
|
||||||
|
+
|
||||||
|
link_set_dnssec_mode(l, mode);
|
||||||
|
|
||||||
|
(void) link_save_user(l);
|
||||||
|
@@ -513,6 +572,15 @@ int bus_link_method_set_dnssec_negative_trust_anchors(sd_bus_message *message, v
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
|
||||||
|
+ "org.freedesktop.resolve1.set-dnssec-negative-trust-anchors",
|
||||||
|
+ NULL, true, UID_INVALID,
|
||||||
|
+ &l->manager->polkit_registry, error);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+ if (r == 0)
|
||||||
|
+ return 1; /* Polkit will call us back */
|
||||||
|
+
|
||||||
|
set_free_free(l->dnssec_negative_trust_anchors);
|
||||||
|
l->dnssec_negative_trust_anchors = TAKE_PTR(ns);
|
||||||
|
|
||||||
|
@@ -532,6 +600,15 @@ int bus_link_method_revert(sd_bus_message *message, void *userdata, sd_bus_error
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
+ r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
|
||||||
|
+ "org.freedesktop.resolve1.revert",
|
||||||
|
+ NULL, true, UID_INVALID,
|
||||||
|
+ &l->manager->polkit_registry, error);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+ if (r == 0)
|
||||||
|
+ return 1; /* Polkit will call us back */
|
||||||
|
+
|
||||||
|
link_flush_settings(l);
|
||||||
|
link_allocate_scopes(l);
|
||||||
|
link_add_rrs(l, false);
|
||||||
|
@@ -556,14 +633,14 @@ const sd_bus_vtable link_vtable[] = {
|
||||||
|
SD_BUS_PROPERTY("DNSSECNegativeTrustAnchors", "as", property_get_ntas, 0, 0),
|
||||||
|
SD_BUS_PROPERTY("DNSSECSupported", "b", property_get_dnssec_supported, 0, 0),
|
||||||
|
|
||||||
|
- SD_BUS_METHOD("SetDNS", "a(iay)", NULL, bus_link_method_set_dns_servers, 0),
|
||||||
|
- SD_BUS_METHOD("SetDomains", "a(sb)", NULL, bus_link_method_set_domains, 0),
|
||||||
|
- SD_BUS_METHOD("SetLLMNR", "s", NULL, bus_link_method_set_llmnr, 0),
|
||||||
|
- SD_BUS_METHOD("SetMulticastDNS", "s", NULL, bus_link_method_set_mdns, 0),
|
||||||
|
- SD_BUS_METHOD("SetDNSOverTLS", "s", NULL, bus_link_method_set_dns_over_tls, 0),
|
||||||
|
- SD_BUS_METHOD("SetDNSSEC", "s", NULL, bus_link_method_set_dnssec, 0),
|
||||||
|
- SD_BUS_METHOD("SetDNSSECNegativeTrustAnchors", "as", NULL, bus_link_method_set_dnssec_negative_trust_anchors, 0),
|
||||||
|
- SD_BUS_METHOD("Revert", NULL, NULL, bus_link_method_revert, 0),
|
||||||
|
+ SD_BUS_METHOD("SetDNS", "a(iay)", NULL, bus_link_method_set_dns_servers, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
+ SD_BUS_METHOD("SetDomains", "a(sb)", NULL, bus_link_method_set_domains, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
+ SD_BUS_METHOD("SetLLMNR", "s", NULL, bus_link_method_set_llmnr, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
+ SD_BUS_METHOD("SetMulticastDNS", "s", NULL, bus_link_method_set_mdns, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
+ SD_BUS_METHOD("SetDNSOverTLS", "s", NULL, bus_link_method_set_dns_over_tls, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
+ SD_BUS_METHOD("SetDNSSEC", "s", NULL, bus_link_method_set_dnssec, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
+ SD_BUS_METHOD("SetDNSSECNegativeTrustAnchors", "as", NULL, bus_link_method_set_dnssec_negative_trust_anchors, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
+ SD_BUS_METHOD("Revert", NULL, NULL, bus_link_method_revert, SD_BUS_VTABLE_UNPRIVILEGED),
|
||||||
|
|
||||||
|
SD_BUS_VTABLE_END
|
||||||
|
};
|
@ -0,0 +1,48 @@
|
|||||||
|
From 7b00cae817e54ee3398ad3b42ec69a3b63676562 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Tue, 27 Aug 2019 19:28:19 +0200
|
||||||
|
Subject: [PATCH] resolved: query polkit only after parsing the data
|
||||||
|
|
||||||
|
That's what we do everywhere else because it leads to nicer user experience.
|
||||||
|
|
||||||
|
Related: #1746857
|
||||||
|
---
|
||||||
|
src/resolve/resolved-bus.c | 18 +++++++++---------
|
||||||
|
1 file changed, 9 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/resolve/resolved-bus.c b/src/resolve/resolved-bus.c
|
||||||
|
index 4d6cc4fd48..3f6a6f9e12 100644
|
||||||
|
--- a/src/resolve/resolved-bus.c
|
||||||
|
+++ b/src/resolve/resolved-bus.c
|
||||||
|
@@ -1632,15 +1632,6 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata,
|
||||||
|
if (m->mdns_support != RESOLVE_SUPPORT_YES)
|
||||||
|
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Support for MulticastDNS is disabled");
|
||||||
|
|
||||||
|
- r = bus_verify_polkit_async(message, CAP_SYS_ADMIN,
|
||||||
|
- "org.freedesktop.resolve1.register-service",
|
||||||
|
- NULL, false, UID_INVALID,
|
||||||
|
- &m->polkit_registry, error);
|
||||||
|
- if (r < 0)
|
||||||
|
- return r;
|
||||||
|
- if (r == 0)
|
||||||
|
- return 1; /* Polkit will call us back */
|
||||||
|
-
|
||||||
|
service = new0(DnssdService, 1);
|
||||||
|
if (!service)
|
||||||
|
return log_oom();
|
||||||
|
@@ -1765,6 +1756,15 @@ static int bus_method_register_service(sd_bus_message *message, void *userdata,
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
+ r = bus_verify_polkit_async(message, CAP_SYS_ADMIN,
|
||||||
|
+ "org.freedesktop.resolve1.register-service",
|
||||||
|
+ NULL, false, UID_INVALID,
|
||||||
|
+ &m->polkit_registry, error);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+ if (r == 0)
|
||||||
|
+ return 1; /* Polkit will call us back */
|
||||||
|
+
|
||||||
|
r = hashmap_ensure_allocated(&m->dnssd_services, &string_hash_ops);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
@ -0,0 +1,48 @@
|
|||||||
|
From 4d2145e3edd6ba6ac2e52a232fa5059ecdacaead Mon Sep 17 00:00:00 2001
|
||||||
|
From: Evgeny Vereshchagin <evvers@ya.ru>
|
||||||
|
Date: Mon, 24 Dec 2018 00:29:56 +0100
|
||||||
|
Subject: [PATCH] journal: rely on _cleanup_free_ to free a temporary string
|
||||||
|
used in client_context_read_cgroup
|
||||||
|
|
||||||
|
Closes https://github.com/systemd/systemd/issues/11253.
|
||||||
|
|
||||||
|
(cherry picked from commit ef30f7cac18a810814ada7e6a68a31d48cc9fccd)
|
||||||
|
|
||||||
|
Resolves: #1764560
|
||||||
|
---
|
||||||
|
src/journal/journald-context.c | 7 ++-----
|
||||||
|
1 file changed, 2 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/journal/journald-context.c b/src/journal/journald-context.c
|
||||||
|
index c8e97e16de..3a768094d9 100644
|
||||||
|
--- a/src/journal/journald-context.c
|
||||||
|
+++ b/src/journal/journald-context.c
|
||||||
|
@@ -282,7 +282,7 @@ static int client_context_read_label(
|
||||||
|
}
|
||||||
|
|
||||||
|
static int client_context_read_cgroup(Server *s, ClientContext *c, const char *unit_id) {
|
||||||
|
- char *t = NULL;
|
||||||
|
+ _cleanup_free_ char *t = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(c);
|
||||||
|
@@ -290,7 +290,6 @@ static int client_context_read_cgroup(Server *s, ClientContext *c, const char *u
|
||||||
|
/* Try to acquire the current cgroup path */
|
||||||
|
r = cg_pid_get_path_shifted(c->pid, s->cgroup_root, &t);
|
||||||
|
if (r < 0 || empty_or_root(t)) {
|
||||||
|
-
|
||||||
|
/* We use the unit ID passed in as fallback if we have nothing cached yet and cg_pid_get_path_shifted()
|
||||||
|
* failed or process is running in a root cgroup. Zombie processes are automatically migrated to root cgroup
|
||||||
|
* on cgroupsv1 and we want to be able to map log messages from them too. */
|
||||||
|
@@ -304,10 +303,8 @@ static int client_context_read_cgroup(Server *s, ClientContext *c, const char *u
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Let's shortcut this if the cgroup path didn't change */
|
||||||
|
- if (streq_ptr(c->cgroup, t)) {
|
||||||
|
- free(t);
|
||||||
|
+ if (streq_ptr(c->cgroup, t))
|
||||||
|
return 0;
|
||||||
|
- }
|
||||||
|
|
||||||
|
free_and_replace(c->cgroup, t);
|
||||||
|
|
90
SOURCES/0250-basic-user-util-allow-dots-in-user-names.patch
Normal file
90
SOURCES/0250-basic-user-util-allow-dots-in-user-names.patch
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
From 76176de0889c3e8b9b3a176da24e4f8dbbd380a3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Synacek <jsynacek@redhat.com>
|
||||||
|
Date: Wed, 2 Oct 2019 11:59:41 +0200
|
||||||
|
Subject: [PATCH] basic/user-util: allow dots in user names
|
||||||
|
|
||||||
|
(based on commit 1a29610f5fa1bcb2eeb37d2c6b79d8d1a6dbb865)
|
||||||
|
|
||||||
|
Resolves: #1717603
|
||||||
|
---
|
||||||
|
src/basic/user-util.c | 9 ++++++---
|
||||||
|
src/test/test-user-util.c | 8 ++++----
|
||||||
|
2 files changed, 10 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/user-util.c b/src/basic/user-util.c
|
||||||
|
index c533f67025..d92969c966 100644
|
||||||
|
--- a/src/basic/user-util.c
|
||||||
|
+++ b/src/basic/user-util.c
|
||||||
|
@@ -575,11 +575,14 @@ bool valid_user_group_name(const char *u) {
|
||||||
|
/* Checks if the specified name is a valid user/group name. Also see POSIX IEEE Std 1003.1-2008, 2016 Edition,
|
||||||
|
* 3.437. We are a bit stricter here however. Specifically we deviate from POSIX rules:
|
||||||
|
*
|
||||||
|
- * - We don't allow any dots (this would break chown syntax which permits dots as user/group name separator)
|
||||||
|
* - We require that names fit into the appropriate utmp field
|
||||||
|
* - We don't allow empty user names
|
||||||
|
*
|
||||||
|
* Note that other systems are even more restrictive, and don't permit underscores or uppercase characters.
|
||||||
|
+ *
|
||||||
|
+ * jsynacek: We now allow dots in user names. The checks are not exhaustive as user names like "..." are allowed
|
||||||
|
+ * and valid according to POSIX, but can't be created using useradd. However, ".user" can be created. Let's not
|
||||||
|
+ * complicate the code by adding additional checks for weird corner cases like these, as they don't really matter here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (isempty(u))
|
||||||
|
@@ -587,14 +590,14 @@ bool valid_user_group_name(const char *u) {
|
||||||
|
|
||||||
|
if (!(u[0] >= 'a' && u[0] <= 'z') &&
|
||||||
|
!(u[0] >= 'A' && u[0] <= 'Z') &&
|
||||||
|
- u[0] != '_')
|
||||||
|
+ u[0] != '_' && u[0] != '.')
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (i = u+1; *i; i++) {
|
||||||
|
if (!(*i >= 'a' && *i <= 'z') &&
|
||||||
|
!(*i >= 'A' && *i <= 'Z') &&
|
||||||
|
!(*i >= '0' && *i <= '9') &&
|
||||||
|
- !IN_SET(*i, '_', '-'))
|
||||||
|
+ !IN_SET(*i, '_', '-', '.'))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/test/test-user-util.c b/src/test/test-user-util.c
|
||||||
|
index c1428fab02..9114d30b8c 100644
|
||||||
|
--- a/src/test/test-user-util.c
|
||||||
|
+++ b/src/test/test-user-util.c
|
||||||
|
@@ -71,8 +71,6 @@ static void test_valid_user_group_name(void) {
|
||||||
|
assert_se(!valid_user_group_name("-1"));
|
||||||
|
assert_se(!valid_user_group_name("-kkk"));
|
||||||
|
assert_se(!valid_user_group_name("rööt"));
|
||||||
|
- assert_se(!valid_user_group_name("."));
|
||||||
|
- assert_se(!valid_user_group_name("eff.eff"));
|
||||||
|
assert_se(!valid_user_group_name("foo\nbar"));
|
||||||
|
assert_se(!valid_user_group_name("0123456789012345678901234567890123456789"));
|
||||||
|
assert_se(!valid_user_group_name_or_id("aaa:bbb"));
|
||||||
|
@@ -83,6 +81,8 @@ static void test_valid_user_group_name(void) {
|
||||||
|
assert_se(valid_user_group_name("_kkk"));
|
||||||
|
assert_se(valid_user_group_name("kkk-"));
|
||||||
|
assert_se(valid_user_group_name("kk-k"));
|
||||||
|
+ assert_se(valid_user_group_name(".moo"));
|
||||||
|
+ assert_se(valid_user_group_name("eff.eff"));
|
||||||
|
|
||||||
|
assert_se(valid_user_group_name("some5"));
|
||||||
|
assert_se(!valid_user_group_name("5some"));
|
||||||
|
@@ -102,8 +102,6 @@ static void test_valid_user_group_name_or_id(void) {
|
||||||
|
assert_se(!valid_user_group_name_or_id("-1"));
|
||||||
|
assert_se(!valid_user_group_name_or_id("-kkk"));
|
||||||
|
assert_se(!valid_user_group_name_or_id("rööt"));
|
||||||
|
- assert_se(!valid_user_group_name_or_id("."));
|
||||||
|
- assert_se(!valid_user_group_name_or_id("eff.eff"));
|
||||||
|
assert_se(!valid_user_group_name_or_id("foo\nbar"));
|
||||||
|
assert_se(!valid_user_group_name_or_id("0123456789012345678901234567890123456789"));
|
||||||
|
assert_se(!valid_user_group_name_or_id("aaa:bbb"));
|
||||||
|
@@ -114,6 +112,8 @@ static void test_valid_user_group_name_or_id(void) {
|
||||||
|
assert_se(valid_user_group_name_or_id("_kkk"));
|
||||||
|
assert_se(valid_user_group_name_or_id("kkk-"));
|
||||||
|
assert_se(valid_user_group_name_or_id("kk-k"));
|
||||||
|
+ assert_se(valid_user_group_name_or_id(".moo"));
|
||||||
|
+ assert_se(valid_user_group_name_or_id("eff.eff"));
|
||||||
|
|
||||||
|
assert_se(valid_user_group_name_or_id("some5"));
|
||||||
|
assert_se(!valid_user_group_name_or_id("5some"));
|
29
SOURCES/0251-sd-bus-bump-message-queue-size-again.patch
Normal file
29
SOURCES/0251-sd-bus-bump-message-queue-size-again.patch
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
From 62623bafd9ce4842122ddeda83f9527e43b9a21f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Synacek <jsynacek@redhat.com>
|
||||||
|
Date: Fri, 8 Nov 2019 14:54:30 +0100
|
||||||
|
Subject: [PATCH] sd-bus: bump message queue size again
|
||||||
|
|
||||||
|
Simliarly to issue #4068, the current limit turns out to be too small for a
|
||||||
|
big storage setup that uses many small disks. Let's bump it further.
|
||||||
|
|
||||||
|
(cherry picked from commit 83a32ea7b03d6707b8e5bb90a0b3a6eb868ef633)
|
||||||
|
Resolves: #1770189
|
||||||
|
---
|
||||||
|
src/libsystemd/sd-bus/bus-internal.h | 4 ++--
|
||||||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
|
||||||
|
index 90e6028983..5d773b14c4 100644
|
||||||
|
--- a/src/libsystemd/sd-bus/bus-internal.h
|
||||||
|
+++ b/src/libsystemd/sd-bus/bus-internal.h
|
||||||
|
@@ -328,8 +328,8 @@ struct sd_bus {
|
||||||
|
* with enough entropy yet and might delay the boot */
|
||||||
|
#define BUS_AUTH_TIMEOUT ((usec_t) DEFAULT_TIMEOUT_USEC)
|
||||||
|
|
||||||
|
-#define BUS_WQUEUE_MAX (192*1024)
|
||||||
|
-#define BUS_RQUEUE_MAX (192*1024)
|
||||||
|
+#define BUS_WQUEUE_MAX (384*1024)
|
||||||
|
+#define BUS_RQUEUE_MAX (384*1024)
|
||||||
|
|
||||||
|
#define BUS_MESSAGE_SIZE_MAX (128*1024*1024)
|
||||||
|
#define BUS_AUTH_SIZE_MAX (64*1024)
|
@ -0,0 +1,109 @@
|
|||||||
|
From 18a45cf91dbdd075fb55d752f959e84d36f3ab3b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Evgeny Vereshchagin <evvers@ya.ru>
|
||||||
|
Date: Fri, 7 Sep 2018 06:13:17 +0000
|
||||||
|
Subject: [PATCH] tests: put fuzz_journald_processing_function in a .c file
|
||||||
|
|
||||||
|
(cherry picked from commit 231dca5579cfba6175d19eee5347d693893fb5aa)
|
||||||
|
|
||||||
|
Resolves: #1764560
|
||||||
|
---
|
||||||
|
src/fuzz/fuzz-journald.c | 30 ++++++++++++++++++++++++++++++
|
||||||
|
src/fuzz/fuzz-journald.h | 24 ++----------------------
|
||||||
|
src/fuzz/meson.build | 6 ++++--
|
||||||
|
3 files changed, 36 insertions(+), 24 deletions(-)
|
||||||
|
create mode 100644 src/fuzz/fuzz-journald.c
|
||||||
|
|
||||||
|
diff --git a/src/fuzz/fuzz-journald.c b/src/fuzz/fuzz-journald.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..f271d7f2fe
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/fuzz/fuzz-journald.c
|
||||||
|
@@ -0,0 +1,30 @@
|
||||||
|
+/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
+
|
||||||
|
+#include "alloc-util.h"
|
||||||
|
+#include "fuzz-journald.h"
|
||||||
|
+#include "journald-server.h"
|
||||||
|
+#include "sd-event.h"
|
||||||
|
+
|
||||||
|
+void fuzz_journald_processing_function(
|
||||||
|
+ const uint8_t *data,
|
||||||
|
+ size_t size,
|
||||||
|
+ void (*f)(Server *s, const char *buf, size_t raw_len, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len)
|
||||||
|
+ ) {
|
||||||
|
+ Server s = {};
|
||||||
|
+ char *label = NULL;
|
||||||
|
+ size_t label_len = 0;
|
||||||
|
+ struct ucred *ucred = NULL;
|
||||||
|
+ struct timeval *tv = NULL;
|
||||||
|
+
|
||||||
|
+ if (size == 0)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ assert_se(sd_event_default(&s.event) >= 0);
|
||||||
|
+ s.syslog_fd = s.native_fd = s.stdout_fd = s.dev_kmsg_fd = s.audit_fd = s.hostname_fd = s.notify_fd = -1;
|
||||||
|
+ s.buffer = memdup_suffix0(data, size);
|
||||||
|
+ assert_se(s.buffer);
|
||||||
|
+ s.buffer_size = size + 1;
|
||||||
|
+ s.storage = STORAGE_NONE;
|
||||||
|
+ (*f)(&s, s.buffer, size, ucred, tv, label, label_len);
|
||||||
|
+ server_done(&s);
|
||||||
|
+}
|
||||||
|
diff --git a/src/fuzz/fuzz-journald.h b/src/fuzz/fuzz-journald.h
|
||||||
|
index e66ef54c9b..e9d32a74aa 100644
|
||||||
|
--- a/src/fuzz/fuzz-journald.h
|
||||||
|
+++ b/src/fuzz/fuzz-journald.h
|
||||||
|
@@ -1,30 +1,10 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
-#include "alloc-util.h"
|
||||||
|
#include "journald-server.h"
|
||||||
|
-#include "sd-event.h"
|
||||||
|
|
||||||
|
-static void fuzz_journald_processing_function(
|
||||||
|
+void fuzz_journald_processing_function(
|
||||||
|
const uint8_t *data,
|
||||||
|
size_t size,
|
||||||
|
void (*f)(Server *s, const char *buf, size_t raw_len, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len)
|
||||||
|
- ) {
|
||||||
|
- Server s = {};
|
||||||
|
- char *label = NULL;
|
||||||
|
- size_t label_len = 0;
|
||||||
|
- struct ucred *ucred = NULL;
|
||||||
|
- struct timeval *tv = NULL;
|
||||||
|
-
|
||||||
|
- if (size == 0)
|
||||||
|
- return;
|
||||||
|
-
|
||||||
|
- assert_se(sd_event_default(&s.event) >= 0);
|
||||||
|
- s.syslog_fd = s.native_fd = s.stdout_fd = s.dev_kmsg_fd = s.audit_fd = s.hostname_fd = s.notify_fd = -1;
|
||||||
|
- s.buffer = memdup_suffix0(data, size);
|
||||||
|
- assert_se(s.buffer);
|
||||||
|
- s.buffer_size = size + 1;
|
||||||
|
- s.storage = STORAGE_NONE;
|
||||||
|
- (*f)(&s, s.buffer, size, ucred, tv, label, label_len);
|
||||||
|
- server_done(&s);
|
||||||
|
-}
|
||||||
|
+);
|
||||||
|
diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build
|
||||||
|
index 483a952421..1f8631bcc0 100644
|
||||||
|
--- a/src/fuzz/meson.build
|
||||||
|
+++ b/src/fuzz/meson.build
|
||||||
|
@@ -33,12 +33,14 @@ fuzzers += [
|
||||||
|
libshared],
|
||||||
|
[libmount]],
|
||||||
|
|
||||||
|
- [['src/fuzz/fuzz-journald-native.c'],
|
||||||
|
+ [['src/fuzz/fuzz-journald-native.c',
|
||||||
|
+ 'src/fuzz/fuzz-journald.c'],
|
||||||
|
[libjournal_core,
|
||||||
|
libshared],
|
||||||
|
[libselinux]],
|
||||||
|
|
||||||
|
- [['src/fuzz/fuzz-journald-syslog.c'],
|
||||||
|
+ [['src/fuzz/fuzz-journald-syslog.c',
|
||||||
|
+ 'src/fuzz/fuzz-journald.c'],
|
||||||
|
[libjournal_core,
|
||||||
|
libshared],
|
||||||
|
[libselinux]],
|
129
SOURCES/0253-tests-add-a-fuzzer-for-dev_kmsg_record.patch
Normal file
129
SOURCES/0253-tests-add-a-fuzzer-for-dev_kmsg_record.patch
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
From e7e70f575840cd021f6429f264911ae0cbff9741 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Evgeny Vereshchagin <evvers@ya.ru>
|
||||||
|
Date: Thu, 15 Nov 2018 17:52:57 +0100
|
||||||
|
Subject: [PATCH] tests: add a fuzzer for dev_kmsg_record
|
||||||
|
|
||||||
|
(cherry picked from commit 8857fb9beb9dcb95a6ce1be14dc94c4dc4cd3ea3)
|
||||||
|
|
||||||
|
Resolves: #1764560
|
||||||
|
---
|
||||||
|
src/fuzz/fuzz-journald-kmsg.c | 29 +++++++++++++++++++
|
||||||
|
src/fuzz/meson.build | 5 ++++
|
||||||
|
src/journal/journald-kmsg.c | 2 +-
|
||||||
|
src/journal/journald-kmsg.h | 2 ++
|
||||||
|
test/fuzz/fuzz-journald-kmsg/basic | 1 +
|
||||||
|
test/fuzz/fuzz-journald-kmsg/dev-null | 2 ++
|
||||||
|
test/fuzz/fuzz-journald-kmsg/loopback | 2 ++
|
||||||
|
.../fuzz-journald-kmsg/subsystem-loopback | 2 ++
|
||||||
|
8 files changed, 44 insertions(+), 1 deletion(-)
|
||||||
|
create mode 100644 src/fuzz/fuzz-journald-kmsg.c
|
||||||
|
create mode 100644 test/fuzz/fuzz-journald-kmsg/basic
|
||||||
|
create mode 100644 test/fuzz/fuzz-journald-kmsg/dev-null
|
||||||
|
create mode 100644 test/fuzz/fuzz-journald-kmsg/loopback
|
||||||
|
create mode 100644 test/fuzz/fuzz-journald-kmsg/subsystem-loopback
|
||||||
|
|
||||||
|
diff --git a/src/fuzz/fuzz-journald-kmsg.c b/src/fuzz/fuzz-journald-kmsg.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..5d99d244b5
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/fuzz/fuzz-journald-kmsg.c
|
||||||
|
@@ -0,0 +1,29 @@
|
||||||
|
+/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
+
|
||||||
|
+#include "fuzz.h"
|
||||||
|
+#include "journald-kmsg.h"
|
||||||
|
+
|
||||||
|
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
|
+ Server s = {};
|
||||||
|
+ _cleanup_free_ char *buffer = NULL;
|
||||||
|
+
|
||||||
|
+ if (size == 0)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ s = (Server) {
|
||||||
|
+ .native_fd = -1,
|
||||||
|
+ .stdout_fd = -1,
|
||||||
|
+ .dev_kmsg_fd = -1,
|
||||||
|
+ .audit_fd = -1,
|
||||||
|
+ .hostname_fd = -1,
|
||||||
|
+ .notify_fd = -1,
|
||||||
|
+ .storage = STORAGE_NONE,
|
||||||
|
+ };
|
||||||
|
+ assert_se(sd_event_default(&s.event) >= 0);
|
||||||
|
+ buffer = memdup(data, size);
|
||||||
|
+ assert_se(buffer);
|
||||||
|
+ dev_kmsg_record(&s, buffer, size);
|
||||||
|
+ server_done(&s);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build
|
||||||
|
index 1f8631bcc0..0520e448a9 100644
|
||||||
|
--- a/src/fuzz/meson.build
|
||||||
|
+++ b/src/fuzz/meson.build
|
||||||
|
@@ -33,6 +33,11 @@ fuzzers += [
|
||||||
|
libshared],
|
||||||
|
[libmount]],
|
||||||
|
|
||||||
|
+ [['src/fuzz/fuzz-journald-kmsg.c'],
|
||||||
|
+ [libjournal_core,
|
||||||
|
+ libshared],
|
||||||
|
+ [libselinux]],
|
||||||
|
+
|
||||||
|
[['src/fuzz/fuzz-journald-native.c',
|
||||||
|
'src/fuzz/fuzz-journald.c'],
|
||||||
|
[libjournal_core,
|
||||||
|
diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c
|
||||||
|
index 7644bebfc8..0cdf1c4794 100644
|
||||||
|
--- a/src/journal/journald-kmsg.c
|
||||||
|
+++ b/src/journal/journald-kmsg.c
|
||||||
|
@@ -93,7 +93,7 @@ static bool is_us(const char *identifier, const char *pid) {
|
||||||
|
streq(identifier, program_invocation_short_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void dev_kmsg_record(Server *s, char *p, size_t l) {
|
||||||
|
+void dev_kmsg_record(Server *s, char *p, size_t l) {
|
||||||
|
|
||||||
|
_cleanup_free_ char *message = NULL, *syslog_priority = NULL, *syslog_pid = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *source_time = NULL, *identifier = NULL, *pid = NULL;
|
||||||
|
struct iovec iovec[N_IOVEC_META_FIELDS + 7 + N_IOVEC_KERNEL_FIELDS + 2 + N_IOVEC_UDEV_FIELDS];
|
||||||
|
diff --git a/src/journal/journald-kmsg.h b/src/journal/journald-kmsg.h
|
||||||
|
index bff24ac310..2326bc8c93 100644
|
||||||
|
--- a/src/journal/journald-kmsg.h
|
||||||
|
+++ b/src/journal/journald-kmsg.h
|
||||||
|
@@ -9,3 +9,5 @@ int server_flush_dev_kmsg(Server *s);
|
||||||
|
void server_forward_kmsg(Server *s, int priority, const char *identifier, const char *message, const struct ucred *ucred);
|
||||||
|
|
||||||
|
int server_open_kernel_seqnum(Server *s);
|
||||||
|
+
|
||||||
|
+void dev_kmsg_record(Server *s, char *p, size_t l);
|
||||||
|
diff --git a/test/fuzz/fuzz-journald-kmsg/basic b/test/fuzz/fuzz-journald-kmsg/basic
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..1299cd0869
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/fuzz/fuzz-journald-kmsg/basic
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+29,456,292891883,-;systemd[1]: Reexecuting.
|
||||||
|
diff --git a/test/fuzz/fuzz-journald-kmsg/dev-null b/test/fuzz/fuzz-journald-kmsg/dev-null
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..de039588b5
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/fuzz/fuzz-journald-kmsg/dev-null
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+12,460,1322026586,-;hey
|
||||||
|
+ DEVICE=c1:3
|
||||||
|
diff --git a/test/fuzz/fuzz-journald-kmsg/loopback b/test/fuzz/fuzz-journald-kmsg/loopback
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..ca320177b7
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/fuzz/fuzz-journald-kmsg/loopback
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+12,460,1322026586,-;hey
|
||||||
|
+ DEVICE=n1
|
||||||
|
diff --git a/test/fuzz/fuzz-journald-kmsg/subsystem-loopback b/test/fuzz/fuzz-journald-kmsg/subsystem-loopback
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..af9c0d91e5
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/fuzz/fuzz-journald-kmsg/subsystem-loopback
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+12,460,1322026586,-;hey
|
||||||
|
+ DEVICE=+net:lo
|
@ -0,0 +1,30 @@
|
|||||||
|
From 43d72623fdfca8500c8c89a4b5023e35a3f0b259 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Evgeny Vereshchagin <evvers@ya.ru>
|
||||||
|
Date: Fri, 16 Nov 2018 07:05:29 +0100
|
||||||
|
Subject: [PATCH] basic: remove an assertion from cunescape_one
|
||||||
|
|
||||||
|
The function takes a pointer to a random block of memory and
|
||||||
|
the length of that block. It shouldn't crash every time it sees
|
||||||
|
a zero byte at the beginning there.
|
||||||
|
|
||||||
|
This should help the dev-kmsg fuzzer to keep going.
|
||||||
|
|
||||||
|
(cherry picked from commit 8dc4de966ce6d32470aaff30ed054f6a2688d6d7)
|
||||||
|
|
||||||
|
Resolves: #1764560
|
||||||
|
---
|
||||||
|
src/basic/escape.c | 1 -
|
||||||
|
1 file changed, 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/escape.c b/src/basic/escape.c
|
||||||
|
index 5004763d97..5f715156fb 100644
|
||||||
|
--- a/src/basic/escape.c
|
||||||
|
+++ b/src/basic/escape.c
|
||||||
|
@@ -106,7 +106,6 @@ int cunescape_one(const char *p, size_t length, char32_t *ret, bool *eight_bit)
|
||||||
|
int r = 1;
|
||||||
|
|
||||||
|
assert(p);
|
||||||
|
- assert(*p);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
/* Unescapes C style. Returns the unescaped character in ret.
|
@ -0,0 +1,25 @@
|
|||||||
|
From f00d221d5dc92a530e260db5f44fa57653f03e8b Mon Sep 17 00:00:00 2001
|
||||||
|
From: Evgeny Vereshchagin <evvers@ya.ru>
|
||||||
|
Date: Fri, 16 Nov 2018 07:11:06 +0100
|
||||||
|
Subject: [PATCH] journal: fix an off-by-one error in dev_kmsg_record
|
||||||
|
|
||||||
|
(cherry picked from commit 080d112caa0dc948555a69a008c1caf4d5d41ed6)
|
||||||
|
|
||||||
|
Resolves: #1764560
|
||||||
|
---
|
||||||
|
src/journal/journald-kmsg.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/journal/journald-kmsg.c b/src/journal/journald-kmsg.c
|
||||||
|
index 0cdf1c4794..726c006ce1 100644
|
||||||
|
--- a/src/journal/journald-kmsg.c
|
||||||
|
+++ b/src/journal/journald-kmsg.c
|
||||||
|
@@ -239,7 +239,7 @@ void dev_kmsg_record(Server *s, char *p, size_t l) {
|
||||||
|
ll = udev_device_get_devlinks_list_entry(ud);
|
||||||
|
udev_list_entry_foreach(ll, ll) {
|
||||||
|
|
||||||
|
- if (j > N_IOVEC_UDEV_FIELDS)
|
||||||
|
+ if (j >= N_IOVEC_UDEV_FIELDS)
|
||||||
|
break;
|
||||||
|
|
||||||
|
g = udev_list_entry_get_name(ll);
|
@ -0,0 +1,25 @@
|
|||||||
|
From 4caa887ae8eabc087d6f9f2b233c96c220de8b02 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Evgeny Vereshchagin <evvers@ya.ru>
|
||||||
|
Date: Fri, 16 Nov 2018 07:20:44 +0100
|
||||||
|
Subject: [PATCH] tests: add a reproducer for a memory leak fixed in
|
||||||
|
30eddcd51b8a472e05d3b8d1 in August
|
||||||
|
|
||||||
|
(cherry picked from commit 1dd485b700fe9ad94d7a780f14fcf18a4738ace4)
|
||||||
|
|
||||||
|
Resolves: #1764560
|
||||||
|
---
|
||||||
|
...leak-ab161e601e82f1ec31d11e2cbae2747834ce9e43 | Bin 0 -> 1847 bytes
|
||||||
|
1 file changed, 0 insertions(+), 0 deletions(-)
|
||||||
|
create mode 100644 test/fuzz/fuzz-journald-kmsg/leak-ab161e601e82f1ec31d11e2cbae2747834ce9e43
|
||||||
|
|
||||||
|
diff --git a/test/fuzz/fuzz-journald-kmsg/leak-ab161e601e82f1ec31d11e2cbae2747834ce9e43 b/test/fuzz/fuzz-journald-kmsg/leak-ab161e601e82f1ec31d11e2cbae2747834ce9e43
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..424ae5cb010aa519758e6af90cc981795b68d3fd
|
||||||
|
GIT binary patch
|
||||||
|
literal 1847
|
||||||
|
zcmXps(lIeJ&@nVNGBPkSGqo_&(Y4M<t>jX0aSiiycD2<{NiEaQE6vG)izFLb8I!<a
|
||||||
|
b7zLvtFd70lLcjrs_^9w`2#kin;0*x)kUJOk
|
||||||
|
|
||||||
|
literal 0
|
||||||
|
HcmV?d00001
|
||||||
|
|
@ -0,0 +1,25 @@
|
|||||||
|
From 375fd5f8b3c6fb0f7c29ceb166f70bfd45314e04 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Evgeny Vereshchagin <evvers@ya.ru>
|
||||||
|
Date: Fri, 16 Nov 2018 07:33:02 +0100
|
||||||
|
Subject: [PATCH] tests: add a reproducer for a heap-buffer-overflow fixed in
|
||||||
|
937b1171378bc1000a
|
||||||
|
|
||||||
|
(cherry picked from commit f7a6b40187a98751a9ab6867e8b52e4e6f1dad5c)
|
||||||
|
|
||||||
|
Resolves: #1764560
|
||||||
|
---
|
||||||
|
...crash-c6c04d83e73f3d1417bc0afce8fa81b99f955963 | Bin 0 -> 112 bytes
|
||||||
|
1 file changed, 0 insertions(+), 0 deletions(-)
|
||||||
|
create mode 100644 test/fuzz/fuzz-journald-kmsg/crash-c6c04d83e73f3d1417bc0afce8fa81b99f955963
|
||||||
|
|
||||||
|
diff --git a/test/fuzz/fuzz-journald-kmsg/crash-c6c04d83e73f3d1417bc0afce8fa81b99f955963 b/test/fuzz/fuzz-journald-kmsg/crash-c6c04d83e73f3d1417bc0afce8fa81b99f955963
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..19887a1fec9fc29b1f7da8a2d1c5ea5054f2bc02
|
||||||
|
GIT binary patch
|
||||||
|
literal 112
|
||||||
|
zcmXpq)Zrxx80r}680lCOP-~&{)k?wIfGehgOM!tQroxI#0Z63Aa4DF?03ibx03hxS
|
||||||
|
A82|tP
|
||||||
|
|
||||||
|
literal 0
|
||||||
|
HcmV?d00001
|
||||||
|
|
@ -0,0 +1,44 @@
|
|||||||
|
From af471e7402a70b670cd50e45c6139a0ac50a74bd Mon Sep 17 00:00:00 2001
|
||||||
|
From: Evgeny Vereshchagin <evvers@ya.ru>
|
||||||
|
Date: Fri, 16 Nov 2018 09:23:53 +0100
|
||||||
|
Subject: [PATCH] test: initialize syslog_fd in fuzz-journald-kmsg too
|
||||||
|
|
||||||
|
This is a follow-up to 8857fb9beb9dcb that prevents the fuzzer from crashing with
|
||||||
|
```
|
||||||
|
==220==ERROR: AddressSanitizer: ABRT on unknown address 0x0000000000dc (pc 0x7ff4953c8428 bp 0x7ffcf66ec290 sp 0x7ffcf66ec128 T0)
|
||||||
|
SCARINESS: 10 (signal)
|
||||||
|
#0 0x7ff4953c8427 in gsignal (/lib/x86_64-linux-gnu/libc.so.6+0x35427)
|
||||||
|
#1 0x7ff4953ca029 in abort (/lib/x86_64-linux-gnu/libc.so.6+0x37029)
|
||||||
|
#2 0x7ff49666503a in log_assert_failed_realm /work/build/../../src/systemd/src/basic/log.c:805:9
|
||||||
|
#3 0x7ff496614ecf in safe_close /work/build/../../src/systemd/src/basic/fd-util.c:66:17
|
||||||
|
#4 0x548806 in server_done /work/build/../../src/systemd/src/journal/journald-server.c:2064:9
|
||||||
|
#5 0x5349fa in LLVMFuzzerTestOneInput /work/build/../../src/systemd/src/fuzz/fuzz-journald-kmsg.c:26:9
|
||||||
|
#6 0x592755 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/libfuzzer/FuzzerLoop.cpp:571:15
|
||||||
|
#7 0x590627 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /src/libfuzzer/FuzzerLoop.cpp:480:3
|
||||||
|
#8 0x594432 in fuzzer::Fuzzer::MutateAndTestOne() /src/libfuzzer/FuzzerLoop.cpp:708:19
|
||||||
|
#9 0x5973c6 in fuzzer::Fuzzer::Loop(std::__1::vector<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, fuzzer::fuzzer_allocator<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > > const&) /src/libfuzzer/FuzzerLoop.cpp:839:5
|
||||||
|
#10 0x574541 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/libfuzzer/FuzzerDriver.cpp:764:6
|
||||||
|
#11 0x5675fc in main /src/libfuzzer/FuzzerMain.cpp:20:10
|
||||||
|
#12 0x7ff4953b382f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
|
||||||
|
#13 0x420f58 in _start (/out/fuzz-journald-kmsg+0x420f58)
|
||||||
|
```
|
||||||
|
|
||||||
|
(cherry picked from commit cc55ac0171a2493768c021faa356513642797e7f)
|
||||||
|
|
||||||
|
Resolves: #1764560
|
||||||
|
---
|
||||||
|
src/fuzz/fuzz-journald-kmsg.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/src/fuzz/fuzz-journald-kmsg.c b/src/fuzz/fuzz-journald-kmsg.c
|
||||||
|
index 5d99d244b5..e2611c6d45 100644
|
||||||
|
--- a/src/fuzz/fuzz-journald-kmsg.c
|
||||||
|
+++ b/src/fuzz/fuzz-journald-kmsg.c
|
||||||
|
@@ -11,6 +11,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
s = (Server) {
|
||||||
|
+ .syslog_fd = -1,
|
||||||
|
.native_fd = -1,
|
||||||
|
.stdout_fd = -1,
|
||||||
|
.dev_kmsg_fd = -1,
|
@ -0,0 +1,99 @@
|
|||||||
|
From f991a9c7644f3fb5155ff823600ba5a6ea403dc4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Evgeny Vereshchagin <evvers@ya.ru>
|
||||||
|
Date: Fri, 16 Nov 2018 21:23:56 +0100
|
||||||
|
Subject: [PATCH] tests: add a fuzzer for process_audit_string
|
||||||
|
|
||||||
|
(cherry picked from commit 090a20cfaf3d5439fa39c5d8df473b0cfef181dd)
|
||||||
|
|
||||||
|
Resolves: #1764560
|
||||||
|
---
|
||||||
|
src/fuzz/fuzz-journald-audit.c | 27 +++++++++++++++++++++++++++
|
||||||
|
src/fuzz/meson.build | 5 +++++
|
||||||
|
src/journal/journald-audit.c | 2 +-
|
||||||
|
src/journal/journald-audit.h | 2 ++
|
||||||
|
test/fuzz/fuzz-journald-audit/basic | 1 +
|
||||||
|
5 files changed, 36 insertions(+), 1 deletion(-)
|
||||||
|
create mode 100644 src/fuzz/fuzz-journald-audit.c
|
||||||
|
create mode 100644 test/fuzz/fuzz-journald-audit/basic
|
||||||
|
|
||||||
|
diff --git a/src/fuzz/fuzz-journald-audit.c b/src/fuzz/fuzz-journald-audit.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..fe401c0d98
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/fuzz/fuzz-journald-audit.c
|
||||||
|
@@ -0,0 +1,27 @@
|
||||||
|
+/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
+
|
||||||
|
+#include "fuzz.h"
|
||||||
|
+#include "journald-audit.h"
|
||||||
|
+
|
||||||
|
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
|
+ Server s;
|
||||||
|
+ _cleanup_free_ char *buffer = NULL;
|
||||||
|
+
|
||||||
|
+ s = (Server) {
|
||||||
|
+ .syslog_fd = -1,
|
||||||
|
+ .native_fd = -1,
|
||||||
|
+ .stdout_fd = -1,
|
||||||
|
+ .dev_kmsg_fd = -1,
|
||||||
|
+ .audit_fd = -1,
|
||||||
|
+ .hostname_fd = -1,
|
||||||
|
+ .notify_fd = -1,
|
||||||
|
+ .storage = STORAGE_NONE,
|
||||||
|
+ };
|
||||||
|
+ assert_se(sd_event_default(&s.event) >= 0);
|
||||||
|
+ buffer = memdup_suffix0(data, size);
|
||||||
|
+ assert_se(buffer);
|
||||||
|
+ process_audit_string(&s, 0, buffer, size);
|
||||||
|
+ server_done(&s);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build
|
||||||
|
index 0520e448a9..5548da3822 100644
|
||||||
|
--- a/src/fuzz/meson.build
|
||||||
|
+++ b/src/fuzz/meson.build
|
||||||
|
@@ -33,6 +33,11 @@ fuzzers += [
|
||||||
|
libshared],
|
||||||
|
[libmount]],
|
||||||
|
|
||||||
|
+ [['src/fuzz/fuzz-journald-audit.c'],
|
||||||
|
+ [libjournal_core,
|
||||||
|
+ libshared],
|
||||||
|
+ [libselinux]],
|
||||||
|
+
|
||||||
|
[['src/fuzz/fuzz-journald-kmsg.c'],
|
||||||
|
[libjournal_core,
|
||||||
|
libshared],
|
||||||
|
diff --git a/src/journal/journald-audit.c b/src/journal/journald-audit.c
|
||||||
|
index 87726684af..7810a0139a 100644
|
||||||
|
--- a/src/journal/journald-audit.c
|
||||||
|
+++ b/src/journal/journald-audit.c
|
||||||
|
@@ -313,7 +313,7 @@ static int map_all_fields(
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void process_audit_string(Server *s, int type, const char *data, size_t size) {
|
||||||
|
+void process_audit_string(Server *s, int type, const char *data, size_t size) {
|
||||||
|
size_t n_iov_allocated = 0, n_iov = 0, z;
|
||||||
|
_cleanup_free_ struct iovec *iov = NULL;
|
||||||
|
uint64_t seconds, msec, id;
|
||||||
|
diff --git a/src/journal/journald-audit.h b/src/journal/journald-audit.h
|
||||||
|
index 57bb1711c9..7766618c98 100644
|
||||||
|
--- a/src/journal/journald-audit.h
|
||||||
|
+++ b/src/journal/journald-audit.h
|
||||||
|
@@ -6,4 +6,6 @@
|
||||||
|
|
||||||
|
void server_process_audit_message(Server *s, const void *buffer, size_t buffer_size, const struct ucred *ucred, const union sockaddr_union *sa, socklen_t salen);
|
||||||
|
|
||||||
|
+void process_audit_string(Server *s, int type, const char *data, size_t size);
|
||||||
|
+
|
||||||
|
int server_open_audit(Server*s);
|
||||||
|
diff --git a/test/fuzz/fuzz-journald-audit/basic b/test/fuzz/fuzz-journald-audit/basic
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..d1ce8cc5f0
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/fuzz/fuzz-journald-audit/basic
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+audit(1542398162.211:744): pid=7376 uid=1000 auid=1000 ses=6 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 msg='op=PAM:accounting grantors=pam_unix,pam_localuser acct="vagrant" exe="/usr/bin/sudo" hostname=? addr=? terminal=/dev/pts/1 res=success'
|
||||||
|
\ No newline at end of file
|
@ -0,0 +1,47 @@
|
|||||||
|
From bef599d1a0e41afe4b6f1d6dfb6fbc86896ab8c5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Evgeny Vereshchagin <evvers@ya.ru>
|
||||||
|
Date: Fri, 16 Nov 2018 23:32:31 +0100
|
||||||
|
Subject: [PATCH] journald: check whether sscanf has changed the value
|
||||||
|
corresponding to %n
|
||||||
|
|
||||||
|
It's possible for sscanf to receive strings containing all three fields
|
||||||
|
and not matching the template at the same time. When this happens the
|
||||||
|
value of k doesn't change, which basically means that process_audit_string
|
||||||
|
tries to access memory randomly. Sometimes it works and sometimes it doesn't :-)
|
||||||
|
|
||||||
|
See also https://bugzilla.redhat.com/show_bug.cgi?id=1059314.
|
||||||
|
|
||||||
|
(cherry picked from commit 1dab14aba749b9c5ab8176c5730107b70834240b)
|
||||||
|
|
||||||
|
Resolves: #1764560
|
||||||
|
---
|
||||||
|
src/journal/journald-audit.c | 3 ++-
|
||||||
|
test/fuzz/fuzz-journald-audit/crash | 1 +
|
||||||
|
2 files changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
create mode 100644 test/fuzz/fuzz-journald-audit/crash
|
||||||
|
|
||||||
|
diff --git a/src/journal/journald-audit.c b/src/journal/journald-audit.c
|
||||||
|
index 7810a0139a..0fd6ab2a84 100644
|
||||||
|
--- a/src/journal/journald-audit.c
|
||||||
|
+++ b/src/journal/journald-audit.c
|
||||||
|
@@ -341,11 +341,12 @@ void process_audit_string(Server *s, int type, const char *data, size_t size) {
|
||||||
|
if (!p)
|
||||||
|
return;
|
||||||
|
|
||||||
|
+ k = 0;
|
||||||
|
if (sscanf(p, "(%" PRIu64 ".%" PRIu64 ":%" PRIu64 "):%n",
|
||||||
|
&seconds,
|
||||||
|
&msec,
|
||||||
|
&id,
|
||||||
|
- &k) != 3)
|
||||||
|
+ &k) != 3 || k == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
p += k;
|
||||||
|
diff --git a/test/fuzz/fuzz-journald-audit/crash b/test/fuzz/fuzz-journald-audit/crash
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..91bd85ca6e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/fuzz/fuzz-journald-audit/crash
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+audit(1542398162.211:744) pid=7376 uid=1000 auid=1000 ses=6 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 msg='op=PAM:accounting grantors=pam_unix,pam_localuser acct="vagrant" exe="/usr/bin/sudo" hostname=? addr=? terminal=/dev/pts/1 res=success'
|
@ -0,0 +1,172 @@
|
|||||||
|
From b276c85200786add6c86b6c1fedc888c71ffe5db Mon Sep 17 00:00:00 2001
|
||||||
|
From: Evgeny Vereshchagin <evvers@ya.ru>
|
||||||
|
Date: Sat, 17 Nov 2018 13:01:09 +0100
|
||||||
|
Subject: [PATCH] tests: introduce dummy_server_init and use it in all journald
|
||||||
|
fuzzers
|
||||||
|
|
||||||
|
(cherry picked from commit ed62712dc6fb236845c489a7f386c7aff0ec31d6)
|
||||||
|
|
||||||
|
Resolves: #1764560
|
||||||
|
---
|
||||||
|
src/fuzz/fuzz-journald-audit.c | 18 +++---------------
|
||||||
|
src/fuzz/fuzz-journald-kmsg.c | 20 ++++----------------
|
||||||
|
src/fuzz/fuzz-journald.c | 26 +++++++++++++++++++-------
|
||||||
|
src/fuzz/fuzz-journald.h | 2 ++
|
||||||
|
src/fuzz/meson.build | 6 ++++--
|
||||||
|
5 files changed, 32 insertions(+), 40 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/fuzz/fuzz-journald-audit.c b/src/fuzz/fuzz-journald-audit.c
|
||||||
|
index fe401c0d98..3f3ce7e8ee 100644
|
||||||
|
--- a/src/fuzz/fuzz-journald-audit.c
|
||||||
|
+++ b/src/fuzz/fuzz-journald-audit.c
|
||||||
|
@@ -1,26 +1,14 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
|
||||||
|
#include "fuzz.h"
|
||||||
|
+#include "fuzz-journald.h"
|
||||||
|
#include "journald-audit.h"
|
||||||
|
|
||||||
|
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
|
Server s;
|
||||||
|
- _cleanup_free_ char *buffer = NULL;
|
||||||
|
|
||||||
|
- s = (Server) {
|
||||||
|
- .syslog_fd = -1,
|
||||||
|
- .native_fd = -1,
|
||||||
|
- .stdout_fd = -1,
|
||||||
|
- .dev_kmsg_fd = -1,
|
||||||
|
- .audit_fd = -1,
|
||||||
|
- .hostname_fd = -1,
|
||||||
|
- .notify_fd = -1,
|
||||||
|
- .storage = STORAGE_NONE,
|
||||||
|
- };
|
||||||
|
- assert_se(sd_event_default(&s.event) >= 0);
|
||||||
|
- buffer = memdup_suffix0(data, size);
|
||||||
|
- assert_se(buffer);
|
||||||
|
- process_audit_string(&s, 0, buffer, size);
|
||||||
|
+ dummy_server_init(&s, data, size);
|
||||||
|
+ process_audit_string(&s, 0, s.buffer, size);
|
||||||
|
server_done(&s);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
diff --git a/src/fuzz/fuzz-journald-kmsg.c b/src/fuzz/fuzz-journald-kmsg.c
|
||||||
|
index e2611c6d45..f7426c8400 100644
|
||||||
|
--- a/src/fuzz/fuzz-journald-kmsg.c
|
||||||
|
+++ b/src/fuzz/fuzz-journald-kmsg.c
|
||||||
|
@@ -1,29 +1,17 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
|
||||||
|
#include "fuzz.h"
|
||||||
|
+#include "fuzz-journald.h"
|
||||||
|
#include "journald-kmsg.h"
|
||||||
|
|
||||||
|
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
|
- Server s = {};
|
||||||
|
- _cleanup_free_ char *buffer = NULL;
|
||||||
|
+ Server s;
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
- s = (Server) {
|
||||||
|
- .syslog_fd = -1,
|
||||||
|
- .native_fd = -1,
|
||||||
|
- .stdout_fd = -1,
|
||||||
|
- .dev_kmsg_fd = -1,
|
||||||
|
- .audit_fd = -1,
|
||||||
|
- .hostname_fd = -1,
|
||||||
|
- .notify_fd = -1,
|
||||||
|
- .storage = STORAGE_NONE,
|
||||||
|
- };
|
||||||
|
- assert_se(sd_event_default(&s.event) >= 0);
|
||||||
|
- buffer = memdup(data, size);
|
||||||
|
- assert_se(buffer);
|
||||||
|
- dev_kmsg_record(&s, buffer, size);
|
||||||
|
+ dummy_server_init(&s, data, size);
|
||||||
|
+ dev_kmsg_record(&s, s.buffer, size);
|
||||||
|
server_done(&s);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
diff --git a/src/fuzz/fuzz-journald.c b/src/fuzz/fuzz-journald.c
|
||||||
|
index f271d7f2fe..0659b92ba3 100644
|
||||||
|
--- a/src/fuzz/fuzz-journald.c
|
||||||
|
+++ b/src/fuzz/fuzz-journald.c
|
||||||
|
@@ -5,12 +5,29 @@
|
||||||
|
#include "journald-server.h"
|
||||||
|
#include "sd-event.h"
|
||||||
|
|
||||||
|
+void dummy_server_init(Server *s, const uint8_t *buffer, size_t size) {
|
||||||
|
+ *s = (Server) {
|
||||||
|
+ .syslog_fd = -1,
|
||||||
|
+ .native_fd = -1,
|
||||||
|
+ .stdout_fd = -1,
|
||||||
|
+ .dev_kmsg_fd = -1,
|
||||||
|
+ .audit_fd = -1,
|
||||||
|
+ .hostname_fd = -1,
|
||||||
|
+ .notify_fd = -1,
|
||||||
|
+ .storage = STORAGE_NONE,
|
||||||
|
+ };
|
||||||
|
+ assert_se(sd_event_default(&s->event) >= 0);
|
||||||
|
+ s->buffer = memdup_suffix0(buffer, size);
|
||||||
|
+ assert_se(s->buffer);
|
||||||
|
+ s->buffer_size = size + 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void fuzz_journald_processing_function(
|
||||||
|
const uint8_t *data,
|
||||||
|
size_t size,
|
||||||
|
void (*f)(Server *s, const char *buf, size_t raw_len, const struct ucred *ucred, const struct timeval *tv, const char *label, size_t label_len)
|
||||||
|
) {
|
||||||
|
- Server s = {};
|
||||||
|
+ Server s;
|
||||||
|
char *label = NULL;
|
||||||
|
size_t label_len = 0;
|
||||||
|
struct ucred *ucred = NULL;
|
||||||
|
@@ -19,12 +36,7 @@ void fuzz_journald_processing_function(
|
||||||
|
if (size == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
- assert_se(sd_event_default(&s.event) >= 0);
|
||||||
|
- s.syslog_fd = s.native_fd = s.stdout_fd = s.dev_kmsg_fd = s.audit_fd = s.hostname_fd = s.notify_fd = -1;
|
||||||
|
- s.buffer = memdup_suffix0(data, size);
|
||||||
|
- assert_se(s.buffer);
|
||||||
|
- s.buffer_size = size + 1;
|
||||||
|
- s.storage = STORAGE_NONE;
|
||||||
|
+ dummy_server_init(&s, data, size);
|
||||||
|
(*f)(&s, s.buffer, size, ucred, tv, label, label_len);
|
||||||
|
server_done(&s);
|
||||||
|
}
|
||||||
|
diff --git a/src/fuzz/fuzz-journald.h b/src/fuzz/fuzz-journald.h
|
||||||
|
index e9d32a74aa..77e3b0c064 100644
|
||||||
|
--- a/src/fuzz/fuzz-journald.h
|
||||||
|
+++ b/src/fuzz/fuzz-journald.h
|
||||||
|
@@ -3,6 +3,8 @@
|
||||||
|
|
||||||
|
#include "journald-server.h"
|
||||||
|
|
||||||
|
+void dummy_server_init(Server *s, const uint8_t *buffer, size_t size);
|
||||||
|
+
|
||||||
|
void fuzz_journald_processing_function(
|
||||||
|
const uint8_t *data,
|
||||||
|
size_t size,
|
||||||
|
diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build
|
||||||
|
index 5548da3822..897c02e4ae 100644
|
||||||
|
--- a/src/fuzz/meson.build
|
||||||
|
+++ b/src/fuzz/meson.build
|
||||||
|
@@ -33,12 +33,14 @@ fuzzers += [
|
||||||
|
libshared],
|
||||||
|
[libmount]],
|
||||||
|
|
||||||
|
- [['src/fuzz/fuzz-journald-audit.c'],
|
||||||
|
+ [['src/fuzz/fuzz-journald-audit.c',
|
||||||
|
+ 'src/fuzz/fuzz-journald.c'],
|
||||||
|
[libjournal_core,
|
||||||
|
libshared],
|
||||||
|
[libselinux]],
|
||||||
|
|
||||||
|
- [['src/fuzz/fuzz-journald-kmsg.c'],
|
||||||
|
+ [['src/fuzz/fuzz-journald-kmsg.c',
|
||||||
|
+ 'src/fuzz/fuzz-journald.c'],
|
||||||
|
[libjournal_core,
|
||||||
|
libshared],
|
||||||
|
[libselinux]],
|
148
SOURCES/0262-tests-add-a-fuzzer-for-journald-streams.patch
Normal file
148
SOURCES/0262-tests-add-a-fuzzer-for-journald-streams.patch
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
From e7077e3a551a3faedfcc3d007de6a72fb5e1df62 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Evgeny Vereshchagin <evvers@ya.ru>
|
||||||
|
Date: Tue, 20 Nov 2018 01:20:32 +0100
|
||||||
|
Subject: [PATCH] tests: add a fuzzer for journald streams
|
||||||
|
|
||||||
|
(cherry picked from commit 9541f5ff5c637bb1b3e3c69706cb73e68ff06813)
|
||||||
|
|
||||||
|
Resolves: #1764560
|
||||||
|
---
|
||||||
|
src/fuzz/fuzz-journald-stream.c | 35 ++++++++++++++++++++++++++++
|
||||||
|
src/fuzz/fuzz-journald.c | 10 +++++---
|
||||||
|
src/fuzz/meson.build | 6 +++++
|
||||||
|
src/journal/journald-stream.c | 4 ++--
|
||||||
|
src/journal/journald-stream.h | 2 ++
|
||||||
|
test/fuzz/fuzz-journald-stream/basic | 8 +++++++
|
||||||
|
6 files changed, 60 insertions(+), 5 deletions(-)
|
||||||
|
create mode 100644 src/fuzz/fuzz-journald-stream.c
|
||||||
|
create mode 100644 test/fuzz/fuzz-journald-stream/basic
|
||||||
|
|
||||||
|
diff --git a/src/fuzz/fuzz-journald-stream.c b/src/fuzz/fuzz-journald-stream.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..247c0889bc
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/fuzz/fuzz-journald-stream.c
|
||||||
|
@@ -0,0 +1,35 @@
|
||||||
|
+/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
+
|
||||||
|
+#include <linux/sockios.h>
|
||||||
|
+
|
||||||
|
+#include "fd-util.h"
|
||||||
|
+#include "fuzz.h"
|
||||||
|
+#include "fuzz-journald.h"
|
||||||
|
+#include "journald-stream.h"
|
||||||
|
+
|
||||||
|
+static int stream_fds[2] = { -1, -1 };
|
||||||
|
+
|
||||||
|
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
|
+ Server s;
|
||||||
|
+ StdoutStream *stream;
|
||||||
|
+ int v;
|
||||||
|
+
|
||||||
|
+ if (size == 0)
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+ if (!getenv("SYSTEMD_LOG_LEVEL"))
|
||||||
|
+ log_set_max_level(LOG_CRIT);
|
||||||
|
+
|
||||||
|
+ assert_se(socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0, stream_fds) >= 0);
|
||||||
|
+ dummy_server_init(&s, NULL, 0);
|
||||||
|
+ assert_se(stdout_stream_install(&s, stream_fds[0], &stream) >= 0);
|
||||||
|
+ assert_se(write(stream_fds[1], data, size) == (ssize_t) size);
|
||||||
|
+ while (ioctl(stream_fds[0], SIOCINQ, &v) == 0 && v)
|
||||||
|
+ sd_event_run(s.event, (uint64_t) -1);
|
||||||
|
+ if (s.n_stdout_streams)
|
||||||
|
+ stdout_stream_destroy(stream);
|
||||||
|
+ server_done(&s);
|
||||||
|
+ stream_fds[1] = safe_close(stream_fds[1]);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/src/fuzz/fuzz-journald.c b/src/fuzz/fuzz-journald.c
|
||||||
|
index 0659b92ba3..950e885cae 100644
|
||||||
|
--- a/src/fuzz/fuzz-journald.c
|
||||||
|
+++ b/src/fuzz/fuzz-journald.c
|
||||||
|
@@ -15,11 +15,15 @@ void dummy_server_init(Server *s, const uint8_t *buffer, size_t size) {
|
||||||
|
.hostname_fd = -1,
|
||||||
|
.notify_fd = -1,
|
||||||
|
.storage = STORAGE_NONE,
|
||||||
|
+ .line_max = 64,
|
||||||
|
};
|
||||||
|
assert_se(sd_event_default(&s->event) >= 0);
|
||||||
|
- s->buffer = memdup_suffix0(buffer, size);
|
||||||
|
- assert_se(s->buffer);
|
||||||
|
- s->buffer_size = size + 1;
|
||||||
|
+
|
||||||
|
+ if (buffer) {
|
||||||
|
+ s->buffer = memdup_suffix0(buffer, size);
|
||||||
|
+ assert_se(s->buffer);
|
||||||
|
+ s->buffer_size = size + 1;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
void fuzz_journald_processing_function(
|
||||||
|
diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build
|
||||||
|
index 897c02e4ae..eea9117360 100644
|
||||||
|
--- a/src/fuzz/meson.build
|
||||||
|
+++ b/src/fuzz/meson.build
|
||||||
|
@@ -51,6 +51,12 @@ fuzzers += [
|
||||||
|
libshared],
|
||||||
|
[libselinux]],
|
||||||
|
|
||||||
|
+ [['src/fuzz/fuzz-journald-stream.c',
|
||||||
|
+ 'src/fuzz/fuzz-journald.c'],
|
||||||
|
+ [libjournal_core,
|
||||||
|
+ libshared],
|
||||||
|
+ [libselinux]],
|
||||||
|
+
|
||||||
|
[['src/fuzz/fuzz-journald-syslog.c',
|
||||||
|
'src/fuzz/fuzz-journald.c'],
|
||||||
|
[libjournal_core,
|
||||||
|
diff --git a/src/journal/journald-stream.c b/src/journal/journald-stream.c
|
||||||
|
index dbf3503a82..6f8a4011ff 100644
|
||||||
|
--- a/src/journal/journald-stream.c
|
||||||
|
+++ b/src/journal/journald-stream.c
|
||||||
|
@@ -125,7 +125,7 @@ void stdout_stream_free(StdoutStream *s) {
|
||||||
|
|
||||||
|
DEFINE_TRIVIAL_CLEANUP_FUNC(StdoutStream*, stdout_stream_free);
|
||||||
|
|
||||||
|
-static void stdout_stream_destroy(StdoutStream *s) {
|
||||||
|
+void stdout_stream_destroy(StdoutStream *s) {
|
||||||
|
if (!s)
|
||||||
|
return;
|
||||||
|
|
||||||
|
@@ -534,7 +534,7 @@ terminate:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int stdout_stream_install(Server *s, int fd, StdoutStream **ret) {
|
||||||
|
+int stdout_stream_install(Server *s, int fd, StdoutStream **ret) {
|
||||||
|
_cleanup_(stdout_stream_freep) StdoutStream *stream = NULL;
|
||||||
|
sd_id128_t id;
|
||||||
|
int r;
|
||||||
|
diff --git a/src/journal/journald-stream.h b/src/journal/journald-stream.h
|
||||||
|
index bc5622ab3b..487376e763 100644
|
||||||
|
--- a/src/journal/journald-stream.h
|
||||||
|
+++ b/src/journal/journald-stream.h
|
||||||
|
@@ -10,4 +10,6 @@ int server_open_stdout_socket(Server *s);
|
||||||
|
int server_restore_streams(Server *s, FDSet *fds);
|
||||||
|
|
||||||
|
void stdout_stream_free(StdoutStream *s);
|
||||||
|
+int stdout_stream_install(Server *s, int fd, StdoutStream **ret);
|
||||||
|
+void stdout_stream_destroy(StdoutStream *s);
|
||||||
|
void stdout_stream_send_notify(StdoutStream *s);
|
||||||
|
diff --git a/test/fuzz/fuzz-journald-stream/basic b/test/fuzz/fuzz-journald-stream/basic
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..a088f1a539
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/fuzz/fuzz-journald-stream/basic
|
||||||
|
@@ -0,0 +1,8 @@
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+6
|
||||||
|
+1
|
||||||
|
+0
|
||||||
|
+0
|
||||||
|
+0
|
||||||
|
+hey
|
||||||
|
\ No newline at end of file
|
@ -0,0 +1,96 @@
|
|||||||
|
From 76e2fa8ed4bbee7c625e3b790f2e38a59fffd93d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Evgeny Vereshchagin <evvers@ya.ru>
|
||||||
|
Date: Fri, 23 Nov 2018 00:27:19 +0100
|
||||||
|
Subject: [PATCH] tests: add a fuzzer for server_process_native_file
|
||||||
|
|
||||||
|
(cherry picked from commit a4aa59bae206eebb4703b291147144def5d4bb3e)
|
||||||
|
|
||||||
|
Resolves: #1764560
|
||||||
|
---
|
||||||
|
src/fuzz/fuzz-journald-native-fd.c | 47 ++++++++++++++++++++++++
|
||||||
|
src/fuzz/meson.build | 6 +++
|
||||||
|
test/fuzz/fuzz-journald-native-fd/basic | Bin 0 -> 34 bytes
|
||||||
|
3 files changed, 53 insertions(+)
|
||||||
|
create mode 100644 src/fuzz/fuzz-journald-native-fd.c
|
||||||
|
create mode 100644 test/fuzz/fuzz-journald-native-fd/basic
|
||||||
|
|
||||||
|
diff --git a/src/fuzz/fuzz-journald-native-fd.c b/src/fuzz/fuzz-journald-native-fd.c
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..95415d9f85
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/fuzz/fuzz-journald-native-fd.c
|
||||||
|
@@ -0,0 +1,47 @@
|
||||||
|
+/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
+
|
||||||
|
+#include "fd-util.h"
|
||||||
|
+#include "fileio.h"
|
||||||
|
+#include "fs-util.h"
|
||||||
|
+#include "fuzz.h"
|
||||||
|
+#include "fuzz-journald.h"
|
||||||
|
+#include "journald-native.h"
|
||||||
|
+#include "memfd-util.h"
|
||||||
|
+#include "process-util.h"
|
||||||
|
+
|
||||||
|
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
|
+ Server s;
|
||||||
|
+ _cleanup_close_ int sealed_fd = -1, unsealed_fd = -1;
|
||||||
|
+ _cleanup_(unlink_tempfilep) char name[] = "/tmp/fuzz-journald-native-fd.XXXXXX";
|
||||||
|
+ char *label = NULL;
|
||||||
|
+ size_t label_len = 0;
|
||||||
|
+ struct ucred ucred;
|
||||||
|
+ struct timeval *tv = NULL;
|
||||||
|
+
|
||||||
|
+ if (!getenv("SYSTEMD_LOG_LEVEL"))
|
||||||
|
+ log_set_max_level(LOG_CRIT);
|
||||||
|
+
|
||||||
|
+ dummy_server_init(&s, NULL, 0);
|
||||||
|
+
|
||||||
|
+ sealed_fd = memfd_new(NULL);
|
||||||
|
+ assert_se(sealed_fd >= 0);
|
||||||
|
+ assert_se(write(sealed_fd, data, size) == (ssize_t) size);
|
||||||
|
+ assert_se(memfd_set_sealed(sealed_fd) >= 0);
|
||||||
|
+ assert_se(lseek(sealed_fd, 0, SEEK_SET) == 0);
|
||||||
|
+ ucred = (struct ucred) {
|
||||||
|
+ .pid = getpid_cached(),
|
||||||
|
+ .uid = geteuid(),
|
||||||
|
+ .gid = getegid(),
|
||||||
|
+ };
|
||||||
|
+ server_process_native_file(&s, sealed_fd, &ucred, tv, label, label_len);
|
||||||
|
+
|
||||||
|
+ unsealed_fd = mkostemp_safe(name);
|
||||||
|
+ assert_se(unsealed_fd >= 0);
|
||||||
|
+ assert_se(write(unsealed_fd, data, size) == (ssize_t) size);
|
||||||
|
+ assert_se(lseek(unsealed_fd, 0, SEEK_SET) == 0);
|
||||||
|
+ server_process_native_file(&s, unsealed_fd, &ucred, tv, label, label_len);
|
||||||
|
+
|
||||||
|
+ server_done(&s);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build
|
||||||
|
index eea9117360..5315d2771c 100644
|
||||||
|
--- a/src/fuzz/meson.build
|
||||||
|
+++ b/src/fuzz/meson.build
|
||||||
|
@@ -51,6 +51,12 @@ fuzzers += [
|
||||||
|
libshared],
|
||||||
|
[libselinux]],
|
||||||
|
|
||||||
|
+ [['src/fuzz/fuzz-journald-native-fd.c',
|
||||||
|
+ 'src/fuzz/fuzz-journald.c'],
|
||||||
|
+ [libjournal_core,
|
||||||
|
+ libshared],
|
||||||
|
+ [libselinux]],
|
||||||
|
+
|
||||||
|
[['src/fuzz/fuzz-journald-stream.c',
|
||||||
|
'src/fuzz/fuzz-journald.c'],
|
||||||
|
[libjournal_core,
|
||||||
|
diff --git a/test/fuzz/fuzz-journald-native-fd/basic b/test/fuzz/fuzz-journald-native-fd/basic
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000000000000000000000000000000000..65f89705a655618851c0e446efaa5c633adf425f
|
||||||
|
GIT binary patch
|
||||||
|
literal 34
|
||||||
|
kcmeZu4Gwm6cjaPXfB;7>M@KGyCofm$koW*k7h3}^0B8*cRR910
|
||||||
|
|
||||||
|
literal 0
|
||||||
|
HcmV?d00001
|
||||||
|
|
@ -0,0 +1,47 @@
|
|||||||
|
From 2d197adc6d7109d5901401a90288530582f3f991 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Tue, 26 Feb 2019 13:00:35 +0100
|
||||||
|
Subject: [PATCH] fuzz-journal-stream: avoid assertion failure on samples which
|
||||||
|
don't fit in pipe
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=11587.
|
||||||
|
We had a sample which was large enough that write(2) failed to push all the
|
||||||
|
data into the pipe, and an assert failed. The code could be changed to use
|
||||||
|
a loop, but then we'd need to interleave writes and sd_event_run (to process
|
||||||
|
the journal). I don't think the complexity is worth it — fuzzing works best
|
||||||
|
if the sample is not too huge anyway. So let's just reject samples above 64k,
|
||||||
|
and tell oss-fuzz about this limit.
|
||||||
|
|
||||||
|
(cherry picked from commit eafadd069c4e30ed62173123326a7237448615d1)
|
||||||
|
|
||||||
|
Resolves: #1764560
|
||||||
|
---
|
||||||
|
src/fuzz/fuzz-journald-stream.c | 2 +-
|
||||||
|
src/fuzz/fuzz-journald-stream.options | 2 ++
|
||||||
|
2 files changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
create mode 100644 src/fuzz/fuzz-journald-stream.options
|
||||||
|
|
||||||
|
diff --git a/src/fuzz/fuzz-journald-stream.c b/src/fuzz/fuzz-journald-stream.c
|
||||||
|
index 247c0889bc..693b197d3a 100644
|
||||||
|
--- a/src/fuzz/fuzz-journald-stream.c
|
||||||
|
+++ b/src/fuzz/fuzz-journald-stream.c
|
||||||
|
@@ -14,7 +14,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
|
StdoutStream *stream;
|
||||||
|
int v;
|
||||||
|
|
||||||
|
- if (size == 0)
|
||||||
|
+ if (size == 0 || size > 65536)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!getenv("SYSTEMD_LOG_LEVEL"))
|
||||||
|
diff --git a/src/fuzz/fuzz-journald-stream.options b/src/fuzz/fuzz-journald-stream.options
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000000..678d526b1e
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/fuzz/fuzz-journald-stream.options
|
||||||
|
@@ -0,0 +1,2 @@
|
||||||
|
+[libfuzzer]
|
||||||
|
+max_len = 65536
|
@ -0,0 +1,45 @@
|
|||||||
|
From 3521217c88b364e2c5b10a1e35d3c036b1ecba64 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Evgeny Vereshchagin <evvers@ya.ru>
|
||||||
|
Date: Fri, 10 Aug 2018 12:55:09 +0000
|
||||||
|
Subject: [PATCH] journald: take leading spaces into account in
|
||||||
|
syslog_parse_identifier
|
||||||
|
|
||||||
|
This is a kind of follow-up to e88baee88fad8bc59d3 which should finally fix
|
||||||
|
the issue which that commit was supposed to fix.
|
||||||
|
|
||||||
|
(cherry picked from commit 937b1171378bc1000a34fcdfe9534d898227e35f)
|
||||||
|
|
||||||
|
Resolves: #1764560
|
||||||
|
---
|
||||||
|
src/journal/journald-syslog.c | 3 ++-
|
||||||
|
src/journal/test-journal-syslog.c | 2 ++
|
||||||
|
2 files changed, 4 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/journal/journald-syslog.c b/src/journal/journald-syslog.c
|
||||||
|
index e0b55cc566..ae966763a0 100644
|
||||||
|
--- a/src/journal/journald-syslog.c
|
||||||
|
+++ b/src/journal/journald-syslog.c
|
||||||
|
@@ -223,8 +223,9 @@ size_t syslog_parse_identifier(const char **buf, char **identifier, char **pid)
|
||||||
|
if (p[e] != '\0' && strchr(WHITESPACE, p[e]))
|
||||||
|
e++;
|
||||||
|
|
||||||
|
+ l = (p - *buf) + e;
|
||||||
|
*buf = p + e;
|
||||||
|
- return e;
|
||||||
|
+ return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void syslog_skip_date(char **buf) {
|
||||||
|
diff --git a/src/journal/test-journal-syslog.c b/src/journal/test-journal-syslog.c
|
||||||
|
index 120477cc9f..415b9d23ca 100644
|
||||||
|
--- a/src/journal/test-journal-syslog.c
|
||||||
|
+++ b/src/journal/test-journal-syslog.c
|
||||||
|
@@ -41,6 +41,8 @@ int main(void) {
|
||||||
|
test_syslog_parse_identifier(" ", NULL, NULL, " ", 0);
|
||||||
|
test_syslog_parse_identifier(":", "", NULL, "", 1);
|
||||||
|
test_syslog_parse_identifier(": ", "", NULL, " ", 2);
|
||||||
|
+ test_syslog_parse_identifier(" :", "", NULL, "", 2);
|
||||||
|
+ test_syslog_parse_identifier(" pidu:", "pidu", NULL, "", 8);
|
||||||
|
test_syslog_parse_identifier("pidu:", "pidu", NULL, "", 5);
|
||||||
|
test_syslog_parse_identifier("pidu: ", "pidu", NULL, "", 6);
|
||||||
|
test_syslog_parse_identifier("pidu : ", NULL, NULL, "pidu : ", 0);
|
@ -0,0 +1,43 @@
|
|||||||
|
From 5df63c2ddf93bab5e7f13e09dfb1f97a011b3451 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Taro Yamada <archer_ame@yahoo.co.jp>
|
||||||
|
Date: Sun, 27 Jan 2019 13:50:04 +0900
|
||||||
|
Subject: [PATCH] Add a warning about the difference in permissions between
|
||||||
|
existing directories and unit settings.
|
||||||
|
|
||||||
|
To follows the intent of 30c81ce, this change does not execute chmod() and just add warnings.
|
||||||
|
|
||||||
|
(cherry picked from commit 6cff72eb0a18d8547f005a481cd0622d3bc78483)
|
||||||
|
|
||||||
|
Related: #1778384
|
||||||
|
---
|
||||||
|
src/core/execute.c | 17 +++++++++++++++--
|
||||||
|
1 file changed, 15 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/execute.c b/src/core/execute.c
|
||||||
|
index 8293c522bc..9ddba00421 100644
|
||||||
|
--- a/src/core/execute.c
|
||||||
|
+++ b/src/core/execute.c
|
||||||
|
@@ -2099,8 +2099,21 @@ static int setup_exec_directory(
|
||||||
|
r = mkdir_label(p, context->directories[type].mode);
|
||||||
|
if (r < 0 && r != -EEXIST)
|
||||||
|
goto fail;
|
||||||
|
- if (r == -EEXIST && !context->dynamic_user)
|
||||||
|
- continue;
|
||||||
|
+ if (r == -EEXIST) {
|
||||||
|
+ struct stat st;
|
||||||
|
+
|
||||||
|
+ if (stat(p, &st) < 0) {
|
||||||
|
+ r = -errno;
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+ if (((st.st_mode ^ context->directories[type].mode) & 07777) != 0)
|
||||||
|
+ log_warning("%s \'%s\' already exists but the mode is different. "
|
||||||
|
+ "(filesystem: %o %sMode: %o)",
|
||||||
|
+ exec_directory_type_to_string(type), *rt,
|
||||||
|
+ st.st_mode & 07777, exec_directory_type_to_string(type), context->directories[type].mode & 07777);
|
||||||
|
+ if (!context->dynamic_user)
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't change the owner of the configuration directory, as in the common case it is not written to by
|
@ -0,0 +1,32 @@
|
|||||||
|
From 81ca39b7b38ef1d44cc146efe75bef412e7c4c97 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Thu, 14 Mar 2019 17:01:46 +0100
|
||||||
|
Subject: [PATCH] execute: remove one redundant comparison check
|
||||||
|
|
||||||
|
(cherry picked from commit d484580ca6f0e79abe6f3f5c677323a22d9e22d7)
|
||||||
|
|
||||||
|
Related: #1778384
|
||||||
|
---
|
||||||
|
src/core/execute.c | 7 ++++---
|
||||||
|
1 file changed, 4 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/execute.c b/src/core/execute.c
|
||||||
|
index 9ddba00421..46aa733937 100644
|
||||||
|
--- a/src/core/execute.c
|
||||||
|
+++ b/src/core/execute.c
|
||||||
|
@@ -2097,11 +2097,12 @@ static int setup_exec_directory(
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
r = mkdir_label(p, context->directories[type].mode);
|
||||||
|
- if (r < 0 && r != -EEXIST)
|
||||||
|
- goto fail;
|
||||||
|
- if (r == -EEXIST) {
|
||||||
|
+ if (r < 0) {
|
||||||
|
struct stat st;
|
||||||
|
|
||||||
|
+ if (r != -EEXIST)
|
||||||
|
+ goto fail;
|
||||||
|
+
|
||||||
|
if (stat(p, &st) < 0) {
|
||||||
|
r = -errno;
|
||||||
|
goto fail;
|
@ -0,0 +1,88 @@
|
|||||||
|
From 789806ac06bb13d1b579fef47dbb85f224b6dbb1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Lennart Poettering <lennart@poettering.net>
|
||||||
|
Date: Thu, 14 Mar 2019 17:19:30 +0100
|
||||||
|
Subject: [PATCH] core: change ownership/mode of the execution directories also
|
||||||
|
for static users
|
||||||
|
|
||||||
|
It's probably unexpected if we do a recursive chown() when dynamic users
|
||||||
|
are used but not on static users.
|
||||||
|
|
||||||
|
hence, let's tweak the logic slightly, and recursively chown in both
|
||||||
|
cases, except when operating on the configuration directory.
|
||||||
|
|
||||||
|
Fixes: #11842
|
||||||
|
(cherry picked from commit 206e9864de460dd79d9edd7bedb47dee168765e1)
|
||||||
|
|
||||||
|
Resolves: #1778384
|
||||||
|
---
|
||||||
|
src/core/execute.c | 47 +++++++++++++++++++++++++---------------------
|
||||||
|
1 file changed, 26 insertions(+), 21 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/execute.c b/src/core/execute.c
|
||||||
|
index 46aa733937..c42300a41e 100644
|
||||||
|
--- a/src/core/execute.c
|
||||||
|
+++ b/src/core/execute.c
|
||||||
|
@@ -2090,37 +2090,42 @@ static int setup_exec_directory(
|
||||||
|
if (r < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
- /* Lock down the access mode */
|
||||||
|
- if (chmod(pp, context->directories[type].mode) < 0) {
|
||||||
|
- r = -errno;
|
||||||
|
- goto fail;
|
||||||
|
- }
|
||||||
|
} else {
|
||||||
|
r = mkdir_label(p, context->directories[type].mode);
|
||||||
|
if (r < 0) {
|
||||||
|
- struct stat st;
|
||||||
|
-
|
||||||
|
if (r != -EEXIST)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
- if (stat(p, &st) < 0) {
|
||||||
|
- r = -errno;
|
||||||
|
- goto fail;
|
||||||
|
- }
|
||||||
|
- if (((st.st_mode ^ context->directories[type].mode) & 07777) != 0)
|
||||||
|
- log_warning("%s \'%s\' already exists but the mode is different. "
|
||||||
|
- "(filesystem: %o %sMode: %o)",
|
||||||
|
- exec_directory_type_to_string(type), *rt,
|
||||||
|
- st.st_mode & 07777, exec_directory_type_to_string(type), context->directories[type].mode & 07777);
|
||||||
|
- if (!context->dynamic_user)
|
||||||
|
+ if (type == EXEC_DIRECTORY_CONFIGURATION) {
|
||||||
|
+ struct stat st;
|
||||||
|
+
|
||||||
|
+ /* Don't change the owner/access mode of the configuration directory,
|
||||||
|
+ * as in the common case it is not written to by a service, and shall
|
||||||
|
+ * not be writable. */
|
||||||
|
+
|
||||||
|
+ if (stat(p, &st) < 0) {
|
||||||
|
+ r = -errno;
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Still complain if the access mode doesn't match */
|
||||||
|
+ if (((st.st_mode ^ context->directories[type].mode) & 07777) != 0)
|
||||||
|
+ log_warning("%s \'%s\' already exists but the mode is different. "
|
||||||
|
+ "(File system: %o %sMode: %o)",
|
||||||
|
+ exec_directory_type_to_string(type), *rt,
|
||||||
|
+ st.st_mode & 07777, exec_directory_type_to_string(type), context->directories[type].mode & 07777);
|
||||||
|
+
|
||||||
|
continue;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* Don't change the owner of the configuration directory, as in the common case it is not written to by
|
||||||
|
- * a service, and shall not be writable. */
|
||||||
|
- if (type == EXEC_DIRECTORY_CONFIGURATION)
|
||||||
|
- continue;
|
||||||
|
+ /* Lock down the access mode (we use chmod_and_chown() to make this idempotent. We don't
|
||||||
|
+ * specifiy UID/GID here, so that path_chown_recursive() can optimize things depending on the
|
||||||
|
+ * current UID/GID ownership.) */
|
||||||
|
+ r = chmod_and_chown(pp ?: p, context->directories[type].mode, UID_INVALID, GID_INVALID);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ goto fail;
|
||||||
|
|
||||||
|
/* Then, change the ownership of the whole tree, if necessary */
|
||||||
|
r = path_chown_recursive(pp ?: p, uid, gid);
|
@ -0,0 +1,25 @@
|
|||||||
|
From 5d7e8cb0e12e4642a760cf00cbb6caf4c07b9cd9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Sun, 19 May 2019 16:05:02 +0200
|
||||||
|
Subject: [PATCH] core/dbus-execute: remove unnecessary initialization
|
||||||
|
|
||||||
|
(cherry picked from commit bd0abfaea1514bdd7cb60228d7a3f94c17ba916d)
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
---
|
||||||
|
src/core/dbus-execute.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
|
||||||
|
index 33a91c012e..5379545d57 100644
|
||||||
|
--- a/src/core/dbus-execute.c
|
||||||
|
+++ b/src/core/dbus-execute.c
|
||||||
|
@@ -1552,7 +1552,7 @@ int bus_exec_context_set_transient_property(
|
||||||
|
#endif
|
||||||
|
if (streq(name, "CPUAffinity")) {
|
||||||
|
const void *a;
|
||||||
|
- size_t n = 0;
|
||||||
|
+ size_t n;
|
||||||
|
|
||||||
|
r = sd_bus_message_read_array(message, 'y', &a, &n);
|
||||||
|
if (r < 0)
|
@ -0,0 +1,215 @@
|
|||||||
|
From 46b4d26c54a773f7da350e89562039ccc5157a8f Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Sun, 19 May 2019 18:02:38 +0200
|
||||||
|
Subject: [PATCH] shared/cpu-set-util: move the part to print cpu-set into a
|
||||||
|
separate function
|
||||||
|
|
||||||
|
Also avoid unnecessary asprintf() when we can write to the output area
|
||||||
|
directly.
|
||||||
|
|
||||||
|
(cherry picked from commit a832893f9c4f0a0329768e90f67e2fa24bb0008e)
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
---
|
||||||
|
src/basic/cpu-set-util.c | 21 +++++++++++++++++++++
|
||||||
|
src/basic/cpu-set-util.h | 1 +
|
||||||
|
src/core/dbus-execute.c | 29 +++++------------------------
|
||||||
|
src/test/test-cpu-set-util.c | 29 +++++++++++++++++++++++++++++
|
||||||
|
4 files changed, 56 insertions(+), 24 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c
|
||||||
|
index b1c927bcb8..8f24a2601a 100644
|
||||||
|
--- a/src/basic/cpu-set-util.c
|
||||||
|
+++ b/src/basic/cpu-set-util.c
|
||||||
|
@@ -5,6 +5,7 @@
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
|
#include "alloc-util.h"
|
||||||
|
@@ -15,6 +16,26 @@
|
||||||
|
#include "parse-util.h"
|
||||||
|
#include "string-util.h"
|
||||||
|
|
||||||
|
+char* cpu_set_to_string(const cpu_set_t *set, size_t setsize) {
|
||||||
|
+ _cleanup_free_ char *str = NULL;
|
||||||
|
+ size_t allocated = 0, len = 0;
|
||||||
|
+ int i, r;
|
||||||
|
+
|
||||||
|
+ for (i = 0; (size_t) i < setsize * 8; i++) {
|
||||||
|
+ if (!CPU_ISSET_S(i, setsize, set))
|
||||||
|
+ continue;
|
||||||
|
+
|
||||||
|
+ if (!GREEDY_REALLOC(str, allocated, len + 1 + DECIMAL_STR_MAX(int)))
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ r = sprintf(str + len, len > 0 ? " %d" : "%d", i);
|
||||||
|
+ assert_se(r > 0);
|
||||||
|
+ len += r;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return TAKE_PTR(str) ?: strdup("");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
|
||||||
|
cpu_set_t *c;
|
||||||
|
unsigned n = 1024;
|
||||||
|
diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h
|
||||||
|
index 88470fe15a..3c546beb55 100644
|
||||||
|
--- a/src/basic/cpu-set-util.h
|
||||||
|
+++ b/src/basic/cpu-set-util.h
|
||||||
|
@@ -26,6 +26,7 @@ static inline cpu_set_t* cpu_set_mfree(cpu_set_t *p) {
|
||||||
|
|
||||||
|
cpu_set_t* cpu_set_malloc(unsigned *ncpus);
|
||||||
|
|
||||||
|
+char* cpu_set_to_string(const cpu_set_t *set, size_t setsize);
|
||||||
|
int parse_cpu_set_internal(const char *rvalue, cpu_set_t **cpu_set, bool warn, const char *unit, const char *filename, unsigned line, const char *lvalue);
|
||||||
|
|
||||||
|
static inline int parse_cpu_set_and_warn(const char *rvalue, cpu_set_t **cpu_set, const char *unit, const char *filename, unsigned line, const char *lvalue) {
|
||||||
|
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
|
||||||
|
index 5379545d57..d9f4445745 100644
|
||||||
|
--- a/src/core/dbus-execute.c
|
||||||
|
+++ b/src/core/dbus-execute.c
|
||||||
|
@@ -1565,32 +1565,13 @@ int bus_exec_context_set_transient_property(
|
||||||
|
unit_write_settingf(u, flags, name, "%s=", name);
|
||||||
|
} else {
|
||||||
|
_cleanup_free_ char *str = NULL;
|
||||||
|
- size_t allocated = 0, len = 0, i, ncpus;
|
||||||
|
+ size_t ncpus;
|
||||||
|
|
||||||
|
- ncpus = CPU_SIZE_TO_NUM(n);
|
||||||
|
-
|
||||||
|
- for (i = 0; i < ncpus; i++) {
|
||||||
|
- _cleanup_free_ char *p = NULL;
|
||||||
|
- size_t add;
|
||||||
|
-
|
||||||
|
- if (!CPU_ISSET_S(i, n, (cpu_set_t*) a))
|
||||||
|
- continue;
|
||||||
|
-
|
||||||
|
- r = asprintf(&p, "%zu", i);
|
||||||
|
- if (r < 0)
|
||||||
|
- return -ENOMEM;
|
||||||
|
-
|
||||||
|
- add = strlen(p);
|
||||||
|
-
|
||||||
|
- if (!GREEDY_REALLOC(str, allocated, len + add + 2))
|
||||||
|
- return -ENOMEM;
|
||||||
|
-
|
||||||
|
- strcpy(mempcpy(str + len, p, add), " ");
|
||||||
|
- len += add + 1;
|
||||||
|
- }
|
||||||
|
+ str = cpu_set_to_string(a, n);
|
||||||
|
+ if (!str)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
|
||||||
|
- if (len != 0)
|
||||||
|
- str[len - 1] = '\0';
|
||||||
|
+ ncpus = CPU_SIZE_TO_NUM(n);
|
||||||
|
|
||||||
|
if (!c->cpuset || c->cpuset_ncpus < ncpus) {
|
||||||
|
cpu_set_t *cpuset;
|
||||||
|
diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
|
||||||
|
index c9272459b4..ff5edb2a69 100644
|
||||||
|
--- a/src/test/test-cpu-set-util.c
|
||||||
|
+++ b/src/test/test-cpu-set-util.c
|
||||||
|
@@ -6,6 +6,7 @@
|
||||||
|
|
||||||
|
static void test_parse_cpu_set(void) {
|
||||||
|
cpu_set_t *c = NULL;
|
||||||
|
+ _cleanup_free_ char *str = NULL;
|
||||||
|
int ncpus;
|
||||||
|
int cpu;
|
||||||
|
|
||||||
|
@@ -15,6 +16,10 @@ static void test_parse_cpu_set(void) {
|
||||||
|
assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
assert_se(CPU_ISSET_S(2, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 2);
|
||||||
|
+
|
||||||
|
+ assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
|
||||||
|
+ log_info("cpu_set_to_string: %s", str);
|
||||||
|
+ str = mfree(str);
|
||||||
|
c = cpu_set_mfree(c);
|
||||||
|
|
||||||
|
/* A more interesting range */
|
||||||
|
@@ -25,6 +30,9 @@ static void test_parse_cpu_set(void) {
|
||||||
|
assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
for (cpu = 8; cpu < 12; cpu++)
|
||||||
|
assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
+ assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
|
||||||
|
+ log_info("cpu_set_to_string: %s", str);
|
||||||
|
+ str = mfree(str);
|
||||||
|
c = cpu_set_mfree(c);
|
||||||
|
|
||||||
|
/* Quoted strings */
|
||||||
|
@@ -33,6 +41,9 @@ static void test_parse_cpu_set(void) {
|
||||||
|
assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 4);
|
||||||
|
for (cpu = 8; cpu < 12; cpu++)
|
||||||
|
assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
+ assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
|
||||||
|
+ log_info("cpu_set_to_string: %s", str);
|
||||||
|
+ str = mfree(str);
|
||||||
|
c = cpu_set_mfree(c);
|
||||||
|
|
||||||
|
/* Use commas as separators */
|
||||||
|
@@ -43,6 +54,9 @@ static void test_parse_cpu_set(void) {
|
||||||
|
assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
for (cpu = 8; cpu < 12; cpu++)
|
||||||
|
assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
+ assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
|
||||||
|
+ log_info("cpu_set_to_string: %s", str);
|
||||||
|
+ str = mfree(str);
|
||||||
|
c = cpu_set_mfree(c);
|
||||||
|
|
||||||
|
/* Commas with spaces (and trailing comma, space) */
|
||||||
|
@@ -51,6 +65,9 @@ static void test_parse_cpu_set(void) {
|
||||||
|
assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
|
||||||
|
for (cpu = 0; cpu < 8; cpu++)
|
||||||
|
assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
+ assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
|
||||||
|
+ log_info("cpu_set_to_string: %s", str);
|
||||||
|
+ str = mfree(str);
|
||||||
|
c = cpu_set_mfree(c);
|
||||||
|
|
||||||
|
/* Ranges */
|
||||||
|
@@ -61,6 +78,9 @@ static void test_parse_cpu_set(void) {
|
||||||
|
assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
for (cpu = 8; cpu < 12; cpu++)
|
||||||
|
assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
+ assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
|
||||||
|
+ log_info("cpu_set_to_string: %s", str);
|
||||||
|
+ str = mfree(str);
|
||||||
|
c = cpu_set_mfree(c);
|
||||||
|
|
||||||
|
/* Ranges with trailing comma, space */
|
||||||
|
@@ -71,6 +91,9 @@ static void test_parse_cpu_set(void) {
|
||||||
|
assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
for (cpu = 8; cpu < 12; cpu++)
|
||||||
|
assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
+ assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
|
||||||
|
+ log_info("cpu_set_to_string: %s", str);
|
||||||
|
+ str = mfree(str);
|
||||||
|
c = cpu_set_mfree(c);
|
||||||
|
|
||||||
|
/* Negative range (returns empty cpu_set) */
|
||||||
|
@@ -85,6 +108,9 @@ static void test_parse_cpu_set(void) {
|
||||||
|
assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 12);
|
||||||
|
for (cpu = 0; cpu < 12; cpu++)
|
||||||
|
assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
+ assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
|
||||||
|
+ log_info("cpu_set_to_string: %s", str);
|
||||||
|
+ str = mfree(str);
|
||||||
|
c = cpu_set_mfree(c);
|
||||||
|
|
||||||
|
/* Mix ranges and individual CPUs */
|
||||||
|
@@ -95,6 +121,9 @@ static void test_parse_cpu_set(void) {
|
||||||
|
assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
for (cpu = 4; cpu < 12; cpu++)
|
||||||
|
assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
+ assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
|
||||||
|
+ log_info("cpu_set_to_string: %s", str);
|
||||||
|
+ str = mfree(str);
|
||||||
|
c = cpu_set_mfree(c);
|
||||||
|
|
||||||
|
/* Garbage */
|
@ -0,0 +1,29 @@
|
|||||||
|
From d6935e61de30967aa82b7722f36193ba782b75e4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Sun, 19 May 2019 18:08:39 +0200
|
||||||
|
Subject: [PATCH] shared/cpu-set-util: remove now-unused CPU_SIZE_TO_NUM()
|
||||||
|
|
||||||
|
(cherry picked from commit b12ef7141648be40fd8c4b0209a742f2151736d9)
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
---
|
||||||
|
src/basic/cpu-set-util.h | 6 ------
|
||||||
|
1 file changed, 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h
|
||||||
|
index 3c546beb55..20612a8876 100644
|
||||||
|
--- a/src/basic/cpu-set-util.h
|
||||||
|
+++ b/src/basic/cpu-set-util.h
|
||||||
|
@@ -9,12 +9,6 @@
|
||||||
|
|
||||||
|
#include "macro.h"
|
||||||
|
|
||||||
|
-#ifdef __NCPUBITS
|
||||||
|
-#define CPU_SIZE_TO_NUM(n) ((n) * __NCPUBITS)
|
||||||
|
-#else
|
||||||
|
-#define CPU_SIZE_TO_NUM(n) ((n) * sizeof(cpu_set_t) * 8)
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
DEFINE_TRIVIAL_CLEANUP_FUNC(cpu_set_t*, CPU_FREE);
|
||||||
|
#define _cleanup_cpu_free_ _cleanup_(CPU_FREEp)
|
||||||
|
|
932
SOURCES/0272-Rework-cpu-affinity-parsing.patch
Normal file
932
SOURCES/0272-Rework-cpu-affinity-parsing.patch
Normal file
@ -0,0 +1,932 @@
|
|||||||
|
From 61e5aed87f1b82a51c6ea8ccde96805cb63e5b15 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Tue, 21 May 2019 08:45:19 +0200
|
||||||
|
Subject: [PATCH] Rework cpu affinity parsing
|
||||||
|
|
||||||
|
The CPU_SET_S api is pretty bad. In particular, it has a parameter for the size
|
||||||
|
of the array, but operations which take two (CPU_EQUAL_S) or even three arrays
|
||||||
|
(CPU_{AND,OR,XOR}_S) still take just one size. This means that all arrays must
|
||||||
|
be of the same size, or buffer overruns will occur. This is exactly what our
|
||||||
|
code would do, if it received an array of unexpected size over the network.
|
||||||
|
("Unexpected" here means anything different from what cpu_set_malloc() detects
|
||||||
|
as the "right" size.)
|
||||||
|
|
||||||
|
Let's rework this, and store the size in bytes of the allocated storage area.
|
||||||
|
|
||||||
|
The code will now parse any number up to 8191, independently of what the current
|
||||||
|
kernel supports. This matches the kernel maximum setting for any architecture,
|
||||||
|
to make things more portable.
|
||||||
|
|
||||||
|
Fixes #12605.
|
||||||
|
|
||||||
|
(cherry picked from commit 0985c7c4e22c8dbbea4398cf3453da45ebf63800)
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
---
|
||||||
|
src/basic/cpu-set-util.c | 133 +++++++++++++++++++++-----
|
||||||
|
src/basic/cpu-set-util.h | 47 ++++++---
|
||||||
|
src/core/dbus-execute.c | 35 ++-----
|
||||||
|
src/core/execute.c | 12 +--
|
||||||
|
src/core/execute.h | 4 +-
|
||||||
|
src/core/load-fragment.c | 31 +-----
|
||||||
|
src/core/main.c | 14 +--
|
||||||
|
src/nspawn/nspawn-settings.c | 33 +------
|
||||||
|
src/nspawn/nspawn-settings.h | 4 +-
|
||||||
|
src/nspawn/nspawn.c | 29 +++---
|
||||||
|
src/shared/bus-unit-util.c | 4 +-
|
||||||
|
src/test/test-cpu-set-util.c | 179 +++++++++++++++++++----------------
|
||||||
|
src/test/test-sizeof.c | 3 +
|
||||||
|
13 files changed, 286 insertions(+), 242 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c
|
||||||
|
index 8f24a2601a..fe440f6381 100644
|
||||||
|
--- a/src/basic/cpu-set-util.c
|
||||||
|
+++ b/src/basic/cpu-set-util.c
|
||||||
|
@@ -15,14 +15,15 @@
|
||||||
|
#include "macro.h"
|
||||||
|
#include "parse-util.h"
|
||||||
|
#include "string-util.h"
|
||||||
|
+#include "util.h"
|
||||||
|
|
||||||
|
-char* cpu_set_to_string(const cpu_set_t *set, size_t setsize) {
|
||||||
|
+char* cpu_set_to_string(const CPUSet *a) {
|
||||||
|
_cleanup_free_ char *str = NULL;
|
||||||
|
size_t allocated = 0, len = 0;
|
||||||
|
int i, r;
|
||||||
|
|
||||||
|
- for (i = 0; (size_t) i < setsize * 8; i++) {
|
||||||
|
- if (!CPU_ISSET_S(i, setsize, set))
|
||||||
|
+ for (i = 0; (size_t) i < a->allocated * 8; i++) {
|
||||||
|
+ if (!CPU_ISSET_S(i, a->allocated, a->set))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!GREEDY_REALLOC(str, allocated, len + 1 + DECIMAL_STR_MAX(int)))
|
||||||
|
@@ -65,24 +66,74 @@ cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-int parse_cpu_set_internal(
|
||||||
|
+static int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus) {
|
||||||
|
+ size_t need;
|
||||||
|
+
|
||||||
|
+ assert(cpu_set);
|
||||||
|
+
|
||||||
|
+ need = CPU_ALLOC_SIZE(ncpus);
|
||||||
|
+ if (need > cpu_set->allocated) {
|
||||||
|
+ cpu_set_t *t;
|
||||||
|
+
|
||||||
|
+ t = realloc(cpu_set->set, need);
|
||||||
|
+ if (!t)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ memzero((uint8_t*) t + cpu_set->allocated, need - cpu_set->allocated);
|
||||||
|
+
|
||||||
|
+ cpu_set->set = t;
|
||||||
|
+ cpu_set->allocated = need;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int cpu_set_add(CPUSet *cpu_set, unsigned cpu) {
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ if (cpu >= 8192)
|
||||||
|
+ /* As of kernel 5.1, CONFIG_NR_CPUS can be set to 8192 on PowerPC */
|
||||||
|
+ return -ERANGE;
|
||||||
|
+
|
||||||
|
+ r = cpu_set_realloc(cpu_set, cpu + 1);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ CPU_SET_S(cpu, cpu_set->allocated, cpu_set->set);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int cpu_set_add_all(CPUSet *a, const CPUSet *b) {
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ /* Do this backwards, so if we fail, we fail before changing anything. */
|
||||||
|
+ for (unsigned cpu_p1 = b->allocated * 8; cpu_p1 > 0; cpu_p1--)
|
||||||
|
+ if (CPU_ISSET_S(cpu_p1 - 1, b->allocated, b->set)) {
|
||||||
|
+ r = cpu_set_add(a, cpu_p1 - 1);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int parse_cpu_set_full(
|
||||||
|
const char *rvalue,
|
||||||
|
- cpu_set_t **cpu_set,
|
||||||
|
+ CPUSet *cpu_set,
|
||||||
|
bool warn,
|
||||||
|
const char *unit,
|
||||||
|
const char *filename,
|
||||||
|
unsigned line,
|
||||||
|
const char *lvalue) {
|
||||||
|
|
||||||
|
- _cleanup_cpu_free_ cpu_set_t *c = NULL;
|
||||||
|
+ _cleanup_(cpu_set_reset) CPUSet c = {};
|
||||||
|
const char *p = rvalue;
|
||||||
|
- unsigned ncpus = 0;
|
||||||
|
|
||||||
|
- assert(rvalue);
|
||||||
|
+ assert(p);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
_cleanup_free_ char *word = NULL;
|
||||||
|
- unsigned cpu, cpu_lower, cpu_upper;
|
||||||
|
+ unsigned cpu_lower, cpu_upper;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = extract_first_word(&p, &word, WHITESPACE ",", EXTRACT_QUOTES);
|
||||||
|
@@ -93,31 +144,63 @@ int parse_cpu_set_internal(
|
||||||
|
if (r == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
- if (!c) {
|
||||||
|
- c = cpu_set_malloc(&ncpus);
|
||||||
|
- if (!c)
|
||||||
|
- return warn ? log_oom() : -ENOMEM;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
r = parse_range(word, &cpu_lower, &cpu_upper);
|
||||||
|
if (r < 0)
|
||||||
|
return warn ? log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse CPU affinity '%s'", word) : r;
|
||||||
|
- if (cpu_lower >= ncpus || cpu_upper >= ncpus)
|
||||||
|
- return warn ? log_syntax(unit, LOG_ERR, filename, line, EINVAL, "CPU out of range '%s' ncpus is %u", word, ncpus) : -EINVAL;
|
||||||
|
|
||||||
|
if (cpu_lower > cpu_upper) {
|
||||||
|
if (warn)
|
||||||
|
- log_syntax(unit, LOG_WARNING, filename, line, 0, "Range '%s' is invalid, %u > %u, ignoring", word, cpu_lower, cpu_upper);
|
||||||
|
- continue;
|
||||||
|
+ log_syntax(unit, LOG_WARNING, filename, line, 0, "Range '%s' is invalid, %u > %u, ignoring.",
|
||||||
|
+ word, cpu_lower, cpu_upper);
|
||||||
|
+
|
||||||
|
+ /* Make sure something is allocated, to distinguish this from the empty case */
|
||||||
|
+ r = cpu_set_realloc(&c, 1);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
- for (cpu = cpu_lower; cpu <= cpu_upper; cpu++)
|
||||||
|
- CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c);
|
||||||
|
+ for (unsigned cpu_p1 = MIN(cpu_upper, UINT_MAX-1) + 1; cpu_p1 > cpu_lower; cpu_p1--) {
|
||||||
|
+ r = cpu_set_add(&c, cpu_p1 - 1);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return warn ? log_syntax(unit, LOG_ERR, filename, line, r,
|
||||||
|
+ "Cannot add CPU %u to set: %m", cpu_p1 - 1) : r;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
- /* On success, sets *cpu_set and returns ncpus for the system. */
|
||||||
|
- if (c)
|
||||||
|
- *cpu_set = TAKE_PTR(c);
|
||||||
|
+ /* On success, transfer ownership to the output variable */
|
||||||
|
+ *cpu_set = c;
|
||||||
|
+ c = (CPUSet) {};
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int parse_cpu_set_extend(
|
||||||
|
+ const char *rvalue,
|
||||||
|
+ CPUSet *old,
|
||||||
|
+ bool warn,
|
||||||
|
+ const char *unit,
|
||||||
|
+ const char *filename,
|
||||||
|
+ unsigned line,
|
||||||
|
+ const char *lvalue) {
|
||||||
|
+
|
||||||
|
+ _cleanup_(cpu_set_reset) CPUSet cpuset = {};
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ r = parse_cpu_set_full(rvalue, &cpuset, true, unit, filename, line, lvalue);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ if (!cpuset.set) {
|
||||||
|
+ /* An empty assignment resets the CPU list */
|
||||||
|
+ cpu_set_reset(old);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!old->set) {
|
||||||
|
+ *old = cpuset;
|
||||||
|
+ cpuset = (CPUSet) {};
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- return (int) ncpus;
|
||||||
|
+ return cpu_set_add_all(old, &cpuset);
|
||||||
|
}
|
||||||
|
diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h
|
||||||
|
index 20612a8876..eb31b362fe 100644
|
||||||
|
--- a/src/basic/cpu-set-util.h
|
||||||
|
+++ b/src/basic/cpu-set-util.h
|
||||||
|
@@ -12,23 +12,40 @@
|
||||||
|
DEFINE_TRIVIAL_CLEANUP_FUNC(cpu_set_t*, CPU_FREE);
|
||||||
|
#define _cleanup_cpu_free_ _cleanup_(CPU_FREEp)
|
||||||
|
|
||||||
|
-static inline cpu_set_t* cpu_set_mfree(cpu_set_t *p) {
|
||||||
|
- if (p)
|
||||||
|
- CPU_FREE(p);
|
||||||
|
- return NULL;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
cpu_set_t* cpu_set_malloc(unsigned *ncpus);
|
||||||
|
|
||||||
|
-char* cpu_set_to_string(const cpu_set_t *set, size_t setsize);
|
||||||
|
-int parse_cpu_set_internal(const char *rvalue, cpu_set_t **cpu_set, bool warn, const char *unit, const char *filename, unsigned line, const char *lvalue);
|
||||||
|
-
|
||||||
|
-static inline int parse_cpu_set_and_warn(const char *rvalue, cpu_set_t **cpu_set, const char *unit, const char *filename, unsigned line, const char *lvalue) {
|
||||||
|
- assert(lvalue);
|
||||||
|
-
|
||||||
|
- return parse_cpu_set_internal(rvalue, cpu_set, true, unit, filename, line, lvalue);
|
||||||
|
+/* This wraps the libc interface with a variable to keep the allocated size. */
|
||||||
|
+typedef struct CPUSet {
|
||||||
|
+ cpu_set_t *set;
|
||||||
|
+ size_t allocated; /* in bytes */
|
||||||
|
+} CPUSet;
|
||||||
|
+
|
||||||
|
+static inline void cpu_set_reset(CPUSet *a) {
|
||||||
|
+ assert((a->allocated > 0) == !!a->set);
|
||||||
|
+ if (a->set)
|
||||||
|
+ CPU_FREE(a->set);
|
||||||
|
+ *a = (CPUSet) {};
|
||||||
|
}
|
||||||
|
|
||||||
|
-static inline int parse_cpu_set(const char *rvalue, cpu_set_t **cpu_set){
|
||||||
|
- return parse_cpu_set_internal(rvalue, cpu_set, false, NULL, NULL, 0, NULL);
|
||||||
|
+int cpu_set_add_all(CPUSet *a, const CPUSet *b);
|
||||||
|
+
|
||||||
|
+char* cpu_set_to_string(const CPUSet *a);
|
||||||
|
+int parse_cpu_set_full(
|
||||||
|
+ const char *rvalue,
|
||||||
|
+ CPUSet *cpu_set,
|
||||||
|
+ bool warn,
|
||||||
|
+ const char *unit,
|
||||||
|
+ const char *filename, unsigned line,
|
||||||
|
+ const char *lvalue);
|
||||||
|
+int parse_cpu_set_extend(
|
||||||
|
+ const char *rvalue,
|
||||||
|
+ CPUSet *old,
|
||||||
|
+ bool warn,
|
||||||
|
+ const char *unit,
|
||||||
|
+ const char *filename,
|
||||||
|
+ unsigned line,
|
||||||
|
+ const char *lvalue);
|
||||||
|
+
|
||||||
|
+static inline int parse_cpu_set(const char *rvalue, CPUSet *cpu_set){
|
||||||
|
+ return parse_cpu_set_full(rvalue, cpu_set, false, NULL, NULL, 0, NULL);
|
||||||
|
}
|
||||||
|
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
|
||||||
|
index d9f4445745..08946627e3 100644
|
||||||
|
--- a/src/core/dbus-execute.c
|
||||||
|
+++ b/src/core/dbus-execute.c
|
||||||
|
@@ -220,7 +220,7 @@ static int property_get_cpu_affinity(
|
||||||
|
assert(reply);
|
||||||
|
assert(c);
|
||||||
|
|
||||||
|
- return sd_bus_message_append_array(reply, 'y', c->cpuset, CPU_ALLOC_SIZE(c->cpuset_ncpus));
|
||||||
|
+ return sd_bus_message_append_array(reply, 'y', c->cpu_set.set, c->cpu_set.allocated);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int property_get_timer_slack_nsec(
|
||||||
|
@@ -1560,37 +1560,22 @@ int bus_exec_context_set_transient_property(
|
||||||
|
|
||||||
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||||
|
if (n == 0) {
|
||||||
|
- c->cpuset = cpu_set_mfree(c->cpuset);
|
||||||
|
- c->cpuset_ncpus = 0;
|
||||||
|
+ cpu_set_reset(&c->cpu_set);
|
||||||
|
unit_write_settingf(u, flags, name, "%s=", name);
|
||||||
|
} else {
|
||||||
|
_cleanup_free_ char *str = NULL;
|
||||||
|
- size_t ncpus;
|
||||||
|
+ const CPUSet set = {(cpu_set_t*) a, n};
|
||||||
|
|
||||||
|
- str = cpu_set_to_string(a, n);
|
||||||
|
+ str = cpu_set_to_string(&set);
|
||||||
|
if (!str)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
- ncpus = CPU_SIZE_TO_NUM(n);
|
||||||
|
-
|
||||||
|
- if (!c->cpuset || c->cpuset_ncpus < ncpus) {
|
||||||
|
- cpu_set_t *cpuset;
|
||||||
|
-
|
||||||
|
- cpuset = CPU_ALLOC(ncpus);
|
||||||
|
- if (!cpuset)
|
||||||
|
- return -ENOMEM;
|
||||||
|
-
|
||||||
|
- CPU_ZERO_S(n, cpuset);
|
||||||
|
- if (c->cpuset) {
|
||||||
|
- CPU_OR_S(CPU_ALLOC_SIZE(c->cpuset_ncpus), cpuset, c->cpuset, (cpu_set_t*) a);
|
||||||
|
- CPU_FREE(c->cpuset);
|
||||||
|
- } else
|
||||||
|
- CPU_OR_S(n, cpuset, cpuset, (cpu_set_t*) a);
|
||||||
|
-
|
||||||
|
- c->cpuset = cpuset;
|
||||||
|
- c->cpuset_ncpus = ncpus;
|
||||||
|
- } else
|
||||||
|
- CPU_OR_S(n, c->cpuset, c->cpuset, (cpu_set_t*) a);
|
||||||
|
+ /* We forego any optimizations here, and always create the structure using
|
||||||
|
+ * cpu_set_add_all(), because we don't want to care if the existing size we
|
||||||
|
+ * got over dbus is appropriate. */
|
||||||
|
+ r = cpu_set_add_all(&c->cpu_set, &set);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
|
||||||
|
unit_write_settingf(u, flags, name, "%s=%s", name, str);
|
||||||
|
}
|
||||||
|
diff --git a/src/core/execute.c b/src/core/execute.c
|
||||||
|
index c42300a41e..22e5825905 100644
|
||||||
|
--- a/src/core/execute.c
|
||||||
|
+++ b/src/core/execute.c
|
||||||
|
@@ -2991,8 +2991,8 @@ static int exec_child(
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (context->cpuset)
|
||||||
|
- if (sched_setaffinity(0, CPU_ALLOC_SIZE(context->cpuset_ncpus), context->cpuset) < 0) {
|
||||||
|
+ if (context->cpu_set.set)
|
||||||
|
+ if (sched_setaffinity(0, context->cpu_set.allocated, context->cpu_set.set) < 0) {
|
||||||
|
*exit_status = EXIT_CPUAFFINITY;
|
||||||
|
return log_unit_error_errno(unit, errno, "Failed to set up CPU affinity: %m");
|
||||||
|
}
|
||||||
|
@@ -3694,7 +3694,7 @@ void exec_context_done(ExecContext *c) {
|
||||||
|
c->temporary_filesystems = NULL;
|
||||||
|
c->n_temporary_filesystems = 0;
|
||||||
|
|
||||||
|
- c->cpuset = cpu_set_mfree(c->cpuset);
|
||||||
|
+ cpu_set_reset(&c->cpu_set);
|
||||||
|
|
||||||
|
c->utmp_id = mfree(c->utmp_id);
|
||||||
|
c->selinux_context = mfree(c->selinux_context);
|
||||||
|
@@ -4097,10 +4097,10 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
|
||||||
|
prefix, yes_no(c->cpu_sched_reset_on_fork));
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (c->cpuset) {
|
||||||
|
+ if (c->cpu_set.set) {
|
||||||
|
fprintf(f, "%sCPUAffinity:", prefix);
|
||||||
|
- for (i = 0; i < c->cpuset_ncpus; i++)
|
||||||
|
- if (CPU_ISSET_S(i, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset))
|
||||||
|
+ for (i = 0; i < c->cpu_set.allocated * 8; i++)
|
||||||
|
+ if (CPU_ISSET_S(i, c->cpu_set.allocated, c->cpu_set.set))
|
||||||
|
fprintf(f, " %u", i);
|
||||||
|
fputs("\n", f);
|
||||||
|
}
|
||||||
|
diff --git a/src/core/execute.h b/src/core/execute.h
|
||||||
|
index 8c91636adc..e1e7a494cd 100644
|
||||||
|
--- a/src/core/execute.h
|
||||||
|
+++ b/src/core/execute.h
|
||||||
|
@@ -14,6 +14,7 @@ typedef struct Manager Manager;
|
||||||
|
#include <sys/capability.h>
|
||||||
|
|
||||||
|
#include "cgroup-util.h"
|
||||||
|
+#include "cpu-set-util.h"
|
||||||
|
#include "fdset.h"
|
||||||
|
#include "list.h"
|
||||||
|
#include "missing.h"
|
||||||
|
@@ -148,8 +149,7 @@ struct ExecContext {
|
||||||
|
int cpu_sched_policy;
|
||||||
|
int cpu_sched_priority;
|
||||||
|
|
||||||
|
- cpu_set_t *cpuset;
|
||||||
|
- unsigned cpuset_ncpus;
|
||||||
|
+ CPUSet cpu_set;
|
||||||
|
|
||||||
|
ExecInput std_input;
|
||||||
|
ExecOutput std_output;
|
||||||
|
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
|
||||||
|
index d9a5094aa0..34ae834188 100644
|
||||||
|
--- a/src/core/load-fragment.c
|
||||||
|
+++ b/src/core/load-fragment.c
|
||||||
|
@@ -1211,42 +1211,13 @@ int config_parse_exec_cpu_affinity(const char *unit,
|
||||||
|
void *userdata) {
|
||||||
|
|
||||||
|
ExecContext *c = data;
|
||||||
|
- _cleanup_cpu_free_ cpu_set_t *cpuset = NULL;
|
||||||
|
- int ncpus;
|
||||||
|
|
||||||
|
assert(filename);
|
||||||
|
assert(lvalue);
|
||||||
|
assert(rvalue);
|
||||||
|
assert(data);
|
||||||
|
|
||||||
|
- ncpus = parse_cpu_set_and_warn(rvalue, &cpuset, unit, filename, line, lvalue);
|
||||||
|
- if (ncpus < 0)
|
||||||
|
- return ncpus;
|
||||||
|
-
|
||||||
|
- if (ncpus == 0) {
|
||||||
|
- /* An empty assignment resets the CPU list */
|
||||||
|
- c->cpuset = cpu_set_mfree(c->cpuset);
|
||||||
|
- c->cpuset_ncpus = 0;
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!c->cpuset) {
|
||||||
|
- c->cpuset = TAKE_PTR(cpuset);
|
||||||
|
- c->cpuset_ncpus = (unsigned) ncpus;
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (c->cpuset_ncpus < (unsigned) ncpus) {
|
||||||
|
- CPU_OR_S(CPU_ALLOC_SIZE(c->cpuset_ncpus), cpuset, c->cpuset, cpuset);
|
||||||
|
- CPU_FREE(c->cpuset);
|
||||||
|
- c->cpuset = TAKE_PTR(cpuset);
|
||||||
|
- c->cpuset_ncpus = (unsigned) ncpus;
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- CPU_OR_S(CPU_ALLOC_SIZE((unsigned) ncpus), c->cpuset, c->cpuset, cpuset);
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
+ return parse_cpu_set_extend(rvalue, &c->cpu_set, true, unit, filename, line, lvalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
int config_parse_capability_set(
|
||||||
|
diff --git a/src/core/main.c b/src/core/main.c
|
||||||
|
index af7b26d6f1..e62b2756ee 100644
|
||||||
|
--- a/src/core/main.c
|
||||||
|
+++ b/src/core/main.c
|
||||||
|
@@ -537,16 +537,18 @@ static int config_parse_cpu_affinity2(
|
||||||
|
void *data,
|
||||||
|
void *userdata) {
|
||||||
|
|
||||||
|
- _cleanup_cpu_free_ cpu_set_t *c = NULL;
|
||||||
|
- int ncpus;
|
||||||
|
+ _cleanup_(cpu_set_reset) CPUSet c = {};
|
||||||
|
+ int r;
|
||||||
|
|
||||||
|
- ncpus = parse_cpu_set_and_warn(rvalue, &c, unit, filename, line, lvalue);
|
||||||
|
- if (ncpus < 0)
|
||||||
|
- return ncpus;
|
||||||
|
+ r = parse_cpu_set_full(rvalue, &c, true, unit, filename, line, lvalue);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
|
||||||
|
- if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0)
|
||||||
|
+ if (sched_setaffinity(0, c.allocated, c.set) < 0)
|
||||||
|
log_warning_errno(errno, "Failed to set CPU affinity: %m");
|
||||||
|
|
||||||
|
+ // FIXME: parsing and execution should be seperated.
|
||||||
|
+
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/nspawn/nspawn-settings.c b/src/nspawn/nspawn-settings.c
|
||||||
|
index 62a3486952..21c24a1111 100644
|
||||||
|
--- a/src/nspawn/nspawn-settings.c
|
||||||
|
+++ b/src/nspawn/nspawn-settings.c
|
||||||
|
@@ -85,7 +85,7 @@ Settings* settings_free(Settings *s) {
|
||||||
|
strv_free(s->syscall_blacklist);
|
||||||
|
rlimit_free_all(s->rlimit);
|
||||||
|
free(s->hostname);
|
||||||
|
- s->cpuset = cpu_set_mfree(s->cpuset);
|
||||||
|
+ cpu_set_reset(&s->cpu_set);
|
||||||
|
|
||||||
|
strv_free(s->network_interfaces);
|
||||||
|
strv_free(s->network_macvlan);
|
||||||
|
@@ -687,41 +687,12 @@ int config_parse_cpu_affinity(
|
||||||
|
void *data,
|
||||||
|
void *userdata) {
|
||||||
|
|
||||||
|
- _cleanup_cpu_free_ cpu_set_t *cpuset = NULL;
|
||||||
|
Settings *settings = data;
|
||||||
|
- int ncpus;
|
||||||
|
|
||||||
|
assert(rvalue);
|
||||||
|
assert(settings);
|
||||||
|
|
||||||
|
- ncpus = parse_cpu_set_and_warn(rvalue, &cpuset, unit, filename, line, lvalue);
|
||||||
|
- if (ncpus < 0)
|
||||||
|
- return ncpus;
|
||||||
|
-
|
||||||
|
- if (ncpus == 0) {
|
||||||
|
- /* An empty assignment resets the CPU list */
|
||||||
|
- settings->cpuset = cpu_set_mfree(settings->cpuset);
|
||||||
|
- settings->cpuset_ncpus = 0;
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (!settings->cpuset) {
|
||||||
|
- settings->cpuset = TAKE_PTR(cpuset);
|
||||||
|
- settings->cpuset_ncpus = (unsigned) ncpus;
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (settings->cpuset_ncpus < (unsigned) ncpus) {
|
||||||
|
- CPU_OR_S(CPU_ALLOC_SIZE(settings->cpuset_ncpus), cpuset, settings->cpuset, cpuset);
|
||||||
|
- CPU_FREE(settings->cpuset);
|
||||||
|
- settings->cpuset = TAKE_PTR(cpuset);
|
||||||
|
- settings->cpuset_ncpus = (unsigned) ncpus;
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- CPU_OR_S(CPU_ALLOC_SIZE((unsigned) ncpus), settings->cpuset, settings->cpuset, cpuset);
|
||||||
|
-
|
||||||
|
- return 0;
|
||||||
|
+ return parse_cpu_set_extend(rvalue, &settings->cpu_set, true, unit, filename, line, lvalue);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_CONFIG_PARSE_ENUM(config_parse_resolv_conf, resolv_conf_mode, ResolvConfMode, "Failed to parse resolv.conf mode");
|
||||||
|
diff --git a/src/nspawn/nspawn-settings.h b/src/nspawn/nspawn-settings.h
|
||||||
|
index d522f3cb36..da863ef11c 100644
|
||||||
|
--- a/src/nspawn/nspawn-settings.h
|
||||||
|
+++ b/src/nspawn/nspawn-settings.h
|
||||||
|
@@ -7,6 +7,7 @@
|
||||||
|
#include "sd-id128.h"
|
||||||
|
|
||||||
|
#include "conf-parser.h"
|
||||||
|
+#include "cpu-set-util.h"
|
||||||
|
#include "macro.h"
|
||||||
|
#include "nspawn-expose-ports.h"
|
||||||
|
#include "nspawn-mount.h"
|
||||||
|
@@ -123,8 +124,7 @@ typedef struct Settings {
|
||||||
|
int no_new_privileges;
|
||||||
|
int oom_score_adjust;
|
||||||
|
bool oom_score_adjust_set;
|
||||||
|
- cpu_set_t *cpuset;
|
||||||
|
- unsigned cpuset_ncpus;
|
||||||
|
+ CPUSet cpu_set;
|
||||||
|
ResolvConfMode resolv_conf;
|
||||||
|
LinkJournal link_journal;
|
||||||
|
bool link_journal_try;
|
||||||
|
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
|
||||||
|
index b40411dcd0..08255b5724 100644
|
||||||
|
--- a/src/nspawn/nspawn.c
|
||||||
|
+++ b/src/nspawn/nspawn.c
|
||||||
|
@@ -199,8 +199,7 @@ static struct rlimit *arg_rlimit[_RLIMIT_MAX] = {};
|
||||||
|
static bool arg_no_new_privileges = false;
|
||||||
|
static int arg_oom_score_adjust = 0;
|
||||||
|
static bool arg_oom_score_adjust_set = false;
|
||||||
|
-static cpu_set_t *arg_cpuset = NULL;
|
||||||
|
-static unsigned arg_cpuset_ncpus = 0;
|
||||||
|
+static CPUSet arg_cpu_set = {};
|
||||||
|
static ResolvConfMode arg_resolv_conf = RESOLV_CONF_AUTO;
|
||||||
|
static TimezoneMode arg_timezone = TIMEZONE_AUTO;
|
||||||
|
|
||||||
|
@@ -1186,17 +1185,14 @@ static int parse_argv(int argc, char *argv[]) {
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARG_CPU_AFFINITY: {
|
||||||
|
- _cleanup_cpu_free_ cpu_set_t *cpuset = NULL;
|
||||||
|
+ CPUSet cpuset;
|
||||||
|
|
||||||
|
r = parse_cpu_set(optarg, &cpuset);
|
||||||
|
if (r < 0)
|
||||||
|
- return log_error_errno(r, "Failed to parse CPU affinity mask: %s", optarg);
|
||||||
|
+ return log_error_errno(r, "Failed to parse CPU affinity mask %s: %m", optarg);
|
||||||
|
|
||||||
|
- if (arg_cpuset)
|
||||||
|
- CPU_FREE(arg_cpuset);
|
||||||
|
-
|
||||||
|
- arg_cpuset = TAKE_PTR(cpuset);
|
||||||
|
- arg_cpuset_ncpus = r;
|
||||||
|
+ cpu_set_reset(&arg_cpu_set);
|
||||||
|
+ arg_cpu_set = cpuset;
|
||||||
|
arg_settings_mask |= SETTING_CPU_AFFINITY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -2631,8 +2627,8 @@ static int inner_child(
|
||||||
|
return log_error_errno(r, "Failed to adjust OOM score: %m");
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (arg_cpuset)
|
||||||
|
- if (sched_setaffinity(0, CPU_ALLOC_SIZE(arg_cpuset_ncpus), arg_cpuset) < 0)
|
||||||
|
+ if (arg_cpu_set.set)
|
||||||
|
+ if (sched_setaffinity(0, arg_cpu_set.allocated, arg_cpu_set.set) < 0)
|
||||||
|
return log_error_errno(errno, "Failed to set CPU affinity: %m");
|
||||||
|
|
||||||
|
r = drop_capabilities();
|
||||||
|
@@ -3494,15 +3490,14 @@ static int merge_settings(Settings *settings, const char *path) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((arg_settings_mask & SETTING_CPU_AFFINITY) == 0 &&
|
||||||
|
- settings->cpuset) {
|
||||||
|
+ settings->cpu_set.set) {
|
||||||
|
|
||||||
|
if (!arg_settings_trusted)
|
||||||
|
log_warning("Ignoring CPUAffinity= setting, file '%s' is not trusted.", path);
|
||||||
|
else {
|
||||||
|
- if (arg_cpuset)
|
||||||
|
- CPU_FREE(arg_cpuset);
|
||||||
|
- arg_cpuset = TAKE_PTR(settings->cpuset);
|
||||||
|
- arg_cpuset_ncpus = settings->cpuset_ncpus;
|
||||||
|
+ cpu_set_reset(&arg_cpu_set);
|
||||||
|
+ arg_cpu_set = settings->cpu_set;
|
||||||
|
+ settings->cpu_set = (CPUSet) {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -4600,7 +4595,7 @@ finish:
|
||||||
|
rlimit_free_all(arg_rlimit);
|
||||||
|
strv_free(arg_syscall_whitelist);
|
||||||
|
strv_free(arg_syscall_blacklist);
|
||||||
|
- arg_cpuset = cpu_set_mfree(arg_cpuset);
|
||||||
|
+ cpu_set_reset(&arg_cpu_set);
|
||||||
|
|
||||||
|
return r < 0 ? EXIT_FAILURE : ret;
|
||||||
|
}
|
||||||
|
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
|
||||||
|
index 271cc054da..75b4aace84 100644
|
||||||
|
--- a/src/shared/bus-unit-util.c
|
||||||
|
+++ b/src/shared/bus-unit-util.c
|
||||||
|
@@ -932,13 +932,13 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
|
||||||
|
}
|
||||||
|
|
||||||
|
if (streq(field, "CPUAffinity")) {
|
||||||
|
- _cleanup_cpu_free_ cpu_set_t *cpuset = NULL;
|
||||||
|
+ _cleanup_(cpu_set_reset) CPUSet cpuset = {};
|
||||||
|
|
||||||
|
r = parse_cpu_set(eq, &cpuset);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to parse %s value: %s", field, eq);
|
||||||
|
|
||||||
|
- return bus_append_byte_array(m, field, cpuset, CPU_ALLOC_SIZE(r));
|
||||||
|
+ return bus_append_byte_array(m, field, cpuset.set, cpuset.allocated);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (STR_IN_SET(field, "RestrictAddressFamilies", "SystemCallFilter")) {
|
||||||
|
diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
|
||||||
|
index ff5edb2a69..b9ec29af66 100644
|
||||||
|
--- a/src/test/test-cpu-set-util.c
|
||||||
|
+++ b/src/test/test-cpu-set-util.c
|
||||||
|
@@ -1,154 +1,171 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
|
||||||
|
+#include <errno.h>
|
||||||
|
+
|
||||||
|
#include "alloc-util.h"
|
||||||
|
#include "cpu-set-util.h"
|
||||||
|
#include "macro.h"
|
||||||
|
|
||||||
|
static void test_parse_cpu_set(void) {
|
||||||
|
- cpu_set_t *c = NULL;
|
||||||
|
+ CPUSet c = {};
|
||||||
|
_cleanup_free_ char *str = NULL;
|
||||||
|
- int ncpus;
|
||||||
|
int cpu;
|
||||||
|
|
||||||
|
/* Simple range (from CPUAffinity example) */
|
||||||
|
- ncpus = parse_cpu_set_and_warn("1 2", &c, NULL, "fake", 1, "CPUAffinity");
|
||||||
|
- assert_se(ncpus >= 1024);
|
||||||
|
- assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
- assert_se(CPU_ISSET_S(2, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 2);
|
||||||
|
-
|
||||||
|
- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
|
||||||
|
+ assert_se(parse_cpu_set_full("1 2", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
+ assert_se(c.set);
|
||||||
|
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(CPU_ISSET_S(1, c.allocated, c.set));
|
||||||
|
+ assert_se(CPU_ISSET_S(2, c.allocated, c.set));
|
||||||
|
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 2);
|
||||||
|
+
|
||||||
|
+ assert_se(str = cpu_set_to_string(&c));
|
||||||
|
log_info("cpu_set_to_string: %s", str);
|
||||||
|
str = mfree(str);
|
||||||
|
- c = cpu_set_mfree(c);
|
||||||
|
+ cpu_set_reset(&c);
|
||||||
|
|
||||||
|
/* A more interesting range */
|
||||||
|
- ncpus = parse_cpu_set_and_warn("0 1 2 3 8 9 10 11", &c, NULL, "fake", 1, "CPUAffinity");
|
||||||
|
- assert_se(ncpus >= 1024);
|
||||||
|
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
|
||||||
|
+ assert_se(parse_cpu_set_full("0 1 2 3 8 9 10 11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
|
||||||
|
for (cpu = 0; cpu < 4; cpu++)
|
||||||
|
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
for (cpu = 8; cpu < 12; cpu++)
|
||||||
|
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
|
||||||
|
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
+ assert_se(str = cpu_set_to_string(&c));
|
||||||
|
log_info("cpu_set_to_string: %s", str);
|
||||||
|
str = mfree(str);
|
||||||
|
- c = cpu_set_mfree(c);
|
||||||
|
+ cpu_set_reset(&c);
|
||||||
|
|
||||||
|
/* Quoted strings */
|
||||||
|
- ncpus = parse_cpu_set_and_warn("8 '9' 10 \"11\"", &c, NULL, "fake", 1, "CPUAffinity");
|
||||||
|
- assert_se(ncpus >= 1024);
|
||||||
|
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 4);
|
||||||
|
+ assert_se(parse_cpu_set_full("8 '9' 10 \"11\"", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 4);
|
||||||
|
for (cpu = 8; cpu < 12; cpu++)
|
||||||
|
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
|
||||||
|
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
+ assert_se(str = cpu_set_to_string(&c));
|
||||||
|
log_info("cpu_set_to_string: %s", str);
|
||||||
|
str = mfree(str);
|
||||||
|
- c = cpu_set_mfree(c);
|
||||||
|
+ cpu_set_reset(&c);
|
||||||
|
|
||||||
|
/* Use commas as separators */
|
||||||
|
- ncpus = parse_cpu_set_and_warn("0,1,2,3 8,9,10,11", &c, NULL, "fake", 1, "CPUAffinity");
|
||||||
|
- assert_se(ncpus >= 1024);
|
||||||
|
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
|
||||||
|
+ assert_se(parse_cpu_set_full("0,1,2,3 8,9,10,11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
|
||||||
|
for (cpu = 0; cpu < 4; cpu++)
|
||||||
|
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
for (cpu = 8; cpu < 12; cpu++)
|
||||||
|
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
|
||||||
|
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
+ assert_se(str = cpu_set_to_string(&c));
|
||||||
|
log_info("cpu_set_to_string: %s", str);
|
||||||
|
str = mfree(str);
|
||||||
|
- c = cpu_set_mfree(c);
|
||||||
|
+ cpu_set_reset(&c);
|
||||||
|
|
||||||
|
/* Commas with spaces (and trailing comma, space) */
|
||||||
|
- ncpus = parse_cpu_set_and_warn("0, 1, 2, 3, 4, 5, 6, 7, ", &c, NULL, "fake", 1, "CPUAffinity");
|
||||||
|
- assert_se(ncpus >= 1024);
|
||||||
|
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
|
||||||
|
+ assert_se(parse_cpu_set_full("0, 1, 2, 3, 4, 5, 6, 7, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
|
||||||
|
for (cpu = 0; cpu < 8; cpu++)
|
||||||
|
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
|
||||||
|
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
+ assert_se(str = cpu_set_to_string(&c));
|
||||||
|
log_info("cpu_set_to_string: %s", str);
|
||||||
|
str = mfree(str);
|
||||||
|
- c = cpu_set_mfree(c);
|
||||||
|
+ cpu_set_reset(&c);
|
||||||
|
|
||||||
|
/* Ranges */
|
||||||
|
- ncpus = parse_cpu_set_and_warn("0-3,8-11", &c, NULL, "fake", 1, "CPUAffinity");
|
||||||
|
- assert_se(ncpus >= 1024);
|
||||||
|
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
|
||||||
|
+ assert_se(parse_cpu_set_full("0-3,8-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
|
||||||
|
for (cpu = 0; cpu < 4; cpu++)
|
||||||
|
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
for (cpu = 8; cpu < 12; cpu++)
|
||||||
|
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
|
||||||
|
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
+ assert_se(str = cpu_set_to_string(&c));
|
||||||
|
log_info("cpu_set_to_string: %s", str);
|
||||||
|
str = mfree(str);
|
||||||
|
- c = cpu_set_mfree(c);
|
||||||
|
+ cpu_set_reset(&c);
|
||||||
|
|
||||||
|
/* Ranges with trailing comma, space */
|
||||||
|
- ncpus = parse_cpu_set_and_warn("0-3 8-11, ", &c, NULL, "fake", 1, "CPUAffinity");
|
||||||
|
- assert_se(ncpus >= 1024);
|
||||||
|
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 8);
|
||||||
|
+ assert_se(parse_cpu_set_full("0-3 8-11, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
|
||||||
|
for (cpu = 0; cpu < 4; cpu++)
|
||||||
|
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
for (cpu = 8; cpu < 12; cpu++)
|
||||||
|
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
|
||||||
|
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
+ assert_se(str = cpu_set_to_string(&c));
|
||||||
|
log_info("cpu_set_to_string: %s", str);
|
||||||
|
str = mfree(str);
|
||||||
|
- c = cpu_set_mfree(c);
|
||||||
|
+ cpu_set_reset(&c);
|
||||||
|
|
||||||
|
/* Negative range (returns empty cpu_set) */
|
||||||
|
- ncpus = parse_cpu_set_and_warn("3-0", &c, NULL, "fake", 1, "CPUAffinity");
|
||||||
|
- assert_se(ncpus >= 1024);
|
||||||
|
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 0);
|
||||||
|
- c = cpu_set_mfree(c);
|
||||||
|
+ assert_se(parse_cpu_set_full("3-0", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 0);
|
||||||
|
+ cpu_set_reset(&c);
|
||||||
|
|
||||||
|
/* Overlapping ranges */
|
||||||
|
- ncpus = parse_cpu_set_and_warn("0-7 4-11", &c, NULL, "fake", 1, "CPUAffinity");
|
||||||
|
- assert_se(ncpus >= 1024);
|
||||||
|
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 12);
|
||||||
|
+ assert_se(parse_cpu_set_full("0-7 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 12);
|
||||||
|
for (cpu = 0; cpu < 12; cpu++)
|
||||||
|
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
|
||||||
|
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
+ assert_se(str = cpu_set_to_string(&c));
|
||||||
|
log_info("cpu_set_to_string: %s", str);
|
||||||
|
str = mfree(str);
|
||||||
|
- c = cpu_set_mfree(c);
|
||||||
|
+ cpu_set_reset(&c);
|
||||||
|
|
||||||
|
/* Mix ranges and individual CPUs */
|
||||||
|
- ncpus = parse_cpu_set_and_warn("0,1 4-11", &c, NULL, "fake", 1, "CPUAffinity");
|
||||||
|
- assert_se(ncpus >= 1024);
|
||||||
|
- assert_se(CPU_COUNT_S(CPU_ALLOC_SIZE(ncpus), c) == 10);
|
||||||
|
- assert_se(CPU_ISSET_S(0, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
- assert_se(CPU_ISSET_S(1, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
+ assert_se(parse_cpu_set_full("0,1 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 10);
|
||||||
|
+ assert_se(CPU_ISSET_S(0, c.allocated, c.set));
|
||||||
|
+ assert_se(CPU_ISSET_S(1, c.allocated, c.set));
|
||||||
|
for (cpu = 4; cpu < 12; cpu++)
|
||||||
|
- assert_se(CPU_ISSET_S(cpu, CPU_ALLOC_SIZE(ncpus), c));
|
||||||
|
- assert_se(str = cpu_set_to_string(c, CPU_ALLOC_SIZE(ncpus)));
|
||||||
|
+ assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
+ assert_se(str = cpu_set_to_string(&c));
|
||||||
|
log_info("cpu_set_to_string: %s", str);
|
||||||
|
str = mfree(str);
|
||||||
|
- c = cpu_set_mfree(c);
|
||||||
|
+ cpu_set_reset(&c);
|
||||||
|
|
||||||
|
/* Garbage */
|
||||||
|
- ncpus = parse_cpu_set_and_warn("0 1 2 3 garbage", &c, NULL, "fake", 1, "CPUAffinity");
|
||||||
|
- assert_se(ncpus < 0);
|
||||||
|
- assert_se(!c);
|
||||||
|
+ assert_se(parse_cpu_set_full("0 1 2 3 garbage", &c, true, NULL, "fake", 1, "CPUAffinity") == -EINVAL);
|
||||||
|
+ assert_se(!c.set);
|
||||||
|
+ assert_se(c.allocated == 0);
|
||||||
|
|
||||||
|
/* Range with garbage */
|
||||||
|
- ncpus = parse_cpu_set_and_warn("0-3 8-garbage", &c, NULL, "fake", 1, "CPUAffinity");
|
||||||
|
- assert_se(ncpus < 0);
|
||||||
|
- assert_se(!c);
|
||||||
|
+ assert_se(parse_cpu_set_full("0-3 8-garbage", &c, true, NULL, "fake", 1, "CPUAffinity") == -EINVAL);
|
||||||
|
+ assert_se(!c.set);
|
||||||
|
+ assert_se(c.allocated == 0);
|
||||||
|
|
||||||
|
/* Empty string */
|
||||||
|
- c = NULL;
|
||||||
|
- ncpus = parse_cpu_set_and_warn("", &c, NULL, "fake", 1, "CPUAffinity");
|
||||||
|
- assert_se(ncpus == 0); /* empty string returns 0 */
|
||||||
|
- assert_se(!c);
|
||||||
|
+ assert_se(parse_cpu_set_full("", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
|
||||||
|
+ assert_se(!c.set); /* empty string returns NULL */
|
||||||
|
+ assert_se(c.allocated == 0);
|
||||||
|
|
||||||
|
/* Runaway quoted string */
|
||||||
|
- ncpus = parse_cpu_set_and_warn("0 1 2 3 \"4 5 6 7 ", &c, NULL, "fake", 1, "CPUAffinity");
|
||||||
|
- assert_se(ncpus < 0);
|
||||||
|
- assert_se(!c);
|
||||||
|
+ assert_se(parse_cpu_set_full("0 1 2 3 \"4 5 6 7 ", &c, true, NULL, "fake", 1, "CPUAffinity") == -EINVAL);
|
||||||
|
+ assert_se(!c.set);
|
||||||
|
+ assert_se(c.allocated == 0);
|
||||||
|
+
|
||||||
|
+ /* Maximum allocation */
|
||||||
|
+ assert_se(parse_cpu_set_full("8000-8191", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
|
||||||
|
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 192);
|
||||||
|
+ assert_se(str = cpu_set_to_string(&c));
|
||||||
|
+ log_info("cpu_set_to_string: %s", str);
|
||||||
|
+ str = mfree(str);
|
||||||
|
+ cpu_set_reset(&c);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
+ log_info("CPU_ALLOC_SIZE(1) = %zu", CPU_ALLOC_SIZE(1));
|
||||||
|
+ log_info("CPU_ALLOC_SIZE(9) = %zu", CPU_ALLOC_SIZE(9));
|
||||||
|
+ log_info("CPU_ALLOC_SIZE(64) = %zu", CPU_ALLOC_SIZE(64));
|
||||||
|
+ log_info("CPU_ALLOC_SIZE(65) = %zu", CPU_ALLOC_SIZE(65));
|
||||||
|
+ log_info("CPU_ALLOC_SIZE(1024) = %zu", CPU_ALLOC_SIZE(1024));
|
||||||
|
+ log_info("CPU_ALLOC_SIZE(1025) = %zu", CPU_ALLOC_SIZE(1025));
|
||||||
|
+ log_info("CPU_ALLOC_SIZE(8191) = %zu", CPU_ALLOC_SIZE(8191));
|
||||||
|
+
|
||||||
|
test_parse_cpu_set();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
diff --git a/src/test/test-sizeof.c b/src/test/test-sizeof.c
|
||||||
|
index 7a1e496ed2..396e68f35f 100644
|
||||||
|
--- a/src/test/test-sizeof.c
|
||||||
|
+++ b/src/test/test-sizeof.c
|
||||||
|
@@ -1,5 +1,6 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
|
||||||
|
+#include <sched.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
@@ -64,6 +65,8 @@ int main(void) {
|
||||||
|
info(uid_t);
|
||||||
|
info(gid_t);
|
||||||
|
|
||||||
|
+ info(__cpu_mask);
|
||||||
|
+
|
||||||
|
info(enum Enum);
|
||||||
|
info(enum BigEnum);
|
||||||
|
info(enum BigEnum2);
|
@ -0,0 +1,125 @@
|
|||||||
|
From 42032749e61076b3d9e5004432073c2a5ea737ce Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Tue, 28 May 2019 21:28:31 +0200
|
||||||
|
Subject: [PATCH] Move cpus_in_affinity_mask() to cpu-set-util.[ch]
|
||||||
|
|
||||||
|
It just seems to fit better there and it's always better to have things
|
||||||
|
in shared/ rather than basic/.
|
||||||
|
|
||||||
|
(cherry picked from commit f44b3035d4a698aa0ce08a552199b54d43de3d85)
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
---
|
||||||
|
src/basic/cpu-set-util.c | 34 ++++++++++++++++++++++++++++++++++
|
||||||
|
src/basic/cpu-set-util.h | 2 ++
|
||||||
|
src/basic/process-util.c | 5 ++---
|
||||||
|
src/shared/condition.c | 1 +
|
||||||
|
src/test/test-condition.c | 1 +
|
||||||
|
5 files changed, 40 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c
|
||||||
|
index fe440f6381..1803539ac6 100644
|
||||||
|
--- a/src/basic/cpu-set-util.c
|
||||||
|
+++ b/src/basic/cpu-set-util.c
|
||||||
|
@@ -204,3 +204,37 @@ int parse_cpu_set_extend(
|
||||||
|
|
||||||
|
return cpu_set_add_all(old, &cpuset);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+int cpus_in_affinity_mask(void) {
|
||||||
|
+ size_t n = 16;
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ for (;;) {
|
||||||
|
+ cpu_set_t *c;
|
||||||
|
+
|
||||||
|
+ c = CPU_ALLOC(n);
|
||||||
|
+ if (!c)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), c) >= 0) {
|
||||||
|
+ int k;
|
||||||
|
+
|
||||||
|
+ k = CPU_COUNT_S(CPU_ALLOC_SIZE(n), c);
|
||||||
|
+ CPU_FREE(c);
|
||||||
|
+
|
||||||
|
+ if (k <= 0)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ return k;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ r = -errno;
|
||||||
|
+ CPU_FREE(c);
|
||||||
|
+
|
||||||
|
+ if (r != -EINVAL)
|
||||||
|
+ return r;
|
||||||
|
+ if (n > SIZE_MAX/2)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+ n *= 2;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h
|
||||||
|
index eb31b362fe..9b026aca09 100644
|
||||||
|
--- a/src/basic/cpu-set-util.h
|
||||||
|
+++ b/src/basic/cpu-set-util.h
|
||||||
|
@@ -49,3 +49,5 @@ int parse_cpu_set_extend(
|
||||||
|
static inline int parse_cpu_set(const char *rvalue, CPUSet *cpu_set){
|
||||||
|
return parse_cpu_set_full(rvalue, cpu_set, false, NULL, NULL, 0, NULL);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+int cpus_in_affinity_mask(void);
|
||||||
|
diff --git a/src/basic/process-util.c b/src/basic/process-util.c
|
||||||
|
index 6dbeee9dda..0a4a747ba4 100644
|
||||||
|
--- a/src/basic/process-util.c
|
||||||
|
+++ b/src/basic/process-util.c
|
||||||
|
@@ -4,7 +4,6 @@
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <linux/oom.h>
|
||||||
|
-#include <sched.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
@@ -1474,7 +1473,7 @@ static const char *const ioprio_class_table[] = {
|
||||||
|
[IOPRIO_CLASS_NONE] = "none",
|
||||||
|
[IOPRIO_CLASS_RT] = "realtime",
|
||||||
|
[IOPRIO_CLASS_BE] = "best-effort",
|
||||||
|
- [IOPRIO_CLASS_IDLE] = "idle"
|
||||||
|
+ [IOPRIO_CLASS_IDLE] = "idle",
|
||||||
|
};
|
||||||
|
|
||||||
|
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ioprio_class, int, IOPRIO_N_CLASSES);
|
||||||
|
@@ -1495,7 +1494,7 @@ static const char* const sched_policy_table[] = {
|
||||||
|
[SCHED_BATCH] = "batch",
|
||||||
|
[SCHED_IDLE] = "idle",
|
||||||
|
[SCHED_FIFO] = "fifo",
|
||||||
|
- [SCHED_RR] = "rr"
|
||||||
|
+ [SCHED_RR] = "rr",
|
||||||
|
};
|
||||||
|
|
||||||
|
DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(sched_policy, int, INT_MAX);
|
||||||
|
diff --git a/src/shared/condition.c b/src/shared/condition.c
|
||||||
|
index 2969a89b4e..b829f0528c 100644
|
||||||
|
--- a/src/shared/condition.c
|
||||||
|
+++ b/src/shared/condition.c
|
||||||
|
@@ -21,6 +21,7 @@
|
||||||
|
#include "cap-list.h"
|
||||||
|
#include "cgroup-util.h"
|
||||||
|
#include "condition.h"
|
||||||
|
+#include "cpu-set-util.h"
|
||||||
|
#include "efivars.h"
|
||||||
|
#include "extract-word.h"
|
||||||
|
#include "fd-util.h"
|
||||||
|
diff --git a/src/test/test-condition.c b/src/test/test-condition.c
|
||||||
|
index 7ce6ee80ea..24395dafc6 100644
|
||||||
|
--- a/src/test/test-condition.c
|
||||||
|
+++ b/src/test/test-condition.c
|
||||||
|
@@ -13,6 +13,7 @@
|
||||||
|
#include "audit-util.h"
|
||||||
|
#include "cgroup-util.h"
|
||||||
|
#include "condition.h"
|
||||||
|
+#include "cpu-set-util.h"
|
||||||
|
#include "efivars.h"
|
||||||
|
#include "hostname-util.h"
|
||||||
|
#include "id128-util.h"
|
@ -0,0 +1,40 @@
|
|||||||
|
From a1ed6bfc5a8c40377b9f1cab1acc3c67a9529427 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Tue, 21 May 2019 09:01:34 +0200
|
||||||
|
Subject: [PATCH] test-cpu-set-util: add simple test for
|
||||||
|
cpus_in_affinity_mask()
|
||||||
|
|
||||||
|
(cherry picked from commit 9d1345f0657c707df89b41b2738776efb40aec8e)
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
---
|
||||||
|
src/test/test-cpu-set-util.c | 9 +++++++++
|
||||||
|
1 file changed, 9 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
|
||||||
|
index b9ec29af66..e87e0ca6e6 100644
|
||||||
|
--- a/src/test/test-cpu-set-util.c
|
||||||
|
+++ b/src/test/test-cpu-set-util.c
|
||||||
|
@@ -157,6 +157,14 @@ static void test_parse_cpu_set(void) {
|
||||||
|
cpu_set_reset(&c);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void test_cpus_in_affinity_mask(void) {
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ r = cpus_in_affinity_mask();
|
||||||
|
+ assert(r > 0);
|
||||||
|
+ log_info("cpus_in_affinity_mask: %d", r);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
log_info("CPU_ALLOC_SIZE(1) = %zu", CPU_ALLOC_SIZE(1));
|
||||||
|
log_info("CPU_ALLOC_SIZE(9) = %zu", CPU_ALLOC_SIZE(9));
|
||||||
|
@@ -167,6 +175,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
log_info("CPU_ALLOC_SIZE(8191) = %zu", CPU_ALLOC_SIZE(8191));
|
||||||
|
|
||||||
|
test_parse_cpu_set();
|
||||||
|
+ test_cpus_in_affinity_mask();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,63 @@
|
|||||||
|
From 69541e93c45efb7ee15d7584c3aa70c3ff0b2200 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Fri, 24 May 2019 08:50:41 +0200
|
||||||
|
Subject: [PATCH] test-cpu-set-util: add a smoke test for
|
||||||
|
test_parse_cpu_set_extend()
|
||||||
|
|
||||||
|
(cherry picked from commit b54d7241f25b859c6c008e516c2131c39902e6e4)
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
---
|
||||||
|
src/test/test-cpu-set-util.c | 25 +++++++++++++++++++++++++
|
||||||
|
1 file changed, 25 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
|
||||||
|
index e87e0ca6e6..81f67647e8 100644
|
||||||
|
--- a/src/test/test-cpu-set-util.c
|
||||||
|
+++ b/src/test/test-cpu-set-util.c
|
||||||
|
@@ -11,6 +11,8 @@ static void test_parse_cpu_set(void) {
|
||||||
|
_cleanup_free_ char *str = NULL;
|
||||||
|
int cpu;
|
||||||
|
|
||||||
|
+ log_info("/* %s */", __func__);
|
||||||
|
+
|
||||||
|
/* Simple range (from CPUAffinity example) */
|
||||||
|
assert_se(parse_cpu_set_full("1 2", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
assert_se(c.set);
|
||||||
|
@@ -157,6 +159,28 @@ static void test_parse_cpu_set(void) {
|
||||||
|
cpu_set_reset(&c);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void test_parse_cpu_set_extend(void) {
|
||||||
|
+ CPUSet c = {};
|
||||||
|
+ _cleanup_free_ char *s1 = NULL, *s2 = NULL;
|
||||||
|
+
|
||||||
|
+ log_info("/* %s */", __func__);
|
||||||
|
+
|
||||||
|
+ assert_se(parse_cpu_set_extend("1 3", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
|
||||||
|
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 2);
|
||||||
|
+ assert_se(s1 = cpu_set_to_string(&c));
|
||||||
|
+ log_info("cpu_set_to_string: %s", s1);
|
||||||
|
+
|
||||||
|
+ assert_se(parse_cpu_set_extend("4", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
|
||||||
|
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 3);
|
||||||
|
+ assert_se(s2 = cpu_set_to_string(&c));
|
||||||
|
+ log_info("cpu_set_to_string: %s", s2);
|
||||||
|
+
|
||||||
|
+ assert_se(parse_cpu_set_extend("", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
|
||||||
|
+ assert_se(!c.set);
|
||||||
|
+ assert_se(c.allocated == 0);
|
||||||
|
+ log_info("cpu_set_to_string: (null)");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void test_cpus_in_affinity_mask(void) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
@@ -175,6 +199,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
log_info("CPU_ALLOC_SIZE(8191) = %zu", CPU_ALLOC_SIZE(8191));
|
||||||
|
|
||||||
|
test_parse_cpu_set();
|
||||||
|
+ test_parse_cpu_set_extend();
|
||||||
|
test_cpus_in_affinity_mask();
|
||||||
|
|
||||||
|
return 0;
|
148
SOURCES/0276-pid1-parse-CPUAffinity-in-incremental-fashion.patch
Normal file
148
SOURCES/0276-pid1-parse-CPUAffinity-in-incremental-fashion.patch
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
From 8bf8409c6e08f5aef35d1976e172b3f61b651c8d Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Fri, 24 May 2019 08:35:51 +0200
|
||||||
|
Subject: [PATCH] pid1: parse CPUAffinity= in incremental fashion
|
||||||
|
|
||||||
|
This makes the handling of this option match what we do in unit files. I think
|
||||||
|
consistency is important here. (As it happens, it is the only option in
|
||||||
|
system.conf that is "non-atomic", i.e. where there's a list of things which can
|
||||||
|
be split over multiple assignments. All other options are single-valued, so
|
||||||
|
there's no issue of how to handle multiple assignments.)
|
||||||
|
|
||||||
|
(cherry picked from commit 61fbbac1d517a0b3498a689c736c6ca918497904)
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
---
|
||||||
|
man/systemd-system.conf.xml | 13 ++++++++-----
|
||||||
|
man/systemd.exec.xml | 2 +-
|
||||||
|
src/core/main.c | 36 ++++++++++++++++++++++++++----------
|
||||||
|
3 files changed, 35 insertions(+), 16 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml
|
||||||
|
index 085086200a..ab23779ec0 100644
|
||||||
|
--- a/man/systemd-system.conf.xml
|
||||||
|
+++ b/man/systemd-system.conf.xml
|
||||||
|
@@ -99,11 +99,14 @@
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>CPUAffinity=</varname></term>
|
||||||
|
|
||||||
|
- <listitem><para>Configures the initial CPU affinity for the
|
||||||
|
- init process. Takes a list of CPU indices or ranges separated
|
||||||
|
- by either whitespace or commas. CPU ranges are specified by
|
||||||
|
- the lower and upper CPU indices separated by a
|
||||||
|
- dash.</para></listitem>
|
||||||
|
+ <listitem><para>Configures the CPU affinity for the service manager as well as the default CPU
|
||||||
|
+ affinity for all forked off processes. Takes a list of CPU indices or ranges separated by either
|
||||||
|
+ whitespace or commas. CPU ranges are specified by the lower and upper CPU indices separated by a
|
||||||
|
+ dash. This option may be specified more than once, in which case the specified CPU affinity masks are
|
||||||
|
+ merged. If the empty string is assigned, the mask is reset, all assignments prior to this will have
|
||||||
|
+ no effect. Individual services may override the CPU affinity for their processes with the
|
||||||
|
+ <varname>CPUAffinity=</varname> setting in unit files, see
|
||||||
|
+ <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
|
||||||
|
index 737c52bcc4..342b8385bc 100644
|
||||||
|
--- a/man/systemd.exec.xml
|
||||||
|
+++ b/man/systemd.exec.xml
|
||||||
|
@@ -703,7 +703,7 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
|
||||||
|
|
||||||
|
<listitem><para>Controls the CPU affinity of the executed processes. Takes a list of CPU indices or ranges
|
||||||
|
separated by either whitespace or commas. CPU ranges are specified by the lower and upper CPU indices separated
|
||||||
|
- by a dash. This option may be specified more than once, in which case the specified CPU affinity masks are
|
||||||
|
+ by a dash. This option may be specified more than once, in which case the specified CPU affinity masks are
|
||||||
|
merged. If the empty string is assigned, the mask is reset, all assignments prior to this will have no
|
||||||
|
effect. See
|
||||||
|
<citerefentry><refentrytitle>sched_setaffinity</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
|
||||||
|
diff --git a/src/core/main.c b/src/core/main.c
|
||||||
|
index e62b2756ee..bc1db2af7b 100644
|
||||||
|
--- a/src/core/main.c
|
||||||
|
+++ b/src/core/main.c
|
||||||
|
@@ -127,6 +127,7 @@ static bool arg_default_tasks_accounting = true;
|
||||||
|
static uint64_t arg_default_tasks_max = UINT64_MAX;
|
||||||
|
static sd_id128_t arg_machine_id = {};
|
||||||
|
static EmergencyAction arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE;
|
||||||
|
+static CPUSet arg_cpu_affinity = {};
|
||||||
|
|
||||||
|
_noreturn_ static void freeze_or_reboot(void) {
|
||||||
|
|
||||||
|
@@ -537,17 +538,11 @@ static int config_parse_cpu_affinity2(
|
||||||
|
void *data,
|
||||||
|
void *userdata) {
|
||||||
|
|
||||||
|
- _cleanup_(cpu_set_reset) CPUSet c = {};
|
||||||
|
- int r;
|
||||||
|
-
|
||||||
|
- r = parse_cpu_set_full(rvalue, &c, true, unit, filename, line, lvalue);
|
||||||
|
- if (r < 0)
|
||||||
|
- return r;
|
||||||
|
+ CPUSet *affinity = data;
|
||||||
|
|
||||||
|
- if (sched_setaffinity(0, c.allocated, c.set) < 0)
|
||||||
|
- log_warning_errno(errno, "Failed to set CPU affinity: %m");
|
||||||
|
+ assert(affinity);
|
||||||
|
|
||||||
|
- // FIXME: parsing and execution should be seperated.
|
||||||
|
+ (void) parse_cpu_set_extend(rvalue, affinity, true, unit, filename, line, lvalue);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -655,7 +650,7 @@ static int parse_config_file(void) {
|
||||||
|
{ "Manager", "CrashShell", config_parse_bool, 0, &arg_crash_shell },
|
||||||
|
{ "Manager", "CrashReboot", config_parse_bool, 0, &arg_crash_reboot },
|
||||||
|
{ "Manager", "ShowStatus", config_parse_show_status, 0, &arg_show_status },
|
||||||
|
- { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, NULL },
|
||||||
|
+ { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, &arg_cpu_affinity },
|
||||||
|
{ "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers },
|
||||||
|
{ "Manager", "RuntimeWatchdogSec", config_parse_sec, 0, &arg_runtime_watchdog },
|
||||||
|
{ "Manager", "ShutdownWatchdogSec", config_parse_sec, 0, &arg_shutdown_watchdog },
|
||||||
|
@@ -1483,6 +1478,21 @@ static void initialize_coredump(bool skip_setup) {
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void update_cpu_affinity(bool skip_setup) {
|
||||||
|
+ _cleanup_free_ char *mask = NULL;
|
||||||
|
+
|
||||||
|
+ if (skip_setup || !arg_cpu_affinity.set)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ assert(arg_cpu_affinity.allocated > 0);
|
||||||
|
+
|
||||||
|
+ mask = cpu_set_to_string(&arg_cpu_affinity);
|
||||||
|
+ log_debug("Setting CPU affinity to %s.", strnull(mask));
|
||||||
|
+
|
||||||
|
+ if (sched_setaffinity(0, arg_cpu_affinity.allocated, arg_cpu_affinity.set) < 0)
|
||||||
|
+ log_warning_errno(errno, "Failed to set CPU affinity: %m");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void do_reexecute(
|
||||||
|
int argc,
|
||||||
|
char *argv[],
|
||||||
|
@@ -1655,6 +1665,8 @@ static int invoke_main_loop(
|
||||||
|
|
||||||
|
set_manager_defaults(m);
|
||||||
|
|
||||||
|
+ update_cpu_affinity(false);
|
||||||
|
+
|
||||||
|
if (saved_log_level >= 0)
|
||||||
|
manager_override_log_level(m, saved_log_level);
|
||||||
|
if (saved_log_target >= 0)
|
||||||
|
@@ -1813,6 +1825,8 @@ static int initialize_runtime(
|
||||||
|
if (arg_action != ACTION_RUN)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
+ update_cpu_affinity(skip_setup);
|
||||||
|
+
|
||||||
|
if (arg_system) {
|
||||||
|
/* Make sure we leave a core dump without panicing the kernel. */
|
||||||
|
install_crash_handler();
|
||||||
|
@@ -1947,6 +1961,8 @@ static void free_arguments(void) {
|
||||||
|
arg_join_controllers = strv_free_free(arg_join_controllers);
|
||||||
|
arg_default_environment = strv_free(arg_default_environment);
|
||||||
|
arg_syscall_archs = set_free(arg_syscall_archs);
|
||||||
|
+
|
||||||
|
+ cpu_set_reset(&arg_cpu_affinity);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int load_configuration(int argc, char **argv, const char **ret_error_message) {
|
@ -0,0 +1,86 @@
|
|||||||
|
From f71f3271fa149d2b5f022830d43071d97b022b38 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Fri, 24 May 2019 08:59:23 +0200
|
||||||
|
Subject: [PATCH] pid1: don't reset setting from /proc/cmdline upon restart
|
||||||
|
|
||||||
|
We have settings which may be set on the kernel command line, and also
|
||||||
|
in /proc/cmdline (for pid1). The settings in /proc/cmdline have higher priority
|
||||||
|
of course. When a reload was done, we'd reload just the configuration file,
|
||||||
|
losing the overrides.
|
||||||
|
|
||||||
|
So read /proc/cmdline again during reload.
|
||||||
|
|
||||||
|
Also, when initially reading the configuration file when program starts,
|
||||||
|
don't treat any errors as fatal. The configuration done in there doesn't
|
||||||
|
seem important enough to refuse boot.
|
||||||
|
|
||||||
|
(cherry picked from commit 470a5e6dcec4637439ae953002127af214d396ac)
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
---
|
||||||
|
src/core/main.c | 26 ++++++++++++++++----------
|
||||||
|
1 file changed, 16 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/main.c b/src/core/main.c
|
||||||
|
index bc1db2af7b..9a9f145080 100644
|
||||||
|
--- a/src/core/main.c
|
||||||
|
+++ b/src/core/main.c
|
||||||
|
@@ -129,6 +129,8 @@ static sd_id128_t arg_machine_id = {};
|
||||||
|
static EmergencyAction arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE;
|
||||||
|
static CPUSet arg_cpu_affinity = {};
|
||||||
|
|
||||||
|
+static int parse_configuration(void);
|
||||||
|
+
|
||||||
|
_noreturn_ static void freeze_or_reboot(void) {
|
||||||
|
|
||||||
|
if (arg_crash_reboot) {
|
||||||
|
@@ -1659,9 +1661,7 @@ static int invoke_main_loop(
|
||||||
|
saved_log_level = m->log_level_overridden ? log_get_max_level() : -1;
|
||||||
|
saved_log_target = m->log_target_overridden ? log_get_target() : _LOG_TARGET_INVALID;
|
||||||
|
|
||||||
|
- r = parse_config_file();
|
||||||
|
- if (r < 0)
|
||||||
|
- log_warning_errno(r, "Failed to parse config file, ignoring: %m");
|
||||||
|
+ (void) parse_configuration();
|
||||||
|
|
||||||
|
set_manager_defaults(m);
|
||||||
|
|
||||||
|
@@ -1965,18 +1965,14 @@ static void free_arguments(void) {
|
||||||
|
cpu_set_reset(&arg_cpu_affinity);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static int load_configuration(int argc, char **argv, const char **ret_error_message) {
|
||||||
|
+static int parse_configuration(void) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
- assert(ret_error_message);
|
||||||
|
-
|
||||||
|
arg_default_tasks_max = system_tasks_max_scale(DEFAULT_TASKS_MAX_PERCENTAGE, 100U);
|
||||||
|
|
||||||
|
r = parse_config_file();
|
||||||
|
- if (r < 0) {
|
||||||
|
- *ret_error_message = "Failed to parse config file";
|
||||||
|
- return r;
|
||||||
|
- }
|
||||||
|
+ if (r < 0)
|
||||||
|
+ log_warning_errno(r, "Failed to parse config file, ignoring: %m");
|
||||||
|
|
||||||
|
if (arg_system) {
|
||||||
|
r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
|
||||||
|
@@ -1987,6 +1983,16 @@ static int load_configuration(int argc, char **argv, const char **ret_error_mess
|
||||||
|
/* Note that this also parses bits from the kernel command line, including "debug". */
|
||||||
|
log_parse_environment();
|
||||||
|
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int load_configuration(int argc, char **argv, const char **ret_error_message) {
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ assert(ret_error_message);
|
||||||
|
+
|
||||||
|
+ (void) parse_configuration();
|
||||||
|
+
|
||||||
|
r = parse_argv(argc, argv);
|
||||||
|
if (r < 0) {
|
||||||
|
*ret_error_message = "Failed to parse commandline arguments";
|
@ -0,0 +1,208 @@
|
|||||||
|
From 0387294ba41ceaf80c79621409aab9508732bda0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Fri, 24 May 2019 09:41:44 +0200
|
||||||
|
Subject: [PATCH] pid1: when reloading configuration, forget old settings
|
||||||
|
|
||||||
|
If we had a configuration setting from a configuration file, and it was
|
||||||
|
removed, we'd still remember the old value, because there's was no mechanism to
|
||||||
|
"reset" everything, just to assign new values.
|
||||||
|
|
||||||
|
Note that the effect of this is limited. For settings that have an "ongoing" effect,
|
||||||
|
like systemd.confirm_spawn, the new value is simply used. But some settings can only
|
||||||
|
be set at start.
|
||||||
|
|
||||||
|
In particular, CPUAffinity= will be updated if set to a new value, but if
|
||||||
|
CPUAffinity= is fully removed, it will not be reset, simply because we don't
|
||||||
|
know what to reset it to. We might have inherited a setting, or we might have
|
||||||
|
set it ourselves. In principle we could remember the "original" value that was
|
||||||
|
set when we were executed, but propagate this over reloads and reexecs, but
|
||||||
|
that would be a lot of work for little gain. So this corner case of removal of
|
||||||
|
CPUAffinity= is not handled fully, and a reboot is needed to execute the
|
||||||
|
change. As a work-around, a full mask of CPUAffinity=0-8191 can be specified.
|
||||||
|
|
||||||
|
(cherry picked from commit fb39af4ce42d7ef9af63009f271f404038703704)
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
---
|
||||||
|
src/core/main.c | 139 +++++++++++++++++++++++++++++++++---------------
|
||||||
|
1 file changed, 95 insertions(+), 44 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/main.c b/src/core/main.c
|
||||||
|
index 9a9f145080..c74dc641c1 100644
|
||||||
|
--- a/src/core/main.c
|
||||||
|
+++ b/src/core/main.c
|
||||||
|
@@ -88,46 +88,52 @@ static enum {
|
||||||
|
ACTION_DUMP_CONFIGURATION_ITEMS,
|
||||||
|
ACTION_DUMP_BUS_PROPERTIES,
|
||||||
|
} arg_action = ACTION_RUN;
|
||||||
|
-static char *arg_default_unit = NULL;
|
||||||
|
-static bool arg_system = false;
|
||||||
|
-static bool arg_dump_core = true;
|
||||||
|
-static int arg_crash_chvt = -1;
|
||||||
|
-static bool arg_crash_shell = false;
|
||||||
|
-static bool arg_crash_reboot = false;
|
||||||
|
-static char *arg_confirm_spawn = NULL;
|
||||||
|
-static ShowStatus arg_show_status = _SHOW_STATUS_UNSET;
|
||||||
|
-static bool arg_switched_root = false;
|
||||||
|
-static bool arg_no_pager = false;
|
||||||
|
-static bool arg_service_watchdogs = true;
|
||||||
|
+
|
||||||
|
+/* Those variables are initalized to 0 automatically, so we avoid uninitialized memory access.
|
||||||
|
+ * Real defaults are assigned in reset_arguments() below. */
|
||||||
|
+static char *arg_default_unit;
|
||||||
|
+static bool arg_system;
|
||||||
|
+static bool arg_dump_core;
|
||||||
|
+static int arg_crash_chvt;
|
||||||
|
+static bool arg_crash_shell;
|
||||||
|
+static bool arg_crash_reboot;
|
||||||
|
+static char *arg_confirm_spawn;
|
||||||
|
+static ShowStatus arg_show_status;
|
||||||
|
+static bool arg_switched_root;
|
||||||
|
+static bool arg_no_pager;
|
||||||
|
+static bool arg_service_watchdogs;
|
||||||
|
static char ***arg_join_controllers = NULL;
|
||||||
|
-static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL;
|
||||||
|
-static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT;
|
||||||
|
-static usec_t arg_default_restart_usec = DEFAULT_RESTART_USEC;
|
||||||
|
-static usec_t arg_default_timeout_start_usec = DEFAULT_TIMEOUT_USEC;
|
||||||
|
-static usec_t arg_default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC;
|
||||||
|
-static usec_t arg_default_start_limit_interval = DEFAULT_START_LIMIT_INTERVAL;
|
||||||
|
-static unsigned arg_default_start_limit_burst = DEFAULT_START_LIMIT_BURST;
|
||||||
|
-static usec_t arg_runtime_watchdog = 0;
|
||||||
|
-static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
|
||||||
|
-static char *arg_watchdog_device = NULL;
|
||||||
|
-static char **arg_default_environment = NULL;
|
||||||
|
-static struct rlimit *arg_default_rlimit[_RLIMIT_MAX] = {};
|
||||||
|
-static uint64_t arg_capability_bounding_set = CAP_ALL;
|
||||||
|
-static bool arg_no_new_privs = false;
|
||||||
|
-static nsec_t arg_timer_slack_nsec = NSEC_INFINITY;
|
||||||
|
-static usec_t arg_default_timer_accuracy_usec = 1 * USEC_PER_MINUTE;
|
||||||
|
-static Set* arg_syscall_archs = NULL;
|
||||||
|
-static FILE* arg_serialization = NULL;
|
||||||
|
-static bool arg_default_cpu_accounting = false;
|
||||||
|
-static bool arg_default_io_accounting = false;
|
||||||
|
-static bool arg_default_ip_accounting = false;
|
||||||
|
-static bool arg_default_blockio_accounting = false;
|
||||||
|
-static bool arg_default_memory_accounting = MEMORY_ACCOUNTING_DEFAULT;
|
||||||
|
-static bool arg_default_tasks_accounting = true;
|
||||||
|
-static uint64_t arg_default_tasks_max = UINT64_MAX;
|
||||||
|
-static sd_id128_t arg_machine_id = {};
|
||||||
|
-static EmergencyAction arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE;
|
||||||
|
-static CPUSet arg_cpu_affinity = {};
|
||||||
|
+static ExecOutput arg_default_std_output;
|
||||||
|
+static ExecOutput arg_default_std_error;
|
||||||
|
+static usec_t arg_default_restart_usec;
|
||||||
|
+static usec_t arg_default_timeout_start_usec;
|
||||||
|
+static usec_t arg_default_timeout_stop_usec;
|
||||||
|
+static usec_t arg_default_timeout_abort_usec;
|
||||||
|
+static bool arg_default_timeout_abort_set;
|
||||||
|
+static usec_t arg_default_start_limit_interval;
|
||||||
|
+static unsigned arg_default_start_limit_burst;
|
||||||
|
+static usec_t arg_runtime_watchdog;
|
||||||
|
+static usec_t arg_shutdown_watchdog;
|
||||||
|
+static char *arg_early_core_pattern;
|
||||||
|
+static char *arg_watchdog_device;
|
||||||
|
+static char **arg_default_environment;
|
||||||
|
+static struct rlimit *arg_default_rlimit[_RLIMIT_MAX];
|
||||||
|
+static uint64_t arg_capability_bounding_set;
|
||||||
|
+static bool arg_no_new_privs;
|
||||||
|
+static nsec_t arg_timer_slack_nsec;
|
||||||
|
+static usec_t arg_default_timer_accuracy_usec;
|
||||||
|
+static Set* arg_syscall_archs;
|
||||||
|
+static FILE* arg_serialization;
|
||||||
|
+static int arg_default_cpu_accounting;
|
||||||
|
+static bool arg_default_io_accounting;
|
||||||
|
+static bool arg_default_ip_accounting;
|
||||||
|
+static bool arg_default_blockio_accounting;
|
||||||
|
+static bool arg_default_memory_accounting;
|
||||||
|
+static bool arg_default_tasks_accounting;
|
||||||
|
+static uint64_t arg_default_tasks_max;
|
||||||
|
+static sd_id128_t arg_machine_id;
|
||||||
|
+static EmergencyAction arg_cad_burst_action;
|
||||||
|
+static CPUSet arg_cpu_affinity;
|
||||||
|
|
||||||
|
static int parse_configuration(void);
|
||||||
|
|
||||||
|
@@ -1951,17 +1957,59 @@ static int do_queue_default_job(
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void free_arguments(void) {
|
||||||
|
-
|
||||||
|
- /* Frees all arg_* variables, with the exception of arg_serialization */
|
||||||
|
- rlimit_free_all(arg_default_rlimit);
|
||||||
|
+static void reset_arguments(void) {
|
||||||
|
+ /* Frees/resets arg_* variables, with a few exceptions commented below. */
|
||||||
|
|
||||||
|
arg_default_unit = mfree(arg_default_unit);
|
||||||
|
+
|
||||||
|
+ /* arg_system — ignore */
|
||||||
|
+
|
||||||
|
+ arg_dump_core = true;
|
||||||
|
+ arg_crash_chvt = -1;
|
||||||
|
+ arg_crash_shell = false;
|
||||||
|
+ arg_crash_reboot = false;
|
||||||
|
arg_confirm_spawn = mfree(arg_confirm_spawn);
|
||||||
|
arg_join_controllers = strv_free_free(arg_join_controllers);
|
||||||
|
+ arg_show_status = _SHOW_STATUS_UNSET;
|
||||||
|
+ arg_switched_root = false;
|
||||||
|
+ arg_no_pager = false;
|
||||||
|
+ arg_service_watchdogs = true;
|
||||||
|
+ arg_default_std_output = EXEC_OUTPUT_JOURNAL;
|
||||||
|
+ arg_default_std_error = EXEC_OUTPUT_INHERIT;
|
||||||
|
+ arg_default_restart_usec = DEFAULT_RESTART_USEC;
|
||||||
|
+ arg_default_timeout_start_usec = DEFAULT_TIMEOUT_USEC;
|
||||||
|
+ arg_default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC;
|
||||||
|
+ arg_default_timeout_abort_usec = DEFAULT_TIMEOUT_USEC;
|
||||||
|
+ arg_default_timeout_abort_set = false;
|
||||||
|
+ arg_default_start_limit_interval = DEFAULT_START_LIMIT_INTERVAL;
|
||||||
|
+ arg_default_start_limit_burst = DEFAULT_START_LIMIT_BURST;
|
||||||
|
+ arg_runtime_watchdog = 0;
|
||||||
|
+ arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
|
||||||
|
+ arg_early_core_pattern = NULL;
|
||||||
|
+ arg_watchdog_device = NULL;
|
||||||
|
+
|
||||||
|
arg_default_environment = strv_free(arg_default_environment);
|
||||||
|
+ rlimit_free_all(arg_default_rlimit);
|
||||||
|
+
|
||||||
|
+ arg_capability_bounding_set = CAP_ALL;
|
||||||
|
+ arg_no_new_privs = false;
|
||||||
|
+ arg_timer_slack_nsec = NSEC_INFINITY;
|
||||||
|
+ arg_default_timer_accuracy_usec = 1 * USEC_PER_MINUTE;
|
||||||
|
+
|
||||||
|
arg_syscall_archs = set_free(arg_syscall_archs);
|
||||||
|
|
||||||
|
+ /* arg_serialization — ignore */
|
||||||
|
+
|
||||||
|
+ arg_default_cpu_accounting = -1;
|
||||||
|
+ arg_default_io_accounting = false;
|
||||||
|
+ arg_default_ip_accounting = false;
|
||||||
|
+ arg_default_blockio_accounting = false;
|
||||||
|
+ arg_default_memory_accounting = MEMORY_ACCOUNTING_DEFAULT;
|
||||||
|
+ arg_default_tasks_accounting = true;
|
||||||
|
+ arg_default_tasks_max = UINT64_MAX;
|
||||||
|
+ arg_machine_id = (sd_id128_t) {};
|
||||||
|
+ arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE;
|
||||||
|
+
|
||||||
|
cpu_set_reset(&arg_cpu_affinity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1970,6 +2018,9 @@ static int parse_configuration(void) {
|
||||||
|
|
||||||
|
arg_default_tasks_max = system_tasks_max_scale(DEFAULT_TASKS_MAX_PERCENTAGE, 100U);
|
||||||
|
|
||||||
|
+ /* Assign configuration defaults */
|
||||||
|
+ reset_arguments();
|
||||||
|
+
|
||||||
|
r = parse_config_file();
|
||||||
|
if (r < 0)
|
||||||
|
log_warning_errno(r, "Failed to parse config file, ignoring: %m");
|
||||||
|
@@ -2460,7 +2511,7 @@ finish:
|
||||||
|
m = manager_free(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
- free_arguments();
|
||||||
|
+ reset_arguments();
|
||||||
|
mac_selinux_finish();
|
||||||
|
|
||||||
|
if (reexecute)
|
114
SOURCES/0279-test-execute-use-CPUSet-too.patch
Normal file
114
SOURCES/0279-test-execute-use-CPUSet-too.patch
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
From 5e6b616ed2708391752ba8c45f183ceb38573d7d Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Tue, 28 May 2019 21:38:41 +0200
|
||||||
|
Subject: [PATCH] test-execute: use CPUSet too
|
||||||
|
|
||||||
|
cpu_set_malloc() was the last user. It doesn't seem useful to keep
|
||||||
|
it just to save the allocation of a few hundred bytes in a test, so
|
||||||
|
it is dropped and a fixed maximum is allocated (1024 bytes).
|
||||||
|
|
||||||
|
(cherry picked from commit 167a776dbe9d033523bd6881e5a695f2155dc321)
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
---
|
||||||
|
src/basic/cpu-set-util.c | 31 +------------------------------
|
||||||
|
src/basic/cpu-set-util.h | 3 +--
|
||||||
|
src/test/test-execute.c | 13 ++++++-------
|
||||||
|
3 files changed, 8 insertions(+), 39 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c
|
||||||
|
index 1803539ac6..c297eab032 100644
|
||||||
|
--- a/src/basic/cpu-set-util.c
|
||||||
|
+++ b/src/basic/cpu-set-util.c
|
||||||
|
@@ -37,36 +37,7 @@ char* cpu_set_to_string(const CPUSet *a) {
|
||||||
|
return TAKE_PTR(str) ?: strdup("");
|
||||||
|
}
|
||||||
|
|
||||||
|
-cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
|
||||||
|
- cpu_set_t *c;
|
||||||
|
- unsigned n = 1024;
|
||||||
|
-
|
||||||
|
- /* Allocates the cpuset in the right size */
|
||||||
|
-
|
||||||
|
- for (;;) {
|
||||||
|
- c = CPU_ALLOC(n);
|
||||||
|
- if (!c)
|
||||||
|
- return NULL;
|
||||||
|
-
|
||||||
|
- if (sched_getaffinity(0, CPU_ALLOC_SIZE(n), c) >= 0) {
|
||||||
|
- CPU_ZERO_S(CPU_ALLOC_SIZE(n), c);
|
||||||
|
-
|
||||||
|
- if (ncpus)
|
||||||
|
- *ncpus = n;
|
||||||
|
-
|
||||||
|
- return c;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- CPU_FREE(c);
|
||||||
|
-
|
||||||
|
- if (errno != EINVAL)
|
||||||
|
- return NULL;
|
||||||
|
-
|
||||||
|
- n *= 2;
|
||||||
|
- }
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
-static int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus) {
|
||||||
|
+int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus) {
|
||||||
|
size_t need;
|
||||||
|
|
||||||
|
assert(cpu_set);
|
||||||
|
diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h
|
||||||
|
index 9b026aca09..b54e737110 100644
|
||||||
|
--- a/src/basic/cpu-set-util.h
|
||||||
|
+++ b/src/basic/cpu-set-util.h
|
||||||
|
@@ -12,8 +12,6 @@
|
||||||
|
DEFINE_TRIVIAL_CLEANUP_FUNC(cpu_set_t*, CPU_FREE);
|
||||||
|
#define _cleanup_cpu_free_ _cleanup_(CPU_FREEp)
|
||||||
|
|
||||||
|
-cpu_set_t* cpu_set_malloc(unsigned *ncpus);
|
||||||
|
-
|
||||||
|
/* This wraps the libc interface with a variable to keep the allocated size. */
|
||||||
|
typedef struct CPUSet {
|
||||||
|
cpu_set_t *set;
|
||||||
|
@@ -30,6 +28,7 @@ static inline void cpu_set_reset(CPUSet *a) {
|
||||||
|
int cpu_set_add_all(CPUSet *a, const CPUSet *b);
|
||||||
|
|
||||||
|
char* cpu_set_to_string(const CPUSet *a);
|
||||||
|
+int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus);
|
||||||
|
int parse_cpu_set_full(
|
||||||
|
const char *rvalue,
|
||||||
|
CPUSet *cpu_set,
|
||||||
|
diff --git a/src/test/test-execute.c b/src/test/test-execute.c
|
||||||
|
index fa8efdddd2..6c22995b1e 100644
|
||||||
|
--- a/src/test/test-execute.c
|
||||||
|
+++ b/src/test/test-execute.c
|
||||||
|
@@ -144,13 +144,12 @@ static void test_exec_bindpaths(Manager *m) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_exec_cpuaffinity(Manager *m) {
|
||||||
|
- _cleanup_cpu_free_ cpu_set_t *c = NULL;
|
||||||
|
- unsigned n;
|
||||||
|
+ _cleanup_(cpu_set_reset) CPUSet c = {};
|
||||||
|
|
||||||
|
- assert_se(c = cpu_set_malloc(&n));
|
||||||
|
- assert_se(sched_getaffinity(0, CPU_ALLOC_SIZE(n), c) >= 0);
|
||||||
|
+ assert_se(cpu_set_realloc(&c, 8192) >= 0); /* just allocate the maximum possible size */
|
||||||
|
+ assert_se(sched_getaffinity(0, c.allocated, c.set) >= 0);
|
||||||
|
|
||||||
|
- if (CPU_ISSET_S(0, CPU_ALLOC_SIZE(n), c) == 0) {
|
||||||
|
+ if (!CPU_ISSET_S(0, c.allocated, c.set)) {
|
||||||
|
log_notice("Cannot use CPU 0, skipping %s", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
@@ -158,8 +157,8 @@ static void test_exec_cpuaffinity(Manager *m) {
|
||||||
|
test(m, "exec-cpuaffinity1.service", 0, CLD_EXITED);
|
||||||
|
test(m, "exec-cpuaffinity2.service", 0, CLD_EXITED);
|
||||||
|
|
||||||
|
- if (CPU_ISSET_S(1, CPU_ALLOC_SIZE(n), c) == 0 ||
|
||||||
|
- CPU_ISSET_S(2, CPU_ALLOC_SIZE(n), c) == 0) {
|
||||||
|
+ if (!CPU_ISSET_S(1, c.allocated, c.set) ||
|
||||||
|
+ !CPU_ISSET_S(2, c.allocated, c.set)) {
|
||||||
|
log_notice("Cannot use CPU 1 or 2, skipping remaining tests in %s", __func__);
|
||||||
|
return;
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
From 7aa32093c3dfc4bf7298f02be553e95c40d7c211 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Tue, 28 May 2019 21:40:10 +0200
|
||||||
|
Subject: [PATCH] shared/cpu-set-util: drop now-unused cleanup function
|
||||||
|
|
||||||
|
(cherry picked from commit cb0d3acf55ef335001cac5dd9c335ec5e75e9b56)
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
---
|
||||||
|
src/basic/cpu-set-util.h | 3 ---
|
||||||
|
1 file changed, 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h
|
||||||
|
index b54e737110..68a73bf9f7 100644
|
||||||
|
--- a/src/basic/cpu-set-util.h
|
||||||
|
+++ b/src/basic/cpu-set-util.h
|
||||||
|
@@ -9,9 +9,6 @@
|
||||||
|
|
||||||
|
#include "macro.h"
|
||||||
|
|
||||||
|
-DEFINE_TRIVIAL_CLEANUP_FUNC(cpu_set_t*, CPU_FREE);
|
||||||
|
-#define _cleanup_cpu_free_ _cleanup_(CPU_FREEp)
|
||||||
|
-
|
||||||
|
/* This wraps the libc interface with a variable to keep the allocated size. */
|
||||||
|
typedef struct CPUSet {
|
||||||
|
cpu_set_t *set;
|
@ -0,0 +1,126 @@
|
|||||||
|
From daa0243fda679c8af723648b8b1e501fc55b0ada Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Sekletar <msekleta@redhat.com>
|
||||||
|
Date: Wed, 22 May 2019 13:55:49 +0200
|
||||||
|
Subject: [PATCH] shared/cpu-set-util: make transfer of cpu_set_t over bus
|
||||||
|
endian safe
|
||||||
|
|
||||||
|
(cherry picked from commit c367f996f5f091a63f812f0140b304c649be77fc)
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
---
|
||||||
|
src/basic/cpu-set-util.c | 38 ++++++++++++++++++++++++++++++++++++++
|
||||||
|
src/basic/cpu-set-util.h | 3 +++
|
||||||
|
src/core/dbus-execute.c | 6 +++++-
|
||||||
|
src/shared/bus-unit-util.c | 8 +++++++-
|
||||||
|
4 files changed, 53 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c
|
||||||
|
index c297eab032..74e35e57dd 100644
|
||||||
|
--- a/src/basic/cpu-set-util.c
|
||||||
|
+++ b/src/basic/cpu-set-util.c
|
||||||
|
@@ -209,3 +209,41 @@ int cpus_in_affinity_mask(void) {
|
||||||
|
n *= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+int cpu_set_to_dbus(const CPUSet *set, uint8_t **ret, size_t *allocated) {
|
||||||
|
+ uint8_t *out;
|
||||||
|
+
|
||||||
|
+ assert(set);
|
||||||
|
+ assert(ret);
|
||||||
|
+
|
||||||
|
+ out = new0(uint8_t, set->allocated);
|
||||||
|
+ if (!out)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ for (unsigned cpu = 0; cpu < set->allocated * 8; cpu++)
|
||||||
|
+ if (CPU_ISSET_S(cpu, set->allocated, set->set))
|
||||||
|
+ out[cpu / 8] |= 1u << (cpu % 8);
|
||||||
|
+
|
||||||
|
+ *ret = out;
|
||||||
|
+ *allocated = set->allocated;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *set) {
|
||||||
|
+ _cleanup_(cpu_set_reset) CPUSet s = {};
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ assert(bits);
|
||||||
|
+ assert(set);
|
||||||
|
+
|
||||||
|
+ for (unsigned cpu = size * 8; cpu > 0; cpu--)
|
||||||
|
+ if (bits[(cpu - 1) / 8] & (1u << ((cpu - 1) % 8))) {
|
||||||
|
+ r = cpu_set_add(&s, cpu - 1);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *set = s;
|
||||||
|
+ s = (CPUSet) {};
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h
|
||||||
|
index 68a73bf9f7..415c6ca295 100644
|
||||||
|
--- a/src/basic/cpu-set-util.h
|
||||||
|
+++ b/src/basic/cpu-set-util.h
|
||||||
|
@@ -46,4 +46,7 @@ static inline int parse_cpu_set(const char *rvalue, CPUSet *cpu_set){
|
||||||
|
return parse_cpu_set_full(rvalue, cpu_set, false, NULL, NULL, 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
+int cpu_set_to_dbus(const CPUSet *set, uint8_t **ret, size_t *allocated);
|
||||||
|
+int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *set);
|
||||||
|
+
|
||||||
|
int cpus_in_affinity_mask(void);
|
||||||
|
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
|
||||||
|
index 08946627e3..50ea71a281 100644
|
||||||
|
--- a/src/core/dbus-execute.c
|
||||||
|
+++ b/src/core/dbus-execute.c
|
||||||
|
@@ -1553,18 +1553,22 @@ int bus_exec_context_set_transient_property(
|
||||||
|
if (streq(name, "CPUAffinity")) {
|
||||||
|
const void *a;
|
||||||
|
size_t n;
|
||||||
|
+ _cleanup_(cpu_set_reset) CPUSet set = {};
|
||||||
|
|
||||||
|
r = sd_bus_message_read_array(message, 'y', &a, &n);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
+ r = cpu_set_from_dbus(a, n, &set);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||||
|
if (n == 0) {
|
||||||
|
cpu_set_reset(&c->cpu_set);
|
||||||
|
unit_write_settingf(u, flags, name, "%s=", name);
|
||||||
|
} else {
|
||||||
|
_cleanup_free_ char *str = NULL;
|
||||||
|
- const CPUSet set = {(cpu_set_t*) a, n};
|
||||||
|
|
||||||
|
str = cpu_set_to_string(&set);
|
||||||
|
if (!str)
|
||||||
|
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
|
||||||
|
index 75b4aace84..ec8732c226 100644
|
||||||
|
--- a/src/shared/bus-unit-util.c
|
||||||
|
+++ b/src/shared/bus-unit-util.c
|
||||||
|
@@ -933,12 +933,18 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
|
||||||
|
|
||||||
|
if (streq(field, "CPUAffinity")) {
|
||||||
|
_cleanup_(cpu_set_reset) CPUSet cpuset = {};
|
||||||
|
+ _cleanup_free_ uint8_t *array = NULL;
|
||||||
|
+ size_t allocated;
|
||||||
|
|
||||||
|
r = parse_cpu_set(eq, &cpuset);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to parse %s value: %s", field, eq);
|
||||||
|
|
||||||
|
- return bus_append_byte_array(m, field, cpuset.set, cpuset.allocated);
|
||||||
|
+ r = cpu_set_to_dbus(&cpuset, &array, &allocated);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_error_errno(r, "Failed to serialize CPUAffinity: %m");
|
||||||
|
+
|
||||||
|
+ return bus_append_byte_array(m, field, array, allocated);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (STR_IN_SET(field, "RestrictAddressFamilies", "SystemCallFilter")) {
|
@ -0,0 +1,61 @@
|
|||||||
|
From fd65eadbbcc068171ee9164610fd1c2016b3bf59 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Wed, 29 May 2019 09:44:16 +0200
|
||||||
|
Subject: [PATCH] test-cpu-set-util: add test for dbus conversions
|
||||||
|
|
||||||
|
(cherry picked from commit 1bf0d6c28f8c884e187c7dacc1a969c0763ff4e3)
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
---
|
||||||
|
src/test/test-cpu-set-util.c | 31 +++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 31 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
|
||||||
|
index 81f67647e8..cae51ad7d9 100644
|
||||||
|
--- a/src/test/test-cpu-set-util.c
|
||||||
|
+++ b/src/test/test-cpu-set-util.c
|
||||||
|
@@ -181,6 +181,36 @@ static void test_parse_cpu_set_extend(void) {
|
||||||
|
log_info("cpu_set_to_string: (null)");
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void test_cpu_set_to_from_dbus(void) {
|
||||||
|
+ _cleanup_(cpu_set_reset) CPUSet c = {}, c2 = {};
|
||||||
|
+ _cleanup_free_ char *s = NULL;
|
||||||
|
+
|
||||||
|
+ log_info("/* %s */", __func__);
|
||||||
|
+
|
||||||
|
+ assert_se(parse_cpu_set_extend("1 3 8 100-200", &c, true, NULL, "fake", 1, "CPUAffinity") == 0);
|
||||||
|
+ assert_se(s = cpu_set_to_string(&c));
|
||||||
|
+ log_info("cpu_set_to_string: %s", s);
|
||||||
|
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 104);
|
||||||
|
+
|
||||||
|
+ _cleanup_free_ uint8_t *array = NULL;
|
||||||
|
+ size_t allocated;
|
||||||
|
+ static const char expected[32] =
|
||||||
|
+ "\x0A\x01\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||||
|
+ "\x00\x00\xF0\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
|
||||||
|
+ "\xFF\xFF\xFF\xFF\xFF\x01";
|
||||||
|
+
|
||||||
|
+ assert_se(cpu_set_to_dbus(&c, &array, &allocated) == 0);
|
||||||
|
+ assert_se(array);
|
||||||
|
+ assert_se(allocated == c.allocated);
|
||||||
|
+
|
||||||
|
+ assert(memcmp(array, expected, sizeof expected) == 0);
|
||||||
|
+
|
||||||
|
+ assert_se(cpu_set_from_dbus(array, allocated, &c2) == 0);
|
||||||
|
+ assert_se(c2.set);
|
||||||
|
+ assert_se(c2.allocated == c.allocated);
|
||||||
|
+ assert_se(memcmp(c.set, c2.set, c.allocated) == 0);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void test_cpus_in_affinity_mask(void) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
@@ -201,6 +231,7 @@ int main(int argc, char *argv[]) {
|
||||||
|
test_parse_cpu_set();
|
||||||
|
test_parse_cpu_set_extend();
|
||||||
|
test_cpus_in_affinity_mask();
|
||||||
|
+ test_cpu_set_to_from_dbus();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -0,0 +1,203 @@
|
|||||||
|
From 93777a6dd8c12d5cba094694bf7ed6e8c06c2d6d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Sekletar <msekleta@redhat.com>
|
||||||
|
Date: Thu, 23 May 2019 14:27:18 +0200
|
||||||
|
Subject: [PATCH] shared/cpu-set-util: introduce cpu_set_to_range()
|
||||||
|
|
||||||
|
(cherry picked from commit 71b28519b55b496237146f9bcb5a627455f15f7e)
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
---
|
||||||
|
src/basic/cpu-set-util.c | 37 ++++++++++++++++++++++++++
|
||||||
|
src/basic/cpu-set-util.h | 2 ++
|
||||||
|
src/test/test-cpu-set-util.c | 50 ++++++++++++++++++++++++++++++++++++
|
||||||
|
3 files changed, 89 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c
|
||||||
|
index 74e35e57dd..bff39ec143 100644
|
||||||
|
--- a/src/basic/cpu-set-util.c
|
||||||
|
+++ b/src/basic/cpu-set-util.c
|
||||||
|
@@ -37,6 +37,43 @@ char* cpu_set_to_string(const CPUSet *a) {
|
||||||
|
return TAKE_PTR(str) ?: strdup("");
|
||||||
|
}
|
||||||
|
|
||||||
|
+char *cpu_set_to_range_string(const CPUSet *set) {
|
||||||
|
+ unsigned range_start = 0, range_end;
|
||||||
|
+ _cleanup_free_ char *str = NULL;
|
||||||
|
+ size_t allocated = 0, len = 0;
|
||||||
|
+ bool in_range = false;
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ for (unsigned i = 0; i < set->allocated * 8; i++)
|
||||||
|
+ if (CPU_ISSET_S(i, set->allocated, set->set)) {
|
||||||
|
+ if (in_range)
|
||||||
|
+ range_end++;
|
||||||
|
+ else {
|
||||||
|
+ range_start = range_end = i;
|
||||||
|
+ in_range = true;
|
||||||
|
+ }
|
||||||
|
+ } else if (in_range) {
|
||||||
|
+ in_range = false;
|
||||||
|
+
|
||||||
|
+ if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(unsigned)))
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end);
|
||||||
|
+ assert_se(r > 0);
|
||||||
|
+ len += r;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (in_range) {
|
||||||
|
+ if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(int)))
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
+ r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end);
|
||||||
|
+ assert_se(r > 0);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return TAKE_PTR(str) ?: strdup("");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus) {
|
||||||
|
size_t need;
|
||||||
|
|
||||||
|
diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h
|
||||||
|
index 415c6ca295..ec640b2ec9 100644
|
||||||
|
--- a/src/basic/cpu-set-util.h
|
||||||
|
+++ b/src/basic/cpu-set-util.h
|
||||||
|
@@ -25,7 +25,9 @@ static inline void cpu_set_reset(CPUSet *a) {
|
||||||
|
int cpu_set_add_all(CPUSet *a, const CPUSet *b);
|
||||||
|
|
||||||
|
char* cpu_set_to_string(const CPUSet *a);
|
||||||
|
+char *cpu_set_to_range_string(const CPUSet *a);
|
||||||
|
int cpu_set_realloc(CPUSet *cpu_set, unsigned ncpus);
|
||||||
|
+
|
||||||
|
int parse_cpu_set_full(
|
||||||
|
const char *rvalue,
|
||||||
|
CPUSet *cpu_set,
|
||||||
|
diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
|
||||||
|
index cae51ad7d9..0d2741cd43 100644
|
||||||
|
--- a/src/test/test-cpu-set-util.c
|
||||||
|
+++ b/src/test/test-cpu-set-util.c
|
||||||
|
@@ -4,6 +4,7 @@
|
||||||
|
|
||||||
|
#include "alloc-util.h"
|
||||||
|
#include "cpu-set-util.h"
|
||||||
|
+#include "string-util.h"
|
||||||
|
#include "macro.h"
|
||||||
|
|
||||||
|
static void test_parse_cpu_set(void) {
|
||||||
|
@@ -13,6 +14,22 @@ static void test_parse_cpu_set(void) {
|
||||||
|
|
||||||
|
log_info("/* %s */", __func__);
|
||||||
|
|
||||||
|
+ /* Single value */
|
||||||
|
+ assert_se(parse_cpu_set_full("0", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
+ assert_se(c.set);
|
||||||
|
+ assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(CPU_ISSET_S(0, c.allocated, c.set));
|
||||||
|
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 1);
|
||||||
|
+
|
||||||
|
+ assert_se(str = cpu_set_to_string(&c));
|
||||||
|
+ log_info("cpu_set_to_string: %s", str);
|
||||||
|
+ str = mfree(str);
|
||||||
|
+ assert_se(str = cpu_set_to_range_string(&c));
|
||||||
|
+ log_info("cpu_set_to_range_string: %s", str);
|
||||||
|
+ assert_se(streq(str, "0-0"));
|
||||||
|
+ str = mfree(str);
|
||||||
|
+ cpu_set_reset(&c);
|
||||||
|
+
|
||||||
|
/* Simple range (from CPUAffinity example) */
|
||||||
|
assert_se(parse_cpu_set_full("1 2", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
assert_se(c.set);
|
||||||
|
@@ -24,6 +41,10 @@ static void test_parse_cpu_set(void) {
|
||||||
|
assert_se(str = cpu_set_to_string(&c));
|
||||||
|
log_info("cpu_set_to_string: %s", str);
|
||||||
|
str = mfree(str);
|
||||||
|
+ assert_se(str = cpu_set_to_range_string(&c));
|
||||||
|
+ log_info("cpu_set_to_range_string: %s", str);
|
||||||
|
+ assert_se(streq(str, "1-2"));
|
||||||
|
+ str = mfree(str);
|
||||||
|
cpu_set_reset(&c);
|
||||||
|
|
||||||
|
/* A more interesting range */
|
||||||
|
@@ -34,9 +55,14 @@ static void test_parse_cpu_set(void) {
|
||||||
|
assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
for (cpu = 8; cpu < 12; cpu++)
|
||||||
|
assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
+
|
||||||
|
assert_se(str = cpu_set_to_string(&c));
|
||||||
|
log_info("cpu_set_to_string: %s", str);
|
||||||
|
str = mfree(str);
|
||||||
|
+ assert_se(str = cpu_set_to_range_string(&c));
|
||||||
|
+ log_info("cpu_set_to_range_string: %s", str);
|
||||||
|
+ assert_se(streq(str, "0-3 8-11"));
|
||||||
|
+ str = mfree(str);
|
||||||
|
cpu_set_reset(&c);
|
||||||
|
|
||||||
|
/* Quoted strings */
|
||||||
|
@@ -48,6 +74,10 @@ static void test_parse_cpu_set(void) {
|
||||||
|
assert_se(str = cpu_set_to_string(&c));
|
||||||
|
log_info("cpu_set_to_string: %s", str);
|
||||||
|
str = mfree(str);
|
||||||
|
+ assert_se(str = cpu_set_to_range_string(&c));
|
||||||
|
+ log_info("cpu_set_to_range_string: %s", str);
|
||||||
|
+ assert_se(streq(str, "8-11"));
|
||||||
|
+ str = mfree(str);
|
||||||
|
cpu_set_reset(&c);
|
||||||
|
|
||||||
|
/* Use commas as separators */
|
||||||
|
@@ -72,6 +102,10 @@ static void test_parse_cpu_set(void) {
|
||||||
|
assert_se(str = cpu_set_to_string(&c));
|
||||||
|
log_info("cpu_set_to_string: %s", str);
|
||||||
|
str = mfree(str);
|
||||||
|
+ assert_se(str = cpu_set_to_range_string(&c));
|
||||||
|
+ log_info("cpu_set_to_range_string: %s", str);
|
||||||
|
+ assert_se(streq(str, "0-7"));
|
||||||
|
+ str = mfree(str);
|
||||||
|
cpu_set_reset(&c);
|
||||||
|
|
||||||
|
/* Ranges */
|
||||||
|
@@ -98,6 +132,10 @@ static void test_parse_cpu_set(void) {
|
||||||
|
assert_se(str = cpu_set_to_string(&c));
|
||||||
|
log_info("cpu_set_to_string: %s", str);
|
||||||
|
str = mfree(str);
|
||||||
|
+ assert_se(str = cpu_set_to_range_string(&c));
|
||||||
|
+ log_info("cpu_set_to_range_string: %s", str);
|
||||||
|
+ assert_se(streq(str, "0-3 8-11"));
|
||||||
|
+ str = mfree(str);
|
||||||
|
cpu_set_reset(&c);
|
||||||
|
|
||||||
|
/* Negative range (returns empty cpu_set) */
|
||||||
|
@@ -115,6 +153,10 @@ static void test_parse_cpu_set(void) {
|
||||||
|
assert_se(str = cpu_set_to_string(&c));
|
||||||
|
log_info("cpu_set_to_string: %s", str);
|
||||||
|
str = mfree(str);
|
||||||
|
+ assert_se(str = cpu_set_to_range_string(&c));
|
||||||
|
+ log_info("cpu_set_to_range_string: %s", str);
|
||||||
|
+ assert_se(streq(str, "0-11"));
|
||||||
|
+ str = mfree(str);
|
||||||
|
cpu_set_reset(&c);
|
||||||
|
|
||||||
|
/* Mix ranges and individual CPUs */
|
||||||
|
@@ -128,6 +170,10 @@ static void test_parse_cpu_set(void) {
|
||||||
|
assert_se(str = cpu_set_to_string(&c));
|
||||||
|
log_info("cpu_set_to_string: %s", str);
|
||||||
|
str = mfree(str);
|
||||||
|
+ assert_se(str = cpu_set_to_range_string(&c));
|
||||||
|
+ log_info("cpu_set_to_range_string: %s", str);
|
||||||
|
+ assert_se(streq(str, "0-1 4-11"));
|
||||||
|
+ str = mfree(str);
|
||||||
|
cpu_set_reset(&c);
|
||||||
|
|
||||||
|
/* Garbage */
|
||||||
|
@@ -156,6 +202,10 @@ static void test_parse_cpu_set(void) {
|
||||||
|
assert_se(str = cpu_set_to_string(&c));
|
||||||
|
log_info("cpu_set_to_string: %s", str);
|
||||||
|
str = mfree(str);
|
||||||
|
+ assert_se(str = cpu_set_to_range_string(&c));
|
||||||
|
+ log_info("cpu_set_to_range_string: %s", str);
|
||||||
|
+ assert_se(streq(str, "8000-8191"));
|
||||||
|
+ str = mfree(str);
|
||||||
|
cpu_set_reset(&c);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,53 @@
|
|||||||
|
From fb1244ef318e9f54628a7c13db9e2ffbc712dd38 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Sekletar <msekleta@redhat.com>
|
||||||
|
Date: Wed, 22 May 2019 17:14:21 +0200
|
||||||
|
Subject: [PATCH] systemctl: present CPUAffinity mask as a list of CPU index
|
||||||
|
ranges
|
||||||
|
|
||||||
|
(cherry picked from commit a047f4f10ed2f922d6079c033d24a443b0e95f38)
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
---
|
||||||
|
src/systemctl/systemctl.c | 22 ++++++++++++++++++++++
|
||||||
|
1 file changed, 22 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
|
||||||
|
index f072ad0c31..0154b300a3 100644
|
||||||
|
--- a/src/systemctl/systemctl.c
|
||||||
|
+++ b/src/systemctl/systemctl.c
|
||||||
|
@@ -30,6 +30,7 @@
|
||||||
|
#include "cgroup-show.h"
|
||||||
|
#include "cgroup-util.h"
|
||||||
|
#include "copy.h"
|
||||||
|
+#include "cpu-set-util.h"
|
||||||
|
#include "dropin.h"
|
||||||
|
#include "efivars.h"
|
||||||
|
#include "env-util.h"
|
||||||
|
@@ -4876,6 +4877,27 @@ static int print_property(const char *name, sd_bus_message *m, bool value, bool
|
||||||
|
|
||||||
|
print_prop(name, "%s", h);
|
||||||
|
|
||||||
|
+ return 1;
|
||||||
|
+ } else if (contents[0] == SD_BUS_TYPE_BYTE && streq(name, "CPUAffinity")) {
|
||||||
|
+ _cleanup_free_ char *affinity = NULL;
|
||||||
|
+ _cleanup_(cpu_set_reset) CPUSet set = {};
|
||||||
|
+ const void *a;
|
||||||
|
+ size_t n;
|
||||||
|
+
|
||||||
|
+ r = sd_bus_message_read_array(m, 'y', &a, &n);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return bus_log_parse_error(r);
|
||||||
|
+
|
||||||
|
+ r = cpu_set_from_dbus(a, n, &set);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_error_errno(r, "Failed to deserialize CPUAffinity: %m");
|
||||||
|
+
|
||||||
|
+ affinity = cpu_set_to_range_string(&set);
|
||||||
|
+ if (!affinity)
|
||||||
|
+ return log_oom();
|
||||||
|
+
|
||||||
|
+ print_prop(name, "%s", affinity);
|
||||||
|
+
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,77 @@
|
|||||||
|
From cabd9055d0d745f7de9625dec6c623d363dd3aa6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Wed, 29 May 2019 10:17:43 +0200
|
||||||
|
Subject: [PATCH] shared/cpu-set-util: only force range printing one time
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
The idea is to have at least one range to make the new format clearly
|
||||||
|
distinguishable from the old. But it is enough to just do it once.
|
||||||
|
In particular, in case the affinity would be specified like 0, 2, 4, 6…,
|
||||||
|
this gives much shorter output.
|
||||||
|
|
||||||
|
(cherry picked from commit 1f57a176af5152d05719bf43740e87a47e37af50)
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
---
|
||||||
|
src/basic/cpu-set-util.c | 10 ++++++++--
|
||||||
|
src/test/test-cpu-set-util.c | 7 ++++---
|
||||||
|
2 files changed, 12 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c
|
||||||
|
index bff39ec143..5024290557 100644
|
||||||
|
--- a/src/basic/cpu-set-util.c
|
||||||
|
+++ b/src/basic/cpu-set-util.c
|
||||||
|
@@ -58,7 +58,10 @@ char *cpu_set_to_range_string(const CPUSet *set) {
|
||||||
|
if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(unsigned)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
- r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end);
|
||||||
|
+ if (range_end > range_start || len == 0)
|
||||||
|
+ r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end);
|
||||||
|
+ else
|
||||||
|
+ r = sprintf(str + len, len > 0 ? " %d" : "%d", range_start);
|
||||||
|
assert_se(r > 0);
|
||||||
|
len += r;
|
||||||
|
}
|
||||||
|
@@ -67,7 +70,10 @@ char *cpu_set_to_range_string(const CPUSet *set) {
|
||||||
|
if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(int)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
- r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end);
|
||||||
|
+ if (range_end > range_start || len == 0)
|
||||||
|
+ r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end);
|
||||||
|
+ else
|
||||||
|
+ r = sprintf(str + len, len > 0 ? " %d" : "%d", range_start);
|
||||||
|
assert_se(r > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
|
||||||
|
index 0d2741cd43..995b981d25 100644
|
||||||
|
--- a/src/test/test-cpu-set-util.c
|
||||||
|
+++ b/src/test/test-cpu-set-util.c
|
||||||
|
@@ -31,19 +31,20 @@ static void test_parse_cpu_set(void) {
|
||||||
|
cpu_set_reset(&c);
|
||||||
|
|
||||||
|
/* Simple range (from CPUAffinity example) */
|
||||||
|
- assert_se(parse_cpu_set_full("1 2", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
+ assert_se(parse_cpu_set_full("1 2 4", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
assert_se(c.set);
|
||||||
|
assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
assert_se(CPU_ISSET_S(1, c.allocated, c.set));
|
||||||
|
assert_se(CPU_ISSET_S(2, c.allocated, c.set));
|
||||||
|
- assert_se(CPU_COUNT_S(c.allocated, c.set) == 2);
|
||||||
|
+ assert_se(CPU_ISSET_S(4, c.allocated, c.set));
|
||||||
|
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 3);
|
||||||
|
|
||||||
|
assert_se(str = cpu_set_to_string(&c));
|
||||||
|
log_info("cpu_set_to_string: %s", str);
|
||||||
|
str = mfree(str);
|
||||||
|
assert_se(str = cpu_set_to_range_string(&c));
|
||||||
|
log_info("cpu_set_to_range_string: %s", str);
|
||||||
|
- assert_se(streq(str, "1-2"));
|
||||||
|
+ assert_se(streq(str, "1-2 4"));
|
||||||
|
str = mfree(str);
|
||||||
|
cpu_set_reset(&c);
|
||||||
|
|
@ -0,0 +1,36 @@
|
|||||||
|
From b90f935f8d2268522480a7c12f7e2213a7a5e19d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Sekletar <msekleta@redhat.com>
|
||||||
|
Date: Fri, 31 May 2019 18:02:20 +0200
|
||||||
|
Subject: [PATCH] execute: dump CPUAffinity as a range string instead of a list
|
||||||
|
of CPUs
|
||||||
|
|
||||||
|
We do this already when printing the property in systemctl so be
|
||||||
|
consistent and do the same for systemd-analyze dump.
|
||||||
|
|
||||||
|
(cherry picked from commit e7fca352ba43988682a927de6b1f629b3f10a415)
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
---
|
||||||
|
src/core/execute.c | 9 ++++-----
|
||||||
|
1 file changed, 4 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/execute.c b/src/core/execute.c
|
||||||
|
index 22e5825905..bc26aa66e7 100644
|
||||||
|
--- a/src/core/execute.c
|
||||||
|
+++ b/src/core/execute.c
|
||||||
|
@@ -4098,11 +4098,10 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->cpu_set.set) {
|
||||||
|
- fprintf(f, "%sCPUAffinity:", prefix);
|
||||||
|
- for (i = 0; i < c->cpu_set.allocated * 8; i++)
|
||||||
|
- if (CPU_ISSET_S(i, c->cpu_set.allocated, c->cpu_set.set))
|
||||||
|
- fprintf(f, " %u", i);
|
||||||
|
- fputs("\n", f);
|
||||||
|
+ _cleanup_free_ char *affinity = NULL;
|
||||||
|
+
|
||||||
|
+ affinity = cpu_set_to_range_string(&c->cpu_set);
|
||||||
|
+ fprintf(f, "%sCPUAffinity: %s\n", prefix, affinity);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->timer_slack_nsec != NSEC_INFINITY)
|
@ -0,0 +1,95 @@
|
|||||||
|
From 35894625624f0e8c7d3ca2c200861005c7ad4435 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michal Sekletar <msekleta@redhat.com>
|
||||||
|
Date: Mon, 3 Jun 2019 10:12:35 +0200
|
||||||
|
Subject: [PATCH] cpu-set-util: use %d-%d format in cpu_set_to_range_string()
|
||||||
|
only for actual ranges
|
||||||
|
|
||||||
|
(cherry picked from commit 71923237b18df35401626993d8a285cd998be78d)
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
---
|
||||||
|
src/basic/cpu-set-util.c | 4 ++--
|
||||||
|
src/test/test-cpu-set-util.c | 16 +++++++++-------
|
||||||
|
2 files changed, 11 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c
|
||||||
|
index 5024290557..103b9703b3 100644
|
||||||
|
--- a/src/basic/cpu-set-util.c
|
||||||
|
+++ b/src/basic/cpu-set-util.c
|
||||||
|
@@ -58,7 +58,7 @@ char *cpu_set_to_range_string(const CPUSet *set) {
|
||||||
|
if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(unsigned)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
- if (range_end > range_start || len == 0)
|
||||||
|
+ if (range_end > range_start)
|
||||||
|
r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end);
|
||||||
|
else
|
||||||
|
r = sprintf(str + len, len > 0 ? " %d" : "%d", range_start);
|
||||||
|
@@ -70,7 +70,7 @@ char *cpu_set_to_range_string(const CPUSet *set) {
|
||||||
|
if (!GREEDY_REALLOC(str, allocated, len + 2 + 2 * DECIMAL_STR_MAX(int)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
- if (range_end > range_start || len == 0)
|
||||||
|
+ if (range_end > range_start)
|
||||||
|
r = sprintf(str + len, len > 0 ? " %d-%d" : "%d-%d", range_start, range_end);
|
||||||
|
else
|
||||||
|
r = sprintf(str + len, len > 0 ? " %d" : "%d", range_start);
|
||||||
|
diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
|
||||||
|
index 995b981d25..9522582891 100644
|
||||||
|
--- a/src/test/test-cpu-set-util.c
|
||||||
|
+++ b/src/test/test-cpu-set-util.c
|
||||||
|
@@ -26,7 +26,7 @@ static void test_parse_cpu_set(void) {
|
||||||
|
str = mfree(str);
|
||||||
|
assert_se(str = cpu_set_to_range_string(&c));
|
||||||
|
log_info("cpu_set_to_range_string: %s", str);
|
||||||
|
- assert_se(streq(str, "0-0"));
|
||||||
|
+ assert_se(streq(str, "0"));
|
||||||
|
str = mfree(str);
|
||||||
|
cpu_set_reset(&c);
|
||||||
|
|
||||||
|
@@ -95,17 +95,19 @@ static void test_parse_cpu_set(void) {
|
||||||
|
cpu_set_reset(&c);
|
||||||
|
|
||||||
|
/* Commas with spaces (and trailing comma, space) */
|
||||||
|
- assert_se(parse_cpu_set_full("0, 1, 2, 3, 4, 5, 6, 7, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
+ assert_se(parse_cpu_set_full("0, 1, 2, 3, 4, 5, 6, 7, 63, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
- assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
|
||||||
|
+ assert_se(CPU_COUNT_S(c.allocated, c.set) == 9);
|
||||||
|
for (cpu = 0; cpu < 8; cpu++)
|
||||||
|
assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
+
|
||||||
|
+ assert_se(CPU_ISSET_S(63, c.allocated, c.set));
|
||||||
|
assert_se(str = cpu_set_to_string(&c));
|
||||||
|
log_info("cpu_set_to_string: %s", str);
|
||||||
|
str = mfree(str);
|
||||||
|
assert_se(str = cpu_set_to_range_string(&c));
|
||||||
|
log_info("cpu_set_to_range_string: %s", str);
|
||||||
|
- assert_se(streq(str, "0-7"));
|
||||||
|
+ assert_se(streq(str, "0-7 63"));
|
||||||
|
str = mfree(str);
|
||||||
|
cpu_set_reset(&c);
|
||||||
|
|
||||||
|
@@ -161,11 +163,11 @@ static void test_parse_cpu_set(void) {
|
||||||
|
cpu_set_reset(&c);
|
||||||
|
|
||||||
|
/* Mix ranges and individual CPUs */
|
||||||
|
- assert_se(parse_cpu_set_full("0,1 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
+ assert_se(parse_cpu_set_full("0,2 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
assert_se(CPU_COUNT_S(c.allocated, c.set) == 10);
|
||||||
|
assert_se(CPU_ISSET_S(0, c.allocated, c.set));
|
||||||
|
- assert_se(CPU_ISSET_S(1, c.allocated, c.set));
|
||||||
|
+ assert_se(CPU_ISSET_S(2, c.allocated, c.set));
|
||||||
|
for (cpu = 4; cpu < 12; cpu++)
|
||||||
|
assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
assert_se(str = cpu_set_to_string(&c));
|
||||||
|
@@ -173,7 +175,7 @@ static void test_parse_cpu_set(void) {
|
||||||
|
str = mfree(str);
|
||||||
|
assert_se(str = cpu_set_to_range_string(&c));
|
||||||
|
log_info("cpu_set_to_range_string: %s", str);
|
||||||
|
- assert_se(streq(str, "0-1 4-11"));
|
||||||
|
+ assert_se(streq(str, "0 2 4-11"));
|
||||||
|
str = mfree(str);
|
||||||
|
cpu_set_reset(&c);
|
||||||
|
|
@ -0,0 +1,779 @@
|
|||||||
|
From a735699a8287c19e043b7d2fe9a387a3938e1e2f Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= <msekleta@redhat.com>
|
||||||
|
Date: Mon, 18 Nov 2019 12:50:11 +0100
|
||||||
|
Subject: [PATCH] core: introduce NUMAPolicy and NUMAMask options
|
||||||
|
|
||||||
|
Make possible to set NUMA allocation policy for manager. Manager's
|
||||||
|
policy is by default inherited to all forked off processes. However, it
|
||||||
|
is possible to override the policy on per-service basis. Currently we
|
||||||
|
support, these policies: default, prefer, bind, interleave, local.
|
||||||
|
See man 2 set_mempolicy for details on each policy.
|
||||||
|
|
||||||
|
Overall NUMA policy actually consists of two parts. Policy itself and
|
||||||
|
bitmask representing NUMA nodes where is policy effective. Node mask can
|
||||||
|
be specified using related option, NUMAMask. Default mask can be
|
||||||
|
overwritten on per-service level.
|
||||||
|
|
||||||
|
(cherry-picked from commit fe9c54b2188e6cd23262a319f96b13215f2c5e9c)
|
||||||
|
|
||||||
|
Resolves: #1734787
|
||||||
|
---
|
||||||
|
man/systemd-system.conf.xml | 19 ++++++
|
||||||
|
man/systemd.exec.xml | 28 +++++++++
|
||||||
|
meson.build | 4 ++
|
||||||
|
src/basic/cpu-set-util.c | 91 +++++++++++++++++++++++++++
|
||||||
|
src/basic/cpu-set-util.h | 28 +++++++++
|
||||||
|
src/basic/exit-status.c | 3 +
|
||||||
|
src/basic/exit-status.h | 1 +
|
||||||
|
src/basic/missing_syscall.h | 43 +++++++++++++
|
||||||
|
src/core/dbus-execute.c | 65 ++++++++++++++++++-
|
||||||
|
src/core/execute.c | 20 ++++++
|
||||||
|
src/core/execute.h | 1 +
|
||||||
|
src/core/load-fragment-gperf.gperf.m4 | 2 +
|
||||||
|
src/core/load-fragment.c | 28 +++++++++
|
||||||
|
src/core/load-fragment.h | 2 +
|
||||||
|
src/core/main.c | 27 ++++++++
|
||||||
|
src/core/system.conf.in | 2 +
|
||||||
|
src/shared/bus-unit-util.c | 28 +++++++++
|
||||||
|
src/systemctl/systemctl.c | 18 +++++-
|
||||||
|
18 files changed, 405 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml
|
||||||
|
index ab23779ec0..988c4e7665 100644
|
||||||
|
--- a/man/systemd-system.conf.xml
|
||||||
|
+++ b/man/systemd-system.conf.xml
|
||||||
|
@@ -132,6 +132,25 @@
|
||||||
|
anymore.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><varname>NUMAPolicy=</varname></term>
|
||||||
|
+
|
||||||
|
+ <listitem><para>Configures the NUMA memory policy for the service manager and the default NUMA memory policy
|
||||||
|
+ for all forked off processes. Individual services may override the default policy with the
|
||||||
|
+ <varname>NUMAPolicy=</varname> setting in unit files, see
|
||||||
|
+ <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><varname>NUMAMask=</varname></term>
|
||||||
|
+
|
||||||
|
+ <listitem><para>Configures the NUMA node mask that will be associated with the selected NUMA policy. Note that
|
||||||
|
+ <option>default</option> and <option>local</option> NUMA policies don't require explicit NUMA node mask and
|
||||||
|
+ value of the option can be empty. Similarly to <varname>NUMAPolicy=</varname>, value can be overriden
|
||||||
|
+ by individual services in unit files, see
|
||||||
|
+ <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>RuntimeWatchdogSec=</varname></term>
|
||||||
|
<term><varname>ShutdownWatchdogSec=</varname></term>
|
||||||
|
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
|
||||||
|
index 342b8385bc..87fb8b34f4 100644
|
||||||
|
--- a/man/systemd.exec.xml
|
||||||
|
+++ b/man/systemd.exec.xml
|
||||||
|
@@ -710,6 +710,28 @@ CapabilityBoundingSet=~CAP_B CAP_C</programlisting>
|
||||||
|
details.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><varname>NUMAPolicy=</varname></term>
|
||||||
|
+
|
||||||
|
+ <listitem><para>Controls the NUMA memory policy of the executed processes. Takes a policy type, one of:
|
||||||
|
+ <option>default</option>, <option>preferred</option>, <option>bind</option>, <option>interleave</option> and
|
||||||
|
+ <option>local</option>. A list of NUMA nodes that should be associated with the policy must be specified
|
||||||
|
+ in <varname>NUMAMask=</varname>. For more details on each policy please see,
|
||||||
|
+ <citerefentry><refentrytitle>set_mempolicy</refentrytitle><manvolnum>2</manvolnum></citerefentry>. For overall
|
||||||
|
+ overview of NUMA support in Linux see,
|
||||||
|
+ <citerefentry><refentrytitle>numa</refentrytitle><manvolnum>7</manvolnum></citerefentry>
|
||||||
|
+ </para></listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term><varname>NUMAMask=</varname></term>
|
||||||
|
+
|
||||||
|
+ <listitem><para>Controls the NUMA node list which will be applied alongside with selected NUMA policy.
|
||||||
|
+ Takes a list of NUMA nodes and has the same syntax as a list of CPUs for <varname>CPUAffinity=</varname>
|
||||||
|
+ option. Note that the list of NUMA nodes is not required for <option>default</option> and <option>local</option>
|
||||||
|
+ policies and for <option>preferred</option> policy we expect a single NUMA node.</para></listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+
|
||||||
|
<varlistentry>
|
||||||
|
<term><varname>IOSchedulingClass=</varname></term>
|
||||||
|
|
||||||
|
@@ -2709,6 +2731,12 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy
|
||||||
|
<entry><constant>EXIT_CONFIGURATION_DIRECTORY</constant></entry>
|
||||||
|
<entry>Failed to set up unit's configuration directory. See <varname>ConfigurationDirectory=</varname> above.</entry>
|
||||||
|
</row>
|
||||||
|
+ <row>
|
||||||
|
+ <entry>242</entry>
|
||||||
|
+ <entry><constant>EXIT_NUMA_POLICY</constant></entry>
|
||||||
|
+ <entry>Failed to set up unit's NUMA memory policy. See <varname>NUMAPolicy=</varname> and <varname>NUMAMask=</varname>above.</entry>
|
||||||
|
+ </row>
|
||||||
|
+
|
||||||
|
</tbody>
|
||||||
|
</tgroup>
|
||||||
|
</table>
|
||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index 613a5133b6..fe82ca4ac2 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -501,6 +501,10 @@ foreach ident : [
|
||||||
|
#include <unistd.h>'''],
|
||||||
|
['explicit_bzero' , '''#include <string.h>'''],
|
||||||
|
['reallocarray', '''#include <malloc.h>'''],
|
||||||
|
+ ['set_mempolicy', '''#include <stdlib.h>
|
||||||
|
+ #include <unistd.h>'''],
|
||||||
|
+ ['get_mempolicy', '''#include <stdlib.h>
|
||||||
|
+ #include <unistd.h>'''],
|
||||||
|
]
|
||||||
|
|
||||||
|
have = cc.has_function(ident[0], prefix : ident[1], args : '-D_GNU_SOURCE')
|
||||||
|
diff --git a/src/basic/cpu-set-util.c b/src/basic/cpu-set-util.c
|
||||||
|
index 103b9703b3..36cb017ae7 100644
|
||||||
|
--- a/src/basic/cpu-set-util.c
|
||||||
|
+++ b/src/basic/cpu-set-util.c
|
||||||
|
@@ -10,11 +10,17 @@
|
||||||
|
|
||||||
|
#include "alloc-util.h"
|
||||||
|
#include "cpu-set-util.h"
|
||||||
|
+#include "dirent-util.h"
|
||||||
|
#include "extract-word.h"
|
||||||
|
+#include "fd-util.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "macro.h"
|
||||||
|
+#include "missing.h"
|
||||||
|
#include "parse-util.h"
|
||||||
|
+#include "stat-util.h"
|
||||||
|
#include "string-util.h"
|
||||||
|
+#include "string-table.h"
|
||||||
|
+#include "strv.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
char* cpu_set_to_string(const CPUSet *a) {
|
||||||
|
@@ -290,3 +296,88 @@ int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *set) {
|
||||||
|
s = (CPUSet) {};
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+bool numa_policy_is_valid(const NUMAPolicy *policy) {
|
||||||
|
+ assert(policy);
|
||||||
|
+
|
||||||
|
+ if (!mpol_is_valid(numa_policy_get_type(policy)))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ if (!policy->nodes.set &&
|
||||||
|
+ !IN_SET(numa_policy_get_type(policy), MPOL_DEFAULT, MPOL_LOCAL, MPOL_PREFERRED))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ if (policy->nodes.set &&
|
||||||
|
+ numa_policy_get_type(policy) == MPOL_PREFERRED &&
|
||||||
|
+ CPU_COUNT_S(policy->nodes.allocated, policy->nodes.set) != 1)
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int numa_policy_to_mempolicy(const NUMAPolicy *policy, unsigned long *ret_maxnode, unsigned long **ret_nodes) {
|
||||||
|
+ unsigned node, bits = 0, ulong_bits;
|
||||||
|
+ _cleanup_free_ unsigned long *out = NULL;
|
||||||
|
+
|
||||||
|
+ assert(policy);
|
||||||
|
+ assert(ret_maxnode);
|
||||||
|
+ assert(ret_nodes);
|
||||||
|
+
|
||||||
|
+ if (IN_SET(numa_policy_get_type(policy), MPOL_DEFAULT, MPOL_LOCAL) ||
|
||||||
|
+ (numa_policy_get_type(policy) == MPOL_PREFERRED && !policy->nodes.set)) {
|
||||||
|
+ *ret_nodes = NULL;
|
||||||
|
+ *ret_maxnode = 0;
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ bits = policy->nodes.allocated * 8;
|
||||||
|
+ ulong_bits = sizeof(unsigned long) * 8;
|
||||||
|
+
|
||||||
|
+ out = new0(unsigned long, DIV_ROUND_UP(policy->nodes.allocated, sizeof(unsigned long)));
|
||||||
|
+ if (!out)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ /* We don't make any assumptions about internal type libc is using to store NUMA node mask.
|
||||||
|
+ Hence we need to convert the node mask to the representation expected by set_mempolicy() */
|
||||||
|
+ for (node = 0; node < bits; node++)
|
||||||
|
+ if (CPU_ISSET_S(node, policy->nodes.allocated, policy->nodes.set))
|
||||||
|
+ out[node / ulong_bits] |= 1ul << (node % ulong_bits);
|
||||||
|
+
|
||||||
|
+ *ret_nodes = TAKE_PTR(out);
|
||||||
|
+ *ret_maxnode = bits + 1;
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int apply_numa_policy(const NUMAPolicy *policy) {
|
||||||
|
+ int r;
|
||||||
|
+ _cleanup_free_ unsigned long *nodes = NULL;
|
||||||
|
+ unsigned long maxnode;
|
||||||
|
+
|
||||||
|
+ assert(policy);
|
||||||
|
+
|
||||||
|
+ if (get_mempolicy(NULL, NULL, 0, 0, 0) < 0 && errno == ENOSYS)
|
||||||
|
+ return -EOPNOTSUPP;
|
||||||
|
+
|
||||||
|
+ if (!numa_policy_is_valid(policy))
|
||||||
|
+ return -EINVAL;
|
||||||
|
+
|
||||||
|
+ r = numa_policy_to_mempolicy(policy, &maxnode, &nodes);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ r = set_mempolicy(numa_policy_get_type(policy), nodes, maxnode);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return -errno;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static const char* const mpol_table[] = {
|
||||||
|
+ [MPOL_DEFAULT] = "default",
|
||||||
|
+ [MPOL_PREFERRED] = "preferred",
|
||||||
|
+ [MPOL_BIND] = "bind",
|
||||||
|
+ [MPOL_INTERLEAVE] = "interleave",
|
||||||
|
+ [MPOL_LOCAL] = "local",
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+DEFINE_STRING_TABLE_LOOKUP(mpol, int);
|
||||||
|
diff --git a/src/basic/cpu-set-util.h b/src/basic/cpu-set-util.h
|
||||||
|
index ec640b2ec9..295028cb54 100644
|
||||||
|
--- a/src/basic/cpu-set-util.h
|
||||||
|
+++ b/src/basic/cpu-set-util.h
|
||||||
|
@@ -8,6 +8,7 @@
|
||||||
|
#include <sched.h>
|
||||||
|
|
||||||
|
#include "macro.h"
|
||||||
|
+#include "missing.h"
|
||||||
|
|
||||||
|
/* This wraps the libc interface with a variable to keep the allocated size. */
|
||||||
|
typedef struct CPUSet {
|
||||||
|
@@ -52,3 +53,30 @@ int cpu_set_to_dbus(const CPUSet *set, uint8_t **ret, size_t *allocated);
|
||||||
|
int cpu_set_from_dbus(const uint8_t *bits, size_t size, CPUSet *set);
|
||||||
|
|
||||||
|
int cpus_in_affinity_mask(void);
|
||||||
|
+
|
||||||
|
+static inline bool mpol_is_valid(int t) {
|
||||||
|
+ return t >= MPOL_DEFAULT && t <= MPOL_LOCAL;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+typedef struct NUMAPolicy {
|
||||||
|
+ /* Always use numa_policy_get_type() to read the value */
|
||||||
|
+ int type;
|
||||||
|
+ CPUSet nodes;
|
||||||
|
+} NUMAPolicy;
|
||||||
|
+
|
||||||
|
+bool numa_policy_is_valid(const NUMAPolicy *p);
|
||||||
|
+
|
||||||
|
+static inline int numa_policy_get_type(const NUMAPolicy *p) {
|
||||||
|
+ return p->type < 0 ? (p->nodes.set ? MPOL_PREFERRED : -1) : p->type;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static inline void numa_policy_reset(NUMAPolicy *p) {
|
||||||
|
+ assert(p);
|
||||||
|
+ cpu_set_reset(&p->nodes);
|
||||||
|
+ p->type = -1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+int apply_numa_policy(const NUMAPolicy *policy);
|
||||||
|
+
|
||||||
|
+const char* mpol_to_string(int i) _const_;
|
||||||
|
+int mpol_from_string(const char *s) _pure_;
|
||||||
|
diff --git a/src/basic/exit-status.c b/src/basic/exit-status.c
|
||||||
|
index 21af8c4c71..0a7a53b73d 100644
|
||||||
|
--- a/src/basic/exit-status.c
|
||||||
|
+++ b/src/basic/exit-status.c
|
||||||
|
@@ -155,6 +155,9 @@ const char* exit_status_to_string(int status, ExitStatusLevel level) {
|
||||||
|
|
||||||
|
case EXIT_CONFIGURATION_DIRECTORY:
|
||||||
|
return "CONFIGURATION_DIRECTORY";
|
||||||
|
+
|
||||||
|
+ case EXIT_NUMA_POLICY:
|
||||||
|
+ return "NUMA_POLICY";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/src/basic/exit-status.h b/src/basic/exit-status.h
|
||||||
|
index c41e8b82c3..dc284aacb1 100644
|
||||||
|
--- a/src/basic/exit-status.h
|
||||||
|
+++ b/src/basic/exit-status.h
|
||||||
|
@@ -69,6 +69,7 @@ enum {
|
||||||
|
EXIT_CACHE_DIRECTORY,
|
||||||
|
EXIT_LOGS_DIRECTORY, /* 240 */
|
||||||
|
EXIT_CONFIGURATION_DIRECTORY,
|
||||||
|
+ EXIT_NUMA_POLICY,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum ExitStatusLevel {
|
||||||
|
diff --git a/src/basic/missing_syscall.h b/src/basic/missing_syscall.h
|
||||||
|
index 93c60458bf..014dd2b326 100644
|
||||||
|
--- a/src/basic/missing_syscall.h
|
||||||
|
+++ b/src/basic/missing_syscall.h
|
||||||
|
@@ -428,3 +428,46 @@ static inline ssize_t missing_statx(int dfd, const char *filename, unsigned flag
|
||||||
|
|
||||||
|
# define statx missing_statx
|
||||||
|
#endif
|
||||||
|
+
|
||||||
|
+#if !HAVE_SET_MEMPOLICY
|
||||||
|
+
|
||||||
|
+enum {
|
||||||
|
+ MPOL_DEFAULT,
|
||||||
|
+ MPOL_PREFERRED,
|
||||||
|
+ MPOL_BIND,
|
||||||
|
+ MPOL_INTERLEAVE,
|
||||||
|
+ MPOL_LOCAL,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static inline long missing_set_mempolicy(int mode, const unsigned long *nodemask,
|
||||||
|
+ unsigned long maxnode) {
|
||||||
|
+ long i;
|
||||||
|
+# ifdef __NR_set_mempolicy
|
||||||
|
+ i = syscall(__NR_set_mempolicy, mode, nodemask, maxnode);
|
||||||
|
+# else
|
||||||
|
+ errno = ENOSYS;
|
||||||
|
+ i = -1;
|
||||||
|
+# endif
|
||||||
|
+ return i;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+# define set_mempolicy missing_set_mempolicy
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+#if !HAVE_GET_MEMPOLICY
|
||||||
|
+static inline long missing_get_mempolicy(int *mode, unsigned long *nodemask,
|
||||||
|
+ unsigned long maxnode, void *addr,
|
||||||
|
+ unsigned long flags) {
|
||||||
|
+ long i;
|
||||||
|
+# ifdef __NR_get_mempolicy
|
||||||
|
+ i = syscall(__NR_get_mempolicy, mode, nodemask, maxnode, addr, flags);
|
||||||
|
+# else
|
||||||
|
+ errno = ENOSYS;
|
||||||
|
+ i = -1;
|
||||||
|
+# endif
|
||||||
|
+ return i;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define get_mempolicy missing_get_mempolicy
|
||||||
|
+#endif
|
||||||
|
diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c
|
||||||
|
index 50ea71a281..198f149210 100644
|
||||||
|
--- a/src/core/dbus-execute.c
|
||||||
|
+++ b/src/core/dbus-execute.c
|
||||||
|
@@ -223,6 +223,48 @@ static int property_get_cpu_affinity(
|
||||||
|
return sd_bus_message_append_array(reply, 'y', c->cpu_set.set, c->cpu_set.allocated);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int property_get_numa_mask(
|
||||||
|
+ sd_bus *bus,
|
||||||
|
+ const char *path,
|
||||||
|
+ const char *interface,
|
||||||
|
+ const char *property,
|
||||||
|
+ sd_bus_message *reply,
|
||||||
|
+ void *userdata,
|
||||||
|
+ sd_bus_error *error) {
|
||||||
|
+
|
||||||
|
+ ExecContext *c = userdata;
|
||||||
|
+ _cleanup_free_ uint8_t *array = NULL;
|
||||||
|
+ size_t allocated;
|
||||||
|
+
|
||||||
|
+ assert(bus);
|
||||||
|
+ assert(reply);
|
||||||
|
+ assert(c);
|
||||||
|
+
|
||||||
|
+ (void) cpu_set_to_dbus(&c->numa_policy.nodes, &array, &allocated);
|
||||||
|
+
|
||||||
|
+ return sd_bus_message_append_array(reply, 'y', array, allocated);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int property_get_numa_policy(
|
||||||
|
+ sd_bus *bus,
|
||||||
|
+ const char *path,
|
||||||
|
+ const char *interface,
|
||||||
|
+ const char *property,
|
||||||
|
+ sd_bus_message *reply,
|
||||||
|
+ void *userdata,
|
||||||
|
+ sd_bus_error *error) {
|
||||||
|
+ ExecContext *c = userdata;
|
||||||
|
+ int32_t policy;
|
||||||
|
+
|
||||||
|
+ assert(bus);
|
||||||
|
+ assert(reply);
|
||||||
|
+ assert(c);
|
||||||
|
+
|
||||||
|
+ policy = numa_policy_get_type(&c->numa_policy);
|
||||||
|
+
|
||||||
|
+ return sd_bus_message_append_basic(reply, 'i', &policy);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int property_get_timer_slack_nsec(
|
||||||
|
sd_bus *bus,
|
||||||
|
const char *path,
|
||||||
|
@@ -698,6 +740,8 @@ const sd_bus_vtable bus_exec_vtable[] = {
|
||||||
|
SD_BUS_PROPERTY("CPUSchedulingPolicy", "i", property_get_cpu_sched_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
SD_BUS_PROPERTY("CPUSchedulingPriority", "i", property_get_cpu_sched_priority, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
SD_BUS_PROPERTY("CPUAffinity", "ay", property_get_cpu_affinity, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
+ SD_BUS_PROPERTY("NUMAPolicy", "i", property_get_numa_policy, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
+ SD_BUS_PROPERTY("NUMAMask", "ay", property_get_numa_mask, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
SD_BUS_PROPERTY("TimerSlackNSec", "t", property_get_timer_slack_nsec, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
SD_BUS_PROPERTY("CPUSchedulingResetOnFork", "b", bus_property_get_bool, offsetof(ExecContext, cpu_sched_reset_on_fork), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
SD_BUS_PROPERTY("NonBlocking", "b", bus_property_get_bool, offsetof(ExecContext, non_blocking), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
@@ -1550,9 +1594,10 @@ int bus_exec_context_set_transient_property(
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
- if (streq(name, "CPUAffinity")) {
|
||||||
|
+ if (STR_IN_SET(name, "CPUAffinity", "NUMAMask")) {
|
||||||
|
const void *a;
|
||||||
|
size_t n;
|
||||||
|
+ bool affinity = streq(name, "CPUAffinity");
|
||||||
|
_cleanup_(cpu_set_reset) CPUSet set = {};
|
||||||
|
|
||||||
|
r = sd_bus_message_read_array(message, 'y', &a, &n);
|
||||||
|
@@ -1565,7 +1610,7 @@ int bus_exec_context_set_transient_property(
|
||||||
|
|
||||||
|
if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
|
||||||
|
if (n == 0) {
|
||||||
|
- cpu_set_reset(&c->cpu_set);
|
||||||
|
+ cpu_set_reset(affinity ? &c->cpu_set : &c->numa_policy.nodes);
|
||||||
|
unit_write_settingf(u, flags, name, "%s=", name);
|
||||||
|
} else {
|
||||||
|
_cleanup_free_ char *str = NULL;
|
||||||
|
@@ -1577,7 +1622,7 @@ int bus_exec_context_set_transient_property(
|
||||||
|
/* We forego any optimizations here, and always create the structure using
|
||||||
|
* cpu_set_add_all(), because we don't want to care if the existing size we
|
||||||
|
* got over dbus is appropriate. */
|
||||||
|
- r = cpu_set_add_all(&c->cpu_set, &set);
|
||||||
|
+ r = cpu_set_add_all(affinity ? &c->cpu_set : &c->numa_policy.nodes, &set);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
@@ -1587,6 +1632,20 @@ int bus_exec_context_set_transient_property(
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
+ } else if (streq(name, "NUMAPolicy")) {
|
||||||
|
+ int32_t type;
|
||||||
|
+
|
||||||
|
+ r = sd_bus_message_read(message, "i", &type);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ if (!mpol_is_valid(type))
|
||||||
|
+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid NUMAPolicy value: %i", type);
|
||||||
|
+
|
||||||
|
+ if (!UNIT_WRITE_FLAGS_NOOP(flags))
|
||||||
|
+ c->numa_policy.type = type;
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
} else if (streq(name, "IOSchedulingClass")) {
|
||||||
|
int32_t q;
|
||||||
|
|
||||||
|
diff --git a/src/core/execute.c b/src/core/execute.c
|
||||||
|
index bc26aa66e7..56aa89e1ec 100644
|
||||||
|
--- a/src/core/execute.c
|
||||||
|
+++ b/src/core/execute.c
|
||||||
|
@@ -2997,6 +2997,16 @@ static int exec_child(
|
||||||
|
return log_unit_error_errno(unit, errno, "Failed to set up CPU affinity: %m");
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (mpol_is_valid(numa_policy_get_type(&context->numa_policy))) {
|
||||||
|
+ r = apply_numa_policy(&context->numa_policy);
|
||||||
|
+ if (r == -EOPNOTSUPP)
|
||||||
|
+ log_unit_debug_errno(unit, r, "NUMA support not available, ignoring.");
|
||||||
|
+ else if (r < 0) {
|
||||||
|
+ *exit_status = EXIT_NUMA_POLICY;
|
||||||
|
+ return log_unit_error_errno(unit, r, "Failed to set NUMA memory policy: %m");
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (context->ioprio_set)
|
||||||
|
if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) {
|
||||||
|
*exit_status = EXIT_IOPRIO;
|
||||||
|
@@ -3651,6 +3661,7 @@ void exec_context_init(ExecContext *c) {
|
||||||
|
assert_cc(NAMESPACE_FLAGS_INITIAL != NAMESPACE_FLAGS_ALL);
|
||||||
|
c->restrict_namespaces = NAMESPACE_FLAGS_INITIAL;
|
||||||
|
c->log_level_max = -1;
|
||||||
|
+ numa_policy_reset(&c->numa_policy);
|
||||||
|
}
|
||||||
|
|
||||||
|
void exec_context_done(ExecContext *c) {
|
||||||
|
@@ -3695,6 +3706,7 @@ void exec_context_done(ExecContext *c) {
|
||||||
|
c->n_temporary_filesystems = 0;
|
||||||
|
|
||||||
|
cpu_set_reset(&c->cpu_set);
|
||||||
|
+ numa_policy_reset(&c->numa_policy);
|
||||||
|
|
||||||
|
c->utmp_id = mfree(c->utmp_id);
|
||||||
|
c->selinux_context = mfree(c->selinux_context);
|
||||||
|
@@ -4104,6 +4116,14 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
|
||||||
|
fprintf(f, "%sCPUAffinity: %s\n", prefix, affinity);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (mpol_is_valid(numa_policy_get_type(&c->numa_policy))) {
|
||||||
|
+ _cleanup_free_ char *nodes = NULL;
|
||||||
|
+
|
||||||
|
+ nodes = cpu_set_to_range_string(&c->numa_policy.nodes);
|
||||||
|
+ fprintf(f, "%sNUMAPolicy: %s\n", prefix, mpol_to_string(numa_policy_get_type(&c->numa_policy)));
|
||||||
|
+ fprintf(f, "%sNUMAMask: %s\n", prefix, strnull(nodes));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (c->timer_slack_nsec != NSEC_INFINITY)
|
||||||
|
fprintf(f, "%sTimerSlackNSec: "NSEC_FMT "\n", prefix, c->timer_slack_nsec);
|
||||||
|
|
||||||
|
diff --git a/src/core/execute.h b/src/core/execute.h
|
||||||
|
index e1e7a494cd..b2eb55f8f5 100644
|
||||||
|
--- a/src/core/execute.h
|
||||||
|
+++ b/src/core/execute.h
|
||||||
|
@@ -150,6 +150,7 @@ struct ExecContext {
|
||||||
|
int cpu_sched_priority;
|
||||||
|
|
||||||
|
CPUSet cpu_set;
|
||||||
|
+ NUMAPolicy numa_policy;
|
||||||
|
|
||||||
|
ExecInput std_input;
|
||||||
|
ExecOutput std_output;
|
||||||
|
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
|
||||||
|
index 1066bcfb8f..cdf4d14c4e 100644
|
||||||
|
--- a/src/core/load-fragment-gperf.gperf.m4
|
||||||
|
+++ b/src/core/load-fragment-gperf.gperf.m4
|
||||||
|
@@ -36,6 +36,8 @@ $1.CPUSchedulingPolicy, config_parse_exec_cpu_sched_policy, 0,
|
||||||
|
$1.CPUSchedulingPriority, config_parse_exec_cpu_sched_prio, 0, offsetof($1, exec_context)
|
||||||
|
$1.CPUSchedulingResetOnFork, config_parse_bool, 0, offsetof($1, exec_context.cpu_sched_reset_on_fork)
|
||||||
|
$1.CPUAffinity, config_parse_exec_cpu_affinity, 0, offsetof($1, exec_context)
|
||||||
|
+$1.NUMAPolicy, config_parse_numa_policy, 0, offsetof($1, exec_context.numa_policy.type)
|
||||||
|
+$1.NUMAMask, config_parse_numa_mask, 0, offsetof($1, exec_context.numa_policy)
|
||||||
|
$1.UMask, config_parse_mode, 0, offsetof($1, exec_context.umask)
|
||||||
|
$1.Environment, config_parse_environ, 0, offsetof($1, exec_context.environment)
|
||||||
|
$1.EnvironmentFile, config_parse_unit_env_file, 0, offsetof($1, exec_context.environment_files)
|
||||||
|
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
|
||||||
|
index 34ae834188..35dd595098 100644
|
||||||
|
--- a/src/core/load-fragment.c
|
||||||
|
+++ b/src/core/load-fragment.c
|
||||||
|
@@ -93,6 +93,7 @@ DEFINE_CONFIG_PARSE_PTR(config_parse_blockio_weight, cg_blkio_weight_parse, uint
|
||||||
|
DEFINE_CONFIG_PARSE_PTR(config_parse_cg_weight, cg_weight_parse, uint64_t, "Invalid weight");
|
||||||
|
DEFINE_CONFIG_PARSE_PTR(config_parse_cpu_shares, cg_cpu_shares_parse, uint64_t, "Invalid CPU shares");
|
||||||
|
DEFINE_CONFIG_PARSE_PTR(config_parse_exec_mount_flags, mount_propagation_flags_from_string, unsigned long, "Failed to parse mount flag");
|
||||||
|
+DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(config_parse_numa_policy, mpol, int, -1, "Invalid NUMA policy type");
|
||||||
|
|
||||||
|
int config_parse_unit_deps(
|
||||||
|
const char *unit,
|
||||||
|
@@ -1159,6 +1160,33 @@ int config_parse_exec_cpu_sched_policy(const char *unit,
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int config_parse_numa_mask(const char *unit,
|
||||||
|
+ const char *filename,
|
||||||
|
+ unsigned line,
|
||||||
|
+ const char *section,
|
||||||
|
+ unsigned section_line,
|
||||||
|
+ const char *lvalue,
|
||||||
|
+ int ltype,
|
||||||
|
+ const char *rvalue,
|
||||||
|
+ void *data,
|
||||||
|
+ void *userdata) {
|
||||||
|
+ int r;
|
||||||
|
+ NUMAPolicy *p = data;
|
||||||
|
+
|
||||||
|
+ assert(filename);
|
||||||
|
+ assert(lvalue);
|
||||||
|
+ assert(rvalue);
|
||||||
|
+ assert(data);
|
||||||
|
+
|
||||||
|
+ r = parse_cpu_set_extend(rvalue, &p->nodes, true, unit, filename, line, lvalue);
|
||||||
|
+ if (r < 0) {
|
||||||
|
+ log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse NUMA node mask, ignoring: %s", rvalue);
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return r;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int config_parse_exec_cpu_sched_prio(const char *unit,
|
||||||
|
const char *filename,
|
||||||
|
unsigned line,
|
||||||
|
diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
|
||||||
|
index dad281ef72..f2ca1b8ee7 100644
|
||||||
|
--- a/src/core/load-fragment.h
|
||||||
|
+++ b/src/core/load-fragment.h
|
||||||
|
@@ -102,6 +102,8 @@ CONFIG_PARSER_PROTOTYPE(config_parse_job_timeout_sec);
|
||||||
|
CONFIG_PARSER_PROTOTYPE(config_parse_job_running_timeout_sec);
|
||||||
|
CONFIG_PARSER_PROTOTYPE(config_parse_log_extra_fields);
|
||||||
|
CONFIG_PARSER_PROTOTYPE(config_parse_collect_mode);
|
||||||
|
+CONFIG_PARSER_PROTOTYPE(config_parse_numa_policy);
|
||||||
|
+CONFIG_PARSER_PROTOTYPE(config_parse_numa_mask);
|
||||||
|
|
||||||
|
/* gperf prototypes */
|
||||||
|
const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
|
||||||
|
diff --git a/src/core/main.c b/src/core/main.c
|
||||||
|
index c74dc641c1..83f9dd5878 100644
|
||||||
|
--- a/src/core/main.c
|
||||||
|
+++ b/src/core/main.c
|
||||||
|
@@ -134,6 +134,7 @@ static uint64_t arg_default_tasks_max;
|
||||||
|
static sd_id128_t arg_machine_id;
|
||||||
|
static EmergencyAction arg_cad_burst_action;
|
||||||
|
static CPUSet arg_cpu_affinity;
|
||||||
|
+static NUMAPolicy arg_numa_policy;
|
||||||
|
|
||||||
|
static int parse_configuration(void);
|
||||||
|
|
||||||
|
@@ -660,6 +661,8 @@ static int parse_config_file(void) {
|
||||||
|
{ "Manager", "ShowStatus", config_parse_show_status, 0, &arg_show_status },
|
||||||
|
{ "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, &arg_cpu_affinity },
|
||||||
|
{ "Manager", "JoinControllers", config_parse_join_controllers, 0, &arg_join_controllers },
|
||||||
|
+ { "Manager", "NUMAPolicy", config_parse_numa_policy, 0, &arg_numa_policy.type },
|
||||||
|
+ { "Manager", "NUMAMask", config_parse_numa_mask, 0, &arg_numa_policy },
|
||||||
|
{ "Manager", "RuntimeWatchdogSec", config_parse_sec, 0, &arg_runtime_watchdog },
|
||||||
|
{ "Manager", "ShutdownWatchdogSec", config_parse_sec, 0, &arg_shutdown_watchdog },
|
||||||
|
{ "Manager", "WatchdogDevice", config_parse_path, 0, &arg_watchdog_device },
|
||||||
|
@@ -1501,6 +1504,27 @@ static void update_cpu_affinity(bool skip_setup) {
|
||||||
|
log_warning_errno(errno, "Failed to set CPU affinity: %m");
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void update_numa_policy(bool skip_setup) {
|
||||||
|
+ int r;
|
||||||
|
+ _cleanup_free_ char *nodes = NULL;
|
||||||
|
+ const char * policy = NULL;
|
||||||
|
+
|
||||||
|
+ if (skip_setup || !mpol_is_valid(numa_policy_get_type(&arg_numa_policy)))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ if (DEBUG_LOGGING) {
|
||||||
|
+ policy = mpol_to_string(numa_policy_get_type(&arg_numa_policy));
|
||||||
|
+ nodes = cpu_set_to_range_string(&arg_numa_policy.nodes);
|
||||||
|
+ log_debug("Setting NUMA policy to %s, with nodes %s.", strnull(policy), strnull(nodes));
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ r = apply_numa_policy(&arg_numa_policy);
|
||||||
|
+ if (r == -EOPNOTSUPP)
|
||||||
|
+ log_debug_errno(r, "NUMA support not available, ignoring.");
|
||||||
|
+ else if (r < 0)
|
||||||
|
+ log_warning_errno(r, "Failed to set NUMA memory policy: %m");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void do_reexecute(
|
||||||
|
int argc,
|
||||||
|
char *argv[],
|
||||||
|
@@ -1672,6 +1696,7 @@ static int invoke_main_loop(
|
||||||
|
set_manager_defaults(m);
|
||||||
|
|
||||||
|
update_cpu_affinity(false);
|
||||||
|
+ update_numa_policy(false);
|
||||||
|
|
||||||
|
if (saved_log_level >= 0)
|
||||||
|
manager_override_log_level(m, saved_log_level);
|
||||||
|
@@ -1832,6 +1857,7 @@ static int initialize_runtime(
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
update_cpu_affinity(skip_setup);
|
||||||
|
+ update_numa_policy(skip_setup);
|
||||||
|
|
||||||
|
if (arg_system) {
|
||||||
|
/* Make sure we leave a core dump without panicing the kernel. */
|
||||||
|
@@ -2011,6 +2037,7 @@ static void reset_arguments(void) {
|
||||||
|
arg_cad_burst_action = EMERGENCY_ACTION_REBOOT_FORCE;
|
||||||
|
|
||||||
|
cpu_set_reset(&arg_cpu_affinity);
|
||||||
|
+ numa_policy_reset(&arg_numa_policy);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_configuration(void) {
|
||||||
|
diff --git a/src/core/system.conf.in b/src/core/system.conf.in
|
||||||
|
index 653ec6b8c9..0d93fbf147 100644
|
||||||
|
--- a/src/core/system.conf.in
|
||||||
|
+++ b/src/core/system.conf.in
|
||||||
|
@@ -24,6 +24,8 @@
|
||||||
|
#CtrlAltDelBurstAction=reboot-force
|
||||||
|
#CPUAffinity=1 2
|
||||||
|
#JoinControllers=cpu,cpuacct net_cls,net_prio
|
||||||
|
+#NUMAPolicy=default
|
||||||
|
+#NUMAMask=
|
||||||
|
#RuntimeWatchdogSec=0
|
||||||
|
#ShutdownWatchdogSec=10min
|
||||||
|
#CapabilityBoundingSet=
|
||||||
|
diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c
|
||||||
|
index ec8732c226..055edd6e22 100644
|
||||||
|
--- a/src/shared/bus-unit-util.c
|
||||||
|
+++ b/src/shared/bus-unit-util.c
|
||||||
|
@@ -947,6 +947,34 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con
|
||||||
|
return bus_append_byte_array(m, field, array, allocated);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if (streq(field, "NUMAPolicy")) {
|
||||||
|
+ r = mpol_from_string(eq);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_error_errno(r, "Failed to parse %s value: %s", field, eq);
|
||||||
|
+
|
||||||
|
+ r = sd_bus_message_append(m, "(sv)", field, "i", (int32_t) r);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return bus_log_create_error(r);
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (streq(field, "NUMAMask")) {
|
||||||
|
+ _cleanup_(cpu_set_reset) CPUSet nodes = {};
|
||||||
|
+ _cleanup_free_ uint8_t *array = NULL;
|
||||||
|
+ size_t allocated;
|
||||||
|
+
|
||||||
|
+ r = parse_cpu_set(eq, &nodes);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_error_errno(r, "Failed to parse %s value: %s", field, eq);
|
||||||
|
+
|
||||||
|
+ r = cpu_set_to_dbus(&nodes, &array, &allocated);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return log_error_errno(r, "Failed to serialize NUMAMask: %m");
|
||||||
|
+
|
||||||
|
+ return bus_append_byte_array(m, field, array, allocated);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (STR_IN_SET(field, "RestrictAddressFamilies", "SystemCallFilter")) {
|
||||||
|
int whitelist = 1;
|
||||||
|
const char *p = eq;
|
||||||
|
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
|
||||||
|
index 0154b300a3..7274921e6d 100644
|
||||||
|
--- a/src/systemctl/systemctl.c
|
||||||
|
+++ b/src/systemctl/systemctl.c
|
||||||
|
@@ -4573,6 +4573,20 @@ static int print_property(const char *name, sd_bus_message *m, bool value, bool
|
||||||
|
|
||||||
|
switch (bus_type) {
|
||||||
|
|
||||||
|
+ case SD_BUS_TYPE_INT32:
|
||||||
|
+ if (streq(name, "NUMAPolicy")) {
|
||||||
|
+ int32_t i;
|
||||||
|
+
|
||||||
|
+ r = sd_bus_message_read_basic(m, bus_type, &i);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ return r;
|
||||||
|
+
|
||||||
|
+ print_prop(name, "%s", strna(mpol_to_string(i)));
|
||||||
|
+
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
case SD_BUS_TYPE_STRUCT:
|
||||||
|
|
||||||
|
if (contents[0] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
|
||||||
|
@@ -4878,7 +4892,7 @@ static int print_property(const char *name, sd_bus_message *m, bool value, bool
|
||||||
|
print_prop(name, "%s", h);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
- } else if (contents[0] == SD_BUS_TYPE_BYTE && streq(name, "CPUAffinity")) {
|
||||||
|
+ } else if (contents[0] == SD_BUS_TYPE_BYTE && STR_IN_SET(name, "CPUAffinity", "NUMAMask")) {
|
||||||
|
_cleanup_free_ char *affinity = NULL;
|
||||||
|
_cleanup_(cpu_set_reset) CPUSet set = {};
|
||||||
|
const void *a;
|
||||||
|
@@ -4890,7 +4904,7 @@ static int print_property(const char *name, sd_bus_message *m, bool value, bool
|
||||||
|
|
||||||
|
r = cpu_set_from_dbus(a, n, &set);
|
||||||
|
if (r < 0)
|
||||||
|
- return log_error_errno(r, "Failed to deserialize CPUAffinity: %m");
|
||||||
|
+ return log_error_errno(r, "Failed to deserialize %s: %m", name);
|
||||||
|
|
||||||
|
affinity = cpu_set_to_range_string(&set);
|
||||||
|
if (!affinity)
|
25
SOURCES/0289-core-disable-CPUAccounting-by-default.patch
Normal file
25
SOURCES/0289-core-disable-CPUAccounting-by-default.patch
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
From b47f26558e5234ec8cf2ecc3674c94a87f20ec69 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= <msekleta@redhat.com>
|
||||||
|
Date: Thu, 28 Nov 2019 15:47:43 +0100
|
||||||
|
Subject: [PATCH] core: disable CPUAccounting by default
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
|
||||||
|
[RHEL-only]
|
||||||
|
---
|
||||||
|
src/core/main.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/main.c b/src/core/main.c
|
||||||
|
index 83f9dd5878..c83249a8dc 100644
|
||||||
|
--- a/src/core/main.c
|
||||||
|
+++ b/src/core/main.c
|
||||||
|
@@ -2026,7 +2026,7 @@ static void reset_arguments(void) {
|
||||||
|
|
||||||
|
/* arg_serialization — ignore */
|
||||||
|
|
||||||
|
- arg_default_cpu_accounting = -1;
|
||||||
|
+ arg_default_cpu_accounting = 0;
|
||||||
|
arg_default_io_accounting = false;
|
||||||
|
arg_default_ip_accounting = false;
|
||||||
|
arg_default_blockio_accounting = false;
|
24
SOURCES/0290-set-kptr_restrict-1.patch
Normal file
24
SOURCES/0290-set-kptr_restrict-1.patch
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
From cf1a9df1171273fc1ed3f977b5ec52aba27674bf Mon Sep 17 00:00:00 2001
|
||||||
|
From: David Tardon <dtardon@redhat.com>
|
||||||
|
Date: Tue, 3 Dec 2019 14:04:00 +0100
|
||||||
|
Subject: [PATCH] set kptr_restrict=1
|
||||||
|
|
||||||
|
Resolves: #1689346
|
||||||
|
---
|
||||||
|
sysctl.d/50-default.conf | 3 +++
|
||||||
|
1 file changed, 3 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/sysctl.d/50-default.conf b/sysctl.d/50-default.conf
|
||||||
|
index e263cf0628..e0afc9c702 100644
|
||||||
|
--- a/sysctl.d/50-default.conf
|
||||||
|
+++ b/sysctl.d/50-default.conf
|
||||||
|
@@ -21,6 +21,9 @@ kernel.sysrq = 16
|
||||||
|
# Append the PID to the core filename
|
||||||
|
kernel.core_uses_pid = 1
|
||||||
|
|
||||||
|
+# https://bugzilla.redhat.com/show_bug.cgi?id=1689346
|
||||||
|
+kernel.kptr_restrict = 1
|
||||||
|
+
|
||||||
|
# Source route verification
|
||||||
|
net.ipv4.conf.all.rp_filter = 1
|
||||||
|
|
@ -0,0 +1,34 @@
|
|||||||
|
From 40612e4e7690c613cba7ac87b9d782724e623a39 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Michal=20Sekleta=CC=81r?= <msekleta@redhat.com>
|
||||||
|
Date: Wed, 27 Nov 2019 14:27:58 +0100
|
||||||
|
Subject: [PATCH] cryptsetup: reduce the chance that we will be OOM killed
|
||||||
|
|
||||||
|
cryptsetup introduced optional locking scheme that should serialize
|
||||||
|
unlocking keyslots which use memory hard key derivation
|
||||||
|
function (argon2). Using the serialization should prevent OOM situation
|
||||||
|
in early boot while unlocking encrypted volumes.
|
||||||
|
|
||||||
|
(cherry picked from commit 408c81f62454684dfbff1c95ce3210d06f256e58)
|
||||||
|
|
||||||
|
Resolves: #1696602
|
||||||
|
---
|
||||||
|
src/cryptsetup/cryptsetup.c | 6 ++++++
|
||||||
|
1 file changed, 6 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
|
||||||
|
index 4e1b3eff19..9071126c2e 100644
|
||||||
|
--- a/src/cryptsetup/cryptsetup.c
|
||||||
|
+++ b/src/cryptsetup/cryptsetup.c
|
||||||
|
@@ -656,6 +656,12 @@ int main(int argc, char *argv[]) {
|
||||||
|
if (arg_discards)
|
||||||
|
flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
|
||||||
|
|
||||||
|
+#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/ */
|
||||||
|
+ flags |= CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
if (arg_timeout == USEC_INFINITY)
|
||||||
|
until = 0;
|
||||||
|
else
|
@ -0,0 +1,136 @@
|
|||||||
|
From cb084637ba1c8558f1538ce300c5520a6764dc76 Mon Sep 17 00:00:00 2001
|
||||||
|
From: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
|
||||||
|
Date: Mon, 28 Oct 2019 19:35:24 +0900
|
||||||
|
Subject: [PATCH] core, job: fix breakage of ordering dependencies by systemctl
|
||||||
|
reload command
|
||||||
|
|
||||||
|
Currently, systemctl reload command breaks ordering dependencies if it's
|
||||||
|
executed when its target service unit is in activating state.
|
||||||
|
|
||||||
|
For example, prepare A.service, B.service and C.target as follows:
|
||||||
|
|
||||||
|
# systemctl cat A.service B.service C.target
|
||||||
|
# /etc/systemd/system/A.service
|
||||||
|
[Unit]
|
||||||
|
Description=A
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/bin/echo A1
|
||||||
|
ExecStart=/usr/bin/sleep 60
|
||||||
|
ExecStart=/usr/bin/echo A2
|
||||||
|
ExecReload=/usr/bin/echo A reloaded
|
||||||
|
RemainAfterExit=yes
|
||||||
|
|
||||||
|
# /etc/systemd/system/B.service
|
||||||
|
[Unit]
|
||||||
|
Description=B
|
||||||
|
After=A.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/bin/echo B
|
||||||
|
RemainAfterExit=yes
|
||||||
|
|
||||||
|
# /etc/systemd/system/C.target
|
||||||
|
[Unit]
|
||||||
|
Description=C
|
||||||
|
Wants=A.service B.service
|
||||||
|
|
||||||
|
Start them.
|
||||||
|
|
||||||
|
# systemctl daemon-reload
|
||||||
|
# systemctl start C.target
|
||||||
|
|
||||||
|
Then, we have:
|
||||||
|
|
||||||
|
# LANG=C journalctl --no-pager -u A.service -u B.service -u C.target -b
|
||||||
|
-- Logs begin at Mon 2019-09-09 00:25:06 EDT, end at Thu 2019-10-24 22:28:47 EDT. --
|
||||||
|
Oct 24 22:27:47 localhost.localdomain systemd[1]: Starting A...
|
||||||
|
Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Child 967 belongs to A.service.
|
||||||
|
Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Main process exited, code=exited, status=0/SUCCESS
|
||||||
|
Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Running next main command for state start.
|
||||||
|
Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Passing 0 fds to service
|
||||||
|
Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: About to execute: /usr/bin/sleep 60
|
||||||
|
Oct 24 22:27:47 localhost.localdomain systemd[1]: A.service: Forked /usr/bin/sleep as 968
|
||||||
|
Oct 24 22:27:47 localhost.localdomain systemd[968]: A.service: Executing: /usr/bin/sleep 60
|
||||||
|
Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Trying to enqueue job A.service/reload/replace
|
||||||
|
Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Merged into running job, re-running: A.service/reload as 1288
|
||||||
|
Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Enqueued job A.service/reload as 1288
|
||||||
|
Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Unit cannot be reloaded because it is inactive.
|
||||||
|
Oct 24 22:27:52 localhost.localdomain systemd[1]: A.service: Job 1288 A.service/reload finished, result=invalid
|
||||||
|
Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Passing 0 fds to service
|
||||||
|
Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: About to execute: /usr/bin/echo B
|
||||||
|
Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Forked /usr/bin/echo as 970
|
||||||
|
Oct 24 22:27:52 localhost.localdomain systemd[970]: B.service: Executing: /usr/bin/echo B
|
||||||
|
Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Failed to send unit change signal for B.service: Connection reset by peer
|
||||||
|
Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Changed dead -> start
|
||||||
|
Oct 24 22:27:52 localhost.localdomain systemd[1]: Starting B...
|
||||||
|
Oct 24 22:27:52 localhost.localdomain echo[970]: B
|
||||||
|
Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Child 970 belongs to B.service.
|
||||||
|
Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Main process exited, code=exited, status=0/SUCCESS
|
||||||
|
Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Changed start -> exited
|
||||||
|
Oct 24 22:27:52 localhost.localdomain systemd[1]: B.service: Job 1371 B.service/start finished, result=done
|
||||||
|
Oct 24 22:27:52 localhost.localdomain systemd[1]: Started B.
|
||||||
|
Oct 24 22:27:52 localhost.localdomain systemd[1]: C.target: Job 1287 C.target/start finished, result=done
|
||||||
|
Oct 24 22:27:52 localhost.localdomain systemd[1]: Reached target C.
|
||||||
|
Oct 24 22:27:52 localhost.localdomain systemd[1]: C.target: Failed to send unit change signal for C.target: Connection reset by peer
|
||||||
|
Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Child 968 belongs to A.service.
|
||||||
|
Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Main process exited, code=exited, status=0/SUCCESS
|
||||||
|
Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Running next main command for state start.
|
||||||
|
Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Passing 0 fds to service
|
||||||
|
Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: About to execute: /usr/bin/echo A2
|
||||||
|
Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Forked /usr/bin/echo as 972
|
||||||
|
Oct 24 22:28:47 localhost.localdomain systemd[972]: A.service: Executing: /usr/bin/echo A2
|
||||||
|
Oct 24 22:28:47 localhost.localdomain echo[972]: A2
|
||||||
|
Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Child 972 belongs to A.service.
|
||||||
|
Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Main process exited, code=exited, status=0/SUCCESS
|
||||||
|
Oct 24 22:28:47 localhost.localdomain systemd[1]: A.service: Changed start -> exited
|
||||||
|
|
||||||
|
The issue occurs not only in reload command, i.e.:
|
||||||
|
|
||||||
|
- reload
|
||||||
|
- try-restart
|
||||||
|
- reload-or-restart
|
||||||
|
- reload-or-try-restart commands
|
||||||
|
|
||||||
|
The cause of this issue is that job_type_collapse() doesn't take care of the
|
||||||
|
activating state.
|
||||||
|
|
||||||
|
Fixes: #10464
|
||||||
|
(cherry picked from commit d1559793df555212271e490a4a72f55826caf5b4)
|
||||||
|
|
||||||
|
Resolves: #1766417
|
||||||
|
---
|
||||||
|
src/core/job.c | 6 +++---
|
||||||
|
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/core/job.c b/src/core/job.c
|
||||||
|
index 8552ffb704..769ed6d603 100644
|
||||||
|
--- a/src/core/job.c
|
||||||
|
+++ b/src/core/job.c
|
||||||
|
@@ -403,21 +403,21 @@ JobType job_type_collapse(JobType t, Unit *u) {
|
||||||
|
|
||||||
|
case JOB_TRY_RESTART:
|
||||||
|
s = unit_active_state(u);
|
||||||
|
- if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
|
||||||
|
+ if (!UNIT_IS_ACTIVE_OR_RELOADING(s))
|
||||||
|
return JOB_NOP;
|
||||||
|
|
||||||
|
return JOB_RESTART;
|
||||||
|
|
||||||
|
case JOB_TRY_RELOAD:
|
||||||
|
s = unit_active_state(u);
|
||||||
|
- if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
|
||||||
|
+ if (!UNIT_IS_ACTIVE_OR_RELOADING(s))
|
||||||
|
return JOB_NOP;
|
||||||
|
|
||||||
|
return JOB_RELOAD;
|
||||||
|
|
||||||
|
case JOB_RELOAD_OR_START:
|
||||||
|
s = unit_active_state(u);
|
||||||
|
- if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
|
||||||
|
+ if (!UNIT_IS_ACTIVE_OR_RELOADING(s))
|
||||||
|
return JOB_START;
|
||||||
|
|
||||||
|
return JOB_RELOAD;
|
@ -0,0 +1,149 @@
|
|||||||
|
From 613a02b7d67864af1860e9137e2ee101d603463e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jan Synacek <jsynacek@redhat.com>
|
||||||
|
Date: Thu, 25 Apr 2019 12:19:16 +0200
|
||||||
|
Subject: [PATCH] debug-generator: enable custom systemd.debug_shell tty
|
||||||
|
|
||||||
|
(cherry picked from commit 93912e872fb14e9c372e090409e429084a6450f5)
|
||||||
|
|
||||||
|
Resolves: #1723722
|
||||||
|
---
|
||||||
|
man/custom-entities.ent.in | 1 +
|
||||||
|
man/systemd-debug-generator.xml | 13 ++++++---
|
||||||
|
meson.build | 1 +
|
||||||
|
src/debug-generator/debug-generator.c | 41 +++++++++++++++++++++------
|
||||||
|
4 files changed, 43 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/man/custom-entities.ent.in b/man/custom-entities.ent.in
|
||||||
|
index e2bd44e5e7..85805777a0 100644
|
||||||
|
--- a/man/custom-entities.ent.in
|
||||||
|
+++ b/man/custom-entities.ent.in
|
||||||
|
@@ -8,3 +8,4 @@
|
||||||
|
<!ENTITY CERTIFICATE_ROOT @CERTIFICATE_ROOT@>
|
||||||
|
<!ENTITY MEMORY_ACCOUNTING_DEFAULT @MEMORY_ACCOUNTING_DEFAULT_YES_NO@>
|
||||||
|
<!ENTITY KILL_USER_PROCESSES @KILL_USER_PROCESSES_YES_NO@>
|
||||||
|
+<!ENTITY DEBUGTTY @DEBUGTTY@>
|
||||||
|
diff --git a/man/systemd-debug-generator.xml b/man/systemd-debug-generator.xml
|
||||||
|
index fa88e8ac01..25d8b1a873 100644
|
||||||
|
--- a/man/systemd-debug-generator.xml
|
||||||
|
+++ b/man/systemd-debug-generator.xml
|
||||||
|
@@ -1,6 +1,10 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--*-nxml-*-->
|
||||||
|
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||||||
|
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||||
|
+ "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
|
||||||
|
+<!ENTITY % entities SYSTEM "custom-entities.ent" >
|
||||||
|
+%entities;
|
||||||
|
+]>
|
||||||
|
<!--
|
||||||
|
SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
-->
|
||||||
|
@@ -57,9 +61,10 @@
|
||||||
|
<option>rd.systemd.debug_shell</option> option is
|
||||||
|
specified, the debug shell service
|
||||||
|
<literal>debug-shell.service</literal> is pulled into the boot
|
||||||
|
- transaction. It will spawn a debug shell on tty9 during early
|
||||||
|
- system startup. Note that the shell may also be turned on
|
||||||
|
- persistently by enabling it with
|
||||||
|
+ transaction and a debug shell will be spawned during early boot.
|
||||||
|
+ By default, <filename>&DEBUGTTY;</filename> is used, but a specific tty can also be set,
|
||||||
|
+ either with or without the <filename>/dev/</filename> prefix.
|
||||||
|
+ Note that the shell may also be turned on persistently by enabling it with
|
||||||
|
<citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>'s
|
||||||
|
<command>enable</command> command.
|
||||||
|
<option>rd.systemd.debug_shell=</option> is honored only by initial
|
||||||
|
diff --git a/meson.build b/meson.build
|
||||||
|
index fe82ca4ac2..70811c29cf 100644
|
||||||
|
--- a/meson.build
|
||||||
|
+++ b/meson.build
|
||||||
|
@@ -768,6 +768,7 @@ conf.set_quoted('GETTEXT_PACKAGE', meson.project_name())
|
||||||
|
|
||||||
|
substs.set('SUSHELL', get_option('debug-shell'))
|
||||||
|
substs.set('DEBUGTTY', get_option('debug-tty'))
|
||||||
|
+conf.set_quoted('DEBUGTTY', get_option('debug-tty'))
|
||||||
|
|
||||||
|
enable_debug_hashmap = false
|
||||||
|
enable_debug_mmap_cache = false
|
||||||
|
diff --git a/src/debug-generator/debug-generator.c b/src/debug-generator/debug-generator.c
|
||||||
|
index 800d31cebe..ddef385833 100644
|
||||||
|
--- a/src/debug-generator/debug-generator.c
|
||||||
|
+++ b/src/debug-generator/debug-generator.c
|
||||||
|
@@ -1,8 +1,11 @@
|
||||||
|
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||||
|
|
||||||
|
#include "alloc-util.h"
|
||||||
|
+#include "dropin.h"
|
||||||
|
+#include "generator.h"
|
||||||
|
#include "mkdir.h"
|
||||||
|
#include "parse-util.h"
|
||||||
|
+#include "path-util.h"
|
||||||
|
#include "proc-cmdline.h"
|
||||||
|
#include "special.h"
|
||||||
|
#include "string-util.h"
|
||||||
|
@@ -14,7 +17,7 @@ static char *arg_default_unit = NULL;
|
||||||
|
static const char *arg_dest = "/tmp";
|
||||||
|
static char **arg_mask = NULL;
|
||||||
|
static char **arg_wants = NULL;
|
||||||
|
-static bool arg_debug_shell = false;
|
||||||
|
+static char *arg_debug_shell = NULL;
|
||||||
|
|
||||||
|
static int parse_proc_cmdline_item(const char *key, const char *value, void *data) {
|
||||||
|
int r;
|
||||||
|
@@ -50,15 +53,16 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
} else if (proc_cmdline_key_streq(key, "systemd.debug_shell")) {
|
||||||
|
+ const char *t = NULL;
|
||||||
|
|
||||||
|
- if (value) {
|
||||||
|
- r = parse_boolean(value);
|
||||||
|
- if (r < 0)
|
||||||
|
- log_error("Failed to parse systemd.debug_shell= argument '%s', ignoring.", value);
|
||||||
|
- else
|
||||||
|
- arg_debug_shell = r;
|
||||||
|
- } else
|
||||||
|
- arg_debug_shell = true;
|
||||||
|
+ r = value ? parse_boolean(value) : 1;
|
||||||
|
+ if (r < 0)
|
||||||
|
+ t = skip_dev_prefix(value);
|
||||||
|
+ else if (r > 0)
|
||||||
|
+ t = skip_dev_prefix(DEBUGTTY);
|
||||||
|
+
|
||||||
|
+ if (free_and_strdup(&arg_debug_shell, t) < 0)
|
||||||
|
+ return log_oom();
|
||||||
|
|
||||||
|
} else if (streq(key, "systemd.unit")) {
|
||||||
|
|
||||||
|
@@ -136,6 +140,23 @@ static int generate_wants_symlinks(void) {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void install_debug_shell_dropin(const char *dir) {
|
||||||
|
+ int r;
|
||||||
|
+
|
||||||
|
+ if (streq(arg_debug_shell, skip_dev_prefix(DEBUGTTY)))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ r = write_drop_in_format(dir, "debug-shell.service", 50, "tty",
|
||||||
|
+ "[Unit]\n"
|
||||||
|
+ "Description=Early root shell on /dev/%s FOR DEBUGGING ONLY\n"
|
||||||
|
+ "ConditionPathExists=\n"
|
||||||
|
+ "[Service]\n"
|
||||||
|
+ "TTYPath=/dev/%s",
|
||||||
|
+ arg_debug_shell, arg_debug_shell);
|
||||||
|
+ if (r < 0)
|
||||||
|
+ log_warning_errno(r, "Failed to write drop-in for debug-shell.service, ignoring: %m");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
int r, q;
|
||||||
|
|
||||||
|
@@ -164,6 +185,8 @@ int main(int argc, char *argv[]) {
|
||||||
|
r = log_oom();
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ install_debug_shell_dropin(arg_dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = generate_mask_symlinks();
|
@ -0,0 +1,118 @@
|
|||||||
|
From f4344bb4055cab8dc3bbe82a7f3d97fc6fabcb7e Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Tue, 4 Jun 2019 09:19:04 +0200
|
||||||
|
Subject: [PATCH] test-cpu-set-util: fix comparison for allocation size
|
||||||
|
|
||||||
|
On i386, __cpu_mask is 4 bytes, so we'd check if c.allocated >= 0, and
|
||||||
|
gcc would warn about a bogus comparison. Let's round up.
|
||||||
|
|
||||||
|
Fixes #12726.
|
||||||
|
|
||||||
|
(cherry picked from commit a299ce058b41b21c87f36e77e2c563b0ddd1be0d)
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
---
|
||||||
|
src/test/test-cpu-set-util.c | 22 +++++++++++-----------
|
||||||
|
1 file changed, 11 insertions(+), 11 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
|
||||||
|
index 9522582891..3456add989 100644
|
||||||
|
--- a/src/test/test-cpu-set-util.c
|
||||||
|
+++ b/src/test/test-cpu-set-util.c
|
||||||
|
@@ -17,7 +17,7 @@ static void test_parse_cpu_set(void) {
|
||||||
|
/* Single value */
|
||||||
|
assert_se(parse_cpu_set_full("0", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
assert_se(c.set);
|
||||||
|
- assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
|
||||||
|
assert_se(CPU_ISSET_S(0, c.allocated, c.set));
|
||||||
|
assert_se(CPU_COUNT_S(c.allocated, c.set) == 1);
|
||||||
|
|
||||||
|
@@ -33,7 +33,7 @@ static void test_parse_cpu_set(void) {
|
||||||
|
/* Simple range (from CPUAffinity example) */
|
||||||
|
assert_se(parse_cpu_set_full("1 2 4", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
assert_se(c.set);
|
||||||
|
- assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
|
||||||
|
assert_se(CPU_ISSET_S(1, c.allocated, c.set));
|
||||||
|
assert_se(CPU_ISSET_S(2, c.allocated, c.set));
|
||||||
|
assert_se(CPU_ISSET_S(4, c.allocated, c.set));
|
||||||
|
@@ -50,7 +50,7 @@ static void test_parse_cpu_set(void) {
|
||||||
|
|
||||||
|
/* A more interesting range */
|
||||||
|
assert_se(parse_cpu_set_full("0 1 2 3 8 9 10 11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
- assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
|
||||||
|
assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
|
||||||
|
for (cpu = 0; cpu < 4; cpu++)
|
||||||
|
assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
@@ -68,7 +68,7 @@ static void test_parse_cpu_set(void) {
|
||||||
|
|
||||||
|
/* Quoted strings */
|
||||||
|
assert_se(parse_cpu_set_full("8 '9' 10 \"11\"", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
- assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
|
||||||
|
assert_se(CPU_COUNT_S(c.allocated, c.set) == 4);
|
||||||
|
for (cpu = 8; cpu < 12; cpu++)
|
||||||
|
assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
@@ -83,7 +83,7 @@ static void test_parse_cpu_set(void) {
|
||||||
|
|
||||||
|
/* Use commas as separators */
|
||||||
|
assert_se(parse_cpu_set_full("0,1,2,3 8,9,10,11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
- assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
|
||||||
|
assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
|
||||||
|
for (cpu = 0; cpu < 4; cpu++)
|
||||||
|
assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
@@ -96,7 +96,7 @@ static void test_parse_cpu_set(void) {
|
||||||
|
|
||||||
|
/* Commas with spaces (and trailing comma, space) */
|
||||||
|
assert_se(parse_cpu_set_full("0, 1, 2, 3, 4, 5, 6, 7, 63, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
- assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
|
||||||
|
assert_se(CPU_COUNT_S(c.allocated, c.set) == 9);
|
||||||
|
for (cpu = 0; cpu < 8; cpu++)
|
||||||
|
assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
@@ -113,7 +113,7 @@ static void test_parse_cpu_set(void) {
|
||||||
|
|
||||||
|
/* Ranges */
|
||||||
|
assert_se(parse_cpu_set_full("0-3,8-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
- assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
|
||||||
|
assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
|
||||||
|
for (cpu = 0; cpu < 4; cpu++)
|
||||||
|
assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
@@ -126,7 +126,7 @@ static void test_parse_cpu_set(void) {
|
||||||
|
|
||||||
|
/* Ranges with trailing comma, space */
|
||||||
|
assert_se(parse_cpu_set_full("0-3 8-11, ", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
- assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
|
||||||
|
assert_se(CPU_COUNT_S(c.allocated, c.set) == 8);
|
||||||
|
for (cpu = 0; cpu < 4; cpu++)
|
||||||
|
assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
@@ -143,13 +143,13 @@ static void test_parse_cpu_set(void) {
|
||||||
|
|
||||||
|
/* Negative range (returns empty cpu_set) */
|
||||||
|
assert_se(parse_cpu_set_full("3-0", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
- assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
|
||||||
|
assert_se(CPU_COUNT_S(c.allocated, c.set) == 0);
|
||||||
|
cpu_set_reset(&c);
|
||||||
|
|
||||||
|
/* Overlapping ranges */
|
||||||
|
assert_se(parse_cpu_set_full("0-7 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
- assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
|
||||||
|
assert_se(CPU_COUNT_S(c.allocated, c.set) == 12);
|
||||||
|
for (cpu = 0; cpu < 12; cpu++)
|
||||||
|
assert_se(CPU_ISSET_S(cpu, c.allocated, c.set));
|
||||||
|
@@ -164,7 +164,7 @@ static void test_parse_cpu_set(void) {
|
||||||
|
|
||||||
|
/* Mix ranges and individual CPUs */
|
||||||
|
assert_se(parse_cpu_set_full("0,2 4-11", &c, true, NULL, "fake", 1, "CPUAffinity") >= 0);
|
||||||
|
- assert_se(c.allocated >= sizeof(__cpu_mask) / 8);
|
||||||
|
+ assert_se(c.allocated >= DIV_ROUND_UP(sizeof(__cpu_mask), 8));
|
||||||
|
assert_se(CPU_COUNT_S(c.allocated, c.set) == 10);
|
||||||
|
assert_se(CPU_ISSET_S(0, c.allocated, c.set));
|
||||||
|
assert_se(CPU_ISSET_S(2, c.allocated, c.set));
|
@ -0,0 +1,30 @@
|
|||||||
|
From 3cf9361996b796eae0bda12aec8c92ddae1d5d48 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||||
|
Date: Tue, 4 Jun 2019 09:40:38 +0200
|
||||||
|
Subject: [PATCH] test-cpu-set-util: fix allocation size check on i386
|
||||||
|
|
||||||
|
We get just 28 bytes not 32 as on 64-bit architectures (__cpu_set_t is 4 bytes,
|
||||||
|
we need at least 26, so 28 satisfies the constraints).
|
||||||
|
|
||||||
|
(cherry picked from commit 64412970ac0d4b6f5c4bbd8816edc9bff9eab2de)
|
||||||
|
|
||||||
|
Related: #1734787
|
||||||
|
---
|
||||||
|
src/test/test-cpu-set-util.c | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/src/test/test-cpu-set-util.c b/src/test/test-cpu-set-util.c
|
||||||
|
index 3456add989..136eaca82d 100644
|
||||||
|
--- a/src/test/test-cpu-set-util.c
|
||||||
|
+++ b/src/test/test-cpu-set-util.c
|
||||||
|
@@ -256,7 +256,9 @@ static void test_cpu_set_to_from_dbus(void) {
|
||||||
|
assert_se(array);
|
||||||
|
assert_se(allocated == c.allocated);
|
||||||
|
|
||||||
|
- assert(memcmp(array, expected, sizeof expected) == 0);
|
||||||
|
+ assert_se(allocated <= sizeof expected);
|
||||||
|
+ assert_se(allocated >= DIV_ROUND_UP(201u, 8u)); /* We need at least 201 bits for our mask */
|
||||||
|
+ assert(memcmp(array, expected, allocated) == 0);
|
||||||
|
|
||||||
|
assert_se(cpu_set_from_dbus(array, allocated, &c2) == 0);
|
||||||
|
assert_se(c2.set);
|
@ -13,7 +13,7 @@
|
|||||||
Name: systemd
|
Name: systemd
|
||||||
Url: http://www.freedesktop.org/wiki/Software/systemd
|
Url: http://www.freedesktop.org/wiki/Software/systemd
|
||||||
Version: 239
|
Version: 239
|
||||||
Release: 15%{?dist}
|
Release: 21%{?dist}
|
||||||
# For a breakdown of the licensing, see README
|
# For a breakdown of the licensing, see README
|
||||||
License: LGPLv2+ and MIT and GPLv2+
|
License: LGPLv2+ and MIT and GPLv2+
|
||||||
Summary: System and Service Manager
|
Summary: System and Service Manager
|
||||||
@ -250,6 +250,101 @@ Patch0197: 0197-test-add-test-for-Type-exec.patch
|
|||||||
Patch0198: 0198-journal-gateway-explicitly-declare-local-variables.patch
|
Patch0198: 0198-journal-gateway-explicitly-declare-local-variables.patch
|
||||||
Patch0199: 0199-tools-drop-unused-variable.patch
|
Patch0199: 0199-tools-drop-unused-variable.patch
|
||||||
Patch0200: 0200-journal-gateway-use-localStorage-cursor-only-when-it.patch
|
Patch0200: 0200-journal-gateway-use-localStorage-cursor-only-when-it.patch
|
||||||
|
Patch0201: 0201-sd-bus-deal-with-cookie-overruns.patch
|
||||||
|
Patch0202: 0202-journal-remote-do-not-request-Content-Length-if-Tran.patch
|
||||||
|
Patch0203: 0203-journal-do-not-remove-multiple-spaces-after-identifi.patch
|
||||||
|
Patch0204: 0204-cryptsetup-Do-not-fallback-to-PLAIN-mapping-if-LUKS-.patch
|
||||||
|
Patch0205: 0205-cryptsetup-call-crypt_load-for-LUKS-only-once.patch
|
||||||
|
Patch0206: 0206-cryptsetup-Add-LUKS2-token-support.patch
|
||||||
|
Patch0207: 0207-udev-scsi_id-fix-incorrect-page-length-when-get-devi.patch
|
||||||
|
Patch0208: 0208-Change-job-mode-of-manager-triggered-restarts-to-JOB.patch
|
||||||
|
Patch0209: 0209-bash-completion-analyze-support-security.patch
|
||||||
|
Patch0210: 0210-man-note-that-journal-does-not-validate-syslog-field.patch
|
||||||
|
Patch0211: 0211-rules-skip-memory-hotplug-on-ppc64.patch
|
||||||
|
Patch0212: 0212-mount-simplify-proc-self-mountinfo-handler.patch
|
||||||
|
Patch0213: 0213-mount-rescan-proc-self-mountinfo-before-processing-w.patch
|
||||||
|
Patch0214: 0214-swap-scan-proc-swaps-before-processing-waitid-result.patch
|
||||||
|
Patch0215: 0215-analyze-security-fix-potential-division-by-zero.patch
|
||||||
|
Patch0216: 0216-core-never-propagate-reload-failure-to-service-resul.patch
|
||||||
|
Patch0217: 0217-man-document-systemd-analyze-security.patch
|
||||||
|
Patch0218: 0218-man-reorder-and-add-examples-to-systemd-analyze-1.patch
|
||||||
|
Patch0219: 0219-travis-move-to-CentOS-8-docker-images.patch
|
||||||
|
Patch0220: 0220-travis-drop-SCL-remains.patch
|
||||||
|
Patch0221: 0221-syslog-fix-segfault-in-syslog_parse_priority.patch
|
||||||
|
Patch0222: 0222-sd-bus-make-strict-asan-shut-up.patch
|
||||||
|
Patch0223: 0223-travis-don-t-run-slow-tests-under-ASan-UBSan.patch
|
||||||
|
Patch0224: 0224-kernel-install-do-not-require-non-empty-kernel-cmdli.patch
|
||||||
|
Patch0225: 0225-ask-password-prevent-buffer-overrow-when-reading-fro.patch
|
||||||
|
Patch0226: 0226-core-try-to-reopen-dev-kmsg-again-right-after-mounti.patch
|
||||||
|
Patch0227: 0227-buildsys-don-t-garbage-collect-sections-while-linkin.patch
|
||||||
|
Patch0228: 0228-udev-introduce-CONST-key-name.patch
|
||||||
|
Patch0229: 0229-Call-getgroups-to-know-size-of-supplementary-groups-.patch
|
||||||
|
Patch0230: 0230-Consider-smb3-as-remote-filesystem.patch
|
||||||
|
Patch0231: 0231-process-util-introduce-pid_is_my_child-helper.patch
|
||||||
|
Patch0232: 0232-core-reduce-the-number-of-stalled-PIDs-from-the-watc.patch
|
||||||
|
Patch0233: 0233-core-only-watch-processes-when-it-s-really-necessary.patch
|
||||||
|
Patch0234: 0234-core-implement-per-unit-journal-rate-limiting.patch
|
||||||
|
Patch0235: 0235-path-stop-watching-path-specs-once-we-triggered-the-.patch
|
||||||
|
Patch0236: 0236-journald-fixed-assertion-failure-when-system-journal.patch
|
||||||
|
Patch0237: 0237-test-use-PBKDF2-instead-of-Argon2-in-cryptsetup.patch
|
||||||
|
Patch0238: 0238-test-mask-several-unnecessary-services.patch
|
||||||
|
Patch0239: 0239-test-bump-the-second-partition-s-size-to-50M.patch
|
||||||
|
Patch0240: 0240-shared-sleep-config-exclude-zram-devices-from-hibern.patch
|
||||||
|
Patch0241: 0241-selinux-don-t-log-SELINUX_INFO-and-SELINUX_WARNING-m.patch
|
||||||
|
Patch0242: 0242-sd-device-introduce-log_device_-macros.patch
|
||||||
|
Patch0243: 0243-udev-Add-id-program-and-rule-for-FIDO-security-token.patch
|
||||||
|
Patch0244: 0244-shared-but-util-drop-trusted-annotation-from-bus_ope.patch
|
||||||
|
Patch0245: 0245-sd-bus-adjust-indentation-of-comments.patch
|
||||||
|
Patch0246: 0246-resolved-do-not-run-loop-twice.patch
|
||||||
|
Patch0247: 0247-resolved-allow-access-to-Set-Link-and-Revert-methods.patch
|
||||||
|
Patch0248: 0248-resolved-query-polkit-only-after-parsing-the-data.patch
|
||||||
|
Patch0249: 0249-journal-rely-on-_cleanup_free_-to-free-a-temporary-s.patch
|
||||||
|
Patch0250: 0250-basic-user-util-allow-dots-in-user-names.patch
|
||||||
|
Patch0251: 0251-sd-bus-bump-message-queue-size-again.patch
|
||||||
|
Patch0252: 0252-tests-put-fuzz_journald_processing_function-in-a-.c-.patch
|
||||||
|
Patch0253: 0253-tests-add-a-fuzzer-for-dev_kmsg_record.patch
|
||||||
|
Patch0254: 0254-basic-remove-an-assertion-from-cunescape_one.patch
|
||||||
|
Patch0255: 0255-journal-fix-an-off-by-one-error-in-dev_kmsg_record.patch
|
||||||
|
Patch0256: 0256-tests-add-a-reproducer-for-a-memory-leak-fixed-in-30.patch
|
||||||
|
Patch0257: 0257-tests-add-a-reproducer-for-a-heap-buffer-overflow-fi.patch
|
||||||
|
Patch0258: 0258-test-initialize-syslog_fd-in-fuzz-journald-kmsg-too.patch
|
||||||
|
Patch0259: 0259-tests-add-a-fuzzer-for-process_audit_string.patch
|
||||||
|
Patch0260: 0260-journald-check-whether-sscanf-has-changed-the-value-.patch
|
||||||
|
Patch0261: 0261-tests-introduce-dummy_server_init-and-use-it-in-all-.patch
|
||||||
|
Patch0262: 0262-tests-add-a-fuzzer-for-journald-streams.patch
|
||||||
|
Patch0263: 0263-tests-add-a-fuzzer-for-server_process_native_file.patch
|
||||||
|
Patch0264: 0264-fuzz-journal-stream-avoid-assertion-failure-on-sampl.patch
|
||||||
|
Patch0265: 0265-journald-take-leading-spaces-into-account-in-syslog_.patch
|
||||||
|
Patch0266: 0266-Add-a-warning-about-the-difference-in-permissions-be.patch
|
||||||
|
Patch0267: 0267-execute-remove-one-redundant-comparison-check.patch
|
||||||
|
Patch0268: 0268-core-change-ownership-mode-of-the-execution-director.patch
|
||||||
|
Patch0269: 0269-core-dbus-execute-remove-unnecessary-initialization.patch
|
||||||
|
Patch0270: 0270-shared-cpu-set-util-move-the-part-to-print-cpu-set-i.patch
|
||||||
|
Patch0271: 0271-shared-cpu-set-util-remove-now-unused-CPU_SIZE_TO_NU.patch
|
||||||
|
Patch0272: 0272-Rework-cpu-affinity-parsing.patch
|
||||||
|
Patch0273: 0273-Move-cpus_in_affinity_mask-to-cpu-set-util.-ch.patch
|
||||||
|
Patch0274: 0274-test-cpu-set-util-add-simple-test-for-cpus_in_affini.patch
|
||||||
|
Patch0275: 0275-test-cpu-set-util-add-a-smoke-test-for-test_parse_cp.patch
|
||||||
|
Patch0276: 0276-pid1-parse-CPUAffinity-in-incremental-fashion.patch
|
||||||
|
Patch0277: 0277-pid1-don-t-reset-setting-from-proc-cmdline-upon-rest.patch
|
||||||
|
Patch0278: 0278-pid1-when-reloading-configuration-forget-old-setting.patch
|
||||||
|
Patch0279: 0279-test-execute-use-CPUSet-too.patch
|
||||||
|
Patch0280: 0280-shared-cpu-set-util-drop-now-unused-cleanup-function.patch
|
||||||
|
Patch0281: 0281-shared-cpu-set-util-make-transfer-of-cpu_set_t-over-.patch
|
||||||
|
Patch0282: 0282-test-cpu-set-util-add-test-for-dbus-conversions.patch
|
||||||
|
Patch0283: 0283-shared-cpu-set-util-introduce-cpu_set_to_range.patch
|
||||||
|
Patch0284: 0284-systemctl-present-CPUAffinity-mask-as-a-list-of-CPU-.patch
|
||||||
|
Patch0285: 0285-shared-cpu-set-util-only-force-range-printing-one-ti.patch
|
||||||
|
Patch0286: 0286-execute-dump-CPUAffinity-as-a-range-string-instead-o.patch
|
||||||
|
Patch0287: 0287-cpu-set-util-use-d-d-format-in-cpu_set_to_range_stri.patch
|
||||||
|
Patch0288: 0288-core-introduce-NUMAPolicy-and-NUMAMask-options.patch
|
||||||
|
Patch0289: 0289-core-disable-CPUAccounting-by-default.patch
|
||||||
|
Patch0290: 0290-set-kptr_restrict-1.patch
|
||||||
|
Patch0291: 0291-cryptsetup-reduce-the-chance-that-we-will-be-OOM-kil.patch
|
||||||
|
Patch0292: 0292-core-job-fix-breakage-of-ordering-dependencies-by-sy.patch
|
||||||
|
Patch0293: 0293-debug-generator-enable-custom-systemd.debug_shell-tt.patch
|
||||||
|
Patch0294: 0294-test-cpu-set-util-fix-comparison-for-allocation-size.patch
|
||||||
|
Patch0295: 0295-test-cpu-set-util-fix-allocation-size-check-on-i386.patch
|
||||||
|
|
||||||
|
|
||||||
%ifarch %{ix86} x86_64 aarch64
|
%ifarch %{ix86} x86_64 aarch64
|
||||||
@ -869,6 +964,120 @@ fi
|
|||||||
%files tests -f .file-list-tests
|
%files tests -f .file-list-tests
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Dec 09 2019 systemd maintenance team <systemd-maint@redhat.com> - 239-21
|
||||||
|
- test-cpu-set-util: fix comparison for allocation size (#1734787)
|
||||||
|
- test-cpu-set-util: fix allocation size check on i386 (#1734787)
|
||||||
|
|
||||||
|
* Mon Dec 09 2019 systemd maintenance team <systemd-maint@redhat.com> - 239-20
|
||||||
|
- journal: rely on _cleanup_free_ to free a temporary string used in client_context_read_cgroup (#1764560)
|
||||||
|
- basic/user-util: allow dots in user names (#1717603)
|
||||||
|
- sd-bus: bump message queue size again (#1770189)
|
||||||
|
- tests: put fuzz_journald_processing_function in a .c file (#1764560)
|
||||||
|
- tests: add a fuzzer for dev_kmsg_record (#1764560)
|
||||||
|
- basic: remove an assertion from cunescape_one (#1764560)
|
||||||
|
- journal: fix an off-by-one error in dev_kmsg_record (#1764560)
|
||||||
|
- tests: add a reproducer for a memory leak fixed in 30eddcd51b8a472e05d3b8d1 in August (#1764560)
|
||||||
|
- tests: add a reproducer for a heap-buffer-overflow fixed in 937b1171378bc1000a (#1764560)
|
||||||
|
- test: initialize syslog_fd in fuzz-journald-kmsg too (#1764560)
|
||||||
|
- tests: add a fuzzer for process_audit_string (#1764560)
|
||||||
|
- journald: check whether sscanf has changed the value corresponding to %n (#1764560)
|
||||||
|
- tests: introduce dummy_server_init and use it in all journald fuzzers (#1764560)
|
||||||
|
- tests: add a fuzzer for journald streams (#1764560)
|
||||||
|
- tests: add a fuzzer for server_process_native_file (#1764560)
|
||||||
|
- fuzz-journal-stream: avoid assertion failure on samples which don't fit in pipe (#1764560)
|
||||||
|
- journald: take leading spaces into account in syslog_parse_identifier (#1764560)
|
||||||
|
- Add a warning about the difference in permissions between existing directories and unit settings. (#1778384)
|
||||||
|
- execute: remove one redundant comparison check (#1778384)
|
||||||
|
- core: change ownership/mode of the execution directories also for static users (#1778384)
|
||||||
|
- core/dbus-execute: remove unnecessary initialization (#1734787)
|
||||||
|
- shared/cpu-set-util: move the part to print cpu-set into a separate function (#1734787)
|
||||||
|
- shared/cpu-set-util: remove now-unused CPU_SIZE_TO_NUM() (#1734787)
|
||||||
|
- Rework cpu affinity parsing (#1734787)
|
||||||
|
- Move cpus_in_affinity_mask() to cpu-set-util.[ch] (#1734787)
|
||||||
|
- test-cpu-set-util: add simple test for cpus_in_affinity_mask() (#1734787)
|
||||||
|
- test-cpu-set-util: add a smoke test for test_parse_cpu_set_extend() (#1734787)
|
||||||
|
- pid1: parse CPUAffinity= in incremental fashion (#1734787)
|
||||||
|
- pid1: don't reset setting from /proc/cmdline upon restart (#1734787)
|
||||||
|
- pid1: when reloading configuration, forget old settings (#1734787)
|
||||||
|
- test-execute: use CPUSet too (#1734787)
|
||||||
|
- shared/cpu-set-util: drop now-unused cleanup function (#1734787)
|
||||||
|
- shared/cpu-set-util: make transfer of cpu_set_t over bus endian safe (#1734787)
|
||||||
|
- test-cpu-set-util: add test for dbus conversions (#1734787)
|
||||||
|
- shared/cpu-set-util: introduce cpu_set_to_range() (#1734787)
|
||||||
|
- systemctl: present CPUAffinity mask as a list of CPU index ranges (#1734787)
|
||||||
|
- shared/cpu-set-util: only force range printing one time (#1734787)
|
||||||
|
- execute: dump CPUAffinity as a range string instead of a list of CPUs (#1734787)
|
||||||
|
- cpu-set-util: use %d-%d format in cpu_set_to_range_string() only for actual ranges (#1734787)
|
||||||
|
- core: introduce NUMAPolicy and NUMAMask options (#1734787)
|
||||||
|
- core: disable CPUAccounting by default (#1734787)
|
||||||
|
- set kptr_restrict=1 (#1689346)
|
||||||
|
- cryptsetup: reduce the chance that we will be OOM killed (#1696602)
|
||||||
|
- core, job: fix breakage of ordering dependencies by systemctl reload command (#1766417)
|
||||||
|
- debug-generator: enable custom systemd.debug_shell tty (#1723722)
|
||||||
|
|
||||||
|
* Thu Oct 24 2019 Lukas Nykryn <lnykryn@redhat.com> - 239-19
|
||||||
|
- core: never propagate reload failure to service result (#1735787)
|
||||||
|
- man: document systemd-analyze security (#1750343)
|
||||||
|
- man: reorder and add examples to systemd-analyze(1) (#1750343)
|
||||||
|
- travis: move to CentOS 8 docker images (#1761519)
|
||||||
|
- travis: drop SCL remains (#1761519)
|
||||||
|
- syslog: fix segfault in syslog_parse_priority() (#1761519)
|
||||||
|
- sd-bus: make strict asan shut up (#1761519)
|
||||||
|
- travis: don't run slow tests under ASan/UBSan (#1761519)
|
||||||
|
- kernel-install: do not require non-empty kernel cmdline (#1701454)
|
||||||
|
- ask-password: prevent buffer overrow when reading from keyring (#1752050)
|
||||||
|
- core: try to reopen /dev/kmsg again right after mounting /dev (#1749212)
|
||||||
|
- buildsys: don't garbage collect sections while linking (#1748258)
|
||||||
|
- udev: introduce CONST key name (#1762679)
|
||||||
|
- Call getgroups() to know size of supplementary groups array to allocate (#1743230256 KB
|
||||||
|
#1743235)
|
||||||
|
- Consider smb3 as remote filesystem (#1757257)
|
||||||
|
- process-util: introduce pid_is_my_child() helper (#1744972)
|
||||||
|
- core: reduce the number of stalled PIDs from the watched processes list when possible (#1744972)
|
||||||
|
- core: only watch processes when it's really necessary (#1744972)
|
||||||
|
- core: implement per unit journal rate limiting (#1719577)
|
||||||
|
- path: stop watching path specs once we triggered the target unit (#1763161)
|
||||||
|
- journald: fixed assertion failure when system journal rotation fails (#9893) (#1763619)
|
||||||
|
- test: use PBKDF2 instead of Argon2 in cryptsetup... (#1761519)
|
||||||
|
- test: mask several unnecessary services (#1761519)
|
||||||
|
- test: bump the second partition's size to 50M (#1761519)
|
||||||
|
- shared/sleep-config: exclude zram devices from hibernation candidates (#1763617)
|
||||||
|
- selinux: don't log SELINUX_INFO and SELINUX_WARNING messages to audit (#1763612)
|
||||||
|
- sd-device: introduce log_device_*() macros (#1753369)
|
||||||
|
- udev: Add id program and rule for FIDO security tokens (#1753369)
|
||||||
|
- shared/but-util: drop trusted annotation from bus_open_system_watch_bind_with_description() (#1746857)
|
||||||
|
- sd-bus: adjust indentation of comments (#1746857)
|
||||||
|
- resolved: do not run loop twice (#1746857)
|
||||||
|
- resolved: allow access to Set*Link and Revert methods through polkit (#1746857)
|
||||||
|
- resolved: query polkit only after parsing the data (#1746857)
|
||||||
|
|
||||||
|
* Fri Aug 30 2019 Lukas Nykryn <lnykryn@redhat.com> - 239-18
|
||||||
|
- shared/but-util: drop trusted annotation from bus_open_system_watch_bind_with_description() (#1746857)
|
||||||
|
- sd-bus: adjust indentation of comments (#1746857)
|
||||||
|
- resolved: do not run loop twice (#1746857)
|
||||||
|
- resolved: allow access to Set*Link and Revert methods through polkit (#1746857)
|
||||||
|
- resolved: query polkit only after parsing the data (#1746857)
|
||||||
|
|
||||||
|
* Wed Aug 07 2019 Lukas Nykryn <lnykryn@redhat.com> - 239-17
|
||||||
|
- mount: simplify /proc/self/mountinfo handler (#1696178)
|
||||||
|
- mount: rescan /proc/self/mountinfo before processing waitid() results (#1696178)
|
||||||
|
- swap: scan /proc/swaps before processing waitid() results (#1696178)
|
||||||
|
- analyze-security: fix potential division by zero (#1734400)
|
||||||
|
|
||||||
|
* Fri Jul 26 2019 Lukas Nykryn <lnykryn@redhat.com> - 239-16
|
||||||
|
- sd-bus: deal with cookie overruns (#1694999)
|
||||||
|
- journal-remote: do not request Content-Length if Transfer-Encoding is chunked (#1708849)
|
||||||
|
- journal: do not remove multiple spaces after identifier in syslog message (#1691817)
|
||||||
|
- cryptsetup: Do not fallback to PLAIN mapping if LUKS data device set fails. (#1719153)
|
||||||
|
- cryptsetup: call crypt_load() for LUKS only once (#1719153)
|
||||||
|
- cryptsetup: Add LUKS2 token support. (#1719153)
|
||||||
|
- udev/scsi_id: fix incorrect page length when get device identification VPD page (#1713227)
|
||||||
|
- Change job mode of manager triggered restarts to JOB_REPLACE (#11456
|
||||||
|
#1712524)
|
||||||
|
- bash-completion: analyze: support 'security' (#1733395)
|
||||||
|
- man: note that journal does not validate syslog fields (#1707175)
|
||||||
|
- rules: skip memory hotplug on ppc64 (#1713159)
|
||||||
|
|
||||||
* Thu May 23 2019 Lukas Nykryn <lnykryn@redhat.com> - 239-15
|
* Thu May 23 2019 Lukas Nykryn <lnykryn@redhat.com> - 239-15
|
||||||
- tree-wide: shorten error logging a bit (#1697893)
|
- tree-wide: shorten error logging a bit (#1697893)
|
||||||
- nspawn: simplify machine terminate bus call (#1697893)
|
- nspawn: simplify machine terminate bus call (#1697893)
|
||||||
|
Loading…
Reference in New Issue
Block a user