1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
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
11 (at your option) any later version.
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
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
24 #include <sys/timerfd.h>
25 #include <sys/epoll.h>
31 #include "load-fragment.h"
32 #include "load-dropin.h"
36 Job* job_new(Manager *m, JobType type, Unit *unit) {
40 assert(type < _JOB_TYPE_MAX);
43 if (!(j = new0(Job, 1)))
47 j->id = m->current_job_id++;
51 j->timer_watch.type = WATCH_INVALID;
53 /* We don't link it here, that's what job_dependency() is for */
58 void job_free(Job *j) {
61 /* Detach from next 'bigger' objects */
63 bus_job_send_removed_signal(j);
65 if (j->unit->job == j) {
67 unit_add_to_gc_queue(j->unit);
70 hashmap_remove(j->manager->jobs, UINT32_TO_PTR(j->id));
74 /* Detach from next 'smaller' objects */
75 manager_transaction_unlink_job(j->manager, j, true);
78 LIST_REMOVE(Job, run_queue, j->manager->run_queue, j);
81 LIST_REMOVE(Job, dbus_queue, j->manager->dbus_job_queue, j);
83 if (j->timer_watch.type != WATCH_INVALID) {
84 assert(j->timer_watch.type == WATCH_JOB_TIMER);
85 assert(j->timer_watch.data.job == j);
86 assert(j->timer_watch.fd >= 0);
88 assert_se(epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_DEL, j->timer_watch.fd, NULL) >= 0);
89 close_nointr_nofail(j->timer_watch.fd);
96 JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts) {
101 /* Adds a new job link, which encodes that the 'subject' job
102 * needs the 'object' job in some way. If 'subject' is NULL
103 * this means the 'anchor' job (i.e. the one the user
104 * explicitly asked for) is the requester. */
106 if (!(l = new0(JobDependency, 1)))
109 l->subject = subject;
111 l->matters = matters;
112 l->conflicts = conflicts;
115 LIST_PREPEND(JobDependency, subject, subject->subject_list, l);
117 LIST_PREPEND(JobDependency, subject, object->manager->transaction_anchor, l);
119 LIST_PREPEND(JobDependency, object, object->object_list, l);
124 void job_dependency_free(JobDependency *l) {
128 LIST_REMOVE(JobDependency, subject, l->subject->subject_list, l);
130 LIST_REMOVE(JobDependency, subject, l->object->manager->transaction_anchor, l);
132 LIST_REMOVE(JobDependency, object, l->object->object_list, l);
137 void job_dump(Job *j, FILE*f, const char *prefix) {
146 "%s\tAction: %s -> %s\n"
150 prefix, j->unit->id, job_type_to_string(j->type),
151 prefix, job_state_to_string(j->state),
152 prefix, yes_no(j->override));
155 bool job_is_anchor(Job *j) {
160 LIST_FOREACH(object, l, j->object_list)
168 * Merging is commutative, so imagine the matrix as symmetric. We store only
169 * its lower triangle to avoid duplication. We don't store the main diagonal,
170 * because A merged with A is simply A.
172 * Merging is associative! A merged with B merged with C is the same as
173 * A merged with C merged with B.
175 * Mergeability is transitive! If A can be merged with B and B with C then
178 * Also, if A merged with B cannot be merged with C, then either A or B cannot
179 * be merged with C either.
181 static const JobType job_merging_table[] = {
182 /* What \ With * JOB_START JOB_VERIFY_ACTIVE JOB_STOP JOB_RELOAD JOB_RELOAD_OR_START JOB_RESTART JOB_TRY_RESTART */
183 /************************************************************************************************************************************/
185 /*JOB_VERIFY_ACTIVE */ JOB_START,
186 /*JOB_STOP */ -1, -1,
187 /*JOB_RELOAD */ JOB_RELOAD_OR_START, JOB_RELOAD, -1,
188 /*JOB_RELOAD_OR_START*/ JOB_RELOAD_OR_START, JOB_RELOAD_OR_START, -1, JOB_RELOAD_OR_START,
189 /*JOB_RESTART */ JOB_RESTART, JOB_RESTART, -1, JOB_RESTART, JOB_RESTART,
190 /*JOB_TRY_RESTART */ JOB_RESTART, JOB_TRY_RESTART, -1, JOB_TRY_RESTART, JOB_RESTART, JOB_RESTART,
193 JobType job_type_lookup_merge(JobType a, JobType b) {
194 assert_cc(ELEMENTSOF(job_merging_table) == _JOB_TYPE_MAX * (_JOB_TYPE_MAX - 1) / 2);
195 assert(a >= 0 && a < _JOB_TYPE_MAX);
196 assert(b >= 0 && b < _JOB_TYPE_MAX);
207 return job_merging_table[(a - 1) * a / 2 + b];
210 bool job_type_is_redundant(JobType a, UnitActiveState b) {
220 b == UNIT_INACTIVE ||
223 case JOB_VERIFY_ACTIVE:
232 case JOB_RELOAD_OR_START:
234 b == UNIT_ACTIVATING ||
239 b == UNIT_ACTIVATING;
241 case JOB_TRY_RESTART:
243 b == UNIT_ACTIVATING;
246 assert_not_reached("Invalid job type");
250 bool job_is_runnable(Job *j) {
255 assert(j->installed);
257 /* Checks whether there is any job running for the units this
258 * job needs to be running after (in the case of a 'positive'
259 * job type) or before (in the case of a 'negative' job
262 /* First check if there is an override */
266 if (j->type == JOB_START ||
267 j->type == JOB_VERIFY_ACTIVE ||
268 j->type == JOB_RELOAD ||
269 j->type == JOB_RELOAD_OR_START) {
271 /* Immediate result is that the job is or might be
272 * started. In this case lets wait for the
273 * dependencies, regardless whether they are
274 * starting or stopping something. */
276 SET_FOREACH(other, j->unit->dependencies[UNIT_AFTER], i)
281 /* Also, if something else is being stopped and we should
282 * change state after it, then lets wait. */
284 SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i)
286 (other->job->type == JOB_STOP ||
287 other->job->type == JOB_RESTART ||
288 other->job->type == JOB_TRY_RESTART))
291 /* This means that for a service a and a service b where b
292 * shall be started after a:
294 * start a + start b → 1st step start a, 2nd step start b
295 * start a + stop b → 1st step stop b, 2nd step start a
296 * stop a + start b → 1st step stop a, 2nd step start b
297 * stop a + stop b → 1st step stop b, 2nd step stop a
299 * This has the side effect that restarts are properly
300 * synchronized too. */
305 static void job_change_type(Job *j, JobType newtype) {
306 log_debug("Converting job %s/%s -> %s/%s",
307 j->unit->id, job_type_to_string(j->type),
308 j->unit->id, job_type_to_string(newtype));
313 int job_run_and_invalidate(Job *j) {
319 assert(j->installed);
321 if (j->in_run_queue) {
322 LIST_REMOVE(Job, run_queue, j->manager->run_queue, j);
323 j->in_run_queue = false;
326 if (j->state != JOB_WAITING)
329 if (!job_is_runnable(j))
332 j->state = JOB_RUNNING;
333 job_add_to_dbus_queue(j);
335 /* While we execute this operation the job might go away (for
336 * example: because it is replaced by a new, conflicting
337 * job.) To make sure we don't access a freed job later on we
338 * store the id here, so that we can verify the job is still
345 case JOB_RELOAD_OR_START:
346 if (unit_active_state(j->unit) == UNIT_ACTIVE) {
347 job_change_type(j, JOB_RELOAD);
348 r = unit_reload(j->unit);
351 job_change_type(j, JOB_START);
355 r = unit_start(j->unit);
357 /* If this unit cannot be started, then simply wait */
362 case JOB_VERIFY_ACTIVE: {
363 UnitActiveState t = unit_active_state(j->unit);
364 if (UNIT_IS_ACTIVE_OR_RELOADING(t))
366 else if (t == UNIT_ACTIVATING)
373 case JOB_TRY_RESTART:
374 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(j->unit))) {
378 job_change_type(j, JOB_RESTART);
383 r = unit_stop(j->unit);
385 /* If this unit cannot stopped, then simply wait. */
391 r = unit_reload(j->unit);
395 assert_not_reached("Unknown job type");
398 if ((j = manager_get_job(m, id))) {
400 r = job_finish_and_invalidate(j, JOB_DONE);
401 else if (r == -ENOEXEC)
402 r = job_finish_and_invalidate(j, JOB_SKIPPED);
403 else if (r == -EAGAIN)
404 j->state = JOB_WAITING;
406 r = job_finish_and_invalidate(j, JOB_FAILED);
412 static void job_print_status_message(Unit *u, JobType t, JobResult result) {
415 if (t == JOB_START) {
420 unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, "Started %s", unit_description(u));
424 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF, "Failed to start %s", unit_description(u));
425 unit_status_printf(u, NULL, "See 'systemctl status %s' for details.", u->id);
429 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " ABORT" ANSI_HIGHLIGHT_OFF, "Dependency failed. Aborted start of %s", unit_description(u));
433 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, "Timed out starting %s", unit_description(u));
440 } else if (t == JOB_STOP) {
445 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, "Timed out stopping %s", unit_description(u));
450 unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, "Stopped %s", unit_description(u));
459 int job_finish_and_invalidate(Job *j, JobResult result) {
464 bool recursed = false;
467 assert(j->installed);
469 job_add_to_dbus_queue(j);
471 /* Patch restart jobs so that they become normal start jobs */
472 if (result == JOB_DONE && j->type == JOB_RESTART) {
474 job_change_type(j, JOB_START);
475 j->state = JOB_WAITING;
477 job_add_to_run_queue(j);
485 log_debug("Job %s/%s finished, result=%s", j->unit->id, job_type_to_string(j->type), job_result_to_string(result));
487 if (result == JOB_FAILED)
488 j->manager->n_failed_jobs ++;
494 job_print_status_message(u, t, result);
496 /* Fail depending jobs on failure */
497 if (result != JOB_DONE) {
499 if (t == JOB_START ||
500 t == JOB_VERIFY_ACTIVE ||
501 t == JOB_RELOAD_OR_START) {
503 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
505 (other->job->type == JOB_START ||
506 other->job->type == JOB_VERIFY_ACTIVE ||
507 other->job->type == JOB_RELOAD_OR_START)) {
508 job_finish_and_invalidate(other->job, JOB_DEPENDENCY);
512 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
514 (other->job->type == JOB_START ||
515 other->job->type == JOB_VERIFY_ACTIVE ||
516 other->job->type == JOB_RELOAD_OR_START)) {
517 job_finish_and_invalidate(other->job, JOB_DEPENDENCY);
521 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
523 !other->job->override &&
524 (other->job->type == JOB_START ||
525 other->job->type == JOB_VERIFY_ACTIVE ||
526 other->job->type == JOB_RELOAD_OR_START)) {
527 job_finish_and_invalidate(other->job, JOB_DEPENDENCY);
531 } else if (t == JOB_STOP) {
533 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
535 (other->job->type == JOB_START ||
536 other->job->type == JOB_VERIFY_ACTIVE ||
537 other->job->type == JOB_RELOAD_OR_START)) {
538 job_finish_and_invalidate(other->job, JOB_DEPENDENCY);
544 /* Trigger OnFailure dependencies that are not generated by
545 * the unit itself. We don't tread JOB_CANCELED as failure in
546 * this context. And JOB_FAILURE is already handled by the
548 if (result == JOB_TIMEOUT || result == JOB_DEPENDENCY) {
549 log_notice("Job %s/%s failed with result '%s'.",
551 job_type_to_string(t),
552 job_result_to_string(result));
554 unit_trigger_on_failure(u);
558 /* Try to start the next jobs that can be started */
559 SET_FOREACH(other, u->dependencies[UNIT_AFTER], i)
561 job_add_to_run_queue(other->job);
562 SET_FOREACH(other, u->dependencies[UNIT_BEFORE], i)
564 job_add_to_run_queue(other->job);
566 manager_check_finished(u->manager);
571 int job_start_timer(Job *j) {
572 struct itimerspec its;
573 struct epoll_event ev;
577 if (j->unit->job_timeout <= 0 ||
578 j->timer_watch.type == WATCH_JOB_TIMER)
581 assert(j->timer_watch.type == WATCH_INVALID);
583 if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) {
589 timespec_store(&its.it_value, j->unit->job_timeout);
591 if (timerfd_settime(fd, 0, &its, NULL) < 0) {
597 ev.data.ptr = &j->timer_watch;
600 if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
605 j->timer_watch.type = WATCH_JOB_TIMER;
606 j->timer_watch.fd = fd;
607 j->timer_watch.data.job = j;
613 close_nointr_nofail(fd);
618 void job_add_to_run_queue(Job *j) {
620 assert(j->installed);
625 LIST_PREPEND(Job, run_queue, j->manager->run_queue, j);
626 j->in_run_queue = true;
629 void job_add_to_dbus_queue(Job *j) {
631 assert(j->installed);
633 if (j->in_dbus_queue)
636 /* We don't check if anybody is subscribed here, since this
637 * job might just have been created and not yet assigned to a
638 * connection/client. */
640 LIST_PREPEND(Job, dbus_queue, j->manager->dbus_job_queue, j);
641 j->in_dbus_queue = true;
644 char *job_dbus_path(Job *j) {
649 if (asprintf(&p, "/org/freedesktop/systemd1/job/%lu", (unsigned long) j->id) < 0)
655 void job_timer_event(Job *j, uint64_t n_elapsed, Watch *w) {
657 assert(w == &j->timer_watch);
659 log_warning("Job %s/%s timed out.", j->unit->id, job_type_to_string(j->type));
660 job_finish_and_invalidate(j, JOB_TIMEOUT);
663 static const char* const job_state_table[_JOB_STATE_MAX] = {
664 [JOB_WAITING] = "waiting",
665 [JOB_RUNNING] = "running"
668 DEFINE_STRING_TABLE_LOOKUP(job_state, JobState);
670 static const char* const job_type_table[_JOB_TYPE_MAX] = {
671 [JOB_START] = "start",
672 [JOB_VERIFY_ACTIVE] = "verify-active",
674 [JOB_RELOAD] = "reload",
675 [JOB_RELOAD_OR_START] = "reload-or-start",
676 [JOB_RESTART] = "restart",
677 [JOB_TRY_RESTART] = "try-restart",
680 DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
682 static const char* const job_mode_table[_JOB_MODE_MAX] = {
684 [JOB_REPLACE] = "replace",
685 [JOB_ISOLATE] = "isolate",
686 [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
687 [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements"
690 DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);
692 static const char* const job_result_table[_JOB_RESULT_MAX] = {
694 [JOB_CANCELED] = "canceled",
695 [JOB_TIMEOUT] = "timeout",
696 [JOB_FAILED] = "failed",
697 [JOB_DEPENDENCY] = "dependency",
698 [JOB_SKIPPED] = "skipped"
701 DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);