From 0d8c31ff7237149b505290652864b4e7e866b2a7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Tue, 7 Jan 2014 08:41:24 -0500 Subject: [PATCH 1/1] test-engine: fix access to unit load path Also add a bit of debugging output to help diagnose problems, add missing units, and simplify cppflags. Move test-engine to normal tests from manual tests, it should now work without destroying the system. --- Makefile.am | 3 +- src/core/cgroup.c | 57 +++++++++++++++++++------------------ src/core/main.c | 11 +++++-- src/core/manager.c | 23 ++++++++++++--- src/core/manager.h | 4 ++- src/test/test-cgroup-mask.c | 5 ++-- src/test/test-engine.c | 24 ++++++++++++---- src/test/test-sched-prio.c | 5 ++-- src/test/test-unit-name.c | 2 +- test/basic.target | 1 + test/paths.target | 1 + test/shutdown.target | 1 + test/sockets.target | 1 + test/sysinit.target | 1 + test/timers.target | 1 + 15 files changed, 92 insertions(+), 48 deletions(-) create mode 120000 test/basic.target create mode 120000 test/paths.target create mode 120000 test/shutdown.target create mode 120000 test/sockets.target create mode 120000 test/sysinit.target create mode 120000 test/timers.target diff --git a/Makefile.am b/Makefile.am index c6853e46e..585786398 100644 --- a/Makefile.am +++ b/Makefile.am @@ -189,6 +189,7 @@ AM_CPPFLAGS = \ -DKEXEC=\"$(KEXEC)\" \ -DLIBDIR=\"$(libdir)\" \ -DROOTLIBDIR=\"$(rootlibdir)\" \ + -DTEST_DIR=\"$(abs_top_srcdir)/test\" \ -I $(top_srcdir)/src \ -I $(top_builddir)/src/shared \ -I $(top_srcdir)/src/shared \ @@ -1224,7 +1225,6 @@ CLEANFILES += \ # ------------------------------------------------------------------------------ manual_tests += \ - test-engine \ test-ns \ test-loopback \ test-hostname \ @@ -1242,6 +1242,7 @@ manual_tests += \ endif tests += \ + test-engine \ test-job-type \ test-env-replace \ test-strbuf \ diff --git a/src/core/cgroup.c b/src/core/cgroup.c index cd6796383..db8b4d770 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -832,7 +832,6 @@ pid_t unit_search_main_pid(Unit *u) { int manager_setup_cgroup(Manager *m) { _cleanup_free_ char *path = NULL; - char *e; int r; assert(m); @@ -851,6 +850,8 @@ int manager_setup_cgroup(Manager *m) { * off. This is to support live upgrades from older systemd * versions where PID 1 was moved there. */ if (m->running_as == SYSTEMD_SYSTEM) { + char *e; + e = endswith(m->cgroup_root, "/" SPECIAL_SYSTEM_SLICE); if (!e) e = endswith(m->cgroup_root, "/system"); @@ -872,40 +873,42 @@ int manager_setup_cgroup(Manager *m) { } log_debug("Using cgroup controller " SYSTEMD_CGROUP_CONTROLLER ". File system hierarchy is at %s.", path); + if (!m->test_run) { - /* 3. Install agent */ - if (m->running_as == SYSTEMD_SYSTEM) { - r = cg_install_release_agent(SYSTEMD_CGROUP_CONTROLLER, SYSTEMD_CGROUP_AGENT_PATH); - if (r < 0) - log_warning("Failed to install release agent, ignoring: %s", strerror(-r)); - else if (r > 0) - log_debug("Installed release agent."); - else - log_debug("Release agent already installed."); - } + /* 3. Install agent */ + if (m->running_as == SYSTEMD_SYSTEM) { + r = cg_install_release_agent(SYSTEMD_CGROUP_CONTROLLER, SYSTEMD_CGROUP_AGENT_PATH); + if (r < 0) + log_warning("Failed to install release agent, ignoring: %s", strerror(-r)); + else if (r > 0) + log_debug("Installed release agent."); + else + log_debug("Release agent already installed."); + } - /* 4. Make sure we are in the root cgroup */ - r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_root, 0); - if (r < 0) { - log_error("Failed to create root cgroup hierarchy: %s", strerror(-r)); - return r; - } + /* 4. Make sure we are in the root cgroup */ + r = cg_create_and_attach(SYSTEMD_CGROUP_CONTROLLER, m->cgroup_root, 0); + if (r < 0) { + log_error("Failed to create root cgroup hierarchy: %s", strerror(-r)); + return r; + } - /* 5. And pin it, so that it cannot be unmounted */ - safe_close(m->pin_cgroupfs_fd); + /* 5. And pin it, so that it cannot be unmounted */ + safe_close(m->pin_cgroupfs_fd); - m->pin_cgroupfs_fd = open(path, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY|O_NONBLOCK); - if (m->pin_cgroupfs_fd < 0) { - log_error("Failed to open pin file: %m"); - return -errno; + m->pin_cgroupfs_fd = open(path, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY|O_NONBLOCK); + if (m->pin_cgroupfs_fd < 0) { + log_error("Failed to open pin file: %m"); + return -errno; + } + + /* 6. Always enable hierarchial support if it exists... */ + cg_set_attribute("memory", "/", "memory.use_hierarchy", "1"); } - /* 6. Figure out which controllers are supported */ + /* 7. Figure out which controllers are supported */ m->cgroup_supported = cg_mask_supported(); - /* 7. Always enable hierarchial support if it exists... */ - cg_set_attribute("memory", "/", "memory.use_hierarchy", "1"); - return 0; } diff --git a/src/core/main.c b/src/core/main.c index ae38b435d..29f97364a 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1473,6 +1473,9 @@ int main(int argc, char *argv[]) { goto finish; } + if (arg_action == ACTION_TEST) + skip_setup = true; + pager_open_if_enabled(); if (arg_action == ACTION_HELP) { @@ -1543,7 +1546,8 @@ int main(int argc, char *argv[]) { if (arg_running_as == SYSTEMD_SYSTEM) { const char *virtualization = NULL; - log_info(PACKAGE_STRING " running in system mode. (" SYSTEMD_FEATURES ")"); + log_info(PACKAGE_STRING " running in %ssystem mode. (" SYSTEMD_FEATURES ")", + arg_action == ACTION_TEST ? "test " : "" ); detect_virtualization(&virtualization); if (virtualization) @@ -1571,7 +1575,8 @@ int main(int argc, char *argv[]) { _cleanup_free_ char *t; t = uid_to_name(getuid()); - log_debug(PACKAGE_STRING " running in user mode for user "UID_FMT"/%s. (" SYSTEMD_FEATURES ")", getuid(), strna(t)); + log_debug(PACKAGE_STRING " running in %suser mode for user "UID_FMT"/%s. (" SYSTEMD_FEATURES ")", + arg_action == ACTION_TEST ? " test" : "", getuid(), t); } if (arg_running_as == SYSTEMD_SYSTEM && !skip_setup) { @@ -1636,7 +1641,7 @@ int main(int argc, char *argv[]) { } } - r = manager_new(arg_running_as, &m); + r = manager_new(arg_running_as, arg_action == ACTION_TEST, &m); if (r < 0) { log_error("Failed to allocate manager object: %s", strerror(-r)); goto finish; diff --git a/src/core/manager.c b/src/core/manager.c index 9d9a71300..2e63c5ef1 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -241,6 +241,9 @@ static int manager_setup_time_change(Manager *m) { assert(m); assert_cc(sizeof(time_t) == sizeof(TIME_T_MAX)); + if (m->test_run) + return 0; + /* Uses TFD_TIMER_CANCEL_ON_SET to get notifications whenever * CLOCK_REALTIME makes a jump relative to CLOCK_MONOTONIC */ @@ -302,6 +305,9 @@ static int manager_setup_signals(Manager *m) { assert(m); + if (m->test_run) + return 0; + /* We are not interested in SIGSTOP and friends. */ assert_se(sigaction(SIGCHLD, &sa, NULL) == 0); @@ -409,7 +415,7 @@ static int manager_default_environment(Manager *m) { return 0; } -int manager_new(SystemdRunningAs running_as, Manager **_m) { +int manager_new(SystemdRunningAs running_as, bool test_run, Manager **_m) { Manager *m; int r; @@ -435,6 +441,8 @@ int manager_new(SystemdRunningAs running_as, Manager **_m) { m->pin_cgroupfs_fd = m->notify_fd = m->signal_fd = m->time_change_fd = m->dev_autofs_fd = m->private_listen_fd = m->kdbus_fd = -1; m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */ + m->test_run = test_run; + r = manager_default_environment(m); if (r < 0) goto fail; @@ -514,6 +522,9 @@ fail: static int manager_setup_notify(Manager *m) { int r; + if (m->test_run) + return 0; + if (m->notify_fd < 0) { _cleanup_close_ int fd = -1; union { @@ -592,12 +603,10 @@ static int manager_setup_notify(Manager *m) { static int manager_setup_kdbus(Manager *m) { #ifdef ENABLE_KDBUS _cleanup_free_ char *p = NULL; -#endif -#ifdef ENABLE_KDBUS assert(m); - if (m->kdbus_fd >= 0) + if (m->test_run || m->kdbus_fd >= 0) return 0; m->kdbus_fd = bus_kernel_create_bus(m->running_as == SYSTEMD_SYSTEM ? "system" : "user", m->running_as == SYSTEMD_SYSTEM, &p); @@ -624,6 +633,9 @@ static int manager_connect_bus(Manager *m, bool reexecuting) { assert(m); + if (m->test_run) + return 0; + try_bus_connect = m->kdbus_fd >= 0 || reexecuting || @@ -2636,6 +2648,9 @@ void manager_run_generators(Manager *m) { assert(m); + if (m->test_run) + return; + generator_path = m->running_as == SYSTEMD_SYSTEM ? SYSTEM_GENERATOR_PATH : USER_GENERATOR_PATH; d = opendir(generator_path); if (!d) { diff --git a/src/core/manager.h b/src/core/manager.h index 718c29fa0..aa6c76fa5 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -230,6 +230,8 @@ struct Manager { bool taint_usr:1; bool first_boot:1; + bool test_run:1; + ShowStatus show_status; bool confirm_spawn; bool no_console_output; @@ -276,7 +278,7 @@ struct Manager { int kdbus_fd; }; -int manager_new(SystemdRunningAs running_as, Manager **m); +int manager_new(SystemdRunningAs running_as, bool test_run, Manager **m); void manager_free(Manager *m); int manager_enumerate(Manager *m); diff --git a/src/test/test-cgroup-mask.c b/src/test/test-cgroup-mask.c index 4d6085951..a230c9777 100644 --- a/src/test/test-cgroup-mask.c +++ b/src/test/test-cgroup-mask.c @@ -37,11 +37,10 @@ static int test_cgroup_mask(void) { FILE *serial = NULL; FDSet *fdset = NULL; int r; - const char *dir = TEST_DIR; /* Prepare the manager. */ - assert_se(set_unit_path(dir) >= 0); - r = manager_new(SYSTEMD_USER, &m); + assert_se(set_unit_path(TEST_DIR) >= 0); + r = manager_new(SYSTEMD_USER, true, &m); if (r == -EPERM || r == -EACCES) { puts("manager_new: Permission denied. Skipping test."); return EXIT_TEST_SKIP; diff --git a/src/test/test-engine.c b/src/test/test-engine.c index 0f3862226..6e39a586c 100644 --- a/src/test/test-engine.c +++ b/src/test/test-engine.c @@ -25,15 +25,26 @@ #include #include "manager.h" +#include "bus-util.h" int main(int argc, char *argv[]) { + _cleanup_bus_error_free_ sd_bus_error err = SD_BUS_ERROR_NULL; Manager *m = NULL; Unit *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL, *g = NULL, *h = NULL; + FILE *serial = NULL; + FDSet *fdset = NULL; Job *j; - - assert_se(set_unit_path("test") >= 0); - - assert_se(manager_new(SYSTEMD_SYSTEM, &m) >= 0); + int r; + + /* prepare the test */ + assert_se(set_unit_path(TEST_DIR) >= 0); + r = manager_new(SYSTEMD_USER, true, &m); + if (r == -EPERM || r == -EACCES || r == -EADDRINUSE || r == -EHOSTDOWN) { + printf("Skipping test: manager_new: %s", strerror(-r)); + return EXIT_TEST_SKIP; + } + assert(r >= 0); + assert_se(manager_startup(m, serial, fdset) >= 0); printf("Load1:\n"); assert_se(manager_load_unit(m, "a.service", NULL, NULL, &a) >= 0); @@ -42,7 +53,10 @@ int main(int argc, char *argv[]) { manager_dump_units(m, stdout, "\t"); printf("Test1: (Trivial)\n"); - assert_se(manager_add_job(m, JOB_START, c, JOB_REPLACE, false, NULL, &j) == 0); + r = manager_add_job(m, JOB_START, c, JOB_REPLACE, false, &err, &j); + if (sd_bus_error_is_set(&err)) + log_error("error: %s: %s", err.name, err.message); + assert(r == 0); manager_dump_jobs(m, stdout, "\t"); printf("Load2:\n"); diff --git a/src/test/test-sched-prio.c b/src/test/test-sched-prio.c index e984ee420..8fdca0ea2 100644 --- a/src/test/test-sched-prio.c +++ b/src/test/test-sched-prio.c @@ -31,11 +31,10 @@ int main(int argc, char *argv[]) { FILE *serial = NULL; FDSet *fdset = NULL; int r; - const char *dir = TEST_DIR; /* prepare the test */ - assert_se(set_unit_path(dir) >= 0); - r = manager_new(SYSTEMD_USER, &m); + assert_se(set_unit_path(TEST_DIR) >= 0); + r = manager_new(SYSTEMD_USER, true, &m); if (r == -EPERM || r == -EACCES || r == -EADDRINUSE || r == -EHOSTDOWN) { printf("Skipping test: manager_new: %s", strerror(-r)); return EXIT_TEST_SKIP; diff --git a/src/test/test-unit-name.c b/src/test/test-unit-name.c index db728bcef..b73317374 100644 --- a/src/test/test-unit-name.c +++ b/src/test/test-unit-name.c @@ -125,7 +125,7 @@ static int test_unit_printf(void) { assert_se((root = getpwnam("root"))); assert_se(asprintf(&root_uid, "%d", (int) root->pw_uid) > 0); - r = manager_new(SYSTEMD_USER, &m); + r = manager_new(SYSTEMD_USER, true, &m); if (r == -EPERM || r == -EACCES || r == -EADDRINUSE) { puts("manager_new: Permission denied. Skipping test."); return EXIT_TEST_SKIP; diff --git a/test/basic.target b/test/basic.target new file mode 120000 index 000000000..061293468 --- /dev/null +++ b/test/basic.target @@ -0,0 +1 @@ +../units/basic.target \ No newline at end of file diff --git a/test/paths.target b/test/paths.target new file mode 120000 index 000000000..e9939c980 --- /dev/null +++ b/test/paths.target @@ -0,0 +1 @@ +../units/paths.target \ No newline at end of file diff --git a/test/shutdown.target b/test/shutdown.target new file mode 120000 index 000000000..1a3c2eec8 --- /dev/null +++ b/test/shutdown.target @@ -0,0 +1 @@ +../units/shutdown.target \ No newline at end of file diff --git a/test/sockets.target b/test/sockets.target new file mode 120000 index 000000000..8ff86a077 --- /dev/null +++ b/test/sockets.target @@ -0,0 +1 @@ +../units/sockets.target \ No newline at end of file diff --git a/test/sysinit.target b/test/sysinit.target new file mode 120000 index 000000000..330133818 --- /dev/null +++ b/test/sysinit.target @@ -0,0 +1 @@ +../units/sysinit.target \ No newline at end of file diff --git a/test/timers.target b/test/timers.target new file mode 120000 index 000000000..576d47fed --- /dev/null +++ b/test/timers.target @@ -0,0 +1 @@ +../units/timers.target \ No newline at end of file -- 2.30.2