openbmc_docs/designs/sol-sysrq.md

121 lines
4.1 KiB
Markdown
Raw Permalink Normal View History

2024-12-23 14:53:31 +08:00
# SysRq Support in SOL
Author: Lei Yu <LeiYU!>
Other contributors: Chen Tingting, Xie Xinnan
Created: Aug 02, 2023
## Problem Description
[SysRq][1] is a special key combination used by Linux to perform various
low-level commands. BMC usually provides SysRq support in KVM and SOL functions,
but this is not available in OpenBMC. This doc is to provide the SysRq support
in OpenBMC's SOL.
## Background and References
The key combination consists of Alt+SysRq (usually the `PrintScreen` key) and
another key, which controls the command issued. This is not typical key code and
requires special handling. A serial console usually invokes SysRq feature by
sending a serial break signal, followed by the desired key. The "break signal"
is usually generated by `ctrl+break` key combination.[2]
In ipmitool, the "break signal" is implemented in [ipmi_sol.c][3] by handling
the special `\n~B` keys.
## Requirements
OpenBMC SOL involves several ways:
- The ipmitool SOL.
- The SOL in WebUI.
- The console with SSH (default) 2200 port.
## Proposed Design
In OpenBMC, the service `obmc-console-server` provides the host console and
could be connected by multiple clients, using unix domain socket.
To implement the SysRq in OpenBMC SOL for ipmi and WebUI, the special key code
sequence `\n~B` is used to send the "break signal" between clients and
console-server. In `obmc-console`, a state machine shall handle the sequence.
Once the sequence is detected, it could invoke `tcsendbreak()` to send the
"break signal" to the Host.
### netipmid
In `phosphor-ipmi-net`, the code in `processInboundPayload()` shall handle the
break signal from ipmitool, and send the sequence `\n~B` to the server.
Then in ipmitool SOL session, user could enter `\n~B` keys to trigger the break,
and then enter a keycode as the SysRq command.
### WebUI
There are no changes required in WebUI, like netipmid, the user could enter the
key code sequence `\n~B` to trigger the break, and then user could enter a
keycode as the SysRq command.
### obmc-console
As the obmc-console server, in `console-server.h`, a simple state machine is
used to detect the sequence `\n~B`:
```mermaid
---
title: SysRq escape state machine
---
stateDiagram-v2
[*] --> Empty
Empty --> Emit: [^#92;n]
Emit --> [*]
Empty --> Newline: [#92;n]
Newline --> Escape: [~]
Newline --> EmitNewline: [^#92;n]
Escape --> EmitEscapeCode: [B]
EmitEscapeCode --> [*]
EmitNewline --> [*]
Escape --> EmitNewlineTilde: [^B]
EmitNewlineTilde --> [*]
```
If `EmitEscapeCode` state is reached, it shall call `tcsendbreak()` to send the
"break message" to the Host.
## Alternatives Considered
An alternative way to send the "break signal" between clients and console-server
is use `MSG_OOB` as the indicator of sysrq. The `MSG_OOB` was already introduced
to [netipmid][4] as the indicator of sysrq. In this solution, bmcweb shall be
modified to send `MSG_OOB` to obmc-console when the user enter the key code
sequence `\n~B`. When obmc-console receive `MSG_OOB`, it shall send the "break
message" to the Host.
However, in this solution, in some scenarios, obmc-console can not handle the
input sequence correctly, as `MSG_OOB` can be anywhere in the input sequence. It
is possible to synchronise the `MSG_OOB` with the stream with
[sockatmark(3)][5]. But it requires signalling the `MSG_OOB` in all obmc-console
clients, which is more work than the state machine solution.
## Impacts
Below services need minor changes to add the SysRq support:
- netipmid
- obmc-console
## Testing
The SysRq in SOL could be verified in both ipmitool SOL and WebUI SOL. In SOL
with SSH, we need enter the key code sequence with more than one tilde. Like
sequence `\n~~B`, the first tilde will be processed by obmc-console-client, the
second tilde will reach obmc-console-server.
[1]: https://en.wikipedia.org/wiki/Magic_SysRq_key
[2]: https://www.kernel.org/doc/html/latest/admin-guide/sysrq.html
[3]: https://github.com/ipmitool/ipmitool/blob/master/lib/ipmi_sol.c#L1398-L1401
[4]:
https://github.com/openbmc/phosphor-net-ipmid/commit/ec4374146147e339132243725d345eb30ec2da1d
[5]: https://man7.org/linux/man-pages/man3/sockatmark.3.html