Host updater: implement GUARD factory reset
This commit extends the functionality of the host updater with a second
implementation of FactoryReset. This implementation is placed under the
/org/openpower/control/guard path and clears the PNOR GUARD partition.
Resolves openbmc/openbmc#2389
Change-Id: Id89aafe9211b48aee5238ff06b957fa7a99324ab
Signed-off-by: Michael Tritz <mtritz@us.ibm.com>
diff --git a/item_updater.cpp b/item_updater.cpp
index 502a8e0..05fbe00 100644
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -32,6 +32,10 @@
"xyz.openbmc_project.State.Chassis.PowerState.Off";
constexpr auto SYSTEMD_PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties";
+// TODO: Change paths once openbmc/openbmc#1663 is completed.
+constexpr auto MBOXD_INTERFACE = "org.openbmc.mboxd";
+constexpr auto MBOXD_PATH = "/org/openbmc/mboxd";
+
void ItemUpdater::createActivation(sdbusplus::message::message& m)
{
using SVersion = server::Version;
@@ -608,6 +612,53 @@
return target.substr(PNOR_RO_PREFIX_LEN);
}
+void GardReset::reset()
+{
+ // The GARD partition is currently misspelled "GUARD." This file path will
+ // need to be updated in the future.
+ auto path = fs::path(PNOR_PRSV_ACTIVE_PATH);
+ path /= "GUARD";
+ std::vector<uint8_t> mboxdArgs;
+
+ auto dbusCall = bus.new_method_call(
+ MBOXD_INTERFACE,
+ MBOXD_PATH,
+ MBOXD_INTERFACE,
+ "cmd");
+
+ // Suspend mboxd - no args required.
+ dbusCall.append(static_cast<uint8_t>(3), mboxdArgs);
+
+ auto responseMsg = bus.call(dbusCall);
+ if (responseMsg.is_method_error())
+ {
+ log<level::ERR>("Error in mboxd suspend call");
+ elog<InternalFailure>();
+ }
+
+ if (fs::is_regular_file(path))
+ {
+ fs::remove(path);
+ }
+
+ dbusCall = bus.new_method_call(
+ MBOXD_INTERFACE,
+ MBOXD_PATH,
+ MBOXD_INTERFACE,
+ "cmd");
+
+ // Resume mboxd with arg 1, indicating that the flash is modified.
+ mboxdArgs.push_back(1);
+ dbusCall.append(static_cast<uint8_t>(4), mboxdArgs);
+
+ responseMsg = bus.call(dbusCall);
+ if (responseMsg.is_method_error())
+ {
+ log<level::ERR>("Error in mboxd resume call");
+ elog<InternalFailure>();
+ }
+}
+
} // namespace updater
} // namespace software
} // namespace openpower
diff --git a/item_updater.hpp b/item_updater.hpp
index 3c8698f..893e8b9 100755
--- a/item_updater.hpp
+++ b/item_updater.hpp
@@ -18,11 +18,57 @@
sdbusplus::xyz::openbmc_project::Common::server::FactoryReset,
sdbusplus::org::openbmc::server::Associations,
sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll>;
+using GardResetInherit = sdbusplus::server::object::object<
+ sdbusplus::xyz::openbmc_project::Common::server::FactoryReset>;
namespace MatchRules = sdbusplus::bus::match::rules;
using AssociationList =
std::vector<std::tuple<std::string, std::string, std::string>>;
+constexpr auto GARD_PATH = "/org/openpower/control/gard";
+
+/** @class GardReset
+ * @brief OpenBMC GARD factory reset implementation.
+ * @details An implementation of xyz.openbmc_project.Common.FactoryReset under
+ * /org/openpower/control/gard.
+ */
+class GardReset : public GardResetInherit
+{
+ public:
+ /** @brief Constructs GardReset.
+ *
+ * @param[in] bus - The Dbus bus object
+ * @param[in] path - The Dbus object path
+ */
+ GardReset(sdbusplus::bus::bus& bus,
+ const std::string& path) :
+ GardResetInherit(bus, path.c_str(), true),
+ bus(bus),
+ path(path)
+ {
+ std::vector<std::string> interfaces({interface});
+ bus.emit_interfaces_added(path.c_str(), interfaces);
+ }
+
+ ~GardReset()
+ {
+ std::vector<std::string> interfaces({interface});
+ bus.emit_interfaces_removed(path.c_str(), interfaces);
+ }
+
+ private:
+ // TODO Remove once openbmc/openbmc#1975 is resolved
+ static constexpr auto interface =
+ "xyz.openbmc_project.Common.FactoryReset";
+ sdbusplus::bus::bus& bus;
+ std::string path;
+
+ /**
+ * @brief GARD factory reset - clears the PNOR GARD partition.
+ */
+ void reset() override;
+};
+
/** @class ItemUpdater
* @brief Manages the activation of the host version items.
*/
@@ -47,6 +93,10 @@
std::placeholders::_1))
{
processPNORImage();
+ gardReset = std::make_unique<GardReset>(bus, GARD_PATH);
+
+ // Emit deferred signal.
+ emit_object_added();
}
/** @brief Sets the given priority free by incrementing
@@ -119,6 +169,9 @@
*/
void removeActiveAssociation(const std::string& path);
+ /** @brief Persistent GardReset dbus object */
+ std::unique_ptr<GardReset> gardReset;
+
private:
/** @brief Callback function for Software.Version match.
* @details Creates an Activation D-Bus object.