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