1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
From c14e31ebc35e0bb7b843d84683f9f2698c9c08d7 Mon Sep 17 00:00:00 2001
From: Yong Li <yong.b.li@linux.intel.com>
Date: Sun, 16 Sep 2018 21:32:38 +0800
Subject: [PATCH] Implement IPMI Commmand - Get Host Restart Cause.
It supports to track the information about what
action last caused the system to restart.
Return value includes: restart_cause and channel_number.
According to IPMI Spec, it includes 12 types as following:
1. Unknown 0x0
2. IpmiCommand 0x1
3. ResetButton 0x2
4. PowerButton 0x3
5. WatchdogTimer 0x4
6. OEM 0x5
7. PowerPolicyAlwaysOn 0x6
8. PowerPolicyPreviousState 0x7
9. PEF-Reset 0x8
10. PEF-PowerCycle 0x9
11. SoftReset 0xA
12. RTC-Wakeup 0xB
Change-Id: Id3b32e271b85b5fc4c69d5ca40227f8f9c08ce48
Signed-off-by: Kuiying Wang <kuiying.wang@intel.com>
Signed-off-by: Yong Li <yong.b.li@linux.intel.com>
---
chassishandler.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++++++
chassishandler.hpp | 1 +
host-ipmid-whitelist.conf | 1 +
3 files changed, 56 insertions(+)
diff --git a/chassishandler.cpp b/chassishandler.cpp
index 77af2dc..2a29755 100644
--- a/chassishandler.cpp
+++ b/chassishandler.cpp
@@ -107,6 +107,11 @@ static constexpr auto chassisPOHStateIntf =
"xyz.openbmc_project.State.PowerOnHours";
static constexpr auto pOHCounterProperty = "POHCounter";
static constexpr auto match = "chassis0";
+const static constexpr char* stateHostInterface =
+ "xyz.openbmc_project.State.Host";
+const static constexpr char* hostRestartCauseInterface =
+ "xyz.openbmc_project.State.Host.HostRestartCause";
+const static constexpr char* hostRestartCause = "HostRestartCause";
const static constexpr char chassisCapIntf[] =
"xyz.openbmc_project.Control.ChassisCapabilities";
const static constexpr char chassisCapFlagsProp[] = "CapabilitiesFlags";
@@ -324,6 +329,13 @@ struct set_sys_boot_options_t
uint8_t data[SIZE_BOOT_OPTION];
} __attribute__((packed));
+struct GetSysRestartCauseResponse
+{
+ uint8_t restartCause;
+ uint8_t channelNum;
+
+} __attribute__((packed));
+
int getHostNetworkData(get_sys_boot_options_response_t* respptr)
{
ipmi::PropertyMap properties;
@@ -1598,6 +1610,44 @@ ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
return rc;
}
+ipmi_ret_t ipmi_chassis_get_sys_restart_cause(
+ ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request,
+ ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context)
+{
+ ipmi_ret_t rc = IPMI_CC_OK;
+
+ GetSysRestartCauseResponse* resp = (GetSysRestartCauseResponse*)response;
+ std::fill(reinterpret_cast<uint8_t*>(resp),
+ reinterpret_cast<uint8_t*>(resp) + sizeof(*resp), 0);
+ if (*data_len != 0)
+ {
+ rc = IPMI_CC_REQ_DATA_LEN_INVALID;
+ return rc;
+ }
+
+ try
+ {
+ sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+ ipmi::DbusObjectInfo hostObject =
+ ipmi::getDbusObject(bus, stateHostInterface);
+ ipmi::Value variant =
+ ipmi::getDbusProperty(bus, hostObject.second, hostObject.first,
+ hostRestartCauseInterface, hostRestartCause);
+ resp->restartCause = variant.get<uint8_t>();
+ }
+
+ catch (std::exception& e)
+ {
+ log<level::ERR>(e.what());
+ rc = IPMI_CC_UNSPECIFIED_ERROR;
+ return rc;
+ }
+ resp->channelNum = 0; // Fix to primary channel.
+ *data_len = sizeof(GetSysRestartCauseResponse);
+
+ return rc;
+}
+
ipmi_ret_t ipmiGetPOHCounter(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
ipmi_request_t request, ipmi_response_t response,
ipmi_data_len_t data_len, ipmi_context_t context)
@@ -1739,4 +1789,8 @@ void register_netfn_chassis_functions()
ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_SET_RESTORE_POLICY, NULL,
ipmi_chassis_set_power_restore_policy,
PRIVILEGE_OPERATOR);
+
+ // <get Host Restart Cause>
+ ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_SYS_RESTART_CAUSE, NULL,
+ ipmi_chassis_get_sys_restart_cause, PRIVILEGE_USER);
}
diff --git a/chassishandler.hpp b/chassishandler.hpp
index 0c6d5a2..e37c4f1 100644
--- a/chassishandler.hpp
+++ b/chassishandler.hpp
@@ -17,6 +17,7 @@ enum ipmi_netfn_chassis_cmds
// Set Power Restore Policy
IPMI_CMD_SET_RESTORE_POLICY = 0x06,
// Get capability bits
+ IPMI_CMD_GET_SYS_RESTART_CAUSE = 0x07,
IPMI_CMD_SET_SYS_BOOT_OPTIONS = 0x08,
IPMI_CMD_GET_SYS_BOOT_OPTIONS = 0x09,
IPMI_CMD_GET_POH_COUNTER = 0x0F,
diff --git a/host-ipmid-whitelist.conf b/host-ipmid-whitelist.conf
index db54a49..827e2dc 100644
--- a/host-ipmid-whitelist.conf
+++ b/host-ipmid-whitelist.conf
@@ -3,6 +3,7 @@
0x00:0x02 //<Chassis>:<Chassis Control>
0x00:0x05 //<Chassis>:<Set Chassis Capabilities>
0x00:0x06 //<Chassis>:<Set Power Restore Policy>
+0x00:0x07 //<Chassis>:<Get System Restart Cause>
0x00:0x08 //<Chassis>:<Set System Boot Options>
0x00:0x09 //<Chassis>:<Get System Boot Options>
0x00:0x0F //<Chassis>:<Get POH Counter Command>
--
2.7.4
|