mctp utilities: v2.0 release
We have recently released version 2.0 of the mctp
userspace utilities. There are a few changes from the v1.x
series, particular some modifications to mctpd
's dbus API. This document
provides an overview of those changes, as a guide for updating applications
that interact with mctpd
to the v2 series and beyond.
mctpd dbus API restructure🔗
In collaboration with Thu Nguyen from Ampere, we have reworked the dbus API to better represent the MCTP bus layout, and provide access to the local MCTP interfaces. These also include a move to a more "dbus-idiomatic" representation of the bus objects. While this change is not backwards-compatible, it does provide a mechanism for future backwards compatibility, so we should only have to break things once.
Then, because we're introducing breaking changes from v1.x to v2.0 anyway, we may as well do some of the other proposed changes that we had deferred due to their impacts on the interfaces. So, there's a fair bit of dbus API churn involved.
There's a full description of the new interface in the mctpd
dbus
documentation, but that
covers the current state of the API, and may not be obvious what has changed.
So, those changes:
-
The root of the dbus hierarchy used to be
/xyz/openbmc_project/mctp
, it is now/au/com/codeconstruct/mctp1
.The original namespace was chosen to suit the core use-case of
mctpd
: OpenBMC. However, we're kind-ofstealingborrowing the OpenBMC namespace for a non-specifically-OpenBMC project. So, we've moved this to its own namespace, and added versioning (the1
suffix). -
MCTP endpoint objects have been moved from
…/<network-id>/<endpoint-id>
in v1 to…/networks/<network-id>/endpoints/<endpoint-id>
in v2The
/<net>/<eid>
approach may have implied that the networks are the only possible sub-objects from the root, and that the endpoints are the only possible sub-objects from the network. This was the case for v1, but we want to introduce new object types too: -
Local interfaces are now represented in dbus, at
…/interfaces/<interface-name>
This allows runtime control of the interfaces, and more importantly, the role of the local interface on those buses. The primary use-case for this was to configure an interface as the MCTP "Bus Owner" of the attached bus, or as a regular endpoint with an external bus owner.
-
Top-level discovery control has moved to BusOwner objects.
In v1, the endpoint discovery methods (
SetupEndpoint
,AssignEndpoint
andLearnEndpoint
) were present on the top-levelmctp
object, and all took a MCTP interface name as their first argument.In v2, these have been moved to the
BusOwner
interfaces, which are present on the interface objects above, and only when those interfaces are configured as bus owners. Since the methods are present on the interface objects, they no longer need an interface name argument. -
Interface names have moved to the
au.com.codeconstruct.MCTP
namespace, and include versioning. The only change that affects existing code will be that the Endpoint interface has been renamed fromau.com.CodeConstruct.MCTP.Endpoint
in v1 toau.com.codeconstruct.MCTP.Endpoint1
in v2.
Endpoint recovery facility🔗
The mctpd
utility now has some features from Andrew Jeffery, that allow
upper-layer applications to attempt recovery if MCTP connectivity is lost.
The typical model for error detection and recovery is:
-
A higher-level MCTP application will be performing some sort of regular communication with a remote endpoint (say, performing a health poll)
-
That application stops receiving responses for some reason. This may trigger a few retries in that higher level application.
-
If those retries fail, the application can query "down the stack" to determine whether all MCTP connectivity is lost, or just connectivity for that application protocol
-
If all MCTP connectivity has failed,
mctpd
can attempt to re-enumerate the device, or flag that endpoint as no longer present
These changes implement support for steps 3 and 4 above, through a new Recover
method and a Connectivity
property on the Endpoint interface:
$ busctl --user introspect \
au.com.codeconstruct.MCTP1 \
/au/com/codeconstruct/mctp1/networks/1/endpoints/9 \
au.com.codeconstruct.MCTP.Endpoint1
NAME TYPE SIGNATURE RESULT/VALUE FLAGS
.Recover method - - -
.Remove method - - -
.SetMTU method u - -
.Connectivity property s "Available" emits-change
Andrew has put together a comprehensive document on endpoint recovery that describes mctpd's recovery process using this interface.
MTU set to baseline by default🔗
In v1.x, mctpd
did not set a route MTU for newly-discovered devices, so new
devices would use the link-global MTU, unless configured otherwise through
SetMTU
.
However, a typical setup would be to set the link MTU to the maximum capable for the platform and transport type, and use endpoint-specific MTUs that are suitable for each device. The latter may be negotiated through external mechanisms. For example, NVMe-MI provides a facility to reconfigure a device's MTU.
Since the baseline MTU of 64 (or 68 including MCTP headers) is required to be supported by all devices, setting this as the initial route MTU will always start device initialisation from a known-good MTU state.
So, for maximum compatibility and configurability, mctpd
will now set the
route MTU to the MCTP-defined baseline of 64. From there, applications can
increase the MTU as needed, using the SetMTU
method on the endpoint's dbus
object. Ideally, this would be performed after negotiation with the endpoint
device.
Support for static EID assignments🔗
A new method has been added on the BusOwner interface: AssignEndpointStatic
,
alongside the existing SetupEndpoint
and AssignEndpoint
methods. This allows
pre-configured EIDs to be used when discovering a new remote MCTP endpoint.
.AssignEndpointStatic
:ayy
→yisb
This takes two arguments:
ay
: a physical device address, andy
: a MCTP EID.
The physical address is in the same format as the other endpoint discovery calls: an array of bytes, reflecting the address representation used by the hardware bus.
AssignEndpointStatic
will perform the standard MCTP discovery on the endpoint
with the given physical address, and allocate the given EID to that endpoint.
The return value from this call is the same as the existing endpoint enumeration methods.
If the given EID is not available, this call will fail. The caller may then either reject the enumeration, or try with a different - possibly dynamic - EID instead.
That covers the major changes that applications may need to be aware of in
migrating to mctpd
v2.0. There are a few application-independent changes too;
the full set is listed in the changelog.
Of course, please feel free to get in touch if you have any queries - either through the github issues, or directly via email.