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