systemd-252-37
Resolves: RHEL-13159,RHEL-20322,RHEL-27512,RHEL-30372,RHEL-31070,RHEL-31219,RHEL-33890,RHEL-35703,RHEL-38864,RHEL-40878,RHEL-6589
This commit is contained in:
parent
db6c9f7775
commit
75aa201631
@ -0,0 +1,25 @@
|
||||
From 43373d851c9f6222f4523b9db7006fbfe14c3d70 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Sekletar <msekleta@redhat.com>
|
||||
Date: Thu, 23 May 2024 18:07:45 +0200
|
||||
Subject: [PATCH] ci(src-git): add RHEL-9.1 and RHEL-9.1.z to allowed versions
|
||||
|
||||
rhel-only
|
||||
|
||||
Related: RHEL-30372
|
||||
---
|
||||
.github/tracker-validator.yml | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/.github/tracker-validator.yml b/.github/tracker-validator.yml
|
||||
index 31ef28f6ea..21cbedd8b0 100644
|
||||
--- a/.github/tracker-validator.yml
|
||||
+++ b/.github/tracker-validator.yml
|
||||
@@ -8,6 +8,8 @@ products:
|
||||
- CentOS Stream 9
|
||||
- rhel-9.0.0
|
||||
- rhel-9.0.0.z
|
||||
+ - rhel-9.1.0
|
||||
+ - rhel-9.1.0.z
|
||||
- rhel-9.2.0
|
||||
- rhel-9.2.0.z
|
||||
- rhel-9.3.0
|
30
0743-libsystemd-link-with-z-nodelete.patch
Normal file
30
0743-libsystemd-link-with-z-nodelete.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From aa18f6b2b2cad6977f39e1e323705e2b11a7829c Mon Sep 17 00:00:00 2001
|
||||
From: Michal Sekletar <msekleta@redhat.com>
|
||||
Date: Thu, 23 May 2024 17:35:51 +0200
|
||||
Subject: [PATCH] libsystemd: link with '-z nodelete'
|
||||
|
||||
We want to avoid reinitialization of our global variables with static
|
||||
storage duration in case we get dlopened multiple times by the same
|
||||
application. This will avoid potential resource leaks that could have
|
||||
happened otherwise (e.g. leaking journal socket fd).
|
||||
|
||||
(cherry picked from commit 9d8533b7152daf792356c601516b57c6412d3e52)
|
||||
|
||||
Resolves: RHEL-6589
|
||||
---
|
||||
meson.build | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/meson.build b/meson.build
|
||||
index 843d823e3e..274e43ba9e 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -2004,6 +2004,8 @@ libsystemd = shared_library(
|
||||
version : libsystemd_version,
|
||||
include_directories : libsystemd_includes,
|
||||
link_args : ['-shared',
|
||||
+ # Make sure our library is never deleted from memory, so that our open logging fds don't leak on dlopen/dlclose cycles.
|
||||
+ '-z', 'nodelete',
|
||||
'-Wl,--version-script=' + libsystemd_sym_path],
|
||||
link_with : [libbasic,
|
||||
libbasic_gcrypt,
|
@ -0,0 +1,54 @@
|
||||
From d26e1ba4539a3a33224ca1019b9e6cf5590744f5 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||
Date: Fri, 23 Jun 2023 11:10:42 -0600
|
||||
Subject: [PATCH] basic/utf8: make utf8_encoded_to_unichar() return length of
|
||||
the codepoint
|
||||
|
||||
(cherry picked from commit 9579e9a5308573c3c9c82f1978456cc71f68760c)
|
||||
|
||||
Related: RHEL-31219
|
||||
---
|
||||
src/basic/utf8.c | 10 ++++------
|
||||
1 file changed, 4 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/basic/utf8.c b/src/basic/utf8.c
|
||||
index 2532fcf81a..9d9e76904e 100644
|
||||
--- a/src/basic/utf8.c
|
||||
+++ b/src/basic/utf8.c
|
||||
@@ -90,7 +90,7 @@ int utf8_encoded_to_unichar(const char *str, char32_t *ret_unichar) {
|
||||
switch (len) {
|
||||
case 1:
|
||||
*ret_unichar = (char32_t)str[0];
|
||||
- return 0;
|
||||
+ return 1;
|
||||
case 2:
|
||||
unichar = str[0] & 0x1f;
|
||||
break;
|
||||
@@ -119,15 +119,14 @@ int utf8_encoded_to_unichar(const char *str, char32_t *ret_unichar) {
|
||||
}
|
||||
|
||||
*ret_unichar = unichar;
|
||||
-
|
||||
- return 0;
|
||||
+ return len;
|
||||
}
|
||||
|
||||
bool utf8_is_printable_newline(const char* str, size_t length, bool allow_newline) {
|
||||
assert(str);
|
||||
|
||||
for (const char *p = str; length > 0;) {
|
||||
- int encoded_len, r;
|
||||
+ int encoded_len;
|
||||
char32_t val;
|
||||
|
||||
encoded_len = utf8_encoded_valid_unichar(p, length);
|
||||
@@ -135,8 +134,7 @@ bool utf8_is_printable_newline(const char* str, size_t length, bool allow_newlin
|
||||
return false;
|
||||
assert(encoded_len > 0 && (size_t) encoded_len <= length);
|
||||
|
||||
- r = utf8_encoded_to_unichar(p, &val);
|
||||
- if (r < 0 ||
|
||||
+ if (utf8_encoded_to_unichar(p, &val) < 0 ||
|
||||
unichar_is_control(val) ||
|
||||
(!allow_newline && val == '\n'))
|
||||
return false;
|
@ -0,0 +1,67 @@
|
||||
From 0fc377b76f10eb283d4de76b8fe7c083b95f70b7 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||
Date: Fri, 23 Jun 2023 17:24:11 -0600
|
||||
Subject: [PATCH] test-gunicode: add new test to show that unichar_iswide() is
|
||||
borked
|
||||
|
||||
I discovered this while looking at the tests with wide characters in the next
|
||||
patch. It's something to fix, but not directly relevant to the issue of
|
||||
skipping ANSI in ellipsization. We will generate output that is wider than
|
||||
expected in some cases, but wide characters are used very rarely so this isn't
|
||||
such a big problem.
|
||||
|
||||
(cherry picked from commit d9c72e54190db2a0845d1558b5beb734e9f629ff)
|
||||
|
||||
Related: RHEL-31219
|
||||
---
|
||||
src/test/meson.build | 2 ++
|
||||
src/test/test-gunicode.c | 27 +++++++++++++++++++++++++++
|
||||
2 files changed, 29 insertions(+)
|
||||
create mode 100644 src/test/test-gunicode.c
|
||||
|
||||
diff --git a/src/test/meson.build b/src/test/meson.build
|
||||
index 5430e72ab5..1d61dc343f 100644
|
||||
--- a/src/test/meson.build
|
||||
+++ b/src/test/meson.build
|
||||
@@ -469,6 +469,8 @@ tests += [
|
||||
|
||||
[files('test-gpt.c')],
|
||||
|
||||
+ [files('test-gunicode.c')],
|
||||
+
|
||||
[files('test-log.c')],
|
||||
|
||||
[files('test-ipcrm.c'),
|
||||
diff --git a/src/test/test-gunicode.c b/src/test/test-gunicode.c
|
||||
new file mode 100644
|
||||
index 0000000000..1836cdc04a
|
||||
--- /dev/null
|
||||
+++ b/src/test/test-gunicode.c
|
||||
@@ -0,0 +1,27 @@
|
||||
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
+
|
||||
+#include "gunicode.h"
|
||||
+#include "tests.h"
|
||||
+#include "utf8.h"
|
||||
+
|
||||
+TEST(unichar_iswide) {
|
||||
+ char32_t c;
|
||||
+ int r;
|
||||
+
|
||||
+ /* FIXME: the cats are wide, but we get this wrong */
|
||||
+ for (const char *narrow = "abX_…ąęµ!" "😼😿🙀😸😻"; *narrow; narrow += r) {
|
||||
+ r = utf8_encoded_to_unichar(narrow, &c);
|
||||
+ bool w = unichar_iswide(c);
|
||||
+ assert_se(r > 0);
|
||||
+ assert_se(!w);
|
||||
+ }
|
||||
+
|
||||
+ for (const char *wide = "🐱/¥"; *wide; wide += r) {
|
||||
+ r = utf8_encoded_to_unichar(wide, &c);
|
||||
+ bool w = unichar_iswide(c);
|
||||
+ assert_se(r > 0);
|
||||
+ assert_se(w);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+DEFINE_TEST_MAIN(LOG_INFO);
|
320
0746-string-util-pass-ANSI-sequences-through-unchanged.patch
Normal file
320
0746-string-util-pass-ANSI-sequences-through-unchanged.patch
Normal file
@ -0,0 +1,320 @@
|
||||
From cec4cc86486d3e212b5e919595feb39c6cee4c2c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||
Date: Fri, 23 Jun 2023 18:40:14 -0600
|
||||
Subject: [PATCH] string-util: pass ANSI sequences through unchanged
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Cutting off in the middle may leave the terminal in a bad state, breaking
|
||||
further output. But we don't know what a given ANSI sequence does, e.g.
|
||||
ANSI_NORMAL should not be skipped. But it is also nice to keep various
|
||||
sequences intact, so that if we had part of the string in blue, and we cut out
|
||||
the beginning of the blue part, we still want to keep the remainder in color.
|
||||
So let's just pass them through, stripping out the characters that take up
|
||||
actual space.
|
||||
|
||||
Also, use memcpy_safe as we may end up copying zero bytes when ellipsizing at
|
||||
the start/end of a string.
|
||||
|
||||
Fixes: #24502
|
||||
|
||||
This also fixes an ugliness where we would ellipsize string with ANSI
|
||||
sequences too much, leading to output that was narrower on screen than the
|
||||
requested length:
|
||||
|
||||
Starting AAAAAAAAAAAAAAAAAAAAA.service
|
||||
Starting BBBBBBBBBBBBBBBBBBBBB.service
|
||||
Starting LONG…ER.service
|
||||
|
||||
Co-authored-by: Jan Janssen <medhefgo@web.de>
|
||||
|
||||
(cherry picked from commit cb558ab222f0dbda3afd985c2190f35693963ffa)
|
||||
|
||||
Resolves: RHEL-31219
|
||||
---
|
||||
src/basic/string-util.c | 163 ++++++++++++++++++++++++++++++--------
|
||||
src/test/test-ellipsize.c | 41 ++++++++++
|
||||
2 files changed, 172 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/src/basic/string-util.c b/src/basic/string-util.c
|
||||
index 17d35fe1a4..fe6e9e94ad 100644
|
||||
--- a/src/basic/string-util.c
|
||||
+++ b/src/basic/string-util.c
|
||||
@@ -288,6 +288,62 @@ static int write_ellipsis(char *buf, bool unicode) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
+static size_t ansi_sequence_length(const char *s, size_t len) {
|
||||
+ assert(s);
|
||||
+
|
||||
+ if (len < 2)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (s[0] != 0x1B) /* ASCII 27, aka ESC, aka Ctrl-[ */
|
||||
+ return 0; /* Not the start of a sequence */
|
||||
+
|
||||
+ if (s[1] == 0x5B) { /* [, start of CSI sequence */
|
||||
+ size_t i = 2;
|
||||
+
|
||||
+ if (i == len)
|
||||
+ return 0;
|
||||
+
|
||||
+ while (s[i] >= 0x30 && s[i] <= 0x3F) /* Parameter bytes */
|
||||
+ if (++i == len)
|
||||
+ return 0;
|
||||
+ while (s[i] >= 0x20 && s[i] <= 0x2F) /* Intermediate bytes */
|
||||
+ if (++i == len)
|
||||
+ return 0;
|
||||
+ if (s[i] >= 0x40 && s[i] <= 0x7E) /* Final byte */
|
||||
+ return i + 1;
|
||||
+ return 0; /* Bad sequence */
|
||||
+
|
||||
+ } else if (s[1] >= 0x40 && s[1] <= 0x5F) /* other non-CSI Fe sequence */
|
||||
+ return 2;
|
||||
+
|
||||
+ return 0; /* Bad escape? */
|
||||
+}
|
||||
+
|
||||
+static bool string_has_ansi_sequence(const char *s, size_t len) {
|
||||
+ const char *t = s;
|
||||
+
|
||||
+ while ((t = memchr(s, 0x1B, len - (t - s))))
|
||||
+ if (ansi_sequence_length(t, len - (t - s)) > 0)
|
||||
+ return true;
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+static size_t previous_ansi_sequence(const char *s, size_t length, const char **ret_where) {
|
||||
+ /* Locate the previous ANSI sequence and save its start in *ret_where and return length. */
|
||||
+
|
||||
+ for (size_t i = length - 2; i > 0; i--) { /* -2 because at least two bytes are needed */
|
||||
+ size_t slen = ansi_sequence_length(s + (i - 1), length - (i - 1));
|
||||
+ if (slen == 0)
|
||||
+ continue;
|
||||
+
|
||||
+ *ret_where = s + (i - 1);
|
||||
+ return slen;
|
||||
+ }
|
||||
+
|
||||
+ *ret_where = NULL;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
|
||||
size_t x, need_space, suffix_len;
|
||||
char *t;
|
||||
@@ -347,7 +403,6 @@ static char *ascii_ellipsize_mem(const char *s, size_t old_length, size_t new_le
|
||||
char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
|
||||
size_t x, k, len, len2;
|
||||
const char *i, *j;
|
||||
- char *e;
|
||||
int r;
|
||||
|
||||
/* Note that 'old_length' refers to bytes in the string, while 'new_length' refers to character cells taken up
|
||||
@@ -371,73 +426,117 @@ char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigne
|
||||
if (new_length == 0)
|
||||
return strdup("");
|
||||
|
||||
- /* If no multibyte characters use ascii_ellipsize_mem for speed */
|
||||
- if (ascii_is_valid_n(s, old_length))
|
||||
+ bool has_ansi_seq = string_has_ansi_sequence(s, old_length);
|
||||
+
|
||||
+ /* If no multibyte characters or ANSI sequences, use ascii_ellipsize_mem for speed */
|
||||
+ if (!has_ansi_seq && ascii_is_valid_n(s, old_length))
|
||||
return ascii_ellipsize_mem(s, old_length, new_length, percent);
|
||||
|
||||
- x = ((new_length - 1) * percent) / 100;
|
||||
+ x = (new_length - 1) * percent / 100;
|
||||
assert(x <= new_length - 1);
|
||||
|
||||
k = 0;
|
||||
- for (i = s; i < s + old_length; i = utf8_next_char(i)) {
|
||||
- char32_t c;
|
||||
- int w;
|
||||
+ for (i = s; i < s + old_length; ) {
|
||||
+ size_t slen = has_ansi_seq ? ansi_sequence_length(i, old_length - (i - s)) : 0;
|
||||
+ if (slen > 0) {
|
||||
+ i += slen;
|
||||
+ continue; /* ANSI sequences don't take up any space in output */
|
||||
+ }
|
||||
|
||||
+ char32_t c;
|
||||
r = utf8_encoded_to_unichar(i, &c);
|
||||
if (r < 0)
|
||||
return NULL;
|
||||
|
||||
- w = unichar_iswide(c) ? 2 : 1;
|
||||
- if (k + w <= x)
|
||||
- k += w;
|
||||
- else
|
||||
+ int w = unichar_iswide(c) ? 2 : 1;
|
||||
+ if (k + w > x)
|
||||
break;
|
||||
+
|
||||
+ k += w;
|
||||
+ i += r;
|
||||
}
|
||||
|
||||
- for (j = s + old_length; j > i; ) {
|
||||
+ const char *ansi_start = s + old_length;
|
||||
+ size_t ansi_len = 0;
|
||||
+
|
||||
+ for (const char *t = j = s + old_length; t > i && k < new_length; ) {
|
||||
char32_t c;
|
||||
int w;
|
||||
- const char *jj;
|
||||
+ const char *tt;
|
||||
+
|
||||
+ if (has_ansi_seq && ansi_start >= t)
|
||||
+ /* Figure out the previous ANSI sequence, if any */
|
||||
+ ansi_len = previous_ansi_sequence(s, t - s, &ansi_start);
|
||||
|
||||
- jj = utf8_prev_char(j);
|
||||
- r = utf8_encoded_to_unichar(jj, &c);
|
||||
+ /* If the sequence extends all the way to the current position, skip it. */
|
||||
+ if (has_ansi_seq && ansi_len > 0 && ansi_start + ansi_len == t) {
|
||||
+ t = ansi_start;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ tt = utf8_prev_char(t);
|
||||
+ r = utf8_encoded_to_unichar(tt, &c);
|
||||
if (r < 0)
|
||||
return NULL;
|
||||
|
||||
w = unichar_iswide(c) ? 2 : 1;
|
||||
- if (k + w <= new_length) {
|
||||
- k += w;
|
||||
- j = jj;
|
||||
- } else
|
||||
+ if (k + w > new_length)
|
||||
break;
|
||||
+
|
||||
+ k += w;
|
||||
+ j = t = tt; /* j should always point to the first "real" character */
|
||||
}
|
||||
- assert(i <= j);
|
||||
|
||||
- /* we don't actually need to ellipsize */
|
||||
- if (i == j)
|
||||
+ /* We don't actually need to ellipsize */
|
||||
+ if (i >= j)
|
||||
return memdup_suffix0(s, old_length);
|
||||
|
||||
- /* make space for ellipsis, if possible */
|
||||
- if (j < s + old_length)
|
||||
- j = utf8_next_char(j);
|
||||
- else if (i > s)
|
||||
- i = utf8_prev_char(i);
|
||||
+ if (k >= new_length) {
|
||||
+ /* Make space for ellipsis, if required and possible. We know that the edge character is not
|
||||
+ * part of an ANSI sequence (because then we'd skip it). If the last character we looked at
|
||||
+ * was wide, we don't need to make space. */
|
||||
+ if (j < s + old_length)
|
||||
+ j = utf8_next_char(j);
|
||||
+ else if (i > s)
|
||||
+ i = utf8_prev_char(i);
|
||||
+ }
|
||||
|
||||
len = i - s;
|
||||
len2 = s + old_length - j;
|
||||
- e = new(char, len + 3 + len2 + 1);
|
||||
+
|
||||
+ /* If we have ANSI, allow the same length as the source string + ellipsis. It'd be too involved to
|
||||
+ * figure out what exact space is needed. Strings with ANSI sequences are most likely to be fairly
|
||||
+ * short anyway. */
|
||||
+ size_t alloc_len = has_ansi_seq ? old_length + 3 + 1 : len + 3 + len2 + 1;
|
||||
+
|
||||
+ char *e = new(char, alloc_len);
|
||||
if (!e)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
- printf("old_length=%zu new_length=%zu x=%zu len=%u len2=%u k=%u\n",
|
||||
+ printf("old_length=%zu new_length=%zu x=%zu len=%zu len2=%zu k=%zu\n",
|
||||
old_length, new_length, x, len, len2, k);
|
||||
*/
|
||||
|
||||
- memcpy(e, s, len);
|
||||
+ memcpy_safe(e, s, len);
|
||||
write_ellipsis(e + len, true);
|
||||
- memcpy(e + len + 3, j, len2);
|
||||
- *(e + len + 3 + len2) = '\0';
|
||||
+
|
||||
+ char *dst = e + len + 3;
|
||||
+
|
||||
+ if (has_ansi_seq)
|
||||
+ /* Copy over any ANSI sequences in full */
|
||||
+ for (const char *p = s + len; p < j; ) {
|
||||
+ size_t slen = ansi_sequence_length(p, j - p);
|
||||
+ if (slen > 0) {
|
||||
+ memcpy(dst, p, slen);
|
||||
+ dst += slen;
|
||||
+ p += slen;
|
||||
+ } else
|
||||
+ p = utf8_next_char(p);
|
||||
+ }
|
||||
+
|
||||
+ memcpy_safe(dst, j, len2);
|
||||
+ dst[len2] = '\0';
|
||||
|
||||
return e;
|
||||
}
|
||||
diff --git a/src/test/test-ellipsize.c b/src/test/test-ellipsize.c
|
||||
index 7317193363..8f7e17bfe9 100644
|
||||
--- a/src/test/test-ellipsize.c
|
||||
+++ b/src/test/test-ellipsize.c
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "def.h"
|
||||
+#include "escape.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
@@ -116,4 +117,44 @@ TEST(ellipsize) {
|
||||
test_ellipsize_one("shórt");
|
||||
}
|
||||
|
||||
+TEST(ellipsize_ansi) {
|
||||
+ const char *s = ANSI_HIGHLIGHT_YELLOW_UNDERLINE "yęllow"
|
||||
+ ANSI_HIGHLIGHT_GREY_UNDERLINE "grěy"
|
||||
+ ANSI_HIGHLIGHT_BLUE_UNDERLINE "blue"
|
||||
+ ANSI_NORMAL "nórmął";
|
||||
+ size_t len = strlen(s);
|
||||
+
|
||||
+ for (unsigned percent = 0; percent <= 100; percent += 15)
|
||||
+ for (ssize_t x = 21; x >= 0; x--) {
|
||||
+ _cleanup_free_ char *t = ellipsize_mem(s, len, x, percent);
|
||||
+ printf("%02zd: \"%s\"\n", x, t);
|
||||
+ assert_se(utf8_is_valid(t));
|
||||
+
|
||||
+ if (DEBUG_LOGGING) {
|
||||
+ _cleanup_free_ char *e = cescape(t);
|
||||
+ printf(" : \"%s\"\n", e);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+TEST(ellipsize_ansi_cats) {
|
||||
+ _cleanup_free_ char *e, *f, *g, *h;
|
||||
+
|
||||
+ /* Make sure we don't cut off in the middle of an ANSI escape sequence. */
|
||||
+
|
||||
+ e = ellipsize("01" ANSI_NORMAL "23", 4, 0);
|
||||
+ puts(e);
|
||||
+ assert_se(streq(e, "01" ANSI_NORMAL "23"));
|
||||
+ f = ellipsize("ab" ANSI_NORMAL "cd", 4, 90);
|
||||
+ puts(f);
|
||||
+ assert_se(streq(f, "ab" ANSI_NORMAL "cd"));
|
||||
+
|
||||
+ g = ellipsize("🐱🐱" ANSI_NORMAL "🐱🐱" ANSI_NORMAL, 5, 0);
|
||||
+ puts(g);
|
||||
+ assert_se(streq(g, "…" ANSI_NORMAL "🐱🐱" ANSI_NORMAL));
|
||||
+ h = ellipsize("🐱🐱" ANSI_NORMAL "🐱🐱" ANSI_NORMAL, 5, 90);
|
||||
+ puts(h);
|
||||
+ assert_se(streq(h, "🐱…" ANSI_NORMAL "🐱" ANSI_NORMAL));
|
||||
+}
|
||||
+
|
||||
DEFINE_TEST_MAIN(LOG_INFO);
|
@ -0,0 +1,75 @@
|
||||
From eac6ff660b32656d2a39bdc13d729e7eb0288596 Mon Sep 17 00:00:00 2001
|
||||
From: Luca Boccassi <bluca@debian.org>
|
||||
Date: Wed, 15 Feb 2023 00:44:01 +0000
|
||||
Subject: [PATCH] cryptsetup: do not assert when unsealing token without salt
|
||||
|
||||
Salt was added in v253. We are not checking whether it was actually found
|
||||
(non-zero size), so when an old tpm+pin enrollment is opened things go boom.
|
||||
For good measure, check both the buffer and the size in both places.
|
||||
|
||||
Assertion 'saltlen > 0' failed at src/shared/tpm2-util.c:2490, function tpm2_util_pbkdf2_hmac_sha256(). Aborting.
|
||||
|
||||
(cherry picked from commit 504d0acf61c8472bc93c2a927e858074873b2eaf)
|
||||
|
||||
Resolves: RHEL-38864
|
||||
---
|
||||
src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c | 3 ++-
|
||||
src/cryptsetup/cryptsetup-tpm2.c | 4 +++-
|
||||
src/shared/tpm2-util.c | 1 +
|
||||
3 files changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c b/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c
|
||||
index 630a2d8d3e..e353e947aa 100644
|
||||
--- a/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c
|
||||
+++ b/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c
|
||||
@@ -40,6 +40,7 @@ int acquire_luks2_key(
|
||||
_cleanup_(erase_and_freep) char *b64_salted_pin = NULL;
|
||||
int r;
|
||||
|
||||
+ assert(salt || salt_size == 0);
|
||||
assert(ret_decrypted_key);
|
||||
assert(ret_decrypted_key_size);
|
||||
|
||||
@@ -60,7 +61,7 @@ int acquire_luks2_key(
|
||||
if ((flags & TPM2_FLAGS_USE_PIN) && salt && !pin)
|
||||
return -ENOANO;
|
||||
|
||||
- if (pin) {
|
||||
+ if (pin && salt_size > 0) {
|
||||
uint8_t salted_pin[SHA256_DIGEST_SIZE] = {};
|
||||
CLEANUP_ERASE(salted_pin);
|
||||
r = tpm2_util_pbkdf2_hmac_sha256(pin, strlen(pin), salt, salt_size, salted_pin);
|
||||
diff --git a/src/cryptsetup/cryptsetup-tpm2.c b/src/cryptsetup/cryptsetup-tpm2.c
|
||||
index c049b8a313..036f3d3a00 100644
|
||||
--- a/src/cryptsetup/cryptsetup-tpm2.c
|
||||
+++ b/src/cryptsetup/cryptsetup-tpm2.c
|
||||
@@ -88,6 +88,8 @@ int acquire_tpm2_key(
|
||||
const void *blob;
|
||||
int r;
|
||||
|
||||
+ assert(salt || salt_size == 0);
|
||||
+
|
||||
if (!device) {
|
||||
r = tpm2_find_device_auto(&auto_device);
|
||||
if (r == -ENODEV)
|
||||
@@ -165,7 +167,7 @@ int acquire_tpm2_key(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
- if (salt) {
|
||||
+ if (salt_size > 0) {
|
||||
uint8_t salted_pin[SHA256_DIGEST_SIZE] = {};
|
||||
CLEANUP_ERASE(salted_pin);
|
||||
|
||||
diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c
|
||||
index 4e382f691e..1d2d4ddda4 100644
|
||||
--- a/src/shared/tpm2-util.c
|
||||
+++ b/src/shared/tpm2-util.c
|
||||
@@ -6041,6 +6041,7 @@ int tpm2_util_pbkdf2_hmac_sha256(const void *pass,
|
||||
*/
|
||||
static const uint8_t block_cnt[] = { 0, 0, 0, 1 };
|
||||
|
||||
+ assert (salt);
|
||||
assert (saltlen > 0);
|
||||
assert (saltlen <= (SIZE_MAX - sizeof(block_cnt)));
|
||||
assert (passlen > 0);
|
@ -0,0 +1,29 @@
|
||||
From 661e3758451dc504eeb176194293c87f238d55dd Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Fri, 17 Feb 2023 08:24:54 +0900
|
||||
Subject: [PATCH] cryptsetup: check the existence of salt by salt_size > 0
|
||||
|
||||
Follow-up for 504d0acf61c8472bc93c2a927e858074873b2eaf.
|
||||
|
||||
The function may be called with non-NULL salt and salt_size == 0.
|
||||
|
||||
(cherry picked from commit 8c2264abb9c16bc2933f95be299f15ee66c21181)
|
||||
|
||||
Related: RHEL-38864
|
||||
---
|
||||
src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c b/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c
|
||||
index e353e947aa..5230a84025 100644
|
||||
--- a/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c
|
||||
+++ b/src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c
|
||||
@@ -58,7 +58,7 @@ int acquire_luks2_key(
|
||||
return -ENOANO;
|
||||
|
||||
/* If we're using a PIN, and the luks header has a salt, it better have a pin too */
|
||||
- if ((flags & TPM2_FLAGS_USE_PIN) && salt && !pin)
|
||||
+ if ((flags & TPM2_FLAGS_USE_PIN) && salt_size > 0 && !pin)
|
||||
return -ENOANO;
|
||||
|
||||
if (pin && salt_size > 0) {
|
@ -0,0 +1,83 @@
|
||||
From 3e65e8111f7cc30ac38901dced3ed0defbd90206 Mon Sep 17 00:00:00 2001
|
||||
From: Mike Yuan <me@yhndnzj.com>
|
||||
Date: Sat, 17 Feb 2024 03:03:50 +0800
|
||||
Subject: [PATCH] core/mount: if umount(8) fails but mount disappeared, assume
|
||||
success
|
||||
|
||||
Fixes #31337
|
||||
|
||||
(cherry picked from commit 8e94bb62a5c1309c56c57e0a505aae13a2ac5f4f)
|
||||
|
||||
Resolves: RHEL-13159
|
||||
---
|
||||
src/core/mount.c | 20 ++++++++++++--------
|
||||
1 file changed, 12 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/core/mount.c b/src/core/mount.c
|
||||
index a46ac804d8..cfe3f40302 100644
|
||||
--- a/src/core/mount.c
|
||||
+++ b/src/core/mount.c
|
||||
@@ -1439,7 +1439,8 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||
|
||||
if (IN_SET(m->state, MOUNT_REMOUNTING, MOUNT_REMOUNTING_SIGKILL, MOUNT_REMOUNTING_SIGTERM))
|
||||
mount_set_reload_result(m, f);
|
||||
- else if (m->result == MOUNT_SUCCESS)
|
||||
+ else if (m->result == MOUNT_SUCCESS && !IN_SET(m->state, MOUNT_MOUNTING, MOUNT_UNMOUNTING))
|
||||
+ /* MOUNT_MOUNTING and MOUNT_UNMOUNTING states need to be patched, see below. */
|
||||
m->result = f;
|
||||
|
||||
if (m->control_command) {
|
||||
@@ -1462,11 +1463,11 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||
switch (m->state) {
|
||||
|
||||
case MOUNT_MOUNTING:
|
||||
- /* Our mount point has not appeared in mountinfo. Something went wrong. */
|
||||
+ /* Our mount point has not appeared in mountinfo. Something went wrong. */
|
||||
|
||||
if (f == MOUNT_SUCCESS) {
|
||||
- /* Either /bin/mount has an unexpected definition of success,
|
||||
- * or someone raced us and we lost. */
|
||||
+ /* Either /bin/mount has an unexpected definition of success, or someone raced us
|
||||
+ * and we lost. */
|
||||
log_unit_warning(UNIT(m), "Mount process finished, but there is no mount.");
|
||||
f = MOUNT_FAILURE_PROTOCOL;
|
||||
}
|
||||
@@ -1484,9 +1485,7 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||
break;
|
||||
|
||||
case MOUNT_UNMOUNTING:
|
||||
-
|
||||
if (f == MOUNT_SUCCESS && m->from_proc_self_mountinfo) {
|
||||
-
|
||||
/* Still a mount point? If so, let's try again. Most likely there were multiple mount points
|
||||
* stacked on top of each other. We might exceed the timeout specified by the user overall,
|
||||
* but we will stop as soon as any one umount times out. */
|
||||
@@ -1499,13 +1498,18 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||
log_unit_warning(u, "Mount still present after %u attempts to unmount, giving up.", m->n_retry_umount);
|
||||
mount_enter_mounted(m, f);
|
||||
}
|
||||
+ } else if (f == MOUNT_FAILURE_EXIT_CODE && !m->from_proc_self_mountinfo) {
|
||||
+ /* Hmm, umount process spawned by us failed, but the mount disappeared anyway?
|
||||
+ * Maybe someone else is trying to unmount at the same time. */
|
||||
+ log_unit_notice(u, "Mount disappeared even though umount process failed, continuing.");
|
||||
+ mount_enter_dead(m, MOUNT_SUCCESS);
|
||||
} else
|
||||
mount_enter_dead_or_mounted(m, f);
|
||||
|
||||
break;
|
||||
|
||||
- case MOUNT_UNMOUNTING_SIGKILL:
|
||||
case MOUNT_UNMOUNTING_SIGTERM:
|
||||
+ case MOUNT_UNMOUNTING_SIGKILL:
|
||||
mount_enter_dead_or_mounted(m, f);
|
||||
break;
|
||||
|
||||
@@ -2040,7 +2044,7 @@ static int mount_process_proc_self_mountinfo(Manager *m) {
|
||||
* then remove it because of an internal error. E.g., fuse.sshfs seems
|
||||
* to do that when the connection fails. See #17617. To handle such the
|
||||
* case, let's once set the state back to mounting. Then, the unit can
|
||||
- * correctly enter the failed state later in mount_sigchld(). */
|
||||
+ * correctly enter the failed state later in mount_sigchld_event(). */
|
||||
mount_set_state(mount, MOUNT_MOUNTING);
|
||||
break;
|
||||
|
31
0750-Drop-log-level-of-header-limits-log-message.patch
Normal file
31
0750-Drop-log-level-of-header-limits-log-message.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From 82231e1834a5936216c666e3488bccb8b82de258 Mon Sep 17 00:00:00 2001
|
||||
From: Daan De Meyer <daan.j.demeyer@gmail.com>
|
||||
Date: Mon, 24 Apr 2023 20:55:15 +0200
|
||||
Subject: [PATCH] Drop log level of header limits log message
|
||||
|
||||
Especially when using in-memory logging, these are too noisy so
|
||||
let's drop them back to debug level.
|
||||
|
||||
(cherry picked from commit afc47ee2af456d12670df862457dcc7f6b864d79)
|
||||
|
||||
Related: RHEL-33890
|
||||
---
|
||||
src/journal/journald-server.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
|
||||
index cbcf1e9d9e..56f2ea8583 100644
|
||||
--- a/src/journal/journald-server.c
|
||||
+++ b/src/journal/journald-server.c
|
||||
@@ -848,8 +848,9 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, size_t n
|
||||
if (!f)
|
||||
return;
|
||||
|
||||
- if (journal_file_rotate_suggested(f->file, s->max_file_usec, LOG_INFO)) {
|
||||
- log_info("%s: Journal header limits reached or header out-of-date, rotating.", f->file->path);
|
||||
+ if (journal_file_rotate_suggested(f->file, s->max_file_usec, LOG_DEBUG)) {
|
||||
+ log_debug("%s: Journal header limits reached or header out-of-date, rotating.",
|
||||
+ f->file->path);
|
||||
rotate = true;
|
||||
}
|
||||
}
|
136
0751-journal-do-not-rotate-unrelated-journal-files-when-f.patch
Normal file
136
0751-journal-do-not-rotate-unrelated-journal-files-when-f.patch
Normal file
@ -0,0 +1,136 @@
|
||||
From 6e5dce6e2f9cc43375eb481c2d533606d2a07e1b Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Mon, 22 Apr 2024 17:25:31 +0900
|
||||
Subject: [PATCH] journal: do not rotate unrelated journal files when full or
|
||||
corrupted
|
||||
|
||||
When we fail to add an entry to a journal file, typically when the file
|
||||
is full or corrupted, it is not necessary to rotate other journal files.
|
||||
|
||||
Not only that's unnecessary, rotating all journal files allows
|
||||
unprivileged users to wipe system or other user's journals by writing
|
||||
many journal entries to their own user journal file.
|
||||
|
||||
Let's rotate all journal files only when
|
||||
- it is really requested by a privileged user (e.g. by journalctl --rotate), or
|
||||
- the system time jumps backwards.
|
||||
And, otherwise rotate only the journal file we are currently writing.
|
||||
|
||||
(cherry picked from commit bd0ec61ae3bb7a5200b344bab46ba2d6b9406aac)
|
||||
|
||||
Resolves: RHEL-33890
|
||||
---
|
||||
src/journal/journald-server.c | 67 +++++++++++++++++++++++++----------
|
||||
1 file changed, 48 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
|
||||
index 56f2ea8583..0ff6a43e5b 100644
|
||||
--- a/src/journal/journald-server.c
|
||||
+++ b/src/journal/journald-server.c
|
||||
@@ -667,6 +667,33 @@ void server_rotate(Server *s) {
|
||||
server_process_deferred_closes(s);
|
||||
}
|
||||
|
||||
+static void server_rotate_journal(Server *s, ManagedJournalFile *f, uid_t uid) {
|
||||
+ int r;
|
||||
+
|
||||
+ assert(s);
|
||||
+ assert(f);
|
||||
+
|
||||
+ /* This is similar to server_rotate(), but rotates only specified journal file.
|
||||
+ *
|
||||
+ * 💣💣💣 This invalidate 'f', and the caller cannot reuse the passed JournalFile object. 💣💣💣 */
|
||||
+
|
||||
+ if (f == s->system_journal)
|
||||
+ (void) do_rotate(s, &s->system_journal, "system", s->seal, /* uid= */ 0);
|
||||
+ else if (f == s->runtime_journal)
|
||||
+ (void) do_rotate(s, &s->runtime_journal, "runtime", /* seal= */ false, /* uid= */ 0);
|
||||
+ else {
|
||||
+ assert(ordered_hashmap_get(s->user_journals, UID_TO_PTR(uid)) == f);
|
||||
+ r = do_rotate(s, &f, "user", s->seal, uid);
|
||||
+ if (r >= 0)
|
||||
+ ordered_hashmap_replace(s->user_journals, UID_TO_PTR(uid), f);
|
||||
+ else if (!f)
|
||||
+ /* Old file has been closed and deallocated */
|
||||
+ ordered_hashmap_remove(s->user_journals, UID_TO_PTR(uid));
|
||||
+ }
|
||||
+
|
||||
+ server_process_deferred_closes(s);
|
||||
+}
|
||||
+
|
||||
void server_sync(Server *s) {
|
||||
ManagedJournalFile *f;
|
||||
int r;
|
||||
@@ -819,7 +846,7 @@ static bool shall_try_append_again(JournalFile *f, int r) {
|
||||
}
|
||||
|
||||
static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, size_t n, int priority) {
|
||||
- bool vacuumed = false, rotate = false;
|
||||
+ bool vacuumed = false;
|
||||
struct dual_timestamp ts;
|
||||
ManagedJournalFile *f;
|
||||
int r;
|
||||
@@ -841,23 +868,25 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, size_t n
|
||||
* bisection works correctly. */
|
||||
|
||||
log_info("Time jumped backwards, rotating.");
|
||||
- rotate = true;
|
||||
- } else {
|
||||
+ server_rotate(s);
|
||||
+ server_vacuum(s, /* verbose = */ false);
|
||||
+ vacuumed = true;
|
||||
+ }
|
||||
|
||||
- f = find_journal(s, uid);
|
||||
- if (!f)
|
||||
- return;
|
||||
+ f = find_journal(s, uid);
|
||||
+ if (!f)
|
||||
+ return;
|
||||
|
||||
- if (journal_file_rotate_suggested(f->file, s->max_file_usec, LOG_DEBUG)) {
|
||||
- log_debug("%s: Journal header limits reached or header out-of-date, rotating.",
|
||||
- f->file->path);
|
||||
- rotate = true;
|
||||
+ if (journal_file_rotate_suggested(f->file, s->max_file_usec, LOG_DEBUG)) {
|
||||
+ if (vacuumed) {
|
||||
+ log_warning("Suppressing rotation, as we already rotated immediately before write attempt. Giving up.");
|
||||
+ return;
|
||||
}
|
||||
- }
|
||||
|
||||
- if (rotate) {
|
||||
- server_rotate(s);
|
||||
- server_vacuum(s, false);
|
||||
+ log_debug("%s: Journal header limits reached or header out-of-date, rotating.", f->file->path);
|
||||
+
|
||||
+ server_rotate_journal(s, TAKE_PTR(f), uid);
|
||||
+ server_vacuum(s, /* verbose = */ false);
|
||||
vacuumed = true;
|
||||
|
||||
f = find_journal(s, uid);
|
||||
@@ -883,8 +912,8 @@ static void write_to_journal(Server *s, uid_t uid, struct iovec *iovec, size_t n
|
||||
else
|
||||
log_ratelimit_full_errno(LOG_INFO, r, "Failed to write entry to %s (%zu items, %zu bytes), rotating before retrying: %m", f->file->path, n, IOVEC_TOTAL_SIZE(iovec, n));
|
||||
|
||||
- server_rotate(s);
|
||||
- server_vacuum(s, false);
|
||||
+ server_rotate_journal(s, TAKE_PTR(f), uid);
|
||||
+ server_vacuum(s, /* verbose = */ false);
|
||||
|
||||
f = find_journal(s, uid);
|
||||
if (!f)
|
||||
@@ -1211,10 +1240,10 @@ int server_flush_to_var(Server *s, bool require_flag_file) {
|
||||
|
||||
log_info("Rotating system journal.");
|
||||
|
||||
- server_rotate(s);
|
||||
- server_vacuum(s, false);
|
||||
+ server_rotate_journal(s, s->system_journal, /* uid = */ 0);
|
||||
+ server_vacuum(s, /* verbose = */ false);
|
||||
|
||||
- if (!s->system_journal) {
|
||||
+ if (!s->system_journal->file) {
|
||||
log_notice("Didn't flush runtime journal since rotation of system journal wasn't successful.");
|
||||
r = -EIO;
|
||||
goto finish;
|
@ -0,0 +1,41 @@
|
||||
From fd3e9815846aa1efe295e897faf1e57f38c6c165 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Wed, 7 Jun 2023 14:54:34 +0200
|
||||
Subject: [PATCH] man: suffix --unit with an equal sign, since it expects an
|
||||
argument
|
||||
|
||||
As per our usual syntax in the docs.
|
||||
|
||||
(cherry picked from commit e754af353c494edfdd25412fae32876a2772a5cd)
|
||||
|
||||
Related: RHEL-31070
|
||||
---
|
||||
man/journalctl.xml | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/man/journalctl.xml b/man/journalctl.xml
|
||||
index 5bf895fce4..29d06aaef8 100644
|
||||
--- a/man/journalctl.xml
|
||||
+++ b/man/journalctl.xml
|
||||
@@ -110,8 +110,8 @@
|
||||
<option>--user</option>). If neither is specified, show all messages that the user can see.
|
||||
</para>
|
||||
|
||||
- <para>The <option>--user</option> option affects how <option>--unit</option> arguments are
|
||||
- treated. See <option>--unit</option>.</para></listitem>
|
||||
+ <para>The <option>--user</option> option affects how <option>--unit=</option> arguments are
|
||||
+ treated. See <option>--unit=</option>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
@@ -285,8 +285,8 @@
|
||||
<citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
unit, all logs of children of the slice will be shown.</para>
|
||||
|
||||
- <para>With <option>--user</option>, all <option>--unit</option> arguments will be converted to match
|
||||
- user messages as if specified with <option>--user-unit</option>.</para>
|
||||
+ <para>With <option>--user</option>, all <option>--unit=</option> arguments will be converted to match
|
||||
+ user messages as if specified with <option>--user-unit=</option>.</para>
|
||||
|
||||
<para>This parameter can be specified multiple times.</para></listitem>
|
||||
</varlistentry>
|
@ -0,0 +1,57 @@
|
||||
From f69edd2042ebf1db72ad1a2c6cbfd8887231da25 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Wed, 7 Jun 2023 15:15:42 +0200
|
||||
Subject: [PATCH] =?UTF-8?q?shared:=20move=20uid-alloc-range.[ch]=20from=20?=
|
||||
=?UTF-8?q?src/shared/=20=E2=86=92=20src/basic/?=
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This way we can use it in libsystemd
|
||||
|
||||
(cherry picked from commit 8a8b4a8784f48e941b6b460b4cb963929d1d6a8d)
|
||||
|
||||
Related: RHEL-31070
|
||||
---
|
||||
src/basic/meson.build | 2 ++
|
||||
src/{shared => basic}/uid-alloc-range.c | 0
|
||||
src/{shared => basic}/uid-alloc-range.h | 0
|
||||
src/shared/meson.build | 2 --
|
||||
4 files changed, 2 insertions(+), 2 deletions(-)
|
||||
rename src/{shared => basic}/uid-alloc-range.c (100%)
|
||||
rename src/{shared => basic}/uid-alloc-range.h (100%)
|
||||
|
||||
diff --git a/src/basic/meson.build b/src/basic/meson.build
|
||||
index bfe52d5879..c0f0b07418 100644
|
||||
--- a/src/basic/meson.build
|
||||
+++ b/src/basic/meson.build
|
||||
@@ -240,6 +240,8 @@ basic_sources = files(
|
||||
'time-util.h',
|
||||
'tmpfile-util.c',
|
||||
'tmpfile-util.h',
|
||||
+ 'uid-alloc-range.c',
|
||||
+ 'uid-alloc-range.h',
|
||||
'uid-range.c',
|
||||
'uid-range.h',
|
||||
'umask-util.h',
|
||||
diff --git a/src/shared/uid-alloc-range.c b/src/basic/uid-alloc-range.c
|
||||
similarity index 100%
|
||||
rename from src/shared/uid-alloc-range.c
|
||||
rename to src/basic/uid-alloc-range.c
|
||||
diff --git a/src/shared/uid-alloc-range.h b/src/basic/uid-alloc-range.h
|
||||
similarity index 100%
|
||||
rename from src/shared/uid-alloc-range.h
|
||||
rename to src/basic/uid-alloc-range.h
|
||||
diff --git a/src/shared/meson.build b/src/shared/meson.build
|
||||
index 9e11e13934..766e4f9506 100644
|
||||
--- a/src/shared/meson.build
|
||||
+++ b/src/shared/meson.build
|
||||
@@ -311,8 +311,6 @@ shared_sources = files(
|
||||
'tpm2-util.h',
|
||||
'udev-util.c',
|
||||
'udev-util.h',
|
||||
- 'uid-alloc-range.c',
|
||||
- 'uid-alloc-range.h',
|
||||
'user-record-nss.c',
|
||||
'user-record-nss.h',
|
||||
'user-record-show.c',
|
@ -0,0 +1,66 @@
|
||||
From c499486907937a823a8a3fe003b4d8bcf232fec6 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Wed, 7 Jun 2023 15:16:50 +0200
|
||||
Subject: [PATCH] journald: move uid_for_system_journal() to uid-alloc-range.h
|
||||
|
||||
Let's move this helper call from journald specific code to src/basic/,
|
||||
so that we can use it from sd-journal.
|
||||
|
||||
While we are at it, slightly extend it to also cover container uids,
|
||||
which are also routed to the system journal now.
|
||||
|
||||
This places the call in uid-alloc-range.[ch] which contains similar
|
||||
functions that match UID ranges for specific purposes.
|
||||
|
||||
(cherry picked from commit 115d5145a257c1a27330acf9f063b5f4d910ca4d)
|
||||
|
||||
Related: RHEL-31070
|
||||
---
|
||||
src/basic/uid-alloc-range.c | 7 +++++++
|
||||
src/basic/uid-alloc-range.h | 2 ++
|
||||
src/journal/journald-server.c | 7 -------
|
||||
3 files changed, 9 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/basic/uid-alloc-range.c b/src/basic/uid-alloc-range.c
|
||||
index dcecdbe343..1b6d761a66 100644
|
||||
--- a/src/basic/uid-alloc-range.c
|
||||
+++ b/src/basic/uid-alloc-range.c
|
||||
@@ -121,3 +121,10 @@ bool gid_is_system(gid_t gid) {
|
||||
|
||||
return gid <= defs->system_gid_max;
|
||||
}
|
||||
+
|
||||
+bool uid_for_system_journal(uid_t uid) {
|
||||
+
|
||||
+ /* Returns true if the specified UID shall get its data stored in the system journal. */
|
||||
+
|
||||
+ return uid_is_system(uid) || uid_is_dynamic(uid) || uid == UID_NOBODY || uid_is_container(uid);
|
||||
+}
|
||||
diff --git a/src/basic/uid-alloc-range.h b/src/basic/uid-alloc-range.h
|
||||
index d3bf077045..5badde148a 100644
|
||||
--- a/src/basic/uid-alloc-range.h
|
||||
+++ b/src/basic/uid-alloc-range.h
|
||||
@@ -32,3 +32,5 @@ typedef struct UGIDAllocationRange {
|
||||
|
||||
int read_login_defs(UGIDAllocationRange *ret_defs, const char *path, const char *root);
|
||||
const UGIDAllocationRange *acquire_ugid_allocation_range(void);
|
||||
+
|
||||
+bool uid_for_system_journal(uid_t uid);
|
||||
diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c
|
||||
index 0ff6a43e5b..6fa182a566 100644
|
||||
--- a/src/journal/journald-server.c
|
||||
+++ b/src/journal/journald-server.c
|
||||
@@ -234,13 +234,6 @@ void server_space_usage_message(Server *s, JournalStorage *storage) {
|
||||
NULL);
|
||||
}
|
||||
|
||||
-static bool uid_for_system_journal(uid_t uid) {
|
||||
-
|
||||
- /* Returns true if the specified UID shall get its data stored in the system journal. */
|
||||
-
|
||||
- return uid_is_system(uid) || uid_is_dynamic(uid) || uid == UID_NOBODY;
|
||||
-}
|
||||
-
|
||||
static void server_add_acls(ManagedJournalFile *f, uid_t uid) {
|
||||
assert(f);
|
||||
|
@ -0,0 +1,65 @@
|
||||
From 8dfa6d7536994c1a75b5d8a2af009efa9135b395 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Wed, 7 Jun 2023 15:19:25 +0200
|
||||
Subject: [PATCH] sd-journal: when SD_JOURNAL_CURRENT_USER is set, and called
|
||||
from system UID, imply SD_JOURNAL_SYSTEM
|
||||
|
||||
Fixes: #26742 #23679
|
||||
(cherry picked from commit 97c621b72d8c5b5eb4bf7f177cd885bfc01518c9)
|
||||
|
||||
Resolves: RHEL-31070
|
||||
---
|
||||
src/libsystemd/sd-journal/sd-journal.c | 20 ++++++++++++++------
|
||||
1 file changed, 14 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/libsystemd/sd-journal/sd-journal.c b/src/libsystemd/sd-journal/sd-journal.c
|
||||
index 9ab31fbbc8..723beec0e8 100644
|
||||
--- a/src/libsystemd/sd-journal/sd-journal.c
|
||||
+++ b/src/libsystemd/sd-journal/sd-journal.c
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "syslog-util.h"
|
||||
+#include "uid-alloc-range.h"
|
||||
|
||||
#define JOURNAL_FILES_MAX 7168
|
||||
|
||||
@@ -1217,25 +1218,32 @@ static bool file_has_type_prefix(const char *prefix, const char *filename) {
|
||||
static bool file_type_wanted(int flags, const char *filename) {
|
||||
assert(filename);
|
||||
|
||||
- if (!endswith(filename, ".journal") && !endswith(filename, ".journal~"))
|
||||
+ if (!ENDSWITH_SET(filename, ".journal", ".journal~"))
|
||||
return false;
|
||||
|
||||
/* no flags set → every type is OK */
|
||||
if (!(flags & (SD_JOURNAL_SYSTEM | SD_JOURNAL_CURRENT_USER)))
|
||||
return true;
|
||||
|
||||
- if (flags & SD_JOURNAL_SYSTEM && file_has_type_prefix("system", filename))
|
||||
- return true;
|
||||
-
|
||||
- if (flags & SD_JOURNAL_CURRENT_USER) {
|
||||
+ if (FLAGS_SET(flags, SD_JOURNAL_CURRENT_USER)) {
|
||||
char prefix[5 + DECIMAL_STR_MAX(uid_t) + 1];
|
||||
|
||||
- xsprintf(prefix, "user-"UID_FMT, getuid());
|
||||
+ xsprintf(prefix, "user-" UID_FMT, getuid());
|
||||
|
||||
if (file_has_type_prefix(prefix, filename))
|
||||
return true;
|
||||
+
|
||||
+ /* If SD_JOURNAL_CURRENT_USER is specified and we are invoked under a system UID, then
|
||||
+ * automatically enable SD_JOURNAL_SYSTEM too, because journald will actually put system user
|
||||
+ * data into the system journal. */
|
||||
+
|
||||
+ if (uid_for_system_journal(getuid()))
|
||||
+ flags |= SD_JOURNAL_SYSTEM;
|
||||
}
|
||||
|
||||
+ if (FLAGS_SET(flags, SD_JOURNAL_SYSTEM) && file_has_type_prefix("system", filename))
|
||||
+ return true;
|
||||
+
|
||||
return false;
|
||||
}
|
||||
|
@ -0,0 +1,46 @@
|
||||
From 6cee9dd4b39082ec7d5afcb1f4c0b91832e294d9 Mon Sep 17 00:00:00 2001
|
||||
From: Lennart Poettering <lennart@poettering.net>
|
||||
Date: Wed, 7 Jun 2023 16:23:45 +0200
|
||||
Subject: [PATCH] man: document that journalctl --user requires
|
||||
Storage=persistent
|
||||
|
||||
Fixes: #25061
|
||||
(cherry picked from commit cad8fa471b9133f38fbd6ddb6ee143f361525e5d)
|
||||
|
||||
Related: RHEL-31070
|
||||
---
|
||||
man/journalctl.xml | 6 +++++-
|
||||
man/journald.conf.xml | 3 +++
|
||||
2 files changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/man/journalctl.xml b/man/journalctl.xml
|
||||
index 29d06aaef8..6be628caf8 100644
|
||||
--- a/man/journalctl.xml
|
||||
+++ b/man/journalctl.xml
|
||||
@@ -111,7 +111,11 @@
|
||||
</para>
|
||||
|
||||
<para>The <option>--user</option> option affects how <option>--unit=</option> arguments are
|
||||
- treated. See <option>--unit=</option>.</para></listitem>
|
||||
+ treated. See <option>--unit=</option>.</para>
|
||||
+
|
||||
+ <para>Note that <option>--user</option> only works if persistent logging is enabled, via the
|
||||
+ <varname>Storage=</varname> setting in
|
||||
+ <citerefentry><refentrytitle>journald.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
diff --git a/man/journald.conf.xml b/man/journald.conf.xml
|
||||
index 24cee4c8b2..a7c3da6653 100644
|
||||
--- a/man/journald.conf.xml
|
||||
+++ b/man/journald.conf.xml
|
||||
@@ -95,6 +95,9 @@
|
||||
<filename>/var/log/journal/</filename>, as the <filename>systemd-journald@.service</filename> service
|
||||
file by default carries <varname>LogsDirectory=</varname>. To turn that off, add a unit file drop-in
|
||||
file that sets <varname>LogsDirectory=</varname> to an empty string.</para>
|
||||
+
|
||||
+ <para>Note that per-user journal files are not supported unless persistent storage is enabled, thus
|
||||
+ making <command>journalctl --user</command> unavailable.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
35
0757-fix-prefix-of-dmesg-pstore-files.patch
Normal file
35
0757-fix-prefix-of-dmesg-pstore-files.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From ee2dd3cada129b39a2da5287f31e6d9e18a82764 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?=D0=94=D0=B0=D0=BC=D1=98=D0=B0=D0=BD=20=D0=93=D0=B5=D0=BE?=
|
||||
=?UTF-8?q?=D1=80=D0=B3=D0=B8=D0=B5=D0=B2=D1=81=D0=BA=D0=B8?=
|
||||
<gdamjan@gmail.com>
|
||||
Date: Fri, 1 Dec 2023 11:46:36 +0100
|
||||
Subject: [PATCH] fix: prefix of dmesg pstore files
|
||||
|
||||
A change in the kernel[1] renamed the prefix of the pstore files from
|
||||
`dmesg-efi-` to `dmesg-efi_pstore-`.
|
||||
|
||||
[1]
|
||||
https://git.kernel.org/linus/893c5f1de620
|
||||
|
||||
(cherry picked from commit ef87c84e812cbdca4ef160fb0536d1f1bc6a2400)
|
||||
|
||||
Resolves: RHEL-20322
|
||||
---
|
||||
src/pstore/pstore.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/pstore/pstore.c b/src/pstore/pstore.c
|
||||
index 7fff6cee62..76657da536 100644
|
||||
--- a/src/pstore/pstore.c
|
||||
+++ b/src/pstore/pstore.c
|
||||
@@ -233,7 +233,9 @@ static int process_dmesg_files(PStoreList *list) {
|
||||
if (!startswith(pe->dirent.d_name, "dmesg-"))
|
||||
continue;
|
||||
|
||||
- if ((p = startswith(pe->dirent.d_name, "dmesg-efi-"))) {
|
||||
+ /* The linux kernel changed the prefix from dmesg-efi- to dmesg-efi_pstore-
|
||||
+ * so now we have to handle both cases. */
|
||||
+ if ((p = STARTSWITH_SET(pe->dirent.d_name, "dmesg-efi-", "dmesg-efi_pstore-"))) {
|
||||
/* For the EFI backend, the 3 least significant digits of record id encodes a
|
||||
* "count" number, the next 2 least significant digits for the dmesg part
|
||||
* (chunk) number, and the remaining digits as the timestamp. See
|
2617
0758-backport-new-mkosi.patch
Normal file
2617
0758-backport-new-mkosi.patch
Normal file
File diff suppressed because it is too large
Load Diff
335
0759-test-Skip-various-tests-when-sys-is-not-mounted.patch
Normal file
335
0759-test-Skip-various-tests-when-sys-is-not-mounted.patch
Normal file
@ -0,0 +1,335 @@
|
||||
From 7b2bb541eba2795e0db1bfedd4b1fa64a6e28a55 Mon Sep 17 00:00:00 2001
|
||||
From: Daan De Meyer <daan.j.demeyer@gmail.com>
|
||||
Date: Tue, 19 Dec 2023 16:03:06 +0100
|
||||
Subject: [PATCH] test: Skip various tests when /sys is not mounted
|
||||
|
||||
When running tests in a container, /sys might not be mounted, so
|
||||
let's make sure we skip tests that depend on /sys in this case.
|
||||
|
||||
(cherry picked from commit a412a1b92ab234a57c646f6779471772b2c355ec)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/libsystemd/sd-bus/test-bus-creds.c | 2 +-
|
||||
src/libsystemd/sd-device/test-sd-device-monitor.c | 4 ++++
|
||||
src/libsystemd/sd-device/test-sd-device-thread.c | 3 +++
|
||||
src/libsystemd/sd-device/test-sd-device.c | 10 +++++++++-
|
||||
src/libsystemd/sd-login/test-login.c | 4 ++++
|
||||
src/libudev/test-udev-device-thread.c | 7 ++++++-
|
||||
src/shared/tests.c | 3 ++-
|
||||
src/test/meson.build | 4 ++--
|
||||
src/test/test-cgroup-util.c | 4 ++--
|
||||
src/test/test-cgroup.c | 4 ++--
|
||||
src/test/test-condition.c | 8 ++++----
|
||||
src/test/test-mountpoint-util.c | 8 ++++----
|
||||
src/test/test-udev-util.c | 4 ++++
|
||||
src/test/test-watch-pid.c | 2 +-
|
||||
src/udev/test-udev-event.c | 4 ++++
|
||||
15 files changed, 52 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/src/libsystemd/sd-bus/test-bus-creds.c b/src/libsystemd/sd-bus/test-bus-creds.c
|
||||
index 13801becc9..d18ce88a25 100644
|
||||
--- a/src/libsystemd/sd-bus/test-bus-creds.c
|
||||
+++ b/src/libsystemd/sd-bus/test-bus-creds.c
|
||||
@@ -12,7 +12,7 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
test_setup_logging(LOG_DEBUG);
|
||||
|
||||
- if (cg_unified() == -ENOMEDIUM)
|
||||
+ if (IN_SET(cg_unified(), -ENOMEDIUM, -ENOENT))
|
||||
return log_tests_skipped("/sys/fs/cgroup/ not available");
|
||||
|
||||
r = sd_bus_creds_new_from_pid(&creds, 0, _SD_BUS_CREDS_ALL);
|
||||
diff --git a/src/libsystemd/sd-device/test-sd-device-monitor.c b/src/libsystemd/sd-device/test-sd-device-monitor.c
|
||||
index 9e64ba01c6..a9a002b5ae 100644
|
||||
--- a/src/libsystemd/sd-device/test-sd-device-monitor.c
|
||||
+++ b/src/libsystemd/sd-device/test-sd-device-monitor.c
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "device-private.h"
|
||||
#include "device-util.h"
|
||||
#include "macro.h"
|
||||
+#include "mountpoint-util.h"
|
||||
#include "path-util.h"
|
||||
#include "stat-util.h"
|
||||
#include "string-util.h"
|
||||
@@ -302,6 +303,9 @@ int main(int argc, char *argv[]) {
|
||||
if (getuid() != 0)
|
||||
return log_tests_skipped("not root");
|
||||
|
||||
+ if (path_is_mount_point("/sys", NULL, 0) <= 0)
|
||||
+ return log_tests_skipped("/sys is not mounted");
|
||||
+
|
||||
if (path_is_read_only_fs("/sys") > 0)
|
||||
return log_tests_skipped("Running in container");
|
||||
|
||||
diff --git a/src/libsystemd/sd-device/test-sd-device-thread.c b/src/libsystemd/sd-device/test-sd-device-thread.c
|
||||
index 644f3c2aee..bf3cd5ce25 100644
|
||||
--- a/src/libsystemd/sd-device/test-sd-device-thread.c
|
||||
+++ b/src/libsystemd/sd-device/test-sd-device-thread.c
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "sd-device.h"
|
||||
|
||||
#include "device-util.h"
|
||||
+#include "tests.h"
|
||||
|
||||
#define handle_error_errno(error, msg) \
|
||||
({ \
|
||||
@@ -31,6 +32,8 @@ int main(int argc, char *argv[]) {
|
||||
int r;
|
||||
|
||||
r = sd_device_new_from_syspath(&loopback, "/sys/class/net/lo");
|
||||
+ if (r == -ENODEV)
|
||||
+ return log_tests_skipped("Loopback device not found");
|
||||
if (r < 0)
|
||||
return handle_error_errno(r, "Failed to create loopback device object");
|
||||
|
||||
diff --git a/src/libsystemd/sd-device/test-sd-device.c b/src/libsystemd/sd-device/test-sd-device.c
|
||||
index a1bcf18059..237681eab8 100644
|
||||
--- a/src/libsystemd/sd-device/test-sd-device.c
|
||||
+++ b/src/libsystemd/sd-device/test-sd-device.c
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "errno-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "hashmap.h"
|
||||
+#include "mountpoint-util.h"
|
||||
#include "nulstr-util.h"
|
||||
#include "path-util.h"
|
||||
#include "rm-rf.h"
|
||||
@@ -656,4 +657,11 @@ TEST(devname_from_devnum) {
|
||||
}
|
||||
}
|
||||
|
||||
-DEFINE_TEST_MAIN(LOG_INFO);
|
||||
+static int intro(void) {
|
||||
+ if (path_is_mount_point("/sys", NULL, 0) <= 0)
|
||||
+ return log_tests_skipped("/sys is not mounted");
|
||||
+
|
||||
+ return EXIT_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+DEFINE_TEST_MAIN_WITH_INTRO(LOG_INFO, intro);
|
||||
diff --git a/src/libsystemd/sd-login/test-login.c b/src/libsystemd/sd-login/test-login.c
|
||||
index f7cef6e304..84fcfab4a0 100644
|
||||
--- a/src/libsystemd/sd-login/test-login.c
|
||||
+++ b/src/libsystemd/sd-login/test-login.c
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "fd-util.h"
|
||||
#include "format-util.h"
|
||||
#include "log.h"
|
||||
+#include "mountpoint-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "tests.h"
|
||||
@@ -295,6 +296,9 @@ TEST(monitor) {
|
||||
}
|
||||
|
||||
static int intro(void) {
|
||||
+ if (IN_SET(cg_unified(), -ENOENT, -ENOMEDIUM))
|
||||
+ return log_tests_skipped("cgroupfs is not mounted");
|
||||
+
|
||||
log_info("/* Information printed is from the live system */");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
diff --git a/src/libudev/test-udev-device-thread.c b/src/libudev/test-udev-device-thread.c
|
||||
index c082fdca46..fdf0818863 100644
|
||||
--- a/src/libudev/test-udev-device-thread.c
|
||||
+++ b/src/libudev/test-udev-device-thread.c
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libudev.h"
|
||||
+#include "tests.h"
|
||||
|
||||
#define handle_error_errno(error, msg) \
|
||||
({ \
|
||||
@@ -29,8 +30,12 @@ int main(int argc, char *argv[]) {
|
||||
int r;
|
||||
|
||||
loopback = udev_device_new_from_syspath(NULL, "/sys/class/net/lo");
|
||||
- if (!loopback)
|
||||
+ if (!loopback) {
|
||||
+ if (errno == ENODEV)
|
||||
+ return log_tests_skipped_errno(errno, "Loopback device not found");
|
||||
+
|
||||
return handle_error_errno(errno, "Failed to create loopback device object");
|
||||
+ }
|
||||
|
||||
entry = udev_device_get_properties_list_entry(loopback);
|
||||
udev_list_entry_foreach(e, entry)
|
||||
diff --git a/src/shared/tests.c b/src/shared/tests.c
|
||||
index a65080cbf4..a4deb7b0d5 100644
|
||||
--- a/src/shared/tests.c
|
||||
+++ b/src/shared/tests.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "fd-util.h"
|
||||
#include "fs-util.h"
|
||||
#include "log.h"
|
||||
+#include "mountpoint-util.h"
|
||||
#include "namespace-util.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
@@ -285,7 +286,7 @@ static int enter_cgroup(char **ret_cgroup, bool enter_subroot) {
|
||||
log_warning_errno(r, "Couldn't allocate a scope unit for this test, proceeding without.");
|
||||
|
||||
r = cg_pid_get_path(NULL, 0, &cgroup_root);
|
||||
- if (r == -ENOMEDIUM)
|
||||
+ if (IN_SET(r, -ENOMEDIUM, -ENOENT))
|
||||
return log_warning_errno(r, "cg_pid_get_path(NULL, 0, ...) failed: %m");
|
||||
assert(r >= 0);
|
||||
|
||||
diff --git a/src/test/meson.build b/src/test/meson.build
|
||||
index 1d61dc343f..5547271ee7 100644
|
||||
--- a/src/test/meson.build
|
||||
+++ b/src/test/meson.build
|
||||
@@ -701,11 +701,11 @@ tests += [
|
||||
libsystemd_static]],
|
||||
|
||||
[files('../libsystemd/sd-device/test-sd-device-thread.c'),
|
||||
- [libsystemd],
|
||||
+ [libbasic, libshared_static, libsystemd_static],
|
||||
[threads]],
|
||||
|
||||
[files('../libudev/test-udev-device-thread.c'),
|
||||
- [libudev],
|
||||
+ [libbasic, libshared_static, libsystemd_static, libudev],
|
||||
[threads]],
|
||||
]
|
||||
|
||||
diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c
|
||||
index 7113b07a95..c6439e2fbb 100644
|
||||
--- a/src/test/test-cgroup-util.c
|
||||
+++ b/src/test/test-cgroup-util.c
|
||||
@@ -334,7 +334,7 @@ TEST(cg_tests) {
|
||||
int all, hybrid, systemd, r;
|
||||
|
||||
r = cg_unified();
|
||||
- if (r == -ENOMEDIUM) {
|
||||
+ if (IN_SET(r, -ENOENT, -ENOMEDIUM)) {
|
||||
log_tests_skipped("cgroup not mounted");
|
||||
return;
|
||||
}
|
||||
@@ -367,7 +367,7 @@ TEST(cg_get_keyed_attribute) {
|
||||
int i, r;
|
||||
|
||||
r = cg_get_keyed_attribute("cpu", "/init.scope", "no_such_file", STRV_MAKE("no_such_attr"), &val);
|
||||
- if (r == -ENOMEDIUM || ERRNO_IS_PRIVILEGE(r)) {
|
||||
+ if (IN_SET(r, -ENOMEDIUM, -ENOENT) || ERRNO_IS_PRIVILEGE(r)) {
|
||||
log_info_errno(r, "Skipping most of %s, /sys/fs/cgroup not accessible: %m", __func__);
|
||||
return;
|
||||
}
|
||||
diff --git a/src/test/test-cgroup.c b/src/test/test-cgroup.c
|
||||
index 7341e5b022..a3d286a669 100644
|
||||
--- a/src/test/test-cgroup.c
|
||||
+++ b/src/test/test-cgroup.c
|
||||
@@ -44,8 +44,8 @@ TEST(cg_create) {
|
||||
int r;
|
||||
|
||||
r = cg_unified_cached(false);
|
||||
- if (r == -ENOMEDIUM) {
|
||||
- log_tests_skipped("cgroup not mounted");
|
||||
+ if (IN_SET(r, -ENOMEDIUM, -ENOENT)) {
|
||||
+ log_tests_skipped("cgroupfs is not mounted");
|
||||
return;
|
||||
}
|
||||
assert_se(r >= 0);
|
||||
diff --git a/src/test/test-condition.c b/src/test/test-condition.c
|
||||
index 4cd23d8e21..57e7d35119 100644
|
||||
--- a/src/test/test-condition.c
|
||||
+++ b/src/test/test-condition.c
|
||||
@@ -138,8 +138,8 @@ TEST(condition_test_control_group_hierarchy) {
|
||||
int r;
|
||||
|
||||
r = cg_unified();
|
||||
- if (r == -ENOMEDIUM) {
|
||||
- log_tests_skipped("cgroup not mounted");
|
||||
+ if (IN_SET(r, -ENOMEDIUM, -ENOENT)) {
|
||||
+ log_tests_skipped("cgroupfs is not mounted");
|
||||
return;
|
||||
}
|
||||
assert_se(r >= 0);
|
||||
@@ -162,8 +162,8 @@ TEST(condition_test_control_group_controller) {
|
||||
int r;
|
||||
|
||||
r = cg_unified();
|
||||
- if (r == -ENOMEDIUM) {
|
||||
- log_tests_skipped("cgroup not mounted");
|
||||
+ if (IN_SET(r, -ENOMEDIUM, -ENOENT)) {
|
||||
+ log_tests_skipped("cgroupfs is not mounted");
|
||||
return;
|
||||
}
|
||||
assert_se(r >= 0);
|
||||
diff --git a/src/test/test-mountpoint-util.c b/src/test/test-mountpoint-util.c
|
||||
index 391e1c97ba..8555c5a7db 100644
|
||||
--- a/src/test/test-mountpoint-util.c
|
||||
+++ b/src/test/test-mountpoint-util.c
|
||||
@@ -138,10 +138,10 @@ TEST(path_is_mount_point) {
|
||||
assert_se(path_is_mount_point("/proc/1/", NULL, AT_SYMLINK_FOLLOW) == 0);
|
||||
assert_se(path_is_mount_point("/proc/1/", NULL, 0) == 0);
|
||||
|
||||
- assert_se(path_is_mount_point("/sys", NULL, AT_SYMLINK_FOLLOW) > 0);
|
||||
- assert_se(path_is_mount_point("/sys", NULL, 0) > 0);
|
||||
- assert_se(path_is_mount_point("/sys/", NULL, AT_SYMLINK_FOLLOW) > 0);
|
||||
- assert_se(path_is_mount_point("/sys/", NULL, 0) > 0);
|
||||
+ assert_se(path_is_mount_point("/dev", NULL, AT_SYMLINK_FOLLOW) > 0);
|
||||
+ assert_se(path_is_mount_point("/dev", NULL, 0) > 0);
|
||||
+ assert_se(path_is_mount_point("/dev/", NULL, AT_SYMLINK_FOLLOW) > 0);
|
||||
+ assert_se(path_is_mount_point("/dev/", NULL, 0) > 0);
|
||||
|
||||
/* we'll create a hierarchy of different kinds of dir/file/link
|
||||
* layouts:
|
||||
diff --git a/src/test/test-udev-util.c b/src/test/test-udev-util.c
|
||||
index 1db2dad4ff..ee089939fd 100644
|
||||
--- a/src/test/test-udev-util.c
|
||||
+++ b/src/test/test-udev-util.c
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "macro.h"
|
||||
+#include "mountpoint-util.h"
|
||||
#include "string-util.h"
|
||||
#include "tests.h"
|
||||
#include "udev-util.h"
|
||||
@@ -137,6 +138,9 @@ static void test_udev_resolve_subsys_kernel_one(const char *str, bool read_value
|
||||
}
|
||||
|
||||
TEST(udev_resolve_subsys_kernel) {
|
||||
+ if (path_is_mount_point("/sys", NULL, 0) <= 0)
|
||||
+ return (void) log_tests_skipped("/sys is not mounted");
|
||||
+
|
||||
test_udev_resolve_subsys_kernel_one("hoge", false, -EINVAL, NULL);
|
||||
test_udev_resolve_subsys_kernel_one("[hoge", false, -EINVAL, NULL);
|
||||
test_udev_resolve_subsys_kernel_one("[hoge/foo", false, -EINVAL, NULL);
|
||||
diff --git a/src/test/test-watch-pid.c b/src/test/test-watch-pid.c
|
||||
index 8c355c1d5f..34291fb539 100644
|
||||
--- a/src/test/test-watch-pid.c
|
||||
+++ b/src/test/test-watch-pid.c
|
||||
@@ -17,7 +17,7 @@ int main(int argc, char *argv[]) {
|
||||
if (getuid() != 0)
|
||||
return log_tests_skipped("not root");
|
||||
r = enter_cgroup_subroot(NULL);
|
||||
- if (r == -ENOMEDIUM)
|
||||
+ if (r < 0)
|
||||
return log_tests_skipped("cgroupfs not available");
|
||||
|
||||
_cleanup_free_ char *unit_dir = NULL;
|
||||
diff --git a/src/udev/test-udev-event.c b/src/udev/test-udev-event.c
|
||||
index b6b2c91b2e..92cab2f354 100644
|
||||
--- a/src/udev/test-udev-event.c
|
||||
+++ b/src/udev/test-udev-event.c
|
||||
@@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
+#include "mountpoint-util.h"
|
||||
#include "path-util.h"
|
||||
#include "signal-util.h"
|
||||
#include "strv.h"
|
||||
@@ -80,6 +81,9 @@ static void test2(void) {
|
||||
int main(int argc, char *argv[]) {
|
||||
_cleanup_free_ char *self = NULL;
|
||||
|
||||
+ if (path_is_mount_point("/sys", NULL, 0) <= 0)
|
||||
+ return log_tests_skipped("/sys is not mounted");
|
||||
+
|
||||
if (argc > 1) {
|
||||
if (streq(argv[1], "test1"))
|
||||
test1();
|
27
0760-string-util-introduce-ascii_ishex.patch
Normal file
27
0760-string-util-introduce-ascii_ishex.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From 2241ee9563bbcb8bf729547926133619d4baa0cd Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Thu, 8 Dec 2022 14:13:47 +0900
|
||||
Subject: [PATCH] string-util: introduce ascii_ishex()
|
||||
|
||||
(cherry picked from commit 0ce8870f19a839c7b09b4ef5b61c2d363050c7d9)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/fundamental/string-util-fundamental.h | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/src/fundamental/string-util-fundamental.h b/src/fundamental/string-util-fundamental.h
|
||||
index 523c612a17..c35ce5b88f 100644
|
||||
--- a/src/fundamental/string-util-fundamental.h
|
||||
+++ b/src/fundamental/string-util-fundamental.h
|
||||
@@ -110,6 +110,10 @@ static inline bool ascii_isdigit(sd_char a) {
|
||||
return a >= '0' && a <= '9';
|
||||
}
|
||||
|
||||
+static inline bool ascii_ishex(sd_char a) {
|
||||
+ return ascii_isdigit(a) || (a >= 'a' && a <= 'f') || (a >= 'A' && a <= 'F');
|
||||
+}
|
||||
+
|
||||
static inline bool ascii_isalpha(sd_char a) {
|
||||
/* A pure ASCII, locale independent version of isalpha() */
|
||||
return (a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z');
|
207
0761-sd-id128-several-cleanups.patch
Normal file
207
0761-sd-id128-several-cleanups.patch
Normal file
@ -0,0 +1,207 @@
|
||||
From 961b82ca7bd6a14fb564a63ae37c6c2af0d87d89 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Thu, 8 Dec 2022 14:20:03 +0900
|
||||
Subject: [PATCH] sd-id128: several cleanups
|
||||
|
||||
- use SD_ID128_STRING_MAX or friend,
|
||||
- use sizeof(sd_id128_t),
|
||||
- use newly introduced ascii_ishex().
|
||||
|
||||
(cherry picked from commit 28bf2de201e890193b57accbf736c7d3d82d813a)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/libsystemd/sd-id128/id128-util.c | 58 ++++++++++------------------
|
||||
src/libsystemd/sd-id128/sd-id128.c | 21 +++++-----
|
||||
2 files changed, 33 insertions(+), 46 deletions(-)
|
||||
|
||||
diff --git a/src/libsystemd/sd-id128/id128-util.c b/src/libsystemd/sd-id128/id128-util.c
|
||||
index cef340f3bc..2ec77bb9f3 100644
|
||||
--- a/src/libsystemd/sd-id128/id128-util.c
|
||||
+++ b/src/libsystemd/sd-id128/id128-util.c
|
||||
@@ -13,50 +13,35 @@
|
||||
#include "sync-util.h"
|
||||
|
||||
bool id128_is_valid(const char *s) {
|
||||
- size_t i, l;
|
||||
+ size_t l;
|
||||
|
||||
assert(s);
|
||||
|
||||
l = strlen(s);
|
||||
- if (l == 32) {
|
||||
|
||||
+ if (l == SD_ID128_STRING_MAX - 1)
|
||||
/* Plain formatted 128bit hex string */
|
||||
+ return in_charset(s, HEXDIGITS);
|
||||
|
||||
- for (i = 0; i < l; i++) {
|
||||
- char c = s[i];
|
||||
-
|
||||
- if (!ascii_isdigit(c) &&
|
||||
- !(c >= 'a' && c <= 'f') &&
|
||||
- !(c >= 'A' && c <= 'F'))
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- } else if (l == 36) {
|
||||
-
|
||||
+ if (l == SD_ID128_UUID_STRING_MAX - 1) {
|
||||
/* Formatted UUID */
|
||||
-
|
||||
- for (i = 0; i < l; i++) {
|
||||
+ for (size_t i = 0; i < l; i++) {
|
||||
char c = s[i];
|
||||
|
||||
if (IN_SET(i, 8, 13, 18, 23)) {
|
||||
if (c != '-')
|
||||
return false;
|
||||
- } else {
|
||||
- if (!ascii_isdigit(c) &&
|
||||
- !(c >= 'a' && c <= 'f') &&
|
||||
- !(c >= 'A' && c <= 'F'))
|
||||
- return false;
|
||||
- }
|
||||
+ } else if (!ascii_ishex(c))
|
||||
+ return false;
|
||||
}
|
||||
+ return true;
|
||||
+ }
|
||||
|
||||
- } else
|
||||
- return false;
|
||||
-
|
||||
- return true;
|
||||
+ return false;
|
||||
}
|
||||
|
||||
int id128_read_fd(int fd, Id128Format f, sd_id128_t *ret) {
|
||||
- char buffer[36 + 2];
|
||||
+ char buffer[SD_ID128_UUID_STRING_MAX + 1]; /* +1 is for trailing newline */
|
||||
ssize_t l;
|
||||
|
||||
assert(fd >= 0);
|
||||
@@ -80,28 +65,28 @@ int id128_read_fd(int fd, Id128Format f, sd_id128_t *ret) {
|
||||
/* Treat an "uninitialized" id file like an empty one */
|
||||
return f == ID128_PLAIN_OR_UNINIT && strneq(buffer, "uninitialized\n", l) ? -ENOMEDIUM : -EINVAL;
|
||||
|
||||
- case 33: /* plain UUID with trailing newline */
|
||||
- if (buffer[32] != '\n')
|
||||
+ case SD_ID128_STRING_MAX: /* plain UUID with trailing newline */
|
||||
+ if (buffer[SD_ID128_STRING_MAX-1] != '\n')
|
||||
return -EINVAL;
|
||||
|
||||
_fallthrough_;
|
||||
- case 32: /* plain UUID without trailing newline */
|
||||
+ case SD_ID128_STRING_MAX-1: /* plain UUID without trailing newline */
|
||||
if (f == ID128_UUID)
|
||||
return -EINVAL;
|
||||
|
||||
- buffer[32] = 0;
|
||||
+ buffer[SD_ID128_STRING_MAX-1] = 0;
|
||||
break;
|
||||
|
||||
- case 37: /* RFC UUID with trailing newline */
|
||||
- if (buffer[36] != '\n')
|
||||
+ case SD_ID128_UUID_STRING_MAX: /* RFC UUID with trailing newline */
|
||||
+ if (buffer[SD_ID128_UUID_STRING_MAX-1] != '\n')
|
||||
return -EINVAL;
|
||||
|
||||
_fallthrough_;
|
||||
- case 36: /* RFC UUID without trailing newline */
|
||||
+ case SD_ID128_UUID_STRING_MAX-1: /* RFC UUID without trailing newline */
|
||||
if (IN_SET(f, ID128_PLAIN, ID128_PLAIN_OR_UNINIT))
|
||||
return -EINVAL;
|
||||
|
||||
- buffer[36] = 0;
|
||||
+ buffer[SD_ID128_UUID_STRING_MAX-1] = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -122,7 +107,7 @@ int id128_read(const char *p, Id128Format f, sd_id128_t *ret) {
|
||||
}
|
||||
|
||||
int id128_write_fd(int fd, Id128Format f, sd_id128_t id, bool do_sync) {
|
||||
- char buffer[36 + 2];
|
||||
+ char buffer[SD_ID128_UUID_STRING_MAX + 1]; /* +1 is for trailing newline */
|
||||
size_t sz;
|
||||
int r;
|
||||
|
||||
@@ -131,14 +116,13 @@ int id128_write_fd(int fd, Id128Format f, sd_id128_t id, bool do_sync) {
|
||||
|
||||
if (f != ID128_UUID) {
|
||||
assert_se(sd_id128_to_string(id, buffer));
|
||||
- buffer[SD_ID128_STRING_MAX - 1] = '\n';
|
||||
sz = SD_ID128_STRING_MAX;
|
||||
} else {
|
||||
assert_se(sd_id128_to_uuid_string(id, buffer));
|
||||
- buffer[SD_ID128_UUID_STRING_MAX - 1] = '\n';
|
||||
sz = SD_ID128_UUID_STRING_MAX;
|
||||
}
|
||||
|
||||
+ buffer[sz - 1] = '\n';
|
||||
r = loop_write(fd, buffer, sz, false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c
|
||||
index 709c8ffb57..07a13be2b2 100644
|
||||
--- a/src/libsystemd/sd-id128/sd-id128.c
|
||||
+++ b/src/libsystemd/sd-id128/sd-id128.c
|
||||
@@ -19,14 +19,17 @@
|
||||
#include "util.h"
|
||||
|
||||
_public_ char *sd_id128_to_string(sd_id128_t id, char s[_SD_ARRAY_STATIC SD_ID128_STRING_MAX]) {
|
||||
+ size_t k = 0;
|
||||
+
|
||||
assert_return(s, NULL);
|
||||
|
||||
- for (size_t n = 0; n < 16; n++) {
|
||||
- s[n*2] = hexchar(id.bytes[n] >> 4);
|
||||
- s[n*2+1] = hexchar(id.bytes[n] & 0xF);
|
||||
+ for (size_t n = 0; n < sizeof(sd_id128_t); n++) {
|
||||
+ s[k++] = hexchar(id.bytes[n] >> 4);
|
||||
+ s[k++] = hexchar(id.bytes[n] & 0xF);
|
||||
}
|
||||
|
||||
- s[SD_ID128_STRING_MAX-1] = 0;
|
||||
+ assert(k == SD_ID128_STRING_MAX - 1);
|
||||
+ s[k] = 0;
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -38,7 +41,7 @@ _public_ char *sd_id128_to_uuid_string(sd_id128_t id, char s[_SD_ARRAY_STATIC SD
|
||||
|
||||
/* Similar to sd_id128_to_string() but formats the result as UUID instead of plain hex chars */
|
||||
|
||||
- for (size_t n = 0; n < 16; n++) {
|
||||
+ for (size_t n = 0; n < sizeof(sd_id128_t); n++) {
|
||||
|
||||
if (IN_SET(n, 4, 6, 8, 10))
|
||||
s[k++] = '-';
|
||||
@@ -53,14 +56,14 @@ _public_ char *sd_id128_to_uuid_string(sd_id128_t id, char s[_SD_ARRAY_STATIC SD
|
||||
return s;
|
||||
}
|
||||
|
||||
-_public_ int sd_id128_from_string(const char s[], sd_id128_t *ret) {
|
||||
- unsigned n, i;
|
||||
+_public_ int sd_id128_from_string(const char *s, sd_id128_t *ret) {
|
||||
+ size_t n, i;
|
||||
sd_id128_t t;
|
||||
bool is_guid = false;
|
||||
|
||||
assert_return(s, -EINVAL);
|
||||
|
||||
- for (n = 0, i = 0; n < 16;) {
|
||||
+ for (n = 0, i = 0; n < sizeof(sd_id128_t);) {
|
||||
int a, b;
|
||||
|
||||
if (s[i] == '-') {
|
||||
@@ -90,7 +93,7 @@ _public_ int sd_id128_from_string(const char s[], sd_id128_t *ret) {
|
||||
t.bytes[n++] = (a << 4) | b;
|
||||
}
|
||||
|
||||
- if (i != (is_guid ? 36 : 32))
|
||||
+ if (i != (is_guid ? SD_ID128_UUID_STRING_MAX : SD_ID128_STRING_MAX) - 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (s[i] != 0)
|
468
0762-sd-id128-make-id128_read-or-friends-return-ENOPKG-wh.patch
Normal file
468
0762-sd-id128-make-id128_read-or-friends-return-ENOPKG-wh.patch
Normal file
@ -0,0 +1,468 @@
|
||||
From 0cb518ec9b1860e553cf539304310a573494743a Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Thu, 8 Dec 2022 14:30:31 +0900
|
||||
Subject: [PATCH] sd-id128: make id128_read() or friends return -ENOPKG when
|
||||
the file contents is "uninitialized"
|
||||
|
||||
Then, this drops ID128_PLAIN_OR_UNINIT. Also, this renames
|
||||
Id128Format -> Id128FormatFlag, and make it bitfield.
|
||||
|
||||
Fixes #25634.
|
||||
|
||||
(cherry picked from commit 057bf780e9d45480fbacdd3b060dbe37b37f9693)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/boot/bootctl.c | 2 +-
|
||||
src/libsystemd/sd-id128/id128-util.c | 35 +++++++++++---------
|
||||
src/libsystemd/sd-id128/id128-util.h | 27 ++++++---------
|
||||
src/libsystemd/sd-id128/sd-id128.c | 4 +--
|
||||
src/libsystemd/sd-journal/journal-file.c | 2 +-
|
||||
src/machine-id-setup/machine-id-setup-main.c | 2 +-
|
||||
src/nspawn/nspawn.c | 6 ++--
|
||||
src/partition/repart.c | 4 +--
|
||||
src/shared/discover-image.c | 2 +-
|
||||
src/shared/machine-id-setup.c | 12 +++----
|
||||
src/shared/specifier.c | 2 +-
|
||||
src/test/test-condition.c | 2 +-
|
||||
src/test/test-fs-util.c | 2 +-
|
||||
src/test/test-id128.c | 26 +++++++--------
|
||||
14 files changed, 63 insertions(+), 65 deletions(-)
|
||||
|
||||
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
|
||||
index 00e8eda992..dc4dc0d391 100644
|
||||
--- a/src/boot/bootctl.c
|
||||
+++ b/src/boot/bootctl.c
|
||||
@@ -182,7 +182,7 @@ static int load_etc_machine_id(void) {
|
||||
int r;
|
||||
|
||||
r = sd_id128_get_machine(&arg_machine_id);
|
||||
- if (IN_SET(r, -ENOENT, -ENOMEDIUM)) /* Not set or empty */
|
||||
+ if (IN_SET(r, -ENOENT, -ENOMEDIUM, -ENOPKG)) /* Not set or empty */
|
||||
return 0;
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get machine-id: %m");
|
||||
diff --git a/src/libsystemd/sd-id128/id128-util.c b/src/libsystemd/sd-id128/id128-util.c
|
||||
index 2ec77bb9f3..9b0ad48e6b 100644
|
||||
--- a/src/libsystemd/sd-id128/id128-util.c
|
||||
+++ b/src/libsystemd/sd-id128/id128-util.c
|
||||
@@ -40,17 +40,21 @@ bool id128_is_valid(const char *s) {
|
||||
return false;
|
||||
}
|
||||
|
||||
-int id128_read_fd(int fd, Id128Format f, sd_id128_t *ret) {
|
||||
+int id128_read_fd(int fd, Id128FormatFlag f, sd_id128_t *ret) {
|
||||
char buffer[SD_ID128_UUID_STRING_MAX + 1]; /* +1 is for trailing newline */
|
||||
ssize_t l;
|
||||
|
||||
assert(fd >= 0);
|
||||
- assert(f < _ID128_FORMAT_MAX);
|
||||
|
||||
/* Reads an 128bit ID from a file, which may either be in plain format (32 hex digits), or in UUID format, both
|
||||
* optionally followed by a newline and nothing else. ID files should really be newline terminated, but if they
|
||||
* aren't that's OK too, following the rule of "Be conservative in what you send, be liberal in what you
|
||||
- * accept". */
|
||||
+ * accept".
|
||||
+ *
|
||||
+ * This returns the following:
|
||||
+ * -ENOMEDIUM: an empty string,
|
||||
+ * -ENOPKG: "uninitialized" or "uninitialized\n",
|
||||
+ * -EINVAL: other invalid strings. */
|
||||
|
||||
l = loop_read(fd, buffer, sizeof(buffer), false); /* we expect a short read of either 32/33 or 36/37 chars */
|
||||
if (l < 0)
|
||||
@@ -60,10 +64,9 @@ int id128_read_fd(int fd, Id128Format f, sd_id128_t *ret) {
|
||||
|
||||
switch (l) {
|
||||
|
||||
- case 13:
|
||||
- case 14:
|
||||
- /* Treat an "uninitialized" id file like an empty one */
|
||||
- return f == ID128_PLAIN_OR_UNINIT && strneq(buffer, "uninitialized\n", l) ? -ENOMEDIUM : -EINVAL;
|
||||
+ case STRLEN("uninitialized"):
|
||||
+ case STRLEN("uninitialized\n"):
|
||||
+ return strneq(buffer, "uninitialized\n", l) ? -ENOPKG : -EINVAL;
|
||||
|
||||
case SD_ID128_STRING_MAX: /* plain UUID with trailing newline */
|
||||
if (buffer[SD_ID128_STRING_MAX-1] != '\n')
|
||||
@@ -71,7 +74,7 @@ int id128_read_fd(int fd, Id128Format f, sd_id128_t *ret) {
|
||||
|
||||
_fallthrough_;
|
||||
case SD_ID128_STRING_MAX-1: /* plain UUID without trailing newline */
|
||||
- if (f == ID128_UUID)
|
||||
+ if (!FLAGS_SET(f, ID128_FORMAT_PLAIN))
|
||||
return -EINVAL;
|
||||
|
||||
buffer[SD_ID128_STRING_MAX-1] = 0;
|
||||
@@ -83,7 +86,7 @@ int id128_read_fd(int fd, Id128Format f, sd_id128_t *ret) {
|
||||
|
||||
_fallthrough_;
|
||||
case SD_ID128_UUID_STRING_MAX-1: /* RFC UUID without trailing newline */
|
||||
- if (IN_SET(f, ID128_PLAIN, ID128_PLAIN_OR_UNINIT))
|
||||
+ if (!FLAGS_SET(f, ID128_FORMAT_UUID))
|
||||
return -EINVAL;
|
||||
|
||||
buffer[SD_ID128_UUID_STRING_MAX-1] = 0;
|
||||
@@ -96,7 +99,7 @@ int id128_read_fd(int fd, Id128Format f, sd_id128_t *ret) {
|
||||
return sd_id128_from_string(buffer, ret);
|
||||
}
|
||||
|
||||
-int id128_read(const char *p, Id128Format f, sd_id128_t *ret) {
|
||||
+int id128_read(const char *p, Id128FormatFlag f, sd_id128_t *ret) {
|
||||
_cleanup_close_ int fd = -1;
|
||||
|
||||
fd = open(p, O_RDONLY|O_CLOEXEC|O_NOCTTY);
|
||||
@@ -106,15 +109,15 @@ int id128_read(const char *p, Id128Format f, sd_id128_t *ret) {
|
||||
return id128_read_fd(fd, f, ret);
|
||||
}
|
||||
|
||||
-int id128_write_fd(int fd, Id128Format f, sd_id128_t id, bool do_sync) {
|
||||
+int id128_write_fd(int fd, Id128FormatFlag f, sd_id128_t id, bool do_sync) {
|
||||
char buffer[SD_ID128_UUID_STRING_MAX + 1]; /* +1 is for trailing newline */
|
||||
size_t sz;
|
||||
int r;
|
||||
|
||||
assert(fd >= 0);
|
||||
- assert(f < _ID128_FORMAT_MAX);
|
||||
+ assert(IN_SET((f & ID128_FORMAT_ANY), ID128_FORMAT_PLAIN, ID128_FORMAT_UUID));
|
||||
|
||||
- if (f != ID128_UUID) {
|
||||
+ if (FLAGS_SET(f, ID128_FORMAT_PLAIN)) {
|
||||
assert_se(sd_id128_to_string(id, buffer));
|
||||
sz = SD_ID128_STRING_MAX;
|
||||
} else {
|
||||
@@ -136,7 +139,7 @@ int id128_write_fd(int fd, Id128Format f, sd_id128_t id, bool do_sync) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int id128_write(const char *p, Id128Format f, sd_id128_t id, bool do_sync) {
|
||||
+int id128_write(const char *p, Id128FormatFlag f, sd_id128_t id, bool do_sync) {
|
||||
_cleanup_close_ int fd = -1;
|
||||
|
||||
fd = open(p, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_TRUNC, 0444);
|
||||
@@ -179,9 +182,9 @@ int id128_get_product(sd_id128_t *ret) {
|
||||
/* Reads the systems product UUID from DMI or devicetree (where it is located on POWER). This is
|
||||
* particularly relevant in VM environments, where VM managers typically place a VM uuid there. */
|
||||
|
||||
- r = id128_read("/sys/class/dmi/id/product_uuid", ID128_UUID, &uuid);
|
||||
+ r = id128_read("/sys/class/dmi/id/product_uuid", ID128_FORMAT_UUID, &uuid);
|
||||
if (r == -ENOENT)
|
||||
- r = id128_read("/proc/device-tree/vm,uuid", ID128_UUID, &uuid);
|
||||
+ r = id128_read("/proc/device-tree/vm,uuid", ID128_FORMAT_UUID, &uuid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
diff --git a/src/libsystemd/sd-id128/id128-util.h b/src/libsystemd/sd-id128/id128-util.h
|
||||
index 9d8fe93641..d031c680f1 100644
|
||||
--- a/src/libsystemd/sd-id128/id128-util.h
|
||||
+++ b/src/libsystemd/sd-id128/id128-util.h
|
||||
@@ -10,22 +10,17 @@
|
||||
|
||||
bool id128_is_valid(const char *s) _pure_;
|
||||
|
||||
-typedef enum Id128Format {
|
||||
- ID128_ANY,
|
||||
- ID128_PLAIN, /* formatted as 32 hex chars as-is */
|
||||
- ID128_PLAIN_OR_UNINIT, /* formatted as 32 hex chars as-is; allow special "uninitialized"
|
||||
- * value when reading from file (id128_read() and id128_read_fd()).
|
||||
- *
|
||||
- * This format should be used when reading a machine-id file. */
|
||||
- ID128_UUID, /* formatted as 36 character uuid string */
|
||||
- _ID128_FORMAT_MAX,
|
||||
-} Id128Format;
|
||||
-
|
||||
-int id128_read_fd(int fd, Id128Format f, sd_id128_t *ret);
|
||||
-int id128_read(const char *p, Id128Format f, sd_id128_t *ret);
|
||||
-
|
||||
-int id128_write_fd(int fd, Id128Format f, sd_id128_t id, bool do_sync);
|
||||
-int id128_write(const char *p, Id128Format f, sd_id128_t id, bool do_sync);
|
||||
+typedef enum Id128FormatFlag {
|
||||
+ ID128_FORMAT_PLAIN = 1 << 0, /* formatted as 32 hex chars as-is */
|
||||
+ ID128_FORMAT_UUID = 1 << 1, /* formatted as 36 character uuid string */
|
||||
+ ID128_FORMAT_ANY = ID128_FORMAT_PLAIN | ID128_FORMAT_UUID,
|
||||
+} Id128FormatFlag;
|
||||
+
|
||||
+int id128_read_fd(int fd, Id128FormatFlag f, sd_id128_t *ret);
|
||||
+int id128_read(const char *p, Id128FormatFlag f, sd_id128_t *ret);
|
||||
+
|
||||
+int id128_write_fd(int fd, Id128FormatFlag f, sd_id128_t id, bool do_sync);
|
||||
+int id128_write(const char *p, Id128FormatFlag f, sd_id128_t id, bool do_sync);
|
||||
|
||||
void id128_hash_func(const sd_id128_t *p, struct siphash *state);
|
||||
int id128_compare_func(const sd_id128_t *a, const sd_id128_t *b) _pure_;
|
||||
diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c
|
||||
index 07a13be2b2..5e9ec2b5f6 100644
|
||||
--- a/src/libsystemd/sd-id128/sd-id128.c
|
||||
+++ b/src/libsystemd/sd-id128/sd-id128.c
|
||||
@@ -127,7 +127,7 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) {
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
if (sd_id128_is_null(saved_machine_id)) {
|
||||
- r = id128_read("/etc/machine-id", ID128_PLAIN, &saved_machine_id);
|
||||
+ r = id128_read("/etc/machine-id", ID128_FORMAT_PLAIN, &saved_machine_id);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -146,7 +146,7 @@ _public_ int sd_id128_get_boot(sd_id128_t *ret) {
|
||||
assert_return(ret, -EINVAL);
|
||||
|
||||
if (sd_id128_is_null(saved_boot_id)) {
|
||||
- r = id128_read("/proc/sys/kernel/random/boot_id", ID128_UUID, &saved_boot_id);
|
||||
+ r = id128_read("/proc/sys/kernel/random/boot_id", ID128_FORMAT_UUID, &saved_boot_id);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
diff --git a/src/libsystemd/sd-journal/journal-file.c b/src/libsystemd/sd-journal/journal-file.c
|
||||
index 3c1385ddb0..2b66b3caed 100644
|
||||
--- a/src/libsystemd/sd-journal/journal-file.c
|
||||
+++ b/src/libsystemd/sd-journal/journal-file.c
|
||||
@@ -421,7 +421,7 @@ static int journal_file_refresh_header(JournalFile *f) {
|
||||
assert(f->header);
|
||||
|
||||
r = sd_id128_get_machine(&f->header->machine_id);
|
||||
- if (IN_SET(r, -ENOENT, -ENOMEDIUM))
|
||||
+ if (IN_SET(r, -ENOENT, -ENOMEDIUM, -ENOPKG))
|
||||
/* We don't have a machine-id, let's continue without */
|
||||
zero(f->header->machine_id);
|
||||
else if (r < 0)
|
||||
diff --git a/src/machine-id-setup/machine-id-setup-main.c b/src/machine-id-setup/machine-id-setup-main.c
|
||||
index 8a3b1efb4c..b595b2ab37 100644
|
||||
--- a/src/machine-id-setup/machine-id-setup-main.c
|
||||
+++ b/src/machine-id-setup/machine-id-setup-main.c
|
||||
@@ -164,7 +164,7 @@ static int run(int argc, char *argv[]) {
|
||||
return r;
|
||||
|
||||
etc_machine_id = prefix_roota(arg_root, "/etc/machine-id");
|
||||
- r = id128_read(etc_machine_id, ID128_PLAIN, &id);
|
||||
+ r = id128_read(etc_machine_id, ID128_FORMAT_PLAIN, &id);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to read machine ID back: %m");
|
||||
} else {
|
||||
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
|
||||
index df7b37ec4e..085f817dd3 100644
|
||||
--- a/src/nspawn/nspawn.c
|
||||
+++ b/src/nspawn/nspawn.c
|
||||
@@ -2195,7 +2195,7 @@ static int setup_boot_id(void) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to generate random boot id: %m");
|
||||
|
||||
- r = id128_write(path, ID128_UUID, rnd, false);
|
||||
+ r = id128_write(path, ID128_FORMAT_UUID, rnd, false);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write boot id: %m");
|
||||
|
||||
@@ -2821,9 +2821,9 @@ static int setup_machine_id(const char *directory) {
|
||||
|
||||
etc_machine_id = prefix_roota(directory, "/etc/machine-id");
|
||||
|
||||
- r = id128_read(etc_machine_id, ID128_PLAIN_OR_UNINIT, &id);
|
||||
+ r = id128_read(etc_machine_id, ID128_FORMAT_PLAIN, &id);
|
||||
if (r < 0) {
|
||||
- if (!IN_SET(r, -ENOENT, -ENOMEDIUM)) /* If the file is missing or empty, we don't mind */
|
||||
+ if (!IN_SET(r, -ENOENT, -ENOMEDIUM, -ENOPKG)) /* If the file is missing, empty, or uninitialized, we don't mind */
|
||||
return log_error_errno(r, "Failed to read machine ID from container image: %m");
|
||||
|
||||
if (sd_id128_is_null(arg_uuid)) {
|
||||
diff --git a/src/partition/repart.c b/src/partition/repart.c
|
||||
index 2b3b384743..553d92e730 100644
|
||||
--- a/src/partition/repart.c
|
||||
+++ b/src/partition/repart.c
|
||||
@@ -4515,8 +4515,8 @@ static int context_read_seed(Context *context, const char *root) {
|
||||
else if (fd < 0)
|
||||
return log_error_errno(fd, "Failed to determine machine ID of image: %m");
|
||||
else {
|
||||
- r = id128_read_fd(fd, ID128_PLAIN_OR_UNINIT, &context->seed);
|
||||
- if (r == -ENOMEDIUM)
|
||||
+ r = id128_read_fd(fd, ID128_FORMAT_PLAIN, &context->seed);
|
||||
+ if (IN_SET(r, -ENOMEDIUM, -ENOPKG))
|
||||
log_info("No machine ID set, using randomized partition UUIDs.");
|
||||
else if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse machine ID of image: %m");
|
||||
diff --git a/src/shared/discover-image.c b/src/shared/discover-image.c
|
||||
index 0488e215fd..75a42efe88 100644
|
||||
--- a/src/shared/discover-image.c
|
||||
+++ b/src/shared/discover-image.c
|
||||
@@ -1153,7 +1153,7 @@ int image_read_metadata(Image *i) {
|
||||
if (fd < 0)
|
||||
log_debug_errno(errno, "Failed to open %s: %m", path);
|
||||
else {
|
||||
- r = id128_read_fd(fd, ID128_PLAIN, &machine_id);
|
||||
+ r = id128_read_fd(fd, ID128_FORMAT_PLAIN, &machine_id);
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Image %s contains invalid machine ID.", i->name);
|
||||
}
|
||||
diff --git a/src/shared/machine-id-setup.c b/src/shared/machine-id-setup.c
|
||||
index df4ac419cb..787c0765d0 100644
|
||||
--- a/src/shared/machine-id-setup.c
|
||||
+++ b/src/shared/machine-id-setup.c
|
||||
@@ -38,7 +38,7 @@ static int generate_machine_id(const char *root, sd_id128_t *ret) {
|
||||
dbus_machine_id = prefix_roota(root, "/var/lib/dbus/machine-id");
|
||||
fd = open(dbus_machine_id, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
|
||||
if (fd >= 0) {
|
||||
- if (id128_read_fd(fd, ID128_PLAIN, ret) >= 0) {
|
||||
+ if (id128_read_fd(fd, ID128_FORMAT_PLAIN, ret) >= 0) {
|
||||
log_info("Initializing machine ID from D-Bus machine ID.");
|
||||
return 0;
|
||||
}
|
||||
@@ -123,7 +123,7 @@ int machine_id_setup(const char *root, bool force_transient, sd_id128_t machine_
|
||||
if (sd_id128_is_null(machine_id)) {
|
||||
|
||||
/* Try to read any existing machine ID */
|
||||
- if (id128_read_fd(fd, ID128_PLAIN, ret) >= 0)
|
||||
+ if (id128_read_fd(fd, ID128_FORMAT_PLAIN, ret) >= 0)
|
||||
return 0;
|
||||
|
||||
/* Hmm, so, the id currently stored is not useful, then let's generate one */
|
||||
@@ -152,7 +152,7 @@ int machine_id_setup(const char *root, bool force_transient, sd_id128_t machine_
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to sync %s: %m", etc_machine_id);
|
||||
} else {
|
||||
- r = id128_write_fd(fd, ID128_PLAIN, machine_id, true);
|
||||
+ r = id128_write_fd(fd, ID128_FORMAT_PLAIN, machine_id, true);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write %s: %m", etc_machine_id);
|
||||
else
|
||||
@@ -168,7 +168,7 @@ int machine_id_setup(const char *root, bool force_transient, sd_id128_t machine_
|
||||
run_machine_id = prefix_roota(root, "/run/machine-id");
|
||||
|
||||
RUN_WITH_UMASK(0022)
|
||||
- r = id128_write(run_machine_id, ID128_PLAIN, machine_id, false);
|
||||
+ r = id128_write(run_machine_id, ID128_FORMAT_PLAIN, machine_id, false);
|
||||
if (r < 0) {
|
||||
(void) unlink(run_machine_id);
|
||||
return log_error_errno(r, "Cannot write %s: %m", run_machine_id);
|
||||
@@ -240,7 +240,7 @@ int machine_id_commit(const char *root) {
|
||||
"%s is not on a temporary file system.",
|
||||
etc_machine_id);
|
||||
|
||||
- r = id128_read_fd(fd, ID128_PLAIN, &id);
|
||||
+ r = id128_read_fd(fd, ID128_FORMAT_PLAIN, &id);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "We didn't find a valid machine ID in %s: %m", etc_machine_id);
|
||||
|
||||
@@ -261,7 +261,7 @@ int machine_id_commit(const char *root) {
|
||||
return r;
|
||||
|
||||
/* Update a persistent version of etc_machine_id */
|
||||
- r = id128_write(etc_machine_id, ID128_PLAIN, id, true);
|
||||
+ r = id128_write(etc_machine_id, ID128_FORMAT_PLAIN, id, true);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Cannot write %s. This is mandatory to get a persistent machine ID: %m", etc_machine_id);
|
||||
|
||||
diff --git a/src/shared/specifier.c b/src/shared/specifier.c
|
||||
index d54ab9f5a9..cd651768bd 100644
|
||||
--- a/src/shared/specifier.c
|
||||
+++ b/src/shared/specifier.c
|
||||
@@ -195,7 +195,7 @@ int specifier_machine_id(char specifier, const void *data, const char *root, con
|
||||
/* Translate error for missing os-release file to EUNATCH. */
|
||||
return fd == -ENOENT ? -EUNATCH : fd;
|
||||
|
||||
- r = id128_read_fd(fd, ID128_PLAIN, &id);
|
||||
+ r = id128_read_fd(fd, ID128_FORMAT_PLAIN, &id);
|
||||
} else
|
||||
r = sd_id128_get_machine(&id);
|
||||
if (r < 0)
|
||||
diff --git a/src/test/test-condition.c b/src/test/test-condition.c
|
||||
index 57e7d35119..b16e8047c6 100644
|
||||
--- a/src/test/test-condition.c
|
||||
+++ b/src/test/test-condition.c
|
||||
@@ -250,7 +250,7 @@ TEST(condition_test_host) {
|
||||
int r;
|
||||
|
||||
r = sd_id128_get_machine(&id);
|
||||
- if (IN_SET(r, -ENOENT, -ENOMEDIUM))
|
||||
+ if (IN_SET(r, -ENOENT, -ENOMEDIUM, -ENOPKG))
|
||||
return (void) log_tests_skipped("/etc/machine-id missing");
|
||||
assert_se(r >= 0);
|
||||
|
||||
diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c
|
||||
index 16f04d6889..0b1f11ebdf 100644
|
||||
--- a/src/test/test-fs-util.c
|
||||
+++ b/src/test/test-fs-util.c
|
||||
@@ -302,7 +302,7 @@ TEST(chase_symlinks) {
|
||||
assert_se(fd >= 0);
|
||||
safe_close(pfd);
|
||||
|
||||
- assert_se(id128_read_fd(fd, ID128_PLAIN, &a) >= 0);
|
||||
+ assert_se(id128_read_fd(fd, ID128_FORMAT_PLAIN, &a) >= 0);
|
||||
assert_se(sd_id128_get_machine(&b) >= 0);
|
||||
assert_se(sd_id128_equal(a, b));
|
||||
}
|
||||
diff --git a/src/test/test-id128.c b/src/test/test-id128.c
|
||||
index 4b71c5c00b..4175ac7b60 100644
|
||||
--- a/src/test/test-id128.c
|
||||
+++ b/src/test/test-id128.c
|
||||
@@ -86,17 +86,17 @@ TEST(id128) {
|
||||
|
||||
/* First, write as UUID */
|
||||
assert_se(sd_id128_randomize(&id) >= 0);
|
||||
- assert_se(id128_write_fd(fd, ID128_UUID, id, false) >= 0);
|
||||
+ assert_se(id128_write_fd(fd, ID128_FORMAT_UUID, id, false) >= 0);
|
||||
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
- assert_se(id128_read_fd(fd, ID128_PLAIN, &id2) == -EINVAL);
|
||||
+ assert_se(id128_read_fd(fd, ID128_FORMAT_PLAIN, &id2) == -EINVAL);
|
||||
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
- assert_se(id128_read_fd(fd, ID128_UUID, &id2) >= 0);
|
||||
+ assert_se(id128_read_fd(fd, ID128_FORMAT_UUID, &id2) >= 0);
|
||||
assert_se(sd_id128_equal(id, id2));
|
||||
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
- assert_se(id128_read_fd(fd, ID128_ANY, &id2) >= 0);
|
||||
+ assert_se(id128_read_fd(fd, ID128_FORMAT_ANY, &id2) >= 0);
|
||||
assert_se(sd_id128_equal(id, id2));
|
||||
|
||||
/* Second, write as plain */
|
||||
@@ -104,17 +104,17 @@ TEST(id128) {
|
||||
assert_se(ftruncate(fd, 0) >= 0);
|
||||
|
||||
assert_se(sd_id128_randomize(&id) >= 0);
|
||||
- assert_se(id128_write_fd(fd, ID128_PLAIN, id, false) >= 0);
|
||||
+ assert_se(id128_write_fd(fd, ID128_FORMAT_PLAIN, id, false) >= 0);
|
||||
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
- assert_se(id128_read_fd(fd, ID128_UUID, &id2) == -EINVAL);
|
||||
+ assert_se(id128_read_fd(fd, ID128_FORMAT_UUID, &id2) == -EINVAL);
|
||||
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
- assert_se(id128_read_fd(fd, ID128_PLAIN, &id2) >= 0);
|
||||
+ assert_se(id128_read_fd(fd, ID128_FORMAT_PLAIN, &id2) >= 0);
|
||||
assert_se(sd_id128_equal(id, id2));
|
||||
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
- assert_se(id128_read_fd(fd, ID128_ANY, &id2) >= 0);
|
||||
+ assert_se(id128_read_fd(fd, ID128_FORMAT_ANY, &id2) >= 0);
|
||||
assert_se(sd_id128_equal(id, id2));
|
||||
|
||||
/* Third, write plain without trailing newline */
|
||||
@@ -125,13 +125,13 @@ TEST(id128) {
|
||||
assert_se(write(fd, sd_id128_to_string(id, t), 32) == 32);
|
||||
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
- assert_se(id128_read_fd(fd, ID128_UUID, &id2) == -EINVAL);
|
||||
+ assert_se(id128_read_fd(fd, ID128_FORMAT_UUID, &id2) == -EINVAL);
|
||||
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
- assert_se(id128_read_fd(fd, ID128_PLAIN, &id2) >= 0);
|
||||
+ assert_se(id128_read_fd(fd, ID128_FORMAT_PLAIN, &id2) >= 0);
|
||||
assert_se(sd_id128_equal(id, id2));
|
||||
|
||||
- /* Third, write UUID without trailing newline */
|
||||
+ /* Fourth, write UUID without trailing newline */
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
assert_se(ftruncate(fd, 0) >= 0);
|
||||
|
||||
@@ -139,10 +139,10 @@ TEST(id128) {
|
||||
assert_se(write(fd, sd_id128_to_uuid_string(id, q), 36) == 36);
|
||||
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
- assert_se(id128_read_fd(fd, ID128_PLAIN, &id2) == -EINVAL);
|
||||
+ assert_se(id128_read_fd(fd, ID128_FORMAT_PLAIN, &id2) == -EINVAL);
|
||||
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
- assert_se(id128_read_fd(fd, ID128_UUID, &id2) >= 0);
|
||||
+ assert_se(id128_read_fd(fd, ID128_FORMAT_UUID, &id2) >= 0);
|
||||
assert_se(sd_id128_equal(id, id2));
|
||||
|
||||
if (sd_booted() > 0 && access("/etc/machine-id", F_OK) >= 0) {
|
@ -0,0 +1,49 @@
|
||||
From 845d23e9b10edfbd3ba28a81acf3871c4566c23b Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Thu, 8 Dec 2022 15:18:28 +0900
|
||||
Subject: [PATCH] test: add tests for "uninitialized" string handling by
|
||||
id128_read_fd()
|
||||
|
||||
(cherry picked from commit 66c7949e08a977a9d0c32dcfadef0bb843956b8d)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/test/test-id128.c | 25 +++++++++++++++++++++++++
|
||||
1 file changed, 25 insertions(+)
|
||||
|
||||
diff --git a/src/test/test-id128.c b/src/test/test-id128.c
|
||||
index 4175ac7b60..dccf3b7fb9 100644
|
||||
--- a/src/test/test-id128.c
|
||||
+++ b/src/test/test-id128.c
|
||||
@@ -145,6 +145,31 @@ TEST(id128) {
|
||||
assert_se(id128_read_fd(fd, ID128_FORMAT_UUID, &id2) >= 0);
|
||||
assert_se(sd_id128_equal(id, id2));
|
||||
|
||||
+ /* Fifth, tests for "uninitialized" */
|
||||
+ assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
+ assert_se(ftruncate(fd, 0) >= 0);
|
||||
+ assert_se(write(fd, "uninitialized", STRLEN("uninitialized")) == STRLEN("uninitialized"));
|
||||
+ assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
+ assert_se(id128_read_fd(fd, ID128_FORMAT_ANY, NULL) == -ENOPKG);
|
||||
+
|
||||
+ assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
+ assert_se(ftruncate(fd, 0) >= 0);
|
||||
+ assert_se(write(fd, "uninitialized\n", STRLEN("uninitialized\n")) == STRLEN("uninitialized\n"));
|
||||
+ assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
+ assert_se(id128_read_fd(fd, ID128_FORMAT_ANY, NULL) == -ENOPKG);
|
||||
+
|
||||
+ assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
+ assert_se(ftruncate(fd, 0) >= 0);
|
||||
+ assert_se(write(fd, "uninitialized\nfoo", STRLEN("uninitialized\nfoo")) == STRLEN("uninitialized\nfoo"));
|
||||
+ assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
+ assert_se(id128_read_fd(fd, ID128_FORMAT_ANY, NULL) == -EINVAL);
|
||||
+
|
||||
+ assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
+ assert_se(ftruncate(fd, 0) >= 0);
|
||||
+ assert_se(write(fd, "uninit", STRLEN("uninit")) == STRLEN("uninit"));
|
||||
+ assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
+ assert_se(id128_read_fd(fd, ID128_FORMAT_ANY, NULL) == -EINVAL);
|
||||
+
|
||||
if (sd_booted() > 0 && access("/etc/machine-id", F_OK) >= 0) {
|
||||
assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id) >= 0);
|
||||
assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id2) >= 0);
|
@ -0,0 +1,32 @@
|
||||
From 1d0f2f8d806758a70e8fc81536e0cf54649f1bf5 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Thu, 8 Dec 2022 15:43:26 +0900
|
||||
Subject: [PATCH] man: mention sd_id128_get_machine() or friend may return
|
||||
-ENOPKG
|
||||
|
||||
(cherry picked from commit a237c6e0b0b294cebc084891a84173a19eb69172)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
man/sd_id128_get_machine.xml | 8 ++++++++
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/man/sd_id128_get_machine.xml b/man/sd_id128_get_machine.xml
|
||||
index a778f8a2b0..8bc76b686b 100644
|
||||
--- a/man/sd_id128_get_machine.xml
|
||||
+++ b/man/sd_id128_get_machine.xml
|
||||
@@ -144,6 +144,14 @@
|
||||
empty or all zeros.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
+ <varlistentry>
|
||||
+ <term><constant>-ENOPKG</constant></term>
|
||||
+
|
||||
+ <listitem><para>Returned by <function>sd_id128_get_machine()</function> and
|
||||
+ <function>sd_id128_get_machine_app_specific()</function> when the content of
|
||||
+ <filename>/etc/machine-id</filename> is <literal>uninitialized</literal>.</para></listitem>
|
||||
+ </varlistentry>
|
||||
+
|
||||
<varlistentry>
|
||||
<term><constant>-ENXIO</constant></term>
|
||||
|
@ -0,0 +1,27 @@
|
||||
From 5e97c9d10934b54dfb93a4d236dd3a9c92840f26 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Thu, 8 Dec 2022 15:48:25 +0900
|
||||
Subject: [PATCH] sd-id128: make sd_id128_get_boot() and friend return
|
||||
-ENOMEDIUM
|
||||
|
||||
(cherry picked from commit 9be90c401e16cf04a9cea0b19fdefa7d0a47f056)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/libsystemd/sd-id128/sd-id128.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c
|
||||
index 5e9ec2b5f6..bff8074f19 100644
|
||||
--- a/src/libsystemd/sd-id128/sd-id128.c
|
||||
+++ b/src/libsystemd/sd-id128/sd-id128.c
|
||||
@@ -149,6 +149,9 @@ _public_ int sd_id128_get_boot(sd_id128_t *ret) {
|
||||
r = id128_read("/proc/sys/kernel/random/boot_id", ID128_FORMAT_UUID, &saved_boot_id);
|
||||
if (r < 0)
|
||||
return r;
|
||||
+
|
||||
+ if (sd_id128_is_null(saved_boot_id))
|
||||
+ return -ENOMEDIUM;
|
||||
}
|
||||
|
||||
*ret = saved_boot_id;
|
@ -0,0 +1,34 @@
|
||||
From 44d5561daff4ffa94e394e18c41001244bc170dc Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Mon, 12 Dec 2022 22:03:52 +0900
|
||||
Subject: [PATCH] sd-id128: make sd_id128_get_boot() and friend return -ENOSYS
|
||||
when /proc/ is not mounted
|
||||
|
||||
(cherry picked from commit e2720340e9fdf3aee2e8998dc72798de50be3630)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/libsystemd/sd-id128/sd-id128.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c
|
||||
index bff8074f19..b3f4728988 100644
|
||||
--- a/src/libsystemd/sd-id128/sd-id128.c
|
||||
+++ b/src/libsystemd/sd-id128/sd-id128.c
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "macro.h"
|
||||
#include "missing_syscall.h"
|
||||
#include "random-util.h"
|
||||
+#include "stat-util.h"
|
||||
#include "user-util.h"
|
||||
#include "util.h"
|
||||
|
||||
@@ -147,6 +148,8 @@ _public_ int sd_id128_get_boot(sd_id128_t *ret) {
|
||||
|
||||
if (sd_id128_is_null(saved_boot_id)) {
|
||||
r = id128_read("/proc/sys/kernel/random/boot_id", ID128_FORMAT_UUID, &saved_boot_id);
|
||||
+ if (r == -ENOENT && proc_mounted() == 0)
|
||||
+ return -ENOSYS;
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
@ -0,0 +1,63 @@
|
||||
From 66c103ed26f623a54318a6f4fa48f895fb6efab8 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Thu, 8 Dec 2022 15:49:02 +0900
|
||||
Subject: [PATCH] man: mention that sd_id128_get_boot() and friend may return
|
||||
-ENOSYS
|
||||
|
||||
And drop to mention sd_id128_get_boot_app_specific() may return -ENOENT
|
||||
or -ENOMEDIUM. The function does not read /etc/machine-id. But reads a
|
||||
file in the procfs, which is a kind of the kernel API. Hence the
|
||||
failures are caused only when the system has wrong setup.
|
||||
|
||||
(cherry picked from commit c576920e673114529c5bfe5ea29891a24a443338)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
man/sd_id128_get_machine.xml | 22 ++++++++++++++--------
|
||||
1 file changed, 14 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/man/sd_id128_get_machine.xml b/man/sd_id128_get_machine.xml
|
||||
index 8bc76b686b..dbc6d4885d 100644
|
||||
--- a/man/sd_id128_get_machine.xml
|
||||
+++ b/man/sd_id128_get_machine.xml
|
||||
@@ -129,19 +129,17 @@
|
||||
<varlistentry>
|
||||
<term><constant>-ENOENT</constant></term>
|
||||
|
||||
- <listitem><para>Returned by <function>sd_id128_get_machine()</function>,
|
||||
- <function>sd_id128_get_machine_app_specific()</function>, and
|
||||
- <function>sd_id128_get_boot_app_specific()</function> when <filename>/etc/machine-id</filename> is
|
||||
- missing.</para></listitem>
|
||||
+ <listitem><para>Returned by <function>sd_id128_get_machine()</function> and
|
||||
+ <function>sd_id128_get_machine_app_specific()</function> when <filename>/etc/machine-id</filename>
|
||||
+ is missing.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><constant>-ENOMEDIUM</constant></term>
|
||||
|
||||
- <listitem><para>Returned by <function>sd_id128_get_machine()</function>,
|
||||
- <function>sd_id128_get_machine_app_specific()</function>, and
|
||||
- <function>sd_id128_get_boot_app_specific()</function> when <filename>/etc/machine-id</filename> is
|
||||
- empty or all zeros.</para></listitem>
|
||||
+ <listitem><para>Returned by <function>sd_id128_get_machine()</function> and
|
||||
+ <function>sd_id128_get_machine_app_specific()</function> when <filename>/etc/machine-id</filename>
|
||||
+ is empty or all zeros.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
@@ -152,6 +150,14 @@
|
||||
<filename>/etc/machine-id</filename> is <literal>uninitialized</literal>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
+ <varlistentry>
|
||||
+ <term><constant>-ENOSYS</constant></term>
|
||||
+
|
||||
+ <listitem><para>Returned by <function>sd_id128_get_boot()</function> and
|
||||
+ <function>sd_id128_get_boot_app_specific()</function> when <filename>/proc/</filename> is not
|
||||
+ mounted.</para></listitem>
|
||||
+ </varlistentry>
|
||||
+
|
||||
<varlistentry>
|
||||
<term><constant>-ENXIO</constant></term>
|
||||
|
143
0768-sd-id128-fold-do_sync-flag-into-Id128FormatFlag.patch
Normal file
143
0768-sd-id128-fold-do_sync-flag-into-Id128FormatFlag.patch
Normal file
@ -0,0 +1,143 @@
|
||||
From 77085bae51bcfaaa0ef356bca93e9aa883a43a89 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Fri, 9 Dec 2022 05:37:12 +0900
|
||||
Subject: [PATCH] sd-id128: fold do_sync flag into Id128FormatFlag
|
||||
|
||||
(cherry picked from commit b40c8ebdc86b61df03207865b5a75cd37900ea4c)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/libsystemd/sd-id128/id128-util.c | 8 ++++----
|
||||
src/libsystemd/sd-id128/id128-util.h | 6 ++++--
|
||||
src/nspawn/nspawn.c | 2 +-
|
||||
src/shared/machine-id-setup.c | 6 +++---
|
||||
src/test/test-id128.c | 4 ++--
|
||||
5 files changed, 14 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/src/libsystemd/sd-id128/id128-util.c b/src/libsystemd/sd-id128/id128-util.c
|
||||
index 9b0ad48e6b..faacc55960 100644
|
||||
--- a/src/libsystemd/sd-id128/id128-util.c
|
||||
+++ b/src/libsystemd/sd-id128/id128-util.c
|
||||
@@ -109,7 +109,7 @@ int id128_read(const char *p, Id128FormatFlag f, sd_id128_t *ret) {
|
||||
return id128_read_fd(fd, f, ret);
|
||||
}
|
||||
|
||||
-int id128_write_fd(int fd, Id128FormatFlag f, sd_id128_t id, bool do_sync) {
|
||||
+int id128_write_fd(int fd, Id128FormatFlag f, sd_id128_t id) {
|
||||
char buffer[SD_ID128_UUID_STRING_MAX + 1]; /* +1 is for trailing newline */
|
||||
size_t sz;
|
||||
int r;
|
||||
@@ -130,7 +130,7 @@ int id128_write_fd(int fd, Id128FormatFlag f, sd_id128_t id, bool do_sync) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
- if (do_sync) {
|
||||
+ if (FLAGS_SET(f, ID128_SYNC_ON_WRITE)) {
|
||||
r = fsync_full(fd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -139,14 +139,14 @@ int id128_write_fd(int fd, Id128FormatFlag f, sd_id128_t id, bool do_sync) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
-int id128_write(const char *p, Id128FormatFlag f, sd_id128_t id, bool do_sync) {
|
||||
+int id128_write(const char *p, Id128FormatFlag f, sd_id128_t id) {
|
||||
_cleanup_close_ int fd = -1;
|
||||
|
||||
fd = open(p, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_TRUNC, 0444);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
- return id128_write_fd(fd, f, id, do_sync);
|
||||
+ return id128_write_fd(fd, f, id);
|
||||
}
|
||||
|
||||
void id128_hash_func(const sd_id128_t *p, struct siphash *state) {
|
||||
diff --git a/src/libsystemd/sd-id128/id128-util.h b/src/libsystemd/sd-id128/id128-util.h
|
||||
index d031c680f1..887f443d69 100644
|
||||
--- a/src/libsystemd/sd-id128/id128-util.h
|
||||
+++ b/src/libsystemd/sd-id128/id128-util.h
|
||||
@@ -14,13 +14,15 @@ typedef enum Id128FormatFlag {
|
||||
ID128_FORMAT_PLAIN = 1 << 0, /* formatted as 32 hex chars as-is */
|
||||
ID128_FORMAT_UUID = 1 << 1, /* formatted as 36 character uuid string */
|
||||
ID128_FORMAT_ANY = ID128_FORMAT_PLAIN | ID128_FORMAT_UUID,
|
||||
+
|
||||
+ ID128_SYNC_ON_WRITE = 1 << 2, /* Sync the file after write. Used only when writing an ID. */
|
||||
} Id128FormatFlag;
|
||||
|
||||
int id128_read_fd(int fd, Id128FormatFlag f, sd_id128_t *ret);
|
||||
int id128_read(const char *p, Id128FormatFlag f, sd_id128_t *ret);
|
||||
|
||||
-int id128_write_fd(int fd, Id128FormatFlag f, sd_id128_t id, bool do_sync);
|
||||
-int id128_write(const char *p, Id128FormatFlag f, sd_id128_t id, bool do_sync);
|
||||
+int id128_write_fd(int fd, Id128FormatFlag f, sd_id128_t id);
|
||||
+int id128_write(const char *p, Id128FormatFlag f, sd_id128_t id);
|
||||
|
||||
void id128_hash_func(const sd_id128_t *p, struct siphash *state);
|
||||
int id128_compare_func(const sd_id128_t *a, const sd_id128_t *b) _pure_;
|
||||
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
|
||||
index 085f817dd3..db45968cd3 100644
|
||||
--- a/src/nspawn/nspawn.c
|
||||
+++ b/src/nspawn/nspawn.c
|
||||
@@ -2195,7 +2195,7 @@ static int setup_boot_id(void) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to generate random boot id: %m");
|
||||
|
||||
- r = id128_write(path, ID128_FORMAT_UUID, rnd, false);
|
||||
+ r = id128_write(path, ID128_FORMAT_UUID, rnd);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write boot id: %m");
|
||||
|
||||
diff --git a/src/shared/machine-id-setup.c b/src/shared/machine-id-setup.c
|
||||
index 787c0765d0..f82a292ea3 100644
|
||||
--- a/src/shared/machine-id-setup.c
|
||||
+++ b/src/shared/machine-id-setup.c
|
||||
@@ -152,7 +152,7 @@ int machine_id_setup(const char *root, bool force_transient, sd_id128_t machine_
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to sync %s: %m", etc_machine_id);
|
||||
} else {
|
||||
- r = id128_write_fd(fd, ID128_FORMAT_PLAIN, machine_id, true);
|
||||
+ r = id128_write_fd(fd, ID128_FORMAT_PLAIN | ID128_SYNC_ON_WRITE, machine_id);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to write %s: %m", etc_machine_id);
|
||||
else
|
||||
@@ -168,7 +168,7 @@ int machine_id_setup(const char *root, bool force_transient, sd_id128_t machine_
|
||||
run_machine_id = prefix_roota(root, "/run/machine-id");
|
||||
|
||||
RUN_WITH_UMASK(0022)
|
||||
- r = id128_write(run_machine_id, ID128_FORMAT_PLAIN, machine_id, false);
|
||||
+ r = id128_write(run_machine_id, ID128_FORMAT_PLAIN, machine_id);
|
||||
if (r < 0) {
|
||||
(void) unlink(run_machine_id);
|
||||
return log_error_errno(r, "Cannot write %s: %m", run_machine_id);
|
||||
@@ -261,7 +261,7 @@ int machine_id_commit(const char *root) {
|
||||
return r;
|
||||
|
||||
/* Update a persistent version of etc_machine_id */
|
||||
- r = id128_write(etc_machine_id, ID128_FORMAT_PLAIN, id, true);
|
||||
+ r = id128_write(etc_machine_id, ID128_FORMAT_PLAIN | ID128_SYNC_ON_WRITE, id);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Cannot write %s. This is mandatory to get a persistent machine ID: %m", etc_machine_id);
|
||||
|
||||
diff --git a/src/test/test-id128.c b/src/test/test-id128.c
|
||||
index dccf3b7fb9..6de0cec426 100644
|
||||
--- a/src/test/test-id128.c
|
||||
+++ b/src/test/test-id128.c
|
||||
@@ -86,7 +86,7 @@ TEST(id128) {
|
||||
|
||||
/* First, write as UUID */
|
||||
assert_se(sd_id128_randomize(&id) >= 0);
|
||||
- assert_se(id128_write_fd(fd, ID128_FORMAT_UUID, id, false) >= 0);
|
||||
+ assert_se(id128_write_fd(fd, ID128_FORMAT_UUID, id) >= 0);
|
||||
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
assert_se(id128_read_fd(fd, ID128_FORMAT_PLAIN, &id2) == -EINVAL);
|
||||
@@ -104,7 +104,7 @@ TEST(id128) {
|
||||
assert_se(ftruncate(fd, 0) >= 0);
|
||||
|
||||
assert_se(sd_id128_randomize(&id) >= 0);
|
||||
- assert_se(id128_write_fd(fd, ID128_FORMAT_PLAIN, id, false) >= 0);
|
||||
+ assert_se(id128_write_fd(fd, ID128_FORMAT_PLAIN, id) >= 0);
|
||||
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
assert_se(id128_read_fd(fd, ID128_FORMAT_UUID, &id2) == -EINVAL);
|
229
0769-sd-id128-make-sd_id128_get_machine-or-friends-return.patch
Normal file
229
0769-sd-id128-make-sd_id128_get_machine-or-friends-return.patch
Normal file
@ -0,0 +1,229 @@
|
||||
From db28b72d475c4e9bbd14286c9ca9366e339dfa28 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Wed, 14 Dec 2022 14:31:09 +0900
|
||||
Subject: [PATCH] sd-id128: make sd_id128_get_machine() or friends return
|
||||
-EUCLEAN when an ID is in an invalid format
|
||||
|
||||
EINVAL suggests that the caller passes an invalid argument. EIO is
|
||||
for "input/output error", i.e. the error you'd get if the disk or
|
||||
file system is borked, and this error code could be returned by the
|
||||
underlying read/write functions.
|
||||
|
||||
Let's make the functions return an unambiguous error code.
|
||||
|
||||
(cherry picked from commit e8a6625422db9d5598b6d640a9f4eec68921ce3d)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
man/sd_id128_get_machine.xml | 2 +-
|
||||
src/libsystemd/sd-id128/id128-util.c | 16 +++++++++-------
|
||||
src/libsystemd/sd-id128/sd-id128.c | 18 ++++++++++--------
|
||||
src/test/test-id128.c | 12 ++++++------
|
||||
4 files changed, 26 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/man/sd_id128_get_machine.xml b/man/sd_id128_get_machine.xml
|
||||
index dbc6d4885d..4f6926fd7d 100644
|
||||
--- a/man/sd_id128_get_machine.xml
|
||||
+++ b/man/sd_id128_get_machine.xml
|
||||
@@ -166,7 +166,7 @@
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
- <term><constant>-EIO</constant></term>
|
||||
+ <term><constant>-EUCLEAN</constant></term>
|
||||
|
||||
<listitem><para>Returned by any of the functions described here when the configured value has
|
||||
invalid format.</para></listitem>
|
||||
diff --git a/src/libsystemd/sd-id128/id128-util.c b/src/libsystemd/sd-id128/id128-util.c
|
||||
index faacc55960..364df6a9c8 100644
|
||||
--- a/src/libsystemd/sd-id128/id128-util.c
|
||||
+++ b/src/libsystemd/sd-id128/id128-util.c
|
||||
@@ -43,6 +43,7 @@ bool id128_is_valid(const char *s) {
|
||||
int id128_read_fd(int fd, Id128FormatFlag f, sd_id128_t *ret) {
|
||||
char buffer[SD_ID128_UUID_STRING_MAX + 1]; /* +1 is for trailing newline */
|
||||
ssize_t l;
|
||||
+ int r;
|
||||
|
||||
assert(fd >= 0);
|
||||
|
||||
@@ -54,7 +55,7 @@ int id128_read_fd(int fd, Id128FormatFlag f, sd_id128_t *ret) {
|
||||
* This returns the following:
|
||||
* -ENOMEDIUM: an empty string,
|
||||
* -ENOPKG: "uninitialized" or "uninitialized\n",
|
||||
- * -EINVAL: other invalid strings. */
|
||||
+ * -EUCLEAN: other invalid strings. */
|
||||
|
||||
l = loop_read(fd, buffer, sizeof(buffer), false); /* we expect a short read of either 32/33 or 36/37 chars */
|
||||
if (l < 0)
|
||||
@@ -70,33 +71,34 @@ int id128_read_fd(int fd, Id128FormatFlag f, sd_id128_t *ret) {
|
||||
|
||||
case SD_ID128_STRING_MAX: /* plain UUID with trailing newline */
|
||||
if (buffer[SD_ID128_STRING_MAX-1] != '\n')
|
||||
- return -EINVAL;
|
||||
+ return -EUCLEAN;
|
||||
|
||||
_fallthrough_;
|
||||
case SD_ID128_STRING_MAX-1: /* plain UUID without trailing newline */
|
||||
if (!FLAGS_SET(f, ID128_FORMAT_PLAIN))
|
||||
- return -EINVAL;
|
||||
+ return -EUCLEAN;
|
||||
|
||||
buffer[SD_ID128_STRING_MAX-1] = 0;
|
||||
break;
|
||||
|
||||
case SD_ID128_UUID_STRING_MAX: /* RFC UUID with trailing newline */
|
||||
if (buffer[SD_ID128_UUID_STRING_MAX-1] != '\n')
|
||||
- return -EINVAL;
|
||||
+ return -EUCLEAN;
|
||||
|
||||
_fallthrough_;
|
||||
case SD_ID128_UUID_STRING_MAX-1: /* RFC UUID without trailing newline */
|
||||
if (!FLAGS_SET(f, ID128_FORMAT_UUID))
|
||||
- return -EINVAL;
|
||||
+ return -EUCLEAN;
|
||||
|
||||
buffer[SD_ID128_UUID_STRING_MAX-1] = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
- return -EINVAL;
|
||||
+ return -EUCLEAN;
|
||||
}
|
||||
|
||||
- return sd_id128_from_string(buffer, ret);
|
||||
+ r = sd_id128_from_string(buffer, ret);
|
||||
+ return r == -EINVAL ? -EUCLEAN : r;
|
||||
}
|
||||
|
||||
int id128_read(const char *p, Id128FormatFlag f, sd_id128_t *ret) {
|
||||
diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c
|
||||
index b3f4728988..b2f0438edf 100644
|
||||
--- a/src/libsystemd/sd-id128/sd-id128.c
|
||||
+++ b/src/libsystemd/sd-id128/sd-id128.c
|
||||
@@ -207,22 +207,22 @@ static int get_invocation_from_keyring(sd_id128_t *ret) {
|
||||
/* Chop off the final description string */
|
||||
d = strrchr(description, ';');
|
||||
if (!d)
|
||||
- return -EIO;
|
||||
+ return -EUCLEAN;
|
||||
*d = 0;
|
||||
|
||||
/* Look for the permissions */
|
||||
p = strrchr(description, ';');
|
||||
if (!p)
|
||||
- return -EIO;
|
||||
+ return -EUCLEAN;
|
||||
|
||||
errno = 0;
|
||||
perms = strtoul(p + 1, &e, 16);
|
||||
if (errno > 0)
|
||||
return -errno;
|
||||
if (e == p + 1) /* Read at least one character */
|
||||
- return -EIO;
|
||||
+ return -EUCLEAN;
|
||||
if (e != d) /* Must reached the end */
|
||||
- return -EIO;
|
||||
+ return -EUCLEAN;
|
||||
|
||||
if ((perms & ~MAX_PERMS) != 0)
|
||||
return -EPERM;
|
||||
@@ -232,7 +232,7 @@ static int get_invocation_from_keyring(sd_id128_t *ret) {
|
||||
/* Look for the group ID */
|
||||
g = strrchr(description, ';');
|
||||
if (!g)
|
||||
- return -EIO;
|
||||
+ return -EUCLEAN;
|
||||
r = parse_gid(g + 1, &gid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -243,7 +243,7 @@ static int get_invocation_from_keyring(sd_id128_t *ret) {
|
||||
/* Look for the user ID */
|
||||
u = strrchr(description, ';');
|
||||
if (!u)
|
||||
- return -EIO;
|
||||
+ return -EUCLEAN;
|
||||
r = parse_uid(u + 1, &uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -254,13 +254,14 @@ static int get_invocation_from_keyring(sd_id128_t *ret) {
|
||||
if (c < 0)
|
||||
return -errno;
|
||||
if (c != sizeof(sd_id128_t))
|
||||
- return -EIO;
|
||||
+ return -EUCLEAN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_invocation_from_environment(sd_id128_t *ret) {
|
||||
const char *e;
|
||||
+ int r;
|
||||
|
||||
assert(ret);
|
||||
|
||||
@@ -268,7 +269,8 @@ static int get_invocation_from_environment(sd_id128_t *ret) {
|
||||
if (!e)
|
||||
return -ENXIO;
|
||||
|
||||
- return sd_id128_from_string(e, ret);
|
||||
+ r = sd_id128_from_string(e, ret);
|
||||
+ return r == -EINVAL ? -EUCLEAN : r;
|
||||
}
|
||||
|
||||
_public_ int sd_id128_get_invocation(sd_id128_t *ret) {
|
||||
diff --git a/src/test/test-id128.c b/src/test/test-id128.c
|
||||
index 6de0cec426..b7a9b03403 100644
|
||||
--- a/src/test/test-id128.c
|
||||
+++ b/src/test/test-id128.c
|
||||
@@ -89,7 +89,7 @@ TEST(id128) {
|
||||
assert_se(id128_write_fd(fd, ID128_FORMAT_UUID, id) >= 0);
|
||||
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
- assert_se(id128_read_fd(fd, ID128_FORMAT_PLAIN, &id2) == -EINVAL);
|
||||
+ assert_se(id128_read_fd(fd, ID128_FORMAT_PLAIN, &id2) == -EUCLEAN);
|
||||
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
assert_se(id128_read_fd(fd, ID128_FORMAT_UUID, &id2) >= 0);
|
||||
@@ -107,7 +107,7 @@ TEST(id128) {
|
||||
assert_se(id128_write_fd(fd, ID128_FORMAT_PLAIN, id) >= 0);
|
||||
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
- assert_se(id128_read_fd(fd, ID128_FORMAT_UUID, &id2) == -EINVAL);
|
||||
+ assert_se(id128_read_fd(fd, ID128_FORMAT_UUID, &id2) == -EUCLEAN);
|
||||
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
assert_se(id128_read_fd(fd, ID128_FORMAT_PLAIN, &id2) >= 0);
|
||||
@@ -125,7 +125,7 @@ TEST(id128) {
|
||||
assert_se(write(fd, sd_id128_to_string(id, t), 32) == 32);
|
||||
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
- assert_se(id128_read_fd(fd, ID128_FORMAT_UUID, &id2) == -EINVAL);
|
||||
+ assert_se(id128_read_fd(fd, ID128_FORMAT_UUID, &id2) == -EUCLEAN);
|
||||
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
assert_se(id128_read_fd(fd, ID128_FORMAT_PLAIN, &id2) >= 0);
|
||||
@@ -139,7 +139,7 @@ TEST(id128) {
|
||||
assert_se(write(fd, sd_id128_to_uuid_string(id, q), 36) == 36);
|
||||
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
- assert_se(id128_read_fd(fd, ID128_FORMAT_PLAIN, &id2) == -EINVAL);
|
||||
+ assert_se(id128_read_fd(fd, ID128_FORMAT_PLAIN, &id2) == -EUCLEAN);
|
||||
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
assert_se(id128_read_fd(fd, ID128_FORMAT_UUID, &id2) >= 0);
|
||||
@@ -162,13 +162,13 @@ TEST(id128) {
|
||||
assert_se(ftruncate(fd, 0) >= 0);
|
||||
assert_se(write(fd, "uninitialized\nfoo", STRLEN("uninitialized\nfoo")) == STRLEN("uninitialized\nfoo"));
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
- assert_se(id128_read_fd(fd, ID128_FORMAT_ANY, NULL) == -EINVAL);
|
||||
+ assert_se(id128_read_fd(fd, ID128_FORMAT_ANY, NULL) == -EUCLEAN);
|
||||
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
assert_se(ftruncate(fd, 0) >= 0);
|
||||
assert_se(write(fd, "uninit", STRLEN("uninit")) == STRLEN("uninit"));
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
- assert_se(id128_read_fd(fd, ID128_FORMAT_ANY, NULL) == -EINVAL);
|
||||
+ assert_se(id128_read_fd(fd, ID128_FORMAT_ANY, NULL) == -EUCLEAN);
|
||||
|
||||
if (sd_booted() > 0 && access("/etc/machine-id", F_OK) >= 0) {
|
||||
assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id) >= 0);
|
@ -0,0 +1,90 @@
|
||||
From 4af87f4d0643fa243aa1fd8e5c52cc5d4fbdd187 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Wed, 14 Dec 2022 13:34:15 +0900
|
||||
Subject: [PATCH] sd-id128: allow sd_id128_get_machine() and friend to be
|
||||
called with NULL
|
||||
|
||||
It may be useful to check if the machine ID or friends is set or not.
|
||||
|
||||
(cherry picked from commit 786b652c8989834f9218ec82b2d824d5b753fad3)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/libsystemd/sd-id128/sd-id128.c | 28 ++++++++++------------------
|
||||
1 file changed, 10 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c
|
||||
index b2f0438edf..dee0df2396 100644
|
||||
--- a/src/libsystemd/sd-id128/sd-id128.c
|
||||
+++ b/src/libsystemd/sd-id128/sd-id128.c
|
||||
@@ -125,8 +125,6 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) {
|
||||
static thread_local sd_id128_t saved_machine_id = {};
|
||||
int r;
|
||||
|
||||
- assert_return(ret, -EINVAL);
|
||||
-
|
||||
if (sd_id128_is_null(saved_machine_id)) {
|
||||
r = id128_read("/etc/machine-id", ID128_FORMAT_PLAIN, &saved_machine_id);
|
||||
if (r < 0)
|
||||
@@ -136,7 +134,8 @@ _public_ int sd_id128_get_machine(sd_id128_t *ret) {
|
||||
return -ENOMEDIUM;
|
||||
}
|
||||
|
||||
- *ret = saved_machine_id;
|
||||
+ if (ret)
|
||||
+ *ret = saved_machine_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -144,8 +143,6 @@ _public_ int sd_id128_get_boot(sd_id128_t *ret) {
|
||||
static thread_local sd_id128_t saved_boot_id = {};
|
||||
int r;
|
||||
|
||||
- assert_return(ret, -EINVAL);
|
||||
-
|
||||
if (sd_id128_is_null(saved_boot_id)) {
|
||||
r = id128_read("/proc/sys/kernel/random/boot_id", ID128_FORMAT_UUID, &saved_boot_id);
|
||||
if (r == -ENOENT && proc_mounted() == 0)
|
||||
@@ -157,7 +154,8 @@ _public_ int sd_id128_get_boot(sd_id128_t *ret) {
|
||||
return -ENOMEDIUM;
|
||||
}
|
||||
|
||||
- *ret = saved_boot_id;
|
||||
+ if (ret)
|
||||
+ *ret = saved_boot_id;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -277,26 +275,20 @@ _public_ int sd_id128_get_invocation(sd_id128_t *ret) {
|
||||
static thread_local sd_id128_t saved_invocation_id = {};
|
||||
int r;
|
||||
|
||||
- assert_return(ret, -EINVAL);
|
||||
-
|
||||
if (sd_id128_is_null(saved_invocation_id)) {
|
||||
/* We first check the environment. The environment variable is primarily relevant for user
|
||||
* services, and sufficiently safe as long as no privilege boundary is involved. */
|
||||
r = get_invocation_from_environment(&saved_invocation_id);
|
||||
- if (r >= 0) {
|
||||
- *ret = saved_invocation_id;
|
||||
- return 0;
|
||||
- } else if (r != -ENXIO)
|
||||
- return r;
|
||||
-
|
||||
- /* The kernel keyring is relevant for system services (as for user services we don't store
|
||||
- * the invocation ID in the keyring, as there'd be no trust benefit in that). */
|
||||
- r = get_invocation_from_keyring(&saved_invocation_id);
|
||||
+ if (r == -ENXIO)
|
||||
+ /* The kernel keyring is relevant for system services (as for user services we don't
|
||||
+ * store the invocation ID in the keyring, as there'd be no trust benefit in that). */
|
||||
+ r = get_invocation_from_keyring(&saved_invocation_id);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
- *ret = saved_invocation_id;
|
||||
+ if (ret)
|
||||
+ *ret = saved_invocation_id;
|
||||
return 0;
|
||||
}
|
||||
|
41
0771-sd-id128-also-refuse-an-empty-invocation-ID.patch
Normal file
41
0771-sd-id128-also-refuse-an-empty-invocation-ID.patch
Normal file
@ -0,0 +1,41 @@
|
||||
From e9054375028335ef1e2946b80d9765f8e69cbb9c Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Wed, 14 Dec 2022 13:40:42 +0900
|
||||
Subject: [PATCH] sd-id128: also refuse an empty invocation ID
|
||||
|
||||
(cherry picked from commit 75fa1f25c08a4b5dc2180893718473be9e4f6bab)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
man/sd_id128_get_machine.xml | 3 ++-
|
||||
src/libsystemd/sd-id128/sd-id128.c | 3 +++
|
||||
2 files changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/man/sd_id128_get_machine.xml b/man/sd_id128_get_machine.xml
|
||||
index 4f6926fd7d..075caffb2b 100644
|
||||
--- a/man/sd_id128_get_machine.xml
|
||||
+++ b/man/sd_id128_get_machine.xml
|
||||
@@ -139,7 +139,8 @@
|
||||
|
||||
<listitem><para>Returned by <function>sd_id128_get_machine()</function> and
|
||||
<function>sd_id128_get_machine_app_specific()</function> when <filename>/etc/machine-id</filename>
|
||||
- is empty or all zeros.</para></listitem>
|
||||
+ is empty or all zeros. Also returned by <function>sd_id128_get_invocation()</function> when the
|
||||
+ invocation ID is all zeros.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
diff --git a/src/libsystemd/sd-id128/sd-id128.c b/src/libsystemd/sd-id128/sd-id128.c
|
||||
index dee0df2396..ec53617fce 100644
|
||||
--- a/src/libsystemd/sd-id128/sd-id128.c
|
||||
+++ b/src/libsystemd/sd-id128/sd-id128.c
|
||||
@@ -285,6 +285,9 @@ _public_ int sd_id128_get_invocation(sd_id128_t *ret) {
|
||||
r = get_invocation_from_keyring(&saved_invocation_id);
|
||||
if (r < 0)
|
||||
return r;
|
||||
+
|
||||
+ if (sd_id128_is_null(saved_invocation_id))
|
||||
+ return -ENOMEDIUM;
|
||||
}
|
||||
|
||||
if (ret)
|
41
0772-man-update-documents-for-sd_id128_get_invocation.patch
Normal file
41
0772-man-update-documents-for-sd_id128_get_invocation.patch
Normal file
@ -0,0 +1,41 @@
|
||||
From 6715fc716fc843c3877160a8220af935c159e789 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Wed, 14 Dec 2022 14:29:25 +0900
|
||||
Subject: [PATCH] man: update documents for sd_id128_get_invocation()
|
||||
|
||||
(cherry picked from commit f0d8358c245b4d0012d8db52dbf42bdebbe1b2bc)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
man/sd_id128_get_machine.xml | 18 ++++++++++++++----
|
||||
1 file changed, 14 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/man/sd_id128_get_machine.xml b/man/sd_id128_get_machine.xml
|
||||
index 075caffb2b..cdab87ab63 100644
|
||||
--- a/man/sd_id128_get_machine.xml
|
||||
+++ b/man/sd_id128_get_machine.xml
|
||||
@@ -94,10 +94,20 @@
|
||||
has properties similar to the machine ID during that time.</para>
|
||||
|
||||
<para><function>sd_id128_get_invocation()</function> returns the invocation ID of the currently executed
|
||||
- service. In its current implementation, this reads and parses the <varname>$INVOCATION_ID</varname> environment
|
||||
- variable that the service manager sets when activating a service, see
|
||||
- <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for details. The
|
||||
- ID is cached internally. In future a different mechanism to determine the invocation ID may be added.</para>
|
||||
+ service. In its current implementation, this tries to read and parse the following:
|
||||
+ <itemizedlist>
|
||||
+ <listitem>
|
||||
+ <para>The <varname>$INVOCATION_ID</varname> environment variable that the service manager sets when
|
||||
+ activating a service.</para>
|
||||
+ </listitem>
|
||||
+ <listitem>
|
||||
+ <para>An entry in the kernel keyring that the system service manager sets when activating a service.
|
||||
+ </para>
|
||||
+ </listitem>
|
||||
+ </itemizedlist>
|
||||
+ See <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
+ for details. The ID is cached internally. In future a different mechanism to determine the invocation ID
|
||||
+ may be added.</para>
|
||||
|
||||
<para>Note that <function>sd_id128_get_machine_app_specific()</function>,
|
||||
<function>sd_id128_get_boot()</function>, <function>sd_id128_get_boot_app_specific()</function>, and
|
48
0773-test-id128-simplify-machine-id-check.patch
Normal file
48
0773-test-id128-simplify-machine-id-check.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From b54eb7dbdad4135fdcf846f6087ca29b6164b60b Mon Sep 17 00:00:00 2001
|
||||
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||
Date: Tue, 27 Feb 2024 16:03:10 +0100
|
||||
Subject: [PATCH] test-id128: simplify machine-id check
|
||||
|
||||
This also ensures that the test is skipped when /etc/machine-id exists,
|
||||
but is not initialized.
|
||||
|
||||
(cherry picked from commit 415eb50570744daf2257fc6fc96e2d5750532785)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/test/test-id128.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/test/test-id128.c b/src/test/test-id128.c
|
||||
index b7a9b03403..afdbf1e4b9 100644
|
||||
--- a/src/test/test-id128.c
|
||||
+++ b/src/test/test-id128.c
|
||||
@@ -38,7 +38,7 @@ TEST(id128) {
|
||||
assert_se(!sd_id128_in_set(id, ID128_WALDI));
|
||||
assert_se(!sd_id128_in_set(id, ID128_WALDI, ID128_WALDI));
|
||||
|
||||
- if (sd_booted() > 0 && access("/etc/machine-id", F_OK) >= 0) {
|
||||
+ if (sd_booted() > 0 && sd_id128_get_machine(NULL) >= 0) {
|
||||
assert_se(sd_id128_get_machine(&id) == 0);
|
||||
printf("machine: %s\n", sd_id128_to_string(id, t));
|
||||
|
||||
@@ -170,7 +170,7 @@ TEST(id128) {
|
||||
assert_se(lseek(fd, 0, SEEK_SET) == 0);
|
||||
assert_se(id128_read_fd(fd, ID128_FORMAT_ANY, NULL) == -EUCLEAN);
|
||||
|
||||
- if (sd_booted() > 0 && access("/etc/machine-id", F_OK) >= 0) {
|
||||
+ if (sd_booted() > 0 && sd_id128_get_machine(NULL) >= 0) {
|
||||
assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id) >= 0);
|
||||
assert_se(sd_id128_get_machine_app_specific(SD_ID128_MAKE(f0,3d,aa,eb,1c,33,4b,43,a7,32,17,29,44,bf,77,2e), &id2) >= 0);
|
||||
assert_se(sd_id128_equal(id, id2));
|
||||
@@ -195,8 +195,8 @@ TEST(benchmark_sd_id128_get_machine_app_specific) {
|
||||
unsigned iterations = slow_tests_enabled() ? 1000000 : 1000;
|
||||
usec_t t, q;
|
||||
|
||||
- if (access("/etc/machine-id", F_OK) < 0 && errno == ENOENT)
|
||||
- return (void) log_tests_skipped("/etc/machine-id does not exist");
|
||||
+ if (sd_id128_get_machine(NULL) < 0)
|
||||
+ return (void) log_tests_skipped("/etc/machine-id is not initialized");
|
||||
|
||||
log_info("/* %s (%u iterations) */", __func__, iterations);
|
||||
|
@ -0,0 +1,30 @@
|
||||
From 70754f42db910937021c74f85adba277c7db88a9 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Rosbrook <nick.rosbrook@canonical.com>
|
||||
Date: Mon, 12 Dec 2022 14:37:52 -0500
|
||||
Subject: [PATCH] test-fs-util: skip part of test_chase_symlinks if machine-id
|
||||
is not initialized
|
||||
|
||||
The part of test_chase_symlink in test-fs-util that calls
|
||||
sd_id128_get_machine will fail if /etc/machine-id is empty, so skip this
|
||||
block if the machine-id is not initialized.
|
||||
|
||||
(cherry picked from commit 079fcdd04f57bfb1e333fea853e050c99eb16e02)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/test/test-fs-util.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c
|
||||
index 0b1f11ebdf..ff248c1a9c 100644
|
||||
--- a/src/test/test-fs-util.c
|
||||
+++ b/src/test/test-fs-util.c
|
||||
@@ -292,7 +292,7 @@ TEST(chase_symlinks) {
|
||||
assert_se(symlink("/usr/../etc/./machine-id", p) >= 0);
|
||||
|
||||
r = chase_symlinks(p, NULL, 0, NULL, &pfd);
|
||||
- if (r != -ENOENT) {
|
||||
+ if (r != -ENOENT && sd_id128_get_machine(NULL) >= 0) {
|
||||
_cleanup_close_ int fd = -1;
|
||||
sd_id128_t a, b;
|
||||
|
34
0775-test-unit-name-simplify-machine-id-check.patch
Normal file
34
0775-test-unit-name-simplify-machine-id-check.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From 1358081487650f718ad84b26313bcc16a3093e04 Mon Sep 17 00:00:00 2001
|
||||
From: Nick Rosbrook <nick.rosbrook@canonical.com>
|
||||
Date: Tue, 13 Dec 2022 12:22:37 -0500
|
||||
Subject: [PATCH] test-unit-name: simplify machine-id check
|
||||
|
||||
(cherry picked from commit a635b6279cf35abad3abe169780ec899df9396df)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/test/test-unit-name.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c
|
||||
index eec4831b4e..1e230ba5f9 100644
|
||||
--- a/src/test/test-unit-name.c
|
||||
+++ b/src/test/test-unit-name.c
|
||||
@@ -3,6 +3,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
+#include "sd-id128.h"
|
||||
+
|
||||
#include "alloc-util.h"
|
||||
#include "all-units.h"
|
||||
#include "glob-util.h"
|
||||
@@ -264,7 +266,7 @@ TEST_RET(unit_printf, .sd_booted = true) {
|
||||
assert_se(short_hostname);
|
||||
assert_se(specifier_pretty_hostname('q', NULL, NULL, NULL, &pretty_hostname) == 0);
|
||||
assert_se(pretty_hostname);
|
||||
- if (access("/etc/machine-id", F_OK) >= 0) {
|
||||
+ if (sd_id128_get_machine(NULL) >= 0) {
|
||||
assert_se(specifier_machine_id('m', NULL, NULL, NULL, &machine_id) >= 0);
|
||||
assert_se(machine_id);
|
||||
}
|
34
0776-test-load-fragment-simplify-machine-id-check.patch
Normal file
34
0776-test-load-fragment-simplify-machine-id-check.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From 5447ec5233b3079075dfac92ae3decf38f845e0e Mon Sep 17 00:00:00 2001
|
||||
From: Nick Rosbrook <nick.rosbrook@canonical.com>
|
||||
Date: Tue, 13 Dec 2022 12:25:35 -0500
|
||||
Subject: [PATCH] test-load-fragment: simplify machine-id check
|
||||
|
||||
(cherry picked from commit 2c6b738badf1404b3ceb7e322eeeb736b57f6162)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/test/test-load-fragment.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/test/test-load-fragment.c b/src/test/test-load-fragment.c
|
||||
index 3cf704134c..997c2b2524 100644
|
||||
--- a/src/test/test-load-fragment.c
|
||||
+++ b/src/test/test-load-fragment.c
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
+#include "sd-id128.h"
|
||||
+
|
||||
#include "all-units.h"
|
||||
#include "alloc-util.h"
|
||||
#include "capability-util.h"
|
||||
@@ -518,7 +520,7 @@ TEST(install_printf, .sd_booted = true) {
|
||||
|
||||
_cleanup_free_ char *mid = NULL, *bid = NULL, *host = NULL, *gid = NULL, *group = NULL, *uid = NULL, *user = NULL;
|
||||
|
||||
- if (access("/etc/machine-id", F_OK) >= 0)
|
||||
+ if (sd_id128_get_machine(NULL) >= 0)
|
||||
assert_se(specifier_machine_id('m', NULL, NULL, NULL, &mid) >= 0 && mid);
|
||||
if (sd_booted() > 0)
|
||||
assert_se(specifier_boot_id('b', NULL, NULL, NULL, &bid) >= 0 && bid);
|
@ -0,0 +1,75 @@
|
||||
From 528e1178026b3f567139c994ce89992379618d2e Mon Sep 17 00:00:00 2001
|
||||
From: Nick Rosbrook <nick.rosbrook@canonical.com>
|
||||
Date: Wed, 14 Dec 2022 10:07:40 -0500
|
||||
Subject: [PATCH] journal: skip part of test-journal-interleaving if no
|
||||
machine-id exists
|
||||
|
||||
When executed on a systemd with an empty /etc/machine-id,
|
||||
test-journal-interleaving fails in test_sequence_numbers_one() when
|
||||
re-opening the existing "two.journal". This is because opening the
|
||||
existing journal file with managed_journal_file_open() causes
|
||||
journal_file_verify_header() to be called. This function tries to
|
||||
compare the current machine-id to the machine-id in the journal file
|
||||
header, but does not handle the case where the machine-id is empty or
|
||||
non-existent.
|
||||
|
||||
Check if we have an initialized machine-id before executing this portion
|
||||
of the test.
|
||||
|
||||
(cherry picked from commit 3a9ca230363e6d1063a789492005d744723f5eed)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/journal/test-journal-interleaving.c | 27 +++++++++++++++----------
|
||||
1 file changed, 16 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/journal/test-journal-interleaving.c b/src/journal/test-journal-interleaving.c
|
||||
index fb38cc7e82..e05eae034b 100644
|
||||
--- a/src/journal/test-journal-interleaving.c
|
||||
+++ b/src/journal/test-journal-interleaving.c
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
+#include "sd-id128.h"
|
||||
#include "sd-journal.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
@@ -263,22 +264,26 @@ static void test_sequence_numbers_one(void) {
|
||||
|
||||
test_close(one);
|
||||
|
||||
- /* restart server */
|
||||
- seqnum = 0;
|
||||
+ /* If the machine-id is not initialized, the header file verification
|
||||
+ * (which happens when re-opening a journal file) will fail. */
|
||||
+ if (sd_id128_get_machine(NULL) >= 0) {
|
||||
+ /* restart server */
|
||||
+ seqnum = 0;
|
||||
|
||||
- assert_se(managed_journal_file_open(-1, "two.journal", O_RDWR, JOURNAL_COMPRESS, 0,
|
||||
- UINT64_MAX, NULL, m, NULL, NULL, &two) == 0);
|
||||
+ assert_se(managed_journal_file_open(-1, "two.journal", O_RDWR, JOURNAL_COMPRESS, 0,
|
||||
+ UINT64_MAX, NULL, m, NULL, NULL, &two) == 0);
|
||||
|
||||
- assert_se(sd_id128_equal(two->file->header->seqnum_id, seqnum_id));
|
||||
+ assert_se(sd_id128_equal(two->file->header->seqnum_id, seqnum_id));
|
||||
|
||||
- append_number(two, 7, &seqnum);
|
||||
- printf("seqnum=%"PRIu64"\n", seqnum);
|
||||
- assert_se(seqnum == 5);
|
||||
+ append_number(two, 7, &seqnum);
|
||||
+ printf("seqnum=%"PRIu64"\n", seqnum);
|
||||
+ assert_se(seqnum == 5);
|
||||
|
||||
- /* So..., here we have the same seqnum in two files with the
|
||||
- * same seqnum_id. */
|
||||
+ /* So..., here we have the same seqnum in two files with the
|
||||
+ * same seqnum_id. */
|
||||
|
||||
- test_close(two);
|
||||
+ test_close(two);
|
||||
+ }
|
||||
|
||||
log_info("Done...");
|
||||
|
111
0778-test-skip-journal-tests-without-valid-etc-machine-id.patch
Normal file
111
0778-test-skip-journal-tests-without-valid-etc-machine-id.patch
Normal file
@ -0,0 +1,111 @@
|
||||
From 80b1fd81ec483b57444572f957e38b5fea5b3db6 Mon Sep 17 00:00:00 2001
|
||||
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||
Date: Tue, 27 Feb 2024 16:10:37 +0100
|
||||
Subject: [PATCH] test: skip journal tests without valid /etc/machine-id
|
||||
|
||||
The journal stuff in RHEL 9 can't handle existing but uninitialized
|
||||
/etc/machine-id and backporting all the necessary changes would mean
|
||||
pulling in another 50+ commits (I stopped after 50, so it's probably
|
||||
much more). And to make matters worse, upstream renamed
|
||||
chase_symlinks*() stuff to chase_*(), which makes the backports even
|
||||
more painful (and risky).
|
||||
|
||||
Related PRs:
|
||||
- https://github.com/systemd/systemd/pull/25734/commits
|
||||
- https://github.com/systemd/systemd/pull/27137/commits
|
||||
- https://github.com/systemd/systemd/pull/27122/commits
|
||||
|
||||
RHEL-only
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/journal/test-journal-flush.c | 14 +++++++++++++-
|
||||
src/journal/test-journal-interleaving.c | 2 +-
|
||||
src/journal/test-journal-stream.c | 2 +-
|
||||
src/journal/test-journal-verify.c | 4 ++++
|
||||
src/journal/test-journal.c | 2 +-
|
||||
5 files changed, 20 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/journal/test-journal-flush.c b/src/journal/test-journal-flush.c
|
||||
index 2a5f7fad5e..4b52544e7f 100644
|
||||
--- a/src/journal/test-journal-flush.c
|
||||
+++ b/src/journal/test-journal-flush.c
|
||||
@@ -16,6 +16,8 @@
|
||||
#include "string-util.h"
|
||||
#include "tests.h"
|
||||
|
||||
+static bool arg_keep = false;
|
||||
+
|
||||
static void test_journal_flush_one(int argc, char *argv[]) {
|
||||
_cleanup_(mmap_cache_unrefp) MMapCache *m = NULL;
|
||||
_cleanup_free_ char *fn = NULL;
|
||||
@@ -117,4 +119,14 @@ TEST(journal_flush_compact) {
|
||||
test_journal_flush_one(saved_argc, saved_argv);
|
||||
}
|
||||
|
||||
-DEFINE_TEST_MAIN(LOG_INFO);
|
||||
+static int intro(void) {
|
||||
+ arg_keep = saved_argc > 1;
|
||||
+
|
||||
+ /* managed_journal_file_open requires a valid machine id */
|
||||
+ if (sd_id128_get_machine(NULL) < 0)
|
||||
+ return log_tests_skipped("/etc/machine-id not found");
|
||||
+
|
||||
+ return EXIT_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+DEFINE_TEST_MAIN_WITH_INTRO(LOG_DEBUG, intro);
|
||||
diff --git a/src/journal/test-journal-interleaving.c b/src/journal/test-journal-interleaving.c
|
||||
index e05eae034b..56b2489277 100644
|
||||
--- a/src/journal/test-journal-interleaving.c
|
||||
+++ b/src/journal/test-journal-interleaving.c
|
||||
@@ -306,7 +306,7 @@ TEST(sequence_numbers) {
|
||||
|
||||
static int intro(void) {
|
||||
/* managed_journal_file_open requires a valid machine id */
|
||||
- if (access("/etc/machine-id", F_OK) != 0)
|
||||
+ if (sd_id128_get_machine(NULL) < 0)
|
||||
return log_tests_skipped("/etc/machine-id not found");
|
||||
|
||||
arg_keep = saved_argc > 1;
|
||||
diff --git a/src/journal/test-journal-stream.c b/src/journal/test-journal-stream.c
|
||||
index ac5b7f0005..fe4bc40eaa 100644
|
||||
--- a/src/journal/test-journal-stream.c
|
||||
+++ b/src/journal/test-journal-stream.c
|
||||
@@ -179,7 +179,7 @@ static void run_test(void) {
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
/* managed_journal_file_open requires a valid machine id */
|
||||
- if (access("/etc/machine-id", F_OK) != 0)
|
||||
+ if (sd_id128_get_machine(NULL) < 0)
|
||||
return log_tests_skipped("/etc/machine-id not found");
|
||||
|
||||
test_setup_logging(LOG_DEBUG);
|
||||
diff --git a/src/journal/test-journal-verify.c b/src/journal/test-journal-verify.c
|
||||
index e36ea8cae1..55be7f451b 100644
|
||||
--- a/src/journal/test-journal-verify.c
|
||||
+++ b/src/journal/test-journal-verify.c
|
||||
@@ -143,6 +143,10 @@ static int run_test(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
+ /* managed_journal_file_open requires a valid machine id */
|
||||
+ if (sd_id128_get_machine(NULL) < 0)
|
||||
+ return log_tests_skipped("/etc/machine-id not found");
|
||||
+
|
||||
assert_se(setenv("SYSTEMD_JOURNAL_COMPACT", "0", 1) >= 0);
|
||||
run_test(argc, argv);
|
||||
|
||||
diff --git a/src/journal/test-journal.c b/src/journal/test-journal.c
|
||||
index 889673cae7..99beb671c5 100644
|
||||
--- a/src/journal/test-journal.c
|
||||
+++ b/src/journal/test-journal.c
|
||||
@@ -271,7 +271,7 @@ static int intro(void) {
|
||||
arg_keep = saved_argc > 1;
|
||||
|
||||
/* managed_journal_file_open requires a valid machine id */
|
||||
- if (access("/etc/machine-id", F_OK) != 0)
|
||||
+ if (sd_id128_get_machine(NULL) < 0)
|
||||
return log_tests_skipped("/etc/machine-id not found");
|
||||
|
||||
return EXIT_SUCCESS;
|
@ -0,0 +1,61 @@
|
||||
From 36b71213e9f734fbf5ab3b032f61614c79737dac Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||
Date: Thu, 19 Oct 2023 16:46:56 +0200
|
||||
Subject: [PATCH] test-recurse-dir: work around nftw() ignoring symlinks()
|
||||
|
||||
We have a test where we compare the results from nftw() and our own
|
||||
resurce_dit_at(). nftw() skips a dangling symlink when running under mkosi and
|
||||
the test fails. I don't understand why nftw() does that, but in our code we
|
||||
don't need to test and care about the details of nftw(), which we don't use,
|
||||
outside of the one test, so let's just skip symlinks in the test.
|
||||
|
||||
Closes #29603.
|
||||
|
||||
(cherry picked from commit 974959e6f6352b76355b76ab550c0e729b2a8c21)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/test/test-recurse-dir.c | 15 ++++++++-------
|
||||
1 file changed, 8 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/test/test-recurse-dir.c b/src/test/test-recurse-dir.c
|
||||
index 2c2120b136..c194896a1b 100644
|
||||
--- a/src/test/test-recurse-dir.c
|
||||
+++ b/src/test/test-recurse-dir.c
|
||||
@@ -26,8 +26,7 @@ static int nftw_cb(
|
||||
break;
|
||||
|
||||
case FTW_SL:
|
||||
- log_debug("ftw found symlink %s", fpath);
|
||||
- assert_se(strv_extendf(&list_nftw, "%s→", fpath) >= 0);
|
||||
+ log_debug("ftw found symlink %s, ignoring.", fpath);
|
||||
break;
|
||||
|
||||
case FTW_D:
|
||||
@@ -71,11 +70,10 @@ static int recurse_dir_callback(
|
||||
case RECURSE_DIR_ENTRY:
|
||||
assert_se(!IN_SET(de->d_type, DT_UNKNOWN, DT_DIR));
|
||||
|
||||
- log_debug("found %s", path);
|
||||
+ log_debug("found %s%s", path,
|
||||
+ de->d_type == DT_LNK ? ", ignoring." : "");
|
||||
|
||||
- if (de->d_type == DT_LNK)
|
||||
- assert_se(strv_extendf(l, "%s→", path) >= 0);
|
||||
- else
|
||||
+ if (de->d_type != DT_LNK)
|
||||
assert_se(strv_extend(l, path) >= 0);
|
||||
break;
|
||||
|
||||
@@ -131,7 +129,10 @@ int main(int argc, char *argv[]) {
|
||||
else
|
||||
p = "/usr/share/man"; /* something hopefully reasonably stable while we run (and limited in size) */
|
||||
|
||||
- /* Enumerate the specified dirs in full, once via nftw(), and once via recurse_dir(), and ensure the results are identical */
|
||||
+ /* Enumerate the specified dirs in full, once via nftw(), and once via recurse_dir(), and ensure the
|
||||
+ * results are identical. nftw() sometimes skips symlinks (see
|
||||
+ * https://github.com/systemd/systemd/issues/29603), so ignore them to avoid bogus errors. */
|
||||
+
|
||||
t1 = now(CLOCK_MONOTONIC);
|
||||
r = recurse_dir_at(AT_FDCWD, p, 0, UINT_MAX, RECURSE_DIR_SORT|RECURSE_DIR_ENSURE_TYPE|RECURSE_DIR_SAME_MOUNT, recurse_dir_callback, &list_recurse_dir);
|
||||
t2 = now(CLOCK_MONOTONIC);
|
70
0780-test-Skip-test-recurse-dir-on-overlayfs.patch
Normal file
70
0780-test-Skip-test-recurse-dir-on-overlayfs.patch
Normal file
@ -0,0 +1,70 @@
|
||||
From d4290244c49c6cc341225151cf0dfd5329dde943 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Maw <richard.maw@codethink.co.uk>
|
||||
Date: Wed, 25 Oct 2023 18:12:58 +0100
|
||||
Subject: [PATCH] test: Skip test-recurse-dir on overlayfs
|
||||
|
||||
(cherry picked from commit 31cfcf50088b69c973b9335a2383fa6502d90419)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/test/test-recurse-dir.c | 26 +++++++++++++++++++-------
|
||||
1 file changed, 19 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/test/test-recurse-dir.c b/src/test/test-recurse-dir.c
|
||||
index c194896a1b..3e42526679 100644
|
||||
--- a/src/test/test-recurse-dir.c
|
||||
+++ b/src/test/test-recurse-dir.c
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
#include <ftw.h>
|
||||
|
||||
+#include "fd-util.h"
|
||||
#include "log.h"
|
||||
+#include "missing_magic.h"
|
||||
#include "recurse-dir.h"
|
||||
#include "strv.h"
|
||||
#include "tests.h"
|
||||
@@ -119,7 +121,7 @@ int main(int argc, char *argv[]) {
|
||||
_cleanup_strv_free_ char **list_recurse_dir = NULL;
|
||||
const char *p;
|
||||
usec_t t1, t2, t3, t4;
|
||||
- int r;
|
||||
+ _cleanup_close_ int fd = -EBADF;
|
||||
|
||||
log_show_color(true);
|
||||
test_setup_logging(LOG_INFO);
|
||||
@@ -129,18 +131,28 @@ int main(int argc, char *argv[]) {
|
||||
else
|
||||
p = "/usr/share/man"; /* something hopefully reasonably stable while we run (and limited in size) */
|
||||
|
||||
+ fd = open(p, O_DIRECTORY|O_CLOEXEC);
|
||||
+ if (fd < 0 && errno == ENOENT) {
|
||||
+ log_warning_errno(errno, "Couldn't open directory %s, ignoring: %m", p);
|
||||
+ return EXIT_TEST_SKIP;
|
||||
+ }
|
||||
+ assert_se(fd >= 0);
|
||||
+
|
||||
+ /* If the test directory is on an overlayfs then files and their direcory may return different st_dev
|
||||
+ * in stat results, which confuses nftw into thinking they're on different filesystems
|
||||
+ * and won't return the result when the FTW_MOUNT flag is set. */
|
||||
+ if (fd_is_fs_type(fd, OVERLAYFS_SUPER_MAGIC)) {
|
||||
+ log_tests_skipped("nftw mountpoint detection produces false-positives on overlayfs");
|
||||
+ return EXIT_TEST_SKIP;
|
||||
+ }
|
||||
+
|
||||
/* Enumerate the specified dirs in full, once via nftw(), and once via recurse_dir(), and ensure the
|
||||
* results are identical. nftw() sometimes skips symlinks (see
|
||||
* https://github.com/systemd/systemd/issues/29603), so ignore them to avoid bogus errors. */
|
||||
|
||||
t1 = now(CLOCK_MONOTONIC);
|
||||
- r = recurse_dir_at(AT_FDCWD, p, 0, UINT_MAX, RECURSE_DIR_SORT|RECURSE_DIR_ENSURE_TYPE|RECURSE_DIR_SAME_MOUNT, recurse_dir_callback, &list_recurse_dir);
|
||||
+ assert_se(recurse_dir(fd, p, 0, UINT_MAX, RECURSE_DIR_SORT|RECURSE_DIR_ENSURE_TYPE|RECURSE_DIR_SAME_MOUNT, recurse_dir_callback, &list_recurse_dir) >= 0);
|
||||
t2 = now(CLOCK_MONOTONIC);
|
||||
- if (r == -ENOENT) {
|
||||
- log_warning_errno(r, "Couldn't open directory %s, ignoring: %m", p);
|
||||
- return EXIT_TEST_SKIP;
|
||||
- }
|
||||
- assert_se(r >= 0);
|
||||
|
||||
t3 = now(CLOCK_MONOTONIC);
|
||||
assert_se(nftw(p, nftw_cb, 64, FTW_PHYS|FTW_MOUNT) >= 0);
|
@ -0,0 +1,28 @@
|
||||
From 62cbc9f00697003069f1c263c0ab3361f0ea4b6a Mon Sep 17 00:00:00 2001
|
||||
From: Daan De Meyer <daan.j.demeyer@gmail.com>
|
||||
Date: Sat, 6 May 2023 11:33:22 +0200
|
||||
Subject: [PATCH] test-specifier: Ignore -ENOPKG from specifier_printf()
|
||||
|
||||
If /etc/machine-id contains "uninitialized", specifier_printf() with
|
||||
%m will fail with ENOPKG, so ignore that error as well.
|
||||
|
||||
(cherry picked from commit 7429c8fe57bef84c3ff6ebd94b560356752af0bc)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/test/test-specifier.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/test/test-specifier.c b/src/test/test-specifier.c
|
||||
index 4a8ff4bd10..d0adc1a87d 100644
|
||||
--- a/src/test/test-specifier.c
|
||||
+++ b/src/test/test-specifier.c
|
||||
@@ -136,7 +136,7 @@ TEST(specifiers) {
|
||||
xsprintf(spec, "%%%c", s->specifier);
|
||||
|
||||
r = specifier_printf(spec, SIZE_MAX, specifier_table, NULL, NULL, &resolved);
|
||||
- if (s->specifier == 'm' && IN_SET(r, -ENOENT, -ENOMEDIUM)) /* machine-id might be missing in build chroots */
|
||||
+ if (s->specifier == 'm' && IN_SET(r, -ENOENT, -ENOMEDIUM, -ENOPKG)) /* machine-id might be missing in build chroots */
|
||||
continue;
|
||||
assert_se(r >= 0);
|
||||
|
29
0782-test-execute-Skip-when-sys-is-read-only.patch
Normal file
29
0782-test-execute-Skip-when-sys-is-read-only.patch
Normal file
@ -0,0 +1,29 @@
|
||||
From db9c5f759c7c4163d9de1db398b72ef01abaec24 Mon Sep 17 00:00:00 2001
|
||||
From: Daan De Meyer <daan.j.demeyer@gmail.com>
|
||||
Date: Wed, 25 Jan 2023 09:39:13 +0100
|
||||
Subject: [PATCH] test-execute: Skip when /sys is read-only
|
||||
|
||||
The test depends on /sys being writable, so let's skip it when /sys
|
||||
is read-only.
|
||||
|
||||
(cherry picked from commit 34b5977015a557840988e825ac116a7f09d0be75)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/test/test-execute.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/src/test/test-execute.c b/src/test/test-execute.c
|
||||
index 0283caeca6..ce3489d708 100644
|
||||
--- a/src/test/test-execute.c
|
||||
+++ b/src/test/test-execute.c
|
||||
@@ -1228,6 +1228,9 @@ int main(int argc, char *argv[]) {
|
||||
if (r == -ENOMEDIUM)
|
||||
return log_tests_skipped("cgroupfs not available");
|
||||
|
||||
+ if (path_is_read_only_fs("/sys") > 0)
|
||||
+ return log_tests_skipped("/sys is mounted read-only");
|
||||
+
|
||||
_cleanup_free_ char *unit_dir = NULL, *unit_paths = NULL;
|
||||
assert_se(get_testdata_dir("test-execute/", &unit_dir) >= 0);
|
||||
assert_se(runtime_dir = setup_fake_runtime_dir());
|
@ -0,0 +1,25 @@
|
||||
From bc68683e1ed1579718291a74edc7c6406ce078a0 Mon Sep 17 00:00:00 2001
|
||||
From: Daan De Meyer <daan.j.demeyer@gmail.com>
|
||||
Date: Mon, 31 Jul 2023 20:58:31 +0200
|
||||
Subject: [PATCH] kernel-install: Make sure KERNEL_INSTALL_BYPASS is disabled
|
||||
in tests
|
||||
|
||||
(cherry picked from commit 4435da1f1732e2078e42b0ee43ad56fde2b021a3)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/kernel-install/test-kernel-install.sh | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/kernel-install/test-kernel-install.sh b/src/kernel-install/test-kernel-install.sh
|
||||
index 2e44063668..3b9ff76e60 100755
|
||||
--- a/src/kernel-install/test-kernel-install.sh
|
||||
+++ b/src/kernel-install/test-kernel-install.sh
|
||||
@@ -32,6 +32,7 @@ export KERNEL_INSTALL_CONF_ROOT="$D/sources"
|
||||
export KERNEL_INSTALL_PLUGINS="$plugin"
|
||||
export BOOT_ROOT="$D/boot"
|
||||
export MACHINE_ID='3e0484f3634a418b8e6a39e8828b03e3'
|
||||
+export KERNEL_INSTALL_BYPASS="no"
|
||||
|
||||
"$kernel_install" -v add 1.1.1 "$D/sources/linux" "$D/sources/initrd"
|
||||
|
@ -0,0 +1,42 @@
|
||||
From d2fcb75822d85a1516bca2fc2e87e1d94d7691c3 Mon Sep 17 00:00:00 2001
|
||||
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||
Date: Tue, 27 Feb 2024 16:59:23 +0100
|
||||
Subject: [PATCH] tools: make sure $KERNEL_INSTALL_BYPASS is disabled when
|
||||
checking help
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Upstream mkosi sets $KERNEL_INSTALL_BYPASS to 1 by default [0] which
|
||||
then trip over check-help tests, as the message about
|
||||
$KERNEL_INSTALL_BYPASS is not printed out to stderr. Upstream systemd
|
||||
doesn't have this issue, since kernel-install there was rewritten in C,
|
||||
so the code base is completely different.
|
||||
|
||||
1068/1073 systemd:dist-check / check-help-kernel-install FAIL 0.02s exit status 4
|
||||
>>> MALLOC_PERTURB_=212 /work/src/tools/check-help.sh /work/build/kernel-install
|
||||
――――――――――――――――――――――――――――――――――――― ✀ ―――――――――――――――――――――――――――――――――――――
|
||||
kernel-install with an unknown parameter does not print to stderr
|
||||
――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――
|
||||
|
||||
[0] https://github.com/systemd/mkosi/commit/deaaa831d4379ef400ffdc5f71bc0eabed072044
|
||||
|
||||
RHEL-only
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
tools/check-help.sh | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/tools/check-help.sh b/tools/check-help.sh
|
||||
index f97429364e..2f062a7515 100755
|
||||
--- a/tools/check-help.sh
|
||||
+++ b/tools/check-help.sh
|
||||
@@ -9,6 +9,7 @@ set -o pipefail
|
||||
|
||||
BINARY="${1:?}"
|
||||
export SYSTEMD_LOG_LEVEL=info
|
||||
+export KERNEL_INSTALL_BYPASS="no"
|
||||
|
||||
if [[ ! -x "$BINARY" ]]; then
|
||||
echo "$BINARY is not an executable"
|
888
0785-test-execute-drop-capabilities-when-testing-with-use.patch
Normal file
888
0785-test-execute-drop-capabilities-when-testing-with-use.patch
Normal file
@ -0,0 +1,888 @@
|
||||
From bdde465ad1df52cb9b9fbaab37d5d7541601d774 Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Fri, 3 Feb 2023 12:28:31 +0900
|
||||
Subject: [PATCH] test-execute: drop capabilities when testing with user
|
||||
manager
|
||||
|
||||
Before this, tests are split into two categories, system and user, but
|
||||
both are running in fully privileged environment. Hence, unprivileged
|
||||
user scope was mostly not covered by the test.
|
||||
|
||||
Let's run all tests in both system and user scopes, and drop capabilities
|
||||
when Manager is running in user scope.
|
||||
|
||||
This also makes the host environment protected more from the test run.
|
||||
|
||||
(cherry picked from commit 4e032f654b94c2544ccf937209303766dfa66c24)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/test/test-execute.c | 351 +++++++++++-------
|
||||
...dynamicuser-statedir-migrate-step1.service | 16 +-
|
||||
...dynamicuser-statedir-migrate-step2.service | 32 +-
|
||||
.../exec-dynamicuser-statedir.service | 122 +++---
|
||||
.../exec-privatenetwork-yes.service | 1 +
|
||||
.../exec-specifier-system.service | 11 +
|
||||
test/test-execute/exec-specifier-user.service | 11 +
|
||||
test/test-execute/exec-specifier.service | 5 -
|
||||
test/test-execute/exec-specifier@.service | 5 -
|
||||
9 files changed, 333 insertions(+), 221 deletions(-)
|
||||
create mode 100644 test/test-execute/exec-specifier-system.service
|
||||
create mode 100644 test/test-execute/exec-specifier-user.service
|
||||
|
||||
diff --git a/src/test/test-execute.c b/src/test/test-execute.c
|
||||
index ce3489d708..665ae8a833 100644
|
||||
--- a/src/test/test-execute.c
|
||||
+++ b/src/test/test-execute.c
|
||||
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <stdio.h>
|
||||
+#include <sys/mount.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
@@ -18,6 +19,7 @@
|
||||
#include "manager.h"
|
||||
#include "missing_prctl.h"
|
||||
#include "mkdir.h"
|
||||
+#include "mount-util.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
#include "rm-rf.h"
|
||||
@@ -35,6 +37,8 @@
|
||||
#include "util.h"
|
||||
#include "virt.h"
|
||||
|
||||
+#define PRIVATE_UNIT_DIR "/run/test-execute-unit-dir"
|
||||
+
|
||||
static char *user_runtime_unit_dir = NULL;
|
||||
static bool can_unshare;
|
||||
|
||||
@@ -414,7 +418,7 @@ static void test_exec_privatedevices(Manager *m) {
|
||||
test(m, "exec-privatedevices-yes.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
|
||||
test(m, "exec-privatedevices-no.service", 0, CLD_EXITED);
|
||||
test(m, "exec-privatedevices-disabled-by-prefix.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
|
||||
- test(m, "exec-privatedevices-yes-with-group.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
|
||||
+ test(m, "exec-privatedevices-yes-with-group.service", can_unshare ? 0 : MANAGER_IS_SYSTEM(m) ? EXIT_FAILURE : EXIT_GROUP, CLD_EXITED);
|
||||
|
||||
/* We use capsh to test if the capabilities are
|
||||
* properly set, so be sure that it exists */
|
||||
@@ -425,9 +429,9 @@ static void test_exec_privatedevices(Manager *m) {
|
||||
}
|
||||
|
||||
test(m, "exec-privatedevices-yes-capability-mknod.service", 0, CLD_EXITED);
|
||||
- test(m, "exec-privatedevices-no-capability-mknod.service", 0, CLD_EXITED);
|
||||
+ test(m, "exec-privatedevices-no-capability-mknod.service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_FAILURE, CLD_EXITED);
|
||||
test(m, "exec-privatedevices-yes-capability-sys-rawio.service", 0, CLD_EXITED);
|
||||
- test(m, "exec-privatedevices-no-capability-sys-rawio.service", 0, CLD_EXITED);
|
||||
+ test(m, "exec-privatedevices-no-capability-sys-rawio.service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_FAILURE, CLD_EXITED);
|
||||
}
|
||||
|
||||
static void test_exec_protecthome(Manager *m) {
|
||||
@@ -457,7 +461,7 @@ static void test_exec_protectkernelmodules(Manager *m) {
|
||||
return;
|
||||
}
|
||||
|
||||
- test(m, "exec-protectkernelmodules-no-capabilities.service", 0, CLD_EXITED);
|
||||
+ test(m, "exec-protectkernelmodules-no-capabilities.service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_FAILURE, CLD_EXITED);
|
||||
test(m, "exec-protectkernelmodules-yes-capabilities.service", 0, CLD_EXITED);
|
||||
test(m, "exec-protectkernelmodules-yes-mount-propagation.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
|
||||
}
|
||||
@@ -778,7 +782,7 @@ static void test_exec_systemcallfilter_system(Manager *m) {
|
||||
return;
|
||||
}
|
||||
|
||||
- test(m, "exec-systemcallfilter-system-user.service", 0, CLD_EXITED);
|
||||
+ test(m, "exec-systemcallfilter-system-user.service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_GROUP, CLD_EXITED);
|
||||
|
||||
if (!check_nobody_user_and_group()) {
|
||||
log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__);
|
||||
@@ -790,12 +794,12 @@ static void test_exec_systemcallfilter_system(Manager *m) {
|
||||
return;
|
||||
}
|
||||
|
||||
- test(m, "exec-systemcallfilter-system-user-" NOBODY_USER_NAME ".service", 0, CLD_EXITED);
|
||||
+ test(m, "exec-systemcallfilter-system-user-" NOBODY_USER_NAME ".service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_GROUP, CLD_EXITED);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void test_exec_user(Manager *m) {
|
||||
- test(m, "exec-user.service", 0, CLD_EXITED);
|
||||
+ test(m, "exec-user.service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_GROUP, CLD_EXITED);
|
||||
|
||||
if (!check_nobody_user_and_group()) {
|
||||
log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__);
|
||||
@@ -807,11 +811,11 @@ static void test_exec_user(Manager *m) {
|
||||
return;
|
||||
}
|
||||
|
||||
- test(m, "exec-user-" NOBODY_USER_NAME ".service", 0, CLD_EXITED);
|
||||
+ test(m, "exec-user-" NOBODY_USER_NAME ".service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_GROUP, CLD_EXITED);
|
||||
}
|
||||
|
||||
static void test_exec_group(Manager *m) {
|
||||
- test(m, "exec-group.service", 0, CLD_EXITED);
|
||||
+ test(m, "exec-group.service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_GROUP, CLD_EXITED);
|
||||
|
||||
if (!check_nobody_user_and_group()) {
|
||||
log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__);
|
||||
@@ -823,16 +827,17 @@ static void test_exec_group(Manager *m) {
|
||||
return;
|
||||
}
|
||||
|
||||
- test(m, "exec-group-" NOBODY_GROUP_NAME ".service", 0, CLD_EXITED);
|
||||
+ test(m, "exec-group-" NOBODY_GROUP_NAME ".service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_GROUP, CLD_EXITED);
|
||||
}
|
||||
|
||||
static void test_exec_supplementarygroups(Manager *m) {
|
||||
- test(m, "exec-supplementarygroups.service", 0, CLD_EXITED);
|
||||
- test(m, "exec-supplementarygroups-single-group.service", 0, CLD_EXITED);
|
||||
- test(m, "exec-supplementarygroups-single-group-user.service", 0, CLD_EXITED);
|
||||
- test(m, "exec-supplementarygroups-multiple-groups-default-group-user.service", 0, CLD_EXITED);
|
||||
- test(m, "exec-supplementarygroups-multiple-groups-withgid.service", 0, CLD_EXITED);
|
||||
- test(m, "exec-supplementarygroups-multiple-groups-withuid.service", 0, CLD_EXITED);
|
||||
+ int status = MANAGER_IS_SYSTEM(m) ? 0 : EXIT_GROUP;
|
||||
+ test(m, "exec-supplementarygroups.service", status, CLD_EXITED);
|
||||
+ test(m, "exec-supplementarygroups-single-group.service", status, CLD_EXITED);
|
||||
+ test(m, "exec-supplementarygroups-single-group-user.service", status, CLD_EXITED);
|
||||
+ test(m, "exec-supplementarygroups-multiple-groups-default-group-user.service", status, CLD_EXITED);
|
||||
+ test(m, "exec-supplementarygroups-multiple-groups-withgid.service", status, CLD_EXITED);
|
||||
+ test(m, "exec-supplementarygroups-multiple-groups-withuid.service", status, CLD_EXITED);
|
||||
}
|
||||
|
||||
static char* private_directory_bad(Manager *m) {
|
||||
@@ -864,14 +869,16 @@ static void test_exec_dynamicuser(Manager *m) {
|
||||
return;
|
||||
}
|
||||
|
||||
- test(m, "exec-dynamicuser-fixeduser.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||||
+ int status = can_unshare ? 0 : MANAGER_IS_SYSTEM(m) ? EXIT_NAMESPACE : EXIT_GROUP;
|
||||
+
|
||||
+ test(m, "exec-dynamicuser-fixeduser.service", status, CLD_EXITED);
|
||||
if (check_user_has_group_with_same_name("adm"))
|
||||
- test(m, "exec-dynamicuser-fixeduser-adm.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||||
+ test(m, "exec-dynamicuser-fixeduser-adm.service", status, CLD_EXITED);
|
||||
if (check_user_has_group_with_same_name("games"))
|
||||
- test(m, "exec-dynamicuser-fixeduser-games.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||||
- test(m, "exec-dynamicuser-fixeduser-one-supplementarygroup.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||||
- test(m, "exec-dynamicuser-supplementarygroups.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||||
- test(m, "exec-dynamicuser-statedir.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||||
+ test(m, "exec-dynamicuser-fixeduser-games.service", status, CLD_EXITED);
|
||||
+ test(m, "exec-dynamicuser-fixeduser-one-supplementarygroup.service", status, CLD_EXITED);
|
||||
+ test(m, "exec-dynamicuser-supplementarygroups.service", status, CLD_EXITED);
|
||||
+ test(m, "exec-dynamicuser-statedir.service", status, CLD_EXITED);
|
||||
|
||||
(void) rm_rf("/var/lib/quux", REMOVE_ROOT|REMOVE_PHYSICAL);
|
||||
(void) rm_rf("/var/lib/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
|
||||
@@ -883,7 +890,7 @@ static void test_exec_dynamicuser(Manager *m) {
|
||||
(void) rm_rf("/var/lib/private/waldo", REMOVE_ROOT|REMOVE_PHYSICAL);
|
||||
|
||||
test(m, "exec-dynamicuser-statedir-migrate-step1.service", 0, CLD_EXITED);
|
||||
- test(m, "exec-dynamicuser-statedir-migrate-step2.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||||
+ test(m, "exec-dynamicuser-statedir-migrate-step2.service", status, CLD_EXITED);
|
||||
test(m, "exec-dynamicuser-statedir-migrate-step1.service", 0, CLD_EXITED);
|
||||
|
||||
(void) rm_rf("/var/lib/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
|
||||
@@ -891,9 +898,9 @@ static void test_exec_dynamicuser(Manager *m) {
|
||||
(void) rm_rf("/var/lib/private/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
|
||||
(void) rm_rf("/var/lib/private/test-dynamicuser-migrate2", REMOVE_ROOT|REMOVE_PHYSICAL);
|
||||
|
||||
- test(m, "exec-dynamicuser-runtimedirectory1.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||||
- test(m, "exec-dynamicuser-runtimedirectory2.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||||
- test(m, "exec-dynamicuser-runtimedirectory3.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||||
+ test(m, "exec-dynamicuser-runtimedirectory1.service", status, CLD_EXITED);
|
||||
+ test(m, "exec-dynamicuser-runtimedirectory2.service", status, CLD_EXITED);
|
||||
+ test(m, "exec-dynamicuser-runtimedirectory3.service", status, CLD_EXITED);
|
||||
}
|
||||
|
||||
static void test_exec_environment(Manager *m) {
|
||||
@@ -959,9 +966,12 @@ static void test_exec_umask(Manager *m) {
|
||||
}
|
||||
|
||||
static void test_exec_runtimedirectory(Manager *m) {
|
||||
+ (void) rm_rf("/run/test-exec_runtimedirectory2", REMOVE_ROOT|REMOVE_PHYSICAL);
|
||||
test(m, "exec-runtimedirectory.service", 0, CLD_EXITED);
|
||||
+ (void) rm_rf("/run/test-exec_runtimedirectory2", REMOVE_ROOT|REMOVE_PHYSICAL);
|
||||
+
|
||||
test(m, "exec-runtimedirectory-mode.service", 0, CLD_EXITED);
|
||||
- test(m, "exec-runtimedirectory-owner.service", 0, CLD_EXITED);
|
||||
+ test(m, "exec-runtimedirectory-owner.service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_GROUP, CLD_EXITED);
|
||||
|
||||
if (!check_nobody_user_and_group()) {
|
||||
log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__);
|
||||
@@ -973,7 +983,7 @@ static void test_exec_runtimedirectory(Manager *m) {
|
||||
return;
|
||||
}
|
||||
|
||||
- test(m, "exec-runtimedirectory-owner-" NOBODY_GROUP_NAME ".service", 0, CLD_EXITED);
|
||||
+ test(m, "exec-runtimedirectory-owner-" NOBODY_GROUP_NAME ".service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_GROUP, CLD_EXITED);
|
||||
}
|
||||
|
||||
static void test_exec_capabilityboundingset(Manager *m) {
|
||||
@@ -1047,7 +1057,7 @@ static void test_exec_privatenetwork(Manager *m) {
|
||||
return;
|
||||
}
|
||||
|
||||
- test(m, "exec-privatenetwork-yes.service", can_unshare ? 0 : EXIT_NETWORK, CLD_EXITED);
|
||||
+ test(m, "exec-privatenetwork-yes.service", can_unshare ? 0 : MANAGER_IS_SYSTEM(m) ? EXIT_NETWORK : EXIT_FAILURE, CLD_EXITED);
|
||||
}
|
||||
|
||||
static void test_exec_oomscoreadjust(Manager *m) {
|
||||
@@ -1057,7 +1067,7 @@ static void test_exec_oomscoreadjust(Manager *m) {
|
||||
log_notice("Testing in container, skipping remaining tests in %s", __func__);
|
||||
return;
|
||||
}
|
||||
- test(m, "exec-oomscoreadjust-negative.service", 0, CLD_EXITED);
|
||||
+ test(m, "exec-oomscoreadjust-negative.service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_FAILURE, CLD_EXITED);
|
||||
}
|
||||
|
||||
static void test_exec_ioschedulingclass(Manager *m) {
|
||||
@@ -1069,7 +1079,7 @@ static void test_exec_ioschedulingclass(Manager *m) {
|
||||
log_notice("Testing in container, skipping remaining tests in %s", __func__);
|
||||
return;
|
||||
}
|
||||
- test(m, "exec-ioschedulingclass-realtime.service", 0, CLD_EXITED);
|
||||
+ test(m, "exec-ioschedulingclass-realtime.service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_IOPRIO, CLD_EXITED);
|
||||
}
|
||||
|
||||
static void test_exec_unsetenvironment(Manager *m) {
|
||||
@@ -1078,9 +1088,13 @@ static void test_exec_unsetenvironment(Manager *m) {
|
||||
|
||||
static void test_exec_specifier(Manager *m) {
|
||||
test(m, "exec-specifier.service", 0, CLD_EXITED);
|
||||
+ if (MANAGER_IS_SYSTEM(m))
|
||||
+ test(m, "exec-specifier-system.service", 0, CLD_EXITED);
|
||||
+ else
|
||||
+ test(m, "exec-specifier-user.service", 0, CLD_EXITED);
|
||||
test(m, "exec-specifier@foo-bar.service", 0, CLD_EXITED);
|
||||
test(m, "exec-specifier-interpolation.service", 0, CLD_EXITED);
|
||||
- test(m, "exec-specifier-credentials-dir.service", 0, CLD_EXITED);
|
||||
+ test(m, "exec-specifier-credentials-dir.service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_CREDENTIALS, CLD_EXITED);
|
||||
}
|
||||
|
||||
static void test_exec_standardinput(Manager *m) {
|
||||
@@ -1113,7 +1127,7 @@ static void test_exec_umask_namespace(Manager *m) {
|
||||
log_notice("Testing without inaccessible, skipping %s", __func__);
|
||||
return;
|
||||
}
|
||||
- test(m, "exec-umask-namespace.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||||
+ test(m, "exec-umask-namespace.service", can_unshare ? 0 : MANAGER_IS_SYSTEM(m) ? EXIT_NAMESPACE : EXIT_GROUP, CLD_EXITED);
|
||||
}
|
||||
|
||||
typedef struct test_entry {
|
||||
@@ -1123,40 +1137,27 @@ typedef struct test_entry {
|
||||
|
||||
#define entry(x) {x, #x}
|
||||
|
||||
-static int run_tests(LookupScope scope, const test_entry tests[], char **patterns) {
|
||||
+static void run_tests(LookupScope scope, char **patterns) {
|
||||
+ _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
|
||||
+ _cleanup_free_ char *unit_paths = NULL;
|
||||
_cleanup_(manager_freep) Manager *m = NULL;
|
||||
int r;
|
||||
|
||||
- assert_se(tests);
|
||||
-
|
||||
- r = manager_new(scope, MANAGER_TEST_RUN_BASIC, &m);
|
||||
- m->default_std_output = EXEC_OUTPUT_NULL; /* don't rely on host journald */
|
||||
- if (manager_errno_skip_test(r))
|
||||
- return log_tests_skipped_errno(r, "manager_new");
|
||||
- assert_se(r >= 0);
|
||||
- assert_se(manager_startup(m, NULL, NULL, NULL) >= 0);
|
||||
-
|
||||
- for (const test_entry *test = tests; test->f; test++)
|
||||
- if (strv_fnmatch_or_empty(patterns, test->name, FNM_NOESCAPE))
|
||||
- test->f(m);
|
||||
- else
|
||||
- log_info("Skipping %s because it does not match any pattern.", test->name);
|
||||
-
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-int main(int argc, char *argv[]) {
|
||||
- _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
|
||||
-
|
||||
- static const test_entry user_tests[] = {
|
||||
+ static const test_entry tests[] = {
|
||||
entry(test_exec_basic),
|
||||
entry(test_exec_ambientcapabilities),
|
||||
entry(test_exec_bindpaths),
|
||||
entry(test_exec_capabilityboundingset),
|
||||
entry(test_exec_condition),
|
||||
entry(test_exec_cpuaffinity),
|
||||
+ entry(test_exec_dynamicuser),
|
||||
entry(test_exec_environment),
|
||||
entry(test_exec_environmentfile),
|
||||
+ entry(test_exec_execsearchpath),
|
||||
+ entry(test_exec_execsearchpath_environment),
|
||||
+ entry(test_exec_execsearchpath_environment_files),
|
||||
+ entry(test_exec_execsearchpath_passenvironment),
|
||||
+ entry(test_exec_execsearchpath_specifier),
|
||||
entry(test_exec_group),
|
||||
entry(test_exec_ignoresigpipe),
|
||||
entry(test_exec_inaccessiblepaths),
|
||||
@@ -1175,6 +1176,7 @@ int main(int argc, char *argv[]) {
|
||||
entry(test_exec_readwritepaths),
|
||||
entry(test_exec_restrictnamespaces),
|
||||
entry(test_exec_runtimedirectory),
|
||||
+ entry(test_exec_specifier),
|
||||
entry(test_exec_standardinput),
|
||||
entry(test_exec_standardoutput),
|
||||
entry(test_exec_standardoutput_append),
|
||||
@@ -1182,35 +1184,15 @@ int main(int argc, char *argv[]) {
|
||||
entry(test_exec_supplementarygroups),
|
||||
entry(test_exec_systemcallerrornumber),
|
||||
entry(test_exec_systemcallfilter),
|
||||
+ entry(test_exec_systemcallfilter_system),
|
||||
entry(test_exec_temporaryfilesystem),
|
||||
entry(test_exec_umask),
|
||||
+ entry(test_exec_umask_namespace),
|
||||
entry(test_exec_unsetenvironment),
|
||||
entry(test_exec_user),
|
||||
entry(test_exec_workingdirectory),
|
||||
- entry(test_exec_execsearchpath),
|
||||
- entry(test_exec_execsearchpath_environment),
|
||||
- entry(test_exec_execsearchpath_environment_files),
|
||||
- entry(test_exec_execsearchpath_passenvironment),
|
||||
- {},
|
||||
- };
|
||||
- static const test_entry system_tests[] = {
|
||||
- entry(test_exec_dynamicuser),
|
||||
- entry(test_exec_specifier),
|
||||
- entry(test_exec_execsearchpath_specifier),
|
||||
- entry(test_exec_systemcallfilter_system),
|
||||
- entry(test_exec_umask_namespace),
|
||||
{},
|
||||
};
|
||||
- int r;
|
||||
-
|
||||
- test_setup_logging(LOG_DEBUG);
|
||||
-
|
||||
-#if HAS_FEATURE_ADDRESS_SANITIZER
|
||||
- if (strstr_ptr(ci_environment(), "travis") || strstr_ptr(ci_environment(), "github-actions")) {
|
||||
- log_notice("Running on Travis CI/GH Actions under ASan, skipping, see https://github.com/systemd/systemd/issues/10696");
|
||||
- return EXIT_TEST_SKIP;
|
||||
- }
|
||||
-#endif
|
||||
|
||||
assert_se(unsetenv("USER") == 0);
|
||||
assert_se(unsetenv("LOGNAME") == 0);
|
||||
@@ -1218,68 +1200,185 @@ int main(int argc, char *argv[]) {
|
||||
assert_se(unsetenv("HOME") == 0);
|
||||
assert_se(unsetenv("TMPDIR") == 0);
|
||||
|
||||
- can_unshare = have_namespaces();
|
||||
-
|
||||
- /* It is needed otherwise cgroup creation fails */
|
||||
- if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0)
|
||||
- return log_tests_skipped("not privileged");
|
||||
-
|
||||
- r = enter_cgroup_subroot(NULL);
|
||||
- if (r == -ENOMEDIUM)
|
||||
- return log_tests_skipped("cgroupfs not available");
|
||||
-
|
||||
- if (path_is_read_only_fs("/sys") > 0)
|
||||
- return log_tests_skipped("/sys is mounted read-only");
|
||||
+ /* Unset VARx, especially, VAR1, VAR2 and VAR3, which are used in the PassEnvironment test cases,
|
||||
+ * otherwise (and if they are present in the environment), `manager_default_environment` will copy
|
||||
+ * them into the default environment which is passed to each created job, which will make the tests
|
||||
+ * that expect those not to be present to fail. */
|
||||
+ assert_se(unsetenv("VAR1") == 0);
|
||||
+ assert_se(unsetenv("VAR2") == 0);
|
||||
+ assert_se(unsetenv("VAR3") == 0);
|
||||
+ assert_se(unsetenv("VAR4") == 0);
|
||||
+ assert_se(unsetenv("VAR5") == 0);
|
||||
|
||||
- _cleanup_free_ char *unit_dir = NULL, *unit_paths = NULL;
|
||||
- assert_se(get_testdata_dir("test-execute/", &unit_dir) >= 0);
|
||||
assert_se(runtime_dir = setup_fake_runtime_dir());
|
||||
assert_se(user_runtime_unit_dir = path_join(runtime_dir, "systemd/user"));
|
||||
- assert_se(unit_paths = strjoin(unit_dir, ":", user_runtime_unit_dir));
|
||||
+ assert_se(unit_paths = strjoin(PRIVATE_UNIT_DIR, ":", user_runtime_unit_dir));
|
||||
assert_se(set_unit_path(unit_paths) >= 0);
|
||||
|
||||
- /* Unset VAR1, VAR2 and VAR3 which are used in the PassEnvironment test
|
||||
- * cases, otherwise (and if they are present in the environment),
|
||||
- * `manager_default_environment` will copy them into the default
|
||||
- * environment which is passed to each created job, which will make the
|
||||
- * tests that expect those not to be present to fail.
|
||||
- */
|
||||
- assert_se(unsetenv("VAR1") == 0);
|
||||
- assert_se(unsetenv("VAR2") == 0);
|
||||
- assert_se(unsetenv("VAR3") == 0);
|
||||
+ r = manager_new(scope, MANAGER_TEST_RUN_BASIC, &m);
|
||||
+ if (manager_errno_skip_test(r))
|
||||
+ return (void) log_tests_skipped_errno(r, "manager_new");
|
||||
+ assert_se(r >= 0);
|
||||
+
|
||||
+ m->default_std_output = EXEC_OUTPUT_NULL; /* don't rely on host journald */
|
||||
+ assert_se(manager_startup(m, NULL, NULL, NULL) >= 0);
|
||||
+
|
||||
+ /* Uncomment below if you want to make debugging logs stored to journal. */
|
||||
+ //manager_override_log_target(m, LOG_TARGET_AUTO);
|
||||
+ //manager_override_log_level(m, LOG_DEBUG);
|
||||
+
|
||||
+ for (const test_entry *test = tests; test->f; test++)
|
||||
+ if (strv_fnmatch_or_empty(patterns, test->name, FNM_NOESCAPE))
|
||||
+ test->f(m);
|
||||
+ else
|
||||
+ log_info("Skipping %s because it does not match any pattern.", test->name);
|
||||
+}
|
||||
+
|
||||
+static int prepare_ns(const char *process_name) {
|
||||
+ int r;
|
||||
+
|
||||
+ r = safe_fork(process_name,
|
||||
+ FORK_RESET_SIGNALS |
|
||||
+ FORK_CLOSE_ALL_FDS |
|
||||
+ FORK_DEATHSIG |
|
||||
+ FORK_WAIT |
|
||||
+ FORK_REOPEN_LOG |
|
||||
+ FORK_LOG |
|
||||
+ FORK_NEW_MOUNTNS |
|
||||
+ FORK_MOUNTNS_SLAVE,
|
||||
+ NULL);
|
||||
+ assert_se(r >= 0);
|
||||
+ if (r == 0) {
|
||||
+ _cleanup_free_ char *unit_dir = NULL;
|
||||
+
|
||||
+ /* Make "/" read-only. */
|
||||
+ assert_se(mount_nofollow_verbose(LOG_DEBUG, NULL, "/", NULL, MS_BIND|MS_REMOUNT, NULL) >= 0);
|
||||
+
|
||||
+ /* Creating a new user namespace in the above means all MS_SHARED mounts become MS_SLAVE.
|
||||
+ * Let's put them back to MS_SHARED here, since that's what we want as defaults. (This will
|
||||
+ * not reconnect propagation, but simply create new peer groups for all our mounts). */
|
||||
+ assert_se(mount_follow_verbose(LOG_DEBUG, NULL, "/", NULL, MS_SHARED|MS_REC, NULL) >= 0);
|
||||
+
|
||||
+ assert_se(mkdir_p(PRIVATE_UNIT_DIR, 0755) >= 0);
|
||||
+
|
||||
+ /* Mount tmpfs on the following directories to make not StateDirectory= or friends disturb the host. */
|
||||
+ FOREACH_STRING(p, "/root", "/tmp", "/var/tmp", "/var/lib", PRIVATE_UNIT_DIR)
|
||||
+ assert_se(mount_nofollow_verbose(LOG_DEBUG, "tmpfs", p, "tmpfs", MS_NOSUID|MS_NODEV, NULL) >= 0);
|
||||
|
||||
- r = run_tests(LOOKUP_SCOPE_USER, user_tests, argv + 1);
|
||||
- if (r != 0)
|
||||
- return r;
|
||||
+ /* Copy unit files to make them accessible even when unprivileged. */
|
||||
+ assert_se(get_testdata_dir("test-execute/", &unit_dir) >= 0);
|
||||
+ assert_se(copy_directory(unit_dir, PRIVATE_UNIT_DIR, COPY_MERGE_EMPTY) >= 0);
|
||||
|
||||
- r = run_tests(LOOKUP_SCOPE_SYSTEM, system_tests, argv + 1);
|
||||
- if (r != 0)
|
||||
- return r;
|
||||
+ /* Prepare credstore like tmpfiles.d/credstore.conf for LoadCredential= tests. */
|
||||
+ FOREACH_STRING(p, "/run/credstore", "/run/credstore.encrypted") {
|
||||
+ assert_se(mkdir_p(p, 0) >= 0);
|
||||
+ assert_se(mount_nofollow_verbose(LOG_DEBUG, "tmpfs", p, "tmpfs", MS_NOSUID|MS_NODEV, "mode=0000") >= 0);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return r;
|
||||
+}
|
||||
+
|
||||
+TEST(run_tests_root) {
|
||||
+ _cleanup_strv_free_ char **filters = NULL;
|
||||
+
|
||||
+ if (!have_namespaces())
|
||||
+ return (void) log_tests_skipped("unshare() is disabled");
|
||||
+
|
||||
+ /* safe_fork() clears saved_argv in the child process. Let's copy it. */
|
||||
+ assert_se(filters = strv_copy(strv_skip(saved_argv, 1)));
|
||||
+
|
||||
+ if (prepare_ns("(test-execute-root)") == 0) {
|
||||
+ can_unshare = true;
|
||||
+ run_tests(LOOKUP_SCOPE_SYSTEM, filters);
|
||||
+ _exit(EXIT_SUCCESS);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+TEST(run_tests_without_unshare) {
|
||||
+ if (!have_namespaces()) {
|
||||
+ /* unshare() is already filtered. */
|
||||
+ can_unshare = false;
|
||||
+ run_tests(LOOKUP_SCOPE_SYSTEM, strv_skip(saved_argv, 1));
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
#if HAVE_SECCOMP
|
||||
+ _cleanup_strv_free_ char **filters = NULL;
|
||||
+ int r;
|
||||
+
|
||||
/* The following tests are for 1beab8b0d0ff2d7d1436b52d4a0c3d56dc908962. */
|
||||
- if (!is_seccomp_available()) {
|
||||
- log_notice("Seccomp not available, skipping unshare() filtered tests.");
|
||||
- return 0;
|
||||
- }
|
||||
+ if (!is_seccomp_available())
|
||||
+ return (void) log_tests_skipped("Seccomp not available, cannot run unshare() filtered tests");
|
||||
+
|
||||
+ /* safe_fork() clears saved_argv in the child process. Let's copy it. */
|
||||
+ assert_se(filters = strv_copy(strv_skip(saved_argv, 1)));
|
||||
|
||||
- _cleanup_hashmap_free_ Hashmap *s = NULL;
|
||||
- assert_se(s = hashmap_new(NULL));
|
||||
- r = seccomp_syscall_resolve_name("unshare");
|
||||
- assert_se(r != __NR_SCMP_ERROR);
|
||||
- assert_se(hashmap_put(s, UINT32_TO_PTR(r + 1), INT_TO_PTR(-1)) >= 0);
|
||||
- assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EOPNOTSUPP), true) >= 0);
|
||||
- assert_se(unshare(CLONE_NEWNS) < 0);
|
||||
- assert_se(errno == EOPNOTSUPP);
|
||||
+ if (prepare_ns("(test-execute-without-unshare)") == 0) {
|
||||
+ _cleanup_hashmap_free_ Hashmap *s = NULL;
|
||||
|
||||
- can_unshare = false;
|
||||
+ r = seccomp_syscall_resolve_name("unshare");
|
||||
+ assert_se(r != __NR_SCMP_ERROR);
|
||||
+ assert_se(hashmap_ensure_put(&s, NULL, UINT32_TO_PTR(r + 1), INT_TO_PTR(-1)) >= 0);
|
||||
+ assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EOPNOTSUPP), true) >= 0);
|
||||
|
||||
- r = run_tests(LOOKUP_SCOPE_USER, user_tests, argv + 1);
|
||||
- if (r != 0)
|
||||
- return r;
|
||||
+ /* Check unshare() is actually filtered. */
|
||||
+ assert_se(unshare(CLONE_NEWNS) < 0);
|
||||
+ assert_se(errno == EOPNOTSUPP);
|
||||
|
||||
- return run_tests(LOOKUP_SCOPE_SYSTEM, system_tests, argv + 1);
|
||||
+ can_unshare = false;
|
||||
+ run_tests(LOOKUP_SCOPE_SYSTEM, filters);
|
||||
+ _exit(EXIT_SUCCESS);
|
||||
+ }
|
||||
#else
|
||||
- return 0;
|
||||
+ log_tests_skipped("Built without seccomp support, cannot run unshare() filtered tests");
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+TEST(run_tests_unprivileged) {
|
||||
+ _cleanup_strv_free_ char **filters = NULL;
|
||||
+
|
||||
+ if (!have_namespaces())
|
||||
+ return (void) log_tests_skipped("unshare() is disabled");
|
||||
+
|
||||
+ /* safe_fork() clears saved_argv in the child process. Let's copy it. */
|
||||
+ assert_se(filters = strv_copy(strv_skip(saved_argv, 1)));
|
||||
+
|
||||
+ if (prepare_ns("(test-execute-unprivileged)") == 0) {
|
||||
+ assert_se(capability_bounding_set_drop(0, /* right_now = */ true) >= 0);
|
||||
+
|
||||
+ can_unshare = false;
|
||||
+ run_tests(LOOKUP_SCOPE_USER, filters);
|
||||
+ _exit(EXIT_SUCCESS);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int intro(void) {
|
||||
+#if HAS_FEATURE_ADDRESS_SANITIZER
|
||||
+ if (strstr_ptr(ci_environment(), "travis") || strstr_ptr(ci_environment(), "github-actions"))
|
||||
+ return log_tests_skipped("Running on Travis CI/GH Actions under ASan, see https://github.com/systemd/systemd/issues/10696");
|
||||
#endif
|
||||
+ /* It is needed otherwise cgroup creation fails */
|
||||
+ if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0)
|
||||
+ return log_tests_skipped("not privileged");
|
||||
+
|
||||
+ if (enter_cgroup_subroot(NULL) == -ENOMEDIUM)
|
||||
+ return log_tests_skipped("cgroupfs not available");
|
||||
+
|
||||
+ if (path_is_read_only_fs("/sys") > 0)
|
||||
+ return log_tests_skipped("/sys is mounted read-only");
|
||||
+
|
||||
+ /* Create dummy network interface for testing PrivateNetwork=yes */
|
||||
+ (void) system("ip link add dummy-test-exec type dummy");
|
||||
+
|
||||
+ return EXIT_SUCCESS;
|
||||
}
|
||||
+
|
||||
+static int outro(void) {
|
||||
+ (void) system("ip link del dummy-test-exec");
|
||||
+ (void) rmdir(PRIVATE_UNIT_DIR);
|
||||
+
|
||||
+ return EXIT_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+DEFINE_TEST_MAIN_FULL(LOG_DEBUG, intro, outro);
|
||||
diff --git a/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service b/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service
|
||||
index 1c79e4f722..2a5a1e1ff3 100644
|
||||
--- a/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service
|
||||
+++ b/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service
|
||||
@@ -3,14 +3,14 @@
|
||||
Description=Test DynamicUser= migrate StateDirectory= (preparation)
|
||||
|
||||
[Service]
|
||||
-ExecStart=test -w /var/lib/test-dynamicuser-migrate
|
||||
-ExecStart=test -w /var/lib/test-dynamicuser-migrate2/hoge
|
||||
-ExecStart=test ! -L /var/lib/test-dynamicuser-migrate
|
||||
-ExecStart=test ! -L /var/lib/test-dynamicuser-migrate2/hoge
|
||||
-ExecStart=test -d /var/lib/test-dynamicuser-migrate
|
||||
-ExecStart=test -d /var/lib/test-dynamicuser-migrate2/hoge
|
||||
-ExecStart=touch /var/lib/test-dynamicuser-migrate/yay
|
||||
-ExecStart=touch /var/lib/test-dynamicuser-migrate2/hoge/yayyay
|
||||
+ExecStart=test -w %S/test-dynamicuser-migrate
|
||||
+ExecStart=test -w %S/test-dynamicuser-migrate2/hoge
|
||||
+ExecStart=test ! -L %S/test-dynamicuser-migrate
|
||||
+ExecStart=test ! -L %S/test-dynamicuser-migrate2/hoge
|
||||
+ExecStart=test -d %S/test-dynamicuser-migrate
|
||||
+ExecStart=test -d %S/test-dynamicuser-migrate2/hoge
|
||||
+ExecStart=touch %S/test-dynamicuser-migrate/yay
|
||||
+ExecStart=touch %S/test-dynamicuser-migrate2/hoge/yayyay
|
||||
ExecStart=/bin/sh -x -c 'test "$$STATE_DIRECTORY" = "%S/test-dynamicuser-migrate:%S/test-dynamicuser-migrate2/hoge"'
|
||||
|
||||
Type=oneshot
|
||||
diff --git a/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service b/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service
|
||||
index 015b74ce22..e89f0c5aae 100644
|
||||
--- a/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service
|
||||
+++ b/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service
|
||||
@@ -3,22 +3,22 @@
|
||||
Description=Test DynamicUser= migrate StateDirectory=
|
||||
|
||||
[Service]
|
||||
-ExecStart=test -w /var/lib/test-dynamicuser-migrate
|
||||
-ExecStart=test -w /var/lib/test-dynamicuser-migrate2/hoge
|
||||
-ExecStart=test -L /var/lib/test-dynamicuser-migrate
|
||||
-ExecStart=test -L /var/lib/test-dynamicuser-migrate2/hoge
|
||||
-ExecStart=test -d /var/lib/test-dynamicuser-migrate
|
||||
-ExecStart=test -d /var/lib/test-dynamicuser-migrate2/hoge
|
||||
-ExecStart=test -f /var/lib/test-dynamicuser-migrate/yay
|
||||
-ExecStart=test -f /var/lib/test-dynamicuser-migrate2/hoge/yayyay
|
||||
-ExecStart=test -d /var/lib/private/test-dynamicuser-migrate
|
||||
-ExecStart=test -d /var/lib/private/test-dynamicuser-migrate2/hoge
|
||||
-ExecStart=test -f /var/lib/private/test-dynamicuser-migrate/yay
|
||||
-ExecStart=test -f /var/lib/private/test-dynamicuser-migrate2/hoge/yayyay
|
||||
-ExecStart=touch /var/lib/test-dynamicuser-migrate/yay
|
||||
-ExecStart=touch /var/lib/test-dynamicuser-migrate2/hoge/yayyay
|
||||
-ExecStart=touch /var/lib/private/test-dynamicuser-migrate/yay
|
||||
-ExecStart=touch /var/lib/private/test-dynamicuser-migrate2/hoge/yayyay
|
||||
+ExecStart=test -w %S/test-dynamicuser-migrate
|
||||
+ExecStart=test -w %S/test-dynamicuser-migrate2/hoge
|
||||
+ExecStart=test -L %S/test-dynamicuser-migrate
|
||||
+ExecStart=test -L %S/test-dynamicuser-migrate2/hoge
|
||||
+ExecStart=test -d %S/test-dynamicuser-migrate
|
||||
+ExecStart=test -d %S/test-dynamicuser-migrate2/hoge
|
||||
+ExecStart=test -f %S/test-dynamicuser-migrate/yay
|
||||
+ExecStart=test -f %S/test-dynamicuser-migrate2/hoge/yayyay
|
||||
+ExecStart=test -d %S/private/test-dynamicuser-migrate
|
||||
+ExecStart=test -d %S/private/test-dynamicuser-migrate2/hoge
|
||||
+ExecStart=test -f %S/private/test-dynamicuser-migrate/yay
|
||||
+ExecStart=test -f %S/private/test-dynamicuser-migrate2/hoge/yayyay
|
||||
+ExecStart=touch %S/test-dynamicuser-migrate/yay
|
||||
+ExecStart=touch %S/test-dynamicuser-migrate2/hoge/yayyay
|
||||
+ExecStart=touch %S/private/test-dynamicuser-migrate/yay
|
||||
+ExecStart=touch %S/private/test-dynamicuser-migrate2/hoge/yayyay
|
||||
ExecStart=/bin/sh -x -c 'test "$$STATE_DIRECTORY" = "%S/test-dynamicuser-migrate:%S/test-dynamicuser-migrate2/hoge"'
|
||||
|
||||
Type=oneshot
|
||||
diff --git a/test/test-execute/exec-dynamicuser-statedir.service b/test/test-execute/exec-dynamicuser-statedir.service
|
||||
index b33b4da74a..b7e36f529e 100644
|
||||
--- a/test/test-execute/exec-dynamicuser-statedir.service
|
||||
+++ b/test/test-execute/exec-dynamicuser-statedir.service
|
||||
@@ -3,71 +3,71 @@
|
||||
Description=Test DynamicUser= with StateDirectory=
|
||||
|
||||
[Service]
|
||||
-ExecStart=test -w /var/lib/waldo
|
||||
-ExecStart=test -w /var/lib/quux/pief
|
||||
-ExecStart=test -w /var/lib/aaa
|
||||
-ExecStart=test -w /var/lib/aaa/bbb
|
||||
-ExecStart=test -w /var/lib/aaa/ccc
|
||||
-ExecStart=test -w /var/lib/xxx
|
||||
-ExecStart=test -w /var/lib/xxx/yyy
|
||||
-ExecStart=test -w /var/lib/xxx/zzz
|
||||
-ExecStart=test -w /var/lib/aaa/111
|
||||
-ExecStart=test -w /var/lib/aaa/222
|
||||
-ExecStart=test -w /var/lib/aaa/333
|
||||
+ExecStart=test -w %S/waldo
|
||||
+ExecStart=test -w %S/quux/pief
|
||||
+ExecStart=test -w %S/aaa
|
||||
+ExecStart=test -w %S/aaa/bbb
|
||||
+ExecStart=test -w %S/aaa/ccc
|
||||
+ExecStart=test -w %S/xxx
|
||||
+ExecStart=test -w %S/xxx/yyy
|
||||
+ExecStart=test -w %S/xxx/zzz
|
||||
+ExecStart=test -w %S/aaa/111
|
||||
+ExecStart=test -w %S/aaa/222
|
||||
+ExecStart=test -w %S/aaa/333
|
||||
|
||||
-ExecStart=test -d /var/lib/waldo
|
||||
-ExecStart=test -d /var/lib/quux/pief
|
||||
-ExecStart=test -d /var/lib/aaa
|
||||
-ExecStart=test -d /var/lib/aaa/bbb
|
||||
-ExecStart=test -d /var/lib/aaa/ccc
|
||||
-ExecStart=test -d /var/lib/xxx
|
||||
-ExecStart=test -d /var/lib/xxx/yyy
|
||||
-ExecStart=test -d /var/lib/xxx/zzz
|
||||
-ExecStart=test -L /var/lib/aaa/111
|
||||
-ExecStart=test -L /var/lib/aaa/222
|
||||
-ExecStart=test -L /var/lib/aaa/333
|
||||
+ExecStart=test -d %S/waldo
|
||||
+ExecStart=test -d %S/quux/pief
|
||||
+ExecStart=test -d %S/aaa
|
||||
+ExecStart=test -d %S/aaa/bbb
|
||||
+ExecStart=test -d %S/aaa/ccc
|
||||
+ExecStart=test -d %S/xxx
|
||||
+ExecStart=test -d %S/xxx/yyy
|
||||
+ExecStart=test -d %S/xxx/zzz
|
||||
+ExecStart=test -L %S/aaa/111
|
||||
+ExecStart=test -L %S/aaa/222
|
||||
+ExecStart=test -L %S/aaa/333
|
||||
|
||||
-ExecStart=touch /var/lib/waldo/hoge
|
||||
-ExecStart=touch /var/lib/quux/pief/hoge
|
||||
-ExecStart=touch /var/lib/aaa/hoge
|
||||
-ExecStart=touch /var/lib/aaa/bbb/hoge
|
||||
-ExecStart=touch /var/lib/aaa/ccc/hoge
|
||||
-ExecStart=touch /var/lib/xxx/hoge
|
||||
-ExecStart=touch /var/lib/xxx/yyy/hoge
|
||||
-ExecStart=touch /var/lib/xxx/zzz/hoge
|
||||
-ExecStart=touch /var/lib/aaa/111/foo
|
||||
-ExecStart=touch /var/lib/aaa/222/foo
|
||||
-ExecStart=touch /var/lib/aaa/333/foo
|
||||
+ExecStart=touch %S/waldo/hoge
|
||||
+ExecStart=touch %S/quux/pief/hoge
|
||||
+ExecStart=touch %S/aaa/hoge
|
||||
+ExecStart=touch %S/aaa/bbb/hoge
|
||||
+ExecStart=touch %S/aaa/ccc/hoge
|
||||
+ExecStart=touch %S/xxx/hoge
|
||||
+ExecStart=touch %S/xxx/yyy/hoge
|
||||
+ExecStart=touch %S/xxx/zzz/hoge
|
||||
+ExecStart=touch %S/aaa/111/foo
|
||||
+ExecStart=touch %S/aaa/222/foo
|
||||
+ExecStart=touch %S/aaa/333/foo
|
||||
|
||||
-ExecStart=test -f /var/lib/waldo/hoge
|
||||
-ExecStart=test -f /var/lib/quux/pief/hoge
|
||||
-ExecStart=test -f /var/lib/aaa/hoge
|
||||
-ExecStart=test -f /var/lib/aaa/bbb/hoge
|
||||
-ExecStart=test -f /var/lib/aaa/ccc/hoge
|
||||
-ExecStart=test -f /var/lib/xxx/hoge
|
||||
-ExecStart=test -f /var/lib/xxx/yyy/hoge
|
||||
-ExecStart=test -f /var/lib/xxx/zzz/hoge
|
||||
-ExecStart=test -f /var/lib/aaa/111/foo
|
||||
-ExecStart=test -f /var/lib/aaa/222/foo
|
||||
-ExecStart=test -f /var/lib/aaa/333/foo
|
||||
-ExecStart=test -f /var/lib/xxx/foo
|
||||
-ExecStart=test -f /var/lib/xxx/yyy/foo
|
||||
-ExecStart=test -f /var/lib/xxx/zzz/foo
|
||||
+ExecStart=test -f %S/waldo/hoge
|
||||
+ExecStart=test -f %S/quux/pief/hoge
|
||||
+ExecStart=test -f %S/aaa/hoge
|
||||
+ExecStart=test -f %S/aaa/bbb/hoge
|
||||
+ExecStart=test -f %S/aaa/ccc/hoge
|
||||
+ExecStart=test -f %S/xxx/hoge
|
||||
+ExecStart=test -f %S/xxx/yyy/hoge
|
||||
+ExecStart=test -f %S/xxx/zzz/hoge
|
||||
+ExecStart=test -f %S/aaa/111/foo
|
||||
+ExecStart=test -f %S/aaa/222/foo
|
||||
+ExecStart=test -f %S/aaa/333/foo
|
||||
+ExecStart=test -f %S/xxx/foo
|
||||
+ExecStart=test -f %S/xxx/yyy/foo
|
||||
+ExecStart=test -f %S/xxx/zzz/foo
|
||||
|
||||
-ExecStart=test -f /var/lib/private/waldo/hoge
|
||||
-ExecStart=test -f /var/lib/private/quux/pief/hoge
|
||||
-ExecStart=test -f /var/lib/private/aaa/hoge
|
||||
-ExecStart=test -f /var/lib/private/aaa/bbb/hoge
|
||||
-ExecStart=test -f /var/lib/private/aaa/ccc/hoge
|
||||
-ExecStart=test -f /var/lib/private/xxx/hoge
|
||||
-ExecStart=test -f /var/lib/private/xxx/yyy/hoge
|
||||
-ExecStart=test -f /var/lib/private/xxx/zzz/hoge
|
||||
-ExecStart=test -f /var/lib/private/aaa/111/foo
|
||||
-ExecStart=test -f /var/lib/private/aaa/222/foo
|
||||
-ExecStart=test -f /var/lib/private/aaa/333/foo
|
||||
-ExecStart=test -f /var/lib/private/xxx/foo
|
||||
-ExecStart=test -f /var/lib/private/xxx/yyy/foo
|
||||
-ExecStart=test -f /var/lib/private/xxx/zzz/foo
|
||||
+ExecStart=test -f %S/private/waldo/hoge
|
||||
+ExecStart=test -f %S/private/quux/pief/hoge
|
||||
+ExecStart=test -f %S/private/aaa/hoge
|
||||
+ExecStart=test -f %S/private/aaa/bbb/hoge
|
||||
+ExecStart=test -f %S/private/aaa/ccc/hoge
|
||||
+ExecStart=test -f %S/private/xxx/hoge
|
||||
+ExecStart=test -f %S/private/xxx/yyy/hoge
|
||||
+ExecStart=test -f %S/private/xxx/zzz/hoge
|
||||
+ExecStart=test -f %S/private/aaa/111/foo
|
||||
+ExecStart=test -f %S/private/aaa/222/foo
|
||||
+ExecStart=test -f %S/private/aaa/333/foo
|
||||
+ExecStart=test -f %S/private/xxx/foo
|
||||
+ExecStart=test -f %S/private/xxx/yyy/foo
|
||||
+ExecStart=test -f %S/private/xxx/zzz/foo
|
||||
|
||||
ExecStart=sh -x -c 'test "$$STATE_DIRECTORY" = "%S/aaa:%S/aaa/bbb:%S/aaa/ccc:%S/quux/pief:%S/waldo:%S/xxx:%S/xxx/yyy:%S/xxx/zzz"'
|
||||
|
||||
diff --git a/test/test-execute/exec-privatenetwork-yes.service b/test/test-execute/exec-privatenetwork-yes.service
|
||||
index 0fff048b94..360099d337 100644
|
||||
--- a/test/test-execute/exec-privatenetwork-yes.service
|
||||
+++ b/test/test-execute/exec-privatenetwork-yes.service
|
||||
@@ -4,5 +4,6 @@ Description=Test for PrivateNetwork
|
||||
|
||||
[Service]
|
||||
ExecStart=/bin/sh -x -c '! ip link | grep -E "^[0-9]+: " | grep -Ev ": (lo|(erspan|gre|gretap|ip_vti|ip6_vti|ip6gre|ip6tnl|sit|tunl)0@.*):"'
|
||||
+ExecStart=/bin/sh -x -c '! ip link | grep -E "^[0-9]+: " | grep -F ": dummy-test-exec:"'
|
||||
Type=oneshot
|
||||
PrivateNetwork=yes
|
||||
diff --git a/test/test-execute/exec-specifier-system.service b/test/test-execute/exec-specifier-system.service
|
||||
new file mode 100644
|
||||
index 0000000000..9e8ee567aa
|
||||
--- /dev/null
|
||||
+++ b/test/test-execute/exec-specifier-system.service
|
||||
@@ -0,0 +1,11 @@
|
||||
+# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
+[Unit]
|
||||
+Description=Test for specifiers (system)
|
||||
+
|
||||
+[Service]
|
||||
+Type=oneshot
|
||||
+ExecStart=test %t = /run
|
||||
+ExecStart=test %S = /var/lib
|
||||
+ExecStart=test %C = /var/cache
|
||||
+ExecStart=test %L = /var/log
|
||||
+ExecStart=test %E = /etc
|
||||
diff --git a/test/test-execute/exec-specifier-user.service b/test/test-execute/exec-specifier-user.service
|
||||
new file mode 100644
|
||||
index 0000000000..ee0301a426
|
||||
--- /dev/null
|
||||
+++ b/test/test-execute/exec-specifier-user.service
|
||||
@@ -0,0 +1,11 @@
|
||||
+# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
+[Unit]
|
||||
+Description=Test for specifiers
|
||||
+
|
||||
+[Service]
|
||||
+Type=oneshot
|
||||
+ExecStart=sh -c 'test %t = $$XDG_RUNTIME_DIR'
|
||||
+ExecStart=sh -c 'test %S = %h/.config'
|
||||
+ExecStart=sh -c 'test %C = %h/.cache'
|
||||
+ExecStart=sh -c 'test %L = %h/.config/log'
|
||||
+ExecStart=sh -c 'test %E = %h/.config'
|
||||
diff --git a/test/test-execute/exec-specifier.service b/test/test-execute/exec-specifier.service
|
||||
index 2b487bae8c..512f786f83 100644
|
||||
--- a/test/test-execute/exec-specifier.service
|
||||
+++ b/test/test-execute/exec-specifier.service
|
||||
@@ -13,11 +13,6 @@ ExecStart=test %I = ""
|
||||
ExecStart=test %j = specifier
|
||||
ExecStart=test %J = specifier
|
||||
ExecStart=test %f = /exec/specifier
|
||||
-ExecStart=test %t = /run
|
||||
-ExecStart=test %S = /var/lib
|
||||
-ExecStart=test %C = /var/cache
|
||||
-ExecStart=test %L = /var/log
|
||||
-ExecStart=test %E = /etc
|
||||
ExecStart=test %T = /tmp
|
||||
ExecStart=test %V = /var/tmp
|
||||
ExecStart=test %d = %t/credentials/%n
|
||||
diff --git a/test/test-execute/exec-specifier@.service b/test/test-execute/exec-specifier@.service
|
||||
index 69e969f716..cb9d0a182a 100644
|
||||
--- a/test/test-execute/exec-specifier@.service
|
||||
+++ b/test/test-execute/exec-specifier@.service
|
||||
@@ -13,11 +13,6 @@ ExecStart=test %I = foo/bar
|
||||
ExecStart=test %j = specifier
|
||||
ExecStart=test %J = specifier
|
||||
ExecStart=test %f = /foo/bar
|
||||
-ExecStart=test %t = /run
|
||||
-ExecStart=test %S = /var/lib
|
||||
-ExecStart=test %C = /var/cache
|
||||
-ExecStart=test %L = /var/log
|
||||
-ExecStart=test %E = /etc
|
||||
ExecStart=sh -c 'test %u = $$(id -un)'
|
||||
ExecStart=sh -c 'test %U = $$(id -u)'
|
||||
ExecStart=sh -c 'test %g = $$(id -gn)'
|
96
0786-tmpfiles-Add-merge-support-for-copy-files-action.patch
Normal file
96
0786-tmpfiles-Add-merge-support-for-copy-files-action.patch
Normal file
@ -0,0 +1,96 @@
|
||||
From 129f8896018377cfe9a64e2877517124b79ca87f Mon Sep 17 00:00:00 2001
|
||||
From: Daan De Meyer <daan.j.demeyer@gmail.com>
|
||||
Date: Tue, 9 May 2023 13:45:16 +0200
|
||||
Subject: [PATCH] tmpfiles: Add merge support for copy files action
|
||||
|
||||
If '+' is specified with 'C', let's merge the tree with any existing
|
||||
tree.
|
||||
|
||||
(cherry picked from commit 1fd5ec5697680e2ec6277431bd74cabf48dbc94f)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
man/tmpfiles.d.xml | 22 +++++++++++-----------
|
||||
src/tmpfiles/tmpfiles.c | 2 +-
|
||||
test/units/testsuite-22.02.sh | 16 ++++++++++++++++
|
||||
3 files changed, 28 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml
|
||||
index bd3bc33ab4..fe2a1dadab 100644
|
||||
--- a/man/tmpfiles.d.xml
|
||||
+++ b/man/tmpfiles.d.xml
|
||||
@@ -58,10 +58,11 @@ c+ /dev/char-device-to-[re]create mode user group - major
|
||||
b /dev/block-device-to-create mode user group - major:minor
|
||||
b+ /dev/block-device-to-[re]create mode user group - major:minor
|
||||
C /target/to/create - - - cleanup-age /source/to/copy
|
||||
+C+ /target/to/create - - - cleanup-age /source/to/copy
|
||||
x /path-or-glob/to/ignore/recursively - - - cleanup-age -
|
||||
X /path-or-glob/to/ignore - - - cleanup-age -
|
||||
-r /empty/dir/to/remove - - - - -
|
||||
-R /dir/to/remove/recursively - - - - -
|
||||
+r /path-or-glob/to/remove - - - - -
|
||||
+R /path-or-glob/to/remove/recursively - - - - -
|
||||
z /path-or-glob/to/adjust/mode mode user group - -
|
||||
Z /path-or-glob/to/adjust/mode/recursively mode user group - -
|
||||
t /path-or-glob/to/set/xattrs - - - - xattrs
|
||||
@@ -325,15 +326,14 @@ L /tmp/foobar - - - - /dev/null</programlisting>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>C</varname></term>
|
||||
- <listitem><para>Recursively copy a file or directory, if the
|
||||
- destination files or directories do not exist yet or the
|
||||
- destination directory is empty. Note that this command will not
|
||||
- descend into subdirectories if the destination directory already
|
||||
- exists and is not empty. Instead, the entire copy operation is
|
||||
- skipped. If the argument is omitted, files from the source directory
|
||||
- <filename>/usr/share/factory/</filename> with the same name
|
||||
- are copied. Does not follow symlinks. Contents of the directories
|
||||
- are subject to time based cleanup if the age argument is specified.
|
||||
+ <term><varname>C+</varname></term>
|
||||
+ <listitem><para>Recursively copy a file or directory, if the destination files or directories do
|
||||
+ not exist yet or the destination directory is empty. Note that this command will not descend into
|
||||
+ subdirectories if the destination directory already exists and is not empty, unless the action is
|
||||
+ suffixed with <varname>+</varname>. Instead, the entire copy operation is skipped. If the argument
|
||||
+ is omitted, files from the source directory <filename>/usr/share/factory/</filename> with the same
|
||||
+ name are copied. Does not follow symlinks. Contents of the directories are subject to time-based
|
||||
+ cleanup if the age argument is specified.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
|
||||
index 18bb75715b..ead5c49874 100644
|
||||
--- a/src/tmpfiles/tmpfiles.c
|
||||
+++ b/src/tmpfiles/tmpfiles.c
|
||||
@@ -1648,7 +1648,7 @@ static int copy_files(Item *i) {
|
||||
dfd, bn,
|
||||
i->uid_set ? i->uid : UID_INVALID,
|
||||
i->gid_set ? i->gid : GID_INVALID,
|
||||
- COPY_REFLINK | COPY_MERGE_EMPTY | COPY_MAC_CREATE | COPY_HARDLINKS);
|
||||
+ COPY_REFLINK | ((i->append_or_force) ? COPY_MERGE : COPY_MERGE_EMPTY) | COPY_MAC_CREATE | COPY_HARDLINKS);
|
||||
|
||||
fd = openat(dfd, bn, O_NOFOLLOW|O_CLOEXEC|O_PATH);
|
||||
if (fd < 0) {
|
||||
diff --git a/test/units/testsuite-22.02.sh b/test/units/testsuite-22.02.sh
|
||||
index 49c55f136b..f233be2499 100755
|
||||
--- a/test/units/testsuite-22.02.sh
|
||||
+++ b/test/units/testsuite-22.02.sh
|
||||
@@ -121,3 +121,19 @@ EOF
|
||||
|
||||
test "$(stat -c %U:%G:%a /tmp/C/3/f1)" = "root:root:644"
|
||||
test ! -e /tmp/C/4
|
||||
+
|
||||
+touch /tmp/C/3-origin/f{2,3,4}
|
||||
+echo -n ABC > /tmp/C/3/f1
|
||||
+
|
||||
+systemd-tmpfiles --create - <<EOF
|
||||
+C+ /tmp/C/3 0755 daemon daemon - /tmp/C/3-origin
|
||||
+EOF
|
||||
+
|
||||
+# Test that the trees got merged, even though /tmp/C/3 already exists.
|
||||
+test -e /tmp/C/3/f1
|
||||
+test -e /tmp/C/3/f2
|
||||
+test -e /tmp/C/3/f3
|
||||
+test -e /tmp/C/3/f4
|
||||
+
|
||||
+# Test that /tmp/C/3/f1 did not get overwritten.
|
||||
+test "$(cat /tmp/C/3/f1)" = "ABC"
|
116
0787-generator-add-generator_open_unit_file_full-to-allow.patch
Normal file
116
0787-generator-add-generator_open_unit_file_full-to-allow.patch
Normal file
@ -0,0 +1,116 @@
|
||||
From 1e4f0fdb8d684007fa0c9747181a8ca70da5eaae Mon Sep 17 00:00:00 2001
|
||||
From: Antonio Alvarez Feijoo <antonio.feijoo@suse.com>
|
||||
Date: Mon, 10 Apr 2023 15:18:33 +0200
|
||||
Subject: [PATCH] generator: add generator_open_unit_file_full to allow
|
||||
creating temporary units
|
||||
|
||||
This function is like `generator_open_unit_file`, but if `ret_temp_path` is
|
||||
passed, a temporary unit is created instead.
|
||||
|
||||
(cherry picked from commit 8a84e0d7960b7970c16a4efd4c5b0b26c810d22d)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/shared/generator.c | 46 ++++++++++++++++++++++++++++--------------
|
||||
src/shared/generator.h | 10 ++++-----
|
||||
2 files changed, 36 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/src/shared/generator.c b/src/shared/generator.c
|
||||
index 284e5fc580..29de8ada6b 100644
|
||||
--- a/src/shared/generator.c
|
||||
+++ b/src/shared/generator.c
|
||||
@@ -20,42 +20,58 @@
|
||||
#include "specifier.h"
|
||||
#include "string-util.h"
|
||||
#include "time-util.h"
|
||||
+#include "tmpfile-util.h"
|
||||
#include "unit-name.h"
|
||||
#include "util.h"
|
||||
|
||||
-int generator_open_unit_file(
|
||||
+int generator_open_unit_file_full(
|
||||
const char *dir,
|
||||
const char *source,
|
||||
const char *fn,
|
||||
- FILE **ret) {
|
||||
+ FILE **ret_file,
|
||||
+ char **ret_temp_path) {
|
||||
|
||||
_cleanup_free_ char *p = NULL;
|
||||
FILE *f;
|
||||
int r;
|
||||
|
||||
assert(dir);
|
||||
- assert(fn);
|
||||
- assert(ret);
|
||||
+ assert(ret_file);
|
||||
|
||||
- p = path_join(dir, fn);
|
||||
- if (!p)
|
||||
- return log_oom();
|
||||
+ /* If <ret_temp_path> is specified, it creates a temporary unit file and also returns its
|
||||
+ * temporary path. */
|
||||
|
||||
- r = fopen_unlocked(p, "wxe", &f);
|
||||
- if (r < 0) {
|
||||
- if (source && r == -EEXIST)
|
||||
- return log_error_errno(r,
|
||||
- "Failed to create unit file '%s', as it already exists. Duplicate entry in '%s'?",
|
||||
- p, source);
|
||||
+ if (ret_temp_path) {
|
||||
+ r = fopen_temporary(dir, &f, &p);
|
||||
+ if (r < 0)
|
||||
+ return log_error_errno(r, "Failed to create temporary unit file in '%s': %m", dir);
|
||||
+
|
||||
+ (void) fchmod(fileno(f), 0644);
|
||||
|
||||
- return log_error_errno(r, "Failed to create unit file '%s': %m", p);
|
||||
+ *ret_temp_path = TAKE_PTR(p);
|
||||
+ } else {
|
||||
+ assert(fn);
|
||||
+
|
||||
+ p = path_join(dir, fn);
|
||||
+ if (!p)
|
||||
+ return log_oom();
|
||||
+
|
||||
+ r = fopen_unlocked(p, "wxe", &f);
|
||||
+ if (r < 0) {
|
||||
+ if (source && r == -EEXIST)
|
||||
+ return log_error_errno(r,
|
||||
+ "Failed to create unit file '%s', as it already exists. Duplicate entry in '%s'?",
|
||||
+ p, source);
|
||||
+
|
||||
+ return log_error_errno(r, "Failed to create unit file '%s': %m", p);
|
||||
+ }
|
||||
}
|
||||
|
||||
fprintf(f,
|
||||
"# Automatically generated by %s\n\n",
|
||||
program_invocation_short_name);
|
||||
|
||||
- *ret = f;
|
||||
+ *ret_file = f;
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/src/shared/generator.h b/src/shared/generator.h
|
||||
index 111900fd45..d97d6edc67 100644
|
||||
--- a/src/shared/generator.h
|
||||
+++ b/src/shared/generator.h
|
||||
@@ -6,11 +6,11 @@
|
||||
#include "macro.h"
|
||||
#include "main-func.h"
|
||||
|
||||
-int generator_open_unit_file(
|
||||
- const char *dest,
|
||||
- const char *source,
|
||||
- const char *name,
|
||||
- FILE **file);
|
||||
+int generator_open_unit_file_full(const char *dest, const char *source, const char *name, FILE **ret_file, char **ret_temp_path);
|
||||
+
|
||||
+static inline int generator_open_unit_file(const char *dest, const char *source, const char *name, FILE **ret_file) {
|
||||
+ return generator_open_unit_file_full(dest, source, name, ret_file, NULL);
|
||||
+}
|
||||
|
||||
int generator_add_symlink_full(const char *dir, const char *dst, const char *dep_type, const char *src, const char *instance);
|
||||
|
142
0788-network-generator-rewrite-unit-if-it-already-exists-.patch
Normal file
142
0788-network-generator-rewrite-unit-if-it-already-exists-.patch
Normal file
@ -0,0 +1,142 @@
|
||||
From 8d7665b3e327deb0868b97a159acfdb266a6a5e9 Mon Sep 17 00:00:00 2001
|
||||
From: Antonio Alvarez Feijoo <antonio.feijoo@suse.com>
|
||||
Date: Mon, 10 Apr 2023 15:18:53 +0200
|
||||
Subject: [PATCH] network-generator: rewrite unit if it already exists and its
|
||||
content changed
|
||||
|
||||
When the `systemd-network-generator` is included in the initrd and runs from
|
||||
there first, the next times it runs after switching to real root it
|
||||
thinks there is a duplicate entry on the kernel command line.
|
||||
|
||||
This patch rewrites the unit file if the content has changed, instead of
|
||||
displaying an error message.
|
||||
|
||||
(cherry picked from commit f3e4d04298bb73b836dd7ca90f7c7b09de1e776b)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/network/generator/main.c | 55 ++++++++++++++++++++++++++++--------
|
||||
1 file changed, 43 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/src/network/generator/main.c b/src/network/generator/main.c
|
||||
index a36fe98c86..2574bc1136 100644
|
||||
--- a/src/network/generator/main.c
|
||||
+++ b/src/network/generator/main.c
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <getopt.h>
|
||||
|
||||
#include "fd-util.h"
|
||||
+#include "fs-util.h"
|
||||
#include "generator.h"
|
||||
#include "macro.h"
|
||||
#include "main-func.h"
|
||||
@@ -16,67 +17,97 @@
|
||||
static const char *arg_root = NULL;
|
||||
|
||||
static int network_save(Network *network, const char *dest_dir) {
|
||||
- _cleanup_free_ char *filename = NULL;
|
||||
+ _cleanup_free_ char *filename = NULL, *p = NULL;
|
||||
+ _cleanup_(unlink_and_freep) char *temp_path = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
int r;
|
||||
|
||||
assert(network);
|
||||
|
||||
+ r = generator_open_unit_file_full(dest_dir, NULL, NULL, &f, &temp_path);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ network_dump(network, f);
|
||||
+
|
||||
r = asprintf(&filename, "%s-%s.network",
|
||||
isempty(network->ifname) ? "91" : "90",
|
||||
isempty(network->ifname) ? "default" : network->ifname);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
- r = generator_open_unit_file(dest_dir, "kernel command line", filename, &f);
|
||||
+ p = path_join(dest_dir, filename);
|
||||
+ if (!p)
|
||||
+ return log_oom();
|
||||
+
|
||||
+ r = conservative_rename(temp_path, p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
- network_dump(network, f);
|
||||
-
|
||||
+ temp_path = mfree(temp_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int netdev_save(NetDev *netdev, const char *dest_dir) {
|
||||
- _cleanup_free_ char *filename = NULL;
|
||||
+ _cleanup_free_ char *filename = NULL, *p = NULL;
|
||||
+ _cleanup_(unlink_and_freep) char *temp_path = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
int r;
|
||||
|
||||
assert(netdev);
|
||||
|
||||
+ r = generator_open_unit_file_full(dest_dir, NULL, NULL, &f, &temp_path);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ netdev_dump(netdev, f);
|
||||
+
|
||||
r = asprintf(&filename, "90-%s.netdev",
|
||||
netdev->ifname);
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
- r = generator_open_unit_file(dest_dir, "kernel command line", filename, &f);
|
||||
+ p = path_join(dest_dir, filename);
|
||||
+ if (!p)
|
||||
+ return log_oom();
|
||||
+
|
||||
+ r = conservative_rename(temp_path, p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
- netdev_dump(netdev, f);
|
||||
-
|
||||
+ temp_path = mfree(temp_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int link_save(Link *link, const char *dest_dir) {
|
||||
- _cleanup_free_ char *filename = NULL;
|
||||
+ _cleanup_free_ char *filename = NULL, *p = NULL;
|
||||
+ _cleanup_(unlink_and_freep) char *temp_path = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
|
||||
+ r = generator_open_unit_file_full(dest_dir, NULL, NULL, &f, &temp_path);
|
||||
+ if (r < 0)
|
||||
+ return r;
|
||||
+
|
||||
+ link_dump(link, f);
|
||||
+
|
||||
filename = strjoin(!isempty(link->ifname) ? "90" :
|
||||
!hw_addr_is_null(&link->mac) ? "91" : "92",
|
||||
"-", link->filename, ".link");
|
||||
if (!filename)
|
||||
return log_oom();
|
||||
|
||||
- r = generator_open_unit_file(dest_dir, "kernel command line", filename, &f);
|
||||
+ p = path_join(dest_dir, filename);
|
||||
+ if (!p)
|
||||
+ return log_oom();
|
||||
+
|
||||
+ r = conservative_rename(temp_path, p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
- link_dump(link, f);
|
||||
-
|
||||
+ temp_path = mfree(temp_path);
|
||||
return 0;
|
||||
}
|
||||
|
38
0789-ci-drop-super-linter-s-shellcheck.patch
Normal file
38
0789-ci-drop-super-linter-s-shellcheck.patch
Normal file
@ -0,0 +1,38 @@
|
||||
From 696206a798647adc73faab26ab5b7543df939372 Mon Sep 17 00:00:00 2001
|
||||
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||
Date: Mon, 17 Jul 2023 17:54:59 +0200
|
||||
Subject: [PATCH] ci: drop super-linter's shellcheck
|
||||
|
||||
It's been a while since we introduced Differential ShellCheck and it
|
||||
proved to be quite useful (and in some ways even better than the shellcheck
|
||||
run by super-linter). So, to have only one linter scream at us for not
|
||||
knowing how to write bash properly, let's drop the super-linter's one in
|
||||
favor of Differential ShellCheck.
|
||||
|
||||
Follow-up for https://github.com/systemd/systemd/pull/24328#pullrequestreview-1074127504
|
||||
|
||||
(cherry picked from commit c4b167f857fe5c228da4d4950a3eae13f53c645c)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
.github/workflows/linter.yml | 8 --------
|
||||
1 file changed, 8 deletions(-)
|
||||
|
||||
diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml
|
||||
index eddd350122..8dd3b075ad 100644
|
||||
--- a/.github/workflows/linter.yml
|
||||
+++ b/.github/workflows/linter.yml
|
||||
@@ -32,13 +32,5 @@ jobs:
|
||||
uses: github/super-linter/slim@01d3218744765b55c3b5ffbb27e50961e50c33c5
|
||||
env:
|
||||
DEFAULT_BRANCH: main
|
||||
- MULTI_STATUS: false
|
||||
- # Excludes:
|
||||
- # - man/.* - all snippets in man pages (false positives due to
|
||||
- # missing shebangs)
|
||||
- # - .*\.(in|SKELETON) - all template/skeleton files
|
||||
- # except kernel-install
|
||||
- FILTER_REGEX_EXCLUDE: .*/(man/.*|([^k]|k(k|ek)*([^ek]|e[^kr]))*(k(k|ek)*e?)?\.(in|SKELETON))$
|
||||
VALIDATE_ALL_CODEBASE: false
|
||||
- VALIDATE_BASH: true
|
||||
VALIDATE_GITHUB_ACTIONS: true
|
130
0790-mkosi-make-sure-we-build-use-RHEL-9-stuff.patch
Normal file
130
0790-mkosi-make-sure-we-build-use-RHEL-9-stuff.patch
Normal file
@ -0,0 +1,130 @@
|
||||
From 57d14d938573b0670d3205bf27a416bcf18424d4 Mon Sep 17 00:00:00 2001
|
||||
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||
Date: Wed, 28 Feb 2024 12:15:44 +0100
|
||||
Subject: [PATCH] mkosi: make sure we build & use RHEL 9 stuff
|
||||
|
||||
- drop Hyperscale SIG repos, so we don't pull in btrfs stuff
|
||||
- use XFS for rootfs
|
||||
- install gnu-efi headers, since RHEL 9 sd-boot still requires it
|
||||
|
||||
RHEL-only
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
mkosi.conf | 2 +-
|
||||
mkosi.conf.d/10-centos.conf | 2 +-
|
||||
mkosi.images/base/mkosi.build.chroot | 8 ++++++++
|
||||
.../base/mkosi.conf.d/10-centos-fedora.conf | 2 ++
|
||||
.../usr/lib/systemd/system-preset/00-mkosi.preset | 13 ++++---------
|
||||
.../system/mkosi.conf.d/10-centos-fedora.conf | 1 +
|
||||
.../mkosi.extra/usr/lib/repart.d/20-root.conf | 3 +--
|
||||
7 files changed, 18 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/mkosi.conf b/mkosi.conf
|
||||
index 9ec4faf122..d5cde391dd 100644
|
||||
--- a/mkosi.conf
|
||||
+++ b/mkosi.conf
|
||||
@@ -23,7 +23,7 @@ KernelCommandLineExtra=systemd.crash_shell
|
||||
systemd.log_level=debug
|
||||
systemd.log_ratelimit_kmsg=0
|
||||
systemd.journald.forward_to_console
|
||||
- systemd.journald.max_level_console=warning
|
||||
+ systemd.journald.max_level_console=info
|
||||
# Disable the kernel's ratelimiting on userspace logging to kmsg.
|
||||
printk.devkmsg=on
|
||||
# Make sure /sysroot is mounted rw in the initrd.
|
||||
diff --git a/mkosi.conf.d/10-centos.conf b/mkosi.conf.d/10-centos.conf
|
||||
index ae2706c791..a740548d46 100644
|
||||
--- a/mkosi.conf.d/10-centos.conf
|
||||
+++ b/mkosi.conf.d/10-centos.conf
|
||||
@@ -7,4 +7,4 @@ Distribution=centos
|
||||
@Release=9
|
||||
Repositories=epel
|
||||
epel-next
|
||||
- hyperscale-packages-main
|
||||
+ crb
|
||||
diff --git a/mkosi.images/base/mkosi.build.chroot b/mkosi.images/base/mkosi.build.chroot
|
||||
index ba0c92eef2..3427d0e241 100755
|
||||
--- a/mkosi.images/base/mkosi.build.chroot
|
||||
+++ b/mkosi.images/base/mkosi.build.chroot
|
||||
@@ -106,6 +106,14 @@ if [ ! -f "$BUILDDIR"/build.ninja ]; then
|
||||
-D xenctrl="$([[ "$ID" =~ debian|ubuntu|fedora|opensuse ]] && echo true || echo false)"
|
||||
-D libiptc="$([[ "$ID" =~ debian|ubuntu ]] && echo true || echo false)"
|
||||
-D libcryptsetup-plugins="$([[ "$ID" = "centos" ]] && [[ "$VERSION" = "8" ]] && echo false || echo true)"
|
||||
+ # Necessary on RHEL 9 to build sd-boot stuff
|
||||
+ -D gnu-efi=true
|
||||
+ # Disable stuff we don't build on RHEL
|
||||
+ -D timesyncd=false
|
||||
+ -D homed=false
|
||||
+ -D userdb=false
|
||||
+ -D portabled=false
|
||||
+ -D networkd=false
|
||||
)
|
||||
|
||||
# On debian-like systems the library directory is not /usr/lib64 but /usr/lib/<arch-triplet>/.
|
||||
diff --git a/mkosi.images/base/mkosi.conf.d/10-centos-fedora.conf b/mkosi.images/base/mkosi.conf.d/10-centos-fedora.conf
|
||||
index d7a135a5c0..b25b7b4185 100644
|
||||
--- a/mkosi.images/base/mkosi.conf.d/10-centos-fedora.conf
|
||||
+++ b/mkosi.images/base/mkosi.conf.d/10-centos-fedora.conf
|
||||
@@ -29,6 +29,8 @@ BuildPackages=
|
||||
bpftool
|
||||
docbook-xsl
|
||||
findutils
|
||||
+ gnu-efi-compat # Necessary for sd-boot on RHEL 9
|
||||
+ gnu-efi-devel # Necessary for sd-boot on RHEL 9
|
||||
libgcrypt-devel # CentOS Stream 8 libgcrypt-devel doesn't ship a pkg-config file.
|
||||
libxslt
|
||||
pam-devel
|
||||
diff --git a/mkosi.images/base/mkosi.extra/usr/lib/systemd/system-preset/00-mkosi.preset b/mkosi.images/base/mkosi.extra/usr/lib/systemd/system-preset/00-mkosi.preset
|
||||
index 070af4c67a..42e5af3ec9 100644
|
||||
--- a/mkosi.images/base/mkosi.extra/usr/lib/systemd/system-preset/00-mkosi.preset
|
||||
+++ b/mkosi.images/base/mkosi.extra/usr/lib/systemd/system-preset/00-mkosi.preset
|
||||
@@ -9,16 +9,9 @@ disable dnsmasq.service
|
||||
disable isc-dhcp-server.service
|
||||
disable isc-dhcp-server6.service
|
||||
|
||||
-# Pulled in via dracut-network by kexec-tools on Fedora.
|
||||
-disable NetworkManager*
|
||||
-
|
||||
# Make sure dbus-broker is started by default on Debian/Ubuntu.
|
||||
enable dbus-broker.service
|
||||
|
||||
-# systemd-networkd is disabled by default on Fedora so make sure it is enabled.
|
||||
-enable systemd-networkd.service
|
||||
-enable systemd-networkd-wait-online.service
|
||||
-
|
||||
# We install dnf in some images but it's only going to be used rarely,
|
||||
# so let's not have dnf create its cache.
|
||||
disable dnf-makecache.*
|
||||
@@ -26,5 +19,7 @@ disable dnf-makecache.*
|
||||
# We have journald to receive audit data so let's make sure we're not running auditd as well
|
||||
disable auditd.service
|
||||
|
||||
-# systemd-timesyncd is not enabled by default in the default systemd preset so enable it here instead.
|
||||
-enable systemd-timesyncd.service
|
||||
+# We don't ship sd-networkd on RHEL 9, so replace it with NM
|
||||
+disable systemd-networkd.service
|
||||
+disable systemd-networkd-wait-online.service
|
||||
+enable NetworkManager*
|
||||
diff --git a/mkosi.images/system/mkosi.conf.d/10-centos-fedora.conf b/mkosi.images/system/mkosi.conf.d/10-centos-fedora.conf
|
||||
index 871186d5ca..23cfd4ecc0 100644
|
||||
--- a/mkosi.images/system/mkosi.conf.d/10-centos-fedora.conf
|
||||
+++ b/mkosi.images/system/mkosi.conf.d/10-centos-fedora.conf
|
||||
@@ -31,3 +31,4 @@ Packages=
|
||||
python3dist(pytest)
|
||||
quota
|
||||
vim-common
|
||||
+ vim
|
||||
diff --git a/mkosi.images/system/mkosi.extra/usr/lib/repart.d/20-root.conf b/mkosi.images/system/mkosi.extra/usr/lib/repart.d/20-root.conf
|
||||
index 71eb9e38c4..31e8313263 100644
|
||||
--- a/mkosi.images/system/mkosi.extra/usr/lib/repart.d/20-root.conf
|
||||
+++ b/mkosi.images/system/mkosi.extra/usr/lib/repart.d/20-root.conf
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
[Partition]
|
||||
Type=root
|
||||
-Format=btrfs
|
||||
+Format=xfs
|
||||
SizeMinBytes=1G
|
||||
-Subvolumes=/home /var
|
||||
MakeDirectories=/home /var
|
217
0791-ci-backport-mkosi-CI-configuration-from-upstream.patch
Normal file
217
0791-ci-backport-mkosi-CI-configuration-from-upstream.patch
Normal file
@ -0,0 +1,217 @@
|
||||
From 45bcebd103f23fb595d0ff1d5e02ea5edd25f12d Mon Sep 17 00:00:00 2001
|
||||
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||
Date: Tue, 27 Feb 2024 12:53:35 +0100
|
||||
Subject: [PATCH] ci: backport mkosi CI configuration from upstream
|
||||
|
||||
Notes:
|
||||
- on RHEL 9 we don't have vsock support in systemd, so we have to fall
|
||||
back to some "older" checks (i.e. pre-6aca147f82).
|
||||
- our systemd-repart doesn't automatically fall back to Format=swap
|
||||
for Type=swap partitions, so we have to do that explicitely
|
||||
- don't pull in sd-resolved and sd-networkd, since the former needs
|
||||
some extra configuration to work alongsideNM, and we don't
|
||||
build the latter at all on RHEL 9
|
||||
|
||||
RHEL-only
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
.github/workflows/mkosi.yml | 139 ++++++++++++++++++
|
||||
.../mkosi.extra/usr/lib/repart.d/15-swap.conf | 1 +
|
||||
.../lib/systemd/mkosi-check-and-shutdown.sh | 3 +
|
||||
.../system/mkosi-check-and-shutdown.service | 5 +-
|
||||
4 files changed, 144 insertions(+), 4 deletions(-)
|
||||
create mode 100644 .github/workflows/mkosi.yml
|
||||
|
||||
diff --git a/.github/workflows/mkosi.yml b/.github/workflows/mkosi.yml
|
||||
new file mode 100644
|
||||
index 0000000000..f9b6d9ba58
|
||||
--- /dev/null
|
||||
+++ b/.github/workflows/mkosi.yml
|
||||
@@ -0,0 +1,139 @@
|
||||
+---
|
||||
+# vi: ts=2 sw=2 et:
|
||||
+# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
+# Simple boot tests that build and boot the mkosi images generated by the mkosi config files in mkosi.conf.d/.
|
||||
+name: mkosi
|
||||
+
|
||||
+on:
|
||||
+ push:
|
||||
+ branches:
|
||||
+ - main
|
||||
+ - v[0-9]+-stable
|
||||
+ paths:
|
||||
+ - '**'
|
||||
+ - '!README*'
|
||||
+ - '!LICENSE*'
|
||||
+ - '!LICENSES/**'
|
||||
+ - '!TODO'
|
||||
+ - '!docs/**'
|
||||
+ - '!man/**'
|
||||
+ - '!catalog/**'
|
||||
+ - '!shell-completion/**'
|
||||
+ - '!po/**'
|
||||
+ - '!.**'
|
||||
+ - '.github/**'
|
||||
+
|
||||
+ pull_request:
|
||||
+ branches:
|
||||
+ - main
|
||||
+ - v[0-9]+-stable
|
||||
+ paths:
|
||||
+ - '**'
|
||||
+ - '!README*'
|
||||
+ - '!LICENSE*'
|
||||
+ - '!LICENSES/**'
|
||||
+ - '!TODO'
|
||||
+ - '!docs/**'
|
||||
+ - '!man/**'
|
||||
+ - '!catalog/**'
|
||||
+ - '!shell-completion/**'
|
||||
+ - '!po/**'
|
||||
+ - '!.**'
|
||||
+ - '.github/**'
|
||||
+
|
||||
+permissions:
|
||||
+ contents: read
|
||||
+
|
||||
+jobs:
|
||||
+ ci:
|
||||
+ runs-on: ubuntu-22.04
|
||||
+ concurrency:
|
||||
+ group: ${{ github.workflow }}-${{ matrix.distro }}-${{ matrix.release }}-${{ github.ref }}
|
||||
+ cancel-in-progress: true
|
||||
+ strategy:
|
||||
+ fail-fast: false
|
||||
+ matrix:
|
||||
+ include:
|
||||
+ - distro: centos
|
||||
+ release: "9"
|
||||
+
|
||||
+ env:
|
||||
+ SYSTEMD_LOG_LEVEL: debug
|
||||
+
|
||||
+ steps:
|
||||
+ - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11
|
||||
+ - uses: systemd/mkosi@070528fec478fc93af7ec057a5d2fd0045123c99
|
||||
+
|
||||
+ - name: Configure
|
||||
+ run: |
|
||||
+ tee mkosi.local.conf <<EOF
|
||||
+ [Distribution]
|
||||
+ Distribution=${{ matrix.distro }}
|
||||
+ Release=${{ matrix.release }}
|
||||
+
|
||||
+ [Output]
|
||||
+ Format=disk
|
||||
+
|
||||
+ [Content]
|
||||
+ Environment=CI_BUILD=1
|
||||
+ SLOW_TESTS=true
|
||||
+
|
||||
+ [Host]
|
||||
+ ToolsTree=default
|
||||
+ ToolsTreeDistribution=fedora
|
||||
+ # Sometimes we run on a host with /dev/kvm, but it is broken, so explicitly disable it
|
||||
+ QemuKvm=no
|
||||
+ EOF
|
||||
+
|
||||
+ # These should override the options from mkosi.conf so we put them in a dropin that's ordered later
|
||||
+ # instead.
|
||||
+ tee mkosi.conf.d/99-ci.conf <<EOF
|
||||
+ [Host]
|
||||
+ KernelCommandLineExtra=systemd.unit=mkosi-check-and-shutdown.service
|
||||
+ systemd.journald.max_level_console=debug
|
||||
+ # udev's debug log output is very verbose, so up it to info in CI.
|
||||
+ udev.log_level=info
|
||||
+ # Root device can take a long time to appear, so let's bump the timeout.
|
||||
+ systemd.default_device_timeout_sec=180
|
||||
+ EOF
|
||||
+
|
||||
+ # For erofs, we have to install linux-modules-extra-azure, but that doesn't match the running kernel
|
||||
+ # version, so we can't load the erofs module. squashfs is a builtin module so we use that instead.
|
||||
+
|
||||
+ mkdir -p mkosi.images/system/mkosi.repart/10-usr.conf.d
|
||||
+ tee mkosi.images/system/mkosi.repart/10-usr.conf.d/squashfs.conf <<EOF
|
||||
+ [Partition]
|
||||
+ Format=squashfs
|
||||
+ EOF
|
||||
+
|
||||
+ # The emergency shell is not useful in the CI, as it just blocks for a long time before the job
|
||||
+ # eventually times out. Override it to just shutdown immediately.
|
||||
+ mkdir -p mkosi.images/initrd/mkosi.extra/usr/lib/systemd/system/emergency.service.d/
|
||||
+ mkdir -p mkosi.images/system/mkosi.extra/usr/lib/systemd/system/emergency.service.d/
|
||||
+ tee mkosi.images/initrd/mkosi.extra/usr/lib/systemd/system/emergency.service.d/poweroff.conf <<EOF
|
||||
+ [Unit]
|
||||
+ FailureAction=exit
|
||||
+ [Service]
|
||||
+ ExecStartPre=
|
||||
+ ExecStart=
|
||||
+ ExecStart=false
|
||||
+ EOF
|
||||
+ cp mkosi.images/initrd/mkosi.extra/usr/lib/systemd/system/emergency.service.d/poweroff.conf mkosi.images/system/mkosi.extra/usr/lib/systemd/system/emergency.service.d/poweroff.conf
|
||||
+
|
||||
+ - name: Generate secure boot key
|
||||
+ run: mkosi --debug genkey
|
||||
+
|
||||
+ - name: Show image summary
|
||||
+ run: mkosi summary
|
||||
+
|
||||
+ - name: Build
|
||||
+ run: mkosi --debug
|
||||
+
|
||||
+ - name: Boot systemd-nspawn
|
||||
+ run: sudo mkosi --debug boot
|
||||
+
|
||||
+ - name: Boot QEMU
|
||||
+ run: timeout -k 30 10m mkosi --debug qemu
|
||||
+
|
||||
+ - name: Check ${{ matrix.distro }} QEMU
|
||||
+ run: sudo mkosi shell bash -c "[[ -e /testok ]] || { cat /failed-services; exit 1; }"
|
||||
diff --git a/mkosi.images/system/mkosi.extra/usr/lib/repart.d/15-swap.conf b/mkosi.images/system/mkosi.extra/usr/lib/repart.d/15-swap.conf
|
||||
index 3755278462..1cbd6c7c2f 100644
|
||||
--- a/mkosi.images/system/mkosi.extra/usr/lib/repart.d/15-swap.conf
|
||||
+++ b/mkosi.images/system/mkosi.extra/usr/lib/repart.d/15-swap.conf
|
||||
@@ -2,5 +2,6 @@
|
||||
|
||||
[Partition]
|
||||
Type=swap
|
||||
+Format=swap
|
||||
SizeMinBytes=100M
|
||||
SizeMaxBytes=100M
|
||||
diff --git a/mkosi.images/system/mkosi.extra/usr/lib/systemd/mkosi-check-and-shutdown.sh b/mkosi.images/system/mkosi.extra/usr/lib/systemd/mkosi-check-and-shutdown.sh
|
||||
index 9bb246263e..210fa78850 100755
|
||||
--- a/mkosi.images/system/mkosi.extra/usr/lib/systemd/mkosi-check-and-shutdown.sh
|
||||
+++ b/mkosi.images/system/mkosi.extra/usr/lib/systemd/mkosi-check-and-shutdown.sh
|
||||
@@ -1,6 +1,8 @@
|
||||
#!/bin/bash -eux
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
+rm -f /testok
|
||||
+
|
||||
# TODO: Figure out why this is failing
|
||||
systemctl reset-failed systemd-vconsole-setup.service
|
||||
|
||||
@@ -17,3 +19,4 @@ fi
|
||||
|
||||
# Exit with non-zero EC if the /failed-services file is not empty (we have -e set)
|
||||
[[ ! -s /failed-services ]]
|
||||
+touch /testok
|
||||
diff --git a/mkosi.images/system/mkosi.extra/usr/lib/systemd/system/mkosi-check-and-shutdown.service b/mkosi.images/system/mkosi.extra/usr/lib/systemd/system/mkosi-check-and-shutdown.service
|
||||
index 7942cbfa77..4021ede274 100644
|
||||
--- a/mkosi.images/system/mkosi.extra/usr/lib/systemd/system/mkosi-check-and-shutdown.service
|
||||
+++ b/mkosi.images/system/mkosi.extra/usr/lib/systemd/system/mkosi-check-and-shutdown.service
|
||||
@@ -3,12 +3,9 @@
|
||||
Description=Check if any service failed and then shutdown the machine
|
||||
After=multi-user.target network-online.target
|
||||
Requires=multi-user.target
|
||||
-Wants=systemd-resolved.service systemd-networkd.service network-online.target
|
||||
+Wants=network-online.target
|
||||
SuccessAction=exit
|
||||
FailureAction=exit
|
||||
-# On success, exit with 123 so that we can check that we receive the actual exit code from the script on the
|
||||
-# host.
|
||||
-SuccessActionExitStatus=123
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
23
0792-mkosi-explicitly-enroll-SecureBoot-keys.patch
Normal file
23
0792-mkosi-explicitly-enroll-SecureBoot-keys.patch
Normal file
@ -0,0 +1,23 @@
|
||||
From 78e911e288b51eff762c67bb3df2b7b59f8c6872 Mon Sep 17 00:00:00 2001
|
||||
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||
Date: Wed, 28 Feb 2024 19:51:17 +0100
|
||||
Subject: [PATCH] mkosi: explicitly enroll SecureBoot keys
|
||||
|
||||
The automagic enrollment works only with systemd v253 onwards, on v252
|
||||
we need to do this one extra step.
|
||||
|
||||
RHEL-only
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
mkosi.images/system/mkosi.extra/efi/loader/loader.conf | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
create mode 100644 mkosi.images/system/mkosi.extra/efi/loader/loader.conf
|
||||
|
||||
diff --git a/mkosi.images/system/mkosi.extra/efi/loader/loader.conf b/mkosi.images/system/mkosi.extra/efi/loader/loader.conf
|
||||
new file mode 100644
|
||||
index 0000000000..f7a9445d89
|
||||
--- /dev/null
|
||||
+++ b/mkosi.images/system/mkosi.extra/efi/loader/loader.conf
|
||||
@@ -0,0 +1 @@
|
||||
+secure-boot-enroll force
|
37
0793-test-execute-also-mount-tmpfs-on-dev-shm.patch
Normal file
37
0793-test-execute-also-mount-tmpfs-on-dev-shm.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From ad27f1973d24a051ddfc80efcd00446eddf4380d Mon Sep 17 00:00:00 2001
|
||||
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||||
Date: Fri, 17 Feb 2023 10:21:58 +0900
|
||||
Subject: [PATCH] test-execute: also mount tmpfs on /dev/shm
|
||||
|
||||
Otherwise, if /dev/shm has a directory that cannot be accessible by
|
||||
unprivileged user, then we cannot pick a dynamic user, and test service
|
||||
may fail with unexpected error code:
|
||||
---
|
||||
Failed to enter shared memory directory /dev/shm/systemd-watch-bind-BqAGlN: Permission denied
|
||||
exec-dynamicuser-supplementarygroups.service: Failed to update dynamic user credentials: Device or resource busy
|
||||
exec-dynamicuser-supplementarygroups.service: Failed at step USER spawning /bin/sh: Device or resource busy
|
||||
src/test/test-execute.c:885:test_exec_dynamicuser: exec-dynamicuser-supplementarygroups.service: can_unshare=no: exit status 217, expected 216
|
||||
---
|
||||
|
||||
Follow-up for 4e032f654b94c2544ccf937209303766dfa66c24.
|
||||
|
||||
(cherry picked from commit d51e31ac4197d971a468ff41f15593bb6fdb29f3)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/test/test-execute.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/test/test-execute.c b/src/test/test-execute.c
|
||||
index 665ae8a833..f37da945b6 100644
|
||||
--- a/src/test/test-execute.c
|
||||
+++ b/src/test/test-execute.c
|
||||
@@ -1262,7 +1262,7 @@ static int prepare_ns(const char *process_name) {
|
||||
assert_se(mkdir_p(PRIVATE_UNIT_DIR, 0755) >= 0);
|
||||
|
||||
/* Mount tmpfs on the following directories to make not StateDirectory= or friends disturb the host. */
|
||||
- FOREACH_STRING(p, "/root", "/tmp", "/var/tmp", "/var/lib", PRIVATE_UNIT_DIR)
|
||||
+ FOREACH_STRING(p, "/dev/shm", "/root", "/tmp", "/var/tmp", "/var/lib", PRIVATE_UNIT_DIR)
|
||||
assert_se(mount_nofollow_verbose(LOG_DEBUG, "tmpfs", p, "tmpfs", MS_NOSUID|MS_NODEV, NULL) >= 0);
|
||||
|
||||
/* Copy unit files to make them accessible even when unprivileged. */
|
106
0794-mkosi-fix-UKI-addons-test.patch
Normal file
106
0794-mkosi-fix-UKI-addons-test.patch
Normal file
@ -0,0 +1,106 @@
|
||||
From 8fd8b29eda64dd09ea01f1b87cc4c65950fb5e3a Mon Sep 17 00:00:00 2001
|
||||
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||
Date: Tue, 5 Mar 2024 11:49:30 +0100
|
||||
Subject: [PATCH] mkosi: fix UKI addons test
|
||||
|
||||
The test hasn't been working for a while, since there's no /efi or /boot
|
||||
in $DESTDIR.
|
||||
|
||||
(cherry picked from commit 374fa8e8533e4834337a22613c7bada205dc1853)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
mkosi.images/base/mkosi.build.chroot | 12 ------------
|
||||
mkosi.images/system/mkosi.conf.d/10-arch.conf | 1 +
|
||||
.../system/mkosi.conf.d/10-debian-ubuntu.conf | 1 +
|
||||
mkosi.images/system/mkosi.conf.d/10-fedora.conf | 1 +
|
||||
mkosi.images/system/mkosi.conf.d/10-opensuse.conf | 1 +
|
||||
mkosi.images/system/mkosi.postinst.chroot | 11 ++++++++++-
|
||||
6 files changed, 14 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/mkosi.images/base/mkosi.build.chroot b/mkosi.images/base/mkosi.build.chroot
|
||||
index 3427d0e241..c46d667a90 100755
|
||||
--- a/mkosi.images/base/mkosi.build.chroot
|
||||
+++ b/mkosi.images/base/mkosi.build.chroot
|
||||
@@ -177,15 +177,3 @@ if [ "$WITH_TESTS" = 1 ]; then
|
||||
fi
|
||||
|
||||
( set -x; meson install -C "$BUILDDIR" --quiet --no-rebuild --only-changed )
|
||||
-
|
||||
-# Ensure that side-loaded PE addons are loaded if signed, and ignored if not
|
||||
-if [ -d "${DESTDIR}/boot/loader" ]; then
|
||||
- addons_dir="${DESTDIR}/boot/loader/addons"
|
||||
-elif [ -d "${DESTDIR}/efi/loader" ]; then
|
||||
- addons_dir="${DESTDIR}/efi/loader/addons"
|
||||
-fi
|
||||
-if [ -n "${addons_dir}" ]; then
|
||||
- mkdir -p "${addons_dir}"
|
||||
- ukify --secureboot-private-key mkosi.secure-boot.key --secureboot-certificate mkosi.secure-boot.crt --cmdline this_should_be_here -o "${addons_dir}/good.addon.efi"
|
||||
- ukify --cmdline this_should_not_be_here -o "${addons_dir}/bad.addon.efi"
|
||||
-fi
|
||||
diff --git a/mkosi.images/system/mkosi.conf.d/10-arch.conf b/mkosi.images/system/mkosi.conf.d/10-arch.conf
|
||||
index e1a511c979..a3d008d10f 100644
|
||||
--- a/mkosi.images/system/mkosi.conf.d/10-arch.conf
|
||||
+++ b/mkosi.images/system/mkosi.conf.d/10-arch.conf
|
||||
@@ -23,5 +23,6 @@ Packages=
|
||||
python-pytest
|
||||
python3
|
||||
quota-tools
|
||||
+ sbsigntools
|
||||
shadow
|
||||
vim
|
||||
diff --git a/mkosi.images/system/mkosi.conf.d/10-debian-ubuntu.conf b/mkosi.images/system/mkosi.conf.d/10-debian-ubuntu.conf
|
||||
index 348bdb2992..d6e3f20222 100644
|
||||
--- a/mkosi.images/system/mkosi.conf.d/10-debian-ubuntu.conf
|
||||
+++ b/mkosi.images/system/mkosi.conf.d/10-debian-ubuntu.conf
|
||||
@@ -19,6 +19,7 @@ Packages=
|
||||
netcat-openbsd
|
||||
openssh-server
|
||||
openssh-client
|
||||
+ sbsigntool
|
||||
passwd
|
||||
policykit-1
|
||||
procps
|
||||
diff --git a/mkosi.images/system/mkosi.conf.d/10-fedora.conf b/mkosi.images/system/mkosi.conf.d/10-fedora.conf
|
||||
index 5863f03b19..7554ad2dc3 100644
|
||||
--- a/mkosi.images/system/mkosi.conf.d/10-fedora.conf
|
||||
+++ b/mkosi.images/system/mkosi.conf.d/10-fedora.conf
|
||||
@@ -9,3 +9,4 @@ Packages=
|
||||
compsize
|
||||
f2fs-tools
|
||||
glibc-langpack-en
|
||||
+ sbsigntools
|
||||
diff --git a/mkosi.images/system/mkosi.conf.d/10-opensuse.conf b/mkosi.images/system/mkosi.conf.d/10-opensuse.conf
|
||||
index 71434b4560..ffcb664224 100644
|
||||
--- a/mkosi.images/system/mkosi.conf.d/10-opensuse.conf
|
||||
+++ b/mkosi.images/system/mkosi.conf.d/10-opensuse.conf
|
||||
@@ -20,5 +20,6 @@ Packages=
|
||||
python3-psutil
|
||||
python3-pytest
|
||||
quota
|
||||
+ sbsigntools
|
||||
shadow
|
||||
vim
|
||||
diff --git a/mkosi.images/system/mkosi.postinst.chroot b/mkosi.images/system/mkosi.postinst.chroot
|
||||
index 692242da38..330fa3b73e 100755
|
||||
--- a/mkosi.images/system/mkosi.postinst.chroot
|
||||
+++ b/mkosi.images/system/mkosi.postinst.chroot
|
||||
@@ -1,4 +1,4 @@
|
||||
-#!/bin/sh
|
||||
+#!/bin/bash
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
set -e
|
||||
|
||||
@@ -100,3 +100,12 @@ mkdir -p /usr/lib/tmpfiles.d
|
||||
cat >/usr/lib/tmpfiles.d/testuser.conf <<EOF
|
||||
q /home/testuser 0700 4711 4711
|
||||
EOF
|
||||
+
|
||||
+# sbsign is not available on CentOS Stream
|
||||
+if command -v sbsign &>/dev/null; then
|
||||
+ # Ensure that side-loaded PE addons are loaded if signed, and ignored if not
|
||||
+ addons_dir=/efi/loader/addons
|
||||
+ mkdir -p "$addons_dir"
|
||||
+ ukify build --secureboot-private-key mkosi.key --secureboot-certificate mkosi.crt --cmdline this_should_be_here -o "$addons_dir/good.addon.efi"
|
||||
+ ukify build --cmdline this_should_not_be_here -o "$addons_dir/bad.addon.efi"
|
||||
+fi
|
36
0795-Revert-mkosi-Disable-cmdline-addon-test-for-now.patch
Normal file
36
0795-Revert-mkosi-Disable-cmdline-addon-test-for-now.patch
Normal file
@ -0,0 +1,36 @@
|
||||
From c77533f7cc265ce7fc4c933f8ebb3828c0c9ff57 Mon Sep 17 00:00:00 2001
|
||||
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||
Date: Tue, 5 Mar 2024 11:51:52 +0100
|
||||
Subject: [PATCH] Revert "mkosi: Disable cmdline addon test for now"
|
||||
|
||||
Let's see if this finally works.
|
||||
|
||||
This reverts commit e167a8283d5964ca0f903b3e362ab7e48a1ed2ab.
|
||||
|
||||
(cherry picked from commit d9c8cf40b5c920ae59a02fa2bab32e93dad33542)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
.../usr/lib/systemd/mkosi-check-and-shutdown.sh | 9 ++++++---
|
||||
1 file changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/mkosi.images/system/mkosi.extra/usr/lib/systemd/mkosi-check-and-shutdown.sh b/mkosi.images/system/mkosi.extra/usr/lib/systemd/mkosi-check-and-shutdown.sh
|
||||
index 210fa78850..076026d097 100755
|
||||
--- a/mkosi.images/system/mkosi.extra/usr/lib/systemd/mkosi-check-and-shutdown.sh
|
||||
+++ b/mkosi.images/system/mkosi.extra/usr/lib/systemd/mkosi-check-and-shutdown.sh
|
||||
@@ -12,9 +12,12 @@ systemctl --failed --no-legend | tee /failed-services
|
||||
if ! systemd-detect-virt --container; then
|
||||
cmp /sys/firmware/efi/efivars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c <(printf '\6\0\0\0\1')
|
||||
cmp /sys/firmware/efi/efivars/SetupMode-8be4df61-93ca-11d2-aa0d-00e098032b8c <(printf '\6\0\0\0\0')
|
||||
- # TODO: Figure out why this is failing
|
||||
- # grep -q this_should_be_here /proc/cmdline
|
||||
- # grep -q this_should_not_be_here /proc/cmdline && exit 1
|
||||
+
|
||||
+ if command -v sbsign &>/dev/null; then
|
||||
+ cat /proc/cmdline
|
||||
+ grep -q this_should_be_here /proc/cmdline
|
||||
+ (! grep -q this_should_not_be_here /proc/cmdline)
|
||||
+ fi
|
||||
fi
|
||||
|
||||
# Exit with non-zero EC if the /failed-services file is not empty (we have -e set)
|
@ -0,0 +1,31 @@
|
||||
From fd051e3de351860b52ff1bbe6cab1fa9c153be76 Mon Sep 17 00:00:00 2001
|
||||
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||
Date: Tue, 5 Mar 2024 12:18:40 +0100
|
||||
Subject: [PATCH] Revert "mkosi: Don't fail on systemd-vconsole-setup.service
|
||||
failure for now"
|
||||
|
||||
This doesn't seem to fail anymore.
|
||||
|
||||
This reverts commit 84c7929cd461f6f1cc2c44c69877b9fd0676c794.
|
||||
|
||||
(cherry picked from commit 193fa9d7fe383801bf3ff53e5ee5a2c52107270f)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
.../mkosi.extra/usr/lib/systemd/mkosi-check-and-shutdown.sh | 3 ---
|
||||
1 file changed, 3 deletions(-)
|
||||
|
||||
diff --git a/mkosi.images/system/mkosi.extra/usr/lib/systemd/mkosi-check-and-shutdown.sh b/mkosi.images/system/mkosi.extra/usr/lib/systemd/mkosi-check-and-shutdown.sh
|
||||
index 076026d097..4011ab930b 100755
|
||||
--- a/mkosi.images/system/mkosi.extra/usr/lib/systemd/mkosi-check-and-shutdown.sh
|
||||
+++ b/mkosi.images/system/mkosi.extra/usr/lib/systemd/mkosi-check-and-shutdown.sh
|
||||
@@ -3,9 +3,6 @@
|
||||
|
||||
rm -f /testok
|
||||
|
||||
-# TODO: Figure out why this is failing
|
||||
-systemctl reset-failed systemd-vconsole-setup.service
|
||||
-
|
||||
systemctl --failed --no-legend | tee /failed-services
|
||||
|
||||
# Check that secure boot keys were properly enrolled.
|
25
0797-mkosi-make-shellcheck-happy.patch
Normal file
25
0797-mkosi-make-shellcheck-happy.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From f3646608832288bb08b705de9b54a04a618a1ce3 Mon Sep 17 00:00:00 2001
|
||||
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||
Date: Tue, 5 Mar 2024 12:41:30 +0100
|
||||
Subject: [PATCH] mkosi: make shellcheck happy
|
||||
|
||||
(cherry picked from commit e86b1a9b0f1d2fc150edde18ea6f748b9423df3c)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
mkosi.images/base/mkosi.build.chroot | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/mkosi.images/base/mkosi.build.chroot b/mkosi.images/base/mkosi.build.chroot
|
||||
index c46d667a90..69430c304d 100755
|
||||
--- a/mkosi.images/base/mkosi.build.chroot
|
||||
+++ b/mkosi.images/base/mkosi.build.chroot
|
||||
@@ -8,7 +8,7 @@ set -e
|
||||
# We don't want to install our build of systemd in the base image, but use it as an extra tree for the
|
||||
# initrd and system images, so override DESTDIR to store it in the output directory so we can reference it as
|
||||
# an extra tree in the initrd and system image builds.
|
||||
-DESTDIR="$OUTPUTDIR/systemd"
|
||||
+export DESTDIR="$OUTPUTDIR/systemd"
|
||||
|
||||
# If mkosi.builddir/ exists mkosi will set $BUILDDIR to it, let's then use it
|
||||
# as out-of-tree build dir. Otherwise, let's make up our own builddir.
|
67
0798-mkosi-use-pesign-for-signing-UKI-addons.patch
Normal file
67
0798-mkosi-use-pesign-for-signing-UKI-addons.patch
Normal file
@ -0,0 +1,67 @@
|
||||
From de81c5b27d15ffc61a2c586f8b9a6a7943c061c7 Mon Sep 17 00:00:00 2001
|
||||
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||
Date: Tue, 5 Mar 2024 20:22:19 +0100
|
||||
Subject: [PATCH] mkosi: use pesign for signing UKI addons
|
||||
|
||||
In C9S/RHEL9 we don't ship sbsign, so we have to use pesign instead.
|
||||
Unfortunately, ukify doesn't support singing with pesign, so we have to
|
||||
do that manually.
|
||||
|
||||
Related: RHEL-27512
|
||||
RHEL-only
|
||||
---
|
||||
.../system/mkosi.conf.d/10-centos/mkosi.conf | 3 +++
|
||||
.../usr/lib/systemd/mkosi-check-and-shutdown.sh | 2 +-
|
||||
mkosi.images/system/mkosi.postinst.chroot | 13 ++++++++++---
|
||||
3 files changed, 14 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/mkosi.images/system/mkosi.conf.d/10-centos/mkosi.conf b/mkosi.images/system/mkosi.conf.d/10-centos/mkosi.conf
|
||||
index 146e03a895..c79ced5130 100644
|
||||
--- a/mkosi.images/system/mkosi.conf.d/10-centos/mkosi.conf
|
||||
+++ b/mkosi.images/system/mkosi.conf.d/10-centos/mkosi.conf
|
||||
@@ -6,3 +6,6 @@ Distribution=centos
|
||||
[Content]
|
||||
Packages=
|
||||
kernel-modules # For squashfs support
|
||||
+ nss-tools
|
||||
+ openssl
|
||||
+ pesign
|
||||
diff --git a/mkosi.images/system/mkosi.extra/usr/lib/systemd/mkosi-check-and-shutdown.sh b/mkosi.images/system/mkosi.extra/usr/lib/systemd/mkosi-check-and-shutdown.sh
|
||||
index 4011ab930b..f32128ead2 100755
|
||||
--- a/mkosi.images/system/mkosi.extra/usr/lib/systemd/mkosi-check-and-shutdown.sh
|
||||
+++ b/mkosi.images/system/mkosi.extra/usr/lib/systemd/mkosi-check-and-shutdown.sh
|
||||
@@ -10,7 +10,7 @@ if ! systemd-detect-virt --container; then
|
||||
cmp /sys/firmware/efi/efivars/SecureBoot-8be4df61-93ca-11d2-aa0d-00e098032b8c <(printf '\6\0\0\0\1')
|
||||
cmp /sys/firmware/efi/efivars/SetupMode-8be4df61-93ca-11d2-aa0d-00e098032b8c <(printf '\6\0\0\0\0')
|
||||
|
||||
- if command -v sbsign &>/dev/null; then
|
||||
+ if command -v pesign &>/dev/null; then
|
||||
cat /proc/cmdline
|
||||
grep -q this_should_be_here /proc/cmdline
|
||||
(! grep -q this_should_not_be_here /proc/cmdline)
|
||||
diff --git a/mkosi.images/system/mkosi.postinst.chroot b/mkosi.images/system/mkosi.postinst.chroot
|
||||
index 330fa3b73e..8d2c3d6a37 100755
|
||||
--- a/mkosi.images/system/mkosi.postinst.chroot
|
||||
+++ b/mkosi.images/system/mkosi.postinst.chroot
|
||||
@@ -101,11 +101,18 @@ cat >/usr/lib/tmpfiles.d/testuser.conf <<EOF
|
||||
q /home/testuser 0700 4711 4711
|
||||
EOF
|
||||
|
||||
-# sbsign is not available on CentOS Stream
|
||||
-if command -v sbsign &>/dev/null; then
|
||||
+# RHEL 9 only: we don't ship sbsigntools in RHEL 9 so we have to use pesign
|
||||
+# instead. Unfortunately, ATTOW ukify doesn't support signing with pesign, so we
|
||||
+# have to do it manually :(
|
||||
+if command -v pesign &>/dev/null; then
|
||||
# Ensure that side-loaded PE addons are loaded if signed, and ignored if not
|
||||
addons_dir=/efi/loader/addons
|
||||
mkdir -p "$addons_dir"
|
||||
- ukify build --secureboot-private-key mkosi.key --secureboot-certificate mkosi.crt --cmdline this_should_be_here -o "$addons_dir/good.addon.efi"
|
||||
+ ukify build --cmdline this_should_be_here -o "good.addon.efi"
|
||||
ukify build --cmdline this_should_not_be_here -o "$addons_dir/bad.addon.efi"
|
||||
+
|
||||
+ openssl pkcs12 -name "mkosi" -passin "pass:" -passout "pass:" -export -out mkosi.p12 -inkey mkosi.key -in mkosi.crt
|
||||
+ pk12util -W "" -i mkosi.p12 -d /etc/pki/pesign
|
||||
+ pesign -v -s -c "mkosi" -i "good.addon.efi" -o "$addons_dir/good.addon.efi"
|
||||
+ pesign -S -i"$addons_dir/good.addon.efi"
|
||||
fi
|
@ -0,0 +1,65 @@
|
||||
From 59162dc947e9c9538f98f0a00ab9eeef9c7bae71 Mon Sep 17 00:00:00 2001
|
||||
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||
Date: Tue, 11 Jul 2023 21:03:22 +0200
|
||||
Subject: [PATCH] test: copy out the necessary test data before we start
|
||||
overmounting stuff
|
||||
|
||||
Otherwise the get_testdata_dir() call fails if the source tree is under
|
||||
/root (which is usually the case in CIs).
|
||||
|
||||
I got bitten by this after leaving the source tree under /root but moving the
|
||||
$BUILD_DIR elsewhere. This used to work by accident, as load_testdata_env()
|
||||
would try to read $BUILD_DIR/systemd-runtest.env, but would fail if the
|
||||
$BUILD_DIR is also under /root and fall back to SYSTEMD_TEST_DATA
|
||||
(/lib/systemd/tests/testdata), which usually exist as we install the just built
|
||||
revision. However, if the $BUILD_DIR is outside of /root we'd read
|
||||
$BUILD_DIR/systemd-runtest.env which contains
|
||||
SYSTEMD_TEST_DATA=/path/to/source/tree/test and that source tree is not visible
|
||||
once we overmount /root with tmpfs making the test fail:
|
||||
|
||||
/* test_run_tests_unprivileged */
|
||||
Successfully forked off '(test-execute-unprivileged)' as PID 10672.
|
||||
Changing mount flags / (MS_REMOUNT|MS_BIND "")...
|
||||
Changing mount propagation / (MS_REC|MS_SHARED "")
|
||||
Mounting tmpfs (tmpfs) on /dev/shm (MS_NOSUID|MS_NODEV "")...
|
||||
Mounting tmpfs (tmpfs) on /root (MS_NOSUID|MS_NODEV "")...
|
||||
Mounting tmpfs (tmpfs) on /tmp (MS_NOSUID|MS_NODEV "")...
|
||||
Mounting tmpfs (tmpfs) on /var/tmp (MS_NOSUID|MS_NODEV "")...
|
||||
Mounting tmpfs (tmpfs) on /var/lib (MS_NOSUID|MS_NODEV "")...
|
||||
Mounting tmpfs (tmpfs) on /run/test-execute-unit-dir (MS_NOSUID|MS_NODEV "")...
|
||||
ERROR: $SYSTEMD_TEST_DATA directory [/root/systemd/test] not accessible: No such file or directory
|
||||
Assertion 'get_testdata_dir("test-execute/", &unit_dir) >= 0' failed at src/test/test-execute.c:1306, function prepare_ns(). Aborting.
|
||||
(test-execute-unprivileged) terminated by signal ABRT.
|
||||
|
||||
(cherry picked from commit c109cff9f998876c3b5abd62501132d0fb0f80a2)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
src/test/test-execute.c | 9 +++++----
|
||||
1 file changed, 5 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/test/test-execute.c b/src/test/test-execute.c
|
||||
index f37da945b6..e6bd21b6b9 100644
|
||||
--- a/src/test/test-execute.c
|
||||
+++ b/src/test/test-execute.c
|
||||
@@ -1260,15 +1260,16 @@ static int prepare_ns(const char *process_name) {
|
||||
assert_se(mount_follow_verbose(LOG_DEBUG, NULL, "/", NULL, MS_SHARED|MS_REC, NULL) >= 0);
|
||||
|
||||
assert_se(mkdir_p(PRIVATE_UNIT_DIR, 0755) >= 0);
|
||||
-
|
||||
- /* Mount tmpfs on the following directories to make not StateDirectory= or friends disturb the host. */
|
||||
- FOREACH_STRING(p, "/dev/shm", "/root", "/tmp", "/var/tmp", "/var/lib", PRIVATE_UNIT_DIR)
|
||||
- assert_se(mount_nofollow_verbose(LOG_DEBUG, "tmpfs", p, "tmpfs", MS_NOSUID|MS_NODEV, NULL) >= 0);
|
||||
+ assert_se(mount_nofollow_verbose(LOG_DEBUG, "tmpfs", PRIVATE_UNIT_DIR, "tmpfs", MS_NOSUID|MS_NODEV, NULL) >= 0);
|
||||
|
||||
/* Copy unit files to make them accessible even when unprivileged. */
|
||||
assert_se(get_testdata_dir("test-execute/", &unit_dir) >= 0);
|
||||
assert_se(copy_directory(unit_dir, PRIVATE_UNIT_DIR, COPY_MERGE_EMPTY) >= 0);
|
||||
|
||||
+ /* Mount tmpfs on the following directories to make not StateDirectory= or friends disturb the host. */
|
||||
+ FOREACH_STRING(p, "/dev/shm", "/root", "/tmp", "/var/tmp", "/var/lib")
|
||||
+ assert_se(mount_nofollow_verbose(LOG_DEBUG, "tmpfs", p, "tmpfs", MS_NOSUID|MS_NODEV, NULL) >= 0);
|
||||
+
|
||||
/* Prepare credstore like tmpfiles.d/credstore.conf for LoadCredential= tests. */
|
||||
FOREACH_STRING(p, "/run/credstore", "/run/credstore.encrypted") {
|
||||
assert_se(mkdir_p(p, 0) >= 0);
|
@ -0,0 +1,39 @@
|
||||
From 5bc5e4eccfccb2935ededa6976d3346b1b6fbdaf Mon Sep 17 00:00:00 2001
|
||||
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||
Date: Wed, 6 Mar 2024 15:04:22 +0100
|
||||
Subject: [PATCH] ci: make the build dir accessible when running w/o privileges
|
||||
|
||||
Otherwise the unprivileged part of test-execute gets silently skipped:
|
||||
|
||||
/* test_run_tests_unprivileged */
|
||||
Successfully forked off '(test-execute-unprivileged)' as PID 20998.
|
||||
...
|
||||
pin_callout_binary: build dir binary: /home/runner/work/systemd/systemd/build/systemd-executor
|
||||
pin_callout_binary: open(/home/runner/work/systemd/systemd/build/systemd-executor)=-13
|
||||
Failed to pin executor binary: No such file or directory
|
||||
(test-execute-unprivileged): manager_new, skipping tests: No such file or directory
|
||||
(test-execute-unprivileged) succeeded.
|
||||
|
||||
(cherry picked from commit c538fecc617d7a5fe0048b1df49f69dead92353f)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
.github/workflows/unit_tests.sh | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/.github/workflows/unit_tests.sh b/.github/workflows/unit_tests.sh
|
||||
index 9a9fbb36ab..cb8ea332aa 100755
|
||||
--- a/.github/workflows/unit_tests.sh
|
||||
+++ b/.github/workflows/unit_tests.sh
|
||||
@@ -52,6 +52,11 @@ for phase in "${PHASES[@]}"; do
|
||||
apt-get -y build-dep systemd
|
||||
apt-get -y install "${ADDITIONAL_DEPS[@]}"
|
||||
pip3 install -r .github/workflows/requirements.txt --require-hashes
|
||||
+
|
||||
+ # Make sure the build dir is accessible even when drop privileges, otherwise the unprivileged
|
||||
+ # part of test-execute gets skipped, since it can't run systemd-executor
|
||||
+ chmod o+x /home/runner
|
||||
+ capsh --drop=all -- -c "stat $PWD/meson.build"
|
||||
;;
|
||||
RUN|RUN_GCC|RUN_CLANG|RUN_CLANG_RELEASE)
|
||||
if [[ "$phase" =~ ^RUN_CLANG ]]; then
|
@ -0,0 +1,74 @@
|
||||
From 5a310f31d5d42bb7a556c274c3839c34c600e9f5 Mon Sep 17 00:00:00 2001
|
||||
From: Frantisek Sumsal <frantisek@sumsal.cz>
|
||||
Date: Wed, 6 Mar 2024 15:21:10 +0100
|
||||
Subject: [PATCH] ci: explicitly change oom-{score}-adj before running tests
|
||||
|
||||
For some reason root in GH actions is able to _decrease_ its oom score
|
||||
even after dropping all capabilities (including CAP_SYS_RESOURCE), until
|
||||
the oom score is changed explicitly after sudo:
|
||||
|
||||
$ systemd-detect-virt
|
||||
microsoft
|
||||
$ sudo su -
|
||||
~# capsh --drop=all -- -c 'capsh --print; grep -H . /proc/self/oom*; choom -p $$ -n -101'
|
||||
Current: =
|
||||
Bounding set =
|
||||
Ambient set =
|
||||
Current IAB: !cap_chown,!cap_dac_override,!cap_dac_read_search,...,!cap_sys_resource,...,!cap_checkpoint_restore
|
||||
Securebits: 00/0x0/1'b0
|
||||
secure-noroot: no (unlocked)
|
||||
secure-no-suid-fixup: no (unlocked)
|
||||
secure-keep-caps: no (unlocked)
|
||||
secure-no-ambient-raise: no (unlocked)
|
||||
uid=0(root) euid=0(root)
|
||||
gid=0(root)
|
||||
groups=0(root)
|
||||
Guessed mode: UNCERTAIN (0)
|
||||
/proc/self/oom_adj:8
|
||||
/proc/self/oom_score:1000
|
||||
/proc/self/oom_score_adj:500
|
||||
pid 22180's OOM score adjust value changed from 500 to -101
|
||||
~# choom -p $$ -n 500
|
||||
pid 22027's OOM score adjust value changed from 500 to 500
|
||||
~# capsh --drop=all -- -c 'capsh --print; grep -H . /proc/self/oom*; choom -p $$ -n -101'
|
||||
Current: =
|
||||
Bounding set =
|
||||
Ambient set =
|
||||
...
|
||||
uid=0(root) euid=0(root)
|
||||
gid=0(root)
|
||||
groups=0(root)
|
||||
Guessed mode: UNCERTAIN (0)
|
||||
/proc/self/oom_adj:8
|
||||
/proc/self/oom_score:1000
|
||||
/proc/self/oom_score_adj:500
|
||||
choom: failed to set score adjust value: Permission denied
|
||||
|
||||
I have no idea what's going on, but it breaks
|
||||
exec-oomscoreadjust-negative.service from test-execute when running
|
||||
unprivileged.
|
||||
|
||||
(cherry picked from commit 7161af9612d2d4f79cfbe8ed34ea7614d08901f7)
|
||||
|
||||
Related: RHEL-27512
|
||||
---
|
||||
.github/workflows/unit_tests.sh | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/.github/workflows/unit_tests.sh b/.github/workflows/unit_tests.sh
|
||||
index cb8ea332aa..6dcbc393fd 100755
|
||||
--- a/.github/workflows/unit_tests.sh
|
||||
+++ b/.github/workflows/unit_tests.sh
|
||||
@@ -41,6 +41,12 @@ set -ex
|
||||
|
||||
MESON_ARGS=(-Dcryptolib=${CRYPTOLIB:-auto})
|
||||
|
||||
+# (Re)set the current oom-{score-}adj. For some reason root on GH actions is able to _decrease_
|
||||
+# its oom-score even after dropping all capabilities (including CAP_SYS_RESOURCE), until the
|
||||
+# score is explicitly changed after sudo. No idea what's going on, but it breaks
|
||||
+# exec-oomscoreadjust-negative.service from test-execute when running unprivileged.
|
||||
+choom -p $$ -n 0
|
||||
+
|
||||
for phase in "${PHASES[@]}"; do
|
||||
case $phase in
|
||||
SETUP)
|
49
0802-ratelimit-add-ratelimit_left-helper.patch
Normal file
49
0802-ratelimit-add-ratelimit_left-helper.patch
Normal file
@ -0,0 +1,49 @@
|
||||
From 90c92458355a64d96f3167bcb510f690446bd76a Mon Sep 17 00:00:00 2001
|
||||
From: Luca Boccassi <bluca@debian.org>
|
||||
Date: Fri, 28 Apr 2023 13:10:23 +0100
|
||||
Subject: [PATCH] ratelimit: add ratelimit_left helper
|
||||
|
||||
(cherry picked from commit 53d6987f9e46927bbc9ad683c091c070ebe06658)
|
||||
|
||||
Resolves: RHEL-35703
|
||||
---
|
||||
src/basic/ratelimit.c | 17 +++++++++++++++++
|
||||
src/basic/ratelimit.h | 3 +++
|
||||
2 files changed, 20 insertions(+)
|
||||
|
||||
diff --git a/src/basic/ratelimit.c b/src/basic/ratelimit.c
|
||||
index c16c8f7103..134ed7c2d8 100644
|
||||
--- a/src/basic/ratelimit.c
|
||||
+++ b/src/basic/ratelimit.c
|
||||
@@ -43,3 +43,20 @@ unsigned ratelimit_num_dropped(RateLimit *r) {
|
||||
|
||||
return r->num > r->burst ? r->num - r->burst : 0;
|
||||
}
|
||||
+
|
||||
+usec_t ratelimit_end(const RateLimit *rl) {
|
||||
+ assert(rl);
|
||||
+ if (rl->begin == 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ return usec_add(rl->begin, rl->interval);
|
||||
+}
|
||||
+
|
||||
+usec_t ratelimit_left(const RateLimit *rl) {
|
||||
+ assert(rl);
|
||||
+
|
||||
+ if (rl->begin == 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ return usec_sub_unsigned(ratelimit_end(rl), now(CLOCK_MONOTONIC));
|
||||
+}
|
||||
diff --git a/src/basic/ratelimit.h b/src/basic/ratelimit.h
|
||||
index 2236189851..bb7160a895 100644
|
||||
--- a/src/basic/ratelimit.h
|
||||
+++ b/src/basic/ratelimit.h
|
||||
@@ -23,3 +23,6 @@ static inline bool ratelimit_configured(RateLimit *rl) {
|
||||
bool ratelimit_below(RateLimit *r);
|
||||
|
||||
unsigned ratelimit_num_dropped(RateLimit *r);
|
||||
+
|
||||
+usec_t ratelimit_end(const RateLimit *rl);
|
||||
+usec_t ratelimit_left(const RateLimit *rl);
|
264
0803-manager-restrict-Dump-to-privileged-callers-or-ratel.patch
Normal file
264
0803-manager-restrict-Dump-to-privileged-callers-or-ratel.patch
Normal file
@ -0,0 +1,264 @@
|
||||
From 10e811e931efd55cab87b85eb75cbe73139cec43 Mon Sep 17 00:00:00 2001
|
||||
From: Luca Boccassi <bluca@debian.org>
|
||||
Date: Thu, 27 Apr 2023 23:23:30 +0100
|
||||
Subject: [PATCH] manager: restrict Dump*() to privileged callers or ratelimit
|
||||
|
||||
Dump*() methods can take quite some time due to the amount of data to
|
||||
serialize, so they can potentially stall the manager. Make them
|
||||
privileged, as they are debugging tools anyway. Use a new 'dump'
|
||||
capability for polkit, and the 'reload' capability for SELinux, as
|
||||
that's also non-destructive but slow.
|
||||
|
||||
If the caller is not privileged, allow it but rate limited to 10 calls
|
||||
every 10 minutes.
|
||||
|
||||
(cherry picked from commit d936595672cf3ee7c1c547f8fd30512f82be8784)
|
||||
|
||||
Resolves: RHEL-35703
|
||||
---
|
||||
man/org.freedesktop.systemd1.xml | 7 +++--
|
||||
man/systemd-analyze.xml | 2 +-
|
||||
src/core/dbus-manager.c | 34 +++++++++++++++++++--
|
||||
src/core/dbus.c | 3 ++
|
||||
src/core/dbus.h | 1 +
|
||||
src/core/manager-serialize.c | 23 ++++++++++++++
|
||||
src/core/manager.c | 5 +++
|
||||
src/core/manager.h | 3 ++
|
||||
src/core/org.freedesktop.systemd1.policy.in | 10 ++++++
|
||||
test/units/testsuite-65.sh | 15 +++++++++
|
||||
10 files changed, 98 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml
|
||||
index c18428a092..7ee649f6a7 100644
|
||||
--- a/man/org.freedesktop.systemd1.xml
|
||||
+++ b/man/org.freedesktop.systemd1.xml
|
||||
@@ -1363,7 +1363,8 @@ node /org/freedesktop/systemd1 {
|
||||
<function>DumpByFileDescriptor()</function>/<function>DumpUnitsMatchingPatternsByFileDescriptor()</function>
|
||||
are usually the preferred interface, since it ensures the data can be passed reliably from the service
|
||||
manager to the client. Note though that they cannot work when communicating with the service manager
|
||||
- remotely, as file descriptors are strictly local to a system.</para>
|
||||
+ remotely, as file descriptors are strictly local to a system. All the <function>Dump*()</function>
|
||||
+ methods are rate limited for unprivileged users.</para>
|
||||
|
||||
<para><function>Reload()</function> may be invoked to reload all unit files.</para>
|
||||
|
||||
@@ -1726,7 +1727,9 @@ node /org/freedesktop/systemd1 {
|
||||
<function>UnsetAndSetEnvironment()</function>) require
|
||||
<interfacename>org.freedesktop.systemd1.set-environment</interfacename>. <function>Reload()</function>
|
||||
and <function>Reexecute()</function> require
|
||||
- <interfacename>org.freedesktop.systemd1.reload-daemon</interfacename>.
|
||||
+ <interfacename>org.freedesktop.systemd1.reload-daemon</interfacename>. Operations which dump internal
|
||||
+ state require <interfacename>org.freedesktop.systemd1.bypass-dump-ratelimit</interfacename> to avoid
|
||||
+ rate limits.
|
||||
</para>
|
||||
</refsect2>
|
||||
</refsect1>
|
||||
diff --git a/man/systemd-analyze.xml b/man/systemd-analyze.xml
|
||||
index 5ba0d40fa0..ff5c84108d 100644
|
||||
--- a/man/systemd-analyze.xml
|
||||
+++ b/man/systemd-analyze.xml
|
||||
@@ -249,7 +249,7 @@ multi-user.target @47.820s
|
||||
<para>Without any parameter, this command outputs a (usually very long) human-readable serialization of
|
||||
the complete service manager state. Optional glob pattern may be specified, causing the output to be
|
||||
limited to units whose names match one of the patterns. The output format is subject to change without
|
||||
- notice and should not be parsed by applications.</para>
|
||||
+ notice and should not be parsed by applications. This command is rate limited for unprivileged users.</para>
|
||||
|
||||
<example>
|
||||
<title>Show the internal state of user manager</title>
|
||||
diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c
|
||||
index 00380cc9c1..44b1027588 100644
|
||||
--- a/src/core/dbus-manager.c
|
||||
+++ b/src/core/dbus-manager.c
|
||||
@@ -1357,17 +1357,47 @@ static int dump_impl(
|
||||
|
||||
assert(message);
|
||||
|
||||
- /* Anyone can call this method */
|
||||
-
|
||||
+ /* 'status' access is the bare minimum always needed for this, as the policy might straight out
|
||||
+ * forbid a client from querying any information from systemd, regardless of any rate limiting. */
|
||||
r = mac_selinux_access_check(message, "status", error);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
+ /* Rate limit reached? Check if the caller is privileged/allowed by policy to bypass this. We
|
||||
+ * check the rate limit first to avoid the expensive roundtrip to polkit when not needed. */
|
||||
+ if (!ratelimit_below(&m->dump_ratelimit)) {
|
||||
+ /* We need a way for SELinux to constrain the operation when the rate limit is active, even
|
||||
+ * if polkit would allow it, but we cannot easily add new named permissions, so we need to
|
||||
+ * use an existing one. Reload/reexec are also slow but non-destructive/modifying
|
||||
+ * operations, and can cause PID1 to stall. So it seems similar enough in terms of security
|
||||
+ * considerations and impact, and thus use the same access check for dumps which, given the
|
||||
+ * large amount of data to fetch, can stall PID1 for quite some time. */
|
||||
+ r = mac_selinux_access_check(message, "reload", error);
|
||||
+ if (r < 0)
|
||||
+ goto ratelimited;
|
||||
+
|
||||
+ r = bus_verify_bypass_dump_ratelimit_async(m, message, error);
|
||||
+ if (r < 0)
|
||||
+ goto ratelimited;
|
||||
+ if (r == 0)
|
||||
+ /* No authorization for now, but the async polkit stuff will call us again when it
|
||||
+ * has it */
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
r = manager_get_dump_string(m, patterns, &dump);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return reply(message, dump);
|
||||
+
|
||||
+ratelimited:
|
||||
+ log_warning("Dump request rejected due to rate limit on unprivileged callers, blocked for %s.",
|
||||
+ FORMAT_TIMESPAN(ratelimit_left(&m->dump_ratelimit), USEC_PER_SEC));
|
||||
+ return sd_bus_error_setf(error,
|
||||
+ SD_BUS_ERROR_LIMITS_EXCEEDED,
|
||||
+ "Dump request rejected due to rate limit on unprivileged callers, blocked for %s.",
|
||||
+ FORMAT_TIMESPAN(ratelimit_left(&m->dump_ratelimit), USEC_PER_SEC));
|
||||
}
|
||||
|
||||
static int reply_dump(sd_bus_message *message, char *dump) {
|
||||
diff --git a/src/core/dbus.c b/src/core/dbus.c
|
||||
index 141c3ffe12..3cbe9c5cfd 100644
|
||||
--- a/src/core/dbus.c
|
||||
+++ b/src/core/dbus.c
|
||||
@@ -1177,6 +1177,9 @@ int bus_verify_reload_daemon_async(Manager *m, sd_bus_message *call, sd_bus_erro
|
||||
int bus_verify_set_environment_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
|
||||
return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.set-environment", NULL, false, UID_INVALID, &m->polkit_registry, error);
|
||||
}
|
||||
+int bus_verify_bypass_dump_ratelimit_async(Manager *m, sd_bus_message *call, sd_bus_error *error) {
|
||||
+ return bus_verify_polkit_async(call, CAP_SYS_ADMIN, "org.freedesktop.systemd1.bypass-dump-ratelimit", NULL, false, UID_INVALID, &m->polkit_registry, error);
|
||||
+}
|
||||
|
||||
uint64_t manager_bus_n_queued_write(Manager *m) {
|
||||
uint64_t c = 0;
|
||||
diff --git a/src/core/dbus.h b/src/core/dbus.h
|
||||
index 369d9f56a2..50e7bb400e 100644
|
||||
--- a/src/core/dbus.h
|
||||
+++ b/src/core/dbus.h
|
||||
@@ -27,6 +27,7 @@ int bus_verify_manage_units_async(Manager *m, sd_bus_message *call, sd_bus_error
|
||||
int bus_verify_manage_unit_files_async(Manager *m, sd_bus_message *call, sd_bus_error *error);
|
||||
int bus_verify_reload_daemon_async(Manager *m, sd_bus_message *call, sd_bus_error *error);
|
||||
int bus_verify_set_environment_async(Manager *m, sd_bus_message *call, sd_bus_error *error);
|
||||
+int bus_verify_bypass_dump_ratelimit_async(Manager *m, sd_bus_message *call, sd_bus_error *error);
|
||||
|
||||
int bus_forward_agent_released(Manager *m, const char *path);
|
||||
|
||||
diff --git a/src/core/manager-serialize.c b/src/core/manager-serialize.c
|
||||
index 27cb0925ae..f3b2d7ee16 100644
|
||||
--- a/src/core/manager-serialize.c
|
||||
+++ b/src/core/manager-serialize.c
|
||||
@@ -164,6 +164,14 @@ int manager_serialize(
|
||||
(void) serialize_item_format(f, "user-lookup", "%i %i", copy0, copy1);
|
||||
}
|
||||
|
||||
+ (void) serialize_item_format(f,
|
||||
+ "dump-ratelimit",
|
||||
+ USEC_FMT " " USEC_FMT " %u %u",
|
||||
+ m->dump_ratelimit.begin,
|
||||
+ m->dump_ratelimit.interval,
|
||||
+ m->dump_ratelimit.num,
|
||||
+ m->dump_ratelimit.burst);
|
||||
+
|
||||
bus_track_serialize(m->subscribed, f, "subscribed");
|
||||
|
||||
r = dynamic_user_serialize(m, f, fds);
|
||||
@@ -549,6 +557,21 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
|
||||
* remains set until all serialized contents are handled. */
|
||||
if (deserialize_varlink_sockets)
|
||||
(void) varlink_server_deserialize_one(m->varlink_server, val, fds);
|
||||
+ } else if ((val = startswith(l, "dump-ratelimit="))) {
|
||||
+ usec_t begin, interval;
|
||||
+ unsigned num, burst;
|
||||
+
|
||||
+ if (sscanf(val, USEC_FMT " " USEC_FMT " %u %u", &begin, &interval, &num, &burst) != 4)
|
||||
+ log_notice("Failed to parse dump ratelimit, ignoring: %s", val);
|
||||
+ else {
|
||||
+ /* If we changed the values across versions, flush the counter */
|
||||
+ if (interval != m->dump_ratelimit.interval || burst != m->dump_ratelimit.burst)
|
||||
+ m->dump_ratelimit.num = 0;
|
||||
+ else
|
||||
+ m->dump_ratelimit.num = num;
|
||||
+ m->dump_ratelimit.begin = begin;
|
||||
+ }
|
||||
+
|
||||
} else {
|
||||
ManagerTimestamp q;
|
||||
|
||||
diff --git a/src/core/manager.c b/src/core/manager.c
|
||||
index eeee395b90..b44c7785cf 100644
|
||||
--- a/src/core/manager.c
|
||||
+++ b/src/core/manager.c
|
||||
@@ -866,6 +866,11 @@ int manager_new(LookupScope scope, ManagerTestRunFlags test_run_flags, Manager *
|
||||
.test_run_flags = test_run_flags,
|
||||
|
||||
.default_oom_policy = OOM_STOP,
|
||||
+
|
||||
+ .dump_ratelimit = {
|
||||
+ .interval = 10 * USEC_PER_MINUTE,
|
||||
+ .burst = 10,
|
||||
+ },
|
||||
};
|
||||
|
||||
#if ENABLE_EFI
|
||||
diff --git a/src/core/manager.h b/src/core/manager.h
|
||||
index 87e63c3b68..86e7e40989 100644
|
||||
--- a/src/core/manager.h
|
||||
+++ b/src/core/manager.h
|
||||
@@ -461,6 +461,9 @@ struct Manager {
|
||||
struct restrict_fs_bpf *restrict_fs;
|
||||
|
||||
char *default_smack_process_label;
|
||||
+
|
||||
+ /* Dump*() are slow, so always rate limit them to 10 per 10 minutes */
|
||||
+ RateLimit dump_ratelimit;
|
||||
};
|
||||
|
||||
static inline usec_t manager_default_timeout_abort_usec(Manager *m) {
|
||||
diff --git a/src/core/org.freedesktop.systemd1.policy.in b/src/core/org.freedesktop.systemd1.policy.in
|
||||
index 74adeadf38..9e9a20f66f 100644
|
||||
--- a/src/core/org.freedesktop.systemd1.policy.in
|
||||
+++ b/src/core/org.freedesktop.systemd1.policy.in
|
||||
@@ -70,4 +70,14 @@
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
+ <action id="org.freedesktop.systemd1.bypass-dump-ratelimit">
|
||||
+ <description gettext-domain="systemd">Dump the systemd state without rate limits</description>
|
||||
+ <message gettext-domain="systemd">Authentication is required to dump the systemd state without rate limits.</message>
|
||||
+ <defaults>
|
||||
+ <allow_any>auth_admin</allow_any>
|
||||
+ <allow_inactive>auth_admin</allow_inactive>
|
||||
+ <allow_active>auth_admin_keep</allow_active>
|
||||
+ </defaults>
|
||||
+ </action>
|
||||
+
|
||||
</policyconfig>
|
||||
diff --git a/test/units/testsuite-65.sh b/test/units/testsuite-65.sh
|
||||
index 7c34948f82..f416194922 100755
|
||||
--- a/test/units/testsuite-65.sh
|
||||
+++ b/test/units/testsuite-65.sh
|
||||
@@ -51,6 +51,21 @@ systemd-analyze dot --require systemd-journald.service systemd-logind.service >/
|
||||
systemd-analyze dot "systemd-*.service" >/dev/null
|
||||
(! systemd-analyze dot systemd-journald.service systemd-logind.service "*" bbb ccc)
|
||||
# dump
|
||||
+# this should be rate limited to 10 calls in 10 minutes for unprivileged callers
|
||||
+for _ in {1..10}; do
|
||||
+ runas testuser systemd-analyze dump systemd-journald.service >/dev/null
|
||||
+done
|
||||
+(! runas testuser systemd-analyze dump >/dev/null)
|
||||
+# still limited after a reload
|
||||
+systemctl daemon-reload
|
||||
+(! runas testuser systemd-analyze dump >/dev/null)
|
||||
+# and a re-exec
|
||||
+systemctl daemon-reexec
|
||||
+(! runas testuser systemd-analyze dump >/dev/null)
|
||||
+# privileged call, so should not be rate limited
|
||||
+for _ in {1..10}; do
|
||||
+ systemd-analyze dump systemd-journald.service >/dev/null
|
||||
+done
|
||||
systemd-analyze dump >/dev/null
|
||||
systemd-analyze dump "*" >/dev/null
|
||||
systemd-analyze dump "*.socket" >/dev/null
|
60
0804-ci-define-runas-function-inline.patch
Normal file
60
0804-ci-define-runas-function-inline.patch
Normal file
@ -0,0 +1,60 @@
|
||||
From 3e5091146213b8b4abf0c5f5577a98b9da9c9f2c Mon Sep 17 00:00:00 2001
|
||||
From: Jan Macku <jamacku@redhat.com>
|
||||
Date: Tue, 11 Jun 2024 15:21:14 +0200
|
||||
Subject: [PATCH] ci: define `runas` function inline
|
||||
|
||||
We don't have `test/units/util.sh`, which provides the definition of `runas` function in the RHEL9 codebase
|
||||
|
||||
Also partially backport https://github.com/systemd/systemd/commit/c7bf1959d7580e1b7e918b75f852b3bf3fb6eb3c
|
||||
|
||||
rhel-only
|
||||
|
||||
Related: RHEL-35703
|
||||
---
|
||||
test/test-functions | 5 +++--
|
||||
test/units/testsuite-65.sh | 7 +++++++
|
||||
2 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/test/test-functions b/test/test-functions
|
||||
index 947f8589c5..52eff07510 100644
|
||||
--- a/test/test-functions
|
||||
+++ b/test/test-functions
|
||||
@@ -206,6 +206,7 @@ BASICTOOLS=(
|
||||
seq
|
||||
setfattr
|
||||
setfont
|
||||
+ setpriv
|
||||
setsid
|
||||
sfdisk
|
||||
sh
|
||||
@@ -2616,10 +2617,10 @@ inst_binary() {
|
||||
# Same as above, but we need to wrap certain libraries unconditionally
|
||||
#
|
||||
# chown, getent, login, su, useradd, userdel - dlopen()s (not only) systemd's PAM modules
|
||||
- # ls, stat - pulls in nss_systemd with certain options (like ls -l) when
|
||||
+ # ls, setpriv, stat - pulls in nss_systemd with certain options (like ls -l) when
|
||||
# nsswitch.conf uses [SUCCESS=merge] (like on Arch Linux)
|
||||
# tar - called by machinectl in TEST-25
|
||||
- if get_bool "$IS_BUILT_WITH_ASAN" && [[ "$bin" =~ /(chown|getent|login|id|ls|stat|su|tar|useradd|userdel)$ ]]; then
|
||||
+ if get_bool "$IS_BUILT_WITH_ASAN" && [[ "$bin" =~ /(chown|getent|login|id|ls|setpriv|stat|su|tar|useradd|userdel)$ ]]; then
|
||||
wrap_binary=1
|
||||
fi
|
||||
|
||||
diff --git a/test/units/testsuite-65.sh b/test/units/testsuite-65.sh
|
||||
index f416194922..0fb143bde7 100755
|
||||
--- a/test/units/testsuite-65.sh
|
||||
+++ b/test/units/testsuite-65.sh
|
||||
@@ -6,6 +6,13 @@ set -eux
|
||||
# shellcheck source=test/units/assert.sh
|
||||
. "$(dirname "$0")"/assert.sh
|
||||
|
||||
+# On RHEL9 we don't have the `util.sh` script, so we need to define the `runas` function here
|
||||
+runas() {
|
||||
+ local userid="${1:?}"
|
||||
+ shift
|
||||
+ XDG_RUNTIME_DIR=/run/user/"$(id -u "$userid")" setpriv --reuid="$userid" --init-groups "$@"
|
||||
+}
|
||||
+
|
||||
systemctl log-level debug
|
||||
export SYSTEMD_LOG_LEVEL=debug
|
||||
|
31
0805-Drop-dev-test-in-test-mountpoint-util.patch
Normal file
31
0805-Drop-dev-test-in-test-mountpoint-util.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From f6fdbbe989e54480882b9eeda452d168eea804a2 Mon Sep 17 00:00:00 2001
|
||||
From: Daan De Meyer <daan.j.demeyer@gmail.com>
|
||||
Date: Thu, 21 Dec 2023 19:46:54 +0100
|
||||
Subject: [PATCH] Drop /dev test in test-mountpoint-util
|
||||
|
||||
Even /dev isn't always guaranteed to be a mount point, so let's drop
|
||||
this part of the test.
|
||||
|
||||
(cherry picked from commit bacad14f94a4e98c3e81d821c56dbe7e2e4726ff)
|
||||
|
||||
Related: RHEL-30372
|
||||
---
|
||||
src/test/test-mountpoint-util.c | 5 -----
|
||||
1 file changed, 5 deletions(-)
|
||||
|
||||
diff --git a/src/test/test-mountpoint-util.c b/src/test/test-mountpoint-util.c
|
||||
index 8555c5a7db..d8e56c0365 100644
|
||||
--- a/src/test/test-mountpoint-util.c
|
||||
+++ b/src/test/test-mountpoint-util.c
|
||||
@@ -138,11 +138,6 @@ TEST(path_is_mount_point) {
|
||||
assert_se(path_is_mount_point("/proc/1/", NULL, AT_SYMLINK_FOLLOW) == 0);
|
||||
assert_se(path_is_mount_point("/proc/1/", NULL, 0) == 0);
|
||||
|
||||
- assert_se(path_is_mount_point("/dev", NULL, AT_SYMLINK_FOLLOW) > 0);
|
||||
- assert_se(path_is_mount_point("/dev", NULL, 0) > 0);
|
||||
- assert_se(path_is_mount_point("/dev/", NULL, AT_SYMLINK_FOLLOW) > 0);
|
||||
- assert_se(path_is_mount_point("/dev/", NULL, 0) > 0);
|
||||
-
|
||||
/* we'll create a hierarchy of different kinds of dir/file/link
|
||||
* layouts:
|
||||
*
|
69
0806-core-manager-export-manager_dbus_is_running.patch
Normal file
69
0806-core-manager-export-manager_dbus_is_running.patch
Normal file
@ -0,0 +1,69 @@
|
||||
From 7302d5d45efc1b157ddbfb04c387d83a87c8384f Mon Sep 17 00:00:00 2001
|
||||
From: Mike Yuan <me@yhndnzj.com>
|
||||
Date: Mon, 8 May 2023 23:10:07 +0800
|
||||
Subject: [PATCH] core/manager: export manager_dbus_is_running
|
||||
|
||||
(cherry picked from commit e8863150653931ae2ffc91757623f179ce763628)
|
||||
|
||||
Resolves: RHEL-40878
|
||||
---
|
||||
src/core/manager.c | 8 ++++----
|
||||
src/core/manager.h | 5 +++++
|
||||
2 files changed, 9 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/core/manager.c b/src/core/manager.c
|
||||
index b44c7785cf..fd6e711c65 100644
|
||||
--- a/src/core/manager.c
|
||||
+++ b/src/core/manager.c
|
||||
@@ -1680,7 +1680,7 @@ static void manager_distribute_fds(Manager *m, FDSet *fds) {
|
||||
}
|
||||
}
|
||||
|
||||
-static bool manager_dbus_is_running(Manager *m, bool deserialized) {
|
||||
+bool manager_dbus_is_running_full(Manager *m, bool deserialized) {
|
||||
Unit *u;
|
||||
|
||||
assert(m);
|
||||
@@ -1722,7 +1722,7 @@ static void manager_setup_bus(Manager *m) {
|
||||
(void) bus_init_system(m);
|
||||
|
||||
/* Let's connect to the bus now, but only if the unit is supposed to be up */
|
||||
- if (manager_dbus_is_running(m, MANAGER_IS_RELOADING(m))) {
|
||||
+ if (manager_dbus_is_running_full(m, MANAGER_IS_RELOADING(m))) {
|
||||
(void) bus_init_api(m);
|
||||
|
||||
if (MANAGER_IS_SYSTEM(m))
|
||||
@@ -2815,7 +2815,7 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
|
||||
break;
|
||||
|
||||
case SIGUSR1:
|
||||
- if (manager_dbus_is_running(m, false)) {
|
||||
+ if (manager_dbus_is_running(m)) {
|
||||
log_info("Trying to reconnect to bus...");
|
||||
|
||||
(void) bus_init_api(m);
|
||||
@@ -3930,7 +3930,7 @@ void manager_recheck_dbus(Manager *m) {
|
||||
if (MANAGER_IS_RELOADING(m))
|
||||
return; /* don't check while we are reloading… */
|
||||
|
||||
- if (manager_dbus_is_running(m, false)) {
|
||||
+ if (manager_dbus_is_running(m)) {
|
||||
(void) bus_init_api(m);
|
||||
|
||||
if (MANAGER_IS_SYSTEM(m))
|
||||
diff --git a/src/core/manager.h b/src/core/manager.h
|
||||
index 86e7e40989..1479813de4 100644
|
||||
--- a/src/core/manager.h
|
||||
+++ b/src/core/manager.h
|
||||
@@ -491,6 +491,11 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
|
||||
|
||||
int manager_startup(Manager *m, FILE *serialization, FDSet *fds, const char *root);
|
||||
|
||||
+bool manager_dbus_is_running_full(Manager *m, bool deserialized);
|
||||
+static inline bool manager_dbus_is_running(Manager *m) {
|
||||
+ return manager_dbus_is_running_full(m, false);
|
||||
+}
|
||||
+
|
||||
Job *manager_get_job(Manager *m, uint32_t id);
|
||||
Unit *manager_get_unit(Manager *m, const char *name);
|
||||
|
@ -0,0 +1,61 @@
|
||||
From 40f8600cfd866e4956fb09ca29bc5dc74e605450 Mon Sep 17 00:00:00 2001
|
||||
From: Mike Yuan <me@yhndnzj.com>
|
||||
Date: Tue, 9 May 2023 00:07:45 +0800
|
||||
Subject: [PATCH] core: refuse dbus activation if dbus is not running
|
||||
|
||||
dbus-broker issues StartUnit directly for activation requests,
|
||||
so let's add a check on bus state in bus_unit_queue_job to refuse
|
||||
that if dbus is not running.
|
||||
|
||||
Replaces #27570
|
||||
Closes #26799
|
||||
|
||||
(cherry picked from commit 53964fd26b4a01191609ffc064aa8ccccd28e377)
|
||||
|
||||
Resolves: RHEL-40878
|
||||
---
|
||||
src/core/dbus-unit.c | 7 +++++++
|
||||
src/core/dbus.c | 5 ++---
|
||||
2 files changed, 9 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
|
||||
index 19a71b6cb3..685d45fc23 100644
|
||||
--- a/src/core/dbus-unit.c
|
||||
+++ b/src/core/dbus-unit.c
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
#include "selinux-access.h"
|
||||
+#include "service.h"
|
||||
#include "signal-util.h"
|
||||
#include "special.h"
|
||||
#include "string-table.h"
|
||||
@@ -1845,6 +1846,12 @@ int bus_unit_queue_job(
|
||||
(type == JOB_RELOAD_OR_START && job_type_collapse(type, u) == JOB_START && u->refuse_manual_start))
|
||||
return sd_bus_error_setf(error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).", u->id);
|
||||
|
||||
+ /* dbus-broker issues StartUnit for activation requests, so let's apply the same check
|
||||
+ * used in signal_activation_request(). */
|
||||
+ if (type == JOB_START && u->type == UNIT_SERVICE &&
|
||||
+ SERVICE(u)->type == SERVICE_DBUS && !manager_dbus_is_running(u->manager))
|
||||
+ return sd_bus_error_set(error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is not running.");
|
||||
+
|
||||
r = sd_bus_message_new_method_return(message, &reply);
|
||||
if (r < 0)
|
||||
return r;
|
||||
diff --git a/src/core/dbus.c b/src/core/dbus.c
|
||||
index 3cbe9c5cfd..b4564f79a2 100644
|
||||
--- a/src/core/dbus.c
|
||||
+++ b/src/core/dbus.c
|
||||
@@ -160,9 +160,8 @@ static int signal_activation_request(sd_bus_message *message, void *userdata, sd
|
||||
return 0;
|
||||
}
|
||||
|
||||
- if (manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SERVICE) ||
|
||||
- manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SOCKET)) {
|
||||
- r = sd_bus_error_set(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is shutting down.");
|
||||
+ if (!manager_dbus_is_running(m)) {
|
||||
+ r = sd_bus_error_set(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is not running.");
|
||||
goto failed;
|
||||
}
|
||||
|
@ -0,0 +1,84 @@
|
||||
From 6e61224e554decd747d6537a4d6839cff6b19909 Mon Sep 17 00:00:00 2001
|
||||
From: Mike Yuan <me@yhndnzj.com>
|
||||
Date: Wed, 10 May 2023 13:54:15 +0800
|
||||
Subject: [PATCH] core: only refuse Type=dbus service enqueuing if dbus has
|
||||
stop job
|
||||
|
||||
Follow-up for #27579
|
||||
|
||||
In #27579 we refused all StartUnit requests for Type=dbus units
|
||||
if dbus is not running, which means if dbus is manually stopped,
|
||||
user can't use systemctl to start Type=dbus units again, which
|
||||
is incorrect.
|
||||
|
||||
The only culprit that leads to the cancellation of the whole
|
||||
transaction mentioned in #26799 is job type conflict on dbus.
|
||||
So let's relax the restriction and only refuse job enqueuing
|
||||
if dbus has a stop job.
|
||||
|
||||
To summarize, the case we want to avoid is:
|
||||
|
||||
1. dbus has a stop job installed
|
||||
2. StartUnit/ActivationRequest is received
|
||||
3. Type=dbus service gets started, which has Requires=dbus.socket
|
||||
4. dbus is pulled in again, resulting in job type conflict
|
||||
|
||||
What we can support is:
|
||||
|
||||
1. dbus is already stopped
|
||||
2. StartUnit is received (possibly through systemctl, i.e. on private bus)
|
||||
3. Type=dbus service gets started, which will wait for dbus to start
|
||||
4. dbus is started again, thus the job for Type=dbus service
|
||||
|
||||
Replaces #27590
|
||||
Fixes #27588
|
||||
|
||||
(cherry picked from commit bee6e755bb8e53a7a436e221b015ce0232ed87c0)
|
||||
|
||||
Resolves: RHEL-40878
|
||||
---
|
||||
src/core/dbus-unit.c | 31 ++++++++++++++++++++++++-------
|
||||
1 file changed, 24 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
|
||||
index 685d45fc23..49eacc977c 100644
|
||||
--- a/src/core/dbus-unit.c
|
||||
+++ b/src/core/dbus-unit.c
|
||||
@@ -1844,13 +1844,30 @@ int bus_unit_queue_job(
|
||||
(type == JOB_STOP && u->refuse_manual_stop) ||
|
||||
(IN_SET(type, JOB_RESTART, JOB_TRY_RESTART) && (u->refuse_manual_start || u->refuse_manual_stop)) ||
|
||||
(type == JOB_RELOAD_OR_START && job_type_collapse(type, u) == JOB_START && u->refuse_manual_start))
|
||||
- return sd_bus_error_setf(error, BUS_ERROR_ONLY_BY_DEPENDENCY, "Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).", u->id);
|
||||
-
|
||||
- /* dbus-broker issues StartUnit for activation requests, so let's apply the same check
|
||||
- * used in signal_activation_request(). */
|
||||
- if (type == JOB_START && u->type == UNIT_SERVICE &&
|
||||
- SERVICE(u)->type == SERVICE_DBUS && !manager_dbus_is_running(u->manager))
|
||||
- return sd_bus_error_set(error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is not running.");
|
||||
+ return sd_bus_error_setf(error,
|
||||
+ BUS_ERROR_ONLY_BY_DEPENDENCY,
|
||||
+ "Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).",
|
||||
+ u->id);
|
||||
+
|
||||
+ /* dbus-broker issues StartUnit for activation requests, and Type=dbus services automatically
|
||||
+ * gain dependency on dbus.socket. Therefore, if dbus has a pending stop job, the new start
|
||||
+ * job that pulls in dbus again would cause job type conflict. Let's avoid that by rejecting
|
||||
+ * job enqueuing early.
|
||||
+ *
|
||||
+ * Note that unlike signal_activation_request(), we can't use unit_inactive_or_pending()
|
||||
+ * here. StartUnit is a more generic interface, and thus users are allowed to use e.g. systemctl
|
||||
+ * to start Type=dbus services even when dbus is inactive. */
|
||||
+ if (type == JOB_START && u->type == UNIT_SERVICE && SERVICE(u)->type == SERVICE_DBUS)
|
||||
+ FOREACH_STRING(dbus_unit, SPECIAL_DBUS_SOCKET, SPECIAL_DBUS_SERVICE) {
|
||||
+ Unit *dbus;
|
||||
+
|
||||
+ dbus = manager_get_unit(u->manager, dbus_unit);
|
||||
+ if (dbus && unit_stop_pending(dbus))
|
||||
+ return sd_bus_error_setf(error,
|
||||
+ BUS_ERROR_SHUTTING_DOWN,
|
||||
+ "Operation for unit %s refused, D-Bus is shutting down.",
|
||||
+ u->id);
|
||||
+ }
|
||||
|
||||
r = sd_bus_message_new_method_return(message, &reply);
|
||||
if (r < 0)
|
@ -0,0 +1,93 @@
|
||||
From 07ec0810cf4dc638c138735eccda78e37ff42be7 Mon Sep 17 00:00:00 2001
|
||||
From: Mike Yuan <me@yhndnzj.com>
|
||||
Date: Thu, 11 May 2023 18:55:43 +0800
|
||||
Subject: [PATCH] Revert "core/manager: export manager_dbus_is_running" and
|
||||
partially "core: refuse dbus activation if dbus is not running"
|
||||
|
||||
This reverts commit e8863150653931ae2ffc91757623f179ce763628
|
||||
and partially 53964fd26b4a01191609ffc064aa8ccccd28e377.
|
||||
|
||||
Specifically, changes to signal_activation_request()
|
||||
is not desired.
|
||||
|
||||
(cherry picked from commit 2b680534c9667341551b39f4cc9735cd6e8c014e)
|
||||
|
||||
Resolves: RHEL-40878
|
||||
---
|
||||
src/core/dbus.c | 5 +++--
|
||||
src/core/manager.c | 8 ++++----
|
||||
src/core/manager.h | 5 -----
|
||||
3 files changed, 7 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/core/dbus.c b/src/core/dbus.c
|
||||
index b4564f79a2..1431e079c2 100644
|
||||
--- a/src/core/dbus.c
|
||||
+++ b/src/core/dbus.c
|
||||
@@ -160,8 +160,9 @@ static int signal_activation_request(sd_bus_message *message, void *userdata, sd
|
||||
return 0;
|
||||
}
|
||||
|
||||
- if (!manager_dbus_is_running(m)) {
|
||||
- r = sd_bus_error_set(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is not running.");
|
||||
+ if (manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SOCKET) ||
|
||||
+ manager_unit_inactive_or_pending(m, SPECIAL_DBUS_SERVICE)) {
|
||||
+ r = sd_bus_error_set(&error, BUS_ERROR_SHUTTING_DOWN, "Refusing activation, D-Bus is shutting down.");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
diff --git a/src/core/manager.c b/src/core/manager.c
|
||||
index fd6e711c65..b44c7785cf 100644
|
||||
--- a/src/core/manager.c
|
||||
+++ b/src/core/manager.c
|
||||
@@ -1680,7 +1680,7 @@ static void manager_distribute_fds(Manager *m, FDSet *fds) {
|
||||
}
|
||||
}
|
||||
|
||||
-bool manager_dbus_is_running_full(Manager *m, bool deserialized) {
|
||||
+static bool manager_dbus_is_running(Manager *m, bool deserialized) {
|
||||
Unit *u;
|
||||
|
||||
assert(m);
|
||||
@@ -1722,7 +1722,7 @@ static void manager_setup_bus(Manager *m) {
|
||||
(void) bus_init_system(m);
|
||||
|
||||
/* Let's connect to the bus now, but only if the unit is supposed to be up */
|
||||
- if (manager_dbus_is_running_full(m, MANAGER_IS_RELOADING(m))) {
|
||||
+ if (manager_dbus_is_running(m, MANAGER_IS_RELOADING(m))) {
|
||||
(void) bus_init_api(m);
|
||||
|
||||
if (MANAGER_IS_SYSTEM(m))
|
||||
@@ -2815,7 +2815,7 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
|
||||
break;
|
||||
|
||||
case SIGUSR1:
|
||||
- if (manager_dbus_is_running(m)) {
|
||||
+ if (manager_dbus_is_running(m, false)) {
|
||||
log_info("Trying to reconnect to bus...");
|
||||
|
||||
(void) bus_init_api(m);
|
||||
@@ -3930,7 +3930,7 @@ void manager_recheck_dbus(Manager *m) {
|
||||
if (MANAGER_IS_RELOADING(m))
|
||||
return; /* don't check while we are reloading… */
|
||||
|
||||
- if (manager_dbus_is_running(m)) {
|
||||
+ if (manager_dbus_is_running(m, false)) {
|
||||
(void) bus_init_api(m);
|
||||
|
||||
if (MANAGER_IS_SYSTEM(m))
|
||||
diff --git a/src/core/manager.h b/src/core/manager.h
|
||||
index 1479813de4..86e7e40989 100644
|
||||
--- a/src/core/manager.h
|
||||
+++ b/src/core/manager.h
|
||||
@@ -491,11 +491,6 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
|
||||
|
||||
int manager_startup(Manager *m, FILE *serialization, FDSet *fds, const char *root);
|
||||
|
||||
-bool manager_dbus_is_running_full(Manager *m, bool deserialized);
|
||||
-static inline bool manager_dbus_is_running(Manager *m) {
|
||||
- return manager_dbus_is_running_full(m, false);
|
||||
-}
|
||||
-
|
||||
Job *manager_get_job(Manager *m, uint32_t id);
|
||||
Unit *manager_get_unit(Manager *m, const char *name);
|
||||
|
127
0810-manager-fix-reloading-in-reload-or-restart-marked.patch
Normal file
127
0810-manager-fix-reloading-in-reload-or-restart-marked.patch
Normal file
@ -0,0 +1,127 @@
|
||||
From 758cd9ddac150342dbac49ed4c80c68531c169b7 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||
Date: Fri, 28 Jul 2023 17:54:59 +0200
|
||||
Subject: [PATCH] manager: fix reloading in reload-or-restart --marked
|
||||
|
||||
bus_unit_queue_job_one has two callers:
|
||||
- bus_unit_queue_job which would do the appropriate transormations
|
||||
to turn JOB_TRY_RESTART into JOB_TRY_RELOAD,
|
||||
- and method_enqueue_marked_jobs which did not.
|
||||
In effect, method_enqueue_marked_jobs() would queue restart jobs for
|
||||
units which has Markers= needs-reload or needs-restart.
|
||||
|
||||
When the chunk of code which does the transformations is moved from
|
||||
bus_unit_queue_job to bus_unit_queue_job_one, there is no change for
|
||||
bus_unit_queue_job, and method_enqueue_marked_jobs is fixed.
|
||||
|
||||
The additional checks that are done seem reasonable to do from
|
||||
method_enqueue_marked_jobs: we shouldn't be restarting units which are
|
||||
configured to not allow that, or force unwanted start of dbus-broker.
|
||||
|
||||
(cherry picked from commit 8ea8e23f4013dbc4f4a66c81eb786f0505434f2e)
|
||||
|
||||
Resolves: RHEL-40878
|
||||
---
|
||||
src/core/dbus-unit.c | 82 ++++++++++++++++++++++----------------------
|
||||
1 file changed, 41 insertions(+), 41 deletions(-)
|
||||
|
||||
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
|
||||
index 49eacc977c..b45b3fdb53 100644
|
||||
--- a/src/core/dbus-unit.c
|
||||
+++ b/src/core/dbus-unit.c
|
||||
@@ -1736,6 +1736,47 @@ int bus_unit_queue_job_one(
|
||||
Job *j, *a;
|
||||
int r;
|
||||
|
||||
+ if (FLAGS_SET(flags, BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE) && unit_can_reload(u)) {
|
||||
+ if (type == JOB_RESTART)
|
||||
+ type = JOB_RELOAD_OR_START;
|
||||
+ else if (type == JOB_TRY_RESTART)
|
||||
+ type = JOB_TRY_RELOAD;
|
||||
+ }
|
||||
+
|
||||
+ if (type == JOB_STOP &&
|
||||
+ IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_ERROR, UNIT_BAD_SETTING) &&
|
||||
+ unit_active_state(u) == UNIT_INACTIVE)
|
||||
+ return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", u->id);
|
||||
+
|
||||
+ if ((type == JOB_START && u->refuse_manual_start) ||
|
||||
+ (type == JOB_STOP && u->refuse_manual_stop) ||
|
||||
+ (IN_SET(type, JOB_RESTART, JOB_TRY_RESTART) && (u->refuse_manual_start || u->refuse_manual_stop)) ||
|
||||
+ (type == JOB_RELOAD_OR_START && job_type_collapse(type, u) == JOB_START && u->refuse_manual_start))
|
||||
+ return sd_bus_error_setf(error,
|
||||
+ BUS_ERROR_ONLY_BY_DEPENDENCY,
|
||||
+ "Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).",
|
||||
+ u->id);
|
||||
+
|
||||
+ /* dbus-broker issues StartUnit for activation requests, and Type=dbus services automatically
|
||||
+ * gain dependency on dbus.socket. Therefore, if dbus has a pending stop job, the new start
|
||||
+ * job that pulls in dbus again would cause job type conflict. Let's avoid that by rejecting
|
||||
+ * job enqueuing early.
|
||||
+ *
|
||||
+ * Note that unlike signal_activation_request(), we can't use unit_inactive_or_pending()
|
||||
+ * here. StartUnit is a more generic interface, and thus users are allowed to use e.g. systemctl
|
||||
+ * to start Type=dbus services even when dbus is inactive. */
|
||||
+ if (type == JOB_START && u->type == UNIT_SERVICE && SERVICE(u)->type == SERVICE_DBUS)
|
||||
+ FOREACH_STRING(dbus_unit, SPECIAL_DBUS_SOCKET, SPECIAL_DBUS_SERVICE) {
|
||||
+ Unit *dbus;
|
||||
+
|
||||
+ dbus = manager_get_unit(u->manager, dbus_unit);
|
||||
+ if (dbus && unit_stop_pending(dbus))
|
||||
+ return sd_bus_error_setf(error,
|
||||
+ BUS_ERROR_SHUTTING_DOWN,
|
||||
+ "Operation for unit %s refused, D-Bus is shutting down.",
|
||||
+ u->id);
|
||||
+ }
|
||||
+
|
||||
if (FLAGS_SET(flags, BUS_UNIT_QUEUE_VERBOSE_REPLY)) {
|
||||
affected = set_new(NULL);
|
||||
if (!affected)
|
||||
@@ -1828,47 +1869,6 @@ int bus_unit_queue_job(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
- if (FLAGS_SET(flags, BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE) && unit_can_reload(u)) {
|
||||
- if (type == JOB_RESTART)
|
||||
- type = JOB_RELOAD_OR_START;
|
||||
- else if (type == JOB_TRY_RESTART)
|
||||
- type = JOB_TRY_RELOAD;
|
||||
- }
|
||||
-
|
||||
- if (type == JOB_STOP &&
|
||||
- IN_SET(u->load_state, UNIT_NOT_FOUND, UNIT_ERROR, UNIT_BAD_SETTING) &&
|
||||
- unit_active_state(u) == UNIT_INACTIVE)
|
||||
- return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", u->id);
|
||||
-
|
||||
- if ((type == JOB_START && u->refuse_manual_start) ||
|
||||
- (type == JOB_STOP && u->refuse_manual_stop) ||
|
||||
- (IN_SET(type, JOB_RESTART, JOB_TRY_RESTART) && (u->refuse_manual_start || u->refuse_manual_stop)) ||
|
||||
- (type == JOB_RELOAD_OR_START && job_type_collapse(type, u) == JOB_START && u->refuse_manual_start))
|
||||
- return sd_bus_error_setf(error,
|
||||
- BUS_ERROR_ONLY_BY_DEPENDENCY,
|
||||
- "Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).",
|
||||
- u->id);
|
||||
-
|
||||
- /* dbus-broker issues StartUnit for activation requests, and Type=dbus services automatically
|
||||
- * gain dependency on dbus.socket. Therefore, if dbus has a pending stop job, the new start
|
||||
- * job that pulls in dbus again would cause job type conflict. Let's avoid that by rejecting
|
||||
- * job enqueuing early.
|
||||
- *
|
||||
- * Note that unlike signal_activation_request(), we can't use unit_inactive_or_pending()
|
||||
- * here. StartUnit is a more generic interface, and thus users are allowed to use e.g. systemctl
|
||||
- * to start Type=dbus services even when dbus is inactive. */
|
||||
- if (type == JOB_START && u->type == UNIT_SERVICE && SERVICE(u)->type == SERVICE_DBUS)
|
||||
- FOREACH_STRING(dbus_unit, SPECIAL_DBUS_SOCKET, SPECIAL_DBUS_SERVICE) {
|
||||
- Unit *dbus;
|
||||
-
|
||||
- dbus = manager_get_unit(u->manager, dbus_unit);
|
||||
- if (dbus && unit_stop_pending(dbus))
|
||||
- return sd_bus_error_setf(error,
|
||||
- BUS_ERROR_SHUTTING_DOWN,
|
||||
- "Operation for unit %s refused, D-Bus is shutting down.",
|
||||
- u->id);
|
||||
- }
|
||||
-
|
||||
r = sd_bus_message_new_method_return(message, &reply);
|
||||
if (r < 0)
|
||||
return r;
|
@ -0,0 +1,98 @@
|
||||
From 8f9211463be196fee3acaba8d0d3aaff1dc166a0 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||
Date: Wed, 26 Jul 2023 09:02:04 +0200
|
||||
Subject: [PATCH] rpm: add `systemd_postun_with_reload` and
|
||||
`systemd_user_postun_with_reload`
|
||||
|
||||
For some units, the package would like to issue a reload. The machinery was
|
||||
already in place since c9615f73521986b3607b852c139036d58973043c:
|
||||
|
||||
systemctl reload-or-restart --marked
|
||||
|
||||
Enqueues restart jobs for all units that have the 'needs-restart'
|
||||
mark, and reload jobs for units that have the 'needs-reload' mark.
|
||||
When a unit marked for reload does not support reload, restart will
|
||||
be queued.
|
||||
|
||||
The new macros allow a reload to be issued instead of a restart.
|
||||
|
||||
Based on the discussion on fedora-devel:
|
||||
https://lists.fedoraproject.org/archives/list/devel@lists.fedoraproject.org/message/IJSUGIEJNYZZRE53FF4YFUEBRHRAVIXR/
|
||||
|
||||
Tested using dummy package https://github.com/keszybz/rpm-test-reload.
|
||||
|
||||
(cherry picked from commit 631d2b05ec5195d1f8f8fbff8a2dfcbf23d0b7aa)
|
||||
|
||||
Resolves: RHEL-40878
|
||||
---
|
||||
src/rpm/macros.systemd.in | 16 ++++++++++++++++
|
||||
src/rpm/systemd-update-helper.in | 22 ++++++++++++++++++++++
|
||||
2 files changed, 38 insertions(+)
|
||||
|
||||
diff --git a/src/rpm/macros.systemd.in b/src/rpm/macros.systemd.in
|
||||
index 8880078b1b..fc607346e3 100644
|
||||
--- a/src/rpm/macros.systemd.in
|
||||
+++ b/src/rpm/macros.systemd.in
|
||||
@@ -101,6 +101,22 @@ if [ $1 -ge 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
|
||||
fi \
|
||||
%{nil}
|
||||
|
||||
+%systemd_postun_with_reload() \
|
||||
+%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_postun_with_reload}} \
|
||||
+if [ $1 -ge 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
|
||||
+ # Package upgrade, not uninstall \
|
||||
+ {{SYSTEMD_UPDATE_HELPER_PATH}} mark-reload-system-units %{?*} || : \
|
||||
+fi \
|
||||
+%{nil}
|
||||
+
|
||||
+%systemd_user_postun_with_reload() \
|
||||
+%{expand:%%{?__systemd_someargs_%#:%%__systemd_someargs_%# systemd_user_postun_with_reload}} \
|
||||
+if [ $1 -ge 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
|
||||
+ # Package upgrade, not uninstall \
|
||||
+ {{SYSTEMD_UPDATE_HELPER_PATH}} mark-reload-user-units %{?*} || : \
|
||||
+fi \
|
||||
+%{nil}
|
||||
+
|
||||
%udev_hwdb_update() %{nil}
|
||||
|
||||
%udev_rules_update() %{nil}
|
||||
diff --git a/src/rpm/systemd-update-helper.in b/src/rpm/systemd-update-helper.in
|
||||
index b35d952fab..1e00877de4 100755
|
||||
--- a/src/rpm/systemd-update-helper.in
|
||||
+++ b/src/rpm/systemd-update-helper.in
|
||||
@@ -47,6 +47,15 @@ case "$command" in
|
||||
wait
|
||||
;;
|
||||
|
||||
+ mark-reload-system-units)
|
||||
+ [ -d /run/systemd/system ] || exit 0
|
||||
+
|
||||
+ for unit in "$@"; do
|
||||
+ systemctl set-property "$unit" Markers=+needs-reload &
|
||||
+ done
|
||||
+ wait
|
||||
+ ;;
|
||||
+
|
||||
mark-restart-user-units)
|
||||
[ -d /run/systemd/system ] || exit 0
|
||||
|
||||
@@ -60,6 +69,19 @@ case "$command" in
|
||||
wait
|
||||
;;
|
||||
|
||||
+ mark-reload-user-units)
|
||||
+ [ -d /run/systemd/system ] || exit 0
|
||||
+
|
||||
+ users=$(systemctl list-units 'user@*' --legend=no | sed -n -r 's/.*user@([0-9]+).service.*/\1/p')
|
||||
+ for user in $users; do
|
||||
+ for unit in "$@"; do
|
||||
+ SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT}} \
|
||||
+ systemctl --user -M "$user@" set-property "$unit" Markers=+needs-reload &
|
||||
+ done
|
||||
+ done
|
||||
+ wait
|
||||
+ ;;
|
||||
+
|
||||
system-reload-restart|system-reload|system-restart)
|
||||
if [ -n "$*" ]; then
|
||||
echo "Unexpected arguments for '$command': $*"
|
38
0812-rpm-add-systemd_user_daemon_reexec.patch
Normal file
38
0812-rpm-add-systemd_user_daemon_reexec.patch
Normal file
@ -0,0 +1,38 @@
|
||||
From 2400e5c6395459fa3629747168c36df8ef543811 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||||
Date: Fri, 28 Jul 2023 19:24:58 +0200
|
||||
Subject: [PATCH] rpm: add `systemd_user_daemon_reexec`
|
||||
|
||||
This macros wraps the call to daemon-reexec in all user managers. It would be
|
||||
called for example from systemd %post right after the call to systemctl
|
||||
daemon-reexec.
|
||||
|
||||
This will be used in the Fedora systemd package to fix a long-standing FIXME.
|
||||
|
||||
Tested via building and reinstalling the systemd package with the patches.
|
||||
|
||||
(cherry picked from commit 9ff28e312bffe7567aa5d3f2c41303dd456f1691)
|
||||
|
||||
Resolves: RHEL-40878
|
||||
---
|
||||
src/rpm/macros.systemd.in | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/src/rpm/macros.systemd.in b/src/rpm/macros.systemd.in
|
||||
index fc607346e3..8d5895eba1 100644
|
||||
--- a/src/rpm/macros.systemd.in
|
||||
+++ b/src/rpm/macros.systemd.in
|
||||
@@ -117,6 +117,13 @@ if [ $1 -ge 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
|
||||
fi \
|
||||
%{nil}
|
||||
|
||||
+%systemd_user_daemon_reexec() \
|
||||
+if [ $1 -ge 1 ] && [ -x "{{SYSTEMD_UPDATE_HELPER_PATH}}" ]; then \
|
||||
+ # Package upgrade, not uninstall \
|
||||
+ {{SYSTEMD_UPDATE_HELPER_PATH}} user-reexec || : \
|
||||
+fi \
|
||||
+%{nil}
|
||||
+
|
||||
%udev_hwdb_update() %{nil}
|
||||
|
||||
%udev_rules_update() %{nil}
|
146
systemd.spec
146
systemd.spec
@ -25,7 +25,7 @@
|
||||
Name: systemd
|
||||
Url: https://systemd.io
|
||||
Version: 252
|
||||
Release: 35%{?dist}
|
||||
Release: 37%{?dist}
|
||||
# For a breakdown of the licensing, see README
|
||||
License: LGPLv2+ and MIT and GPLv2+
|
||||
Summary: System and Service Manager
|
||||
@ -830,6 +830,77 @@ Patch0738: 0738-bootspec-fix-null-dereference-read.patch
|
||||
Patch0739: 0739-units-don-t-install-pcrphase-related-units-without-g.patch
|
||||
Patch0740: 0740-kernel-install-fix-uki-copy-deinstall.patch
|
||||
Patch0741: 0741-ci-packit-explicitly-clone-c9s-branch.patch
|
||||
Patch0742: 0742-ci-src-git-add-RHEL-9.1-and-RHEL-9.1.z-to-allowed-ve.patch
|
||||
Patch0743: 0743-libsystemd-link-with-z-nodelete.patch
|
||||
Patch0744: 0744-basic-utf8-make-utf8_encoded_to_unichar-return-lengt.patch
|
||||
Patch0745: 0745-test-gunicode-add-new-test-to-show-that-unichar_iswi.patch
|
||||
Patch0746: 0746-string-util-pass-ANSI-sequences-through-unchanged.patch
|
||||
Patch0747: 0747-cryptsetup-do-not-assert-when-unsealing-token-withou.patch
|
||||
Patch0748: 0748-cryptsetup-check-the-existence-of-salt-by-salt_size-.patch
|
||||
Patch0749: 0749-core-mount-if-umount-8-fails-but-mount-disappeared-a.patch
|
||||
Patch0750: 0750-Drop-log-level-of-header-limits-log-message.patch
|
||||
Patch0751: 0751-journal-do-not-rotate-unrelated-journal-files-when-f.patch
|
||||
Patch0752: 0752-man-suffix-unit-with-an-equal-sign-since-it-expects-.patch
|
||||
Patch0753: 0753-shared-move-uid-alloc-range.-ch-from-src-shared-src-.patch
|
||||
Patch0754: 0754-journald-move-uid_for_system_journal-to-uid-alloc-ra.patch
|
||||
Patch0755: 0755-sd-journal-when-SD_JOURNAL_CURRENT_USER-is-set-and-c.patch
|
||||
Patch0756: 0756-man-document-that-journalctl-user-requires-Storage-p.patch
|
||||
Patch0757: 0757-fix-prefix-of-dmesg-pstore-files.patch
|
||||
Patch0758: 0758-backport-new-mkosi.patch
|
||||
Patch0759: 0759-test-Skip-various-tests-when-sys-is-not-mounted.patch
|
||||
Patch0760: 0760-string-util-introduce-ascii_ishex.patch
|
||||
Patch0761: 0761-sd-id128-several-cleanups.patch
|
||||
Patch0762: 0762-sd-id128-make-id128_read-or-friends-return-ENOPKG-wh.patch
|
||||
Patch0763: 0763-test-add-tests-for-uninitialized-string-handling-by-.patch
|
||||
Patch0764: 0764-man-mention-sd_id128_get_machine-or-friend-may-retur.patch
|
||||
Patch0765: 0765-sd-id128-make-sd_id128_get_boot-and-friend-return-EN.patch
|
||||
Patch0766: 0766-sd-id128-make-sd_id128_get_boot-and-friend-return-EN.patch
|
||||
Patch0767: 0767-man-mention-that-sd_id128_get_boot-and-friend-may-re.patch
|
||||
Patch0768: 0768-sd-id128-fold-do_sync-flag-into-Id128FormatFlag.patch
|
||||
Patch0769: 0769-sd-id128-make-sd_id128_get_machine-or-friends-return.patch
|
||||
Patch0770: 0770-sd-id128-allow-sd_id128_get_machine-and-friend-to-be.patch
|
||||
Patch0771: 0771-sd-id128-also-refuse-an-empty-invocation-ID.patch
|
||||
Patch0772: 0772-man-update-documents-for-sd_id128_get_invocation.patch
|
||||
Patch0773: 0773-test-id128-simplify-machine-id-check.patch
|
||||
Patch0774: 0774-test-fs-util-skip-part-of-test_chase_symlinks-if-mac.patch
|
||||
Patch0775: 0775-test-unit-name-simplify-machine-id-check.patch
|
||||
Patch0776: 0776-test-load-fragment-simplify-machine-id-check.patch
|
||||
Patch0777: 0777-journal-skip-part-of-test-journal-interleaving-if-no.patch
|
||||
Patch0778: 0778-test-skip-journal-tests-without-valid-etc-machine-id.patch
|
||||
Patch0779: 0779-test-recurse-dir-work-around-nftw-ignoring-symlinks.patch
|
||||
Patch0780: 0780-test-Skip-test-recurse-dir-on-overlayfs.patch
|
||||
Patch0781: 0781-test-specifier-Ignore-ENOPKG-from-specifier_printf.patch
|
||||
Patch0782: 0782-test-execute-Skip-when-sys-is-read-only.patch
|
||||
Patch0783: 0783-kernel-install-Make-sure-KERNEL_INSTALL_BYPASS-is-di.patch
|
||||
Patch0784: 0784-tools-make-sure-KERNEL_INSTALL_BYPASS-is-disabled-wh.patch
|
||||
Patch0785: 0785-test-execute-drop-capabilities-when-testing-with-use.patch
|
||||
Patch0786: 0786-tmpfiles-Add-merge-support-for-copy-files-action.patch
|
||||
Patch0787: 0787-generator-add-generator_open_unit_file_full-to-allow.patch
|
||||
Patch0788: 0788-network-generator-rewrite-unit-if-it-already-exists-.patch
|
||||
Patch0789: 0789-ci-drop-super-linter-s-shellcheck.patch
|
||||
Patch0790: 0790-mkosi-make-sure-we-build-use-RHEL-9-stuff.patch
|
||||
Patch0791: 0791-ci-backport-mkosi-CI-configuration-from-upstream.patch
|
||||
Patch0792: 0792-mkosi-explicitly-enroll-SecureBoot-keys.patch
|
||||
Patch0793: 0793-test-execute-also-mount-tmpfs-on-dev-shm.patch
|
||||
Patch0794: 0794-mkosi-fix-UKI-addons-test.patch
|
||||
Patch0795: 0795-Revert-mkosi-Disable-cmdline-addon-test-for-now.patch
|
||||
Patch0796: 0796-Revert-mkosi-Don-t-fail-on-systemd-vconsole-setup.se.patch
|
||||
Patch0797: 0797-mkosi-make-shellcheck-happy.patch
|
||||
Patch0798: 0798-mkosi-use-pesign-for-signing-UKI-addons.patch
|
||||
Patch0799: 0799-test-copy-out-the-necessary-test-data-before-we-star.patch
|
||||
Patch0800: 0800-ci-make-the-build-dir-accessible-when-running-w-o-pr.patch
|
||||
Patch0801: 0801-ci-explicitly-change-oom-score-adj-before-running-te.patch
|
||||
Patch0802: 0802-ratelimit-add-ratelimit_left-helper.patch
|
||||
Patch0803: 0803-manager-restrict-Dump-to-privileged-callers-or-ratel.patch
|
||||
Patch0804: 0804-ci-define-runas-function-inline.patch
|
||||
Patch0805: 0805-Drop-dev-test-in-test-mountpoint-util.patch
|
||||
Patch0806: 0806-core-manager-export-manager_dbus_is_running.patch
|
||||
Patch0807: 0807-core-refuse-dbus-activation-if-dbus-is-not-running.patch
|
||||
Patch0808: 0808-core-only-refuse-Type-dbus-service-enqueuing-if-dbus.patch
|
||||
Patch0809: 0809-Revert-core-manager-export-manager_dbus_is_running-a.patch
|
||||
Patch0810: 0810-manager-fix-reloading-in-reload-or-restart-marked.patch
|
||||
Patch0811: 0811-rpm-add-systemd_postun_with_reload-and-systemd_user_.patch
|
||||
Patch0812: 0812-rpm-add-systemd_user_daemon_reexec.patch
|
||||
|
||||
# Downstream-only patches (9000–9999)
|
||||
|
||||
@ -1710,6 +1781,79 @@ systemd-hwdb update &>/dev/null || :
|
||||
%{_prefix}/lib/dracut/modules.d/70rhel-net-naming-sysattrs/*
|
||||
|
||||
%changelog
|
||||
* Thu Jun 13 2024 systemd maintenance team <systemd-maint@redhat.com> - 252-37
|
||||
- ci(src-git): add RHEL-9.1 and RHEL-9.1.z to allowed versions (RHEL-30372)
|
||||
- libsystemd: link with '-z nodelete' (RHEL-6589)
|
||||
- basic/utf8: make utf8_encoded_to_unichar() return length of the codepoint (RHEL-31219)
|
||||
- test-gunicode: add new test to show that unichar_iswide() is borked (RHEL-31219)
|
||||
- string-util: pass ANSI sequences through unchanged (RHEL-31219)
|
||||
- cryptsetup: do not assert when unsealing token without salt (RHEL-38864)
|
||||
- cryptsetup: check the existence of salt by salt_size > 0 (RHEL-38864)
|
||||
- core/mount: if umount(8) fails but mount disappeared, assume success (RHEL-13159)
|
||||
- Drop log level of header limits log message (RHEL-33890)
|
||||
- journal: do not rotate unrelated journal files when full or corrupted (RHEL-33890)
|
||||
- man: suffix --unit with an equal sign, since it expects an argument (RHEL-31070)
|
||||
- shared: move uid-alloc-range.[ch] from src/shared/ → src/basic/ (RHEL-31070)
|
||||
- journald: move uid_for_system_journal() to uid-alloc-range.h (RHEL-31070)
|
||||
- sd-journal: when SD_JOURNAL_CURRENT_USER is set, and called from system UID, imply SD_JOURNAL_SYSTEM (RHEL-31070)
|
||||
- man: document that journalctl --user requires Storage=persistent (RHEL-31070)
|
||||
- fix: prefix of dmesg pstore files (RHEL-20322)
|
||||
- backport new mkosi (RHEL-27512)
|
||||
- test: Skip various tests when /sys is not mounted (RHEL-27512)
|
||||
- string-util: introduce ascii_ishex() (RHEL-27512)
|
||||
- sd-id128: several cleanups (RHEL-27512)
|
||||
- sd-id128: make id128_read() or friends return -ENOPKG when the file contents is "uninitialized" (RHEL-27512)
|
||||
- test: add tests for "uninitialized" string handling by id128_read_fd() (RHEL-27512)
|
||||
- man: mention sd_id128_get_machine() or friend may return -ENOPKG (RHEL-27512)
|
||||
- sd-id128: make sd_id128_get_boot() and friend return -ENOMEDIUM (RHEL-27512)
|
||||
- sd-id128: make sd_id128_get_boot() and friend return -ENOSYS when /proc/ is not mounted (RHEL-27512)
|
||||
- man: mention that sd_id128_get_boot() and friend may return -ENOSYS (RHEL-27512)
|
||||
- sd-id128: fold do_sync flag into Id128FormatFlag (RHEL-27512)
|
||||
- sd-id128: make sd_id128_get_machine() or friends return -EUCLEAN when an ID is in an invalid format (RHEL-27512)
|
||||
- sd-id128: allow sd_id128_get_machine() and friend to be called with NULL (RHEL-27512)
|
||||
- sd-id128: also refuse an empty invocation ID (RHEL-27512)
|
||||
- man: update documents for sd_id128_get_invocation() (RHEL-27512)
|
||||
- test-id128: simplify machine-id check (RHEL-27512)
|
||||
- test-fs-util: skip part of test_chase_symlinks if machine-id is not initialized (RHEL-27512)
|
||||
- test-unit-name: simplify machine-id check (RHEL-27512)
|
||||
- test-load-fragment: simplify machine-id check (RHEL-27512)
|
||||
- journal: skip part of test-journal-interleaving if no machine-id exists (RHEL-27512)
|
||||
- test: skip journal tests without valid /etc/machine-id (RHEL-27512)
|
||||
- test-recurse-dir: work around nftw() ignoring symlinks() (RHEL-27512)
|
||||
- test: Skip test-recurse-dir on overlayfs (RHEL-27512)
|
||||
- test-specifier: Ignore -ENOPKG from specifier_printf() (RHEL-27512)
|
||||
- test-execute: Skip when /sys is read-only (RHEL-27512)
|
||||
- kernel-install: Make sure KERNEL_INSTALL_BYPASS is disabled in tests (RHEL-27512)
|
||||
- tools: make sure $KERNEL_INSTALL_BYPASS is disabled when checking help (RHEL-27512)
|
||||
- test-execute: drop capabilities when testing with user manager (RHEL-27512)
|
||||
- tmpfiles: Add merge support for copy files action (RHEL-27512)
|
||||
- generator: add generator_open_unit_file_full to allow creating temporary units (RHEL-27512)
|
||||
- network-generator: rewrite unit if it already exists and its content changed (RHEL-27512)
|
||||
- ci: drop super-linter's shellcheck (RHEL-27512)
|
||||
- mkosi: make sure we build & use RHEL 9 stuff (RHEL-27512)
|
||||
- ci: backport mkosi CI configuration from upstream (RHEL-27512)
|
||||
- mkosi: explicitly enroll SecureBoot keys (RHEL-27512)
|
||||
- test-execute: also mount tmpfs on /dev/shm (RHEL-27512)
|
||||
- mkosi: fix UKI addons test (RHEL-27512)
|
||||
- Revert "mkosi: Disable cmdline addon test for now" (RHEL-27512)
|
||||
- Revert "mkosi: Don't fail on systemd-vconsole-setup.service failure for now" (RHEL-27512)
|
||||
- mkosi: make shellcheck happy (RHEL-27512)
|
||||
- mkosi: use pesign for signing UKI addons (RHEL-27512)
|
||||
- test: copy out the necessary test data before we start overmounting stuff (RHEL-27512)
|
||||
- ci: make the build dir accessible when running w/o privileges (RHEL-27512)
|
||||
- ci: explicitly change oom-{score}-adj before running tests (RHEL-27512)
|
||||
- ratelimit: add ratelimit_left helper (RHEL-35703)
|
||||
- manager: restrict Dump*() to privileged callers or ratelimit (RHEL-35703)
|
||||
- ci: define `runas` function inline (RHEL-35703)
|
||||
- Drop /dev test in test-mountpoint-util (RHEL-30372)
|
||||
- core/manager: export manager_dbus_is_running (RHEL-40878)
|
||||
- core: refuse dbus activation if dbus is not running (RHEL-40878)
|
||||
- core: only refuse Type=dbus service enqueuing if dbus has stop job (RHEL-40878)
|
||||
- Revert "core/manager: export manager_dbus_is_running" and partially "core: refuse dbus activation if dbus is not running" (RHEL-40878)
|
||||
- manager: fix reloading in reload-or-restart --marked (RHEL-40878)
|
||||
- rpm: add `systemd_postun_with_reload` and `systemd_user_postun_with_reload` (RHEL-40878)
|
||||
- rpm: add `systemd_user_daemon_reexec` (RHEL-40878)
|
||||
|
||||
* Wed May 22 2024 Jan Macku <jamacku@redhat.com> - 252-35
|
||||
- spec: return selinux dependencies (RHEL-35732)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user