Find P10 OCCs by looking in /dev
Find the exact OCCs present in the system by looking for the OCC devices
in /dev. They look like /dev/occ1, /dev/occ2, etc. The /dev/occ1 entry
will translate to Status object /org/open_power/control/occ0.
In order to handle the case where the application starts before all
devices show up, keep checking until at least 10 seconds have gone by
without a new device showing up (with at least one device present).
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
Change-Id: I42289d55a6266d710b313af0a49070eeacccd725
diff --git a/occ_manager.cpp b/occ_manager.cpp
index 69f01ea..04276b9 100644
--- a/occ_manager.cpp
+++ b/occ_manager.cpp
@@ -6,6 +6,7 @@
#include "occ_dbus.hpp"
#include "utils.hpp"
+#include <chrono>
#include <cmath>
#include <experimental/filesystem>
#include <phosphor-logging/elog-errors.hpp>
@@ -50,12 +51,62 @@
void Manager::findAndCreateObjects()
{
+#ifndef POWER10
for (auto id = 0; id < MAX_CPUS; ++id)
{
// Create one occ per cpu
auto occ = std::string(OCC_NAME) + std::to_string(id);
createObjects(occ);
}
+#else
+ // Create the OCCs based on on the /dev/occX devices
+ auto occs = findOCCsInDev();
+
+ if (occs.empty() || (prevOCCSearch.size() != occs.size()))
+ {
+ // Something changed or no OCCs yet, try again in 10s.
+ // Note on the first pass prevOCCSearch will be empty,
+ // so there will be at least one delay to give things
+ // a chance to settle.
+ prevOCCSearch = occs;
+
+ using namespace std::literals::chrono_literals;
+ discoverTimer->restartOnce(10s);
+ }
+ else
+ {
+ discoverTimer.reset();
+
+ // createObjects requires OCC0 first.
+ std::sort(occs.begin(), occs.end());
+
+ for (auto id : occs)
+ {
+ createObjects(std::string(OCC_NAME) + std::to_string(id));
+ }
+ }
+#endif
+}
+
+std::vector<int> Manager::findOCCsInDev()
+{
+ std::vector<int> occs;
+ std::regex expr{R"(occ(\d+)$)"};
+
+ for (auto& file : fs::directory_iterator("/dev"))
+ {
+ std::smatch match;
+ std::string path{file.path().string()};
+ if (std::regex_search(path, match, expr))
+ {
+ auto num = std::stoi(match[1].str());
+
+ // /dev numbering starts at 1, ours starts at 0.
+ occs.push_back(num - 1);
+ }
+ }
+
+ return occs;
}
int Manager::cpuCreated(sdbusplus::message::message& msg)