if (c->std_output != EXEC_OUTPUT_KMSG &&
c->std_output != EXEC_OUTPUT_SYSLOG &&
+ c->std_output != EXEC_OUTPUT_KMSG_AND_CONSOLE &&
+ c->std_output != EXEC_OUTPUT_SYSLOG_AND_CONSOLE &&
c->std_error != EXEC_OUTPUT_KMSG &&
- c->std_error != EXEC_OUTPUT_SYSLOG)
+ c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE &&
+ c->std_error != EXEC_OUTPUT_KMSG &&
+ c->std_error != EXEC_OUTPUT_SYSLOG_AND_CONSOLE)
return 0;
/* If syslog or kernel logging is requested, make sure our own
if (target->meta.type != UNIT_TARGET)
return 0;
- /* Only add the dependency if boths units are loaded, so that
+ /* Only add the dependency if both units are loaded, so that
* that loop check below is reliable */
if (u->meta.load_state != UNIT_LOADED ||
target->meta.load_state != UNIT_LOADED)
unit_check_unneeded(other);
}
-void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) {
+void unit_trigger_on_failure(Unit *u) {
+ Unit *other;
+ Iterator i;
+
+ assert(u);
+
+ SET_FOREACH(other, u->meta.dependencies[UNIT_ON_FAILURE], i)
+ manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
+}
+
+void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) {
dual_timestamp ts;
bool unexpected;
job_add_to_run_queue(u->meta.job);
/* Let's check whether this state change constitutes a
- * finished job, or maybe cotradicts a running job and
+ * finished job, or maybe contradicts a running job and
* hence needs to invalidate jobs. */
switch (u->meta.job->type) {
case JOB_VERIFY_ACTIVE:
if (UNIT_IS_ACTIVE_OR_RELOADING(ns))
- job_finish_and_invalidate(u->meta.job, true);
+ job_finish_and_invalidate(u->meta.job, JOB_DONE);
else if (u->meta.job->state == JOB_RUNNING && ns != UNIT_ACTIVATING) {
unexpected = true;
if (UNIT_IS_INACTIVE_OR_FAILED(ns))
- job_finish_and_invalidate(u->meta.job, ns != UNIT_FAILED);
+ job_finish_and_invalidate(u->meta.job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE);
}
break;
if (u->meta.job->state == JOB_RUNNING) {
if (ns == UNIT_ACTIVE)
- job_finish_and_invalidate(u->meta.job, true);
+ job_finish_and_invalidate(u->meta.job, reload_success ? JOB_DONE : JOB_FAILED);
else if (ns != UNIT_ACTIVATING && ns != UNIT_RELOADING) {
unexpected = true;
if (UNIT_IS_INACTIVE_OR_FAILED(ns))
- job_finish_and_invalidate(u->meta.job, ns != UNIT_FAILED);
+ job_finish_and_invalidate(u->meta.job, ns == UNIT_FAILED ? JOB_FAILED : JOB_DONE);
}
}
case JOB_TRY_RESTART:
if (UNIT_IS_INACTIVE_OR_FAILED(ns))
- job_finish_and_invalidate(u->meta.job, true);
+ job_finish_and_invalidate(u->meta.job, JOB_DONE);
else if (u->meta.job->state == JOB_RUNNING && ns != UNIT_DEACTIVATING) {
unexpected = true;
- job_finish_and_invalidate(u->meta.job, false);
+ job_finish_and_invalidate(u->meta.job, JOB_FAILED);
}
break;
}
if (ns != os && ns == UNIT_FAILED) {
- Iterator i;
- Unit *other;
-
- SET_FOREACH(other, u->meta.dependencies[UNIT_ON_FAILURE], i)
- manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
-
log_notice("Unit %s entered failed state.", u->meta.id);
+ unit_trigger_on_failure(u);
}
/* Some names are special */
/* The bus just might have become available,
* hence try to connect to it, if we aren't
* yet connected. */
- bus_init(u->meta.manager);
+ bus_init(u->meta.manager, true);
if (unit_has_name(u, SPECIAL_SYSLOG_SERVICE))
/* The syslog daemon just might have become
if (u == other)
return 0;
- if (UNIT_VTABLE(u)->no_requires &&
- (d == UNIT_REQUIRES ||
- d == UNIT_REQUIRES_OVERRIDABLE ||
- d == UNIT_REQUISITE ||
- d == UNIT_REQUISITE_OVERRIDABLE ||
- d == UNIT_BIND_TO)) {
- return -EINVAL;
- }
-
if ((r = set_ensure_allocated(&u->meta.dependencies[d], trivial_hash_func, trivial_compare_func)) < 0)
return r;
}
int unit_add_cgroup(Unit *u, CGroupBonding *b) {
- CGroupBonding *l;
int r;
assert(u);
/* Ensure this hasn't been added yet */
assert(!b->unit);
- l = hashmap_get(u->meta.manager->cgroup_bondings, b->path);
- LIST_PREPEND(CGroupBonding, by_path, l, b);
+ if (streq(b->controller, SYSTEMD_CGROUP_CONTROLLER)) {
+ CGroupBonding *l;
- if ((r = hashmap_replace(u->meta.manager->cgroup_bondings, b->path, l)) < 0) {
- LIST_REMOVE(CGroupBonding, by_path, l, b);
- return r;
+ l = hashmap_get(u->meta.manager->cgroup_bondings, b->path);
+ LIST_PREPEND(CGroupBonding, by_path, l, b);
+
+ if ((r = hashmap_replace(u->meta.manager->cgroup_bondings, b->path, l)) < 0) {
+ LIST_REMOVE(CGroupBonding, by_path, l, b);
+ return r;
+ }
}
LIST_PREPEND(CGroupBonding, by_unit, u->meta.cgroup_bondings, b);
b->controller = controller;
b->path = path;
- b->only_us = false;
- b->clean_up = false;
+ b->ours = false;
if ((r = unit_add_cgroup(u, b)) < 0)
goto fail;
return r;
}
-int unit_add_default_cgroup(Unit *u) {
- CGroupBonding *b;
+static int unit_add_one_default_cgroup(Unit *u, const char *controller) {
+ CGroupBonding *b = NULL;
int r = -ENOMEM;
assert(u);
- /* Adds in the default cgroup data, if it wasn't specified yet */
+ if (!controller)
+ controller = SYSTEMD_CGROUP_CONTROLLER;
- if (unit_get_default_cgroup(u))
+ if (cgroup_bonding_find_list(u->meta.cgroup_bondings, controller))
return 0;
if (!(b = new0(CGroupBonding, 1)))
return -ENOMEM;
+ if (!(b->controller = strdup(controller)))
+ goto fail;
+
if (!(b->path = default_cgroup_path(u)))
goto fail;
- b->clean_up = true;
- b->only_us = true;
+ b->ours = true;
+ b->essential = streq(controller, SYSTEMD_CGROUP_CONTROLLER);
if ((r = unit_add_cgroup(u, b)) < 0)
goto fail;
return r;
}
+int unit_add_default_cgroups(Unit *u) {
+ char **c;
+ int r;
+ assert(u);
+
+ /* Adds in the default cgroups, if they weren't specified
+ * otherwise. */
+
+ if ((r = unit_add_one_default_cgroup(u, NULL)) < 0)
+ return r;
+
+ STRV_FOREACH(c, u->meta.manager->default_controllers)
+ if ((r = unit_add_one_default_cgroup(u, *c)) < 0)
+ return r;
+
+ return 0;
+}
+
CGroupBonding* unit_get_default_cgroup(Unit *u) {
assert(u);
return UNIT_VTABLE(u)->kill(u, w, m, signo, error);
}
+
+int unit_following_set(Unit *u, Set **s) {
+ assert(u);
+ assert(s);
+
+ if (UNIT_VTABLE(u)->following_set)
+ return UNIT_VTABLE(u)->following_set(u, s);
+
+ *s = NULL;
+ return 0;
+}
+
static const char* const unit_load_state_table[_UNIT_LOAD_STATE_MAX] = {
[UNIT_STUB] = "stub",
[UNIT_LOADED] = "loaded",