| #pragma once |
| |
| #include "NVMeCache.hpp" |
| #include "Utils.hpp" |
| |
| #include <libnvme-mi.h> |
| |
| #include <functional> |
| #include <memory> |
| #include <span> |
| #include <string> |
| #include <unordered_map> |
| |
| class NVMeSubsystem; |
| class NVMeController; |
| |
| class NVMePlugin; |
| class NVMeControllerPlugin; |
| |
| // A map from library name to the dlopen() pointer |
| extern std::unordered_map<std::string, void*> pluginLibMap; |
| |
| // entry function for plugin library to create the plugin instance |
| using createplugin_t = std::shared_ptr<NVMePlugin> (*)( |
| std::shared_ptr<NVMeSubsystem> subsys, const SensorData& config); |
| |
| class NVMeControllerPlugin |
| { |
| public: |
| using getlogpage_t = std::function<void( |
| uint8_t lid, uint32_t nsid, uint8_t lsp, uint16_t lsi, |
| std::function<void(const std::error_code&, std::span<uint8_t>)>&& cb)>; |
| |
| // The controller plugin can only be created from NVMePlugin |
| NVMeControllerPlugin(std::shared_ptr<NVMeController> cntl, |
| [[maybe_unused]] const SensorData& cfg) : |
| nvmeController(std::move(cntl)) |
| {} |
| |
| virtual ~NVMeControllerPlugin() = default; |
| virtual getlogpage_t getGetLogPageHandler() |
| { |
| return {}; |
| } |
| |
| protected: |
| const std::string& getPath() const; |
| sdbusplus::asio::object_server& getDbusServer(); |
| std::shared_ptr<sdbusplus::asio::connection> getDbusConnection(); |
| boost::asio::io_context& getIOContext(); |
| bool isPrimary() const; |
| |
| /** |
| * adminXfer() - transfer Raw admin cmd to the binded conntroller |
| * @admin_req: request header |
| * @data: request data payload |
| * @timeout_ms: timeout in ms |
| * @resp_data_offset: offset into request data to retrieve from controller |
| * @cb: callback function after the response received. |
| * @ec: error code |
| * @admin_resp: response header |
| * @resp_data: response data payload |
| * |
| * Performs an arbitrary NVMe Admin command, using the provided request |
| * header, in @admin_req. The requested data is attached by @data, if any. |
| * |
| * On success, @cb will be called and response header and data are stored |
| * in |
| * @admin_resp and @resp_data, which has an optional appended payload |
| * buffer. The response data does not include the Admin request header, so |
| * 0 represents no payload. |
| * |
| * As with all Admin commands, we can request partial data from the Admin |
| * Response payload, offset by @resp_data_offset. In case of resp_data |
| * contains only partial data of the caller's requirement, a follow-up |
| * call to adminXfer with offset is required. |
| * |
| * See: &struct nvme_mi_admin_req_hdr and &struct nvme_mi_admin_resp_hdr. |
| * |
| * @ec will be returned on failure. |
| */ |
| void 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); |
| /** |
| * @brief Get cntrl_id for the binded NVMe controller |
| * |
| * @return cntrl_id |
| */ |
| uint16_t getCntrlId() const; |
| |
| private: |
| std::shared_ptr<NVMeController> nvmeController; |
| }; |
| |
| class NVMePlugin |
| { |
| public: |
| NVMePlugin(std::shared_ptr<NVMeSubsystem> subsys, const SensorData& config); |
| |
| virtual ~NVMePlugin(); |
| |
| std::shared_ptr<NVMeControllerPlugin> |
| createControllerPlugin(const NVMeController& controller, |
| const SensorData& config); |
| |
| // the NVMe subsystem will start the plugin after NVMesubsystem finished |
| // intialization and started. |
| virtual void start() {} |
| |
| // the NVMe subsystem will stop the plugin before NVMe subsystem stop |
| // 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: |
| const std::string& getPath() const; |
| const std::string& getName() const; |
| boost::asio::io_context& getIOContext(); |
| sdbusplus::asio::object_server& getDbusServer(); |
| std::shared_ptr<sdbusplus::asio::connection> getDbusConnection(); |
| |
| const std::map<uint16_t, std::pair<std::shared_ptr<NVMeController>, |
| std::shared_ptr<NVMeControllerPlugin>>>& |
| getControllers(); |
| // The nvme plugin implemenation need to overload the function to create a |
| // derived controller plugin. |
| virtual std::shared_ptr<NVMeControllerPlugin> |
| makeController(std::shared_ptr<NVMeController> cntl, |
| const SensorData&) = 0; |
| |
| private: |
| std::shared_ptr<NVMeSubsystem> subsystem; |
| }; |