From 6124958c7bda3fed9b079e8217781480797703f5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 1 Jul 2010 00:31:53 +0200 Subject: [PATCH] unit: add new abstracted maintenance state for units --- fixme | 14 ++++++++++---- src/automount.c | 2 +- src/job.c | 7 ++++--- src/manager.c | 2 +- src/mount.c | 2 +- src/path.c | 2 +- src/service.c | 4 ++-- src/socket.c | 2 +- src/swap.c | 2 +- src/timer.c | 4 ++-- src/unit.c | 26 ++++++++++++++++++++------ src/unit.h | 7 ++++++- 12 files changed, 50 insertions(+), 24 deletions(-) diff --git a/fixme b/fixme index 3ca6a02e0..09aba7de0 100644 --- 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? @@ -37,9 +35,17 @@ * 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: diff --git a/src/automount.c b/src/automount.c index 75c10538b..84f2d97ed 100644 --- a/src/automount.c +++ b/src/automount.c @@ -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); diff --git a/src/job.c b/src/job.c index 78fe13632..8273a39c3 100644 --- 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; diff --git a/src/manager.c b/src/manager.c index b8daffd67..74a414aab 100644 --- a/src/manager.c +++ b/src/manager.c @@ -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? */ diff --git a/src/mount.c b/src/mount.c index 081e92c02..f0336163a 100644 --- a/src/mount.c +++ b/src/mount.c @@ -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) { diff --git a/src/path.c b/src/path.c index 24545bad3..16ea08dde 100644 --- a/src/path.c +++ b/src/path.c @@ -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) { diff --git a/src/service.c b/src/service.c index e1dab70f8..3102acc08 100644 --- a/src/service.c +++ b/src/service.c @@ -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) { diff --git a/src/socket.c b/src/socket.c index f20b78d1a..83f8ebe6a 100644 --- a/src/socket.c +++ b/src/socket.c @@ -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) { diff --git a/src/swap.c b/src/swap.c index 663c56896..e2afcc02e 100644 --- a/src/swap.c +++ b/src/swap.c @@ -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) { diff --git a/src/timer.c b/src/timer.c index ead8ab92a..96c6e8e8e 100644 --- a/src/timer.c +++ b/src/timer.c @@ -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); } diff --git a/src/unit.c b/src/unit.c index 76e8cd74a..79b9e2bb8 100644 --- a/src/unit.c +++ b/src/unit.c @@ -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" }; diff --git a/src/unit.h b/src/unit.h index 70b3c9a4c..03031892d 100644 --- a/src/unit.h +++ b/src/unit.h @@ -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 { -- 2.30.2