No functional change.
The source unit manages the reference. It allocates the UnitRef structure and
registers it in the target unit, and then the reference must be destroyed
before the source unit is destroyed. Thus, is should be OK to include the
pointer to the source unit, it should be live as long as the reference exists.
v2:
- rename refs to refs_by_target
return -ENOEXEC;
}
- unit_ref_set(&s->service, x);
+ unit_ref_set(&s->service, UNIT(s), x);
return 0;
}
if (r < 0)
log_unit_debug_errno(u, r, "Failed to load accept-socket unit: %s", value);
else {
- unit_ref_set(&s->accept_socket, socket);
+ unit_ref_set(&s->accept_socket, u, socket);
SOCKET(socket)->n_connections++;
}
s->socket_fd = fd;
s->socket_fd_selinux_context_net = selinux_context_net;
- unit_ref_set(&s->accept_socket, UNIT(sock));
+ unit_ref_set(&s->accept_socket, UNIT(s), UNIT(sock));
return 0;
}
if (r < 0)
return r;
- unit_ref_set(&u->slice, parent);
+ unit_ref_set(&u->slice, u, parent);
return 0;
}
if (r < 0)
return r;
- unit_ref_set(&s->service, u);
+ unit_ref_set(&s->service, UNIT(s), u);
return unit_add_two_dependencies(UNIT(s), UNIT_BEFORE, UNIT_TRIGGERS, u, false, UNIT_DEPENDENCY_IMPLICIT);
}
if (r < 0)
return r;
- unit_ref_set(&s->service, x);
+ unit_ref_set(&s->service, u, x);
}
r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(s->service), true, UNIT_DEPENDENCY_IMPLICIT);
if (u->perpetual)
return false;
- if (u->refs)
+ if (u->refs_by_target)
return false;
if (sd_bus_track_count(u->bus_track) > 0)
free(u->reboot_arg);
unit_ref_unset(&u->slice);
-
- while (u->refs)
- unit_ref_unset(u->refs);
+ while (u->refs_by_target)
+ unit_ref_unset(u->refs_by_target);
safe_close(u->ip_accounting_ingress_map_fd);
safe_close(u->ip_accounting_egress_map_fd);
return r;
/* Redirect all references */
- while (other->refs)
- unit_ref_set(other->refs, u);
+ while (other->refs_by_target)
+ unit_ref_set(other->refs_by_target, other->refs_by_target->source, u);
/* Merge dependencies */
for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++)
if (UNIT_ISSET(u->slice) && u->cgroup_realized)
return -EBUSY;
- unit_ref_unset(&u->slice);
- unit_ref_set(&u->slice, slice);
+ unit_ref_set(&u->slice, u, slice);
return 1;
}
return u->unit_file_preset;
}
-Unit* unit_ref_set(UnitRef *ref, Unit *u) {
+Unit* unit_ref_set(UnitRef *ref, Unit *source, Unit *target) {
assert(ref);
- assert(u);
+ assert(source);
+ assert(target);
- if (ref->unit)
+ if (ref->target)
unit_ref_unset(ref);
- ref->unit = u;
- LIST_PREPEND(refs, u->refs, ref);
- return u;
+ ref->source = source;
+ ref->target = target;
+ LIST_PREPEND(refs_by_target, target->refs_by_target, ref);
+ return target;
}
void unit_ref_unset(UnitRef *ref) {
assert(ref);
- if (!ref->unit)
+ if (!ref->target)
return;
/* We are about to drop a reference to the unit, make sure the garbage collection has a look at it as it might
* be unreferenced now. */
- unit_add_to_gc_queue(ref->unit);
+ unit_add_to_gc_queue(ref->target);
- LIST_REMOVE(refs, ref->unit->refs, ref);
- ref->unit = NULL;
+ LIST_REMOVE(refs_by_target, ref->target->refs_by_target, ref);
+ ref->source = ref->target = NULL;
}
static int user_from_unit_name(Unit *u, char **ret) {
* that we can merge two units if necessary and correct all
* references to them */
- Unit* unit;
- LIST_FIELDS(UnitRef, refs);
+ Unit *source, *target;
+ LIST_FIELDS(UnitRef, refs_by_target);
};
typedef enum UnitCGroupBPFState {
char *job_timeout_reboot_arg;
/* References to this */
- LIST_HEAD(UnitRef, refs);
+ LIST_HEAD(UnitRef, refs_by_target);
/* Conditions to check */
LIST_HEAD(Condition, conditions);
UnitFileState unit_get_unit_file_state(Unit *u);
int unit_get_unit_file_preset(Unit *u);
-Unit* unit_ref_set(UnitRef *ref, Unit *u);
+Unit* unit_ref_set(UnitRef *ref, Unit *source, Unit *target);
void unit_ref_unset(UnitRef *ref);
-#define UNIT_DEREF(ref) ((ref).unit)
-#define UNIT_ISSET(ref) (!!(ref).unit)
+#define UNIT_DEREF(ref) ((ref).target)
+#define UNIT_ISSET(ref) (!!(ref).target)
int unit_patch_contexts(Unit *u);