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 invalid id update that. 32 // If there a completed one with same source id ignore it 33 // if there is no invalid id, create new entry 34 openpower::dump::resource::Entry* upEntry = NULL; 35 for (auto& entry : entries) 36 { 37 openpower::dump::resource::Entry* resEntry = 38 dynamic_cast<openpower::dump::resource::Entry*>(entry.second.get()); 39 40 // If there is already a completed entry with input source id then 41 // ignore this notification. 42 if ((resEntry->sourceDumpId() == dumpId) && 43 (resEntry->status() == phosphor::dump::OperationStatus::Completed)) 44 { 45 log<level::INFO>( 46 fmt::format("Resource dump entry with source dump id({}) is " 47 "already present with entry id({})", 48 dumpId, resEntry->getDumpId()) 49 .c_str()); 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 log<level::INFO>( 67 fmt::format("Resource Dump Notify: Updating dumpId({}) " 68 "with source Id({}) Size({})", 69 upEntry->getDumpId(), dumpId, size) 70 .c_str()); 71 upEntry->update(timeStamp, size, dumpId); 72 return; 73 } 74 75 // Get the id 76 auto id = lastEntryId + 1; 77 auto idString = std::to_string(id); 78 auto objPath = std::filesystem::path(baseEntryPath) / idString; 79 80 try 81 { 82 log<level::INFO>(fmt::format("Resouce Dump Notify: creating new dump " 83 "entry dumpId({}) Id({}) Size({})", 84 id, dumpId, size) 85 .c_str()); 86 entries.insert(std::make_pair( 87 id, std::make_unique<resource::Entry>( 88 bus, objPath.c_str(), id, timeStamp, size, dumpId, 89 std::string(), std::string(), 90 phosphor::dump::OperationStatus::Completed, *this))); 91 } 92 catch (const std::invalid_argument& e) 93 { 94 log<level::ERR>(fmt::format("Error in creating resource dump entry, " 95 "errormsg({}),OBJECTPATH({}),ID({})," 96 "TIMESTAMP({}),SIZE({}),SOURCEID({})", 97 e.what(), objPath.c_str(), id, timeStamp, 98 size, dumpId) 99 .c_str()); 100 report<InternalFailure>(); 101 return; 102 } 103 lastEntryId++; 104 } 105 106 sdbusplus::message::object_path 107 Manager::createDump(phosphor::dump::DumpCreateParams params) 108 { 109 110 using NotAllowed = 111 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed; 112 using Reason = xyz::openbmc_project::Common::NotAllowed::REASON; 113 114 // Allow creating resource dump only when the host is up. 115 if (!phosphor::dump::isHostRunning()) 116 { 117 elog<NotAllowed>( 118 Reason("Resource dump can be initiated only when the host is up")); 119 return std::string(); 120 } 121 122 using InvalidArgument = 123 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument; 124 using Argument = xyz::openbmc_project::Common::InvalidArgument; 125 using CreateParameters = 126 sdbusplus::com::ibm::Dump::server::Create::CreateParameters; 127 128 auto id = lastEntryId + 1; 129 auto idString = std::to_string(id); 130 auto objPath = std::filesystem::path(baseEntryPath) / idString; 131 std::time_t timeStamp = std::time(nullptr); 132 133 std::string vspString; 134 auto iter = params.find( 135 sdbusplus::com::ibm::Dump::server::Create:: 136 convertCreateParametersToString(CreateParameters::VSPString)); 137 if (iter == params.end()) 138 { 139 // Host will generate a default dump if no resource selector string 140 // is provided. The default dump will be a non-disruptive system dump. 141 log<level::INFO>( 142 "VSP string is not provided, a non-disruptive system dump will be " 143 "generated by the host"); 144 } 145 else 146 { 147 try 148 { 149 vspString = std::get<std::string>(iter->second); 150 } 151 catch (const std::bad_variant_access& e) 152 { 153 // Exception will be raised if the input is not string 154 log<level::ERR>( 155 fmt::format("An invalid vsp string is passed errormsg({})", 156 e.what()) 157 .c_str()); 158 elog<InvalidArgument>(Argument::ARGUMENT_NAME("VSP_STRING"), 159 Argument::ARGUMENT_VALUE("INVALID INPUT")); 160 } 161 } 162 163 std::string pwd; 164 iter = params.find( 165 sdbusplus::com::ibm::Dump::server::Create:: 166 convertCreateParametersToString(CreateParameters::Password)); 167 if (iter == params.end()) 168 { 169 log<level::INFO>("Password is not provided for resource dump"); 170 } 171 else 172 { 173 try 174 { 175 pwd = std::get<std::string>(iter->second); 176 } 177 catch (const std::bad_variant_access& e) 178 { 179 // Exception will be raised if the input is not string 180 log<level::ERR>( 181 fmt::format("An invalid password string is passed errormsg({})", 182 e.what()) 183 .c_str()); 184 elog<InvalidArgument>(Argument::ARGUMENT_NAME("PASSWORD"), 185 Argument::ARGUMENT_VALUE("INVALID INPUT")); 186 } 187 } 188 189 try 190 { 191 entries.insert(std::make_pair( 192 id, std::make_unique<resource::Entry>( 193 bus, objPath.c_str(), id, timeStamp, 0, INVALID_SOURCE_ID, 194 vspString, pwd, phosphor::dump::OperationStatus::InProgress, 195 *this))); 196 } 197 catch (const std::invalid_argument& e) 198 { 199 log<level::ERR>( 200 fmt::format( 201 "Error in creating resource dump " 202 "entry,errormsg({}),OBJECTPATH({}), VSPSTRING({}), ID({})", 203 e.what(), objPath.c_str(), vspString, id) 204 .c_str()); 205 elog<InternalFailure>(); 206 return std::string(); 207 } 208 lastEntryId++; 209 return objPath.string(); 210 } 211 212 } // namespace resource 213 } // namespace dump 214 } // namespace openpower 215