]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core/transaction: do not override unit load state when unit_load() failed
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 20 May 2025 19:38:07 +0000 (04:38 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 28 May 2025 20:37:34 +0000 (05:37 +0900)
When unit_load() failed for some reasons, previously we overrided the
load state with UNIT_NOT_FOUND, but we did not update the
Unit.fragment_not_found_timestamp_hash. So, the unit may be loaded
multiple times when the unit is in a dependency list of another unit,
as manager_unit_cache_should_retry_load() will be true again even on
next call.
Let's not override the unit state set by unit_load().

Note, after unit_load(), the unit state should not be UNIT_STUB.
Let's also add the assertion about that.

This change is important when combined with the next commit, as with the
next commit we will restart the FOREACH_UNIT_DEPENDENCY() loop if an unit
is reloaded, hence overriding load state with UNIT_NOT_FOUND may cause
infinit loop.

src/core/transaction.c

index 14efecdd2266b855c87d1685fd4d4a2977e409bd..503547cd4ae4ef62e9f9b4c96b8099eb7a18214c 100644 (file)
@@ -973,9 +973,9 @@ int transaction_add_job_and_dependencies(
                 if (manager_unit_cache_should_retry_load(unit)) {
                         assert(unit->load_state == UNIT_NOT_FOUND);
                         unit->load_state = UNIT_STUB;
-                        r = unit_load(unit);
-                        if (r < 0 || unit->load_state == UNIT_STUB)
-                                unit->load_state = UNIT_NOT_FOUND;
+                        unit->load_error = 0;
+                        (void) unit_load(unit);
+                        assert(unit->load_state != UNIT_STUB);
                 }
 
                 r = bus_unit_validate_load_state(unit, e);