phosphor-ipmi-net: Add sysrq handle in netipmid for ipmitool sol.
Send MSG_OOB flag to console server to generate a break.
Tested:
1. Open SOL by ipmitool: ipmitool -H <bmcip> -I lanp -U <user> -P <password> sol activate
2. In SOL terminal, login os and "echo 1 > /proc/sys/kernel/sysrq" to open sysrq function
3. In SOL terminal, Enter ~+B to generate break, then enter "h" in 5 second.
4. Veirfy below message shown in SOL:
root@bytedance:~# ~B [send break]
[ 366.377331] sysrq: HELP : loglevel(0-9) reboot(b) crash(c) terminate-all-tasks(e)
memory-full-oom-kill(f) kill-all-tasks(i) thaw-filesystems(j) sak(k) show-backtrace-all-active-cpus(l)
show-memory-usage(m) nice-all-RT-tasks(n) poweroff(o) show-registers(p) show-all-timers(q) unraw(r)
sync(s) show-task-states(t) unmount(u) force-fb(V) show-blocked-tasks(w) dump-ftrace-buffer(z)
Change-Id: Ieac3ee0c7f964920214aa185a947e0449034726f
Signed-off-by: Tingting Chen <chentingting.2150@bytedance.com>
diff --git a/command/sol_cmds.cpp b/command/sol_cmds.cpp
index ceee3d8..9bb92ce 100644
--- a/command/sol_cmds.cpp
+++ b/command/sol_cmds.cpp
@@ -39,7 +39,8 @@
context.processInboundPayload(
request->packetSeqNum, request->packetAckSeqNum,
- request->acceptedCharCount, request->inOperation.ack, charData);
+ request->acceptedCharCount, request->inOperation.ack,
+ request->inOperation.generateBreak, charData);
}
catch (const std::exception& e)
{
diff --git a/sol/sol_context.cpp b/sol/sol_context.cpp
index 4702bbe..06dabcc 100644
--- a/sol/sol_context.cpp
+++ b/sol/sol_context.cpp
@@ -82,7 +82,7 @@
}
void Context::processInboundPayload(uint8_t seqNum, uint8_t ackSeqNum,
- uint8_t count, bool status,
+ uint8_t count, bool status, bool isBreak,
const std::vector<uint8_t>& input)
{
uint8_t respAckSeqNum = 0;
@@ -145,10 +145,24 @@
payloadCache.clear();
}
+ if (isBreak && seqNum)
+ {
+ lg2::info("Writing break to console socket descriptor");
+ constexpr uint8_t sysrqValue = 72; // use this to notify sol server
+ const std::vector<uint8_t> test{sysrqValue};
+ auto ret = sol::Manager::get().writeConsoleSocket(test, isBreak);
+ if (ret)
+ {
+ lg2::error("Writing to console socket descriptor failed: {ERROR}",
+ "ERROR", strerror(errno));
+ }
+ }
+
+ isBreak = false;
// Write character data to the Host Console
if (!input.empty() && seqNum)
{
- auto rc = sol::Manager::get().writeConsoleSocket(input);
+ auto rc = sol::Manager::get().writeConsoleSocket(input, isBreak);
if (rc)
{
lg2::error("Writing to console socket descriptor failed: {ERROR}",
diff --git a/sol/sol_context.hpp b/sol/sol_context.hpp
index 34a0076..fe70dbf 100644
--- a/sol/sol_context.hpp
+++ b/sol/sol_context.hpp
@@ -252,7 +252,8 @@
* @param[in] input - Incoming SOL character data.
*/
void processInboundPayload(uint8_t seqNum, uint8_t ackSeqNum, uint8_t count,
- bool status, const std::vector<uint8_t>& input);
+ bool status, bool isBreak,
+ const std::vector<uint8_t>& input);
/** @brief Send the outbound SOL payload.
*
diff --git a/sol/sol_manager.cpp b/sol/sol_manager.cpp
index 42296e3..a8a9faa 100644
--- a/sol/sol_manager.cpp
+++ b/sol/sol_manager.cpp
@@ -70,10 +70,19 @@
dataBuffer.write(buffer);
}
-int Manager::writeConsoleSocket(const std::vector<uint8_t>& input) const
+int Manager::writeConsoleSocket(const std::vector<uint8_t>& input,
+ bool breakFlag) const
{
boost::system::error_code ec;
- boost::asio::write(*consoleSocket, boost::asio::buffer(input), ec);
+ if (breakFlag)
+ {
+ consoleSocket->send(boost::asio::buffer(input), MSG_OOB, ec);
+ }
+ else
+ {
+ consoleSocket->send(boost::asio::buffer(input), 0, ec);
+ }
+
return ec.value();
}
diff --git a/sol/sol_manager.hpp b/sol/sol_manager.hpp
index 72c13b4..33a537d 100644
--- a/sol/sol_manager.hpp
+++ b/sol/sol_manager.hpp
@@ -273,7 +273,8 @@
*
* @return 0 on success and errno on failure.
*/
- int writeConsoleSocket(const std::vector<uint8_t>& input) const;
+ int writeConsoleSocket(const std::vector<uint8_t>& input,
+ bool breakFlag) const;
void updateSOLParameter(uint8_t channelNum);
private: