blob: 51ac4e0440e16221a66500644862033857778ec6 [file] [log] [blame]
#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);
}