| #include "NVMeVolume.hpp" | |
| #include "dbus-sensor_config.h" | |
| #include "NVMeCacheImpl.hpp" | |
| #include "Utils.hpp" | |
| using SchedulerClockType = std::chrono::steady_clock; | |
| NVMeVolume::NVMeVolume(sdbusplus::asio::object_server& objServer, | |
| const std::shared_ptr<sdbusplus::asio::connection>& conn, | |
| const std::shared_ptr<NVMeSubsystem>& subsys, | |
| const NVMeNSIdentify& ns) : | |
| VolumeBase(dynamic_cast<sdbusplus::bus_t&>(*conn), | |
| subsys->volumePath(ns.namespaceId).c_str()), | |
| NvmeVolumeBase(dynamic_cast<sdbusplus::bus_t&>(*conn), | |
| subsys->volumePath(ns.namespaceId).c_str()), | |
| path(subsys->volumePath(ns.namespaceId)), objServer(objServer), conn(conn), | |
| subsys(subsys) | |
| { | |
| namespaceId(ns.namespaceId, false); | |
| size(ns.size, false); | |
| blockSize(ns.blockSize, false); | |
| lbaFormat(ns.lbaFormat, false); | |
| metadataAtEnd(ns.metadataAtEnd, false); | |
| // see init() for other initialisation | |
| } | |
| void NVMeVolume::initializeMetricStore() | |
| { | |
| // if metric store feature is disabled then create empty metric store | |
| // the dbus interface will be there but with no metrics | |
| if (!isMetricStoreEnabled()) | |
| { | |
| metricStore.emplace(conn->get_io_context(), conn, path); | |
| return; | |
| } | |
| auto scheduler = Scheduler<SchedulerClockType>::getScheduler(path); | |
| using IdentifyMetric = | |
| IdentifyMetric<NVME_IDENTIFY_CNS_NS, SchedulerClockType>; | |
| auto identify = std::make_shared<IdentifyMetric>( | |
| this->shared_from_this(), scheduler, | |
| // Identify info is persist throughout the namespace | |
| // lifecycle i.e. from start() to stop() | |
| IdentifyMetric::ClockType::duration::max()); | |
| metricStore.emplace(conn->get_io_context(), conn, path, | |
| std::move(identify)); | |
| } | |
| void NVMeVolume::init() | |
| { | |
| deleteInterface = | |
| objServer.add_interface(path, "xyz.openbmc_project.Object.Delete"); | |
| deleteInterface->register_method( | |
| "Delete", [weak{weak_from_this()}](boost::asio::yield_context yield) { | |
| auto self = weak.lock(); | |
| if (!self) | |
| { | |
| throw std::runtime_error("volume delete called twice?"); | |
| } | |
| auto subsys = self->subsys.lock(); | |
| if (!subsys) | |
| { | |
| throw std::runtime_error("nvmesensor is shutting down"); | |
| } | |
| subsys->deleteVolume(std::move(yield), self); | |
| }); | |
| deleteInterface->initialize(); | |
| VolumeBase::emit_added(); | |
| NvmeVolumeBase::emit_added(); | |
| initializeMetricStore(); | |
| initializeFeatureStore(); | |
| } | |
| std::shared_ptr<NVMeVolume> | |
| NVMeVolume::create(sdbusplus::asio::object_server& objServer, | |
| const std::shared_ptr<sdbusplus::asio::connection>& conn, | |
| const std::shared_ptr<NVMeSubsystem>& subsys, | |
| const NVMeNSIdentify& ns) | |
| { | |
| auto self = std::shared_ptr<NVMeVolume>( | |
| new NVMeVolume(objServer, conn, subsys, ns)); | |
| self->init(); | |
| return self; | |
| } | |
| NVMeVolume::~NVMeVolume() | |
| { | |
| metricStore.reset(); | |
| NvmeVolumeBase::emit_removed(); | |
| VolumeBase::emit_removed(); | |
| objServer.remove_interface(deleteInterface); | |
| } | |
| void NVMeVolume::erase(VolumeBase::EraseMethod eraseType) | |
| { | |
| (void)eraseType; | |
| // TODO: will need dbus async method handling. | |
| throw std::runtime_error("volume erase not yet implemented"); | |
| } | |
| // Additional methods on Volume that are not relevant. | |
| void NVMeVolume::formatLuks([[maybe_unused]] std::vector<uint8_t> password, | |
| [[maybe_unused]] VolumeBase::FilesystemType type) | |
| { | |
| throw std::runtime_error("Method Not Supported"); | |
| } | |
| void NVMeVolume::lock() | |
| { | |
| throw std::runtime_error("Method Not Supported"); | |
| } | |
| void NVMeVolume::unlock([[maybe_unused]] std::vector<uint8_t> password) | |
| { | |
| throw std::runtime_error("Method Not Supported"); | |
| } | |
| void NVMeVolume::changePassword( | |
| [[maybe_unused]] std::vector<uint8_t> oldPassword, | |
| [[maybe_unused]] std::vector<uint8_t> newPassword) | |
| { | |
| throw std::runtime_error("Method Not Supported"); | |
| } | |
| void NVMeVolume::initializeFeatureStore() | |
| { | |
| if (featureStore) | |
| { | |
| return; | |
| } | |
| auto subsysPtr = subsys.lock(); | |
| if (!subsysPtr) | |
| { | |
| return; | |
| } | |
| std::shared_ptr<NVMeControllerEnabled> ctrl; | |
| try | |
| { | |
| ctrl = subsysPtr->getPrimaryController(); | |
| } | |
| catch (const std::exception& e) | |
| { | |
| lg2::error( | |
| "Failed to get primary controller for feature store: {ERROR}", | |
| "ERROR", e.what()); | |
| return; | |
| } | |
| if (!ctrl) | |
| { | |
| return; | |
| } | |
| this->featureStore = std::make_shared<FeatureStore>( | |
| conn->get_io_context(), objServer, conn, path, ctrl->getNvmeIntf(), | |
| ctrl->getMiCtrl(), namespaceId(), FeatureScope::Namespace); | |
| this->featureStore->init([](const std::error_code& ec) { | |
| if (ec) | |
| { | |
| lg2::error("Failed to initialize feature store for volume: {ERROR}", | |
| "ERROR", ec.message()); | |
| } | |
| }); | |
| } |