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;
209 uj->manager->n_running_jobs--;
215 /* Install the job */
218 j->manager->n_installed_jobs ++;
219 log_debug_unit(j->unit->id,
220 "Installed new job %s/%s as %u",
221 j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
225 int job_install_deserialized(Job *j) {
228 assert(!j->installed);
230 if (j->type < 0 || j->type >= _JOB_TYPE_MAX_IN_TRANSACTION) {
231 log_debug("Invalid job type %s in deserialization.", strna(job_type_to_string(j->type)));
235 pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
238 log_debug_unit(j->unit->id,
239 "Unit %s already has a job installed. Not installing deserialized job.",
245 log_debug_unit(j->unit->id,
246 "Reinstalled deserialized job %s/%s as %u",
247 j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
251 JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts) {
256 /* Adds a new job link, which encodes that the 'subject' job
257 * needs the 'object' job in some way. If 'subject' is NULL
258 * this means the 'anchor' job (i.e. the one the user
259 * explicitly asked for) is the requester. */
261 if (!(l = new0(JobDependency, 1)))
264 l->subject = subject;
266 l->matters = matters;
267 l->conflicts = conflicts;
270 LIST_PREPEND(JobDependency, subject, subject->subject_list, l);
272 LIST_PREPEND(JobDependency, object, object->object_list, l);
277 void job_dependency_free(JobDependency *l) {
281 LIST_REMOVE(JobDependency, subject, l->subject->subject_list, l);
283 LIST_REMOVE(JobDependency, object, l->object->object_list, l);
288 void job_dump(Job *j, FILE*f, const char *prefix) {
297 "%s\tAction: %s -> %s\n"
300 "%s\tIrreversible: %s\n",
302 prefix, j->unit->id, job_type_to_string(j->type),
303 prefix, job_state_to_string(j->state),
304 prefix, yes_no(j->override),
305 prefix, yes_no(j->irreversible));
309 * Merging is commutative, so imagine the matrix as symmetric. We store only
310 * its lower triangle to avoid duplication. We don't store the main diagonal,
311 * because A merged with A is simply A.
313 * If the resulting type is collapsed immediately afterwards (to get rid of
314 * the JOB_RELOAD_OR_START, which lies outside the lookup function's domain),
315 * the following properties hold:
317 * Merging is associative! A merged with B merged with C is the same as
318 * A merged with C merged with B.
320 * Mergeability is transitive! If A can be merged with B and B with C then
323 * Also, if A merged with B cannot be merged with C, then either A or B cannot
324 * be merged with C either.
326 static const JobType job_merging_table[] = {
327 /* What \ With * JOB_START JOB_VERIFY_ACTIVE JOB_STOP JOB_RELOAD */
328 /*********************************************************************************/
330 /*JOB_VERIFY_ACTIVE */ JOB_START,
331 /*JOB_STOP */ -1, -1,
332 /*JOB_RELOAD */ JOB_RELOAD_OR_START, JOB_RELOAD, -1,
333 /*JOB_RESTART */ JOB_RESTART, JOB_RESTART, -1, JOB_RESTART,
336 JobType job_type_lookup_merge(JobType a, JobType b) {
337 assert_cc(ELEMENTSOF(job_merging_table) == _JOB_TYPE_MAX_MERGING * (_JOB_TYPE_MAX_MERGING - 1) / 2);
338 assert(a >= 0 && a < _JOB_TYPE_MAX_MERGING);
339 assert(b >= 0 && b < _JOB_TYPE_MAX_MERGING);
350 return job_merging_table[(a - 1) * a / 2 + b];
353 bool job_type_is_redundant(JobType a, UnitActiveState b) {
363 b == UNIT_INACTIVE ||
366 case JOB_VERIFY_ACTIVE:
377 b == UNIT_ACTIVATING;
380 assert_not_reached("Invalid job type");
384 void job_type_collapse(JobType *t, Unit *u) {
389 case JOB_TRY_RESTART:
390 s = unit_active_state(u);
391 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
397 case JOB_RELOAD_OR_START:
398 s = unit_active_state(u);
399 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
410 int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u) {
411 JobType t = job_type_lookup_merge(*a, b);
415 job_type_collapse(a, u);
419 bool job_is_runnable(Job *j) {
424 assert(j->installed);
426 /* Checks whether there is any job running for the units this
427 * job needs to be running after (in the case of a 'positive'
428 * job type) or before (in the case of a 'negative' job
431 /* First check if there is an override */
435 if (j->type == JOB_NOP)
438 if (j->type == JOB_START ||
439 j->type == JOB_VERIFY_ACTIVE ||
440 j->type == JOB_RELOAD) {
442 /* Immediate result is that the job is or might be
443 * started. In this case lets wait for the
444 * dependencies, regardless whether they are
445 * starting or stopping something. */
447 SET_FOREACH(other, j->unit->dependencies[UNIT_AFTER], i)
452 /* Also, if something else is being stopped and we should
453 * change state after it, then lets wait. */
455 SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i)
457 (other->job->type == JOB_STOP ||
458 other->job->type == JOB_RESTART))
461 /* This means that for a service a and a service b where b
462 * shall be started after a:
464 * start a + start b → 1st step start a, 2nd step start b
465 * start a + stop b → 1st step stop b, 2nd step start a
466 * stop a + start b → 1st step stop a, 2nd step start b
467 * stop a + stop b → 1st step stop b, 2nd step stop a
469 * This has the side effect that restarts are properly
470 * synchronized too. */
475 static void job_change_type(Job *j, JobType newtype) {
476 log_debug_unit(j->unit->id,
477 "Converting job %s/%s -> %s/%s",
478 j->unit->id, job_type_to_string(j->type),
479 j->unit->id, job_type_to_string(newtype));
484 int job_run_and_invalidate(Job *j) {
487 Manager *m = j->manager;
490 assert(j->installed);
491 assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
492 assert(j->in_run_queue);
494 LIST_REMOVE(Job, run_queue, j->manager->run_queue, j);
495 j->in_run_queue = false;
497 if (j->state != JOB_WAITING)
500 if (!job_is_runnable(j))
503 j->state = JOB_RUNNING;
505 job_add_to_dbus_queue(j);
507 /* While we execute this operation the job might go away (for
508 * example: because it is replaced by a new, conflicting
509 * job.) To make sure we don't access a freed job later on we
510 * store the id here, so that we can verify the job is still
517 r = unit_start(j->unit);
519 /* If this unit cannot be started, then simply wait */
524 case JOB_VERIFY_ACTIVE: {
525 UnitActiveState t = unit_active_state(j->unit);
526 if (UNIT_IS_ACTIVE_OR_RELOADING(t))
528 else if (t == UNIT_ACTIVATING)
537 r = unit_stop(j->unit);
539 /* If this unit cannot stopped, then simply wait. */
545 r = unit_reload(j->unit);
553 assert_not_reached("Unknown job type");
556 j = manager_get_job(m, id);
559 r = job_finish_and_invalidate(j, JOB_DONE, true);
560 else if (r == -ENOEXEC)
561 r = job_finish_and_invalidate(j, JOB_SKIPPED, true);
562 else if (r == -EAGAIN) {
563 j->state = JOB_WAITING;
566 r = job_finish_and_invalidate(j, JOB_FAILED, true);
572 _pure_ static const char *job_get_status_message_format(Unit *u, JobType t, JobResult result) {
573 const UnitStatusMessageFormats *format_table;
577 assert(t < _JOB_TYPE_MAX);
579 format_table = &UNIT_VTABLE(u)->status_message_formats;
584 return format_table->finished_start_job[result];
585 else if (t == JOB_STOP || t == JOB_RESTART)
586 return format_table->finished_stop_job[result];
591 _pure_ static const char *job_get_status_message_format_try_harder(Unit *u, JobType t, JobResult result) {
596 assert(t < _JOB_TYPE_MAX);
598 format = job_get_status_message_format(u, t, result);
602 /* Return generic strings */
603 if (t == JOB_START) {
604 if (result == JOB_DONE)
605 return "Started %s.";
606 else if (result == JOB_FAILED)
607 return "Failed to start %s.";
608 else if (result == JOB_DEPENDENCY)
609 return "Dependency failed for %s.";
610 else if (result == JOB_TIMEOUT)
611 return "Timed out starting %s.";
612 } else if (t == JOB_STOP || t == JOB_RESTART) {
613 if (result == JOB_DONE)
614 return "Stopped %s.";
615 else if (result == JOB_FAILED)
616 return "Stopped (with error) %s.";
617 else if (result == JOB_TIMEOUT)
618 return "Timed out stoppping %s.";
619 } else if (t == JOB_RELOAD) {
620 if (result == JOB_DONE)
621 return "Reloaded %s.";
622 else if (result == JOB_FAILED)
623 return "Reload failed for %s.";
624 else if (result == JOB_TIMEOUT)
625 return "Timed out reloading %s.";
631 static void job_print_status_message(Unit *u, JobType t, JobResult result) {
636 assert(t < _JOB_TYPE_MAX);
638 if (t == JOB_START) {
639 format = job_get_status_message_format(u, t, result);
646 if (u->condition_result)
647 unit_status_printf(u, ANSI_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, format);
651 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF, format);
652 manager_status_printf(u->manager, false, NULL, "See 'systemctl status %s' for details.", u->id);
656 unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "DEPEND" ANSI_HIGHLIGHT_OFF, format);
660 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format);
667 } else if (t == JOB_STOP || t == JOB_RESTART) {
669 format = job_get_status_message_format(u, t, result);
676 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format);
681 unit_status_printf(u, ANSI_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, format);
688 } else if (t == JOB_VERIFY_ACTIVE) {
690 /* When verify-active detects the unit is inactive, report it.
691 * Most likely a DEPEND warning from a requisiting unit will
692 * occur next and it's nice to see what was requisited. */
693 if (result == JOB_SKIPPED)
694 unit_status_printf(u, ANSI_HIGHLIGHT_ON " INFO " ANSI_HIGHLIGHT_OFF, "%s is not active.");
698 #pragma GCC diagnostic push
699 #pragma GCC diagnostic ignored "-Wformat-nonliteral"
700 static void job_log_status_message(Unit *u, JobType t, JobResult result) {
706 assert(t < _JOB_TYPE_MAX);
708 /* Skip this if it goes to the console. since we already print
709 * to the console anyway... */
711 if (log_on_console())
714 format = job_get_status_message_format_try_harder(u, t, result);
718 snprintf(buf, sizeof(buf), format, unit_description(u));
721 if (t == JOB_START) {
724 mid = result == JOB_DONE ? SD_MESSAGE_UNIT_STARTED : SD_MESSAGE_UNIT_FAILED;
725 log_struct_unit(result == JOB_DONE ? LOG_INFO : LOG_ERR,
728 "RESULT=%s", job_result_to_string(result),
732 } else if (t == JOB_STOP)
733 log_struct_unit(result == JOB_DONE ? LOG_INFO : LOG_ERR,
735 MESSAGE_ID(SD_MESSAGE_UNIT_STOPPED),
736 "RESULT=%s", job_result_to_string(result),
740 else if (t == JOB_RELOAD)
741 log_struct_unit(result == JOB_DONE ? LOG_INFO : LOG_ERR,
743 MESSAGE_ID(SD_MESSAGE_UNIT_RELOADED),
744 "RESULT=%s", job_result_to_string(result),
748 #pragma GCC diagnostic pop
750 int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) {
757 assert(j->installed);
758 assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
765 if (j->state == JOB_RUNNING)
766 j->manager->n_running_jobs--;
768 log_debug_unit(u->id, "Job %s/%s finished, result=%s",
769 u->id, job_type_to_string(t), job_result_to_string(result));
771 job_print_status_message(u, t, result);
772 job_log_status_message(u, t, result);
774 job_add_to_dbus_queue(j);
776 /* Patch restart jobs so that they become normal start jobs */
777 if (result == JOB_DONE && t == JOB_RESTART) {
779 job_change_type(j, JOB_START);
780 j->state = JOB_WAITING;
782 job_add_to_run_queue(j);
787 if (result == JOB_FAILED)
788 j->manager->n_failed_jobs ++;
793 /* Fail depending jobs on failure */
794 if (result != JOB_DONE && recursive) {
796 if (t == JOB_START ||
797 t == JOB_VERIFY_ACTIVE) {
799 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
801 (other->job->type == JOB_START ||
802 other->job->type == JOB_VERIFY_ACTIVE))
803 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
805 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
807 (other->job->type == JOB_START ||
808 other->job->type == JOB_VERIFY_ACTIVE))
809 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
811 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
813 !other->job->override &&
814 (other->job->type == JOB_START ||
815 other->job->type == JOB_VERIFY_ACTIVE))
816 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
818 } else if (t == JOB_STOP) {
820 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
822 (other->job->type == JOB_START ||
823 other->job->type == JOB_VERIFY_ACTIVE))
824 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
828 /* Trigger OnFailure dependencies that are not generated by
829 * the unit itself. We don't treat JOB_CANCELED as failure in
830 * this context. And JOB_FAILURE is already handled by the
832 if (result == JOB_TIMEOUT || result == JOB_DEPENDENCY) {
833 log_struct_unit(LOG_NOTICE,
835 "JOB_TYPE=%s", job_type_to_string(t),
836 "JOB_RESULT=%s", job_result_to_string(result),
837 "Job %s/%s failed with result '%s'.",
839 job_type_to_string(t),
840 job_result_to_string(result),
843 unit_start_on_failure(u);
846 unit_trigger_notify(u);
849 /* Try to start the next jobs that can be started */
850 SET_FOREACH(other, u->dependencies[UNIT_AFTER], i)
852 job_add_to_run_queue(other->job);
853 SET_FOREACH(other, u->dependencies[UNIT_BEFORE], i)
855 job_add_to_run_queue(other->job);
857 manager_check_finished(u->manager);
862 int job_start_timer(Job *j) {
863 struct itimerspec its = {};
864 struct epoll_event ev = {
865 .data.ptr = &j->timer_watch,
870 if (j->unit->job_timeout <= 0 ||
871 j->timer_watch.type == WATCH_JOB_TIMER)
874 assert(j->timer_watch.type == WATCH_INVALID);
876 if ((fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK|TFD_CLOEXEC)) < 0) {
881 timespec_store(&its.it_value, j->unit->job_timeout);
883 if (timerfd_settime(fd, 0, &its, NULL) < 0) {
888 if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
893 j->timer_watch.type = WATCH_JOB_TIMER;
894 j->timer_watch.fd = fd;
895 j->timer_watch.data.job = j;
901 close_nointr_nofail(fd);
906 void job_add_to_run_queue(Job *j) {
908 assert(j->installed);
913 LIST_PREPEND(Job, run_queue, j->manager->run_queue, j);
914 j->in_run_queue = true;
917 void job_add_to_dbus_queue(Job *j) {
919 assert(j->installed);
921 if (j->in_dbus_queue)
924 /* We don't check if anybody is subscribed here, since this
925 * job might just have been created and not yet assigned to a
926 * connection/client. */
928 LIST_PREPEND(Job, dbus_queue, j->manager->dbus_job_queue, j);
929 j->in_dbus_queue = true;
932 char *job_dbus_path(Job *j) {
937 if (asprintf(&p, "/org/freedesktop/systemd1/job/%lu", (unsigned long) j->id) < 0)
943 void job_timer_event(Job *j, uint64_t n_elapsed, Watch *w) {
945 assert(w == &j->timer_watch);
947 log_warning_unit(j->unit->id, "Job %s/%s timed out.",
948 j->unit->id, job_type_to_string(j->type));
949 job_finish_and_invalidate(j, JOB_TIMEOUT, true);
952 int job_serialize(Job *j, FILE *f, FDSet *fds) {
953 fprintf(f, "job-id=%u\n", j->id);
954 fprintf(f, "job-type=%s\n", job_type_to_string(j->type));
955 fprintf(f, "job-state=%s\n", job_state_to_string(j->state));
956 fprintf(f, "job-override=%s\n", yes_no(j->override));
957 fprintf(f, "job-irreversible=%s\n", yes_no(j->irreversible));
958 fprintf(f, "job-sent-dbus-new-signal=%s\n", yes_no(j->sent_dbus_new_signal));
959 fprintf(f, "job-ignore-order=%s\n", yes_no(j->ignore_order));
960 /* Cannot save bus clients. Just note the fact that we're losing
961 * them. job_send_message() will fallback to broadcasting. */
962 fprintf(f, "job-forgot-bus-clients=%s\n",
963 yes_no(j->forgot_bus_clients || j->bus_client_list));
964 if (j->timer_watch.type == WATCH_JOB_TIMER) {
965 int copy = fdset_put_dup(fds, j->timer_watch.fd);
968 fprintf(f, "job-timer-watch-fd=%d\n", copy);
976 int job_deserialize(Job *j, FILE *f, FDSet *fds) {
978 char line[LINE_MAX], *l, *v;
981 if (!fgets(line, sizeof(line), f)) {
1002 if (streq(l, "job-id")) {
1003 if (safe_atou32(v, &j->id) < 0)
1004 log_debug("Failed to parse job id value %s", v);
1005 } else if (streq(l, "job-type")) {
1006 JobType t = job_type_from_string(v);
1008 log_debug("Failed to parse job type %s", v);
1009 else if (t >= _JOB_TYPE_MAX_IN_TRANSACTION)
1010 log_debug("Cannot deserialize job of type %s", v);
1013 } else if (streq(l, "job-state")) {
1014 JobState s = job_state_from_string(v);
1016 log_debug("Failed to parse job state %s", v);
1019 } else if (streq(l, "job-override")) {
1020 int b = parse_boolean(v);
1022 log_debug("Failed to parse job override flag %s", v);
1024 j->override = j->override || b;
1025 } else if (streq(l, "job-irreversible")) {
1026 int b = parse_boolean(v);
1028 log_debug("Failed to parse job irreversible flag %s", v);
1030 j->irreversible = j->irreversible || b;
1031 } else if (streq(l, "job-sent-dbus-new-signal")) {
1032 int b = parse_boolean(v);
1034 log_debug("Failed to parse job sent_dbus_new_signal flag %s", v);
1036 j->sent_dbus_new_signal = j->sent_dbus_new_signal || b;
1037 } else if (streq(l, "job-ignore-order")) {
1038 int b = parse_boolean(v);
1040 log_debug("Failed to parse job ignore_order flag %s", v);
1042 j->ignore_order = j->ignore_order || b;
1043 } else if (streq(l, "job-forgot-bus-clients")) {
1044 int b = parse_boolean(v);
1046 log_debug("Failed to parse job forgot_bus_clients flag %s", v);
1048 j->forgot_bus_clients = j->forgot_bus_clients || b;
1049 } else if (streq(l, "job-timer-watch-fd")) {
1051 if (safe_atoi(v, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
1052 log_debug("Failed to parse job-timer-watch-fd value %s", v);
1054 if (j->timer_watch.type == WATCH_JOB_TIMER)
1055 close_nointr_nofail(j->timer_watch.fd);
1057 j->timer_watch.type = WATCH_JOB_TIMER;
1058 j->timer_watch.fd = fdset_remove(fds, fd);
1059 j->timer_watch.data.job = j;
1065 int job_coldplug(Job *j) {
1066 struct epoll_event ev = {
1067 .data.ptr = &j->timer_watch,
1071 if (j->timer_watch.type != WATCH_JOB_TIMER)
1074 if (epoll_ctl(j->manager->epoll_fd, EPOLL_CTL_ADD, j->timer_watch.fd, &ev) < 0)
1080 void job_shutdown_magic(Job *j) {
1083 /* The shutdown target gets some special treatment here: we
1084 * tell the kernel to begin with flushing its disk caches, to
1085 * optimize shutdown time a bit. Ideally we wouldn't hardcode
1086 * this magic into PID 1. However all other processes aren't
1087 * options either since they'd exit much sooner than PID 1 and
1088 * asynchronous sync() would cause their exit to be
1091 if (j->type != JOB_START)
1094 if (j->unit->manager->running_as != SYSTEMD_SYSTEM)
1097 if (!unit_has_name(j->unit, SPECIAL_SHUTDOWN_TARGET))
1100 if (detect_container(NULL) > 0)
1103 asynchronous_sync();
1106 static const char* const job_state_table[_JOB_STATE_MAX] = {
1107 [JOB_WAITING] = "waiting",
1108 [JOB_RUNNING] = "running"
1111 DEFINE_STRING_TABLE_LOOKUP(job_state, JobState);
1113 static const char* const job_type_table[_JOB_TYPE_MAX] = {
1114 [JOB_START] = "start",
1115 [JOB_VERIFY_ACTIVE] = "verify-active",
1116 [JOB_STOP] = "stop",
1117 [JOB_RELOAD] = "reload",
1118 [JOB_RELOAD_OR_START] = "reload-or-start",
1119 [JOB_RESTART] = "restart",
1120 [JOB_TRY_RESTART] = "try-restart",
1124 DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
1126 static const char* const job_mode_table[_JOB_MODE_MAX] = {
1127 [JOB_FAIL] = "fail",
1128 [JOB_REPLACE] = "replace",
1129 [JOB_REPLACE_IRREVERSIBLY] = "replace-irreversibly",
1130 [JOB_ISOLATE] = "isolate",
1131 [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
1132 [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements"
1135 DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);
1137 static const char* const job_result_table[_JOB_RESULT_MAX] = {
1138 [JOB_DONE] = "done",
1139 [JOB_CANCELED] = "canceled",
1140 [JOB_TIMEOUT] = "timeout",
1141 [JOB_FAILED] = "failed",
1142 [JOB_DEPENDENCY] = "dependency",
1143 [JOB_SKIPPED] = "skipped"
1146 DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);