]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/job.c
Merge pull request #11827 from keszybz/pkgconfig-variables
[thirdparty/systemd.git] / src / core / job.c
index cc55bd01b8ee2879395db80e638318ccf62596d9..b2aa0c600fded6610aca1e859b7f95de1557e864 100644 (file)
@@ -151,6 +151,8 @@ void job_uninstall(Job *j) {
 
         unit_add_to_gc_queue(j->unit);
 
+        unit_add_to_dbus_queue(j->unit); /* The Job property of the unit has changed now */
+
         hashmap_remove_value(j->manager->jobs, UINT32_TO_PTR(j->id), j);
         j->installed = false;
 }
@@ -1025,6 +1027,31 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool alr
                         job_fail_dependencies(u, UNIT_CONFLICTED_BY);
         }
 
+        /* A special check to make sure we take down anything RequisiteOf if we
+         * aren't active. This is when the verify-active job merges with a
+         * satisfying job type, and then loses it's invalidation effect, as the
+         * result there is JOB_DONE for the start job we merged into, while we
+         * should be failing the depending job if the said unit isn't infact
+         * active. Oneshots are an example of this, where going directly from
+         * activating to inactive is success.
+         *
+         * This happens when you use ConditionXYZ= in a unit too, since in that
+         * case the job completes with the JOB_DONE result, but the unit never
+         * really becomes active. Note that such a case still involves merging:
+         *
+         * A start job waits for something else, and a verify-active comes in
+         * and merges in the installed job. Then, later, when it becomes
+         * runnable, it finishes with JOB_DONE result as execution on conditions
+         * not being met is skipped, breaking our dependency semantics.
+         *
+         * Also, depending on if start job waits or not, the merging may or may
+         * not happen (the verify-active job may trigger after it finishes), so
+         * you get undeterministic results without this check.
+         */
+        if (result == JOB_DONE && recursive && !UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) {
+                if (IN_SET(t, JOB_START, JOB_RELOAD))
+                        job_fail_dependencies(u, UNIT_REQUISITE_OF);
+        }
         /* Trigger OnFailure dependencies that are not generated by
          * the unit itself. We don't treat JOB_CANCELED as failure in
          * this context. And JOB_FAILURE is already handled by the