monitor: Re-log fan error on a power off
In the case where a power off rule runs to completion and powers off the
system due to either missing or faulted fans, at the point of power off
re-post the event log for the previous fan error.
This way, there can be an error associated with the power off, because
depending on the power off rule delays the original error could have
happened several minutes or more in the past.
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I1a38062cf75ffd4a11baa417ef3983b6c1a47ada
diff --git a/monitor/power_off_action.hpp b/monitor/power_off_action.hpp
index 05d4ff6..59b1406 100644
--- a/monitor/power_off_action.hpp
+++ b/monitor/power_off_action.hpp
@@ -33,6 +33,8 @@
class PowerOffAction
{
public:
+ using PrePowerOffFunc = std::function<void()>;
+
PowerOffAction() = delete;
virtual ~PowerOffAction() = default;
PowerOffAction(const PowerOffAction&) = delete;
@@ -44,13 +46,18 @@
* @brief Constructor
*
* @param[in] name - The action name. Used for tracing.
- * powerInterface - The object used to invoke the power off.
+ * @param[in] powerInterface - The object used to invoke the power off.
+ * @param[in] powerOffFunc - A function to call right before the power
+ * off occurs (after any delays). May be
+ * empty if no function is necessary.
*/
PowerOffAction(const std::string& name,
- std::shared_ptr<PowerInterfaceBase> powerInterface) :
+ std::shared_ptr<PowerInterfaceBase> powerInterface,
+ PrePowerOffFunc& powerOffFunc) :
_name(name),
_powerIface(std::move(powerInterface)),
- _event(sdeventplus::Event::get_default())
+ _event(sdeventplus::Event::get_default()),
+ _prePowerOffFunc(powerOffFunc)
{}
/**
@@ -120,6 +127,12 @@
* @brief The event loop object. Needed by timers.
*/
sdeventplus::Event _event;
+
+ /**
+ * @brief A function that will be called right before
+ * the power off.
+ */
+ PrePowerOffFunc _prePowerOffFunc;
};
/**
@@ -144,11 +157,15 @@
* @param[in] delay - The amount of time in seconds to wait before
* doing the power off
* @param[in] powerInterface - The object to use to do the power off
+ * @param[in] func - A function to call right before the power
+ * off occurs (after the delay). May be
+ * empty if no function is necessary.
*/
HardPowerOff(uint32_t delay,
- std::shared_ptr<PowerInterfaceBase> powerInterface) :
+ std::shared_ptr<PowerInterfaceBase> powerInterface,
+ PrePowerOffFunc func) :
PowerOffAction("Hard Power Off: " + std::to_string(delay) + "s",
- powerInterface),
+ powerInterface, func),
_delay(delay),
_timer(_event, std::bind(std::mem_fn(&HardPowerOff::powerOff), this))
{}
@@ -185,6 +202,12 @@
*/
void powerOff()
{
+
+ if (_prePowerOffFunc)
+ {
+ _prePowerOffFunc();
+ }
+
getLogger().log(
fmt::format("Action '{}' executing hard power off", name()));
_powerIface->hardPowerOff();
@@ -225,11 +248,15 @@
* @param[in] delay - The amount of time in seconds to wait before
* doing the power off
* @param[in] powerInterface - The object to use to do the power off
+ * @param[in] func - A function to call right before the power
+ * off occurs (after the delay). May be
+ * empty if no function is necessary.
*/
SoftPowerOff(uint32_t delay,
- std::shared_ptr<PowerInterfaceBase> powerInterface) :
+ std::shared_ptr<PowerInterfaceBase> powerInterface,
+ PrePowerOffFunc func) :
PowerOffAction("Soft Power Off: " + std::to_string(delay) + "s",
- powerInterface),
+ powerInterface, func),
_delay(delay),
_timer(_event, std::bind(std::mem_fn(&SoftPowerOff::powerOff), this))
{}
@@ -266,6 +293,11 @@
*/
void powerOff()
{
+ if (_prePowerOffFunc)
+ {
+ _prePowerOffFunc();
+ }
+
getLogger().log(
fmt::format("Action '{}' executing soft power off", name()));
_powerIface->softPowerOff();
@@ -302,10 +334,11 @@
EpowPowerOff& operator=(EpowPowerOff&&) = delete;
EpowPowerOff(uint32_t serviceModeDelay, uint32_t meltdownDelay,
- std::shared_ptr<PowerInterfaceBase> powerInterface) :
+ std::shared_ptr<PowerInterfaceBase> powerInterface,
+ PrePowerOffFunc func) :
PowerOffAction("EPOW Power Off: " + std::to_string(serviceModeDelay) +
"s/" + std::to_string(meltdownDelay) + "s",
- powerInterface),
+ powerInterface, func),
_serviceModeDelay(serviceModeDelay), _meltdownDelay(meltdownDelay)
{}