mirror of
https://github.com/systemd/systemd.git
synced 2025-02-23 13:57:33 +03:00
core: set $SERVICE_RESULT, $EXIT_CODE and $EXIT_STATUS in ExecStop=/ExecStopPost= commands
This should simplify monitoring tools for services, by passing the most basic information about service result/exit information via environment variables, thus making it unnecessary to retrieve them explicitly via the bus.
This commit is contained in:
parent
af9d16e10a
commit
136dc4c435
@ -1602,6 +1602,43 @@
|
||||
functions) if their standard output or standard error output is connected to the journal anyway, thus enabling
|
||||
delivery of structured metadata along with logged messages.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$SERVICE_RESULT</varname></term>
|
||||
|
||||
<listitem><para>Only defined for the service unit type, this environment variable is passed to all
|
||||
<varname>ExecStop=</varname> and <varname>ExecStopPost=</varname> processes, and encodes the service
|
||||
"result". Currently, the following values are defined: <literal>timeout</literal> (in case of an operation
|
||||
timeout), <literal>exit-code</literal> (if a service process exited with a non-zero exit code; see
|
||||
<varname>$EXIT_STATUS</varname> below for the actual exit status returned), <literal>signal</literal> (if a
|
||||
service process was terminated abnormally by a signal; see <varname>$EXIT_STATUS</varname> below for the actual
|
||||
signal used for the termination), <literal>core-dump</literal> (if a service process terminated abnormally and
|
||||
dumped core), <literal>watchdog</literal> (if the watchdog keep-alive ping was enabled for the service but it
|
||||
missed the deadline), or <literal>resources</literal> (a catch-all condition in case a system operation
|
||||
failed).</para>
|
||||
|
||||
<para>This environment variable is useful to monitor failure or successful termination of a service. Even
|
||||
though this variable is available in both <varname>ExecStop=</varname> and <varname>ExecStopPost=</varname>, it
|
||||
is usually a better choice to place monitoring tools in the latter, as the former is only invoked for services
|
||||
that managed to start up correctly, and the latter covers both services that failed during their start-up and
|
||||
those which failed during their runtime.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>$EXIT_CODE</varname></term>
|
||||
<term><varname>$EXIT_STATUS</varname></term>
|
||||
|
||||
<listitem><para>Only defined for the service unit type, these environment variables are passed to all
|
||||
<varname>ExecStop=</varname>, <varname>ExecStopPost=</varname> processes and contain exit status/code
|
||||
information of the main process of the service. For the precise definition of the exit code and status, see
|
||||
<citerefentry><refentrytitle>wait</refentrytitle><manvolnum>2</manvolnum></citerefentry>. <varname>$EXIT_CODE</varname>
|
||||
is one of <literal>exited</literal>, <literal>killed</literal>,
|
||||
<literal>dumped</literal>. <varname>$EXIT_STATUS</varname> contains the numeric exit code formatted as string
|
||||
if <varname>$EXIT_CODE</varname> is <literal>exited</literal>, and the signal name in all other cases. Note
|
||||
that these environment variables are only set if the service manager succeeded to start and identify the main
|
||||
process of the service.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<para>Additional variables may be configured by the following
|
||||
|
@ -429,7 +429,13 @@
|
||||
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.</para></listitem>
|
||||
not attempt to communicate with them.</para>
|
||||
|
||||
<para>Note that all commands that are configured with this setting are invoked with the result code of the
|
||||
service, as well as the main process' exit code and status, set in the <varname>$SERVICE_RESULT</varname>,
|
||||
<varname>$EXIT_CODE</varname> and <varname>$EXIT_STATUS</varname> environment variables, see
|
||||
<citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
|
||||
details.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
|
@ -217,6 +217,7 @@ typedef enum ExecFlags {
|
||||
/* The following are not used by execute.c, but by consumers internally */
|
||||
EXEC_PASS_FDS = 1U << 4,
|
||||
EXEC_IS_CONTROL = 1U << 5,
|
||||
EXEC_SETENV_RESULT = 1U << 6,
|
||||
} ExecFlags;
|
||||
|
||||
struct ExecParameters {
|
||||
|
@ -1216,7 +1216,7 @@ static int service_spawn(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
our_env = new0(char*, 6);
|
||||
our_env = new0(char*, 9);
|
||||
if (!our_env)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1264,6 +1264,24 @@ static int service_spawn(
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & EXEC_SETENV_RESULT) {
|
||||
if (asprintf(our_env + n_env++, "SERVICE_RESULT=%s", service_result_to_string(s->result)) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
if (s->main_exec_status.pid > 0 &&
|
||||
dual_timestamp_is_set(&s->main_exec_status.exit_timestamp)) {
|
||||
if (asprintf(our_env + n_env++, "EXIT_CODE=%s", sigchld_code_to_string(s->main_exec_status.code)) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
if (s->main_exec_status.code == CLD_EXITED)
|
||||
r = asprintf(our_env + n_env++, "EXIT_STATUS=%i", s->main_exec_status.status);
|
||||
else
|
||||
r = asprintf(our_env + n_env++, "EXIT_STATUS=%s", signal_to_string(s->main_exec_status.status));
|
||||
if (r < 0)
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
final_env = strv_env_merge(2, UNIT(s)->manager->environment, our_env, NULL);
|
||||
if (!final_env)
|
||||
return -ENOMEM;
|
||||
@ -1467,7 +1485,7 @@ static void service_enter_stop_post(Service *s, ServiceResult f) {
|
||||
r = service_spawn(s,
|
||||
s->control_command,
|
||||
s->timeout_stop_usec,
|
||||
EXEC_APPLY_PERMISSIONS|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN|EXEC_IS_CONTROL,
|
||||
EXEC_APPLY_PERMISSIONS|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN|EXEC_IS_CONTROL|EXEC_SETENV_RESULT,
|
||||
&s->control_pid);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
@ -1578,7 +1596,7 @@ static void service_enter_stop(Service *s, ServiceResult f) {
|
||||
r = service_spawn(s,
|
||||
s->control_command,
|
||||
s->timeout_stop_usec,
|
||||
EXEC_APPLY_PERMISSIONS|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL,
|
||||
EXEC_APPLY_PERMISSIONS|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_SETENV_RESULT,
|
||||
&s->control_pid);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
@ -1898,7 +1916,8 @@ static void service_run_next_control(Service *s) {
|
||||
s->control_command,
|
||||
timeout,
|
||||
EXEC_APPLY_PERMISSIONS|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|
|
||||
(IN_SET(s->control_command_id, SERVICE_EXEC_START_PRE, SERVICE_EXEC_STOP_POST) ? EXEC_APPLY_TTY_STDIN : 0),
|
||||
(IN_SET(s->control_command_id, SERVICE_EXEC_START_PRE, SERVICE_EXEC_STOP_POST) ? EXEC_APPLY_TTY_STDIN : 0)|
|
||||
(IN_SET(s->control_command_id, SERVICE_EXEC_STOP, SERVICE_EXEC_STOP_POST) ? EXEC_SETENV_RESULT : 0),
|
||||
&s->control_pid);
|
||||
if (r < 0)
|
||||
goto fail;
|
||||
|
Loading…
x
Reference in New Issue
Block a user