]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/job.h
udev: use interface before the string that interface points to is freed by device_add...
[thirdparty/systemd.git] / src / core / job.h
CommitLineData
c2f1db8f 1#pragma once
60918275 2
a7334b09
LP
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
a7334b09
LP
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 16 Lesser General Public License for more details.
a7334b09 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
60918275 22#include <stdbool.h>
60918275 23
07630cea
LP
24#include "sd-event.h"
25
26#include "list.h"
71d35b6b 27#include "unit-name.h"
07630cea 28
60918275 29typedef struct Job Job;
e5b5ae50 30typedef struct JobDependency JobDependency;
60918275 31typedef enum JobType JobType;
e5b5ae50 32typedef enum JobState JobState;
5cb5a6ff 33typedef enum JobMode JobMode;
5d44db4a 34typedef enum JobResult JobResult;
60918275 35
348e27fe 36/* Be careful when changing the job types! Adjust job_merging_table[] accordingly! */
60918275 37enum JobType {
87f0e418 38 JOB_START, /* if a unit does not support being started, we'll just wait until it becomes active */
5cb5a6ff
LP
39 JOB_VERIFY_ACTIVE,
40
60918275 41 JOB_STOP,
5cb5a6ff 42
e0209d83 43 JOB_RELOAD, /* if running, reload */
5cb5a6ff
LP
44
45 /* Note that restarts are first treated like JOB_STOP, but
46 * then instead of finishing are patched to become
47 * JOB_START. */
e0209d83
MS
48 JOB_RESTART, /* If running, stop. Then start unconditionally. */
49
50 _JOB_TYPE_MAX_MERGING,
51
52 /* JOB_NOP can enter into a transaction, but as it won't pull in
7e803f5e
MS
53 * any dependencies and it uses the special 'nop_job' slot in Unit,
54 * it won't have to merge with anything (except possibly into another
55 * JOB_NOP, previously installed). JOB_NOP is special-cased in
56 * job_type_is_*() functions so that the transaction can be
57 * activated. */
e0209d83
MS
58 JOB_NOP = _JOB_TYPE_MAX_MERGING, /* do nothing */
59
60 _JOB_TYPE_MAX_IN_TRANSACTION,
61
62 /* JOB_TRY_RESTART can never appear in a transaction, because
63 * it always collapses into JOB_RESTART or JOB_NOP before entering.
64 * Thus we never need to merge it with anything. */
65 JOB_TRY_RESTART = _JOB_TYPE_MAX_IN_TRANSACTION, /* if running, stop and then start */
66
3282591d
LP
67 /* Similar to JOB_TRY_RESTART but collapses to JOB_RELOAD or JOB_NOP */
68 JOB_TRY_RELOAD,
69
e0209d83
MS
70 /* JOB_RELOAD_OR_START won't enter into a transaction and cannot result
71 * from transaction merging (there's no way for JOB_RELOAD and
72 * JOB_START to meet in one transaction). It can result from a merge
73 * during job installation, but then it will immediately collapse into
74 * one of the two simpler types. */
75 JOB_RELOAD_OR_START, /* if running, reload, otherwise start */
5cb5a6ff 76
e5b5ae50
LP
77 _JOB_TYPE_MAX,
78 _JOB_TYPE_INVALID = -1
60918275
LP
79};
80
e5b5ae50 81enum JobState {
60918275
LP
82 JOB_WAITING,
83 JOB_RUNNING,
94f04347
LP
84 _JOB_STATE_MAX,
85 _JOB_STATE_INVALID = -1
e5b5ae50 86};
60918275
LP
87
88enum JobMode {
cebe0d41
LP
89 JOB_FAIL, /* Fail if a conflicting job is already queued */
90 JOB_REPLACE, /* Replace an existing conflicting job */
d420282b 91 JOB_REPLACE_IRREVERSIBLY,/* Like JOB_REPLACE + produce irreversible jobs */
cebe0d41 92 JOB_ISOLATE, /* Start a unit, and stop all others */
255baef6 93 JOB_FLUSH, /* Flush out all other queued jobs when queing this one */
cebe0d41
LP
94 JOB_IGNORE_DEPENDENCIES, /* Ignore both requirement and ordering dependencies */
95 JOB_IGNORE_REQUIREMENTS, /* Ignore requirement dependencies */
b548631a
LP
96 _JOB_MODE_MAX,
97 _JOB_MODE_INVALID = -1
60918275
LP
98};
99
5d44db4a 100enum JobResult {
65eb544e
MS
101 JOB_DONE, /* Job completed successfully */
102 JOB_CANCELED, /* Job canceled by a conflicting job installation or by explicit cancel request */
0faacd47 103 JOB_TIMEOUT, /* Job timeout elapsed */
65eb544e
MS
104 JOB_FAILED, /* Job failed */
105 JOB_DEPENDENCY, /* A required dependency job did not result in JOB_DONE */
6a371e23
ZJS
106 JOB_SKIPPED, /* Negative result of JOB_VERIFY_ACTIVE */
107 JOB_INVALID, /* JOB_RELOAD of inactive unit */
59fccdc5 108 JOB_ASSERT, /* Couldn't start a unit, because an assert didn't hold */
0faacd47 109 JOB_UNSUPPORTED, /* Couldn't start a unit, because the unit type is not supported on the system */
c5a97ed1 110 JOB_COLLECTED, /* Job was garbage collected, since nothing needed it anymore */
5d44db4a
LP
111 _JOB_RESULT_MAX,
112 _JOB_RESULT_INVALID = -1
113};
114
c6918296 115#include "unit.h"
c6918296 116
e5b5ae50
LP
117struct JobDependency {
118 /* Encodes that the 'subject' job needs the 'object' job in
119 * some way. This structure is used only while building a transaction. */
120 Job *subject;
121 Job *object;
122
034c6ed7
LP
123 LIST_FIELDS(JobDependency, subject);
124 LIST_FIELDS(JobDependency, object);
9d58f1db 125
0a23a627
LP
126 bool matters:1;
127 bool conflicts:1;
e5b5ae50
LP
128};
129
60918275
LP
130struct Job {
131 Manager *manager;
87f0e418 132 Unit *unit;
e5b5ae50 133
034c6ed7
LP
134 LIST_FIELDS(Job, transaction);
135 LIST_FIELDS(Job, run_queue);
c1e1601e 136 LIST_FIELDS(Job, dbus_queue);
c5a97ed1 137 LIST_FIELDS(Job, gc_queue);
e5b5ae50 138
44d8db9e
LP
139 LIST_HEAD(JobDependency, subject_list);
140 LIST_HEAD(JobDependency, object_list);
e5b5ae50 141
5cb5a6ff 142 /* Used for graph algs as a "I have been here" marker */
e5b5ae50
LP
143 Job* marker;
144 unsigned generation;
034c6ed7 145
9d58f1db
LP
146 uint32_t id;
147
148 JobType type;
149 JobState state;
150
718db961
LP
151 sd_event_source *timer_event_source;
152 usec_t begin_usec;
faf919f1 153
b39a2770
SW
154 /*
155 * This tracks where to send signals, and also which clients
156 * are allowed to call DBus methods on the job (other than
157 * root).
158 *
159 * There can be more than one client, because of job merging.
160 */
1a465207 161 sd_bus_track *bus_track;
b39a2770 162 char **deserialized_clients;
a567261a 163
5d44db4a
LP
164 JobResult result;
165
9d58f1db
LP
166 bool installed:1;
167 bool in_run_queue:1;
168 bool matters_to_anchor:1;
9d58f1db
LP
169 bool in_dbus_queue:1;
170 bool sent_dbus_new_signal:1;
cebe0d41 171 bool ignore_order:1;
23ade460 172 bool irreversible:1;
c5a97ed1
LP
173 bool in_gc_queue:1;
174 bool ref_by_private_bus:1;
60918275
LP
175};
176
668ad332 177Job* job_new(Unit *unit, JobType type);
39a18c60 178Job* job_new_raw(Unit *unit);
60918275 179void job_free(Job *job);
656bbffc 180Job* job_install(Job *j);
e0209d83 181int job_install_deserialized(Job *j);
05d576f1 182void job_uninstall(Job *j);
ceed3570 183void job_dump(Job *j, FILE*f, const char *prefix);
05a98afd
LP
184int job_serialize(Job *j, FILE *f);
185int job_deserialize(Job *j, FILE *f);
39a18c60 186int job_coldplug(Job *j);
60918275 187
1da4264f
MS
188JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts);
189void job_dependency_free(JobDependency *l);
e5b5ae50 190
e5b5ae50
LP
191int job_merge(Job *j, Job *other);
192
44a6b1b6 193JobType job_type_lookup_merge(JobType a, JobType b) _pure_;
348e27fe 194
44a6b1b6 195_pure_ static inline bool job_type_is_mergeable(JobType a, JobType b) {
348e27fe
MS
196 return job_type_lookup_merge(a, b) >= 0;
197}
198
44a6b1b6 199_pure_ static inline bool job_type_is_conflicting(JobType a, JobType b) {
7e803f5e 200 return a != JOB_NOP && b != JOB_NOP && !job_type_is_mergeable(a, b);
348e27fe
MS
201}
202
44a6b1b6 203_pure_ static inline bool job_type_is_superset(JobType a, JobType b) {
348e27fe 204 /* Checks whether operation a is a "superset" of b in its actions */
7e803f5e
MS
205 if (b == JOB_NOP)
206 return true;
207 if (a == JOB_NOP)
208 return false;
348e27fe
MS
209 return a == job_type_lookup_merge(a, b);
210}
211
44a6b1b6 212bool job_type_is_redundant(JobType a, UnitActiveState b) _pure_;
5cb5a6ff 213
e0209d83
MS
214/* Collapses a state-dependent job type into a simpler type by observing
215 * the state of the unit which it is going to be applied to. */
c6497ccb 216JobType job_type_collapse(JobType t, Unit *u);
e0209d83
MS
217
218int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u);
219
c1e1601e
LP
220void job_add_to_run_queue(Job *j);
221void job_add_to_dbus_queue(Job *j);
222
a2df3ea4 223int job_start_timer(Job *j, bool job_running);
faf919f1 224
5cb5a6ff 225int job_run_and_invalidate(Job *j);
833f92ad 226int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool already);
1ffba6fe 227
faf919f1
LP
228char *job_dbus_path(Job *j);
229
c65eb836
LP
230void job_shutdown_magic(Job *j);
231
7a7821c8
LP
232int job_get_timeout(Job *j, usec_t *timeout) _pure_;
233
c5a97ed1
LP
234bool job_check_gc(Job *j);
235void job_add_to_gc_queue(Job *j);
236
15ea79f8
LP
237int job_get_before(Job *j, Job*** ret);
238int job_get_after(Job *j, Job*** ret);
239
44a6b1b6
ZJS
240const char* job_type_to_string(JobType t) _const_;
241JobType job_type_from_string(const char *s) _pure_;
94f04347 242
44a6b1b6
ZJS
243const char* job_state_to_string(JobState t) _const_;
244JobState job_state_from_string(const char *s) _pure_;
94f04347 245
44a6b1b6
ZJS
246const char* job_mode_to_string(JobMode t) _const_;
247JobMode job_mode_from_string(const char *s) _pure_;
b548631a 248
44a6b1b6
ZJS
249const char* job_result_to_string(JobResult t) _const_;
250JobResult job_result_from_string(const char *s) _pure_;
68db7a3b 251
94bd7323 252const char* job_type_to_access_method(JobType t);