core: introduce seperate reverse dependencies for Requires= and Requisite=
This allows us to ensure that Requisite= dependencies never cause propagation between units, while Requires= dependencies might. http://lists.freedesktop.org/archives/systemd-devel/2015-May/031742.html
This commit is contained in:
parent
9530e0d023
commit
be7d9ff730
|
@ -561,6 +561,8 @@ const sd_bus_vtable bus_unit_vtable[] = {
|
||||||
SD_BUS_PROPERTY("PartOf", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_PART_OF]), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("PartOf", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_PART_OF]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("RequiredBy", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUIRED_BY]), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("RequiredBy", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUIRED_BY]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("RequiredByOverridable", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUIRED_BY_OVERRIDABLE]), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("RequiredByOverridable", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUIRED_BY_OVERRIDABLE]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
SD_BUS_PROPERTY("RequisiteOf", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUISITE_OF]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
SD_BUS_PROPERTY("RequisiteOfOverridable", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_REQUISITE_OF_OVERRIDABLE]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("WantedBy", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_WANTED_BY]), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("WantedBy", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_WANTED_BY]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("BoundBy", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_BOUND_BY]), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("BoundBy", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_BOUND_BY]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
SD_BUS_PROPERTY("ConsistsOf", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_CONSISTS_OF]), SD_BUS_VTABLE_PROPERTY_CONST),
|
SD_BUS_PROPERTY("ConsistsOf", "as", property_get_dependencies, offsetof(Unit, dependencies[UNIT_CONSISTS_OF]), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||||
|
|
|
@ -790,6 +790,24 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void job_fail_dependencies(Unit *u, UnitDependency d) {
|
||||||
|
Unit *other;
|
||||||
|
Iterator i;
|
||||||
|
|
||||||
|
assert(u);
|
||||||
|
|
||||||
|
SET_FOREACH(other, u->dependencies[d], i) {
|
||||||
|
Job *j = other->job;
|
||||||
|
|
||||||
|
if (!j)
|
||||||
|
continue;
|
||||||
|
if (!IN_SET(j->type, JOB_START, JOB_VERIFY_ACTIVE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
job_finish_and_invalidate(j, JOB_DEPENDENCY, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) {
|
int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) {
|
||||||
Unit *u;
|
Unit *u;
|
||||||
Unit *other;
|
Unit *other;
|
||||||
|
@ -831,37 +849,14 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) {
|
||||||
|
|
||||||
/* Fail depending jobs on failure */
|
/* Fail depending jobs on failure */
|
||||||
if (result != JOB_DONE && recursive) {
|
if (result != JOB_DONE && recursive) {
|
||||||
|
if (IN_SET(t, JOB_START, JOB_VERIFY_ACTIVE)) {
|
||||||
if (t == JOB_START ||
|
job_fail_dependencies(u, UNIT_REQUIRED_BY);
|
||||||
t == JOB_VERIFY_ACTIVE) {
|
job_fail_dependencies(u, UNIT_REQUISITE_OF);
|
||||||
|
job_fail_dependencies(u, UNIT_BOUND_BY);
|
||||||
SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
|
job_fail_dependencies(u, UNIT_REQUIRED_BY_OVERRIDABLE);
|
||||||
if (other->job &&
|
job_fail_dependencies(u, UNIT_REQUISITE_OF_OVERRIDABLE);
|
||||||
(other->job->type == JOB_START ||
|
} else if (t == JOB_STOP)
|
||||||
other->job->type == JOB_VERIFY_ACTIVE))
|
job_fail_dependencies(u, UNIT_CONFLICTED_BY);
|
||||||
job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
|
|
||||||
|
|
||||||
SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
|
|
||||||
if (other->job &&
|
|
||||||
(other->job->type == JOB_START ||
|
|
||||||
other->job->type == JOB_VERIFY_ACTIVE))
|
|
||||||
job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
|
|
||||||
|
|
||||||
SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
|
|
||||||
if (other->job &&
|
|
||||||
!other->job->override &&
|
|
||||||
(other->job->type == JOB_START ||
|
|
||||||
other->job->type == JOB_VERIFY_ACTIVE))
|
|
||||||
job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
|
|
||||||
|
|
||||||
} else if (t == JOB_STOP) {
|
|
||||||
|
|
||||||
SET_FOREACH(other, u->dependencies[UNIT_CONFLICTED_BY], i)
|
|
||||||
if (other->job &&
|
|
||||||
(other->job->type == JOB_START ||
|
|
||||||
other->job->type == JOB_VERIFY_ACTIVE))
|
|
||||||
job_finish_and_invalidate(other->job, JOB_DEPENDENCY, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Trigger OnFailure dependencies that are not generated by
|
/* Trigger OnFailure dependencies that are not generated by
|
||||||
|
|
|
@ -1092,6 +1092,8 @@ static int unit_add_target_dependencies(Unit *u) {
|
||||||
static const UnitDependency deps[] = {
|
static const UnitDependency deps[] = {
|
||||||
UNIT_REQUIRED_BY,
|
UNIT_REQUIRED_BY,
|
||||||
UNIT_REQUIRED_BY_OVERRIDABLE,
|
UNIT_REQUIRED_BY_OVERRIDABLE,
|
||||||
|
UNIT_REQUISITE_OF,
|
||||||
|
UNIT_REQUISITE_OF_OVERRIDABLE,
|
||||||
UNIT_WANTED_BY,
|
UNIT_WANTED_BY,
|
||||||
UNIT_BOUND_BY
|
UNIT_BOUND_BY
|
||||||
};
|
};
|
||||||
|
@ -1589,8 +1591,20 @@ bool unit_can_reload(Unit *u) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unit_check_unneeded(Unit *u) {
|
static void unit_check_unneeded(Unit *u) {
|
||||||
Iterator i;
|
|
||||||
|
static const UnitDependency needed_dependencies[] = {
|
||||||
|
UNIT_REQUIRED_BY,
|
||||||
|
UNIT_REQUIRED_BY_OVERRIDABLE,
|
||||||
|
UNIT_REQUISITE,
|
||||||
|
UNIT_REQUISITE_OF_OVERRIDABLE,
|
||||||
|
UNIT_WANTED_BY,
|
||||||
|
UNIT_BOUND_BY,
|
||||||
|
};
|
||||||
|
|
||||||
Unit *other;
|
Unit *other;
|
||||||
|
Iterator i;
|
||||||
|
unsigned j;
|
||||||
|
int r;
|
||||||
|
|
||||||
assert(u);
|
assert(u);
|
||||||
|
|
||||||
|
@ -1603,26 +1617,17 @@ static void unit_check_unneeded(Unit *u) {
|
||||||
if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
|
if (!UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY], i)
|
for (j = 0; j < ELEMENTSOF(needed_dependencies); j++)
|
||||||
if (unit_active_or_pending(other))
|
SET_FOREACH(other, u->dependencies[j], i)
|
||||||
return;
|
if (unit_active_or_pending(other))
|
||||||
|
return;
|
||||||
SET_FOREACH(other, u->dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
|
|
||||||
if (unit_active_or_pending(other))
|
|
||||||
return;
|
|
||||||
|
|
||||||
SET_FOREACH(other, u->dependencies[UNIT_WANTED_BY], i)
|
|
||||||
if (unit_active_or_pending(other))
|
|
||||||
return;
|
|
||||||
|
|
||||||
SET_FOREACH(other, u->dependencies[UNIT_BOUND_BY], i)
|
|
||||||
if (unit_active_or_pending(other))
|
|
||||||
return;
|
|
||||||
|
|
||||||
log_unit_info(u, "Unit not needed anymore. Stopping.");
|
log_unit_info(u, "Unit not needed anymore. Stopping.");
|
||||||
|
|
||||||
/* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
|
/* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
|
||||||
manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
|
r = manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
|
||||||
|
if (r < 0)
|
||||||
|
log_unit_warning_errno(u, r, "Failed to enqueue stop job, ignoring: %m");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void unit_check_binds_to(Unit *u) {
|
static void unit_check_binds_to(Unit *u) {
|
||||||
|
@ -2163,13 +2168,15 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen
|
||||||
[UNIT_REQUIRES] = UNIT_REQUIRED_BY,
|
[UNIT_REQUIRES] = UNIT_REQUIRED_BY,
|
||||||
[UNIT_REQUIRES_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
|
[UNIT_REQUIRES_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
|
||||||
[UNIT_WANTS] = UNIT_WANTED_BY,
|
[UNIT_WANTS] = UNIT_WANTED_BY,
|
||||||
[UNIT_REQUISITE] = UNIT_REQUIRED_BY,
|
[UNIT_REQUISITE] = UNIT_REQUISITE_OF,
|
||||||
[UNIT_REQUISITE_OVERRIDABLE] = UNIT_REQUIRED_BY_OVERRIDABLE,
|
[UNIT_REQUISITE_OVERRIDABLE] = UNIT_REQUISITE_OF_OVERRIDABLE,
|
||||||
[UNIT_BINDS_TO] = UNIT_BOUND_BY,
|
[UNIT_BINDS_TO] = UNIT_BOUND_BY,
|
||||||
[UNIT_PART_OF] = UNIT_CONSISTS_OF,
|
[UNIT_PART_OF] = UNIT_CONSISTS_OF,
|
||||||
[UNIT_REQUIRED_BY] = _UNIT_DEPENDENCY_INVALID,
|
[UNIT_REQUIRED_BY] = UNIT_REQUIRES,
|
||||||
[UNIT_REQUIRED_BY_OVERRIDABLE] = _UNIT_DEPENDENCY_INVALID,
|
[UNIT_REQUIRED_BY_OVERRIDABLE] = UNIT_REQUIRES_OVERRIDABLE,
|
||||||
[UNIT_WANTED_BY] = _UNIT_DEPENDENCY_INVALID,
|
[UNIT_REQUISITE_OF] = UNIT_REQUISITE,
|
||||||
|
[UNIT_REQUISITE_OF_OVERRIDABLE] = UNIT_REQUISITE_OVERRIDABLE,
|
||||||
|
[UNIT_WANTED_BY] = UNIT_WANTS,
|
||||||
[UNIT_BOUND_BY] = UNIT_BINDS_TO,
|
[UNIT_BOUND_BY] = UNIT_BINDS_TO,
|
||||||
[UNIT_CONSISTS_OF] = UNIT_PART_OF,
|
[UNIT_CONSISTS_OF] = UNIT_PART_OF,
|
||||||
[UNIT_CONFLICTS] = UNIT_CONFLICTED_BY,
|
[UNIT_CONFLICTS] = UNIT_CONFLICTED_BY,
|
||||||
|
|
|
@ -812,6 +812,8 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
|
||||||
[UNIT_PART_OF] = "PartOf",
|
[UNIT_PART_OF] = "PartOf",
|
||||||
[UNIT_REQUIRED_BY] = "RequiredBy",
|
[UNIT_REQUIRED_BY] = "RequiredBy",
|
||||||
[UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable",
|
[UNIT_REQUIRED_BY_OVERRIDABLE] = "RequiredByOverridable",
|
||||||
|
[UNIT_REQUISITE_OF] = "RequisiteOf",
|
||||||
|
[UNIT_REQUISITE_OF_OVERRIDABLE] = "RequisiteOfOverridable",
|
||||||
[UNIT_WANTED_BY] = "WantedBy",
|
[UNIT_WANTED_BY] = "WantedBy",
|
||||||
[UNIT_BOUND_BY] = "BoundBy",
|
[UNIT_BOUND_BY] = "BoundBy",
|
||||||
[UNIT_CONSISTS_OF] = "ConsistsOf",
|
[UNIT_CONSISTS_OF] = "ConsistsOf",
|
||||||
|
|
|
@ -71,8 +71,10 @@ enum UnitDependency {
|
||||||
UNIT_PART_OF,
|
UNIT_PART_OF,
|
||||||
|
|
||||||
/* Inverse of the above */
|
/* Inverse of the above */
|
||||||
UNIT_REQUIRED_BY, /* inverse of 'requires' and 'requisite' is 'required_by' */
|
UNIT_REQUIRED_BY, /* inverse of 'requires' is 'required_by' */
|
||||||
UNIT_REQUIRED_BY_OVERRIDABLE, /* inverse of 'requires_overridable' and 'requisite_overridable' is 'soft_required_by' */
|
UNIT_REQUIRED_BY_OVERRIDABLE, /* inverse of 'requires_overridable' is 'required_by_overridable' */
|
||||||
|
UNIT_REQUISITE_OF, /* inverse of 'requisite' is 'requisite_of' */
|
||||||
|
UNIT_REQUISITE_OF_OVERRIDABLE,/* inverse of 'requisite_overridable' is 'requisite_of_overridable' */
|
||||||
UNIT_WANTED_BY, /* inverse of 'wants' */
|
UNIT_WANTED_BY, /* inverse of 'wants' */
|
||||||
UNIT_BOUND_BY, /* inverse of 'binds_to' */
|
UNIT_BOUND_BY, /* inverse of 'binds_to' */
|
||||||
UNIT_CONSISTS_OF, /* inverse of 'part_of' */
|
UNIT_CONSISTS_OF, /* inverse of 'part_of' */
|
||||||
|
|
Loading…
Reference in New Issue