chiark / gitweb /
util: close all fds before freezing execution
[elogind.git] / src / unit.c
index 1ca8e82af736b558f8bc753a6699b4f79a09d280..117af4df4477700d06c4a88c2732a5236d4c6e67 100644 (file)
@@ -736,12 +736,18 @@ int unit_add_default_target_dependency(Unit *u, Unit *target) {
         if (target->meta.type != UNIT_TARGET)
                 return 0;
 
-        /* Only add the dependency if boths units are loaded, so that
+        /* Only add the dependency if both units are loaded, so that
          * that loop check below is reliable */
         if (u->meta.load_state != UNIT_LOADED ||
             target->meta.load_state != UNIT_LOADED)
                 return 0;
 
+        /* If either side wants no automatic dependencies, then let's
+         * skip this */
+        if (!u->meta.default_dependencies ||
+            target->meta.default_dependencies)
+                return 0;
+
         /* Don't create loops */
         if (set_get(target->meta.dependencies[UNIT_BEFORE], u))
                 return 0;
@@ -750,27 +756,24 @@ int unit_add_default_target_dependency(Unit *u, Unit *target) {
 }
 
 static int unit_add_default_dependencies(Unit *u) {
+        static const UnitDependency deps[] = {
+                UNIT_REQUIRED_BY,
+                UNIT_REQUIRED_BY_OVERRIDABLE,
+                UNIT_WANTED_BY,
+                UNIT_BOUND_BY
+        };
+
         Unit *target;
         Iterator i;
         int r;
+        unsigned k;
 
         assert(u);
 
-        SET_FOREACH(target, u->meta.dependencies[UNIT_REQUIRED_BY], i)
-                if ((r = unit_add_default_target_dependency(u, target)) < 0)
-                        return r;
-
-        SET_FOREACH(target, u->meta.dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
-                if ((r = unit_add_default_target_dependency(u, target)) < 0)
-                        return r;
-
-        SET_FOREACH(target, u->meta.dependencies[UNIT_WANTED_BY], i)
-                if ((r = unit_add_default_target_dependency(u, target)) < 0)
-                        return r;
-
-        SET_FOREACH(target, u->meta.dependencies[UNIT_BOUND_BY], i)
-                if ((r = unit_add_default_target_dependency(u, target)) < 0)
-                        return r;
+        for (k = 0; k < ELEMENTSOF(deps); k++)
+                SET_FOREACH(target, u->meta.dependencies[deps[k]], i)
+                        if ((r = unit_add_default_target_dependency(u, target)) < 0)
+                                return r;
 
         return 0;
 }
@@ -822,6 +825,15 @@ fail:
         return r;
 }
 
+bool unit_condition_test(Unit *u) {
+        assert(u);
+
+        dual_timestamp_get(&u->meta.condition_timestamp);
+        u->meta.condition_result = condition_test_list(u->meta.conditions);
+
+        return u->meta.condition_result;
+}
+
 /* Errors:
  *         -EBADR:     This unit type does not support starting.
  *         -EALREADY:  Unit is already started.
@@ -846,7 +858,7 @@ int unit_start(Unit *u) {
                 return -EALREADY;
 
         /* If the conditions failed, don't do anything at all */
-        if (!condition_test_list(u->meta.conditions)) {
+        if (!unit_condition_test(u)) {
                 log_debug("Starting of %s requested but condition failed. Ignoring.", u->meta.id);
                 return -EALREADY;
         }
@@ -1071,6 +1083,16 @@ static void retroactively_stop_dependencies(Unit *u) {
                         unit_check_unneeded(other);
 }
 
+void unit_trigger_on_failure(Unit *u) {
+        Unit *other;
+        Iterator i;
+
+        assert(u);
+
+        SET_FOREACH(other, u->meta.dependencies[UNIT_ON_FAILURE], i)
+                manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
+}
+
 void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) {
         dual_timestamp ts;
         bool unexpected;
@@ -1114,7 +1136,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
                         job_add_to_run_queue(u->meta.job);
 
                 /* Let's check whether this state change constitutes a
-                 * finished job, or maybe cotradicts a running job and
+                 * finished job, or maybe contradicts a running job and
                  * hence needs to invalidate jobs. */
 
                 switch (u->meta.job->type) {
@@ -1183,13 +1205,8 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
         }
 
         if (ns != os && ns == UNIT_FAILED) {
-                Iterator i;
-                Unit *other;
-
-                SET_FOREACH(other, u->meta.dependencies[UNIT_ON_FAILURE], i)
-                        manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
-
                 log_notice("Unit %s entered failed state.", u->meta.id);
+                unit_trigger_on_failure(u);
         }
 
         /* Some names are special */