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(); }