xref: /openbmc/docs/designs/uart-mux-support.md (revision 8e6dbb4d)
1*8e6dbb4dSAlexander Hansen# uart-mux-support design
2*8e6dbb4dSAlexander Hansen
3*8e6dbb4dSAlexander HansenAuthor: Alexander Hansen <alexander.hansen@9elements.com>
4*8e6dbb4dSAlexander Hansen
5*8e6dbb4dSAlexander HansenOther contributors: Andrew Jeffery <andrew@codeconstruct.com.au> @arj, Jeremy
6*8e6dbb4dSAlexander HansenKerr <jk@ozlabs.org>, Patrick Williams <patrick@stwcx.xyz>
7*8e6dbb4dSAlexander Hansen
8*8e6dbb4dSAlexander HansenCreated: June 17, 2024
9*8e6dbb4dSAlexander Hansen
10*8e6dbb4dSAlexander Hansen## Problem Description
11*8e6dbb4dSAlexander Hansen
12*8e6dbb4dSAlexander HansenSome hardware configurations feature a UART mux which can be switched via GPIOs.
13*8e6dbb4dSAlexander HansenTo support this configuration, obmc-console needs to provide a method for
14*8e6dbb4dSAlexander Hansenconsole selection to avoid manually setting GPIOs.
15*8e6dbb4dSAlexander Hansen
16*8e6dbb4dSAlexander Hansen## Background and References
17*8e6dbb4dSAlexander Hansen
18*8e6dbb4dSAlexander HansenThere are already [open changes for obmc-console][obmc-console-uart-mux-series]
19*8e6dbb4dSAlexander Hansenbut it has been determined that this feature needs a design document.
20*8e6dbb4dSAlexander Hansen
21*8e6dbb4dSAlexander Hansen[obmc-console-uart-mux-series]:
22*8e6dbb4dSAlexander Hansen  https://gerrit.openbmc.org/c/openbmc/obmc-console/+/71864
23*8e6dbb4dSAlexander Hansen
24*8e6dbb4dSAlexander HansenThe background here is that there are some design choices which may affect other
25*8e6dbb4dSAlexander Hansensubprojects - not in the way of causing regression, but later when the mentioned
26*8e6dbb4dSAlexander Hansenhardware configuration needs to be supported in those projects.
27*8e6dbb4dSAlexander Hansen
28*8e6dbb4dSAlexander Hansen## Requirements
29*8e6dbb4dSAlexander Hansen
30*8e6dbb4dSAlexander Hansen- The user can select a console to be muxed
31*8e6dbb4dSAlexander Hansen
32*8e6dbb4dSAlexander Hansen- Platform policy (whichever service implements it) can select the appropriate
33*8e6dbb4dSAlexander Hansen  console depending on the host state and other information.
34*8e6dbb4dSAlexander Hansen
35*8e6dbb4dSAlexander Hansen- It is clear to whoever is reading the logs of that console when a console was
36*8e6dbb4dSAlexander Hansen  connected or disconnected via mux control. There should be no inexplicable
37*8e6dbb4dSAlexander Hansen  gaps in log files.
38*8e6dbb4dSAlexander Hansen
39*8e6dbb4dSAlexander Hansen- The mux configuration can be specified in a single file
40*8e6dbb4dSAlexander Hansen
41*8e6dbb4dSAlexander Hansen- Console selection (implies mux control) must be possible from an external
42*8e6dbb4dSAlexander Hansen  application.
43*8e6dbb4dSAlexander Hansen
44*8e6dbb4dSAlexander HansenThe scope of this change is obmc-console and other projects which rely on the
45*8e6dbb4dSAlexander HansenAPIs exposed by it.
46*8e6dbb4dSAlexander Hansen
47*8e6dbb4dSAlexander HansenThe change will not affect users who do not have this hardware configuration.
48*8e6dbb4dSAlexander Hansen
49*8e6dbb4dSAlexander Hansen## Design Considerations
50*8e6dbb4dSAlexander Hansen
51*8e6dbb4dSAlexander HansenThere are a number of choices available for adding mux support into
52*8e6dbb4dSAlexander Hansenobmc-console:
53*8e6dbb4dSAlexander Hansen
54*8e6dbb4dSAlexander Hansen1. What the "connection endpoint" (Unix domain socket, D-Bus object) represents.
55*8e6dbb4dSAlexander Hansen   This could be either:
56*8e6dbb4dSAlexander Hansen
57*8e6dbb4dSAlexander Hansen   1. The TTY device exposed by Linux
58*8e6dbb4dSAlexander Hansen   2. The desired downstream mux port
59*8e6dbb4dSAlexander Hansen
60*8e6dbb4dSAlexander Hansen2. How the mux state is controlled. We might control it by any of:
61*8e6dbb4dSAlexander Hansen
62*8e6dbb4dSAlexander Hansen   1. An out-of-band command (e.g. via a D-Bus method that's somehow associated
63*8e6dbb4dSAlexander Hansen      with the connection endpoint)
64*8e6dbb4dSAlexander Hansen   2. An in-band command (e.g. introducing an SSH-style escape-sequence)
65*8e6dbb4dSAlexander Hansen   3. Selecting the mux port based on the endpoint to which the user has
66*8e6dbb4dSAlexander Hansen      connected
67*8e6dbb4dSAlexander Hansen
68*8e6dbb4dSAlexander Hansen3. The circumstances under which we allow the mux state to be changed
69*8e6dbb4dSAlexander Hansen
70*8e6dbb4dSAlexander Hansen   1. Active connections prevent the mux state from being changed
71*8e6dbb4dSAlexander Hansen   2. The mux state can always change but will terminate any existing
72*8e6dbb4dSAlexander Hansen      conflicting connections
73*8e6dbb4dSAlexander Hansen   3. The mux state can always change and has no impact on existing conflicting
74*8e6dbb4dSAlexander Hansen      connections
75*8e6dbb4dSAlexander Hansen
76*8e6dbb4dSAlexander Hansen4. Whether we want the data stream on a given connection to represent:
77*8e6dbb4dSAlexander Hansen   1. The console IO regardless of the mux state
78*8e6dbb4dSAlexander Hansen   2. The console IO isolated to a specific mux port
79*8e6dbb4dSAlexander Hansen
80*8e6dbb4dSAlexander HansenThere are constraints on some combinations of these. For instance:
81*8e6dbb4dSAlexander Hansen
82*8e6dbb4dSAlexander Hansen- If the connection endpoint represents the TTY device exposed by Linux (1.1)
83*8e6dbb4dSAlexander Hansen  then we can't select the mux port based on the endpoint to which the user has
84*8e6dbb4dSAlexander Hansen  connected (2.3) as we simply don't have the information required
85*8e6dbb4dSAlexander Hansen
86*8e6dbb4dSAlexander Hansen- If the connection endpoint represents the desired downstream mux port (1.2)
87*8e6dbb4dSAlexander Hansen  then it doesn't make sense to implement support for an in-band command to
88*8e6dbb4dSAlexander Hansen  change the mux state (2.2) as it's a violation of the abstraction
89*8e6dbb4dSAlexander Hansen
90*8e6dbb4dSAlexander Hansen- If the connection endpoint represents the desired downstream mux port (1.2)
91*8e6dbb4dSAlexander Hansen  then it can't provide the console IO of another mux port (4.1) as that's
92*8e6dbb4dSAlexander Hansen  contrary to the definition.
93*8e6dbb4dSAlexander Hansen
94*8e6dbb4dSAlexander HansenWith these in mind we end up with the following table of design options:
95*8e6dbb4dSAlexander Hansen
96*8e6dbb4dSAlexander Hansen| ID  | Connection Endpoint (1) | Mux Control Defined By (2) | Mux Control Policy (3)                           | Stream Data (4)   |
97*8e6dbb4dSAlexander Hansen| --- | ----------------------- | -------------------------- | ------------------------------------------------ | ----------------- |
98*8e6dbb4dSAlexander Hansen| A   | TTY (1.1)               | Out-of-band command (2.1)  | Active connections prevent mux change (3.1)      | Isolated (4.2)    |
99*8e6dbb4dSAlexander Hansen| B   | TTY                     | Out-of-band command        | Mux change with disconnections (3.2)             | Isolated          |
100*8e6dbb4dSAlexander Hansen| C   | TTY                     | Out-of-band command        | Mux change without disconnections (3.3)          | Multiplexed (4.1) |
101*8e6dbb4dSAlexander Hansen| D   | TTY                     | In-band command (2.2)      | Mux change without disconnections                | Multiplexed       |
102*8e6dbb4dSAlexander Hansen| E   | Mux port (1.2)          | Connection-based (2.3)     | Conflicting connections prevent mux change (3.1) | Isolated          |
103*8e6dbb4dSAlexander Hansen| F   | Mux port                | Connection-based           | Mux change with disconnections                   | Isolated          |
104*8e6dbb4dSAlexander Hansen| G   | Mux port                | Connection-based           | Mux change without disconnections                | Isolated          |
105*8e6dbb4dSAlexander Hansen| H   | Mux port                | Out-of-band command        | Conflicting connections prevent mux change       | Isolated          |
106*8e6dbb4dSAlexander Hansen| I   | Mux port                | Out-of-band command        | Mux change with disconnections                   | Isolated          |
107*8e6dbb4dSAlexander Hansen| J   | Mux port                | Out-of-band command        | Mux change without disconnections                | Isolated          |
108*8e6dbb4dSAlexander Hansen
109*8e6dbb4dSAlexander Hansen### Scenarios and Use Cases
110*8e6dbb4dSAlexander Hansen
111*8e6dbb4dSAlexander Hansen1. A UART mux selecting between a satellite BMC on a blade and the blade host
112*8e6dbb4dSAlexander Hansen
113*8e6dbb4dSAlexander Hansen   A software update is in progress on the satellite BMC and the mux has been
114*8e6dbb4dSAlexander Hansen   switched to capture the output of whatever the satellite is printing. It is
115*8e6dbb4dSAlexander Hansen   important to log the output of the update process to understand any failures
116*8e6dbb4dSAlexander Hansen   that might result.
117*8e6dbb4dSAlexander Hansen
118*8e6dbb4dSAlexander Hansen   While the satellite BMC update is in progress, a user chooses to connect to
119*8e6dbb4dSAlexander Hansen   the host console.
120*8e6dbb4dSAlexander Hansen
121*8e6dbb4dSAlexander Hansen2. A blade's satellite BMC, CPLD and host are all on separate ports of a UART
122*8e6dbb4dSAlexander Hansen   mux, and relevant output from the blade's boot process must be captured
123*8e6dbb4dSAlexander Hansen
124*8e6dbb4dSAlexander Hansen   The boot process for a blade requires a sequence of actions across its
125*8e6dbb4dSAlexander Hansen   satellite BMC, CPLD and host. Each component contributes critical information
126*8e6dbb4dSAlexander Hansen   about the boot process, which is output on the respective consoles at various
127*8e6dbb4dSAlexander Hansen   points in time.
128*8e6dbb4dSAlexander Hansen
129*8e6dbb4dSAlexander Hansen   For ease of correlation, their output should be logged together.
130*8e6dbb4dSAlexander Hansen
131*8e6dbb4dSAlexander Hansen### Discussion
132*8e6dbb4dSAlexander Hansen
133*8e6dbb4dSAlexander HansenScenario 1 is problematic. It highlights the fundamental concern of ownership of
134*8e6dbb4dSAlexander Hansenthe mux state. In the scenario the system is in a sensitive state where a
135*8e6dbb4dSAlexander Hansenspecific mux configuration is required (to output update progress from the
136*8e6dbb4dSAlexander Hansensatellite BMC), but a user has shown intent for the selection of another (to
137*8e6dbb4dSAlexander Hanseninteract with the host console).
138*8e6dbb4dSAlexander Hansen
139*8e6dbb4dSAlexander HansenWhat should occur? And does this choice impact how we choose to control the mux?
140*8e6dbb4dSAlexander Hansen
141*8e6dbb4dSAlexander HansenTaking a connection-based approach to setting the mux state (2.3) will cause the
142*8e6dbb4dSAlexander Hansenuser connecting to the host console endpoint to immediately disrupt the update
143*8e6dbb4dSAlexander Hansenprogress output from the satellite BMC.
144*8e6dbb4dSAlexander Hansen
145*8e6dbb4dSAlexander HansenBy contrast, by setting the mux state with an out-of-band command (2.1) and not
146*8e6dbb4dSAlexander Hansenon the initiation of a connection (2.3), the user connecting to the host console
147*8e6dbb4dSAlexander Hansenwill not immediately disrupt the update progress output from the satellite BMC.
148*8e6dbb4dSAlexander Hansen
149*8e6dbb4dSAlexander HansenHowever, we can presume the user is connecting to the host console endpoint for
150*8e6dbb4dSAlexander Hansena reason. With extra actions, using the out-of-band command interface, they may
151*8e6dbb4dSAlexander Hansenequally choose to switch the mux without regard for the system state, disrupting
152*8e6dbb4dSAlexander Hansenthe update progress output from the satellite BMC.
153*8e6dbb4dSAlexander Hansen
154*8e6dbb4dSAlexander HansenThis highlights that the fundamental problem is access to the system by multiple
155*8e6dbb4dSAlexander Hansenusers who are neither coordinating with each other nor the system state. The
156*8e6dbb4dSAlexander Hansenquestion that follows is:
157*8e6dbb4dSAlexander Hansen
158*8e6dbb4dSAlexander HansenShould it be the responsibility of obmc-console to coordinate otherwise
159*8e6dbb4dSAlexander Hansenun-coordinated users?
160*8e6dbb4dSAlexander Hansen
161*8e6dbb4dSAlexander HansenThis is a question of policy: How those users should be coordinated will likely
162*8e6dbb4dSAlexander Hansenlook very different based on concerns such as the role of the platform in a
163*8e6dbb4dSAlexander Hansenlarger system, the roles and needs of the users interacting with it, and the
164*8e6dbb4dSAlexander Hansenconcrete design of the platform itself.
165*8e6dbb4dSAlexander Hansen
166*8e6dbb4dSAlexander Hansenobmc-console should implement a mechanism to control the mux state, but likely
167*8e6dbb4dSAlexander Hansenshouldn't apply any policy governing access to the muxed consoles.
168*8e6dbb4dSAlexander Hansen
169*8e6dbb4dSAlexander HansenA further concern for the out-of-band command approach is its interactions with
170*8e6dbb4dSAlexander Hansenother components exposing consoles:
171*8e6dbb4dSAlexander Hansen
172*8e6dbb4dSAlexander Hansen1. The dropbear/obmc-console-client integration exposing consoles via SSH
173*8e6dbb4dSAlexander Hansen2. [bmcweb](https://github.com/openbmc/bmcweb/blob/master/include/obmc_console.hpp)
174*8e6dbb4dSAlexander Hansen3. [phosphor-net-ipmid](https://github.com/openbmc/phosphor-net-ipmid/blob/master/sol/sol_manager.hpp)
175*8e6dbb4dSAlexander Hansen
176*8e6dbb4dSAlexander HansenWith the out-of-band command approach these components have to choose between:
177*8e6dbb4dSAlexander Hansen
178*8e6dbb4dSAlexander Hansen- Not providing any capability to change the mux state; rather, they defer to
179*8e6dbb4dSAlexander Hansen  making the user log in via SSH to affect the change themselves
180*8e6dbb4dSAlexander Hansen
181*8e6dbb4dSAlexander Hansen- Expose some mechanism for setting the mux state in terms of their own external
182*8e6dbb4dSAlexander Hansen  interfaces
183*8e6dbb4dSAlexander Hansen
184*8e6dbb4dSAlexander Hansen- Assume that a user connecting to the exposed console endpoint wants to select
185*8e6dbb4dSAlexander Hansen  that console if it's behind a mux
186*8e6dbb4dSAlexander Hansen
187*8e6dbb4dSAlexander HansenThe first assumes that SSH is exposed at all and accessible by users who need
188*8e6dbb4dSAlexander Hansenaccess to the muxed consoles. It's not yet clear whether this is a reasonable
189*8e6dbb4dSAlexander Hansenexpectation.
190*8e6dbb4dSAlexander Hansen
191*8e6dbb4dSAlexander HansenThe second assumes that these external interfaces have the capability to model
192*8e6dbb4dSAlexander Hansenthe problem. It's not yet clear that this is the case for either of IPMI or
193*8e6dbb4dSAlexander HansenRedfish, and it's not the case for serial over SSH.
194*8e6dbb4dSAlexander Hansen
195*8e6dbb4dSAlexander HansenThe third implies that we must add capability to all three components to drive
196*8e6dbb4dSAlexander Hansenthe out-of-band command interface when they receive a connection for a given
197*8e6dbb4dSAlexander Hansenconsole. The net result is no behavioural difference from obmc-console
198*8e6dbb4dSAlexander Hansenimplementing this itself (2.3), but increased complexity across the system.
199*8e6dbb4dSAlexander Hansen
200*8e6dbb4dSAlexander Hansen## Implementation Considerations
201*8e6dbb4dSAlexander Hansen
202*8e6dbb4dSAlexander Hansen### How are muxed consoles represented on D-Bus?
203*8e6dbb4dSAlexander Hansen
204*8e6dbb4dSAlexander HansenEvery console will have its own D-Bus name, as this is backwards-compatible with
205*8e6dbb4dSAlexander Hansenthe current implementation.
206*8e6dbb4dSAlexander Hansen
207*8e6dbb4dSAlexander HansenMultiple consoles can be represented as a split- or unified- object tree.
208*8e6dbb4dSAlexander Hansen
209*8e6dbb4dSAlexander Hansen### Tradeoffs of unified vs split object tree on D-Bus
210*8e6dbb4dSAlexander Hansen
211*8e6dbb4dSAlexander HansenIn split-tree, it is not clear which consoles all belong to one UART mux, but in
212*8e6dbb4dSAlexander Hansenunified-tree, this is clear.
213*8e6dbb4dSAlexander Hansen
214*8e6dbb4dSAlexander HansenIn unified-tree, one console is reachable via the D-Bus name of another,
215*8e6dbb4dSAlexander Hanseneffectively creating multiple ways of doing something.
216*8e6dbb4dSAlexander Hansen
217*8e6dbb4dSAlexander HansenExample:
218*8e6dbb4dSAlexander Hansen
219*8e6dbb4dSAlexander Hansen```
220*8e6dbb4dSAlexander Hansenbusctl set-property xyz.openbmc_project.Console.host1 \
221*8e6dbb4dSAlexander Hansen/xyz/openbmc_project/console/host2 \
222*8e6dbb4dSAlexander Hansenxyz.openbmc_project.Console.Access Connect ""
223*8e6dbb4dSAlexander Hansen```
224*8e6dbb4dSAlexander Hansen
225*8e6dbb4dSAlexander HansenSo a choice has to be made how to represent multiple consoles on dbus, and what
226*8e6dbb4dSAlexander Hanseninformation needs to be exposed to other subprojects.
227*8e6dbb4dSAlexander Hansen
228*8e6dbb4dSAlexander HansenUnified Tree:
229*8e6dbb4dSAlexander Hansen
230*8e6dbb4dSAlexander Hansen```
231*8e6dbb4dSAlexander Hansenbusctl tree --user xyz.openbmc_project.Console.host1
232*8e6dbb4dSAlexander Hansen└─/xyz
233*8e6dbb4dSAlexander Hansen  └─/xyz/openbmc_project
234*8e6dbb4dSAlexander Hansen    └─/xyz/openbmc_project/console
235*8e6dbb4dSAlexander Hansen      ├─/xyz/openbmc_project/console/host1
236*8e6dbb4dSAlexander Hansen      └─/xyz/openbmc_project/console/host2
237*8e6dbb4dSAlexander Hansen```
238*8e6dbb4dSAlexander Hansen
239*8e6dbb4dSAlexander HansenSplit Tree:
240*8e6dbb4dSAlexander Hansen
241*8e6dbb4dSAlexander Hansen```
242*8e6dbb4dSAlexander Hansenbusctl tree --user xyz.openbmc_project.Console.host1
243*8e6dbb4dSAlexander Hansen└─/xyz
244*8e6dbb4dSAlexander Hansen  └─/xyz/openbmc_project
245*8e6dbb4dSAlexander Hansen    └─/xyz/openbmc_project/console
246*8e6dbb4dSAlexander Hansen      └─/xyz/openbmc_project/console/host1
247*8e6dbb4dSAlexander Hansen
248*8e6dbb4dSAlexander Hansenbusctl tree --user xyz.openbmc_project.Console.host2
249*8e6dbb4dSAlexander Hansen└─/xyz
250*8e6dbb4dSAlexander Hansen  └─/xyz/openbmc_project
251*8e6dbb4dSAlexander Hansen    └─/xyz/openbmc_project/console
252*8e6dbb4dSAlexander Hansen      └─/xyz/openbmc_project/console/host2
253*8e6dbb4dSAlexander Hansen```
254*8e6dbb4dSAlexander Hansen
255*8e6dbb4dSAlexander HansenThe choice of representation impacts how the mux can be described on D-Bus,
256*8e6dbb4dSAlexander Hansenwhich is necessary if the out-of-band command strategy (2.1) is chosen. Two
257*8e6dbb4dSAlexander Hansenpossibilities for exposing an out-of-band mux control on D-Bus are:
258*8e6dbb4dSAlexander Hansen
259*8e6dbb4dSAlexander Hansen1. Implement an interface on each console object that defines a boolean `Active`
260*8e6dbb4dSAlexander Hansen   property, and an `Activate()` method. The `Activate()` method, by nature of
261*8e6dbb4dSAlexander Hansen   being implemented on the console object, has all the context it needs to
262*8e6dbb4dSAlexander Hansen   switch the mux without requiring caller-supplied parameters. The `Activate`
263*8e6dbb4dSAlexander Hansen   property is `true` when the mux is configured for the console of interest,
264*8e6dbb4dSAlexander Hansen   and `false` otherwise. A `PropertiesChanged` D-Bus signal for the `Active`
265*8e6dbb4dSAlexander Hansen   variable may alert local users to changes of mux state.
266*8e6dbb4dSAlexander Hansen
267*8e6dbb4dSAlexander Hansen2. Implement a `Mux` interface on an object common to all consoles exposed by
268*8e6dbb4dSAlexander Hansen   the mux. The `Mux` interface might have a writable string `Selected` property
269*8e6dbb4dSAlexander Hansen   that represents the state of the mux and provides a mechanism to switch it to
270*8e6dbb4dSAlexander Hansen   a given console.
271*8e6dbb4dSAlexander Hansen
272*8e6dbb4dSAlexander HansenThese have both been [discussed on an existing patch to
273*8e6dbb4dSAlexander Hansenphosphor-dbus-interfaces][pdi-uart-mux-control-interface].
274*8e6dbb4dSAlexander Hansen
275*8e6dbb4dSAlexander Hansen[pdi-uart-mux-control-interface]:
276*8e6dbb4dSAlexander Hansen  https://gerrit.openbmc.org/c/openbmc/phosphor-dbus-interfaces/+/71878/comment/dd34b099_66dbc49e/
277*8e6dbb4dSAlexander Hansen
278*8e6dbb4dSAlexander HansenThe second approach is quite explicit - directly representing the mux state
279*8e6dbb4dSAlexander Hansenmakes it easy to discover the state of the system. However, it motivates the
280*8e6dbb4dSAlexander Hansenchoice of a unified object tree to provide a common object path to host the
281*8e6dbb4dSAlexander Hansen`Mux` interface (e.g. at `/xyz/openbmc_project/console`). This is desired to
282*8e6dbb4dSAlexander Hansenavoid an alternative instance of the "multiple representations of one thing"
283*8e6dbb4dSAlexander Hansenproblem highlighted in the discussion of claiming multiple bus names for the
284*8e6dbb4dSAlexander Hansenunified object tree: If the tree isn't unified, this `Mux` interface would have
285*8e6dbb4dSAlexander Hansento be represented and synchronised on objects across multiple D-Bus connections.
286*8e6dbb4dSAlexander Hansen
287*8e6dbb4dSAlexander HansenThe first approach doesn't have this limitation. However, it does have the
288*8e6dbb4dSAlexander Hansentrade-off previously mentioned, that it's unclear how any of the consoles in the
289*8e6dbb4dSAlexander Hansensystem are related, and what the impact might be of activating any one of them.
290*8e6dbb4dSAlexander Hansen
291*8e6dbb4dSAlexander HansenChoosing a strategy for D-Bus representation is required if we add to the D-Bus
292*8e6dbb4dSAlexander HansenAPI, i.e. with the out-of-band command design point (2.1). However, the choice
293*8e6dbb4dSAlexander Hansenbecomes more of an implementation detail if either of design options 2.2 or 2.3
294*8e6dbb4dSAlexander Hansenare selected. The choice in those cases is instead motivated by the level of
295*8e6dbb4dSAlexander Hansenclarity we desire in describing the relationships between consoles.
296*8e6dbb4dSAlexander Hansen
297*8e6dbb4dSAlexander Hansen## Pruning the Design Decision Tree
298*8e6dbb4dSAlexander Hansen
299*8e6dbb4dSAlexander HansenTo help shape the choices here, we have the existing behaviours of obmc-console
300*8e6dbb4dSAlexander Hansen[discussed on the PDI patch][pdi-uart-mux-control-interface]:
301*8e6dbb4dSAlexander Hansen
302*8e6dbb4dSAlexander Hansen1. We already have support for concurrent console server instances
303*8e6dbb4dSAlexander Hansen
304*8e6dbb4dSAlexander Hansen2. Concurrent console support is implemented as one obmc-console-server process
305*8e6dbb4dSAlexander Hansen   per Linux TTY device
306*8e6dbb4dSAlexander Hansen
307*8e6dbb4dSAlexander Hansen3. As each Linux TTY device is paired with its obmc-console-server process, each
308*8e6dbb4dSAlexander Hansen   obmc-console-server D-Bus connection needs a unique name
309*8e6dbb4dSAlexander Hansen
310*8e6dbb4dSAlexander Hansen4. We use the unique console-ids to name global resources, including both the
311*8e6dbb4dSAlexander Hansen   D-Bus connection and the instance's unix domain socket.
312*8e6dbb4dSAlexander Hansen
313*8e6dbb4dSAlexander HansenAs in the linked discussion, given the `console-id` value really represents
314*8e6dbb4dSAlexander Hansenwhat's at the remote end of the BMC's TTY device for regular unmuxed consoles,
315*8e6dbb4dSAlexander Hansenit stands to reason that we should continue this strategy for muxed consoles.
316*8e6dbb4dSAlexander HansenTaking this approach avoids adding a new endpoint ABI to obmc-console and
317*8e6dbb4dSAlexander Hanseneliminates design options A-D inclusive.
318*8e6dbb4dSAlexander Hansen
319*8e6dbb4dSAlexander HansenFurther, on the basis of frustrating behaviour in the face of lingering network
320*8e6dbb4dSAlexander Hansenconnections, preventing mux changes on the grounds of an existing connection
321*8e6dbb4dSAlexander Hansenseems like a bad path forward.
322*8e6dbb4dSAlexander Hansen
323*8e6dbb4dSAlexander HansenThis leaves us with design options `F`, `G`, `I`, and `J`, which are
324*8e6dbb4dSAlexander Hansendifferentiated by how the mux is switched, and its effect on already-connected
325*8e6dbb4dSAlexander Hansenclients.
326*8e6dbb4dSAlexander Hansen
327*8e6dbb4dSAlexander HansenConcentrating on how the mux is switched, based on the discussion about the
328*8e6dbb4dSAlexander HansenD-Bus representation above, the discussion on the PDI patch, and the impact on
329*8e6dbb4dSAlexander Hansenrelated applications, it's reasonable to say there are some complications with
330*8e6dbb4dSAlexander Hansenthe out-of-band command method (2.1).
331*8e6dbb4dSAlexander Hansen
332*8e6dbb4dSAlexander HansenBy contrast we can consider the alternative: We make the mux state reflect the
333*8e6dbb4dSAlexander Hansenendpoint of the most recent connection. This has the benefit of functioning for
334*8e6dbb4dSAlexander Hansenboth the Unix domain socket and D-Bus access with no further effort. Neither
335*8e6dbb4dSAlexander Hansenbmcweb nor phosphor-net-ipmid need be patched. The choice also eliminates the
336*8e6dbb4dSAlexander HansenD-Bus complications mentioned above as there's no need for the additional D-Bus
337*8e6dbb4dSAlexander Hanseninterface.
338*8e6dbb4dSAlexander Hansen
339*8e6dbb4dSAlexander HansenThis reasoning leaves us the choice of design options `F` and `G`.
340*8e6dbb4dSAlexander Hansen
341*8e6dbb4dSAlexander Hansen`F` and `G` are differentiated by whether or not we drop connections on
342*8e6dbb4dSAlexander Hansenendpoints that are not the endpoint selected by the mux. There's been some back
343*8e6dbb4dSAlexander Hansenand forth on that subject elsewhere[[1][drop-connections-discussion-1]]
344*8e6dbb4dSAlexander Hansen[[2][drop-connections-discussion-2]], but it seems that not disconnecting
345*8e6dbb4dSAlexander Hansenclients is effectively a worse implementation of design option `C`, which we've
346*8e6dbb4dSAlexander Hansenalready eliminated. It's worse than `C` because instead of 1 connection we could
347*8e6dbb4dSAlexander Hansenhave `N` connections for `N` mux ports, `(N - 1)` of which are idle. Not only
348*8e6dbb4dSAlexander Hansenthat, but the `(N - 1)` connections are effectively zombies, as they have no way
349*8e6dbb4dSAlexander Hansento switch the mux back to their associated port without establishing yet another
350*8e6dbb4dSAlexander Hansenconnection. It follows that if we're establishing a subsequent connection in
351*8e6dbb4dSAlexander Hansenorder to switch the mux we may as well disconnect the existing session, in which
352*8e6dbb4dSAlexander Hansencase it may as well have been disconnected when the mux switched away to begin
353*8e6dbb4dSAlexander Hansenwith[^1].
354*8e6dbb4dSAlexander Hansen
355*8e6dbb4dSAlexander Hansen[drop-connections-discussion-1]:
356*8e6dbb4dSAlexander Hansen  https://gerrit.openbmc.org/c/openbmc/obmc-console/+/71228/comment/62a5fce9_60c3ad3e/
357*8e6dbb4dSAlexander Hansen[drop-connections-discussion-2]:
358*8e6dbb4dSAlexander Hansen  https://gerrit.openbmc.org/c/openbmc/obmc-console/+/71867/comment/756f0abe_5ebe8d66/
359*8e6dbb4dSAlexander Hansen
360*8e6dbb4dSAlexander Hansen[^1]: which also saves resources
361*8e6dbb4dSAlexander Hansen
362*8e6dbb4dSAlexander HansenThese arguments combined eliminate all but option `F`. It seems to sit at a neat
363*8e6dbb4dSAlexander Hansennexus in terms of both existing ABI, desired behaviour, and implementation
364*8e6dbb4dSAlexander Hansencomplexity.
365*8e6dbb4dSAlexander Hansen
366*8e6dbb4dSAlexander HansenAddendum: Discussions so far have been are around a _minimal_ design that
367*8e6dbb4dSAlexander Hansenachieves the desired console behaviour. It's worth noting that design option `F`
368*8e6dbb4dSAlexander Hansen(connection-based mux control which disconnects conflicting clients) allows us
369*8e6dbb4dSAlexander Hansento _optionally_ implement an out-of-band command interface in addition, because
370*8e6dbb4dSAlexander Hansenthe observable behaviour is no different to a new connection being accepted:
371*8e6dbb4dSAlexander Hansenconflicting clients are disconnected and the mux is switched. This may be
372*8e6dbb4dSAlexander Hansenhelpful to implement platform policy around logging.
373*8e6dbb4dSAlexander Hansen
374*8e6dbb4dSAlexander Hansen## Proposed Design
375*8e6dbb4dSAlexander Hansen
376*8e6dbb4dSAlexander HansenIt's proposed that we use one obmc-console-server process to expose the `N`
377*8e6dbb4dSAlexander Hansenconsoles connected to a UART mux, where each console represents one mux port.
378*8e6dbb4dSAlexander HansenThe mux is switched based on the endpoint of the most recent client connection,
379*8e6dbb4dSAlexander Hansenand any conflicting clients are disconnected. This is design option `F` in the
380*8e6dbb4dSAlexander Hansentable above.
381*8e6dbb4dSAlexander Hansen
382*8e6dbb4dSAlexander HansenThe internal datastructures of obmc-console will change to accomodate the
383*8e6dbb4dSAlexander Hansendesign.
384*8e6dbb4dSAlexander Hansen
385*8e6dbb4dSAlexander HansenWe will use one config file for the `N` muxed consoles. The configuration will
386*8e6dbb4dSAlexander Hansenprovide a similar approach for specifying the mux GPIOs to that used by [the
387*8e6dbb4dSAlexander Hanseni2c-mux-gpio devicetree binding][linux-i2c-mux-gpio].
388*8e6dbb4dSAlexander Hansen
389*8e6dbb4dSAlexander Hansen[linux-i2c-mux-gpio]:
390*8e6dbb4dSAlexander Hansen  https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/i2c/i2c-mux-gpio.yaml?h=v6.9#n12
391*8e6dbb4dSAlexander Hansen
392*8e6dbb4dSAlexander HansenBelow is a block diagram of the relationships between the software and hardware
393*8e6dbb4dSAlexander Hansencomponents:
394*8e6dbb4dSAlexander Hansen
395*8e6dbb4dSAlexander Hansen```
396*8e6dbb4dSAlexander Hansen                                          +--------------------+
397*8e6dbb4dSAlexander Hansen                                          | server.conf        |
398*8e6dbb4dSAlexander Hansen                                          +--------------------+
399*8e6dbb4dSAlexander Hansen                                               |
400*8e6dbb4dSAlexander Hansen                                               |
401*8e6dbb4dSAlexander Hansen                                               |
402*8e6dbb4dSAlexander Hansen                                               |
403*8e6dbb4dSAlexander Hansen                                          +----+----+                                 +-----+     +-------+
404*8e6dbb4dSAlexander Hansen                                          |         |                                 |     |     |       |
405*8e6dbb4dSAlexander Hansen                                          |         |     +-------+     +-------+     |     +-----+ UART1 |
406*8e6dbb4dSAlexander Hansen+-----------------------------------+     |         |     |       |     |       |     |     |     |       |
407*8e6dbb4dSAlexander Hansen| xyz.openbmc_project.Console.host1 +-----+         +-----+ ttyS0 +-----+ UART0 +-----+     |     +-------+
408*8e6dbb4dSAlexander Hansen+-----------------------------------+     |         |     |       |     |       |     |     |
409*8e6dbb4dSAlexander Hansen                                          |  obmc   |     +-------+     +-------+     |     |
410*8e6dbb4dSAlexander Hansen                                          | console |                                 | MUX |
411*8e6dbb4dSAlexander Hansen                                          | server  |                   +-------+     |     |
412*8e6dbb4dSAlexander Hansen+-----------------------------------+     |         |                   |       |     |     |
413*8e6dbb4dSAlexander Hansen| xyz.openbmc_project.Console.host2 +-----+         +-------------------+ GPIO  +-----+     |     +-------+
414*8e6dbb4dSAlexander Hansen+-----------------------------------+     |         |                   |       |     |     |     |       |
415*8e6dbb4dSAlexander Hansen                                          |         |                   +-------+     |     +-----+ UART2 |
416*8e6dbb4dSAlexander Hansen                                          |         |                                 |     |     |       |
417*8e6dbb4dSAlexander Hansen                                          +----+----+                                 +-----+     +-------+
418*8e6dbb4dSAlexander Hansen
419*8e6dbb4dSAlexander Hansen```
420*8e6dbb4dSAlexander Hansen
421*8e6dbb4dSAlexander HansenTo inform people who may be reading log files for a console, connection and
422*8e6dbb4dSAlexander Hansendisconnection events of a console via mux control will produce messages for
423*8e6dbb4dSAlexander Hansenclients and in log files.
424*8e6dbb4dSAlexander Hansen
425*8e6dbb4dSAlexander HansenRequirements are:
426*8e6dbb4dSAlexander Hansen
427*8e6dbb4dSAlexander Hansen- Making it clear this message is from obmc-console
428*8e6dbb4dSAlexander Hansen- Timestamp
429*8e6dbb4dSAlexander Hansen- Indication of connected/disconnected
430*8e6dbb4dSAlexander Hansen
431*8e6dbb4dSAlexander HansenThese messages are not meant as an API or reliable means to get information
432*8e6dbb4dSAlexander Hansenabout mux state. Any application on the other side of the uart could also
433*8e6dbb4dSAlexander Hansenproduce the exact same messages, even if unlikely.
434*8e6dbb4dSAlexander Hansen
435*8e6dbb4dSAlexander HansenThe initial format of these messages will be something like:
436*8e6dbb4dSAlexander Hansen
437*8e6dbb4dSAlexander Hansen```
438*8e6dbb4dSAlexander Hansen[obmc-console] %Y-%m-%d %H:%M:%S UTC CONNECTED
439*8e6dbb4dSAlexander Hansen[obmc-console] %Y-%m-%d %H:%M:%S UTC DISCONNECTED
440*8e6dbb4dSAlexander Hansen```
441*8e6dbb4dSAlexander Hansen
442*8e6dbb4dSAlexander Hansenfor the connect and disconnect case.
443*8e6dbb4dSAlexander Hansen
444*8e6dbb4dSAlexander HansenFor the D-Bus representation we choose the unified tree.
445*8e6dbb4dSAlexander Hansen
446*8e6dbb4dSAlexander Hansen## Other Alternatives Considered
447*8e6dbb4dSAlexander Hansen
448*8e6dbb4dSAlexander Hansen### Kernel implementation
449*8e6dbb4dSAlexander Hansen
450*8e6dbb4dSAlexander HansenDid not do that since the support can be implemented in userspace. Also it may
451*8e6dbb4dSAlexander Hansennot be merged since the hardware configuration it supports may not be widely
452*8e6dbb4dSAlexander Hansenavailable. It may be better to have a userspace implementation to refer back to
453*8e6dbb4dSAlexander Hansenin case someone wants to do a kernel implementation later.
454*8e6dbb4dSAlexander Hansen
455*8e6dbb4dSAlexander Hansen### Multiple obmc-console-server processes for the multiple consoles
456*8e6dbb4dSAlexander Hansen
457*8e6dbb4dSAlexander HansenThis was considered and implemented is a PoC, but discarded later as it would be
458*8e6dbb4dSAlexander Hanseneasier to synchronize everything in a single process.
459*8e6dbb4dSAlexander Hansen
460*8e6dbb4dSAlexander Hansen### Multiple configuration files for multiple consoles
461*8e6dbb4dSAlexander Hansen
462*8e6dbb4dSAlexander HansenThis was considered but it would duplicate configuration, like the definition of
463*8e6dbb4dSAlexander Hansenthe mux GPIOs. Inconsistencies across the files would also need to be managed.
464*8e6dbb4dSAlexander Hansen
465*8e6dbb4dSAlexander Hansen## Impacts
466*8e6dbb4dSAlexander Hansen
467*8e6dbb4dSAlexander Hansen### API Impact
468*8e6dbb4dSAlexander Hansen
469*8e6dbb4dSAlexander Hansen### Performance Impact
470*8e6dbb4dSAlexander Hansen
471*8e6dbb4dSAlexander HansenMinimal to none.
472*8e6dbb4dSAlexander Hansen
473*8e6dbb4dSAlexander Hansen### Developer Impact
474*8e6dbb4dSAlexander Hansen
475*8e6dbb4dSAlexander HansenMinimal. Existing users do not need to change anything about their
476*8e6dbb4dSAlexander Hansenconfiguration.
477*8e6dbb4dSAlexander Hansen
478*8e6dbb4dSAlexander Hansen### Organizational
479*8e6dbb4dSAlexander Hansen
480*8e6dbb4dSAlexander Hansen- Does this repository require a new repository? No
481*8e6dbb4dSAlexander Hansen- Who will be the initial maintainer(s) of this repository?
482*8e6dbb4dSAlexander Hansen- Which repositories are expected to be modified to execute this design?
483*8e6dbb4dSAlexander Hansen  obmc-console, docs
484*8e6dbb4dSAlexander Hansen- Make a list, and add listed repository maintainers to the gerrit review.
485*8e6dbb4dSAlexander Hansen
486*8e6dbb4dSAlexander Hansen## Testing
487*8e6dbb4dSAlexander Hansen
488*8e6dbb4dSAlexander HansenThere are already integration tests for this feature available on gerrit.
489