]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: let manager_load_startable_unit_or_warn take a log level
authorZbigniew Jędrzejewski-Szmek <zbyszek@amutable.com>
Tue, 23 Jun 2026 10:00:40 +0000 (12:00 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@amutable.com>
Thu, 2 Jul 2026 15:19:18 +0000 (17:19 +0200)
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.

src/analyze/analyze-condition.c
src/analyze/analyze-security.c
src/analyze/analyze-verify-util.c
src/core/main.c
src/core/manager.c
src/core/manager.h
src/test/test-cgroup-mask.c
src/test/test-engine.c
src/test/test-execute.c
src/test/test-path.c
src/test/test-sched-prio.c

index 5c5177c3bea6a0f9416815a046692cd9dc948b0b..8704e0a6e365eab6f8b8be5cbcd125ed08bd8c9e 100644 (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 {
index 6901956b8d18db5952692e6863caef381f8417da..fbef7e3d2e8aa021c5a0381debe1506495c09c55 100644 (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;
index ad553078d4833878db993e88b12b6899b58481cc..e2adf760a64bfce01d4c7976f67bcc9eb4782d3e 100644 (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;
index 3dd227f24439e2db10258749d6d2e617e3eba818..b967a57264984ac15681a3986658a189f4cf823e 100644 (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;
index 7fe2fe0a014f70cb6edfd3ce9320ec574ad84a89..baaac37482af68c5a7462f92bc48d9a4104c863e 100644 (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;
index 0a0974bf1cc591e83cc48eb7ccea2afbbd0d2c87..ab5187cde4cc53a72b6af8df8a188b3f23ab5fc0 100644 (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(
index 967341508053efd9ea9834a360a4d663d747d1aa..adc2f4747f2e8ac74d19219be7cc6555d834d306 100644 (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);
index 5a6a1a42044060deaddcdbe3a20e4b0e73620dad..abe04182be7fcaf1a75c9b65e487e8430d68e5d9 100644 (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");
 
index 1a832ad2f711f66c56f590f075e6e723a4a97488..8206452f4cefa58a04cc85d91ccd740897b575a7 100644 (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);
 }
index ff1dee8474515fb0f9078ca6d38e5989b6891d6d..3a4aa64c2fa829fddbd6100d00e69d74fb2194d7 100644 (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));
 
index a523c01e8f01b1f174bbdadf4c79affd5fdcc458..83204eb0d995efa428dc1e6b049b99c00ca18c7a 100644 (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);