From 62b3010d44ad6cd9fe450ae51dc093d4d1ee8dd6 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Jul 22 2022 08:10:56 +0000 Subject: import systemd-239-62.el8 --- diff --git a/.systemd.metadata b/.systemd.metadata index 8ab9fd3..a883c33 100644 --- a/.systemd.metadata +++ b/.systemd.metadata @@ -1 +1 @@ -249634e3d6b3532f15465719f0437ce04c3eb377 SOURCES/systemd-239.tar.gz +8803baa484cbe36680463c8c5e6febeff074b8e7 SOURCES/systemd-239.tar.gz diff --git a/SOURCES/0771-mkosi-Add-gnutls-package.patch b/SOURCES/0771-mkosi-Add-gnutls-package.patch new file mode 100644 index 0000000..c8e174b --- /dev/null +++ b/SOURCES/0771-mkosi-Add-gnutls-package.patch @@ -0,0 +1,24 @@ +From 3cdbda49a4eca0dc28f1ebc7923c387bc9b69a9f Mon Sep 17 00:00:00 2001 +From: Jacek Migacz +Date: Sun, 26 Jun 2022 22:11:55 +0200 +Subject: [PATCH] mkosi: Add gnutls package + +RHEL-only + +Resolves: #2101227 +--- + .mkosi/mkosi.fedora | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/.mkosi/mkosi.fedora b/.mkosi/mkosi.fedora +index 63027d9fc7..b0451adec2 100644 +--- a/.mkosi/mkosi.fedora ++++ b/.mkosi/mkosi.fedora +@@ -61,6 +61,7 @@ BuildPackages= + + Packages= + libidn2 ++ gnutls + + BuildDirectory=mkosi.builddir + Cache=mkosi.cache diff --git a/SOURCES/0772-unit-name-tighten-checks-for-building-valid-unit-nam.patch b/SOURCES/0772-unit-name-tighten-checks-for-building-valid-unit-nam.patch new file mode 100644 index 0000000..aa8bb9c --- /dev/null +++ b/SOURCES/0772-unit-name-tighten-checks-for-building-valid-unit-nam.patch @@ -0,0 +1,181 @@ +From e3e479fc9c51e0b6f2c21087e2e78e7c6f55169c Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 25 May 2020 00:34:58 +0200 +Subject: [PATCH] unit-name: tighten checks for building valid unit names + +Let's be more thorough that whenever we build a unit name based on +parameters, that the result is actually a valid user name. If it isn't +fail early. + +This should allows us to catch various issues earlier, in particular +when we synthesize mount units from /proc/self/mountinfo: instead of +actually attempting to allocate a mount unit we will fail much earlier +when we build the name to synthesize the unit under. Failing early is a +good thing generally. + +(cherry picked from commit ab19db01ae1826efb3cbdf6dcb6a14412f8844d4) + +Related: #1940973 +--- + src/basic/unit-name.c | 61 ++++++++++++++++++++++++++++++------------- + 1 file changed, 43 insertions(+), 18 deletions(-) + +diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c +index 614eb8649b..f9b3fafd4d 100644 +--- a/src/basic/unit-name.c ++++ b/src/basic/unit-name.c +@@ -207,8 +207,9 @@ UnitType unit_name_to_type(const char *n) { + } + + int unit_name_change_suffix(const char *n, const char *suffix, char **ret) { +- char *e, *s; ++ _cleanup_free_ char *s = NULL; + size_t a, b; ++ char *e; + + assert(n); + assert(suffix); +@@ -230,8 +231,12 @@ int unit_name_change_suffix(const char *n, const char *suffix, char **ret) { + return -ENOMEM; + + strcpy(mempcpy(s, n, a), suffix); +- *ret = s; + ++ /* Make sure the name is still valid (i.e. didn't grow too large due to longer suffix) */ ++ if (!unit_name_is_valid(s, UNIT_NAME_ANY)) ++ return -EINVAL; ++ ++ *ret = TAKE_PTR(s); + return 0; + } + +@@ -253,8 +258,8 @@ int unit_name_build(const char *prefix, const char *instance, const char *suffix + } + + int unit_name_build_from_type(const char *prefix, const char *instance, UnitType type, char **ret) { ++ _cleanup_free_ char *s = NULL; + const char *ut; +- char *s; + + assert(prefix); + assert(type >= 0); +@@ -264,19 +269,23 @@ int unit_name_build_from_type(const char *prefix, const char *instance, UnitType + if (!unit_prefix_is_valid(prefix)) + return -EINVAL; + +- if (instance && !unit_instance_is_valid(instance)) +- return -EINVAL; +- + ut = unit_type_to_string(type); + +- if (!instance) +- s = strjoin(prefix, ".", ut); +- else ++ if (instance) { ++ if (!unit_instance_is_valid(instance)) ++ return -EINVAL; ++ + s = strjoin(prefix, "@", instance, ".", ut); ++ } else ++ s = strjoin(prefix, ".", ut); + if (!s) + return -ENOMEM; + +- *ret = s; ++ /* Verify that this didn't grow too large (or otherwise is invalid) */ ++ if (!unit_name_is_valid(s, instance ? UNIT_NAME_INSTANCE : UNIT_NAME_PLAIN)) ++ return -EINVAL; ++ ++ *ret = TAKE_PTR(s); + return 0; + } + +@@ -445,8 +454,8 @@ int unit_name_path_unescape(const char *f, char **ret) { + } + + int unit_name_replace_instance(const char *f, const char *i, char **ret) { ++ _cleanup_free_ char *s = NULL; + const char *p, *e; +- char *s; + size_t a, b; + + assert(f); +@@ -470,7 +479,11 @@ int unit_name_replace_instance(const char *f, const char *i, char **ret) { + + strcpy(mempcpy(mempcpy(s, f, a + 1), i, b), e); + +- *ret = s; ++ /* Make sure the resulting name still is valid, i.e. didn't grow too large */ ++ if (!unit_name_is_valid(s, UNIT_NAME_INSTANCE)) ++ return -EINVAL; ++ ++ *ret = TAKE_PTR(s); + return 0; + } + +@@ -501,8 +514,7 @@ int unit_name_template(const char *f, char **ret) { + } + + int unit_name_from_path(const char *path, const char *suffix, char **ret) { +- _cleanup_free_ char *p = NULL; +- char *s = NULL; ++ _cleanup_free_ char *p = NULL, *s = NULL; + int r; + + assert(path); +@@ -520,7 +532,11 @@ int unit_name_from_path(const char *path, const char *suffix, char **ret) { + if (!s) + return -ENOMEM; + +- *ret = s; ++ /* Refuse this if this got too long or for some other reason didn't result in a valid name */ ++ if (!unit_name_is_valid(s, UNIT_NAME_PLAIN)) ++ return -EINVAL; ++ ++ *ret = TAKE_PTR(s); + return 0; + } + +@@ -548,6 +564,10 @@ int unit_name_from_path_instance(const char *prefix, const char *path, const cha + if (!s) + return -ENOMEM; + ++ /* Refuse this if this got too long or for some other reason didn't result in a valid name */ ++ if (!unit_name_is_valid(s, UNIT_NAME_INSTANCE)) ++ return -EINVAL; ++ + *ret = s; + return 0; + } +@@ -601,7 +621,7 @@ static bool do_escape_mangle(const char *f, bool allow_globs, char *t) { + * If @allow_globs, globs characters are preserved. Otherwise, they are escaped. + */ + int unit_name_mangle_with_suffix(const char *name, UnitNameMangle flags, const char *suffix, char **ret) { +- char *s; ++ _cleanup_free_ char *s = NULL; + int r; + bool mangled; + +@@ -656,7 +676,12 @@ int unit_name_mangle_with_suffix(const char *name, UnitNameMangle flags, const c + if ((!(flags & UNIT_NAME_MANGLE_GLOB) || !string_is_glob(s)) && unit_name_to_type(s) < 0) + strcat(s, suffix); + +- *ret = s; ++ /* Make sure mangling didn't grow this too large (but don't do this check if globbing is allowed, ++ * since globs generally do not qualify as valid unit names) */ ++ if (!FLAGS_SET(flags, UNIT_NAME_MANGLE_GLOB) && !unit_name_is_valid(s, UNIT_NAME_ANY)) ++ return -EINVAL; ++ ++ *ret = TAKE_PTR(s); + return 1; + + good: +@@ -664,7 +689,7 @@ good: + if (!s) + return -ENOMEM; + +- *ret = s; ++ *ret = TAKE_PTR(s); + return 0; + } + diff --git a/SOURCES/0773-core-shorten-long-unit-names-that-are-based-on-paths.patch b/SOURCES/0773-core-shorten-long-unit-names-that-are-based-on-paths.patch new file mode 100644 index 0000000..7705a2c --- /dev/null +++ b/SOURCES/0773-core-shorten-long-unit-names-that-are-based-on-paths.patch @@ -0,0 +1,275 @@ +From f62231a54abff6566415ea82aa8773e61f5688d6 Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Tue, 15 Mar 2022 19:02:05 +0100 +Subject: [PATCH] core: shorten long unit names that are based on paths and + append path hash at the end + +Fixes #18077 + +(cherry picked from commit 1d0727e76fd5e9a07cc9991ec9a10ea1d78a99c7) + +Resolves: #1940973 +--- + src/basic/string-util.h | 23 +++++----- + src/basic/unit-name.c | 88 ++++++++++++++++++++++++++++++++++++++- + src/basic/unit-name.h | 3 ++ + src/core/mount.c | 3 ++ + src/test/test-unit-name.c | 25 ++++++++++- + 5 files changed, 129 insertions(+), 13 deletions(-) + +diff --git a/src/basic/string-util.h b/src/basic/string-util.h +index 742b566932..0d406ff64a 100644 +--- a/src/basic/string-util.h ++++ b/src/basic/string-util.h +@@ -9,17 +9,18 @@ + #include "macro.h" + + /* What is interpreted as whitespace? */ +-#define WHITESPACE " \t\n\r" +-#define NEWLINE "\n\r" +-#define QUOTES "\"\'" +-#define COMMENTS "#;" +-#define GLOB_CHARS "*?[" +-#define DIGITS "0123456789" +-#define LOWERCASE_LETTERS "abcdefghijklmnopqrstuvwxyz" +-#define UPPERCASE_LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +-#define LETTERS LOWERCASE_LETTERS UPPERCASE_LETTERS +-#define ALPHANUMERICAL LETTERS DIGITS +-#define HEXDIGITS DIGITS "abcdefABCDEF" ++#define WHITESPACE " \t\n\r" ++#define NEWLINE "\n\r" ++#define QUOTES "\"\'" ++#define COMMENTS "#;" ++#define GLOB_CHARS "*?[" ++#define DIGITS "0123456789" ++#define LOWERCASE_LETTERS "abcdefghijklmnopqrstuvwxyz" ++#define UPPERCASE_LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ++#define LETTERS LOWERCASE_LETTERS UPPERCASE_LETTERS ++#define ALPHANUMERICAL LETTERS DIGITS ++#define HEXDIGITS DIGITS "abcdefABCDEF" ++#define LOWERCASE_HEXDIGITS DIGITS "abcdef" + + #define streq(a,b) (strcmp((a),(b)) == 0) + #define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) +diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c +index f9b3fafd4d..65ed979e39 100644 +--- a/src/basic/unit-name.c ++++ b/src/basic/unit-name.c +@@ -6,11 +6,17 @@ + #include + #include + ++#include "sd-id128.h" ++ + #include "alloc-util.h" + #include "glob-util.h" + #include "hexdecoct.h" + #include "path-util.h" ++#include "random-util.h" ++#include "siphash24.h" ++#include "sparse-endian.h" + #include "special.h" ++#include "stdio-util.h" + #include "string-util.h" + #include "strv.h" + #include "unit-name.h" +@@ -31,6 +37,9 @@ + VALID_CHARS_WITH_AT \ + "[]!-*?" + ++#define LONG_UNIT_NAME_HASH_KEY SD_ID128_MAKE(ec,f2,37,fb,58,32,4a,32,84,9f,06,9b,0d,21,eb,9a) ++#define UNIT_NAME_HASH_LENGTH_CHARS 16 ++ + bool unit_name_is_valid(const char *n, UnitNameFlags flags) { + const char *e, *i, *at; + +@@ -513,6 +522,68 @@ int unit_name_template(const char *f, char **ret) { + return 0; + } + ++bool unit_name_is_hashed(const char *name) { ++ char *s; ++ ++ if (!unit_name_is_valid(name, UNIT_NAME_PLAIN)) ++ return false; ++ ++ assert_se(s = strrchr(name, '.')); ++ ++ if (s - name < UNIT_NAME_HASH_LENGTH_CHARS + 1) ++ return false; ++ ++ s -= UNIT_NAME_HASH_LENGTH_CHARS; ++ if (s[-1] != '_') ++ return false; ++ ++ for (size_t i = 0; i < UNIT_NAME_HASH_LENGTH_CHARS; i++) ++ if (!strchr(LOWERCASE_HEXDIGITS, s[i])) ++ return false; ++ ++ return true; ++} ++ ++int unit_name_hash_long(const char *name, char **ret) { ++ _cleanup_free_ char *n = NULL, *hash = NULL; ++ char *suffix; ++ le64_t h; ++ size_t len; ++ ++ if (strlen(name) < UNIT_NAME_MAX) ++ return -EMSGSIZE; ++ ++ suffix = strrchr(name, '.'); ++ if (!suffix) ++ return -EINVAL; ++ ++ if (unit_type_from_string(suffix+1) < 0) ++ return -EINVAL; ++ ++ h = htole64(siphash24(name, strlen(name) + 1, LONG_UNIT_NAME_HASH_KEY.bytes)); ++ ++ hash = hexmem(&h, sizeof(h)); ++ if (!hash) ++ return -ENOMEM; ++ ++ assert_se(strlen(hash) == UNIT_NAME_HASH_LENGTH_CHARS); ++ ++ len = UNIT_NAME_MAX - 1 - strlen(suffix+1) - UNIT_NAME_HASH_LENGTH_CHARS - 2; ++ assert(len > 0 && len < UNIT_NAME_MAX); ++ ++ n = strndup(name, len); ++ if (!n) ++ return -ENOMEM; ++ ++ if (!strextend(&n, "_", hash, suffix, NULL)) ++ return -ENOMEM; ++ assert_se(unit_name_is_valid(n, UNIT_NAME_PLAIN)); ++ ++ *ret = TAKE_PTR(n); ++ ++ return 0; ++} ++ + int unit_name_from_path(const char *path, const char *suffix, char **ret) { + _cleanup_free_ char *p = NULL, *s = NULL; + int r; +@@ -532,7 +603,19 @@ int unit_name_from_path(const char *path, const char *suffix, char **ret) { + if (!s) + return -ENOMEM; + +- /* Refuse this if this got too long or for some other reason didn't result in a valid name */ ++ if (strlen(s) >= UNIT_NAME_MAX) { ++ _cleanup_free_ char *n = NULL; ++ ++ log_debug("Unit name \"%s\" too long, falling back to hashed unit name.", s); ++ ++ r = unit_name_hash_long(s, &n); ++ if (r < 0) ++ return r; ++ ++ free_and_replace(s, n); ++ } ++ ++ /* Refuse if this for some other reason didn't result in a valid name */ + if (!unit_name_is_valid(s, UNIT_NAME_PLAIN)) + return -EINVAL; + +@@ -582,6 +665,9 @@ int unit_name_to_path(const char *name, char **ret) { + if (r < 0) + return r; + ++ if (unit_name_is_hashed(name)) ++ return -ENAMETOOLONG; ++ + return unit_name_path_unescape(prefix, ret); + } + +diff --git a/src/basic/unit-name.h b/src/basic/unit-name.h +index 61abcd585b..602295af8f 100644 +--- a/src/basic/unit-name.h ++++ b/src/basic/unit-name.h +@@ -45,6 +45,9 @@ int unit_name_replace_instance(const char *f, const char *i, char **ret); + + int unit_name_template(const char *f, char **ret); + ++int unit_name_hash_long(const char *name, char **ret); ++bool unit_name_is_hashed(const char *name); ++ + int unit_name_from_path(const char *path, const char *suffix, char **ret); + int unit_name_from_path_instance(const char *prefix, const char *path, const char *suffix, char **ret); + int unit_name_to_path(const char *name, char **ret); +diff --git a/src/core/mount.c b/src/core/mount.c +index d37b5731f8..e69ecb7ce3 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -572,6 +572,9 @@ static int mount_add_extras(Mount *m) { + + if (!m->where) { + r = unit_name_to_path(u->id, &m->where); ++ if (r == -ENAMETOOLONG) ++ log_unit_error_errno(u, r, "Failed to derive mount point path from unit name, because unit name is hashed. " ++ "Set \"Where=\" in the unit file explicitly."); + if (r < 0) + return r; + } +diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c +index 2b00ef8cb7..35cfaafd30 100644 +--- a/src/test/test-unit-name.c ++++ b/src/test/test-unit-name.c +@@ -82,6 +82,7 @@ static void test_unit_name_replace_instance(void) { + + static void test_unit_name_from_path_one(const char *path, const char *suffix, const char *expected, int ret) { + _cleanup_free_ char *t = NULL; ++ int r; + + assert_se(unit_name_from_path(path, suffix, &t) == ret); + puts(strna(t)); +@@ -89,12 +90,31 @@ static void test_unit_name_from_path_one(const char *path, const char *suffix, c + + if (t) { + _cleanup_free_ char *k = NULL; +- assert_se(unit_name_to_path(t, &k) == 0); ++ ++ /* We don't support converting hashed unit names back to paths */ ++ r = unit_name_to_path(t, &k); ++ if (r == -ENAMETOOLONG) ++ return; ++ assert(r == 0); ++ + puts(strna(k)); + assert_se(path_equal(k, empty_to_root(path))); + } + } + ++static void test_unit_name_is_hashed(void) { ++ assert_se(!unit_name_is_hashed("")); ++ assert_se(!unit_name_is_hashed("foo@bar.service")); ++ assert_se(!unit_name_is_hashed("foo@.service")); ++ assert_se(unit_name_is_hashed("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_7736d9ed33c2ec55.mount")); ++ assert_se(!unit_name_is_hashed("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_7736D9ED33C2EC55.mount")); ++ assert_se(!unit_name_is_hashed("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!7736d9ed33c2ec55.mount")); ++ assert_se(!unit_name_is_hashed("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_7736d9gd33c2ec55.mount")); ++ assert_se(!unit_name_is_hashed("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_.mount")); ++ assert_se(!unit_name_is_hashed("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_2103e1466b87f7f7@waldo.mount")); ++ assert_se(!unit_name_is_hashed("waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_2103e1466b87f7f7@.mount")); ++} ++ + static void test_unit_name_from_path(void) { + puts("-------------------------------------------------"); + test_unit_name_from_path_one("/waldo", ".mount", "waldo.mount", 0); +@@ -105,6 +125,8 @@ static void test_unit_name_from_path(void) { + test_unit_name_from_path_one("///", ".mount", "-.mount", 0); + test_unit_name_from_path_one("/foo/../bar", ".mount", NULL, -EINVAL); + test_unit_name_from_path_one("/foo/./bar", ".mount", NULL, -EINVAL); ++ test_unit_name_from_path_one("/waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", ".mount", ++ "waldoaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa_7736d9ed33c2ec55.mount", 0); + } + + static void test_unit_name_from_path_instance_one(const char *pattern, const char *path, const char *suffix, const char *expected, int ret) { +@@ -824,6 +846,7 @@ int main(int argc, char* argv[]) { + + test_unit_name_is_valid(); + test_unit_name_replace_instance(); ++ test_unit_name_is_hashed(); + test_unit_name_from_path(); + test_unit_name_from_path_instance(); + test_unit_name_mangle(); diff --git a/SOURCES/0774-test-add-extended-test-for-triggering-mount-rate-lim.patch b/SOURCES/0774-test-add-extended-test-for-triggering-mount-rate-lim.patch new file mode 100644 index 0000000..635a2a0 --- /dev/null +++ b/SOURCES/0774-test-add-extended-test-for-triggering-mount-rate-lim.patch @@ -0,0 +1,162 @@ +From 2b390a10d826f060a672d9f01c6ad43714691274 Mon Sep 17 00:00:00 2001 +From: Anita Zhang +Date: Tue, 8 Jun 2021 00:04:35 -0700 +Subject: [PATCH] test: add extended test for triggering mount rate limit + +It's hard to trigger the failure to exit the rate limit state in +isolation as it needs multiple event sources in order to show that it +gets stuck in the queue. Hence why this is an extended test. + +(cherry picked from commit 0c81900965a72b29eb76e0737ed899b925ee75b6) + +Related: #1940973 +--- + test/TEST-60-MOUNT-RATELIMIT/Makefile | 1 + + test/TEST-60-MOUNT-RATELIMIT/test.sh | 48 +++++++++++++++ + test/TEST-60-MOUNT-RATELIMIT/testsuite.sh | 73 +++++++++++++++++++++++ + 3 files changed, 122 insertions(+) + create mode 120000 test/TEST-60-MOUNT-RATELIMIT/Makefile + create mode 100755 test/TEST-60-MOUNT-RATELIMIT/test.sh + create mode 100755 test/TEST-60-MOUNT-RATELIMIT/testsuite.sh + +diff --git a/test/TEST-60-MOUNT-RATELIMIT/Makefile b/test/TEST-60-MOUNT-RATELIMIT/Makefile +new file mode 120000 +index 0000000000..e9f93b1104 +--- /dev/null ++++ b/test/TEST-60-MOUNT-RATELIMIT/Makefile +@@ -0,0 +1 @@ ++../TEST-01-BASIC/Makefile +\ No newline at end of file +diff --git a/test/TEST-60-MOUNT-RATELIMIT/test.sh b/test/TEST-60-MOUNT-RATELIMIT/test.sh +new file mode 100755 +index 0000000000..e3c9288546 +--- /dev/null ++++ b/test/TEST-60-MOUNT-RATELIMIT/test.sh +@@ -0,0 +1,48 @@ ++#!/usr/bin/env bash ++set -e ++TEST_DESCRIPTION="Test that mount/unmount storms can enter/exit rate limit state and will not leak units" ++ ++. $TEST_BASE_DIR/test-functions ++ ++test_setup() { ++ create_empty_image ++ mkdir -p $TESTDIR/root ++ mount ${LOOPDEV}p1 $TESTDIR/root ++ ++ ( ++ LOG_LEVEL=5 ++ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) ++ ++ setup_basic_environment ++ ++ # mask some services that we do not want to run in these tests ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service ++ ++ # setup the testsuite service ++ cat >$initdir/etc/systemd/system/testsuite.service </testok ++ ++exit 0 diff --git a/SOURCES/0775-tests-add-test-case-for-long-unit-names.patch b/SOURCES/0775-tests-add-test-case-for-long-unit-names.patch new file mode 100644 index 0000000..197b19b --- /dev/null +++ b/SOURCES/0775-tests-add-test-case-for-long-unit-names.patch @@ -0,0 +1,42 @@ +From 1c2a0bde1bc3510d9bdc07410ff90429ebed391f Mon Sep 17 00:00:00 2001 +From: Michal Sekletar +Date: Wed, 23 Mar 2022 13:35:44 +0100 +Subject: [PATCH] tests: add test case for long unit names + +(cherry picked from commit 2ef0101e0b2813e8c99fc8f137dbaa763ca16057) + +Related: #1940973 +--- + test/TEST-60-MOUNT-RATELIMIT/testsuite.sh | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh b/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh +index 8158754667..6211050faf 100755 +--- a/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh ++++ b/test/TEST-60-MOUNT-RATELIMIT/testsuite.sh +@@ -7,6 +7,25 @@ systemd-analyze log-target journal + + NUM_DIRS=20 + ++# make sure we can handle mounts at very long paths such that mount unit name must be hashed to fall within our unit name limit ++LONGPATH="$(printf "/$(printf "x%0.s" {1..255})%0.s" {1..7})" ++LONGMNT="$(systemd-escape --suffix=mount --path "$LONGPATH")" ++TS="$(date '+%H:%M:%S')" ++ ++mkdir -p "$LONGPATH" ++mount -t tmpfs tmpfs "$LONGPATH" ++systemctl daemon-reload ++ ++# check that unit is active(mounted) ++systemctl --no-pager show -p SubState --value "$LONGPATH" | grep -q mounted ++ ++# check that relevant part of journal doesn't contain any errors related to unit ++[ "$(journalctl -b --since="$TS" --priority=err | grep -c "$LONGMNT")" = "0" ] ++ ++# check that we can successfully stop the mount unit ++systemctl stop "$LONGPATH" ++rm -rf "$LONGPATH" ++ + # mount/unmount enough times to trigger the /proc/self/mountinfo parsing rate limiting + + for ((i = 0; i < NUM_DIRS; i++)); do diff --git a/SOURCES/0776-core-unset-HOME-that-the-kernel-gives-us.patch b/SOURCES/0776-core-unset-HOME-that-the-kernel-gives-us.patch new file mode 100644 index 0000000..1753f0c --- /dev/null +++ b/SOURCES/0776-core-unset-HOME-that-the-kernel-gives-us.patch @@ -0,0 +1,33 @@ +From 9ba5d8811630a3d2af90fdc52f4fd6b03ee9e692 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Tue, 21 May 2019 19:26:12 +0200 +Subject: [PATCH] core: unset HOME=/ that the kernel gives us + +Partially fixes #12389. + +%h would return "/" in a machine, but "/root" in a container. Let's fix +this by resetting $HOME to the expected value. + +(cherry picked from commit 9d48671c62de133a2b9fe7c31e70c0ff8e68f2db) + +Resolves: #2056527 +--- + src/core/main.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/core/main.c b/src/core/main.c +index d897155644..08a4df3c97 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -1307,6 +1307,11 @@ static int fixup_environment(void) { + if (setenv("TERM", t, 1) < 0) + return -errno; + ++ /* The kernels sets HOME=/ for init. Let's undo this. */ ++ if (path_equal_ptr(getenv("HOME"), "/") && ++ unsetenv("HOME") < 0) ++ log_warning_errno(errno, "Failed to unset $HOME: %m"); ++ + return 0; + } + diff --git a/SOURCES/0777-journal-remote-check-return-value-from-MHD_add_respo.patch b/SOURCES/0777-journal-remote-check-return-value-from-MHD_add_respo.patch new file mode 100644 index 0000000..e4a1e2d --- /dev/null +++ b/SOURCES/0777-journal-remote-check-return-value-from-MHD_add_respo.patch @@ -0,0 +1,94 @@ +From c20e06c1c0319e3759a11bf9051a8041898f79b2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Sun, 7 Mar 2021 12:08:06 +0100 +Subject: [PATCH] journal-remote: check return value from + MHD_add_response_header + +Sadly, the API does not allow us to distinguish oom from invalid settings. +If the call fails, let's assume oom happened. + +Coverity CID#1444714. + +(cherry picked from commit 60d9c4f3b972ce70dfadc0a3f1a478a056c2ea7a) + +Resolves: #2051981 +--- + src/journal-remote/journal-gatewayd.c | 22 ++++++++++++++++------ + src/journal-remote/microhttpd-util.c | 3 ++- + 2 files changed, 18 insertions(+), 7 deletions(-) + +diff --git a/src/journal-remote/journal-gatewayd.c b/src/journal-remote/journal-gatewayd.c +index 3a167ab890..54446ff7b5 100644 +--- a/src/journal-remote/journal-gatewayd.c ++++ b/src/journal-remote/journal-gatewayd.c +@@ -492,7 +492,9 @@ static int request_handler_entries( + if (!response) + return respond_oom(connection); + +- MHD_add_response_header(response, "Content-Type", mime_types[m->mode]); ++ if (MHD_add_response_header(response, "Content-Type", mime_types[m->mode]) == MHD_NO) ++ return respond_oom(connection); ++ + return MHD_queue_response(connection, MHD_HTTP_OK, response); + } + +@@ -627,7 +629,9 @@ static int request_handler_fields( + if (!response) + return respond_oom(connection); + +- MHD_add_response_header(response, "Content-Type", mime_types[m->mode == OUTPUT_JSON ? OUTPUT_JSON : OUTPUT_SHORT]); ++ if (MHD_add_response_header(response, "Content-Type", mime_types[m->mode == OUTPUT_JSON ? OUTPUT_JSON : OUTPUT_SHORT]) == MHD_NO) ++ return respond_oom(connection); ++ + return MHD_queue_response(connection, MHD_HTTP_OK, response); + } + +@@ -650,8 +654,10 @@ static int request_handler_redirect( + return respond_oom(connection); + } + +- MHD_add_response_header(response, "Content-Type", "text/html"); +- MHD_add_response_header(response, "Location", target); ++ if (MHD_add_response_header(response, "Content-Type", "text/html") == MHD_NO || ++ MHD_add_response_header(response, "Location", target) == MHD_NO) ++ return respond_oom(connection); ++ + return MHD_queue_response(connection, MHD_HTTP_MOVED_PERMANENTLY, response); + } + +@@ -680,7 +686,9 @@ static int request_handler_file( + return respond_oom(connection); + TAKE_FD(fd); + +- MHD_add_response_header(response, "Content-Type", mime_type); ++ if (MHD_add_response_header(response, "Content-Type", mime_type) == MHD_NO) ++ return respond_oom(connection); ++ + return MHD_queue_response(connection, MHD_HTTP_OK, response); + } + +@@ -781,7 +789,9 @@ static int request_handler_machine( + return respond_oom(connection); + TAKE_PTR(json); + +- MHD_add_response_header(response, "Content-Type", "application/json"); ++ if (MHD_add_response_header(response, "Content-Type", "application/json") == MHD_NO) ++ return respond_oom(connection); ++ + return MHD_queue_response(connection, MHD_HTTP_OK, response); + } + +diff --git a/src/journal-remote/microhttpd-util.c b/src/journal-remote/microhttpd-util.c +index 2ae5172fe9..fdfeaeb2f5 100644 +--- a/src/journal-remote/microhttpd-util.c ++++ b/src/journal-remote/microhttpd-util.c +@@ -40,7 +40,8 @@ static int mhd_respond_internal(struct MHD_Connection *connection, + return MHD_NO; + + log_debug("Queueing response %u: %s", code, buffer); +- MHD_add_response_header(response, "Content-Type", "text/plain"); ++ if (MHD_add_response_header(response, "Content-Type", "text/plain") == MHD_NO) ++ return MHD_NO; + return MHD_queue_response(connection, code, response); + } + diff --git a/SOURCES/0778-journalctl-in-follow-mode-watch-stdout-for-POLLHUP-P.patch b/SOURCES/0778-journalctl-in-follow-mode-watch-stdout-for-POLLHUP-P.patch new file mode 100644 index 0000000..6d0cf4d --- /dev/null +++ b/SOURCES/0778-journalctl-in-follow-mode-watch-stdout-for-POLLHUP-P.patch @@ -0,0 +1,117 @@ +From 67d3aade15bede6b162e8bfe88db60311efb0d1f Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 24 Oct 2018 21:49:52 +0200 +Subject: [PATCH] journalctl: in --follow mode watch stdout for POLLHUP/POLLERR + and exit + +Fixes: #9374 +(cherry picked from commit 2a1e0f2228bbdfbc18635e959f47df7da50b62fe) + +Resolves: #2003236 +--- + src/journal/journalctl.c | 65 +++++++++++++++++++++++++++++----------- + 1 file changed, 48 insertions(+), 17 deletions(-) + +diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c +index 56b1be530d..fa83dce562 100644 +--- a/src/journal/journalctl.c ++++ b/src/journal/journalctl.c +@@ -2064,14 +2064,46 @@ static int sync_journal(void) { + return send_signal_and_wait(SIGRTMIN+1, "/run/systemd/journal/synced"); + } + +-int main(int argc, char *argv[]) { ++static int wait_for_change(sd_journal *j, int poll_fd) { ++ struct pollfd pollfds[] = { ++ { .fd = poll_fd, .events = POLLIN }, ++ { .fd = STDOUT_FILENO }, ++ }; ++ ++ struct timespec ts; ++ usec_t timeout; + int r; ++ ++ assert(j); ++ assert(poll_fd >= 0); ++ ++ /* Much like sd_journal_wait() but also keeps an eye on STDOUT, and exits as soon as we see a POLLHUP on that, ++ * i.e. when it is closed. */ ++ ++ r = sd_journal_get_timeout(j, &timeout); ++ if (r < 0) ++ return log_error_errno(r, "Failed to determine journal waiting time: %m"); ++ ++ if (ppoll(pollfds, ELEMENTSOF(pollfds), timeout == USEC_INFINITY ? NULL : timespec_store(&ts, timeout), NULL) < 0) ++ return log_error_errno(errno, "Couldn't wait for journal event: %m"); ++ ++ if (pollfds[1].revents & (POLLHUP|POLLERR)) { /* STDOUT has been closed? */ ++ log_debug("Standard output has been closed."); ++ return -ECANCELED; ++ } ++ ++ r = sd_journal_process(j); ++ if (r < 0) ++ return log_error_errno(r, "Failed to process journal events: %m"); ++ ++ return 0; ++} ++ ++int main(int argc, char *argv[]) { ++ bool previous_boot_id_valid = false, first_line = true, ellipsized = false, need_seek = false; + _cleanup_(sd_journal_closep) sd_journal *j = NULL; +- bool need_seek = false; + sd_id128_t previous_boot_id; +- bool previous_boot_id_valid = false, first_line = true; +- int n_shown = 0; +- bool ellipsized = false; ++ int n_shown = 0, r, poll_fd = -1; + + setlocale(LC_ALL, ""); + log_parse_environment(); +@@ -2391,15 +2423,15 @@ int main(int argc, char *argv[]) { + + /* Opening the fd now means the first sd_journal_wait() will actually wait */ + if (arg_follow) { +- r = sd_journal_get_fd(j); +- if (r == -EMFILE) { +- log_warning("Insufficent watch descriptors available. Reverting to -n."); ++ poll_fd = sd_journal_get_fd(j); ++ if (poll_fd == -EMFILE) { ++ log_warning_errno(poll_fd, "Insufficent watch descriptors available. Reverting to -n."); + arg_follow = false; +- } else if (r == -EMEDIUMTYPE) { +- log_error_errno(r, "The --follow switch is not supported in conjunction with reading from STDIN."); ++ } else if (poll_fd == -EMEDIUMTYPE) { ++ log_error_errno(poll_fd, "The --follow switch is not supported in conjunction with reading from STDIN."); + goto finish; +- } else if (r < 0) { +- log_error_errno(r, "Failed to get journal fd: %m"); ++ } else if (poll_fd < 0) { ++ log_error_errno(poll_fd, "Failed to get journal fd: %m"); + goto finish; + } + } +@@ -2621,7 +2653,7 @@ int main(int argc, char *argv[]) { + need_seek = true; + if (r == -EADDRNOTAVAIL) + break; +- else if (r < 0 || ferror(stdout)) ++ else if (r < 0) + goto finish; + + n_shown++; +@@ -2659,11 +2691,10 @@ int main(int argc, char *argv[]) { + } + + fflush(stdout); +- r = sd_journal_wait(j, (uint64_t) -1); +- if (r < 0) { +- log_error_errno(r, "Couldn't wait for journal event: %m"); ++ ++ r = wait_for_change(j, poll_fd); ++ if (r < 0) + goto finish; +- } + + first_line = false; + } diff --git a/SOURCES/0779-sd-bus-make-BUS_DEFAULT_TIMEOUT-configurable.patch b/SOURCES/0779-sd-bus-make-BUS_DEFAULT_TIMEOUT-configurable.patch new file mode 100644 index 0000000..02d9904 --- /dev/null +++ b/SOURCES/0779-sd-bus-make-BUS_DEFAULT_TIMEOUT-configurable.patch @@ -0,0 +1,182 @@ +From 3022d49ba2276eb5634d84a89a078aa3c357b70a Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Fri, 13 Jul 2018 17:38:47 +0900 +Subject: [PATCH] sd-bus: make BUS_DEFAULT_TIMEOUT configurable + +This adds sd_bus_{get,set}_method_call_timeout(). +If the timeout is not set or set to 0, then the timeout value is +parsed from $SYSTEMD_BUS_TIMEOUT= environment variable. If the +environment variable is not set, then built-in timeout is used. + +(cherry picked from commit 385b2eb262a99373f09d01b7f5571dd71a14dc98) + +Resolves: #2039461 +--- + doc/ENVIRONMENT.md | 5 ++++ + src/libsystemd/libsystemd.sym | 7 ++++- + src/libsystemd/sd-bus/bus-internal.h | 9 ++++--- + src/libsystemd/sd-bus/bus-message.c | 7 +++-- + src/libsystemd/sd-bus/sd-bus.c | 40 ++++++++++++++++++++++++++-- + src/systemd/sd-bus.h | 3 +++ + 6 files changed, 62 insertions(+), 9 deletions(-) + +diff --git a/doc/ENVIRONMENT.md b/doc/ENVIRONMENT.md +index 8d7ce6ae2c..d1a79eaa4f 100644 +--- a/doc/ENVIRONMENT.md ++++ b/doc/ENVIRONMENT.md +@@ -50,6 +50,11 @@ All tools: + this only controls use of Unicode emoji glyphs, and has no effect on other + Unicode glyphs. + ++* `$SYSTEMD_BUS_TIMEOUT=SECS` — specifies the maximum time to wait for method call ++ completion. If no time unit is specified, assumes seconds. The usual other units ++ are understood, too (us, ms, s, min, h, d, w, month, y). If it is not set or set ++ to 0, then the built-in default is used. ++ + systemctl: + + * `$SYSTEMCTL_FORCE_BUS=1` — if set, do not connect to PID1's private D-Bus +diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym +index f4a1426248..3b55fc6473 100644 +--- a/src/libsystemd/libsystemd.sym ++++ b/src/libsystemd/libsystemd.sym +@@ -573,12 +573,17 @@ global: + sd_event_source_disable_unref; + } LIBSYSTEMD_238; + ++LIBSYSTEMD_240 { ++ sd_bus_set_method_call_timeout; ++ sd_bus_get_method_call_timeout; ++} LIBSYSTEMD_239; ++ + LIBSYSTEMD_248 { + global: + sd_event_source_set_ratelimit; + sd_event_source_get_ratelimit; + sd_event_source_is_ratelimited; +-} LIBSYSTEMD_239; ++} LIBSYSTEMD_240; + + LIBSYSTEMD_250 { + global: +diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h +index 06bd7862cb..88415ae678 100644 +--- a/src/libsystemd/sd-bus/bus-internal.h ++++ b/src/libsystemd/sd-bus/bus-internal.h +@@ -319,6 +319,9 @@ struct sd_bus { + + int *inotify_watches; + size_t n_inotify_watches; ++ ++ /* zero means use value specified by $SYSTEMD_BUS_TIMEOUT= environment variable or built-in default */ ++ usec_t method_call_timeout; + }; + + /* For method calls we time-out at 25s, like in the D-Bus reference implementation */ +@@ -340,8 +343,7 @@ struct sd_bus { + + #define BUS_CONTAINER_DEPTH 128 + +-/* Defined by the specification as maximum size of an array in +- * bytes */ ++/* Defined by the specification as maximum size of an array in bytes */ + #define BUS_ARRAY_MAX_SIZE 67108864 + + #define BUS_FDS_MAX 1024 +@@ -392,8 +394,7 @@ void bus_close_io_fds(sd_bus *b); + _slash = streq((prefix), "/") ? NULL : strrchr((prefix), '/')) + + /* If we are invoking callbacks of a bus object, ensure unreffing the +- * bus from the callback doesn't destroy the object we are working +- * on */ ++ * bus from the callback doesn't destroy the object we are working on */ + #define BUS_DONT_DESTROY(bus) \ + _cleanup_(sd_bus_unrefp) _unused_ sd_bus *_dont_destroy_##bus = sd_bus_ref(bus) + +diff --git a/src/libsystemd/sd-bus/bus-message.c b/src/libsystemd/sd-bus/bus-message.c +index 7fe8929f82..3ffe559b8d 100644 +--- a/src/libsystemd/sd-bus/bus-message.c ++++ b/src/libsystemd/sd-bus/bus-message.c +@@ -5882,8 +5882,11 @@ int bus_message_remarshal(sd_bus *bus, sd_bus_message **m) { + return r; + + timeout = (*m)->timeout; +- if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)) +- timeout = BUS_DEFAULT_TIMEOUT; ++ if (timeout == 0 && !((*m)->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)) { ++ r = sd_bus_get_method_call_timeout(bus, &timeout); ++ if (r < 0) ++ return r; ++ } + + r = sd_bus_message_seal(n, BUS_MESSAGE_COOKIE(*m), timeout); + if (r < 0) +diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c +index c65e24b2d1..803f3f50d6 100644 +--- a/src/libsystemd/sd-bus/sd-bus.c ++++ b/src/libsystemd/sd-bus/sd-bus.c +@@ -1651,8 +1651,11 @@ static int bus_seal_message(sd_bus *b, sd_bus_message *m, usec_t timeout) { + return 0; + } + +- if (timeout == 0) +- timeout = BUS_DEFAULT_TIMEOUT; ++ if (timeout == 0) { ++ r = sd_bus_get_method_call_timeout(b, &timeout); ++ if (r < 0) ++ return r; ++ } + + if (!m->sender && b->patch_sender) { + r = sd_bus_message_set_sender(m, b->patch_sender); +@@ -4141,3 +4144,36 @@ _public_ int sd_bus_enqueue_for_read(sd_bus *bus, sd_bus_message *m) { + bus->rqueue[bus->rqueue_size++] = bus_message_ref_queued(m, bus); + return 0; + } ++ ++_public_ int sd_bus_set_method_call_timeout(sd_bus *bus, uint64_t usec) { ++ assert_return(bus, -EINVAL); ++ assert_return(bus = bus_resolve(bus), -ENOPKG); ++ ++ bus->method_call_timeout = usec; ++ return 0; ++} ++ ++_public_ int sd_bus_get_method_call_timeout(sd_bus *bus, uint64_t *ret) { ++ const char *e; ++ usec_t usec; ++ ++ assert_return(bus, -EINVAL); ++ assert_return(bus = bus_resolve(bus), -ENOPKG); ++ assert_return(ret, -EINVAL); ++ ++ if (bus->method_call_timeout != 0) { ++ *ret = bus->method_call_timeout; ++ return 0; ++ } ++ ++ e = secure_getenv("SYSTEMD_BUS_TIMEOUT"); ++ if (e && parse_sec(e, &usec) >= 0 && usec != 0) { ++ /* Save the parsed value to avoid multiple parsing. To change the timeout value, ++ * use sd_bus_set_method_call_timeout() instead of setenv(). */ ++ *ret = bus->method_call_timeout = usec; ++ return 0; ++ } ++ ++ *ret = bus->method_call_timeout = BUS_DEFAULT_TIMEOUT; ++ return 0; ++} +diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h +index 9ba757b13d..8b6f70bd68 100644 +--- a/src/systemd/sd-bus.h ++++ b/src/systemd/sd-bus.h +@@ -207,6 +207,9 @@ sd_event *sd_bus_get_event(sd_bus *bus); + int sd_bus_get_n_queued_read(sd_bus *bus, uint64_t *ret); + int sd_bus_get_n_queued_write(sd_bus *bus, uint64_t *ret); + ++int sd_bus_set_method_call_timeout(sd_bus *bus, uint64_t usec); ++int sd_bus_get_method_call_timeout(sd_bus *bus, uint64_t *ret); ++ + int sd_bus_add_filter(sd_bus *bus, sd_bus_slot **slot, sd_bus_message_handler_t callback, void *userdata); + int sd_bus_add_match(sd_bus *bus, sd_bus_slot **slot, const char *match, sd_bus_message_handler_t callback, void *userdata); + int sd_bus_add_match_async(sd_bus *bus, sd_bus_slot **slot, const char *match, sd_bus_message_handler_t callback, sd_bus_message_handler_t install_callback, void *userdata); diff --git a/SOURCES/0780-fstab-generator-fix-debug-log.patch b/SOURCES/0780-fstab-generator-fix-debug-log.patch new file mode 100644 index 0000000..f8318f9 --- /dev/null +++ b/SOURCES/0780-fstab-generator-fix-debug-log.patch @@ -0,0 +1,25 @@ +From bbf71447d5de3b2cb86623a870cad21bbf114390 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Mon, 18 Feb 2019 11:29:45 +0900 +Subject: [PATCH] fstab-generator: fix debug log + +(cherry picked from commit 7731c1c20aeba4f1042f6076408db1f107d0706c) + +Resolves: #2101433 +--- + src/fstab-generator/fstab-generator.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c +index 482229b4a5..f24c1d29da 100644 +--- a/src/fstab-generator/fstab-generator.c ++++ b/src/fstab-generator/fstab-generator.c +@@ -561,7 +561,7 @@ static int parse_fstab(bool initrd) { + noauto = fstab_test_yes_no_option(me->mnt_opts, "noauto\0" "auto\0"); + nofail = fstab_test_yes_no_option(me->mnt_opts, "nofail\0" "fail\0"); + +- log_debug("Found entry what=%s where=%s type=%s makefs=%s nofail=%s noauto=%s", ++ log_debug("Found entry what=%s where=%s type=%s makefs=%s noauto=%s nofail=%s", + what, where, me->mnt_type, + yes_no(makefs), + yes_no(noauto), yes_no(nofail)); diff --git a/SOURCES/0781-logind-session-dbus-allow-to-set-display-name-via-db.patch b/SOURCES/0781-logind-session-dbus-allow-to-set-display-name-via-db.patch new file mode 100644 index 0000000..c024d91 --- /dev/null +++ b/SOURCES/0781-logind-session-dbus-allow-to-set-display-name-via-db.patch @@ -0,0 +1,123 @@ +From 54a8d932442d02f5a7dbf6038c8f557ce41f468b Mon Sep 17 00:00:00 2001 +From: David Tardon +Date: Fri, 10 Jun 2022 15:07:01 +0200 +Subject: [PATCH] logind-session-dbus: allow to set display name via dbus + +Currently, the only way to set display name of a graphical session is to +pass it to CreateSession(). But modern display managers like gdm start +the display server as part of the user session, which means that the +display name isn't known yet when the session is being created. Hence, +let's make it possible to set it later. + +(cherry picked from commit 4885d7490b23e08d8444e5a68927ce9ce8727e5a) + +Resolves: #1857969 +--- + src/login/logind-session-dbus.c | 26 ++++++++++++++++++++++++++ + src/login/logind-session.c | 20 ++++++++++++++++++++ + src/login/logind-session.h | 1 + + src/login/org.freedesktop.login1.conf | 4 ++++ + 4 files changed, 51 insertions(+) + +diff --git a/src/login/logind-session-dbus.c b/src/login/logind-session-dbus.c +index 03585b7f8e..c935959e02 100644 +--- a/src/login/logind-session-dbus.c ++++ b/src/login/logind-session-dbus.c +@@ -381,6 +381,31 @@ static int method_release_control(sd_bus_message *message, void *userdata, sd_bu + return sd_bus_reply_method_return(message, NULL); + } + ++static int method_set_display(sd_bus_message *message, void *userdata, sd_bus_error *error) { ++ Session *s = userdata; ++ const char *display; ++ int r; ++ ++ assert(message); ++ assert(s); ++ ++ r = sd_bus_message_read(message, "s", &display); ++ if (r < 0) ++ return r; ++ ++ if (!session_is_controller(s, sd_bus_message_get_sender(message))) ++ return sd_bus_error_set(error, BUS_ERROR_NOT_IN_CONTROL, "You must be in control of this session to set display"); ++ ++ if (!SESSION_TYPE_IS_GRAPHICAL(s->type)) ++ return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "Setting display is only supported for graphical sessions"); ++ ++ r = session_set_display(s, display); ++ if (r < 0) ++ return r; ++ ++ return sd_bus_reply_method_return(message, NULL); ++} ++ + static int method_take_device(sd_bus_message *message, void *userdata, sd_bus_error *error) { + Session *s = userdata; + uint32_t major, minor; +@@ -523,6 +548,7 @@ const sd_bus_vtable session_vtable[] = { + SD_BUS_METHOD("TakeDevice", "uu", "hb", method_take_device, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("ReleaseDevice", "uu", NULL, method_release_device, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("PauseDeviceComplete", "uu", NULL, method_pause_device_complete, SD_BUS_VTABLE_UNPRIVILEGED), ++ SD_BUS_METHOD("SetDisplay", "s", NULL, method_set_display, SD_BUS_VTABLE_UNPRIVILEGED), + + SD_BUS_SIGNAL("PauseDevice", "uus", 0), + SD_BUS_SIGNAL("ResumeDevice", "uuh", 0), +diff --git a/src/login/logind-session.c b/src/login/logind-session.c +index e4c8bb36f6..1143a834a4 100644 +--- a/src/login/logind-session.c ++++ b/src/login/logind-session.c +@@ -953,6 +953,26 @@ void session_set_locked_hint(Session *s, bool b) { + session_send_changed(s, "LockedHint", NULL); + } + ++int session_set_display(Session *s, const char *display) { ++ int r; ++ ++ assert(s); ++ assert(display); ++ ++ if (streq(s->display, display)) ++ return 0; ++ ++ r = free_and_strdup(&s->display, display); ++ if (r < 0) ++ return r; ++ ++ session_save(s); ++ ++ session_send_changed(s, "Display", NULL); ++ ++ return 1; ++} ++ + static int session_dispatch_fifo(sd_event_source *es, int fd, uint32_t revents, void *userdata) { + Session *s = userdata; + +diff --git a/src/login/logind-session.h b/src/login/logind-session.h +index 7d17d9a25f..9bd0c96a03 100644 +--- a/src/login/logind-session.h ++++ b/src/login/logind-session.h +@@ -123,6 +123,7 @@ int session_get_idle_hint(Session *s, dual_timestamp *t); + void session_set_idle_hint(Session *s, bool b); + int session_get_locked_hint(Session *s); + void session_set_locked_hint(Session *s, bool b); ++int session_set_display(Session *s, const char *display); + int session_create_fifo(Session *s); + int session_start(Session *s, sd_bus_message *properties, sd_bus_error *error); + int session_stop(Session *s, bool force); +diff --git a/src/login/org.freedesktop.login1.conf b/src/login/org.freedesktop.login1.conf +index dcde0c22c6..b780ae08cf 100644 +--- a/src/login/org.freedesktop.login1.conf ++++ b/src/login/org.freedesktop.login1.conf +@@ -314,6 +314,10 @@ + send_interface="org.freedesktop.login1.User" + send_member="Kill"/> + ++ ++ + + + diff --git a/SOURCES/0782-Allow-restart-for-oneshot-units.patch b/SOURCES/0782-Allow-restart-for-oneshot-units.patch new file mode 100644 index 0000000..fbf2bed --- /dev/null +++ b/SOURCES/0782-Allow-restart-for-oneshot-units.patch @@ -0,0 +1,160 @@ +From ffc616d9c4d2c64d211c9e63601a321524fe2d31 Mon Sep 17 00:00:00 2001 +From: Claudio Zumbo +Date: Tue, 8 Oct 2019 15:04:29 -0700 +Subject: [PATCH] Allow restart for oneshot units + +Picked up from https://github.com/systemd/systemd/pull/7474 , so +coauthored by @robermorales. + +(cherry picked from commit 10e72727eeeeb1a495303ec406fa8d1e1a83dc6e) + +Resolves: #2042896 +--- + man/systemd.service.xml | 7 ++-- + src/core/service.c | 5 +-- + test/TEST-41-ONESHOT-RESTART/Makefile | 9 +++++ + test/TEST-41-ONESHOT-RESTART/test.sh | 44 +++++++++++++++++++++++ + test/TEST-41-ONESHOT-RESTART/testsuite.sh | 33 +++++++++++++++++ + 5 files changed, 93 insertions(+), 5 deletions(-) + create mode 100644 test/TEST-41-ONESHOT-RESTART/Makefile + create mode 100755 test/TEST-41-ONESHOT-RESTART/test.sh + create mode 100755 test/TEST-41-ONESHOT-RESTART/testsuite.sh + +diff --git a/man/systemd.service.xml b/man/systemd.service.xml +index 1e30a564df..133296d386 100644 +--- a/man/systemd.service.xml ++++ b/man/systemd.service.xml +@@ -1276,9 +1276,10 @@ WantedBy=multi-user.target + + Type= are the + only service units that may have more than one +- ExecStart= specified. They will be executed +- in order until either they are all successful or one of them +- fails. ++ ExecStart= specified. For units with multiple ++ commands (Type=oneshot), all commands will be run again. ++ For Type=oneshot, Restart= ++ and Restart= are not allowed. + + + +diff --git a/src/core/service.c b/src/core/service.c +index e8ae1a5772..e05d0e0514 100644 +--- a/src/core/service.c ++++ b/src/core/service.c +@@ -581,8 +581,9 @@ static int service_verify(Service *s) { + return -ENOEXEC; + } + +- if (s->type == SERVICE_ONESHOT && s->restart != SERVICE_RESTART_NO) { +- log_unit_error(UNIT(s), "Service has Restart= setting other than no, which isn't allowed for Type=oneshot services. Refusing."); ++ if (s->type == SERVICE_ONESHOT ++ && !IN_SET(s->restart, SERVICE_RESTART_NO, SERVICE_RESTART_ON_FAILURE, SERVICE_RESTART_ON_ABNORMAL, SERVICE_RESTART_ON_WATCHDOG, SERVICE_RESTART_ON_ABORT)) { ++ log_unit_error(UNIT(s), "Service has Restart= set to either always or on-success, which isn't allowed for Type=oneshot services. Refusing."); + return -ENOEXEC; + } + +diff --git a/test/TEST-41-ONESHOT-RESTART/Makefile b/test/TEST-41-ONESHOT-RESTART/Makefile +new file mode 100644 +index 0000000000..45e9bfc67c +--- /dev/null ++++ b/test/TEST-41-ONESHOT-RESTART/Makefile +@@ -0,0 +1,9 @@ ++BUILD_DIR=$(shell ../../tools/find-build-dir.sh) ++ ++all setup run: ++ @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --$@ ++ ++clean clean-again: ++ @basedir=../.. TEST_BASE_DIR=../ BUILD_DIR=$(BUILD_DIR) ./test.sh --clean ++ ++.PHONY: all setup run clean clean-again +diff --git a/test/TEST-41-ONESHOT-RESTART/test.sh b/test/TEST-41-ONESHOT-RESTART/test.sh +new file mode 100755 +index 0000000000..35de08b1e9 +--- /dev/null ++++ b/test/TEST-41-ONESHOT-RESTART/test.sh +@@ -0,0 +1,44 @@ ++#!/bin/bash ++set -e ++TEST_DESCRIPTION="Test oneshot unit restart on failure" ++. $TEST_BASE_DIR/test-functions ++ ++test_setup() { ++ create_empty_image ++ mkdir -p $TESTDIR/root ++ mount ${LOOPDEV}p1 $TESTDIR/root ++ ++ ( ++ LOG_LEVEL=5 ++ eval $(udevadm info --export --query=env --name=${LOOPDEV}p2) ++ ++ setup_basic_environment ++ ++ # mask some services that we do not want to run in these tests ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-hwdb-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-journal-catalog-update.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-networkd.socket ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-resolved.service ++ ln -fs /dev/null $initdir/etc/systemd/system/systemd-machined.service ++ ++ # setup the testsuite service ++ cat >$initdir/etc/systemd/system/testsuite.service <> $TMP_FILE\"" /bin/bash -c "exit 1" ++ ++sleep 5 ++ ++if [[ $(cat $TMP_FILE) != "aaa" ]]; then ++ exit 1 ++fi ++ ++systemd-analyze log-level info ++ ++echo OK > /testok ++ ++exit 0 diff --git a/SOURCES/0783-test-correct-TEST-41-StartLimitBurst-test.patch b/SOURCES/0783-test-correct-TEST-41-StartLimitBurst-test.patch new file mode 100644 index 0000000..44eef8b --- /dev/null +++ b/SOURCES/0783-test-correct-TEST-41-StartLimitBurst-test.patch @@ -0,0 +1,76 @@ +From a7375d12da80d633dfa802f2b66d2361c70c62f5 Mon Sep 17 00:00:00 2001 +From: Dan Streetman +Date: Thu, 17 Oct 2019 11:06:18 -0400 +Subject: [PATCH] test: correct TEST-41 StartLimitBurst test + +TEST-41 verifies that the StartLimitBurst property will correctly +limit the number of unit restarts, but the test currently doesn't +adjust the StartLimitIntervalSec which defaults to 10 seconds. + +On Ubuntu CI, running under un-accelerated qemu, it can take more than +10 seconds to perform all 3 restarts, which avoids the burst limit, +and fails the test. + +Instead, specify a long StartLimitIntervalSec in the test, so we can +be sure to correctly test StartLimitBurst even on slow testbeds. + +Fixes #13794. + +(cherry picked from commit dfec314d41159117c28dffc2b980d3bdd67c3dcb) + +Related: #2042896 +--- + test/TEST-41-ONESHOT-RESTART/testsuite.sh | 26 ++++++++++++++++++----- + 1 file changed, 21 insertions(+), 5 deletions(-) + +diff --git a/test/TEST-41-ONESHOT-RESTART/testsuite.sh b/test/TEST-41-ONESHOT-RESTART/testsuite.sh +index f7423dbf9a..4465614ff3 100755 +--- a/test/TEST-41-ONESHOT-RESTART/testsuite.sh ++++ b/test/TEST-41-ONESHOT-RESTART/testsuite.sh +@@ -2,14 +2,19 @@ + set -ex + set -o pipefail + ++# wait this many secs for each test service to succeed in what is being tested ++MAX_SECS=60 ++ + systemd-analyze log-level debug + systemd-analyze log-target console + +-# These three commands should succeed. ++# test one: Restart=on-failure should restart the service + ! systemd-run --unit=one -p Type=oneshot -p Restart=on-failure /bin/bash -c "exit 1" + +-sleep 5 +- ++for ((secs=0; secs<$MAX_SECS; secs++)); do ++ [[ "$(systemctl show one.service -p NRestarts --value)" -le 0 ]] || break ++ sleep 1 ++done + if [[ "$(systemctl show one.service -p NRestarts --value)" -le 0 ]]; then + exit 1 + fi +@@ -18,10 +23,21 @@ TMP_FILE="/test-41-oneshot-restart-test" + + touch $TMP_FILE + +-! systemd-run --unit=two -p StartLimitBurst=3 -p Type=oneshot -p Restart=on-failure -p ExecStart="/bin/bash -c \"printf a >> $TMP_FILE\"" /bin/bash -c "exit 1" ++# test two: make sure StartLimitBurst correctly limits the number of restarts ++# and restarts execution of the unit from the first ExecStart= ++! systemd-run --unit=two -p StartLimitIntervalSec=120 -p StartLimitBurst=3 -p Type=oneshot -p Restart=on-failure -p ExecStart="/bin/bash -c \"printf a >> $TMP_FILE\"" /bin/bash -c "exit 1" + +-sleep 5 ++# wait for at least 3 restarts ++for ((secs=0; secs<$MAX_SECS; secs++)); do ++ [[ $(cat $TMP_FILE) != "aaa" ]] || break ++ sleep 1 ++done ++if [[ $(cat $TMP_FILE) != "aaa" ]]; then ++ exit 1 ++fi + ++# wait for 5 more seconds to make sure there aren't excess restarts ++sleep 5 + if [[ $(cat $TMP_FILE) != "aaa" ]]; then + exit 1 + fi diff --git a/SOURCES/0784-core-fix-assert-about-number-of-built-environment-va.patch b/SOURCES/0784-core-fix-assert-about-number-of-built-environment-va.patch new file mode 100644 index 0000000..20ab06d --- /dev/null +++ b/SOURCES/0784-core-fix-assert-about-number-of-built-environment-va.patch @@ -0,0 +1,29 @@ +From 32ef99e27ca6242cd86e06b7f63ba49562a77335 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 11 Sep 2018 12:56:06 +0900 +Subject: [PATCH] core: fix assert() about number of built environment + variables + +Follow-up for 4b58153dd22172d817055d2a09a0cdf3f4bd9db3 and +fd63e712b2025d235ce4bfbb512fada10e2690b5. + +(cherry picked from commit 76a9460d44b03a86691a8481544f4525bb43610a) + +Related: #2049788 +--- + src/core/execute.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/execute.c b/src/core/execute.c +index a104294966..c842b14ce7 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -1733,7 +1733,7 @@ static int build_environment( + } + + our_env[n_env++] = NULL; +- assert(n_env <= 12); ++ assert(n_env <= 14); + + *ret = TAKE_PTR(our_env); + diff --git a/SOURCES/0785-core-add-one-more-assert.patch b/SOURCES/0785-core-add-one-more-assert.patch new file mode 100644 index 0000000..b8dc682 --- /dev/null +++ b/SOURCES/0785-core-add-one-more-assert.patch @@ -0,0 +1,24 @@ +From 09b6ae4da2d8b60d3619dcd0e6712e1a106efba0 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 11 Sep 2018 13:18:33 +0900 +Subject: [PATCH] core: add one more assert() + +(cherry picked from commit 7c1cb6f1989074e144b1625607950fce80c951ec) + +Related: #2049788 +--- + src/core/execute.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/core/execute.c b/src/core/execute.c +index c842b14ce7..3ff1a51aa1 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -1624,6 +1624,7 @@ static int build_environment( + + assert(u); + assert(c); ++ assert(p); + assert(ret); + + our_env = new0(char*, 14); diff --git a/SOURCES/0786-strv-introduce-strv_join_prefix.patch b/SOURCES/0786-strv-introduce-strv_join_prefix.patch new file mode 100644 index 0000000..8275c5b --- /dev/null +++ b/SOURCES/0786-strv-introduce-strv_join_prefix.patch @@ -0,0 +1,69 @@ +From 23ef6c470418b50119dc0bf13b681bfeae820352 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 11 Sep 2018 13:22:31 +0900 +Subject: [PATCH] strv: introduce strv_join_prefix() + +(cherry picked from commit 2b9a7d2e96f5f852cdf8cc704930ea2ee456f6a1) + +Related: #2049788 +--- + src/basic/strv.c | 10 +++++++--- + src/basic/strv.h | 5 ++++- + 2 files changed, 11 insertions(+), 4 deletions(-) + +diff --git a/src/basic/strv.c b/src/basic/strv.c +index b3716233b5..f1605e4fbb 100644 +--- a/src/basic/strv.c ++++ b/src/basic/strv.c +@@ -335,21 +335,22 @@ int strv_split_extract(char ***t, const char *s, const char *separators, Extract + return (int) n; + } + +-char *strv_join(char **l, const char *separator) { ++char *strv_join_prefix(char **l, const char *separator, const char *prefix) { + char *r, *e; + char **s; +- size_t n, k; ++ size_t n, k, m; + + if (!separator) + separator = " "; + + k = strlen(separator); ++ m = strlen_ptr(prefix); + + n = 0; + STRV_FOREACH(s, l) { + if (s != l) + n += k; +- n += strlen(*s); ++ n += m + strlen(*s); + } + + r = new(char, n+1); +@@ -361,6 +362,9 @@ char *strv_join(char **l, const char *separator) { + if (s != l) + e = stpcpy(e, separator); + ++ if (prefix) ++ e = stpcpy(e, prefix); ++ + e = stpcpy(e, *s); + } + +diff --git a/src/basic/strv.h b/src/basic/strv.h +index a09d76706d..9285bc2642 100644 +--- a/src/basic/strv.h ++++ b/src/basic/strv.h +@@ -71,7 +71,10 @@ char **strv_split_newlines(const char *s); + + int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags); + +-char *strv_join(char **l, const char *separator); ++char *strv_join_prefix(char **l, const char *separator, const char *prefix); ++static inline char *strv_join(char **l, const char *separator) { ++ return strv_join_prefix(l, separator, NULL); ++} + + char **strv_parse_nulstr(const char *s, size_t l); + char **strv_split_nulstr(const char *s); diff --git a/SOURCES/0787-test-add-tests-for-strv_join_prefix.patch b/SOURCES/0787-test-add-tests-for-strv_join_prefix.patch new file mode 100644 index 0000000..28533b3 --- /dev/null +++ b/SOURCES/0787-test-add-tests-for-strv_join_prefix.patch @@ -0,0 +1,63 @@ +From d829e7163f6a98547cef3b0106a6a98728275065 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 11 Sep 2018 13:35:27 +0900 +Subject: [PATCH] test: add tests for strv_join_prefix() + +(cherry picked from commit 474a595af7544a670de70e1eb873bcee1bb00044) + +Related: #2049788 +--- + src/test/test-strv.c | 33 +++++++++++++++++++++++++++++++++ + 1 file changed, 33 insertions(+) + +diff --git a/src/test/test-strv.c b/src/test/test-strv.c +index 79d999d3ed..9e7d98500f 100644 +--- a/src/test/test-strv.c ++++ b/src/test/test-strv.c +@@ -158,6 +158,38 @@ static void test_strv_join(void) { + assert_se(streq(w, "")); + } + ++static void test_strv_join_prefix(void) { ++ _cleanup_free_ char *p = NULL, *q = NULL, *r = NULL, *s = NULL, *t = NULL, *v = NULL, *w = NULL; ++ ++ p = strv_join_prefix((char **)input_table_multiple, ", ", "foo"); ++ assert_se(p); ++ assert_se(streq(p, "fooone, footwo, foothree")); ++ ++ q = strv_join_prefix((char **)input_table_multiple, ";", "foo"); ++ assert_se(q); ++ assert_se(streq(q, "fooone;footwo;foothree")); ++ ++ r = strv_join_prefix((char **)input_table_multiple, NULL, "foo"); ++ assert_se(r); ++ assert_se(streq(r, "fooone footwo foothree")); ++ ++ s = strv_join_prefix((char **)input_table_one, ", ", "foo"); ++ assert_se(s); ++ assert_se(streq(s, "fooone")); ++ ++ t = strv_join_prefix((char **)input_table_none, ", ", "foo"); ++ assert_se(t); ++ assert_se(streq(t, "")); ++ ++ v = strv_join_prefix((char **)input_table_two_empties, ", ", "foo"); ++ assert_se(v); ++ assert_se(streq(v, "foo, foo")); ++ ++ w = strv_join_prefix((char **)input_table_one_empty, ", ", "foo"); ++ assert_se(w); ++ assert_se(streq(w, "foo")); ++} ++ + static void test_strv_unquote(const char *quoted, char **list) { + _cleanup_strv_free_ char **s; + _cleanup_free_ char *j; +@@ -722,6 +754,7 @@ int main(int argc, char *argv[]) { + test_strv_find_prefix(); + test_strv_find_startswith(); + test_strv_join(); ++ test_strv_join_prefix(); + + test_strv_unquote(" foo=bar \"waldo\" zzz ", STRV_MAKE("foo=bar", "waldo", "zzz")); + test_strv_unquote("", STRV_MAKE_EMPTY); diff --git a/SOURCES/0788-test-replace-swear-words-by-hoge.patch b/SOURCES/0788-test-replace-swear-words-by-hoge.patch new file mode 100644 index 0000000..c8c8083 --- /dev/null +++ b/SOURCES/0788-test-replace-swear-words-by-hoge.patch @@ -0,0 +1,54 @@ +From 48b22b82853c6697669b078de5eae35728fbba30 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 11 Sep 2018 13:41:09 +0900 +Subject: [PATCH] test: replace swear words by 'hoge' + +(cherry picked from commit a2917d3d2a3ce926f74b63aa60a47f838a8e1f83) + +Related: #2049788 +--- + src/test/test-cgroup-util.c | 2 +- + src/test/test-strv.c | 10 +++++----- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/test/test-cgroup-util.c b/src/test/test-cgroup-util.c +index 60d7bb19cb..2cb93ad0be 100644 +--- a/src/test/test-cgroup-util.c ++++ b/src/test/test-cgroup-util.c +@@ -296,7 +296,7 @@ static void test_shift_path(void) { + test_shift_path_one("/foobar/waldo", "/", "/foobar/waldo"); + test_shift_path_one("/foobar/waldo", "", "/foobar/waldo"); + test_shift_path_one("/foobar/waldo", "/foobar", "/waldo"); +- test_shift_path_one("/foobar/waldo", "/fuckfuck", "/foobar/waldo"); ++ test_shift_path_one("/foobar/waldo", "/hogehoge", "/foobar/waldo"); + } + + static void test_mask_supported(void) { +diff --git a/src/test/test-strv.c b/src/test/test-strv.c +index 9e7d98500f..165a5de91d 100644 +--- a/src/test/test-strv.c ++++ b/src/test/test-strv.c +@@ -279,18 +279,18 @@ static void test_strv_split_nulstr(void) { + + static void test_strv_parse_nulstr(void) { + _cleanup_strv_free_ char **l = NULL; +- const char nulstr[] = "fuck\0fuck2\0fuck3\0\0fuck5\0\0xxx"; ++ const char nulstr[] = "hoge\0hoge2\0hoge3\0\0hoge5\0\0xxx"; + + l = strv_parse_nulstr(nulstr, sizeof(nulstr)-1); + assert_se(l); + puts("Parse nulstr:"); + strv_print(l); + +- assert_se(streq(l[0], "fuck")); +- assert_se(streq(l[1], "fuck2")); +- assert_se(streq(l[2], "fuck3")); ++ assert_se(streq(l[0], "hoge")); ++ assert_se(streq(l[1], "hoge2")); ++ assert_se(streq(l[2], "hoge3")); + assert_se(streq(l[3], "")); +- assert_se(streq(l[4], "fuck5")); ++ assert_se(streq(l[4], "hoge5")); + assert_se(streq(l[5], "")); + assert_se(streq(l[6], "xxx")); + } diff --git a/SOURCES/0789-core-add-new-environment-variable-RUNTIME_DIRECTORY-.patch b/SOURCES/0789-core-add-new-environment-variable-RUNTIME_DIRECTORY-.patch new file mode 100644 index 0000000..ca2f947 --- /dev/null +++ b/SOURCES/0789-core-add-new-environment-variable-RUNTIME_DIRECTORY-.patch @@ -0,0 +1,124 @@ +From f41927c026d65e9005c0ba418c6bfff511055bd2 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 11 Sep 2018 14:05:08 +0900 +Subject: [PATCH] core: add new environment variable $RUNTIME_DIRECTORY= or + friends + +The variable is generated from RuntimeDirectory= or friends. +If multiple directories are set, then they are concatenated with +the separator ':'. + +(cherry picked from commit fb2042dd55de5019f55931b4f20a44700ec1222b) + +Resolves: #2049788 +--- + TODO | 9 --------- + src/core/execute.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 44 insertions(+), 11 deletions(-) + +diff --git a/TODO b/TODO +index 0705b6b08e..c52f9b25f3 100644 +--- a/TODO ++++ b/TODO +@@ -214,15 +214,6 @@ Features: + for all units. It should be both a way to pin units into memory as well as a + wait to retrieve their exit data. + +-* maybe set a new set of env vars for services, based on RuntimeDirectory=, +- StateDirectory=, LogsDirectory=, CacheDirectory= and ConfigurationDirectory= +- automatically. For example, there could be $RUNTIME_DIRECTORY, +- $STATE_DIRECTORY, $LOGS_DIRECTORY=, $CACHE_DIRECTORY and +- $CONFIGURATION_DIRECTORY or so. This could be useful to write services that +- can adapt to varying directories for these purposes. Special care has to be +- taken if multiple dirs are configured. Maybe avoid setting the env vars in +- that case? +- + * expose IO accounting data on the bus, show it in systemd-run --wait and log + about it in the resource log message + +diff --git a/src/core/execute.c b/src/core/execute.c +index 3ff1a51aa1..9cbb678ac4 100644 +--- a/src/core/execute.c ++++ b/src/core/execute.c +@@ -1606,6 +1606,8 @@ static void do_idle_pipe_dance(int idle_pipe[4]) { + idle_pipe[3] = safe_close(idle_pipe[3]); + } + ++static const char *exec_directory_env_name_to_string(ExecDirectoryType t); ++ + static int build_environment( + const Unit *u, + const ExecContext *c, +@@ -1619,6 +1621,7 @@ static int build_environment( + char ***ret) { + + _cleanup_strv_free_ char **our_env = NULL; ++ ExecDirectoryType t; + size_t n_env = 0; + char *x; + +@@ -1627,7 +1630,7 @@ static int build_environment( + assert(p); + assert(ret); + +- our_env = new0(char*, 14); ++ our_env = new0(char*, 14 + _EXEC_DIRECTORY_TYPE_MAX); + if (!our_env) + return -ENOMEM; + +@@ -1733,8 +1736,37 @@ static int build_environment( + our_env[n_env++] = x; + } + ++ for (t = 0; t < _EXEC_DIRECTORY_TYPE_MAX; t++) { ++ _cleanup_free_ char *pre = NULL, *joined = NULL; ++ const char *n; ++ ++ if (!p->prefix[t]) ++ continue; ++ ++ if (strv_isempty(c->directories[t].paths)) ++ continue; ++ ++ n = exec_directory_env_name_to_string(t); ++ if (!n) ++ continue; ++ ++ pre = strjoin(p->prefix[t], "/"); ++ if (!pre) ++ return -ENOMEM; ++ ++ joined = strv_join_prefix(c->directories[t].paths, ":", pre); ++ if (!joined) ++ return -ENOMEM; ++ ++ x = strjoin(n, "=", joined); ++ if (!x) ++ return -ENOMEM; ++ ++ our_env[n_env++] = x; ++ } ++ + our_env[n_env++] = NULL; +- assert(n_env <= 14); ++ assert(n_env <= 14 + _EXEC_DIRECTORY_TYPE_MAX); + + *ret = TAKE_PTR(our_env); + +@@ -5197,6 +5229,16 @@ static const char* const exec_directory_type_table[_EXEC_DIRECTORY_TYPE_MAX] = { + + DEFINE_STRING_TABLE_LOOKUP(exec_directory_type, ExecDirectoryType); + ++static const char* const exec_directory_env_name_table[_EXEC_DIRECTORY_TYPE_MAX] = { ++ [EXEC_DIRECTORY_RUNTIME] = "RUNTIME_DIRECTORY", ++ [EXEC_DIRECTORY_STATE] = "STATE_DIRECTORY", ++ [EXEC_DIRECTORY_CACHE] = "CACHE_DIRECTORY", ++ [EXEC_DIRECTORY_LOGS] = "LOGS_DIRECTORY", ++ [EXEC_DIRECTORY_CONFIGURATION] = "CONFIGURATION_DIRECTORY", ++}; ++ ++DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(exec_directory_env_name, ExecDirectoryType); ++ + static const char* const exec_keyring_mode_table[_EXEC_KEYRING_MODE_MAX] = { + [EXEC_KEYRING_INHERIT] = "inherit", + [EXEC_KEYRING_PRIVATE] = "private", diff --git a/SOURCES/0790-test-execute-add-tests-for-RUNTIME_DIRECTORY-or-frie.patch b/SOURCES/0790-test-execute-add-tests-for-RUNTIME_DIRECTORY-or-frie.patch new file mode 100644 index 0000000..ec10dec --- /dev/null +++ b/SOURCES/0790-test-execute-add-tests-for-RUNTIME_DIRECTORY-or-frie.patch @@ -0,0 +1,76 @@ +From 5226df888c28ede9219d7f018af02cca1d1f6d2a Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 11 Sep 2018 14:07:53 +0900 +Subject: [PATCH] test-execute: add tests for $RUNTIME_DIRECTORY= or friends + +(cherry picked from commit 6088662d57bbd81167bd272d385fdd1044b287ec) + +Related: #2049788 +--- + .../test-execute/exec-dynamicuser-statedir-migrate-step1.service | 1 + + .../test-execute/exec-dynamicuser-statedir-migrate-step2.service | 1 + + test/test-execute/exec-dynamicuser-statedir.service | 1 + + test/test-execute/exec-runtimedirectory-mode.service | 1 + + test/test-execute/exec-runtimedirectory.service | 1 + + 5 files changed, 5 insertions(+) + +diff --git a/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service b/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service +index 72e6d7686f..5efc5483b8 100644 +--- a/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service ++++ b/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service +@@ -10,6 +10,7 @@ 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=/bin/sh -x -c 'test "$$STATE_DIRECTORY" = "%S/test-dynamicuser-migrate:%S/test-dynamicuser-migrate2/hoge"' + + Type=oneshot + DynamicUser=no +diff --git a/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service b/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service +index edb0be7ef8..c72302ffd5 100644 +--- a/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service ++++ b/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service +@@ -18,6 +18,7 @@ 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=/bin/sh -x -c 'test "$$STATE_DIRECTORY" = "%S/test-dynamicuser-migrate:%S/test-dynamicuser-migrate2/hoge"' + + Type=oneshot + DynamicUser=yes +diff --git a/test/test-execute/exec-dynamicuser-statedir.service b/test/test-execute/exec-dynamicuser-statedir.service +index f459f3c1eb..2fb7b8660b 100644 +--- a/test/test-execute/exec-dynamicuser-statedir.service ++++ b/test/test-execute/exec-dynamicuser-statedir.service +@@ -10,6 +10,7 @@ ExecStart=test -f /var/lib/waldo/yay + ExecStart=test -f /var/lib/quux/pief/yayyay + ExecStart=test -f /var/lib/private/waldo/yay + ExecStart=test -f /var/lib/private/quux/pief/yayyay ++ExecStart=/bin/sh -x -c 'test "$$STATE_DIRECTORY" = "%S/waldo:%S/quux/pief"' + + # Make sure that /var/lib/private/waldo is really the only writable directory besides the obvious candidates + ExecStart=sh -x -c 'test $$(find / \( -path /var/tmp -o -path /tmp -o -path /proc -o -path /dev/mqueue -o -path /dev/shm -o -path /sys/fs/bpf \) -prune -o -type d -writable -print 2>/dev/null | sort -u | tr -d '\\\\n') = /var/lib/private/quux/pief/var/lib/private/waldo' +diff --git a/test/test-execute/exec-runtimedirectory-mode.service b/test/test-execute/exec-runtimedirectory-mode.service +index 480f904155..85ae5161c4 100644 +--- a/test/test-execute/exec-runtimedirectory-mode.service ++++ b/test/test-execute/exec-runtimedirectory-mode.service +@@ -3,6 +3,7 @@ Description=Test for RuntimeDirectoryMode + + [Service] + ExecStart=/bin/sh -x -c 'mode=$$(stat -c %%a %t/test-exec_runtimedirectory-mode); test "$$mode" = "750"' ++ExecStart=/bin/sh -x -c 'test "$$RUNTIME_DIRECTORY" = "%t/test-exec_runtimedirectory-mode"' + Type=oneshot + RuntimeDirectory=test-exec_runtimedirectory-mode + RuntimeDirectoryMode=0750 +diff --git a/test/test-execute/exec-runtimedirectory.service b/test/test-execute/exec-runtimedirectory.service +index 6a4383110f..a33044d23c 100644 +--- a/test/test-execute/exec-runtimedirectory.service ++++ b/test/test-execute/exec-runtimedirectory.service +@@ -4,6 +4,7 @@ Description=Test for RuntimeDirectory + [Service] + ExecStart=/bin/sh -x -c 'test -d %t/test-exec_runtimedirectory' + ExecStart=/bin/sh -x -c 'test -d %t/test-exec_runtimedirectory2/hogehoge' ++ExecStart=/bin/sh -x -c 'test "$$RUNTIME_DIRECTORY" = "%t/test-exec_runtimedirectory:%t/test-exec_runtimedirectory2/hogehoge"' + Type=oneshot + RuntimeDirectory=test-exec_runtimedirectory + RuntimeDirectory=./test-exec_runtimedirectory2///./hogehoge/. diff --git a/SOURCES/0791-man-document-RUNTIME_DIRECTORY-or-friends.patch b/SOURCES/0791-man-document-RUNTIME_DIRECTORY-or-friends.patch new file mode 100644 index 0000000..863c21b --- /dev/null +++ b/SOURCES/0791-man-document-RUNTIME_DIRECTORY-or-friends.patch @@ -0,0 +1,85 @@ +From a729ea1a59b63c5f3e7fdce6a6c4e2ce12faa972 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Tue, 11 Sep 2018 14:24:47 +0900 +Subject: [PATCH] man: document RUNTIME_DIRECTORY= or friends + +(cherry picked from commit d491e65e74a92898d6e7f95032b5b037c6e3cb60) + +Related: #2049788 +--- + man/systemd.exec.xml | 22 ++++++++++++++++++---- + 1 file changed, 18 insertions(+), 4 deletions(-) + +diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml +index 696438c4ef..dc88cf9781 100644 +--- a/man/systemd.exec.xml ++++ b/man/systemd.exec.xml +@@ -820,15 +820,18 @@ CapabilityBoundingSet=~CAP_B CAP_C + These options take a whitespace-separated list of directory names. The specified directory + names must be relative, and may not include ... If set, one or more + directories by the specified names will be created (including their parents) below the locations +- defined in the following table, when the unit is started. ++ defined in the following table, when the unit is started. Also, the corresponding environment variable ++ is defined with the full path of directories. If multiple directories are set, then int the environment variable ++ the paths are concatenated with colon (:). + +- Automatic directory creation +- ++ Automatic directory creation and environment variables ++ + + + Locations + for system + for users ++ Environment variable + + + +@@ -836,26 +839,31 @@ CapabilityBoundingSet=~CAP_B CAP_C + RuntimeDirectory= + /run + $XDG_RUNTIME_DIR ++ $RUNTIME_DIRECTORY + + + StateDirectory= + /var/lib + $XDG_CONFIG_HOME ++ $STATE_DIRECTORY + + + CacheDirectory= + /var/cache + $XDG_CACHE_HOME ++ $CACHE_DIRECTORY + + + LogsDirectory= + /var/log + $XDG_CONFIG_HOME/log ++ $LOGS_DIRECTORY + + + ConfigurationDirectory= + /etc + $XDG_CONFIG_HOME ++ $CONFIGURATION_DIRECTORY + + + +@@ -905,7 +913,13 @@ CapabilityBoundingSet=~CAP_B CAP_C + /run/foo/bar, and /run/baz. The directories + /run/foo/bar and /run/baz except /run/foo are + owned by the user and group specified in User= and Group=, and removed +- when the service is stopped. ++ when the service is stopped. ++ ++ Example: if a system service unit has the following, ++ RuntimeDirectory=foo/bar ++StateDirectory=aaa/bbb ccc ++ then the environment variable RUNTIME_DIRECTORY is set with /run/foo/bar, and ++ STATE_DIRECTORY is set with /var/lib/aaa/bbb:/var/lib/ccc. + + + diff --git a/SPECS/systemd.spec b/SPECS/systemd.spec index 657a3f4..61646ee 100644 --- a/SPECS/systemd.spec +++ b/SPECS/systemd.spec @@ -13,7 +13,7 @@ Name: systemd Url: http://www.freedesktop.org/wiki/Software/systemd Version: 239 -Release: 60%{?dist} +Release: 62%{?dist} # For a breakdown of the licensing, see README License: LGPLv2+ and MIT and GPLv2+ Summary: System and Service Manager @@ -820,6 +820,27 @@ Patch0767: 0767-core-Move-r-variable-declaration-to-start-of-unit_st.patch Patch0768: 0768-core-Delay-start-rate-limit-check-when-starting-a-un.patch Patch0769: 0769-core-Propagate-condition-failed-state-to-triggering-.patch Patch0770: 0770-unit-check-for-mount-rate-limiting-before-checking-a.patch +Patch0771: 0771-mkosi-Add-gnutls-package.patch +Patch0772: 0772-unit-name-tighten-checks-for-building-valid-unit-nam.patch +Patch0773: 0773-core-shorten-long-unit-names-that-are-based-on-paths.patch +Patch0774: 0774-test-add-extended-test-for-triggering-mount-rate-lim.patch +Patch0775: 0775-tests-add-test-case-for-long-unit-names.patch +Patch0776: 0776-core-unset-HOME-that-the-kernel-gives-us.patch +Patch0777: 0777-journal-remote-check-return-value-from-MHD_add_respo.patch +Patch0778: 0778-journalctl-in-follow-mode-watch-stdout-for-POLLHUP-P.patch +Patch0779: 0779-sd-bus-make-BUS_DEFAULT_TIMEOUT-configurable.patch +Patch0780: 0780-fstab-generator-fix-debug-log.patch +Patch0781: 0781-logind-session-dbus-allow-to-set-display-name-via-db.patch +Patch0782: 0782-Allow-restart-for-oneshot-units.patch +Patch0783: 0783-test-correct-TEST-41-StartLimitBurst-test.patch +Patch0784: 0784-core-fix-assert-about-number-of-built-environment-va.patch +Patch0785: 0785-core-add-one-more-assert.patch +Patch0786: 0786-strv-introduce-strv_join_prefix.patch +Patch0787: 0787-test-add-tests-for-strv_join_prefix.patch +Patch0788: 0788-test-replace-swear-words-by-hoge.patch +Patch0789: 0789-core-add-new-environment-variable-RUNTIME_DIRECTORY-.patch +Patch0790: 0790-test-execute-add-tests-for-RUNTIME_DIRECTORY-or-frie.patch +Patch0791: 0791-man-document-RUNTIME_DIRECTORY-or-friends.patch %ifarch %{ix86} x86_64 aarch64 @@ -883,7 +904,6 @@ Requires: %{name}-pam = %{version}-%{release} Requires: %{name}-libs = %{version}-%{release} Recommends: diffutils Requires: util-linux -Requires: timedatex Recommends: libxkbcommon%{?_isa} Provides: /bin/systemctl Provides: /sbin/shutdown @@ -1319,7 +1339,7 @@ fi function mod_nss() { if [ -f "$1" ] ; then - # sed-fu to add myhostanme to hosts line + # sed-fu to add myhostname to hosts line grep -E -q '^hosts:.* myhostname' "$1" || sed -i.bak -e ' /^hosts:/ !b @@ -1336,14 +1356,14 @@ function mod_nss() { } FILE="$(readlink /etc/nsswitch.conf || echo /etc/nsswitch.conf)" -mod_nss "$FILE" - -if [ "$FILE" = "/etc/authselect/user-nsswitch.conf" ] ; then - authselect apply-changes &> /dev/null +if [ "$FILE" = "/etc/authselect/nsswitch.conf" ] && authselect check &>/dev/null; then + mod_nss "/etc/authselect/user-nsswitch.conf" + authselect apply-changes &> /dev/null || : else - # also apply the same changes to nsswitch.conf to affect + mod_nss "$FILE" + # also apply the same changes to user-nsswitch.conf to affect # possible future authselect configuration - mod_nss "/etc/authselect/user-nsswitch.conf" + mod_nss "/etc/authselect/user-nsswitch.conf" fi # check if nobody or nfsnobody is defined @@ -1451,6 +1471,32 @@ fi %files tests -f .file-list-tests %changelog +* Mon Jul 18 2022 systemd maintenance team - 239-62 +- spec: Remove dependency on timedatex (#2066946) + +* Thu Jul 14 2022 systemd maintenance team - 239-61 +- mkosi: Add gnutls package (#2101227) +- unit-name: tighten checks for building valid unit names (#1940973) +- core: shorten long unit names that are based on paths and append path hash at the end (#1940973) +- test: add extended test for triggering mount rate limit (#1940973) +- tests: add test case for long unit names (#1940973) +- core: unset HOME=/ that the kernel gives us (#2056527) +- journal-remote: check return value from MHD_add_response_header (#2051981) +- journalctl: in --follow mode watch stdout for POLLHUP/POLLERR and exit (#2003236) +- sd-bus: make BUS_DEFAULT_TIMEOUT configurable (#2039461) +- fstab-generator: fix debug log (#2101433) +- logind-session-dbus: allow to set display name via dbus (#1857969) +- Allow restart for oneshot units (#2042896) +- test: correct TEST-41 StartLimitBurst test (#2042896) +- core: fix assert() about number of built environment variables (#2049788) +- core: add one more assert() (#2049788) +- strv: introduce strv_join_prefix() (#2049788) +- test: add tests for strv_join_prefix() (#2049788) +- test: replace swear words by 'hoge' (#2049788) +- core: add new environment variable $RUNTIME_DIRECTORY= or friends (#2049788) +- test-execute: add tests for $RUNTIME_DIRECTORY= or friends (#2049788) +- man: document RUNTIME_DIRECTORY= or friends (#2049788) + * Thu Jun 23 2022 systemd maintenance team - 239-60 - unit: don't emit PropertiesChanged signal if adding a dependency to a unit is a no-op (#1948480) - tests: make inverted tests actually count (#2087152)