blob: bfb615094bed05af16d3754eba29d19f59b8c28f [file]
#include "NVMeVolume.hpp"
#include "NVMeCacheImpl.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::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();
/* create the MetricStore interface */
auto scheduler = Scheduler<SchedulerClockType>::getScheduler(path);
// NOLINTBEGIN(performance-unnecessary-value-param)
auto completeCB =
[wealSelf{weak_from_this()},
path{path}](std::string_view name,
std::shared_ptr<MetricBase<SchedulerClockType>> metric) {
auto self = wealSelf.lock();
if (!self || !self->metricStore)
{
// TODO: log_level = INFO
std::cerr << std::format(
"[{}]Metrics interface for controller expired, update signal skipped.\n",
path);
}
if (!metric->isCacheValid())
{
// broadcast invalid metric signal
self->metricStore->metricUpdated(std::string{name}, {});
return;
}
auto data = metric->getCache();
std::vector<uint8_t> headerBuf;
headerBuf.resize(sizeof(MetricHeader));
MetricHeader& header =
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
*reinterpret_cast<MetricHeader*>(headerBuf.data());
header.lens = boost::endian::little_uint32_t(sizeof(header));
header.version = 0;
header.dataFormat = 0;
header.startTime = boost::endian::little_uint64_t(
std::get<0>(data).time_since_epoch().count());
header.finishTime = boost::endian::little_uint64_t(
std::get<1>(data).time_since_epoch().count());
self->metricStore->metricUpdated(std::string{name}, headerBuf);
};
// NOLINTEND(performance-unnecessary-value-param)
using IdentifyMetric =
IdentifyMetric<NVME_IDENTIFY_CNS_NS, SchedulerClockType>;
// NOLINTBEGIN(modernize-make-shared)
auto identify = std::shared_ptr<IdentifyMetric>(new IdentifyMetric(
this->shared_from_this(), scheduler,
// Identify info is persist throughout the namespace lifecycle
// i.e. from start() to stop()
IdentifyMetric::ClockType::duration::max(),
std::bind_front(completeCB, IdentifyMetric::identifyIdentifier())));
// NOLINTEND(modernize-make-shared)
metricStore.emplace(conn->get_io_context(), conn, path,
std::move(identify));
}
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");
}