Add Restore Configuration command
Run this one weird command and you will get your factory settings back!
It is known by many names, restore defaults, factory reset, default
config, etc. A rose by any other name never smelled so great. And you
can get yours for the low, low, price of $49.99/mo for 36 months.
Tested-by:
# check status
ipmitool raw 0x30 0x02 0x43 0x4c 0x52 0
01
# restore defaults
ipmitool raw 0x30 0x02 0x43 0x4c 0x52 0xaa
00
# restore full
ipmitool raw 0x30 0x02 0x43 0x4c 0x52 0xaa
00
# restore format
ipmitool raw 0x30 0x02 0x43 0x4c 0x52 0xaa
00
# check status
ipmitool raw 0x30 0x02 0x43 0x4c 0x52 0
00
No animals were harmed in the testing of this feature
Change-Id: Icbffe63f6ce0ae045d588caffe3b1e839ae61d08
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5ab4157..ac3687f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -97,6 +97,7 @@
)
set_target_properties (zinteloemcmds PROPERTIES VERSION "0.1.0")
set_target_properties (zinteloemcmds PROPERTIES SOVERSION "0")
+target_link_libraries (zinteloemcmds stdc++fs)
target_link_libraries (zinteloemcmds ipmid)
target_link_libraries (zinteloemcmds sdbusplus)
target_link_libraries (zinteloemcmds phosphor_logging)
diff --git a/src/oemcommands.cpp b/src/oemcommands.cpp
index 0711183..028671a 100644
--- a/src/oemcommands.cpp
+++ b/src/oemcommands.cpp
@@ -25,6 +25,7 @@
#include <boost/process/io.hpp>
#include <com/intel/Control/OCOTShutdownPolicy/server.hpp>
#include <commandutils.hpp>
+#include <filesystem>
#include <iostream>
#include <ipmid/api.hpp>
#include <ipmid/utils.hpp>
@@ -39,6 +40,13 @@
namespace ipmi
{
static void registerOEMFunctions() __attribute__((constructor));
+
+namespace netfn::intel
+{
+constexpr NetFn oemGeneral = netFnOemOne;
+constexpr Cmd cmdRestoreConfiguration = 0x02;
+} // namespace netfn::intel
+
sdbusplus::bus::bus dbus(ipmid_get_sd_bus_connection()); // from ipmid/api.h
static constexpr size_t maxFRUStringLength = 0x3F;
@@ -1867,6 +1875,53 @@
return ipmi::responseSuccess(prodId);
}
+ipmi::RspType<uint8_t /* restore status */>
+ ipmiRestoreConfiguration(const std::array<uint8_t, 3>& clr, uint8_t cmd)
+{
+ static constexpr std::array<uint8_t, 3> expClr = {'C', 'L', 'R'};
+
+ if (clr != expClr)
+ {
+ return ipmi::responseInvalidFieldRequest();
+ }
+ constexpr uint8_t cmdStatus = 0;
+ constexpr uint8_t cmdDefaultRestore = 0xaa;
+ constexpr uint8_t cmdFullRestore = 0xbb;
+ constexpr uint8_t cmdFormat = 0xcc;
+
+ constexpr const char* restoreOpFname = "/tmp/.rwfs/.restore_op";
+
+ switch (cmd)
+ {
+ case cmdStatus:
+ break;
+ case cmdDefaultRestore:
+ case cmdFullRestore:
+ case cmdFormat:
+ {
+ // write file to rwfs root
+ int value = (cmd - 1) & 0x03; // map aa, bb, cc => 1, 2, 3
+ std::ofstream restoreFile(restoreOpFname);
+ if (!restoreFile)
+ {
+ return ipmi::responseUnspecifiedError();
+ }
+ restoreFile << value << "\n";
+ break;
+ }
+ default:
+ return ipmi::responseInvalidFieldRequest();
+ }
+
+ constexpr uint8_t restorePending = 0;
+ constexpr uint8_t restoreComplete = 1;
+
+ uint8_t restoreStatus = std::filesystem::exists(restoreOpFname)
+ ? restorePending
+ : restoreComplete;
+ return ipmi::responseSuccess(restoreStatus);
+}
+
static void registerOEMFunctions(void)
{
phosphor::logging::log<phosphor::logging::level::INFO>(
@@ -2002,7 +2057,10 @@
static_cast<ipmi::Cmd>(
IPMINetfnIntelOEMGeneralCmd::cmdSetFaultIndication),
ipmi::Privilege::Operator, ipmiOEMSetFaultIndication);
- return;
+
+ registerHandler(prioOemBase, netfn::intel::oemGeneral,
+ netfn::intel::cmdRestoreConfiguration, Privilege::Admin,
+ ipmiRestoreConfiguration);
}
} // namespace ipmi