chiark / gitweb /
manager: always pull 'following' units into transaction
[elogind.git] / src / unit.c
index 410ff9f6071c8faca98a0219fbb5a991d0eba58e..b3a8210a577ac897af818982ce11a7fd6df66fb1 100644 (file)
@@ -826,6 +826,7 @@ fail:
  */
 int unit_start(Unit *u) {
         UnitActiveState state;
+        Unit *following;
 
         assert(u);
 
@@ -840,16 +841,22 @@ int unit_start(Unit *u) {
         if (UNIT_IS_ACTIVE_OR_RELOADING(state))
                 return -EALREADY;
 
-        /* If it is stopped, but we cannot start it, then fail */
-        if (!UNIT_VTABLE(u)->start)
-                return -EBADR;
-
         /* If the conditions failed, don't do anything at all */
         if (!condition_test_list(u->meta.conditions)) {
                 log_debug("Starting of %s requested but condition failed. Ignoring.", u->meta.id);
                 return -EALREADY;
         }
 
+        /* Forward to the main object, if we aren't it. */
+        if ((following = unit_following(u))) {
+                log_debug("Redirecting start request from %s to %s.", u->meta.id, following->meta.id);
+                return unit_start(following);
+        }
+
+        /* If it is stopped, but we cannot start it, then fail */
+        if (!UNIT_VTABLE(u)->start)
+                return -EBADR;
+
         /* We don't suppress calls to ->start() here when we are
          * already starting, to allow this request to be used as a
          * "hurry up" call, for example when the unit is in some "auto
@@ -859,7 +866,6 @@ int unit_start(Unit *u) {
         unit_add_to_dbus_queue(u);
 
         unit_status_printf(u, "Starting %s...\n", unit_description(u));
-
         return UNIT_VTABLE(u)->start(u);
 }
 
@@ -883,6 +889,7 @@ bool unit_can_isolate(Unit *u) {
  */
 int unit_stop(Unit *u) {
         UnitActiveState state;
+        Unit *following;
 
         assert(u);
 
@@ -890,13 +897,17 @@ int unit_stop(Unit *u) {
         if (UNIT_IS_INACTIVE_OR_FAILED(state))
                 return -EALREADY;
 
+        if ((following = unit_following(u))) {
+                log_debug("Redirecting stop request from %s to %s.", u->meta.id, following->meta.id);
+                return unit_stop(following);
+        }
+
         if (!UNIT_VTABLE(u)->stop)
                 return -EBADR;
 
         unit_add_to_dbus_queue(u);
 
         unit_status_printf(u, "Stopping %s...\n", unit_description(u));
-
         return UNIT_VTABLE(u)->stop(u);
 }
 
@@ -907,6 +918,7 @@ int unit_stop(Unit *u) {
  */
 int unit_reload(Unit *u) {
         UnitActiveState state;
+        Unit *following;
 
         assert(u);
 
@@ -923,6 +935,11 @@ int unit_reload(Unit *u) {
         if (state != UNIT_ACTIVE)
                 return -ENOEXEC;
 
+        if ((following = unit_following(u))) {
+                log_debug("Redirecting reload request from %s to %s.", u->meta.id, following->meta.id);
+                return unit_reload(following);
+        }
+
         unit_add_to_dbus_queue(u);
         return UNIT_VTABLE(u)->reload(u);
 }
@@ -1386,9 +1403,9 @@ bool unit_job_is_applicable(Unit *u, JobType j) {
 
         case JOB_VERIFY_ACTIVE:
         case JOB_START:
+        case JOB_STOP:
                 return true;
 
-        case JOB_STOP:
         case JOB_RESTART:
         case JOB_TRY_RESTART:
                 return unit_can_start(u);
@@ -2302,6 +2319,18 @@ int unit_kill(Unit *u, KillWho w, KillMode m, int signo, DBusError *error) {
         return UNIT_VTABLE(u)->kill(u, w, m, signo, error);
 }
 
+
+int unit_following_set(Unit *u, Set **s) {
+        assert(u);
+        assert(s);
+
+        if (UNIT_VTABLE(u)->following_set)
+                return UNIT_VTABLE(u)->following_set(u, s);
+
+        *s = NULL;
+        return 0;
+}
+
 static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = {
         [UNIT_STUB] = "stub",
         [UNIT_LOADED] = "loaded",