-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <errno.h>
return log_unit_debug_errno(j->unit, SYNTHETIC_ERRNO(EEXIST),
"Unit already has a job installed. Not installing deserialized job.");
+ r = hashmap_ensure_allocated(&j->manager->jobs, NULL);
+ if (r < 0)
+ return r;
+
r = hashmap_put(j->manager->jobs, UINT32_TO_PTR(j->id), j);
if (r == -EEXIST)
return log_unit_debug_errno(j->unit, r, "Job ID %" PRIu32 " already used, cannot deserialize job.", j->id);
case JOB_TRY_RESTART:
s = unit_active_state(u);
- if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
+ if (!UNIT_IS_ACTIVE_OR_RELOADING(s))
return JOB_NOP;
return JOB_RESTART;
case JOB_TRY_RELOAD:
s = unit_active_state(u);
- if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
+ if (!UNIT_IS_ACTIVE_OR_RELOADING(s))
return JOB_NOP;
return JOB_RELOAD;
case JOB_RELOAD_OR_START:
s = unit_active_state(u);
- if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
+ if (!UNIT_IS_ACTIVE_OR_RELOADING(s))
return JOB_START;
return JOB_RELOAD;
}
static bool job_is_runnable(Job *j) {
- Iterator i;
Unit *other;
void *v;
if (j->type == JOB_NOP)
return true;
- HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_AFTER], i)
- if (other->job && job_compare(j, other->job, UNIT_AFTER) > 0)
+ HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_AFTER])
+ if (other->job && job_compare(j, other->job, UNIT_AFTER) > 0) {
+ log_unit_debug(j->unit,
+ "starting held back, waiting for: %s",
+ other->id);
return false;
+ }
- HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_BEFORE], i)
- if (other->job && job_compare(j, other->job, UNIT_BEFORE) > 0)
+ HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_BEFORE])
+ if (other->job && job_compare(j, other->job, UNIT_BEFORE) > 0) {
+ log_unit_debug(j->unit,
+ "stopping held back, waiting for: %s",
+ other->id);
return false;
+ }
return true;
}
format = job_get_begin_status_message_format(u, t);
DISABLE_WARNING_FORMAT_NONLITERAL;
- unit_status_printf(u, "", format);
+ unit_status_printf(u, STATUS_TYPE_NORMAL, "", format);
REENABLE_WARNING;
}
assert(t < _JOB_TYPE_MAX);
if (IN_SET(t, JOB_START, JOB_STOP, JOB_RESTART)) {
+ const UnitStatusMessageFormats *formats = &UNIT_VTABLE(u)->status_message_formats;
+ if (formats->finished_job) {
+ format = formats->finished_job(u, t, result);
+ if (format)
+ return format;
+ }
format = t == JOB_START ?
- UNIT_VTABLE(u)->status_message_formats.finished_start_job[result] :
- UNIT_VTABLE(u)->status_message_formats.finished_stop_job[result];
+ formats->finished_start_job[result] :
+ formats->finished_stop_job[result];
if (format)
return format;
}
else
status = job_print_done_status_messages[result].word;
- if (result != JOB_DONE)
- manager_flip_auto_status(u->manager, true);
-
DISABLE_WARNING_FORMAT_NONLITERAL;
- unit_status_printf(u, status, format);
+ unit_status_printf(u,
+ result == JOB_DONE ? STATUS_TYPE_NORMAL : STATUS_TYPE_NOTICE,
+ status, format);
REENABLE_WARNING;
if (t == JOB_START && result == JOB_FAILED) {
static void job_fail_dependencies(Unit *u, UnitDependency d) {
Unit *other;
- Iterator i;
void *v;
assert(u);
- HASHMAP_FOREACH_KEY(v, other, u->dependencies[d], i) {
+ HASHMAP_FOREACH_KEY(v, other, u->dependencies[d]) {
Job *j = other->job;
if (!j)
Unit *u;
Unit *other;
JobType t;
- Iterator i;
void *v;
assert(j);
j->result = result;
- log_unit_debug(u, "Job %" PRIu32 " %s/%s finished, result=%s", j->id, u->id, job_type_to_string(t), job_result_to_string(result));
+ log_unit_debug(u, "Job %" PRIu32 " %s/%s finished, result=%s",
+ j->id, u->id, job_type_to_string(t), job_result_to_string(result));
- /* If this job did nothing to respective unit we don't log the status message */
+ /* If this job did nothing to the respective unit we don't log the status message */
if (!already)
job_emit_done_status_message(u, j->id, t, result);
* aren't active. This is when the verify-active job merges with a
* satisfying job type, and then loses it's invalidation effect, as the
* result there is JOB_DONE for the start job we merged into, while we
- * should be failing the depending job if the said unit isn't infact
+ * should be failing the depending job if the said unit isn't in fact
* active. Oneshots are an example of this, where going directly from
* activating to inactive is success.
*
finish:
/* Try to start the next jobs that can be started */
- HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_AFTER], i)
+ HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_AFTER])
if (other->job) {
job_add_to_run_queue(other->job);
job_add_to_gc_queue(other->job);
}
- HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_BEFORE], i)
+ HASHMAP_FOREACH_KEY(v, other, u->dependencies[UNIT_BEFORE])
if (other->job) {
job_add_to_run_queue(other->job);
job_add_to_gc_queue(other->job);
bool job_may_gc(Job *j) {
Unit *other;
- Iterator i;
void *v;
assert(j);
return false;
/* The logic is inverse to job_is_runnable, we cannot GC as long as we block any job. */
- HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_BEFORE], i)
+ HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_BEFORE])
if (other->job && job_compare(j, other->job, UNIT_BEFORE) < 0)
return false;
- HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_AFTER], i)
+ HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_AFTER])
if (other->job && job_compare(j, other->job, UNIT_AFTER) < 0)
return false;
_cleanup_free_ Job** list = NULL;
size_t n = 0, n_allocated = 0;
Unit *other = NULL;
- Iterator i;
void *v;
/* Returns a list of all pending jobs that need to finish before this job may be started. */
return 0;
}
- HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_AFTER], i) {
+ HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_AFTER]) {
if (!other->job)
continue;
if (job_compare(j, other->job, UNIT_AFTER) <= 0)
list[n++] = other->job;
}
- HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_BEFORE], i) {
+ HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_BEFORE]) {
if (!other->job)
continue;
if (job_compare(j, other->job, UNIT_BEFORE) <= 0)
size_t n = 0, n_allocated = 0;
Unit *other = NULL;
void *v;
- Iterator i;
assert(j);
assert(ret);
/* Returns a list of all pending jobs that are waiting for this job to finish. */
- HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_BEFORE], i) {
+ HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_BEFORE]) {
if (!other->job)
continue;
list[n++] = other->job;
}
- HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_AFTER], i) {
+ HASHMAP_FOREACH_KEY(v, other, j->unit->dependencies[UNIT_AFTER]) {
if (!other->job)
continue;
[JOB_FLUSH] = "flush",
[JOB_IGNORE_DEPENDENCIES] = "ignore-dependencies",
[JOB_IGNORE_REQUIREMENTS] = "ignore-requirements",
+ [JOB_TRIGGERING] = "triggering",
};
DEFINE_STRING_TABLE_LOOKUP(job_mode, JobMode);