1 /* SPDX-License-Identifier: LGPL-2.1+ */
11 typedef struct Job Job
;
12 typedef struct JobDependency JobDependency
;
13 typedef enum JobType JobType
;
14 typedef enum JobState JobState
;
15 typedef enum JobMode JobMode
;
16 typedef enum JobResult JobResult
;
18 /* Be careful when changing the job types! Adjust job_merging_table[] accordingly! */
20 JOB_START
, /* if a unit does not support being started, we'll just wait until it becomes active */
25 JOB_RELOAD
, /* if running, reload */
27 /* Note that restarts are first treated like JOB_STOP, but
28 * then instead of finishing are patched to become
30 JOB_RESTART
, /* If running, stop. Then start unconditionally. */
32 _JOB_TYPE_MAX_MERGING
,
34 /* JOB_NOP can enter into a transaction, but as it won't pull in
35 * any dependencies and it uses the special 'nop_job' slot in Unit,
36 * it won't have to merge with anything (except possibly into another
37 * JOB_NOP, previously installed). JOB_NOP is special-cased in
38 * job_type_is_*() functions so that the transaction can be
40 JOB_NOP
= _JOB_TYPE_MAX_MERGING
, /* do nothing */
42 _JOB_TYPE_MAX_IN_TRANSACTION
,
44 /* JOB_TRY_RESTART can never appear in a transaction, because
45 * it always collapses into JOB_RESTART or JOB_NOP before entering.
46 * Thus we never need to merge it with anything. */
47 JOB_TRY_RESTART
= _JOB_TYPE_MAX_IN_TRANSACTION
, /* if running, stop and then start */
49 /* Similar to JOB_TRY_RESTART but collapses to JOB_RELOAD or JOB_NOP */
52 /* JOB_RELOAD_OR_START won't enter into a transaction and cannot result
53 * from transaction merging (there's no way for JOB_RELOAD and
54 * JOB_START to meet in one transaction). It can result from a merge
55 * during job installation, but then it will immediately collapse into
56 * one of the two simpler types. */
57 JOB_RELOAD_OR_START
, /* if running, reload, otherwise start */
60 _JOB_TYPE_INVALID
= -1
67 _JOB_STATE_INVALID
= -1
71 JOB_FAIL
, /* Fail if a conflicting job is already queued */
72 JOB_REPLACE
, /* Replace an existing conflicting job */
73 JOB_REPLACE_IRREVERSIBLY
,/* Like JOB_REPLACE + produce irreversible jobs */
74 JOB_ISOLATE
, /* Start a unit, and stop all others */
75 JOB_FLUSH
, /* Flush out all other queued jobs when queing this one */
76 JOB_IGNORE_DEPENDENCIES
, /* Ignore both requirement and ordering dependencies */
77 JOB_IGNORE_REQUIREMENTS
, /* Ignore requirement dependencies */
79 _JOB_MODE_INVALID
= -1
83 JOB_DONE
, /* Job completed successfully (or skipped due to a failed ConditionXYZ=) */
84 JOB_CANCELED
, /* Job canceled by a conflicting job installation or by explicit cancel request */
85 JOB_TIMEOUT
, /* Job timeout elapsed */
86 JOB_FAILED
, /* Job failed */
87 JOB_DEPENDENCY
, /* A required dependency job did not result in JOB_DONE */
88 JOB_SKIPPED
, /* Negative result of JOB_VERIFY_ACTIVE */
89 JOB_INVALID
, /* JOB_RELOAD of inactive unit */
90 JOB_ASSERT
, /* Couldn't start a unit, because an assert didn't hold */
91 JOB_UNSUPPORTED
, /* Couldn't start a unit, because the unit type is not supported on the system */
92 JOB_COLLECTED
, /* Job was garbage collected, since nothing needed it anymore */
93 JOB_ONCE
, /* Unit was started before, and hence can't be started again */
95 _JOB_RESULT_INVALID
= -1
100 struct JobDependency
{
101 /* Encodes that the 'subject' job needs the 'object' job in
102 * some way. This structure is used only while building a transaction. */
106 LIST_FIELDS(JobDependency
, subject
);
107 LIST_FIELDS(JobDependency
, object
);
117 LIST_FIELDS(Job
, transaction
);
118 LIST_FIELDS(Job
, run_queue
);
119 LIST_FIELDS(Job
, dbus_queue
);
120 LIST_FIELDS(Job
, gc_queue
);
122 LIST_HEAD(JobDependency
, subject_list
);
123 LIST_HEAD(JobDependency
, object_list
);
125 /* Used for graph algs as a "I have been here" marker */
134 sd_event_source
*timer_event_source
;
136 usec_t begin_running_usec
;
139 * This tracks where to send signals, and also which clients
140 * are allowed to call DBus methods on the job (other than
143 * There can be more than one client, because of job merging.
145 sd_bus_track
*bus_track
;
146 char **deserialized_clients
;
152 bool matters_to_anchor
:1;
153 bool in_dbus_queue
:1;
154 bool sent_dbus_new_signal
:1;
158 bool ref_by_private_bus
:1;
162 Job
* job_new(Unit
*unit
, JobType type
);
163 Job
* job_new_raw(Unit
*unit
);
164 void job_unlink(Job
*job
);
165 void job_free(Job
*job
);
166 Job
* job_install(Job
*j
);
167 int job_install_deserialized(Job
*j
);
168 void job_uninstall(Job
*j
);
169 void job_dump(Job
*j
, FILE*f
, const char *prefix
);
170 int job_serialize(Job
*j
, FILE *f
);
171 int job_deserialize(Job
*j
, FILE *f
);
172 int job_coldplug(Job
*j
);
174 JobDependency
* job_dependency_new(Job
*subject
, Job
*object
, bool matters
, bool conflicts
);
175 void job_dependency_free(JobDependency
*l
);
177 int job_merge(Job
*j
, Job
*other
);
179 JobType
job_type_lookup_merge(JobType a
, JobType b
) _pure_
;
181 _pure_
static inline bool job_type_is_mergeable(JobType a
, JobType b
) {
182 return job_type_lookup_merge(a
, b
) >= 0;
185 _pure_
static inline bool job_type_is_conflicting(JobType a
, JobType b
) {
186 return a
!= JOB_NOP
&& b
!= JOB_NOP
&& !job_type_is_mergeable(a
, b
);
189 _pure_
static inline bool job_type_is_superset(JobType a
, JobType b
) {
190 /* Checks whether operation a is a "superset" of b in its actions */
195 return a
== job_type_lookup_merge(a
, b
);
198 bool job_type_is_redundant(JobType a
, UnitActiveState b
) _pure_
;
200 /* Collapses a state-dependent job type into a simpler type by observing
201 * the state of the unit which it is going to be applied to. */
202 JobType
job_type_collapse(JobType t
, Unit
*u
);
204 int job_type_merge_and_collapse(JobType
*a
, JobType b
, Unit
*u
);
206 void job_add_to_run_queue(Job
*j
);
207 void job_add_to_dbus_queue(Job
*j
);
209 int job_start_timer(Job
*j
, bool job_running
);
211 int job_run_and_invalidate(Job
*j
);
212 int job_finish_and_invalidate(Job
*j
, JobResult result
, bool recursive
, bool already
);
214 char *job_dbus_path(Job
*j
);
216 void job_shutdown_magic(Job
*j
);
218 int job_get_timeout(Job
*j
, usec_t
*timeout
) _pure_
;
220 bool job_may_gc(Job
*j
);
221 void job_add_to_gc_queue(Job
*j
);
223 int job_get_before(Job
*j
, Job
*** ret
);
224 int job_get_after(Job
*j
, Job
*** ret
);
226 const char* job_type_to_string(JobType t
) _const_
;
227 JobType
job_type_from_string(const char *s
) _pure_
;
229 const char* job_state_to_string(JobState t
) _const_
;
230 JobState
job_state_from_string(const char *s
) _pure_
;
232 const char* job_mode_to_string(JobMode t
) _const_
;
233 JobMode
job_mode_from_string(const char *s
) _pure_
;
235 const char* job_result_to_string(JobResult t
) _const_
;
236 JobResult
job_result_from_string(const char *s
) _pure_
;
238 const char* job_type_to_access_method(JobType t
);