entity-manager: remove global io_context
Remove the global var
```
boost::asio::io_context io
```
and move it to be a local var in the main function.
Since boost::asio::io_context io is declared first, it in scope for the
entire program duration and should not cause any issues from that
perspective.
The io_context is passed through where needed. In case there is a class
already defined, the class now has a reference to the io_context to
avoid passing it through everywhere.
Tested: Capturing or passing a reference which is always valid should
not introduce any issues.
Tested on Tyan S8030:
```
Jul 01 09:59:26 s8030-bmc-30303035c0c1 entity-manager[4204]: Inventory Added: Supermicro PWS 920P SQ 0
Jul 01 09:59:26 s8030-bmc-30303035c0c1 entity-manager[4204]: Inventory Added: Supermicro PWS 920P SQ 1
Jul 01 09:59:26 s8030-bmc-30303035c0c1 entity-manager[4204]: Inventory Added: chassis
Jul 01 09:59:26 s8030-bmc-30303035c0c1 entity-manager[4204]: Inventory Added: MBX 1.57 Chassis
```
busctl tree output as before
Change-Id: Ie8f7d18c38d166c57a9cb645ab45c9103bbdff6e
Signed-off-by: Alexander Hansen <alexander.hansen@9elements.com>
diff --git a/src/entity_manager/dbus_interface.cpp b/src/entity_manager/dbus_interface.cpp
index 45c90fa..ff8094e 100644
--- a/src/entity_manager/dbus_interface.cpp
+++ b/src/entity_manager/dbus_interface.cpp
@@ -72,12 +72,12 @@
const std::string& jsonPointerPath,
const std::shared_ptr<sdbusplus::asio::dbus_interface>& iface,
sdbusplus::asio::object_server& objServer,
- nlohmann::json& systemConfiguration)
+ nlohmann::json& systemConfiguration, boost::asio::io_context& io)
{
std::weak_ptr<sdbusplus::asio::dbus_interface> interface = iface;
iface->register_method(
"Delete", [&objServer, &systemConfiguration, interface,
- jsonPointerPath{std::string(jsonPointerPath)}]() {
+ jsonPointerPath{std::string(jsonPointerPath)}, &io]() {
std::shared_ptr<sdbusplus::asio::dbus_interface> dbusInterface =
interface.lock();
if (!dbusInterface)
@@ -203,7 +203,8 @@
// adds simple json types to interface's properties
void populateInterfaceFromJson(
- nlohmann::json& systemConfiguration, const std::string& jsonPointerPath,
+ boost::asio::io_context& io, nlohmann::json& systemConfiguration,
+ const std::string& jsonPointerPath,
std::shared_ptr<sdbusplus::asio::dbus_interface>& iface,
nlohmann::json& dict, sdbusplus::asio::object_server& objServer,
sdbusplus::asio::PropertyPermission permission)
@@ -238,14 +239,14 @@
if (permission == sdbusplus::asio::PropertyPermission::readWrite)
{
createDeleteObjectMethod(jsonPointerPath, iface, objServer,
- systemConfiguration);
+ systemConfiguration, io);
}
tryIfaceInitialize(iface);
}
void createAddObjectMethod(
- const std::string& jsonPointerPath, const std::string& path,
- nlohmann::json& systemConfiguration,
+ boost::asio::io_context& io, const std::string& jsonPointerPath,
+ const std::string& path, nlohmann::json& systemConfiguration,
sdbusplus::asio::object_server& objServer, const std::string& board)
{
std::shared_ptr<sdbusplus::asio::dbus_interface> iface = createInterface(
@@ -255,8 +256,9 @@
"AddObject",
[&systemConfiguration, &objServer,
jsonPointerPath{std::string(jsonPointerPath)}, path{std::string(path)},
- board](const boost::container::flat_map<std::string, JsonVariantType>&
- data) {
+ board,
+ &io](const boost::container::flat_map<std::string, JsonVariantType>&
+ data) {
nlohmann::json::json_pointer ptr(jsonPointerPath);
nlohmann::json& base = systemConfiguration[ptr];
auto findExposes = base.find("Exposes");
@@ -363,7 +365,7 @@
// permission is read-write, as since we just created it, must be
// runtime modifiable
populateInterfaceFromJson(
- systemConfiguration,
+ io, systemConfiguration,
jsonPointerPath + "/Exposes/" + std::to_string(lastIndex),
interface, newData, objServer,
sdbusplus::asio::PropertyPermission::readWrite);
diff --git a/src/entity_manager/dbus_interface.hpp b/src/entity_manager/dbus_interface.hpp
index 60527e3..84cfbba 100644
--- a/src/entity_manager/dbus_interface.hpp
+++ b/src/entity_manager/dbus_interface.hpp
@@ -123,18 +123,19 @@
const std::string& jsonPointerPath,
const std::shared_ptr<sdbusplus::asio::dbus_interface>& iface,
sdbusplus::asio::object_server& objServer,
- nlohmann::json& systemConfiguration);
+ nlohmann::json& systemConfiguration, boost::asio::io_context& io);
void populateInterfaceFromJson(
- nlohmann::json& systemConfiguration, const std::string& jsonPointerPath,
+ boost::asio::io_context& io, nlohmann::json& systemConfiguration,
+ const std::string& jsonPointerPath,
std::shared_ptr<sdbusplus::asio::dbus_interface>& iface,
nlohmann::json& dict, sdbusplus::asio::object_server& objServer,
sdbusplus::asio::PropertyPermission permission =
sdbusplus::asio::PropertyPermission::readOnly);
void createAddObjectMethod(
- const std::string& jsonPointerPath, const std::string& path,
- nlohmann::json& systemConfiguration,
+ boost::asio::io_context& io, const std::string& jsonPointerPath,
+ const std::string& path, nlohmann::json& systemConfiguration,
sdbusplus::asio::object_server& objServer, const std::string& board);
std::vector<std::weak_ptr<sdbusplus::asio::dbus_interface>>&
diff --git a/src/entity_manager/entity_manager.cpp b/src/entity_manager/entity_manager.cpp
index 6a003f5..5a6955d 100644
--- a/src/entity_manager/entity_manager.cpp
+++ b/src/entity_manager/entity_manager.cpp
@@ -53,10 +53,6 @@
static constexpr std::array<const char*, 6> settableInterfaces = {
"FanProfile", "Pid", "Pid.Zone", "Stepwise", "Thresholds", "Polling"};
-// NOLINTBEGIN(cppcoreguidelines-avoid-non-const-global-variables)
-boost::asio::io_context io;
-// NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)
-
const std::regex illegalDbusPathRegex("[^A-Za-z0-9_.]");
const std::regex illegalDbusMemberRegex("[^A-Za-z0-9_]");
@@ -69,11 +65,12 @@
}
EntityManager::EntityManager(
- std::shared_ptr<sdbusplus::asio::connection>& systemBus) :
+ std::shared_ptr<sdbusplus::asio::connection>& systemBus,
+ boost::asio::io_context& io) :
systemBus(systemBus),
objServer(sdbusplus::asio::object_server(systemBus, /*skipManager=*/true)),
lastJson(nlohmann::json::object()),
- systemConfiguration(nlohmann::json::object())
+ systemConfiguration(nlohmann::json::object()), io(io)
{
// All other objects that EntityManager currently support are under the
// inventory subtree.
@@ -138,11 +135,11 @@
boardNameOrig);
dbus_interface::createAddObjectMethod(
- jsonPointerPath, boardPath, systemConfiguration, objServer,
+ io, jsonPointerPath, boardPath, systemConfiguration, objServer,
boardNameOrig);
dbus_interface::populateInterfaceFromJson(
- systemConfiguration, jsonPointerPath, boardIface, boardValues,
+ io, systemConfiguration, jsonPointerPath, boardIface, boardValues,
objServer);
jsonPointerPath += "/";
// iterate through board properties
@@ -155,7 +152,7 @@
propName, boardNameOrig);
dbus_interface::populateInterfaceFromJson(
- systemConfiguration, jsonPointerPath + propName, iface,
+ io, systemConfiguration, jsonPointerPath + propName, iface,
propValue, objServer);
}
}
@@ -219,7 +216,7 @@
"xyz.openbmc_project.Inventory.Item.Bmc",
boardNameOrig);
dbus_interface::populateInterfaceFromJson(
- systemConfiguration, jsonPointerPath, bmcIface, item,
+ io, systemConfiguration, jsonPointerPath, bmcIface, item,
objServer, getPermission(itemType));
}
else if (itemType == "System")
@@ -230,7 +227,7 @@
"xyz.openbmc_project.Inventory.Item.System",
boardNameOrig);
dbus_interface::populateInterfaceFromJson(
- systemConfiguration, jsonPointerPath, systemIface, item,
+ io, systemConfiguration, jsonPointerPath, systemIface, item,
objServer, getPermission(itemType));
}
@@ -251,7 +248,7 @@
objServer, ifacePath, ifaceName, boardNameOrig);
dbus_interface::populateInterfaceFromJson(
- systemConfiguration, jsonPointerPath, objectIface,
+ io, systemConfiguration, jsonPointerPath, objectIface,
config, objServer, getPermission(name));
}
else if (config.type() == nlohmann::json::value_t::array)
@@ -295,7 +292,7 @@
objServer, ifacePath, ifaceName, boardNameOrig);
dbus_interface::populateInterfaceFromJson(
- systemConfiguration,
+ io, systemConfiguration,
jsonPointerPath + "/" + std::to_string(index),
objectIface, arrayItem, objServer,
getPermission(name));
@@ -311,7 +308,7 @@
boardNameOrig);
dbus_interface::populateInterfaceFromJson(
- systemConfiguration, jsonPointerPath, itemIface, item,
+ io, systemConfiguration, jsonPointerPath, itemIface, item,
objServer, getPermission(itemType));
topology.addBoard(boardPath, boardType, boardNameOrig, item);
@@ -452,7 +449,7 @@
// NOLINTNEXTLINE(performance-unnecessary-value-param)
const nlohmann::json newConfiguration)
{
- loadOverlays(newConfiguration);
+ loadOverlays(newConfiguration, io);
boost::asio::post(io, [this]() {
if (!configuration::writeJsonFiles(systemConfiguration))
@@ -514,7 +511,7 @@
}
auto perfScan = std::make_shared<scan::PerformScan>(
- *this, *missingConfigurations, configurations,
+ *this, *missingConfigurations, configurations, io,
[this, count, oldConfiguration, missingConfigurations]() {
// this is something that since ac has been applied to the bmc
// we saw, and we no longer see it
@@ -694,9 +691,10 @@
int main()
{
+ boost::asio::io_context io;
auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
systemBus->request_name("xyz.openbmc_project.EntityManager");
- EntityManager em(systemBus);
+ EntityManager em(systemBus, io);
nlohmann::json systemConfiguration = nlohmann::json::object();
diff --git a/src/entity_manager/entity_manager.hpp b/src/entity_manager/entity_manager.hpp
index 8490d1c..ba3914f 100644
--- a/src/entity_manager/entity_manager.hpp
+++ b/src/entity_manager/entity_manager.hpp
@@ -33,7 +33,8 @@
{
public:
explicit EntityManager(
- std::shared_ptr<sdbusplus::asio::connection>& systemBus);
+ std::shared_ptr<sdbusplus::asio::connection>& systemBus,
+ boost::asio::io_context& io);
std::shared_ptr<sdbusplus::asio::connection> systemBus;
sdbusplus::asio::object_server objServer;
@@ -41,6 +42,7 @@
nlohmann::json lastJson;
nlohmann::json systemConfiguration;
Topology topology;
+ boost::asio::io_context& io;
void propertiesChangedCallback();
void registerCallback(const std::string& path);
diff --git a/src/entity_manager/overlay.cpp b/src/entity_manager/overlay.cpp
index 7d7de96..958ced5 100644
--- a/src/entity_manager/overlay.cpp
+++ b/src/entity_manager/overlay.cpp
@@ -169,7 +169,8 @@
const std::string& parameters, uint64_t bus, uint64_t address,
const std::string& constructor, const std::string& destructor,
const devices::createsHWMon hasHWMonDir,
- std::vector<std::string> channelNames, const size_t retries = 5)
+ std::vector<std::string> channelNames, boost::asio::io_context& io,
+ const size_t retries = 5)
{
if (retries == 0U)
{
@@ -193,8 +194,8 @@
createTimer->async_wait(
[createTimer, name, busPath, parameters, bus, address,
constructor, destructor, hasHWMonDir,
- channelNames(std::move(channelNames)),
- retries](const boost::system::error_code& ec) mutable {
+ channelNames(std::move(channelNames)), retries,
+ &io](const boost::system::error_code& ec) mutable {
if (ec)
{
std::cerr << "Timer error: " << ec << "\n";
@@ -202,7 +203,8 @@
}
return buildDevice(name, busPath, parameters, bus, address,
constructor, destructor, hasHWMonDir,
- std::move(channelNames), retries - 1);
+ std::move(channelNames), io,
+ retries - 1);
});
return -1;
}
@@ -219,7 +221,8 @@
void exportDevice(const std::string& type,
const devices::ExportTemplate& exportTemplate,
- const nlohmann::json& configuration)
+ const nlohmann::json& configuration,
+ boost::asio::io_context& io)
{
std::string parameters = exportTemplate.parameters;
std::string busPath = exportTemplate.busPath;
@@ -273,10 +276,11 @@
}
buildDevice(name, busPath, parameters, *bus, *address, constructor,
- destructor, hasHWMonDir, std::move(channels));
+ destructor, hasHWMonDir, std::move(channels), io);
}
-bool loadOverlays(const nlohmann::json& systemConfiguration)
+bool loadOverlays(const nlohmann::json& systemConfiguration,
+ boost::asio::io_context& io)
{
std::filesystem::create_directory(outputDir);
for (auto entity = systemConfiguration.begin();
@@ -307,7 +311,7 @@
auto device = devices::exportTemplates.find(type.c_str());
if (device != devices::exportTemplates.end())
{
- exportDevice(type, device->second, configuration);
+ exportDevice(type, device->second, configuration, io);
continue;
}
diff --git a/src/entity_manager/overlay.hpp b/src/entity_manager/overlay.hpp
index 3bc6eb7..2742de7 100644
--- a/src/entity_manager/overlay.hpp
+++ b/src/entity_manager/overlay.hpp
@@ -16,7 +16,9 @@
/// \file overlay.hpp
#pragma once
+#include <boost/asio/io_context.hpp>
#include <nlohmann/json.hpp>
void unloadAllOverlays();
-bool loadOverlays(const nlohmann::json& systemConfiguration);
+bool loadOverlays(const nlohmann::json& systemConfiguration,
+ boost::asio::io_context& io);
diff --git a/src/entity_manager/perform_scan.cpp b/src/entity_manager/perform_scan.cpp
index 04d3c67..5e56f9c 100644
--- a/src/entity_manager/perform_scan.cpp
+++ b/src/entity_manager/perform_scan.cpp
@@ -44,7 +44,8 @@
void getInterfaces(
const DBusInterfaceInstance& instance,
const std::vector<std::shared_ptr<probe::PerformProbe>>& probeVector,
- const std::shared_ptr<scan::PerformScan>& scan, size_t retries = 5)
+ const std::shared_ptr<scan::PerformScan>& scan, boost::asio::io_context& io,
+ size_t retries = 5)
{
if (retries == 0U)
{
@@ -54,8 +55,8 @@
}
scan->_em.systemBus->async_method_call(
- [instance, scan, probeVector,
- retries](boost::system::error_code& errc, const DBusInterface& resp) {
+ [instance, scan, probeVector, retries,
+ &io](boost::system::error_code& errc, const DBusInterface& resp) {
if (errc)
{
std::cerr << "error calling getall on " << instance.busName
@@ -65,9 +66,9 @@
auto timer = std::make_shared<boost::asio::steady_timer>(io);
timer->expires_after(std::chrono::seconds(2));
- timer->async_wait([timer, instance, scan, probeVector,
- retries](const boost::system::error_code&) {
- getInterfaces(instance, probeVector, scan, retries - 1);
+ timer->async_wait([timer, instance, scan, probeVector, retries,
+ &io](const boost::system::error_code&) {
+ getInterfaces(instance, probeVector, scan, io, retries - 1);
});
return;
}
@@ -81,7 +82,7 @@
static void processDbusObjects(
std::vector<std::shared_ptr<probe::PerformProbe>>& probeVector,
const std::shared_ptr<scan::PerformScan>& scan,
- const GetSubTreeType& interfaceSubtree)
+ const GetSubTreeType& interfaceSubtree, boost::asio::io_context& io)
{
for (const auto& [path, object] : interfaceSubtree)
{
@@ -98,7 +99,8 @@
// with the GetAll call to save some cycles.
if (!boost::algorithm::starts_with(iface, "org.freedesktop"))
{
- getInterfaces({busname, path, iface}, probeVector, scan);
+ getInterfaces({busname, path, iface}, probeVector, scan,
+ io);
}
}
}
@@ -110,7 +112,8 @@
void findDbusObjects(
std::vector<std::shared_ptr<probe::PerformProbe>>&& probeVector,
boost::container::flat_set<std::string>&& interfaces,
- const std::shared_ptr<scan::PerformScan>& scan, size_t retries = 5)
+ const std::shared_ptr<scan::PerformScan>& scan, boost::asio::io_context& io,
+ size_t retries = 5)
{
// Filter out interfaces already obtained.
for (const auto& [path, probeInterfaces] : scan->dbusProbeObjects)
@@ -127,9 +130,9 @@
// find all connections in the mapper that expose a specific type
scan->_em.systemBus->async_method_call(
- [interfaces, probeVector{std::move(probeVector)}, scan,
- retries](boost::system::error_code& ec,
- const GetSubTreeType& interfaceSubtree) mutable {
+ [interfaces, probeVector{std::move(probeVector)}, scan, retries,
+ &io](boost::system::error_code& ec,
+ const GetSubTreeType& interfaceSubtree) mutable {
if (ec)
{
if (ec.value() == ENOENT)
@@ -150,16 +153,16 @@
timer->async_wait(
[timer, interfaces{std::move(interfaces)}, scan,
- probeVector{std::move(probeVector)},
- retries](const boost::system::error_code&) mutable {
+ probeVector{std::move(probeVector)}, retries,
+ &io](const boost::system::error_code&) mutable {
findDbusObjects(std::move(probeVector),
- std::move(interfaces), scan,
+ std::move(interfaces), scan, io,
retries - 1);
});
return;
}
- processDbusObjects(probeVector, scan, interfaceSubtree);
+ processDbusObjects(probeVector, scan, interfaceSubtree, io);
},
"xyz.openbmc_project.ObjectMapper",
"/xyz/openbmc_project/object_mapper",
@@ -191,12 +194,12 @@
return std::to_string(std::hash<std::string>{}(probeName + device.dump()));
}
-scan::PerformScan::PerformScan(EntityManager& em,
- nlohmann::json& missingConfigurations,
- std::list<nlohmann::json>& configurations,
- std::function<void()>&& callback) :
+scan::PerformScan::PerformScan(
+ EntityManager& em, nlohmann::json& missingConfigurations,
+ std::list<nlohmann::json>& configurations, boost::asio::io_context& io,
+ std::function<void()>&& callback) :
_em(em), _missingConfigurations(missingConfigurations),
- _configurations(configurations), _callback(std::move(callback))
+ _configurations(configurations), _callback(std::move(callback)), io(io)
{}
static void pruneRecordExposes(nlohmann::json& record)
@@ -608,7 +611,7 @@
// probe vector stores a shared_ptr to each PerformProbe that cares
// about a dbus interface
findDbusObjects(std::move(dbusProbePointers),
- std::move(dbusProbeInterfaces), shared_from_this());
+ std::move(dbusProbeInterfaces), shared_from_this(), io);
}
scan::PerformScan::~PerformScan()
@@ -616,7 +619,8 @@
if (_passed)
{
auto nextScan = std::make_shared<PerformScan>(
- _em, _missingConfigurations, _configurations, std::move(_callback));
+ _em, _missingConfigurations, _configurations, io,
+ std::move(_callback));
nextScan->passedProbes = std::move(passedProbes);
nextScan->dbusProbeObjects = std::move(dbusProbeObjects);
nextScan->run();
diff --git a/src/entity_manager/perform_scan.hpp b/src/entity_manager/perform_scan.hpp
index 54d0e67..17396d4 100644
--- a/src/entity_manager/perform_scan.hpp
+++ b/src/entity_manager/perform_scan.hpp
@@ -27,7 +27,7 @@
{
PerformScan(EntityManager& em, nlohmann::json& missingConfigurations,
std::list<nlohmann::json>& configurations,
- std::function<void()>&& callback);
+ boost::asio::io_context& io, std::function<void()>&& callback);
void updateSystemConfiguration(const nlohmann::json& recordRef,
const std::string& probeName,
@@ -41,6 +41,8 @@
bool _passed = false;
MapperGetSubTreeResponse dbusProbeObjects;
std::vector<std::string> passedProbes;
+
+ boost::asio::io_context& io;
};
} // namespace scan
diff --git a/src/entity_manager/utils.hpp b/src/entity_manager/utils.hpp
index ac72c80..fb25b24 100644
--- a/src/entity_manager/utils.hpp
+++ b/src/entity_manager/utils.hpp
@@ -5,9 +5,6 @@
#include <nlohmann/json.hpp>
#include <sdbusplus/asio/connection.hpp>
-// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
-extern boost::asio::io_context io;
-
using DBusValueVariant =
std::variant<std::string, int64_t, uint64_t, double, int32_t, uint32_t,
int16_t, uint16_t, uint8_t, bool, std::vector<uint8_t>>;