Fix for restoreFromFile cereal exception
This commit provides a fix for an issue in which the cereal
restoreFromFile() would crash the host software updater in the event
that a priority persistence file is empty.
Resolves openbmc/openbmc#2091
Change-Id: Icca5d68ef250e2662cd02075c6ba731e4ab768b0
Signed-off-by: Michael Tritz <mtritz@us.ibm.com>
diff --git a/item_updater.cpp b/item_updater.cpp
index d022c96..0f583ed 100755
--- a/item_updater.cpp
+++ b/item_updater.cpp
@@ -194,23 +194,18 @@
// If Active, create RedundancyPriority instance for this version.
if (activationState == server::Activation::Activations::Active)
{
- if(fs::is_regular_file(PERSIST_DIR + id))
+ uint8_t priority = std::numeric_limits<uint8_t>::max();
+ if (!restoreFromFile(id, priority))
{
- uint8_t priority;
- restoreFromFile(id, &priority);
- activations.find(id)->second->redundancyPriority =
- std::make_unique<RedundancyPriority>(
- bus,
- path,
- *(activations.find(id)->second),
- priority);
+ log<level::ERR>("Unable to restore priority from file.",
+ entry("VERSIONID=%s", id));
}
- else
- {
- activations.find(id)->second->activation(
- server::Activation::Activations::Invalid);
- }
-
+ activations.find(id)->second->redundancyPriority =
+ std::make_unique<RedundancyPriority>(
+ bus,
+ path,
+ *(activations.find(id)->second),
+ priority);
}
// Create Version instance for this version.
diff --git a/serialize.cpp b/serialize.cpp
index 8e95727..a499798 100644
--- a/serialize.cpp
+++ b/serialize.cpp
@@ -26,15 +26,24 @@
oarchive(cereal::make_nvp("priority", priority));
}
-void restoreFromFile(std::string versionId, uint8_t *priority)
+bool restoreFromFile(std::string versionId, uint8_t& priority)
{
std::string path = PERSIST_DIR + versionId;
if (fs::exists(path))
{
std::ifstream is(path.c_str(), std::ios::in);
- cereal::JSONInputArchive iarchive(is);
- iarchive(cereal::make_nvp("priority", *priority));
+ try
+ {
+ cereal::JSONInputArchive iarchive(is);
+ iarchive(cereal::make_nvp("priority", priority));
+ return true;
+ }
+ catch(cereal::RapidJSONException& e)
+ {
+ fs::remove(path);
+ }
}
+ return false;
}
void removeFile(std::string versionId)
diff --git a/serialize.hpp b/serialize.hpp
index 90210a5..4e6e99f 100644
--- a/serialize.hpp
+++ b/serialize.hpp
@@ -21,8 +21,9 @@
/** @brief Serialization function - restores activation information from file
* @param[in] versionId - The version for which to retrieve information.
* @param[in] priority - RedundancyPriority pointer for that version.
+ * @return true if restore was successful, false if not
*/
-void restoreFromFile(std::string versionId, uint8_t *priority);
+bool restoreFromFile(std::string versionId, uint8_t& priority);
/** @brief Removes the serial file for a given version.
* @param[in] versionId - The version for which to remove a file, if it exists.