restart_usec_next = service_restart_usec_next(s);
r = service_arm_timer(s, /* relative= */ true, restart_usec_next);
- if (r < 0)
- goto fail;
+ if (r < 0) {
+ log_unit_warning_errno(UNIT(s), r, "Failed to install restart timer: %m");
+ service_enter_dead(s, SERVICE_FAILURE_RESOURCES, /* allow_restart= */ false);
+ return;
+ }
log_unit_debug(UNIT(s), "Next restart interval calculated as: %s", FORMAT_TIMESPAN(restart_usec_next, 0));
/* Reset TTY ownership if necessary */
exec_context_revert_tty(&s->exec_context);
-
- return;
-
-fail:
- log_unit_warning_errno(UNIT(s), r, "Failed to run install restart timer: %m");
- service_enter_dead(s, SERVICE_FAILURE_RESOURCES, false);
}
static void service_enter_stop_post(Service *s, ServiceResult f) {
s->timeout_stop_usec,
EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN|EXEC_IS_CONTROL|EXEC_SETENV_RESULT|EXEC_CONTROL_CGROUP,
&s->control_pid);
- if (r < 0)
- goto fail;
+ if (r < 0) {
+ log_unit_warning_errno(UNIT(s), r, "Failed to spawn 'stop-post' task: %m");
+ service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES);
+ return;
+ }
service_set_state(s, SERVICE_STOP_POST);
} else
service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_SUCCESS);
-
- return;
-
-fail:
- log_unit_warning_errno(UNIT(s), r, "Failed to run 'stop-post' task: %m");
- service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES);
}
static int state_to_kill_operation(Service *s, ServiceState state) {
&s->main_pid,
&s->control_pid,
s->main_pid_alien);
- if (r < 0)
+ if (r < 0) {
+ log_unit_warning_errno(UNIT(s), r, "Failed to kill processes: %m");
goto fail;
+ }
if (r > 0) {
r = service_arm_timer(s, /* relative= */ true,
kill_operation == KILL_WATCHDOG ? service_timeout_abort_usec(s) : s->timeout_stop_usec);
- if (r < 0)
+ if (r < 0) {
+ log_unit_warning_errno(UNIT(s), r, "Failed to install timer: %m");
goto fail;
+ }
service_set_state(s, state);
} else if (IN_SET(state, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM) && s->kill_context.send_sigkill)
else if (IN_SET(state, SERVICE_FINAL_WATCHDOG, SERVICE_FINAL_SIGTERM) && s->kill_context.send_sigkill)
service_enter_signal(s, SERVICE_FINAL_SIGKILL, SERVICE_SUCCESS);
else
- service_enter_dead(s, SERVICE_SUCCESS, true);
+ service_enter_dead(s, SERVICE_SUCCESS, /* allow_restart= */ true);
return;
fail:
- log_unit_warning_errno(UNIT(s), r, "Failed to kill processes: %m");
-
if (IN_SET(state, SERVICE_STOP_WATCHDOG, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL))
service_enter_stop_post(s, SERVICE_FAILURE_RESOURCES);
else
- service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true);
+ service_enter_dead(s, SERVICE_FAILURE_RESOURCES, /* allow_restart= */ true);
}
static void service_enter_stop_by_notify(Service *s) {
s->timeout_stop_usec,
EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_SETENV_RESULT|EXEC_CONTROL_CGROUP,
&s->control_pid);
- if (r < 0)
- goto fail;
+ if (r < 0) {
+ log_unit_warning_errno(UNIT(s), r, "Failed to spawn 'stop' task: %m");
+ service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES);
+ return;
+ }
service_set_state(s, SERVICE_STOP);
} else
service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_SUCCESS);
-
- return;
-
-fail:
- log_unit_warning_errno(UNIT(s), r, "Failed to run 'stop' task: %m");
- service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES);
}
static bool service_good(Service *s) {
s->timeout_start_usec,
EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_CONTROL_CGROUP,
&s->control_pid);
- if (r < 0)
- goto fail;
+ if (r < 0) {
+ log_unit_warning_errno(UNIT(s), r, "Failed to spawn 'start-post' task: %m");
+ service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
+ return;
+ }
service_set_state(s, SERVICE_START_POST);
} else
service_enter_running(s, SERVICE_SUCCESS);
-
- return;
-
-fail:
- log_unit_warning_errno(UNIT(s), r, "Failed to run 'start-post' task: %m");
- service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
}
static void service_kill_control_process(Service *s) {
timeout,
EXEC_PASS_FDS|EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN|EXEC_SET_WATCHDOG|EXEC_WRITE_CREDENTIALS|EXEC_SETENV_MONITOR_RESULT,
&pidref);
- if (r < 0)
+ if (r < 0) {
+ log_unit_warning_errno(UNIT(s), r, "Failed to spawn 'start' task: %m");
goto fail;
+ }
if (IN_SET(s->type, SERVICE_SIMPLE, SERVICE_IDLE)) {
/* For simple services we immediately start
return;
fail:
- log_unit_warning_errno(UNIT(s), r, "Failed to run 'start' task: %m");
service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES);
}
s->timeout_start_usec,
EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_APPLY_TTY_STDIN|EXEC_SETENV_MONITOR_RESULT|EXEC_WRITE_CREDENTIALS,
&s->control_pid);
- if (r < 0)
+ if (r < 0) {
+ log_unit_warning_errno(UNIT(s), r, "Failed to spawn 'start-pre' task: %m");
goto fail;
+ }
service_set_state(s, SERVICE_START_PRE);
} else
return;
fail:
- log_unit_warning_errno(UNIT(s), r, "Failed to run 'start-pre' task: %m");
- service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true);
+ service_enter_dead(s, SERVICE_FAILURE_RESOURCES, /* allow_restart= */ true);
}
static void service_enter_condition(Service *s) {
EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_APPLY_TTY_STDIN,
&s->control_pid);
- if (r < 0)
+ if (r < 0) {
+ log_unit_warning_errno(UNIT(s), r, "Failed to spawn 'exec-condition' task: %m");
goto fail;
+ }
service_set_state(s, SERVICE_CONDITION);
} else
return;
fail:
- log_unit_warning_errno(UNIT(s), r, "Failed to run 'exec-condition' task: %m");
- service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true);
+ service_enter_dead(s, SERVICE_FAILURE_RESOURCES, /* allow_restart= */ true);
}
static void service_enter_restart(Service *s) {
/* Any units that are bound to this service must also be restarted. We use JOB_START for ourselves
* but then set JOB_RESTART_DEPENDENCIES which will enqueue JOB_RESTART for those dependency jobs. */
r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT(s), JOB_RESTART_DEPENDENCIES, NULL, &error, NULL);
- if (r < 0)
- goto fail;
+ if (r < 0) {
+ log_unit_warning(UNIT(s), "Failed to schedule restart job: %s", bus_error_message(&error, r));
+ service_enter_dead(s, SERVICE_FAILURE_RESOURCES, /* allow_restart= */ false);
+ return;
+ }
/* Count the jobs we enqueue for restarting. This counter is maintained as long as the unit isn't
* fully stopped, i.e. as long as it remains up or remains in auto-start states. The user can reset
/* Notify clients about changed restart counter */
unit_add_to_dbus_queue(UNIT(s));
- return;
-
-fail:
- log_unit_warning(UNIT(s), "Failed to schedule restart job: %s", bus_error_message(&error, r));
- service_enter_dead(s, SERVICE_FAILURE_RESOURCES, false);
}
static void service_enter_reload_by_notify(Service *s) {
EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_CONTROL_CGROUP,
&s->control_pid);
if (r < 0) {
- log_unit_warning_errno(UNIT(s), r, "Failed to run 'reload' task: %m");
+ log_unit_warning_errno(UNIT(s), r, "Failed to spawn 'reload' task: %m");
goto fail;
}
(IN_SET(s->control_command_id, SERVICE_EXEC_START_PRE, SERVICE_EXEC_START) ? EXEC_SETENV_MONITOR_RESULT : 0)|
(IN_SET(s->control_command_id, SERVICE_EXEC_START_POST, SERVICE_EXEC_RELOAD, SERVICE_EXEC_STOP, SERVICE_EXEC_STOP_POST) ? EXEC_CONTROL_CGROUP : 0),
&s->control_pid);
- if (r < 0)
- goto fail;
-
- return;
-
-fail:
- log_unit_warning_errno(UNIT(s), r, "Failed to run next control task: %m");
-
- if (IN_SET(s->state, SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START_POST, SERVICE_STOP))
- service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES);
- else if (s->state == SERVICE_STOP_POST)
- service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true);
- else if (s->state == SERVICE_RELOAD) {
- s->reload_result = SERVICE_FAILURE_RESOURCES;
- service_enter_running(s, SERVICE_SUCCESS);
- } else
- service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
+ if (r < 0) {
+ log_unit_warning_errno(UNIT(s), r, "Failed to spawn next control task: %m");
+
+ if (IN_SET(s->state, SERVICE_CONDITION, SERVICE_START_PRE, SERVICE_START_POST, SERVICE_STOP))
+ service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES);
+ else if (s->state == SERVICE_STOP_POST)
+ service_enter_dead(s, SERVICE_FAILURE_RESOURCES, /* allow_restart= */ true);
+ else if (s->state == SERVICE_RELOAD) {
+ s->reload_result = SERVICE_FAILURE_RESOURCES;
+ service_enter_running(s, SERVICE_SUCCESS);
+ } else
+ service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
+ }
}
static void service_run_next_main(Service *s) {
s->timeout_start_usec,
EXEC_PASS_FDS|EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN|EXEC_SET_WATCHDOG|EXEC_SETENV_MONITOR_RESULT|EXEC_WRITE_CREDENTIALS,
&pidref);
- if (r < 0)
- goto fail;
+ if (r < 0) {
+ log_unit_warning_errno(UNIT(s), r, "Failed to spawn next main task: %m");
+ service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
+ return;
+ }
(void) service_set_main_pidref(s, &pidref);
- return;
-
-fail:
- log_unit_warning_errno(UNIT(s), r, "Failed to run next main task: %m");
- service_enter_stop(s, SERVICE_FAILURE_RESOURCES);
}
static int service_start(Unit *u) {
log_unit_debug(UNIT(s), "Setting watch for PID file %s", s->pid_file_pathspec->path);
r = path_spec_watch(s->pid_file_pathspec, service_dispatch_inotify_io);
- if (r < 0)
- goto fail;
+ if (r < 0) {
+ log_unit_error_errno(UNIT(s), r, "Failed to set a watch for PID file %s: %m", s->pid_file_pathspec->path);
+ service_unwatch_pid_file(s);
+ return r;
+ }
/* the pidfile might have appeared just before we set the watch */
log_unit_debug(UNIT(s), "Trying to read PID file %s in case it changed", s->pid_file_pathspec->path);
service_retry_pid_file(s);
return 0;
-fail:
- log_unit_error_errno(UNIT(s), r, "Failed to set a watch for PID file %s: %m", s->pid_file_pathspec->path);
- service_unwatch_pid_file(s);
- return r;
}
static int service_demand_pid_file(Service *s) {
s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID;
r = service_arm_timer(s, /* relative= */ true, s->exec_context.timeout_clean_usec);
- if (r < 0)
+ if (r < 0) {
+ log_unit_warning_errno(u, r, "Failed to install timer: %m");
goto fail;
+ }
r = unit_fork_and_watch_rm_rf(u, l, &s->control_pid);
- if (r < 0)
+ if (r < 0) {
+ log_unit_warning_errno(u, r, "Failed to spawn cleaning task: %m");
goto fail;
+ }
service_set_state(s, SERVICE_CLEANING);
return 0;
fail:
- log_unit_warning_errno(u, r, "Failed to initiate cleaning: %m");
s->clean_result = SERVICE_FAILURE_RESOURCES;
s->timer_event_source = sd_event_source_disable_unref(s->timer_event_source);
return r;