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.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2026-07-02 17:19:18 +02:00
parent a0146fe807
commit 7bff0f09fe
11 changed files with 47 additions and 43 deletions
+1 -1
View File
@@ -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 {
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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;
+7 -4
View File
@@ -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;
+5 -4
View File
@@ -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;
+1 -1
View File
@@ -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(
+7 -7
View File
@@ -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);
+9 -9
View File
@@ -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");
+2 -2
View File
@@ -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);
}
+7 -7
View File
@@ -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));
+6 -6
View File
@@ -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);