| #include "NVMePlugin.hpp" |
| |
| #include "NVMeIntf.hpp" |
| #include "NVMeMetricStore.hpp" |
| #include "NVMeSubsys.hpp" |
| #include "Utils.hpp" |
| |
| // map from plugin path (subsystem path) to getMetric function |
| std::unordered_map<std::string, |
| std::function<std::vector<std::shared_ptr<MetricBase<>>>( |
| const std::string& path)>> |
| pluginMetricFunctions; |
| |
| std::shared_ptr<NVMeControllerPlugin> |
| NVMePlugin::createControllerPlugin(const NVMeController& controller, |
| const SensorData& config) |
| { |
| // searching for the target controller in NVMe subsystem |
| auto res = subsystem->controllers.find(controller.getCntrlId()); |
| if (res == subsystem->controllers.end() || |
| &controller != res->second.first.get()) |
| { |
| std::cerr << ("Failed to create controller plugin: " |
| "cannot find the controller") |
| << '\n'; |
| res->second.second.reset(); |
| return {}; |
| } |
| |
| // insert the plugin |
| res->second.second = makeController(res->second.first, config); |
| return res->second.second; |
| } |
| |
| NVMePlugin::NVMePlugin(std::shared_ptr<NVMeSubsystem> subsys, |
| const SensorData& /*config*/) : |
| subsystem(std::move(subsys)) |
| { |
| // register the path to metric function table. |
| auto [_, res] = pluginMetricFunctions.try_emplace( |
| getPath(), std::bind_front(&NVMePlugin::getMetric, this)); |
| assert(res && "found duplicate plugin path for metric function"); |
| } |
| |
| NVMePlugin::~NVMePlugin() |
| { |
| // remove the metric function |
| pluginMetricFunctions.erase(getPath()); |
| } |
| |
| const std::string& NVMePlugin::getPath() const |
| { |
| return subsystem->path; |
| } |
| |
| const std::string& NVMePlugin::getName() const |
| { |
| return subsystem->name; |
| } |
| |
| boost::asio::io_context& NVMePlugin::getIOContext() |
| { |
| return subsystem->io; |
| } |
| |
| sdbusplus::asio::object_server& NVMePlugin::getDbusServer() |
| { |
| return subsystem->objServer; |
| } |
| |
| std::shared_ptr<sdbusplus::asio::connection> NVMePlugin::getDbusConnection() |
| { |
| return subsystem->conn; |
| } |
| |
| const std::map<uint16_t, std::pair<std::shared_ptr<NVMeController>, |
| std::shared_ptr<NVMeControllerPlugin>>>& |
| NVMePlugin::getControllers() |
| { |
| return subsystem->controllers; |
| } |
| |
| const std::string& NVMeControllerPlugin::getPath() const |
| { |
| return nvmeController->path; |
| } |
| |
| sdbusplus::asio::object_server& NVMeControllerPlugin::getDbusServer() |
| { |
| return nvmeController->objServer; |
| } |
| |
| std::shared_ptr<sdbusplus::asio::connection> |
| NVMeControllerPlugin::getDbusConnection() |
| { |
| return nvmeController->conn; |
| } |
| |
| boost::asio::io_context& NVMeControllerPlugin::getIOContext() |
| { |
| return nvmeController->io; |
| } |
| |
| bool NVMeControllerPlugin::isPrimary() const |
| { |
| return nvmeController->isPrimary; |
| } |
| |
| void NVMeControllerPlugin::adminXfer( |
| const nvme_mi_admin_req_hdr& adminReq, std::span<uint8_t> data, |
| unsigned int timeoutMs, |
| std::function<void(const std::error_code& ec, |
| const nvme_mi_admin_resp_hdr& adminResp, |
| std::span<uint8_t> respData)>&& cb) |
| { |
| nvmeController->nvmeIntf->adminXfer(nvmeController->nvmeCtrl, adminReq, |
| data, timeoutMs, std::move(cb)); |
| } |
| |
| uint16_t NVMeControllerPlugin::getCntrlId() const |
| { |
| return nvmeController->getCntrlId(); |
| } |
| |
| std::vector<std::shared_ptr<MetricBase<>>> |
| MetricStore::getVendorMatrics(const std::string& path) |
| { |
| auto itr = std::find_if( |
| pluginMetricFunctions.begin(), pluginMetricFunctions.end(), |
| [&path](const std::pair< |
| std::string, |
| std::function<std::vector<std::shared_ptr<MetricBase<>>>( |
| const std::string& path)>>& pair) { |
| // check if the given path is subdir of the subsystem path |
| const std::string& parent = pair.first; |
| if (parent.empty() || path.empty()) |
| { |
| return false; |
| } |
| if (parent.size() > path.size()) |
| { |
| return false; |
| } |
| if (!path.starts_with(parent)) |
| { |
| return false; |
| } |
| if (parent.back() != '/' && path.size() > parent.size() && |
| path.at(parent.size()) != '/') |
| { |
| return false; |
| } |
| |
| return true; |
| }); |
| if (itr == pluginMetricFunctions.end()) |
| { |
| return {}; |
| } |
| if (!itr->second) |
| { |
| return {}; |
| } |
| return itr->second(path); |
| } |