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(Unit *unit, JobType type) {
39 assert(type < _JOB_TYPE_MAX);
42 if (!(j = new0(Job, 1)))
45 j->manager = unit->manager;
46 j->id = j->manager->current_job_id++;
50 j->timer_watch.type = WATCH_INVALID;
52 /* We don't link it here, that's what job_dependency() is for */
57 void job_uninstall(Job *j) {
59 /* Detach from next 'bigger' objects */
61 bus_job_send_removed_signal(j);
63 if (j->unit->job == j) {
65 unit_add_to_gc_queue(j->unit);
68 hashmap_remove(j->manager->jobs, UINT32_TO_PTR(j->id));
72 void job_free(Job *j) {
74 assert(!j->installed);
75 assert(!j->transaction_prev);
76 assert(!j->transaction_next);
77 assert(!j->subject_list);
78 assert(!j->object_list);
81 LIST_REMOVE(Job, run_queue, j->manager->run_queue, j);
84 LIST_REMOVE(Job, dbus_queue, j->manager->dbus_job_queue, j);
86 if (j->timer_watch.type != WATCH_INVALID) {
87 assert(j->timer_watch.type == WATCH_JOB_TIMER);
88 assert(j->timer_watch.data.job == j);
89 assert(j->timer_watch.fd >= 0);
91 assert_se(epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_DEL, j->timer_watch.fd, NULL) >= 0);
92 close_nointr_nofail(j->timer_watch.fd);
99 JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts, Transaction *tr) {
104 /* Adds a new job link, which encodes that the 'subject' job
105 * needs the 'object' job in some way. If 'subject' is NULL
106 * this means the 'anchor' job (i.e. the one the user
107 * explicitly asked for) is the requester. */
109 if (!(l = new0(JobDependency, 1)))
112 l->subject = subject;
114 l->matters = matters;
115 l->conflicts = conflicts;
118 LIST_PREPEND(JobDependency, subject, subject->subject_list, l);
120 LIST_PREPEND(JobDependency, subject, tr->anchor, l);
122 LIST_PREPEND(JobDependency, object, object->object_list, l);
127 void job_dependency_free(JobDependency *l, Transaction *tr) {
131 LIST_REMOVE(JobDependency, subject, l->subject->subject_list, l);
133 LIST_REMOVE(JobDependency, subject, tr->anchor, l);
135 LIST_REMOVE(JobDependency, object, l->object->object_list, l);
140 void job_dump(Job *j, FILE*f, const char *prefix) {
149 "%s\tAction: %s -> %s\n"
153 prefix, j->unit->id, job_type_to_string(j->type),
154 prefix, job_state_to_string(j->state),
155 prefix, yes_no(j->override));
158 bool job_is_anchor(Job *j) {
163 LIST_FOREACH(object, l, j->object_list)
171 * Merging is commutative, so imagine the matrix as symmetric. We store only
172 * its lower triangle to avoid duplication. We don't store the main diagonal,
173 * because A merged with A is simply A.
175 * Merging is associative! A merged with B merged with C is the same as
176 * A merged with C merged with B.
178 * Mergeability is transitive! If A can be merged with B and B with C then
181 * Also, if A merged with B cannot be merged with C, then either A or B cannot
182 * be merged with C either.
184 static const JobType job_merging_table[] = {
185 /* What \ With * JOB_START JOB_VERIFY_ACTIVE JOB_STOP JOB_RELOAD JOB_RELOAD_OR_START JOB_RESTART JOB_TRY_RESTART */
186 /************************************************************************************************************************************/
188 /*JOB_VERIFY_ACTIVE */ JOB_START,
189 /*JOB_STOP */ -1, -1,
190 /*JOB_RELOAD */ JOB_RELOAD_OR_START, JOB_RELOAD, -1,
191 /*JOB_RELOAD_OR_START*/ JOB_RELOAD_OR_START, JOB_RELOAD_OR_START, -1, JOB_RELOAD_OR_START,
192 /*JOB_RESTART */ JOB_RESTART, JOB_RESTART, -1, JOB_RESTART, JOB_RESTART,
193 /*JOB_TRY_RESTART */ JOB_RESTART, JOB_TRY_RESTART, -1, JOB_TRY_RESTART, JOB_RESTART, JOB_RESTART,
196 JobType job_type_lookup_merge(JobType a, JobType b) {
197 assert_cc(ELEMENTSOF(job_merging_table) == _JOB_TYPE_MAX * (_JOB_TYPE_MAX - 1) / 2);
198 assert(a >= 0 && a < _JOB_TYPE_MAX);
199 assert(b >= 0 && b < _JOB_TYPE_MAX);
210 return job_merging_table[(a - 1) * a / 2 + b];
213 bool job_type_is_redundant(JobType a, UnitActiveState b) {
223 b == UNIT_INACTIVE ||
226 case JOB_VERIFY_ACTIVE:
235 case JOB_RELOAD_OR_START:
237 b == UNIT_ACTIVATING ||
242 b == UNIT_ACTIVATING;
244 case JOB_TRY_RESTART:
246 b == UNIT_ACTIVATING;
249 assert_not_reached("Invalid job type");
253 bool job_is_runnable(Job *j) {
258 assert(j->installed);
260 /* Checks whether there is any job running for the units this
261 * job needs to be running after (in the case of a 'positive'
262 * job type) or before (in the case of a 'negative' job
265 /* First check if there is an override */
269 if (j->type == JOB_START ||
270 j->type == JOB_VERIFY_ACTIVE ||
271 j->type == JOB_RELOAD ||
272 j->type == JOB_RELOAD_OR_START) {
274 /* Immediate result is that the job is or might be
275 * started. In this case lets wait for the
276 * dependencies, regardless whether they are
277 * starting or stopping something. */
279 SET_FOREACH(other, j->unit->dependencies[UNIT_AFTER], i)
284 /* Also, if something else is being stopped and we should
285 * change state after it, then lets wait. */
287 SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i)
289 (other->job->type == JOB_STOP ||
290 other->job->type == JOB_RESTART ||
291 other->job->type == JOB_TRY_RESTART))
294 /* This means that for a service a and a service b where b
295 * shall be started after a:
297 * start a + start b → 1st step start a, 2nd step start b
298 * start a + stop b → 1st step stop b, 2nd step start a
299 * stop a + start b → 1st step stop a, 2nd step start b
300 * stop a + stop b → 1st step stop b, 2nd step stop a
302 * This has the side effect that restarts are properly
303 * synchronized too. */
308 static void job_change_type(Job *j, JobType newtype) {
309 log_debug("Converting job %s/%s -> %s/%s",
310 j->unit->id, job_type_to_string(j->type),
311 j->unit->id, job_type_to_string(newtype));
316 int job_run_and_invalidate(Job *j) {
322 assert(j->installed);
324 if (j->in_run_queue) {
325 LIST_REMOVE(Job, run_queue, j->manager->run_queue, j);
326 j->in_run_queue = false;
329 if (j->state != JOB_WAITING)
332 if (!job_is_runnable(j))
335 j->state = JOB_RUNNING;
336 job_add_to_dbus_queue(j);
338 /* While we execute this operation the job might go away (for
339 * example: because it is replaced by a new, conflicting
340 * job.) To make sure we don't access a freed job later on we
341 * store the id here, so that we can verify the job is still
348 case JOB_RELOAD_OR_START:
349 if (unit_active_state(j->unit) == UNIT_ACTIVE) {
350 job_change_type(j, JOB_RELOAD);
351 r = unit_reload(j->unit);
354 job_change_type(j, JOB_START);
358 r = unit_start(j->unit);
360 /* If this unit cannot be started, then simply wait */
365 case JOB_VERIFY_ACTIVE: {
366 UnitActiveState t = unit_active_state(j->unit);
367 if (UNIT_IS_ACTIVE_OR_RELOADING(t))
369 else if (t == UNIT_ACTIVATING)
376 case JOB_TRY_RESTART:
377 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(j->unit))) {
381 job_change_type(j, JOB_RESTART);
386 r = unit_stop(j->unit);
388 /* If this unit cannot stopped, then simply wait. */
394 r = unit_reload(j->unit);
398 assert_not_reached("Unknown job type");
401 if ((j = manager_get_job(m, id))) {
403 r = job_finish_and_invalidate(j, JOB_DONE);
404 else if (r == -ENOEXEC)
405 r = job_finish_and_invalidate(j, JOB_SKIPPED);
406 else if (r == -EAGAIN)
407 j->state = JOB_WAITING;
409 r = job_finish_and_invalidate(j, JOB_FAILED);
415 static void job_print_status_message(Unit *u, JobType t, JobResult result) {
418 if (t == JOB_START) {
423 if (u->condition_result)
424 unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, "Started %s", unit_description(u));
428 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF, "Failed to start %s", unit_description(u));
429 unit_status_printf(u, NULL, "See 'systemctl status %s' for details.", u->id);
433 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " ABORT" ANSI_HIGHLIGHT_OFF, "Dependency failed. Aborted start of %s", unit_description(u));
437 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, "Timed out starting %s", unit_description(u));
444 } else if (t == JOB_STOP) {
449 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, "Timed out stopping %s", unit_description(u));
454 unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, "Stopped %s", unit_description(u));
463 int job_finish_and_invalidate(Job *j, JobResult result) {
468 bool recursed = false;
471 assert(j->installed);
473 job_add_to_dbus_queue(j);
475 /* Patch restart jobs so that they become normal start jobs */
476 if (result == JOB_DONE && j->type == JOB_RESTART) {
478 job_change_type(j, JOB_START);
479 j->state = JOB_WAITING;
481 job_add_to_run_queue(j);
489 log_debug("Job %s/%s finished, result=%s", j->unit->id, job_type_to_string(j->type), job_result_to_string(result));
491 if (result == JOB_FAILED)
492 j->manager->n_failed_jobs ++;
499 job_print_status_message(u, t, result);
501 /* Fail depending jobs on failure */
502 if (result != JOB_DONE) {
504 if (t == JOB_START ||
505 t == JOB_VERIFY_ACTIVE ||
506 t == JOB_RELOAD_OR_START) {
508 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
510 (other->job->type == JOB_START ||
511 other->job->type == JOB_VERIFY_ACTIVE ||
512 other->job->type == JOB_RELOAD_OR_START)) {
513 job_finish_and_invalidate(other->job, JOB_DEPENDENCY);
517 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
519 (other->job->type == JOB_START ||
520 other->job->type == JOB_VERIFY_ACTIVE ||
521 other->job->type == JOB_RELOAD_OR_START)) {
522 job_finish_and_invalidate(other->job, JOB_DEPENDENCY);
526 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
528 !other->job->override &&
529 (other->job->type == JOB_START ||
530 other->job->type == JOB_VERIFY_ACTIVE ||
531 other->job->type == JOB_RELOAD_OR_START)) {
532 job_finish_and_invalidate(other->job, JOB_DEPENDENCY);
536 } else if (t == JOB_STOP) {
538 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
540 (other->job->type == JOB_START ||
541 other->job->type == JOB_VERIFY_ACTIVE ||
542 other->job->type == JOB_RELOAD_OR_START)) {
543 job_finish_and_invalidate(other->job, JOB_DEPENDENCY);
549 /* Trigger OnFailure dependencies that are not generated by
550 * the unit itself. We don't tread JOB_CANCELED as failure in
551 * this context. And JOB_FAILURE is already handled by the
553 if (result == JOB_TIMEOUT || result == JOB_DEPENDENCY) {
554 log_notice("Job %s/%s failed with result '%s'.",
556 job_type_to_string(t),
557 job_result_to_string(result));
559 unit_trigger_on_failure(u);
563 /* Try to start the next jobs that can be started */
564 SET_FOREACH(other, u->dependencies[UNIT_AFTER], i)
566 job_add_to_run_queue(other->job);
567 SET_FOREACH(other, u->dependencies[UNIT_BEFORE], i)
569 job_add_to_run_queue(other->job);
571 manager_check_finished(u->manager);
576 int job_start_timer(Job *j) {
577 struct itimerspec its;
578 struct epoll_event ev;
582 if (j->unit->job_timeout <= 0 ||
583 j->timer_watch.type == WATCH_JOB_TIMER)
586 assert(j->timer_watch.type == WATCH_INVALID);
588 if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) {
594 timespec_store(&its.it_value, j->unit->job_timeout);
596 if (timerfd_settime(fd, 0, &its, NULL) < 0) {
602 ev.data.ptr = &j->timer_watch;
605 if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
610 j->timer_watch.type = WATCH_JOB_TIMER;
611 j->timer_watch.fd = fd;
612 j->timer_watch.data.job = j;
618 close_nointr_nofail(fd);
623 void job_add_to_run_queue(Job *j) {
625 assert(j->installed);
630 LIST_PREPEND(Job, run_queue, j->manager->run_queue, j);
631 j->in_run_queue = true;
634 void job_add_to_dbus_queue(Job *j) {
636 assert(j->installed);
638 if (j->in_dbus_queue)
641 /* We don't check if anybody is subscribed here, since this
642 * job might just have been created and not yet assigned to a
643 * connection/client. */
645 LIST_PREPEND(Job, dbus_queue, j->manager->dbus_job_queue, j);
646 j->in_dbus_queue = true;
649 char *job_dbus_path(Job *j) {
654 if (asprintf(&p, "/org/freedesktop/systemd1/job/%lu", (unsigned long) j->id) < 0)
660 void job_timer_event(Job *j, uint64_t n_elapsed, Watch *w) {
662 assert(w == &j->timer_watch);
664 log_warning("Job %s/%s timed out.", j->unit->id, job_type_to_string(j->type));
665 job_finish_and_invalidate(j, JOB_TIMEOUT);
668 static const char* const job_state_table[_JOB_STATE_MAX] = {
669 [JOB_WAITING] = "waiting",
670 [JOB_RUNNING] = "running"
673 DEFINE_STRING_TABLE_LOOKUP(job_state, JobState);
675 static const char* const job_type_table[_JOB_TYPE_MAX] = {
676 [JOB_START] = "start",
677 [JOB_VERIFY_ACTIVE] = "verify-active",
679 [JOB_RELOAD] = "reload",
680 [JOB_RELOAD_OR_START] = "reload-or-start",
681 [JOB_RESTART] = "restart",
682 [JOB_TRY_RESTART] = "try-restart",
685 DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
687 static const char* const job_mode_table[_JOB_MODE_MAX] = {
689 [JOB_REPLACE] = "replace",
690 [JOB_ISOLATE] = "isolate",
691 [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
692 [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements"
695 DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);
697 static const char* const job_result_table[_JOB_RESULT_MAX] = {
699 [JOB_CANCELED] = "canceled",
700 [JOB_TIMEOUT] = "timeout",
701 [JOB_FAILED] = "failed",
702 [JOB_DEPENDENCY] = "dependency",
703 [JOB_SKIPPED] = "skipped"
706 DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);