]> 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)
committerLuca Boccassi <luca.boccassi@gmail.com>
Wed, 25 Jun 2025 17:17:42 +0000 (18:17 +0100)
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.

(cherry picked from commit 9b6aa9e443859f1eb69cfe37ca755ac4db31c475)
(cherry picked from commit 0e5fc0a29c4a98f781d4d4911b5f589f31c9f10e)

src/core/transaction.c

index f541054d7232c5a9b6f9d50310b945c3a4a380e6..349dda81f079a8c0be84a32221f581a2dafe540b 100644 (file)
@@ -976,9 +976,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);