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 JobBusClient* job_bus_client_new(DBusConnection *connection, const char *name) {
40 name_len = strlen(name);
41 cl = malloc0(sizeof(JobBusClient) + name_len + 1);
46 memcpy(cl->name, name, name_len + 1);
50 Job* job_new(Unit *unit, JobType type) {
53 assert(type < _JOB_TYPE_MAX);
56 if (!(j = new0(Job, 1)))
59 j->manager = unit->manager;
60 j->id = j->manager->current_job_id++;
64 j->timer_watch.type = WATCH_INVALID;
66 /* We don't link it here, that's what job_dependency() is for */
71 void job_free(Job *j) {
75 assert(!j->installed);
76 assert(!j->transaction_prev);
77 assert(!j->transaction_next);
78 assert(!j->subject_list);
79 assert(!j->object_list);
82 LIST_REMOVE(Job, run_queue, j->manager->run_queue, j);
85 LIST_REMOVE(Job, dbus_queue, j->manager->dbus_job_queue, j);
87 if (j->timer_watch.type != WATCH_INVALID) {
88 assert(j->timer_watch.type == WATCH_JOB_TIMER);
89 assert(j->timer_watch.data.job == j);
90 assert(j->timer_watch.fd >= 0);
92 assert_se(epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_DEL, j->timer_watch.fd, NULL) >= 0);
93 close_nointr_nofail(j->timer_watch.fd);
96 while ((cl = j->bus_client_list)) {
97 LIST_REMOVE(JobBusClient, client, j->bus_client_list, cl);
103 void job_uninstall(Job *j) {
104 assert(j->installed);
105 assert(j->unit->job == j);
106 /* Detach from next 'bigger' objects */
108 bus_job_send_removed_signal(j);
111 unit_add_to_gc_queue(j->unit);
113 hashmap_remove(j->manager->jobs, UINT32_TO_PTR(j->id));
114 j->installed = false;
117 static bool job_type_allows_late_merge(JobType t) {
118 /* Tells whether it is OK to merge a job of type 't' with an already
120 * Reloads cannot be merged this way. Think of the sequence:
121 * 1. Reload of a daemon is in progress; the daemon has already loaded
122 * its config file, but hasn't completed the reload operation yet.
123 * 2. Edit foo's config file.
124 * 3. Trigger another reload to have the daemon use the new config.
125 * Should the second reload job be merged into the first one, the daemon
126 * would not know about the new config.
127 * JOB_RESTART jobs on the other hand can be merged, because they get
128 * patched into JOB_START after stopping the unit. So if we see a
129 * JOB_RESTART running, it means the unit hasn't stopped yet and at
130 * this time the merge is still allowed. */
131 return !(t == JOB_RELOAD || t == JOB_RELOAD_OR_START);
134 static void job_merge_into_installed(Job *j, Job *other) {
135 assert(j->installed);
136 assert(j->unit == other->unit);
138 j->type = job_type_lookup_merge(j->type, other->type);
139 assert(j->type >= 0);
141 j->override = j->override || other->override;
144 Job* job_install(Job *j) {
145 Job *uj = j->unit->job;
147 assert(!j->installed);
150 if (job_type_is_conflicting(uj->type, j->type))
151 job_finish_and_invalidate(uj, JOB_CANCELED);
153 /* not conflicting, i.e. mergeable */
155 if (uj->state == JOB_WAITING ||
156 (job_type_allows_late_merge(j->type) && job_type_is_superset(uj->type, j->type))) {
157 job_merge_into_installed(uj, j);
158 log_debug("Merged into installed job %s/%s as %u",
159 uj->unit->id, job_type_to_string(uj->type), (unsigned) uj->id);
162 /* already running and not safe to merge into */
163 /* Patch uj to become a merged job and re-run it. */
164 /* XXX It should be safer to queue j to run after uj finishes, but it is
165 * not currently possible to have more than one installed job per unit. */
166 job_merge_into_installed(uj, j);
167 log_debug("Merged into running job, re-running: %s/%s as %u",
168 uj->unit->id, job_type_to_string(uj->type), (unsigned) uj->id);
169 uj->state = JOB_WAITING;
175 /* Install the job */
178 j->manager->n_installed_jobs ++;
179 log_debug("Installed new job %s/%s as %u", j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
183 JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts) {
188 /* Adds a new job link, which encodes that the 'subject' job
189 * needs the 'object' job in some way. If 'subject' is NULL
190 * this means the 'anchor' job (i.e. the one the user
191 * explicitly asked for) is the requester. */
193 if (!(l = new0(JobDependency, 1)))
196 l->subject = subject;
198 l->matters = matters;
199 l->conflicts = conflicts;
202 LIST_PREPEND(JobDependency, subject, subject->subject_list, l);
204 LIST_PREPEND(JobDependency, object, object->object_list, l);
209 void job_dependency_free(JobDependency *l) {
213 LIST_REMOVE(JobDependency, subject, l->subject->subject_list, l);
215 LIST_REMOVE(JobDependency, object, l->object->object_list, l);
220 void job_dump(Job *j, FILE*f, const char *prefix) {
229 "%s\tAction: %s -> %s\n"
233 prefix, j->unit->id, job_type_to_string(j->type),
234 prefix, job_state_to_string(j->state),
235 prefix, yes_no(j->override));
239 * Merging is commutative, so imagine the matrix as symmetric. We store only
240 * its lower triangle to avoid duplication. We don't store the main diagonal,
241 * because A merged with A is simply A.
243 * Merging is associative! A merged with B merged with C is the same as
244 * A merged with C merged with B.
246 * Mergeability is transitive! If A can be merged with B and B with C then
249 * Also, if A merged with B cannot be merged with C, then either A or B cannot
250 * be merged with C either.
252 static const JobType job_merging_table[] = {
253 /* What \ With * JOB_START JOB_VERIFY_ACTIVE JOB_STOP JOB_RELOAD JOB_RELOAD_OR_START JOB_RESTART JOB_TRY_RESTART */
254 /************************************************************************************************************************************/
256 /*JOB_VERIFY_ACTIVE */ JOB_START,
257 /*JOB_STOP */ -1, -1,
258 /*JOB_RELOAD */ JOB_RELOAD_OR_START, JOB_RELOAD, -1,
259 /*JOB_RELOAD_OR_START*/ JOB_RELOAD_OR_START, JOB_RELOAD_OR_START, -1, JOB_RELOAD_OR_START,
260 /*JOB_RESTART */ JOB_RESTART, JOB_RESTART, -1, JOB_RESTART, JOB_RESTART,
261 /*JOB_TRY_RESTART */ JOB_RESTART, JOB_TRY_RESTART, -1, JOB_TRY_RESTART, JOB_RESTART, JOB_RESTART,
264 JobType job_type_lookup_merge(JobType a, JobType b) {
265 assert_cc(ELEMENTSOF(job_merging_table) == _JOB_TYPE_MAX * (_JOB_TYPE_MAX - 1) / 2);
266 assert(a >= 0 && a < _JOB_TYPE_MAX);
267 assert(b >= 0 && b < _JOB_TYPE_MAX);
278 return job_merging_table[(a - 1) * a / 2 + b];
281 bool job_type_is_redundant(JobType a, UnitActiveState b) {
291 b == UNIT_INACTIVE ||
294 case JOB_VERIFY_ACTIVE:
303 case JOB_RELOAD_OR_START:
305 b == UNIT_ACTIVATING ||
310 b == UNIT_ACTIVATING;
312 case JOB_TRY_RESTART:
314 b == UNIT_ACTIVATING;
317 assert_not_reached("Invalid job type");
321 bool job_is_runnable(Job *j) {
326 assert(j->installed);
328 /* Checks whether there is any job running for the units this
329 * job needs to be running after (in the case of a 'positive'
330 * job type) or before (in the case of a 'negative' job
333 /* First check if there is an override */
337 if (j->type == JOB_START ||
338 j->type == JOB_VERIFY_ACTIVE ||
339 j->type == JOB_RELOAD ||
340 j->type == JOB_RELOAD_OR_START) {
342 /* Immediate result is that the job is or might be
343 * started. In this case lets wait for the
344 * dependencies, regardless whether they are
345 * starting or stopping something. */
347 SET_FOREACH(other, j->unit->dependencies[UNIT_AFTER], i)
352 /* Also, if something else is being stopped and we should
353 * change state after it, then lets wait. */
355 SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i)
357 (other->job->type == JOB_STOP ||
358 other->job->type == JOB_RESTART ||
359 other->job->type == JOB_TRY_RESTART))
362 /* This means that for a service a and a service b where b
363 * shall be started after a:
365 * start a + start b → 1st step start a, 2nd step start b
366 * start a + stop b → 1st step stop b, 2nd step start a
367 * stop a + start b → 1st step stop a, 2nd step start b
368 * stop a + stop b → 1st step stop b, 2nd step stop a
370 * This has the side effect that restarts are properly
371 * synchronized too. */
376 static void job_change_type(Job *j, JobType newtype) {
377 log_debug("Converting job %s/%s -> %s/%s",
378 j->unit->id, job_type_to_string(j->type),
379 j->unit->id, job_type_to_string(newtype));
384 int job_run_and_invalidate(Job *j) {
390 assert(j->installed);
392 if (j->in_run_queue) {
393 LIST_REMOVE(Job, run_queue, j->manager->run_queue, j);
394 j->in_run_queue = false;
397 if (j->state != JOB_WAITING)
400 if (!job_is_runnable(j))
403 j->state = JOB_RUNNING;
404 job_add_to_dbus_queue(j);
406 /* While we execute this operation the job might go away (for
407 * example: because it is replaced by a new, conflicting
408 * job.) To make sure we don't access a freed job later on we
409 * store the id here, so that we can verify the job is still
416 case JOB_RELOAD_OR_START:
417 if (unit_active_state(j->unit) == UNIT_ACTIVE) {
418 job_change_type(j, JOB_RELOAD);
419 r = unit_reload(j->unit);
422 job_change_type(j, JOB_START);
426 r = unit_start(j->unit);
428 /* If this unit cannot be started, then simply wait */
433 case JOB_VERIFY_ACTIVE: {
434 UnitActiveState t = unit_active_state(j->unit);
435 if (UNIT_IS_ACTIVE_OR_RELOADING(t))
437 else if (t == UNIT_ACTIVATING)
444 case JOB_TRY_RESTART:
445 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(unit_active_state(j->unit))) {
449 job_change_type(j, JOB_RESTART);
454 r = unit_stop(j->unit);
456 /* If this unit cannot stopped, then simply wait. */
462 r = unit_reload(j->unit);
466 assert_not_reached("Unknown job type");
469 if ((j = manager_get_job(m, id))) {
471 r = job_finish_and_invalidate(j, JOB_DONE);
472 else if (r == -ENOEXEC)
473 r = job_finish_and_invalidate(j, JOB_SKIPPED);
474 else if (r == -EAGAIN)
475 j->state = JOB_WAITING;
477 r = job_finish_and_invalidate(j, JOB_FAILED);
483 static void job_print_status_message(Unit *u, JobType t, JobResult result) {
486 if (t == JOB_START) {
491 if (u->condition_result)
492 unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, "Started %s", unit_description(u));
496 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF, "Failed to start %s", unit_description(u));
497 unit_status_printf(u, NULL, "See 'systemctl status %s' for details.", u->id);
501 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " ABORT" ANSI_HIGHLIGHT_OFF, "Dependency failed. Aborted start of %s", unit_description(u));
505 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, "Timed out starting %s", unit_description(u));
512 } else if (t == JOB_STOP) {
517 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, "Timed out stopping %s", unit_description(u));
522 unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, "Stopped %s", unit_description(u));
531 int job_finish_and_invalidate(Job *j, JobResult result) {
536 bool recursed = false;
539 assert(j->installed);
541 job_add_to_dbus_queue(j);
543 /* Patch restart jobs so that they become normal start jobs */
544 if (result == JOB_DONE && j->type == JOB_RESTART) {
546 job_change_type(j, JOB_START);
547 j->state = JOB_WAITING;
549 job_add_to_run_queue(j);
557 log_debug("Job %s/%s finished, result=%s", j->unit->id, job_type_to_string(j->type), job_result_to_string(result));
559 if (result == JOB_FAILED)
560 j->manager->n_failed_jobs ++;
567 job_print_status_message(u, t, result);
569 /* Fail depending jobs on failure */
570 if (result != JOB_DONE) {
572 if (t == JOB_START ||
573 t == JOB_VERIFY_ACTIVE ||
574 t == JOB_RELOAD_OR_START) {
576 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
578 (other->job->type == JOB_START ||
579 other->job->type == JOB_VERIFY_ACTIVE ||
580 other->job->type == JOB_RELOAD_OR_START)) {
581 job_finish_and_invalidate(other->job, JOB_DEPENDENCY);
585 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
587 (other->job->type == JOB_START ||
588 other->job->type == JOB_VERIFY_ACTIVE ||
589 other->job->type == JOB_RELOAD_OR_START)) {
590 job_finish_and_invalidate(other->job, JOB_DEPENDENCY);
594 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
596 !other->job->override &&
597 (other->job->type == JOB_START ||
598 other->job->type == JOB_VERIFY_ACTIVE ||
599 other->job->type == JOB_RELOAD_OR_START)) {
600 job_finish_and_invalidate(other->job, JOB_DEPENDENCY);
604 } else if (t == JOB_STOP) {
606 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
608 (other->job->type == JOB_START ||
609 other->job->type == JOB_VERIFY_ACTIVE ||
610 other->job->type == JOB_RELOAD_OR_START)) {
611 job_finish_and_invalidate(other->job, JOB_DEPENDENCY);
617 /* Trigger OnFailure dependencies that are not generated by
618 * the unit itself. We don't tread JOB_CANCELED as failure in
619 * this context. And JOB_FAILURE is already handled by the
621 if (result == JOB_TIMEOUT || result == JOB_DEPENDENCY) {
622 log_notice("Job %s/%s failed with result '%s'.",
624 job_type_to_string(t),
625 job_result_to_string(result));
627 unit_trigger_on_failure(u);
631 /* Try to start the next jobs that can be started */
632 SET_FOREACH(other, u->dependencies[UNIT_AFTER], i)
634 job_add_to_run_queue(other->job);
635 SET_FOREACH(other, u->dependencies[UNIT_BEFORE], i)
637 job_add_to_run_queue(other->job);
639 manager_check_finished(u->manager);
644 int job_start_timer(Job *j) {
645 struct itimerspec its;
646 struct epoll_event ev;
650 if (j->unit->job_timeout <= 0 ||
651 j->timer_watch.type == WATCH_JOB_TIMER)
654 assert(j->timer_watch.type == WATCH_INVALID);
656 if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) {
662 timespec_store(&its.it_value, j->unit->job_timeout);
664 if (timerfd_settime(fd, 0, &its, NULL) < 0) {
670 ev.data.ptr = &j->timer_watch;
673 if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
678 j->timer_watch.type = WATCH_JOB_TIMER;
679 j->timer_watch.fd = fd;
680 j->timer_watch.data.job = j;
686 close_nointr_nofail(fd);
691 void job_add_to_run_queue(Job *j) {
693 assert(j->installed);
698 LIST_PREPEND(Job, run_queue, j->manager->run_queue, j);
699 j->in_run_queue = true;
702 void job_add_to_dbus_queue(Job *j) {
704 assert(j->installed);
706 if (j->in_dbus_queue)
709 /* We don't check if anybody is subscribed here, since this
710 * job might just have been created and not yet assigned to a
711 * connection/client. */
713 LIST_PREPEND(Job, dbus_queue, j->manager->dbus_job_queue, j);
714 j->in_dbus_queue = true;
717 char *job_dbus_path(Job *j) {
722 if (asprintf(&p, "/org/freedesktop/systemd1/job/%lu", (unsigned long) j->id) < 0)
728 void job_timer_event(Job *j, uint64_t n_elapsed, Watch *w) {
730 assert(w == &j->timer_watch);
732 log_warning("Job %s/%s timed out.", j->unit->id, job_type_to_string(j->type));
733 job_finish_and_invalidate(j, JOB_TIMEOUT);
736 static const char* const job_state_table[_JOB_STATE_MAX] = {
737 [JOB_WAITING] = "waiting",
738 [JOB_RUNNING] = "running"
741 DEFINE_STRING_TABLE_LOOKUP(job_state, JobState);
743 static const char* const job_type_table[_JOB_TYPE_MAX] = {
744 [JOB_START] = "start",
745 [JOB_VERIFY_ACTIVE] = "verify-active",
747 [JOB_RELOAD] = "reload",
748 [JOB_RELOAD_OR_START] = "reload-or-start",
749 [JOB_RESTART] = "restart",
750 [JOB_TRY_RESTART] = "try-restart",
753 DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
755 static const char* const job_mode_table[_JOB_MODE_MAX] = {
757 [JOB_REPLACE] = "replace",
758 [JOB_ISOLATE] = "isolate",
759 [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
760 [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements"
763 DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);
765 static const char* const job_result_table[_JOB_RESULT_MAX] = {
767 [JOB_CANCELED] = "canceled",
768 [JOB_TIMEOUT] = "timeout",
769 [JOB_FAILED] = "failed",
770 [JOB_DEPENDENCY] = "dependency",
771 [JOB_SKIPPED] = "skipped"
774 DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);