firmware_handler: implement session stat w/ verification
Implement session stat to handle checking on the verification state as
well as properly reporting when there isn't an image handler.
Signed-off-by: Patrick Venture <venture@google.com>
Change-Id: I98079a0f38976e1aa9876c8a2232481231dbc6e1
diff --git a/firmware_handler.cpp b/firmware_handler.cpp
index 8daead6..a07ddbb 100644
--- a/firmware_handler.cpp
+++ b/firmware_handler.cpp
@@ -21,6 +21,7 @@
#include <algorithm>
#include <cstdint>
#include <cstring>
+#include <fstream>
#include <memory>
#include <phosphor-logging/log.hpp>
#include <string>
@@ -35,6 +36,7 @@
static constexpr auto systemdRoot = "/org/freedesktop/systemd1";
static constexpr auto systemdInterface = "org.freedesktop.systemd1.Manager";
static constexpr auto verifyTarget = "verify_image.service";
+static constexpr auto statusPath = "/tmp/bmc.verify";
const std::string FirmwareBlobHandler::verifyBlobID = "/flash/verify";
const std::string FirmwareBlobHandler::hashBlobID = "/flash/hash";
@@ -42,6 +44,43 @@
"/flash/active/image";
const std::string FirmwareBlobHandler::activeHashBlobID = "/flash/active/hash";
+namespace
+{
+
+FirmwareBlobHandler::VerifyCheckResponses checkVerificationState()
+{
+ FirmwareBlobHandler::VerifyCheckResponses result =
+ FirmwareBlobHandler::VerifyCheckResponses::other;
+
+ std::ifstream ifs;
+ ifs.open(statusPath);
+ if (ifs.good())
+ {
+ /*
+ * Check for the contents of the file, accepting:
+ * running, success, or failed.
+ */
+ std::string status;
+ ifs >> status;
+ if (status == "running")
+ {
+ result = FirmwareBlobHandler::VerifyCheckResponses::running;
+ }
+ else if (status == "success")
+ {
+ result = FirmwareBlobHandler::VerifyCheckResponses::success;
+ }
+ else if (status == "failed")
+ {
+ result = FirmwareBlobHandler::VerifyCheckResponses::failed;
+ }
+ }
+
+ return result;
+}
+
+} // namespace
+
std::unique_ptr<GenericBlobInterface>
FirmwareBlobHandler::CreateFirmwareBlobHandler(
sdbusplus::bus::bus&& bus, const std::vector<HandlerPack>& firmwares,
@@ -217,20 +256,30 @@
*/
meta->blobState = item->second->flags;
+ /* The size here refers to the size of the file -- of something analagous.
+ */
+ meta->size = (item->second->imageHandler)
+ ? item->second->imageHandler->getSize()
+ : 0;
+
+ meta->metadata.clear();
+
/* TODO: Implement this for the verification blob, which is what we expect.
* Calling stat() on the verify blob without an active session should not
* provide insight.
*/
+ if (item->second->activePath == verifyBlobID)
+ {
+ meta->metadata.push_back(
+ static_cast<std::uint8_t>(checkVerificationState()));
- /* The size here refers to the size of the file -- of something analagous.
- */
- meta->size = item->second->imageHandler->getSize();
+ return true;
+ }
/* The metadata blob returned comes from the data handler... it's used for
* instance, in P2A bridging to get required information about the mapping,
* and is the "opposite" of the lpc writemeta requirement.
*/
- meta->metadata.clear();
if (item->second->dataHandler)
{
auto bytes = item->second->dataHandler->readMeta();
@@ -238,10 +287,6 @@
bytes.end());
}
- /* TODO: During things like verification, etc, we can report the state as
- * committed, etc, so we'll need to do that.
- */
-
return true;
}
diff --git a/firmware_handler.hpp b/firmware_handler.hpp
index 212e570..fe410a1 100644
--- a/firmware_handler.hpp
+++ b/firmware_handler.hpp
@@ -111,7 +111,7 @@
};
/** The return values for verification. */
- enum VerifyCheckResponses : std::uint8_t
+ enum class VerifyCheckResponses : std::uint8_t
{
running = 0,
success = 1,