diff --git a/man/systemd.service.xml b/man/systemd.service.xml index 14f6cd6adc..4cd36ac70e 100644 --- a/man/systemd.service.xml +++ b/man/systemd.service.xml @@ -383,6 +383,11 @@ used to start long-running processes. All processes forked off by processes invoked via ExecStartPre= will be killed before the next service process is run. + + Note that if any of the commands specified in ExecStartPre=, + ExecStart=, or ExecStartPost= fail (and are not prefixed with + -, see above) or time out before the service is fully up, execution continues with commands + specified in ExecStopPost=, the commands in ExecStop= are skipped. @@ -438,21 +443,36 @@ SIGKILL immediately after the command exited, this would not result in a clean stop. The specified command should hence be a synchronous operation, not an - asynchronous one. + asynchronous one. + + Note that the commands specified in ExecStop= are only executed when the service + started successfuly first. They are not invoked if the service was never started at all, or in case its + start-up failed, for example because any of the commands specified in ExecStart=, + ExecStartPre= or ExecStartPost= failed (and weren't prefixed with + -, see above) or timed out. Use ExecStopPost= to invoke commands when a + service failed to start up correctly and is shut down again. + + It is recommended to use this setting for commands that communicate with the service requesting clean + termination. When the commands specified with this option are executed it should be assumed that the service is + still fully up and is able to react correctly to all commands. For post-mortem clean-up steps use + ExecStopPost= instead. ExecStopPost= - Additional commands that are executed after - the service was stopped. This includes cases where the - commands configured in ExecStop= were used, - where the service does not have any - ExecStop= defined, or where the service - exited unexpectedly. This argument takes multiple command - lines, following the same scheme as described for - ExecStart=. Use of these settings is - optional. Specifier and environment variable substitution is - supported. + Additional commands that are executed after the service is stopped. This includes cases where + the commands configured in ExecStop= were used, where the service does not have any + ExecStop= defined, or where the service exited unexpectedly. This argument takes multiple + command lines, following the same scheme as described for ExecStart=. Use of these settings + is optional. Specifier and environment variable substitution is supported. Note that – unlike + ExecStop= – commands specified with this setting are invoked when a service failed to start + up correctly and is shut down again. + + It is recommended to use this setting for clean-up operations that shall be executed even when the + service failed to start up correctly. Commands configured with this setting need to be able to operate even if + the service failed starting up half-way and left incompletely initialized data around. As the service's + processes have been terminated already when the commands specified with this setting are executed they should + not attempt to communicate with them. diff --git a/src/core/service.c b/src/core/service.c index a9345e38b9..4942fc425d 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -2788,7 +2788,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) { case SERVICE_START_POST: if (f != SERVICE_SUCCESS) { - service_enter_stop(s, f); + service_enter_signal(s, SERVICE_STOP_SIGTERM, f); break; } @@ -2878,7 +2878,7 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us case SERVICE_START_POST: log_unit_warning(UNIT(s), "Start-post operation timed out. Stopping."); - service_enter_stop(s, SERVICE_FAILURE_TIMEOUT); + service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_TIMEOUT); break; case SERVICE_RUNNING: