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