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 <phosphor-logging/elog-errors.hpp> 11 #include <phosphor-logging/elog.hpp> 12 #include <phosphor-logging/lg2.hpp> 13 14 namespace openpower 15 { 16 namespace dump 17 { 18 namespace resource 19 { 20 21 using namespace phosphor::logging; 22 using InternalFailure = 23 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; 24 25 void Manager::notify(uint32_t dumpId, uint64_t size) 26 { 27 // Get the timestamp 28 uint64_t timeStamp = 29 std::chrono::duration_cast<std::chrono::microseconds>( 30 std::chrono::system_clock::now().time_since_epoch()) 31 .count(); 32 33 // If there is an entry with invalid id update that. 34 // If there a completed one with same source id ignore it 35 // if there is no invalid id, create new entry 36 openpower::dump::resource::Entry* upEntry = NULL; 37 for (auto& entry : entries) 38 { 39 openpower::dump::resource::Entry* resEntry = 40 dynamic_cast<openpower::dump::resource::Entry*>(entry.second.get()); 41 42 // If there is already a completed entry with input source id then 43 // ignore this notification. 44 if ((resEntry->sourceDumpId() == dumpId) && 45 (resEntry->status() == phosphor::dump::OperationStatus::Completed)) 46 { 47 lg2::info("Resource dump entry with source dump id: {DUMP_ID} " 48 "is already present with entry id: {ENTRY_ID}", 49 "DUMP_ID", dumpId, "ENTRY_ID", resEntry->getDumpId()); 50 return; 51 } 52 53 // Save the first entry with INVALID_SOURCE_ID 54 // but continue in the loop to make sure the 55 // new entry is not duplicate 56 if ((resEntry->status() == 57 phosphor::dump::OperationStatus::InProgress) && 58 (resEntry->sourceDumpId() == INVALID_SOURCE_ID) && 59 (upEntry == NULL)) 60 { 61 upEntry = resEntry; 62 } 63 } 64 if (upEntry != NULL) 65 { 66 lg2::info("Resource Dump Notify: Updating dumpId: {DUMP_ID} with " 67 "source Id: {SOURCE_ID} Size: {SIZE}", 68 "DUMP_ID", upEntry->getDumpId(), "SOURCE_ID", dumpId, "SIZE", 69 size); 70 upEntry->update(timeStamp, size, dumpId); 71 return; 72 } 73 74 // Get the id 75 auto id = lastEntryId + 1; 76 auto idString = std::to_string(id); 77 auto objPath = std::filesystem::path(baseEntryPath) / idString; 78 79 // TODO: Get the originator Id, type from the persisted file. 80 // For now replacing it with null 81 82 try 83 { 84 lg2::info( 85 "Resouce Dump Notify: creating new dump entry dumpId: {DUMP_ID} " 86 "Id: {ID} Size: {SIZE}", 87 "DUMP_ID", id, "ID", dumpId, "SIZE", size); 88 entries.insert(std::make_pair( 89 id, std::make_unique<resource::Entry>( 90 bus, objPath.c_str(), id, timeStamp, size, dumpId, 91 std::string(), std::string(), 92 phosphor::dump::OperationStatus::Completed, std::string(), 93 originatorTypes::Internal, *this))); 94 } 95 catch (const std::invalid_argument& e) 96 { 97 lg2::error( 98 "Error in creating resource dump entry, errormsg: {ERROR}, " 99 "OBJECTPATH: {OBJECT_PATH}, ID: {ID}, TIMESTAMP: {TIMESTAMP}, " 100 "SIZE: {SIZE}, SOURCEID: {SOURCE_ID}", 101 "ERROR", e, "OBJECT_PATH", objPath, "ID", id, "TIMESTAMP", 102 timeStamp, "SIZE", size, "SOURCE_ID", dumpId); 103 report<InternalFailure>(); 104 return; 105 } 106 lastEntryId++; 107 } 108 109 sdbusplus::message::object_path 110 Manager::createDump(phosphor::dump::DumpCreateParams params) 111 { 112 using NotAllowed = 113 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed; 114 using Reason = xyz::openbmc_project::Common::NotAllowed::REASON; 115 116 // Allow creating resource dump only when the host is up. 117 if (!phosphor::dump::isHostRunning()) 118 { 119 elog<NotAllowed>( 120 Reason("Resource dump can be initiated only when the host is up")); 121 return std::string(); 122 } 123 124 using InvalidArgument = 125 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument; 126 using Argument = xyz::openbmc_project::Common::InvalidArgument; 127 using CreateParameters = 128 sdbusplus::com::ibm::Dump::server::Create::CreateParameters; 129 130 auto id = lastEntryId + 1; 131 auto idString = std::to_string(id); 132 auto objPath = std::filesystem::path(baseEntryPath) / idString; 133 uint64_t timeStamp = 134 std::chrono::duration_cast<std::chrono::microseconds>( 135 std::chrono::system_clock::now().time_since_epoch()) 136 .count(); 137 138 std::string vspString; 139 auto iter = params.find( 140 sdbusplus::com::ibm::Dump::server::Create:: 141 convertCreateParametersToString(CreateParameters::VSPString)); 142 if (iter == params.end()) 143 { 144 // Host will generate a default dump if no resource selector string 145 // is provided. The default dump will be a non-disruptive system dump. 146 lg2::info( 147 "VSP string is not provided, a non-disruptive system dump will be " 148 "generated by the host"); 149 } 150 else 151 { 152 try 153 { 154 vspString = std::get<std::string>(iter->second); 155 } 156 catch (const std::bad_variant_access& e) 157 { 158 // Exception will be raised if the input is not string 159 lg2::error("An invalid vsp string is passed, errormsg: {ERROR}", 160 "ERROR", e); 161 elog<InvalidArgument>(Argument::ARGUMENT_NAME("VSP_STRING"), 162 Argument::ARGUMENT_VALUE("INVALID INPUT")); 163 } 164 } 165 166 std::string pwd; 167 iter = params.find( 168 sdbusplus::com::ibm::Dump::server::Create:: 169 convertCreateParametersToString(CreateParameters::Password)); 170 if (iter == params.end()) 171 { 172 lg2::info("Password is not provided for resource dump"); 173 } 174 else 175 { 176 try 177 { 178 pwd = std::get<std::string>(iter->second); 179 } 180 catch (const std::bad_variant_access& e) 181 { 182 // Exception will be raised if the input is not string 183 lg2::error( 184 "An invalid password string is passed, errormsg: {ERROR}", 185 "ERROR", e); 186 elog<InvalidArgument>(Argument::ARGUMENT_NAME("PASSWORD"), 187 Argument::ARGUMENT_VALUE("INVALID INPUT")); 188 } 189 } 190 191 // Get the originator id and type from params 192 std::string originatorId; 193 originatorTypes originatorType; 194 195 phosphor::dump::extractOriginatorProperties(params, originatorId, 196 originatorType); 197 198 try 199 { 200 entries.insert(std::make_pair( 201 id, std::make_unique<resource::Entry>( 202 bus, objPath.c_str(), id, timeStamp, 0, INVALID_SOURCE_ID, 203 vspString, pwd, phosphor::dump::OperationStatus::InProgress, 204 originatorId, originatorType, *this))); 205 } 206 catch (const std::invalid_argument& e) 207 { 208 lg2::error( 209 "Error in creating resource dump entry, errormsg: {ERROR}, " 210 "OBJECTPATH: {OBJECT_PATH}, VSPSTRING: {VSP_STRING}, ID: {ID}", 211 "ERROR", e, "OBJECT_PATH", objPath, "VSP_STRING", vspString, "ID", 212 id); 213 elog<InternalFailure>(); 214 return std::string(); 215 } 216 lastEntryId++; 217 return objPath.string(); 218 } 219 220 } // namespace resource 221 } // namespace dump 222 } // namespace openpower 223