Author: Lei Yu <LeiYU!>
Other contributors: Chen Tingting, Xie Xinnan
Created: Aug 02, 2023
SysRq 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.
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 by handling
the special \n~B
keys.
OpenBMC SOL involves several ways:
- The ipmitool SOL.
- The SOL in WebUI.
- The console with SSH (default) 2200 port.
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.
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.
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.
As the obmc-console server, in console-server.h
, a simple state machine is
used to detect the sequence \n~B
:
---
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.
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 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). But it requires signalling the MSG_OOB
in all obmc-console
clients, which is more work than the state machine solution.
Below services need minor changes to add the SysRq support:
- netipmid
- obmc-console
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.