Line data Source code
1 : /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2 :
3 : /***
4 : This file is part of systemd.
5 :
6 : Copyright 2010 Lennart Poettering
7 :
8 : systemd is free software; you can redistribute it and/or modify it
9 : under the terms of the GNU Lesser General Public License as published by
10 : the Free Software Foundation; either version 2.1 of the License, or
11 : (at your option) any later version.
12 :
13 : systemd is distributed in the hope that it will be useful, but
14 : WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : Lesser General Public License for more details.
17 :
18 : You should have received a copy of the GNU Lesser General Public License
19 : along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 : ***/
21 :
22 : #include <errno.h>
23 :
24 : #include "sd-id128.h"
25 : #include "sd-messages.h"
26 : #include "set.h"
27 : #include "unit.h"
28 : #include "macro.h"
29 : #include "strv.h"
30 : #include "log.h"
31 : #include "dbus-job.h"
32 : #include "special.h"
33 : #include "async.h"
34 : #include "virt.h"
35 : #include "dbus.h"
36 : #include "terminal-util.h"
37 :
38 159 : Job* job_new_raw(Unit *unit) {
39 : Job *j;
40 :
41 : /* used for deserialization */
42 :
43 159 : assert(unit);
44 :
45 159 : j = new0(Job, 1);
46 159 : if (!j)
47 0 : return NULL;
48 :
49 159 : j->manager = unit->manager;
50 159 : j->unit = unit;
51 159 : j->type = _JOB_TYPE_INVALID;
52 :
53 159 : return j;
54 : }
55 :
56 159 : Job* job_new(Unit *unit, JobType type) {
57 : Job *j;
58 :
59 159 : assert(type < _JOB_TYPE_MAX);
60 :
61 159 : j = job_new_raw(unit);
62 159 : if (!j)
63 0 : return NULL;
64 :
65 159 : j->id = j->manager->current_job_id++;
66 159 : j->type = type;
67 :
68 : /* We don't link it here, that's what job_dependency() is for */
69 :
70 159 : return j;
71 : }
72 :
73 159 : void job_free(Job *j) {
74 159 : assert(j);
75 159 : assert(!j->installed);
76 159 : assert(!j->transaction_prev);
77 159 : assert(!j->transaction_next);
78 159 : assert(!j->subject_list);
79 159 : assert(!j->object_list);
80 :
81 159 : if (j->in_run_queue)
82 21 : LIST_REMOVE(run_queue, j->manager->run_queue, j);
83 :
84 159 : if (j->in_dbus_queue)
85 0 : LIST_REMOVE(dbus_queue, j->manager->dbus_job_queue, j);
86 :
87 159 : sd_event_source_unref(j->timer_event_source);
88 :
89 159 : sd_bus_track_unref(j->clients);
90 159 : strv_free(j->deserialized_clients);
91 :
92 159 : free(j);
93 159 : }
94 :
95 105 : static void job_set_state(Job *j, JobState state) {
96 105 : assert(j);
97 105 : assert(state >= 0);
98 105 : assert(state < _JOB_STATE_MAX);
99 :
100 105 : if (j->state == state)
101 21 : return;
102 :
103 84 : j->state = state;
104 :
105 84 : if (!j->installed)
106 0 : return;
107 :
108 84 : if (j->state == JOB_RUNNING)
109 42 : j->unit->manager->n_running_jobs++;
110 : else {
111 42 : assert(j->state == JOB_WAITING);
112 42 : assert(j->unit->manager->n_running_jobs > 0);
113 :
114 42 : j->unit->manager->n_running_jobs--;
115 :
116 42 : if (j->unit->manager->n_running_jobs <= 0)
117 42 : j->unit->manager->jobs_in_progress_event_source = sd_event_source_unref(j->unit->manager->jobs_in_progress_event_source);
118 : }
119 : }
120 :
121 63 : void job_uninstall(Job *j) {
122 : Job **pj;
123 :
124 63 : assert(j->installed);
125 :
126 63 : job_set_state(j, JOB_WAITING);
127 :
128 63 : pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
129 63 : assert(*pj == j);
130 :
131 : /* Detach from next 'bigger' objects */
132 :
133 : /* daemon-reload should be transparent to job observers */
134 63 : if (j->manager->n_reloading <= 0)
135 63 : bus_job_send_removed_signal(j);
136 :
137 63 : *pj = NULL;
138 :
139 63 : unit_add_to_gc_queue(j->unit);
140 :
141 63 : hashmap_remove(j->manager->jobs, UINT32_TO_PTR(j->id));
142 63 : j->installed = false;
143 63 : }
144 :
145 0 : static bool job_type_allows_late_merge(JobType t) {
146 : /* Tells whether it is OK to merge a job of type 't' with an already
147 : * running job.
148 : * Reloads cannot be merged this way. Think of the sequence:
149 : * 1. Reload of a daemon is in progress; the daemon has already loaded
150 : * its config file, but hasn't completed the reload operation yet.
151 : * 2. Edit foo's config file.
152 : * 3. Trigger another reload to have the daemon use the new config.
153 : * Should the second reload job be merged into the first one, the daemon
154 : * would not know about the new config.
155 : * JOB_RESTART jobs on the other hand can be merged, because they get
156 : * patched into JOB_START after stopping the unit. So if we see a
157 : * JOB_RESTART running, it means the unit hasn't stopped yet and at
158 : * this time the merge is still allowed. */
159 0 : return t != JOB_RELOAD;
160 : }
161 :
162 26 : static void job_merge_into_installed(Job *j, Job *other) {
163 26 : assert(j->installed);
164 26 : assert(j->unit == other->unit);
165 :
166 26 : if (j->type != JOB_NOP)
167 26 : job_type_merge_and_collapse(&j->type, other->type, j->unit);
168 : else
169 0 : assert(other->type == JOB_NOP);
170 :
171 26 : j->override = j->override || other->override;
172 26 : j->irreversible = j->irreversible || other->irreversible;
173 26 : j->ignore_order = j->ignore_order || other->ignore_order;
174 26 : }
175 :
176 89 : Job* job_install(Job *j) {
177 : Job **pj;
178 : Job *uj;
179 :
180 89 : assert(!j->installed);
181 89 : assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
182 89 : assert(j->state == JOB_WAITING);
183 :
184 89 : pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
185 89 : uj = *pj;
186 :
187 89 : if (uj) {
188 28 : if (job_type_is_conflicting(uj->type, j->type))
189 2 : job_finish_and_invalidate(uj, JOB_CANCELED, false);
190 : else {
191 : /* not conflicting, i.e. mergeable */
192 :
193 26 : if (uj->state == JOB_WAITING ||
194 0 : (job_type_allows_late_merge(j->type) && job_type_is_superset(uj->type, j->type))) {
195 26 : job_merge_into_installed(uj, j);
196 26 : log_unit_debug(uj->unit,
197 : "Merged into installed job %s/%s as %u",
198 : uj->unit->id, job_type_to_string(uj->type), (unsigned) uj->id);
199 26 : return uj;
200 : } else {
201 : /* already running and not safe to merge into */
202 : /* Patch uj to become a merged job and re-run it. */
203 : /* XXX It should be safer to queue j to run after uj finishes, but it is
204 : * not currently possible to have more than one installed job per unit. */
205 0 : job_merge_into_installed(uj, j);
206 0 : log_unit_debug(uj->unit,
207 : "Merged into running job, re-running: %s/%s as %u",
208 : uj->unit->id, job_type_to_string(uj->type), (unsigned) uj->id);
209 :
210 0 : job_set_state(uj, JOB_WAITING);
211 0 : return uj;
212 : }
213 : }
214 : }
215 :
216 : /* Install the job */
217 63 : *pj = j;
218 63 : j->installed = true;
219 :
220 63 : j->manager->n_installed_jobs ++;
221 63 : log_unit_debug(j->unit,
222 : "Installed new job %s/%s as %u",
223 : j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
224 63 : return j;
225 : }
226 :
227 0 : int job_install_deserialized(Job *j) {
228 : Job **pj;
229 :
230 0 : assert(!j->installed);
231 :
232 0 : if (j->type < 0 || j->type >= _JOB_TYPE_MAX_IN_TRANSACTION) {
233 0 : log_debug("Invalid job type %s in deserialization.", strna(job_type_to_string(j->type)));
234 0 : return -EINVAL;
235 : }
236 :
237 0 : pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
238 0 : if (*pj) {
239 0 : log_unit_debug(j->unit, "Unit already has a job installed. Not installing deserialized job.");
240 0 : return -EEXIST;
241 : }
242 :
243 0 : *pj = j;
244 0 : j->installed = true;
245 :
246 0 : if (j->state == JOB_RUNNING)
247 0 : j->unit->manager->n_running_jobs++;
248 :
249 0 : log_unit_debug(j->unit,
250 : "Reinstalled deserialized job %s/%s as %u",
251 : j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
252 0 : return 0;
253 : }
254 :
255 266 : JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts) {
256 : JobDependency *l;
257 :
258 266 : assert(object);
259 :
260 : /* Adds a new job link, which encodes that the 'subject' job
261 : * needs the 'object' job in some way. If 'subject' is NULL
262 : * this means the 'anchor' job (i.e. the one the user
263 : * explicitly asked for) is the requester. */
264 :
265 266 : if (!(l = new0(JobDependency, 1)))
266 0 : return NULL;
267 :
268 266 : l->subject = subject;
269 266 : l->object = object;
270 266 : l->matters = matters;
271 266 : l->conflicts = conflicts;
272 :
273 266 : if (subject)
274 266 : LIST_PREPEND(subject, subject->subject_list, l);
275 :
276 266 : LIST_PREPEND(object, object->object_list, l);
277 :
278 266 : return l;
279 : }
280 :
281 266 : void job_dependency_free(JobDependency *l) {
282 266 : assert(l);
283 :
284 266 : if (l->subject)
285 266 : LIST_REMOVE(subject, l->subject->subject_list, l);
286 :
287 266 : LIST_REMOVE(object, l->object->object_list, l);
288 :
289 266 : free(l);
290 266 : }
291 :
292 72 : void job_dump(Job *j, FILE*f, const char *prefix) {
293 72 : assert(j);
294 72 : assert(f);
295 :
296 72 : if (!prefix)
297 0 : prefix = "";
298 :
299 216 : fprintf(f,
300 : "%s-> Job %u:\n"
301 : "%s\tAction: %s -> %s\n"
302 : "%s\tState: %s\n"
303 : "%s\tForced: %s\n"
304 : "%s\tIrreversible: %s\n",
305 : prefix, j->id,
306 72 : prefix, j->unit->id, job_type_to_string(j->type),
307 : prefix, job_state_to_string(j->state),
308 72 : prefix, yes_no(j->override),
309 72 : prefix, yes_no(j->irreversible));
310 72 : }
311 :
312 : /*
313 : * Merging is commutative, so imagine the matrix as symmetric. We store only
314 : * its lower triangle to avoid duplication. We don't store the main diagonal,
315 : * because A merged with A is simply A.
316 : *
317 : * If the resulting type is collapsed immediately afterwards (to get rid of
318 : * the JOB_RELOAD_OR_START, which lies outside the lookup function's domain),
319 : * the following properties hold:
320 : *
321 : * Merging is associative! A merged with B, and then merged with C is the same
322 : * as A merged with the result of B merged with C.
323 : *
324 : * Mergeability is transitive! If A can be merged with B and B with C then
325 : * A also with C.
326 : *
327 : * Also, if A merged with B cannot be merged with C, then either A or B cannot
328 : * be merged with C either.
329 : */
330 : static const JobType job_merging_table[] = {
331 : /* What \ With * JOB_START JOB_VERIFY_ACTIVE JOB_STOP JOB_RELOAD */
332 : /*********************************************************************************/
333 : /*JOB_START */
334 : /*JOB_VERIFY_ACTIVE */ JOB_START,
335 : /*JOB_STOP */ -1, -1,
336 : /*JOB_RELOAD */ JOB_RELOAD_OR_START, JOB_RELOAD, -1,
337 : /*JOB_RESTART */ JOB_RESTART, JOB_RESTART, -1, JOB_RESTART,
338 : };
339 :
340 2049 : JobType job_type_lookup_merge(JobType a, JobType b) {
341 : assert_cc(ELEMENTSOF(job_merging_table) == _JOB_TYPE_MAX_MERGING * (_JOB_TYPE_MAX_MERGING - 1) / 2);
342 2049 : assert(a >= 0 && a < _JOB_TYPE_MAX_MERGING);
343 2049 : assert(b >= 0 && b < _JOB_TYPE_MAX_MERGING);
344 :
345 2049 : if (a == b)
346 538 : return a;
347 :
348 1511 : if (a < b) {
349 701 : JobType tmp = a;
350 701 : a = b;
351 701 : b = tmp;
352 : }
353 :
354 1511 : return job_merging_table[(a - 1) * a / 2 + b];
355 : }
356 :
357 377 : bool job_type_is_redundant(JobType a, UnitActiveState b) {
358 377 : switch (a) {
359 :
360 : case JOB_START:
361 : return
362 326 : b == UNIT_ACTIVE ||
363 : b == UNIT_RELOADING;
364 :
365 : case JOB_STOP:
366 : return
367 51 : b == UNIT_INACTIVE ||
368 : b == UNIT_FAILED;
369 :
370 : case JOB_VERIFY_ACTIVE:
371 : return
372 0 : b == UNIT_ACTIVE ||
373 : b == UNIT_RELOADING;
374 :
375 : case JOB_RELOAD:
376 : return
377 0 : b == UNIT_RELOADING;
378 :
379 : case JOB_RESTART:
380 : return
381 0 : b == UNIT_ACTIVATING;
382 :
383 : case JOB_NOP:
384 0 : return true;
385 :
386 : default:
387 0 : assert_not_reached("Invalid job type");
388 : }
389 : }
390 :
391 596 : JobType job_type_collapse(JobType t, Unit *u) {
392 : UnitActiveState s;
393 :
394 596 : switch (t) {
395 :
396 : case JOB_TRY_RESTART:
397 0 : s = unit_active_state(u);
398 0 : if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
399 0 : return JOB_NOP;
400 :
401 0 : return JOB_RESTART;
402 :
403 : case JOB_RELOAD_OR_START:
404 68 : s = unit_active_state(u);
405 68 : if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
406 34 : return JOB_START;
407 :
408 34 : return JOB_RELOAD;
409 :
410 : default:
411 528 : return t;
412 : }
413 : }
414 :
415 636 : int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u) {
416 : JobType t;
417 :
418 636 : t = job_type_lookup_merge(*a, b);
419 636 : if (t < 0)
420 56 : return -EEXIST;
421 :
422 580 : *a = job_type_collapse(t, u);
423 580 : return 0;
424 : }
425 :
426 55 : static bool job_is_runnable(Job *j) {
427 : Iterator i;
428 : Unit *other;
429 :
430 55 : assert(j);
431 55 : assert(j->installed);
432 :
433 : /* Checks whether there is any job running for the units this
434 : * job needs to be running after (in the case of a 'positive'
435 : * job type) or before (in the case of a 'negative' job
436 : * type. */
437 :
438 : /* Note that unit types have a say in what is runnable,
439 : * too. For example, if they return -EAGAIN from
440 : * unit_start() they can indicate they are not
441 : * runnable yet. */
442 :
443 : /* First check if there is an override */
444 55 : if (j->ignore_order)
445 0 : return true;
446 :
447 55 : if (j->type == JOB_NOP)
448 0 : return true;
449 :
450 55 : if (j->type == JOB_START ||
451 0 : j->type == JOB_VERIFY_ACTIVE ||
452 0 : j->type == JOB_RELOAD) {
453 :
454 : /* Immediate result is that the job is or might be
455 : * started. In this case let's wait for the
456 : * dependencies, regardless whether they are
457 : * starting or stopping something. */
458 :
459 223 : SET_FOREACH(other, j->unit->dependencies[UNIT_AFTER], i)
460 126 : if (other->job)
461 13 : return false;
462 : }
463 :
464 : /* Also, if something else is being stopped and we should
465 : * change state after it, then let's wait. */
466 :
467 174 : SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i)
468 120 : if (other->job &&
469 60 : (other->job->type == JOB_STOP ||
470 30 : other->job->type == JOB_RESTART))
471 0 : return false;
472 :
473 : /* This means that for a service a and a service b where b
474 : * shall be started after a:
475 : *
476 : * start a + start b → 1st step start a, 2nd step start b
477 : * start a + stop b → 1st step stop b, 2nd step start a
478 : * stop a + start b → 1st step stop a, 2nd step start b
479 : * stop a + stop b → 1st step stop b, 2nd step stop a
480 : *
481 : * This has the side effect that restarts are properly
482 : * synchronized too. */
483 :
484 42 : return true;
485 : }
486 :
487 0 : static void job_change_type(Job *j, JobType newtype) {
488 0 : assert(j);
489 :
490 0 : log_unit_debug(j->unit,
491 : "Converting job %s/%s -> %s/%s",
492 : j->unit->id, job_type_to_string(j->type),
493 : j->unit->id, job_type_to_string(newtype));
494 :
495 0 : j->type = newtype;
496 0 : }
497 :
498 42 : static int job_perform_on_unit(Job **j) {
499 : /* While we execute this operation the job might go away (for
500 : * example: because it finishes immediately or is replaced by a new,
501 : * conflicting job.) To make sure we don't access a freed job later on
502 : * we store the id here, so that we can verify the job is still
503 : * valid. */
504 42 : Manager *m = (*j)->manager;
505 42 : Unit *u = (*j)->unit;
506 42 : JobType t = (*j)->type;
507 42 : uint32_t id = (*j)->id;
508 : int r;
509 :
510 42 : switch (t) {
511 : case JOB_START:
512 42 : r = unit_start(u);
513 42 : break;
514 :
515 : case JOB_RESTART:
516 0 : t = JOB_STOP;
517 : case JOB_STOP:
518 0 : r = unit_stop(u);
519 0 : break;
520 :
521 : case JOB_RELOAD:
522 0 : r = unit_reload(u);
523 0 : break;
524 :
525 : default:
526 0 : assert_not_reached("Invalid job type");
527 : }
528 :
529 : /* Log if the job still exists and the start/stop/reload function
530 : * actually did something. */
531 42 : *j = manager_get_job(m, id);
532 42 : if (*j && r > 0)
533 6 : unit_status_emit_starting_stopping_reloading(u, t);
534 :
535 42 : return r;
536 : }
537 :
538 55 : int job_run_and_invalidate(Job *j) {
539 : int r;
540 :
541 55 : assert(j);
542 55 : assert(j->installed);
543 55 : assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
544 55 : assert(j->in_run_queue);
545 :
546 55 : LIST_REMOVE(run_queue, j->manager->run_queue, j);
547 55 : j->in_run_queue = false;
548 :
549 55 : if (j->state != JOB_WAITING)
550 0 : return 0;
551 :
552 55 : if (!job_is_runnable(j))
553 13 : return -EAGAIN;
554 :
555 42 : job_set_state(j, JOB_RUNNING);
556 42 : job_add_to_dbus_queue(j);
557 :
558 :
559 42 : switch (j->type) {
560 :
561 : case JOB_VERIFY_ACTIVE: {
562 0 : UnitActiveState t = unit_active_state(j->unit);
563 0 : if (UNIT_IS_ACTIVE_OR_RELOADING(t))
564 0 : r = -EALREADY;
565 0 : else if (t == UNIT_ACTIVATING)
566 0 : r = -EAGAIN;
567 : else
568 0 : r = -EBADR;
569 0 : break;
570 : }
571 :
572 : case JOB_START:
573 : case JOB_STOP:
574 : case JOB_RESTART:
575 42 : r = job_perform_on_unit(&j);
576 :
577 : /* If the unit type does not support starting/stopping,
578 : * then simply wait. */
579 42 : if (r == -EBADR)
580 0 : r = 0;
581 42 : break;
582 :
583 : case JOB_RELOAD:
584 0 : r = job_perform_on_unit(&j);
585 0 : break;
586 :
587 : case JOB_NOP:
588 0 : r = -EALREADY;
589 0 : break;
590 :
591 : default:
592 0 : assert_not_reached("Unknown job type");
593 : }
594 :
595 42 : if (j) {
596 6 : if (r == -EALREADY)
597 0 : r = job_finish_and_invalidate(j, JOB_DONE, true);
598 6 : else if (r == -EBADR)
599 0 : r = job_finish_and_invalidate(j, JOB_SKIPPED, true);
600 6 : else if (r == -ENOEXEC)
601 0 : r = job_finish_and_invalidate(j, JOB_INVALID, true);
602 6 : else if (r == -EPROTO)
603 0 : r = job_finish_and_invalidate(j, JOB_ASSERT, true);
604 6 : else if (r == -EOPNOTSUPP)
605 0 : r = job_finish_and_invalidate(j, JOB_UNSUPPORTED, true);
606 6 : else if (r == -EAGAIN)
607 0 : job_set_state(j, JOB_WAITING);
608 6 : else if (r < 0)
609 0 : r = job_finish_and_invalidate(j, JOB_FAILED, true);
610 : }
611 :
612 42 : return r;
613 : }
614 :
615 48 : _pure_ static const char *job_get_status_message_format(Unit *u, JobType t, JobResult result) {
616 : const char *format;
617 : const UnitStatusMessageFormats *format_table;
618 : static const char *const generic_finished_start_job[_JOB_RESULT_MAX] = {
619 : [JOB_DONE] = "Started %s.",
620 : [JOB_TIMEOUT] = "Timed out starting %s.",
621 : [JOB_FAILED] = "Failed to start %s.",
622 : [JOB_DEPENDENCY] = "Dependency failed for %s.",
623 : [JOB_ASSERT] = "Assertion failed for %s.",
624 : [JOB_UNSUPPORTED] = "Starting of %s not supported.",
625 : };
626 : static const char *const generic_finished_stop_job[_JOB_RESULT_MAX] = {
627 : [JOB_DONE] = "Stopped %s.",
628 : [JOB_FAILED] = "Stopped (with error) %s.",
629 : [JOB_TIMEOUT] = "Timed out stoppping %s.",
630 : };
631 : static const char *const generic_finished_reload_job[_JOB_RESULT_MAX] = {
632 : [JOB_DONE] = "Reloaded %s.",
633 : [JOB_FAILED] = "Reload failed for %s.",
634 : [JOB_TIMEOUT] = "Timed out reloading %s.",
635 : };
636 : /* When verify-active detects the unit is inactive, report it.
637 : * Most likely a DEPEND warning from a requisiting unit will
638 : * occur next and it's nice to see what was requisited. */
639 : static const char *const generic_finished_verify_active_job[_JOB_RESULT_MAX] = {
640 : [JOB_SKIPPED] = "%s is not active.",
641 : };
642 :
643 48 : assert(u);
644 48 : assert(t >= 0);
645 48 : assert(t < _JOB_TYPE_MAX);
646 :
647 48 : if (t == JOB_START || t == JOB_STOP || t == JOB_RESTART) {
648 48 : format_table = &UNIT_VTABLE(u)->status_message_formats;
649 48 : if (format_table) {
650 48 : format = t == JOB_START ? format_table->finished_start_job[result] :
651 : format_table->finished_stop_job[result];
652 48 : if (format)
653 36 : return format;
654 : }
655 : }
656 :
657 : /* Return generic strings */
658 12 : if (t == JOB_START)
659 11 : return generic_finished_start_job[result];
660 1 : else if (t == JOB_STOP || t == JOB_RESTART)
661 1 : return generic_finished_stop_job[result];
662 0 : else if (t == JOB_RELOAD)
663 0 : return generic_finished_reload_job[result];
664 0 : else if (t == JOB_VERIFY_ACTIVE)
665 0 : return generic_finished_verify_active_job[result];
666 :
667 0 : return NULL;
668 : }
669 :
670 48 : static void job_print_status_message(Unit *u, JobType t, JobResult result) {
671 : const char *format;
672 : static const char* const job_result_status_table[_JOB_RESULT_MAX] = {
673 : [JOB_DONE] = ANSI_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF,
674 : [JOB_TIMEOUT] = ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF,
675 : [JOB_FAILED] = ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF,
676 : [JOB_DEPENDENCY] = ANSI_HIGHLIGHT_YELLOW_ON "DEPEND" ANSI_HIGHLIGHT_OFF,
677 : [JOB_SKIPPED] = ANSI_HIGHLIGHT_ON " INFO " ANSI_HIGHLIGHT_OFF,
678 : [JOB_ASSERT] = ANSI_HIGHLIGHT_YELLOW_ON "ASSERT" ANSI_HIGHLIGHT_OFF,
679 : [JOB_UNSUPPORTED] = ANSI_HIGHLIGHT_YELLOW_ON "UNSUPP" ANSI_HIGHLIGHT_OFF,
680 : };
681 :
682 48 : assert(u);
683 48 : assert(t >= 0);
684 48 : assert(t < _JOB_TYPE_MAX);
685 :
686 48 : format = job_get_status_message_format(u, t, result);
687 48 : if (!format)
688 12 : return;
689 :
690 36 : if (result != JOB_DONE)
691 0 : manager_flip_auto_status(u->manager, true);
692 :
693 : DISABLE_WARNING_FORMAT_NONLITERAL;
694 36 : unit_status_printf(u, job_result_status_table[result], format);
695 : REENABLE_WARNING;
696 :
697 36 : if (t == JOB_START && result == JOB_FAILED) {
698 0 : _cleanup_free_ char *quoted = shell_maybe_quote(u->id);
699 :
700 0 : manager_status_printf(u->manager, STATUS_TYPE_NORMAL, NULL,
701 : "See 'systemctl status %s' for details.", strna(quoted));
702 : }
703 : }
704 :
705 48 : static void job_log_status_message(Unit *u, JobType t, JobResult result) {
706 : const char *format;
707 : char buf[LINE_MAX];
708 : sd_id128_t mid;
709 : static const int job_result_log_level[_JOB_RESULT_MAX] = {
710 : [JOB_DONE] = LOG_INFO,
711 : [JOB_CANCELED] = LOG_INFO,
712 : [JOB_TIMEOUT] = LOG_ERR,
713 : [JOB_FAILED] = LOG_ERR,
714 : [JOB_DEPENDENCY] = LOG_WARNING,
715 : [JOB_SKIPPED] = LOG_NOTICE,
716 : [JOB_INVALID] = LOG_INFO,
717 : [JOB_ASSERT] = LOG_WARNING,
718 : [JOB_UNSUPPORTED] = LOG_WARNING,
719 : };
720 :
721 48 : assert(u);
722 48 : assert(t >= 0);
723 48 : assert(t < _JOB_TYPE_MAX);
724 :
725 : /* Skip this if it goes to the console. since we already print
726 : * to the console anyway... */
727 :
728 48 : if (log_on_console())
729 96 : return;
730 :
731 0 : format = job_get_status_message_format(u, t, result);
732 0 : if (!format)
733 0 : return;
734 :
735 : DISABLE_WARNING_FORMAT_NONLITERAL;
736 0 : snprintf(buf, sizeof(buf), format, unit_description(u));
737 : REENABLE_WARNING;
738 :
739 0 : if (t == JOB_START)
740 0 : mid = result == JOB_DONE ? SD_MESSAGE_UNIT_STARTED : SD_MESSAGE_UNIT_FAILED;
741 0 : else if (t == JOB_STOP || t == JOB_RESTART)
742 0 : mid = SD_MESSAGE_UNIT_STOPPED;
743 0 : else if (t == JOB_RELOAD)
744 0 : mid = SD_MESSAGE_UNIT_RELOADED;
745 : else {
746 0 : log_struct(job_result_log_level[result],
747 : LOG_UNIT_ID(u),
748 : LOG_MESSAGE("%s", buf),
749 : "RESULT=%s", job_result_to_string(result),
750 : NULL);
751 0 : return;
752 : }
753 :
754 0 : log_struct(job_result_log_level[result],
755 : LOG_MESSAGE_ID(mid),
756 : LOG_UNIT_ID(u),
757 : LOG_MESSAGE("%s", buf),
758 : "RESULT=%s", job_result_to_string(result),
759 : NULL);
760 : }
761 :
762 48 : static void job_emit_status_message(Unit *u, JobType t, JobResult result) {
763 :
764 : /* No message if the job did not actually do anything due to failed condition. */
765 48 : if (t == JOB_START && result == JOB_DONE && !u->condition_result)
766 0 : return;
767 :
768 48 : job_log_status_message(u, t, result);
769 :
770 : /* Reload status messages have traditionally not been printed to console. */
771 48 : if (t != JOB_RELOAD)
772 48 : job_print_status_message(u, t, result);
773 : }
774 :
775 0 : static void job_fail_dependencies(Unit *u, UnitDependency d) {
776 : Unit *other;
777 : Iterator i;
778 :
779 0 : assert(u);
780 :
781 0 : SET_FOREACH(other, u->dependencies[d], i) {
782 0 : Job *j = other->job;
783 :
784 0 : if (!j)
785 0 : continue;
786 0 : if (!IN_SET(j->type, JOB_START, JOB_VERIFY_ACTIVE))
787 0 : continue;
788 :
789 0 : job_finish_and_invalidate(j, JOB_DEPENDENCY, true);
790 : }
791 0 : }
792 :
793 48 : int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) {
794 : Unit *u;
795 : Unit *other;
796 : JobType t;
797 : Iterator i;
798 :
799 48 : assert(j);
800 48 : assert(j->installed);
801 48 : assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
802 :
803 48 : u = j->unit;
804 48 : t = j->type;
805 :
806 48 : j->result = result;
807 :
808 48 : log_unit_debug(u, "Job %s/%s finished, result=%s", u->id, job_type_to_string(t), job_result_to_string(result));
809 :
810 48 : job_emit_status_message(u, t, result);
811 :
812 48 : job_add_to_dbus_queue(j);
813 :
814 : /* Patch restart jobs so that they become normal start jobs */
815 48 : if (result == JOB_DONE && t == JOB_RESTART) {
816 :
817 0 : job_change_type(j, JOB_START);
818 0 : job_set_state(j, JOB_WAITING);
819 :
820 0 : job_add_to_run_queue(j);
821 :
822 0 : goto finish;
823 : }
824 :
825 48 : if (result == JOB_FAILED || result == JOB_INVALID)
826 0 : j->manager->n_failed_jobs ++;
827 :
828 48 : job_uninstall(j);
829 48 : job_free(j);
830 :
831 : /* Fail depending jobs on failure */
832 48 : if (result != JOB_DONE && recursive) {
833 0 : if (IN_SET(t, JOB_START, JOB_VERIFY_ACTIVE)) {
834 0 : job_fail_dependencies(u, UNIT_REQUIRED_BY);
835 0 : job_fail_dependencies(u, UNIT_REQUISITE_OF);
836 0 : job_fail_dependencies(u, UNIT_BOUND_BY);
837 0 : job_fail_dependencies(u, UNIT_REQUIRED_BY_OVERRIDABLE);
838 0 : job_fail_dependencies(u, UNIT_REQUISITE_OF_OVERRIDABLE);
839 0 : } else if (t == JOB_STOP)
840 0 : job_fail_dependencies(u, UNIT_CONFLICTED_BY);
841 : }
842 :
843 : /* Trigger OnFailure dependencies that are not generated by
844 : * the unit itself. We don't treat JOB_CANCELED as failure in
845 : * this context. And JOB_FAILURE is already handled by the
846 : * unit itself. */
847 48 : if (result == JOB_TIMEOUT || result == JOB_DEPENDENCY) {
848 0 : log_struct(LOG_NOTICE,
849 : "JOB_TYPE=%s", job_type_to_string(t),
850 : "JOB_RESULT=%s", job_result_to_string(result),
851 : LOG_UNIT_ID(u),
852 : LOG_UNIT_MESSAGE(u, "Job %s/%s failed with result '%s'.",
853 : u->id,
854 : job_type_to_string(t),
855 : job_result_to_string(result)),
856 : NULL);
857 :
858 0 : unit_start_on_failure(u);
859 : }
860 :
861 48 : unit_trigger_notify(u);
862 :
863 : finish:
864 : /* Try to start the next jobs that can be started */
865 192 : SET_FOREACH(other, u->dependencies[UNIT_AFTER], i)
866 96 : if (other->job)
867 12 : job_add_to_run_queue(other->job);
868 208 : SET_FOREACH(other, u->dependencies[UNIT_BEFORE], i)
869 112 : if (other->job)
870 34 : job_add_to_run_queue(other->job);
871 :
872 48 : manager_check_finished(u->manager);
873 :
874 48 : return 0;
875 : }
876 :
877 0 : static int job_dispatch_timer(sd_event_source *s, uint64_t monotonic, void *userdata) {
878 0 : Job *j = userdata;
879 : Unit *u;
880 :
881 0 : assert(j);
882 0 : assert(s == j->timer_event_source);
883 :
884 0 : log_unit_warning(j->unit, "Job %s/%s timed out.", j->unit->id, job_type_to_string(j->type));
885 :
886 0 : u = j->unit;
887 0 : job_finish_and_invalidate(j, JOB_TIMEOUT, true);
888 :
889 0 : failure_action(u->manager, u->job_timeout_action, u->job_timeout_reboot_arg);
890 :
891 0 : return 0;
892 : }
893 :
894 89 : int job_start_timer(Job *j) {
895 : int r;
896 :
897 89 : if (j->timer_event_source)
898 0 : return 0;
899 :
900 89 : j->begin_usec = now(CLOCK_MONOTONIC);
901 :
902 89 : if (j->unit->job_timeout <= 0)
903 89 : return 0;
904 :
905 0 : r = sd_event_add_time(
906 0 : j->manager->event,
907 : &j->timer_event_source,
908 : CLOCK_MONOTONIC,
909 0 : j->begin_usec + j->unit->job_timeout, 0,
910 : job_dispatch_timer, j);
911 0 : if (r < 0)
912 0 : return r;
913 :
914 0 : (void) sd_event_source_set_description(j->timer_event_source, "job-start");
915 :
916 0 : return 0;
917 : }
918 :
919 135 : void job_add_to_run_queue(Job *j) {
920 135 : assert(j);
921 135 : assert(j->installed);
922 :
923 135 : if (j->in_run_queue)
924 59 : return;
925 :
926 76 : if (!j->manager->run_queue)
927 16 : sd_event_source_set_enabled(j->manager->run_queue_event_source, SD_EVENT_ONESHOT);
928 :
929 76 : LIST_PREPEND(run_queue, j->manager->run_queue, j);
930 76 : j->in_run_queue = true;
931 : }
932 :
933 179 : void job_add_to_dbus_queue(Job *j) {
934 179 : assert(j);
935 179 : assert(j->installed);
936 :
937 179 : if (j->in_dbus_queue)
938 116 : return;
939 :
940 : /* We don't check if anybody is subscribed here, since this
941 : * job might just have been created and not yet assigned to a
942 : * connection/client. */
943 :
944 63 : LIST_PREPEND(dbus_queue, j->manager->dbus_job_queue, j);
945 63 : j->in_dbus_queue = true;
946 : }
947 :
948 0 : char *job_dbus_path(Job *j) {
949 : char *p;
950 :
951 0 : assert(j);
952 :
953 0 : if (asprintf(&p, "/org/freedesktop/systemd1/job/%"PRIu32, j->id) < 0)
954 0 : return NULL;
955 :
956 0 : return p;
957 : }
958 :
959 0 : int job_serialize(Job *j, FILE *f, FDSet *fds) {
960 0 : fprintf(f, "job-id=%u\n", j->id);
961 0 : fprintf(f, "job-type=%s\n", job_type_to_string(j->type));
962 0 : fprintf(f, "job-state=%s\n", job_state_to_string(j->state));
963 0 : fprintf(f, "job-override=%s\n", yes_no(j->override));
964 0 : fprintf(f, "job-irreversible=%s\n", yes_no(j->irreversible));
965 0 : fprintf(f, "job-sent-dbus-new-signal=%s\n", yes_no(j->sent_dbus_new_signal));
966 0 : fprintf(f, "job-ignore-order=%s\n", yes_no(j->ignore_order));
967 :
968 0 : if (j->begin_usec > 0)
969 0 : fprintf(f, "job-begin="USEC_FMT"\n", j->begin_usec);
970 :
971 0 : bus_track_serialize(j->clients, f);
972 :
973 : /* End marker */
974 0 : fputc('\n', f);
975 0 : return 0;
976 : }
977 :
978 0 : int job_deserialize(Job *j, FILE *f, FDSet *fds) {
979 0 : assert(j);
980 :
981 : for (;;) {
982 : char line[LINE_MAX], *l, *v;
983 : size_t k;
984 :
985 0 : if (!fgets(line, sizeof(line), f)) {
986 0 : if (feof(f))
987 0 : return 0;
988 0 : return -errno;
989 : }
990 :
991 0 : char_array_0(line);
992 0 : l = strstrip(line);
993 :
994 : /* End marker */
995 0 : if (l[0] == 0)
996 0 : return 0;
997 :
998 0 : k = strcspn(l, "=");
999 :
1000 0 : if (l[k] == '=') {
1001 0 : l[k] = 0;
1002 0 : v = l+k+1;
1003 : } else
1004 0 : v = l+k;
1005 :
1006 0 : if (streq(l, "job-id")) {
1007 :
1008 0 : if (safe_atou32(v, &j->id) < 0)
1009 0 : log_debug("Failed to parse job id value %s", v);
1010 :
1011 0 : } else if (streq(l, "job-type")) {
1012 : JobType t;
1013 :
1014 0 : t = job_type_from_string(v);
1015 0 : if (t < 0)
1016 0 : log_debug("Failed to parse job type %s", v);
1017 0 : else if (t >= _JOB_TYPE_MAX_IN_TRANSACTION)
1018 0 : log_debug("Cannot deserialize job of type %s", v);
1019 : else
1020 0 : j->type = t;
1021 :
1022 0 : } else if (streq(l, "job-state")) {
1023 : JobState s;
1024 :
1025 0 : s = job_state_from_string(v);
1026 0 : if (s < 0)
1027 0 : log_debug("Failed to parse job state %s", v);
1028 : else
1029 0 : job_set_state(j, s);
1030 :
1031 0 : } else if (streq(l, "job-override")) {
1032 : int b;
1033 :
1034 0 : b = parse_boolean(v);
1035 0 : if (b < 0)
1036 0 : log_debug("Failed to parse job override flag %s", v);
1037 : else
1038 0 : j->override = j->override || b;
1039 :
1040 0 : } else if (streq(l, "job-irreversible")) {
1041 : int b;
1042 :
1043 0 : b = parse_boolean(v);
1044 0 : if (b < 0)
1045 0 : log_debug("Failed to parse job irreversible flag %s", v);
1046 : else
1047 0 : j->irreversible = j->irreversible || b;
1048 :
1049 0 : } else if (streq(l, "job-sent-dbus-new-signal")) {
1050 : int b;
1051 :
1052 0 : b = parse_boolean(v);
1053 0 : if (b < 0)
1054 0 : log_debug("Failed to parse job sent_dbus_new_signal flag %s", v);
1055 : else
1056 0 : j->sent_dbus_new_signal = j->sent_dbus_new_signal || b;
1057 :
1058 0 : } else if (streq(l, "job-ignore-order")) {
1059 : int b;
1060 :
1061 0 : b = parse_boolean(v);
1062 0 : if (b < 0)
1063 0 : log_debug("Failed to parse job ignore_order flag %s", v);
1064 : else
1065 0 : j->ignore_order = j->ignore_order || b;
1066 :
1067 0 : } else if (streq(l, "job-begin")) {
1068 : unsigned long long ull;
1069 :
1070 0 : if (sscanf(v, "%llu", &ull) != 1)
1071 0 : log_debug("Failed to parse job-begin value %s", v);
1072 : else
1073 0 : j->begin_usec = ull;
1074 :
1075 0 : } else if (streq(l, "subscribed")) {
1076 :
1077 0 : if (strv_extend(&j->deserialized_clients, v) < 0)
1078 0 : return log_oom();
1079 : }
1080 0 : }
1081 : }
1082 :
1083 0 : int job_coldplug(Job *j) {
1084 : int r;
1085 :
1086 0 : assert(j);
1087 :
1088 : /* After deserialization is complete and the bus connection
1089 : * set up again, let's start watching our subscribers again */
1090 0 : r = bus_track_coldplug(j->manager, &j->clients, &j->deserialized_clients);
1091 0 : if (r < 0)
1092 0 : return r;
1093 :
1094 0 : if (j->state == JOB_WAITING)
1095 0 : job_add_to_run_queue(j);
1096 :
1097 0 : if (j->begin_usec == 0 || j->unit->job_timeout == 0)
1098 0 : return 0;
1099 :
1100 0 : if (j->timer_event_source)
1101 0 : j->timer_event_source = sd_event_source_unref(j->timer_event_source);
1102 :
1103 0 : r = sd_event_add_time(
1104 0 : j->manager->event,
1105 : &j->timer_event_source,
1106 : CLOCK_MONOTONIC,
1107 0 : j->begin_usec + j->unit->job_timeout, 0,
1108 : job_dispatch_timer, j);
1109 0 : if (r < 0)
1110 0 : log_debug_errno(r, "Failed to restart timeout for job: %m");
1111 :
1112 0 : (void) sd_event_source_set_description(j->timer_event_source, "job-timeout");
1113 :
1114 0 : return r;
1115 : }
1116 :
1117 89 : void job_shutdown_magic(Job *j) {
1118 89 : assert(j);
1119 :
1120 : /* The shutdown target gets some special treatment here: we
1121 : * tell the kernel to begin with flushing its disk caches, to
1122 : * optimize shutdown time a bit. Ideally we wouldn't hardcode
1123 : * this magic into PID 1. However all other processes aren't
1124 : * options either since they'd exit much sooner than PID 1 and
1125 : * asynchronous sync() would cause their exit to be
1126 : * delayed. */
1127 :
1128 89 : if (j->type != JOB_START)
1129 3 : return;
1130 :
1131 86 : if (j->unit->manager->running_as != MANAGER_SYSTEM)
1132 86 : return;
1133 :
1134 0 : if (!unit_has_name(j->unit, SPECIAL_SHUTDOWN_TARGET))
1135 0 : return;
1136 :
1137 : /* In case messages on console has been disabled on boot */
1138 0 : j->unit->manager->no_console_output = false;
1139 :
1140 0 : if (detect_container(NULL) > 0)
1141 0 : return;
1142 :
1143 0 : asynchronous_sync();
1144 : }
1145 :
1146 0 : int job_get_timeout(Job *j, uint64_t *timeout) {
1147 0 : Unit *u = j->unit;
1148 0 : uint64_t x = -1, y = -1;
1149 0 : int r = 0, q = 0;
1150 :
1151 0 : assert(u);
1152 :
1153 0 : if (j->timer_event_source) {
1154 0 : r = sd_event_source_get_time(j->timer_event_source, &x);
1155 0 : if (r < 0)
1156 0 : return r;
1157 0 : r = 1;
1158 : }
1159 :
1160 0 : if (UNIT_VTABLE(u)->get_timeout) {
1161 0 : q = UNIT_VTABLE(u)->get_timeout(u, &y);
1162 0 : if (q < 0)
1163 0 : return q;
1164 : }
1165 :
1166 0 : if (r == 0 && q == 0)
1167 0 : return 0;
1168 :
1169 0 : *timeout = MIN(x, y);
1170 :
1171 0 : return 1;
1172 : }
1173 :
1174 : static const char* const job_state_table[_JOB_STATE_MAX] = {
1175 : [JOB_WAITING] = "waiting",
1176 : [JOB_RUNNING] = "running"
1177 : };
1178 :
1179 80 : DEFINE_STRING_TABLE_LOOKUP(job_state, JobState);
1180 :
1181 : static const char* const job_type_table[_JOB_TYPE_MAX] = {
1182 : [JOB_START] = "start",
1183 : [JOB_VERIFY_ACTIVE] = "verify-active",
1184 : [JOB_STOP] = "stop",
1185 : [JOB_RELOAD] = "reload",
1186 : [JOB_RELOAD_OR_START] = "reload-or-start",
1187 : [JOB_RESTART] = "restart",
1188 : [JOB_TRY_RESTART] = "try-restart",
1189 : [JOB_NOP] = "nop",
1190 : };
1191 :
1192 934 : DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
1193 :
1194 : static const char* const job_mode_table[_JOB_MODE_MAX] = {
1195 : [JOB_FAIL] = "fail",
1196 : [JOB_REPLACE] = "replace",
1197 : [JOB_REPLACE_IRREVERSIBLY] = "replace-irreversibly",
1198 : [JOB_ISOLATE] = "isolate",
1199 : [JOB_FLUSH] = "flush",
1200 : [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
1201 : [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements",
1202 : };
1203 :
1204 339 : DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);
1205 :
1206 : static const char* const job_result_table[_JOB_RESULT_MAX] = {
1207 : [JOB_DONE] = "done",
1208 : [JOB_CANCELED] = "canceled",
1209 : [JOB_TIMEOUT] = "timeout",
1210 : [JOB_FAILED] = "failed",
1211 : [JOB_DEPENDENCY] = "dependency",
1212 : [JOB_SKIPPED] = "skipped",
1213 : [JOB_INVALID] = "invalid",
1214 : [JOB_ASSERT] = "assert",
1215 : [JOB_UNSUPPORTED] = "unsupported",
1216 : };
1217 :
1218 70 : DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);
|