* "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:
[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);
case JOB_STOP:
return
- b == UNIT_INACTIVE;
+ b == UNIT_INACTIVE ||
+ b == UNIT_INACTIVE_MAINTENANCE;
case JOB_VERIFY_ACTIVE:
return
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
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;
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? */
[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) {
[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) {
[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) {
[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) {
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) {
[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) {
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);
}
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);
}
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 */
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
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)
assert(u);
+ if (u->meta.load_state != UNIT_LOADED)
+ return -EINVAL;
+
if (!unit_can_reload(u))
return -EBADR;
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))
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);
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"
};
UNIT_ACTIVE,
UNIT_ACTIVE_RELOADING,
UNIT_INACTIVE,
+ UNIT_INACTIVE_MAINTENANCE,
UNIT_ACTIVATING,
UNIT_DEACTIVATING,
_UNIT_ACTIVE_STATE_MAX,
}
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 {