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 (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 (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_unit_debug(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_unit_debug(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_unit_debug(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_unit_debug(j
->unit
->id
,
215 "Unit %s already has a job installed. Not installing deserialized job.",
221 log_unit_debug(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
;
359 assert_not_reached("Invalid job type");
363 void job_type_collapse(JobType
*t
, Unit
*u
) {
368 case JOB_TRY_RESTART
:
369 s
= unit_active_state(u
);
370 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s
))
376 case JOB_RELOAD_OR_START
:
377 s
= unit_active_state(u
);
378 if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s
))
389 int job_type_merge_and_collapse(JobType
*a
, JobType b
, Unit
*u
) {
390 JobType t
= job_type_lookup_merge(*a
, b
);
394 job_type_collapse(a
, u
);
398 static bool job_is_runnable(Job
*j
) {
403 assert(j
->installed
);
405 /* Checks whether there is any job running for the units this
406 * job needs to be running after (in the case of a 'positive'
407 * job type) or before (in the case of a 'negative' job
410 /* Note that unit types have a say in what is runnable,
411 * too. For example, if they return -EAGAIN from
412 * unit_start() they can indicate they are not
415 /* First check if there is an override */
419 if (j
->type
== JOB_NOP
)
422 if (j
->type
== JOB_START
||
423 j
->type
== JOB_VERIFY_ACTIVE
||
424 j
->type
== JOB_RELOAD
) {
426 /* Immediate result is that the job is or might be
427 * started. In this case lets wait for the
428 * dependencies, regardless whether they are
429 * starting or stopping something. */
431 SET_FOREACH(other
, j
->unit
->dependencies
[UNIT_AFTER
], i
)
436 /* Also, if something else is being stopped and we should
437 * change state after it, then lets wait. */
439 SET_FOREACH(other
, j
->unit
->dependencies
[UNIT_BEFORE
], i
)
441 (other
->job
->type
== JOB_STOP
||
442 other
->job
->type
== JOB_RESTART
))
445 /* This means that for a service a and a service b where b
446 * shall be started after a:
448 * start a + start b → 1st step start a, 2nd step start b
449 * start a + stop b → 1st step stop b, 2nd step start a
450 * stop a + start b → 1st step stop a, 2nd step start b
451 * stop a + stop b → 1st step stop b, 2nd step stop a
453 * This has the side effect that restarts are properly
454 * synchronized too. */
459 static void job_change_type(Job
*j
, JobType newtype
) {
460 log_unit_debug(j
->unit
->id
,
461 "Converting job %s/%s -> %s/%s",
462 j
->unit
->id
, job_type_to_string(j
->type
),
463 j
->unit
->id
, job_type_to_string(newtype
));
468 int job_run_and_invalidate(Job
*j
) {
471 Manager
*m
= j
->manager
;
474 assert(j
->installed
);
475 assert(j
->type
< _JOB_TYPE_MAX_IN_TRANSACTION
);
476 assert(j
->in_run_queue
);
478 LIST_REMOVE(run_queue
, j
->manager
->run_queue
, j
);
479 j
->in_run_queue
= false;
481 if (j
->state
!= JOB_WAITING
)
484 if (!job_is_runnable(j
))
487 j
->state
= JOB_RUNNING
;
489 job_add_to_dbus_queue(j
);
491 /* While we execute this operation the job might go away (for
492 * example: because it is replaced by a new, conflicting
493 * job.) To make sure we don't access a freed job later on we
494 * store the id here, so that we can verify the job is still
501 r
= unit_start(j
->unit
);
503 /* If this unit cannot be started, then simply wait */
508 case JOB_VERIFY_ACTIVE
: {
509 UnitActiveState t
= unit_active_state(j
->unit
);
510 if (UNIT_IS_ACTIVE_OR_RELOADING(t
))
512 else if (t
== UNIT_ACTIVATING
)
521 r
= unit_stop(j
->unit
);
523 /* If this unit cannot stopped, then simply wait. */
529 r
= unit_reload(j
->unit
);
537 assert_not_reached("Unknown job type");
540 j
= manager_get_job(m
, id
);
543 r
= job_finish_and_invalidate(j
, JOB_DONE
, true);
544 else if (r
== -EBADR
)
545 r
= job_finish_and_invalidate(j
, JOB_SKIPPED
, true);
546 else if (r
== -ENOEXEC
)
547 r
= job_finish_and_invalidate(j
, JOB_INVALID
, true);
548 else if (r
== -EPROTO
)
549 r
= job_finish_and_invalidate(j
, JOB_ASSERT
, true);
550 else if (r
== -EAGAIN
) {
551 j
->state
= JOB_WAITING
;
554 r
= job_finish_and_invalidate(j
, JOB_FAILED
, true);
560 _pure_
static const char *job_get_status_message_format(Unit
*u
, JobType t
, JobResult result
) {
561 const UnitStatusMessageFormats
*format_table
;
565 assert(t
< _JOB_TYPE_MAX
);
567 format_table
= &UNIT_VTABLE(u
)->status_message_formats
;
572 return format_table
->finished_start_job
[result
];
573 else if (t
== JOB_STOP
|| t
== JOB_RESTART
)
574 return format_table
->finished_stop_job
[result
];
579 _pure_
static const char *job_get_status_message_format_try_harder(Unit
*u
, JobType t
, JobResult result
) {
584 assert(t
< _JOB_TYPE_MAX
);
586 format
= job_get_status_message_format(u
, t
, result
);
590 /* Return generic strings */
591 if (t
== JOB_START
) {
592 if (result
== JOB_DONE
)
593 return "Started %s.";
594 else if (result
== JOB_FAILED
)
595 return "Failed to start %s.";
596 else if (result
== JOB_DEPENDENCY
)
597 return "Dependency failed for %s.";
598 else if (result
== JOB_TIMEOUT
)
599 return "Timed out starting %s.";
600 } else if (t
== JOB_STOP
|| t
== JOB_RESTART
) {
601 if (result
== JOB_DONE
)
602 return "Stopped %s.";
603 else if (result
== JOB_FAILED
)
604 return "Stopped (with error) %s.";
605 else if (result
== JOB_TIMEOUT
)
606 return "Timed out stoppping %s.";
607 } else if (t
== JOB_RELOAD
) {
608 if (result
== JOB_DONE
)
609 return "Reloaded %s.";
610 else if (result
== JOB_FAILED
)
611 return "Reload failed for %s.";
612 else if (result
== JOB_TIMEOUT
)
613 return "Timed out reloading %s.";
619 static void job_print_status_message(Unit
*u
, JobType t
, JobResult result
) {
624 assert(t
< _JOB_TYPE_MAX
);
626 DISABLE_WARNING_FORMAT_NONLITERAL
;
628 if (t
== JOB_START
) {
629 format
= job_get_status_message_format(u
, t
, result
);
636 if (u
->condition_result
)
637 unit_status_printf(u
, ANSI_GREEN_ON
" OK " ANSI_HIGHLIGHT_OFF
, format
);
643 quotes
= chars_intersect(u
->id
, SHELL_NEED_QUOTES
);
645 manager_flip_auto_status(u
->manager
, true);
646 unit_status_printf(u
, ANSI_HIGHLIGHT_RED_ON
"FAILED" ANSI_HIGHLIGHT_OFF
, format
);
647 manager_status_printf(u
->manager
, STATUS_TYPE_NORMAL
, NULL
,
648 "See \"systemctl status %s%s%s\" for details.",
649 quotes
? "'" : "", u
->id
, quotes
? "'" : "");
654 manager_flip_auto_status(u
->manager
, true);
655 unit_status_printf(u
, ANSI_HIGHLIGHT_YELLOW_ON
"DEPEND" ANSI_HIGHLIGHT_OFF
, format
);
659 manager_flip_auto_status(u
->manager
, true);
660 unit_status_printf(u
, ANSI_HIGHLIGHT_RED_ON
" TIME " ANSI_HIGHLIGHT_OFF
, format
);
664 manager_flip_auto_status(u
->manager
, true);
665 unit_status_printf(u
, ANSI_HIGHLIGHT_YELLOW_ON
"ASSERT" ANSI_HIGHLIGHT_OFF
, format
);
672 } else if (t
== JOB_STOP
|| t
== JOB_RESTART
) {
674 format
= job_get_status_message_format(u
, t
, result
);
681 manager_flip_auto_status(u
->manager
, true);
682 unit_status_printf(u
, ANSI_HIGHLIGHT_RED_ON
" TIME " ANSI_HIGHLIGHT_OFF
, format
);
687 unit_status_printf(u
, ANSI_GREEN_ON
" OK " ANSI_HIGHLIGHT_OFF
, format
);
694 } else if (t
== JOB_VERIFY_ACTIVE
) {
696 /* When verify-active detects the unit is inactive, report it.
697 * Most likely a DEPEND warning from a requisiting unit will
698 * occur next and it's nice to see what was requisited. */
699 if (result
== JOB_SKIPPED
)
700 unit_status_printf(u
, ANSI_HIGHLIGHT_ON
" INFO " ANSI_HIGHLIGHT_OFF
, "%s is not active.");
706 static void job_log_status_message(Unit
*u
, JobType t
, JobResult result
) {
712 assert(t
< _JOB_TYPE_MAX
);
714 /* Skip this if it goes to the console. since we already print
715 * to the console anyway... */
717 if (log_on_console())
720 format
= job_get_status_message_format_try_harder(u
, t
, result
);
724 DISABLE_WARNING_FORMAT_NONLITERAL
;
725 snprintf(buf
, sizeof(buf
), format
, unit_description(u
));
729 if (t
== JOB_START
) {
732 mid
= result
== JOB_DONE
? SD_MESSAGE_UNIT_STARTED
: SD_MESSAGE_UNIT_FAILED
;
733 log_unit_struct(u
->id
,
734 result
== JOB_DONE
? LOG_INFO
: LOG_ERR
,
736 LOG_MESSAGE("%s", buf
),
737 "RESULT=%s", job_result_to_string(result
),
740 } else if (t
== JOB_STOP
)
741 log_unit_struct(u
->id
,
742 result
== JOB_DONE
? LOG_INFO
: LOG_ERR
,
743 LOG_MESSAGE_ID(SD_MESSAGE_UNIT_STOPPED
),
744 LOG_MESSAGE("%s", buf
),
745 "RESULT=%s", job_result_to_string(result
),
748 else if (t
== JOB_RELOAD
)
749 log_unit_struct(u
->id
,
750 result
== JOB_DONE
? LOG_INFO
: LOG_ERR
,
751 LOG_MESSAGE_ID(SD_MESSAGE_UNIT_RELOADED
),
752 LOG_MESSAGE("%s", buf
),
753 "RESULT=%s", job_result_to_string(result
),
757 int job_finish_and_invalidate(Job
*j
, JobResult result
, bool recursive
) {
764 assert(j
->installed
);
765 assert(j
->type
< _JOB_TYPE_MAX_IN_TRANSACTION
);
772 if (j
->state
== JOB_RUNNING
)
773 j
->manager
->n_running_jobs
--;
775 log_unit_debug(u
->id
, "Job %s/%s finished, result=%s",
776 u
->id
, job_type_to_string(t
), job_result_to_string(result
));
778 job_print_status_message(u
, t
, result
);
779 job_log_status_message(u
, t
, result
);
781 job_add_to_dbus_queue(j
);
783 /* Patch restart jobs so that they become normal start jobs */
784 if (result
== JOB_DONE
&& t
== JOB_RESTART
) {
786 job_change_type(j
, JOB_START
);
787 j
->state
= JOB_WAITING
;
789 job_add_to_run_queue(j
);
794 if (result
== JOB_FAILED
|| result
== JOB_INVALID
)
795 j
->manager
->n_failed_jobs
++;
800 /* Fail depending jobs on failure */
801 if (result
!= JOB_DONE
&& recursive
) {
803 if (t
== JOB_START
||
804 t
== JOB_VERIFY_ACTIVE
) {
806 SET_FOREACH(other
, u
->dependencies
[UNIT_REQUIRED_BY
], i
)
808 (other
->job
->type
== JOB_START
||
809 other
->job
->type
== JOB_VERIFY_ACTIVE
))
810 job_finish_and_invalidate(other
->job
, JOB_DEPENDENCY
, true);
812 SET_FOREACH(other
, u
->dependencies
[UNIT_BOUND_BY
], i
)
814 (other
->job
->type
== JOB_START
||
815 other
->job
->type
== JOB_VERIFY_ACTIVE
))
816 job_finish_and_invalidate(other
->job
, JOB_DEPENDENCY
, true);
818 SET_FOREACH(other
, u
->dependencies
[UNIT_REQUIRED_BY_OVERRIDABLE
], i
)
820 !other
->job
->override
&&
821 (other
->job
->type
== JOB_START
||
822 other
->job
->type
== JOB_VERIFY_ACTIVE
))
823 job_finish_and_invalidate(other
->job
, JOB_DEPENDENCY
, true);
825 } else if (t
== JOB_STOP
) {
827 SET_FOREACH(other
, u
->dependencies
[UNIT_CONFLICTED_BY
], i
)
829 (other
->job
->type
== JOB_START
||
830 other
->job
->type
== JOB_VERIFY_ACTIVE
))
831 job_finish_and_invalidate(other
->job
, JOB_DEPENDENCY
, true);
835 /* Trigger OnFailure dependencies that are not generated by
836 * the unit itself. We don't treat JOB_CANCELED as failure in
837 * this context. And JOB_FAILURE is already handled by the
839 if (result
== JOB_TIMEOUT
|| result
== JOB_DEPENDENCY
) {
840 log_unit_struct(u
->id
,
842 "JOB_TYPE=%s", job_type_to_string(t
),
843 "JOB_RESULT=%s", job_result_to_string(result
),
844 LOG_MESSAGE("Job %s/%s failed with result '%s'.",
846 job_type_to_string(t
),
847 job_result_to_string(result
)),
850 unit_start_on_failure(u
);
853 unit_trigger_notify(u
);
856 /* Try to start the next jobs that can be started */
857 SET_FOREACH(other
, u
->dependencies
[UNIT_AFTER
], i
)
859 job_add_to_run_queue(other
->job
);
860 SET_FOREACH(other
, u
->dependencies
[UNIT_BEFORE
], i
)
862 job_add_to_run_queue(other
->job
);
864 manager_check_finished(u
->manager
);
869 static int job_dispatch_timer(sd_event_source
*s
, uint64_t monotonic
, void *userdata
) {
874 assert(s
== j
->timer_event_source
);
876 log_unit_warning(j
->unit
->id
, "Job %s/%s timed out.", j
->unit
->id
, job_type_to_string(j
->type
));
879 job_finish_and_invalidate(j
, JOB_TIMEOUT
, true);
881 failure_action(u
->manager
, u
->job_timeout_action
, u
->job_timeout_reboot_arg
);
886 int job_start_timer(Job
*j
) {
889 if (j
->timer_event_source
)
892 j
->begin_usec
= now(CLOCK_MONOTONIC
);
894 if (j
->unit
->job_timeout
<= 0)
897 r
= sd_event_add_time(
899 &j
->timer_event_source
,
901 j
->begin_usec
+ j
->unit
->job_timeout
, 0,
902 job_dispatch_timer
, j
);
909 void job_add_to_run_queue(Job
*j
) {
911 assert(j
->installed
);
916 if (!j
->manager
->run_queue
)
917 sd_event_source_set_enabled(j
->manager
->run_queue_event_source
, SD_EVENT_ONESHOT
);
919 LIST_PREPEND(run_queue
, j
->manager
->run_queue
, j
);
920 j
->in_run_queue
= true;
923 void job_add_to_dbus_queue(Job
*j
) {
925 assert(j
->installed
);
927 if (j
->in_dbus_queue
)
930 /* We don't check if anybody is subscribed here, since this
931 * job might just have been created and not yet assigned to a
932 * connection/client. */
934 LIST_PREPEND(dbus_queue
, j
->manager
->dbus_job_queue
, j
);
935 j
->in_dbus_queue
= true;
938 char *job_dbus_path(Job
*j
) {
943 if (asprintf(&p
, "/org/freedesktop/systemd1/job/%"PRIu32
, j
->id
) < 0)
949 int job_serialize(Job
*j
, FILE *f
, FDSet
*fds
) {
950 fprintf(f
, "job-id=%u\n", j
->id
);
951 fprintf(f
, "job-type=%s\n", job_type_to_string(j
->type
));
952 fprintf(f
, "job-state=%s\n", job_state_to_string(j
->state
));
953 fprintf(f
, "job-override=%s\n", yes_no(j
->override
));
954 fprintf(f
, "job-irreversible=%s\n", yes_no(j
->irreversible
));
955 fprintf(f
, "job-sent-dbus-new-signal=%s\n", yes_no(j
->sent_dbus_new_signal
));
956 fprintf(f
, "job-ignore-order=%s\n", yes_no(j
->ignore_order
));
958 if (j
->begin_usec
> 0)
959 fprintf(f
, "job-begin="USEC_FMT
"\n", j
->begin_usec
);
961 bus_track_serialize(j
->clients
, f
);
968 int job_deserialize(Job
*j
, FILE *f
, FDSet
*fds
) {
972 char line
[LINE_MAX
], *l
, *v
;
975 if (!fgets(line
, sizeof(line
), f
)) {
996 if (streq(l
, "job-id")) {
998 if (safe_atou32(v
, &j
->id
) < 0)
999 log_debug("Failed to parse job id value %s", v
);
1001 } else if (streq(l
, "job-type")) {
1004 t
= job_type_from_string(v
);
1006 log_debug("Failed to parse job type %s", v
);
1007 else if (t
>= _JOB_TYPE_MAX_IN_TRANSACTION
)
1008 log_debug("Cannot deserialize job of type %s", v
);
1012 } else if (streq(l
, "job-state")) {
1015 s
= job_state_from_string(v
);
1017 log_debug("Failed to parse job state %s", v
);
1021 } else if (streq(l
, "job-override")) {
1024 b
= parse_boolean(v
);
1026 log_debug("Failed to parse job override flag %s", v
);
1028 j
->override
= j
->override
|| b
;
1030 } else if (streq(l
, "job-irreversible")) {
1033 b
= parse_boolean(v
);
1035 log_debug("Failed to parse job irreversible flag %s", v
);
1037 j
->irreversible
= j
->irreversible
|| b
;
1039 } else if (streq(l
, "job-sent-dbus-new-signal")) {
1042 b
= parse_boolean(v
);
1044 log_debug("Failed to parse job sent_dbus_new_signal flag %s", v
);
1046 j
->sent_dbus_new_signal
= j
->sent_dbus_new_signal
|| b
;
1048 } else if (streq(l
, "job-ignore-order")) {
1051 b
= parse_boolean(v
);
1053 log_debug("Failed to parse job ignore_order flag %s", v
);
1055 j
->ignore_order
= j
->ignore_order
|| b
;
1057 } else if (streq(l
, "job-begin")) {
1058 unsigned long long ull
;
1060 if (sscanf(v
, "%llu", &ull
) != 1)
1061 log_debug("Failed to parse job-begin value %s", v
);
1063 j
->begin_usec
= ull
;
1065 } else if (streq(l
, "subscribed")) {
1067 if (strv_extend(&j
->deserialized_clients
, v
) < 0)
1073 int job_coldplug(Job
*j
) {
1078 /* After deserialization is complete and the bus connection
1079 * set up again, let's start watching our subscribers again */
1080 r
= bus_track_coldplug(j
->manager
, &j
->clients
, &j
->deserialized_clients
);
1084 if (j
->state
== JOB_WAITING
)
1085 job_add_to_run_queue(j
);
1087 if (j
->begin_usec
== 0 || j
->unit
->job_timeout
== 0)
1090 if (j
->timer_event_source
)
1091 j
->timer_event_source
= sd_event_source_unref(j
->timer_event_source
);
1093 r
= sd_event_add_time(
1095 &j
->timer_event_source
,
1097 j
->begin_usec
+ j
->unit
->job_timeout
, 0,
1098 job_dispatch_timer
, j
);
1100 log_debug_errno(r
, "Failed to restart timeout for job: %m");
1105 void job_shutdown_magic(Job
*j
) {
1108 /* The shutdown target gets some special treatment here: we
1109 * tell the kernel to begin with flushing its disk caches, to
1110 * optimize shutdown time a bit. Ideally we wouldn't hardcode
1111 * this magic into PID 1. However all other processes aren't
1112 * options either since they'd exit much sooner than PID 1 and
1113 * asynchronous sync() would cause their exit to be
1116 if (j
->type
!= JOB_START
)
1119 if (j
->unit
->manager
->running_as
!= SYSTEMD_SYSTEM
)
1122 if (!unit_has_name(j
->unit
, SPECIAL_SHUTDOWN_TARGET
))
1125 /* In case messages on console has been disabled on boot */
1126 j
->unit
->manager
->no_console_output
= false;
1128 if (detect_container(NULL
) > 0)
1131 asynchronous_sync();
1134 int job_get_timeout(Job
*j
, uint64_t *timeout
) {
1136 uint64_t x
= -1, y
= -1;
1141 if (j
->timer_event_source
) {
1142 r
= sd_event_source_get_time(j
->timer_event_source
, &x
);
1148 if (UNIT_VTABLE(u
)->get_timeout
) {
1149 q
= UNIT_VTABLE(u
)->get_timeout(u
, &y
);
1154 if (r
== 0 && q
== 0)
1157 *timeout
= MIN(x
, y
);
1162 static const char* const job_state_table
[_JOB_STATE_MAX
] = {
1163 [JOB_WAITING
] = "waiting",
1164 [JOB_RUNNING
] = "running"
1167 DEFINE_STRING_TABLE_LOOKUP(job_state
, JobState
);
1169 static const char* const job_type_table
[_JOB_TYPE_MAX
] = {
1170 [JOB_START
] = "start",
1171 [JOB_VERIFY_ACTIVE
] = "verify-active",
1172 [JOB_STOP
] = "stop",
1173 [JOB_RELOAD
] = "reload",
1174 [JOB_RELOAD_OR_START
] = "reload-or-start",
1175 [JOB_RESTART
] = "restart",
1176 [JOB_TRY_RESTART
] = "try-restart",
1180 DEFINE_STRING_TABLE_LOOKUP(job_type
, JobType
);
1182 static const char* const job_mode_table
[_JOB_MODE_MAX
] = {
1183 [JOB_FAIL
] = "fail",
1184 [JOB_REPLACE
] = "replace",
1185 [JOB_REPLACE_IRREVERSIBLY
] = "replace-irreversibly",
1186 [JOB_ISOLATE
] = "isolate",
1187 [JOB_FLUSH
] = "flush",
1188 [JOB_IGNORE_DEPENDENCIES
] = "ignore-dependencies",
1189 [JOB_IGNORE_REQUIREMENTS
] = "ignore-requirements",
1192 DEFINE_STRING_TABLE_LOOKUP(job_mode
, JobMode
);
1194 static const char* const job_result_table
[_JOB_RESULT_MAX
] = {
1195 [JOB_DONE
] = "done",
1196 [JOB_CANCELED
] = "canceled",
1197 [JOB_TIMEOUT
] = "timeout",
1198 [JOB_FAILED
] = "failed",
1199 [JOB_DEPENDENCY
] = "dependency",
1200 [JOB_SKIPPED
] = "skipped",
1201 [JOB_INVALID
] = "invalid",
1202 [JOB_ASSERT
] = "assert",
1205 DEFINE_STRING_TABLE_LOOKUP(job_result
, JobResult
);