metric-collector: Update reboot time if LastRebootTime changed
After
https://gerrit.openbmc.org/c/openbmc/phosphor-state-manager/+/66936 is
in, the LastRebootTime can change once the timsync happens. This is
needed becuase it is possible tha the lastRebootTime at bootup is less
than the saved value from the previous reboot in a reboot loop. This
allows us to update the count after timesync to make sure that we have
the proper lastRebootTime.
Example failures:
After the system rebooted, the reboot count wasn't updated. Restart the
metric-collector and found that the current reboot time doesn't match
the one that was saved...
```
$ /tmp/metric-collector
current reboot time: 1704819274000 vs. saved reboot time: 1704819146000
```
Suggesting that the reboot time fetched pre-timesync was less than the
saved reboot time. With the signal matcher, the new reboot time will
be used and update the count properly.
Tested:
```
root@dddev2-nfd01:~# busctl get-property xyz.openbmc_project.State.BMC /xyz/openbmc_project/state/bmc0 xyz.openbmc_project.State.BMC LastRebootTime
t 1704859755000
root@dddev2-nfd01:~# cat /var/google/bootinfo
11 0 1704859755000
root@dddev2-nfd01:~# systemctl status phosphor-metric-collector.service
● phosphor-metric-collector.service - BMC Metric Collection
Loaded: loaded (/usr/lib/systemd/system/phosphor-metric-collector.service; enabled; preset: enabled)
Active: active (running) since Tue 2024-01-09 20:17:06 PST; 3min 38s ago
Main PID: 4256 (metric-collecto)
CPU: 3.340s
CGroup: /system.slice/phosphor-metric-collector.service
└─4256 /usr/bin/metric-collector
Jan 09 20:17:06 dddev2-nfd01.prod.google.com systemd[1]: Started BMC Metric Collection.
root@dddev2-nfd01:~# systemctl status xyz.openbmc_project.State.BMC
● xyz.openbmc_project.State.BMC.service - Phosphor BMC State Manager
Loaded: loaded (/usr/lib/systemd/system/xyz.openbmc_project.State.BMC.service; enabled; preset: enabled)
Active: active (running) since Tue 2024-01-09 20:07:39 PST; 13min ago
Main PID: 437 (phosphor-bmc-st)
CPU: 300ms
CGroup: /system.slice/xyz.openbmc_project.State.BMC.service
└─437 /usr/bin/phosphor-bmc-state-manager
```
Google-Bug-Id: 313338463
Change-Id: Idd13f28dc238c6803281d3195e2dd63bf680a94e
Signed-off-by: Willy Tu <wltu@google.com>
(cherry picked from commit ce4946a231a417b92a30f34f407f3d482fa594d1)
diff --git a/recipes-google/metric-collector/metric-collector/0002-Metric-Collection-Daemon.patch b/recipes-google/metric-collector/metric-collector/0002-Metric-Collection-Daemon.patch
index d7b782c..4cca4f1 100644
--- a/recipes-google/metric-collector/metric-collector/0002-Metric-Collection-Daemon.patch
+++ b/recipes-google/metric-collector/metric-collector/0002-Metric-Collection-Daemon.patch
@@ -1,4 +1,4 @@
-From 72cbfbea9d2f9fafec035d1bd5c89a0eb22cb7a3 Mon Sep 17 00:00:00 2001
+From e561a16af403c525e44dcff7e0a06ce8ecb3410a Mon Sep 17 00:00:00 2001
From: Edward Lee <edwarddl@google.com>
Date: Wed, 18 Jan 2023 21:37:49 +0000
Subject: [PATCH] Metric-Collection-Daemon
@@ -76,21 +76,22 @@
Signed-off-by: Edward Lee <edwarddl@google.com>
Signed-off-by: Willy Tu <wltu@google.com>
Change-Id: I88ec028efcd9373f72589a321bc8246c3664d40f
+Signed-off-by: Willy Tu <wltu@google.com>
---
.gitignore | 1 +
meson.build | 1 +
metric-collection-daemon | 1 +
- .../metric-collection-daemon/daemon.cpp | 221 ++++++++++
+ .../metric-collection-daemon/daemon.cpp | 221 +++++++++
.../metric-collection-daemon/daemon.hpp | 55 +++
.../metric-collection-daemon/meson.build | 44 ++
- .../metricCollector.cpp | 398 ++++++++++++++++++
- .../metricCollector.hpp | 79 ++++
+ .../metricCollector.cpp | 430 ++++++++++++++++++
+ .../metricCollector.hpp | 81 ++++
.../phosphor-metric-collector.service.in | 11 +
- subprojects/metric-collection-daemon/port.cpp | 197 +++++++++
+ subprojects/metric-collection-daemon/port.cpp | 197 ++++++++
subprojects/metric-collection-daemon/port.hpp | 64 +++
.../metric-collection-daemon/utils.cpp | 186 ++++++++
.../metric-collection-daemon/utils.hpp | 36 ++
- 13 files changed, 1294 insertions(+)
+ 13 files changed, 1328 insertions(+)
create mode 120000 metric-collection-daemon
create mode 100644 subprojects/metric-collection-daemon/daemon.cpp
create mode 100644 subprojects/metric-collection-daemon/daemon.hpp
@@ -475,10 +476,10 @@
+ install_dir: systemd.get_pkgconfig_variable('systemdsystemunitdir'))
diff --git a/subprojects/metric-collection-daemon/metricCollector.cpp b/subprojects/metric-collection-daemon/metricCollector.cpp
new file mode 100644
-index 0000000..80f4aee
+index 0000000..880a0d0
--- /dev/null
+++ b/subprojects/metric-collection-daemon/metricCollector.cpp
-@@ -0,0 +1,398 @@
+@@ -0,0 +1,430 @@
+#include "metricCollector.hpp"
+
+#include "utils.hpp"
@@ -506,6 +507,7 @@
+#include <tuple>
+#include <unordered_map>
+#include <unordered_set>
++#include <variant>
+#include <vector>
+
+// TODO: Make this configurable
@@ -519,7 +521,27 @@
+ std::shared_ptr<sdbusplus::asio::connection> conn,
+ sdbusplus::asio::object_server& objServer) :
+ ioc(ioc),
-+ conn(conn), objServer(objServer)
++ conn(conn), objServer(objServer),
++ rebootTimeSignal(std::make_unique<decltype(rebootTimeSignal)::element_type>(
++ *conn,
++ sdbusplus::bus::match::rules::propertiesChanged(
++ "/xyz/openbmc_project/state/bmc0", "xyz.openbmc_project.State.BMC"),
++ [this](sdbusplus::message_t& m) {
++ std::string interface;
++ std::unordered_map<std::string, std::variant<uint64_t>> propertyChanged;
++ m.read(interface, propertyChanged);
++
++ for (const auto& [key, value] : propertyChanged)
++ {
++ if (key == "LastRebootTime" && std::holds_alternative<uint64_t>(value))
++ {
++ stdplus::println(stderr, "LastRebootTime updated post timesync");
++ updateBootCount();
++ rebootTimeSignal.reset();
++ break;
++ }
++ }
++}))
+{
+ registerAssociations();
+ updateBootCount();
@@ -774,10 +796,16 @@
+
+ if (updateRebootCount)
+ {
-+ ++bootinfo[0];
-+ if (updateCrashCount)
++ // If this is triggered by rebootTimeSignal and that we have already
++ // updated the reboot count, then only update the last reboot time
++ // to make sure that time is valid.
++ if (!updatedBootCount)
+ {
-+ ++bootinfo[1];
++ ++bootinfo[0];
++ if (updateCrashCount)
++ {
++ ++bootinfo[1];
++ }
+ }
+
+ std::ofstream bootinfoFile("/var/google/bootinfo");
@@ -788,7 +816,12 @@
+
+ bootCount = bootinfo[0];
+ crashCount = bootinfo[1];
++ if (updatedBootCount)
++ {
++ return;
++ }
+
++ updatedBootCount = true;
+ metrics->set_property("BootCount", bootCount);
+ metrics->set_property("CrashCount", crashCount);
+ },
@@ -879,10 +912,10 @@
+}
diff --git a/subprojects/metric-collection-daemon/metricCollector.hpp b/subprojects/metric-collection-daemon/metricCollector.hpp
new file mode 100644
-index 0000000..a3da156
+index 0000000..0423fa8
--- /dev/null
+++ b/subprojects/metric-collection-daemon/metricCollector.hpp
-@@ -0,0 +1,79 @@
+@@ -0,0 +1,81 @@
+#include "daemon.hpp"
+#include "port.hpp"
+#include "utils.hpp"
@@ -959,6 +992,8 @@
+ std::shared_ptr<sdbusplus::asio::dbus_interface> association_interface;
+ std::shared_ptr<std::vector<Association>> associations;
+ uint32_t associationCounter = 0;
++ std::unique_ptr<sdbusplus::bus::match_t> rebootTimeSignal;
++ bool updatedBootCount;
+};
+
+} // namespace
@@ -1486,6 +1521,6 @@
+std::array<uint64_t, 3> parseBootInfo();
+
+std::optional<std::string> getPortIdByNum(const int portNum);
---
+--
2.43.0.472.g3155946c3a-goog