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->irreversible = j->irreversible || other->irreversible;
173 j->ignore_order = j->ignore_order || other->ignore_order;
176 Job* job_install(Job *j) {
180 assert(!j->installed);
181 assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
183 pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
187 if (j->type != JOB_NOP && job_type_is_conflicting(uj->type, j->type))
188 job_finish_and_invalidate(uj, JOB_CANCELED, false);
190 /* not conflicting, i.e. mergeable */
192 if (j->type == JOB_NOP || uj->state == JOB_WAITING ||
193 (job_type_allows_late_merge(j->type) && job_type_is_superset(uj->type, j->type))) {
194 job_merge_into_installed(uj, j);
195 log_debug_unit(uj->unit->id,
196 "Merged into installed job %s/%s as %u",
197 uj->unit->id, job_type_to_string(uj->type), (unsigned) uj->id);
200 /* already running and not safe to merge into */
201 /* Patch uj to become a merged job and re-run it. */
202 /* XXX It should be safer to queue j to run after uj finishes, but it is
203 * not currently possible to have more than one installed job per unit. */
204 job_merge_into_installed(uj, j);
205 log_debug_unit(uj->unit->id,
206 "Merged into running job, re-running: %s/%s as %u",
207 uj->unit->id, job_type_to_string(uj->type), (unsigned) uj->id);
208 uj->state = JOB_WAITING;
214 /* Install the job */
217 j->manager->n_installed_jobs ++;
218 log_debug_unit(j->unit->id,
219 "Installed new job %s/%s as %u",
220 j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
224 int job_install_deserialized(Job *j) {
227 assert(!j->installed);
229 if (j->type < 0 || j->type >= _JOB_TYPE_MAX_IN_TRANSACTION) {
230 log_debug("Invalid job type %s in deserialization.", strna(job_type_to_string(j->type)));
234 pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
237 log_debug_unit(j->unit->id,
238 "Unit %s already has a job installed. Not installing deserialized job.",
244 log_debug_unit(j->unit->id,
245 "Reinstalled deserialized job %s/%s as %u",
246 j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
250 JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts) {
255 /* Adds a new job link, which encodes that the 'subject' job
256 * needs the 'object' job in some way. If 'subject' is NULL
257 * this means the 'anchor' job (i.e. the one the user
258 * explicitly asked for) is the requester. */
260 if (!(l = new0(JobDependency, 1)))
263 l->subject = subject;
265 l->matters = matters;
266 l->conflicts = conflicts;
269 LIST_PREPEND(JobDependency, subject, subject->subject_list, l);
271 LIST_PREPEND(JobDependency, object, object->object_list, l);
276 void job_dependency_free(JobDependency *l) {
280 LIST_REMOVE(JobDependency, subject, l->subject->subject_list, l);
282 LIST_REMOVE(JobDependency, object, l->object->object_list, l);
287 void job_dump(Job *j, FILE*f, const char *prefix) {
296 "%s\tAction: %s -> %s\n"
299 "%s\tIrreversible: %s\n",
301 prefix, j->unit->id, job_type_to_string(j->type),
302 prefix, job_state_to_string(j->state),
303 prefix, yes_no(j->override),
304 prefix, yes_no(j->irreversible));
308 * Merging is commutative, so imagine the matrix as symmetric. We store only
309 * its lower triangle to avoid duplication. We don't store the main diagonal,
310 * because A merged with A is simply A.
312 * If the resulting type is collapsed immediately afterwards (to get rid of
313 * the JOB_RELOAD_OR_START, which lies outside the lookup function's domain),
314 * the following properties hold:
316 * Merging is associative! A merged with B merged with C is the same as
317 * A merged with C merged with B.
319 * Mergeability is transitive! If A can be merged with B and B with C then
322 * Also, if A merged with B cannot be merged with C, then either A or B cannot
323 * be merged with C either.
325 static const JobType job_merging_table[] = {
326 /* What \ With * JOB_START JOB_VERIFY_ACTIVE JOB_STOP JOB_RELOAD */
327 /*********************************************************************************/
329 /*JOB_VERIFY_ACTIVE */ JOB_START,
330 /*JOB_STOP */ -1, -1,
331 /*JOB_RELOAD */ JOB_RELOAD_OR_START, JOB_RELOAD, -1,
332 /*JOB_RESTART */ JOB_RESTART, JOB_RESTART, -1, JOB_RESTART,
335 JobType job_type_lookup_merge(JobType a, JobType b) {
336 assert_cc(ELEMENTSOF(job_merging_table) == _JOB_TYPE_MAX_MERGING * (_JOB_TYPE_MAX_MERGING - 1) / 2);
337 assert(a >= 0 && a < _JOB_TYPE_MAX_MERGING);
338 assert(b >= 0 && b < _JOB_TYPE_MAX_MERGING);
349 return job_merging_table[(a - 1) * a / 2 + b];
352 bool job_type_is_redundant(JobType a, UnitActiveState b) {
362 b == UNIT_INACTIVE ||
365 case JOB_VERIFY_ACTIVE:
376 b == UNIT_ACTIVATING;
379 assert_not_reached("Invalid job type");
383 void job_type_collapse(JobType *t, Unit *u) {
388 case JOB_TRY_RESTART:
389 s = unit_active_state(u);
390 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
396 case JOB_RELOAD_OR_START:
397 s = unit_active_state(u);
398 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
409 int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u) {
410 JobType t = job_type_lookup_merge(*a, b);
414 job_type_collapse(a, u);
418 bool job_is_runnable(Job *j) {
423 assert(j->installed);
425 /* Checks whether there is any job running for the units this
426 * job needs to be running after (in the case of a 'positive'
427 * job type) or before (in the case of a 'negative' job
430 /* First check if there is an override */
434 if (j->type == JOB_NOP)
437 if (j->type == JOB_START ||
438 j->type == JOB_VERIFY_ACTIVE ||
439 j->type == JOB_RELOAD) {
441 /* Immediate result is that the job is or might be
442 * started. In this case lets wait for the
443 * dependencies, regardless whether they are
444 * starting or stopping something. */
446 SET_FOREACH(other, j->unit->dependencies[UNIT_AFTER], i)
451 /* Also, if something else is being stopped and we should
452 * change state after it, then lets wait. */
454 SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i)
456 (other->job->type == JOB_STOP ||
457 other->job->type == JOB_RESTART))
460 /* This means that for a service a and a service b where b
461 * shall be started after a:
463 * start a + start b → 1st step start a, 2nd step start b
464 * start a + stop b → 1st step stop b, 2nd step start a
465 * stop a + start b → 1st step stop a, 2nd step start b
466 * stop a + stop b → 1st step stop b, 2nd step stop a
468 * This has the side effect that restarts are properly
469 * synchronized too. */
474 static void job_change_type(Job *j, JobType newtype) {
475 log_debug_unit(j->unit->id,
476 "Converting job %s/%s -> %s/%s",
477 j->unit->id, job_type_to_string(j->type),
478 j->unit->id, job_type_to_string(newtype));
483 int job_run_and_invalidate(Job *j) {
489 assert(j->installed);
490 assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
491 assert(j->in_run_queue);
493 LIST_REMOVE(Job, run_queue, j->manager->run_queue, j);
494 j->in_run_queue = false;
496 if (j->state != JOB_WAITING)
499 if (!job_is_runnable(j))
502 j->state = JOB_RUNNING;
503 job_add_to_dbus_queue(j);
505 /* While we execute this operation the job might go away (for
506 * example: because it is replaced by a new, conflicting
507 * job.) To make sure we don't access a freed job later on we
508 * store the id here, so that we can verify the job is still
516 r = unit_start(j->unit);
518 /* If this unit cannot be started, then simply wait */
523 case JOB_VERIFY_ACTIVE: {
524 UnitActiveState t = unit_active_state(j->unit);
525 if (UNIT_IS_ACTIVE_OR_RELOADING(t))
527 else if (t == UNIT_ACTIVATING)
536 r = unit_stop(j->unit);
538 /* If this unit cannot stopped, then simply wait. */
544 r = unit_reload(j->unit);
552 assert_not_reached("Unknown job type");
555 j = manager_get_job(m, id);
558 r = job_finish_and_invalidate(j, JOB_DONE, true);
559 else if (r == -ENOEXEC)
560 r = job_finish_and_invalidate(j, JOB_SKIPPED, true);
561 else if (r == -EAGAIN)
562 j->state = JOB_WAITING;
564 r = job_finish_and_invalidate(j, JOB_FAILED, true);
570 static const char *job_get_status_message_format(Unit *u, JobType t, JobResult result) {
571 const UnitStatusMessageFormats *format_table;
575 assert(t < _JOB_TYPE_MAX);
577 format_table = &UNIT_VTABLE(u)->status_message_formats;
582 return format_table->finished_start_job[result];
583 else if (t == JOB_STOP || t == JOB_RESTART)
584 return format_table->finished_stop_job[result];
589 static const char *job_get_status_message_format_try_harder(Unit *u, JobType t, JobResult result) {
594 assert(t < _JOB_TYPE_MAX);
596 format = job_get_status_message_format(u, t, result);
600 /* Return generic strings */
601 if (t == JOB_START) {
602 if (result == JOB_DONE)
603 return "Started %s.";
604 else if (result == JOB_FAILED)
605 return "Failed to start %s.";
606 else if (result == JOB_DEPENDENCY)
607 return "Dependency failed for %s.";
608 else if (result == JOB_TIMEOUT)
609 return "Timed out starting %s.";
610 } else if (t == JOB_STOP || t == JOB_RESTART) {
611 if (result == JOB_DONE)
612 return "Stopped %s.";
613 else if (result == JOB_FAILED)
614 return "Stopped (with error) %s.";
615 else if (result == JOB_TIMEOUT)
616 return "Timed out stoppping %s.";
617 } else if (t == JOB_RELOAD) {
618 if (result == JOB_DONE)
619 return "Reloaded %s.";
620 else if (result == JOB_FAILED)
621 return "Reload failed for %s.";
622 else if (result == JOB_TIMEOUT)
623 return "Timed out reloading %s.";
629 static void job_print_status_message(Unit *u, JobType t, JobResult result) {
634 assert(t < _JOB_TYPE_MAX);
636 if (t == JOB_START) {
637 format = job_get_status_message_format(u, t, result);
644 if (u->condition_result)
645 unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, format, unit_description(u));
649 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF, format, unit_description(u));
650 unit_status_printf(u, NULL, "See 'systemctl status %s' for details.", u->id);
654 unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "DEPEND" ANSI_HIGHLIGHT_OFF, format, unit_description(u));
658 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format, unit_description(u));
665 } else if (t == JOB_STOP || t == JOB_RESTART) {
667 format = job_get_status_message_format(u, t, result);
674 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format, unit_description(u));
679 unit_status_printf(u, ANSI_HIGHLIGHT_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, format, unit_description(u));
686 } else if (t == JOB_VERIFY_ACTIVE) {
688 /* When verify-active detects the unit is inactive, report it.
689 * Most likely a DEPEND warning from a requisiting unit will
690 * occur next and it's nice to see what was requisited. */
691 if (result == JOB_SKIPPED)
692 unit_status_printf(u, ANSI_HIGHLIGHT_ON " INFO " ANSI_HIGHLIGHT_OFF, "%s is not active.", unit_description(u));
696 #pragma GCC diagnostic push
697 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
698 static void job_log_status_message(Unit *u, JobType t, JobResult result) {
704 assert(t < _JOB_TYPE_MAX);
706 /* Skip this if it goes to the console. since we already print
707 * to the console anyway... */
709 if (log_on_console())
712 format = job_get_status_message_format_try_harder(u, t, result);
716 snprintf(buf, sizeof(buf), format, unit_description(u));
719 if (t == JOB_START) {
722 mid = result == JOB_DONE ? SD_MESSAGE_UNIT_STARTED : SD_MESSAGE_UNIT_FAILED;
723 log_struct_unit(result == JOB_DONE ? LOG_INFO : LOG_ERR,
726 "RESULT=%s", job_result_to_string(result),
730 } else if (t == JOB_STOP)
731 log_struct_unit(result == JOB_DONE ? LOG_INFO : LOG_ERR,
733 MESSAGE_ID(SD_MESSAGE_UNIT_STOPPED),
734 "RESULT=%s", job_result_to_string(result),
738 else if (t == JOB_RELOAD)
739 log_struct_unit(result == JOB_DONE ? LOG_INFO : LOG_ERR,
741 MESSAGE_ID(SD_MESSAGE_UNIT_RELOADED),
742 "RESULT=%s", job_result_to_string(result),
746 #pragma GCC diagnostic pop
748 int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) {
755 assert(j->installed);
756 assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
763 log_debug_unit(u->id, "Job %s/%s finished, result=%s",
764 u->id, job_type_to_string(t), job_result_to_string(result));
766 job_print_status_message(u, t, result);
767 job_log_status_message(u, t, result);
769 job_add_to_dbus_queue(j);
771 /* Patch restart jobs so that they become normal start jobs */
772 if (result == JOB_DONE && t == JOB_RESTART) {
774 job_change_type(j, JOB_START);
775 j->state = JOB_WAITING;
777 job_add_to_run_queue(j);
782 if (result == JOB_FAILED)
783 j->manager->n_failed_jobs ++;
788 /* Fail depending jobs on failure */
789 if (result != JOB_DONE && recursive) {
791 if (t == JOB_START ||
792 t == JOB_VERIFY_ACTIVE) {
794 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
796 (other->job->type == JOB_START ||
797 other->job->type == JOB_VERIFY_ACTIVE))
798 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
800 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
802 (other->job->type == JOB_START ||
803 other->job->type == JOB_VERIFY_ACTIVE))
804 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
806 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
808 !other->job->override &&
809 (other->job->type == JOB_START ||
810 other->job->type == JOB_VERIFY_ACTIVE))
811 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
813 } else if (t == JOB_STOP) {
815 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
817 (other->job->type == JOB_START ||
818 other->job->type == JOB_VERIFY_ACTIVE))
819 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
823 /* Trigger OnFailure dependencies that are not generated by
824 * the unit itself. We don't treat JOB_CANCELED as failure in
825 * this context. And JOB_FAILURE is already handled by the
827 if (result == JOB_TIMEOUT || result == JOB_DEPENDENCY) {
828 log_struct_unit(LOG_NOTICE,
830 "JOB_TYPE=%s", job_type_to_string(t),
831 "JOB_RESULT=%s", job_result_to_string(result),
832 "Job %s/%s failed with result '%s'.",
834 job_type_to_string(t),
835 job_result_to_string(result),
838 unit_trigger_on_failure(u);
842 /* Try to start the next jobs that can be started */
843 SET_FOREACH(other, u->dependencies[UNIT_AFTER], i)
845 job_add_to_run_queue(other->job);
846 SET_FOREACH(other, u->dependencies[UNIT_BEFORE], i)
848 job_add_to_run_queue(other->job);
850 manager_check_finished(u->manager);
855 int job_start_timer(Job *j) {
856 struct itimerspec its;
857 struct epoll_event ev;
861 if (j->unit->job_timeout <= 0 ||
862 j->timer_watch.type == WATCH_JOB_TIMER)
865 assert(j->timer_watch.type == WATCH_INVALID);
867 if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) {
873 timespec_store(&its.it_value, j->unit->job_timeout);
875 if (timerfd_settime(fd, 0, &its, NULL) < 0) {
881 ev.data.ptr = &j->timer_watch;
884 if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
889 j->timer_watch.type = WATCH_JOB_TIMER;
890 j->timer_watch.fd = fd;
891 j->timer_watch.data.job = j;
897 close_nointr_nofail(fd);
902 void job_add_to_run_queue(Job *j) {
904 assert(j->installed);
909 LIST_PREPEND(Job, run_queue, j->manager->run_queue, j);
910 j->in_run_queue = true;
913 void job_add_to_dbus_queue(Job *j) {
915 assert(j->installed);
917 if (j->in_dbus_queue)
920 /* We don't check if anybody is subscribed here, since this
921 * job might just have been created and not yet assigned to a
922 * connection/client. */
924 LIST_PREPEND(Job, dbus_queue, j->manager->dbus_job_queue, j);
925 j->in_dbus_queue = true;
928 char *job_dbus_path(Job *j) {
933 if (asprintf(&p, "/org/freedesktop/systemd1/job/%lu", (unsigned long) j->id) < 0)
939 void job_timer_event(Job *j, uint64_t n_elapsed, Watch *w) {
941 assert(w == &j->timer_watch);
943 log_warning_unit(j->unit->id, "Job %s/%s timed out.",
944 j->unit->id, job_type_to_string(j->type));
945 job_finish_and_invalidate(j, JOB_TIMEOUT, true);
948 int job_serialize(Job *j, FILE *f, FDSet *fds) {
949 fprintf(f, "job-id=%u\n", j->id);
950 fprintf(f, "job-type=%s\n", job_type_to_string(j->type));
951 fprintf(f, "job-state=%s\n", job_state_to_string(j->state));
952 fprintf(f, "job-override=%s\n", yes_no(j->override));
953 fprintf(f, "job-irreversible=%s\n", yes_no(j->irreversible));
954 fprintf(f, "job-sent-dbus-new-signal=%s\n", yes_no(j->sent_dbus_new_signal));
955 fprintf(f, "job-ignore-order=%s\n", yes_no(j->ignore_order));
956 /* Cannot save bus clients. Just note the fact that we're losing
957 * them. job_send_message() will fallback to broadcasting. */
958 fprintf(f, "job-forgot-bus-clients=%s\n",
959 yes_no(j->forgot_bus_clients || j->bus_client_list));
960 if (j->timer_watch.type == WATCH_JOB_TIMER) {
961 int copy = fdset_put_dup(fds, j->timer_watch.fd);
964 fprintf(f, "job-timer-watch-fd=%d\n", copy);
972 int job_deserialize(Job *j, FILE *f, FDSet *fds) {
974 char line[LINE_MAX], *l, *v;
977 if (!fgets(line, sizeof(line), f)) {
998 if (streq(l, "job-id")) {
999 if (safe_atou32(v, &j->id) < 0)
1000 log_debug("Failed to parse job id value %s", v);
1001 } else if (streq(l, "job-type")) {
1002 JobType t = job_type_from_string(v);
1004 log_debug("Failed to parse job type %s", v);
1005 else if (t >= _JOB_TYPE_MAX_IN_TRANSACTION)
1006 log_debug("Cannot deserialize job of type %s", v);
1009 } else if (streq(l, "job-state")) {
1010 JobState s = job_state_from_string(v);
1012 log_debug("Failed to parse job state %s", v);
1015 } else if (streq(l, "job-override")) {
1016 int b = parse_boolean(v);
1018 log_debug("Failed to parse job override flag %s", v);
1020 j->override = j->override || b;
1021 } else if (streq(l, "job-irreversible")) {
1022 int b = parse_boolean(v);
1024 log_debug("Failed to parse job irreversible flag %s", v);
1026 j->irreversible = j->irreversible || b;
1027 } else if (streq(l, "job-sent-dbus-new-signal")) {
1028 int b = parse_boolean(v);
1030 log_debug("Failed to parse job sent_dbus_new_signal flag %s", v);
1032 j->sent_dbus_new_signal = j->sent_dbus_new_signal || b;
1033 } else if (streq(l, "job-ignore-order")) {
1034 int b = parse_boolean(v);
1036 log_debug("Failed to parse job ignore_order flag %s", v);
1038 j->ignore_order = j->ignore_order || b;
1039 } else if (streq(l, "job-forgot-bus-clients")) {
1040 int b = parse_boolean(v);
1042 log_debug("Failed to parse job forgot_bus_clients flag %s", v);
1044 j->forgot_bus_clients = j->forgot_bus_clients || b;
1045 } else if (streq(l, "job-timer-watch-fd")) {
1047 if (safe_atoi(v, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
1048 log_debug("Failed to parse job-timer-watch-fd value %s", v);
1050 if (j->timer_watch.type == WATCH_JOB_TIMER)
1051 close_nointr_nofail(j->timer_watch.fd);
1053 j->timer_watch.type = WATCH_JOB_TIMER;
1054 j->timer_watch.fd = fdset_remove(fds, fd);
1055 j->timer_watch.data.job = j;
1061 int job_coldplug(Job *j) {
1062 struct epoll_event ev;
1064 if (j->timer_watch.type != WATCH_JOB_TIMER)
1068 ev.data.ptr = &j->timer_watch;
1069 ev.events = EPOLLIN;
1071 if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, j->timer_watch.fd, &ev) < 0)
1077 void job_shutdown_magic(Job *j) {
1080 /* The shutdown target gets some special treatment here: we
1081 * tell the kernel to begin with flushing its disk caches, to
1082 * optimize shutdown time a bit. Ideally we wouldn't hardcode
1083 * this magic into PID 1. However all other processes aren't
1084 * options either since they'd exit much sooner than PID 1 and
1085 * asynchronous sync() would cause their exit to be
1088 if (!unit_has_name(j->unit, SPECIAL_SHUTDOWN_TARGET))
1091 if (j->type != JOB_START)
1094 if (detect_container(NULL) > 0)
1097 asynchronous_sync();
1100 static const char* const job_state_table[_JOB_STATE_MAX] = {
1101 [JOB_WAITING] = "waiting",
1102 [JOB_RUNNING] = "running"
1105 DEFINE_STRING_TABLE_LOOKUP(job_state, JobState);
1107 static const char* const job_type_table[_JOB_TYPE_MAX] = {
1108 [JOB_START] = "start",
1109 [JOB_VERIFY_ACTIVE] = "verify-active",
1110 [JOB_STOP] = "stop",
1111 [JOB_RELOAD] = "reload",
1112 [JOB_RELOAD_OR_START] = "reload-or-start",
1113 [JOB_RESTART] = "restart",
1114 [JOB_TRY_RESTART] = "try-restart",
1118 DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
1120 static const char* const job_mode_table[_JOB_MODE_MAX] = {
1121 [JOB_FAIL] = "fail",
1122 [JOB_REPLACE] = "replace",
1123 [JOB_REPLACE_IRREVERSIBLY] = "replace-irreversibly",
1124 [JOB_ISOLATE] = "isolate",
1125 [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
1126 [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements"
1129 DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);
1131 static const char* const job_result_table[_JOB_RESULT_MAX] = {
1132 [JOB_DONE] = "done",
1133 [JOB_CANCELED] = "canceled",
1134 [JOB_TIMEOUT] = "timeout",
1135 [JOB_FAILED] = "failed",
1136 [JOB_DEPENDENCY] = "dependency",
1137 [JOB_SKIPPED] = "skipped"
1140 DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);