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