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