FruDevice: improve boot
i2c-devices changing is not very common after boot,
since we are scanning everything during boot, we end
up rescanning everything multiple times. Just rescan
the newly added busses instead.
Tested: ipmitool sensor list and ipmitool fru list
looked normal
Change-Id: I52d6647ac3bcee6b192539d512d21edc315e85f7
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/src/FruDevice.cpp b/src/FruDevice.cpp
index 22ad48b..d593c30 100644
--- a/src/FruDevice.cpp
+++ b/src/FruDevice.cpp
@@ -259,6 +259,16 @@
return read(fd, buf, len);
}
+static int busStrToInt(const std::string& busName)
+{
+ auto findBus = busName.rfind("-");
+ if (findBus == std::string::npos)
+ {
+ return -1;
+ }
+ return std::stoi(busName.substr(findBus + 1));
+}
+
static int getRootBus(size_t bus)
{
auto ec = std::error_code();
@@ -691,15 +701,13 @@
{
for (auto& i2cBus : i2cBuses)
{
- auto busnum = i2cBus.string();
- auto lastDash = busnum.rfind(std::string("-"));
- // delete everything before dash inclusive
- if (lastDash != std::string::npos)
- {
- busnum.erase(0, lastDash + 1);
- }
+ int bus = busStrToInt(i2cBus);
- auto bus = std::stoi(busnum);
+ if (bus < 0)
+ {
+ std::cerr << "Cannot translate " << i2cBus << " to int\n";
+ continue;
+ }
if (busBlacklist.find(bus) != busBlacklist.end())
{
continue; // skip previously failed busses
@@ -1304,19 +1312,9 @@
BusMap& busmap, uint8_t busNum,
boost::container::flat_map<
std::pair<size_t, size_t>,
- std::shared_ptr<sdbusplus::asio::dbus_interface>>& dbusInterfaceMap)
+ std::shared_ptr<sdbusplus::asio::dbus_interface>>& dbusInterfaceMap,
+ bool dbusCall)
{
- fs::path busPath = fs::path("/dev/i2c-" + std::to_string(busNum));
- if (!fs::exists(busPath))
- {
- std::cerr << "Unable to access i2c bus " << static_cast<int>(busNum)
- << "\n";
- throw std::invalid_argument("Invalid Bus.");
- }
-
- std::vector<fs::path> i2cBuses;
- i2cBuses.emplace_back(busPath);
-
for (auto& [pair, interface] : foundDevices)
{
if (pair.first == static_cast<size_t>(busNum))
@@ -1326,6 +1324,21 @@
}
}
+ fs::path busPath = fs::path("/dev/i2c-" + std::to_string(busNum));
+ if (!fs::exists(busPath))
+ {
+ if (dbusCall)
+ {
+ std::cerr << "Unable to access i2c bus " << static_cast<int>(busNum)
+ << "\n";
+ throw std::invalid_argument("Invalid Bus.");
+ }
+ return;
+ }
+
+ std::vector<fs::path> i2cBuses;
+ i2cBuses.emplace_back(busPath);
+
auto scan = std::make_shared<FindDevicesWithCallback>(
i2cBuses, busmap, [busNum, &busmap, &dbusInterfaceMap]() {
for (auto& busIface : dbusInterfaceMap)
@@ -1441,7 +1454,7 @@
[&]() { rescanBusses(busMap, dbusInterfaceMap); });
iface->register_method("ReScanBus", [&](uint8_t bus) {
- rescanOneBus(busMap, bus, dbusInterfaceMap);
+ rescanOneBus(busMap, bus, dbusInterfaceMap, true);
});
iface->register_method("GetRawFru", getFruInfo);
@@ -1503,7 +1516,6 @@
return;
}
pendingBuffer += std::string(readBuffer.data(), bytes_transferred);
- bool devChange = false;
while (pendingBuffer.size() > sizeof(inotify_event))
{
const inotify_event* iEvent =
@@ -1514,19 +1526,23 @@
case IN_CREATE:
case IN_MOVED_TO:
case IN_DELETE:
- if (boost::starts_with(std::string(iEvent->name),
- "i2c"))
+ std::string name(iEvent->name);
+ if (boost::starts_with(name, "i2c"))
{
- devChange = true;
+ int bus = busStrToInt(name);
+ if (bus < 0)
+ {
+ std::cerr << "Could not parse bus " << name
+ << "\n";
+ continue;
+ }
+ rescanOneBus(busMap, static_cast<uint8_t>(bus),
+ dbusInterfaceMap, false);
}
}
pendingBuffer.erase(0, sizeof(inotify_event) + iEvent->len);
}
- if (devChange)
- {
- rescanBusses(busMap, dbusInterfaceMap);
- }
dirWatch.async_read_some(boost::asio::buffer(readBuffer),
watchI2cBusses);