From c6713cff6f28a6d78146a7406123e66ce1d5d320 Mon Sep 17 00:00:00 2001 From: Yong Li Date: Wed, 12 Sep 2018 12:35:13 +0800 Subject: Implement chassis set power restore policy command Implement the IPMI set power restore policy command 0x06. This command can be used to configure the power restore policy. This configuration parameter is kept in nonvolatile storage. The power restore policy determines how the system or chassis behaves when AC power returns after an AC power loss Tested: Run the below command to check the current Power Restore Policy: ipmitool -H -P 0penBmc -I lanplus chassis status Run the below command to change it: ipmitool -H -P 0penBmc -I lanplus chassis policy always-off Change-Id: I224912890f9a9e8b4dc98f840cd6f223c9f7dfe5 Signed-off-by: Yong Li --- chassishandler.cpp | 91 +++++++++++++++++++++++++++++++++++++++++++++++ chassishandler.h | 2 ++ host-ipmid-whitelist.conf | 1 + 3 files changed, 94 insertions(+) diff --git a/chassishandler.cpp b/chassishandler.cpp index 6002e7a..bfc079d 100644 --- a/chassishandler.cpp +++ b/chassishandler.cpp @@ -775,6 +775,10 @@ std::map dbusToIpmi = { {RestorePolicy::Policy::Restore, 0x01}, {RestorePolicy::Policy::AlwaysOn, 0x02}}; +static constexpr uint8_t noChange = 0x03; +static constexpr uint8_t allSupport = 0x01 | 0x02 | 0x04; +static constexpr uint8_t policyBitMask = 0x07; +static constexpr uint8_t setPolicyReqLen = 1; } // namespace power_policy //---------------------------------------------------------------------- @@ -1616,6 +1620,88 @@ ipmi_ret_t ipmiGetPOHCounter(ipmi_netfn_t netfn, ipmi_cmd_t cmd, return rc; } +ipmi_ret_t ipmi_chassis_set_power_restore_policy( + 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) +{ + auto* reqptr = reinterpret_cast(request); + auto* resptr = reinterpret_cast(response); + uint8_t reqPolicy = 0; + + power_policy::DbusValue value = + power_policy::RestorePolicy::Policy::AlwaysOff; + + if (*data_len != power_policy::setPolicyReqLen) + { + phosphor::logging::log("Unsupported request length", + entry("LEN=0x%x", *data_len)); + *data_len = 0; + return IPMI_CC_REQ_DATA_LEN_INVALID; + } + + reqPolicy = *reqptr & power_policy::policyBitMask; + if (reqPolicy > power_policy::noChange) + { + phosphor::logging::log("Reserved request parameter", + entry("REQ=0x%x", reqPolicy)); + *data_len = 0; + return IPMI_CC_PARM_NOT_SUPPORTED; + } + + if (reqPolicy == power_policy::noChange) + { + // just return the supported policy + *resptr = power_policy::allSupport; + *data_len = power_policy::setPolicyReqLen; + return IPMI_CC_OK; + } + + for (auto const& it : power_policy::dbusToIpmi) + { + if (it.second == reqPolicy) + { + value = it.first; + break; + } + } + + try + { + const settings::Path& powerRestoreSetting = + chassis::internal::cache::objects.map + .at(chassis::internal::powerRestoreIntf) + .front(); + sdbusplus::message::variant property = + convertForMessage(value); + + auto method = chassis::internal::dbus.new_method_call( + chassis::internal::cache::objects + .service(powerRestoreSetting, + chassis::internal::powerRestoreIntf) + .c_str(), + powerRestoreSetting.c_str(), ipmi::PROP_INTF, "Set"); + + method.append(chassis::internal::powerRestoreIntf, "PowerRestorePolicy", + property); + auto reply = chassis::internal::dbus.call(method); + if (reply.is_method_error()) + { + phosphor::logging::log("Unspecified Error"); + *data_len = 0; + return IPMI_CC_UNSPECIFIED_ERROR; + } + } + catch (InternalFailure& e) + { + report(); + *data_len = 0; + return IPMI_CC_UNSPECIFIED_ERROR; + } + + *data_len = power_policy::setPolicyReqLen; + return IPMI_CC_OK; +} + void register_netfn_chassis_functions() { createIdentifyTimer(); @@ -1652,4 +1738,9 @@ void register_netfn_chassis_functions() // ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_POH_COUNTER, NULL, ipmiGetPOHCounter, PRIVILEGE_USER); + + // + ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_SET_RESTORE_POLICY, NULL, + ipmi_chassis_set_power_restore_policy, + PRIVILEGE_OPERATOR); } diff --git a/chassishandler.h b/chassishandler.h index edbac89..0c6d5a2 100644 --- a/chassishandler.h +++ b/chassishandler.h @@ -14,6 +14,8 @@ enum ipmi_netfn_chassis_cmds // Chassis Control IPMI_CMD_CHASSIS_CONTROL = 0x02, IPMI_CMD_CHASSIS_IDENTIFY = 0x04, + // Set Power Restore Policy + IPMI_CMD_SET_RESTORE_POLICY = 0x06, // Get capability bits IPMI_CMD_SET_SYS_BOOT_OPTIONS = 0x08, IPMI_CMD_GET_SYS_BOOT_OPTIONS = 0x09, diff --git a/host-ipmid-whitelist.conf b/host-ipmid-whitelist.conf index a95e99e..2c37ac9 100644 --- a/host-ipmid-whitelist.conf +++ b/host-ipmid-whitelist.conf @@ -2,6 +2,7 @@ 0x00:0x00 //: 0x00:0x01 //: 0x00:0x02 //: +0x00:0x06 //: 0x00:0x08 //: 0x00:0x09 //: 0x00:0x0F //: -- cgit v1.2.1