| #pragma once |
| #include "NVMeBasic.hpp" |
| #include "NVMeController.hpp" |
| #include "NVMeDrive.hpp" |
| #include "NVMePlugin.hpp" |
| #include "NVMeProgress.hpp" |
| #include "NVMeSensor.hpp" |
| #include "NVMeStorage.hpp" |
| #include "NVMeUtil.hpp" |
| #include "Utils.hpp" |
| |
| #include <cstdint> |
| |
| class NVMeVolume; |
| class NVMeCreateVolumeProgress; |
| |
| #ifdef NVME_UNIT_TEST |
| class NVMeTest; |
| #endif |
| |
| class NVMeSubsystem : |
| public std::enable_shared_from_this<NVMeSubsystem>, |
| public NVMeStorage |
| { |
| public: |
| static std::shared_ptr<NVMeSubsystem> |
| create(boost::asio::io_context& io, |
| sdbusplus::asio::object_server& objServer, |
| const std::shared_ptr<sdbusplus::asio::connection>& conn, |
| const std::string& path, const std::string& name, |
| const SensorData& configData, NVMeIntf intf); |
| |
| ~NVMeSubsystem() override; |
| |
| void start(); |
| |
| void stop(); |
| |
| /** @brief Returns the dbus path for a given volume. |
| * |
| * @param[in] nsid - The NSID of the volume |
| * |
| * @return path[std::string] - The dbus path for the volume. |
| */ |
| std::string volumePath(uint32_t nsid) const; |
| |
| /** |
| * @brief delete given namespace from the nvme device and nvme daemon, |
| * throws on error |
| */ |
| void deleteVolume(boost::asio::yield_context yield, |
| const std::shared_ptr<NVMeVolume>& volume); |
| |
| std::vector<uint32_t> attachedVolumes(uint16_t ctrlId) const; |
| |
| /** |
| * @brief Attach the namespace to controller, throws std::runtime_error on |
| * failure |
| */ |
| void attachCtrlVolume(uint16_t ctrlId, uint32_t nsid); |
| /** |
| * @brief Detach the namespace from controller, throws std::runtime_error on |
| * failure |
| */ |
| void detachCtrlVolume(uint16_t ctrlId, uint32_t nsid); |
| void detachAllCtrlVolume(uint32_t nsid); |
| std::shared_ptr<NVMeVolume> |
| getVolume(const sdbusplus::message::object_path& volPath) const; |
| |
| void startSanitize(const NVMeSanitizeParams& params, |
| std::function<void(nvme_ex_ptr ex)>&& submitCb); |
| void sanitizeStatus( |
| std::function<void(nvme_ex_ptr ex, bool inProgress, bool failed, |
| bool completed, uint16_t sstat, uint16_t sprog, |
| uint32_t scdw10)>&& cb); |
| |
| const std::string path; |
| |
| NVMeSubsystem(boost::asio::io_context& io, |
| sdbusplus::asio::object_server& objServer, |
| const std::shared_ptr<sdbusplus::asio::connection>& conn, |
| const std::string& path, const std::string& name, |
| const SensorData& configData, NVMeIntf intf); |
| |
| void init(); |
| |
| const std::string& getName() const |
| { |
| return name; |
| } |
| |
| #if defined NVME_UNIT_TEST |
| // allow the test fixture change the settings for subsystem |
| friend class NVMeTest; |
| #endif |
| |
| private: |
| friend class NVMePlugin; |
| |
| template <nvme_identify_cns CNS, class ClockType> |
| friend class IdentifyMetric; |
| |
| boost::asio::io_context& io; |
| sdbusplus::asio::object_server& objServer; |
| std::shared_ptr<sdbusplus::asio::connection> conn; |
| std::string name; |
| SensorData config; |
| |
| NVMeIntf nvmeIntf; |
| |
| /* |
| * stateDiagram |
| * [*] --> Stop |
| * Stop --> Intiatilzing |
| * Intiatilzing --> Start |
| * Intiatilzing --> Aborting |
| * Start --> Terminating |
| * Aborting --> Terminating |
| * Terminating --> Stop |
| */ |
| enum class Status : uint8_t |
| { |
| Stop, |
| Intiatilzing, |
| Aborting, |
| Start, |
| Terminating, |
| }; |
| |
| Status status; |
| |
| // plugin |
| std::shared_ptr<NVMePlugin> plugin; |
| |
| /* thermal sensor for the subsystem */ |
| std::shared_ptr<NVMeSensor> ctemp; |
| std::shared_ptr<boost::asio::steady_timer> ctempTimer; |
| std::chrono::milliseconds pollingInterval = std::chrono::milliseconds(1000); |
| |
| /* Begin of patch context |
| * |
| * |
| * |
| */ |
| /* |
| * |
| * |
| * End of patch context |
| */ |
| |
| /* |
| Drive interface: xyz.openbmc_project.Inventory.Item.Drive |
| */ |
| std::shared_ptr<NVMeDrive> drive; |
| |
| // map from cntrlid to a pair of {controller, controller_plugin} |
| std::map<uint16_t, std::pair<std::shared_ptr<NVMeController>, |
| std::shared_ptr<NVMeControllerPlugin>>> |
| controllers; |
| |
| /* |
| map of nsid to volumes |
| */ |
| std::map<uint32_t, std::shared_ptr<NVMeVolume>> volumes; |
| |
| /* |
| * volumes attached to controllers |
| */ |
| std::map<uint16_t, std::set<uint32_t>> attached; |
| |
| /* |
| In-progress or completed create operations |
| */ |
| std::unordered_map<std::string, std::shared_ptr<NVMeCreateVolumeProgress>> |
| createProgress; |
| |
| // controller to use for NVMe operations. Is a member of the controllers |
| // map. Access this through getPrimaryController() to test for nullness. |
| std::shared_ptr<NVMeControllerEnabled> primaryController; |
| |
| std::shared_ptr<sdbusplus::asio::dbus_interface> assocIntf; |
| |
| void createAssociation(); |
| void updateAssociation(); |
| std::vector<Association> makeAssociation() const; |
| |
| // make the subsystem functional/functional be enabling/disabling the |
| // storage controller, namespaces and thermal sensors. |
| void markFunctional(bool toggle); |
| |
| // mark the availability of the Storage device. |
| void markAvailable(bool toggle); |
| |
| // may throw NVMeError if no controller is available |
| std::shared_ptr<NVMeControllerEnabled> getPrimaryController() const; |
| |
| sdbusplus::message::object_path |
| createVolume(boost::asio::yield_context yield, uint64_t size, |
| size_t lbaFormat, bool metadataAtEnd) override; |
| |
| // callback when drive completes. not called in dbus method context. |
| void createVolumeFinished(const std::string& progId, const nvme_ex_ptr& ex, |
| NVMeNSIdentify ns); |
| |
| void addIdentifyNamespace(boost::asio::yield_context yield, uint32_t nsid); |
| |
| // fill DBus object for Drive, throws on failure |
| void fillDrive(boost::asio::yield_context yield); |
| |
| // update all namespaces in the subsystem, throws on failure |
| void updateVolumes(boost::asio::yield_context yield); |
| |
| // removes state associated with the volume. Does not manipulate the drive. |
| // throws on error |
| void forgetVolume(const std::shared_ptr<NVMeVolume>& volume); |
| |
| // adds state associated with the volume. Does not create a volume. |
| // may throw if the volume exists. |
| std::shared_ptr<NVMeVolume> addVolume(const NVMeNSIdentify& ns); |
| |
| // query the supported LBA formats from identify ns, throws on failure |
| void querySupportedFormats(boost::asio::yield_context yield); |
| |
| // a counter to skip health poll when NVMe subsystem becomes Unavailable |
| unsigned unavailableCount = 0; |
| unsigned unavailableMaxCount = 60; |
| |
| // process Secondary controller and start controllers and the associated |
| // Plugin |
| void processSecondaryControllerList(nvme_secondary_ctrl_list* secCntlrList); |
| }; |