From 069481b815c694d4e158de80892c3d34b7959cb1 Mon Sep 17 00:00:00 2001 From: Yuanhong Peng Date: Tue, 14 Dec 2021 21:13:37 +0800 Subject: [PATCH] Add optimized patches - core: fix a null reference case in load_from_path() - sysctl: Don't pass null directive argument to '%s' - test: remove support for suffix in get_testdata_dir() - test: use ${builddir}/systemd-runtest.env to set $SYSTEMD_TEST_DATA - test: use ${builddir}/systemd-runtest.env for $SYSTEMD_CATALOG_DIR - strv: rework FOREACH_STRING() macro - exit-status: introduce EXIT_EXCEPTION mapping to 255 - main: don't freeze PID 1 in containers, exit with non-zero instead - Do not go into freeze when systemd crashd - mount-setup: change the system mount propagation to shared by default only at bootup - mount: don't propagate errors from mount_setup_unit() further up - cgroup-util: make definition of CGROUP_CONTROLLER_TO_MASK() unsigned - cgroup: update only siblings that got realized once - core: add a config item to support setting the value of cpuset.clone_children when systemd is starting Signed-off-by: Yuanhong Peng --- ...ull-reference-case-in-load_from_path.patch | 34 ++ ...-t-pass-null-directive-argument-to-s.patch | 30 ++ ...pport-for-suffix-in-get_testdata_dir.patch | 312 ++++++++++++++++++ ...r-systemd-runtest.env-to-set-SYSTEMD.patch | 171 ++++++++++ ...r-systemd-runtest.env-for-SYSTEMD_CA.patch | 139 ++++++++ 1007-strv-rework-FOREACH_STRING-macro.patch | 50 +++ ...roduce-EXIT_EXCEPTION-mapping-to-255.patch | 61 ++++ ...e-PID-1-in-containers-exit-with-non-.patch | 59 ++++ ...t-go-into-freeze-when-systemd-crashd.patch | 111 +++++++ ...ge-the-system-mount-propagation-to-s.patch | 77 +++++ ...agate-errors-from-mount_setup_unit-f.patch | 58 ++++ ...-definition-of-CGROUP_CONTROLLER_TO_.patch | 33 ++ ...only-siblings-that-got-realized-once.patch | 67 ++++ ...g-item-to-support-setting-the-value-.patch | 121 +++++++ systemd.spec | 32 +- 15 files changed, 1354 insertions(+), 1 deletion(-) create mode 100644 1002-core-fix-a-null-reference-case-in-load_from_path.patch create mode 100644 1003-sysctl-Don-t-pass-null-directive-argument-to-s.patch create mode 100644 1004-test-remove-support-for-suffix-in-get_testdata_dir.patch create mode 100644 1005-test-use-builddir-systemd-runtest.env-to-set-SYSTEMD.patch create mode 100644 1006-test-use-builddir-systemd-runtest.env-for-SYSTEMD_CA.patch create mode 100644 1007-strv-rework-FOREACH_STRING-macro.patch create mode 100644 1008-exit-status-introduce-EXIT_EXCEPTION-mapping-to-255.patch create mode 100644 1009-main-don-t-freeze-PID-1-in-containers-exit-with-non-.patch create mode 100644 1010-Do-not-go-into-freeze-when-systemd-crashd.patch create mode 100644 1011-mount-setup-change-the-system-mount-propagation-to-s.patch create mode 100644 1012-mount-don-t-propagate-errors-from-mount_setup_unit-f.patch create mode 100644 1013-cgroup-util-make-definition-of-CGROUP_CONTROLLER_TO_.patch create mode 100644 1014-cgroup-update-only-siblings-that-got-realized-once.patch create mode 100644 1015-core-add-a-config-item-to-support-setting-the-value-.patch diff --git a/1002-core-fix-a-null-reference-case-in-load_from_path.patch b/1002-core-fix-a-null-reference-case-in-load_from_path.patch new file mode 100644 index 0000000..a8f6284 --- /dev/null +++ b/1002-core-fix-a-null-reference-case-in-load_from_path.patch @@ -0,0 +1,34 @@ +From e221918d31d0e148bb2b9f606a4e5ab4be15c48f Mon Sep 17 00:00:00 2001 +From: Wen Yang +Date: Mon, 1 Jun 2020 17:06:53 +0800 +Subject: [PATCH] core: fix a null reference case in load_from_path() + +--- + src/core/load-fragment.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c +index 2082166..58c2824 100644 +--- a/src/core/load-fragment.c ++++ b/src/core/load-fragment.c +@@ -4327,7 +4327,6 @@ static int load_from_path(Unit *u, const char *path) { + r = open_follow(&filename, &f, symlink_names, &id); + if (r >= 0) + break; +- filename = mfree(filename); + + /* ENOENT means that the file is missing or is a dangling symlink. + * ENOTDIR means that one of paths we expect to be is a directory +@@ -4336,7 +4335,8 @@ static int load_from_path(Unit *u, const char *path) { + */ + if (r == -EACCES) + log_debug_errno(r, "Cannot access \"%s\": %m", filename); +- else if (!IN_SET(r, -ENOENT, -ENOTDIR)) ++ filename = mfree(filename); ++ if (!IN_SET(r, -ENOENT, -ENOTDIR)) + return r; + + /* Empty the symlink names for the next run */ +-- +2.18.1 + diff --git a/1003-sysctl-Don-t-pass-null-directive-argument-to-s.patch b/1003-sysctl-Don-t-pass-null-directive-argument-to-s.patch new file mode 100644 index 0000000..bcdecd0 --- /dev/null +++ b/1003-sysctl-Don-t-pass-null-directive-argument-to-s.patch @@ -0,0 +1,30 @@ +From 9424b8cac1aef19181125906d434a1a139ae0128 Mon Sep 17 00:00:00 2001 +From: Khem Raj +Date: Sun, 16 Dec 2018 20:53:38 -0800 +Subject: [PATCH] sysctl: Don't pass null directive argument to '%s' + +value pointer here is always NULL but subsequent use of that pointer +with a %s format will always be NULL, printing p instead would be a +valid string + +Signed-off-by: Khem Raj +--- + src/sysctl/sysctl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c +index 0151f7d..61447bb 100644 +--- a/src/sysctl/sysctl.c ++++ b/src/sysctl/sysctl.c +@@ -112,7 +112,7 @@ static int parse_file(OrderedHashmap *sysctl_options, const char *path, bool ign + + value = strchr(p, '='); + if (!value) { +- log_error("Line is not an assignment at '%s:%u': %s", path, c, value); ++ log_error("Line is not an assignment at '%s:%u': %s", path, c, p); + + if (r == 0) + r = -EINVAL; +-- +2.18.1 + diff --git a/1004-test-remove-support-for-suffix-in-get_testdata_dir.patch b/1004-test-remove-support-for-suffix-in-get_testdata_dir.patch new file mode 100644 index 0000000..9055e38 --- /dev/null +++ b/1004-test-remove-support-for-suffix-in-get_testdata_dir.patch @@ -0,0 +1,312 @@ +From 427f4d98cea638549df00e65eaa7fed14698ef11 Mon Sep 17 00:00:00 2001 +From: Filipe Brandenburger +Date: Tue, 11 Sep 2018 23:15:09 -0700 +Subject: [PATCH] test: remove support for suffix in get_testdata_dir() + +Instead, use path_join() in callers wherever needed. + +Signed-off-by: Yuanhong Peng +(cherry picked from commit 55890a40c3ec0c061c04d1395a38c26313132d12) +--- + src/resolve/test-dns-packet.c | 5 ++++- + src/shared/tests.c | 4 +--- + src/shared/tests.h | 2 +- + src/test/test-bpf.c | 2 +- + src/test/test-cgroup-mask.c | 2 +- + src/test/test-engine.c | 2 +- + src/test/test-execute.c | 4 +++- + src/test/test-journal-importer.c | 10 ++++++++-- + src/test/test-path.c | 5 ++++- + src/test/test-sched-prio.c | 2 +- + src/test/test-umount.c | 18 ++++++++++++++---- + src/test/test-watch-pid.c | 2 +- + 12 files changed, 40 insertions(+), 18 deletions(-) + +diff --git a/src/resolve/test-dns-packet.c b/src/resolve/test-dns-packet.c +index 905f000..0dac05e 100644 +--- a/src/resolve/test-dns-packet.c ++++ b/src/resolve/test-dns-packet.c +@@ -12,6 +12,7 @@ + #include "macro.h" + #include "resolved-dns-packet.h" + #include "resolved-dns-rr.h" ++#include "path-util.h" + #include "string-util.h" + #include "strv.h" + #include "tests.h" +@@ -92,6 +93,7 @@ static void test_packet_from_file(const char* filename, bool canonical) { + + int main(int argc, char **argv) { + int i, N; ++ _cleanup_free_ char *pkts_glob = NULL; + _cleanup_globfree_ glob_t g = {}; + char **fnames; + +@@ -101,7 +103,8 @@ int main(int argc, char **argv) { + N = argc - 1; + fnames = argv + 1; + } else { +- assert_se(glob(get_testdata_dir("/test-resolve/*.pkts"), GLOB_NOSORT, NULL, &g) == 0); ++ pkts_glob = path_join(NULL, get_testdata_dir(), "test-resolve/*.pkts"); ++ assert_se(glob(pkts_glob, GLOB_NOSORT, NULL, &g) == 0); + N = g.gl_pathc; + fnames = g.gl_pathv; + } +diff --git a/src/shared/tests.c b/src/shared/tests.c +index c77eb00..100b62b 100644 +--- a/src/shared/tests.c ++++ b/src/shared/tests.c +@@ -37,7 +37,7 @@ bool test_is_running_from_builddir(char **exedir) { + return r; + } + +-const char* get_testdata_dir(const char *suffix) { ++const char* get_testdata_dir(void) { + const char *env; + /* convenience: caller does not need to free result */ + static char testdir[PATH_MAX]; +@@ -61,14 +61,12 @@ const char* get_testdata_dir(const char *suffix) { + /* Try relative path, according to the install-test layout */ + assert_se(snprintf(testdir, sizeof(testdir), "%s/testdata", exedir) > 0); + +- /* test this without the suffix, as it may contain a glob */ + if (access(testdir, F_OK) < 0) { + fputs("ERROR: Cannot find testdata directory, set $SYSTEMD_TEST_DATA\n", stderr); + exit(EXIT_FAILURE); + } + } + +- strncpy(testdir + strlen(testdir), suffix, sizeof(testdir) - strlen(testdir) - 1); + return testdir; + } + +diff --git a/src/shared/tests.h b/src/shared/tests.h +index 7f45c32..3d696d0 100644 +--- a/src/shared/tests.h ++++ b/src/shared/tests.h +@@ -3,5 +3,5 @@ + + char* setup_fake_runtime_dir(void); + bool test_is_running_from_builddir(char **exedir); +-const char* get_testdata_dir(const char *suffix); ++const char* get_testdata_dir(void); + void test_setup_logging(int level); +diff --git a/src/test/test-bpf.c b/src/test/test-bpf.c +index 4d89bd4..6f4a22a 100644 +--- a/src/test/test-bpf.c ++++ b/src/test/test-bpf.c +@@ -38,7 +38,7 @@ int main(int argc, char *argv[]) { + return EXIT_TEST_SKIP; + } + +- assert_se(set_unit_path(get_testdata_dir("")) >= 0); ++ assert_se(set_unit_path(get_testdata_dir()) >= 0); + assert_se(runtime_dir = setup_fake_runtime_dir()); + + r = bpf_program_new(BPF_PROG_TYPE_CGROUP_SKB, &p); +diff --git a/src/test/test-cgroup-mask.c b/src/test/test-cgroup-mask.c +index 93c3f5d..ed2d810 100644 +--- a/src/test/test-cgroup-mask.c ++++ b/src/test/test-cgroup-mask.c +@@ -26,7 +26,7 @@ static int test_cgroup_mask(void) { + } + + /* Prepare the manager. */ +- assert_se(set_unit_path(get_testdata_dir("")) >= 0); ++ assert_se(set_unit_path(get_testdata_dir()) >= 0); + assert_se(runtime_dir = setup_fake_runtime_dir()); + r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m); + if (IN_SET(r, -EPERM, -EACCES)) { +diff --git a/src/test/test-engine.c b/src/test/test-engine.c +index d072a15..0f3e244 100644 +--- a/src/test/test-engine.c ++++ b/src/test/test-engine.c +@@ -29,7 +29,7 @@ int main(int argc, char *argv[]) { + } + + /* prepare the test */ +- assert_se(set_unit_path(get_testdata_dir("")) >= 0); ++ assert_se(set_unit_path(get_testdata_dir()) >= 0); + assert_se(runtime_dir = setup_fake_runtime_dir()); + r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m); + if (MANAGER_SKIP_TEST(r)) { +diff --git a/src/test/test-execute.c b/src/test/test-execute.c +index 637ffe9..02242ad 100644 +--- a/src/test/test-execute.c ++++ b/src/test/test-execute.c +@@ -674,6 +674,7 @@ static int run_tests(UnitFileScope scope, const test_function_t *tests) { + + int main(int argc, char *argv[]) { + _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL; ++ _cleanup_free_ char *test_execute_path = NULL; + static const test_function_t user_tests[] = { + test_exec_basic, + test_exec_ambientcapabilities, +@@ -737,7 +738,8 @@ int main(int argc, char *argv[]) { + } + + assert_se(runtime_dir = setup_fake_runtime_dir()); +- assert_se(set_unit_path(get_testdata_dir("/test-execute")) >= 0); ++ test_execute_path = path_join(NULL, get_testdata_dir(), "test-execute"); ++ assert_se(set_unit_path(test_execute_path) >= 0); + + /* Unset VAR1, VAR2 and VAR3 which are used in the PassEnvironment test + * cases, otherwise (and if they are present in the environment), +diff --git a/src/test/test-journal-importer.c b/src/test/test-journal-importer.c +index 56bf6a1..8f09d5a 100644 +--- a/src/test/test-journal-importer.c ++++ b/src/test/test-journal-importer.c +@@ -4,8 +4,10 @@ + #include + #include + ++#include "alloc-util.h" + #include "log.h" + #include "journal-importer.h" ++#include "path-util.h" + #include "string-util.h" + #include "tests.h" + +@@ -20,9 +22,11 @@ static void assert_iovec_entry(const struct iovec *iovec, const char* content) { + + static void test_basic_parsing(void) { + _cleanup_(journal_importer_cleanup) JournalImporter imp = {}; ++ _cleanup_free_ char *journal_data_path = NULL; + int r; + +- imp.fd = open(get_testdata_dir("/journal-data/journal-1.txt"), O_RDONLY|O_CLOEXEC); ++ journal_data_path = path_join(NULL, get_testdata_dir(), "journal-data/journal-1.txt"); ++ imp.fd = open(journal_data_path, O_RDONLY|O_CLOEXEC); + assert_se(imp.fd >= 0); + + do +@@ -49,9 +53,11 @@ static void test_basic_parsing(void) { + + static void test_bad_input(void) { + _cleanup_(journal_importer_cleanup) JournalImporter imp = {}; ++ _cleanup_free_ char *journal_data_path = NULL; + int r; + +- imp.fd = open(get_testdata_dir("/journal-data/journal-2.txt"), O_RDONLY|O_CLOEXEC); ++ journal_data_path = path_join(NULL, get_testdata_dir(), "journal-data/journal-2.txt"); ++ imp.fd = open(journal_data_path, O_RDONLY|O_CLOEXEC); + assert_se(imp.fd >= 0); + + do +diff --git a/src/test/test-path.c b/src/test/test-path.c +index 209eb2e..5e78a56 100644 +--- a/src/test/test-path.c ++++ b/src/test/test-path.c +@@ -12,6 +12,7 @@ + #include "macro.h" + #include "manager.h" + #include "mkdir.h" ++#include "path-util.h" + #include "rm-rf.h" + #include "string-util.h" + #include "strv.h" +@@ -247,6 +248,7 @@ int main(int argc, char *argv[]) { + }; + + _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL; ++ _cleanup_free_ char *test_path = NULL; + const test_function_t *test = NULL; + Manager *m = NULL; + +@@ -255,7 +257,8 @@ int main(int argc, char *argv[]) { + log_parse_environment(); + log_open(); + +- assert_se(set_unit_path(get_testdata_dir("/test-path")) >= 0); ++ test_path = path_join(NULL, get_testdata_dir(), "test-path"); ++ assert_se(set_unit_path(test_path) >= 0); + assert_se(runtime_dir = setup_fake_runtime_dir()); + + for (test = tests; test && *test; test++) { +diff --git a/src/test/test-sched-prio.c b/src/test/test-sched-prio.c +index c986284..60012e4 100644 +--- a/src/test/test-sched-prio.c ++++ b/src/test/test-sched-prio.c +@@ -26,7 +26,7 @@ int main(int argc, char *argv[]) { + } + + /* prepare the test */ +- assert_se(set_unit_path(get_testdata_dir("")) >= 0); ++ assert_se(set_unit_path(get_testdata_dir()) >= 0); + assert_se(runtime_dir = setup_fake_runtime_dir()); + r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_BASIC, &m); + if (MANAGER_SKIP_TEST(r)) { +diff --git a/src/test/test-umount.c b/src/test/test-umount.c +index 770d1a7..c068f7a 100644 +--- a/src/test/test-umount.c ++++ b/src/test/test-umount.c +@@ -1,6 +1,8 @@ + /* SPDX-License-Identifier: LGPL-2.1+ */ + ++#include "alloc-util.h" + #include "log.h" ++#include "path-util.h" + #include "string-util.h" + #include "tests.h" + #include "umount.h" +@@ -8,10 +10,14 @@ + + static void test_mount_points_list(const char *fname) { + _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, mp_list_head); ++ _cleanup_free_ char *testdata_fname = NULL; + MountPoint *m; + + log_info("/* %s(\"%s\") */", __func__, fname ?: "/proc/self/mountinfo"); + ++ if (fname) ++ fname = testdata_fname = path_join(NULL, get_testdata_dir(), fname); ++ + LIST_HEAD_INIT(mp_list_head); + assert_se(mount_points_list_get(fname, &mp_list_head) >= 0); + +@@ -26,10 +32,14 @@ static void test_mount_points_list(const char *fname) { + + static void test_swap_list(const char *fname) { + _cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, mp_list_head); ++ _cleanup_free_ char *testdata_fname = NULL; + MountPoint *m; + + log_info("/* %s(\"%s\") */", __func__, fname ?: "/proc/swaps"); + ++ if (fname) ++ fname = testdata_fname = path_join(NULL, get_testdata_dir(), fname); ++ + LIST_HEAD_INIT(mp_list_head); + assert_se(swap_list_get(fname, &mp_list_head) >= 0); + +@@ -48,10 +58,10 @@ int main(int argc, char **argv) { + log_open(); + + test_mount_points_list(NULL); +- test_mount_points_list(get_testdata_dir("/test-umount/empty.mountinfo")); +- test_mount_points_list(get_testdata_dir("/test-umount/garbled.mountinfo")); +- test_mount_points_list(get_testdata_dir("/test-umount/rhbug-1554943.mountinfo")); ++ test_mount_points_list("/test-umount/empty.mountinfo"); ++ test_mount_points_list("/test-umount/garbled.mountinfo"); ++ test_mount_points_list("/test-umount/rhbug-1554943.mountinfo"); + + test_swap_list(NULL); +- test_swap_list(get_testdata_dir("/test-umount/example.swaps")); ++ test_swap_list("/test-umount/example.swaps"); + } +diff --git a/src/test/test-watch-pid.c b/src/test/test-watch-pid.c +index 8c70175..d6e2886 100644 +--- a/src/test/test-watch-pid.c ++++ b/src/test/test-watch-pid.c +@@ -28,7 +28,7 @@ int main(int argc, char *argv[]) { + return EXIT_TEST_SKIP; + } + +- assert_se(set_unit_path(get_testdata_dir("")) >= 0); ++ assert_se(set_unit_path(get_testdata_dir()) >= 0); + assert_se(runtime_dir = setup_fake_runtime_dir()); + + assert_se(manager_new(UNIT_FILE_USER, true, &m) >= 0); +-- +2.18.1 + diff --git a/1005-test-use-builddir-systemd-runtest.env-to-set-SYSTEMD.patch b/1005-test-use-builddir-systemd-runtest.env-to-set-SYSTEMD.patch new file mode 100644 index 0000000..8a820d3 --- /dev/null +++ b/1005-test-use-builddir-systemd-runtest.env-to-set-SYSTEMD.patch @@ -0,0 +1,171 @@ +From 768c23b13c3401440d9c139238e2dd7af50ab320 Mon Sep 17 00:00:00 2001 +From: Filipe Brandenburger +Date: Tue, 11 Sep 2018 23:55:02 -0700 +Subject: [PATCH] test: use ${builddir}/systemd-runtest.env to set + $SYSTEMD_TEST_DATA + +This simplifies get_testdata_dir() to simply checking for an environment +variable, with an additional function to locate a systemd-runtest.env file in +the same directory as the test binary and reading environment variable +assignments from that file if it exists. + +This makes it possible to: +- Run `ninja test` from the build dir and have it use ${srcdir}/test for + test unit definitions. +- Run a test directly, such as `build/test-execute` and have it locate + them correctly. +- Run installed tests (from systemd-tests package) and locate the test + units in the installed location (/usr/lib/systemd/tests/testdata), in + which case the absence of the systemd-runtest.env file will have + get_testdata_dir() use the installed location hardcoded into the + binaries. + +Explicit setting of $SYSTEMD_TEST_DATA still overrides the contents of +systemd-runtest.env. + +Signed-off-by: Wen Yang +(cherry picked from commit e2d413707fc68ed033a83e10a055ca638a1e1e18) +--- + meson.build | 10 ++++++- + src/shared/tests.c | 67 ++++++++++++++++++++++------------------------ + 2 files changed, 41 insertions(+), 36 deletions(-) + +diff --git a/meson.build b/meson.build +index 70811c2..2b96ffe 100644 +--- a/meson.build ++++ b/meson.build +@@ -206,6 +206,7 @@ conf.set_quoted('SYSTEM_SHUTDOWN_PATH', systemshutdowndir) + conf.set_quoted('SYSTEM_SLEEP_PATH', systemsleepdir) + conf.set_quoted('SYSTEMD_KBD_MODEL_MAP', join_paths(pkgdatadir, 'kbd-model-map')) + conf.set_quoted('SYSTEMD_LANGUAGE_FALLBACK_MAP', join_paths(pkgdatadir, 'language-fallback-map')) ++conf.set_quoted('SYSTEMD_TEST_DATA', join_paths(testsdir, 'testdata')) + conf.set_quoted('UDEVLIBEXECDIR', udevlibexecdir) + conf.set_quoted('POLKIT_AGENT_BINARY_PATH', join_paths(bindir, 'pkttyagent')) + conf.set_quoted('LIBDIR', libdir) +@@ -222,7 +223,6 @@ conf.set('MEMORY_ACCOUNTING_DEFAULT', memory_accounting_ + conf.set_quoted('MEMORY_ACCOUNTING_DEFAULT_YES_NO', memory_accounting_default ? 'yes' : 'no') + + conf.set_quoted('ABS_BUILD_DIR', meson.build_root()) +-conf.set_quoted('ABS_SRC_DIR', meson.source_root()) + + substs.set('prefix', prefixdir) + substs.set('exec_prefix', prefixdir) +@@ -2584,6 +2584,14 @@ executable('systemd-sulogin-shell', + + ############################################################ + ++custom_target( ++ 'systemd-runtest.env', ++ output : 'systemd-runtest.env', ++ command : ['sh', '-c', '{ ' + ++ 'echo SYSTEMD_TEST_DATA=@0@; '.format(join_paths(meson.current_source_dir(), 'test')) + ++ '} >@OUTPUT@'], ++ build_by_default : true) ++ + foreach tuple : tests + sources = tuple[0] + link_with = tuple[1].length() > 0 ? tuple[1] : [libshared] +diff --git a/src/shared/tests.c b/src/shared/tests.c +index 100b62b..102b343 100644 +--- a/src/shared/tests.c ++++ b/src/shared/tests.c +@@ -6,8 +6,11 @@ + #include + #include + +-#include "tests.h" ++#include "alloc-util.h" ++#include "fileio.h" + #include "path-util.h" ++#include "strv.h" ++#include "tests.h" + + char* setup_fake_runtime_dir(void) { + char t[] = "/tmp/fake-xdg-runtime-XXXXXX", *p; +@@ -19,55 +22,49 @@ char* setup_fake_runtime_dir(void) { + return p; + } + +-bool test_is_running_from_builddir(char **exedir) { ++static void load_testdata_env(void) { ++ static bool called = false; + _cleanup_free_ char *s = NULL; +- bool r; ++ _cleanup_free_ char *envpath = NULL; ++ _cleanup_strv_free_ char **pairs = NULL; ++ char **k, **v; + +- /* Check if we're running from the builddir. Optionally, this returns +- * the path to the directory where the binary is located. */ ++ if (called) ++ return; ++ called = true; + + assert_se(readlink_and_make_absolute("/proc/self/exe", &s) >= 0); +- r = path_startswith(s, ABS_BUILD_DIR); ++ dirname(s); + +- if (exedir) { +- dirname(s); +- *exedir = TAKE_PTR(s); +- } ++ envpath = path_join(NULL, s, "systemd-runtest.env"); ++ if (load_env_file_pairs(NULL, envpath, NULL, &pairs) < 0) ++ return; + +- return r; ++ STRV_FOREACH_PAIR(k, v, pairs) ++ setenv(*k, *v, 0); ++} ++ ++bool test_is_running_from_builddir(char **exedir) { ++ load_testdata_env(); ++ ++ return !!getenv("SYSTEMD_TEST_DATA"); + } + + const char* get_testdata_dir(void) { + const char *env; +- /* convenience: caller does not need to free result */ +- static char testdir[PATH_MAX]; ++ ++ load_testdata_env(); + + /* if the env var is set, use that */ + env = getenv("SYSTEMD_TEST_DATA"); +- testdir[sizeof(testdir) - 1] = '\0'; +- if (env) { +- if (access(env, F_OK) < 0) { +- fputs("ERROR: $SYSTEMD_TEST_DATA directory does not exist\n", stderr); +- exit(EXIT_FAILURE); +- } +- strncpy(testdir, env, sizeof(testdir) - 1); +- } else { +- _cleanup_free_ char *exedir = NULL; +- +- /* Check if we're running from the builddir. If so, use the compiled in path. */ +- if (test_is_running_from_builddir(&exedir)) +- assert_se(snprintf(testdir, sizeof(testdir), "%s/test", ABS_SRC_DIR) > 0); +- else +- /* Try relative path, according to the install-test layout */ +- assert_se(snprintf(testdir, sizeof(testdir), "%s/testdata", exedir) > 0); +- +- if (access(testdir, F_OK) < 0) { +- fputs("ERROR: Cannot find testdata directory, set $SYSTEMD_TEST_DATA\n", stderr); +- exit(EXIT_FAILURE); +- } ++ if (!env) ++ env = SYSTEMD_TEST_DATA; ++ if (access(env, F_OK) < 0) { ++ fprintf(stderr, "ERROR: $SYSTEMD_TEST_DATA directory [%s] does not exist\n", env); ++ exit(EXIT_FAILURE); + } + +- return testdir; ++ return env; + } + + void test_setup_logging(int level) { +-- +2.18.1 + diff --git a/1006-test-use-builddir-systemd-runtest.env-for-SYSTEMD_CA.patch b/1006-test-use-builddir-systemd-runtest.env-for-SYSTEMD_CA.patch new file mode 100644 index 0000000..d3caa0d --- /dev/null +++ b/1006-test-use-builddir-systemd-runtest.env-for-SYSTEMD_CA.patch @@ -0,0 +1,139 @@ +From e9f7fcbcb242c7f19d000bc80d20bf25420375dc Mon Sep 17 00:00:00 2001 +From: Filipe Brandenburger +Date: Wed, 12 Sep 2018 00:23:40 -0700 +Subject: [PATCH] test: use ${builddir}/systemd-runtest.env for + $SYSTEMD_CATALOG_DIR + +This makes it so that tests no longer need to know the absolute paths to the +source and build dirs, instead using the systemd-runtest.env file to get these +paths when running from the build tree. + +Confirmed that test-catalog works on `ninja test`, when called standalone and +also when the environment file is not present, in which case it will use the +installed location under /usr/lib/systemd/catalog. + +The location can now also be overridden for this test by setting the +$SYSTEMD_CATALOG_DIR environment variable. + +Signed-off-by: Wen Yang +(cherry picked from commit fef716b28be6e866b8afe995805d5ebe2af6bbfa) +--- + meson.build | 4 ++-- + src/journal/test-catalog.c | 6 +----- + src/shared/tests.c | 22 ++++++++++++++++------ + src/shared/tests.h | 2 +- + src/test/meson.build | 3 +-- + 5 files changed, 21 insertions(+), 16 deletions(-) + +diff --git a/meson.build b/meson.build +index 2b96ffe..8020ef1 100644 +--- a/meson.build ++++ b/meson.build +@@ -207,6 +207,7 @@ conf.set_quoted('SYSTEM_SLEEP_PATH', systemsleepdir) + conf.set_quoted('SYSTEMD_KBD_MODEL_MAP', join_paths(pkgdatadir, 'kbd-model-map')) + conf.set_quoted('SYSTEMD_LANGUAGE_FALLBACK_MAP', join_paths(pkgdatadir, 'language-fallback-map')) + conf.set_quoted('SYSTEMD_TEST_DATA', join_paths(testsdir, 'testdata')) ++conf.set_quoted('SYSTEMD_CATALOG_DIR', catalogdir) + conf.set_quoted('UDEVLIBEXECDIR', udevlibexecdir) + conf.set_quoted('POLKIT_AGENT_BINARY_PATH', join_paths(bindir, 'pkttyagent')) + conf.set_quoted('LIBDIR', libdir) +@@ -222,8 +223,6 @@ conf.set_quoted('DOCUMENT_ROOT', join_paths(pkgdata + conf.set('MEMORY_ACCOUNTING_DEFAULT', memory_accounting_default ? 'true' : 'false') + conf.set_quoted('MEMORY_ACCOUNTING_DEFAULT_YES_NO', memory_accounting_default ? 'yes' : 'no') + +-conf.set_quoted('ABS_BUILD_DIR', meson.build_root()) +- + substs.set('prefix', prefixdir) + substs.set('exec_prefix', prefixdir) + substs.set('libdir', libdir) +@@ -2589,6 +2588,7 @@ custom_target( + output : 'systemd-runtest.env', + command : ['sh', '-c', '{ ' + + 'echo SYSTEMD_TEST_DATA=@0@; '.format(join_paths(meson.current_source_dir(), 'test')) + ++ 'echo SYSTEMD_CATALOG_DIR=@0@; '.format(join_paths(meson.current_build_dir(), 'catalog')) + + '} >@OUTPUT@'], + build_by_default : true) + +diff --git a/src/journal/test-catalog.c b/src/journal/test-catalog.c +index 0c4da29..d9ee557 100644 +--- a/src/journal/test-catalog.c ++++ b/src/journal/test-catalog.c +@@ -212,11 +212,7 @@ int main(int argc, char *argv[]) { + + /* If test-catalog is located at the build directory, then use catalogs in that. + * If it is not, e.g. installed by systemd-tests package, then use installed catalogs. */ +- if (test_is_running_from_builddir(NULL)) { +- assert_se(catalog_dir = path_join(NULL, ABS_BUILD_DIR, "catalog")); +- catalog_dirs = STRV_MAKE(catalog_dir); +- } else +- catalog_dirs = STRV_MAKE(CATALOG_DIR); ++ catalog_dirs = STRV_MAKE(get_catalog_dir()); + + assert_se(access(catalog_dirs[0], F_OK) >= 0); + log_notice("Using catalog directory '%s'", catalog_dirs[0]); +diff --git a/src/shared/tests.c b/src/shared/tests.c +index 102b343..7bd6f80 100644 +--- a/src/shared/tests.c ++++ b/src/shared/tests.c +@@ -44,12 +44,6 @@ static void load_testdata_env(void) { + setenv(*k, *v, 0); + } + +-bool test_is_running_from_builddir(char **exedir) { +- load_testdata_env(); +- +- return !!getenv("SYSTEMD_TEST_DATA"); +-} +- + const char* get_testdata_dir(void) { + const char *env; + +@@ -72,3 +66,19 @@ void test_setup_logging(int level) { + log_parse_environment(); + log_open(); + } ++ ++const char* get_catalog_dir(void) { ++ const char *env; ++ ++ load_testdata_env(); ++ ++ /* if the env var is set, use that */ ++ env = getenv("SYSTEMD_CATALOG_DIR"); ++ if (!env) ++ env = SYSTEMD_CATALOG_DIR; ++ if (access(env, F_OK) < 0) { ++ fprintf(stderr, "ERROR: $SYSTEMD_CATALOG_DIR directory [%s] does not exist\n", env); ++ exit(EXIT_FAILURE); ++ } ++ return env; ++} +diff --git a/src/shared/tests.h b/src/shared/tests.h +index 3d696d0..19a9fa0 100644 +--- a/src/shared/tests.h ++++ b/src/shared/tests.h +@@ -2,6 +2,6 @@ + #pragma once + + char* setup_fake_runtime_dir(void); +-bool test_is_running_from_builddir(char **exedir); + const char* get_testdata_dir(void); ++const char* get_catalog_dir(void); + void test_setup_logging(int level); +diff --git a/src/test/meson.build b/src/test/meson.build +index ead000e..5395de4 100644 +--- a/src/test/meson.build ++++ b/src/test/meson.build +@@ -765,8 +765,7 @@ tests += [ + libshared], + [threads, + libxz, +- liblz4], +- '', '', '-DCATALOG_DIR="@0@"'.format(catalogdir)], ++ liblz4]], + + [['src/journal/test-compress.c'], + [libjournal_core, +-- +2.18.1 + diff --git a/1007-strv-rework-FOREACH_STRING-macro.patch b/1007-strv-rework-FOREACH_STRING-macro.patch new file mode 100644 index 0000000..17900ff --- /dev/null +++ b/1007-strv-rework-FOREACH_STRING-macro.patch @@ -0,0 +1,50 @@ +From 29b6676e1d169ecfaa1c9a918d2551955aadfdf6 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 2 Jun 2020 02:48:29 +0000 +Subject: [PATCH] strv: rework FOREACH_STRING() macro + +upstream commit 66a64081f82dfad90f2f9394a477820a2e3e6510 + +So it's apparently problematic that we use STRV_MAKE() (i.e. a compound +initializer) outside of the {} block we use it in (and that includes +outside of the ({}) block, too). Hence, let's rework the macro to not +need that. + +This also makes the macro shorter, which is definitely a good and more +readable. Moreover, it will now complain if the iterator is a "char*" +instead of a "const char*", which is good too. + +Fixes: #11394 +--- + src/basic/strv.h | 15 ++++----------- + 1 file changed, 4 insertions(+), 11 deletions(-) + +diff --git a/src/basic/strv.h b/src/basic/strv.h +index c1e4c97..a09d767 100644 +--- a/src/basic/strv.h ++++ b/src/basic/strv.h +@@ -148,17 +148,10 @@ void strv_print(char **l); + _found; \ + }) + +-#define FOREACH_STRING(x, ...) \ +- for (char **_l = ({ \ +- char **_ll = STRV_MAKE(__VA_ARGS__); \ +- x = _ll ? _ll[0] : NULL; \ +- _ll; \ +- }); \ +- _l && *_l; \ +- x = ({ \ +- _l ++; \ +- _l[0]; \ +- })) ++#define FOREACH_STRING(x, y, ...) \ ++ for (char **_l = STRV_MAKE(({ x = y; }), ##__VA_ARGS__); \ ++ x; \ ++ x = *(++_l)) + + char **strv_reverse(char **l); + char **strv_shell_escape(char **l, const char *bad); +-- +2.18.1 + diff --git a/1008-exit-status-introduce-EXIT_EXCEPTION-mapping-to-255.patch b/1008-exit-status-introduce-EXIT_EXCEPTION-mapping-to-255.patch new file mode 100644 index 0000000..3b67531 --- /dev/null +++ b/1008-exit-status-introduce-EXIT_EXCEPTION-mapping-to-255.patch @@ -0,0 +1,61 @@ +From 99040e765a457265b6995cbef8611546e3c989d8 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 20 Nov 2018 16:55:51 +0100 +Subject: [PATCH] exit-status: introduce EXIT_EXCEPTION mapping to 255 + +cherry-picked from upstream 3584d3ca. + +Conflicts: + src/basic/exit-status.c + src/basic/exit-status.h + +Signed-off-by: Yuanhong Peng +--- + src/basic/exit-status.c | 10 +++++++--- + src/basic/exit-status.h | 2 ++ + 2 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/src/basic/exit-status.c b/src/basic/exit-status.c +index 0a7a53b..58ebc3c 100644 +--- a/src/basic/exit-status.c ++++ b/src/basic/exit-status.c +@@ -19,9 +19,10 @@ const char* exit_status_to_string(int status, ExitStatusLevel level) { + * 79…199 │ (Currently unmapped) + * 200…241 │ systemd's private error codes (might be extended to 254 in future development) + * 242…254 │ (Currently unmapped, but see above) +- * 255 │ (We should probably stay away from that one, it's frequently used by applications to indicate an +- * │ exit reason that cannot really be expressed in a single exit status value — such as a propagated +- * │ signal or such) ++ * ++ * 255 │ EXIT_EXCEPTION (We use this to propagate exit-by-signal events. It's frequently used by others apps (like bash) ++ * │ to indicate exit reason that cannot really be expressed in a single exit status value — such as a propagated ++ * │ signal or such, and we follow that logic here.) + */ + + switch (status) { /* We always cover the ISO C ones */ +@@ -158,6 +159,9 @@ const char* exit_status_to_string(int status, ExitStatusLevel level) { + + case EXIT_NUMA_POLICY: + return "NUMA_POLICY"; ++ ++ case EXIT_EXCEPTION: ++ return "EXCEPTION"; + } + } + +diff --git a/src/basic/exit-status.h b/src/basic/exit-status.h +index dc284aa..5637e6a 100644 +--- a/src/basic/exit-status.h ++++ b/src/basic/exit-status.h +@@ -70,6 +70,8 @@ enum { + EXIT_LOGS_DIRECTORY, /* 240 */ + EXIT_CONFIGURATION_DIRECTORY, + EXIT_NUMA_POLICY, ++ ++ EXIT_EXCEPTION = 255, /* Whenever we want to propagate an abnormal/signal exit, in line with bash */ + }; + + typedef enum ExitStatusLevel { +-- +2.18.1 + diff --git a/1009-main-don-t-freeze-PID-1-in-containers-exit-with-non-.patch b/1009-main-don-t-freeze-PID-1-in-containers-exit-with-non-.patch new file mode 100644 index 0000000..d42253b --- /dev/null +++ b/1009-main-don-t-freeze-PID-1-in-containers-exit-with-non-.patch @@ -0,0 +1,59 @@ +From 00484798ee2bfe3ca7156a4fa253abc2f5e0ad86 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Tue, 20 Nov 2018 13:16:48 +0100 +Subject: [PATCH] main: don't freeze PID 1 in containers, exit with non-zero + instead + +After all we have a nice way to propagate total failures, hence let's +use it. + +cherry-picked from upstream bb259772 without conflict. + +Signed-off-by: Yuanhong Peng +--- + src/core/main.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/src/core/main.c b/src/core/main.c +index 9f238a8..4b885fc 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -139,7 +139,14 @@ static NUMAPolicy arg_numa_policy; + static int parse_configuration(const struct rlimit *saved_rlimit_nofile, + const struct rlimit *saved_rlimit_memlock); + +-_noreturn_ static void freeze_or_reboot(void) { ++_noreturn_ static void freeze_or_exit_or_reboot(void) { ++ ++ /* If we are running in a contianer, let's prefer exiting, after all we can propagate an exit code to the ++ * container manager, and thus inform it that something went wrong. */ ++ if (detect_container() > 0) { ++ log_emergency("Exiting PID 1..."); ++ exit(EXIT_EXCEPTION); ++ } + + if (arg_crash_reboot) { + log_notice("Rebooting in 10s..."); +@@ -247,7 +254,7 @@ _noreturn_ static void crash(int sig) { + } + } + +- freeze_or_reboot(); ++ freeze_or_exit_or_reboot(); + } + + static void install_crash_handler(void) { +@@ -2664,8 +2671,8 @@ finish: + if (error_message) + manager_status_printf(NULL, STATUS_TYPE_EMERGENCY, + ANSI_HIGHLIGHT_RED "!!!!!!" ANSI_NORMAL, +- "%s, freezing.", error_message); +- freeze_or_reboot(); ++ "%s.", error_message); ++ freeze_or_exit_or_reboot(); + } + + return retval; +-- +2.18.1 + diff --git a/1010-Do-not-go-into-freeze-when-systemd-crashd.patch b/1010-Do-not-go-into-freeze-when-systemd-crashd.patch new file mode 100644 index 0000000..5eba2ed --- /dev/null +++ b/1010-Do-not-go-into-freeze-when-systemd-crashd.patch @@ -0,0 +1,111 @@ +From 0dd2881ae121ff87c2ebf2647f95a5f3066e2c8d Mon Sep 17 00:00:00 2001 +From: Yuanhong Peng +Date: Mon, 14 Dec 2020 17:04:28 +0800 +Subject: [PATCH] Do not go into freeze when systemd crashd + +If something unexpected happens which cause systemd to freeze, the system +cannot resume without a reboot, furthermore, if a service dies or exits, +no one else can recycle all child processes of the service, which will +cause a number of zombie processes remaining in the system. So we +introduce a mechanism, when systemd enters freeze state, you can send +SIGTERM to it to force systemd to re-exec. This may helps to resume the +system if it cannot reboot. + +Signed-off-by: Yuanhong Peng +--- + src/core/main.c | 40 +++++++++++++++++++++++++++++++++++++++- + 1 file changed, 39 insertions(+), 1 deletion(-) + +diff --git a/src/core/main.c b/src/core/main.c +index 4b885fc..c92d383 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -3,6 +3,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -10,6 +11,7 @@ + #include + #include + #include ++#include + #include + #if HAVE_SECCOMP + #include +@@ -135,10 +137,41 @@ static sd_id128_t arg_machine_id; + static EmergencyAction arg_cad_burst_action; + static CPUSet arg_cpu_affinity; + static NUMAPolicy arg_numa_policy; ++static bool reexec_jmp_can = false; ++static bool reexec_jmp_inited = false; ++static sigjmp_buf reexec_jmp_buf; + + static int parse_configuration(const struct rlimit *saved_rlimit_nofile, + const struct rlimit *saved_rlimit_memlock); + ++static void reexec_handler(int sig) { ++ reexec_jmp_can = true; ++} ++ ++_noreturn_ static void freeze_wait_upgrade(void) { ++ struct sigaction sa; ++ sigset_t ss; ++ ++ sigemptyset(&ss); ++ sigaddset(&ss, SIGTERM); ++ sigprocmask(SIG_UNBLOCK, &ss, NULL); ++ ++ sa.sa_handler = reexec_handler; ++ sa.sa_flags = SA_RESTART; ++ sigaction(SIGTERM, &sa, NULL); ++ ++ log_error("freeze_wait_upgrade: %d\n", reexec_jmp_inited); ++ reexec_jmp_can = false; ++ while(1) { ++ usleep(10000); ++ if (reexec_jmp_inited && reexec_jmp_can) { ++ log_error("goto manager_reexecute.\n"); ++ siglongjmp(reexec_jmp_buf, 1); ++ } ++ waitpid(-1, NULL, WNOHANG); ++ } ++} ++ + _noreturn_ static void freeze_or_exit_or_reboot(void) { + + /* If we are running in a contianer, let's prefer exiting, after all we can propagate an exit code to the +@@ -158,7 +191,7 @@ _noreturn_ static void freeze_or_exit_or_reboot(void) { + } + + log_emergency("Freezing execution."); +- freeze(); ++ freeze_wait_upgrade(); + } + + _noreturn_ static void crash(int sig) { +@@ -1668,6 +1701,10 @@ static int invoke_main_loop( + assert(ret_switch_root_init); + assert(ret_error_message); + ++ reexec_jmp_inited = true; ++ if (sigsetjmp(reexec_jmp_buf, 1)) ++ goto manager_reexecute; ++ + for (;;) { + r = manager_loop(m); + if (r < 0) { +@@ -1710,6 +1747,7 @@ static int invoke_main_loop( + + case MANAGER_REEXECUTE: + ++manager_reexecute: + r = prepare_reexecute(m, &arg_serialization, ret_fds, false); + if (r < 0) { + *ret_error_message = "Failed to prepare for reexecution"; +-- +2.27.0 + diff --git a/1011-mount-setup-change-the-system-mount-propagation-to-s.patch b/1011-mount-setup-change-the-system-mount-propagation-to-s.patch new file mode 100644 index 0000000..79f322f --- /dev/null +++ b/1011-mount-setup-change-the-system-mount-propagation-to-s.patch @@ -0,0 +1,77 @@ +From c5aa57f077ba61952f844f57f84c37345f906060 Mon Sep 17 00:00:00 2001 +From: Wen Yang +Date: Mon, 23 Mar 2020 10:42:46 +0800 +Subject: [PATCH] mount-setup: change the system mount propagation to shared by + default only at bootup + +The commit b3ac5f8cb987 has changed the system mount propagation to +shared by default, and according to the following patch: +https://github.com/opencontainers/runc/pull/208 +When starting the container, the pouch daemon will call runc to execute +make-private. + +However, if the systemctl daemon-reexec is executed after the container +has been started, the system mount propagation will be changed to share +again by default, and the make-private operation above will have no chance +to execute. + +cherry-picked from upstream f74349d8 without conflict. + +Signed-off-by: Yuanhong Peng +--- + src/core/main.c | 2 +- + src/core/mount-setup.c | 4 ++-- + src/core/mount-setup.h | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/core/main.c b/src/core/main.c +index c92d383..154d1bd 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -2519,7 +2519,7 @@ int main(int argc, char *argv[]) { + if (!skip_setup) + kmod_setup(); + +- r = mount_setup(loaded_policy); ++ r = mount_setup(loaded_policy, skip_setup); + if (r < 0) { + error_message = "Failed to mount API filesystems"; + goto finish; +diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c +index 16880e6..9619e6f 100644 +--- a/src/core/mount-setup.c ++++ b/src/core/mount-setup.c +@@ -398,7 +398,7 @@ static int relabel_cgroup_filesystems(void) { + } + #endif + +-int mount_setup(bool loaded_policy) { ++int mount_setup(bool loaded_policy, bool leave_propagation) { + int r = 0; + + r = mount_points_setup(ELEMENTSOF(mount_table), loaded_policy); +@@ -442,7 +442,7 @@ int mount_setup(bool loaded_policy) { + * needed. Note that we set this only when we are invoked directly by the kernel. If we are invoked by a + * container manager we assume the container manager knows what it is doing (for example, because it set up + * some directories with different propagation modes). */ +- if (detect_container() <= 0) ++ if (detect_container() <= 0 && !leave_propagation) + if (mount(NULL, "/", NULL, MS_REC|MS_SHARED, NULL) < 0) + log_warning_errno(errno, "Failed to set up the root directory for shared mount propagation: %m"); + +diff --git a/src/core/mount-setup.h b/src/core/mount-setup.h +index 43cd890..7a011b2 100644 +--- a/src/core/mount-setup.h ++++ b/src/core/mount-setup.h +@@ -4,7 +4,7 @@ + #include + + int mount_setup_early(void); +-int mount_setup(bool loaded_policy); ++int mount_setup(bool loaded_policy, bool leave_propagation); + + int mount_cgroup_controllers(char ***join_controllers); + +-- +2.18.1 + diff --git a/1012-mount-don-t-propagate-errors-from-mount_setup_unit-f.patch b/1012-mount-don-t-propagate-errors-from-mount_setup_unit-f.patch new file mode 100644 index 0000000..8f9602d --- /dev/null +++ b/1012-mount-don-t-propagate-errors-from-mount_setup_unit-f.patch @@ -0,0 +1,58 @@ +From 3587b250231c8a84641c7df57418b4d02ca7430d Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Wed, 28 Nov 2018 12:41:44 +0100 +Subject: [PATCH] mount: don't propagate errors from mount_setup_unit() further + up + +If we can't process a specific line in /proc/self/mountinfo we should +log about it (which we do), but this should not affect other lines, nor +further processing of mount units. Let's keep these failures local. + +Fixes: #10874 + +cherry-picked from upstream ba0d56f5 without conflict. + +Signed-off-by: Yuanhong Peng +--- + src/core/mount.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +diff --git a/src/core/mount.c b/src/core/mount.c +index 5878814..1ac6feb 100644 +--- a/src/core/mount.c ++++ b/src/core/mount.c +@@ -1606,7 +1606,7 @@ fail: + static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { + _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL; + _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL; +- int r = 0; ++ int r; + + assert(m); + +@@ -1619,7 +1619,6 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { + if (r < 0) + return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m"); + +- r = 0; + for (;;) { + struct libmnt_fs *fs; + const char *device, *path, *options, *fstype; +@@ -1648,12 +1647,10 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { + + device_found_node(m, d, DEVICE_FOUND_MOUNT, DEVICE_FOUND_MOUNT); + +- k = mount_setup_unit(m, d, p, options, fstype, set_flags); +- if (r == 0 && k < 0) +- r = k; ++ (void) mount_setup_unit(m, d, p, options, fstype, set_flags); + } + +- return r; ++ return 0; + } + + static void mount_shutdown(Manager *m) { +-- +2.18.1 + diff --git a/1013-cgroup-util-make-definition-of-CGROUP_CONTROLLER_TO_.patch b/1013-cgroup-util-make-definition-of-CGROUP_CONTROLLER_TO_.patch new file mode 100644 index 0000000..30eec1c --- /dev/null +++ b/1013-cgroup-util-make-definition-of-CGROUP_CONTROLLER_TO_.patch @@ -0,0 +1,33 @@ +From 2fc903c9e199d329cdd5f0230585a155ebe79cf8 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Fri, 26 Oct 2018 15:31:30 +0200 +Subject: [PATCH] cgroup-util: make definition of CGROUP_CONTROLLER_TO_MASK() + unsigned + +Otherwise doing comparing a CGroupMask (which is unsigned in effect) +with the result of CGROUP_CONTROLLER_TO_MASK() will result in warnings +about signedness differences. + +cherry-picked from upstream 46f84f95 without conflict. + +Signed-off-by: Yuanhong Peng +--- + src/basic/cgroup-util.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/basic/cgroup-util.h b/src/basic/cgroup-util.h +index b414600..ad21184 100644 +--- a/src/basic/cgroup-util.h ++++ b/src/basic/cgroup-util.h +@@ -31,7 +31,7 @@ typedef enum CGroupController { + _CGROUP_CONTROLLER_INVALID = -1, + } CGroupController; + +-#define CGROUP_CONTROLLER_TO_MASK(c) (1 << (c)) ++#define CGROUP_CONTROLLER_TO_MASK(c) (1U << (c)) + + /* A bit mask of well known cgroup controllers */ + typedef enum CGroupMask { +-- +2.18.1 + diff --git a/1014-cgroup-update-only-siblings-that-got-realized-once.patch b/1014-cgroup-update-only-siblings-that-got-realized-once.patch new file mode 100644 index 0000000..14bbde7 --- /dev/null +++ b/1014-cgroup-update-only-siblings-that-got-realized-once.patch @@ -0,0 +1,67 @@ +From c997afaee923f4cf94804e97693add82040dc948 Mon Sep 17 00:00:00 2001 +From: Lennart Poettering +Date: Mon, 13 Jan 2020 20:06:39 +0100 +Subject: [PATCH] cgroup: update only siblings that got realized once + +Fixes: #14475 +Replaces: #14554 + +cherry-picked from upstream e1e98911 without conflict. + +Signed-off-by: Yuanhong Peng +--- + src/core/cgroup.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +diff --git a/src/core/cgroup.c b/src/core/cgroup.c +index 9e4c3c7..11de9e4 100644 +--- a/src/core/cgroup.c ++++ b/src/core/cgroup.c +@@ -1797,7 +1797,15 @@ static void unit_add_siblings_to_cgroup_realize_queue(Unit *u) { + Unit *slice; + + /* This adds the siblings of the specified unit and the siblings of all parent units to the cgroup +- * queue. (But neither the specified unit itself nor the parents.) */ ++ * queue. (But neither the specified unit itself nor the parents.) ++ * ++ * Propagation of realization "side-ways" (i.e. towards siblings) is in relevant on cgroup-v1 where ++ * scheduling become very weird if two units that own processes reside in the same slice, but one is ++ * realized in the "cpu" hierarchy and once is not (for example because one has CPUWeight= set and ++ * the other does not), because that means processes need to be scheduled against groups. Let's avoid ++ * this asymmetry by always ensuring that units below a slice that are realized at all are hence ++ * always realized in *all* their hierarchies, and it is sufficient for a unit's sibling to be ++ * realized for a unit to be realized too. */ + + while ((slice = UNIT_DEREF(u->slice))) { + Iterator i; +@@ -1805,6 +1813,7 @@ static void unit_add_siblings_to_cgroup_realize_queue(Unit *u) { + void *v; + + HASHMAP_FOREACH_KEY(v, m, slice->dependencies[UNIT_BEFORE], i) { ++ + /* Skip units that have a dependency on the slice but aren't actually in it. */ + if (UNIT_DEREF(m->slice) != slice) + continue; +@@ -1813,6 +1822,11 @@ static void unit_add_siblings_to_cgroup_realize_queue(Unit *u) { + if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(m))) + continue; + ++ /* We only enqueue siblings if they were realized once at least, in the main ++ * hierarchy. */ ++ if (!m->cgroup_realized) ++ continue; ++ + /* If the unit doesn't need any new controllers and has current ones realized, it + * doesn't need any changes. */ + if (unit_has_mask_realized(m, +@@ -2097,6 +2111,7 @@ void unit_add_to_cgroup_empty_queue(Unit *u) { + /* Let's verify that the cgroup is really empty */ + if (!u->cgroup_path) + return; ++ + r = cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path); + if (r < 0) { + log_unit_debug_errno(u, r, "Failed to determine whether cgroup %s is empty: %m", u->cgroup_path); +-- +2.18.1 + diff --git a/1015-core-add-a-config-item-to-support-setting-the-value-.patch b/1015-core-add-a-config-item-to-support-setting-the-value-.patch new file mode 100644 index 0000000..4fd3493 --- /dev/null +++ b/1015-core-add-a-config-item-to-support-setting-the-value-.patch @@ -0,0 +1,121 @@ +From 7b23f560993ad06228132d39d731fb510afb06eb Mon Sep 17 00:00:00 2001 +From: Yuanhong Peng +Date: Tue, 15 Dec 2020 11:47:49 +0800 +Subject: [PATCH] core: add a config item to support setting the value of + cpuset.clone_children when systemd is starting + +Signed-off-by: Yuanhong Peng +--- + src/core/main.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 68 insertions(+) + +diff --git a/src/core/main.c b/src/core/main.c +index 154d1bd..57da7b8 100644 +--- a/src/core/main.c ++++ b/src/core/main.c +@@ -140,6 +140,7 @@ static NUMAPolicy arg_numa_policy; + static bool reexec_jmp_can = false; + static bool reexec_jmp_inited = false; + static sigjmp_buf reexec_jmp_buf; ++static bool arg_default_cpuset_clone_children = false; + + static int parse_configuration(const struct rlimit *saved_rlimit_nofile, + const struct rlimit *saved_rlimit_memlock); +@@ -528,6 +529,14 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat + + parse_path_argument_and_warn(value, false, &arg_watchdog_device); + ++ } else if (proc_cmdline_key_streq(key, "systemd.cpuset_clone_children") && value) { ++ ++ r = parse_boolean(value); ++ if (r < 0) ++ log_warning("Failed to parse cpuset_clone_children switch %s. Ignoring.", value); ++ else ++ arg_default_cpuset_clone_children = r; ++ + } else if (streq(key, "quiet") && !value) { + + if (arg_show_status == _SHOW_STATUS_UNSET) +@@ -756,6 +765,7 @@ static int parse_config_file(void) { + { "Manager", "DefaultTasksAccounting", config_parse_bool, 0, &arg_default_tasks_accounting }, + { "Manager", "DefaultTasksMax", config_parse_tasks_max, 0, &arg_default_tasks_max }, + { "Manager", "CtrlAltDelBurstAction", config_parse_emergency_action, 0, &arg_cad_burst_action }, ++ { "Manager", "DefaultCPUSetCloneChildren",config_parse_bool, 0, &arg_default_cpuset_clone_children }, + {} + }; + +@@ -1872,6 +1882,63 @@ static void log_execution_mode(bool *ret_first_boot) { + } + } + ++static bool is_use_triple_cgroup(void) { ++ const char * path ="/sys/fs/cgroup/cpuset"; ++ _cleanup_strv_free_ char **l = NULL; ++ char buf[128] = {0}; ++ int r; ++ ++ r = is_symlink(path); ++ if (r <= 0) ++ return false; ++ ++ r = readlink(path, buf, sizeof(buf)); ++ if (r < 0 || (unsigned int)r >= sizeof(buf)) ++ return false; ++ ++ buf[r] = '\0'; ++ l = strv_split(buf, ","); ++ if (!l) ++ return false; ++ ++ strv_sort(l); ++ if (strv_length(l) != 3) ++ return false; ++ ++ if (streq(l[0],"cpu") && streq(l[1], "cpuacct") && ++ streq(l[2], "cpuset")) { ++ log_debug(PACKAGE_STRING " use_triple_cgroup: %s", buf); ++ return true; ++ } ++ return false; ++} ++ ++static int ali_handle_cpuset_clone_children(void) ++{ ++ const char *file = "/sys/fs/cgroup/cpuset/cgroup.clone_children"; ++ _cleanup_free_ char *buf = NULL; ++ int r; ++ ++ r = read_one_line_file(file, &buf); ++ if (r < 0) { ++ log_warning_errno(r, "Cannot read %s: %m", file); ++ return r; ++ } ++ ++ if (streq(buf, "1") && arg_default_cpuset_clone_children) ++ return 0; ++ ++ if (streq(buf, "0") && (!arg_default_cpuset_clone_children)) ++ return 0; ++ ++ if (!is_use_triple_cgroup()) ++ return 0; ++ ++ r = write_string_file(file, one_zero(arg_default_cpuset_clone_children), 0); ++ log_info(PACKAGE_STRING " set %s to %s, ret=%d", file, one_zero(arg_default_cpuset_clone_children), r); ++ return r; ++} ++ + static int initialize_runtime( + bool skip_setup, + struct rlimit *saved_rlimit_nofile, +@@ -1906,6 +1973,7 @@ static int initialize_runtime( + return r; + } + ++ ali_handle_cpuset_clone_children(); + status_welcome(); + hostname_setup(); + machine_id_setup(NULL, arg_machine_id, NULL); +-- +2.18.1 + diff --git a/systemd.spec b/systemd.spec index 932532f..2c47a09 100644 --- a/systemd.spec +++ b/systemd.spec @@ -1,4 +1,4 @@ -%define anolis_release .0.1 +%define anolis_release .0.2 #global gitcommit 10e465b5321bd53c1fc59ffab27e724535c6bc0f %{?gitcommit:%global gitcommitshort %(c=%{gitcommit}; echo ${c:0:7})} @@ -441,6 +441,20 @@ Patch0386: 0386-disable-cap-list-test.patch Patch1000: 1000-anolis-update-to-latest-hwdb.patch Patch1001: 1001-anolis-update-hwdb-ma-files.patch +Patch1002: 1002-core-fix-a-null-reference-case-in-load_from_path.patch +Patch1003: 1003-sysctl-Don-t-pass-null-directive-argument-to-s.patch +Patch1004: 1004-test-remove-support-for-suffix-in-get_testdata_dir.patch +Patch1005: 1005-test-use-builddir-systemd-runtest.env-to-set-SYSTEMD.patch +Patch1006: 1006-test-use-builddir-systemd-runtest.env-for-SYSTEMD_CA.patch +Patch1007: 1007-strv-rework-FOREACH_STRING-macro.patch +Patch1008: 1008-exit-status-introduce-EXIT_EXCEPTION-mapping-to-255.patch +Patch1009: 1009-main-don-t-freeze-PID-1-in-containers-exit-with-non-.patch +Patch1010: 1010-Do-not-go-into-freeze-when-systemd-crashd.patch +Patch1011: 1011-mount-setup-change-the-system-mount-propagation-to-s.patch +Patch1012: 1012-mount-don-t-propagate-errors-from-mount_setup_unit-f.patch +Patch1013: 1013-cgroup-util-make-definition-of-CGROUP_CONTROLLER_TO_.patch +Patch1014: 1014-cgroup-update-only-siblings-that-got-realized-once.patch +Patch1015: 1015-core-add-a-config-item-to-support-setting-the-value-.patch @@ -1067,6 +1081,22 @@ fi %files tests -f .file-list-tests %changelog +* Tue Dec 14 2021 Yuanhong Peng - 239-31.7.0.2 +- core: fix a null reference case in load_from_path() +- sysctl: Don't pass null directive argument to '%s' +- test: remove support for suffix in get_testdata_dir() +- test: use ${builddir}/systemd-runtest.env to set $SYSTEMD_TEST_DATA +- test: use ${builddir}/systemd-runtest.env for $SYSTEMD_CATALOG_DIR +- strv: rework FOREACH_STRING() macro +- exit-status: introduce EXIT_EXCEPTION mapping to 255 +- main: don't freeze PID 1 in containers, exit with non-zero instead +- Do not go into freeze when systemd crashd +- mount-setup: change the system mount propagation to shared by default only at bootup +- mount: don't propagate errors from mount_setup_unit() further up +- cgroup-util: make definition of CGROUP_CONTROLLER_TO_MASK() unsigned +- cgroup: update only siblings that got realized once +- core: add a config item to support setting the value of cpuset.clone_children when systemd is starting + * Thu Nov 11 2021 Liwei Ge - 239-31.7.0.1 - Update to latest hwdb - cherry-pick [69e310f] -- Gitee