Add new google ipmi sys command: SysHostPowerOff
New google ipmi sys command to let the BMC knows host shutdown,
allow host to gracefully shutdown and disable the watchdog with given
time delay.
Signed-off-by: Yunyun Lin <linyuny@google.com>
Change-Id: I02171c9cfed57ae5d10d66b515e4ab7ee8856466
diff --git a/handler.cpp b/handler.cpp
index ef48842..e99bfff 100644
--- a/handler.cpp
+++ b/handler.cpp
@@ -308,6 +308,48 @@
}
}
+static constexpr auto HOST_TIME_DELAY_FILENAME = "/run/host_poweroff_delay";
+static constexpr auto HOST_POWEROFF_TARGET = "gbmc-host-poweroff.target";
+
+void Handler::hostPowerOffDelay(std::uint32_t delay) const
+{
+ // Set time delay
+ std::ofstream ofs;
+ ofs.open(HOST_TIME_DELAY_FILENAME, std::ofstream::out);
+ if (!ofs.good())
+ {
+ std::fprintf(stderr, "Unable to open file for output.\n");
+ throw IpmiException(IPMI_CC_UNSPECIFIED_ERROR);
+ }
+
+ ofs << "HOST_POWEROFF_DELAY=" << delay << std::endl;
+ ofs.close();
+ if (ofs.fail())
+ {
+ std::fprintf(stderr, "Write failed\n");
+ throw IpmiException(IPMI_CC_UNSPECIFIED_ERROR);
+ }
+
+ // Write succeeded, please continue.
+ auto bus = sdbusplus::bus::new_default();
+ auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT,
+ SYSTEMD_INTERFACE, "StartUnit");
+
+ method.append(HOST_POWEROFF_TARGET);
+ method.append("replace");
+
+ try
+ {
+ bus.call_noreply(method);
+ }
+ catch (const sdbusplus::exception::SdBusError& ex)
+ {
+ log<level::ERR>("Failed to call Power Off",
+ entry("WHAT=%s", ex.what()));
+ throw IpmiException(IPMI_CC_UNSPECIFIED_ERROR);
+ }
+}
+
std::string readNameFromConfig(const std::string& type, uint8_t instance,
const Json& config)
{