]> git.proxmox.com Git - systemd.git/blame - src/core/job.c
bump version to 252.11-pve1
[systemd.git] / src / core / job.c
CommitLineData
a032b68d 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
663996b3 2
663996b3 3#include <errno.h>
663996b3 4
60f067b4
JS
5#include "sd-id128.h"
6#include "sd-messages.h"
db2df898
MP
7
8#include "alloc-util.h"
14228c0d 9#include "async.h"
f2dec872 10#include "cgroup.h"
db2df898 11#include "dbus-job.h"
60f067b4 12#include "dbus.h"
db2df898 13#include "escape.h"
6e866b33 14#include "fileio.h"
db2df898
MP
15#include "job.h"
16#include "log.h"
17#include "macro.h"
18#include "parse-util.h"
6e866b33 19#include "serialize.h"
db2df898 20#include "set.h"
bb4f798a 21#include "sort-util.h"
db2df898 22#include "special.h"
4c89c718 23#include "stdio-util.h"
db2df898
MP
24#include "string-table.h"
25#include "string-util.h"
26#include "strv.h"
e3bff60a 27#include "terminal-util.h"
db2df898
MP
28#include "unit.h"
29#include "virt.h"
663996b3
MS
30
31Job* job_new_raw(Unit *unit) {
32 Job *j;
33
34 /* used for deserialization */
35
36 assert(unit);
37
6e866b33 38 j = new(Job, 1);
663996b3
MS
39 if (!j)
40 return NULL;
41
6e866b33
MB
42 *j = (Job) {
43 .manager = unit->manager,
44 .unit = unit,
45 .type = _JOB_TYPE_INVALID,
46 };
663996b3
MS
47
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
63 /* We don't link it here, that's what job_dependency() is for */
64
65 return j;
66}
67
b012e921 68void job_unlink(Job *j) {
663996b3
MS
69 assert(j);
70 assert(!j->installed);
71 assert(!j->transaction_prev);
72 assert(!j->transaction_next);
73 assert(!j->subject_list);
74 assert(!j->object_list);
75
b012e921 76 if (j->in_run_queue) {
f2dec872 77 prioq_remove(j->manager->run_queue, j, &j->run_queue_idx);
b012e921
MB
78 j->in_run_queue = false;
79 }
663996b3 80
b012e921 81 if (j->in_dbus_queue) {
60f067b4 82 LIST_REMOVE(dbus_queue, j->manager->dbus_job_queue, j);
b012e921
MB
83 j->in_dbus_queue = false;
84 }
663996b3 85
b012e921 86 if (j->in_gc_queue) {
2897b343 87 LIST_REMOVE(gc_queue, j->manager->gc_job_queue, j);
b012e921
MB
88 j->in_gc_queue = false;
89 }
90
67bbd050 91 j->timer_event_source = sd_event_source_disable_unref(j->timer_event_source);
b012e921
MB
92}
93
6e866b33 94Job* job_free(Job *j) {
b012e921
MB
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);
2897b343 101
b012e921 102 job_unlink(j);
663996b3 103
2897b343 104 sd_bus_track_unref(j->bus_track);
5eef597e 105 strv_free(j->deserialized_clients);
663996b3 106
086111aa
LB
107 activation_details_unref(j->activation_details);
108
6e866b33 109 return mfree(j);
663996b3
MS
110}
111
e735f4d4
MP
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)
67bbd050 134 j->unit->manager->jobs_in_progress_event_source = sd_event_source_disable_unref(j->unit->manager->jobs_in_progress_event_source);
e735f4d4
MP
135 }
136}
137
663996b3
MS
138void job_uninstall(Job *j) {
139 Job **pj;
140
141 assert(j->installed);
142
e735f4d4
MP
143 job_set_state(j, JOB_WAITING);
144
086111aa 145 pj = j->type == JOB_NOP ? &j->unit->nop_job : &j->unit->job;
663996b3
MS
146 assert(*pj == j);
147
148 /* Detach from next 'bigger' objects */
149
150 /* daemon-reload should be transparent to job observers */
aa27b158 151 if (!MANAGER_IS_RELOADING(j->manager))
663996b3
MS
152 bus_job_send_removed_signal(j);
153
154 *pj = NULL;
155
156 unit_add_to_gc_queue(j->unit);
157
7c20daf6
FS
158 unit_add_to_dbus_queue(j->unit); /* The Job property of the unit has changed now */
159
6e866b33 160 hashmap_remove_value(j->manager->jobs, UINT32_TO_PTR(j->id), j);
663996b3
MS
161 j->installed = false;
162}
163
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. */
178 return t != JOB_RELOAD;
179}
180
181static void job_merge_into_installed(Job *j, Job *other) {
182 assert(j->installed);
183 assert(j->unit == other->unit);
184
086111aa 185 if (j->type != JOB_NOP) {
6e866b33 186 assert_se(job_type_merge_and_collapse(&j->type, other->type, j->unit) == 0);
086111aa
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
663996b3
MS
192 assert(other->type == JOB_NOP);
193
663996b3
MS
194 j->irreversible = j->irreversible || other->irreversible;
195 j->ignore_order = j->ignore_order || other->ignore_order;
196}
197
198Job* job_install(Job *j) {
199 Job **pj;
200 Job *uj;
201
202 assert(!j->installed);
203 assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
e735f4d4 204 assert(j->state == JOB_WAITING);
663996b3 205
086111aa 206 pj = j->type == JOB_NOP ? &j->unit->nop_job : &j->unit->job;
663996b3
MS
207 uj = *pj;
208
209 if (uj) {
f47781d8 210 if (job_type_is_conflicting(uj->type, j->type))
aa27b158 211 job_finish_and_invalidate(uj, JOB_CANCELED, false, false);
663996b3
MS
212 else {
213 /* not conflicting, i.e. mergeable */
214
f47781d8 215 if (uj->state == JOB_WAITING ||
663996b3
MS
216 (job_type_allows_late_merge(j->type) && job_type_is_superset(uj->type, j->type))) {
217 job_merge_into_installed(uj, j);
e3bff60a 218 log_unit_debug(uj->unit,
7c20daf6
FS
219 "Merged %s/%s into installed job %s/%s as %"PRIu32,
220 j->unit->id, job_type_to_string(j->type), uj->unit->id,
221 job_type_to_string(uj->type), uj->id);
663996b3
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);
e3bff60a 229 log_unit_debug(uj->unit,
7c20daf6
FS
230 "Merged into running job, re-running: %s/%s as %"PRIu32,
231 uj->unit->id, job_type_to_string(uj->type), uj->id);
e735f4d4
MP
232
233 job_set_state(uj, JOB_WAITING);
663996b3
MS
234 return uj;
235 }
236 }
237 }
238
239 /* Install the job */
240 *pj = j;
241 j->installed = true;
e735f4d4 242
aa27b158 243 j->manager->n_installed_jobs++;
e3bff60a 244 log_unit_debug(j->unit,
663996b3
MS
245 "Installed new job %s/%s as %u",
246 j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
2897b343
MP
247
248 job_add_to_gc_queue(j);
249
6e866b33
MB
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
663996b3
MS
253 return j;
254}
255
256int job_install_deserialized(Job *j) {
257 Job **pj;
6e866b33 258 int r;
663996b3
MS
259
260 assert(!j->installed);
261
6e866b33
MB
262 if (j->type < 0 || j->type >= _JOB_TYPE_MAX_IN_TRANSACTION)
263 return log_unit_debug_errno(j->unit, SYNTHETIC_ERRNO(EINVAL),
264 "Invalid job type %s in deserialization.",
265 strna(job_type_to_string(j->type)));
663996b3 266
086111aa 267 pj = j->type == JOB_NOP ? &j->unit->nop_job : &j->unit->job;
6e866b33
MB
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
3a6ce677 272 r = hashmap_ensure_put(&j->manager->jobs, NULL, UINT32_TO_PTR(j->id), j);
6e866b33
MB
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");
e735f4d4 277
663996b3
MS
278 *pj = j;
279 j->installed = true;
e735f4d4
MP
280
281 if (j->state == JOB_RUNNING)
282 j->unit->manager->n_running_jobs++;
283
e3bff60a 284 log_unit_debug(j->unit,
663996b3
MS
285 "Reinstalled deserialized job %s/%s as %u",
286 j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
287 return 0;
288}
289
290JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts) {
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
298 * explicitly asked for) is the requester. */
299
2897b343
MP
300 l = new0(JobDependency, 1);
301 if (!l)
663996b3
MS
302 return NULL;
303
304 l->subject = subject;
305 l->object = object;
306 l->matters = matters;
307 l->conflicts = conflicts;
308
309 if (subject)
60f067b4 310 LIST_PREPEND(subject, subject->subject_list, l);
663996b3 311
60f067b4 312 LIST_PREPEND(object, object->object_list, l);
663996b3
MS
313
314 return l;
315}
316
317void job_dependency_free(JobDependency *l) {
318 assert(l);
319
320 if (l->subject)
60f067b4 321 LIST_REMOVE(subject, l->subject->subject_list, l);
663996b3 322
60f067b4 323 LIST_REMOVE(object, l->object->object_list, l);
663996b3
MS
324
325 free(l);
326}
327
6e866b33 328void job_dump(Job *j, FILE *f, const char *prefix) {
663996b3
MS
329 assert(j);
330 assert(f);
331
1d42b86d 332 prefix = strempty(prefix);
663996b3
MS
333
334 fprintf(f,
335 "%s-> Job %u:\n"
336 "%s\tAction: %s -> %s\n"
337 "%s\tState: %s\n"
98393f85
MB
338 "%s\tIrreversible: %s\n"
339 "%s\tMay GC: %s\n",
663996b3
MS
340 prefix, j->id,
341 prefix, j->unit->id, job_type_to_string(j->type),
342 prefix, job_state_to_string(j->state),
98393f85
MB
343 prefix, yes_no(j->irreversible),
344 prefix, yes_no(job_may_gc(j)));
663996b3
MS
345}
346
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 *
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 *
e3bff60a
MP
356 * Merging is associative! A merged with B, and then merged with C is the same
357 * as A merged with the result of B merged with C.
663996b3
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[] = {
366/* What \ With * JOB_START JOB_VERIFY_ACTIVE JOB_STOP JOB_RELOAD */
367/*********************************************************************************/
368/*JOB_START */
369/*JOB_VERIFY_ACTIVE */ JOB_START,
370/*JOB_STOP */ -1, -1,
371/*JOB_RELOAD */ JOB_RELOAD_OR_START, JOB_RELOAD, -1,
372/*JOB_RESTART */ JOB_RESTART, JOB_RESTART, -1, JOB_RESTART,
373};
374
375JobType job_type_lookup_merge(JobType a, JobType b) {
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);
379
380 if (a == b)
381 return a;
382
383 if (a < b) {
384 JobType tmp = a;
385 a = b;
386 b = tmp;
387 }
388
389 return job_merging_table[(a - 1) * a / 2 + b];
390}
391
478ed938
MB
392bool job_type_is_redundant(JobType a, UnitActiveState b) {
393 switch (a) {
663996b3
MS
394
395 case JOB_START:
478ed938 396 return IN_SET(b, UNIT_ACTIVE, UNIT_RELOADING);
663996b3
MS
397
398 case JOB_STOP:
478ed938 399 return IN_SET(b, UNIT_INACTIVE, UNIT_FAILED);
663996b3
MS
400
401 case JOB_VERIFY_ACTIVE:
478ed938 402 return IN_SET(b, UNIT_ACTIVE, UNIT_RELOADING);
663996b3
MS
403
404 case JOB_RELOAD:
405 return
478ed938 406 b == UNIT_RELOADING;
663996b3
MS
407
408 case JOB_RESTART:
086111aa
LB
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;
663996b3 425
f47781d8
MP
426 case JOB_NOP:
427 return true;
428
663996b3 429 default:
ea0999c9 430 assert_not_reached();
663996b3
MS
431 }
432}
433
e3bff60a 434JobType job_type_collapse(JobType t, Unit *u) {
663996b3
MS
435 UnitActiveState s;
436
e3bff60a 437 switch (t) {
663996b3
MS
438
439 case JOB_TRY_RESTART:
086111aa
LB
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 */
663996b3 444 s = unit_active_state(u);
086111aa 445 if (!UNIT_IS_ACTIVE_OR_ACTIVATING(s))
e3bff60a
MP
446 return JOB_NOP;
447
448 return JOB_RESTART;
663996b3 449
4c89c718
MP
450 case JOB_TRY_RELOAD:
451 s = unit_active_state(u);
e1f67bc7 452 if (!UNIT_IS_ACTIVE_OR_RELOADING(s))
4c89c718
MP
453 return JOB_NOP;
454
455 return JOB_RELOAD;
456
663996b3
MS
457 case JOB_RELOAD_OR_START:
458 s = unit_active_state(u);
e1f67bc7 459 if (!UNIT_IS_ACTIVE_OR_RELOADING(s))
e3bff60a
MP
460 return JOB_START;
461
462 return JOB_RELOAD;
663996b3
MS
463
464 default:
e3bff60a 465 return t;
663996b3
MS
466 }
467}
468
469int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u) {
e3bff60a
MP
470 JobType t;
471
472 t = job_type_lookup_merge(*a, b);
663996b3
MS
473 if (t < 0)
474 return -EEXIST;
e3bff60a
MP
475
476 *a = job_type_collapse(t, u);
663996b3
MS
477 return 0;
478}
479
60f067b4 480static bool job_is_runnable(Job *j) {
663996b3
MS
481 Unit *other;
482
483 assert(j);
484 assert(j->installed);
485
486 /* Checks whether there is any job running for the units this
487 * job needs to be running after (in the case of a 'positive'
488 * job type) or before (in the case of a 'negative' job
489 * type. */
490
60f067b4
JS
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
663996b3
MS
496 /* First check if there is an override */
497 if (j->ignore_order)
498 return true;
499
500 if (j->type == JOB_NOP)
501 return true;
502
8b3d4ff0
MB
503 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_AFTER)
504 if (other->job && job_compare(j, other->job, UNIT_ATOM_AFTER) > 0) {
20a6e51f
MB
505 log_unit_debug(j->unit,
506 "starting held back, waiting for: %s",
507 other->id);
f2dec872 508 return false;
20a6e51f 509 }
663996b3 510
8b3d4ff0
MB
511 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_BEFORE)
512 if (other->job && job_compare(j, other->job, UNIT_ATOM_BEFORE) > 0) {
20a6e51f
MB
513 log_unit_debug(j->unit,
514 "stopping held back, waiting for: %s",
515 other->id);
663996b3 516 return false;
20a6e51f 517 }
663996b3 518
663996b3
MS
519 return true;
520}
521
522static void job_change_type(Job *j, JobType newtype) {
e3bff60a
MP
523 assert(j);
524
525 log_unit_debug(j->unit,
663996b3
MS
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));
529
530 j->type = newtype;
531}
532
67bbd050 533static const char* job_start_message_format(Unit *u, JobType t) {
6e866b33 534 assert(u);
67bbd050 535 assert(IN_SET(t, JOB_START, JOB_STOP, JOB_RELOAD));
6e866b33
MB
536
537 if (t == JOB_RELOAD)
67bbd050
MB
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}
6e866b33 544
67bbd050
MB
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;
6e866b33 548
67bbd050
MB
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. */
6e866b33 553
67bbd050
MB
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;
6e866b33
MB
595 }
596}
597
67bbd050
MB
598static const char* job_done_message_format(Unit *u, JobType t, JobResult result) {
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 };
6e866b33
MB
625 const char *format;
626
627 assert(u);
67bbd050
MB
628 assert(t >= 0);
629 assert(t < _JOB_TYPE_MAX);
6e866b33 630
086111aa 631 /* Show condition check message if the job did not actually do anything due to unmet condition. */
67bbd050
MB
632 if (t == JOB_START && result == JOB_DONE && !u->condition_result)
633 return "Condition check resulted in %s being skipped.";
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)
640 return format;
641 }
6e866b33 642
67bbd050
MB
643 format = (t == JOB_START ? formats->finished_start_job : formats->finished_stop_job)[result];
644 if (format)
645 return format;
646 }
6e866b33 647
67bbd050
MB
648 /* Return generic strings */
649 switch (t) {
650 case JOB_START:
651 return generic_finished_start_job[result];
652 case JOB_STOP:
653 case JOB_RESTART:
654 return generic_finished_stop_job[result];
655 case JOB_RELOAD:
656 return generic_finished_reload_job[result];
657 case JOB_VERIFY_ACTIVE:
658 return generic_finished_verify_active_job[result];
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 }
6e866b33
MB
699}
700
67bbd050
MB
701static void job_emit_done_message(Unit *u, uint32_t job_id, JobType t, JobResult result) {
702 _cleanup_free_ char *free_ident = NULL;
703 const char *ident, *format;
6e866b33
MB
704
705 assert(u);
706 assert(t >= 0);
707 assert(t < _JOB_TYPE_MAX);
708
67bbd050 709 if (!unit_log_level_test(u, job_done_messages[result].log_level))
6e866b33
MB
710 return;
711
67bbd050
MB
712 format = job_done_message_format(u, t, result);
713 if (!format)
5b5a102a
MB
714 return;
715
67bbd050 716 ident = unit_status_string(u, &free_ident);
6e866b33 717
67bbd050
MB
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();
6e866b33 721
67bbd050 722 if (t == JOB_START && result == JOB_DONE && !u->condition_result) {
086111aa 723 /* No message on the console if the job did not actually do anything due to unmet condition. */
67bbd050
MB
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. */
ea0999c9 732 Condition *c;
67bbd050 733 const char *mid = job_done_mid(t, result); /* mid may be NULL. log_unit_struct() will ignore it. */
67bbd050 734
ea0999c9
MB
735 c = t == JOB_START && result == JOB_DONE ? unit_find_failed_condition(u) : NULL;
736 if (c) {
086111aa 737 /* Special case units that were skipped because of a unmet condition check so that
ea0999c9
MB
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,
086111aa 743 LOG_MESSAGE("%s was skipped because no trigger condition checks were met.",
b3e21333 744 ident),
ea0999c9
MB
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,
086111aa 754 LOG_MESSAGE("%s was skipped because of an unmet condition check (%s=%s%s).",
b3e21333
LB
755 ident,
756 condition_type_to_string(c->type),
757 c->negate ? "!" : "",
758 c->parameter),
ea0999c9
MB
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 }
67bbd050
MB
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 }
6e866b33
MB
800}
801
7035cd9e 802static int job_perform_on_unit(Job **j) {
086111aa 803 ActivationDetails *a;
db2df898
MP
804 uint32_t id;
805 Manager *m;
806 JobType t;
807 Unit *u;
7035cd9e
MP
808 int r;
809
db2df898
MP
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;
086111aa 823 a = (*j)->activation_details;
db2df898 824
7035cd9e
MP
825 switch (t) {
826 case JOB_START:
086111aa 827 r = unit_start(u, a);
7035cd9e
MP
828 break;
829
830 case JOB_RESTART:
831 t = JOB_STOP;
52ad194e 832 _fallthrough_;
7035cd9e
MP
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:
ea0999c9 842 assert_not_reached();
7035cd9e
MP
843 }
844
6e866b33
MB
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. */
7035cd9e
MP
848 *j = manager_get_job(m, id);
849 if (*j && r > 0)
67bbd050 850 job_emit_start_message(u, id, t);
7035cd9e
MP
851
852 return r;
853}
854
663996b3
MS
855int job_run_and_invalidate(Job *j) {
856 int r;
663996b3
MS
857
858 assert(j);
859 assert(j->installed);
860 assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
861 assert(j->in_run_queue);
862
f2dec872 863 prioq_remove(j->manager->run_queue, j, &j->run_queue_idx);
663996b3
MS
864 j->in_run_queue = false;
865
866 if (j->state != JOB_WAITING)
867 return 0;
868
869 if (!job_is_runnable(j))
870 return -EAGAIN;
871
81c58355 872 job_start_timer(j, true);
e735f4d4 873 job_set_state(j, JOB_RUNNING);
663996b3
MS
874 job_add_to_dbus_queue(j);
875
663996b3
MS
876 switch (j->type) {
877
663996b3 878 case JOB_VERIFY_ACTIVE: {
6e866b33
MB
879 UnitActiveState t;
880
881 t = unit_active_state(j->unit);
663996b3
MS
882 if (UNIT_IS_ACTIVE_OR_RELOADING(t))
883 r = -EALREADY;
884 else if (t == UNIT_ACTIVATING)
885 r = -EAGAIN;
886 else
60f067b4 887 r = -EBADR;
663996b3
MS
888 break;
889 }
890
7035cd9e 891 case JOB_START:
663996b3
MS
892 case JOB_STOP:
893 case JOB_RESTART:
7035cd9e 894 r = job_perform_on_unit(&j);
663996b3 895
6e866b33 896 /* If the unit type does not support starting/stopping, then simply wait. */
663996b3
MS
897 if (r == -EBADR)
898 r = 0;
899 break;
900
901 case JOB_RELOAD:
7035cd9e 902 r = job_perform_on_unit(&j);
663996b3
MS
903 break;
904
905 case JOB_NOP:
906 r = -EALREADY;
907 break;
908
909 default:
ea0999c9 910 assert_not_reached();
663996b3
MS
911 }
912
663996b3 913 if (j) {
6e866b33
MB
914 if (r == -EAGAIN)
915 job_set_state(j, JOB_WAITING); /* Hmm, not ready after all, let's return to JOB_WAITING state */
916 else if (r == -EALREADY) /* already being executed */
aa27b158 917 r = job_finish_and_invalidate(j, JOB_DONE, true, true);
086111aa
LB
918 else if (r == -ECOMM)
919 r = job_finish_and_invalidate(j, JOB_DONE, true, false);
60f067b4 920 else if (r == -EBADR)
aa27b158 921 r = job_finish_and_invalidate(j, JOB_SKIPPED, true, false);
60f067b4 922 else if (r == -ENOEXEC)
aa27b158 923 r = job_finish_and_invalidate(j, JOB_INVALID, true, false);
f47781d8 924 else if (r == -EPROTO)
aa27b158 925 r = job_finish_and_invalidate(j, JOB_ASSERT, true, false);
e3bff60a 926 else if (r == -EOPNOTSUPP)
aa27b158 927 r = job_finish_and_invalidate(j, JOB_UNSUPPORTED, true, false);
2897b343
MP
928 else if (r == -ENOLINK)
929 r = job_finish_and_invalidate(j, JOB_DEPENDENCY, true, false);
b012e921
MB
930 else if (r == -ESTALE)
931 r = job_finish_and_invalidate(j, JOB_ONCE, true, false);
e735f4d4 932 else if (r < 0)
aa27b158 933 r = job_finish_and_invalidate(j, JOB_FAILED, true, false);
663996b3
MS
934 }
935
936 return r;
937}
938
8b3d4ff0 939static void job_fail_dependencies(Unit *u, UnitDependencyAtom match_atom) {
e3bff60a 940 Unit *other;
e3bff60a
MP
941
942 assert(u);
943
8b3d4ff0 944 UNIT_FOREACH_DEPENDENCY(other, u, match_atom) {
e3bff60a
MP
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
aa27b158 952 job_finish_and_invalidate(j, JOB_DEPENDENCY, true, false);
e3bff60a 953 }
663996b3 954}
663996b3 955
aa27b158 956int job_finish_and_invalidate(Job *j, JobResult result, bool recursive, bool already) {
8b3d4ff0 957 Unit *u, *other;
663996b3 958 JobType t;
663996b3
MS
959
960 assert(j);
961 assert(j->installed);
962 assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
963
964 u = j->unit;
965 t = j->type;
966
967 j->result = result;
968
a10f5d05
MB
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));
663996b3 971
a10f5d05 972 /* If this job did nothing to the respective unit we don't log the status message */
aa27b158 973 if (!already)
67bbd050 974 job_emit_done_message(u, j->id, t, result);
663996b3 975
663996b3
MS
976 /* Patch restart jobs so that they become normal start jobs */
977 if (result == JOB_DONE && t == JOB_RESTART) {
978
979 job_change_type(j, JOB_START);
e735f4d4 980 job_set_state(j, JOB_WAITING);
663996b3 981
52ad194e 982 job_add_to_dbus_queue(j);
663996b3 983 job_add_to_run_queue(j);
2897b343 984 job_add_to_gc_queue(j);
663996b3
MS
985
986 goto finish;
987 }
988
f5e65279 989 if (IN_SET(result, JOB_FAILED, JOB_INVALID))
aa27b158 990 j->manager->n_failed_jobs++;
663996b3
MS
991
992 job_uninstall(j);
6e866b33 993 job_free(j);
663996b3
MS
994
995 /* Fail depending jobs on failure */
996 if (result != JOB_DONE && recursive) {
8b3d4ff0
MB
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);
663996b3
MS
1001 }
1002
8b3d4ff0 1003 /* A special check to make sure we take down anything RequisiteOf= if we aren't active. This is when
ecfb185f 1004 * the verify-active job merges with a satisfying job type, and then loses its invalidation effect,
8b3d4ff0
MB
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.
bb4f798a 1008 *
8b3d4ff0
MB
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:
bb4f798a 1012 *
8b3d4ff0
MB
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.
bb4f798a 1016 *
8b3d4ff0
MB
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.
bb4f798a 1019 */
8b3d4ff0
MB
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. */
f5e65279 1027 if (IN_SET(result, JOB_TIMEOUT, JOB_DEPENDENCY)) {
5b5a102a
MB
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)));
663996b3 1035
8b3d4ff0 1036 unit_start_on_failure(u, "OnFailure=", UNIT_ATOM_ON_FAILURE, u->on_failure_job_mode);
663996b3
MS
1037 }
1038
1039 unit_trigger_notify(u);
1040
1041finish:
1042 /* Try to start the next jobs that can be started */
8b3d4ff0 1043 UNIT_FOREACH_DEPENDENCY(other, u, UNIT_ATOM_AFTER)
2897b343 1044 if (other->job) {
663996b3 1045 job_add_to_run_queue(other->job);
2897b343
MP
1046 job_add_to_gc_queue(other->job);
1047 }
8b3d4ff0 1048 UNIT_FOREACH_DEPENDENCY(other, u, UNIT_ATOM_BEFORE)
2897b343 1049 if (other->job) {
663996b3 1050 job_add_to_run_queue(other->job);
2897b343
MP
1051 job_add_to_gc_queue(other->job);
1052 }
663996b3 1053
ecfb185f
LB
1054 /* Ensure that when an upheld/unneeded/bound unit activation job fails we requeue it, if it still
1055 * necessary. If there are no state changes in the triggerer, it would not be retried otherwise. */
1056 unit_submit_to_start_when_upheld_queue(u);
1057 unit_submit_to_stop_when_bound_queue(u);
1058 unit_submit_to_stop_when_unneeded_queue(u);
1059
663996b3
MS
1060 manager_check_finished(u->manager);
1061
1062 return 0;
1063}
1064
60f067b4 1065static int job_dispatch_timer(sd_event_source *s, uint64_t monotonic, void *userdata) {
086111aa 1066 Job *j = ASSERT_PTR(userdata);
5eef597e 1067 Unit *u;
663996b3 1068
60f067b4 1069 assert(s == j->timer_event_source);
663996b3 1070
e3bff60a 1071 log_unit_warning(j->unit, "Job %s/%s timed out.", j->unit->id, job_type_to_string(j->type));
663996b3 1072
5eef597e 1073 u = j->unit;
aa27b158 1074 job_finish_and_invalidate(j, JOB_TIMEOUT, true, false);
5eef597e 1075
6e866b33
MB
1076 emergency_action(u->manager, u->job_timeout_action,
1077 EMERGENCY_ACTION_IS_WATCHDOG|EMERGENCY_ACTION_WARN,
1078 u->job_timeout_reboot_arg, -1, "job timed out");
5eef597e 1079
60f067b4
JS
1080 return 0;
1081}
663996b3 1082
81c58355 1083int job_start_timer(Job *j, bool job_running) {
60f067b4 1084 int r;
81c58355 1085 usec_t timeout_time, old_timeout_time;
663996b3 1086
81c58355
MB
1087 if (job_running) {
1088 j->begin_running_usec = now(CLOCK_MONOTONIC);
663996b3 1089
81c58355
MB
1090 if (j->unit->job_running_timeout == USEC_INFINITY)
1091 return 0;
663996b3 1092
81c58355
MB
1093 timeout_time = usec_add(j->begin_running_usec, j->unit->job_running_timeout);
1094
1095 if (j->timer_event_source) {
1096 /* Update only if JobRunningTimeoutSec= results in earlier timeout */
1097 r = sd_event_source_get_time(j->timer_event_source, &old_timeout_time);
1098 if (r < 0)
1099 return r;
1100
1101 if (old_timeout_time <= timeout_time)
1102 return 0;
1103
1104 return sd_event_source_set_time(j->timer_event_source, timeout_time);
1105 }
1106 } else {
1107 if (j->timer_event_source)
1108 return 0;
1109
1110 j->begin_usec = now(CLOCK_MONOTONIC);
1111
1112 if (j->unit->job_timeout == USEC_INFINITY)
1113 return 0;
1114
1115 timeout_time = usec_add(j->begin_usec, j->unit->job_timeout);
1116 }
663996b3 1117
60f067b4
JS
1118 r = sd_event_add_time(
1119 j->manager->event,
1120 &j->timer_event_source,
1121 CLOCK_MONOTONIC,
81c58355 1122 timeout_time, 0,
60f067b4
JS
1123 job_dispatch_timer, j);
1124 if (r < 0)
1125 return r;
663996b3 1126
e3bff60a
MP
1127 (void) sd_event_source_set_description(j->timer_event_source, "job-start");
1128
60f067b4 1129 return 0;
663996b3
MS
1130}
1131
1132void job_add_to_run_queue(Job *j) {
6e866b33
MB
1133 int r;
1134
663996b3
MS
1135 assert(j);
1136 assert(j->installed);
1137
1138 if (j->in_run_queue)
1139 return;
1140
c5fca32e
MB
1141 r = prioq_put(j->manager->run_queue, j, &j->run_queue_idx);
1142 if (r < 0)
1143 log_warning_errno(r, "Failed put job in run queue, ignoring: %m");
1144 else
1145 j->in_run_queue = true;
ea0999c9
MB
1146
1147 manager_trigger_run_queue(j->manager);
663996b3
MS
1148}
1149
1150void job_add_to_dbus_queue(Job *j) {
1151 assert(j);
1152 assert(j->installed);
1153
1154 if (j->in_dbus_queue)
1155 return;
1156
1157 /* We don't check if anybody is subscribed here, since this
1158 * job might just have been created and not yet assigned to a
1159 * connection/client. */
1160
60f067b4 1161 LIST_PREPEND(dbus_queue, j->manager->dbus_job_queue, j);
663996b3
MS
1162 j->in_dbus_queue = true;
1163}
1164
1165char *job_dbus_path(Job *j) {
1166 char *p;
1167
1168 assert(j);
1169
60f067b4 1170 if (asprintf(&p, "/org/freedesktop/systemd1/job/%"PRIu32, j->id) < 0)
663996b3
MS
1171 return NULL;
1172
1173 return p;
1174}
1175
8a584da2
MP
1176int job_serialize(Job *j, FILE *f) {
1177 assert(j);
1178 assert(f);
1179
6e866b33
MB
1180 (void) serialize_item_format(f, "job-id", "%u", j->id);
1181 (void) serialize_item(f, "job-type", job_type_to_string(j->type));
1182 (void) serialize_item(f, "job-state", job_state_to_string(j->state));
1183 (void) serialize_bool(f, "job-irreversible", j->irreversible);
1184 (void) serialize_bool(f, "job-sent-dbus-new-signal", j->sent_dbus_new_signal);
1185 (void) serialize_bool(f, "job-ignore-order", j->ignore_order);
60f067b4
JS
1186
1187 if (j->begin_usec > 0)
6e866b33 1188 (void) serialize_usec(f, "job-begin", j->begin_usec);
81c58355 1189 if (j->begin_running_usec > 0)
6e866b33 1190 (void) serialize_usec(f, "job-begin-running", j->begin_running_usec);
60f067b4 1191
2897b343 1192 bus_track_serialize(j->bus_track, f, "subscribed");
663996b3 1193
086111aa
LB
1194 activation_details_serialize(j->activation_details, f);
1195
663996b3
MS
1196 /* End marker */
1197 fputc('\n', f);
1198 return 0;
1199}
1200
8a584da2 1201int job_deserialize(Job *j, FILE *f) {
6e866b33
MB
1202 int r;
1203
60f067b4 1204 assert(j);
8a584da2 1205 assert(f);
60f067b4 1206
663996b3 1207 for (;;) {
6e866b33
MB
1208 _cleanup_free_ char *line = NULL;
1209 char *l, *v;
663996b3
MS
1210 size_t k;
1211
6e866b33
MB
1212 r = read_line(f, LONG_LINE_MAX, &line);
1213 if (r < 0)
1214 return log_error_errno(r, "Failed to read serialization line: %m");
1215 if (r == 0)
1216 return 0;
663996b3 1217
663996b3
MS
1218 l = strstrip(line);
1219
1220 /* End marker */
6e866b33 1221 if (isempty(l))
663996b3
MS
1222 return 0;
1223
1224 k = strcspn(l, "=");
1225
1226 if (l[k] == '=') {
1227 l[k] = 0;
1228 v = l+k+1;
1229 } else
1230 v = l+k;
1231
1232 if (streq(l, "job-id")) {
60f067b4 1233
663996b3 1234 if (safe_atou32(v, &j->id) < 0)
6e866b33 1235 log_debug("Failed to parse job id value: %s", v);
60f067b4 1236
663996b3 1237 } else if (streq(l, "job-type")) {
60f067b4
JS
1238 JobType t;
1239
1240 t = job_type_from_string(v);
663996b3 1241 if (t < 0)
6e866b33 1242 log_debug("Failed to parse job type: %s", v);
663996b3 1243 else if (t >= _JOB_TYPE_MAX_IN_TRANSACTION)
6e866b33 1244 log_debug("Cannot deserialize job of type: %s", v);
663996b3
MS
1245 else
1246 j->type = t;
60f067b4 1247
663996b3 1248 } else if (streq(l, "job-state")) {
60f067b4
JS
1249 JobState s;
1250
1251 s = job_state_from_string(v);
663996b3 1252 if (s < 0)
6e866b33 1253 log_debug("Failed to parse job state: %s", v);
663996b3 1254 else
e735f4d4 1255 job_set_state(j, s);
60f067b4 1256
663996b3 1257 } else if (streq(l, "job-irreversible")) {
60f067b4
JS
1258 int b;
1259
1260 b = parse_boolean(v);
663996b3 1261 if (b < 0)
6e866b33 1262 log_debug("Failed to parse job irreversible flag: %s", v);
663996b3
MS
1263 else
1264 j->irreversible = j->irreversible || b;
60f067b4 1265
663996b3 1266 } else if (streq(l, "job-sent-dbus-new-signal")) {
60f067b4
JS
1267 int b;
1268
1269 b = parse_boolean(v);
663996b3 1270 if (b < 0)
6e866b33 1271 log_debug("Failed to parse job sent_dbus_new_signal flag: %s", v);
663996b3
MS
1272 else
1273 j->sent_dbus_new_signal = j->sent_dbus_new_signal || b;
60f067b4 1274
663996b3 1275 } else if (streq(l, "job-ignore-order")) {
60f067b4
JS
1276 int b;
1277
1278 b = parse_boolean(v);
663996b3 1279 if (b < 0)
6e866b33 1280 log_debug("Failed to parse job ignore_order flag: %s", v);
663996b3
MS
1281 else
1282 j->ignore_order = j->ignore_order || b;
60f067b4 1283
6e866b33
MB
1284 } else if (streq(l, "job-begin"))
1285 (void) deserialize_usec(v, &j->begin_usec);
81c58355 1286
6e866b33
MB
1287 else if (streq(l, "job-begin-running"))
1288 (void) deserialize_usec(v, &j->begin_running_usec);
60f067b4 1289
6e866b33 1290 else if (streq(l, "subscribed")) {
5eef597e 1291 if (strv_extend(&j->deserialized_clients, v) < 0)
6e866b33 1292 return log_oom();
086111aa
LB
1293
1294 } else if (startswith(l, "activation-details")) {
1295 if (activation_details_deserialize(l, v, &j->activation_details) < 0)
1296 log_debug("Failed to parse job ActivationDetails element: %s", v);
1297
6e866b33
MB
1298 } else
1299 log_debug("Unknown job serialization key: %s", l);
663996b3
MS
1300 }
1301}
1302
1303int job_coldplug(Job *j) {
60f067b4 1304 int r;
81c58355 1305 usec_t timeout_time = USEC_INFINITY;
663996b3 1306
60f067b4
JS
1307 assert(j);
1308
1309 /* After deserialization is complete and the bus connection
1310 * set up again, let's start watching our subscribers again */
2897b343 1311 (void) bus_job_coldplug_bus_track(j);
60f067b4
JS
1312
1313 if (j->state == JOB_WAITING)
1314 job_add_to_run_queue(j);
1315
2897b343
MP
1316 /* Maybe due to new dependencies we don't actually need this job anymore? */
1317 job_add_to_gc_queue(j);
1318
81c58355
MB
1319 /* Create timer only when job began or began running and the respective timeout is finite.
1320 * Follow logic of job_start_timer() if both timeouts are finite */
1321 if (j->begin_usec == 0)
1322 return 0;
1323
1324 if (j->unit->job_timeout != USEC_INFINITY)
1325 timeout_time = usec_add(j->begin_usec, j->unit->job_timeout);
1326
f2dec872 1327 if (timestamp_is_set(j->begin_running_usec))
81c58355
MB
1328 timeout_time = MIN(timeout_time, usec_add(j->begin_running_usec, j->unit->job_running_timeout));
1329
1330 if (timeout_time == USEC_INFINITY)
663996b3
MS
1331 return 0;
1332
67bbd050 1333 j->timer_event_source = sd_event_source_disable_unref(j->timer_event_source);
663996b3 1334
60f067b4
JS
1335 r = sd_event_add_time(
1336 j->manager->event,
1337 &j->timer_event_source,
1338 CLOCK_MONOTONIC,
81c58355 1339 timeout_time, 0,
60f067b4
JS
1340 job_dispatch_timer, j);
1341 if (r < 0)
f47781d8 1342 log_debug_errno(r, "Failed to restart timeout for job: %m");
60f067b4 1343
e3bff60a
MP
1344 (void) sd_event_source_set_description(j->timer_event_source, "job-timeout");
1345
60f067b4 1346 return r;
663996b3
MS
1347}
1348
1349void job_shutdown_magic(Job *j) {
1350 assert(j);
1351
1352 /* The shutdown target gets some special treatment here: we
1353 * tell the kernel to begin with flushing its disk caches, to
1354 * optimize shutdown time a bit. Ideally we wouldn't hardcode
1355 * this magic into PID 1. However all other processes aren't
1356 * options either since they'd exit much sooner than PID 1 and
1357 * asynchronous sync() would cause their exit to be
1358 * delayed. */
1359
14228c0d 1360 if (j->type != JOB_START)
663996b3
MS
1361 return;
1362
aa27b158 1363 if (!MANAGER_IS_SYSTEM(j->unit->manager))
14228c0d
MB
1364 return;
1365
1366 if (!unit_has_name(j->unit, SPECIAL_SHUTDOWN_TARGET))
663996b3
MS
1367 return;
1368
60f067b4
JS
1369 /* In case messages on console has been disabled on boot */
1370 j->unit->manager->no_console_output = false;
1371
ea0999c9
MB
1372 manager_invalidate_startup_units(j->unit->manager);
1373
6300502b 1374 if (detect_container() > 0)
663996b3
MS
1375 return;
1376
1d42b86d 1377 (void) asynchronous_sync(NULL);
663996b3
MS
1378}
1379
4c89c718
MP
1380int job_get_timeout(Job *j, usec_t *timeout) {
1381 usec_t x = USEC_INFINITY, y = USEC_INFINITY;
086111aa 1382 Unit *u = ASSERT_PTR(ASSERT_PTR(j)->unit);
4c89c718 1383 int r;
60f067b4 1384
60f067b4
JS
1385 if (j->timer_event_source) {
1386 r = sd_event_source_get_time(j->timer_event_source, &x);
1387 if (r < 0)
1388 return r;
60f067b4
JS
1389 }
1390
1391 if (UNIT_VTABLE(u)->get_timeout) {
4c89c718
MP
1392 r = UNIT_VTABLE(u)->get_timeout(u, &y);
1393 if (r < 0)
1394 return r;
60f067b4
JS
1395 }
1396
4c89c718 1397 if (x == USEC_INFINITY && y == USEC_INFINITY)
60f067b4
JS
1398 return 0;
1399
1400 *timeout = MIN(x, y);
60f067b4
JS
1401 return 1;
1402}
1403
98393f85 1404bool job_may_gc(Job *j) {
2897b343 1405 Unit *other;
2897b343
MP
1406
1407 assert(j);
1408
1409 /* Checks whether this job should be GC'ed away. We only do this for jobs of units that have no effect on their
98393f85
MB
1410 * own and just track external state. For now the only unit type that qualifies for this are .device units.
1411 * Returns true if the job can be collected. */
2897b343
MP
1412
1413 if (!UNIT_VTABLE(j->unit)->gc_jobs)
98393f85 1414 return false;
2897b343
MP
1415
1416 if (sd_bus_track_count(j->bus_track) > 0)
98393f85 1417 return false;
2897b343
MP
1418
1419 /* FIXME: So this is a bit ugly: for now we don't properly track references made via private bus connections
1420 * (because it's nasty, as sd_bus_track doesn't apply to it). We simply remember that the job was once
1421 * referenced by one, and reset this whenever we notice that no private bus connections are around. This means
1422 * the GC is a bit too conservative when it comes to jobs created by private bus connections. */
1423 if (j->ref_by_private_bus) {
1424 if (set_isempty(j->unit->manager->private_buses))
1425 j->ref_by_private_bus = false;
1426 else
98393f85 1427 return false;
2897b343
MP
1428 }
1429
1430 if (j->type == JOB_NOP)
98393f85 1431 return false;
2897b343 1432
f2dec872 1433 /* The logic is inverse to job_is_runnable, we cannot GC as long as we block any job. */
8b3d4ff0
MB
1434 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_BEFORE)
1435 if (other->job && job_compare(j, other->job, UNIT_ATOM_BEFORE) < 0)
98393f85 1436 return false;
2897b343 1437
8b3d4ff0
MB
1438 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_AFTER)
1439 if (other->job && job_compare(j, other->job, UNIT_ATOM_AFTER) < 0)
98393f85 1440 return false;
2897b343 1441
98393f85 1442 return true;
2897b343
MP
1443}
1444
1445void job_add_to_gc_queue(Job *j) {
1446 assert(j);
1447
1448 if (j->in_gc_queue)
1449 return;
1450
98393f85 1451 if (!job_may_gc(j))
2897b343
MP
1452 return;
1453
1454 LIST_PREPEND(gc_queue, j->unit->manager->gc_job_queue, j);
1455 j->in_gc_queue = true;
1456}
1457
f2dec872 1458static int job_compare_id(Job * const *a, Job * const *b) {
6e866b33 1459 return CMP((*a)->id, (*b)->id);
2897b343
MP
1460}
1461
1462static size_t sort_job_list(Job **list, size_t n) {
1463 Job *previous = NULL;
1464 size_t a, b;
1465
1466 /* Order by numeric IDs */
f2dec872 1467 typesafe_qsort(list, n, job_compare_id);
2897b343
MP
1468
1469 /* Filter out duplicates */
1470 for (a = 0, b = 0; a < n; a++) {
1471
1472 if (previous == list[a])
1473 continue;
1474
1475 previous = list[b++] = list[a];
1476 }
1477
1478 return b;
1479}
1480
1481int job_get_before(Job *j, Job*** ret) {
1482 _cleanup_free_ Job** list = NULL;
2897b343 1483 Unit *other = NULL;
8b3d4ff0 1484 size_t n = 0;
2897b343
MP
1485
1486 /* Returns a list of all pending jobs that need to finish before this job may be started. */
1487
1488 assert(j);
1489 assert(ret);
1490
1491 if (j->ignore_order) {
1492 *ret = NULL;
1493 return 0;
1494 }
1495
8b3d4ff0 1496 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_AFTER) {
f2dec872
BR
1497 if (!other->job)
1498 continue;
8b3d4ff0 1499 if (job_compare(j, other->job, UNIT_ATOM_AFTER) <= 0)
f2dec872 1500 continue;
2897b343 1501
8b3d4ff0 1502 if (!GREEDY_REALLOC(list, n+1))
f2dec872
BR
1503 return -ENOMEM;
1504 list[n++] = other->job;
2897b343
MP
1505 }
1506
8b3d4ff0 1507 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_BEFORE) {
2897b343
MP
1508 if (!other->job)
1509 continue;
8b3d4ff0 1510 if (job_compare(j, other->job, UNIT_ATOM_BEFORE) <= 0)
2897b343
MP
1511 continue;
1512
8b3d4ff0 1513 if (!GREEDY_REALLOC(list, n+1))
2897b343
MP
1514 return -ENOMEM;
1515 list[n++] = other->job;
1516 }
1517
1518 n = sort_job_list(list, n);
1519
b012e921 1520 *ret = TAKE_PTR(list);
2897b343
MP
1521
1522 return (int) n;
1523}
1524
1525int job_get_after(Job *j, Job*** ret) {
1526 _cleanup_free_ Job** list = NULL;
2897b343 1527 Unit *other = NULL;
8b3d4ff0 1528 size_t n = 0;
2897b343
MP
1529
1530 assert(j);
1531 assert(ret);
1532
1533 /* Returns a list of all pending jobs that are waiting for this job to finish. */
1534
8b3d4ff0 1535 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_BEFORE) {
2897b343
MP
1536 if (!other->job)
1537 continue;
1538
1539 if (other->job->ignore_order)
1540 continue;
1541
8b3d4ff0 1542 if (job_compare(j, other->job, UNIT_ATOM_BEFORE) >= 0)
2897b343
MP
1543 continue;
1544
8b3d4ff0 1545 if (!GREEDY_REALLOC(list, n+1))
2897b343
MP
1546 return -ENOMEM;
1547 list[n++] = other->job;
1548 }
1549
8b3d4ff0 1550 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_AFTER) {
f2dec872
BR
1551 if (!other->job)
1552 continue;
2897b343 1553
f2dec872
BR
1554 if (other->job->ignore_order)
1555 continue;
2897b343 1556
8b3d4ff0 1557 if (job_compare(j, other->job, UNIT_ATOM_AFTER) >= 0)
f2dec872 1558 continue;
2897b343 1559
8b3d4ff0 1560 if (!GREEDY_REALLOC(list, n+1))
f2dec872
BR
1561 return -ENOMEM;
1562 list[n++] = other->job;
2897b343
MP
1563 }
1564
1565 n = sort_job_list(list, n);
1566
b012e921 1567 *ret = TAKE_PTR(list);
2897b343
MP
1568
1569 return (int) n;
1570}
1571
663996b3
MS
1572static const char* const job_state_table[_JOB_STATE_MAX] = {
1573 [JOB_WAITING] = "waiting",
2897b343 1574 [JOB_RUNNING] = "running",
663996b3
MS
1575};
1576
1577DEFINE_STRING_TABLE_LOOKUP(job_state, JobState);
1578
1579static const char* const job_type_table[_JOB_TYPE_MAX] = {
ea0999c9
MB
1580 [JOB_START] = "start",
1581 [JOB_VERIFY_ACTIVE] = "verify-active",
1582 [JOB_STOP] = "stop",
1583 [JOB_RELOAD] = "reload",
663996b3 1584 [JOB_RELOAD_OR_START] = "reload-or-start",
ea0999c9
MB
1585 [JOB_RESTART] = "restart",
1586 [JOB_TRY_RESTART] = "try-restart",
1587 [JOB_TRY_RELOAD] = "try-reload",
1588 [JOB_NOP] = "nop",
663996b3
MS
1589};
1590
1591DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
1592
1593static const char* const job_mode_table[_JOB_MODE_MAX] = {
ea0999c9
MB
1594 [JOB_FAIL] = "fail",
1595 [JOB_REPLACE] = "replace",
663996b3 1596 [JOB_REPLACE_IRREVERSIBLY] = "replace-irreversibly",
ea0999c9
MB
1597 [JOB_ISOLATE] = "isolate",
1598 [JOB_FLUSH] = "flush",
1599 [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
1600 [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements",
1601 [JOB_TRIGGERING] = "triggering",
663996b3
MS
1602};
1603
1604DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);
1605
1606static const char* const job_result_table[_JOB_RESULT_MAX] = {
ea0999c9
MB
1607 [JOB_DONE] = "done",
1608 [JOB_CANCELED] = "canceled",
1609 [JOB_TIMEOUT] = "timeout",
1610 [JOB_FAILED] = "failed",
1611 [JOB_DEPENDENCY] = "dependency",
1612 [JOB_SKIPPED] = "skipped",
1613 [JOB_INVALID] = "invalid",
1614 [JOB_ASSERT] = "assert",
e735f4d4 1615 [JOB_UNSUPPORTED] = "unsupported",
ea0999c9
MB
1616 [JOB_COLLECTED] = "collected",
1617 [JOB_ONCE] = "once",
663996b3
MS
1618};
1619
1620DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);
4c89c718
MP
1621
1622const char* job_type_to_access_method(JobType t) {
1623 assert(t >= 0);
1624 assert(t < _JOB_TYPE_MAX);
1625
1626 if (IN_SET(t, JOB_START, JOB_RESTART, JOB_TRY_RESTART))
1627 return "start";
1628 else if (t == JOB_STOP)
1629 return "stop";
1630 else
1631 return "reload";
1632}
f2dec872
BR
1633
1634/*
1635 * assume_dep assumed dependency between units (a is before/after b)
1636 *
1637 * Returns
1638 * 0 jobs are independent,
1639 * >0 a should run after b,
1640 * <0 a should run before b,
1641 *
1642 * The logic means that for a service a and a service b where b.After=a:
1643 *
1644 * start a + start b → 1st step start a, 2nd step start b
1645 * start a + stop b → 1st step stop b, 2nd step start a
1646 * stop a + start b → 1st step stop a, 2nd step start b
1647 * stop a + stop b → 1st step stop b, 2nd step stop a
1648 *
8b3d4ff0 1649 * This has the side effect that restarts are properly synchronized too.
f2dec872 1650 */
8b3d4ff0
MB
1651int job_compare(Job *a, Job *b, UnitDependencyAtom assume_dep) {
1652 assert(a);
1653 assert(b);
f2dec872
BR
1654 assert(a->type < _JOB_TYPE_MAX_IN_TRANSACTION);
1655 assert(b->type < _JOB_TYPE_MAX_IN_TRANSACTION);
8b3d4ff0 1656 assert(IN_SET(assume_dep, UNIT_ATOM_AFTER, UNIT_ATOM_BEFORE));
f2dec872
BR
1657
1658 /* Trivial cases first */
1659 if (a->type == JOB_NOP || b->type == JOB_NOP)
1660 return 0;
1661
1662 if (a->ignore_order || b->ignore_order)
1663 return 0;
1664
8b3d4ff0
MB
1665 if (assume_dep == UNIT_ATOM_AFTER)
1666 return -job_compare(b, a, UNIT_ATOM_BEFORE);
f2dec872 1667
8b3d4ff0
MB
1668 /* Let's make it simple, JOB_STOP goes always first (in case both ua and ub stop, then ub's stop goes
1669 * first anyway). JOB_RESTART is JOB_STOP in disguise (before it is patched to JOB_START). */
f2dec872
BR
1670 if (IN_SET(b->type, JOB_STOP, JOB_RESTART))
1671 return 1;
1672 else
1673 return -1;
1674}
086111aa
LB
1675
1676void job_set_activation_details(Job *j, ActivationDetails *info) {
1677 /* Existing (older) ActivationDetails win, newer ones are discarded. */
1678 if (!j || j->activation_details || !info)
1679 return; /* Nothing to do. */
1680
1681 j->activation_details = activation_details_ref(info);
1682}