Skip to content

Commit 371c0b7

Browse files
committed
core: track scope controllers on the bus
This watches controllers on the bus, and unsets them automatically when they disappear. Note that this is primarily a cosmetical fix. Since unique bus names are not recycled, there's strictly no need to forget about them, but it's a lot nicer to do so.
1 parent f2c49c8 commit 371c0b7

File tree

4 files changed

+53
-5
lines changed

4 files changed

+53
-5
lines changed

src/core/dbus-scope.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, scope_result, ScopeResu
6161

6262
const sd_bus_vtable bus_scope_vtable[] = {
6363
SD_BUS_VTABLE_START(0),
64-
SD_BUS_PROPERTY("Controller", "s", NULL, offsetof(Scope, controller), SD_BUS_VTABLE_PROPERTY_CONST),
64+
SD_BUS_PROPERTY("Controller", "s", NULL, offsetof(Scope, controller), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
6565
SD_BUS_PROPERTY("TimeoutStopUSec", "t", bus_property_get_usec, offsetof(Scope, timeout_stop_usec), SD_BUS_VTABLE_PROPERTY_CONST),
6666
SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Scope, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
6767
SD_BUS_SIGNAL("RequestStop", NULL, 0),
@@ -233,3 +233,40 @@ int bus_scope_send_request_stop(Scope *s) {
233233

234234
return sd_bus_send_to(UNIT(s)->manager->api_bus, m, s->controller, NULL);
235235
}
236+
237+
static int on_controller_gone(sd_bus_track *track, void *userdata) {
238+
Scope *s = userdata;
239+
240+
assert(track);
241+
242+
if (s->controller) {
243+
log_unit_debug(UNIT(s), "Controller %s disappeared from bus.", s->controller);
244+
unit_add_to_dbus_queue(UNIT(s));
245+
s->controller = mfree(s->controller);
246+
}
247+
248+
s->controller_track = sd_bus_track_unref(s->controller_track);
249+
250+
return 0;
251+
}
252+
253+
int bus_scope_track_controller(Scope *s) {
254+
int r;
255+
256+
assert(s);
257+
258+
if (!s->controller || s->controller_track)
259+
return 0;
260+
261+
r = sd_bus_track_new(UNIT(s)->manager->api_bus, &s->controller_track, on_controller_gone, s);
262+
if (r < 0)
263+
return r;
264+
265+
r = sd_bus_track_add_name(s->controller_track, s->controller);
266+
if (r < 0) {
267+
s->controller_track = sd_bus_track_unref(s->controller_track);
268+
return r;
269+
}
270+
271+
return 0;
272+
}

src/core/dbus-scope.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,5 @@ int bus_scope_set_property(Unit *u, const char *name, sd_bus_message *i, UnitSet
3030
int bus_scope_commit_properties(Unit *u);
3131

3232
int bus_scope_send_request_stop(Scope *s);
33+
34+
int bus_scope_track_controller(Scope *s);

src/core/scope.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ static void scope_done(Unit *u) {
5959

6060
assert(u);
6161

62-
free(s->controller);
62+
s->controller = mfree(s->controller);
63+
s->controller_track = sd_bus_track_unref(s->controller_track);
6364

6465
s->timer_event_source = sd_event_source_unref(s->timer_event_source);
6566
}
@@ -229,6 +230,8 @@ static int scope_coldplug(Unit *u) {
229230
if (!IN_SET(s->deserialized_state, SCOPE_DEAD, SCOPE_FAILED))
230231
unit_watch_all_pids(UNIT(s));
231232

233+
bus_scope_track_controller(s);
234+
232235
scope_set_state(s, s->deserialized_state);
233236
return 0;
234237
}
@@ -272,9 +275,8 @@ static void scope_enter_signal(Scope *s, ScopeState state, ScopeResult f) {
272275

273276
unit_watch_all_pids(UNIT(s));
274277

275-
/* If we have a controller set let's ask the controller nicely
276-
* to terminate the scope, instead of us going directly into
277-
* SIGTERM berserk mode */
278+
/* If we have a controller set let's ask the controller nicely to terminate the scope, instead of us going
279+
* directly into SIGTERM berserk mode */
278280
if (state == SCOPE_STOP_SIGTERM)
279281
skip_signal = bus_scope_send_request_stop(s) > 0;
280282

@@ -332,6 +334,8 @@ static int scope_start(Unit *u) {
332334
if (!u->transient && !MANAGER_IS_RELOADING(u->manager))
333335
return -ENOENT;
334336

337+
(void) bus_scope_track_controller(s);
338+
335339
r = unit_acquire_invocation_id(u);
336340
if (r < 0)
337341
return r;
@@ -536,7 +540,10 @@ int scope_abandon(Scope *s) {
536540
return -ESTALE;
537541

538542
s->was_abandoned = true;
543+
539544
s->controller = mfree(s->controller);
545+
s->controller_track = sd_bus_track_unref(s->controller_track);
546+
540547
scope_set_state(s, SCOPE_ABANDONED);
541548

542549
/* The client is no longer watching the remaining processes,

src/core/scope.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ struct Scope {
4646
usec_t timeout_stop_usec;
4747

4848
char *controller;
49+
sd_bus_track *controller_track;
50+
4951
bool was_abandoned;
5052

5153
sd_event_source *timer_event_source;

0 commit comments

Comments
 (0)