X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Funit.c;h=a5f6b2ead071fdf3a86ee310dbabebb955597f7f;hb=b5af2aca120f1bf13cffc270803c2232918dd967;hp=0e4ebfde9bc37bdfd8a7bd6df1ebb30ce25ebcf3;hpb=8eea868708923a092ee85d6146ba4c04b7baea06;p=elogind.git diff --git a/src/core/unit.c b/src/core/unit.c index 0e4ebfde9..a5f6b2ead 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -69,6 +69,8 @@ const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = { [UNIT_SCOPE] = &scope_vtable }; +static int maybe_warn_about_dependency(const char *id, const char *other, UnitDependency dependency); + Unit *unit_new(Manager *m, size_t size) { Unit *u; @@ -583,7 +585,7 @@ static void merge_names(Unit *u, Unit *other) { assert_se(hashmap_replace(u->manager->units, t, u) == 0); } -static void merge_dependencies(Unit *u, Unit *other, UnitDependency d) { +static void merge_dependencies(Unit *u, Unit *other, const char *other_id, UnitDependency d) { Iterator i; Unit *back; int r; @@ -597,14 +599,25 @@ static void merge_dependencies(Unit *u, Unit *other, UnitDependency d) { UnitDependency k; for (k = 0; k < _UNIT_DEPENDENCY_MAX; k++) { - r = set_remove_and_put(back->dependencies[k], other, u); - if (r == -EEXIST) - set_remove(back->dependencies[k], other); - else - assert(r >= 0 || r == -ENOENT); + /* Do not add dependencies between u and itself */ + if (back == u) { + if (set_remove(back->dependencies[k], other)) + maybe_warn_about_dependency(u->id, other_id, k); + } else { + r = set_remove_and_put(back->dependencies[k], other, u); + if (r == -EEXIST) + set_remove(back->dependencies[k], other); + else + assert(r >= 0 || r == -ENOENT); + } } } + /* Also do not move dependencies on u to itself */ + back = set_remove(other->dependencies[d], u); + if (back) + maybe_warn_about_dependency(u->id, other_id, d); + complete_move(&u->dependencies[d], &other->dependencies[d]); set_free(other->dependencies[d]); @@ -613,6 +626,7 @@ static void merge_dependencies(Unit *u, Unit *other, UnitDependency d) { int unit_merge(Unit *u, Unit *other) { UnitDependency d; + const char *other_id = NULL; assert(u); assert(other); @@ -643,6 +657,9 @@ int unit_merge(Unit *u, Unit *other) { if (!UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(other))) return -EEXIST; + if (other->id) + other_id = strdupa(other->id); + /* Merge names */ merge_names(u, other); @@ -652,7 +669,7 @@ int unit_merge(Unit *u, Unit *other) { /* Merge dependencies */ for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) - merge_dependencies(u, other, d); + merge_dependencies(u, other, other_id, d); other->load_state = UNIT_MERGED; other->merged_into = u; @@ -1031,6 +1048,9 @@ static int unit_add_slice_dependencies(Unit *u) { if (UNIT_ISSET(u->slice)) return unit_add_two_dependencies(u, UNIT_AFTER, UNIT_WANTS, UNIT_DEREF(u->slice), true); + if (streq(u->id, SPECIAL_ROOT_SLICE)) + return 0; + return unit_add_two_dependencies_by_name(u, UNIT_AFTER, UNIT_WANTS, SPECIAL_ROOT_SLICE, NULL, true); } @@ -1937,6 +1957,50 @@ bool unit_job_is_applicable(Unit *u, JobType j) { } } +static int maybe_warn_about_dependency(const char *id, const char *other, UnitDependency dependency) { + switch (dependency) { + case UNIT_REQUIRES: + case UNIT_REQUIRES_OVERRIDABLE: + case UNIT_WANTS: + case UNIT_REQUISITE: + case UNIT_REQUISITE_OVERRIDABLE: + case UNIT_BINDS_TO: + case UNIT_PART_OF: + case UNIT_REQUIRED_BY: + case UNIT_REQUIRED_BY_OVERRIDABLE: + case UNIT_WANTED_BY: + case UNIT_BOUND_BY: + case UNIT_CONSISTS_OF: + case UNIT_REFERENCES: + case UNIT_REFERENCED_BY: + case UNIT_PROPAGATES_RELOAD_TO: + case UNIT_RELOAD_PROPAGATED_FROM: + case UNIT_JOINS_NAMESPACE_OF: + return 0; + + case UNIT_CONFLICTS: + case UNIT_CONFLICTED_BY: + case UNIT_BEFORE: + case UNIT_AFTER: + case UNIT_ON_FAILURE: + case UNIT_TRIGGERS: + case UNIT_TRIGGERED_BY: + if (streq_ptr(id, other)) + log_warning_unit(id, "Dependency %s=%s dropped from unit %s", + unit_dependency_to_string(dependency), id, other); + else + log_warning_unit(id, "Dependency %s=%s dropped from unit %s merged into %s", + unit_dependency_to_string(dependency), id, + strna(other), id); + return -EINVAL; + + case _UNIT_DEPENDENCY_MAX: + case _UNIT_DEPENDENCY_INVALID: + break; + } + assert_not_reached("Invalid dependency type"); +} + int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_reference) { static const UnitDependency inverse_table[_UNIT_DEPENDENCY_MAX] = { @@ -1966,6 +2030,7 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen [UNIT_JOINS_NAMESPACE_OF] = UNIT_JOINS_NAMESPACE_OF, }; int r, q = 0, v = 0, w = 0; + Unit *orig_u = u, *orig_other = other; assert(u); assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX); @@ -1976,8 +2041,10 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen /* We won't allow dependencies on ourselves. We will not * consider them an error however. */ - if (u == other) + if (u == other) { + maybe_warn_about_dependency(orig_u->id, orig_other->id, d); return 0; + } r = set_ensure_allocated(&u->dependencies[d], trivial_hash_func, trivial_compare_func); if (r < 0) @@ -2165,11 +2232,8 @@ int unit_add_two_dependencies_by_name_inverse(Unit *u, UnitDependency d, UnitDep } int set_unit_path(const char *p) { - _cleanup_free_ char *c = NULL; - /* This is mostly for debug purposes */ - c = path_make_absolute_cwd(p); - if (setenv("SYSTEMD_UNIT_PATH", c, 0) < 0) + if (setenv("SYSTEMD_UNIT_PATH", p, 0) < 0) return -errno; return 0;