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>
28 #include "sd-messages.h"
33 #include "load-fragment.h"
34 #include "load-dropin.h"
42 Job* job_new_raw(Unit *unit) {
45 /* used for deserialization */
53 j->manager = unit->manager;
55 j->type = _JOB_TYPE_INVALID;
60 Job* job_new(Unit *unit, JobType type) {
63 assert(type < _JOB_TYPE_MAX);
65 j = job_new_raw(unit);
69 j->id = j->manager->current_job_id++;
72 /* We don't link it here, that's what job_dependency() is for */
77 void job_free(Job *j) {
79 assert(!j->installed);
80 assert(!j->transaction_prev);
81 assert(!j->transaction_next);
82 assert(!j->subject_list);
83 assert(!j->object_list);
86 LIST_REMOVE(run_queue, j->manager->run_queue, j);
89 LIST_REMOVE(dbus_queue, j->manager->dbus_job_queue, j);
91 sd_event_source_unref(j->timer_event_source);
93 sd_bus_track_unref(j->clients);
94 strv_free(j->deserialized_clients);
99 void job_uninstall(Job *j) {
102 assert(j->installed);
104 pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
107 /* Detach from next 'bigger' objects */
109 /* daemon-reload should be transparent to job observers */
110 if (j->manager->n_reloading <= 0)
111 bus_job_send_removed_signal(j);
115 unit_add_to_gc_queue(j->unit);
117 hashmap_remove(j->manager->jobs, UINT32_TO_PTR(j->id));
118 j->installed = false;
121 static bool job_type_allows_late_merge(JobType t) {
122 /* Tells whether it is OK to merge a job of type 't' with an already
124 * Reloads cannot be merged this way. Think of the sequence:
125 * 1. Reload of a daemon is in progress; the daemon has already loaded
126 * its config file, but hasn't completed the reload operation yet.
127 * 2. Edit foo's config file.
128 * 3. Trigger another reload to have the daemon use the new config.
129 * Should the second reload job be merged into the first one, the daemon
130 * would not know about the new config.
131 * JOB_RESTART jobs on the other hand can be merged, because they get
132 * patched into JOB_START after stopping the unit. So if we see a
133 * JOB_RESTART running, it means the unit hasn't stopped yet and at
134 * this time the merge is still allowed. */
135 return t != JOB_RELOAD;
138 static void job_merge_into_installed(Job *j, Job *other) {
139 assert(j->installed);
140 assert(j->unit == other->unit);
142 if (j->type != JOB_NOP)
143 job_type_merge_and_collapse(&j->type, other->type, j->unit);
145 assert(other->type == JOB_NOP);
147 j->override = j->override || other->override;
148 j->irreversible = j->irreversible || other->irreversible;
149 j->ignore_order = j->ignore_order || other->ignore_order;
152 Job* job_install(Job *j) {
156 assert(!j->installed);
157 assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
159 pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
163 if (j->type != JOB_NOP && job_type_is_conflicting(uj->type, j->type))
164 job_finish_and_invalidate(uj, JOB_CANCELED, false);
166 /* not conflicting, i.e. mergeable */
168 if (j->type == JOB_NOP || uj->state == JOB_WAITING ||
169 (job_type_allows_late_merge(j->type) && job_type_is_superset(uj->type, j->type))) {
170 job_merge_into_installed(uj, j);
171 log_debug_unit(uj->unit->id,
172 "Merged into installed job %s/%s as %u",
173 uj->unit->id, job_type_to_string(uj->type), (unsigned) uj->id);
176 /* already running and not safe to merge into */
177 /* Patch uj to become a merged job and re-run it. */
178 /* XXX It should be safer to queue j to run after uj finishes, but it is
179 * not currently possible to have more than one installed job per unit. */
180 job_merge_into_installed(uj, j);
181 log_debug_unit(uj->unit->id,
182 "Merged into running job, re-running: %s/%s as %u",
183 uj->unit->id, job_type_to_string(uj->type), (unsigned) uj->id);
184 uj->state = JOB_WAITING;
185 uj->manager->n_running_jobs--;
191 /* Install the job */
194 j->manager->n_installed_jobs ++;
195 log_debug_unit(j->unit->id,
196 "Installed new job %s/%s as %u",
197 j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
201 int job_install_deserialized(Job *j) {
204 assert(!j->installed);
206 if (j->type < 0 || j->type >= _JOB_TYPE_MAX_IN_TRANSACTION) {
207 log_debug("Invalid job type %s in deserialization.", strna(job_type_to_string(j->type)));
211 pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
214 log_debug_unit(j->unit->id,
215 "Unit %s already has a job installed. Not installing deserialized job.",
221 log_debug_unit(j->unit->id,
222 "Reinstalled deserialized job %s/%s as %u",
223 j->unit->id, job_type_to_string(j->type), (unsigned) j->id);
227 JobDependency* job_dependency_new(Job *subject, Job *object, bool matters, bool conflicts) {
232 /* Adds a new job link, which encodes that the 'subject' job
233 * needs the 'object' job in some way. If 'subject' is NULL
234 * this means the 'anchor' job (i.e. the one the user
235 * explicitly asked for) is the requester. */
237 if (!(l = new0(JobDependency, 1)))
240 l->subject = subject;
242 l->matters = matters;
243 l->conflicts = conflicts;
246 LIST_PREPEND(subject, subject->subject_list, l);
248 LIST_PREPEND(object, object->object_list, l);
253 void job_dependency_free(JobDependency *l) {
257 LIST_REMOVE(subject, l->subject->subject_list, l);
259 LIST_REMOVE(object, l->object->object_list, l);
264 void job_dump(Job *j, FILE*f, const char *prefix) {
273 "%s\tAction: %s -> %s\n"
276 "%s\tIrreversible: %s\n",
278 prefix, j->unit->id, job_type_to_string(j->type),
279 prefix, job_state_to_string(j->state),
280 prefix, yes_no(j->override),
281 prefix, yes_no(j->irreversible));
285 * Merging is commutative, so imagine the matrix as symmetric. We store only
286 * its lower triangle to avoid duplication. We don't store the main diagonal,
287 * because A merged with A is simply A.
289 * If the resulting type is collapsed immediately afterwards (to get rid of
290 * the JOB_RELOAD_OR_START, which lies outside the lookup function's domain),
291 * the following properties hold:
293 * Merging is associative! A merged with B merged with C is the same as
294 * A merged with C merged with B.
296 * Mergeability is transitive! If A can be merged with B and B with C then
299 * Also, if A merged with B cannot be merged with C, then either A or B cannot
300 * be merged with C either.
302 static const JobType job_merging_table[] = {
303 /* What \ With * JOB_START JOB_VERIFY_ACTIVE JOB_STOP JOB_RELOAD */
304 /*********************************************************************************/
306 /*JOB_VERIFY_ACTIVE */ JOB_START,
307 /*JOB_STOP */ -1, -1,
308 /*JOB_RELOAD */ JOB_RELOAD_OR_START, JOB_RELOAD, -1,
309 /*JOB_RESTART */ JOB_RESTART, JOB_RESTART, -1, JOB_RESTART,
312 JobType job_type_lookup_merge(JobType a, JobType b) {
313 assert_cc(ELEMENTSOF(job_merging_table) == _JOB_TYPE_MAX_MERGING * (_JOB_TYPE_MAX_MERGING - 1) / 2);
314 assert(a >= 0 && a < _JOB_TYPE_MAX_MERGING);
315 assert(b >= 0 && b < _JOB_TYPE_MAX_MERGING);
326 return job_merging_table[(a - 1) * a / 2 + b];
329 bool job_type_is_redundant(JobType a, UnitActiveState b) {
339 b == UNIT_INACTIVE ||
342 case JOB_VERIFY_ACTIVE:
353 b == UNIT_ACTIVATING;
356 assert_not_reached("Invalid job type");
360 void job_type_collapse(JobType *t, Unit *u) {
365 case JOB_TRY_RESTART:
366 s = unit_active_state(u);
367 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
373 case JOB_RELOAD_OR_START:
374 s = unit_active_state(u);
375 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
386 int job_type_merge_and_collapse(JobType *a, JobType b, Unit *u) {
387 JobType t = job_type_lookup_merge(*a, b);
391 job_type_collapse(a, u);
395 static bool job_is_runnable(Job *j) {
400 assert(j->installed);
402 /* Checks whether there is any job running for the units this
403 * job needs to be running after (in the case of a 'positive'
404 * job type) or before (in the case of a 'negative' job
407 /* Note that unit types have a say in what is runnable,
408 * too. For example, if they return -EAGAIN from
409 * unit_start() they can indicate they are not
412 /* First check if there is an override */
416 if (j->type == JOB_NOP)
419 if (j->type == JOB_START ||
420 j->type == JOB_VERIFY_ACTIVE ||
421 j->type == JOB_RELOAD) {
423 /* Immediate result is that the job is or might be
424 * started. In this case lets wait for the
425 * dependencies, regardless whether they are
426 * starting or stopping something. */
428 SET_FOREACH(other, j->unit->dependencies[UNIT_AFTER], i)
433 /* Also, if something else is being stopped and we should
434 * change state after it, then lets wait. */
436 SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i)
438 (other->job->type == JOB_STOP ||
439 other->job->type == JOB_RESTART))
442 /* This means that for a service a and a service b where b
443 * shall be started after a:
445 * start a + start b → 1st step start a, 2nd step start b
446 * start a + stop b → 1st step stop b, 2nd step start a
447 * stop a + start b → 1st step stop a, 2nd step start b
448 * stop a + stop b → 1st step stop b, 2nd step stop a
450 * This has the side effect that restarts are properly
451 * synchronized too. */
456 static void job_change_type(Job *j, JobType newtype) {
457 log_debug_unit(j->unit->id,
458 "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) {
468 Manager *m = j->manager;
471 assert(j->installed);
472 assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
473 assert(j->in_run_queue);
475 LIST_REMOVE(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;
486 job_add_to_dbus_queue(j);
488 /* While we execute this operation the job might go away (for
489 * example: because it is replaced by a new, conflicting
490 * job.) To make sure we don't access a freed job later on we
491 * 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 == -EBADR)
542 r = job_finish_and_invalidate(j, JOB_SKIPPED, true);
543 else if (r == -ENOEXEC)
544 r = job_finish_and_invalidate(j, JOB_INVALID, true);
545 else if (r == -EPROTO)
546 r = job_finish_and_invalidate(j, JOB_ASSERT, true);
547 else if (r == -EAGAIN) {
548 j->state = JOB_WAITING;
551 r = job_finish_and_invalidate(j, JOB_FAILED, true);
557 _pure_ static const char *job_get_status_message_format(Unit *u, JobType t, JobResult result) {
558 const UnitStatusMessageFormats *format_table;
562 assert(t < _JOB_TYPE_MAX);
564 format_table = &UNIT_VTABLE(u)->status_message_formats;
569 return format_table->finished_start_job[result];
570 else if (t == JOB_STOP || t == JOB_RESTART)
571 return format_table->finished_stop_job[result];
576 _pure_ static const char *job_get_status_message_format_try_harder(Unit *u, JobType t, JobResult result) {
581 assert(t < _JOB_TYPE_MAX);
583 format = job_get_status_message_format(u, t, result);
587 /* Return generic strings */
588 if (t == JOB_START) {
589 if (result == JOB_DONE)
590 return "Started %s.";
591 else if (result == JOB_FAILED)
592 return "Failed to start %s.";
593 else if (result == JOB_DEPENDENCY)
594 return "Dependency failed for %s.";
595 else if (result == JOB_TIMEOUT)
596 return "Timed out starting %s.";
597 } else if (t == JOB_STOP || t == JOB_RESTART) {
598 if (result == JOB_DONE)
599 return "Stopped %s.";
600 else if (result == JOB_FAILED)
601 return "Stopped (with error) %s.";
602 else if (result == JOB_TIMEOUT)
603 return "Timed out stoppping %s.";
604 } else if (t == JOB_RELOAD) {
605 if (result == JOB_DONE)
606 return "Reloaded %s.";
607 else if (result == JOB_FAILED)
608 return "Reload failed for %s.";
609 else if (result == JOB_TIMEOUT)
610 return "Timed out reloading %s.";
616 static void job_print_status_message(Unit *u, JobType t, JobResult result) {
621 assert(t < _JOB_TYPE_MAX);
623 DISABLE_WARNING_FORMAT_NONLITERAL;
625 if (t == JOB_START) {
626 format = job_get_status_message_format(u, t, result);
633 if (u->condition_result)
634 unit_status_printf(u, ANSI_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, format);
640 quotes = chars_intersect(u->id, SHELL_NEED_QUOTES);
642 manager_flip_auto_status(u->manager, true);
643 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF, format);
644 manager_status_printf(u->manager, STATUS_TYPE_NORMAL, NULL,
645 "See \"systemctl status %s%s%s\" for details.",
646 quotes ? "'" : "", u->id, quotes ? "'" : "");
651 manager_flip_auto_status(u->manager, true);
652 unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "DEPEND" ANSI_HIGHLIGHT_OFF, format);
656 manager_flip_auto_status(u->manager, true);
657 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format);
661 manager_flip_auto_status(u->manager, true);
662 unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "ASSERT" ANSI_HIGHLIGHT_OFF, format);
669 } else if (t == JOB_STOP || t == JOB_RESTART) {
671 format = job_get_status_message_format(u, t, result);
678 manager_flip_auto_status(u->manager, true);
679 unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format);
684 unit_status_printf(u, ANSI_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, format);
691 } else if (t == JOB_VERIFY_ACTIVE) {
693 /* When verify-active detects the unit is inactive, report it.
694 * Most likely a DEPEND warning from a requisiting unit will
695 * occur next and it's nice to see what was requisited. */
696 if (result == JOB_SKIPPED)
697 unit_status_printf(u, ANSI_HIGHLIGHT_ON " INFO " ANSI_HIGHLIGHT_OFF, "%s is not active.");
703 static void job_log_status_message(Unit *u, JobType t, JobResult result) {
709 assert(t < _JOB_TYPE_MAX);
711 /* Skip this if it goes to the console. since we already print
712 * to the console anyway... */
714 if (log_on_console())
717 format = job_get_status_message_format_try_harder(u, t, result);
721 DISABLE_WARNING_FORMAT_NONLITERAL;
722 snprintf(buf, sizeof(buf), format, unit_description(u));
726 if (t == JOB_START) {
729 mid = result == JOB_DONE ? SD_MESSAGE_UNIT_STARTED : SD_MESSAGE_UNIT_FAILED;
730 log_struct_unit(result == JOB_DONE ? LOG_INFO : LOG_ERR,
733 "RESULT=%s", job_result_to_string(result),
737 } else if (t == JOB_STOP)
738 log_struct_unit(result == JOB_DONE ? LOG_INFO : LOG_ERR,
740 MESSAGE_ID(SD_MESSAGE_UNIT_STOPPED),
741 "RESULT=%s", job_result_to_string(result),
745 else if (t == JOB_RELOAD)
746 log_struct_unit(result == JOB_DONE ? LOG_INFO : LOG_ERR,
748 MESSAGE_ID(SD_MESSAGE_UNIT_RELOADED),
749 "RESULT=%s", job_result_to_string(result),
754 int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) {
761 assert(j->installed);
762 assert(j->type < _JOB_TYPE_MAX_IN_TRANSACTION);
769 if (j->state == JOB_RUNNING)
770 j->manager->n_running_jobs--;
772 log_debug_unit(u->id, "Job %s/%s finished, result=%s",
773 u->id, job_type_to_string(t), job_result_to_string(result));
775 job_print_status_message(u, t, result);
776 job_log_status_message(u, t, result);
778 job_add_to_dbus_queue(j);
780 /* Patch restart jobs so that they become normal start jobs */
781 if (result == JOB_DONE && t == JOB_RESTART) {
783 job_change_type(j, JOB_START);
784 j->state = JOB_WAITING;
786 job_add_to_run_queue(j);
791 if (result == JOB_FAILED || result == JOB_INVALID)
792 j->manager->n_failed_jobs ++;
797 /* Fail depending jobs on failure */
798 if (result != JOB_DONE && recursive) {
800 if (t == JOB_START ||
801 t == JOB_VERIFY_ACTIVE) {
803 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
805 (other->job->type == JOB_START ||
806 other->job->type == JOB_VERIFY_ACTIVE))
807 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
809 SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
811 (other->job->type == JOB_START ||
812 other->job->type == JOB_VERIFY_ACTIVE))
813 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
815 SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
817 !other->job->override &&
818 (other->job->type == JOB_START ||
819 other->job->type == JOB_VERIFY_ACTIVE))
820 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
822 } else if (t == JOB_STOP) {
824 SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
826 (other->job->type == JOB_START ||
827 other->job->type == JOB_VERIFY_ACTIVE))
828 job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
832 /* Trigger OnFailure dependencies that are not generated by
833 * the unit itself. We don't treat JOB_CANCELED as failure in
834 * this context. And JOB_FAILURE is already handled by the
836 if (result == JOB_TIMEOUT || result == JOB_DEPENDENCY) {
837 log_struct_unit(LOG_NOTICE,
839 "JOB_TYPE=%s", job_type_to_string(t),
840 "JOB_RESULT=%s", job_result_to_string(result),
841 "Job %s/%s failed with result '%s'.",
843 job_type_to_string(t),
844 job_result_to_string(result),
847 unit_start_on_failure(u);
850 unit_trigger_notify(u);
853 /* Try to start the next jobs that can be started */
854 SET_FOREACH(other, u->dependencies[UNIT_AFTER], i)
856 job_add_to_run_queue(other->job);
857 SET_FOREACH(other, u->dependencies[UNIT_BEFORE], i)
859 job_add_to_run_queue(other->job);
861 manager_check_finished(u->manager);
866 static int job_dispatch_timer(sd_event_source *s, uint64_t monotonic, void *userdata) {
871 assert(s == j->timer_event_source);
873 log_warning_unit(j->unit->id, "Job %s/%s timed out.", j->unit->id, job_type_to_string(j->type));
876 job_finish_and_invalidate(j, JOB_TIMEOUT, true);
878 failure_action(u->manager, u->job_timeout_action, u->job_timeout_reboot_arg);
883 int job_start_timer(Job *j) {
886 if (j->timer_event_source)
889 j->begin_usec = now(CLOCK_MONOTONIC);
891 if (j->unit->job_timeout <= 0)
894 r = sd_event_add_time(
896 &j->timer_event_source,
898 j->begin_usec + j->unit->job_timeout, 0,
899 job_dispatch_timer, j);
906 void job_add_to_run_queue(Job *j) {
908 assert(j->installed);
913 if (!j->manager->run_queue)
914 sd_event_source_set_enabled(j->manager->run_queue_event_source, SD_EVENT_ONESHOT);
916 LIST_PREPEND(run_queue, j->manager->run_queue, j);
917 j->in_run_queue = true;
920 void job_add_to_dbus_queue(Job *j) {
922 assert(j->installed);
924 if (j->in_dbus_queue)
927 /* We don't check if anybody is subscribed here, since this
928 * job might just have been created and not yet assigned to a
929 * connection/client. */
931 LIST_PREPEND(dbus_queue, j->manager->dbus_job_queue, j);
932 j->in_dbus_queue = true;
935 char *job_dbus_path(Job *j) {
940 if (asprintf(&p, "/org/freedesktop/systemd1/job/%"PRIu32, j->id) < 0)
946 int job_serialize(Job *j, FILE *f, FDSet *fds) {
947 fprintf(f, "job-id=%u\n", j->id);
948 fprintf(f, "job-type=%s\n", job_type_to_string(j->type));
949 fprintf(f, "job-state=%s\n", job_state_to_string(j->state));
950 fprintf(f, "job-override=%s\n", yes_no(j->override));
951 fprintf(f, "job-irreversible=%s\n", yes_no(j->irreversible));
952 fprintf(f, "job-sent-dbus-new-signal=%s\n", yes_no(j->sent_dbus_new_signal));
953 fprintf(f, "job-ignore-order=%s\n", yes_no(j->ignore_order));
955 if (j->begin_usec > 0)
956 fprintf(f, "job-begin="USEC_FMT"\n", j->begin_usec);
958 bus_track_serialize(j->clients, f);
965 int job_deserialize(Job *j, FILE *f, FDSet *fds) {
969 char line[LINE_MAX], *l, *v;
972 if (!fgets(line, sizeof(line), f)) {
993 if (streq(l, "job-id")) {
995 if (safe_atou32(v, &j->id) < 0)
996 log_debug("Failed to parse job id value %s", v);
998 } else if (streq(l, "job-type")) {
1001 t = job_type_from_string(v);
1003 log_debug("Failed to parse job type %s", v);
1004 else if (t >= _JOB_TYPE_MAX_IN_TRANSACTION)
1005 log_debug("Cannot deserialize job of type %s", v);
1009 } else if (streq(l, "job-state")) {
1012 s = job_state_from_string(v);
1014 log_debug("Failed to parse job state %s", v);
1018 } else if (streq(l, "job-override")) {
1021 b = parse_boolean(v);
1023 log_debug("Failed to parse job override flag %s", v);
1025 j->override = j->override || b;
1027 } else if (streq(l, "job-irreversible")) {
1030 b = parse_boolean(v);
1032 log_debug("Failed to parse job irreversible flag %s", v);
1034 j->irreversible = j->irreversible || b;
1036 } else if (streq(l, "job-sent-dbus-new-signal")) {
1039 b = parse_boolean(v);
1041 log_debug("Failed to parse job sent_dbus_new_signal flag %s", v);
1043 j->sent_dbus_new_signal = j->sent_dbus_new_signal || b;
1045 } else if (streq(l, "job-ignore-order")) {
1048 b = parse_boolean(v);
1050 log_debug("Failed to parse job ignore_order flag %s", v);
1052 j->ignore_order = j->ignore_order || b;
1054 } else if (streq(l, "job-begin")) {
1055 unsigned long long ull;
1057 if (sscanf(v, "%llu", &ull) != 1)
1058 log_debug("Failed to parse job-begin value %s", v);
1060 j->begin_usec = ull;
1062 } else if (streq(l, "subscribed")) {
1064 if (strv_extend(&j->deserialized_clients, v) < 0)
1070 int job_coldplug(Job *j) {
1075 /* After deserialization is complete and the bus connection
1076 * set up again, let's start watching our subscribers again */
1077 r = bus_track_coldplug(j->manager, &j->clients, &j->deserialized_clients);
1081 if (j->state == JOB_WAITING)
1082 job_add_to_run_queue(j);
1084 if (j->begin_usec == 0 || j->unit->job_timeout == 0)
1087 if (j->timer_event_source)
1088 j->timer_event_source = sd_event_source_unref(j->timer_event_source);
1090 r = sd_event_add_time(
1092 &j->timer_event_source,
1094 j->begin_usec + j->unit->job_timeout, 0,
1095 job_dispatch_timer, j);
1097 log_debug("Failed to restart timeout for job: %s", strerror(-r));
1102 void job_shutdown_magic(Job *j) {
1105 /* The shutdown target gets some special treatment here: we
1106 * tell the kernel to begin with flushing its disk caches, to
1107 * optimize shutdown time a bit. Ideally we wouldn't hardcode
1108 * this magic into PID 1. However all other processes aren't
1109 * options either since they'd exit much sooner than PID 1 and
1110 * asynchronous sync() would cause their exit to be
1113 if (j->type != JOB_START)
1116 if (j->unit->manager->running_as != SYSTEMD_SYSTEM)
1119 if (!unit_has_name(j->unit, SPECIAL_SHUTDOWN_TARGET))
1122 /* In case messages on console has been disabled on boot */
1123 j->unit->manager->no_console_output = false;
1125 if (detect_container(NULL) > 0)
1128 asynchronous_sync();
1131 int job_get_timeout(Job *j, uint64_t *timeout) {
1133 uint64_t x = -1, y = -1;
1138 if (j->timer_event_source) {
1139 r = sd_event_source_get_time(j->timer_event_source, &x);
1145 if (UNIT_VTABLE(u)->get_timeout) {
1146 q = UNIT_VTABLE(u)->get_timeout(u, &y);
1151 if (r == 0 && q == 0)
1154 *timeout = MIN(x, y);
1159 static const char* const job_state_table[_JOB_STATE_MAX] = {
1160 [JOB_WAITING] = "waiting",
1161 [JOB_RUNNING] = "running"
1164 DEFINE_STRING_TABLE_LOOKUP(job_state, JobState);
1166 static const char* const job_type_table[_JOB_TYPE_MAX] = {
1167 [JOB_START] = "start",
1168 [JOB_VERIFY_ACTIVE] = "verify-active",
1169 [JOB_STOP] = "stop",
1170 [JOB_RELOAD] = "reload",
1171 [JOB_RELOAD_OR_START] = "reload-or-start",
1172 [JOB_RESTART] = "restart",
1173 [JOB_TRY_RESTART] = "try-restart",
1177 DEFINE_STRING_TABLE_LOOKUP(job_type, JobType);
1179 static const char* const job_mode_table[_JOB_MODE_MAX] = {
1180 [JOB_FAIL] = "fail",
1181 [JOB_REPLACE] = "replace",
1182 [JOB_REPLACE_IRREVERSIBLY] = "replace-irreversibly",
1183 [JOB_ISOLATE] = "isolate",
1184 [JOB_FLUSH] = "flush",
1185 [JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
1186 [JOB_IGNORE_REQUIREMENTS] = "ignore-requirements",
1189 DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);
1191 static const char* const job_result_table[_JOB_RESULT_MAX] = {
1192 [JOB_DONE] = "done",
1193 [JOB_CANCELED] = "canceled",
1194 [JOB_TIMEOUT] = "timeout",
1195 [JOB_FAILED] = "failed",
1196 [JOB_DEPENDENCY] = "dependency",
1197 [JOB_SKIPPED] = "skipped",
1198 [JOB_INVALID] = "invalid",
1199 [JOB_ASSERT] = "assert",
1202 DEFINE_STRING_TABLE_LOOKUP(job_result, JobResult);