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