unit: add new abstracted maintenance state for units
This commit is contained in:
parent
4fd5948e74
commit
6124958c7b
14
fixme
14
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
|
||||
|
||||
* 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:
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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? */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
26
src/unit.c
26
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"
|
||||
};
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue