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