162337a92SDhruvaraj Subhashchandran #include "config.h" 262337a92SDhruvaraj Subhashchandran 362337a92SDhruvaraj Subhashchandran #include "dump_manager_resource.hpp" 462337a92SDhruvaraj Subhashchandran 562337a92SDhruvaraj Subhashchandran #include "dump_utils.hpp" 6ad50d422SDhruvaraj Subhashchandran #include "op_dump_consts.hpp" 762337a92SDhruvaraj Subhashchandran #include "resource_dump_entry.hpp" 862337a92SDhruvaraj Subhashchandran #include "xyz/openbmc_project/Common/error.hpp" 962337a92SDhruvaraj Subhashchandran 10858fbb2eSGeorge Liu #include <fmt/core.h> 11858fbb2eSGeorge Liu 1262337a92SDhruvaraj Subhashchandran #include <phosphor-logging/elog-errors.hpp> 1362337a92SDhruvaraj Subhashchandran #include <phosphor-logging/elog.hpp> 1462337a92SDhruvaraj Subhashchandran 15341d683dSDhruvaraj Subhashchandran namespace openpower 1662337a92SDhruvaraj Subhashchandran { 1762337a92SDhruvaraj Subhashchandran namespace dump 1862337a92SDhruvaraj Subhashchandran { 1962337a92SDhruvaraj Subhashchandran namespace resource 2062337a92SDhruvaraj Subhashchandran { 2162337a92SDhruvaraj Subhashchandran 2262337a92SDhruvaraj Subhashchandran using namespace phosphor::logging; 2362337a92SDhruvaraj Subhashchandran using InternalFailure = 2462337a92SDhruvaraj Subhashchandran sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; 2562337a92SDhruvaraj Subhashchandran 2662337a92SDhruvaraj Subhashchandran void Manager::notify(uint32_t dumpId, uint64_t size) 2762337a92SDhruvaraj Subhashchandran { 2862337a92SDhruvaraj Subhashchandran // Get the timestamp 29*c0ab9d43SClaire Weinan uint64_t timeStamp = 30*c0ab9d43SClaire Weinan std::chrono::duration_cast<std::chrono::microseconds>( 31*c0ab9d43SClaire Weinan std::chrono::system_clock::now().time_since_epoch()) 32*c0ab9d43SClaire Weinan .count(); 3362337a92SDhruvaraj Subhashchandran 34583ebc09SDhruvaraj Subhashchandran // If there is an entry with invalid id update that. 35583ebc09SDhruvaraj Subhashchandran // If there a completed one with same source id ignore it 36583ebc09SDhruvaraj Subhashchandran // if there is no invalid id, create new entry 37583ebc09SDhruvaraj Subhashchandran openpower::dump::resource::Entry* upEntry = NULL; 3862337a92SDhruvaraj Subhashchandran for (auto& entry : entries) 3962337a92SDhruvaraj Subhashchandran { 40341d683dSDhruvaraj Subhashchandran openpower::dump::resource::Entry* resEntry = 41341d683dSDhruvaraj Subhashchandran dynamic_cast<openpower::dump::resource::Entry*>(entry.second.get()); 42583ebc09SDhruvaraj Subhashchandran 43583ebc09SDhruvaraj Subhashchandran // If there is already a completed entry with input source id then 44583ebc09SDhruvaraj Subhashchandran // ignore this notification. 45583ebc09SDhruvaraj Subhashchandran if ((resEntry->sourceDumpId() == dumpId) && 46583ebc09SDhruvaraj Subhashchandran (resEntry->status() == phosphor::dump::OperationStatus::Completed)) 4762337a92SDhruvaraj Subhashchandran { 48583ebc09SDhruvaraj Subhashchandran log<level::INFO>( 49583ebc09SDhruvaraj Subhashchandran fmt::format("Resource dump entry with source dump id({}) is " 50583ebc09SDhruvaraj Subhashchandran "already present with entry id({})", 51583ebc09SDhruvaraj Subhashchandran dumpId, resEntry->getDumpId()) 52583ebc09SDhruvaraj Subhashchandran .c_str()); 5362337a92SDhruvaraj Subhashchandran return; 5462337a92SDhruvaraj Subhashchandran } 55583ebc09SDhruvaraj Subhashchandran 56583ebc09SDhruvaraj Subhashchandran // Save the first entry with INVALID_SOURCE_ID 57583ebc09SDhruvaraj Subhashchandran // but continue in the loop to make sure the 58583ebc09SDhruvaraj Subhashchandran // new entry is not duplicate 59583ebc09SDhruvaraj Subhashchandran if ((resEntry->status() == 60583ebc09SDhruvaraj Subhashchandran phosphor::dump::OperationStatus::InProgress) && 61583ebc09SDhruvaraj Subhashchandran (resEntry->sourceDumpId() == INVALID_SOURCE_ID) && 62583ebc09SDhruvaraj Subhashchandran (upEntry == NULL)) 63583ebc09SDhruvaraj Subhashchandran { 64583ebc09SDhruvaraj Subhashchandran upEntry = resEntry; 6562337a92SDhruvaraj Subhashchandran } 66583ebc09SDhruvaraj Subhashchandran } 67583ebc09SDhruvaraj Subhashchandran if (upEntry != NULL) 68583ebc09SDhruvaraj Subhashchandran { 69583ebc09SDhruvaraj Subhashchandran log<level::INFO>( 70583ebc09SDhruvaraj Subhashchandran fmt::format("Resource Dump Notify: Updating dumpId({}) " 71583ebc09SDhruvaraj Subhashchandran "with source Id({}) Size({})", 72583ebc09SDhruvaraj Subhashchandran upEntry->getDumpId(), dumpId, size) 73583ebc09SDhruvaraj Subhashchandran .c_str()); 74583ebc09SDhruvaraj Subhashchandran upEntry->update(timeStamp, size, dumpId); 75583ebc09SDhruvaraj Subhashchandran return; 76583ebc09SDhruvaraj Subhashchandran } 77583ebc09SDhruvaraj Subhashchandran 7862337a92SDhruvaraj Subhashchandran // Get the id 7962337a92SDhruvaraj Subhashchandran auto id = lastEntryId + 1; 8062337a92SDhruvaraj Subhashchandran auto idString = std::to_string(id); 813fc6df48SJayanth Othayoth auto objPath = std::filesystem::path(baseEntryPath) / idString; 8262337a92SDhruvaraj Subhashchandran 8362337a92SDhruvaraj Subhashchandran try 8462337a92SDhruvaraj Subhashchandran { 85583ebc09SDhruvaraj Subhashchandran log<level::INFO>(fmt::format("Resouce Dump Notify: creating new dump " 86583ebc09SDhruvaraj Subhashchandran "entry dumpId({}) Id({}) Size({})", 87583ebc09SDhruvaraj Subhashchandran id, dumpId, size) 88583ebc09SDhruvaraj Subhashchandran .c_str()); 8962337a92SDhruvaraj Subhashchandran entries.insert(std::make_pair( 9062337a92SDhruvaraj Subhashchandran id, std::make_unique<resource::Entry>( 9162337a92SDhruvaraj Subhashchandran bus, objPath.c_str(), id, timeStamp, size, dumpId, 9262337a92SDhruvaraj Subhashchandran std::string(), std::string(), 9362337a92SDhruvaraj Subhashchandran phosphor::dump::OperationStatus::Completed, *this))); 9462337a92SDhruvaraj Subhashchandran } 9562337a92SDhruvaraj Subhashchandran catch (const std::invalid_argument& e) 9662337a92SDhruvaraj Subhashchandran { 97858fbb2eSGeorge Liu log<level::ERR>(fmt::format("Error in creating resource dump entry, " 98858fbb2eSGeorge Liu "errormsg({}),OBJECTPATH({}),ID({})," 99858fbb2eSGeorge Liu "TIMESTAMP({}),SIZE({}),SOURCEID({})", 100363af249SGeorge Liu e.what(), objPath.c_str(), id, timeStamp, 101363af249SGeorge Liu size, dumpId) 102858fbb2eSGeorge Liu .c_str()); 10362337a92SDhruvaraj Subhashchandran report<InternalFailure>(); 10462337a92SDhruvaraj Subhashchandran return; 10562337a92SDhruvaraj Subhashchandran } 10662337a92SDhruvaraj Subhashchandran lastEntryId++; 10762337a92SDhruvaraj Subhashchandran } 10862337a92SDhruvaraj Subhashchandran 10962337a92SDhruvaraj Subhashchandran sdbusplus::message::object_path 110ddc3366eSDhruvaraj Subhashchandran Manager::createDump(phosphor::dump::DumpCreateParams params) 11162337a92SDhruvaraj Subhashchandran { 11262337a92SDhruvaraj Subhashchandran 11362337a92SDhruvaraj Subhashchandran using NotAllowed = 11462337a92SDhruvaraj Subhashchandran sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed; 11562337a92SDhruvaraj Subhashchandran using Reason = xyz::openbmc_project::Common::NotAllowed::REASON; 11662337a92SDhruvaraj Subhashchandran 11762337a92SDhruvaraj Subhashchandran // Allow creating resource dump only when the host is up. 11862337a92SDhruvaraj Subhashchandran if (!phosphor::dump::isHostRunning()) 11962337a92SDhruvaraj Subhashchandran { 12062337a92SDhruvaraj Subhashchandran elog<NotAllowed>( 12162337a92SDhruvaraj Subhashchandran Reason("Resource dump can be initiated only when the host is up")); 12262337a92SDhruvaraj Subhashchandran return std::string(); 12362337a92SDhruvaraj Subhashchandran } 124ddc3366eSDhruvaraj Subhashchandran 125ddc3366eSDhruvaraj Subhashchandran using InvalidArgument = 126ddc3366eSDhruvaraj Subhashchandran sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument; 127ddc3366eSDhruvaraj Subhashchandran using Argument = xyz::openbmc_project::Common::InvalidArgument; 12862337a92SDhruvaraj Subhashchandran using CreateParameters = 12962337a92SDhruvaraj Subhashchandran sdbusplus::com::ibm::Dump::server::Create::CreateParameters; 13062337a92SDhruvaraj Subhashchandran 13162337a92SDhruvaraj Subhashchandran auto id = lastEntryId + 1; 13262337a92SDhruvaraj Subhashchandran auto idString = std::to_string(id); 1333fc6df48SJayanth Othayoth auto objPath = std::filesystem::path(baseEntryPath) / idString; 134*c0ab9d43SClaire Weinan uint64_t timeStamp = 135*c0ab9d43SClaire Weinan std::chrono::duration_cast<std::chrono::microseconds>( 136*c0ab9d43SClaire Weinan std::chrono::system_clock::now().time_since_epoch()) 137*c0ab9d43SClaire Weinan .count(); 13862337a92SDhruvaraj Subhashchandran 139ddc3366eSDhruvaraj Subhashchandran std::string vspString; 140ddc3366eSDhruvaraj Subhashchandran auto iter = params.find( 141ddc3366eSDhruvaraj Subhashchandran sdbusplus::com::ibm::Dump::server::Create:: 142ddc3366eSDhruvaraj Subhashchandran convertCreateParametersToString(CreateParameters::VSPString)); 143ddc3366eSDhruvaraj Subhashchandran if (iter == params.end()) 144ddc3366eSDhruvaraj Subhashchandran { 145ddc3366eSDhruvaraj Subhashchandran // Host will generate a default dump if no resource selector string 146ddc3366eSDhruvaraj Subhashchandran // is provided. The default dump will be a non-disruptive system dump. 147ddc3366eSDhruvaraj Subhashchandran log<level::INFO>( 148ddc3366eSDhruvaraj Subhashchandran "VSP string is not provided, a non-disruptive system dump will be " 149ddc3366eSDhruvaraj Subhashchandran "generated by the host"); 150ddc3366eSDhruvaraj Subhashchandran } 151ddc3366eSDhruvaraj Subhashchandran else 152ddc3366eSDhruvaraj Subhashchandran { 153ddc3366eSDhruvaraj Subhashchandran try 154ddc3366eSDhruvaraj Subhashchandran { 155ddc3366eSDhruvaraj Subhashchandran vspString = std::get<std::string>(iter->second); 156ddc3366eSDhruvaraj Subhashchandran } 157ddc3366eSDhruvaraj Subhashchandran catch (const std::bad_variant_access& e) 158ddc3366eSDhruvaraj Subhashchandran { 159ddc3366eSDhruvaraj Subhashchandran // Exception will be raised if the input is not string 160ddc3366eSDhruvaraj Subhashchandran log<level::ERR>( 161ddc3366eSDhruvaraj Subhashchandran fmt::format("An invalid vsp string is passed errormsg({})", 162ddc3366eSDhruvaraj Subhashchandran e.what()) 163ddc3366eSDhruvaraj Subhashchandran .c_str()); 164ddc3366eSDhruvaraj Subhashchandran elog<InvalidArgument>(Argument::ARGUMENT_NAME("VSP_STRING"), 165ddc3366eSDhruvaraj Subhashchandran Argument::ARGUMENT_VALUE("INVALID INPUT")); 166ddc3366eSDhruvaraj Subhashchandran } 167ddc3366eSDhruvaraj Subhashchandran } 168ddc3366eSDhruvaraj Subhashchandran 169ddc3366eSDhruvaraj Subhashchandran std::string pwd; 170ddc3366eSDhruvaraj Subhashchandran iter = params.find( 171ddc3366eSDhruvaraj Subhashchandran sdbusplus::com::ibm::Dump::server::Create:: 172ddc3366eSDhruvaraj Subhashchandran convertCreateParametersToString(CreateParameters::Password)); 173ddc3366eSDhruvaraj Subhashchandran if (iter == params.end()) 174ddc3366eSDhruvaraj Subhashchandran { 175a5097b9eSDhruvaraj Subhashchandran log<level::INFO>("Password is not provided for resource dump"); 176ddc3366eSDhruvaraj Subhashchandran } 177a5097b9eSDhruvaraj Subhashchandran else 178a5097b9eSDhruvaraj Subhashchandran { 179ddc3366eSDhruvaraj Subhashchandran try 180ddc3366eSDhruvaraj Subhashchandran { 181ddc3366eSDhruvaraj Subhashchandran pwd = std::get<std::string>(iter->second); 182ddc3366eSDhruvaraj Subhashchandran } 183ddc3366eSDhruvaraj Subhashchandran catch (const std::bad_variant_access& e) 184ddc3366eSDhruvaraj Subhashchandran { 185ddc3366eSDhruvaraj Subhashchandran // Exception will be raised if the input is not string 186ddc3366eSDhruvaraj Subhashchandran log<level::ERR>( 187ddc3366eSDhruvaraj Subhashchandran fmt::format("An invalid password string is passed errormsg({})", 188ddc3366eSDhruvaraj Subhashchandran e.what()) 189ddc3366eSDhruvaraj Subhashchandran .c_str()); 190ddc3366eSDhruvaraj Subhashchandran elog<InvalidArgument>(Argument::ARGUMENT_NAME("PASSWORD"), 191ddc3366eSDhruvaraj Subhashchandran Argument::ARGUMENT_VALUE("INVALID INPUT")); 192ddc3366eSDhruvaraj Subhashchandran } 193a5097b9eSDhruvaraj Subhashchandran } 19462337a92SDhruvaraj Subhashchandran 19562337a92SDhruvaraj Subhashchandran try 19662337a92SDhruvaraj Subhashchandran { 19762337a92SDhruvaraj Subhashchandran entries.insert(std::make_pair( 19862337a92SDhruvaraj Subhashchandran id, std::make_unique<resource::Entry>( 19962337a92SDhruvaraj Subhashchandran bus, objPath.c_str(), id, timeStamp, 0, INVALID_SOURCE_ID, 20062337a92SDhruvaraj Subhashchandran vspString, pwd, phosphor::dump::OperationStatus::InProgress, 20162337a92SDhruvaraj Subhashchandran *this))); 20262337a92SDhruvaraj Subhashchandran } 20362337a92SDhruvaraj Subhashchandran catch (const std::invalid_argument& e) 20462337a92SDhruvaraj Subhashchandran { 205858fbb2eSGeorge Liu log<level::ERR>( 206858fbb2eSGeorge Liu fmt::format( 207858fbb2eSGeorge Liu "Error in creating resource dump " 208858fbb2eSGeorge Liu "entry,errormsg({}),OBJECTPATH({}), VSPSTRING({}), ID({})", 209363af249SGeorge Liu e.what(), objPath.c_str(), vspString, id) 210858fbb2eSGeorge Liu .c_str()); 21162337a92SDhruvaraj Subhashchandran elog<InternalFailure>(); 21262337a92SDhruvaraj Subhashchandran return std::string(); 21362337a92SDhruvaraj Subhashchandran } 21462337a92SDhruvaraj Subhashchandran lastEntryId++; 21562337a92SDhruvaraj Subhashchandran return objPath.string(); 21662337a92SDhruvaraj Subhashchandran } 21762337a92SDhruvaraj Subhashchandran 21862337a92SDhruvaraj Subhashchandran } // namespace resource 21962337a92SDhruvaraj Subhashchandran } // namespace dump 220341d683dSDhruvaraj Subhashchandran } // namespace openpower 221