NVMePlugin: Add VU metric Add a new function `getMetric` to the plugin to fetch VU NVMe Metric from a plugin. The function will be call upon the creation of a metric store with given the path of the metric store. The VU NVMe Metric will be inserted into the target metric store afterwards. Google-Bug-Id: 348660385#comment14 Tested: b/348660385#comment15 Signed-off-by: Hao Jiang <jianghao@google.com> Change-Id: I81d1b569cd716c392d9445b08cd3fff64cbf0790
diff --git a/src/NVMeMetricStore.hpp b/src/NVMeMetricStore.hpp index f88b4d5..4456997 100644 --- a/src/NVMeMetricStore.hpp +++ b/src/NVMeMetricStore.hpp
@@ -58,6 +58,19 @@ metricStore{ {std::string{metrics->getIdentifier()}, std::move(metrics)}...} { + auto vuMetrics = getVendorMatrics(path); + for (auto& metric : vuMetrics) + { + auto [itr, res] = metricStore.try_emplace( + std::string{metric->getIdentifier()}, std::move(metric)); + if (!res) + { + std::cerr << std::format( + "[{}, {}] drop a duplicated vendor metic\n", path, + itr->first); + } + } + std::vector<std::string> idCollection; for (auto& [identifier, metric] : metricStore) { @@ -73,6 +86,8 @@ } private: + static std::vector<std::shared_ptr<MetricBase<>>> + getVendorMatrics(const std::string& path); /** * @brief Writes to file descriptor after getting results from the * registered callback function
diff --git a/src/NVMePlugin.cpp b/src/NVMePlugin.cpp index 7b31e37..51ac4e0 100644 --- a/src/NVMePlugin.cpp +++ b/src/NVMePlugin.cpp
@@ -1,9 +1,16 @@ #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) @@ -25,6 +32,22 @@ 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; @@ -98,3 +121,45 @@ { 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); +}
diff --git a/src/NVMePlugin.hpp b/src/NVMePlugin.hpp index b45e718..88ed189 100644 --- a/src/NVMePlugin.hpp +++ b/src/NVMePlugin.hpp
@@ -1,5 +1,6 @@ #pragma once +#include "NVMeCache.hpp" #include "Utils.hpp" #include <libnvme-mi.h> @@ -97,10 +98,9 @@ class NVMePlugin { public: - NVMePlugin(std::shared_ptr<NVMeSubsystem> subsys, - const SensorData& /*config*/) : subsystem(std::move(subsys)) {}; + NVMePlugin(std::shared_ptr<NVMeSubsystem> subsys, const SensorData& config); - virtual ~NVMePlugin() = default; + virtual ~NVMePlugin(); std::shared_ptr<NVMeControllerPlugin> createControllerPlugin(const NVMeController& controller, @@ -114,6 +114,13 @@ // itself. virtual void stop() {} + // get Vendor Metric for given path + virtual std::vector<std::shared_ptr<MetricBase<>>> + getMetric(const std::string& /*path*/) noexcept + { + return {}; + } + static constexpr const char* libraryPath = "/usr/lib/nvmed/"; protected: