#include "config.h" #include "dump_manager_resource.hpp" #include "dump_utils.hpp" #include "op_dump_consts.hpp" #include "resource_dump_entry.hpp" #include "xyz/openbmc_project/Common/error.hpp" #include #include #include namespace openpower { namespace dump { namespace resource { using namespace phosphor::logging; using InternalFailure = sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; void Manager::notify(uint32_t dumpId, uint64_t size) { // Get the timestamp std::time_t timeStamp = std::time(nullptr); // If there is an entry with invalid id update that. // If there a completed one with same source id ignore it // if there is no invalid id, create new entry openpower::dump::resource::Entry* upEntry = NULL; for (auto& entry : entries) { openpower::dump::resource::Entry* resEntry = dynamic_cast(entry.second.get()); // If there is already a completed entry with input source id then // ignore this notification. if ((resEntry->sourceDumpId() == dumpId) && (resEntry->status() == phosphor::dump::OperationStatus::Completed)) { log( fmt::format("Resource dump entry with source dump id({}) is " "already present with entry id({})", dumpId, resEntry->getDumpId()) .c_str()); return; } // Save the first entry with INVALID_SOURCE_ID // but continue in the loop to make sure the // new entry is not duplicate if ((resEntry->status() == phosphor::dump::OperationStatus::InProgress) && (resEntry->sourceDumpId() == INVALID_SOURCE_ID) && (upEntry == NULL)) { upEntry = resEntry; } } if (upEntry != NULL) { log( fmt::format("Resource Dump Notify: Updating dumpId({}) " "with source Id({}) Size({})", upEntry->getDumpId(), dumpId, size) .c_str()); upEntry->update(timeStamp, size, dumpId); return; } // Get the id auto id = lastEntryId + 1; auto idString = std::to_string(id); auto objPath = std::filesystem::path(baseEntryPath) / idString; try { log(fmt::format("Resouce Dump Notify: creating new dump " "entry dumpId({}) Id({}) Size({})", id, dumpId, size) .c_str()); entries.insert(std::make_pair( id, std::make_unique( bus, objPath.c_str(), id, timeStamp, size, dumpId, std::string(), std::string(), phosphor::dump::OperationStatus::Completed, *this))); } catch (const std::invalid_argument& e) { log(fmt::format("Error in creating resource dump entry, " "errormsg({}),OBJECTPATH({}),ID({})," "TIMESTAMP({}),SIZE({}),SOURCEID({})", e.what(), objPath.c_str(), id, timeStamp, size, dumpId) .c_str()); report(); return; } lastEntryId++; } sdbusplus::message::object_path Manager::createDump(phosphor::dump::DumpCreateParams params) { using NotAllowed = sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed; using Reason = xyz::openbmc_project::Common::NotAllowed::REASON; // Allow creating resource dump only when the host is up. if (!phosphor::dump::isHostRunning()) { elog( Reason("Resource dump can be initiated only when the host is up")); return std::string(); } using InvalidArgument = sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument; using Argument = xyz::openbmc_project::Common::InvalidArgument; using CreateParameters = sdbusplus::com::ibm::Dump::server::Create::CreateParameters; auto id = lastEntryId + 1; auto idString = std::to_string(id); auto objPath = std::filesystem::path(baseEntryPath) / idString; std::time_t timeStamp = std::time(nullptr); std::string vspString; auto iter = params.find( sdbusplus::com::ibm::Dump::server::Create:: convertCreateParametersToString(CreateParameters::VSPString)); if (iter == params.end()) { // Host will generate a default dump if no resource selector string // is provided. The default dump will be a non-disruptive system dump. log( "VSP string is not provided, a non-disruptive system dump will be " "generated by the host"); } else { try { vspString = std::get(iter->second); } catch (const std::bad_variant_access& e) { // Exception will be raised if the input is not string log( fmt::format("An invalid vsp string is passed errormsg({})", e.what()) .c_str()); elog(Argument::ARGUMENT_NAME("VSP_STRING"), Argument::ARGUMENT_VALUE("INVALID INPUT")); } } std::string pwd; iter = params.find( sdbusplus::com::ibm::Dump::server::Create:: convertCreateParametersToString(CreateParameters::Password)); if (iter == params.end()) { log("Password is not provided for resource dump"); } else { try { pwd = std::get(iter->second); } catch (const std::bad_variant_access& e) { // Exception will be raised if the input is not string log( fmt::format("An invalid password string is passed errormsg({})", e.what()) .c_str()); elog(Argument::ARGUMENT_NAME("PASSWORD"), Argument::ARGUMENT_VALUE("INVALID INPUT")); } } try { entries.insert(std::make_pair( id, std::make_unique( bus, objPath.c_str(), id, timeStamp, 0, INVALID_SOURCE_ID, vspString, pwd, phosphor::dump::OperationStatus::InProgress, *this))); } catch (const std::invalid_argument& e) { log( fmt::format( "Error in creating resource dump " "entry,errormsg({}),OBJECTPATH({}), VSPSTRING({}), ID({})", e.what(), objPath.c_str(), vspString, id) .c_str()); elog(); return std::string(); } lastEntryId++; return objPath.string(); } } // namespace resource } // namespace dump } // namespace openpower