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