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/>.
25 #include "sd-messages.h"
27 #include "alloc-util.h"
35 #include "parse-util.h"
38 #include "stdio-util.h"
39 #include "string-table.h"
40 #include "string-util.h"
42 #include "terminal-util.h"
46 Job
* job_new_raw(Unit
*unit
) {
49 /* used for deserialization */
57 j
->manager
= unit
->manager
;
59 j
->type
= _JOB_TYPE_INVALID
;
64 Job
* job_new(Unit
*unit
, JobType type
) {
67 assert(type
< _JOB_TYPE_MAX
);
69 j
= job_new_raw(unit
);
73 j
->id
= j
->manager
->current_job_id
++;
76 /* We don't link it here, that's what job_dependency() is for */
81 void job_free(Job
*j
) {
83 assert(!j
->installed
);
84 assert(!j
->transaction_prev
);
85 assert(!j
->transaction_next
);
86 assert(!j
->subject_list
);
87 assert(!j
->object_list
);
90 LIST_REMOVE(run_queue
, j
->manager
->run_queue
, j
);
93 LIST_REMOVE(dbus_queue
, j
->manager
->dbus_job_queue
, j
);
95 sd_event_source_unref(j
->timer_event_source
);
97 sd_bus_track_unref(j
->clients
);
98 strv_free(j
->deserialized_clients
);
103 static void job_set_state(Job
*j
, JobState state
) {
106 assert(state
< _JOB_STATE_MAX
);
108 if (j
->state
== state
)
116 if (j
->state
== JOB_RUNNING
)
117 j
->unit
->manager
->n_running_jobs
++;
119 assert(j
->state
== JOB_WAITING
);
120 assert(j
->unit
->manager
->n_running_jobs
> 0);
122 j
->unit
->manager
->n_running_jobs
--;
124 if (j
->unit
->manager
->n_running_jobs
<= 0)
125 j
->unit
->manager
->jobs_in_progress_event_source
= sd_event_source_unref(j
->unit
->manager
->jobs_in_progress_event_source
);
129 void job_uninstall(Job
*j
) {
132 assert(j
->installed
);
134 job_set_state(j
, JOB_WAITING
);
136 pj
= (j
->type
== JOB_NOP
) ? &j
->unit
->nop_job
: &j
->unit
->job
;
139 /* Detach from next 'bigger' objects */
141 /* daemon-reload should be transparent to job observers */
142 if (j
->manager
->n_reloading
<= 0)
143 bus_job_send_removed_signal(j
);
147 unit_add_to_gc_queue(j
->unit
);
149 hashmap_remove(j
->manager
->jobs
, UINT32_TO_PTR(j
->id
));
150 j
->installed
= false;
153 static bool job_type_allows_late_merge(JobType t
) {
154 /* Tells whether it is OK to merge a job of type 't' with an already
156 * Reloads cannot be merged this way. Think of the sequence:
157 * 1. Reload of a daemon is in progress; the daemon has already loaded
158 * its config file, but hasn't completed the reload operation yet.
159 * 2. Edit foo's config file.
160 * 3. Trigger another reload to have the daemon use the new config.
161 * Should the second reload job be merged into the first one, the daemon
162 * would not know about the new config.
163 * JOB_RESTART jobs on the other hand can be merged, because they get
164 * patched into JOB_START after stopping the unit. So if we see a
165 * JOB_RESTART running, it means the unit hasn't stopped yet and at
166 * this time the merge is still allowed. */
167 return t
!= JOB_RELOAD
;
170 static void job_merge_into_installed(Job
*j
, Job
*other
) {
171 assert(j
->installed
);
172 assert(j
->unit
== other
->unit
);
174 if (j
->type
!= JOB_NOP
)
175 job_type_merge_and_collapse(&j
->type
, other
->type
, j
->unit
);
177 assert(other
->type
== JOB_NOP
);
179 j
->irreversible
= j
->irreversible
|| other
->irreversible
;
180 j
->ignore_order
= j
->ignore_order
|| other
->ignore_order
;
183 Job
* job_install(Job
*j
) {
187 assert(!j
->installed
);
188 assert(j
->type
< _JOB_TYPE_MAX_IN_TRANSACTION
);
189 assert(j
->state
== JOB_WAITING
);
191 pj
= (j
->type
== JOB_NOP
) ? &j
->unit
->nop_job
: &j
->unit
->job
;
195 if (job_type_is_conflicting(uj
->type
, j
->type
))
196 job_finish_and_invalidate(uj
, JOB_CANCELED
, false);
198 /* not conflicting, i.e. mergeable */
200 if (uj
->state
== JOB_WAITING
||
201 (job_type_allows_late_merge(j
->type
) && job_type_is_superset(uj
->type
, j
->type
))) {
202 job_merge_into_installed(uj
, j
);
203 log_unit_debug(uj
->unit
,
204 "Merged into installed job %s/%s as %u",
205 uj
->unit
->id
, job_type_to_string(uj
->type
), (unsigned) uj
->id
);
208 /* already running and not safe to merge into */
209 /* Patch uj to become a merged job and re-run it. */
210 /* XXX It should be safer to queue j to run after uj finishes, but it is
211 * not currently possible to have more than one installed job per unit. */
212 job_merge_into_installed(uj
, j
);
213 log_unit_debug(uj
->unit
,
214 "Merged into running job, re-running: %s/%s as %u",
215 uj
->unit
->id
, job_type_to_string(uj
->type
), (unsigned) uj
->id
);
217 job_set_state(uj
, JOB_WAITING
);
223 /* Install the job */
227 j
->manager
->n_installed_jobs
++;
228 log_unit_debug(j
->unit
,
229 "Installed new job %s/%s as %u",
230 j
->unit
->id
, job_type_to_string(j
->type
), (unsigned) j
->id
);
234 int job_install_deserialized(Job
*j
) {
237 assert(!j
->installed
);
239 if (j
->type
< 0 || j
->type
>= _JOB_TYPE_MAX_IN_TRANSACTION
) {
240 log_debug("Invalid job type %s in deserialization.", strna(job_type_to_string(j
->type
)));
244 pj
= (j
->type
== JOB_NOP
) ? &j
->unit
->nop_job
: &j
->unit
->job
;
246 log_unit_debug(j
->unit
, "Unit already has a job installed. Not installing deserialized job.");
253 if (j
->state
== JOB_RUNNING
)
254 j
->unit
->manager
->n_running_jobs
++;
256 log_unit_debug(j
->unit
,
257 "Reinstalled deserialized job %s/%s as %u",
258 j
->unit
->id
, job_type_to_string(j
->type
), (unsigned) j
->id
);
262 JobDependency
* job_dependency_new(Job
*subject
, Job
*object
, bool matters
, bool conflicts
) {
267 /* Adds a new job link, which encodes that the 'subject' job
268 * needs the 'object' job in some way. If 'subject' is NULL
269 * this means the 'anchor' job (i.e. the one the user
270 * explicitly asked for) is the requester. */
272 if (!(l
= new0(JobDependency
, 1)))
275 l
->subject
= subject
;
277 l
->matters
= matters
;
278 l
->conflicts
= conflicts
;
281 LIST_PREPEND(subject
, subject
->subject_list
, l
);
283 LIST_PREPEND(object
, object
->object_list
, l
);
288 void job_dependency_free(JobDependency
*l
) {
292 LIST_REMOVE(subject
, l
->subject
->subject_list
, l
);
294 LIST_REMOVE(object
, l
->object
->object_list
, l
);
299 void job_dump(Job
*j
, FILE*f
, const char *prefix
) {
308 "%s\tAction: %s -> %s\n"
310 "%s\tIrreversible: %s\n",
312 prefix
, j
->unit
->id
, job_type_to_string(j
->type
),
313 prefix
, job_state_to_string(j
->state
),
314 prefix
, yes_no(j
->irreversible
));
318 * Merging is commutative, so imagine the matrix as symmetric. We store only
319 * its lower triangle to avoid duplication. We don't store the main diagonal,
320 * because A merged with A is simply A.
322 * If the resulting type is collapsed immediately afterwards (to get rid of
323 * the JOB_RELOAD_OR_START, which lies outside the lookup function's domain),
324 * the following properties hold:
326 * Merging is associative! A merged with B, and then merged with C is the same
327 * as A merged with the result of B merged with C.
329 * Mergeability is transitive! If A can be merged with B and B with C then
332 * Also, if A merged with B cannot be merged with C, then either A or B cannot
333 * be merged with C either.
335 static const JobType job_merging_table
[] = {
336 /* What \ With * JOB_START JOB_VERIFY_ACTIVE JOB_STOP JOB_RELOAD */
337 /*********************************************************************************/
339 /*JOB_VERIFY_ACTIVE */ JOB_START
,
340 /*JOB_STOP */ -1, -1,
341 /*JOB_RELOAD */ JOB_RELOAD_OR_START
, JOB_RELOAD
, -1,
342 /*JOB_RESTART */ JOB_RESTART
, JOB_RESTART
, -1, JOB_RESTART
,
345 JobType
job_type_lookup_merge(JobType a
, JobType b
) {
346 assert_cc(ELEMENTSOF(job_merging_table
) == _JOB_TYPE_MAX_MERGING
* (_JOB_TYPE_MAX_MERGING
- 1) / 2);
347 assert(a
>= 0 && a
< _JOB_TYPE_MAX_MERGING
);
348 assert(b
>= 0 && b
< _JOB_TYPE_MAX_MERGING
);
359 return job_merging_table
[(a
- 1) * a
/ 2 + b
];
362 bool job_type_is_redundant(JobType a
, UnitActiveState b
) {
372 b
== UNIT_INACTIVE
||
375 case JOB_VERIFY_ACTIVE
:
386 b
== UNIT_ACTIVATING
;
392 assert_not_reached("Invalid job type");
396 JobType
job_type_collapse(JobType t
, Unit
*u
) {
401 case JOB_TRY_RESTART
:
402 s
= unit_active_state(u
);
403 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s
))
408 case JOB_RELOAD_OR_START
:
409 s
= unit_active_state(u
);
410 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s
))
420 int job_type_merge_and_collapse(JobType
*a
, JobType b
, Unit
*u
) {
423 t
= job_type_lookup_merge(*a
, b
);
427 *a
= job_type_collapse(t
, u
);
431 static bool job_is_runnable(Job
*j
) {
436 assert(j
->installed
);
438 /* Checks whether there is any job running for the units this
439 * job needs to be running after (in the case of a 'positive'
440 * job type) or before (in the case of a 'negative' job
443 /* Note that unit types have a say in what is runnable,
444 * too. For example, if they return -EAGAIN from
445 * unit_start() they can indicate they are not
448 /* First check if there is an override */
452 if (j
->type
== JOB_NOP
)
455 if (j
->type
== JOB_START
||
456 j
->type
== JOB_VERIFY_ACTIVE
||
457 j
->type
== JOB_RELOAD
) {
459 /* Immediate result is that the job is or might be
460 * started. In this case let's wait for the
461 * dependencies, regardless whether they are
462 * starting or stopping something. */
464 SET_FOREACH(other
, j
->unit
->dependencies
[UNIT_AFTER
], i
)
469 /* Also, if something else is being stopped and we should
470 * change state after it, then let's wait. */
472 SET_FOREACH(other
, j
->unit
->dependencies
[UNIT_BEFORE
], i
)
474 (other
->job
->type
== JOB_STOP
||
475 other
->job
->type
== JOB_RESTART
))
478 /* This means that for a service a and a service b where b
479 * shall be started after a:
481 * start a + start b → 1st step start a, 2nd step start b
482 * start a + stop b → 1st step stop b, 2nd step start a
483 * stop a + start b → 1st step stop a, 2nd step start b
484 * stop a + stop b → 1st step stop b, 2nd step stop a
486 * This has the side effect that restarts are properly
487 * synchronized too. */
492 static void job_change_type(Job
*j
, JobType newtype
) {
495 log_unit_debug(j
->unit
,
496 "Converting job %s/%s -> %s/%s",
497 j
->unit
->id
, job_type_to_string(j
->type
),
498 j
->unit
->id
, job_type_to_string(newtype
));
503 static int job_perform_on_unit(Job
**j
) {
510 /* While we execute this operation the job might go away (for
511 * example: because it finishes immediately or is replaced by
512 * a new, conflicting job.) To make sure we don't access a
513 * freed job later on we store the id here, so that we can
514 * verify the job is still valid. */
541 assert_not_reached("Invalid job type");
544 /* Log if the job still exists and the start/stop/reload function
545 * actually did something. */
546 *j
= manager_get_job(m
, id
);
548 unit_status_emit_starting_stopping_reloading(u
, t
);
553 int job_run_and_invalidate(Job
*j
) {
557 assert(j
->installed
);
558 assert(j
->type
< _JOB_TYPE_MAX_IN_TRANSACTION
);
559 assert(j
->in_run_queue
);
561 LIST_REMOVE(run_queue
, j
->manager
->run_queue
, j
);
562 j
->in_run_queue
= false;
564 if (j
->state
!= JOB_WAITING
)
567 if (!job_is_runnable(j
))
570 job_set_state(j
, JOB_RUNNING
);
571 job_add_to_dbus_queue(j
);
576 case JOB_VERIFY_ACTIVE
: {
577 UnitActiveState t
= unit_active_state(j
->unit
);
578 if (UNIT_IS_ACTIVE_OR_RELOADING(t
))
580 else if (t
== UNIT_ACTIVATING
)
590 r
= job_perform_on_unit(&j
);
592 /* If the unit type does not support starting/stopping,
593 * then simply wait. */
599 r
= job_perform_on_unit(&j
);
607 assert_not_reached("Unknown job type");
612 r
= job_finish_and_invalidate(j
, JOB_DONE
, true);
613 else if (r
== -EBADR
)
614 r
= job_finish_and_invalidate(j
, JOB_SKIPPED
, true);
615 else if (r
== -ENOEXEC
)
616 r
= job_finish_and_invalidate(j
, JOB_INVALID
, true);
617 else if (r
== -EPROTO
)
618 r
= job_finish_and_invalidate(j
, JOB_ASSERT
, true);
619 else if (r
== -EOPNOTSUPP
)
620 r
= job_finish_and_invalidate(j
, JOB_UNSUPPORTED
, true);
621 else if (r
== -EAGAIN
)
622 job_set_state(j
, JOB_WAITING
);
624 r
= job_finish_and_invalidate(j
, JOB_FAILED
, true);
630 _pure_
static const char *job_get_status_message_format(Unit
*u
, JobType t
, JobResult result
) {
632 static const char *const generic_finished_start_job
[_JOB_RESULT_MAX
] = {
633 [JOB_DONE
] = "Started %s.",
634 [JOB_TIMEOUT
] = "Timed out starting %s.",
635 [JOB_FAILED
] = "Failed to start %s.",
636 [JOB_DEPENDENCY
] = "Dependency failed for %s.",
637 [JOB_ASSERT
] = "Assertion failed for %s.",
638 [JOB_UNSUPPORTED
] = "Starting of %s not supported.",
640 static const char *const generic_finished_stop_job
[_JOB_RESULT_MAX
] = {
641 [JOB_DONE
] = "Stopped %s.",
642 [JOB_FAILED
] = "Stopped (with error) %s.",
643 [JOB_TIMEOUT
] = "Timed out stoppping %s.",
645 static const char *const generic_finished_reload_job
[_JOB_RESULT_MAX
] = {
646 [JOB_DONE
] = "Reloaded %s.",
647 [JOB_FAILED
] = "Reload failed for %s.",
648 [JOB_TIMEOUT
] = "Timed out reloading %s.",
650 /* When verify-active detects the unit is inactive, report it.
651 * Most likely a DEPEND warning from a requisiting unit will
652 * occur next and it's nice to see what was requisited. */
653 static const char *const generic_finished_verify_active_job
[_JOB_RESULT_MAX
] = {
654 [JOB_SKIPPED
] = "%s is not active.",
657 const UnitStatusMessageFormats
*format_table
;
662 assert(t
< _JOB_TYPE_MAX
);
664 if (IN_SET(t
, JOB_START
, JOB_STOP
, JOB_RESTART
)) {
665 format_table
= &UNIT_VTABLE(u
)->status_message_formats
;
667 format
= t
== JOB_START
? format_table
->finished_start_job
[result
] :
668 format_table
->finished_stop_job
[result
];
674 /* Return generic strings */
676 return generic_finished_start_job
[result
];
677 else if (t
== JOB_STOP
|| t
== JOB_RESTART
)
678 return generic_finished_stop_job
[result
];
679 else if (t
== JOB_RELOAD
)
680 return generic_finished_reload_job
[result
];
681 else if (t
== JOB_VERIFY_ACTIVE
)
682 return generic_finished_verify_active_job
[result
];
687 static void job_print_status_message(Unit
*u
, JobType t
, JobResult result
) {
688 static const char* const job_result_status_table
[_JOB_RESULT_MAX
] = {
689 [JOB_DONE
] = ANSI_GREEN
" OK " ANSI_NORMAL
,
690 [JOB_TIMEOUT
] = ANSI_HIGHLIGHT_RED
" TIME " ANSI_NORMAL
,
691 [JOB_FAILED
] = ANSI_HIGHLIGHT_RED
"FAILED" ANSI_NORMAL
,
692 [JOB_DEPENDENCY
] = ANSI_HIGHLIGHT_YELLOW
"DEPEND" ANSI_NORMAL
,
693 [JOB_SKIPPED
] = ANSI_HIGHLIGHT
" INFO " ANSI_NORMAL
,
694 [JOB_ASSERT
] = ANSI_HIGHLIGHT_YELLOW
"ASSERT" ANSI_NORMAL
,
695 [JOB_UNSUPPORTED
] = ANSI_HIGHLIGHT_YELLOW
"UNSUPP" ANSI_NORMAL
,
702 assert(t
< _JOB_TYPE_MAX
);
704 /* Reload status messages have traditionally not been printed to console. */
708 format
= job_get_status_message_format(u
, t
, result
);
712 if (result
!= JOB_DONE
)
713 manager_flip_auto_status(u
->manager
, true);
715 DISABLE_WARNING_FORMAT_NONLITERAL
;
716 unit_status_printf(u
, job_result_status_table
[result
], format
);
719 if (t
== JOB_START
&& result
== JOB_FAILED
) {
720 _cleanup_free_
char *quoted
;
722 quoted
= shell_maybe_quote(u
->id
);
723 manager_status_printf(u
->manager
, STATUS_TYPE_NORMAL
, NULL
, "See 'systemctl status %s' for details.", strna(quoted
));
727 static void job_log_status_message(Unit
*u
, JobType t
, JobResult result
) {
731 static const int job_result_log_level
[_JOB_RESULT_MAX
] = {
732 [JOB_DONE
] = LOG_INFO
,
733 [JOB_CANCELED
] = LOG_INFO
,
734 [JOB_TIMEOUT
] = LOG_ERR
,
735 [JOB_FAILED
] = LOG_ERR
,
736 [JOB_DEPENDENCY
] = LOG_WARNING
,
737 [JOB_SKIPPED
] = LOG_NOTICE
,
738 [JOB_INVALID
] = LOG_INFO
,
739 [JOB_ASSERT
] = LOG_WARNING
,
740 [JOB_UNSUPPORTED
] = LOG_WARNING
,
745 assert(t
< _JOB_TYPE_MAX
);
747 /* Skip this if it goes to the console. since we already print
748 * to the console anyway... */
750 if (log_on_console())
753 format
= job_get_status_message_format(u
, t
, result
);
757 DISABLE_WARNING_FORMAT_NONLITERAL
;
758 xsprintf(buf
, format
, unit_description(u
));
764 mid
= result
== JOB_DONE
? SD_MESSAGE_UNIT_STARTED
: SD_MESSAGE_UNIT_FAILED
;
768 mid
= SD_MESSAGE_UNIT_RELOADED
;
773 mid
= SD_MESSAGE_UNIT_STOPPED
;
777 log_struct(job_result_log_level
[result
],
779 LOG_MESSAGE("%s", buf
),
780 "RESULT=%s", job_result_to_string(result
),
785 log_struct(job_result_log_level
[result
],
788 LOG_MESSAGE("%s", buf
),
789 "RESULT=%s", job_result_to_string(result
),
793 static void job_emit_status_message(Unit
*u
, JobType t
, JobResult result
) {
795 /* No message if the job did not actually do anything due to failed condition. */
796 if (t
== JOB_START
&& result
== JOB_DONE
&& !u
->condition_result
)
799 job_log_status_message(u
, t
, result
);
800 job_print_status_message(u
, t
, result
);
803 static void job_fail_dependencies(Unit
*u
, UnitDependency d
) {
809 SET_FOREACH(other
, u
->dependencies
[d
], i
) {
814 if (!IN_SET(j
->type
, JOB_START
, JOB_VERIFY_ACTIVE
))
817 job_finish_and_invalidate(j
, JOB_DEPENDENCY
, true);
821 int job_finish_and_invalidate(Job
*j
, JobResult result
, bool recursive
) {
828 assert(j
->installed
);
829 assert(j
->type
< _JOB_TYPE_MAX_IN_TRANSACTION
);
836 log_unit_debug(u
, "Job %s/%s finished, result=%s", u
->id
, job_type_to_string(t
), job_result_to_string(result
));
838 job_emit_status_message(u
, t
, result
);
840 job_add_to_dbus_queue(j
);
842 /* Patch restart jobs so that they become normal start jobs */
843 if (result
== JOB_DONE
&& t
== JOB_RESTART
) {
845 job_change_type(j
, JOB_START
);
846 job_set_state(j
, JOB_WAITING
);
848 job_add_to_run_queue(j
);
853 if (result
== JOB_FAILED
|| result
== JOB_INVALID
)
854 j
->manager
->n_failed_jobs
++;
859 /* Fail depending jobs on failure */
860 if (result
!= JOB_DONE
&& recursive
) {
861 if (IN_SET(t
, JOB_START
, JOB_VERIFY_ACTIVE
)) {
862 job_fail_dependencies(u
, UNIT_REQUIRED_BY
);
863 job_fail_dependencies(u
, UNIT_REQUISITE_OF
);
864 job_fail_dependencies(u
, UNIT_BOUND_BY
);
865 } else if (t
== JOB_STOP
)
866 job_fail_dependencies(u
, UNIT_CONFLICTED_BY
);
869 /* Trigger OnFailure dependencies that are not generated by
870 * the unit itself. We don't treat JOB_CANCELED as failure in
871 * this context. And JOB_FAILURE is already handled by the
873 if (result
== JOB_TIMEOUT
|| result
== JOB_DEPENDENCY
) {
874 log_struct(LOG_NOTICE
,
875 "JOB_TYPE=%s", job_type_to_string(t
),
876 "JOB_RESULT=%s", job_result_to_string(result
),
878 LOG_UNIT_MESSAGE(u
, "Job %s/%s failed with result '%s'.",
880 job_type_to_string(t
),
881 job_result_to_string(result
)),
884 unit_start_on_failure(u
);
887 unit_trigger_notify(u
);
890 /* Try to start the next jobs that can be started */
891 SET_FOREACH(other
, u
->dependencies
[UNIT_AFTER
], i
)
893 job_add_to_run_queue(other
->job
);
894 SET_FOREACH(other
, u
->dependencies
[UNIT_BEFORE
], i
)
896 job_add_to_run_queue(other
->job
);
898 manager_check_finished(u
->manager
);
903 static int job_dispatch_timer(sd_event_source
*s
, uint64_t monotonic
, void *userdata
) {
908 assert(s
== j
->timer_event_source
);
910 log_unit_warning(j
->unit
, "Job %s/%s timed out.", j
->unit
->id
, job_type_to_string(j
->type
));
913 job_finish_and_invalidate(j
, JOB_TIMEOUT
, true);
915 failure_action(u
->manager
, u
->job_timeout_action
, u
->job_timeout_reboot_arg
);
920 int job_start_timer(Job
*j
) {
923 if (j
->timer_event_source
)
926 j
->begin_usec
= now(CLOCK_MONOTONIC
);
928 if (j
->unit
->job_timeout
<= 0)
931 r
= sd_event_add_time(
933 &j
->timer_event_source
,
935 j
->begin_usec
+ j
->unit
->job_timeout
, 0,
936 job_dispatch_timer
, j
);
940 (void) sd_event_source_set_description(j
->timer_event_source
, "job-start");
945 void job_add_to_run_queue(Job
*j
) {
947 assert(j
->installed
);
952 if (!j
->manager
->run_queue
)
953 sd_event_source_set_enabled(j
->manager
->run_queue_event_source
, SD_EVENT_ONESHOT
);
955 LIST_PREPEND(run_queue
, j
->manager
->run_queue
, j
);
956 j
->in_run_queue
= true;
959 void job_add_to_dbus_queue(Job
*j
) {
961 assert(j
->installed
);
963 if (j
->in_dbus_queue
)
966 /* We don't check if anybody is subscribed here, since this
967 * job might just have been created and not yet assigned to a
968 * connection/client. */
970 LIST_PREPEND(dbus_queue
, j
->manager
->dbus_job_queue
, j
);
971 j
->in_dbus_queue
= true;
974 char *job_dbus_path(Job
*j
) {
979 if (asprintf(&p
, "/org/freedesktop/systemd1/job/%"PRIu32
, j
->id
) < 0)
985 int job_serialize(Job
*j
, FILE *f
, FDSet
*fds
) {
986 fprintf(f
, "job-id=%u\n", j
->id
);
987 fprintf(f
, "job-type=%s\n", job_type_to_string(j
->type
));
988 fprintf(f
, "job-state=%s\n", job_state_to_string(j
->state
));
989 fprintf(f
, "job-irreversible=%s\n", yes_no(j
->irreversible
));
990 fprintf(f
, "job-sent-dbus-new-signal=%s\n", yes_no(j
->sent_dbus_new_signal
));
991 fprintf(f
, "job-ignore-order=%s\n", yes_no(j
->ignore_order
));
993 if (j
->begin_usec
> 0)
994 fprintf(f
, "job-begin="USEC_FMT
"\n", j
->begin_usec
);
996 bus_track_serialize(j
->clients
, f
);
1003 int job_deserialize(Job
*j
, FILE *f
, FDSet
*fds
) {
1007 char line
[LINE_MAX
], *l
, *v
;
1010 if (!fgets(line
, sizeof(line
), f
)) {
1023 k
= strcspn(l
, "=");
1031 if (streq(l
, "job-id")) {
1033 if (safe_atou32(v
, &j
->id
) < 0)
1034 log_debug("Failed to parse job id value %s", v
);
1036 } else if (streq(l
, "job-type")) {
1039 t
= job_type_from_string(v
);
1041 log_debug("Failed to parse job type %s", v
);
1042 else if (t
>= _JOB_TYPE_MAX_IN_TRANSACTION
)
1043 log_debug("Cannot deserialize job of type %s", v
);
1047 } else if (streq(l
, "job-state")) {
1050 s
= job_state_from_string(v
);
1052 log_debug("Failed to parse job state %s", v
);
1054 job_set_state(j
, s
);
1056 } else if (streq(l
, "job-irreversible")) {
1059 b
= parse_boolean(v
);
1061 log_debug("Failed to parse job irreversible flag %s", v
);
1063 j
->irreversible
= j
->irreversible
|| b
;
1065 } else if (streq(l
, "job-sent-dbus-new-signal")) {
1068 b
= parse_boolean(v
);
1070 log_debug("Failed to parse job sent_dbus_new_signal flag %s", v
);
1072 j
->sent_dbus_new_signal
= j
->sent_dbus_new_signal
|| b
;
1074 } else if (streq(l
, "job-ignore-order")) {
1077 b
= parse_boolean(v
);
1079 log_debug("Failed to parse job ignore_order flag %s", v
);
1081 j
->ignore_order
= j
->ignore_order
|| b
;
1083 } else if (streq(l
, "job-begin")) {
1084 unsigned long long ull
;
1086 if (sscanf(v
, "%llu", &ull
) != 1)
1087 log_debug("Failed to parse job-begin value %s", v
);
1089 j
->begin_usec
= ull
;
1091 } else if (streq(l
, "subscribed")) {
1093 if (strv_extend(&j
->deserialized_clients
, v
) < 0)
1099 int job_coldplug(Job
*j
) {
1104 /* After deserialization is complete and the bus connection
1105 * set up again, let's start watching our subscribers again */
1106 r
= bus_track_coldplug(j
->manager
, &j
->clients
, &j
->deserialized_clients
);
1110 if (j
->state
== JOB_WAITING
)
1111 job_add_to_run_queue(j
);
1113 if (j
->begin_usec
== 0 || j
->unit
->job_timeout
== 0)
1116 if (j
->timer_event_source
)
1117 j
->timer_event_source
= sd_event_source_unref(j
->timer_event_source
);
1119 r
= sd_event_add_time(
1121 &j
->timer_event_source
,
1123 j
->begin_usec
+ j
->unit
->job_timeout
, 0,
1124 job_dispatch_timer
, j
);
1126 log_debug_errno(r
, "Failed to restart timeout for job: %m");
1128 (void) sd_event_source_set_description(j
->timer_event_source
, "job-timeout");
1133 void job_shutdown_magic(Job
*j
) {
1136 /* The shutdown target gets some special treatment here: we
1137 * tell the kernel to begin with flushing its disk caches, to
1138 * optimize shutdown time a bit. Ideally we wouldn't hardcode
1139 * this magic into PID 1. However all other processes aren't
1140 * options either since they'd exit much sooner than PID 1 and
1141 * asynchronous sync() would cause their exit to be
1144 if (j
->type
!= JOB_START
)
1147 if (j
->unit
->manager
->running_as
!= MANAGER_SYSTEM
)
1150 if (!unit_has_name(j
->unit
, SPECIAL_SHUTDOWN_TARGET
))
1153 /* In case messages on console has been disabled on boot */
1154 j
->unit
->manager
->no_console_output
= false;
1156 if (detect_container() > 0)
1159 asynchronous_sync();
1162 int job_get_timeout(Job
*j
, uint64_t *timeout
) {
1164 uint64_t x
= -1, y
= -1;
1169 if (j
->timer_event_source
) {
1170 r
= sd_event_source_get_time(j
->timer_event_source
, &x
);
1176 if (UNIT_VTABLE(u
)->get_timeout
) {
1177 q
= UNIT_VTABLE(u
)->get_timeout(u
, &y
);
1182 if (r
== 0 && q
== 0)
1185 *timeout
= MIN(x
, y
);
1190 static const char* const job_state_table
[_JOB_STATE_MAX
] = {
1191 [JOB_WAITING
] = "waiting",
1192 [JOB_RUNNING
] = "running"
1195 DEFINE_STRING_TABLE_LOOKUP(job_state
, JobState
);
1197 static const char* const job_type_table
[_JOB_TYPE_MAX
] = {
1198 [JOB_START
] = "start",
1199 [JOB_VERIFY_ACTIVE
] = "verify-active",
1200 [JOB_STOP
] = "stop",
1201 [JOB_RELOAD
] = "reload",
1202 [JOB_RELOAD_OR_START
] = "reload-or-start",
1203 [JOB_RESTART
] = "restart",
1204 [JOB_TRY_RESTART
] = "try-restart",
1208 DEFINE_STRING_TABLE_LOOKUP(job_type
, JobType
);
1210 static const char* const job_mode_table
[_JOB_MODE_MAX
] = {
1211 [JOB_FAIL
] = "fail",
1212 [JOB_REPLACE
] = "replace",
1213 [JOB_REPLACE_IRREVERSIBLY
] = "replace-irreversibly",
1214 [JOB_ISOLATE
] = "isolate",
1215 [JOB_FLUSH
] = "flush",
1216 [JOB_IGNORE_DEPENDENCIES
] = "ignore-dependencies",
1217 [JOB_IGNORE_REQUIREMENTS
] = "ignore-requirements",
1220 DEFINE_STRING_TABLE_LOOKUP(job_mode
, JobMode
);
1222 static const char* const job_result_table
[_JOB_RESULT_MAX
] = {
1223 [JOB_DONE
] = "done",
1224 [JOB_CANCELED
] = "canceled",
1225 [JOB_TIMEOUT
] = "timeout",
1226 [JOB_FAILED
] = "failed",
1227 [JOB_DEPENDENCY
] = "dependency",
1228 [JOB_SKIPPED
] = "skipped",
1229 [JOB_INVALID
] = "invalid",
1230 [JOB_ASSERT
] = "assert",
1231 [JOB_UNSUPPORTED
] = "unsupported",
1234 DEFINE_STRING_TABLE_LOOKUP(job_result
, JobResult
);