| #pragma once |
| |
| /** |
| * This file defines the MetricStore class, which is the DBus inplemention to |
| * interact with a collection of NVMe Metrics Cache for a Storage |
| * object(e.g. NVMe Contoller) |
| */ |
| |
| #include "NVMeCache.hpp" |
| |
| #include <boost/asio.hpp> |
| #include <boost/asio/write.hpp> |
| #include <boost/endian.hpp> |
| #include <sdbusplus/asio/connection.hpp> |
| #include <sdbusplus/asio/object_server.hpp> |
| #include <sdbusplus/sdbus.hpp> |
| #include <sdbusplus/server.hpp> |
| #include <xyz/openbmc_project/NVMe/MetricStore/server.hpp> |
| |
| #include <functional> |
| #include <iostream> |
| #include <memory> |
| #include <string> |
| #include <tuple> |
| #include <unordered_map> |
| |
| constexpr bool debug = false; |
| |
| struct MetricHeader |
| { |
| boost::endian::little_uint32_t lens; // Header length |
| boost::endian::little_uint16_t version; // Header version |
| uint8_t dataFormat; // the data format. 0x00 = Raw NVMe format |
| uint8_t reserved; |
| boost::endian::little_uint64_t |
| startTime; // time stamp when the Metric started the retrival from the |
| // device |
| boost::endian::little_uint64_t |
| finishTime; // time stamp when the Metric finished the retrival from |
| // the device |
| }; |
| |
| class MetricStore : |
| public sdbusplus::xyz::openbmc_project::NVMe::server::MetricStore |
| { |
| public: |
| template <class... Args> |
| requires(std::is_base_of_v<MetricBase<std::chrono::steady_clock>, |
| Args> && |
| ...) |
| MetricStore(boost::asio::io_context& io, |
| const std::shared_ptr<sdbusplus::asio::connection>& conn, |
| const std::string& objectPath, |
| std::shared_ptr<Args>&&... metrics) : |
| sdbusplus::xyz::openbmc_project::NVMe::server::MetricStore( |
| dynamic_cast<sdbusplus::bus_t&>(*conn), objectPath.c_str()), |
| path(objectPath), io(io), |
| metricStore{ |
| {std::string{metrics->getIdentifier()}, std::move(metrics)}...} |
| { |
| std::vector<std::string> idCollection; |
| for (auto& [identifier, metric] : metricStore) |
| { |
| idCollection.push_back(identifier); |
| metric->refresh({}); |
| } |
| metricCollection(std::move(idCollection), true); |
| emit_added(); |
| } |
| ~MetricStore() override |
| { |
| emit_removed(); |
| } |
| |
| private: |
| /** |
| * @brief Writes to file descriptor after getting results from the |
| * registered callback function |
| * |
| * @param[in] data: Vector of raw bytes (header + actual data) to be written |
| * to file descriptor |
| * |
| * @return sdbusplus::message::unix_fd: Returns the read end of the pipe |
| */ |
| sdbusplus::message::unix_fd writeToFd(std::span<uint8_t> header, |
| std::span<uint8_t> data); |
| |
| /** |
| * @brief Gets Metric using a unique metric name. Metric must be registered |
| * with that unique name |
| * |
| * @param[in] name: Registered metric name |
| * |
| * @return file descriptor pointing to the data |
| */ |
| sdbusplus::message::unix_fd getMetric(std::string name) override; // NOLINT |
| |
| std::string path; |
| boost::asio::io_context& io; |
| std::unordered_map<std::string, std::shared_ptr<MetricBase<>>> metricStore; |
| }; |