chiark / gitweb /
unit: add new abstracted maintenance state for units
authorLennart Poettering <lennart@poettering.net>
Wed, 30 Jun 2010 22:31:53 +0000 (00:31 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 30 Jun 2010 22:31:53 +0000 (00:31 +0200)
12 files changed:
fixme
src/automount.c
src/job.c
src/manager.c
src/mount.c
src/path.c
src/service.c
src/socket.c
src/swap.c
src/timer.c
src/unit.c
src/unit.h

diff --git a/fixme b/fixme
index 3ca6a02e006b36ea719d7c2fc7655cb4dcf90f8b..09aba7de0da1619a90860da4f66f4b87afac6f6d 100644 (file)
--- a/fixme
+++ b/fixme
@@ -10,8 +10,6 @@
 
 * "disabled" load state?
 
-* gc: don't reap broken services
-
 * ability to kill services? i.e. in contrast to stopping them, go directly
   into killing mode?
 
 
 * selinux
 
-External:
+* systemctl check
+
+* nettere fehlermeldung bei systemctl start foo.service failure
+
+* systemd-install disable sollte den service runterfahren
 
-* systemd-sysvinit as package
+* systemctl daemon-reload is kaputt
+
+* keinerlei fehlermeldung bei dead symlink muss gefixt werden
+
+External:
 
 * patch /etc/init.d/functions with:
 
index 75c10538b7dd4bcc55f26902d6cbd8f9d45de0ef..84f2d97edae77e8cbb4830674c07929b051ffadb 100644 (file)
@@ -40,7 +40,7 @@ static const UnitActiveState state_translation_table[_AUTOMOUNT_STATE_MAX] = {
         [AUTOMOUNT_DEAD] = UNIT_INACTIVE,
         [AUTOMOUNT_WAITING] = UNIT_ACTIVE,
         [AUTOMOUNT_RUNNING] = UNIT_ACTIVE,
-        [AUTOMOUNT_MAINTENANCE] = UNIT_INACTIVE,
+        [AUTOMOUNT_MAINTENANCE] = UNIT_INACTIVE_MAINTENANCE
 };
 
 static int open_dev_autofs(Manager *m);
index 78fe136328500a4ab29af7c438966112a394d8da..8273a39c350c609f280baf49a57a4dd1d92d2171 100644 (file)
--- a/src/job.c
+++ b/src/job.c
@@ -279,7 +279,8 @@ bool job_type_is_redundant(JobType a, UnitActiveState b) {
 
         case JOB_STOP:
                 return
-                        b == UNIT_INACTIVE;
+                        b == UNIT_INACTIVE ||
+                        b == UNIT_INACTIVE_MAINTENANCE;
 
         case JOB_VERIFY_ACTIVE:
                 return
@@ -415,7 +416,7 @@ int job_run_and_invalidate(Job *j) {
 
                 case JOB_RESTART: {
                         UnitActiveState t = unit_active_state(j->unit);
-                        if (t == UNIT_INACTIVE || t == UNIT_ACTIVATING) {
+                        if (t == UNIT_INACTIVE || t == UNIT_INACTIVE_MAINTENANCE || t == UNIT_ACTIVATING) {
                                 j->type = JOB_START;
                                 r = unit_start(j->unit);
                         } else
@@ -425,7 +426,7 @@ int job_run_and_invalidate(Job *j) {
 
                 case JOB_TRY_RESTART: {
                         UnitActiveState t = unit_active_state(j->unit);
-                        if (t == UNIT_INACTIVE || t == UNIT_DEACTIVATING)
+                        if (t == UNIT_INACTIVE || t == UNIT_INACTIVE_MAINTENANCE || t == UNIT_DEACTIVATING)
                                 r = -ENOEXEC;
                         else if (t == UNIT_ACTIVATING) {
                                 j->type = JOB_START;
index b8daffd67b78164aa66255959920bb985391aa00..74a414aab11405b7a4e953686bebce3270066e95 100644 (file)
@@ -1343,7 +1343,7 @@ static int transaction_add_isolate_jobs(Manager *m) {
                         continue;
 
                 /* No need to stop inactive jobs */
-                if (unit_active_state(u) == UNIT_INACTIVE)
+                if (UNIT_IS_INACTIVE_OR_MAINTENANCE(unit_active_state(u)))
                         continue;
 
                 /* Is there already something listed for this? */
index 081e92c029a172b43cf0c65bb746cc935ae3147d..f0336163ace7ffa7f885f58553f2503b6d597938 100644 (file)
@@ -50,7 +50,7 @@ static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = {
         [MOUNT_REMOUNTING_SIGKILL] = UNIT_ACTIVE_RELOADING,
         [MOUNT_UNMOUNTING_SIGTERM] = UNIT_DEACTIVATING,
         [MOUNT_UNMOUNTING_SIGKILL] = UNIT_DEACTIVATING,
-        [MOUNT_MAINTENANCE] = UNIT_INACTIVE,
+        [MOUNT_MAINTENANCE] = UNIT_INACTIVE_MAINTENANCE
 };
 
 static void mount_init(Unit *u) {
index 24545bad35d395c8f6ff8ebdb9e3ef5675e9fc04..16ea08ddedca3445a3768587180310fe442905d3 100644 (file)
@@ -34,7 +34,7 @@ static const UnitActiveState state_translation_table[_PATH_STATE_MAX] = {
         [PATH_DEAD] = UNIT_INACTIVE,
         [PATH_WAITING] = UNIT_ACTIVE,
         [PATH_RUNNING] = UNIT_ACTIVE,
-        [PATH_MAINTENANCE] = UNIT_INACTIVE
+        [PATH_MAINTENANCE] = UNIT_INACTIVE_MAINTENANCE
 };
 
 static void path_done(Unit *u) {
index e1dab70f816eb2a9ccb8b67e4ad0e2455c1d8440..3102acc0860d3d4516d4fbb18086abc5ac1aad35 100644 (file)
@@ -83,8 +83,8 @@ static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = {
         [SERVICE_STOP_POST] = UNIT_DEACTIVATING,
         [SERVICE_FINAL_SIGTERM] = UNIT_DEACTIVATING,
         [SERVICE_FINAL_SIGKILL] = UNIT_DEACTIVATING,
-        [SERVICE_MAINTENANCE] = UNIT_INACTIVE,
-        [SERVICE_AUTO_RESTART] = UNIT_ACTIVATING,
+        [SERVICE_MAINTENANCE] = UNIT_INACTIVE_MAINTENANCE,
+        [SERVICE_AUTO_RESTART] = UNIT_ACTIVATING
 };
 
 static void service_init(Unit *u) {
index f20b78d1a611adca0aade1c1531b6b50bc2ba917..83f8ebe6ad3fa91d70271593f8ffbb242a5c4cde 100644 (file)
@@ -50,7 +50,7 @@ static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
         [SOCKET_STOP_POST] = UNIT_DEACTIVATING,
         [SOCKET_FINAL_SIGTERM] = UNIT_DEACTIVATING,
         [SOCKET_FINAL_SIGKILL] = UNIT_DEACTIVATING,
-        [SOCKET_MAINTENANCE] = UNIT_INACTIVE,
+        [SOCKET_MAINTENANCE] = UNIT_INACTIVE_MAINTENANCE
 };
 
 static void socket_init(Unit *u) {
index 663c568961b38519bf87c6b8c119da5c6296a37c..e2afcc02eb4933c6b639c7062807d619d6dd63dc 100644 (file)
@@ -38,7 +38,7 @@
 static const UnitActiveState state_translation_table[_SWAP_STATE_MAX] = {
         [SWAP_DEAD] = UNIT_INACTIVE,
         [SWAP_ACTIVE] = UNIT_ACTIVE,
-        [SWAP_MAINTENANCE] = UNIT_INACTIVE
+        [SWAP_MAINTENANCE] = UNIT_INACTIVE_MAINTENANCE
 };
 
 static void swap_init(Unit *u) {
index ead8ab92a4b0881de1120cfe78b93775f6e44e00..96c6e8e8ed3affd0bbb554de7c97938baf4966b3 100644 (file)
@@ -31,7 +31,7 @@ static const UnitActiveState state_translation_table[_TIMER_STATE_MAX] = {
         [TIMER_WAITING] = UNIT_ACTIVE,
         [TIMER_RUNNING] = UNIT_ACTIVE,
         [TIMER_ELAPSED] = UNIT_ACTIVE,
-        [TIMER_MAINTENANCE] = UNIT_INACTIVE
+        [TIMER_MAINTENANCE] = UNIT_INACTIVE_MAINTENANCE
 };
 
 static void timer_init(Unit *u) {
@@ -401,7 +401,7 @@ void timer_unit_notify(Unit *u, UnitActiveState new_state) {
 
                 case TIMER_RUNNING:
 
-                        if (new_state == UNIT_INACTIVE) {
+                        if (UNIT_IS_INACTIVE_OR_MAINTENANCE(new_state)) {
                                 log_debug("%s got notified about unit deactivation.", t->meta.id);
                                 timer_enter_waiting(t, false);
                         }
index 76e8cd74a0b5843788eb5f0067cbb6c040ae3a85..79b9e2bb8a0f8dc9563a6f6e42439e8bdb03a5fb 100644 (file)
@@ -365,8 +365,12 @@ void unit_free(Unit *u) {
 UnitActiveState unit_active_state(Unit *u) {
         assert(u);
 
-        if (u->meta.load_state != UNIT_LOADED)
-                return UNIT_INACTIVE;
+        if (u->meta.load_state == UNIT_MERGED)
+                return unit_active_state(unit_follow_merge(u));
+
+        /* After a reload it might happen that a unit is not correctly
+         * loaded but still has a process around. That's why we won't
+         * shortcut failed loading to UNIT_INACTIVE_MAINTENANCE. */
 
         return UNIT_VTABLE(u)->active_state(u);
 }
@@ -463,7 +467,7 @@ int unit_merge(Unit *u, Unit *other) {
         if (other->meta.job)
                 return -EEXIST;
 
-        if (unit_active_state(other) != UNIT_INACTIVE)
+        if (!UNIT_IS_INACTIVE_OR_MAINTENANCE(unit_active_state(other)))
                 return -EEXIST;
 
         /* Merge names */
@@ -746,6 +750,9 @@ int unit_start(Unit *u) {
 
         assert(u);
 
+        if (u->meta.load_state != UNIT_LOADED)
+                return -EINVAL;
+
         /* If this is already (being) started, then this will
          * succeed. Note that this will even succeed if this unit is
          * not startable by the user. This is relied on to detect when
@@ -785,7 +792,7 @@ int unit_stop(Unit *u) {
         assert(u);
 
         state = unit_active_state(u);
-        if (state == UNIT_INACTIVE)
+        if (UNIT_IS_INACTIVE_OR_MAINTENANCE(state))
                 return -EALREADY;
 
         if (!UNIT_VTABLE(u)->stop)
@@ -805,6 +812,9 @@ int unit_reload(Unit *u) {
 
         assert(u);
 
+        if (u->meta.load_state != UNIT_LOADED)
+                return -EINVAL;
+
         if (!unit_can_reload(u))
                 return -EBADR;
 
@@ -941,9 +951,9 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) {
 
         dual_timestamp_get(&ts);
 
-        if (os == UNIT_INACTIVE && ns != UNIT_INACTIVE)
+        if (UNIT_IS_INACTIVE_OR_MAINTENANCE(os) && !UNIT_IS_INACTIVE_OR_MAINTENANCE(ns))
                 u->meta.inactive_exit_timestamp = ts;
-        else if (os != UNIT_INACTIVE && ns == UNIT_INACTIVE)
+        else if (!UNIT_IS_INACTIVE_OR_MAINTENANCE(os) && UNIT_IS_INACTIVE_OR_MAINTENANCE(ns))
                 u->meta.inactive_enter_timestamp = ts;
 
         if (!UNIT_IS_ACTIVE_OR_RELOADING(os) && UNIT_IS_ACTIVE_OR_RELOADING(ns))
@@ -1002,6 +1012,8 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) {
 
                         if (ns == UNIT_INACTIVE)
                                 job_finish_and_invalidate(u->meta.job, true);
+                        else if (ns == UNIT_INACTIVE_MAINTENANCE)
+                                job_finish_and_invalidate(u->meta.job, false);
                         else if (u->meta.job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) {
                                 unexpected = true;
                                 job_finish_and_invalidate(u->meta.job, false);
@@ -1952,7 +1964,9 @@ DEFINE_STRING_TABLE_LOOKUP(unit_load_state, UnitLoadState);
 
 static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
         [UNIT_ACTIVE] = "active",
+        [UNIT_ACTIVE_RELOADING] = "active-reloading",
         [UNIT_INACTIVE] = "inactive",
+        [UNIT_INACTIVE_MAINTENANCE] = "inactive-maintenance",
         [UNIT_ACTIVATING] = "activating",
         [UNIT_DEACTIVATING] = "deactivating"
 };
index 70b3c9a4c104985896bc5358c4b6124ea940b7f5..03031892d0f33f8b5477218d01db5a18a356603e 100644 (file)
@@ -80,6 +80,7 @@ enum UnitActiveState {
         UNIT_ACTIVE,
         UNIT_ACTIVE_RELOADING,
         UNIT_INACTIVE,
+        UNIT_INACTIVE_MAINTENANCE,
         UNIT_ACTIVATING,
         UNIT_DEACTIVATING,
         _UNIT_ACTIVE_STATE_MAX,
@@ -95,7 +96,11 @@ static inline bool UNIT_IS_ACTIVE_OR_ACTIVATING(UnitActiveState t) {
 }
 
 static inline bool UNIT_IS_INACTIVE_OR_DEACTIVATING(UnitActiveState t) {
-        return t == UNIT_INACTIVE || t == UNIT_DEACTIVATING;
+        return t == UNIT_INACTIVE || t == UNIT_INACTIVE_MAINTENANCE || t == UNIT_DEACTIVATING;
+}
+
+static inline bool UNIT_IS_INACTIVE_OR_MAINTENANCE(UnitActiveState t) {
+        return t == UNIT_INACTIVE || t == UNIT_INACTIVE_MAINTENANCE;
 }
 
 enum UnitDependency {