Skip to content

Commit c999cf3

Browse files
committed
core: add internal API to remove dependencies again, based on dependency mask
let's make use of the dependency mask, and add internal API to remove dependencies ago, based on bits in the dependency mask.
1 parent 2651d03 commit c999cf3

File tree

3 files changed

+98
-0
lines changed

3 files changed

+98
-0
lines changed

src/core/unit.c

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4831,3 +4831,72 @@ int unit_fork_helper_process(Unit *u, pid_t *ret) {
48314831
*ret = pid;
48324832
return 1;
48334833
}
4834+
4835+
static void unit_update_dependency_mask(Unit *u, UnitDependency d, Unit *other, UnitDependencyInfo di) {
4836+
assert(u);
4837+
assert(d >= 0);
4838+
assert(d < _UNIT_DEPENDENCY_MAX);
4839+
assert(other);
4840+
4841+
if (di.origin_mask == 0 && di.destination_mask == 0) {
4842+
/* No bit set anymore, let's drop the whole entry */
4843+
assert_se(hashmap_remove(u->dependencies[d], other));
4844+
log_unit_debug(u, "%s lost dependency %s=%s", u->id, unit_dependency_to_string(d), other->id);
4845+
} else
4846+
/* Mask was reduced, let's update the entry */
4847+
assert_se(hashmap_update(u->dependencies[d], other, di.data) == 0);
4848+
}
4849+
4850+
void unit_remove_dependencies(Unit *u, UnitDependencyMask mask) {
4851+
UnitDependency d;
4852+
4853+
assert(u);
4854+
4855+
/* Removes all dependencies u has on other units marked for ownership by 'mask'. */
4856+
4857+
if (mask == 0)
4858+
return;
4859+
4860+
for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
4861+
bool done;
4862+
4863+
do {
4864+
UnitDependencyInfo di;
4865+
Unit *other;
4866+
Iterator i;
4867+
4868+
done = true;
4869+
4870+
HASHMAP_FOREACH_KEY(di.data, other, u->dependencies[d], i) {
4871+
UnitDependency q;
4872+
4873+
if ((di.origin_mask & ~mask) == di.origin_mask)
4874+
continue;
4875+
di.origin_mask &= ~mask;
4876+
unit_update_dependency_mask(u, d, other, di);
4877+
4878+
/* We updated the dependency from our unit to the other unit now. But most dependencies
4879+
* imply a reverse dependency. Hence, let's delete that one too. For that we go through
4880+
* all dependency types on the other unit and delete all those which point to us and
4881+
* have the right mask set. */
4882+
4883+
for (q = 0; q < _UNIT_DEPENDENCY_MAX; q++) {
4884+
UnitDependencyInfo dj;
4885+
4886+
dj.data = hashmap_get(other->dependencies[q], u);
4887+
if ((dj.destination_mask & ~mask) == dj.destination_mask)
4888+
continue;
4889+
dj.destination_mask &= ~mask;
4890+
4891+
unit_update_dependency_mask(other, q, u, dj);
4892+
}
4893+
4894+
unit_add_to_gc_queue(other);
4895+
4896+
done = false;
4897+
break;
4898+
}
4899+
4900+
} while (!done);
4901+
}
4902+
}

src/core/unit.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,8 @@ void unit_set_exec_params(Unit *s, ExecParameters *p);
740740

741741
int unit_fork_helper_process(Unit *u, pid_t *ret);
742742

743+
void unit_remove_dependencies(Unit *u, UnitDependencyMask mask);
744+
743745
/* Macros which append UNIT= or USER_UNIT= to the message */
744746

745747
#define log_unit_full(unit, level, error, ...) \

src/test/test-engine.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,33 @@ int main(int argc, char *argv[]) {
115115
assert_se(manager_add_job(m, JOB_START, h, JOB_FAIL, NULL, &j) == 0);
116116
manager_dump_jobs(m, stdout, "\t");
117117

118+
assert_se(!hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], b));
119+
assert_se(!hashmap_get(b->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
120+
assert_se(!hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], c));
121+
assert_se(!hashmap_get(c->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
122+
123+
assert_se(unit_add_dependency(a, UNIT_PROPAGATES_RELOAD_TO, b, true, UNIT_DEPENDENCY_UDEV) == 0);
124+
assert_se(unit_add_dependency(a, UNIT_PROPAGATES_RELOAD_TO, c, true, UNIT_DEPENDENCY_PROC_SWAP) == 0);
125+
126+
assert_se(hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], b));
127+
assert_se(hashmap_get(b->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
128+
assert_se(hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], c));
129+
assert_se(hashmap_get(c->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
130+
131+
unit_remove_dependencies(a, UNIT_DEPENDENCY_UDEV);
132+
133+
assert_se(!hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], b));
134+
assert_se(!hashmap_get(b->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
135+
assert_se(hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], c));
136+
assert_se(hashmap_get(c->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
137+
138+
unit_remove_dependencies(a, UNIT_DEPENDENCY_PROC_SWAP);
139+
140+
assert_se(!hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], b));
141+
assert_se(!hashmap_get(b->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
142+
assert_se(!hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], c));
143+
assert_se(!hashmap_get(c->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
144+
118145
manager_free(m);
119146

120147
return 0;

0 commit comments

Comments
 (0)