1 #include "config.h" 2 3 #include "dump_manager_resource.hpp" 4 5 #include "dump_utils.hpp" 6 #include "op_dump_consts.hpp" 7 #include "resource_dump_entry.hpp" 8 #include "xyz/openbmc_project/Common/error.hpp" 9 10 #include <fmt/core.h> 11 12 #include <phosphor-logging/elog-errors.hpp> 13 #include <phosphor-logging/elog.hpp> 14 15 namespace openpower 16 { 17 namespace dump 18 { 19 namespace resource 20 { 21 22 using namespace phosphor::logging; 23 using InternalFailure = 24 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; 25 26 void Manager::notify(uint32_t dumpId, uint64_t size) 27 { 28 // Get the timestamp 29 std::time_t timeStamp = std::time(nullptr); 30 31 // If there is an entry with this sourceId or an invalid id 32 // update that. 33 // If host is sending the source id before the completion 34 // the source id will be updated by the transport layer with host. 35 // if not the source id will stay as invalid one. 36 for (auto& entry : entries) 37 { 38 openpower::dump::resource::Entry* resEntry = 39 dynamic_cast<openpower::dump::resource::Entry*>(entry.second.get()); 40 if ((resEntry->status() == 41 phosphor::dump::OperationStatus::InProgress) && 42 ((resEntry->sourceDumpId() == dumpId) || 43 (resEntry->sourceDumpId() == INVALID_SOURCE_ID))) 44 { 45 resEntry->update(timeStamp, size, dumpId); 46 return; 47 } 48 } 49 // Get the id 50 auto id = lastEntryId + 1; 51 auto idString = std::to_string(id); 52 auto objPath = std::filesystem::path(baseEntryPath) / idString; 53 54 try 55 { 56 entries.insert(std::make_pair( 57 id, std::make_unique<resource::Entry>( 58 bus, objPath.c_str(), id, timeStamp, size, dumpId, 59 std::string(), std::string(), 60 phosphor::dump::OperationStatus::Completed, *this))); 61 } 62 catch (const std::invalid_argument& e) 63 { 64 log<level::ERR>(fmt::format("Error in creating resource dump entry, " 65 "errormsg({}),OBJECTPATH({}),ID({})," 66 "TIMESTAMP({}),SIZE({}),SOURCEID({})", 67 e.what(), objPath.c_str(), id, timeStamp, 68 size, dumpId) 69 .c_str()); 70 report<InternalFailure>(); 71 return; 72 } 73 lastEntryId++; 74 } 75 76 sdbusplus::message::object_path 77 Manager::createDump(phosphor::dump::DumpCreateParams params) 78 { 79 80 using NotAllowed = 81 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed; 82 using Reason = xyz::openbmc_project::Common::NotAllowed::REASON; 83 84 // Allow creating resource dump only when the host is up. 85 if (!phosphor::dump::isHostRunning()) 86 { 87 elog<NotAllowed>( 88 Reason("Resource dump can be initiated only when the host is up")); 89 return std::string(); 90 } 91 92 using InvalidArgument = 93 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument; 94 using Argument = xyz::openbmc_project::Common::InvalidArgument; 95 using CreateParameters = 96 sdbusplus::com::ibm::Dump::server::Create::CreateParameters; 97 98 auto id = lastEntryId + 1; 99 auto idString = std::to_string(id); 100 auto objPath = std::filesystem::path(baseEntryPath) / idString; 101 std::time_t timeStamp = std::time(nullptr); 102 103 std::string vspString; 104 auto iter = params.find( 105 sdbusplus::com::ibm::Dump::server::Create:: 106 convertCreateParametersToString(CreateParameters::VSPString)); 107 if (iter == params.end()) 108 { 109 // Host will generate a default dump if no resource selector string 110 // is provided. The default dump will be a non-disruptive system dump. 111 log<level::INFO>( 112 "VSP string is not provided, a non-disruptive system dump will be " 113 "generated by the host"); 114 } 115 else 116 { 117 try 118 { 119 vspString = std::get<std::string>(iter->second); 120 } 121 catch (const std::bad_variant_access& e) 122 { 123 // Exception will be raised if the input is not string 124 log<level::ERR>( 125 fmt::format("An invalid vsp string is passed errormsg({})", 126 e.what()) 127 .c_str()); 128 elog<InvalidArgument>(Argument::ARGUMENT_NAME("VSP_STRING"), 129 Argument::ARGUMENT_VALUE("INVALID INPUT")); 130 } 131 } 132 133 std::string pwd; 134 iter = params.find( 135 sdbusplus::com::ibm::Dump::server::Create:: 136 convertCreateParametersToString(CreateParameters::Password)); 137 if (iter == params.end()) 138 { 139 log<level::ERR>("Required argument password is missing"); 140 elog<InvalidArgument>(Argument::ARGUMENT_NAME("PASSOWORD"), 141 Argument::ARGUMENT_VALUE("MISSING")); 142 } 143 144 try 145 { 146 pwd = std::get<std::string>(iter->second); 147 } 148 catch (const std::bad_variant_access& e) 149 { 150 // Exception will be raised if the input is not string 151 log<level::ERR>( 152 fmt::format("An invalid password string is passed errormsg({})", 153 e.what()) 154 .c_str()); 155 elog<InvalidArgument>(Argument::ARGUMENT_NAME("PASSWORD"), 156 Argument::ARGUMENT_VALUE("INVALID INPUT")); 157 } 158 159 try 160 { 161 entries.insert(std::make_pair( 162 id, std::make_unique<resource::Entry>( 163 bus, objPath.c_str(), id, timeStamp, 0, INVALID_SOURCE_ID, 164 vspString, pwd, phosphor::dump::OperationStatus::InProgress, 165 *this))); 166 } 167 catch (const std::invalid_argument& e) 168 { 169 log<level::ERR>( 170 fmt::format( 171 "Error in creating resource dump " 172 "entry,errormsg({}),OBJECTPATH({}), VSPSTRING({}), ID({})", 173 e.what(), objPath.c_str(), vspString, id) 174 .c_str()); 175 elog<InternalFailure>(); 176 return std::string(); 177 } 178 lastEntryId++; 179 return objPath.string(); 180 } 181 182 } // namespace resource 183 } // namespace dump 184 } // namespace openpower 185