]> git.proxmox.com Git - systemd.git/blame - src/core/job.c
New upstream version 252.7
[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
MB
1003 /* A special check to make sure we take down anything RequisiteOf= if we aren't active. This is when
1004 * the verify-active job merges with a satisfying job type, and then loses it's invalidation effect,
1005 * as the result there is JOB_DONE for the start job we merged into, while we should be failing the
1006 * depending job if the said unit isn't in fact active. Oneshots are an example of this, where going
1007 * directly from activating to inactive is success.
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
MS
1053
1054 manager_check_finished(u->manager);
1055
1056 return 0;
1057}
1058
60f067b4 1059static int job_dispatch_timer(sd_event_source *s, uint64_t monotonic, void *userdata) {
086111aa 1060 Job *j = ASSERT_PTR(userdata);
5eef597e 1061 Unit *u;
663996b3 1062
60f067b4 1063 assert(s == j->timer_event_source);
663996b3 1064
e3bff60a 1065 log_unit_warning(j->unit, "Job %s/%s timed out.", j->unit->id, job_type_to_string(j->type));
663996b3 1066
5eef597e 1067 u = j->unit;
aa27b158 1068 job_finish_and_invalidate(j, JOB_TIMEOUT, true, false);
5eef597e 1069
6e866b33
MB
1070 emergency_action(u->manager, u->job_timeout_action,
1071 EMERGENCY_ACTION_IS_WATCHDOG|EMERGENCY_ACTION_WARN,
1072 u->job_timeout_reboot_arg, -1, "job timed out");
5eef597e 1073
60f067b4
JS
1074 return 0;
1075}
663996b3 1076
81c58355 1077int job_start_timer(Job *j, bool job_running) {
60f067b4 1078 int r;
81c58355 1079 usec_t timeout_time, old_timeout_time;
663996b3 1080
81c58355
MB
1081 if (job_running) {
1082 j->begin_running_usec = now(CLOCK_MONOTONIC);
663996b3 1083
81c58355
MB
1084 if (j->unit->job_running_timeout == USEC_INFINITY)
1085 return 0;
663996b3 1086
81c58355
MB
1087 timeout_time = usec_add(j->begin_running_usec, j->unit->job_running_timeout);
1088
1089 if (j->timer_event_source) {
1090 /* Update only if JobRunningTimeoutSec= results in earlier timeout */
1091 r = sd_event_source_get_time(j->timer_event_source, &old_timeout_time);
1092 if (r < 0)
1093 return r;
1094
1095 if (old_timeout_time <= timeout_time)
1096 return 0;
1097
1098 return sd_event_source_set_time(j->timer_event_source, timeout_time);
1099 }
1100 } else {
1101 if (j->timer_event_source)
1102 return 0;
1103
1104 j->begin_usec = now(CLOCK_MONOTONIC);
1105
1106 if (j->unit->job_timeout == USEC_INFINITY)
1107 return 0;
1108
1109 timeout_time = usec_add(j->begin_usec, j->unit->job_timeout);
1110 }
663996b3 1111
60f067b4
JS
1112 r = sd_event_add_time(
1113 j->manager->event,
1114 &j->timer_event_source,
1115 CLOCK_MONOTONIC,
81c58355 1116 timeout_time, 0,
60f067b4
JS
1117 job_dispatch_timer, j);
1118 if (r < 0)
1119 return r;
663996b3 1120
e3bff60a
MP
1121 (void) sd_event_source_set_description(j->timer_event_source, "job-start");
1122
60f067b4 1123 return 0;
663996b3
MS
1124}
1125
1126void job_add_to_run_queue(Job *j) {
6e866b33
MB
1127 int r;
1128
663996b3
MS
1129 assert(j);
1130 assert(j->installed);
1131
1132 if (j->in_run_queue)
1133 return;
1134
c5fca32e
MB
1135 r = prioq_put(j->manager->run_queue, j, &j->run_queue_idx);
1136 if (r < 0)
1137 log_warning_errno(r, "Failed put job in run queue, ignoring: %m");
1138 else
1139 j->in_run_queue = true;
ea0999c9
MB
1140
1141 manager_trigger_run_queue(j->manager);
663996b3
MS
1142}
1143
1144void job_add_to_dbus_queue(Job *j) {
1145 assert(j);
1146 assert(j->installed);
1147
1148 if (j->in_dbus_queue)
1149 return;
1150
1151 /* We don't check if anybody is subscribed here, since this
1152 * job might just have been created and not yet assigned to a
1153 * connection/client. */
1154
60f067b4 1155 LIST_PREPEND(dbus_queue, j->manager->dbus_job_queue, j);
663996b3
MS
1156 j->in_dbus_queue = true;
1157}
1158
1159char *job_dbus_path(Job *j) {
1160 char *p;
1161
1162 assert(j);
1163
60f067b4 1164 if (asprintf(&p, "/org/freedesktop/systemd1/job/%"PRIu32, j->id) < 0)
663996b3
MS
1165 return NULL;
1166
1167 return p;
1168}
1169
8a584da2
MP
1170int job_serialize(Job *j, FILE *f) {
1171 assert(j);
1172 assert(f);
1173
6e866b33
MB
1174 (void) serialize_item_format(f, "job-id", "%u", j->id);
1175 (void) serialize_item(f, "job-type", job_type_to_string(j->type));
1176 (void) serialize_item(f, "job-state", job_state_to_string(j->state));
1177 (void) serialize_bool(f, "job-irreversible", j->irreversible);
1178 (void) serialize_bool(f, "job-sent-dbus-new-signal", j->sent_dbus_new_signal);
1179 (void) serialize_bool(f, "job-ignore-order", j->ignore_order);
60f067b4
JS
1180
1181 if (j->begin_usec > 0)
6e866b33 1182 (void) serialize_usec(f, "job-begin", j->begin_usec);
81c58355 1183 if (j->begin_running_usec > 0)
6e866b33 1184 (void) serialize_usec(f, "job-begin-running", j->begin_running_usec);
60f067b4 1185
2897b343 1186 bus_track_serialize(j->bus_track, f, "subscribed");
663996b3 1187
086111aa
LB
1188 activation_details_serialize(j->activation_details, f);
1189
663996b3
MS
1190 /* End marker */
1191 fputc('\n', f);
1192 return 0;
1193}
1194
8a584da2 1195int job_deserialize(Job *j, FILE *f) {
6e866b33
MB
1196 int r;
1197
60f067b4 1198 assert(j);
8a584da2 1199 assert(f);
60f067b4 1200
663996b3 1201 for (;;) {
6e866b33
MB
1202 _cleanup_free_ char *line = NULL;
1203 char *l, *v;
663996b3
MS
1204 size_t k;
1205
6e866b33
MB
1206 r = read_line(f, LONG_LINE_MAX, &line);
1207 if (r < 0)
1208 return log_error_errno(r, "Failed to read serialization line: %m");
1209 if (r == 0)
1210 return 0;
663996b3 1211
663996b3
MS
1212 l = strstrip(line);
1213
1214 /* End marker */
6e866b33 1215 if (isempty(l))
663996b3
MS
1216 return 0;
1217
1218 k = strcspn(l, "=");
1219
1220 if (l[k] == '=') {
1221 l[k] = 0;
1222 v = l+k+1;
1223 } else
1224 v = l+k;
1225
1226 if (streq(l, "job-id")) {
60f067b4 1227
663996b3 1228 if (safe_atou32(v, &j->id) < 0)
6e866b33 1229 log_debug("Failed to parse job id value: %s", v);
60f067b4 1230
663996b3 1231 } else if (streq(l, "job-type")) {
60f067b4
JS
1232 JobType t;
1233
1234 t = job_type_from_string(v);
663996b3 1235 if (t < 0)
6e866b33 1236 log_debug("Failed to parse job type: %s", v);
663996b3 1237 else if (t >= _JOB_TYPE_MAX_IN_TRANSACTION)
6e866b33 1238 log_debug("Cannot deserialize job of type: %s", v);
663996b3
MS
1239 else
1240 j->type = t;
60f067b4 1241
663996b3 1242 } else if (streq(l, "job-state")) {
60f067b4
JS
1243 JobState s;
1244
1245 s = job_state_from_string(v);
663996b3 1246 if (s < 0)
6e866b33 1247 log_debug("Failed to parse job state: %s", v);
663996b3 1248 else
e735f4d4 1249 job_set_state(j, s);
60f067b4 1250
663996b3 1251 } else if (streq(l, "job-irreversible")) {
60f067b4
JS
1252 int b;
1253
1254 b = parse_boolean(v);
663996b3 1255 if (b < 0)
6e866b33 1256 log_debug("Failed to parse job irreversible flag: %s", v);
663996b3
MS
1257 else
1258 j->irreversible = j->irreversible || b;
60f067b4 1259
663996b3 1260 } else if (streq(l, "job-sent-dbus-new-signal")) {
60f067b4
JS
1261 int b;
1262
1263 b = parse_boolean(v);
663996b3 1264 if (b < 0)
6e866b33 1265 log_debug("Failed to parse job sent_dbus_new_signal flag: %s", v);
663996b3
MS
1266 else
1267 j->sent_dbus_new_signal = j->sent_dbus_new_signal || b;
60f067b4 1268
663996b3 1269 } else if (streq(l, "job-ignore-order")) {
60f067b4
JS
1270 int b;
1271
1272 b = parse_boolean(v);
663996b3 1273 if (b < 0)
6e866b33 1274 log_debug("Failed to parse job ignore_order flag: %s", v);
663996b3
MS
1275 else
1276 j->ignore_order = j->ignore_order || b;
60f067b4 1277
6e866b33
MB
1278 } else if (streq(l, "job-begin"))
1279 (void) deserialize_usec(v, &j->begin_usec);
81c58355 1280
6e866b33
MB
1281 else if (streq(l, "job-begin-running"))
1282 (void) deserialize_usec(v, &j->begin_running_usec);
60f067b4 1283
6e866b33 1284 else if (streq(l, "subscribed")) {
5eef597e 1285 if (strv_extend(&j->deserialized_clients, v) < 0)
6e866b33 1286 return log_oom();
086111aa
LB
1287
1288 } else if (startswith(l, "activation-details")) {
1289 if (activation_details_deserialize(l, v, &j->activation_details) < 0)
1290 log_debug("Failed to parse job ActivationDetails element: %s", v);
1291
6e866b33
MB
1292 } else
1293 log_debug("Unknown job serialization key: %s", l);
663996b3
MS
1294 }
1295}
1296
1297int job_coldplug(Job *j) {
60f067b4 1298 int r;
81c58355 1299 usec_t timeout_time = USEC_INFINITY;
663996b3 1300
60f067b4
JS
1301 assert(j);
1302
1303 /* After deserialization is complete and the bus connection
1304 * set up again, let's start watching our subscribers again */
2897b343 1305 (void) bus_job_coldplug_bus_track(j);
60f067b4
JS
1306
1307 if (j->state == JOB_WAITING)
1308 job_add_to_run_queue(j);
1309
2897b343
MP
1310 /* Maybe due to new dependencies we don't actually need this job anymore? */
1311 job_add_to_gc_queue(j);
1312
81c58355
MB
1313 /* Create timer only when job began or began running and the respective timeout is finite.
1314 * Follow logic of job_start_timer() if both timeouts are finite */
1315 if (j->begin_usec == 0)
1316 return 0;
1317
1318 if (j->unit->job_timeout != USEC_INFINITY)
1319 timeout_time = usec_add(j->begin_usec, j->unit->job_timeout);
1320
f2dec872 1321 if (timestamp_is_set(j->begin_running_usec))
81c58355
MB
1322 timeout_time = MIN(timeout_time, usec_add(j->begin_running_usec, j->unit->job_running_timeout));
1323
1324 if (timeout_time == USEC_INFINITY)
663996b3
MS
1325 return 0;
1326
67bbd050 1327 j->timer_event_source = sd_event_source_disable_unref(j->timer_event_source);
663996b3 1328
60f067b4
JS
1329 r = sd_event_add_time(
1330 j->manager->event,
1331 &j->timer_event_source,
1332 CLOCK_MONOTONIC,
81c58355 1333 timeout_time, 0,
60f067b4
JS
1334 job_dispatch_timer, j);
1335 if (r < 0)
f47781d8 1336 log_debug_errno(r, "Failed to restart timeout for job: %m");
60f067b4 1337
e3bff60a
MP
1338 (void) sd_event_source_set_description(j->timer_event_source, "job-timeout");
1339
60f067b4 1340 return r;
663996b3
MS
1341}
1342
1343void job_shutdown_magic(Job *j) {
1344 assert(j);
1345
1346 /* The shutdown target gets some special treatment here: we
1347 * tell the kernel to begin with flushing its disk caches, to
1348 * optimize shutdown time a bit. Ideally we wouldn't hardcode
1349 * this magic into PID 1. However all other processes aren't
1350 * options either since they'd exit much sooner than PID 1 and
1351 * asynchronous sync() would cause their exit to be
1352 * delayed. */
1353
14228c0d 1354 if (j->type != JOB_START)
663996b3
MS
1355 return;
1356
aa27b158 1357 if (!MANAGER_IS_SYSTEM(j->unit->manager))
14228c0d
MB
1358 return;
1359
1360 if (!unit_has_name(j->unit, SPECIAL_SHUTDOWN_TARGET))
663996b3
MS
1361 return;
1362
60f067b4
JS
1363 /* In case messages on console has been disabled on boot */
1364 j->unit->manager->no_console_output = false;
1365
ea0999c9
MB
1366 manager_invalidate_startup_units(j->unit->manager);
1367
6300502b 1368 if (detect_container() > 0)
663996b3
MS
1369 return;
1370
1d42b86d 1371 (void) asynchronous_sync(NULL);
663996b3
MS
1372}
1373
4c89c718
MP
1374int job_get_timeout(Job *j, usec_t *timeout) {
1375 usec_t x = USEC_INFINITY, y = USEC_INFINITY;
086111aa 1376 Unit *u = ASSERT_PTR(ASSERT_PTR(j)->unit);
4c89c718 1377 int r;
60f067b4 1378
60f067b4
JS
1379 if (j->timer_event_source) {
1380 r = sd_event_source_get_time(j->timer_event_source, &x);
1381 if (r < 0)
1382 return r;
60f067b4
JS
1383 }
1384
1385 if (UNIT_VTABLE(u)->get_timeout) {
4c89c718
MP
1386 r = UNIT_VTABLE(u)->get_timeout(u, &y);
1387 if (r < 0)
1388 return r;
60f067b4
JS
1389 }
1390
4c89c718 1391 if (x == USEC_INFINITY && y == USEC_INFINITY)
60f067b4
JS
1392 return 0;
1393
1394 *timeout = MIN(x, y);
60f067b4
JS
1395 return 1;
1396}
1397
98393f85 1398bool job_may_gc(Job *j) {
2897b343 1399 Unit *other;
2897b343
MP
1400
1401 assert(j);
1402
1403 /* 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
1404 * own and just track external state. For now the only unit type that qualifies for this are .device units.
1405 * Returns true if the job can be collected. */
2897b343
MP
1406
1407 if (!UNIT_VTABLE(j->unit)->gc_jobs)
98393f85 1408 return false;
2897b343
MP
1409
1410 if (sd_bus_track_count(j->bus_track) > 0)
98393f85 1411 return false;
2897b343
MP
1412
1413 /* FIXME: So this is a bit ugly: for now we don't properly track references made via private bus connections
1414 * (because it's nasty, as sd_bus_track doesn't apply to it). We simply remember that the job was once
1415 * referenced by one, and reset this whenever we notice that no private bus connections are around. This means
1416 * the GC is a bit too conservative when it comes to jobs created by private bus connections. */
1417 if (j->ref_by_private_bus) {
1418 if (set_isempty(j->unit->manager->private_buses))
1419 j->ref_by_private_bus = false;
1420 else
98393f85 1421 return false;
2897b343
MP
1422 }
1423
1424 if (j->type == JOB_NOP)
98393f85 1425 return false;
2897b343 1426
f2dec872 1427 /* The logic is inverse to job_is_runnable, we cannot GC as long as we block any job. */
8b3d4ff0
MB
1428 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_BEFORE)
1429 if (other->job && job_compare(j, other->job, UNIT_ATOM_BEFORE) < 0)
98393f85 1430 return false;
2897b343 1431
8b3d4ff0
MB
1432 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_AFTER)
1433 if (other->job && job_compare(j, other->job, UNIT_ATOM_AFTER) < 0)
98393f85 1434 return false;
2897b343 1435
98393f85 1436 return true;
2897b343
MP
1437}
1438
1439void job_add_to_gc_queue(Job *j) {
1440 assert(j);
1441
1442 if (j->in_gc_queue)
1443 return;
1444
98393f85 1445 if (!job_may_gc(j))
2897b343
MP
1446 return;
1447
1448 LIST_PREPEND(gc_queue, j->unit->manager->gc_job_queue, j);
1449 j->in_gc_queue = true;
1450}
1451
f2dec872 1452static int job_compare_id(Job * const *a, Job * const *b) {
6e866b33 1453 return CMP((*a)->id, (*b)->id);
2897b343
MP
1454}
1455
1456static size_t sort_job_list(Job **list, size_t n) {
1457 Job *previous = NULL;
1458 size_t a, b;
1459
1460 /* Order by numeric IDs */
f2dec872 1461 typesafe_qsort(list, n, job_compare_id);
2897b343
MP
1462
1463 /* Filter out duplicates */
1464 for (a = 0, b = 0; a < n; a++) {
1465
1466 if (previous == list[a])
1467 continue;
1468
1469 previous = list[b++] = list[a];
1470 }
1471
1472 return b;
1473}
1474
1475int job_get_before(Job *j, Job*** ret) {
1476 _cleanup_free_ Job** list = NULL;
2897b343 1477 Unit *other = NULL;
8b3d4ff0 1478 size_t n = 0;
2897b343
MP
1479
1480 /* Returns a list of all pending jobs that need to finish before this job may be started. */
1481
1482 assert(j);
1483 assert(ret);
1484
1485 if (j->ignore_order) {
1486 *ret = NULL;
1487 return 0;
1488 }
1489
8b3d4ff0 1490 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_AFTER) {
f2dec872
BR
1491 if (!other->job)
1492 continue;
8b3d4ff0 1493 if (job_compare(j, other->job, UNIT_ATOM_AFTER) <= 0)
f2dec872 1494 continue;
2897b343 1495
8b3d4ff0 1496 if (!GREEDY_REALLOC(list, n+1))
f2dec872
BR
1497 return -ENOMEM;
1498 list[n++] = other->job;
2897b343
MP
1499 }
1500
8b3d4ff0 1501 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_BEFORE) {
2897b343
MP
1502 if (!other->job)
1503 continue;
8b3d4ff0 1504 if (job_compare(j, other->job, UNIT_ATOM_BEFORE) <= 0)
2897b343
MP
1505 continue;
1506
8b3d4ff0 1507 if (!GREEDY_REALLOC(list, n+1))
2897b343
MP
1508 return -ENOMEM;
1509 list[n++] = other->job;
1510 }
1511
1512 n = sort_job_list(list, n);
1513
b012e921 1514 *ret = TAKE_PTR(list);
2897b343
MP
1515
1516 return (int) n;
1517}
1518
1519int job_get_after(Job *j, Job*** ret) {
1520 _cleanup_free_ Job** list = NULL;
2897b343 1521 Unit *other = NULL;
8b3d4ff0 1522 size_t n = 0;
2897b343
MP
1523
1524 assert(j);
1525 assert(ret);
1526
1527 /* Returns a list of all pending jobs that are waiting for this job to finish. */
1528
8b3d4ff0 1529 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_BEFORE) {
2897b343
MP
1530 if (!other->job)
1531 continue;
1532
1533 if (other->job->ignore_order)
1534 continue;
1535
8b3d4ff0 1536 if (job_compare(j, other->job, UNIT_ATOM_BEFORE) >= 0)
2897b343
MP
1537 continue;
1538
8b3d4ff0 1539 if (!GREEDY_REALLOC(list, n+1))
2897b343
MP
1540 return -ENOMEM;
1541 list[n++] = other->job;
1542 }
1543
8b3d4ff0 1544 UNIT_FOREACH_DEPENDENCY(other, j->unit, UNIT_ATOM_AFTER) {
f2dec872
BR
1545 if (!other->job)
1546 continue;
2897b343 1547
f2dec872
BR
1548 if (other->job->ignore_order)
1549 continue;
2897b343 1550
8b3d4ff0 1551 if (job_compare(j, other->job, UNIT_ATOM_AFTER) >= 0)
f2dec872 1552 continue;
2897b343 1553
8b3d4ff0 1554 if (!GREEDY_REALLOC(list, n+1))
f2dec872
BR
1555 return -ENOMEM;
1556 list[n++] = other->job;
2897b343
MP
1557 }
1558
1559 n = sort_job_list(list, n);
1560
b012e921 1561 *ret = TAKE_PTR(list);
2897b343
MP
1562
1563 return (int) n;
1564}
1565
663996b3
MS
1566static const char* const job_state_table[_JOB_STATE_MAX] = {
1567 [JOB_WAITING] = "waiting",
2897b343 1568 [JOB_RUNNING] = "running",
663996b3
MS
1569};
1570
1571DEFINE_STRING_TABLE_LOOKUP(job_state, JobState);
1572
1573static const char* const job_type_table[_JOB_TYPE_MAX] = {
ea0999c9
MB
1574 [JOB_START] = "start",
1575 [JOB_VERIFY_ACTIVE] = "verify-active",
1576 [JOB_STOP] = "stop",
1577 [JOB_RELOAD] = "reload",
663996b3 1578 [JOB_RELOAD_OR_START] = "reload-or-start",
ea0999c9
MB
1579 [JOB_RESTART] = "restart",
1580 [JOB_TRY_RESTART] = "try-restart",
1581 [JOB_TRY_RELOAD] = "try-reload",
1582 [JOB_NOP] = "nop",
663996b3
MS
1583};
1584
1585DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
1586
1587static const char* const job_mode_table[_JOB_MODE_MAX] = {
ea0999c9
MB
1588 [JOB_FAIL] = "fail",
1589 [JOB_REPLACE] = "replace",
663996b3 1590 [JOB_REPLACE_IRREVERSIBLY] = "replace-irreversibly",
ea0999c9
MB
1591 [JOB_ISOLATE] = "isolate",
1592 [JOB_FLUSH] = "flush",
1593 [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
1594 [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements",
1595 [JOB_TRIGGERING] = "triggering",
663996b3
MS
1596};
1597
1598DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);
1599
1600static const char* const job_result_table[_JOB_RESULT_MAX] = {
ea0999c9
MB
1601 [JOB_DONE] = "done",
1602 [JOB_CANCELED] = "canceled",
1603 [JOB_TIMEOUT] = "timeout",
1604 [JOB_FAILED] = "failed",
1605 [JOB_DEPENDENCY] = "dependency",
1606 [JOB_SKIPPED] = "skipped",
1607 [JOB_INVALID] = "invalid",
1608 [JOB_ASSERT] = "assert",
e735f4d4 1609 [JOB_UNSUPPORTED] = "unsupported",
ea0999c9
MB
1610 [JOB_COLLECTED] = "collected",
1611 [JOB_ONCE] = "once",
663996b3
MS
1612};
1613
1614DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);
4c89c718
MP
1615
1616const char* job_type_to_access_method(JobType t) {
1617 assert(t >= 0);
1618 assert(t < _JOB_TYPE_MAX);
1619
1620 if (IN_SET(t, JOB_START, JOB_RESTART, JOB_TRY_RESTART))
1621 return "start";
1622 else if (t == JOB_STOP)
1623 return "stop";
1624 else
1625 return "reload";
1626}
f2dec872
BR
1627
1628/*
1629 * assume_dep assumed dependency between units (a is before/after b)
1630 *
1631 * Returns
1632 * 0 jobs are independent,
1633 * >0 a should run after b,
1634 * <0 a should run before b,
1635 *
1636 * The logic means that for a service a and a service b where b.After=a:
1637 *
1638 * start a + start b → 1st step start a, 2nd step start b
1639 * start a + stop b → 1st step stop b, 2nd step start a
1640 * stop a + start b → 1st step stop a, 2nd step start b
1641 * stop a + stop b → 1st step stop b, 2nd step stop a
1642 *
8b3d4ff0 1643 * This has the side effect that restarts are properly synchronized too.
f2dec872 1644 */
8b3d4ff0
MB
1645int job_compare(Job *a, Job *b, UnitDependencyAtom assume_dep) {
1646 assert(a);
1647 assert(b);
f2dec872
BR
1648 assert(a->type < _JOB_TYPE_MAX_IN_TRANSACTION);
1649 assert(b->type < _JOB_TYPE_MAX_IN_TRANSACTION);
8b3d4ff0 1650 assert(IN_SET(assume_dep, UNIT_ATOM_AFTER, UNIT_ATOM_BEFORE));
f2dec872
BR
1651
1652 /* Trivial cases first */
1653 if (a->type == JOB_NOP || b->type == JOB_NOP)
1654 return 0;
1655
1656 if (a->ignore_order || b->ignore_order)
1657 return 0;
1658
8b3d4ff0
MB
1659 if (assume_dep == UNIT_ATOM_AFTER)
1660 return -job_compare(b, a, UNIT_ATOM_BEFORE);
f2dec872 1661
8b3d4ff0
MB
1662 /* Let's make it simple, JOB_STOP goes always first (in case both ua and ub stop, then ub's stop goes
1663 * first anyway). JOB_RESTART is JOB_STOP in disguise (before it is patched to JOB_START). */
f2dec872
BR
1664 if (IN_SET(b->type, JOB_STOP, JOB_RESTART))
1665 return 1;
1666 else
1667 return -1;
1668}
086111aa
LB
1669
1670void job_set_activation_details(Job *j, ActivationDetails *info) {
1671 /* Existing (older) ActivationDetails win, newer ones are discarded. */
1672 if (!j || j->activation_details || !info)
1673 return; /* Nothing to do. */
1674
1675 j->activation_details = activation_details_ref(info);
1676}