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>
27 #include "systemd/sd-id128.h"
28 #include "systemd/sd-messages.h"
33 #include "load-fragment.h"
34 #include "load-dropin.h"
41 JobBusClient* job_bus_client_new(DBusConnection *connection, const char *name) {
45 name_len = strlen(name);
46 cl = malloc0(sizeof(JobBusClient) + name_len + 1);
51 memcpy(cl->name, name, name_len + 1);
55 Job* job_new_raw(Unit *unit) {
58 /* used for deserialization */
66 j->manager = unit->manager;
68 j->type = _JOB_TYPE_INVALID;
69 j->timer_watch.type = WATCH_INVALID;
74 Job* job_new(Unit *unit, JobType type) {
77 assert(type < _JOB_TYPE_MAX);
79 j = job_new_raw(unit);
83 j->id = j->manager->current_job_id++;
86 /* We don't link it here, that's what job_dependency() is for */
91 void job_free(Job *j) {
95 assert(!j->installed);
96 assert(!j->transaction_prev);
97 assert(!j->transaction_next);
98 assert(!j->subject_list);
99 assert(!j->object_list);
102 LIST_REMOVE(Job, run_queue, j->manager->run_queue, j);
104 if (j->in_dbus_queue)
105 LIST_REMOVE(Job, dbus_queue, j->manager->dbus_job_queue, j);
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);
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);
116 while ((cl = j->bus_client_list)) {
117 LIST_REMOVE(JobBusClient, client, j->bus_client_list, cl);
123 void job_uninstall(Job *j) {
126 assert(j->installed);
128 pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
131 /* Detach from next 'bigger' objects */
133 /* daemon-reload should be transparent to job observers */
134 if (j->manager->n_reloading <= 0)
135 bus_job_send_removed_signal(j);
139 unit_add_to_gc_queue(j->unit);
141 hashmap_remove(j->manager->jobs, UINT32_TO_PTR(j->id));
142 j->installed = false;
145 static bool job_type_allows_late_merge(JobType t) {
146 /* Tells whether it is OK to merge a job of type 't' with an already
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. */
159 return t != JOB_RELOAD;
162 static void job_merge_into_installed(Job *j, Job *other) {
163 assert(j->installed);
164 assert(j->unit == other->unit);
166 if (j->type != JOB_NOP)
167 job_type_merge_and_collapse(&j->type, other->type, j->unit);
169 assert(other->type == JOB_NOP);
171 j->override = j->override || other->override;
172 j->ignore_order = j->ignore_order || other->ignore_order;
175 Job* job_install(Job *j) {
179 assert(!j->installed);
180 assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
182 pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
186 if (j->type != JOB_NOP && job_type_is_conflicting(uj->type, j->type))
187 job_finish_and_invalidate(uj, JOB_CANCELED, false);
189 /* not conflicting, i.e. mergeable */
191 if (j->type == JOB_NOP || uj->state == JOB_WAITING ||
192 (job_type_allows_late_merge(j->type) && job_type_is_superset(uj->type, j->type))) {
193 job_merge_into_installed(uj, j);
194 log_debug_unit(uj->unit->id,
195 "Merged into installed job %s/%s as %u",
196 uj->unit->id, job_type_to_string(uj->type), (unsigned) uj->id);
199 /* already running and not safe to merge into */
200 /* Patch uj to become a merged job and re-run it. */
201 /* XXX It should be safer to queue j to run after uj finishes, but it is
202 * not currently possible to have more than one installed job per unit. */
203 job_merge_into_installed(uj, j);
204 log_debug_unit(uj->unit->id,
205 "Merged into running job, re-running: %s/%s as %u",
206 uj->unit->id, job_type_to_string(uj->type), (unsigned) uj->id);
207 uj->state = JOB_WAITING;
213 /* Install the job */
216 j->manager->n_installed_jobs ++;
217 log_debug_unit(j->unit->id,
218 "Installed new job %s/%s as %u",
219 j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
223 int job_install_deserialized(Job *j) {
226 assert(!j->installed);
228 if (j->type < 0 || j->type >= _JOB_TYPE_MAX_IN_TRANSACTION) {
229 log_debug("Invalid job type %s in deserialization.", strna(job_type_to_string(j->type)));
233 pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
236 log_debug_unit(j->unit->id,
237 "Unit %s already has a job installed. Not installing deserialized job.",
243 log_debug_unit(j->unit->id,
244 "Reinstalled deserialized job %s/%s as %u",
245 j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
249 JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts) {
254 /* Adds a new job link, which encodes that the 'subject' job
255 * needs the 'object' job in some way. If 'subject' is NULL
256 * this means the 'anchor' job (i.e. the one the user
257 * explicitly asked for) is the requester. */
259 if (!(l = new0(JobDependency, 1)))
262 l->subject = subject;
264 l->matters = matters;
265 l->conflicts = conflicts;
268 LIST_PREPEND(JobDependency, subject, subject->subject_list, l);
270 LIST_PREPEND(JobDependency, object, object->object_list, l);
275 void job_dependency_free(JobDependency *l) {
279 LIST_REMOVE(JobDependency, subject, l->subject->subject_list, l);
281 LIST_REMOVE(JobDependency, object, l->object->object_list, l);
286 void job_dump(Job *j, FILE*f, const char *prefix) {
295 "%s\tAction: %s -> %s\n"
299 prefix, j->unit->id, job_type_to_string(j->type),
300 prefix, job_state_to_string(j->state),
301 prefix, yes_no(j->override));
305 * Merging is commutative, so imagine the matrix as symmetric. We store only
306 * its lower triangle to avoid duplication. We don't store the main diagonal,
307 * because A merged with A is simply A.
309 * If the resulting type is collapsed immediately afterwards (to get rid of
310 * the JOB_RELOAD_OR_START, which lies outside the lookup function's domain),
311 * the following properties hold:
313 * Merging is associative! A merged with B merged with C is the same as
314 * A merged with C merged with B.
316 * Mergeability is transitive! If A can be merged with B and B with C then
319 * Also, if A merged with B cannot be merged with C, then either A or B cannot
320 * be merged with C either.
322 static const JobType job_merging_table[] = {
323 /* What \ With * JOB_START JOB_VERIFY_ACTIVE JOB_STOP JOB_RELOAD */
324 /*********************************************************************************/
326 /*JOB_VERIFY_ACTIVE */ JOB_START,
327 /*JOB_STOP */ -1, -1,
328 /*JOB_RELOAD */ JOB_RELOAD_OR_START, JOB_RELOAD, -1,
329 /*JOB_RESTART */ JOB_RESTART, JOB_RESTART, -1, JOB_RESTART,
332 JobType job_type_lookup_merge(JobType a, JobType b) {
333 assert_cc(ELEMENTSOF(job_merging_table) == _JOB_TYPE_MAX_MERGING * (_JOB_TYPE_MAX_MERGING - 1) / 2);
334 assert(a >= 0 && a < _JOB_TYPE_MAX_MERGING);
335 assert(b >= 0 && b < _JOB_TYPE_MAX_MERGING);
346 return job_merging_table[(a - 1) * a / 2 + b];
349 bool job_type_is_redundant(JobType a, UnitActiveState b) {
359 b == UNIT_INACTIVE ||
362 case JOB_VERIFY_ACTIVE:
373 b == UNIT_ACTIVATING;
376 assert_not_reached("Invalid job type");
380 void job_type_collapse(JobType *t, Unit *u) {
385 case JOB_TRY_RESTART:
386 s = unit_active_state(u);
387 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
393 case JOB_RELOAD_OR_START:
394 s = unit_active_state(u);
395 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
406 int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u) {
407 JobType t = job_type_lookup_merge(*a, b);
411 job_type_collapse(a, u);
415 bool job_is_runnable(Job *j) {
420 assert(j->installed);
422 /* Checks whether there is any job running for the units this
423 * job needs to be running after (in the case of a 'positive'
424 * job type) or before (in the case of a 'negative' job
427 /* First check if there is an override */
431 if (j->type == JOB_NOP)
434 if (j->type == JOB_START ||
435 j->type == JOB_VERIFY_ACTIVE ||
436 j->type == JOB_RELOAD) {
438 /* Immediate result is that the job is or might be
439 * started. In this case lets wait for the
440 * dependencies, regardless whether they are
441 * starting or stopping something. */
443 SET_FOREACH(other, j->unit->dependencies[UNIT_AFTER], i)
448 /* Also, if something else is being stopped and we should
449 * change state after it, then lets wait. */
451 SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i)
453 (other->job->type == JOB_STOP ||
454 other->job->type == JOB_RESTART))
457 /* This means that for a service a and a service b where b
458 * shall be started after a:
460 * start a + start b → 1st step start a, 2nd step start b
461 * start a + stop b → 1st step stop b, 2nd step start a
462 * stop a + start b → 1st step stop a, 2nd step start b
463 * stop a + stop b → 1st step stop b, 2nd step stop a
465 * This has the side effect that restarts are properly
466 * synchronized too. */
471 static void job_change_type(Job *j, JobType newtype) {
472 log_debug_unit(j->unit->id,
473 "Converting job %s/%s -> %s/%s",
474 j->unit->id, job_type_to_string(j->type),
475 j->unit->id, job_type_to_string(newtype));
480 int job_run_and_invalidate(Job *j) {
486 assert(j->installed);
487 assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
488 assert(j->in_run_queue);
490 LIST_REMOVE(Job, run_queue, j->manager->run_queue, j);
491 j->in_run_queue = false;
493 if (j->state != JOB_WAITING)
496 if (!job_is_runnable(j))
499 j->state = JOB_RUNNING;
500 job_add_to_dbus_queue(j);
502 /* While we execute this operation the job might go away (for
503 * example: because it is replaced by a new, conflicting
504 * job.) To make sure we don't access a freed job later on we
505 * store the id here, so that we can verify the job is still
513 r = unit_start(j->unit);
515 /* If this unit cannot be started, then simply wait */
520 case JOB_VERIFY_ACTIVE: {
521 UnitActiveState t = unit_active_state(j->unit);
522 if (UNIT_IS_ACTIVE_OR_RELOADING(t))
524 else if (t == UNIT_ACTIVATING)
533 r = unit_stop(j->unit);
535 /* If this unit cannot stopped, then simply wait. */
541 r = unit_reload(j->unit);
549 assert_not_reached("Unknown job type");
552 j = manager_get_job(m, id);
555 r = job_finish_and_invalidate(j, JOB_DONE, true);
556 else if (r == -ENOEXEC)
557 r = job_finish_and_invalidate(j, JOB_SKIPPED, true);
558 else if (r == -EAGAIN)
559 j->state = JOB_WAITING;
561 r = job_finish_and_invalidate(j, JOB_FAILED, true);
567 static const char *job_get_status_message_format(Unit *u, JobType t, JobResult result) {
568 const UnitStatusMessageFormats *format_table;
572 assert(t < _JOB_TYPE_MAX);
574 format_table = &UNIT_VTABLE(u)->status_message_formats;
579 return format_table->finished_start_job[result];
580 else if (t == JOB_STOP || t == JOB_RESTART)
581 return format_table->finished_stop_job[result];
586 static const char *job_get_status_message_format_try_harder(Unit *u, JobType t, JobResult result) {
591 assert(t < _JOB_TYPE_MAX);
593 format = job_get_status_message_format(u, t, result);
597 /* Return generic strings */
598 if (t == JOB_START) {
599 if (result == JOB_DONE)
600 return "Started %s.";
601 else if (result == JOB_FAILED)
602 return "Failed to start %s.";
603 else if (result == JOB_DEPENDENCY)
604 return "Dependency failed for %s.";
605 else if (result == JOB_TIMEOUT)
606 return "Timed out starting %s.";
607 } else if (t == JOB_STOP || t == JOB_RESTART) {
608 if (result == JOB_DONE)
609 return "Stopped %s.";
610 else if (result == JOB_FAILED)
611 return "Stopped (with error) %s.";
612 else if (result == JOB_TIMEOUT)
613 return "Timed out stoppping %s.";
614 } else if (t == JOB_RELOAD) {
615 if (result == JOB_DONE)
616 return "Reloaded %s.";
617 else if (result == JOB_FAILED)
618 return "Reload failed for %s.";
619 else if (result == JOB_TIMEOUT)
620 return "Timed out reloading %s.";
626 static void job_print_status_message(Unit *u, JobType t, JobResult result) {
631 assert(t < _JOB_TYPE_MAX);
633 if (t == JOB_START) {
634 format = job_get_status_message_format(u, t, result);
641 if (u->condition_result)
642 unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, format, unit_description(u));
646 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF, format, unit_description(u));
647 unit_status_printf(u, NULL, "See 'systemctl status %s' for details.", u->id);
651 unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "DEPEND" ANSI_HIGHLIGHT_OFF, format, unit_description(u));
655 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format, unit_description(u));
662 } else if (t == JOB_STOP || t == JOB_RESTART) {
664 format = job_get_status_message_format(u, t, result);
671 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format, unit_description(u));
676 unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, format, unit_description(u));
683 } else if (t == JOB_VERIFY_ACTIVE) {
685 /* When verify-active detects the unit is inactive, report it.
686 * Most likely a DEPEND warning from a requisiting unit will
687 * occur next and it's nice to see what was requisited. */
688 if (result == JOB_SKIPPED)
689 unit_status_printf(u, ANSI_HIGHLIGHT_ON " INFO " ANSI_HIGHLIGHT_OFF, "%s is not active.", unit_description(u));
693 #pragma GCC diagnostic push
694 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
695 static void job_log_status_message(Unit *u, JobType t, JobResult result) {
701 assert(t < _JOB_TYPE_MAX);
703 /* Skip this if it goes to the console. since we already print
704 * to the console anyway... */
706 if (log_on_console())
709 format = job_get_status_message_format_try_harder(u, t, result);
713 snprintf(buf, sizeof(buf), format, unit_description(u));
716 if (t == JOB_START) {
719 mid = result == JOB_DONE ? SD_MESSAGE_UNIT_STARTED : SD_MESSAGE_UNIT_FAILED;
720 log_struct_unit(result == JOB_DONE ? LOG_INFO : LOG_ERR,
723 "RESULT=%s", job_result_to_string(result),
727 } else if (t == JOB_STOP)
728 log_struct_unit(result == JOB_DONE ? LOG_INFO : LOG_ERR,
730 MESSAGE_ID(SD_MESSAGE_UNIT_STOPPED),
731 "RESULT=%s", job_result_to_string(result),
735 else if (t == JOB_RELOAD)
736 log_struct_unit(result == JOB_DONE ? LOG_INFO : LOG_ERR,
738 MESSAGE_ID(SD_MESSAGE_UNIT_RELOADED),
739 "RESULT=%s", job_result_to_string(result),
743 #pragma GCC diagnostic pop
745 int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) {
752 assert(j->installed);
753 assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
760 log_debug_unit(u->id, "Job %s/%s finished, result=%s",
761 u->id, job_type_to_string(t), job_result_to_string(result));
763 job_print_status_message(u, t, result);
764 job_log_status_message(u, t, result);
766 job_add_to_dbus_queue(j);
768 /* Patch restart jobs so that they become normal start jobs */
769 if (result == JOB_DONE && t == JOB_RESTART) {
771 job_change_type(j, JOB_START);
772 j->state = JOB_WAITING;
774 job_add_to_run_queue(j);
779 if (result == JOB_FAILED)
780 j->manager->n_failed_jobs ++;
785 /* Fail depending jobs on failure */
786 if (result != JOB_DONE && recursive) {
788 if (t == JOB_START ||
789 t == JOB_VERIFY_ACTIVE) {
791 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
793 (other->job->type == JOB_START ||
794 other->job->type == JOB_VERIFY_ACTIVE))
795 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
797 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
799 (other->job->type == JOB_START ||
800 other->job->type == JOB_VERIFY_ACTIVE))
801 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
803 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
805 !other->job->override &&
806 (other->job->type == JOB_START ||
807 other->job->type == JOB_VERIFY_ACTIVE))
808 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
810 } else if (t == JOB_STOP) {
812 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
814 (other->job->type == JOB_START ||
815 other->job->type == JOB_VERIFY_ACTIVE))
816 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
820 /* Trigger OnFailure dependencies that are not generated by
821 * the unit itself. We don't treat JOB_CANCELED as failure in
822 * this context. And JOB_FAILURE is already handled by the
824 if (result == JOB_TIMEOUT || result == JOB_DEPENDENCY) {
825 log_struct_unit(LOG_NOTICE,
827 "JOB_TYPE=%s", job_type_to_string(t),
828 "JOB_RESULT=%s", job_result_to_string(result),
829 "Job %s/%s failed with result '%s'.",
831 job_type_to_string(t),
832 job_result_to_string(result),
835 unit_trigger_on_failure(u);
839 /* Try to start the next jobs that can be started */
840 SET_FOREACH(other, u->dependencies[UNIT_AFTER], i)
842 job_add_to_run_queue(other->job);
843 SET_FOREACH(other, u->dependencies[UNIT_BEFORE], i)
845 job_add_to_run_queue(other->job);
847 manager_check_finished(u->manager);
852 int job_start_timer(Job *j) {
853 struct itimerspec its;
854 struct epoll_event ev;
858 if (j->unit->job_timeout <= 0 ||
859 j->timer_watch.type == WATCH_JOB_TIMER)
862 assert(j->timer_watch.type == WATCH_INVALID);
864 if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) {
870 timespec_store(&its.it_value, j->unit->job_timeout);
872 if (timerfd_settime(fd, 0, &its, NULL) < 0) {
878 ev.data.ptr = &j->timer_watch;
881 if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
886 j->timer_watch.type = WATCH_JOB_TIMER;
887 j->timer_watch.fd = fd;
888 j->timer_watch.data.job = j;
894 close_nointr_nofail(fd);
899 void job_add_to_run_queue(Job *j) {
901 assert(j->installed);
906 LIST_PREPEND(Job, run_queue, j->manager->run_queue, j);
907 j->in_run_queue = true;
910 void job_add_to_dbus_queue(Job *j) {
912 assert(j->installed);
914 if (j->in_dbus_queue)
917 /* We don't check if anybody is subscribed here, since this
918 * job might just have been created and not yet assigned to a
919 * connection/client. */
921 LIST_PREPEND(Job, dbus_queue, j->manager->dbus_job_queue, j);
922 j->in_dbus_queue = true;
925 char *job_dbus_path(Job *j) {
930 if (asprintf(&p, "/org/freedesktop/systemd1/job/%lu", (unsigned long) j->id) < 0)
936 void job_timer_event(Job *j, uint64_t n_elapsed, Watch *w) {
938 assert(w == &j->timer_watch);
940 log_warning_unit(j->unit->id, "Job %s/%s timed out.",
941 j->unit->id, job_type_to_string(j->type));
942 job_finish_and_invalidate(j, JOB_TIMEOUT, true);
945 int job_serialize(Job *j, FILE *f, FDSet *fds) {
946 fprintf(f, "job-id=%u\n", j->id);
947 fprintf(f, "job-type=%s\n", job_type_to_string(j->type));
948 fprintf(f, "job-state=%s\n", job_state_to_string(j->state));
949 fprintf(f, "job-override=%s\n", yes_no(j->override));
950 fprintf(f, "job-sent-dbus-new-signal=%s\n", yes_no(j->sent_dbus_new_signal));
951 fprintf(f, "job-ignore-order=%s\n", yes_no(j->ignore_order));
952 /* Cannot save bus clients. Just note the fact that we're losing
953 * them. job_send_message() will fallback to broadcasting. */
954 fprintf(f, "job-forgot-bus-clients=%s\n",
955 yes_no(j->forgot_bus_clients || j->bus_client_list));
956 if (j->timer_watch.type == WATCH_JOB_TIMER) {
957 int copy = fdset_put_dup(fds, j->timer_watch.fd);
960 fprintf(f, "job-timer-watch-fd=%d\n", copy);
968 int job_deserialize(Job *j, FILE *f, FDSet *fds) {
970 char line[LINE_MAX], *l, *v;
973 if (!fgets(line, sizeof(line), f)) {
994 if (streq(l, "job-id")) {
995 if (safe_atou32(v, &j->id) < 0)
996 log_debug("Failed to parse job id value %s", v);
997 } else if (streq(l, "job-type")) {
998 JobType t = job_type_from_string(v);
1000 log_debug("Failed to parse job type %s", v);
1001 else if (t >= _JOB_TYPE_MAX_IN_TRANSACTION)
1002 log_debug("Cannot deserialize job of type %s", v);
1005 } else if (streq(l, "job-state")) {
1006 JobState s = job_state_from_string(v);
1008 log_debug("Failed to parse job state %s", v);
1011 } else if (streq(l, "job-override")) {
1012 int b = parse_boolean(v);
1014 log_debug("Failed to parse job override flag %s", v);
1016 j->override = j->override || b;
1017 } else if (streq(l, "job-sent-dbus-new-signal")) {
1018 int b = parse_boolean(v);
1020 log_debug("Failed to parse job sent_dbus_new_signal flag %s", v);
1022 j->sent_dbus_new_signal = j->sent_dbus_new_signal || b;
1023 } else if (streq(l, "job-ignore-order")) {
1024 int b = parse_boolean(v);
1026 log_debug("Failed to parse job ignore_order flag %s", v);
1028 j->ignore_order = j->ignore_order || b;
1029 } else if (streq(l, "job-forgot-bus-clients")) {
1030 int b = parse_boolean(v);
1032 log_debug("Failed to parse job forgot_bus_clients flag %s", v);
1034 j->forgot_bus_clients = j->forgot_bus_clients || b;
1035 } else if (streq(l, "job-timer-watch-fd")) {
1037 if (safe_atoi(v, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
1038 log_debug("Failed to parse job-timer-watch-fd value %s", v);
1040 if (j->timer_watch.type == WATCH_JOB_TIMER)
1041 close_nointr_nofail(j->timer_watch.fd);
1043 j->timer_watch.type = WATCH_JOB_TIMER;
1044 j->timer_watch.fd = fdset_remove(fds, fd);
1045 j->timer_watch.data.job = j;
1051 int job_coldplug(Job *j) {
1052 struct epoll_event ev;
1054 if (j->timer_watch.type != WATCH_JOB_TIMER)
1058 ev.data.ptr = &j->timer_watch;
1059 ev.events = EPOLLIN;
1061 if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, j->timer_watch.fd, &ev) < 0)
1067 void job_shutdown_magic(Job *j) {
1070 /* The shutdown target gets some special treatment here: we
1071 * tell the kernel to begin with flushing its disk caches, to
1072 * optimize shutdown time a bit. Ideally we wouldn't hardcode
1073 * this magic into PID 1. However all other processes aren't
1074 * options either since they'd exit much sooner than PID 1 and
1075 * asynchronous sync() would cause their exit to be
1078 if (!unit_has_name(j->unit, SPECIAL_SHUTDOWN_TARGET))
1081 if (j->type != JOB_START)
1084 if (detect_container(NULL) > 0)
1087 asynchronous_sync();
1090 static const char* const job_state_table[_JOB_STATE_MAX] = {
1091 [JOB_WAITING] = "waiting",
1092 [JOB_RUNNING] = "running"
1095 DEFINE_STRING_TABLE_LOOKUP(job_state, JobState);
1097 static const char* const job_type_table[_JOB_TYPE_MAX] = {
1098 [JOB_START] = "start",
1099 [JOB_VERIFY_ACTIVE] = "verify-active",
1100 [JOB_STOP] = "stop",
1101 [JOB_RELOAD] = "reload",
1102 [JOB_RELOAD_OR_START] = "reload-or-start",
1103 [JOB_RESTART] = "restart",
1104 [JOB_TRY_RESTART] = "try-restart",
1108 DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
1110 static const char* const job_mode_table[_JOB_MODE_MAX] = {
1111 [JOB_FAIL] = "fail",
1112 [JOB_REPLACE] = "replace",
1113 [JOB_ISOLATE] = "isolate",
1114 [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
1115 [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements"
1118 DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);
1120 static const char* const job_result_table[_JOB_RESULT_MAX] = {
1121 [JOB_DONE] = "done",
1122 [JOB_CANCELED] = "canceled",
1123 [JOB_TIMEOUT] = "timeout",
1124 [JOB_FAILED] = "failed",
1125 [JOB_DEPENDENCY] = "dependency",
1126 [JOB_SKIPPED] = "skipped"
1129 DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);