X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Funit.c;h=117af4df4477700d06c4a88c2732a5236d4c6e67;hb=e677657e8dddb33d1f1e32eda0ebc126e08a538d;hp=bfb1dd644ebb62013d7f98cd23e112b9998f504b;hpb=d686d8a97bd7945af0a61504392d01a3167b576f;p=elogind.git diff --git a/src/unit.c b/src/unit.c index bfb1dd644..117af4df4 100644 --- a/src/unit.c +++ b/src/unit.c @@ -556,8 +556,12 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) { 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 @@ -732,12 +736,18 @@ int unit_add_default_target_dependency(Unit *u, Unit *target) { 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) return 0; + /* If either side wants no automatic dependencies, then let's + * skip this */ + if (!u->meta.default_dependencies || + target->meta.default_dependencies) + return 0; + /* Don't create loops */ if (set_get(target->meta.dependencies[UNIT_BEFORE], u)) return 0; @@ -746,27 +756,24 @@ int unit_add_default_target_dependency(Unit *u, Unit *target) { } static int unit_add_default_dependencies(Unit *u) { + static const UnitDependency deps[] = { + UNIT_REQUIRED_BY, + UNIT_REQUIRED_BY_OVERRIDABLE, + UNIT_WANTED_BY, + UNIT_BOUND_BY + }; + Unit *target; Iterator i; int r; + unsigned k; assert(u); - SET_FOREACH(target, u->meta.dependencies[UNIT_REQUIRED_BY], i) - if ((r = unit_add_default_target_dependency(u, target)) < 0) - return r; - - SET_FOREACH(target, u->meta.dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i) - if ((r = unit_add_default_target_dependency(u, target)) < 0) - return r; - - SET_FOREACH(target, u->meta.dependencies[UNIT_WANTED_BY], i) - if ((r = unit_add_default_target_dependency(u, target)) < 0) - return r; - - SET_FOREACH(target, u->meta.dependencies[UNIT_BOUND_BY], i) - if ((r = unit_add_default_target_dependency(u, target)) < 0) - return r; + for (k = 0; k < ELEMENTSOF(deps); k++) + SET_FOREACH(target, u->meta.dependencies[deps[k]], i) + if ((r = unit_add_default_target_dependency(u, target)) < 0) + return r; return 0; } @@ -818,6 +825,15 @@ fail: return r; } +bool unit_condition_test(Unit *u) { + assert(u); + + dual_timestamp_get(&u->meta.condition_timestamp); + u->meta.condition_result = condition_test_list(u->meta.conditions); + + return u->meta.condition_result; +} + /* Errors: * -EBADR: This unit type does not support starting. * -EALREADY: Unit is already started. @@ -842,7 +858,7 @@ int unit_start(Unit *u) { return -EALREADY; /* If the conditions failed, don't do anything at all */ - if (!condition_test_list(u->meta.conditions)) { + if (!unit_condition_test(u)) { log_debug("Starting of %s requested but condition failed. Ignoring.", u->meta.id); return -EALREADY; } @@ -1067,7 +1083,17 @@ static void retroactively_stop_dependencies(Unit *u) { 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; @@ -1110,7 +1136,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { 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) { @@ -1119,12 +1145,12 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { 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; @@ -1134,12 +1160,12 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { 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); } } @@ -1150,10 +1176,10 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { 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; @@ -1179,13 +1205,8 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { } 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 */ @@ -1194,7 +1215,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { /* 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 @@ -1785,55 +1806,61 @@ fail: return r; } -int unit_add_default_cgroups(Unit *u) { +static int unit_add_one_default_cgroup(Unit *u, const char *controller) { CGroupBonding *b = NULL; int r = -ENOMEM; - const char * const default_controllers[] = { - SYSTEMD_CGROUP_CONTROLLER, - "cpu", - NULL - }; - const char * const*c; assert(u); - /* Adds in the default cgroups, if it wasn't specified yet */ - - STRV_FOREACH(c, default_controllers) { - - if (cgroup_bonding_find_list(u->meta.cgroup_bondings, *c)) - continue; + if (!controller) + controller = SYSTEMD_CGROUP_CONTROLLER; - if (!(b = new0(CGroupBonding, 1))) - return -ENOMEM; + if (cgroup_bonding_find_list(u->meta.cgroup_bondings, controller)) + return 0; - if (!(b->path = default_cgroup_path(u))) - goto fail; + if (!(b = new0(CGroupBonding, 1))) + return -ENOMEM; - if (!(b->controller = strdup(*c))) - goto fail; + if (!(b->controller = strdup(controller))) + goto fail; - b->ours = true; - b->essential = c == default_controllers; /* the first one is essential */ + if (!(b->path = default_cgroup_path(u))) + goto fail; - if ((r = unit_add_cgroup(u, b)) < 0) - goto fail; + b->ours = true; + b->essential = streq(controller, SYSTEMD_CGROUP_CONTROLLER); - b = NULL; - } + if ((r = unit_add_cgroup(u, b)) < 0) + goto fail; return 0; fail: - if (b) { - free(b->path); - free(b->controller); - free(b); - } + free(b->path); + free(b->controller); + free(b); 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);