From: Zbigniew Jędrzejewski-Szmek Date: Tue, 23 Jun 2026 10:00:40 +0000 (+0200) Subject: core: let manager_load_startable_unit_or_warn take a log level X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7bff0f09fe8b87bb1d9aa7fd1667c6a7d483d34e;p=thirdparty%2Fsystemd.git core: let manager_load_startable_unit_or_warn take a log level Add a log_level parameter so callers can control the severity of load failures. During boot, when no unit was explicitly requested on the kernel command line (arg_default_unit is unset), failing to load the default unit is not fatal since we fall back to other targets, so log those attempts at LOG_INFO instead of LOG_ERR. All other callers pass LOG_ERR to keep their existing behaviour. --- diff --git a/src/analyze/analyze-condition.c b/src/analyze/analyze-condition.c index 5c5177c3bea..8704e0a6e36 100644 --- a/src/analyze/analyze-condition.c +++ b/src/analyze/analyze-condition.c @@ -109,7 +109,7 @@ static int verify_conditions(char **lines, RuntimeScope scope, const char *unit, if (r < 0) return log_error_errno(r, "Failed to prepare filename %s: %m", unit); - r = manager_load_startable_unit_or_warn(m, NULL, prepared, &u); + r = manager_load_startable_unit_or_warn(m, /* name= */ NULL, prepared, LOG_ERR, &u); if (r < 0) return r; } else { diff --git a/src/analyze/analyze-security.c b/src/analyze/analyze-security.c index 6901956b8d1..fbef7e3d2e8 100644 --- a/src/analyze/analyze-security.c +++ b/src/analyze/analyze-security.c @@ -2792,7 +2792,7 @@ static int offline_security_checks( return log_error_errno(r, "Failed to copy: %m"); } - k = manager_load_startable_unit_or_warn(m, NULL, prepared, &units[count]); + k = manager_load_startable_unit_or_warn(m, /* name= */ NULL, prepared, LOG_ERR, &units[count]); if (k < 0) { RET_GATHER(r, k); continue; diff --git a/src/analyze/analyze-verify-util.c b/src/analyze/analyze-verify-util.c index ad553078d48..e2adf760a64 100644 --- a/src/analyze/analyze-verify-util.c +++ b/src/analyze/analyze-verify-util.c @@ -335,7 +335,7 @@ int verify_units( continue; } - k = manager_load_startable_unit_or_warn(m, NULL, prepared, &units[count]); + k = manager_load_startable_unit_or_warn(m, /* name= */ NULL, prepared, LOG_ERR, &units[count]); if (k < 0) { RET_GATHER(r, k); continue; diff --git a/src/core/main.c b/src/core/main.c index 3dd227f2443..b967a572649 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -2765,9 +2765,12 @@ static int do_queue_default_job( else unit = SPECIAL_DEFAULT_TARGET; - log_debug("Activating default unit: %s", unit); + /* When no unit was explicitly requested, failures to load the default unit are not fatal, + * since we fall back to other targets below. Log them at a lower level in that case. */ + int log_level = arg_default_unit ? LOG_ERR : LOG_INFO; - r = manager_load_startable_unit_or_warn(m, unit, NULL, &target); + log_debug("Activating default unit: %s", unit); + r = manager_load_startable_unit_or_warn(m, unit, /* path= */ NULL, log_level, &target); if (r == -ENOENT && !arg_default_unit) { if (in_initrd()) /* Fall back to default.target, which we used to always use by default. @@ -2780,13 +2783,13 @@ static int do_queue_default_job( unit = FALLBACK_DEFAULT_TARGET; log_info("Falling back to %s.", unit); - r = manager_load_startable_unit_or_warn(m, unit, NULL, &target); + r = manager_load_startable_unit_or_warn(m, unit, /* path= */ NULL, log_level, &target); } if (r < 0) { /* We failed. Activate rescue mode. */ log_info("Falling back to %s.", SPECIAL_RESCUE_TARGET); - r = manager_load_startable_unit_or_warn(m, SPECIAL_RESCUE_TARGET, NULL, &target); + r = manager_load_startable_unit_or_warn(m, SPECIAL_RESCUE_TARGET, /* path= */ NULL, log_level, &target); if (r < 0) { *ret_error_message = r == -ERFKILL ? SPECIAL_RESCUE_TARGET " masked" : "Failed to load " SPECIAL_RESCUE_TARGET; diff --git a/src/core/manager.c b/src/core/manager.c index 7fe2fe0a014..baaac37482a 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -2788,6 +2788,7 @@ int manager_load_startable_unit_or_warn( Manager *m, const char *name, const char *path, + int log_level, Unit **ret) { /* Load a unit, make sure it loaded fully and is not masked. */ @@ -2800,13 +2801,13 @@ int manager_load_startable_unit_or_warn( r = manager_load_unit(m, name, path, &error, &unit); if (r < 0) - return log_error_errno(r, "Failed to load %s %s: %s", - name ? "unit" : "unit file", name ?: path, - bus_error_message(&error, r)); + return log_full_errno(log_level, r, "Failed to load %s %s: %s", + name ? "unit" : "unit file", name ?: path, + bus_error_message(&error, r)); r = bus_unit_validate_load_state(unit, &error); if (r < 0) - return log_error_errno(r, "%s", bus_error_message(&error, r)); + return log_full_errno(log_level, r, "%s", bus_error_message(&error, r)); *ret = unit; return 0; diff --git a/src/core/manager.h b/src/core/manager.h index 0a0974bf1cc..ab5187cde4c 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -592,7 +592,7 @@ bool manager_unit_cache_should_retry_load(Unit *u); int manager_load_unit_prepare(Manager *m, const char *name, const char *path, sd_bus_error *e, Unit **ret); int manager_load_unit(Manager *m, const char *name, const char *path, sd_bus_error *e, Unit **ret); int manager_dispatch_external_fd_to_unit(Manager *m, const char *unit_id, const char *fdname, uint64_t index, int fd, const char *log_context); -int manager_load_startable_unit_or_warn(Manager *m, const char *name, const char *path, Unit **ret); +int manager_load_startable_unit_or_warn(Manager *m, const char *name, const char *path, int log_level, Unit **ret); int manager_load_unit_from_dbus_path(Manager *m, const char *s, sd_bus_error *e, Unit **_u); int manager_add_jobs( diff --git a/src/test/test-cgroup-mask.c b/src/test/test-cgroup-mask.c index 96734150805..adc2f4747f2 100644 --- a/src/test/test-cgroup-mask.c +++ b/src/test/test-cgroup-mask.c @@ -54,13 +54,13 @@ TEST_RET(cgroup_mask, .sd_booted = true) { assert_se(manager_startup(m, NULL, NULL, NULL, NULL) >= 0); /* Load units and verify hierarchy. */ - ASSERT_OK(manager_load_startable_unit_or_warn(m, "parent.slice", NULL, &parent)); - ASSERT_OK(manager_load_startable_unit_or_warn(m, "son.service", NULL, &son)); - ASSERT_OK(manager_load_startable_unit_or_warn(m, "daughter.service", NULL, &daughter)); - ASSERT_OK(manager_load_startable_unit_or_warn(m, "grandchild.service", NULL, &grandchild)); - ASSERT_OK(manager_load_startable_unit_or_warn(m, "parent-deep.slice", NULL, &parent_deep)); - ASSERT_OK(manager_load_startable_unit_or_warn(m, "nomem.slice", NULL, &nomem_parent)); - ASSERT_OK(manager_load_startable_unit_or_warn(m, "nomemleaf.service", NULL, &nomem_leaf)); + ASSERT_OK(manager_load_startable_unit_or_warn(m, "parent.slice", NULL, LOG_ERR, &parent)); + ASSERT_OK(manager_load_startable_unit_or_warn(m, "son.service", NULL, LOG_ERR, &son)); + ASSERT_OK(manager_load_startable_unit_or_warn(m, "daughter.service", NULL, LOG_ERR, &daughter)); + ASSERT_OK(manager_load_startable_unit_or_warn(m, "grandchild.service", NULL, LOG_ERR, &grandchild)); + ASSERT_OK(manager_load_startable_unit_or_warn(m, "parent-deep.slice", NULL, LOG_ERR, &parent_deep)); + ASSERT_OK(manager_load_startable_unit_or_warn(m, "nomem.slice", NULL, LOG_ERR, &nomem_parent)); + ASSERT_OK(manager_load_startable_unit_or_warn(m, "nomemleaf.service", NULL, LOG_ERR, &nomem_leaf)); assert_se(UNIT_GET_SLICE(son) == parent); assert_se(UNIT_GET_SLICE(daughter) == parent); assert_se(UNIT_GET_SLICE(parent_deep) == parent); diff --git a/src/test/test-engine.c b/src/test/test-engine.c index 5a6a1a42044..abe04182be7 100644 --- a/src/test/test-engine.c +++ b/src/test/test-engine.c @@ -100,9 +100,9 @@ int main(int argc, char *argv[]) { assert_se(manager_startup(m, NULL, NULL, NULL, NULL) >= 0); printf("Load1:\n"); - assert_se(manager_load_startable_unit_or_warn(m, "a.service", NULL, &a) >= 0); - assert_se(manager_load_startable_unit_or_warn(m, "b.service", NULL, &b) >= 0); - assert_se(manager_load_startable_unit_or_warn(m, "c.service", NULL, &c) >= 0); + assert_se(manager_load_startable_unit_or_warn(m, "a.service", NULL, LOG_ERR, &a) >= 0); + assert_se(manager_load_startable_unit_or_warn(m, "b.service", NULL, LOG_ERR, &b) >= 0); + assert_se(manager_load_startable_unit_or_warn(m, "c.service", NULL, LOG_ERR, &c) >= 0); manager_dump_units(m, stdout, /* patterns= */ NULL, "\t"); printf("Test1: (Trivial)\n"); @@ -114,8 +114,8 @@ int main(int argc, char *argv[]) { printf("Load2:\n"); manager_clear_jobs(m); - assert_se(manager_load_startable_unit_or_warn(m, "d.service", NULL, &d) >= 0); - assert_se(manager_load_startable_unit_or_warn(m, "e.service", NULL, &e) >= 0); + assert_se(manager_load_startable_unit_or_warn(m, "d.service", NULL, LOG_ERR, &d) >= 0); + assert_se(manager_load_startable_unit_or_warn(m, "e.service", NULL, LOG_ERR, &e) >= 0); manager_dump_units(m, stdout, /* patterns= */ NULL, "\t"); printf("Test2: (Cyclic Order, Unfixable)\n"); @@ -131,7 +131,7 @@ int main(int argc, char *argv[]) { manager_dump_jobs(m, stdout, /* patterns= */ NULL, "\t"); printf("Load3:\n"); - assert_se(manager_load_startable_unit_or_warn(m, "g.service", NULL, &g) >= 0); + assert_se(manager_load_startable_unit_or_warn(m, "g.service", NULL, LOG_ERR, &g) >= 0); manager_dump_units(m, stdout, /* patterns= */ NULL, "\t"); printf("Test5: (Colliding transaction, fail)\n"); @@ -153,7 +153,7 @@ int main(int argc, char *argv[]) { manager_dump_jobs(m, stdout, /* patterns= */ NULL, "\t"); printf("Load4:\n"); - assert_se(manager_load_startable_unit_or_warn(m, "h.service", NULL, &h) >= 0); + assert_se(manager_load_startable_unit_or_warn(m, "h.service", NULL, LOG_ERR, &h) >= 0); manager_dump_units(m, stdout, /* patterns= */ NULL, "\t"); printf("Test10: (Unmergeable job type of auxiliary job, fail)\n"); @@ -162,7 +162,7 @@ int main(int argc, char *argv[]) { printf("Load5:\n"); manager_clear_jobs(m); - assert_se(manager_load_startable_unit_or_warn(m, "i.service", NULL, &i) >= 0); + assert_se(manager_load_startable_unit_or_warn(m, "i.service", NULL, LOG_ERR, &i) >= 0); SERVICE(a)->state = SERVICE_RUNNING; SERVICE(d)->state = SERVICE_RUNNING; manager_dump_units(m, stdout, /* patterns= */ NULL, "\t"); @@ -176,7 +176,7 @@ int main(int argc, char *argv[]) { printf("Load6:\n"); manager_clear_jobs(m); - assert_se(manager_load_startable_unit_or_warn(m, "a-conj.service", NULL, &a_conj) >= 0); + assert_se(manager_load_startable_unit_or_warn(m, "a-conj.service", NULL, LOG_ERR, &a_conj) >= 0); SERVICE(a)->state = SERVICE_DEAD; manager_dump_units(m, stdout, /* patterns= */ NULL, "\t"); diff --git a/src/test/test-execute.c b/src/test/test-execute.c index 1a832ad2f71..8206452f4ce 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -304,7 +304,7 @@ static void _test(const char *file, unsigned line, const char *func, ASSERT_NOT_NULL(unit_name); - ASSERT_OK(manager_load_startable_unit_or_warn(m, unit_name, NULL, &unit)); + ASSERT_OK(manager_load_startable_unit_or_warn(m, unit_name, NULL, LOG_ERR, &unit)); /* We need to start the slices as well otherwise the slice cgroups might be pruned * in on_cgroup_empty_event. */ start_parent_slices(unit); @@ -322,7 +322,7 @@ static void _test_service(const char *file, unsigned line, const char *func, ASSERT_NOT_NULL(unit_name); - ASSERT_OK(manager_load_startable_unit_or_warn(m, unit_name, NULL, &unit)); + ASSERT_OK(manager_load_startable_unit_or_warn(m, unit_name, NULL, LOG_ERR, &unit)); ASSERT_OK(unit_start(unit, NULL)); check_service_result(file, line, func, m, unit, result_expected); } diff --git a/src/test/test-path.c b/src/test/test-path.c index ff1dee84745..3a4aa64c2fa 100644 --- a/src/test/test-path.c +++ b/src/test/test-path.c @@ -150,7 +150,7 @@ TEST_RET(path_exists) { return r; Unit *unit; - ASSERT_OK(manager_load_startable_unit_or_warn(m, "path-exists.path", NULL, &unit)); + ASSERT_OK(manager_load_startable_unit_or_warn(m, "path-exists.path", NULL, LOG_ERR, &unit)); Path *path = PATH(unit); Service *service = service_for_path(m, path, NULL); @@ -183,7 +183,7 @@ TEST_RET(path_existsglob) { return r; Unit *unit; - ASSERT_OK(manager_load_startable_unit_or_warn(m, "path-existsglob.path", NULL, &unit)); + ASSERT_OK(manager_load_startable_unit_or_warn(m, "path-existsglob.path", NULL, LOG_ERR, &unit)); Path *path = PATH(unit); Service *service = service_for_path(m, path, NULL); @@ -216,7 +216,7 @@ TEST_RET(path_changed) { return r; Unit *unit; - ASSERT_OK(manager_load_startable_unit_or_warn(m, "path-changed.path", NULL, &unit)); + ASSERT_OK(manager_load_startable_unit_or_warn(m, "path-changed.path", NULL, LOG_ERR, &unit)); Path *path = PATH(unit); Service *service = service_for_path(m, path, NULL); @@ -253,7 +253,7 @@ TEST_RET(path_modified) { return r; Unit *unit; - ASSERT_OK(manager_load_startable_unit_or_warn(m, "path-modified.path", NULL, &unit)); + ASSERT_OK(manager_load_startable_unit_or_warn(m, "path-modified.path", NULL, LOG_ERR, &unit)); Path *path = PATH(unit); Service *service = service_for_path(m, path, NULL); @@ -291,7 +291,7 @@ TEST_RET(path_unit) { return r; Unit *unit; - ASSERT_OK(manager_load_startable_unit_or_warn(m, "path-unit.path", NULL, &unit)); + ASSERT_OK(manager_load_startable_unit_or_warn(m, "path-unit.path", NULL, LOG_ERR, &unit)); Path *path = PATH(unit); Service *service = service_for_path(m, path, "path-mycustomunit.service"); @@ -320,7 +320,7 @@ TEST_RET(path_directorynotempty) { return r; Unit *unit; - ASSERT_OK(manager_load_startable_unit_or_warn(m, "path-directorynotempty.path", NULL, &unit)); + ASSERT_OK(manager_load_startable_unit_or_warn(m, "path-directorynotempty.path", NULL, LOG_ERR, &unit)); Path *path = PATH(unit); Service *service = service_for_path(m, path, NULL); @@ -360,7 +360,7 @@ TEST_RET(path_makedirectory_directorymode) { return r; Unit *unit; - ASSERT_OK(manager_load_startable_unit_or_warn(m, "path-makedirectory.path", NULL, &unit)); + ASSERT_OK(manager_load_startable_unit_or_warn(m, "path-makedirectory.path", NULL, LOG_ERR, &unit)); ASSERT_FAIL(access(test_path, F_OK)); diff --git a/src/test/test-sched-prio.c b/src/test/test-sched-prio.c index a523c01e8f0..83204eb0d99 100644 --- a/src/test/test-sched-prio.c +++ b/src/test/test-sched-prio.c @@ -36,7 +36,7 @@ int main(int argc, char *argv[]) { assert_se(manager_startup(m, NULL, NULL, NULL, NULL) >= 0); /* load idle ok */ - assert_se(manager_load_startable_unit_or_warn(m, "sched_idle_ok.service", NULL, &idle_ok) >= 0); + assert_se(manager_load_startable_unit_or_warn(m, "sched_idle_ok.service", NULL, LOG_ERR, &idle_ok) >= 0); ser = SERVICE(idle_ok); assert_se(ser->exec_context.cpu_sched_policy == SCHED_OTHER); assert_se(ser->exec_context.cpu_sched_priority == 0); @@ -44,7 +44,7 @@ int main(int argc, char *argv[]) { /* * load idle bad. This should print a warning but we have no way to look at it. */ - assert_se(manager_load_startable_unit_or_warn(m, "sched_idle_bad.service", NULL, &idle_bad) >= 0); + assert_se(manager_load_startable_unit_or_warn(m, "sched_idle_bad.service", NULL, LOG_ERR, &idle_bad) >= 0); ser = SERVICE(idle_ok); assert_se(ser->exec_context.cpu_sched_policy == SCHED_OTHER); assert_se(ser->exec_context.cpu_sched_priority == 0); @@ -53,7 +53,7 @@ int main(int argc, char *argv[]) { * load rr ok. * Test that the default priority is moving from 0 to 1. */ - assert_se(manager_load_startable_unit_or_warn(m, "sched_rr_ok.service", NULL, &rr_ok) >= 0); + assert_se(manager_load_startable_unit_or_warn(m, "sched_rr_ok.service", NULL, LOG_ERR, &rr_ok) >= 0); ser = SERVICE(rr_ok); assert_se(ser->exec_context.cpu_sched_policy == SCHED_RR); assert_se(ser->exec_context.cpu_sched_priority == 1); @@ -62,7 +62,7 @@ int main(int argc, char *argv[]) { * load rr bad. * Test that the value of 0 and 100 is ignored. */ - assert_se(manager_load_startable_unit_or_warn(m, "sched_rr_bad.service", NULL, &rr_bad) >= 0); + assert_se(manager_load_startable_unit_or_warn(m, "sched_rr_bad.service", NULL, LOG_ERR, &rr_bad) >= 0); ser = SERVICE(rr_bad); assert_se(ser->exec_context.cpu_sched_policy == SCHED_RR); assert_se(ser->exec_context.cpu_sched_priority == 1); @@ -71,13 +71,13 @@ int main(int argc, char *argv[]) { * load rr change. * Test that anything between 1 and 99 can be set. */ - assert_se(manager_load_startable_unit_or_warn(m, "sched_rr_change.service", NULL, &rr_sched) >= 0); + assert_se(manager_load_startable_unit_or_warn(m, "sched_rr_change.service", NULL, LOG_ERR, &rr_sched) >= 0); ser = SERVICE(rr_sched); assert_se(ser->exec_context.cpu_sched_policy == SCHED_RR); assert_se(ser->exec_context.cpu_sched_priority == 99); /* load ext ok */ - assert_se(manager_load_startable_unit_or_warn(m, "sched_ext_ok.service", NULL, &ext_ok) >= 0); + assert_se(manager_load_startable_unit_or_warn(m, "sched_ext_ok.service", NULL, LOG_ERR, &ext_ok) >= 0); ser = SERVICE(ext_ok); assert_se(ser->exec_context.cpu_sched_policy == SCHED_EXT); assert_se(ser->exec_context.cpu_sched_priority == 0);