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_raw(Unit *unit) {
53 /* used for deserialization */
61 j->manager = unit->manager;
63 j->type = _JOB_TYPE_INVALID;
64 j->timer_watch.type = WATCH_INVALID;
69 Job* job_new(Unit *unit, JobType type) {
72 assert(type < _JOB_TYPE_MAX);
74 j = job_new_raw(unit);
78 j->id = j->manager->current_job_id++;
81 /* We don't link it here, that's what job_dependency() is for */
86 void job_free(Job *j) {
90 assert(!j->installed);
91 assert(!j->transaction_prev);
92 assert(!j->transaction_next);
93 assert(!j->subject_list);
94 assert(!j->object_list);
97 LIST_REMOVE(Job, run_queue, j->manager->run_queue, j);
100 LIST_REMOVE(Job, dbus_queue, j->manager->dbus_job_queue, j);
102 if (j->timer_watch.type != WATCH_INVALID) {
103 assert(j->timer_watch.type == WATCH_JOB_TIMER);
104 assert(j->timer_watch.data.job == j);
105 assert(j->timer_watch.fd >= 0);
107 assert_se(epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_DEL, j->timer_watch.fd, NULL) >= 0);
108 close_nointr_nofail(j->timer_watch.fd);
111 while ((cl = j->bus_client_list)) {
112 LIST_REMOVE(JobBusClient, client, j->bus_client_list, cl);
118 void job_uninstall(Job *j) {
121 assert(j->installed);
123 pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
126 /* Detach from next 'bigger' objects */
128 /* daemon-reload should be transparent to job observers */
129 if (j->manager->n_reloading <= 0)
130 bus_job_send_removed_signal(j);
134 unit_add_to_gc_queue(j->unit);
136 hashmap_remove(j->manager->jobs, UINT32_TO_PTR(j->id));
137 j->installed = false;
140 static bool job_type_allows_late_merge(JobType t) {
141 /* Tells whether it is OK to merge a job of type 't' with an already
143 * Reloads cannot be merged this way. Think of the sequence:
144 * 1. Reload of a daemon is in progress; the daemon has already loaded
145 * its config file, but hasn't completed the reload operation yet.
146 * 2. Edit foo's config file.
147 * 3. Trigger another reload to have the daemon use the new config.
148 * Should the second reload job be merged into the first one, the daemon
149 * would not know about the new config.
150 * JOB_RESTART jobs on the other hand can be merged, because they get
151 * patched into JOB_START after stopping the unit. So if we see a
152 * JOB_RESTART running, it means the unit hasn't stopped yet and at
153 * this time the merge is still allowed. */
154 return t != JOB_RELOAD;
157 static void job_merge_into_installed(Job *j, Job *other) {
158 assert(j->installed);
159 assert(j->unit == other->unit);
161 if (j->type != JOB_NOP)
162 job_type_merge_and_collapse(&j->type, other->type, j->unit);
164 assert(other->type == JOB_NOP);
166 j->override = j->override || other->override;
169 Job* job_install(Job *j) {
173 assert(!j->installed);
174 assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
176 pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
180 if (j->type != JOB_NOP && job_type_is_conflicting(uj->type, j->type))
181 job_finish_and_invalidate(uj, JOB_CANCELED, true);
183 /* not conflicting, i.e. mergeable */
185 if (j->type == JOB_NOP || uj->state == JOB_WAITING ||
186 (job_type_allows_late_merge(j->type) && job_type_is_superset(uj->type, j->type))) {
187 job_merge_into_installed(uj, j);
188 log_debug("Merged into installed job %s/%s as %u",
189 uj->unit->id, job_type_to_string(uj->type), (unsigned) uj->id);
192 /* already running and not safe to merge into */
193 /* Patch uj to become a merged job and re-run it. */
194 /* XXX It should be safer to queue j to run after uj finishes, but it is
195 * not currently possible to have more than one installed job per unit. */
196 job_merge_into_installed(uj, j);
197 log_debug("Merged into running job, re-running: %s/%s as %u",
198 uj->unit->id, job_type_to_string(uj->type), (unsigned) uj->id);
199 uj->state = JOB_WAITING;
205 /* Install the job */
208 j->manager->n_installed_jobs ++;
209 log_debug("Installed new job %s/%s as %u", j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
213 int job_install_deserialized(Job *j) {
216 assert(!j->installed);
218 if (j->type < 0 || j->type >= _JOB_TYPE_MAX_IN_TRANSACTION) {
219 log_debug("Invalid job type %s in deserialization.", strna(job_type_to_string(j->type)));
223 pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
226 log_debug("Unit %s already has a job installed. Not installing deserialized job.", j->unit->id);
231 log_debug("Reinstalled deserialized job %s/%s as %u", j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
235 JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts) {
240 /* Adds a new job link, which encodes that the 'subject' job
241 * needs the 'object' job in some way. If 'subject' is NULL
242 * this means the 'anchor' job (i.e. the one the user
243 * explicitly asked for) is the requester. */
245 if (!(l = new0(JobDependency, 1)))
248 l->subject = subject;
250 l->matters = matters;
251 l->conflicts = conflicts;
254 LIST_PREPEND(JobDependency, subject, subject->subject_list, l);
256 LIST_PREPEND(JobDependency, object, object->object_list, l);
261 void job_dependency_free(JobDependency *l) {
265 LIST_REMOVE(JobDependency, subject, l->subject->subject_list, l);
267 LIST_REMOVE(JobDependency, object, l->object->object_list, l);
272 void job_dump(Job *j, FILE*f, const char *prefix) {
281 "%s\tAction: %s -> %s\n"
285 prefix, j->unit->id, job_type_to_string(j->type),
286 prefix, job_state_to_string(j->state),
287 prefix, yes_no(j->override));
291 * Merging is commutative, so imagine the matrix as symmetric. We store only
292 * its lower triangle to avoid duplication. We don't store the main diagonal,
293 * because A merged with A is simply A.
295 * If the resulting type is collapsed immediately afterwards (to get rid of
296 * the JOB_RELOAD_OR_START, which lies outside the lookup function's domain),
297 * the following properties hold:
299 * Merging is associative! A merged with B merged with C is the same as
300 * A merged with C merged with B.
302 * Mergeability is transitive! If A can be merged with B and B with C then
305 * Also, if A merged with B cannot be merged with C, then either A or B cannot
306 * be merged with C either.
308 static const JobType job_merging_table[] = {
309 /* What \ With * JOB_START JOB_VERIFY_ACTIVE JOB_STOP JOB_RELOAD */
310 /*********************************************************************************/
312 /*JOB_VERIFY_ACTIVE */ JOB_START,
313 /*JOB_STOP */ -1, -1,
314 /*JOB_RELOAD */ JOB_RELOAD_OR_START, JOB_RELOAD, -1,
315 /*JOB_RESTART */ JOB_RESTART, JOB_RESTART, -1, JOB_RESTART,
318 JobType job_type_lookup_merge(JobType a, JobType b) {
319 assert_cc(ELEMENTSOF(job_merging_table) == _JOB_TYPE_MAX_MERGING * (_JOB_TYPE_MAX_MERGING - 1) / 2);
320 assert(a >= 0 && a < _JOB_TYPE_MAX_MERGING);
321 assert(b >= 0 && b < _JOB_TYPE_MAX_MERGING);
332 return job_merging_table[(a - 1) * a / 2 + b];
335 bool job_type_is_redundant(JobType a, UnitActiveState b) {
345 b == UNIT_INACTIVE ||
348 case JOB_VERIFY_ACTIVE:
359 b == UNIT_ACTIVATING;
362 assert_not_reached("Invalid job type");
366 void job_type_collapse(JobType *t, Unit *u) {
371 case JOB_TRY_RESTART:
372 s = unit_active_state(u);
373 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
379 case JOB_RELOAD_OR_START:
380 s = unit_active_state(u);
381 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
392 int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u) {
393 JobType t = job_type_lookup_merge(*a, b);
397 job_type_collapse(a, u);
401 bool job_is_runnable(Job *j) {
406 assert(j->installed);
408 /* Checks whether there is any job running for the units this
409 * job needs to be running after (in the case of a 'positive'
410 * job type) or before (in the case of a 'negative' job
413 /* First check if there is an override */
417 if (j->type == JOB_NOP)
420 if (j->type == JOB_START ||
421 j->type == JOB_VERIFY_ACTIVE ||
422 j->type == JOB_RELOAD) {
424 /* Immediate result is that the job is or might be
425 * started. In this case lets wait for the
426 * dependencies, regardless whether they are
427 * starting or stopping something. */
429 SET_FOREACH(other, j->unit->dependencies[UNIT_AFTER], i)
434 /* Also, if something else is being stopped and we should
435 * change state after it, then lets wait. */
437 SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i)
439 (other->job->type == JOB_STOP ||
440 other->job->type == JOB_RESTART))
443 /* This means that for a service a and a service b where b
444 * shall be started after a:
446 * start a + start b → 1st step start a, 2nd step start b
447 * start a + stop b → 1st step stop b, 2nd step start a
448 * stop a + start b → 1st step stop a, 2nd step start b
449 * stop a + stop b → 1st step stop b, 2nd step stop a
451 * This has the side effect that restarts are properly
452 * synchronized too. */
457 static void job_change_type(Job *j, JobType newtype) {
458 log_debug("Converting job %s/%s -> %s/%s",
459 j->unit->id, job_type_to_string(j->type),
460 j->unit->id, job_type_to_string(newtype));
465 int job_run_and_invalidate(Job *j) {
471 assert(j->installed);
472 assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
473 assert(j->in_run_queue);
475 LIST_REMOVE(Job, run_queue, j->manager->run_queue, j);
476 j->in_run_queue = false;
478 if (j->state != JOB_WAITING)
481 if (!job_is_runnable(j))
484 j->state = JOB_RUNNING;
485 job_add_to_dbus_queue(j);
487 /* While we execute this operation the job might go away (for
488 * example: because it is replaced by a new, conflicting
489 * job.) To make sure we don't access a freed job later on we
490 * store the id here, so that we can verify the job is still
498 r = unit_start(j->unit);
500 /* If this unit cannot be started, then simply wait */
505 case JOB_VERIFY_ACTIVE: {
506 UnitActiveState t = unit_active_state(j->unit);
507 if (UNIT_IS_ACTIVE_OR_RELOADING(t))
509 else if (t == UNIT_ACTIVATING)
518 r = unit_stop(j->unit);
520 /* If this unit cannot stopped, then simply wait. */
526 r = unit_reload(j->unit);
534 assert_not_reached("Unknown job type");
537 j = manager_get_job(m, id);
540 r = job_finish_and_invalidate(j, JOB_DONE, true);
541 else if (r == -ENOEXEC)
542 r = job_finish_and_invalidate(j, JOB_SKIPPED, true);
543 else if (r == -EAGAIN)
544 j->state = JOB_WAITING;
546 r = job_finish_and_invalidate(j, JOB_FAILED, true);
552 static void job_print_status_message(Unit *u, JobType t, JobResult result) {
553 const UnitStatusMessageFormats *format_table;
556 format_table = &UNIT_VTABLE(u)->status_message_formats;
560 if (t == JOB_START) {
562 format = format_table->finished_start_job[result];
569 if (u->condition_result)
570 unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, format, unit_description(u));
574 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF, format, unit_description(u));
575 unit_status_printf(u, "", "See 'systemctl status %s' for details.", u->id);
579 unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "DEPEND" ANSI_HIGHLIGHT_OFF, format, unit_description(u));
583 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format, unit_description(u));
590 } else if (t == JOB_STOP || t == JOB_RESTART) {
592 format = format_table->finished_stop_job[result];
599 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format, unit_description(u));
604 unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, format, unit_description(u));
611 } else if (t == JOB_VERIFY_ACTIVE) {
613 /* When verify-active detects the unit is inactive, report it.
614 * Most likely a DEPEND warning from a requisiting unit will
615 * occur next and it's nice to see what was requisited. */
616 if (result == JOB_SKIPPED)
617 unit_status_printf(u, ANSI_HIGHLIGHT_ON " INFO " ANSI_HIGHLIGHT_OFF, "%s is not active.", unit_description(u));
621 int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) {
628 assert(j->installed);
629 assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
636 log_debug("Job %s/%s finished, result=%s", u->id, job_type_to_string(t), job_result_to_string(result));
638 job_print_status_message(u, t, result);
640 job_add_to_dbus_queue(j);
642 /* Patch restart jobs so that they become normal start jobs */
643 if (result == JOB_DONE && t == JOB_RESTART) {
645 job_change_type(j, JOB_START);
646 j->state = JOB_WAITING;
648 job_add_to_run_queue(j);
653 if (result == JOB_FAILED)
654 j->manager->n_failed_jobs ++;
659 /* Fail depending jobs on failure */
660 if (result != JOB_DONE && recursive) {
662 if (t == JOB_START ||
663 t == JOB_VERIFY_ACTIVE) {
665 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
667 (other->job->type == JOB_START ||
668 other->job->type == JOB_VERIFY_ACTIVE))
669 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
671 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
673 (other->job->type == JOB_START ||
674 other->job->type == JOB_VERIFY_ACTIVE))
675 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
677 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
679 !other->job->override &&
680 (other->job->type == JOB_START ||
681 other->job->type == JOB_VERIFY_ACTIVE))
682 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
684 } else if (t == JOB_STOP) {
686 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
688 (other->job->type == JOB_START ||
689 other->job->type == JOB_VERIFY_ACTIVE))
690 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
694 /* Trigger OnFailure dependencies that are not generated by
695 * the unit itself. We don't tread JOB_CANCELED as failure in
696 * this context. And JOB_FAILURE is already handled by the
698 if (result == JOB_TIMEOUT || result == JOB_DEPENDENCY) {
699 log_notice("Job %s/%s failed with result '%s'.",
701 job_type_to_string(t),
702 job_result_to_string(result));
704 unit_trigger_on_failure(u);
708 /* Try to start the next jobs that can be started */
709 SET_FOREACH(other, u->dependencies[UNIT_AFTER], i)
711 job_add_to_run_queue(other->job);
712 SET_FOREACH(other, u->dependencies[UNIT_BEFORE], i)
714 job_add_to_run_queue(other->job);
716 manager_check_finished(u->manager);
721 int job_start_timer(Job *j) {
722 struct itimerspec its;
723 struct epoll_event ev;
727 if (j->unit->job_timeout <= 0 ||
728 j->timer_watch.type == WATCH_JOB_TIMER)
731 assert(j->timer_watch.type == WATCH_INVALID);
733 if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) {
739 timespec_store(&its.it_value, j->unit->job_timeout);
741 if (timerfd_settime(fd, 0, &its, NULL) < 0) {
747 ev.data.ptr = &j->timer_watch;
750 if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
755 j->timer_watch.type = WATCH_JOB_TIMER;
756 j->timer_watch.fd = fd;
757 j->timer_watch.data.job = j;
763 close_nointr_nofail(fd);
768 void job_add_to_run_queue(Job *j) {
770 assert(j->installed);
775 LIST_PREPEND(Job, run_queue, j->manager->run_queue, j);
776 j->in_run_queue = true;
779 void job_add_to_dbus_queue(Job *j) {
781 assert(j->installed);
783 if (j->in_dbus_queue)
786 /* We don't check if anybody is subscribed here, since this
787 * job might just have been created and not yet assigned to a
788 * connection/client. */
790 LIST_PREPEND(Job, dbus_queue, j->manager->dbus_job_queue, j);
791 j->in_dbus_queue = true;
794 char *job_dbus_path(Job *j) {
799 if (asprintf(&p, "/org/freedesktop/systemd1/job/%lu", (unsigned long) j->id) < 0)
805 void job_timer_event(Job *j, uint64_t n_elapsed, Watch *w) {
807 assert(w == &j->timer_watch);
809 log_warning("Job %s/%s timed out.", j->unit->id, job_type_to_string(j->type));
810 job_finish_and_invalidate(j, JOB_TIMEOUT, true);
813 int job_serialize(Job *j, FILE *f, FDSet *fds) {
814 fprintf(f, "job-id=%u\n", j->id);
815 fprintf(f, "job-type=%s\n", job_type_to_string(j->type));
816 fprintf(f, "job-state=%s\n", job_state_to_string(j->state));
817 fprintf(f, "job-override=%s\n", yes_no(j->override));
818 fprintf(f, "job-sent-dbus-new-signal=%s\n", yes_no(j->sent_dbus_new_signal));
819 fprintf(f, "job-ignore-order=%s\n", yes_no(j->ignore_order));
820 /* Cannot save bus clients. Just note the fact that we're losing
821 * them. job_send_message() will fallback to broadcasting. */
822 fprintf(f, "job-forgot-bus-clients=%s\n",
823 yes_no(j->forgot_bus_clients || j->bus_client_list));
824 if (j->timer_watch.type == WATCH_JOB_TIMER) {
825 int copy = fdset_put_dup(fds, j->timer_watch.fd);
828 fprintf(f, "job-timer-watch-fd=%d\n", copy);
836 int job_deserialize(Job *j, FILE *f, FDSet *fds) {
838 char line[LINE_MAX], *l, *v;
841 if (!fgets(line, sizeof(line), f)) {
862 if (streq(l, "job-id")) {
863 if (safe_atou32(v, &j->id) < 0)
864 log_debug("Failed to parse job id value %s", v);
865 } else if (streq(l, "job-type")) {
866 JobType t = job_type_from_string(v);
868 log_debug("Failed to parse job type %s", v);
869 else if (t >= _JOB_TYPE_MAX_IN_TRANSACTION)
870 log_debug("Cannot deserialize job of type %s", v);
873 } else if (streq(l, "job-state")) {
874 JobState s = job_state_from_string(v);
876 log_debug("Failed to parse job state %s", v);
879 } else if (streq(l, "job-override")) {
880 int b = parse_boolean(v);
882 log_debug("Failed to parse job override flag %s", v);
884 j->override = j->override || b;
885 } else if (streq(l, "job-sent-dbus-new-signal")) {
886 int b = parse_boolean(v);
888 log_debug("Failed to parse job sent_dbus_new_signal flag %s", v);
890 j->sent_dbus_new_signal = j->sent_dbus_new_signal || b;
891 } else if (streq(l, "job-ignore-order")) {
892 int b = parse_boolean(v);
894 log_debug("Failed to parse job ignore_order flag %s", v);
896 j->ignore_order = j->ignore_order || b;
897 } else if (streq(l, "job-forgot-bus-clients")) {
898 int b = parse_boolean(v);
900 log_debug("Failed to parse job forgot_bus_clients flag %s", v);
902 j->forgot_bus_clients = j->forgot_bus_clients || b;
903 } else if (streq(l, "job-timer-watch-fd")) {
905 if (safe_atoi(v, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
906 log_debug("Failed to parse job-timer-watch-fd value %s", v);
908 if (j->timer_watch.type == WATCH_JOB_TIMER)
909 close_nointr_nofail(j->timer_watch.fd);
911 j->timer_watch.type = WATCH_JOB_TIMER;
912 j->timer_watch.fd = fdset_remove(fds, fd);
913 j->timer_watch.data.job = j;
919 int job_coldplug(Job *j) {
920 struct epoll_event ev;
922 if (j->timer_watch.type != WATCH_JOB_TIMER)
926 ev.data.ptr = &j->timer_watch;
929 if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, j->timer_watch.fd, &ev) < 0)
935 static const char* const job_state_table[_JOB_STATE_MAX] = {
936 [JOB_WAITING] = "waiting",
937 [JOB_RUNNING] = "running"
940 DEFINE_STRING_TABLE_LOOKUP(job_state, JobState);
942 static const char* const job_type_table[_JOB_TYPE_MAX] = {
943 [JOB_START] = "start",
944 [JOB_VERIFY_ACTIVE] = "verify-active",
946 [JOB_RELOAD] = "reload",
947 [JOB_RELOAD_OR_START] = "reload-or-start",
948 [JOB_RESTART] = "restart",
949 [JOB_TRY_RESTART] = "try-restart",
953 DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
955 static const char* const job_mode_table[_JOB_MODE_MAX] = {
957 [JOB_REPLACE] = "replace",
958 [JOB_ISOLATE] = "isolate",
959 [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
960 [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements"
963 DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);
965 static const char* const job_result_table[_JOB_RESULT_MAX] = {
967 [JOB_CANCELED] = "canceled",
968 [JOB_TIMEOUT] = "timeout",
969 [JOB_FAILED] = "failed",
970 [JOB_DEPENDENCY] = "dependency",
971 [JOB_SKIPPED] = "skipped"
974 DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);