metrics-ipmi-blobs: Support ECC Error Counts
Export the ECC Error Cournter from
http://github.com/openbmc/phosphor-ecc to ipmi blob.
Tested:
The blob output is updated if MemoryECC dbus object exists compared to
the blob output if MemoryECC doesn't exists.
Change-Id: I2c63dbcd0970afc587f5c2ee01f8c261909f0b08
Signed-off-by: Willy Tu <wltu@google.com>
diff --git a/subprojects/metrics-ipmi-blobs/metric.cpp b/subprojects/metrics-ipmi-blobs/metric.cpp
index 4b21347..59954c4 100644
--- a/subprojects/metrics-ipmi-blobs/metric.cpp
+++ b/subprojects/metrics-ipmi-blobs/metric.cpp
@@ -314,6 +314,20 @@
};
}
+static bmcmetrics_metricproto_BmcECCMetric getECCMetric(bool& use) noexcept
+{
+ EccCounts eccCounts;
+ use = getECCErrorCounts(eccCounts);
+ if (!use)
+ {
+ return {};
+ }
+ return bmcmetrics_metricproto_BmcECCMetric{
+ .correctable_error_count = eccCounts.correctableErrCount,
+ .uncorrectable_error_count = eccCounts.uncorrectableErrCount,
+ };
+}
+
static bmcmetrics_metricproto_BmcMemoryMetric getMemMetric() noexcept
{
bmcmetrics_metricproto_BmcMemoryMetric ret = {};
@@ -460,6 +474,8 @@
.has_fdstat_metric = false,
.fdstat_metric = getFdStatMetric(*this, ticksPerSec, fds,
snapshot.has_fdstat_metric),
+ .has_ecc_metric = false,
+ .ecc_metric = getECCMetric(snapshot.has_ecc_metric),
};
pb_ostream_t nost = {};
if (!pb_encode(&nost, bmcmetrics_metricproto_BmcMetricSnapshot_fields,
diff --git a/subprojects/metrics-ipmi-blobs/metricblob.proto b/subprojects/metrics-ipmi-blobs/metricblob.proto
index 9842692..4d3038f 100644
--- a/subprojects/metrics-ipmi-blobs/metricblob.proto
+++ b/subprojects/metrics-ipmi-blobs/metricblob.proto
@@ -61,6 +61,11 @@
repeated StringEntry entries = 10;
}
+message BmcECCMetric {
+ int32 correctable_error_count = 1;
+ int32 uncorrectable_error_count = 2;
+}
+
message BmcMetricSnapshot {
BmcStringTable string_table = 1;
BmcMemoryMetric memory_metric = 2;
@@ -68,4 +73,7 @@
BmcDiskSpaceMetric storage_space_metric = 4;
BmcProcStatMetric procstat_metric = 5;
BmcFdStatMetric fdstat_metric = 6;
+ reserved 7;
+ reserved 8;
+ BmcECCMetric ecc_metric = 9;
}
diff --git a/subprojects/metrics-ipmi-blobs/util.cpp b/subprojects/metrics-ipmi-blobs/util.cpp
index 5bfc9c8..0e14698 100644
--- a/subprojects/metrics-ipmi-blobs/util.cpp
+++ b/subprojects/metrics-ipmi-blobs/util.cpp
@@ -348,4 +348,52 @@
return true;
}
+bool getECCErrorCounts(EccCounts& eccCounts)
+{
+ std::vector<
+ std::pair<std::string, std::variant<uint64_t, uint8_t, std::string>>>
+ values;
+ try
+ {
+ auto bus = sdbusplus::bus::new_default_system();
+ auto m =
+ bus.new_method_call("xyz.openbmc_project.memory.ECC",
+ "/xyz/openbmc_project/metrics/memory/BmcECC",
+ "org.freedesktop.DBus.Properties", "GetAll");
+ m.append("xyz.openbmc_project.Memory.MemoryECC");
+ auto reply = bus.call(m);
+ reply.read(values);
+ }
+ catch (const sdbusplus::exception::SdBusError& ex)
+ {
+ return false;
+ }
+ bool hasCorrectable = false;
+ bool hasUncorrectable = false;
+ for (const auto& [key, value] : values)
+ {
+ if (key == "ceCount")
+ {
+ eccCounts.correctableErrCount =
+ static_cast<int32_t>(std::get<uint64_t>(value));
+ hasCorrectable = true;
+ if (hasUncorrectable)
+ {
+ return true;
+ }
+ }
+ if (key == "ueCount")
+ {
+ eccCounts.uncorrectableErrCount =
+ static_cast<int32_t>(std::get<uint64_t>(value));
+ hasUncorrectable = true;
+ if (hasCorrectable)
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
} // namespace metric_blob
diff --git a/subprojects/metrics-ipmi-blobs/util.hpp b/subprojects/metrics-ipmi-blobs/util.hpp
index 642e0f2..f3ad222 100644
--- a/subprojects/metrics-ipmi-blobs/util.hpp
+++ b/subprojects/metrics-ipmi-blobs/util.hpp
@@ -55,4 +55,12 @@
char controlCharsToSpace(char c);
std::string trimStringRight(std::string_view s);
+struct EccCounts
+{
+ int32_t correctableErrCount;
+ int32_t uncorrectableErrCount;
+};
+
+bool getECCErrorCounts(EccCounts& eccCounts);
+
} // namespace metric_blob