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