*ret = pid;
return 1;
}
+
+static void unit_update_dependency_mask(Unit *u, UnitDependency d, Unit *other, UnitDependencyInfo di) {
+ assert(u);
+ assert(d >= 0);
+ assert(d < _UNIT_DEPENDENCY_MAX);
+ assert(other);
+
+ if (di.origin_mask == 0 && di.destination_mask == 0) {
+ /* No bit set anymore, let's drop the whole entry */
+ assert_se(hashmap_remove(u->dependencies[d], other));
+ log_unit_debug(u, "%s lost dependency %s=%s", u->id, unit_dependency_to_string(d), other->id);
+ } else
+ /* Mask was reduced, let's update the entry */
+ assert_se(hashmap_update(u->dependencies[d], other, di.data) == 0);
+}
+
+void unit_remove_dependencies(Unit *u, UnitDependencyMask mask) {
+ UnitDependency d;
+
+ assert(u);
+
+ /* Removes all dependencies u has on other units marked for ownership by 'mask'. */
+
+ if (mask == 0)
+ return;
+
+ for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
+ bool done;
+
+ do {
+ UnitDependencyInfo di;
+ Unit *other;
+ Iterator i;
+
+ done = true;
+
+ HASHMAP_FOREACH_KEY(di.data, other, u->dependencies[d], i) {
+ UnitDependency q;
+
+ if ((di.origin_mask & ~mask) == di.origin_mask)
+ continue;
+ di.origin_mask &= ~mask;
+ unit_update_dependency_mask(u, d, other, di);
+
+ /* We updated the dependency from our unit to the other unit now. But most dependencies
+ * imply a reverse dependency. Hence, let's delete that one too. For that we go through
+ * all dependency types on the other unit and delete all those which point to us and
+ * have the right mask set. */
+
+ for (q = 0; q < _UNIT_DEPENDENCY_MAX; q++) {
+ UnitDependencyInfo dj;
+
+ dj.data = hashmap_get(other->dependencies[q], u);
+ if ((dj.destination_mask & ~mask) == dj.destination_mask)
+ continue;
+ dj.destination_mask &= ~mask;
+
+ unit_update_dependency_mask(other, q, u, dj);
+ }
+
+ unit_add_to_gc_queue(other);
+
+ done = false;
+ break;
+ }
+
+ } while (!done);
+ }
+}
int unit_fork_helper_process(Unit *u, pid_t *ret);
+void unit_remove_dependencies(Unit *u, UnitDependencyMask mask);
+
/* Macros which append UNIT= or USER_UNIT= to the message */
#define log_unit_full(unit, level, error, ...) \
assert_se(manager_add_job(m, JOB_START, h, JOB_FAIL, NULL, &j) == 0);
manager_dump_jobs(m, stdout, "\t");
+ assert_se(!hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], b));
+ assert_se(!hashmap_get(b->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
+ assert_se(!hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], c));
+ assert_se(!hashmap_get(c->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
+
+ assert_se(unit_add_dependency(a, UNIT_PROPAGATES_RELOAD_TO, b, true, UNIT_DEPENDENCY_UDEV) == 0);
+ assert_se(unit_add_dependency(a, UNIT_PROPAGATES_RELOAD_TO, c, true, UNIT_DEPENDENCY_PROC_SWAP) == 0);
+
+ assert_se(hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], b));
+ assert_se(hashmap_get(b->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
+ assert_se(hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], c));
+ assert_se(hashmap_get(c->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
+
+ unit_remove_dependencies(a, UNIT_DEPENDENCY_UDEV);
+
+ assert_se(!hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], b));
+ assert_se(!hashmap_get(b->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
+ assert_se(hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], c));
+ assert_se(hashmap_get(c->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
+
+ unit_remove_dependencies(a, UNIT_DEPENDENCY_PROC_SWAP);
+
+ assert_se(!hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], b));
+ assert_se(!hashmap_get(b->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
+ assert_se(!hashmap_get(a->dependencies[UNIT_PROPAGATES_RELOAD_TO], c));
+ assert_se(!hashmap_get(c->dependencies[UNIT_RELOAD_PROPAGATED_FROM], a));
+
manager_free(m);
return 0;