1 #include "dump_utils.hpp" 2 3 #include <phosphor-logging/elog-errors.hpp> 4 #include <phosphor-logging/elog.hpp> 5 #include <phosphor-logging/lg2.hpp> 6 #include <phosphor-logging/log.hpp> 7 #include <xyz/openbmc_project/Common/File/error.hpp> 8 9 #include <format> 10 #include <fstream> 11 #include <string> 12 13 namespace openpower::dump::util 14 { 15 using namespace phosphor::logging; 16 17 static void monitorDumpCreation(const std::string& path, const uint32_t timeout) 18 { 19 bool inProgress = true; 20 auto bus = sdbusplus::bus::new_system(); 21 auto match = sdbusplus::bus::match_t( 22 bus, 23 sdbusplus::bus::match::rules::propertiesChanged( 24 path, "xyz.openbmc_project.Common.Progress"), 25 [&](sdbusplus::message_t& msg) { 26 std::string interface; 27 std::map<std::string, std::variant<std::string, uint8_t>> property; 28 msg.read(interface, property); 29 30 const auto dumpStatus = property.find("Status"); 31 if (dumpStatus != property.end()) 32 { 33 const std::string* status = 34 std::get_if<std::string>(&(dumpStatus->second)); 35 if (status && 36 *status != 37 "xyz.openbmc_project.Common.Progress.OperationStatus.InProgress") 38 { 39 lg2::info("Dump status({STATUS}) : path={PATH}", "STATUS", 40 status->c_str(), "PATH", path.c_str()); 41 inProgress = false; 42 } 43 } 44 }); 45 46 // Timeout management 47 for (uint32_t secondsCount = 0; inProgress && secondsCount < timeout; 48 ++secondsCount) 49 { 50 bus.wait(std::chrono::seconds(1)); 51 bus.process_discard(); 52 } 53 54 if (inProgress) 55 { 56 lg2::error("Dump progress timeout; dump may not be complete."); 57 } 58 } 59 60 void requestSBEDump(const uint32_t failingUnit, const uint32_t eid, 61 SBETypes sbeType) 62 { 63 lg2::info( 64 "Requesting Dump PEL({EID}) chip({CHIPTYPE}) position({FAILINGUNIT})", 65 "EID", eid, "CHIPTYPE", sbeTypeAttributes.at(sbeType).chipName, 66 "FAILINGUNIT", failingUnit); 67 68 auto path = sbeTypeAttributes.at(sbeType).dumpPath.c_str(); 69 constexpr auto interface = "xyz.openbmc_project.Dump.Create"; 70 constexpr auto function = "CreateDump"; 71 72 try 73 { 74 auto bus = sdbusplus::bus::new_default(); 75 auto service = getService(bus, interface, path); 76 auto method = bus.new_method_call(service.c_str(), path, interface, 77 function); 78 79 std::unordered_map<std::string, std::variant<std::string, uint64_t>> 80 createParams = { 81 {"com.ibm.Dump.Create.CreateParameters.ErrorLogId", 82 uint64_t(eid)}, 83 {"com.ibm.Dump.Create.CreateParameters.FailingUnitId", 84 uint64_t(failingUnit)}}; 85 86 method.append(createParams); 87 sdbusplus::message::object_path reply; 88 bus.call(method).read(reply); 89 90 monitorDumpCreation(reply.str, SBE_DUMP_TIMEOUT); 91 } 92 catch (const sdbusplus::exception_t& e) 93 { 94 lg2::error("D-Bus call createDump exception OBJPATH={OBJPATH}, " 95 "INTERFACE={INTERFACE}, EXCEPTION={ERROR}", 96 "OBJPATH", path, "INTERFACE", interface, "ERROR", e); 97 constexpr auto ERROR_DUMP_DISABLED = 98 "xyz.openbmc_project.Dump.Create.Error.Disabled"; 99 if (e.name() == ERROR_DUMP_DISABLED) 100 { 101 // Dump is disabled, Skip the dump collection. 102 lg2::info("Dump is disabled unit({FAILINGUNIT}), " 103 "skipping dump collection", 104 "FAILINGUNIT", failingUnit); 105 } 106 else 107 { 108 throw; 109 } 110 } 111 catch (const std::exception& e) 112 { 113 throw e; 114 } 115 } 116 117 std::string getService(sdbusplus::bus_t& bus, const std::string& intf, 118 const std::string& path) 119 { 120 constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper"; 121 constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper"; 122 constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper"; 123 try 124 { 125 auto mapper = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH, 126 MAPPER_INTERFACE, "GetObject"); 127 128 mapper.append(path, std::vector<std::string>({intf})); 129 130 auto mapperResponseMsg = bus.call(mapper); 131 std::map<std::string, std::vector<std::string>> mapperResponse; 132 mapperResponseMsg.read(mapperResponse); 133 134 if (mapperResponse.empty()) 135 { 136 lg2::error( 137 "Empty mapper response for GetObject interface({INTERFACE}), " 138 "path({PATH})", 139 "INTERFACE", intf, "PATH", path); 140 141 throw std::runtime_error("Empty mapper response for GetObject"); 142 } 143 return mapperResponse.begin()->first; 144 } 145 catch (const sdbusplus::exception_t& ex) 146 { 147 lg2::error( 148 "Mapper call failed for GetObject errorMsg({ERROR}), path({PATH})," 149 "interface({INTERFACE})", 150 "ERROR", ex, "PATH", path, "INTERFACE", intf); 151 152 throw; 153 } 154 } 155 156 } // namespace openpower::dump::util 157