Skip to content

Commit 4df64d5

Browse files
committed
mctpd: Update interface vtables when we change to BusOwner role
Currently, setting an interface's Role property only sets the link->role. However, we also want to expose the BusOwner1 interface when changing from Unknown to BusOwner, so register the bus_link_owner_vtable on the interface object when this happens. dbus does not like the vtables changing during a call, so we defer this to the main loop context. Fixes: #130 Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au>
1 parent 6082872 commit 4df64d5

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
1111
1. `mctpd` now queries endpoints for their vendor-defined message support,
1212
and publishes as the newly-specced `VendorDefinedMessageTypes` dbus property.
1313

14+
### Fixes
15+
16+
1. mctpd's interface objects now expose the BusOwner1 interface when set
17+
as a BusOwner via the Role property
18+
1419
## [2.5] - 2026-02-17
1520

1621
### Added

src/mctpd.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ struct link {
144144
char *path;
145145
sd_bus_slot *slot_iface;
146146
sd_bus_slot *slot_busowner;
147+
sd_event_source *role_defer;
147148

148149
struct ctx *ctx;
149150
};
@@ -4207,6 +4208,27 @@ static int bus_link_get_prop(sd_bus *bus, const char *path,
42074208
return rc;
42084209
}
42094210

4211+
/* deferred handler for link changes, which may alter vtable state */
4212+
static int link_set_role(sd_event_source *ev, void *userdata)
4213+
{
4214+
struct link *link = userdata;
4215+
int rc;
4216+
4217+
sd_event_source_unref(link->role_defer);
4218+
link->role_defer = NULL;
4219+
4220+
if (link->role != ENDPOINT_ROLE_BUS_OWNER)
4221+
return 0;
4222+
4223+
rc = sd_bus_add_object_vtable(link->ctx->bus, &link->slot_busowner,
4224+
link->path, CC_MCTP_DBUS_IFACE_BUSOWNER,
4225+
bus_link_owner_vtable, link);
4226+
if (rc)
4227+
warnx("adding link owner vtable failed: %d", rc);
4228+
4229+
return 0;
4230+
}
4231+
42104232
static int bus_link_set_prop(sd_bus *bus, const char *path,
42114233
const char *interface, const char *property,
42124234
sd_bus_message *value, void *userdata,
@@ -4247,8 +4269,15 @@ static int bus_link_set_prop(sd_bus *bus, const char *path,
42474269
rc = -EINVAL;
42484270
goto out;
42494271
}
4272+
4273+
printf("Role for %s set to %s, via dbus\n", link->path, role.conf_val);
42504274
link->role = role.role;
42514275

4276+
/* We need to defer the link role change, as we cannot update the vtables
4277+
* during the call.
4278+
*/
4279+
sd_event_add_defer(ctx->event, &link->role_defer, link_set_role, link);
4280+
42524281
out:
42534282
set_berr(ctx, rc, berr);
42544283
return rc;
@@ -4683,6 +4712,7 @@ static int prune_old_nets(struct ctx *ctx)
46834712

46844713
static void free_link(struct link *link)
46854714
{
4715+
sd_event_source_disable_unref(link->role_defer);
46864716
sd_bus_slot_unref(link->slot_iface);
46874717
sd_bus_slot_unref(link->slot_busowner);
46884718
free(link->path);

0 commit comments

Comments
 (0)