]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/job.c
Use initalization instead of explicit zeroing
[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
877d54e9 572static 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
877d54e9
LP
591static const char *job_get_status_message_format_try_harder(Unit *u, JobType t, JobResult result) {
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
c0daa706 843 unit_trigger_on_failure(u);
222ae6a8 844 }
c0daa706 845
57981b98 846finish:
5cb5a6ff 847 /* Try to start the next jobs that can be started */
ac155bb8
MS
848 SET_FOREACH(other, u->dependencies[UNIT_AFTER], i)
849 if (other->job)
850 job_add_to_run_queue(other->job);
851 SET_FOREACH(other, u->dependencies[UNIT_BEFORE], i)
852 if (other->job)
853 job_add_to_run_queue(other->job);
5cb5a6ff 854
ac155bb8 855 manager_check_finished(u->manager);
b0c918b9 856
5273510e 857 return 0;
5cb5a6ff 858}
034c6ed7 859
faf919f1 860int job_start_timer(Job *j) {
b92bea5d
ZJS
861 struct itimerspec its = {};
862 struct epoll_event ev = {
863 .data.ptr = &j->timer_watch,
864 .events = EPOLLIN,
865 };
faf919f1 866 int fd, r;
faf919f1 867
ac155bb8 868 if (j->unit->job_timeout <= 0 ||
faf919f1
LP
869 j->timer_watch.type == WATCH_JOB_TIMER)
870 return 0;
871
872 assert(j->timer_watch.type == WATCH_INVALID);
873
874 if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) {
875 r = -errno;
876 goto fail;
877 }
878
ac155bb8 879 timespec_store(&its.it_value, j->unit->job_timeout);
faf919f1
LP
880
881 if (timerfd_settime(fd, 0, &its, NULL) < 0) {
882 r = -errno;
883 goto fail;
884 }
885
faf919f1
LP
886 if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
887 r = -errno;
888 goto fail;
889 }
890
891 j->timer_watch.type = WATCH_JOB_TIMER;
892 j->timer_watch.fd = fd;
893 j->timer_watch.data.job = j;
894
895 return 0;
896
897fail:
898 if (fd >= 0)
899 close_nointr_nofail(fd);
900
901 return r;
902}
903
c1e1601e 904void job_add_to_run_queue(Job *j) {
034c6ed7 905 assert(j);
ac1135be 906 assert(j->installed);
034c6ed7
LP
907
908 if (j->in_run_queue)
909 return;
910
911 LIST_PREPEND(Job, run_queue, j->manager->run_queue, j);
912 j->in_run_queue = true;
913}
94f04347 914
c1e1601e
LP
915void job_add_to_dbus_queue(Job *j) {
916 assert(j);
917 assert(j->installed);
918
919 if (j->in_dbus_queue)
920 return;
921
a567261a
LP
922 /* We don't check if anybody is subscribed here, since this
923 * job might just have been created and not yet assigned to a
924 * connection/client. */
94b6dfa2 925
c1e1601e
LP
926 LIST_PREPEND(Job, dbus_queue, j->manager->dbus_job_queue, j);
927 j->in_dbus_queue = true;
928}
929
ea430986
LP
930char *job_dbus_path(Job *j) {
931 char *p;
932
933 assert(j);
934
935 if (asprintf(&p, "/org/freedesktop/systemd1/job/%lu", (unsigned long) j->id) < 0)
936 return NULL;
937
938 return p;
939}
940
faf919f1
LP
941void job_timer_event(Job *j, uint64_t n_elapsed, Watch *w) {
942 assert(j);
943 assert(w == &j->timer_watch);
944
66870f90
ZJS
945 log_warning_unit(j->unit->id, "Job %s/%s timed out.",
946 j->unit->id, job_type_to_string(j->type));
5273510e 947 job_finish_and_invalidate(j, JOB_TIMEOUT, true);
faf919f1
LP
948}
949
39a18c60
MS
950int job_serialize(Job *j, FILE *f, FDSet *fds) {
951 fprintf(f, "job-id=%u\n", j->id);
952 fprintf(f, "job-type=%s\n", job_type_to_string(j->type));
953 fprintf(f, "job-state=%s\n", job_state_to_string(j->state));
954 fprintf(f, "job-override=%s\n", yes_no(j->override));
23ade460 955 fprintf(f, "job-irreversible=%s\n", yes_no(j->irreversible));
39a18c60
MS
956 fprintf(f, "job-sent-dbus-new-signal=%s\n", yes_no(j->sent_dbus_new_signal));
957 fprintf(f, "job-ignore-order=%s\n", yes_no(j->ignore_order));
958 /* Cannot save bus clients. Just note the fact that we're losing
959 * them. job_send_message() will fallback to broadcasting. */
960 fprintf(f, "job-forgot-bus-clients=%s\n",
961 yes_no(j->forgot_bus_clients || j->bus_client_list));
962 if (j->timer_watch.type == WATCH_JOB_TIMER) {
963 int copy = fdset_put_dup(fds, j->timer_watch.fd);
964 if (copy < 0)
965 return copy;
966 fprintf(f, "job-timer-watch-fd=%d\n", copy);
967 }
968
969 /* End marker */
970 fputc('\n', f);
971 return 0;
972}
973
974int job_deserialize(Job *j, FILE *f, FDSet *fds) {
975 for (;;) {
976 char line[LINE_MAX], *l, *v;
977 size_t k;
978
979 if (!fgets(line, sizeof(line), f)) {
980 if (feof(f))
981 return 0;
982 return -errno;
983 }
984
985 char_array_0(line);
986 l = strstrip(line);
987
988 /* End marker */
989 if (l[0] == 0)
990 return 0;
991
992 k = strcspn(l, "=");
993
994 if (l[k] == '=') {
995 l[k] = 0;
996 v = l+k+1;
997 } else
998 v = l+k;
999
1000 if (streq(l, "job-id")) {
1001 if (safe_atou32(v, &j->id) < 0)
1002 log_debug("Failed to parse job id value %s", v);
1003 } else if (streq(l, "job-type")) {
1004 JobType t = job_type_from_string(v);
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;
1011 } else if (streq(l, "job-state")) {
1012 JobState s = job_state_from_string(v);
1013 if (s < 0)
1014 log_debug("Failed to parse job state %s", v);
1015 else
1016 j->state = s;
1017 } else if (streq(l, "job-override")) {
1018 int b = parse_boolean(v);
1019 if (b < 0)
1020 log_debug("Failed to parse job override flag %s", v);
1021 else
1022 j->override = j->override || b;
23ade460
MS
1023 } else if (streq(l, "job-irreversible")) {
1024 int b = parse_boolean(v);
1025 if (b < 0)
1026 log_debug("Failed to parse job irreversible flag %s", v);
1027 else
1028 j->irreversible = j->irreversible || b;
39a18c60
MS
1029 } else if (streq(l, "job-sent-dbus-new-signal")) {
1030 int b = parse_boolean(v);
1031 if (b < 0)
1032 log_debug("Failed to parse job sent_dbus_new_signal flag %s", v);
1033 else
1034 j->sent_dbus_new_signal = j->sent_dbus_new_signal || b;
1035 } else if (streq(l, "job-ignore-order")) {
1036 int b = parse_boolean(v);
1037 if (b < 0)
1038 log_debug("Failed to parse job ignore_order flag %s", v);
1039 else
1040 j->ignore_order = j->ignore_order || b;
1041 } else if (streq(l, "job-forgot-bus-clients")) {
1042 int b = parse_boolean(v);
1043 if (b < 0)
1044 log_debug("Failed to parse job forgot_bus_clients flag %s", v);
1045 else
1046 j->forgot_bus_clients = j->forgot_bus_clients || b;
1047 } else if (streq(l, "job-timer-watch-fd")) {
1048 int fd;
1049 if (safe_atoi(v, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
1050 log_debug("Failed to parse job-timer-watch-fd value %s", v);
1051 else {
1052 if (j->timer_watch.type == WATCH_JOB_TIMER)
1053 close_nointr_nofail(j->timer_watch.fd);
1054
1055 j->timer_watch.type = WATCH_JOB_TIMER;
1056 j->timer_watch.fd = fdset_remove(fds, fd);
1057 j->timer_watch.data.job = j;
1058 }
1059 }
1060 }
1061}
1062
1063int job_coldplug(Job *j) {
b92bea5d
ZJS
1064 struct epoll_event ev = {
1065 .data.ptr = &j->timer_watch,
1066 .events = EPOLLIN,
1067 };
39a18c60
MS
1068
1069 if (j->timer_watch.type != WATCH_JOB_TIMER)
1070 return 0;
1071
39a18c60
MS
1072 if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, j->timer_watch.fd, &ev) < 0)
1073 return -errno;
1074
1075 return 0;
1076}
1077
c65eb836
LP
1078void job_shutdown_magic(Job *j) {
1079 assert(j);
1080
1081 /* The shutdown target gets some special treatment here: we
1082 * tell the kernel to begin with flushing its disk caches, to
1083 * optimize shutdown time a bit. Ideally we wouldn't hardcode
1084 * this magic into PID 1. However all other processes aren't
1085 * options either since they'd exit much sooner than PID 1 and
1086 * asynchronous sync() would cause their exit to be
1087 * delayed. */
1088
1089 if (!unit_has_name(j->unit, SPECIAL_SHUTDOWN_TARGET))
1090 return;
1091
1092 if (j->type != JOB_START)
1093 return;
1094
1095 if (detect_container(NULL) > 0)
1096 return;
1097
1098 asynchronous_sync();
1099}
1100
94f04347
LP
1101static const char* const job_state_table[_JOB_STATE_MAX] = {
1102 [JOB_WAITING] = "waiting",
1103 [JOB_RUNNING] = "running"
1104};
1105
1106DEFINE_STRING_TABLE_LOOKUP(job_state, JobState);
1107
1108static const char* const job_type_table[_JOB_TYPE_MAX] = {
1109 [JOB_START] = "start",
1110 [JOB_VERIFY_ACTIVE] = "verify-active",
1111 [JOB_STOP] = "stop",
1112 [JOB_RELOAD] = "reload",
1113 [JOB_RELOAD_OR_START] = "reload-or-start",
1114 [JOB_RESTART] = "restart",
1115 [JOB_TRY_RESTART] = "try-restart",
e0209d83 1116 [JOB_NOP] = "nop",
94f04347
LP
1117};
1118
1119DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
b548631a
LP
1120
1121static const char* const job_mode_table[_JOB_MODE_MAX] = {
1122 [JOB_FAIL] = "fail",
c497c7a9 1123 [JOB_REPLACE] = "replace",
23ade460 1124 [JOB_REPLACE_IRREVERSIBLY] = "replace-irreversibly",
e67c3609 1125 [JOB_ISOLATE] = "isolate",
cebe0d41
LP
1126 [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
1127 [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements"
b548631a
LP
1128};
1129
1130DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);
5d44db4a
LP
1131
1132static const char* const job_result_table[_JOB_RESULT_MAX] = {
1133 [JOB_DONE] = "done",
1134 [JOB_CANCELED] = "canceled",
1135 [JOB_TIMEOUT] = "timeout",
1136 [JOB_FAILED] = "failed",
d68201e9
LP
1137 [JOB_DEPENDENCY] = "dependency",
1138 [JOB_SKIPPED] = "skipped"
5d44db4a
LP
1139};
1140
1141DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);