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 "string-table.h"
39 #include "string-util.h"
41 #include "terminal-util.h"
45 Job
* job_new_raw(Unit
*unit
) {
48 /* used for deserialization */
56 j
->manager
= unit
->manager
;
58 j
->type
= _JOB_TYPE_INVALID
;
63 Job
* job_new(Unit
*unit
, JobType type
) {
66 assert(type
< _JOB_TYPE_MAX
);
68 j
= job_new_raw(unit
);
72 j
->id
= j
->manager
->current_job_id
++;
75 /* We don't link it here, that's what job_dependency() is for */
80 void job_free(Job
*j
) {
82 assert(!j
->installed
);
83 assert(!j
->transaction_prev
);
84 assert(!j
->transaction_next
);
85 assert(!j
->subject_list
);
86 assert(!j
->object_list
);
89 LIST_REMOVE(run_queue
, j
->manager
->run_queue
, j
);
92 LIST_REMOVE(dbus_queue
, j
->manager
->dbus_job_queue
, j
);
94 sd_event_source_unref(j
->timer_event_source
);
96 sd_bus_track_unref(j
->clients
);
97 strv_free(j
->deserialized_clients
);
102 static void job_set_state(Job
*j
, JobState state
) {
105 assert(state
< _JOB_STATE_MAX
);
107 if (j
->state
== state
)
115 if (j
->state
== JOB_RUNNING
)
116 j
->unit
->manager
->n_running_jobs
++;
118 assert(j
->state
== JOB_WAITING
);
119 assert(j
->unit
->manager
->n_running_jobs
> 0);
121 j
->unit
->manager
->n_running_jobs
--;
123 if (j
->unit
->manager
->n_running_jobs
<= 0)
124 j
->unit
->manager
->jobs_in_progress_event_source
= sd_event_source_unref(j
->unit
->manager
->jobs_in_progress_event_source
);
128 void job_uninstall(Job
*j
) {
131 assert(j
->installed
);
133 job_set_state(j
, JOB_WAITING
);
135 pj
= (j
->type
== JOB_NOP
) ? &j
->unit
->nop_job
: &j
->unit
->job
;
138 /* Detach from next 'bigger' objects */
140 /* daemon-reload should be transparent to job observers */
141 if (j
->manager
->n_reloading
<= 0)
142 bus_job_send_removed_signal(j
);
146 unit_add_to_gc_queue(j
->unit
);
148 hashmap_remove(j
->manager
->jobs
, UINT32_TO_PTR(j
->id
));
149 j
->installed
= false;
152 static bool job_type_allows_late_merge(JobType t
) {
153 /* Tells whether it is OK to merge a job of type 't' with an already
155 * Reloads cannot be merged this way. Think of the sequence:
156 * 1. Reload of a daemon is in progress; the daemon has already loaded
157 * its config file, but hasn't completed the reload operation yet.
158 * 2. Edit foo's config file.
159 * 3. Trigger another reload to have the daemon use the new config.
160 * Should the second reload job be merged into the first one, the daemon
161 * would not know about the new config.
162 * JOB_RESTART jobs on the other hand can be merged, because they get
163 * patched into JOB_START after stopping the unit. So if we see a
164 * JOB_RESTART running, it means the unit hasn't stopped yet and at
165 * this time the merge is still allowed. */
166 return t
!= JOB_RELOAD
;
169 static void job_merge_into_installed(Job
*j
, Job
*other
) {
170 assert(j
->installed
);
171 assert(j
->unit
== other
->unit
);
173 if (j
->type
!= JOB_NOP
)
174 job_type_merge_and_collapse(&j
->type
, other
->type
, j
->unit
);
176 assert(other
->type
== JOB_NOP
);
178 j
->irreversible
= j
->irreversible
|| other
->irreversible
;
179 j
->ignore_order
= j
->ignore_order
|| other
->ignore_order
;
182 Job
* job_install(Job
*j
) {
186 assert(!j
->installed
);
187 assert(j
->type
< _JOB_TYPE_MAX_IN_TRANSACTION
);
188 assert(j
->state
== JOB_WAITING
);
190 pj
= (j
->type
== JOB_NOP
) ? &j
->unit
->nop_job
: &j
->unit
->job
;
194 if (job_type_is_conflicting(uj
->type
, j
->type
))
195 job_finish_and_invalidate(uj
, JOB_CANCELED
, false);
197 /* not conflicting, i.e. mergeable */
199 if (uj
->state
== JOB_WAITING
||
200 (job_type_allows_late_merge(j
->type
) && job_type_is_superset(uj
->type
, j
->type
))) {
201 job_merge_into_installed(uj
, j
);
202 log_unit_debug(uj
->unit
,
203 "Merged into installed job %s/%s as %u",
204 uj
->unit
->id
, job_type_to_string(uj
->type
), (unsigned) uj
->id
);
207 /* already running and not safe to merge into */
208 /* Patch uj to become a merged job and re-run it. */
209 /* XXX It should be safer to queue j to run after uj finishes, but it is
210 * not currently possible to have more than one installed job per unit. */
211 job_merge_into_installed(uj
, j
);
212 log_unit_debug(uj
->unit
,
213 "Merged into running job, re-running: %s/%s as %u",
214 uj
->unit
->id
, job_type_to_string(uj
->type
), (unsigned) uj
->id
);
216 job_set_state(uj
, JOB_WAITING
);
222 /* Install the job */
226 j
->manager
->n_installed_jobs
++;
227 log_unit_debug(j
->unit
,
228 "Installed new job %s/%s as %u",
229 j
->unit
->id
, job_type_to_string(j
->type
), (unsigned) j
->id
);
233 int job_install_deserialized(Job
*j
) {
236 assert(!j
->installed
);
238 if (j
->type
< 0 || j
->type
>= _JOB_TYPE_MAX_IN_TRANSACTION
) {
239 log_debug("Invalid job type %s in deserialization.", strna(job_type_to_string(j
->type
)));
243 pj
= (j
->type
== JOB_NOP
) ? &j
->unit
->nop_job
: &j
->unit
->job
;
245 log_unit_debug(j
->unit
, "Unit already has a job installed. Not installing deserialized job.");
252 if (j
->state
== JOB_RUNNING
)
253 j
->unit
->manager
->n_running_jobs
++;
255 log_unit_debug(j
->unit
,
256 "Reinstalled deserialized job %s/%s as %u",
257 j
->unit
->id
, job_type_to_string(j
->type
), (unsigned) j
->id
);
261 JobDependency
* job_dependency_new(Job
*subject
, Job
*object
, bool matters
, bool conflicts
) {
266 /* Adds a new job link, which encodes that the 'subject' job
267 * needs the 'object' job in some way. If 'subject' is NULL
268 * this means the 'anchor' job (i.e. the one the user
269 * explicitly asked for) is the requester. */
271 if (!(l
= new0(JobDependency
, 1)))
274 l
->subject
= subject
;
276 l
->matters
= matters
;
277 l
->conflicts
= conflicts
;
280 LIST_PREPEND(subject
, subject
->subject_list
, l
);
282 LIST_PREPEND(object
, object
->object_list
, l
);
287 void job_dependency_free(JobDependency
*l
) {
291 LIST_REMOVE(subject
, l
->subject
->subject_list
, l
);
293 LIST_REMOVE(object
, l
->object
->object_list
, l
);
298 void job_dump(Job
*j
, FILE*f
, const char *prefix
) {
307 "%s\tAction: %s -> %s\n"
309 "%s\tIrreversible: %s\n",
311 prefix
, j
->unit
->id
, job_type_to_string(j
->type
),
312 prefix
, job_state_to_string(j
->state
),
313 prefix
, yes_no(j
->irreversible
));
317 * Merging is commutative, so imagine the matrix as symmetric. We store only
318 * its lower triangle to avoid duplication. We don't store the main diagonal,
319 * because A merged with A is simply A.
321 * If the resulting type is collapsed immediately afterwards (to get rid of
322 * the JOB_RELOAD_OR_START, which lies outside the lookup function's domain),
323 * the following properties hold:
325 * Merging is associative! A merged with B, and then merged with C is the same
326 * as A merged with the result of B merged with C.
328 * Mergeability is transitive! If A can be merged with B and B with C then
331 * Also, if A merged with B cannot be merged with C, then either A or B cannot
332 * be merged with C either.
334 static const JobType job_merging_table
[] = {
335 /* What \ With * JOB_START JOB_VERIFY_ACTIVE JOB_STOP JOB_RELOAD */
336 /*********************************************************************************/
338 /*JOB_VERIFY_ACTIVE */ JOB_START
,
339 /*JOB_STOP */ -1, -1,
340 /*JOB_RELOAD */ JOB_RELOAD_OR_START
, JOB_RELOAD
, -1,
341 /*JOB_RESTART */ JOB_RESTART
, JOB_RESTART
, -1, JOB_RESTART
,
344 JobType
job_type_lookup_merge(JobType a
, JobType b
) {
345 assert_cc(ELEMENTSOF(job_merging_table
) == _JOB_TYPE_MAX_MERGING
* (_JOB_TYPE_MAX_MERGING
- 1) / 2);
346 assert(a
>= 0 && a
< _JOB_TYPE_MAX_MERGING
);
347 assert(b
>= 0 && b
< _JOB_TYPE_MAX_MERGING
);
358 return job_merging_table
[(a
- 1) * a
/ 2 + b
];
361 bool job_type_is_redundant(JobType a
, UnitActiveState b
) {
371 b
== UNIT_INACTIVE
||
374 case JOB_VERIFY_ACTIVE
:
385 b
== UNIT_ACTIVATING
;
391 assert_not_reached("Invalid job type");
395 JobType
job_type_collapse(JobType t
, Unit
*u
) {
400 case JOB_TRY_RESTART
:
401 s
= unit_active_state(u
);
402 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s
))
407 case JOB_RELOAD_OR_START
:
408 s
= unit_active_state(u
);
409 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s
))
419 int job_type_merge_and_collapse(JobType
*a
, JobType b
, Unit
*u
) {
422 t
= job_type_lookup_merge(*a
, b
);
426 *a
= job_type_collapse(t
, u
);
430 static bool job_is_runnable(Job
*j
) {
435 assert(j
->installed
);
437 /* Checks whether there is any job running for the units this
438 * job needs to be running after (in the case of a 'positive'
439 * job type) or before (in the case of a 'negative' job
442 /* Note that unit types have a say in what is runnable,
443 * too. For example, if they return -EAGAIN from
444 * unit_start() they can indicate they are not
447 /* First check if there is an override */
451 if (j
->type
== JOB_NOP
)
454 if (j
->type
== JOB_START
||
455 j
->type
== JOB_VERIFY_ACTIVE
||
456 j
->type
== JOB_RELOAD
) {
458 /* Immediate result is that the job is or might be
459 * started. In this case let's wait for the
460 * dependencies, regardless whether they are
461 * starting or stopping something. */
463 SET_FOREACH(other
, j
->unit
->dependencies
[UNIT_AFTER
], i
)
468 /* Also, if something else is being stopped and we should
469 * change state after it, then let's wait. */
471 SET_FOREACH(other
, j
->unit
->dependencies
[UNIT_BEFORE
], i
)
473 (other
->job
->type
== JOB_STOP
||
474 other
->job
->type
== JOB_RESTART
))
477 /* This means that for a service a and a service b where b
478 * shall be started after a:
480 * start a + start b → 1st step start a, 2nd step start b
481 * start a + stop b → 1st step stop b, 2nd step start a
482 * stop a + start b → 1st step stop a, 2nd step start b
483 * stop a + stop b → 1st step stop b, 2nd step stop a
485 * This has the side effect that restarts are properly
486 * synchronized too. */
491 static void job_change_type(Job
*j
, JobType newtype
) {
494 log_unit_debug(j
->unit
,
495 "Converting job %s/%s -> %s/%s",
496 j
->unit
->id
, job_type_to_string(j
->type
),
497 j
->unit
->id
, job_type_to_string(newtype
));
502 static int job_perform_on_unit(Job
**j
) {
509 /* While we execute this operation the job might go away (for
510 * example: because it finishes immediately or is replaced by
511 * a new, conflicting job.) To make sure we don't access a
512 * freed job later on we store the id here, so that we can
513 * verify the job is still valid. */
540 assert_not_reached("Invalid job type");
543 /* Log if the job still exists and the start/stop/reload function
544 * actually did something. */
545 *j
= manager_get_job(m
, id
);
547 unit_status_emit_starting_stopping_reloading(u
, t
);
552 int job_run_and_invalidate(Job
*j
) {
556 assert(j
->installed
);
557 assert(j
->type
< _JOB_TYPE_MAX_IN_TRANSACTION
);
558 assert(j
->in_run_queue
);
560 LIST_REMOVE(run_queue
, j
->manager
->run_queue
, j
);
561 j
->in_run_queue
= false;
563 if (j
->state
!= JOB_WAITING
)
566 if (!job_is_runnable(j
))
569 job_set_state(j
, JOB_RUNNING
);
570 job_add_to_dbus_queue(j
);
575 case JOB_VERIFY_ACTIVE
: {
576 UnitActiveState t
= unit_active_state(j
->unit
);
577 if (UNIT_IS_ACTIVE_OR_RELOADING(t
))
579 else if (t
== UNIT_ACTIVATING
)
589 r
= job_perform_on_unit(&j
);
591 /* If the unit type does not support starting/stopping,
592 * then simply wait. */
598 r
= job_perform_on_unit(&j
);
606 assert_not_reached("Unknown job type");
611 r
= job_finish_and_invalidate(j
, JOB_DONE
, true);
612 else if (r
== -EBADR
)
613 r
= job_finish_and_invalidate(j
, JOB_SKIPPED
, true);
614 else if (r
== -ENOEXEC
)
615 r
= job_finish_and_invalidate(j
, JOB_INVALID
, true);
616 else if (r
== -EPROTO
)
617 r
= job_finish_and_invalidate(j
, JOB_ASSERT
, true);
618 else if (r
== -EOPNOTSUPP
)
619 r
= job_finish_and_invalidate(j
, JOB_UNSUPPORTED
, true);
620 else if (r
== -EAGAIN
)
621 job_set_state(j
, JOB_WAITING
);
623 r
= job_finish_and_invalidate(j
, JOB_FAILED
, true);
629 _pure_
static const char *job_get_status_message_format(Unit
*u
, JobType t
, JobResult result
) {
631 static const char *const generic_finished_start_job
[_JOB_RESULT_MAX
] = {
632 [JOB_DONE
] = "Started %s.",
633 [JOB_TIMEOUT
] = "Timed out starting %s.",
634 [JOB_FAILED
] = "Failed to start %s.",
635 [JOB_DEPENDENCY
] = "Dependency failed for %s.",
636 [JOB_ASSERT
] = "Assertion failed for %s.",
637 [JOB_UNSUPPORTED
] = "Starting of %s not supported.",
639 static const char *const generic_finished_stop_job
[_JOB_RESULT_MAX
] = {
640 [JOB_DONE
] = "Stopped %s.",
641 [JOB_FAILED
] = "Stopped (with error) %s.",
642 [JOB_TIMEOUT
] = "Timed out stoppping %s.",
644 static const char *const generic_finished_reload_job
[_JOB_RESULT_MAX
] = {
645 [JOB_DONE
] = "Reloaded %s.",
646 [JOB_FAILED
] = "Reload failed for %s.",
647 [JOB_TIMEOUT
] = "Timed out reloading %s.",
649 /* When verify-active detects the unit is inactive, report it.
650 * Most likely a DEPEND warning from a requisiting unit will
651 * occur next and it's nice to see what was requisited. */
652 static const char *const generic_finished_verify_active_job
[_JOB_RESULT_MAX
] = {
653 [JOB_SKIPPED
] = "%s is not active.",
656 const UnitStatusMessageFormats
*format_table
;
661 assert(t
< _JOB_TYPE_MAX
);
663 if (IN_SET(t
, JOB_START
, JOB_STOP
, JOB_RESTART
)) {
664 format_table
= &UNIT_VTABLE(u
)->status_message_formats
;
666 format
= t
== JOB_START
? format_table
->finished_start_job
[result
] :
667 format_table
->finished_stop_job
[result
];
673 /* Return generic strings */
675 return generic_finished_start_job
[result
];
676 else if (t
== JOB_STOP
|| t
== JOB_RESTART
)
677 return generic_finished_stop_job
[result
];
678 else if (t
== JOB_RELOAD
)
679 return generic_finished_reload_job
[result
];
680 else if (t
== JOB_VERIFY_ACTIVE
)
681 return generic_finished_verify_active_job
[result
];
686 static void job_print_status_message(Unit
*u
, JobType t
, JobResult result
) {
687 static const char* const job_result_status_table
[_JOB_RESULT_MAX
] = {
688 [JOB_DONE
] = ANSI_GREEN
" OK " ANSI_NORMAL
,
689 [JOB_TIMEOUT
] = ANSI_HIGHLIGHT_RED
" TIME " ANSI_NORMAL
,
690 [JOB_FAILED
] = ANSI_HIGHLIGHT_RED
"FAILED" ANSI_NORMAL
,
691 [JOB_DEPENDENCY
] = ANSI_HIGHLIGHT_YELLOW
"DEPEND" ANSI_NORMAL
,
692 [JOB_SKIPPED
] = ANSI_HIGHLIGHT
" INFO " ANSI_NORMAL
,
693 [JOB_ASSERT
] = ANSI_HIGHLIGHT_YELLOW
"ASSERT" ANSI_NORMAL
,
694 [JOB_UNSUPPORTED
] = ANSI_HIGHLIGHT_YELLOW
"UNSUPP" ANSI_NORMAL
,
701 assert(t
< _JOB_TYPE_MAX
);
703 /* Reload status messages have traditionally not been printed to console. */
707 format
= job_get_status_message_format(u
, t
, result
);
711 if (result
!= JOB_DONE
)
712 manager_flip_auto_status(u
->manager
, true);
714 DISABLE_WARNING_FORMAT_NONLITERAL
;
715 unit_status_printf(u
, job_result_status_table
[result
], format
);
718 if (t
== JOB_START
&& result
== JOB_FAILED
) {
719 _cleanup_free_
char *quoted
;
721 quoted
= shell_maybe_quote(u
->id
);
722 manager_status_printf(u
->manager
, STATUS_TYPE_NORMAL
, NULL
, "See 'systemctl status %s' for details.", strna(quoted
));
726 static void job_log_status_message(Unit
*u
, JobType t
, JobResult result
) {
730 static const int job_result_log_level
[_JOB_RESULT_MAX
] = {
731 [JOB_DONE
] = LOG_INFO
,
732 [JOB_CANCELED
] = LOG_INFO
,
733 [JOB_TIMEOUT
] = LOG_ERR
,
734 [JOB_FAILED
] = LOG_ERR
,
735 [JOB_DEPENDENCY
] = LOG_WARNING
,
736 [JOB_SKIPPED
] = LOG_NOTICE
,
737 [JOB_INVALID
] = LOG_INFO
,
738 [JOB_ASSERT
] = LOG_WARNING
,
739 [JOB_UNSUPPORTED
] = LOG_WARNING
,
744 assert(t
< _JOB_TYPE_MAX
);
746 /* Skip this if it goes to the console. since we already print
747 * to the console anyway... */
749 if (log_on_console())
752 format
= job_get_status_message_format(u
, t
, result
);
756 DISABLE_WARNING_FORMAT_NONLITERAL
;
757 snprintf(buf
, sizeof(buf
), format
, unit_description(u
));
763 mid
= result
== JOB_DONE
? SD_MESSAGE_UNIT_STARTED
: SD_MESSAGE_UNIT_FAILED
;
767 mid
= SD_MESSAGE_UNIT_RELOADED
;
772 mid
= SD_MESSAGE_UNIT_STOPPED
;
776 log_struct(job_result_log_level
[result
],
778 LOG_MESSAGE("%s", buf
),
779 "RESULT=%s", job_result_to_string(result
),
784 log_struct(job_result_log_level
[result
],
787 LOG_MESSAGE("%s", buf
),
788 "RESULT=%s", job_result_to_string(result
),
792 static void job_emit_status_message(Unit
*u
, JobType t
, JobResult result
) {
794 /* No message if the job did not actually do anything due to failed condition. */
795 if (t
== JOB_START
&& result
== JOB_DONE
&& !u
->condition_result
)
798 job_log_status_message(u
, t
, result
);
799 job_print_status_message(u
, t
, result
);
802 static void job_fail_dependencies(Unit
*u
, UnitDependency d
) {
808 SET_FOREACH(other
, u
->dependencies
[d
], i
) {
813 if (!IN_SET(j
->type
, JOB_START
, JOB_VERIFY_ACTIVE
))
816 job_finish_and_invalidate(j
, JOB_DEPENDENCY
, true);
820 int job_finish_and_invalidate(Job
*j
, JobResult result
, bool recursive
) {
827 assert(j
->installed
);
828 assert(j
->type
< _JOB_TYPE_MAX_IN_TRANSACTION
);
835 log_unit_debug(u
, "Job %s/%s finished, result=%s", u
->id
, job_type_to_string(t
), job_result_to_string(result
));
837 job_emit_status_message(u
, t
, result
);
839 job_add_to_dbus_queue(j
);
841 /* Patch restart jobs so that they become normal start jobs */
842 if (result
== JOB_DONE
&& t
== JOB_RESTART
) {
844 job_change_type(j
, JOB_START
);
845 job_set_state(j
, JOB_WAITING
);
847 job_add_to_run_queue(j
);
852 if (result
== JOB_FAILED
|| result
== JOB_INVALID
)
853 j
->manager
->n_failed_jobs
++;
858 /* Fail depending jobs on failure */
859 if (result
!= JOB_DONE
&& recursive
) {
860 if (IN_SET(t
, JOB_START
, JOB_VERIFY_ACTIVE
)) {
861 job_fail_dependencies(u
, UNIT_REQUIRED_BY
);
862 job_fail_dependencies(u
, UNIT_REQUISITE_OF
);
863 job_fail_dependencies(u
, UNIT_BOUND_BY
);
864 } else if (t
== JOB_STOP
)
865 job_fail_dependencies(u
, UNIT_CONFLICTED_BY
);
868 /* Trigger OnFailure dependencies that are not generated by
869 * the unit itself. We don't treat JOB_CANCELED as failure in
870 * this context. And JOB_FAILURE is already handled by the
872 if (result
== JOB_TIMEOUT
|| result
== JOB_DEPENDENCY
) {
873 log_struct(LOG_NOTICE
,
874 "JOB_TYPE=%s", job_type_to_string(t
),
875 "JOB_RESULT=%s", job_result_to_string(result
),
877 LOG_UNIT_MESSAGE(u
, "Job %s/%s failed with result '%s'.",
879 job_type_to_string(t
),
880 job_result_to_string(result
)),
883 unit_start_on_failure(u
);
886 unit_trigger_notify(u
);
889 /* Try to start the next jobs that can be started */
890 SET_FOREACH(other
, u
->dependencies
[UNIT_AFTER
], i
)
892 job_add_to_run_queue(other
->job
);
893 SET_FOREACH(other
, u
->dependencies
[UNIT_BEFORE
], i
)
895 job_add_to_run_queue(other
->job
);
897 manager_check_finished(u
->manager
);
902 static int job_dispatch_timer(sd_event_source
*s
, uint64_t monotonic
, void *userdata
) {
907 assert(s
== j
->timer_event_source
);
909 log_unit_warning(j
->unit
, "Job %s/%s timed out.", j
->unit
->id
, job_type_to_string(j
->type
));
912 job_finish_and_invalidate(j
, JOB_TIMEOUT
, true);
914 failure_action(u
->manager
, u
->job_timeout_action
, u
->job_timeout_reboot_arg
);
919 int job_start_timer(Job
*j
) {
922 if (j
->timer_event_source
)
925 j
->begin_usec
= now(CLOCK_MONOTONIC
);
927 if (j
->unit
->job_timeout
<= 0)
930 r
= sd_event_add_time(
932 &j
->timer_event_source
,
934 j
->begin_usec
+ j
->unit
->job_timeout
, 0,
935 job_dispatch_timer
, j
);
939 (void) sd_event_source_set_description(j
->timer_event_source
, "job-start");
944 void job_add_to_run_queue(Job
*j
) {
946 assert(j
->installed
);
951 if (!j
->manager
->run_queue
)
952 sd_event_source_set_enabled(j
->manager
->run_queue_event_source
, SD_EVENT_ONESHOT
);
954 LIST_PREPEND(run_queue
, j
->manager
->run_queue
, j
);
955 j
->in_run_queue
= true;
958 void job_add_to_dbus_queue(Job
*j
) {
960 assert(j
->installed
);
962 if (j
->in_dbus_queue
)
965 /* We don't check if anybody is subscribed here, since this
966 * job might just have been created and not yet assigned to a
967 * connection/client. */
969 LIST_PREPEND(dbus_queue
, j
->manager
->dbus_job_queue
, j
);
970 j
->in_dbus_queue
= true;
973 char *job_dbus_path(Job
*j
) {
978 if (asprintf(&p
, "/org/freedesktop/systemd1/job/%"PRIu32
, j
->id
) < 0)
984 int job_serialize(Job
*j
, FILE *f
, FDSet
*fds
) {
985 fprintf(f
, "job-id=%u\n", j
->id
);
986 fprintf(f
, "job-type=%s\n", job_type_to_string(j
->type
));
987 fprintf(f
, "job-state=%s\n", job_state_to_string(j
->state
));
988 fprintf(f
, "job-irreversible=%s\n", yes_no(j
->irreversible
));
989 fprintf(f
, "job-sent-dbus-new-signal=%s\n", yes_no(j
->sent_dbus_new_signal
));
990 fprintf(f
, "job-ignore-order=%s\n", yes_no(j
->ignore_order
));
992 if (j
->begin_usec
> 0)
993 fprintf(f
, "job-begin="USEC_FMT
"\n", j
->begin_usec
);
995 bus_track_serialize(j
->clients
, f
);
1002 int job_deserialize(Job
*j
, FILE *f
, FDSet
*fds
) {
1006 char line
[LINE_MAX
], *l
, *v
;
1009 if (!fgets(line
, sizeof(line
), f
)) {
1022 k
= strcspn(l
, "=");
1030 if (streq(l
, "job-id")) {
1032 if (safe_atou32(v
, &j
->id
) < 0)
1033 log_debug("Failed to parse job id value %s", v
);
1035 } else if (streq(l
, "job-type")) {
1038 t
= job_type_from_string(v
);
1040 log_debug("Failed to parse job type %s", v
);
1041 else if (t
>= _JOB_TYPE_MAX_IN_TRANSACTION
)
1042 log_debug("Cannot deserialize job of type %s", v
);
1046 } else if (streq(l
, "job-state")) {
1049 s
= job_state_from_string(v
);
1051 log_debug("Failed to parse job state %s", v
);
1053 job_set_state(j
, s
);
1055 } else if (streq(l
, "job-irreversible")) {
1058 b
= parse_boolean(v
);
1060 log_debug("Failed to parse job irreversible flag %s", v
);
1062 j
->irreversible
= j
->irreversible
|| b
;
1064 } else if (streq(l
, "job-sent-dbus-new-signal")) {
1067 b
= parse_boolean(v
);
1069 log_debug("Failed to parse job sent_dbus_new_signal flag %s", v
);
1071 j
->sent_dbus_new_signal
= j
->sent_dbus_new_signal
|| b
;
1073 } else if (streq(l
, "job-ignore-order")) {
1076 b
= parse_boolean(v
);
1078 log_debug("Failed to parse job ignore_order flag %s", v
);
1080 j
->ignore_order
= j
->ignore_order
|| b
;
1082 } else if (streq(l
, "job-begin")) {
1083 unsigned long long ull
;
1085 if (sscanf(v
, "%llu", &ull
) != 1)
1086 log_debug("Failed to parse job-begin value %s", v
);
1088 j
->begin_usec
= ull
;
1090 } else if (streq(l
, "subscribed")) {
1092 if (strv_extend(&j
->deserialized_clients
, v
) < 0)
1098 int job_coldplug(Job
*j
) {
1103 /* After deserialization is complete and the bus connection
1104 * set up again, let's start watching our subscribers again */
1105 r
= bus_track_coldplug(j
->manager
, &j
->clients
, &j
->deserialized_clients
);
1109 if (j
->state
== JOB_WAITING
)
1110 job_add_to_run_queue(j
);
1112 if (j
->begin_usec
== 0 || j
->unit
->job_timeout
== 0)
1115 if (j
->timer_event_source
)
1116 j
->timer_event_source
= sd_event_source_unref(j
->timer_event_source
);
1118 r
= sd_event_add_time(
1120 &j
->timer_event_source
,
1122 j
->begin_usec
+ j
->unit
->job_timeout
, 0,
1123 job_dispatch_timer
, j
);
1125 log_debug_errno(r
, "Failed to restart timeout for job: %m");
1127 (void) sd_event_source_set_description(j
->timer_event_source
, "job-timeout");
1132 void job_shutdown_magic(Job
*j
) {
1135 /* The shutdown target gets some special treatment here: we
1136 * tell the kernel to begin with flushing its disk caches, to
1137 * optimize shutdown time a bit. Ideally we wouldn't hardcode
1138 * this magic into PID 1. However all other processes aren't
1139 * options either since they'd exit much sooner than PID 1 and
1140 * asynchronous sync() would cause their exit to be
1143 if (j
->type
!= JOB_START
)
1146 if (j
->unit
->manager
->running_as
!= MANAGER_SYSTEM
)
1149 if (!unit_has_name(j
->unit
, SPECIAL_SHUTDOWN_TARGET
))
1152 /* In case messages on console has been disabled on boot */
1153 j
->unit
->manager
->no_console_output
= false;
1155 if (detect_container() > 0)
1158 asynchronous_sync();
1161 int job_get_timeout(Job
*j
, uint64_t *timeout
) {
1163 uint64_t x
= -1, y
= -1;
1168 if (j
->timer_event_source
) {
1169 r
= sd_event_source_get_time(j
->timer_event_source
, &x
);
1175 if (UNIT_VTABLE(u
)->get_timeout
) {
1176 q
= UNIT_VTABLE(u
)->get_timeout(u
, &y
);
1181 if (r
== 0 && q
== 0)
1184 *timeout
= MIN(x
, y
);
1189 static const char* const job_state_table
[_JOB_STATE_MAX
] = {
1190 [JOB_WAITING
] = "waiting",
1191 [JOB_RUNNING
] = "running"
1194 DEFINE_STRING_TABLE_LOOKUP(job_state
, JobState
);
1196 static const char* const job_type_table
[_JOB_TYPE_MAX
] = {
1197 [JOB_START
] = "start",
1198 [JOB_VERIFY_ACTIVE
] = "verify-active",
1199 [JOB_STOP
] = "stop",
1200 [JOB_RELOAD
] = "reload",
1201 [JOB_RELOAD_OR_START
] = "reload-or-start",
1202 [JOB_RESTART
] = "restart",
1203 [JOB_TRY_RESTART
] = "try-restart",
1207 DEFINE_STRING_TABLE_LOOKUP(job_type
, JobType
);
1209 static const char* const job_mode_table
[_JOB_MODE_MAX
] = {
1210 [JOB_FAIL
] = "fail",
1211 [JOB_REPLACE
] = "replace",
1212 [JOB_REPLACE_IRREVERSIBLY
] = "replace-irreversibly",
1213 [JOB_ISOLATE
] = "isolate",
1214 [JOB_FLUSH
] = "flush",
1215 [JOB_IGNORE_DEPENDENCIES
] = "ignore-dependencies",
1216 [JOB_IGNORE_REQUIREMENTS
] = "ignore-requirements",
1219 DEFINE_STRING_TABLE_LOOKUP(job_mode
, JobMode
);
1221 static const char* const job_result_table
[_JOB_RESULT_MAX
] = {
1222 [JOB_DONE
] = "done",
1223 [JOB_CANCELED
] = "canceled",
1224 [JOB_TIMEOUT
] = "timeout",
1225 [JOB_FAILED
] = "failed",
1226 [JOB_DEPENDENCY
] = "dependency",
1227 [JOB_SKIPPED
] = "skipped",
1228 [JOB_INVALID
] = "invalid",
1229 [JOB_ASSERT
] = "assert",
1230 [JOB_UNSUPPORTED
] = "unsupported",
1233 DEFINE_STRING_TABLE_LOOKUP(job_result
, JobResult
);