Code Update: Host ApplyTime support
Get the requested image apply time value provided through the
UpdateService redfish schema. If the apply time value is Immediate, then
host reboot will be triggered just after the new pnor image activation. The
default apply time value is OnReset in which the new image remains at
Active state and user has to manualy reboot the host for applying the new
image.
Tested: Verified that host is getting rebooted while doing a pnor code update
if the apply time value is Immediate. Tested this use case at server power Off
and Running scenarios. OnReset scenario was also tested in which new image
remained at Active state as pnor code update application did not trigger the
host reboot.
Note: This change is applicable to ubi based systems (Witherspoon)
Signed-off-by: Jayashankar Padath <jayashankar.padath@in.ibm.com>
Change-Id: I74f73172626919b225efef43d9baacd64eadbf60
diff --git a/activation.cpp b/activation.cpp
index dd52fb6..48baf6d 100644
--- a/activation.cpp
+++ b/activation.cpp
@@ -5,16 +5,15 @@
#include "item_updater.hpp"
#include <experimental/filesystem>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/elog.hpp>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/exception.hpp>
+#include <sdbusplus/server.hpp>
+#include <xyz/openbmc_project/Common/error.hpp>
#ifdef WANT_SIGNATURE_VERIFY
#include "image_verify.hpp"
-
-#include <phosphor-logging/elog-errors.hpp>
-#include <phosphor-logging/elog.hpp>
-#include <sdbusplus/server.hpp>
-#include <xyz/openbmc_project/Common/error.hpp>
#endif
namespace openpower
@@ -29,11 +28,10 @@
using namespace phosphor::logging;
using sdbusplus::exception::SdBusError;
-
-#ifdef WANT_SIGNATURE_VERIFY
using InternalFailure =
sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
+#ifdef WANT_SIGNATURE_VERIFY
// Field mode path and interface.
constexpr auto FIELDMODE_PATH("/xyz/openbmc_project/software");
constexpr auto FIELDMODE_INTERFACE("xyz.openbmc_project.Control.FieldMode");
@@ -166,6 +164,74 @@
}
}
+bool Activation::checkApplyTimeImmediate()
+{
+ auto service = utils::getService(bus, applyTimeObjPath, applyTimeIntf);
+ if (service.empty())
+ {
+ log<level::INFO>("Error getting the service name for Host image "
+ "ApplyTime. The Host needs to be manually rebooted to "
+ "complete the image activation if needed "
+ "immediately.");
+ }
+ else
+ {
+
+ auto method = bus.new_method_call(service.c_str(), applyTimeObjPath,
+ dbusPropIntf, "Get");
+ method.append(applyTimeIntf, applyTimeProp);
+
+ try
+ {
+ auto reply = bus.call(method);
+
+ sdbusplus::message::variant<std::string> result;
+ reply.read(result);
+ auto applyTime =
+ sdbusplus::message::variant_ns::get<std::string>(result);
+ if (applyTime == applyTimeImmediate)
+ {
+ return true;
+ }
+ }
+ catch (const SdBusError& e)
+ {
+ log<level::ERR>("Error in getting ApplyTime",
+ entry("ERROR=%s", e.what()));
+ }
+ }
+ return false;
+}
+
+void Activation::rebootHost()
+{
+ auto service = utils::getService(bus, hostStateObjPath, hostStateIntf);
+ if (service.empty())
+ {
+ log<level::ALERT>("Error in getting the service name to reboot the "
+ "Host. The Host needs to be manually rebooted to "
+ "complete the image activation.");
+ }
+
+ auto method = bus.new_method_call(service.c_str(), hostStateObjPath,
+ dbusPropIntf, "Set");
+ sdbusplus::message::variant<std::string> hostReboot = hostStateRebootVal;
+ method.append(hostStateIntf, hostStateRebootProp, hostReboot);
+
+ try
+ {
+ auto reply = bus.call(method);
+ }
+ catch (const SdBusError& e)
+ {
+ log<level::ALERT>("Error in trying to reboot the Host. "
+ "The Host needs to be manually rebooted to complete "
+ "the image activation.",
+ entry("ERROR=%s", e.what()));
+ report<InternalFailure>();
+ }
+}
+
uint8_t RedundancyPriority::priority(uint8_t value)
{
parent.parent.freePriority(value, parent.versionId);