}
}
-static bool service_will_restart(Service *s) {
+static bool service_will_restart(Unit *u) {
+ Service *s = SERVICE(u);
+
assert(s);
+ if (s->will_auto_restart)
+ return true;
if (s->state == SERVICE_AUTO_RESTART)
return true;
if (!UNIT(s)->job)
if (s->result != SERVICE_SUCCESS)
log_unit_warning(UNIT(s), "Failed with result '%s'.", service_result_to_string(s->result));
+ if (allow_restart && service_shall_restart(s))
+ s->will_auto_restart = true;
+
/* Make sure service_release_resources() doesn't destroy our FD store, while we are changing through
* SERVICE_FAILED/SERVICE_DEAD before entering into SERVICE_AUTO_RESTART. */
s->n_keep_fd_store ++;
service_set_state(s, s->result != SERVICE_SUCCESS ? SERVICE_FAILED : SERVICE_DEAD);
- if (allow_restart && service_shall_restart(s)) {
+ if (s->will_auto_restart) {
+ s->will_auto_restart = false;
r = service_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), s->restart_usec));
if (r < 0) {
s->exec_runtime = exec_runtime_unref(s->exec_runtime);
if (s->exec_context.runtime_directory_preserve_mode == EXEC_PRESERVE_NO ||
- (s->exec_context.runtime_directory_preserve_mode == EXEC_PRESERVE_RESTART && !service_will_restart(s)))
+ (s->exec_context.runtime_directory_preserve_mode == EXEC_PRESERVE_RESTART && !service_will_restart(UNIT(s))))
/* Also, remove the runtime directory */
exec_context_destroy_runtime_directory(&s->exec_context, UNIT(s)->manager->prefix[EXEC_DIRECTORY_RUNTIME]);
.active_state = service_active_state,
.sub_state_to_string = service_sub_state_to_string,
+ .will_restart = service_will_restart,
+
.check_gc = service_check_gc,
.sigchld_event = service_sigchld_event,
void *v;
HASHMAP_FOREACH_KEY(v, other, u->dependencies[needed_dependencies[j]], i)
- if (unit_active_or_pending(other))
+ if (unit_active_or_pending(other) || unit_will_restart(other))
return;
}
return false;
}
+bool unit_will_restart(Unit *u) {
+ assert(u);
+
+ if (!UNIT_VTABLE(u)->will_restart)
+ return false;
+
+ return UNIT_VTABLE(u)->will_restart(u);
+}
+
int unit_kill(Unit *u, KillWho w, int signo, sd_bus_error *error) {
assert(u);
assert(w >= 0 && w < _KILL_WHO_MAX);
* unit is in. */
const char* (*sub_state_to_string)(Unit *u);
+ /* Additionally to UnitActiveState determine whether unit is to be restarted. */
+ bool (*will_restart)(Unit *u);
+
/* Return true when there is reason to keep this entry around
* even nothing references it and it isn't active in any
* way */
bool unit_stop_pending(Unit *u) _pure_;
bool unit_inactive_or_pending(Unit *u) _pure_;
bool unit_active_or_pending(Unit *u);
+bool unit_will_restart(Unit *u);
int unit_add_default_target_dependency(Unit *u, Unit *target);