Store boot events as raw data instead of parsing it
This CL stores the host stat events in a raw format so parsing can
be done in userland where it's more flexible to do changes.
Tested:
```
busctl call --verbose com.google.gbmc.boot_time_monitor \
/xyz/openbmc_project/time/boot/host0 \
xyz.openbmc_project.Time.Boot.Checkpoint GetCheckpointList
MESSAGE "a(sxx)" {
ARRAY "(sxx)" {
STRUCT "sxx" {
STRING "Shutdown:BEGIN";
INT64 1721722017000;
INT64 569778660;
};
STRUCT "sxx" {
STRING "Shutdown";
INT64 1721722028000;
INT64 569789660;
};
STRUCT "sxx" {
STRING "HostState:Off";
INT64 1721722411715;
INT64 569868660;
};
STRUCT "sxx" {
STRING "OSStatus:Inactive";
INT64 1721722411759;
INT64 569868710;
};
STRUCT "sxx" {
STRING "HostState:Off";
INT64 1721722511519;
INT64 82500;
};
STRUCT "sxx" {
STRING "OSStatus:Inactive";
INT64 1721722511536;
INT64 82510;
};
STRUCT "sxx" {
STRING "HostState:Running";
INT64 1721722596037;
INT64 167010;
};
STRUCT "sxx" {
STRING "OSStatus:Standby";
INT64 1721722718742;
INT64 289720;
};
STRUCT "sxx" {
STRING "Loader";
INT64 136000;
INT64 430620;
};
STRUCT "sxx" {
STRING "Userspace:BEGIN";
INT64 1721723134000;
INT64 567380;
};
STRUCT "sxx" {
STRING "Userspace";
INT64 1721723167000;
INT64 600380;
};
};
};
```
Google-Bug-Id: 296787899
Change-Id: I359dd43da7c302151d2b6c226809de424f8967d2
Signed-off-by: Medicine Yeh <medicineyeh@google.com>
diff --git a/include/boot_manager.hpp b/include/boot_manager.hpp
index 182fd8d..32c0022 100644
--- a/include/boot_manager.hpp
+++ b/include/boot_manager.hpp
@@ -79,7 +79,7 @@
class BootManager : public BootManagerIface
{
public:
- constexpr static std::string_view kTransitionStagePrefix = "To_";
+ constexpr static std::string_view kBeginStageSuffix = ":BEGIN";
BootManager(std::shared_ptr<UtilIface> util,
const std::shared_ptr<FileUtilIface>& cpCSV,
diff --git a/include/host_monitor_app.hpp b/include/host_monitor_app.hpp
index ca3f835..850237d 100644
--- a/include/host_monitor_app.hpp
+++ b/include/host_monitor_app.hpp
@@ -23,8 +23,8 @@
const std::string kNodeName;
const std::string kObjPath;
sdbusplus::server::manager::manager objManager;
- std::unique_ptr<sdbusplus::bus::match::match> powerMatcher;
- std::unique_ptr<sdbusplus::bus::match::match> osStatusMatcher;
+ std::unique_ptr<sdbusplus::bus::match::match> hostStateWatcher;
+ std::unique_ptr<sdbusplus::bus::match::match> osStatusWatcher;
std::shared_ptr<Util> util;
std::shared_ptr<FileUtil> cpCSV;
diff --git a/src/boot_manager.cpp b/src/boot_manager.cpp
index 79d41ea..4a726b5 100644
--- a/src/boot_manager.cpp
+++ b/src/boot_manager.cpp
@@ -46,7 +46,7 @@
if (!util->isValidName(cpName))
{
fmt::print(
- "[{}] Name is invalid. Only allows [0-9a-zA-Z_] but get: {}\n",
+ "[{}] Name is invalid. Only allows [0-9a-zA-Z_:] but get: {}\n",
__FUNCTION__, cpName);
return;
}
@@ -69,7 +69,7 @@
if (duration != 0)
{
checkpoints.emplace_back(
- std::string{kTransitionStagePrefix} + cpName.data(),
+ cpName.data() + std::string{kBeginStageSuffix},
wallTime - duration, upTime.value() - duration);
cpCSV->addCheckpoint(checkpoints.back().name,
checkpoints.back().wallTime,
@@ -96,7 +96,7 @@
if (!util->isValidName(durName))
{
fmt::print(
- "[{}] Name is invalid. Only allows [0-9a-zA-Z_] but get: {}\n",
+ "[{}] Name is invalid. Only allows [0-9a-zA-Z_:] but get: {}\n",
__FUNCTION__, durName);
return;
}
diff --git a/src/host_monitor_app.cpp b/src/host_monitor_app.cpp
index 788a268..07c3ac0 100644
--- a/src/host_monitor_app.cpp
+++ b/src/host_monitor_app.cpp
@@ -12,6 +12,7 @@
#include <sdbusplus/message.hpp>
#include <memory>
+#include <ranges>
#include <string>
#include <string_view>
#include <variant>
@@ -40,8 +41,15 @@
"xyz.openbmc_project.State.OperatingSystem.Status";
constexpr std::string_view kOSStatusProperty = "OperatingSystemState";
-constexpr std::string_view kOSStatusStandby = "Standby";
-constexpr std::string_view kOSStatusInactivate = "Inactive";
+std::string inline translateHostStateName(std::string_view state) {
+ std::size_t found = state.find_last_of('.');
+ return std::string("HostState:") + std::string(state.substr(found+1));
+}
+
+std::string inline translateOSStatus(std::string_view status) {
+ std::size_t found = status.find_last_of('.');
+ return std::string("OSStatus:") + std::string(status.substr(found+1));
+}
HostMonitorApp::HostMonitorApp(sdbusplus::bus::bus& bus, uint32_t hostNum) :
kNodeName(std::string{"host"} + std::to_string(hostNum)),
@@ -75,13 +83,11 @@
__FUNCTION__);
}
- powerMatcher = std::make_unique<sdbusplus::bus::match::match>(
+ hostStateWatcher = std::make_unique<sdbusplus::bus::match::match>(
bus,
sdbusplus::bus::match::rules::propertiesChanged(kHostPath.data(),
kHostIface.data()),
[this](sdbusplus::message::message& message) {
- constexpr std::string_view kS0 = "Off";
- constexpr std::string_view kS5 = "To_Off";
std::string objectName;
boost::container::flat_map<
@@ -97,18 +103,9 @@
std::get<std::string>(findState->second);
fmt::print(
stderr,
- "[powerMatcher] CurrentHostState has changed from {} to {}\n",
+ "[hostStateWatcher] CurrentHostState has changed from {} to {}\n",
preHostState, curHostState);
- if (preHostState == kHostStateOff &&
- curHostState == kHostStateRunning)
- {
- bootManager->setCheckpoint(kS0.data(), 0, 0);
- }
- else if (preHostState == kHostStateRunning &&
- curHostState == kHostStateOff)
- {
- bootManager->setCheckpoint(kS5.data(), 0, 0);
- }
+ bootManager->setCheckpoint(translateHostStateName(curHostState), 0, 0);
preHostState = curHostState;
}
});
@@ -134,13 +131,11 @@
__FUNCTION__);
}
- osStatusMatcher = std::make_unique<sdbusplus::bus::match::match>(
+ osStatusWatcher = std::make_unique<sdbusplus::bus::match::match>(
bus,
sdbusplus::bus::match::rules::propertiesChanged(kOSStatusPath.data(),
kOSStatusIface.data()),
[this](sdbusplus::message::message& message) {
- constexpr std::string_view kStandby2Inactive = "CPU_reset";
- constexpr std::string_view kInactive2Standby = "Firmware";
std::string objectName;
boost::container::flat_map<
@@ -157,18 +152,9 @@
fmt::print(
stderr,
- "[osStatusMatcher] curOSStatus has changed from {} to {}\n",
+ "[osStatusWatcher] curOSStatus has changed from {} to {}\n",
preOSStatus, curOSStatus);
- if (preOSStatus == kOSStatusInactivate &&
- curOSStatus == kOSStatusStandby)
- {
- bootManager->setCheckpoint(kInactive2Standby.data(), 0, 0);
- }
- else if (preOSStatus == kOSStatusStandby &&
- curOSStatus == kOSStatusInactivate)
- {
- bootManager->setCheckpoint(kStandby2Inactive.data(), 0, 0);
- }
+ bootManager->setCheckpoint(translateOSStatus(curOSStatus), 0, 0);
preOSStatus = curOSStatus;
}
});
diff --git a/src/utils.cpp b/src/utils.cpp
index 42783d8..2509ae3 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -46,7 +46,7 @@
inline bool Util::isValidName(std::string_view name)
{
- return !std::regex_search(name.data(), std::regex("[^0-9a-zA-Z_]"));
+ return !std::regex_search(name.data(), std::regex("[^0-9a-zA-Z_:]"));
}
inline std::string Util::getCPPath(std::string_view nodeName,
@@ -161,7 +161,7 @@
std::array<char, kBufSize> buf;
std::cmatch match;
- const std::regex reg("^([0-9a-zA-Z_]*),([0-9]+),([0-9]+)$");
+ const std::regex reg("^([0-9a-zA-Z_:]*),([0-9]+),([0-9]+)$");
while (ifs.getline(buf.data(), kBufSize))
{
if (regex_match(buf.data(), match, reg))
@@ -199,7 +199,7 @@
std::array<char, kBufSize> buf;
std::cmatch match;
- const std::regex reg("^([0-9a-zA-Z_]*),([0-9]+)$");
+ const std::regex reg("^([0-9a-zA-Z_:]*),([0-9]+)$");
while (ifs.getline(buf.data(), kBufSize))
{
if (regex_match(buf.data(), match, reg))
diff --git a/test/boot_manager_test.cpp b/test/boot_manager_test.cpp
index 262f0a5..30fe1a6 100644
--- a/test/boot_manager_test.cpp
+++ b/test/boot_manager_test.cpp
@@ -94,8 +94,8 @@
{
EXPECT_CALL(
*cpFilePtr,
- addCheckpoint(std::string{BootManager::kTransitionStagePrefix} +
- std::get<0>(inCP[i]).data(),
+ addCheckpoint(std::get<0>(inCP[i]).data() +
+ std::string{BootManager::kBeginStageSuffix},
_, _));
}
EXPECT_CALL(*cpFilePtr, addCheckpoint(std::get<0>(inCP[i]), _, _));
@@ -120,8 +120,8 @@
if (i != 0 && duration != 0)
{
EXPECT_EQ(cps[count].name,
- std::string{BootManager::kTransitionStagePrefix} +
- name.data());
+ name.data() +
+ std::string{BootManager::kBeginStageSuffix});
EXPECT_EQ(cps[count].wallTime, 1000 * (i + 1) - duration);
EXPECT_EQ(cps[count].monoTime, 10000 + 1000 * i - duration);
count++;