job.c revision aa49ab5f22c0fdc7a5381d4e452f40705f3d7bf8
c46bcd7c6908745e19b0b1fe18a23bbaaee553edBob Halley/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
c46bcd7c6908745e19b0b1fe18a23bbaaee553edBob Halley This file is part of systemd.
c46bcd7c6908745e19b0b1fe18a23bbaaee553edBob Halley Copyright 2010 Lennart Poettering
c46bcd7c6908745e19b0b1fe18a23bbaaee553edBob Halley systemd is free software; you can redistribute it and/or modify it
c46bcd7c6908745e19b0b1fe18a23bbaaee553edBob Halley under the terms of the GNU Lesser General Public License as published by
c46bcd7c6908745e19b0b1fe18a23bbaaee553edBob Halley the Free Software Foundation; either version 2.1 of the License, or
c46bcd7c6908745e19b0b1fe18a23bbaaee553edBob Halley (at your option) any later version.
c46bcd7c6908745e19b0b1fe18a23bbaaee553edBob Halley systemd is distributed in the hope that it will be useful, but
c46bcd7c6908745e19b0b1fe18a23bbaaee553edBob Halley WITHOUT ANY WARRANTY; without even the implied warranty of
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
f41f183f628a148860a6d1f0070208cddd45b0c6Bob Halley Lesser General Public License for more details.
f41f183f628a148860a6d1f0070208cddd45b0c6Bob Halley You should have received a copy of the GNU Lesser General Public License
f41f183f628a148860a6d1f0070208cddd45b0c6Bob Halley along with systemd; If not, see <http://www.gnu.org/licenses/>.
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley /* used for deserialization */
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley /* We don't link it here, that's what job_dependency() is for */
60804eec9b2e36ead801e6ff7ad46586774ad828Michael Graff LIST_REMOVE(run_queue, j->manager->run_queue, j);
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley LIST_REMOVE(dbus_queue, j->manager->dbus_job_queue, j);
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halleystatic void job_set_state(Job *j, JobState state) {
e535faecc70425e7c9fc3faf4064792804c125a0Bob Halley j->unit->manager->jobs_in_progress_event_source = sd_event_source_unref(j->unit->manager->jobs_in_progress_event_source);
44aae046c38e796e581110b7ecdf4478167d684dBob Halley pj = (j->type == JOB_NOP) ? &j->unit->nop_job : &j->unit->job;
j->installed = false;
return t != JOB_RELOAD;
if (uj) {
return uj;
return uj;
*pj = j;
j->installed = true;
return -EINVAL;
if (*pj) {
return -EEXIST;
*pj = j;
j->installed = true;
JobDependency *l;
return NULL;
if (subject)
assert(l);
if (l->subject)
free(l);
assert(j);
assert(f);
if (!prefix)
fprintf(f,
assert_cc(ELEMENTSOF(job_merging_table) == _JOB_TYPE_MAX_MERGING * (_JOB_TYPE_MAX_MERGING - 1) / 2);
b = tmp;
case JOB_START:
b == UNIT_ACTIVE ||
b == UNIT_RELOADING;
case JOB_STOP:
b == UNIT_INACTIVE ||
b == UNIT_FAILED;
case JOB_VERIFY_ACTIVE:
b == UNIT_ACTIVE ||
b == UNIT_RELOADING;
case JOB_RELOAD:
b == UNIT_RELOADING;
case JOB_RESTART:
b == UNIT_ACTIVATING;
case JOB_NOP:
case JOB_TRY_RESTART:
s = unit_active_state(u);
if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
return JOB_NOP;
return JOB_RESTART;
case JOB_RELOAD_OR_START:
s = unit_active_state(u);
if (UNIT_IS_INACTIVE_OR_DEACTIVATING(s))
return JOB_START;
return JOB_RELOAD;
JobType t;
t = job_type_lookup_merge(*a, b);
return -EEXIST;
*a = job_type_collapse(t, u);
Iterator i;
assert(j);
if (j->ignore_order)
assert(j);
case JOB_START:
r = unit_start(u);
case JOB_RESTART:
t = JOB_STOP;
case JOB_STOP:
r = unit_stop(u);
case JOB_RELOAD:
r = unit_reload(u);
assert(j);
j->in_run_queue = false;
if (!job_is_runnable(j))
return -EAGAIN;
switch (j->type) {
case JOB_VERIFY_ACTIVE: {
if (UNIT_IS_ACTIVE_OR_RELOADING(t))
r = -EALREADY;
else if (t == UNIT_ACTIVATING)
r = -EAGAIN;
r = -EBADR;
case JOB_START:
case JOB_STOP:
case JOB_RESTART:
r = job_perform_on_unit(&j);
if (r == -EBADR)
case JOB_RELOAD:
r = job_perform_on_unit(&j);
case JOB_NOP:
r = -EALREADY;
if (r == -EALREADY)
else if (r == -EBADR)
else if (r == -ENOEXEC)
else if (r == -EPROTO)
else if (r == -EOPNOTSUPP)
else if (r == -EAGAIN)
const char *format;
assert(u);
assert(t >= 0);
if (format_table) {
if (format)
return format;
if (t == JOB_START)
else if (t == JOB_RELOAD)
else if (t == JOB_VERIFY_ACTIVE)
return NULL;
const char *format;
assert(u);
assert(t >= 0);
if (t == JOB_RELOAD)
if (!format)
const char *format;
assert(u);
assert(t >= 0);
if (log_on_console())
if (!format)
if (t == JOB_START) {
LOG_UNIT_ID(u),
NULL);
} else if (t == JOB_STOP)
LOG_UNIT_ID(u),
NULL);
else if (t == JOB_RELOAD)
LOG_UNIT_ID(u),
NULL);
Iterator i;
assert(u);
Unit *u;
JobType t;
Iterator i;
assert(j);
u = j->unit;
t = j->type;
log_unit_debug(u, "Job %s/%s finished, result=%s", u->id, job_type_to_string(t), job_result_to_string(result));
goto finish;
job_uninstall(j);
job_free(j);
} else if (t == JOB_STOP)
LOG_UNIT_ID(u),
u->id,
NULL);
Unit *u;
assert(j);
u = j->unit;
if (j->timer_event_source)
r = sd_event_add_time(
&j->timer_event_source,
job_dispatch_timer, j);
assert(j);
if (j->in_run_queue)
j->in_run_queue = true;
assert(j);
if (j->in_dbus_queue)
* connection/client. */
j->in_dbus_queue = true;
assert(j);
return NULL;
if (j->begin_usec > 0)
assert(j);
size_t k;
if (feof(f))
return -errno;
JobType t;
t = job_type_from_string(v);
else if (t >= _JOB_TYPE_MAX_IN_TRANSACTION)
j->type = t;
JobState s;
s = job_state_from_string(v);
job_set_state(j, s);
b = parse_boolean(v);
b = parse_boolean(v);
b = parse_boolean(v);
b = parse_boolean(v);
unsigned long long ull;
return log_oom();
assert(j);
if (j->timer_event_source)
r = sd_event_add_time(
&j->timer_event_source,
job_dispatch_timer, j);
assert(j);
assert(u);
if (j->timer_event_source) {