]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/job.c
Move bus path definitions to def.h
[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
6a371e23 511 r = -EBADR;
5cb5a6ff
LP
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);
6a371e23 540 else if (r == -EBADR)
5273510e 541 r = job_finish_and_invalidate(j, JOB_SKIPPED, true);
6a371e23
ZJS
542 else if (r == -ENOEXEC)
543 r = job_finish_and_invalidate(j, JOB_INVALID, true);
637f8b8e 544 else if (r == -EAGAIN) {
2cf19a7a 545 j->state = JOB_WAITING;
637f8b8e
MS
546 m->n_running_jobs--;
547 } else if (r < 0)
5273510e 548 r = job_finish_and_invalidate(j, JOB_FAILED, true);
2cf19a7a 549 }
5cb5a6ff
LP
550
551 return r;
552}
553
44a6b1b6 554_pure_ static const char *job_get_status_message_format(Unit *u, JobType t, JobResult result) {
c6918296 555 const UnitStatusMessageFormats *format_table;
877d54e9
LP
556
557 assert(u);
558 assert(t >= 0);
559 assert(t < _JOB_TYPE_MAX);
c6918296
MS
560
561 format_table = &UNIT_VTABLE(u)->status_message_formats;
562 if (!format_table)
877d54e9
LP
563 return NULL;
564
565 if (t == JOB_START)
566 return format_table->finished_start_job[result];
567 else if (t == JOB_STOP || t == JOB_RESTART)
568 return format_table->finished_stop_job[result];
569
570 return NULL;
571}
e02cd6f7 572
44a6b1b6 573_pure_ static const char *job_get_status_message_format_try_harder(Unit *u, JobType t, JobResult result) {
877d54e9
LP
574 const char *format;
575
576 assert(u);
577 assert(t >= 0);
578 assert(t < _JOB_TYPE_MAX);
579
580 format = job_get_status_message_format(u, t, result);
581 if (format)
582 return format;
583
584 /* Return generic strings */
e02cd6f7 585 if (t == JOB_START) {
877d54e9
LP
586 if (result == JOB_DONE)
587 return "Started %s.";
588 else if (result == JOB_FAILED)
589 return "Failed to start %s.";
590 else if (result == JOB_DEPENDENCY)
591 return "Dependency failed for %s.";
592 else if (result == JOB_TIMEOUT)
593 return "Timed out starting %s.";
594 } else if (t == JOB_STOP || t == JOB_RESTART) {
595 if (result == JOB_DONE)
596 return "Stopped %s.";
597 else if (result == JOB_FAILED)
598 return "Stopped (with error) %s.";
599 else if (result == JOB_TIMEOUT)
600 return "Timed out stoppping %s.";
601 } else if (t == JOB_RELOAD) {
602 if (result == JOB_DONE)
603 return "Reloaded %s.";
604 else if (result == JOB_FAILED)
605 return "Reload failed for %s.";
606 else if (result == JOB_TIMEOUT)
607 return "Timed out reloading %s.";
608 }
609
610 return NULL;
611}
612
9091e686
TA
613#pragma GCC diagnostic push
614#pragma GCC diagnostic ignored "-Wformat-nonliteral"
877d54e9
LP
615static void job_print_status_message(Unit *u, JobType t, JobResult result) {
616 const char *format;
e02cd6f7 617
877d54e9
LP
618 assert(u);
619 assert(t >= 0);
620 assert(t < _JOB_TYPE_MAX);
621
622 if (t == JOB_START) {
623 format = job_get_status_message_format(u, t, result);
c6918296
MS
624 if (!format)
625 return;
626
e02cd6f7
LP
627 switch (result) {
628
629 case JOB_DONE:
69120666 630 if (u->condition_result)
076a24ad 631 unit_status_printf(u, ANSI_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, format);
e02cd6f7
LP
632 break;
633
634 case JOB_FAILED:
49b1d377 635 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF, format);
984a2be4 636 manager_status_printf(u->manager, false, NULL, "See 'systemctl status %s' for details.", u->id);
e02cd6f7
LP
637 break;
638
639 case JOB_DEPENDENCY:
49b1d377 640 unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "DEPEND" ANSI_HIGHLIGHT_OFF, format);
e02cd6f7
LP
641 break;
642
643 case JOB_TIMEOUT:
49b1d377 644 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format);
e02cd6f7
LP
645 break;
646
647 default:
648 ;
649 }
650
1f136e7a 651 } else if (t == JOB_STOP || t == JOB_RESTART) {
e02cd6f7 652
877d54e9 653 format = job_get_status_message_format(u, t, result);
c6918296
MS
654 if (!format)
655 return;
656
e02cd6f7
LP
657 switch (result) {
658
659 case JOB_TIMEOUT:
49b1d377 660 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format);
e02cd6f7
LP
661 break;
662
663 case JOB_DONE:
664 case JOB_FAILED:
076a24ad 665 unit_status_printf(u, ANSI_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, format);
e02cd6f7
LP
666 break;
667
668 default:
669 ;
670 }
7cf82e0b
MS
671
672 } else if (t == JOB_VERIFY_ACTIVE) {
673
674 /* When verify-active detects the unit is inactive, report it.
675 * Most likely a DEPEND warning from a requisiting unit will
676 * occur next and it's nice to see what was requisited. */
677 if (result == JOB_SKIPPED)
49b1d377 678 unit_status_printf(u, ANSI_HIGHLIGHT_ON " INFO " ANSI_HIGHLIGHT_OFF, "%s is not active.");
e02cd6f7
LP
679 }
680}
9091e686 681#pragma GCC diagnostic pop
e02cd6f7 682
877d54e9
LP
683#pragma GCC diagnostic push
684#pragma GCC diagnostic ignored "-Wformat-nonliteral"
685static void job_log_status_message(Unit *u, JobType t, JobResult result) {
686 const char *format;
687 char buf[LINE_MAX];
688
689 assert(u);
690 assert(t >= 0);
691 assert(t < _JOB_TYPE_MAX);
692
81270860
LP
693 /* Skip this if it goes to the console. since we already print
694 * to the console anyway... */
695
696 if (log_on_console())
697 return;
698
877d54e9
LP
699 format = job_get_status_message_format_try_harder(u, t, result);
700 if (!format)
701 return;
702
703 snprintf(buf, sizeof(buf), format, unit_description(u));
704 char_array_0(buf);
705
706 if (t == JOB_START) {
707 sd_id128_t mid;
708
709 mid = result == JOB_DONE ? SD_MESSAGE_UNIT_STARTED : SD_MESSAGE_UNIT_FAILED;
bbc9006e
MT
710 log_struct_unit(result == JOB_DONE ? LOG_INFO : LOG_ERR,
711 u->id,
1ca6783f 712 MESSAGE_ID(mid),
877d54e9
LP
713 "RESULT=%s", job_result_to_string(result),
714 "MESSAGE=%s", buf,
715 NULL);
716
717 } else if (t == JOB_STOP)
bbc9006e
MT
718 log_struct_unit(result == JOB_DONE ? LOG_INFO : LOG_ERR,
719 u->id,
1ca6783f 720 MESSAGE_ID(SD_MESSAGE_UNIT_STOPPED),
877d54e9
LP
721 "RESULT=%s", job_result_to_string(result),
722 "MESSAGE=%s", buf,
723 NULL);
724
725 else if (t == JOB_RELOAD)
bbc9006e
MT
726 log_struct_unit(result == JOB_DONE ? LOG_INFO : LOG_ERR,
727 u->id,
1ca6783f 728 MESSAGE_ID(SD_MESSAGE_UNIT_RELOADED),
877d54e9
LP
729 "RESULT=%s", job_result_to_string(result),
730 "MESSAGE=%s", buf,
731 NULL);
732}
733#pragma GCC diagnostic pop
734
5273510e 735int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) {
87f0e418
LP
736 Unit *u;
737 Unit *other;
b866264a 738 JobType t;
034c6ed7 739 Iterator i;
5cb5a6ff
LP
740
741 assert(j);
ac1135be 742 assert(j->installed);
e0209d83 743 assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
5cb5a6ff 744
c6918296
MS
745 u = j->unit;
746 t = j->type;
747
748 j->result = result;
749
637f8b8e
MS
750 if (j->state == JOB_RUNNING)
751 j->manager->n_running_jobs--;
752
66870f90
ZJS
753 log_debug_unit(u->id, "Job %s/%s finished, result=%s",
754 u->id, job_type_to_string(t), job_result_to_string(result));
c6918296
MS
755
756 job_print_status_message(u, t, result);
877d54e9 757 job_log_status_message(u, t, result);
c6918296 758
c1e1601e 759 job_add_to_dbus_queue(j);
f50e0a01 760
034c6ed7 761 /* Patch restart jobs so that they become normal start jobs */
c6918296 762 if (result == JOB_DONE && t == JOB_RESTART) {
f50e0a01 763
bbd1a837 764 job_change_type(j, JOB_START);
9c2d9caa 765 j->state = JOB_WAITING;
cc42e081
LP
766
767 job_add_to_run_queue(j);
57981b98 768
57981b98 769 goto finish;
5cb5a6ff
LP
770 }
771
6a371e23 772 if (result == JOB_FAILED || result == JOB_INVALID)
76bf48b7
LP
773 j->manager->n_failed_jobs ++;
774
97e7d748 775 job_uninstall(j);
5cb5a6ff
LP
776 job_free(j);
777
778 /* Fail depending jobs on failure */
5273510e 779 if (result != JOB_DONE && recursive) {
5cb5a6ff
LP
780
781 if (t == JOB_START ||
e0209d83 782 t == JOB_VERIFY_ACTIVE) {
5cb5a6ff 783
ac155bb8
MS
784 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
785 if (other->job &&
786 (other->job->type == JOB_START ||
e0209d83 787 other->job->type == JOB_VERIFY_ACTIVE))
5273510e 788 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
5cb5a6ff 789
ac155bb8
MS
790 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
791 if (other->job &&
792 (other->job->type == JOB_START ||
e0209d83 793 other->job->type == JOB_VERIFY_ACTIVE))
5273510e 794 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
e6a3ff95 795
ac155bb8
MS
796 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
797 if (other->job &&
798 !other->job->override &&
799 (other->job->type == JOB_START ||
e0209d83 800 other->job->type == JOB_VERIFY_ACTIVE))
5273510e 801 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
5cb5a6ff
LP
802
803 } else if (t == JOB_STOP) {
804
ac155bb8
MS
805 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
806 if (other->job &&
807 (other->job->type == JOB_START ||
e0209d83 808 other->job->type == JOB_VERIFY_ACTIVE))
5273510e 809 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
5cb5a6ff
LP
810 }
811 }
812
c0daa706 813 /* Trigger OnFailure dependencies that are not generated by
66870f90 814 * the unit itself. We don't treat JOB_CANCELED as failure in
c0daa706
LP
815 * this context. And JOB_FAILURE is already handled by the
816 * unit itself. */
222ae6a8 817 if (result == JOB_TIMEOUT || result == JOB_DEPENDENCY) {
bbc9006e
MT
818 log_struct_unit(LOG_NOTICE,
819 u->id,
66870f90 820 "JOB_TYPE=%s", job_type_to_string(t),
38c888a4 821 "JOB_RESULT=%s", job_result_to_string(result),
66870f90 822 "Job %s/%s failed with result '%s'.",
ac155bb8 823 u->id,
222ae6a8 824 job_type_to_string(t),
66870f90
ZJS
825 job_result_to_string(result),
826 NULL);
222ae6a8 827
3ecaa09b 828 unit_start_on_failure(u);
222ae6a8 829 }
c0daa706 830
3ecaa09b
LP
831 unit_trigger_notify(u);
832
57981b98 833finish:
5cb5a6ff 834 /* Try to start the next jobs that can be started */
ac155bb8
MS
835 SET_FOREACH(other, u->dependencies[UNIT_AFTER], i)
836 if (other->job)
837 job_add_to_run_queue(other->job);
838 SET_FOREACH(other, u->dependencies[UNIT_BEFORE], i)
839 if (other->job)
840 job_add_to_run_queue(other->job);
5cb5a6ff 841
ac155bb8 842 manager_check_finished(u->manager);
b0c918b9 843
5273510e 844 return 0;
5cb5a6ff 845}
034c6ed7 846
718db961
LP
847static int job_dispatch_timer(sd_event_source *s, uint64_t monotonic, void *userdata) {
848 Job *j = userdata;
faf919f1 849
718db961
LP
850 assert(j);
851 assert(s == j->timer_event_source);
faf919f1 852
718db961
LP
853 log_warning_unit(j->unit->id, "Job %s/%s timed out.",
854 j->unit->id, job_type_to_string(j->type));
faf919f1 855
718db961
LP
856 job_finish_and_invalidate(j, JOB_TIMEOUT, true);
857 return 0;
858}
faf919f1 859
718db961
LP
860int job_start_timer(Job *j) {
861 int r;
faf919f1 862
718db961
LP
863 if (j->unit->job_timeout <= 0 || j->timer_event_source)
864 return 0;
faf919f1 865
718db961 866 j->begin_usec = now(CLOCK_MONOTONIC);
faf919f1 867
718db961
LP
868 r = sd_event_add_monotonic(j->manager->event, j->begin_usec + j->unit->job_timeout, 0, job_dispatch_timer, j, &j->timer_event_source);
869 if (r < 0)
870 return r;
faf919f1 871
718db961 872 return 0;
faf919f1
LP
873}
874
c1e1601e 875void job_add_to_run_queue(Job *j) {
034c6ed7 876 assert(j);
ac1135be 877 assert(j->installed);
034c6ed7
LP
878
879 if (j->in_run_queue)
880 return;
881
752b5905
LP
882 if (!j->manager->run_queue)
883 sd_event_source_set_enabled(j->manager->run_queue_event_source, SD_EVENT_ONESHOT);
884
71fda00f 885 LIST_PREPEND(run_queue, j->manager->run_queue, j);
034c6ed7
LP
886 j->in_run_queue = true;
887}
94f04347 888
c1e1601e
LP
889void job_add_to_dbus_queue(Job *j) {
890 assert(j);
891 assert(j->installed);
892
893 if (j->in_dbus_queue)
894 return;
895
a567261a
LP
896 /* We don't check if anybody is subscribed here, since this
897 * job might just have been created and not yet assigned to a
898 * connection/client. */
94b6dfa2 899
71fda00f 900 LIST_PREPEND(dbus_queue, j->manager->dbus_job_queue, j);
c1e1601e
LP
901 j->in_dbus_queue = true;
902}
903
ea430986
LP
904char *job_dbus_path(Job *j) {
905 char *p;
906
907 assert(j);
908
909 if (asprintf(&p, "/org/freedesktop/systemd1/job/%lu", (unsigned long) j->id) < 0)
910 return NULL;
911
912 return p;
913}
914
39a18c60
MS
915int job_serialize(Job *j, FILE *f, FDSet *fds) {
916 fprintf(f, "job-id=%u\n", j->id);
917 fprintf(f, "job-type=%s\n", job_type_to_string(j->type));
918 fprintf(f, "job-state=%s\n", job_state_to_string(j->state));
919 fprintf(f, "job-override=%s\n", yes_no(j->override));
23ade460 920 fprintf(f, "job-irreversible=%s\n", yes_no(j->irreversible));
39a18c60
MS
921 fprintf(f, "job-sent-dbus-new-signal=%s\n", yes_no(j->sent_dbus_new_signal));
922 fprintf(f, "job-ignore-order=%s\n", yes_no(j->ignore_order));
718db961
LP
923
924 if (j->begin_usec > 0)
66ca4ec4 925 fprintf(f, "job-begin=%llu\n", (unsigned long long) j->begin_usec);
718db961
LP
926
927 bus_client_track_serialize(j->manager, f, j->subscribed);
39a18c60
MS
928
929 /* End marker */
930 fputc('\n', f);
931 return 0;
932}
933
934int job_deserialize(Job *j, FILE *f, FDSet *fds) {
718db961
LP
935 assert(j);
936
39a18c60
MS
937 for (;;) {
938 char line[LINE_MAX], *l, *v;
939 size_t k;
940
941 if (!fgets(line, sizeof(line), f)) {
942 if (feof(f))
943 return 0;
944 return -errno;
945 }
946
947 char_array_0(line);
948 l = strstrip(line);
949
950 /* End marker */
951 if (l[0] == 0)
952 return 0;
953
954 k = strcspn(l, "=");
955
956 if (l[k] == '=') {
957 l[k] = 0;
958 v = l+k+1;
959 } else
960 v = l+k;
961
962 if (streq(l, "job-id")) {
718db961 963
39a18c60
MS
964 if (safe_atou32(v, &j->id) < 0)
965 log_debug("Failed to parse job id value %s", v);
718db961 966
39a18c60 967 } else if (streq(l, "job-type")) {
718db961
LP
968 JobType t;
969
970 t = job_type_from_string(v);
39a18c60
MS
971 if (t < 0)
972 log_debug("Failed to parse job type %s", v);
e0209d83
MS
973 else if (t >= _JOB_TYPE_MAX_IN_TRANSACTION)
974 log_debug("Cannot deserialize job of type %s", v);
39a18c60
MS
975 else
976 j->type = t;
718db961 977
39a18c60 978 } else if (streq(l, "job-state")) {
718db961
LP
979 JobState s;
980
981 s = job_state_from_string(v);
39a18c60
MS
982 if (s < 0)
983 log_debug("Failed to parse job state %s", v);
984 else
985 j->state = s;
718db961 986
39a18c60 987 } else if (streq(l, "job-override")) {
718db961
LP
988 int b;
989
990 b = parse_boolean(v);
39a18c60
MS
991 if (b < 0)
992 log_debug("Failed to parse job override flag %s", v);
993 else
994 j->override = j->override || b;
718db961 995
23ade460 996 } else if (streq(l, "job-irreversible")) {
718db961
LP
997 int b;
998
999 b = parse_boolean(v);
23ade460
MS
1000 if (b < 0)
1001 log_debug("Failed to parse job irreversible flag %s", v);
1002 else
1003 j->irreversible = j->irreversible || b;
718db961 1004
39a18c60 1005 } else if (streq(l, "job-sent-dbus-new-signal")) {
718db961
LP
1006 int b;
1007
1008 b = parse_boolean(v);
39a18c60
MS
1009 if (b < 0)
1010 log_debug("Failed to parse job sent_dbus_new_signal flag %s", v);
1011 else
1012 j->sent_dbus_new_signal = j->sent_dbus_new_signal || b;
718db961 1013
39a18c60 1014 } else if (streq(l, "job-ignore-order")) {
718db961
LP
1015 int b;
1016
1017 b = parse_boolean(v);
39a18c60
MS
1018 if (b < 0)
1019 log_debug("Failed to parse job ignore_order flag %s", v);
1020 else
1021 j->ignore_order = j->ignore_order || b;
718db961
LP
1022
1023 } else if (streq(l, "job-begin")) {
1024 unsigned long long ull;
1025
1026 if (sscanf(v, "%llu", &ull) != 1)
1027 log_debug("Failed to parse job-begin value %s", v);
39a18c60 1028 else
718db961
LP
1029 j->begin_usec = ull;
1030
1031 } else {
1032 char t[strlen(l) + 1 + strlen(v) + 1];
1033
1034 strcpy(stpcpy(stpcpy(t, l), "="), v);
1035
1036 if (bus_client_track_deserialize_item(j->manager, &j->subscribed, t) == 0)
1037 log_debug("Unknown deserialization key '%s'", l);
39a18c60
MS
1038 }
1039 }
1040}
1041
1042int job_coldplug(Job *j) {
718db961
LP
1043 int r;
1044
1045 assert(j);
39a18c60 1046
718db961 1047 if (j->begin_usec <= 0)
39a18c60
MS
1048 return 0;
1049
718db961
LP
1050 if (j->timer_event_source)
1051 j->timer_event_source = sd_event_source_unref(j->timer_event_source);
39a18c60 1052
718db961
LP
1053 r = sd_event_add_monotonic(j->manager->event, j->begin_usec + j->unit->job_timeout, 0, job_dispatch_timer, j, &j->timer_event_source);
1054 if (r < 0)
1055 log_debug("Failed to restart timeout for job: %s", strerror(-r));
1056
1057 return r;
39a18c60
MS
1058}
1059
c65eb836
LP
1060void job_shutdown_magic(Job *j) {
1061 assert(j);
1062
1063 /* The shutdown target gets some special treatment here: we
1064 * tell the kernel to begin with flushing its disk caches, to
1065 * optimize shutdown time a bit. Ideally we wouldn't hardcode
1066 * this magic into PID 1. However all other processes aren't
1067 * options either since they'd exit much sooner than PID 1 and
1068 * asynchronous sync() would cause their exit to be
1069 * delayed. */
1070
c2756a68 1071 if (j->type != JOB_START)
c65eb836
LP
1072 return;
1073
c2756a68
LP
1074 if (j->unit->manager->running_as != SYSTEMD_SYSTEM)
1075 return;
1076
1077 if (!unit_has_name(j->unit, SPECIAL_SHUTDOWN_TARGET))
c65eb836
LP
1078 return;
1079
5b1869ea
OB
1080 /* In case messages on console has been disabled on boot */
1081 j->unit->manager->no_console_output = false;
1082
c65eb836
LP
1083 if (detect_container(NULL) > 0)
1084 return;
1085
1086 asynchronous_sync();
1087}
1088
94f04347
LP
1089static const char* const job_state_table[_JOB_STATE_MAX] = {
1090 [JOB_WAITING] = "waiting",
1091 [JOB_RUNNING] = "running"
1092};
1093
1094DEFINE_STRING_TABLE_LOOKUP(job_state, JobState);
1095
1096static const char* const job_type_table[_JOB_TYPE_MAX] = {
1097 [JOB_START] = "start",
1098 [JOB_VERIFY_ACTIVE] = "verify-active",
1099 [JOB_STOP] = "stop",
1100 [JOB_RELOAD] = "reload",
1101 [JOB_RELOAD_OR_START] = "reload-or-start",
1102 [JOB_RESTART] = "restart",
1103 [JOB_TRY_RESTART] = "try-restart",
e0209d83 1104 [JOB_NOP] = "nop",
94f04347
LP
1105};
1106
1107DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
b548631a
LP
1108
1109static const char* const job_mode_table[_JOB_MODE_MAX] = {
1110 [JOB_FAIL] = "fail",
c497c7a9 1111 [JOB_REPLACE] = "replace",
23ade460 1112 [JOB_REPLACE_IRREVERSIBLY] = "replace-irreversibly",
e67c3609 1113 [JOB_ISOLATE] = "isolate",
cebe0d41 1114 [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
255baef6
LP
1115 [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements",
1116 [JOB_FLUSH] = "flush",
b548631a
LP
1117};
1118
1119DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);
5d44db4a
LP
1120
1121static const char* const job_result_table[_JOB_RESULT_MAX] = {
1122 [JOB_DONE] = "done",
1123 [JOB_CANCELED] = "canceled",
1124 [JOB_TIMEOUT] = "timeout",
1125 [JOB_FAILED] = "failed",
d68201e9 1126 [JOB_DEPENDENCY] = "dependency",
6a371e23
ZJS
1127 [JOB_SKIPPED] = "skipped",
1128 [JOB_INVALID] = "invalid",
5d44db4a
LP
1129};
1130
1131DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);