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