]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/job.c
tree-wide: use ASSERT_PTR more
[thirdparty/systemd.git] / src / core / job.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
a7334b09 2
1ffba6fe 3#include <errno.h>
60918275 4
718db961
LP
5#include "sd-id128.h"
6#include "sd-messages.h"
4f5dd394 7
b5efdb8a 8#include "alloc-util.h"
f485606b 9#include "async.h"
da8e1782 10#include "cgroup.h"
4f5dd394 11#include "dbus-job.h"
8f8f05a9 12#include "dbus.h"
4f5dd394 13#include "escape.h"
8948b341 14#include "fileio.h"
6bedfcbb 15#include "job.h"
4f5dd394
LP
16#include "log.h"
17#include "macro.h"
6bedfcbb 18#include "parse-util.h"
d68c645b 19#include "serialize.h"
4f5dd394 20#include "set.h"
760877e9 21#include "sort-util.h"
4f5dd394 22#include "special.h"
d054f0a4 23#include "stdio-util.h"
8b43440b 24#include "string-table.h"
07630cea 25#include "string-util.h"
4f5dd394 26#include "strv.h"
288a74cc 27#include "terminal-util.h"
4f5dd394
LP
28#include "unit.h"
29#include "virt.h"
97e6a119 30
39a18c60 31Job* job_new_raw(Unit *unit) {
60918275
LP
32 Job *j;
33
39a18c60
MS
34 /* used for deserialization */
35
87f0e418 36 assert(unit);
60918275 37
08ac00f2 38 j = new(Job, 1);
39a18c60 39 if (!j)
60918275
LP
40 return NULL;
41
08ac00f2
LP
42 *j = (Job) {
43 .manager = unit->manager,
44 .unit = unit,
45 .type = _JOB_TYPE_INVALID,
46 };
faf919f1 47
39a18c60
MS
48 return j;
49}
50
51Job* job_new(Unit *unit, JobType type) {
52 Job *j;
53
54 assert(type < _JOB_TYPE_MAX);
55
56 j = job_new_raw(unit);
57 if (!j)
58 return NULL;
59
60 j->id = j->manager->current_job_id++;
61 j->type = type;
62
e5b5ae50 63 /* We don't link it here, that's what job_dependency() is for */
60918275
LP
64
65 return j;
66}
67
a7a7163d 68void job_unlink(Job *j) {
97e7d748
MS
69 assert(j);
70 assert(!j->installed);
02a3bcc6
MS
71 assert(!j->transaction_prev);
72 assert(!j->transaction_next);
73 assert(!j->subject_list);
74 assert(!j->object_list);
60918275 75
a7a7163d 76 if (j->in_run_queue) {
da8e1782 77 prioq_remove(j->manager->run_queue, j, &j->run_queue_idx);
a7a7163d
DT
78 j->in_run_queue = false;
79 }
c1e1601e 80
a7a7163d 81 if (j->in_dbus_queue) {
71fda00f 82 LIST_REMOVE(dbus_queue, j->manager->dbus_job_queue, j);
a7a7163d
DT
83 j->in_dbus_queue = false;
84 }
c1e1601e 85
a7a7163d 86 if (j->in_gc_queue) {
c5a97ed1 87 LIST_REMOVE(gc_queue, j->manager->gc_job_queue, j);
a7a7163d
DT
88 j->in_gc_queue = false;
89 }
c5a97ed1 90
5dcadb4c 91 j->timer_event_source = sd_event_source_disable_unref(j->timer_event_source);
a7a7163d
DT
92}
93
728ba51e 94Job* job_free(Job *j) {
a7a7163d
DT
95 assert(j);
96 assert(!j->installed);
97 assert(!j->transaction_prev);
98 assert(!j->transaction_next);
99 assert(!j->subject_list);
100 assert(!j->object_list);
101
102 job_unlink(j);
faf919f1 103
1a465207 104 sd_bus_track_unref(j->bus_track);
b39a2770 105 strv_free(j->deserialized_clients);
faf919f1 106
48b92b37
LB
107 activation_details_unref(j->activation_details);
108
728ba51e 109 return mfree(j);
60918275 110}
a66d02c3 111
9c3349e2
LP
112static void job_set_state(Job *j, JobState state) {
113 assert(j);
114 assert(state >= 0);
115 assert(state < _JOB_STATE_MAX);
116
117 if (j->state == state)
118 return;
119
120 j->state = state;
121
122 if (!j->installed)
123 return;
124
125 if (j->state == JOB_RUNNING)
126 j->unit->manager->n_running_jobs++;
127 else {
128 assert(j->state == JOB_WAITING);
129 assert(j->unit->manager->n_running_jobs > 0);
130
131 j->unit->manager->n_running_jobs--;
132
133 if (j->unit->manager->n_running_jobs <= 0)
5dcadb4c 134 j->unit->manager->jobs_in_progress_event_source = sd_event_source_disable_unref(j->unit->manager->jobs_in_progress_event_source);
9c3349e2
LP
135 }
136}
137
05d576f1 138void job_uninstall(Job *j) {
e0209d83
MS
139 Job **pj;
140
05d576f1 141 assert(j->installed);
e0209d83 142
9c3349e2
LP
143 job_set_state(j, JOB_WAITING);
144
e0209d83
MS
145 pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
146 assert(*pj == j);
147
05d576f1
MS
148 /* Detach from next 'bigger' objects */
149
39a18c60 150 /* daemon-reload should be transparent to job observers */
2c289ea8 151 if (!MANAGER_IS_RELOADING(j->manager))
39a18c60 152 bus_job_send_removed_signal(j);
05d576f1 153
e0209d83
MS
154 *pj = NULL;
155
d6a093d0 156 unit_add_to_gc_queue(j->unit);
05d576f1 157
52c6c9ea
AM
158 unit_add_to_dbus_queue(j->unit); /* The Job property of the unit has changed now */
159
48235ad6 160 hashmap_remove_value(j->manager->jobs, UINT32_TO_PTR(j->id), j);
05d576f1
MS
161 j->installed = false;
162}
163
656bbffc
MS
164static bool job_type_allows_late_merge(JobType t) {
165 /* Tells whether it is OK to merge a job of type 't' with an already
166 * running job.
167 * Reloads cannot be merged this way. Think of the sequence:
168 * 1. Reload of a daemon is in progress; the daemon has already loaded
169 * its config file, but hasn't completed the reload operation yet.
170 * 2. Edit foo's config file.
171 * 3. Trigger another reload to have the daemon use the new config.
172 * Should the second reload job be merged into the first one, the daemon
173 * would not know about the new config.
174 * JOB_RESTART jobs on the other hand can be merged, because they get
175 * patched into JOB_START after stopping the unit. So if we see a
176 * JOB_RESTART running, it means the unit hasn't stopped yet and at
177 * this time the merge is still allowed. */
e0209d83 178 return t != JOB_RELOAD;
656bbffc
MS
179}
180
181static void job_merge_into_installed(Job *j, Job *other) {
182 assert(j->installed);
183 assert(j->unit == other->unit);
184
48b92b37 185 if (j->type != JOB_NOP) {
53a2383b 186 assert_se(job_type_merge_and_collapse(&j->type, other->type, j->unit) == 0);
48b92b37
LB
187
188 /* Keep the oldest ActivationDetails, if any */
189 if (!j->activation_details)
190 j->activation_details = TAKE_PTR(other->activation_details);
191 } else
e0209d83 192 assert(other->type == JOB_NOP);
656bbffc 193
23ade460 194 j->irreversible = j->irreversible || other->irreversible;
e45460d6 195 j->ignore_order = j->ignore_order || other->ignore_order;
656bbffc
MS
196}
197
198Job* job_install(Job *j) {
e0209d83
MS
199 Job **pj;
200 Job *uj;
05d576f1 201
656bbffc 202 assert(!j->installed);
e0209d83 203 assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
9c3349e2 204 assert(j->state == JOB_WAITING);
e0209d83
MS
205
206 pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
207 uj = *pj;
656bbffc 208
05d576f1 209 if (uj) {
61da906a 210 if (job_type_is_conflicting(uj->type, j->type))
833f92ad 211 job_finish_and_invalidate(uj, JOB_CANCELED, false, false);
656bbffc
MS
212 else {
213 /* not conflicting, i.e. mergeable */
214
61da906a 215 if (uj->state == JOB_WAITING ||
656bbffc
MS
216 (job_type_allows_late_merge(j->type) && job_type_is_superset(uj->type, j->type))) {
217 job_merge_into_installed(uj, j);
f2341e0a 218 log_unit_debug(uj->unit,
28d78d07 219 "Merged %s/%s into installed job %s/%s as %"PRIu32,
92e29d82 220 j->unit->id, job_type_to_string(j->type), uj->unit->id,
28d78d07 221 job_type_to_string(uj->type), uj->id);
656bbffc
MS
222 return uj;
223 } else {
224 /* already running and not safe to merge into */
225 /* Patch uj to become a merged job and re-run it. */
226 /* XXX It should be safer to queue j to run after uj finishes, but it is
227 * not currently possible to have more than one installed job per unit. */
228 job_merge_into_installed(uj, j);
f2341e0a 229 log_unit_debug(uj->unit,
28d78d07
JK
230 "Merged into running job, re-running: %s/%s as %"PRIu32,
231 uj->unit->id, job_type_to_string(uj->type), uj->id);
9c3349e2
LP
232
233 job_set_state(uj, JOB_WAITING);
656bbffc
MS
234 return uj;
235 }
236 }
05d576f1
MS
237 }
238
656bbffc 239 /* Install the job */
e0209d83 240 *pj = j;
05d576f1 241 j->installed = true;
9c3349e2 242
313cefa1 243 j->manager->n_installed_jobs++;
f2341e0a 244 log_unit_debug(j->unit,
66870f90
ZJS
245 "Installed new job %s/%s as %u",
246 j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
c5a97ed1
LP
247
248 job_add_to_gc_queue(j);
249
e6d05912
LP
250 job_add_to_dbus_queue(j); /* announce this job to clients */
251 unit_add_to_dbus_queue(j->unit); /* The Job property of the unit has changed now */
252
656bbffc 253 return j;
05d576f1
MS
254}
255
e0209d83
MS
256int job_install_deserialized(Job *j) {
257 Job **pj;
b17c9620 258 int r;
e0209d83 259
39a18c60
MS
260 assert(!j->installed);
261
baaa35ad 262 if (j->type < 0 || j->type >= _JOB_TYPE_MAX_IN_TRANSACTION)
b17c9620 263 return log_unit_debug_errno(j->unit, SYNTHETIC_ERRNO(EINVAL),
baaa35ad
ZJS
264 "Invalid job type %s in deserialization.",
265 strna(job_type_to_string(j->type)));
e0209d83
MS
266
267 pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
b17c9620
LP
268 if (*pj)
269 return log_unit_debug_errno(j->unit, SYNTHETIC_ERRNO(EEXIST),
270 "Unit already has a job installed. Not installing deserialized job.");
271
53dba3ef 272 r = hashmap_ensure_put(&j->manager->jobs, NULL, UINT32_TO_PTR(j->id), j);
b17c9620
LP
273 if (r == -EEXIST)
274 return log_unit_debug_errno(j->unit, r, "Job ID %" PRIu32 " already used, cannot deserialize job.", j->id);
275 if (r < 0)
276 return log_unit_debug_errno(j->unit, r, "Failed to insert job into jobs hash table: %m");
9c3349e2 277
e0209d83 278 *pj = j;
39a18c60 279 j->installed = true;
9c3349e2
LP
280
281 if (j->state == JOB_RUNNING)
282 j->unit->manager->n_running_jobs++;
283
f2341e0a 284 log_unit_debug(j->unit,
66870f90
ZJS
285 "Reinstalled deserialized job %s/%s as %u",
286 j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
e0209d83 287 return 0;
39a18c60
MS
288}
289
1da4264f 290JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts) {
e5b5ae50
LP
291 JobDependency *l;
292
293 assert(object);
294
295 /* Adds a new job link, which encodes that the 'subject' job
296 * needs the 'object' job in some way. If 'subject' is NULL
297 * this means the 'anchor' job (i.e. the one the user
35b8ca3a 298 * explicitly asked for) is the requester. */
e5b5ae50 299
0a23a627
LP
300 l = new0(JobDependency, 1);
301 if (!l)
e5b5ae50
LP
302 return NULL;
303
304 l->subject = subject;
305 l->object = object;
306 l->matters = matters;
69dd2852 307 l->conflicts = conflicts;
e5b5ae50 308
44d8db9e 309 if (subject)
71fda00f 310 LIST_PREPEND(subject, subject->subject_list, l);
e5b5ae50 311
71fda00f 312 LIST_PREPEND(object, object->object_list, l);
e5b5ae50
LP
313
314 return l;
315}
316
1da4264f 317void job_dependency_free(JobDependency *l) {
e5b5ae50
LP
318 assert(l);
319
44d8db9e 320 if (l->subject)
71fda00f 321 LIST_REMOVE(subject, l->subject->subject_list, l);
e5b5ae50 322
71fda00f 323 LIST_REMOVE(object, l->object->object_list, l);
e5b5ae50
LP
324
325 free(l);
326}
327
f2a3de01 328void job_dump(Job *j, FILE *f, const char *prefix) {
a66d02c3
LP
329 assert(j);
330 assert(f);
331
ad5d4b17 332 prefix = strempty(prefix);
9eb63b3c 333
ceed3570 334 fprintf(f,
40d50879
LP
335 "%s-> Job %u:\n"
336 "%s\tAction: %s -> %s\n"
5cb5a6ff 337 "%s\tState: %s\n"
f698d99c
ZJS
338 "%s\tIrreversible: %s\n"
339 "%s\tMay GC: %s\n",
ceed3570 340 prefix, j->id,
ac155bb8 341 prefix, j->unit->id, job_type_to_string(j->type),
94f04347 342 prefix, job_state_to_string(j->state),
f698d99c
ZJS
343 prefix, yes_no(j->irreversible),
344 prefix, yes_no(job_may_gc(j)));
a66d02c3 345}
e5b5ae50 346
348e27fe
MS
347/*
348 * Merging is commutative, so imagine the matrix as symmetric. We store only
349 * its lower triangle to avoid duplication. We don't store the main diagonal,
350 * because A merged with A is simply A.
351 *
e0209d83
MS
352 * If the resulting type is collapsed immediately afterwards (to get rid of
353 * the JOB_RELOAD_OR_START, which lies outside the lookup function's domain),
354 * the following properties hold:
355 *
48b4eab4 356 * Merging is associative! A merged with B, and then merged with C is the same
103635db 357 * as A merged with the result of B merged with C.
348e27fe
MS
358 *
359 * Mergeability is transitive! If A can be merged with B and B with C then
360 * A also with C.
361 *
362 * Also, if A merged with B cannot be merged with C, then either A or B cannot
363 * be merged with C either.
364 */
365static const JobType job_merging_table[] = {
e0209d83
MS
366/* What \ With * JOB_START JOB_VERIFY_ACTIVE JOB_STOP JOB_RELOAD */
367/*********************************************************************************/
348e27fe
MS
368/*JOB_START */
369/*JOB_VERIFY_ACTIVE */ JOB_START,
370/*JOB_STOP */ -1, -1,
371/*JOB_RELOAD */ JOB_RELOAD_OR_START, JOB_RELOAD, -1,
e0209d83 372/*JOB_RESTART */ JOB_RESTART, JOB_RESTART, -1, JOB_RESTART,
348e27fe
MS
373};
374
375JobType job_type_lookup_merge(JobType a, JobType b) {
e0209d83
MS
376 assert_cc(ELEMENTSOF(job_merging_table) == _JOB_TYPE_MAX_MERGING * (_JOB_TYPE_MAX_MERGING - 1) / 2);
377 assert(a >= 0 && a < _JOB_TYPE_MAX_MERGING);
378 assert(b >= 0 && b < _JOB_TYPE_MAX_MERGING);
1ffba6fe
LP
379
380 if (a == b)
348e27fe 381 return a;
1ffba6fe 382
348e27fe
MS
383 if (a < b) {
384 JobType tmp = a;
385 a = b;
386 b = tmp;
1ffba6fe 387 }
e094e853 388
348e27fe 389 return job_merging_table[(a - 1) * a / 2 + b];
e094e853 390}
cd2dbd7d 391
cc479760
DR
392bool job_type_is_redundant(JobType a, UnitActiveState b) {
393 switch (a) {
593fbdd2
LP
394
395 case JOB_START:
cc479760 396 return IN_SET(b, UNIT_ACTIVE, UNIT_RELOADING);
593fbdd2
LP
397
398 case JOB_STOP:
cc479760 399 return IN_SET(b, UNIT_INACTIVE, UNIT_FAILED);
593fbdd2
LP
400
401 case JOB_VERIFY_ACTIVE:
cc479760 402 return IN_SET(b, UNIT_ACTIVE, UNIT_RELOADING);
593fbdd2
LP
403
404 case JOB_RELOAD:
405 return
cc479760 406 b == UNIT_RELOADING;
593fbdd2 407
593fbdd2 408 case JOB_RESTART:
dc06321f
AS
409 /* Restart jobs must always be kept.
410 *
411 * For ACTIVE/RELOADING units, this is obvious.
412 *
413 * For ACTIVATING units, it's more subtle:
414 *
415 * Generally, if a service Requires= another unit, restarts of
416 * the unit must be propagated to the service. If the service is
417 * ACTIVATING, it must still be restarted since it might have
418 * stale information regarding the other unit.
419 *
420 * For example, consider a service that Requires= a socket: if
421 * the socket is restarted, but the service is still ACTIVATING,
422 * it's necessary to restart the service so that it gets the new
423 * socket. */
424 return false;
593fbdd2 425
7e803f5e
MS
426 case JOB_NOP:
427 return true;
428
e0209d83 429 default:
04499a70 430 assert_not_reached();
e0209d83
MS
431 }
432}
433
c6497ccb 434JobType job_type_collapse(JobType t, Unit *u) {
e0209d83
MS
435 UnitActiveState s;
436
c6497ccb 437 switch (t) {
e0209d83 438
593fbdd2 439 case JOB_TRY_RESTART:
dc06321f
AS
440 /* Be sure to keep the restart job even if the unit is
441 * ACTIVATING.
442 *
443 * See the job_type_is_redundant(JOB_RESTART) for more info */
e0209d83 444 s = unit_active_state(u);
dc06321f 445 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(s))
c6497ccb
LP
446 return JOB_NOP;
447
448 return JOB_RESTART;
e0209d83 449
3282591d
LP
450 case JOB_TRY_RELOAD:
451 s = unit_active_state(u);
d1559793 452 if (!UNIT_IS_ACTIVE_OR_RELOADING(s))
3282591d
LP
453 return JOB_NOP;
454
455 return JOB_RELOAD;
456
e0209d83
MS
457 case JOB_RELOAD_OR_START:
458 s = unit_active_state(u);
d1559793 459 if (!UNIT_IS_ACTIVE_OR_RELOADING(s))
c6497ccb
LP
460 return JOB_START;
461
462 return JOB_RELOAD;
593fbdd2
LP
463
464 default:
c6497ccb 465 return t;
593fbdd2
LP
466 }
467}
468
e0209d83 469int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u) {
c6497ccb
LP
470 JobType t;
471
472 t = job_type_lookup_merge(*a, b);
e0209d83
MS
473 if (t < 0)
474 return -EEXIST;
c6497ccb
LP
475
476 *a = job_type_collapse(t, u);
e0209d83
MS
477 return 0;
478}
479
9588bc32 480static bool job_is_runnable(Job *j) {
87f0e418 481 Unit *other;
5cb5a6ff
LP
482
483 assert(j);
ac1135be 484 assert(j->installed);
5cb5a6ff 485
87f0e418 486 /* Checks whether there is any job running for the units this
5cb5a6ff 487 * job needs to be running after (in the case of a 'positive'
e67c3609
LP
488 * job type) or before (in the case of a 'negative' job
489 * type. */
490
66ca4ec4
LP
491 /* Note that unit types have a say in what is runnable,
492 * too. For example, if they return -EAGAIN from
493 * unit_start() they can indicate they are not
494 * runnable yet. */
495
e67c3609 496 /* First check if there is an override */
cebe0d41 497 if (j->ignore_order)
e67c3609 498 return true;
5cb5a6ff 499
e0209d83
MS
500 if (j->type == JOB_NOP)
501 return true;
502
15ed3c3a
LP
503 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_AFTER)
504 if (other->job && job_compare(j, other->job, UNIT_ATOM_AFTER) > 0) {
c03fbd37
LB
505 log_unit_debug(j->unit,
506 "starting held back, waiting for: %s",
507 other->id);
e602f152 508 return false;
c03fbd37 509 }
5cb5a6ff 510
15ed3c3a
LP
511 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_BEFORE)
512 if (other->job && job_compare(j, other->job, UNIT_ATOM_BEFORE) > 0) {
c03fbd37
LB
513 log_unit_debug(j->unit,
514 "stopping held back, waiting for: %s",
515 other->id);
5cb5a6ff 516 return false;
c03fbd37 517 }
5cb5a6ff 518
5cb5a6ff
LP
519 return true;
520}
521
bbd1a837 522static void job_change_type(Job *j, JobType newtype) {
f2341e0a
LP
523 assert(j);
524
525 log_unit_debug(j->unit,
66870f90
ZJS
526 "Converting job %s/%s -> %s/%s",
527 j->unit->id, job_type_to_string(j->type),
528 j->unit->id, job_type_to_string(newtype));
bbd1a837
MS
529
530 j->type = newtype;
531}
532
04d232d8 533static const char* job_start_message_format(Unit *u, JobType t) {
33a3fdd9 534 assert(u);
04d232d8 535 assert(IN_SET(t, JOB_START, JOB_STOP, JOB_RELOAD));
a69b3872
LP
536
537 if (t == JOB_RELOAD)
04d232d8
ZJS
538 return "Reloading %s...";
539 else if (t == JOB_START)
540 return UNIT_VTABLE(u)->status_message_formats.starting_stopping[0] ?: "Starting %s...";
541 else
542 return UNIT_VTABLE(u)->status_message_formats.starting_stopping[1] ?: "Stopping %s...";
543}
a69b3872 544
04d232d8
ZJS
545static void job_emit_start_message(Unit *u, uint32_t job_id, JobType t) {
546 _cleanup_free_ char *free_ident = NULL;
547 const char *ident, *format;
a69b3872 548
04d232d8
ZJS
549 assert(u);
550 assert(t >= 0);
551 assert(t < _JOB_TYPE_MAX);
552 assert(u->id); /* We better don't try to run a unit that doesn't even have an id. */
33a3fdd9 553
04d232d8
ZJS
554 if (!IN_SET(t, JOB_START, JOB_STOP, JOB_RELOAD))
555 return;
556
557 if (!unit_log_level_test(u, LOG_INFO))
558 return;
559
560 format = job_start_message_format(u, t);
561 ident = unit_status_string(u, &free_ident);
562
563 bool do_console = t != JOB_RELOAD;
564 bool console_only = do_console && log_on_console(); /* Reload status messages have traditionally
565 * not been printed to the console. */
566
567 /* Print to the log first. */
568 if (!console_only) { /* Skip this if it would only go on the console anyway */
569
570 const char *mid =
571 t == JOB_START ? "MESSAGE_ID=" SD_MESSAGE_UNIT_STARTING_STR :
572 t == JOB_STOP ? "MESSAGE_ID=" SD_MESSAGE_UNIT_STOPPING_STR :
573 "MESSAGE_ID=" SD_MESSAGE_UNIT_RELOADING_STR;
574 const char *msg_fmt = strjoina("MESSAGE=", format);
575
576 /* Note that we deliberately use LOG_MESSAGE() instead of LOG_UNIT_MESSAGE() here, since this
577 * is supposed to mimic closely what is written to screen using the status output, which is
578 * supposed to be high level friendly output. */
579
580 DISABLE_WARNING_FORMAT_NONLITERAL;
581 log_unit_struct(u, LOG_INFO,
582 msg_fmt, ident,
583 "JOB_ID=%" PRIu32, job_id,
584 "JOB_TYPE=%s", job_type_to_string(t),
585 LOG_UNIT_INVOCATION_ID(u),
586 mid);
587 REENABLE_WARNING;
588 }
589
590 /* Log to the console second. */
591 if (do_console) {
592 DISABLE_WARNING_FORMAT_NONLITERAL;
593 unit_status_printf(u, STATUS_TYPE_NORMAL, "", format, ident);
594 REENABLE_WARNING;
a69b3872 595 }
33a3fdd9
LP
596}
597
b8643ee2 598static const char* job_done_message_format(Unit *u, JobType t, JobResult result) {
04d232d8
ZJS
599 static const char* const generic_finished_start_job[_JOB_RESULT_MAX] = {
600 [JOB_DONE] = "Started %s.",
601 [JOB_TIMEOUT] = "Timed out starting %s.",
602 [JOB_FAILED] = "Failed to start %s.",
603 [JOB_DEPENDENCY] = "Dependency failed for %s.",
604 [JOB_ASSERT] = "Assertion failed for %s.",
605 [JOB_UNSUPPORTED] = "Starting of %s unsupported.",
606 [JOB_COLLECTED] = "Unnecessary job was removed for %s.",
607 [JOB_ONCE] = "Unit %s has been started before and cannot be started again.",
608 };
609 static const char* const generic_finished_stop_job[_JOB_RESULT_MAX] = {
610 [JOB_DONE] = "Stopped %s.",
611 [JOB_FAILED] = "Stopped %s with error.",
612 [JOB_TIMEOUT] = "Timed out stopping %s.",
613 };
614 static const char* const generic_finished_reload_job[_JOB_RESULT_MAX] = {
615 [JOB_DONE] = "Reloaded %s.",
616 [JOB_FAILED] = "Reload failed for %s.",
617 [JOB_TIMEOUT] = "Timed out reloading %s.",
618 };
619 /* When verify-active detects the unit is inactive, report it.
620 * Most likely a DEPEND warning from a requisiting unit will
621 * occur next and it's nice to see what was requisited. */
622 static const char* const generic_finished_verify_active_job[_JOB_RESULT_MAX] = {
623 [JOB_SKIPPED] = "%s is inactive.",
624 };
33a3fdd9
LP
625 const char *format;
626
627 assert(u);
04d232d8
ZJS
628 assert(t >= 0);
629 assert(t < _JOB_TYPE_MAX);
33a3fdd9 630
413e8650 631 /* Show condition check message if the job did not actually do anything due to unmet condition. */
b8643ee2
LP
632 if (t == JOB_START && result == JOB_DONE && !u->condition_result)
633 return "Condition check resulted in %s being skipped.";
04d232d8
ZJS
634
635 if (IN_SET(t, JOB_START, JOB_STOP, JOB_RESTART)) {
636 const UnitStatusMessageFormats *formats = &UNIT_VTABLE(u)->status_message_formats;
637 if (formats->finished_job) {
638 format = formats->finished_job(u, t, result);
639 if (format)
b8643ee2 640 return format;
04d232d8 641 }
33a3fdd9 642
04d232d8
ZJS
643 format = (t == JOB_START ? formats->finished_start_job : formats->finished_stop_job)[result];
644 if (format)
b8643ee2 645 return format;
04d232d8 646 }
33a3fdd9 647
04d232d8
ZJS
648 /* Return generic strings */
649 switch (t) {
650 case JOB_START:
b8643ee2 651 return generic_finished_start_job[result];
04d232d8
ZJS
652 case JOB_STOP:
653 case JOB_RESTART:
b8643ee2 654 return generic_finished_stop_job[result];
04d232d8 655 case JOB_RELOAD:
b8643ee2 656 return generic_finished_reload_job[result];
04d232d8 657 case JOB_VERIFY_ACTIVE:
b8643ee2 658 return generic_finished_verify_active_job[result];
04d232d8
ZJS
659 default:
660 return NULL;
661 }
662}
663
664static const struct {
665 int log_level;
666 const char *color, *word;
667} job_done_messages[_JOB_RESULT_MAX] = {
668 [JOB_DONE] = { LOG_INFO, ANSI_OK_COLOR, " OK " },
669 [JOB_CANCELED] = { LOG_INFO, },
670 [JOB_TIMEOUT] = { LOG_ERR, ANSI_HIGHLIGHT_RED, " TIME " },
671 [JOB_FAILED] = { LOG_ERR, ANSI_HIGHLIGHT_RED, "FAILED" },
672 [JOB_DEPENDENCY] = { LOG_WARNING, ANSI_HIGHLIGHT_YELLOW, "DEPEND" },
673 [JOB_SKIPPED] = { LOG_NOTICE, ANSI_HIGHLIGHT, " INFO " },
674 [JOB_INVALID] = { LOG_INFO, },
675 [JOB_ASSERT] = { LOG_WARNING, ANSI_HIGHLIGHT_YELLOW, "ASSERT" },
676 [JOB_UNSUPPORTED] = { LOG_WARNING, ANSI_HIGHLIGHT_YELLOW, "UNSUPP" },
677 [JOB_COLLECTED] = { LOG_INFO, },
678 [JOB_ONCE] = { LOG_ERR, ANSI_HIGHLIGHT_RED, " ONCE " },
679};
680
681static const char* job_done_mid(JobType type, JobResult result) {
682 switch (type) {
683 case JOB_START:
684 if (result == JOB_DONE)
685 return "MESSAGE_ID=" SD_MESSAGE_UNIT_STARTED_STR;
686 else
687 return "MESSAGE_ID=" SD_MESSAGE_UNIT_FAILED_STR;
688
689 case JOB_RELOAD:
690 return "MESSAGE_ID=" SD_MESSAGE_UNIT_RELOADED_STR;
691
692 case JOB_STOP:
693 case JOB_RESTART:
694 return "MESSAGE_ID=" SD_MESSAGE_UNIT_STOPPED_STR;
695
696 default:
697 return NULL;
698 }
33a3fdd9
LP
699}
700
04d232d8 701static void job_emit_done_message(Unit *u, uint32_t job_id, JobType t, JobResult result) {
b8643ee2
LP
702 _cleanup_free_ char *free_ident = NULL;
703 const char *ident, *format;
33a3fdd9
LP
704
705 assert(u);
b344b363
LP
706 assert(t >= 0);
707 assert(t < _JOB_TYPE_MAX);
33a3fdd9 708
04d232d8 709 if (!unit_log_level_test(u, job_done_messages[result].log_level))
33a3fdd9
LP
710 return;
711
04d232d8
ZJS
712 format = job_done_message_format(u, t, result);
713 if (!format)
c2503e35
RH
714 return;
715
04d232d8 716 ident = unit_status_string(u, &free_ident);
33a3fdd9 717
04d232d8
ZJS
718 const char *status = job_done_messages[result].word;
719 bool do_console = t != JOB_RELOAD && status;
720 bool console_only = do_console && log_on_console();
33a3fdd9 721
04d232d8 722 if (t == JOB_START && result == JOB_DONE && !u->condition_result) {
413e8650 723 /* No message on the console if the job did not actually do anything due to unmet condition. */
04d232d8
ZJS
724 if (console_only)
725 return;
726 else
727 do_console = false;
728 }
729
730 if (!console_only) { /* Skip printing if output goes to the console, and job_print_status_message()
731 * will actually print something to the console. */
6e548561 732 Condition *c;
04d232d8 733 const char *mid = job_done_mid(t, result); /* mid may be NULL. log_unit_struct() will ignore it. */
04d232d8 734
6e548561
DDM
735 c = t == JOB_START && result == JOB_DONE ? unit_find_failed_condition(u) : NULL;
736 if (c) {
413e8650 737 /* Special case units that were skipped because of a unmet condition check so that
6e548561
DDM
738 * we can add more information to the message. */
739 if (c->trigger)
740 log_unit_struct(
741 u,
742 job_done_messages[result].log_level,
413e8650 743 LOG_MESSAGE("%s was skipped because no trigger condition checks were met.",
92663a5e 744 ident),
6e548561
DDM
745 "JOB_ID=%" PRIu32, job_id,
746 "JOB_TYPE=%s", job_type_to_string(t),
747 "JOB_RESULT=%s", job_result_to_string(result),
748 LOG_UNIT_INVOCATION_ID(u),
749 mid);
750 else
751 log_unit_struct(
752 u,
753 job_done_messages[result].log_level,
413e8650 754 LOG_MESSAGE("%s was skipped because of an unmet condition check (%s=%s%s).",
92663a5e
ZJS
755 ident,
756 condition_type_to_string(c->type),
757 c->negate ? "!" : "",
758 c->parameter),
6e548561
DDM
759 "JOB_ID=%" PRIu32, job_id,
760 "JOB_TYPE=%s", job_type_to_string(t),
761 "JOB_RESULT=%s", job_result_to_string(result),
762 LOG_UNIT_INVOCATION_ID(u),
763 mid);
764 } else {
765 const char *msg_fmt = strjoina("MESSAGE=", format);
766
767 DISABLE_WARNING_FORMAT_NONLITERAL;
768 log_unit_struct(u, job_done_messages[result].log_level,
769 msg_fmt, ident,
770 "JOB_ID=%" PRIu32, job_id,
771 "JOB_TYPE=%s", job_type_to_string(t),
772 "JOB_RESULT=%s", job_result_to_string(result),
773 LOG_UNIT_INVOCATION_ID(u),
774 mid);
775 REENABLE_WARNING;
776 }
04d232d8
ZJS
777 }
778
779 if (do_console) {
780 if (log_get_show_color())
781 status = strjoina(job_done_messages[result].color,
782 status,
783 ANSI_NORMAL);
784
785 DISABLE_WARNING_FORMAT_NONLITERAL;
786 unit_status_printf(u,
787 result == JOB_DONE ? STATUS_TYPE_NORMAL : STATUS_TYPE_NOTICE,
788 status, format, ident);
789 REENABLE_WARNING;
790
791 if (t == JOB_START && result == JOB_FAILED) {
792 _cleanup_free_ char *quoted = NULL;
793
794 quoted = shell_maybe_quote(u->id, 0);
795 if (quoted)
796 manager_status_printf(u->manager, STATUS_TYPE_NORMAL, NULL,
797 "See 'systemctl status %s' for details.", quoted);
798 }
799 }
33a3fdd9
LP
800}
801
d1a34ae9 802static int job_perform_on_unit(Job **j) {
48b92b37 803 ActivationDetails *a;
df446f96
LP
804 uint32_t id;
805 Manager *m;
806 JobType t;
807 Unit *u;
d1a34ae9
MS
808 int r;
809
df446f96
LP
810 /* While we execute this operation the job might go away (for
811 * example: because it finishes immediately or is replaced by
812 * a new, conflicting job.) To make sure we don't access a
813 * freed job later on we store the id here, so that we can
814 * verify the job is still valid. */
815
816 assert(j);
817 assert(*j);
818
819 m = (*j)->manager;
820 u = (*j)->unit;
821 t = (*j)->type;
822 id = (*j)->id;
48b92b37 823 a = (*j)->activation_details;
df446f96 824
d1a34ae9
MS
825 switch (t) {
826 case JOB_START:
48b92b37 827 r = unit_start(u, a);
d1a34ae9
MS
828 break;
829
830 case JOB_RESTART:
831 t = JOB_STOP;
4831981d 832 _fallthrough_;
d1a34ae9
MS
833 case JOB_STOP:
834 r = unit_stop(u);
835 break;
836
837 case JOB_RELOAD:
838 r = unit_reload(u);
839 break;
840
841 default:
04499a70 842 assert_not_reached();
d1a34ae9
MS
843 }
844
0e2b4a82
LP
845 /* Log if the job still exists and the start/stop/reload function actually did something. Note that this means
846 * for units for which there's no 'activating' phase (i.e. because we transition directly from 'inactive' to
847 * 'active') we'll possibly skip the "Starting..." message. */
d1a34ae9
MS
848 *j = manager_get_job(m, id);
849 if (*j && r > 0)
04d232d8 850 job_emit_start_message(u, id, t);
d1a34ae9
MS
851
852 return r;
853}
854
5cb5a6ff
LP
855int job_run_and_invalidate(Job *j) {
856 int r;
ac1135be 857
5cb5a6ff 858 assert(j);
ac1135be 859 assert(j->installed);
e0209d83 860 assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
66aa6f7f 861 assert(j->in_run_queue);
5cb5a6ff 862
da8e1782 863 prioq_remove(j->manager->run_queue, j, &j->run_queue_idx);
66aa6f7f 864 j->in_run_queue = false;
5cb5a6ff
LP
865
866 if (j->state != JOB_WAITING)
867 return 0;
868
034c6ed7
LP
869 if (!job_is_runnable(j))
870 return -EAGAIN;
871
a2df3ea4 872 job_start_timer(j, true);
9c3349e2 873 job_set_state(j, JOB_RUNNING);
c1e1601e 874 job_add_to_dbus_queue(j);
83c60c9f 875
5cb5a6ff
LP
876 switch (j->type) {
877
5cb5a6ff 878 case JOB_VERIFY_ACTIVE: {
ea2c0e45
LP
879 UnitActiveState t;
880
881 t = unit_active_state(j->unit);
87f0e418 882 if (UNIT_IS_ACTIVE_OR_RELOADING(t))
5cb5a6ff 883 r = -EALREADY;
87f0e418 884 else if (t == UNIT_ACTIVATING)
5cb5a6ff
LP
885 r = -EAGAIN;
886 else
6a371e23 887 r = -EBADR;
5cb5a6ff
LP
888 break;
889 }
890
d1a34ae9 891 case JOB_START:
5cb5a6ff 892 case JOB_STOP:
dd17d388 893 case JOB_RESTART:
d1a34ae9 894 r = job_perform_on_unit(&j);
57339f47 895
ea2c0e45 896 /* If the unit type does not support starting/stopping, then simply wait. */
57339f47
LP
897 if (r == -EBADR)
898 r = 0;
5cb5a6ff
LP
899 break;
900
901 case JOB_RELOAD:
d1a34ae9 902 r = job_perform_on_unit(&j);
5cb5a6ff
LP
903 break;
904
e0209d83
MS
905 case JOB_NOP:
906 r = -EALREADY;
907 break;
908
5cb5a6ff 909 default:
04499a70 910 assert_not_reached();
5cb5a6ff
LP
911 }
912
e0209d83 913 if (j) {
8ebd9175
LP
914 if (r == -EAGAIN)
915 job_set_state(j, JOB_WAITING); /* Hmm, not ready after all, let's return to JOB_WAITING state */
6e64994d 916 else if (r == -EALREADY) /* already being executed */
833f92ad 917 r = job_finish_and_invalidate(j, JOB_DONE, true, true);
2e3bb01d
LB
918 else if (r == -ECOMM)
919 r = job_finish_and_invalidate(j, JOB_DONE, true, false);
6a371e23 920 else if (r == -EBADR)
833f92ad 921 r = job_finish_and_invalidate(j, JOB_SKIPPED, true, false);
6a371e23 922 else if (r == -ENOEXEC)
833f92ad 923 r = job_finish_and_invalidate(j, JOB_INVALID, true, false);
59fccdc5 924 else if (r == -EPROTO)
833f92ad 925 r = job_finish_and_invalidate(j, JOB_ASSERT, true, false);
15411c0c 926 else if (r == -EOPNOTSUPP)
833f92ad 927 r = job_finish_and_invalidate(j, JOB_UNSUPPORTED, true, false);
631b676b
LP
928 else if (r == -ENOLINK)
929 r = job_finish_and_invalidate(j, JOB_DEPENDENCY, true, false);
d4fd1cf2
LP
930 else if (r == -ESTALE)
931 r = job_finish_and_invalidate(j, JOB_ONCE, true, false);
9c3349e2 932 else if (r < 0)
833f92ad 933 r = job_finish_and_invalidate(j, JOB_FAILED, true, false);
2cf19a7a 934 }
5cb5a6ff
LP
935
936 return r;
937}
938
15ed3c3a 939static void job_fail_dependencies(Unit *u, UnitDependencyAtom match_atom) {
be7d9ff7 940 Unit *other;
be7d9ff7
LP
941
942 assert(u);
943
15ed3c3a 944 UNIT_FOREACH_DEPENDENCY(other, u, match_atom) {
be7d9ff7
LP
945 Job *j = other->job;
946
947 if (!j)
948 continue;
949 if (!IN_SET(j->type, JOB_START, JOB_VERIFY_ACTIVE))
950 continue;
951
833f92ad 952 job_finish_and_invalidate(j, JOB_DEPENDENCY, true, false);
be7d9ff7
LP
953 }
954}
955
833f92ad 956int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool already) {
15ed3c3a 957 Unit *u, *other;
b866264a 958 JobType t;
5cb5a6ff
LP
959
960 assert(j);
ac1135be 961 assert(j->installed);
e0209d83 962 assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
5cb5a6ff 963
c6918296
MS
964 u = j->unit;
965 t = j->type;
966
967 j->result = result;
968
771b5242
ZJS
969 log_unit_debug(u, "Job %" PRIu32 " %s/%s finished, result=%s",
970 j->id, u->id, job_type_to_string(t), job_result_to_string(result));
c6918296 971
771b5242 972 /* If this job did nothing to the respective unit we don't log the status message */
833f92ad 973 if (!already)
04d232d8 974 job_emit_done_message(u, j->id, t, result);
c6918296 975
034c6ed7 976 /* Patch restart jobs so that they become normal start jobs */
c6918296 977 if (result == JOB_DONE && t == JOB_RESTART) {
f50e0a01 978
bbd1a837 979 job_change_type(j, JOB_START);
9c3349e2 980 job_set_state(j, JOB_WAITING);
cc42e081 981
fec7615c 982 job_add_to_dbus_queue(j);
cc42e081 983 job_add_to_run_queue(j);
c5a97ed1 984 job_add_to_gc_queue(j);
57981b98 985
57981b98 986 goto finish;
5cb5a6ff
LP
987 }
988
3742095b 989 if (IN_SET(result, JOB_FAILED, JOB_INVALID))
313cefa1 990 j->manager->n_failed_jobs++;
76bf48b7 991
97e7d748 992 job_uninstall(j);
4a53080b 993 job_free(j);
5cb5a6ff
LP
994
995 /* Fail depending jobs on failure */
5273510e 996 if (result != JOB_DONE && recursive) {
15ed3c3a
LP
997 if (IN_SET(t, JOB_START, JOB_VERIFY_ACTIVE))
998 job_fail_dependencies(u, UNIT_ATOM_PROPAGATE_START_FAILURE);
999 else if (t == JOB_STOP)
1000 job_fail_dependencies(u, UNIT_ATOM_PROPAGATE_STOP_FAILURE);
5cb5a6ff
LP
1001 }
1002
defe63b0
LP
1003 /* A special check to make sure we take down anything RequisiteOf= if we aren't active. This is when
1004 * the verify-active job merges with a satisfying job type, and then loses it's invalidation effect,
1005 * as the result there is JOB_DONE for the start job we merged into, while we should be failing the
1006 * depending job if the said unit isn't in fact active. Oneshots are an example of this, where going
1007 * directly from activating to inactive is success.
791cd159 1008 *
defe63b0
LP
1009 * This happens when you use ConditionXYZ= in a unit too, since in that case the job completes with
1010 * the JOB_DONE result, but the unit never really becomes active. Note that such a case still
1011 * involves merging:
791cd159 1012 *
defe63b0
LP
1013 * A start job waits for something else, and a verify-active comes in and merges in the installed
1014 * job. Then, later, when it becomes runnable, it finishes with JOB_DONE result as execution on
1015 * conditions not being met is skipped, breaking our dependency semantics.
791cd159 1016 *
defe63b0
LP
1017 * Also, depending on if start job waits or not, the merging may or may not happen (the verify-active
1018 * job may trigger after it finishes), so you get undeterministic results without this check.
791cd159 1019 */
15ed3c3a
LP
1020 if (result == JOB_DONE && recursive &&
1021 IN_SET(t, JOB_START, JOB_RELOAD) &&
1022 !UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u)))
1023 job_fail_dependencies(u, UNIT_ATOM_PROPAGATE_INACTIVE_START_AS_FAILURE);
1024
1025 /* Trigger OnFailure= dependencies that are not generated by the unit itself. We don't treat
1026 * JOB_CANCELED as failure in this context. And JOB_FAILURE is already handled by the unit itself. */
646cc98d 1027 if (IN_SET(result, JOB_TIMEOUT, JOB_DEPENDENCY)) {
c2503e35
RH
1028 log_unit_struct(u, LOG_NOTICE,
1029 "JOB_TYPE=%s", job_type_to_string(t),
1030 "JOB_RESULT=%s", job_result_to_string(result),
1031 LOG_UNIT_MESSAGE(u, "Job %s/%s failed with result '%s'.",
1032 u->id,
1033 job_type_to_string(t),
1034 job_result_to_string(result)));
222ae6a8 1035
294446dc 1036 unit_start_on_failure(u, "OnFailure=", UNIT_ATOM_ON_FAILURE, u->on_failure_job_mode);
222ae6a8 1037 }
c0daa706 1038
3ecaa09b
LP
1039 unit_trigger_notify(u);
1040
57981b98 1041finish:
5cb5a6ff 1042 /* Try to start the next jobs that can be started */
15ed3c3a 1043 UNIT_FOREACH_DEPENDENCY(other, u, UNIT_ATOM_AFTER)
c5a97ed1 1044 if (other->job) {
ac155bb8 1045 job_add_to_run_queue(other->job);
c5a97ed1
LP
1046 job_add_to_gc_queue(other->job);
1047 }
15ed3c3a 1048 UNIT_FOREACH_DEPENDENCY(other, u, UNIT_ATOM_BEFORE)
c5a97ed1 1049 if (other->job) {
ac155bb8 1050 job_add_to_run_queue(other->job);
c5a97ed1
LP
1051 job_add_to_gc_queue(other->job);
1052 }
5cb5a6ff 1053
ac155bb8 1054 manager_check_finished(u->manager);
b0c918b9 1055
5273510e 1056 return 0;
5cb5a6ff 1057}
034c6ed7 1058
718db961 1059static int job_dispatch_timer(sd_event_source *s, uint64_t monotonic, void *userdata) {
99534007 1060 Job *j = ASSERT_PTR(userdata);
f189ab18 1061 Unit *u;
faf919f1 1062
718db961 1063 assert(s == j->timer_event_source);
faf919f1 1064
f2341e0a 1065 log_unit_warning(j->unit, "Job %s/%s timed out.", j->unit->id, job_type_to_string(j->type));
faf919f1 1066
f189ab18 1067 u = j->unit;
833f92ad 1068 job_finish_and_invalidate(j, JOB_TIMEOUT, true, false);
f189ab18 1069
c7adcb1a
ZJS
1070 emergency_action(u->manager, u->job_timeout_action,
1071 EMERGENCY_ACTION_IS_WATCHDOG|EMERGENCY_ACTION_WARN,
7af67e9a 1072 u->job_timeout_reboot_arg, -1, "job timed out");
f189ab18 1073
718db961
LP
1074 return 0;
1075}
faf919f1 1076
a2df3ea4 1077int job_start_timer(Job *j, bool job_running) {
718db961 1078 int r;
171f12ce 1079 usec_t timeout_time, old_timeout_time;
faf919f1 1080
a2df3ea4 1081 if (job_running) {
171f12ce
MK
1082 j->begin_running_usec = now(CLOCK_MONOTONIC);
1083
a2df3ea4
MK
1084 if (j->unit->job_running_timeout == USEC_INFINITY)
1085 return 0;
faf919f1 1086
171f12ce 1087 timeout_time = usec_add(j->begin_running_usec, j->unit->job_running_timeout);
faf919f1 1088
a2df3ea4
MK
1089 if (j->timer_event_source) {
1090 /* Update only if JobRunningTimeoutSec= results in earlier timeout */
1091 r = sd_event_source_get_time(j->timer_event_source, &old_timeout_time);
1092 if (r < 0)
1093 return r;
1094
1095 if (old_timeout_time <= timeout_time)
1096 return 0;
1097
1098 return sd_event_source_set_time(j->timer_event_source, timeout_time);
1099 }
1100 } else {
1101 if (j->timer_event_source)
1102 return 0;
1103
1104 j->begin_usec = now(CLOCK_MONOTONIC);
1105
1106 if (j->unit->job_timeout == USEC_INFINITY)
1107 return 0;
1108
1109 timeout_time = usec_add(j->begin_usec, j->unit->job_timeout);
1110 }
8bb310c3 1111
6a0f1f6d
LP
1112 r = sd_event_add_time(
1113 j->manager->event,
1114 &j->timer_event_source,
1115 CLOCK_MONOTONIC,
a2df3ea4 1116 timeout_time, 0,
6a0f1f6d 1117 job_dispatch_timer, j);
718db961
LP
1118 if (r < 0)
1119 return r;
faf919f1 1120
7dfbe2e3
TG
1121 (void) sd_event_source_set_description(j->timer_event_source, "job-start");
1122
718db961 1123 return 0;
faf919f1
LP
1124}
1125
c1e1601e 1126void job_add_to_run_queue(Job *j) {
f8c34706
LP
1127 int r;
1128
034c6ed7 1129 assert(j);
ac1135be 1130 assert(j->installed);
034c6ed7
LP
1131
1132 if (j->in_run_queue)
1133 return;
1134
735a8b6d
LP
1135 r = prioq_put(j->manager->run_queue, j, &j->run_queue_idx);
1136 if (r < 0)
1137 log_warning_errno(r, "Failed put job in run queue, ignoring: %m");
1138 else
1139 j->in_run_queue = true;
b0c4b282
LP
1140
1141 manager_trigger_run_queue(j->manager);
034c6ed7 1142}
94f04347 1143
c1e1601e
LP
1144void job_add_to_dbus_queue(Job *j) {
1145 assert(j);
1146 assert(j->installed);
1147
1148 if (j->in_dbus_queue)
1149 return;
1150
a567261a
LP
1151 /* We don't check if anybody is subscribed here, since this
1152 * job might just have been created and not yet assigned to a
1153 * connection/client. */
94b6dfa2 1154
71fda00f 1155 LIST_PREPEND(dbus_queue, j->manager->dbus_job_queue, j);
c1e1601e
LP
1156 j->in_dbus_queue = true;
1157}
1158
ea430986
LP
1159char *job_dbus_path(Job *j) {
1160 char *p;
1161
1162 assert(j);
1163
ccd06097 1164 if (asprintf(&p, "/org/freedesktop/systemd1/job/%"PRIu32, j->id) < 0)
ea430986
LP
1165 return NULL;
1166
1167 return p;
1168}
1169
05a98afd
LP
1170int job_serialize(Job *j, FILE *f) {
1171 assert(j);
1172 assert(f);
1173
d68c645b
LP
1174 (void) serialize_item_format(f, "job-id", "%u", j->id);
1175 (void) serialize_item(f, "job-type", job_type_to_string(j->type));
1176 (void) serialize_item(f, "job-state", job_state_to_string(j->state));
1177 (void) serialize_bool(f, "job-irreversible", j->irreversible);
1178 (void) serialize_bool(f, "job-sent-dbus-new-signal", j->sent_dbus_new_signal);
1179 (void) serialize_bool(f, "job-ignore-order", j->ignore_order);
718db961
LP
1180
1181 if (j->begin_usec > 0)
d68c645b 1182 (void) serialize_usec(f, "job-begin", j->begin_usec);
171f12ce 1183 if (j->begin_running_usec > 0)
d68c645b 1184 (void) serialize_usec(f, "job-begin-running", j->begin_running_usec);
718db961 1185
1a465207 1186 bus_track_serialize(j->bus_track, f, "subscribed");
39a18c60 1187
48b92b37
LB
1188 activation_details_serialize(j->activation_details, f);
1189
39a18c60
MS
1190 /* End marker */
1191 fputc('\n', f);
1192 return 0;
1193}
1194
05a98afd 1195int job_deserialize(Job *j, FILE *f) {
8948b341
LP
1196 int r;
1197
718db961 1198 assert(j);
05a98afd 1199 assert(f);
718db961 1200
39a18c60 1201 for (;;) {
8948b341
LP
1202 _cleanup_free_ char *line = NULL;
1203 char *l, *v;
39a18c60
MS
1204 size_t k;
1205
8948b341
LP
1206 r = read_line(f, LONG_LINE_MAX, &line);
1207 if (r < 0)
1208 return log_error_errno(r, "Failed to read serialization line: %m");
1209 if (r == 0)
1210 return 0;
39a18c60 1211
39a18c60
MS
1212 l = strstrip(line);
1213
1214 /* End marker */
8948b341 1215 if (isempty(l))
39a18c60
MS
1216 return 0;
1217
1218 k = strcspn(l, "=");
1219
1220 if (l[k] == '=') {
1221 l[k] = 0;
1222 v = l+k+1;
1223 } else
1224 v = l+k;
1225
1226 if (streq(l, "job-id")) {
718db961 1227
39a18c60 1228 if (safe_atou32(v, &j->id) < 0)
15ec1021 1229 log_debug("Failed to parse job id value: %s", v);
718db961 1230
39a18c60 1231 } else if (streq(l, "job-type")) {
718db961
LP
1232 JobType t;
1233
1234 t = job_type_from_string(v);
39a18c60 1235 if (t < 0)
15ec1021 1236 log_debug("Failed to parse job type: %s", v);
e0209d83 1237 else if (t >= _JOB_TYPE_MAX_IN_TRANSACTION)
15ec1021 1238 log_debug("Cannot deserialize job of type: %s", v);
39a18c60
MS
1239 else
1240 j->type = t;
718db961 1241
39a18c60 1242 } else if (streq(l, "job-state")) {
718db961
LP
1243 JobState s;
1244
1245 s = job_state_from_string(v);
39a18c60 1246 if (s < 0)
15ec1021 1247 log_debug("Failed to parse job state: %s", v);
39a18c60 1248 else
9c3349e2 1249 job_set_state(j, s);
718db961 1250
23ade460 1251 } else if (streq(l, "job-irreversible")) {
718db961
LP
1252 int b;
1253
1254 b = parse_boolean(v);
23ade460 1255 if (b < 0)
15ec1021 1256 log_debug("Failed to parse job irreversible flag: %s", v);
23ade460
MS
1257 else
1258 j->irreversible = j->irreversible || b;
718db961 1259
39a18c60 1260 } else if (streq(l, "job-sent-dbus-new-signal")) {
718db961
LP
1261 int b;
1262
1263 b = parse_boolean(v);
39a18c60 1264 if (b < 0)
15ec1021 1265 log_debug("Failed to parse job sent_dbus_new_signal flag: %s", v);
39a18c60
MS
1266 else
1267 j->sent_dbus_new_signal = j->sent_dbus_new_signal || b;
718db961 1268
39a18c60 1269 } else if (streq(l, "job-ignore-order")) {
718db961
LP
1270 int b;
1271
1272 b = parse_boolean(v);
39a18c60 1273 if (b < 0)
15ec1021 1274 log_debug("Failed to parse job ignore_order flag: %s", v);
39a18c60
MS
1275 else
1276 j->ignore_order = j->ignore_order || b;
718db961 1277
d68c645b
LP
1278 } else if (streq(l, "job-begin"))
1279 (void) deserialize_usec(v, &j->begin_usec);
718db961 1280
d68c645b
LP
1281 else if (streq(l, "job-begin-running"))
1282 (void) deserialize_usec(v, &j->begin_running_usec);
718db961 1283
d68c645b 1284 else if (streq(l, "subscribed")) {
b39a2770 1285 if (strv_extend(&j->deserialized_clients, v) < 0)
d68c645b 1286 return log_oom();
48b92b37
LB
1287
1288 } else if (startswith(l, "activation-details")) {
1289 if (activation_details_deserialize(l, v, &j->activation_details) < 0)
1290 log_debug("Failed to parse job ActivationDetails element: %s", v);
1291
d68c645b
LP
1292 } else
1293 log_debug("Unknown job serialization key: %s", l);
39a18c60
MS
1294 }
1295}
1296
1297int job_coldplug(Job *j) {
718db961 1298 int r;
171f12ce 1299 usec_t timeout_time = USEC_INFINITY;
718db961
LP
1300
1301 assert(j);
39a18c60 1302
8f8f05a9
LP
1303 /* After deserialization is complete and the bus connection
1304 * set up again, let's start watching our subscribers again */
c5a97ed1 1305 (void) bus_job_coldplug_bus_track(j);
8f8f05a9 1306
1727a595
MM
1307 if (j->state == JOB_WAITING)
1308 job_add_to_run_queue(j);
1309
c5a97ed1
LP
1310 /* Maybe due to new dependencies we don't actually need this job anymore? */
1311 job_add_to_gc_queue(j);
1312
171f12ce
MK
1313 /* Create timer only when job began or began running and the respective timeout is finite.
1314 * Follow logic of job_start_timer() if both timeouts are finite */
1315 if (j->begin_usec == 0)
1316 return 0;
1317
1318 if (j->unit->job_timeout != USEC_INFINITY)
1319 timeout_time = usec_add(j->begin_usec, j->unit->job_timeout);
1320
1f65fd49 1321 if (timestamp_is_set(j->begin_running_usec))
171f12ce
MK
1322 timeout_time = MIN(timeout_time, usec_add(j->begin_running_usec, j->unit->job_running_timeout));
1323
1324 if (timeout_time == USEC_INFINITY)
39a18c60
MS
1325 return 0;
1326
5dcadb4c 1327 j->timer_event_source = sd_event_source_disable_unref(j->timer_event_source);
39a18c60 1328
6a0f1f6d
LP
1329 r = sd_event_add_time(
1330 j->manager->event,
1331 &j->timer_event_source,
1332 CLOCK_MONOTONIC,
171f12ce 1333 timeout_time, 0,
6a0f1f6d 1334 job_dispatch_timer, j);
718db961 1335 if (r < 0)
da927ba9 1336 log_debug_errno(r, "Failed to restart timeout for job: %m");
718db961 1337
7dfbe2e3
TG
1338 (void) sd_event_source_set_description(j->timer_event_source, "job-timeout");
1339
718db961 1340 return r;
39a18c60
MS
1341}
1342
c65eb836
LP
1343void job_shutdown_magic(Job *j) {
1344 assert(j);
1345
1346 /* The shutdown target gets some special treatment here: we
1347 * tell the kernel to begin with flushing its disk caches, to
1348 * optimize shutdown time a bit. Ideally we wouldn't hardcode
1349 * this magic into PID 1. However all other processes aren't
1350 * options either since they'd exit much sooner than PID 1 and
1351 * asynchronous sync() would cause their exit to be
1352 * delayed. */
1353
c2756a68 1354 if (j->type != JOB_START)
c65eb836
LP
1355 return;
1356
463d0d15 1357 if (!MANAGER_IS_SYSTEM(j->unit->manager))
c2756a68
LP
1358 return;
1359
1360 if (!unit_has_name(j->unit, SPECIAL_SHUTDOWN_TARGET))
c65eb836
LP
1361 return;
1362
5b1869ea
OB
1363 /* In case messages on console has been disabled on boot */
1364 j->unit->manager->no_console_output = false;
1365
9dfb6a3a
PM
1366 manager_invalidate_startup_units(j->unit->manager);
1367
75f86906 1368 if (detect_container() > 0)
c65eb836
LP
1369 return;
1370
d00c2631 1371 (void) asynchronous_sync(NULL);
c65eb836
LP
1372}
1373
7a7821c8
LP
1374int job_get_timeout(Job *j, usec_t *timeout) {
1375 usec_t x = USEC_INFINITY, y = USEC_INFINITY;
68db7a3b 1376 Unit *u = j->unit;
7a7821c8 1377 int r;
68db7a3b
ZJS
1378
1379 assert(u);
1380
1381 if (j->timer_event_source) {
1382 r = sd_event_source_get_time(j->timer_event_source, &x);
1383 if (r < 0)
1384 return r;
68db7a3b
ZJS
1385 }
1386
1387 if (UNIT_VTABLE(u)->get_timeout) {
7a7821c8
LP
1388 r = UNIT_VTABLE(u)->get_timeout(u, &y);
1389 if (r < 0)
1390 return r;
68db7a3b
ZJS
1391 }
1392
7a7821c8 1393 if (x == USEC_INFINITY && y == USEC_INFINITY)
68db7a3b
ZJS
1394 return 0;
1395
1396 *timeout = MIN(x, y);
68db7a3b
ZJS
1397 return 1;
1398}
1399
2ab3050f 1400bool job_may_gc(Job *j) {
c5a97ed1 1401 Unit *other;
c5a97ed1
LP
1402
1403 assert(j);
1404
1405 /* Checks whether this job should be GC'ed away. We only do this for jobs of units that have no effect on their
2ab3050f
ZJS
1406 * own and just track external state. For now the only unit type that qualifies for this are .device units.
1407 * Returns true if the job can be collected. */
c5a97ed1
LP
1408
1409 if (!UNIT_VTABLE(j->unit)->gc_jobs)
2ab3050f 1410 return false;
c5a97ed1
LP
1411
1412 if (sd_bus_track_count(j->bus_track) > 0)
2ab3050f 1413 return false;
c5a97ed1
LP
1414
1415 /* FIXME: So this is a bit ugly: for now we don't properly track references made via private bus connections
1416 * (because it's nasty, as sd_bus_track doesn't apply to it). We simply remember that the job was once
1417 * referenced by one, and reset this whenever we notice that no private bus connections are around. This means
1418 * the GC is a bit too conservative when it comes to jobs created by private bus connections. */
1419 if (j->ref_by_private_bus) {
1420 if (set_isempty(j->unit->manager->private_buses))
1421 j->ref_by_private_bus = false;
1422 else
2ab3050f 1423 return false;
c5a97ed1
LP
1424 }
1425
1426 if (j->type == JOB_NOP)
2ab3050f 1427 return false;
c5a97ed1 1428
e602f152 1429 /* The logic is inverse to job_is_runnable, we cannot GC as long as we block any job. */
15ed3c3a
LP
1430 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_BEFORE)
1431 if (other->job && job_compare(j, other->job, UNIT_ATOM_BEFORE) < 0)
2ab3050f 1432 return false;
c5a97ed1 1433
15ed3c3a
LP
1434 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_AFTER)
1435 if (other->job && job_compare(j, other->job, UNIT_ATOM_AFTER) < 0)
2ab3050f 1436 return false;
c5a97ed1 1437
2ab3050f 1438 return true;
c5a97ed1
LP
1439}
1440
1441void job_add_to_gc_queue(Job *j) {
1442 assert(j);
1443
1444 if (j->in_gc_queue)
1445 return;
1446
2ab3050f 1447 if (!job_may_gc(j))
c5a97ed1
LP
1448 return;
1449
1450 LIST_PREPEND(gc_queue, j->unit->manager->gc_job_queue, j);
1451 j->in_gc_queue = true;
1452}
1453
e602f152 1454static int job_compare_id(Job * const *a, Job * const *b) {
93bab288 1455 return CMP((*a)->id, (*b)->id);
15ea79f8
LP
1456}
1457
1458static size_t sort_job_list(Job **list, size_t n) {
1459 Job *previous = NULL;
1460 size_t a, b;
1461
1462 /* Order by numeric IDs */
e602f152 1463 typesafe_qsort(list, n, job_compare_id);
15ea79f8
LP
1464
1465 /* Filter out duplicates */
1466 for (a = 0, b = 0; a < n; a++) {
1467
1468 if (previous == list[a])
1469 continue;
1470
1471 previous = list[b++] = list[a];
1472 }
1473
1474 return b;
1475}
1476
1477int job_get_before(Job *j, Job*** ret) {
1478 _cleanup_free_ Job** list = NULL;
15ea79f8 1479 Unit *other = NULL;
319a4f4b 1480 size_t n = 0;
15ea79f8
LP
1481
1482 /* Returns a list of all pending jobs that need to finish before this job may be started. */
1483
1484 assert(j);
1485 assert(ret);
1486
1487 if (j->ignore_order) {
1488 *ret = NULL;
1489 return 0;
1490 }
1491
15ed3c3a 1492 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_AFTER) {
e602f152
MK
1493 if (!other->job)
1494 continue;
15ed3c3a 1495 if (job_compare(j, other->job, UNIT_ATOM_AFTER) <= 0)
e602f152 1496 continue;
15ea79f8 1497
319a4f4b 1498 if (!GREEDY_REALLOC(list, n+1))
e602f152
MK
1499 return -ENOMEM;
1500 list[n++] = other->job;
15ea79f8
LP
1501 }
1502
15ed3c3a 1503 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_BEFORE) {
15ea79f8
LP
1504 if (!other->job)
1505 continue;
15ed3c3a 1506 if (job_compare(j, other->job, UNIT_ATOM_BEFORE) <= 0)
15ea79f8
LP
1507 continue;
1508
319a4f4b 1509 if (!GREEDY_REALLOC(list, n+1))
15ea79f8
LP
1510 return -ENOMEM;
1511 list[n++] = other->job;
1512 }
1513
1514 n = sort_job_list(list, n);
1515
1cc6c93a 1516 *ret = TAKE_PTR(list);
15ea79f8
LP
1517
1518 return (int) n;
1519}
1520
1521int job_get_after(Job *j, Job*** ret) {
1522 _cleanup_free_ Job** list = NULL;
15ea79f8 1523 Unit *other = NULL;
319a4f4b 1524 size_t n = 0;
15ea79f8
LP
1525
1526 assert(j);
1527 assert(ret);
1528
1529 /* Returns a list of all pending jobs that are waiting for this job to finish. */
1530
15ed3c3a 1531 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_BEFORE) {
15ea79f8
LP
1532 if (!other->job)
1533 continue;
1534
1535 if (other->job->ignore_order)
1536 continue;
1537
15ed3c3a 1538 if (job_compare(j, other->job, UNIT_ATOM_BEFORE) >= 0)
15ea79f8
LP
1539 continue;
1540
319a4f4b 1541 if (!GREEDY_REALLOC(list, n+1))
15ea79f8
LP
1542 return -ENOMEM;
1543 list[n++] = other->job;
1544 }
1545
15ed3c3a 1546 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_AFTER) {
e602f152
MK
1547 if (!other->job)
1548 continue;
1549
1550 if (other->job->ignore_order)
1551 continue;
15ea79f8 1552
15ed3c3a 1553 if (job_compare(j, other->job, UNIT_ATOM_AFTER) >= 0)
e602f152 1554 continue;
15ea79f8 1555
319a4f4b 1556 if (!GREEDY_REALLOC(list, n+1))
e602f152
MK
1557 return -ENOMEM;
1558 list[n++] = other->job;
15ea79f8
LP
1559 }
1560
1561 n = sort_job_list(list, n);
1562
1cc6c93a 1563 *ret = TAKE_PTR(list);
15ea79f8
LP
1564
1565 return (int) n;
1566}
1567
94f04347
LP
1568static const char* const job_state_table[_JOB_STATE_MAX] = {
1569 [JOB_WAITING] = "waiting",
0a23a627 1570 [JOB_RUNNING] = "running",
94f04347
LP
1571};
1572
1573DEFINE_STRING_TABLE_LOOKUP(job_state, JobState);
1574
1575static const char* const job_type_table[_JOB_TYPE_MAX] = {
48d83e33
ZJS
1576 [JOB_START] = "start",
1577 [JOB_VERIFY_ACTIVE] = "verify-active",
1578 [JOB_STOP] = "stop",
1579 [JOB_RELOAD] = "reload",
94f04347 1580 [JOB_RELOAD_OR_START] = "reload-or-start",
48d83e33
ZJS
1581 [JOB_RESTART] = "restart",
1582 [JOB_TRY_RESTART] = "try-restart",
1583 [JOB_TRY_RELOAD] = "try-reload",
1584 [JOB_NOP] = "nop",
94f04347
LP
1585};
1586
1587DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
b548631a
LP
1588
1589static const char* const job_mode_table[_JOB_MODE_MAX] = {
48d83e33
ZJS
1590 [JOB_FAIL] = "fail",
1591 [JOB_REPLACE] = "replace",
23ade460 1592 [JOB_REPLACE_IRREVERSIBLY] = "replace-irreversibly",
48d83e33
ZJS
1593 [JOB_ISOLATE] = "isolate",
1594 [JOB_FLUSH] = "flush",
1595 [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
1596 [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements",
1597 [JOB_TRIGGERING] = "triggering",
b548631a
LP
1598};
1599
1600DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);
5d44db4a
LP
1601
1602static const char* const job_result_table[_JOB_RESULT_MAX] = {
48d83e33
ZJS
1603 [JOB_DONE] = "done",
1604 [JOB_CANCELED] = "canceled",
1605 [JOB_TIMEOUT] = "timeout",
1606 [JOB_FAILED] = "failed",
1607 [JOB_DEPENDENCY] = "dependency",
1608 [JOB_SKIPPED] = "skipped",
1609 [JOB_INVALID] = "invalid",
1610 [JOB_ASSERT] = "assert",
0faacd47 1611 [JOB_UNSUPPORTED] = "unsupported",
48d83e33
ZJS
1612 [JOB_COLLECTED] = "collected",
1613 [JOB_ONCE] = "once",
5d44db4a
LP
1614};
1615
1616DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);
94bd7323
EV
1617
1618const char* job_type_to_access_method(JobType t) {
1619 assert(t >= 0);
1620 assert(t < _JOB_TYPE_MAX);
1621
1622 if (IN_SET(t, JOB_START, JOB_RESTART, JOB_TRY_RESTART))
1623 return "start";
1624 else if (t == JOB_STOP)
1625 return "stop";
1626 else
1627 return "reload";
1628}
e602f152
MK
1629
1630/*
1631 * assume_dep assumed dependency between units (a is before/after b)
1632 *
1633 * Returns
1634 * 0 jobs are independent,
1635 * >0 a should run after b,
1636 * <0 a should run before b,
1637 *
1638 * The logic means that for a service a and a service b where b.After=a:
1639 *
1640 * start a + start b → 1st step start a, 2nd step start b
1641 * start a + stop b → 1st step stop b, 2nd step start a
1642 * stop a + start b → 1st step stop a, 2nd step start b
1643 * stop a + stop b → 1st step stop b, 2nd step stop a
1644 *
defe63b0 1645 * This has the side effect that restarts are properly synchronized too.
e602f152 1646 */
15ed3c3a
LP
1647int job_compare(Job *a, Job *b, UnitDependencyAtom assume_dep) {
1648 assert(a);
1649 assert(b);
e602f152
MK
1650 assert(a->type < _JOB_TYPE_MAX_IN_TRANSACTION);
1651 assert(b->type < _JOB_TYPE_MAX_IN_TRANSACTION);
15ed3c3a 1652 assert(IN_SET(assume_dep, UNIT_ATOM_AFTER, UNIT_ATOM_BEFORE));
e602f152
MK
1653
1654 /* Trivial cases first */
1655 if (a->type == JOB_NOP || b->type == JOB_NOP)
1656 return 0;
1657
1658 if (a->ignore_order || b->ignore_order)
1659 return 0;
1660
15ed3c3a
LP
1661 if (assume_dep == UNIT_ATOM_AFTER)
1662 return -job_compare(b, a, UNIT_ATOM_BEFORE);
e602f152 1663
defe63b0
LP
1664 /* Let's make it simple, JOB_STOP goes always first (in case both ua and ub stop, then ub's stop goes
1665 * first anyway). JOB_RESTART is JOB_STOP in disguise (before it is patched to JOB_START). */
e602f152
MK
1666 if (IN_SET(b->type, JOB_STOP, JOB_RESTART))
1667 return 1;
1668 else
1669 return -1;
1670}
48b92b37
LB
1671
1672void job_set_activation_details(Job *j, ActivationDetails *info) {
1673 /* Existing (older) ActivationDetails win, newer ones are discarded. */
1674 if (!j || j->activation_details || !info)
1675 return; /* Nothing to do. */
1676
1677 j->activation_details = activation_details_ref(info);
1678}