1 /* SPDX-License-Identifier: LGPL-2.1+ */
5 This file is part of systemd.
7 Copyright 2010 Lennart Poettering
15 #include "unit-name.h"
17 typedef struct Job Job
;
18 typedef struct JobDependency JobDependency
;
19 typedef enum JobType JobType
;
20 typedef enum JobState JobState
;
21 typedef enum JobMode JobMode
;
22 typedef enum JobResult JobResult
;
24 /* Be careful when changing the job types! Adjust job_merging_table[] accordingly! */
26 JOB_START
, /* if a unit does not support being started, we'll just wait until it becomes active */
31 JOB_RELOAD
, /* if running, reload */
33 /* Note that restarts are first treated like JOB_STOP, but
34 * then instead of finishing are patched to become
36 JOB_RESTART
, /* If running, stop. Then start unconditionally. */
38 _JOB_TYPE_MAX_MERGING
,
40 /* JOB_NOP can enter into a transaction, but as it won't pull in
41 * any dependencies and it uses the special 'nop_job' slot in Unit,
42 * it won't have to merge with anything (except possibly into another
43 * JOB_NOP, previously installed). JOB_NOP is special-cased in
44 * job_type_is_*() functions so that the transaction can be
46 JOB_NOP
= _JOB_TYPE_MAX_MERGING
, /* do nothing */
48 _JOB_TYPE_MAX_IN_TRANSACTION
,
50 /* JOB_TRY_RESTART can never appear in a transaction, because
51 * it always collapses into JOB_RESTART or JOB_NOP before entering.
52 * Thus we never need to merge it with anything. */
53 JOB_TRY_RESTART
= _JOB_TYPE_MAX_IN_TRANSACTION
, /* if running, stop and then start */
55 /* Similar to JOB_TRY_RESTART but collapses to JOB_RELOAD or JOB_NOP */
58 /* JOB_RELOAD_OR_START won't enter into a transaction and cannot result
59 * from transaction merging (there's no way for JOB_RELOAD and
60 * JOB_START to meet in one transaction). It can result from a merge
61 * during job installation, but then it will immediately collapse into
62 * one of the two simpler types. */
63 JOB_RELOAD_OR_START
, /* if running, reload, otherwise start */
66 _JOB_TYPE_INVALID
= -1
73 _JOB_STATE_INVALID
= -1
77 JOB_FAIL
, /* Fail if a conflicting job is already queued */
78 JOB_REPLACE
, /* Replace an existing conflicting job */
79 JOB_REPLACE_IRREVERSIBLY
,/* Like JOB_REPLACE + produce irreversible jobs */
80 JOB_ISOLATE
, /* Start a unit, and stop all others */
81 JOB_FLUSH
, /* Flush out all other queued jobs when queing this one */
82 JOB_IGNORE_DEPENDENCIES
, /* Ignore both requirement and ordering dependencies */
83 JOB_IGNORE_REQUIREMENTS
, /* Ignore requirement dependencies */
85 _JOB_MODE_INVALID
= -1
89 JOB_DONE
, /* Job completed successfully */
90 JOB_CANCELED
, /* Job canceled by a conflicting job installation or by explicit cancel request */
91 JOB_TIMEOUT
, /* Job timeout elapsed */
92 JOB_FAILED
, /* Job failed */
93 JOB_DEPENDENCY
, /* A required dependency job did not result in JOB_DONE */
94 JOB_SKIPPED
, /* Negative result of JOB_VERIFY_ACTIVE */
95 JOB_INVALID
, /* JOB_RELOAD of inactive unit */
96 JOB_ASSERT
, /* Couldn't start a unit, because an assert didn't hold */
97 JOB_UNSUPPORTED
, /* Couldn't start a unit, because the unit type is not supported on the system */
98 JOB_COLLECTED
, /* Job was garbage collected, since nothing needed it anymore */
100 _JOB_RESULT_INVALID
= -1
105 struct JobDependency
{
106 /* Encodes that the 'subject' job needs the 'object' job in
107 * some way. This structure is used only while building a transaction. */
111 LIST_FIELDS(JobDependency
, subject
);
112 LIST_FIELDS(JobDependency
, object
);
122 LIST_FIELDS(Job
, transaction
);
123 LIST_FIELDS(Job
, run_queue
);
124 LIST_FIELDS(Job
, dbus_queue
);
125 LIST_FIELDS(Job
, gc_queue
);
127 LIST_HEAD(JobDependency
, subject_list
);
128 LIST_HEAD(JobDependency
, object_list
);
130 /* Used for graph algs as a "I have been here" marker */
139 sd_event_source
*timer_event_source
;
141 usec_t begin_running_usec
;
144 * This tracks where to send signals, and also which clients
145 * are allowed to call DBus methods on the job (other than
148 * There can be more than one client, because of job merging.
150 sd_bus_track
*bus_track
;
151 char **deserialized_clients
;
157 bool matters_to_anchor
:1;
158 bool in_dbus_queue
:1;
159 bool sent_dbus_new_signal
:1;
163 bool ref_by_private_bus
:1;
166 Job
* job_new(Unit
*unit
, JobType type
);
167 Job
* job_new_raw(Unit
*unit
);
168 void job_free(Job
*job
);
169 Job
* job_install(Job
*j
);
170 int job_install_deserialized(Job
*j
);
171 void job_uninstall(Job
*j
);
172 void job_dump(Job
*j
, FILE*f
, const char *prefix
);
173 int job_serialize(Job
*j
, FILE *f
);
174 int job_deserialize(Job
*j
, FILE *f
);
175 int job_coldplug(Job
*j
);
177 JobDependency
* job_dependency_new(Job
*subject
, Job
*object
, bool matters
, bool conflicts
);
178 void job_dependency_free(JobDependency
*l
);
180 int job_merge(Job
*j
, Job
*other
);
182 JobType
job_type_lookup_merge(JobType a
, JobType b
) _pure_
;
184 _pure_
static inline bool job_type_is_mergeable(JobType a
, JobType b
) {
185 return job_type_lookup_merge(a
, b
) >= 0;
188 _pure_
static inline bool job_type_is_conflicting(JobType a
, JobType b
) {
189 return a
!= JOB_NOP
&& b
!= JOB_NOP
&& !job_type_is_mergeable(a
, b
);
192 _pure_
static inline bool job_type_is_superset(JobType a
, JobType b
) {
193 /* Checks whether operation a is a "superset" of b in its actions */
198 return a
== job_type_lookup_merge(a
, b
);
201 bool job_type_is_redundant(JobType a
, UnitActiveState b
) _pure_
;
203 /* Collapses a state-dependent job type into a simpler type by observing
204 * the state of the unit which it is going to be applied to. */
205 JobType
job_type_collapse(JobType t
, Unit
*u
);
207 int job_type_merge_and_collapse(JobType
*a
, JobType b
, Unit
*u
);
209 void job_add_to_run_queue(Job
*j
);
210 void job_add_to_dbus_queue(Job
*j
);
212 int job_start_timer(Job
*j
, bool job_running
);
214 int job_run_and_invalidate(Job
*j
);
215 int job_finish_and_invalidate(Job
*j
, JobResult result
, bool recursive
, bool already
);
217 char *job_dbus_path(Job
*j
);
219 void job_shutdown_magic(Job
*j
);
221 int job_get_timeout(Job
*j
, usec_t
*timeout
) _pure_
;
223 bool job_may_gc(Job
*j
);
224 void job_add_to_gc_queue(Job
*j
);
226 int job_get_before(Job
*j
, Job
*** ret
);
227 int job_get_after(Job
*j
, Job
*** ret
);
229 const char* job_type_to_string(JobType t
) _const_
;
230 JobType
job_type_from_string(const char *s
) _pure_
;
232 const char* job_state_to_string(JobState t
) _const_
;
233 JobState
job_state_from_string(const char *s
) _pure_
;
235 const char* job_mode_to_string(JobMode t
) _const_
;
236 JobMode
job_mode_from_string(const char *s
) _pure_
;
238 const char* job_result_to_string(JobResult t
) _const_
;
239 JobResult
job_result_from_string(const char *s
) _pure_
;
241 const char* job_type_to_access_method(JobType t
);