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 */
99 JOB_ONCE
, /* Unit was started before, and hence can't be started again */
101 _JOB_RESULT_INVALID
= -1
106 struct JobDependency
{
107 /* Encodes that the 'subject' job needs the 'object' job in
108 * some way. This structure is used only while building a transaction. */
112 LIST_FIELDS(JobDependency
, subject
);
113 LIST_FIELDS(JobDependency
, object
);
123 LIST_FIELDS(Job
, transaction
);
124 LIST_FIELDS(Job
, run_queue
);
125 LIST_FIELDS(Job
, dbus_queue
);
126 LIST_FIELDS(Job
, gc_queue
);
128 LIST_HEAD(JobDependency
, subject_list
);
129 LIST_HEAD(JobDependency
, object_list
);
131 /* Used for graph algs as a "I have been here" marker */
140 sd_event_source
*timer_event_source
;
142 usec_t begin_running_usec
;
145 * This tracks where to send signals, and also which clients
146 * are allowed to call DBus methods on the job (other than
149 * There can be more than one client, because of job merging.
151 sd_bus_track
*bus_track
;
152 char **deserialized_clients
;
158 bool matters_to_anchor
:1;
159 bool in_dbus_queue
:1;
160 bool sent_dbus_new_signal
:1;
164 bool ref_by_private_bus
:1;
167 Job
* job_new(Unit
*unit
, JobType type
);
168 Job
* job_new_raw(Unit
*unit
);
169 void job_free(Job
*job
);
170 Job
* job_install(Job
*j
);
171 int job_install_deserialized(Job
*j
);
172 void job_uninstall(Job
*j
);
173 void job_dump(Job
*j
, FILE*f
, const char *prefix
);
174 int job_serialize(Job
*j
, FILE *f
);
175 int job_deserialize(Job
*j
, FILE *f
);
176 int job_coldplug(Job
*j
);
178 JobDependency
* job_dependency_new(Job
*subject
, Job
*object
, bool matters
, bool conflicts
);
179 void job_dependency_free(JobDependency
*l
);
181 int job_merge(Job
*j
, Job
*other
);
183 JobType
job_type_lookup_merge(JobType a
, JobType b
) _pure_
;
185 _pure_
static inline bool job_type_is_mergeable(JobType a
, JobType b
) {
186 return job_type_lookup_merge(a
, b
) >= 0;
189 _pure_
static inline bool job_type_is_conflicting(JobType a
, JobType b
) {
190 return a
!= JOB_NOP
&& b
!= JOB_NOP
&& !job_type_is_mergeable(a
, b
);
193 _pure_
static inline bool job_type_is_superset(JobType a
, JobType b
) {
194 /* Checks whether operation a is a "superset" of b in its actions */
199 return a
== job_type_lookup_merge(a
, b
);
202 bool job_type_is_redundant(JobType a
, UnitActiveState b
) _pure_
;
204 /* Collapses a state-dependent job type into a simpler type by observing
205 * the state of the unit which it is going to be applied to. */
206 JobType
job_type_collapse(JobType t
, Unit
*u
);
208 int job_type_merge_and_collapse(JobType
*a
, JobType b
, Unit
*u
);
210 void job_add_to_run_queue(Job
*j
);
211 void job_add_to_dbus_queue(Job
*j
);
213 int job_start_timer(Job
*j
, bool job_running
);
215 int job_run_and_invalidate(Job
*j
);
216 int job_finish_and_invalidate(Job
*j
, JobResult result
, bool recursive
, bool already
);
218 char *job_dbus_path(Job
*j
);
220 void job_shutdown_magic(Job
*j
);
222 int job_get_timeout(Job
*j
, usec_t
*timeout
) _pure_
;
224 bool job_may_gc(Job
*j
);
225 void job_add_to_gc_queue(Job
*j
);
227 int job_get_before(Job
*j
, Job
*** ret
);
228 int job_get_after(Job
*j
, Job
*** ret
);
230 const char* job_type_to_string(JobType t
) _const_
;
231 JobType
job_type_from_string(const char *s
) _pure_
;
233 const char* job_state_to_string(JobState t
) _const_
;
234 JobState
job_state_from_string(const char *s
) _pure_
;
236 const char* job_mode_to_string(JobMode t
) _const_
;
237 JobMode
job_mode_from_string(const char *s
) _pure_
;
239 const char* job_result_to_string(JobResult t
) _const_
;
240 JobResult
job_result_from_string(const char *s
) _pure_
;
242 const char* job_type_to_access_method(JobType t
);