diff options
author | Peter Morrow <pemorrow@linux.microsoft.com> | 2021-09-23 16:54:32 +0100 |
---|---|---|
committer | Peter Morrow <pemorrow@linux.microsoft.com> | 2021-12-13 11:25:57 +0000 |
commit | cdebedb4d40277aad62a7734ba920b4033228197 (patch) | |
tree | 7523417a1b08669301aa1dafacab30342f54e5b6 /src/core/job.c | |
parent | a0630d46a59d5c8296c71413eb50c2572e20f046 (diff) | |
download | systemd-cdebedb4d40277aad62a7734ba920b4033228197.tar.gz |
service: pass service exit status to spawned On{Failure,Success}= dependency
When a service exits and triggers either an OnFailure= or OnSuccess=
dependency we now set a new environment variable for the ExecStart= and
ExecStartPre= process. This variable $MONITOR_METADATA exposes the
metadata relating to the service which triggered the dependency.
MONITOR_METADATA takes the following form:
MONITOR_METADATA="SERVICE_RESULT=<result-string0>,EXIT_CODE=<exit-code0>,EXIT_STATUS=<exit-status0>,INVOCATION_ID=<id>,UNIT=<triggering-unit0.service>;SERVICE_RESULT=<result-stringN>,EXIT_CODE=<exit-codeN>,=EXIT_STATUS=<exit-statusN>,INVOCATION_ID=<id>,UNIT=<triggering-unitN.service>"
MONITOR_METADATA is space separated set of metadata relating to the
service(s) which triggered the dependency. This is a list since if we
have 2 services which trigger the same dependency then the dependency
start job may be merged. In this case we need to pass both service
metadata to the triggered service. If there is no job merging then
MONITOR_METADATA will be a single entry.
For example, in the case we had a service "failer.service" which
triggers "failer-handler.service", the following variable is exported to
the ExecStart= and ExecStartPre= processes in failer-handler.service:
MONITOR_METADATA="SERVICE_RESULT=exit-code,EXIT_CODE=exited,EXIT_STATUS=1,INVOCATION_ID=67c657ed7b34466ea369abdf994c6393,UNIT=failer.service"
In another example where we have failer.service and failer2.service
which both also trigger failer-handler.service then the start job for
failer-handler.service may be merged and we might get the following:
MONITOR_METADATA="SERVICE_RESULT=exit-code,EXIT_CODE=exited,EXIT_STATUS=1,INVOCATION_ID=16a93ad196c94109990fb8b9aa5eef5f,UNIT=failer.service;SERVICE_RESULT=exit-code,EXIT_CODE=exited,EXIT_STATUS=1,INVOCATION_ID=ff70131e4cc145e994fb621de25a3e8f,UNIT=failer2.service"
Diffstat (limited to 'src/core/job.c')
-rw-r--r-- | src/core/job.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/src/core/job.c b/src/core/job.c index 94ab381626..67c3c8fdd2 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -99,6 +99,13 @@ Job* job_free(Job *j) { assert(!j->subject_list); assert(!j->object_list); + do { + Unit *tu = NULL; + + LIST_FOREACH(triggered_by, tu, j->triggered_by) + LIST_REMOVE(triggered_by, j->triggered_by, tu); + } while (!LIST_IS_EMPTY(j->triggered_by)); + job_unlink(j); sd_bus_track_unref(j->bus_track); @@ -107,6 +114,13 @@ Job* job_free(Job *j) { return mfree(j); } +void job_add_triggering_unit(Job *j, Unit *u) { + assert(j); + assert(u); + + LIST_APPEND(triggered_by, j->triggered_by, u); +} + static void job_set_state(Job *j, JobState state) { assert(j); assert(state >= 0); @@ -187,6 +201,8 @@ static void job_merge_into_installed(Job *j, Job *other) { j->irreversible = j->irreversible || other->irreversible; j->ignore_order = j->ignore_order || other->ignore_order; + if (other->triggered_by) + LIST_JOIN(triggered_by, j->triggered_by, other->triggered_by); } Job* job_install(Job *j) { |