adcsensor: Add CPU presence checking
This adds a match to catch cpu presence coming from
cpusensor.
Tested: ipmitool sensor list no longer showed ADCs that
monitored unavailable CPU
Change-Id: I39c067e5da3565c5b229cc19ed4ccf7767c1e85c
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/service_files/xyz.openbmc_project.adcsensor.service b/service_files/xyz.openbmc_project.adcsensor.service
index 666ff16..536b318 100644
--- a/service_files/xyz.openbmc_project.adcsensor.service
+++ b/service_files/xyz.openbmc_project.adcsensor.service
@@ -1,6 +1,7 @@
[Unit]
Description=Adc Sensor
StopWhenUnneeded=false
+Before=xyz.openbmc_project.cpusensor.service
[Service]
Restart=always
diff --git a/src/ADCSensorMain.cpp b/src/ADCSensorMain.cpp
index 8cfba87..7cb31d0 100644
--- a/src/ADCSensorMain.cpp
+++ b/src/ADCSensorMain.cpp
@@ -17,6 +17,7 @@
#include <ADCSensor.hpp>
#include <Utils.hpp>
#include <VariantVisitors.hpp>
+#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/container/flat_set.hpp>
@@ -35,6 +36,8 @@
"xyz.openbmc_project.Configuration.ADC"};
static std::regex inputRegex(R"(in(\d+)_input)");
+static boost::container::flat_map<size_t, bool> cpuPresence;
+
// filter out adc from any other voltage sensor
bool isAdc(const fs::path& parentPath)
{
@@ -212,6 +215,21 @@
setReadState(powerState, readState);
}
+ auto findCPU = baseConfiguration->second.find("CPURequired");
+ if (findCPU != baseConfiguration->second.end())
+ {
+ size_t index = std::visit(VariantToIntVisitor(), findCPU->second);
+ auto presenceFind = cpuPresence.find(index);
+ if (presenceFind == cpuPresence.end())
+ {
+ continue; // no such cpu
+ }
+ if (!presenceFind->second)
+ {
+ continue; // cpu not installed
+ }
+ }
+
auto findBridgeGpio = baseConfiguration->second.find("BridgeGpio");
std::optional<int> gpioNum;
@@ -221,8 +239,9 @@
std::visit(VariantToIntVisitor(), findBridgeGpio->second);
gpioNum = static_cast<std::optional<int>>(gpioPin);
}
-
- sensors[sensorName] = std::make_unique<ADCSensor>(
+ auto& sensor = sensors[sensorName];
+ sensor = nullptr;
+ sensor = std::make_unique<ADCSensor>(
path.string(), objectServer, dbusConnection, io, sensorName,
std::move(sensorThresholds), scaleFactor, readState, *interfacePath,
gpioNum);
@@ -272,6 +291,53 @@
});
};
+ std::function<void(sdbusplus::message::message&)> cpuPresenceHandler =
+ [&](sdbusplus::message::message& message) {
+ std::string path = message.get_path();
+ boost::to_lower(path);
+
+ if (path.rfind("cpu") == std::string::npos)
+ {
+ return; // not interested
+ }
+ size_t index = 0;
+ try
+ {
+ index = std::stoi(path.substr(path.size() - 1));
+ }
+ catch (std::invalid_argument&)
+ {
+ std::cerr << "Found invalid path " << path << "\n";
+ return;
+ }
+
+ std::string objectName;
+ boost::container::flat_map<std::string, std::variant<bool>> values;
+ message.read(objectName, values);
+ auto findPresence = values.find("Present");
+ if (findPresence != values.end())
+ {
+ cpuPresence[index] = std::get<bool>(findPresence->second);
+ }
+
+ // this implicitly cancels the timer
+ filterTimer.expires_from_now(boost::posix_time::seconds(1));
+
+ filterTimer.async_wait([&](const boost::system::error_code& ec) {
+ if (ec == boost::asio::error::operation_aborted)
+ {
+ /* we were canceled*/
+ return;
+ }
+ else if (ec)
+ {
+ std::cerr << "timer error\n";
+ return;
+ }
+ createSensors(io, objectServer, sensors, systemBus, {});
+ });
+ };
+
for (const char* type : sensorTypes)
{
auto match = std::make_unique<sdbusplus::bus::match::match>(
@@ -281,6 +347,12 @@
eventHandler);
matches.emplace_back(std::move(match));
}
+ matches.emplace_back(std::make_unique<sdbusplus::bus::match::match>(
+ static_cast<sdbusplus::bus::bus&>(*systemBus),
+ "type='signal',member='PropertiesChanged',path_namespace='" +
+ std::string(cpuInventoryPath) +
+ "',arg0namespace='xyz.openbmc_project.Inventory.Item'",
+ cpuPresenceHandler));
io.run();
}