unit: add new abstracted maintenance state for units

This commit is contained in:
Lennart Poettering 2010-07-01 00:31:53 +02:00
parent 4fd5948e74
commit 6124958c7b
12 changed files with 50 additions and 24 deletions

14
fixme
View File

@ -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
* systemd-sysvinit as package
* nettere fehlermeldung bei systemctl start foo.service failure
* systemd-install disable sollte den service runterfahren
* systemctl daemon-reload is kaputt
* keinerlei fehlermeldung bei dead symlink muss gefixt werden
External:
* patch /etc/init.d/functions with:

View 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);

View File

@ -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;

View 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? */

View 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) {

View 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) {

View 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) {

View 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) {

View 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) {

View 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);
}

View 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"
};

View 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 {