1 #include "config.h" 2 3 #include "ramoops_manager.hpp" 4 5 #include "dump_manager.hpp" 6 7 #include <phosphor-logging/elog-errors.hpp> 8 #include <phosphor-logging/lg2.hpp> 9 #include <sdbusplus/bus.hpp> 10 #include <sdbusplus/exception.hpp> 11 #include <xyz/openbmc_project/Dump/Create/common.hpp> 12 #include <xyz/openbmc_project/Dump/Create/server.hpp> 13 14 #include <filesystem> 15 #include <set> 16 17 namespace phosphor 18 { 19 namespace dump 20 { 21 namespace ramoops 22 { 23 24 Manager::Manager(const std::string& filePath) 25 { 26 namespace fs = std::filesystem; 27 28 fs::path dir(filePath); 29 if (!fs::exists(dir) || fs::is_empty(dir)) 30 { 31 return; 32 } 33 34 // Create error to notify user that a ramoops has been detected 35 createError(); 36 37 std::vector<std::string> files; 38 files.push_back(filePath); 39 40 createHelper(files); 41 } 42 43 void Manager::createError() 44 { 45 try 46 { 47 std::map<std::string, std::string> additionalData; 48 49 // Always add the _PID on for some extra logging debug 50 additionalData.emplace("_PID", std::to_string(getpid())); 51 52 auto bus = sdbusplus::bus::new_default(); 53 auto method = bus.new_method_call( 54 "xyz.openbmc_project.Logging", "/xyz/openbmc_project/logging", 55 "xyz.openbmc_project.Logging.Create", "Create"); 56 57 method.append("xyz.openbmc_project.Dump.Error.Ramoops", 58 sdbusplus::server::xyz::openbmc_project::logging::Entry:: 59 Level::Error, 60 additionalData); 61 auto resp = bus.call(method); 62 } 63 catch (const sdbusplus::exception_t& e) 64 { 65 lg2::error( 66 "sdbusplus D-Bus call exception, error {ERROR} trying to create " 67 "an error for ramoops detection", 68 "ERROR", e); 69 // This is a best-effort logging situation so don't throw anything 70 } 71 catch (const std::exception& e) 72 { 73 lg2::error("D-bus call exception: {ERROR}", "ERROR", e); 74 // This is a best-effort logging situation so don't throw anything 75 } 76 } 77 78 void Manager::createHelper(const std::vector<std::string>& files) 79 { 80 constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper"; 81 constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper"; 82 constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper"; 83 constexpr auto DUMP_CREATE_IFACE = "xyz.openbmc_project.Dump.Create"; 84 85 auto b = sdbusplus::bus::new_default(); 86 auto mapper = b.new_method_call(MAPPER_BUSNAME, MAPPER_PATH, 87 MAPPER_INTERFACE, "GetObject"); 88 mapper.append(BMC_DUMP_OBJPATH, std::set<std::string>({DUMP_CREATE_IFACE})); 89 90 std::map<std::string, std::set<std::string>> mapperResponse; 91 try 92 { 93 auto mapperResponseMsg = b.call(mapper); 94 mapperResponseMsg.read(mapperResponse); 95 } 96 catch (const sdbusplus::exception_t& e) 97 { 98 lg2::error("Failed to parse dump create message, error: {ERROR}", 99 "ERROR", e); 100 return; 101 } 102 if (mapperResponse.empty()) 103 { 104 lg2::error("Error reading mapper response"); 105 return; 106 } 107 108 const auto& host = mapperResponse.cbegin()->first; 109 auto m = b.new_method_call(host.c_str(), BMC_DUMP_OBJPATH, 110 DUMP_CREATE_IFACE, "CreateDump"); 111 phosphor::dump::DumpCreateParams params; 112 using CreateParameters = 113 sdbusplus::common::xyz::openbmc_project::dump::Create::CreateParameters; 114 using DumpType = 115 sdbusplus::common::xyz::openbmc_project::dump::Create::DumpType; 116 using DumpIntr = sdbusplus::common::xyz::openbmc_project::dump::Create; 117 params[DumpIntr::convertCreateParametersToString( 118 CreateParameters::DumpType)] = 119 DumpIntr::convertDumpTypeToString(DumpType::Ramoops); 120 params[DumpIntr::convertCreateParametersToString( 121 CreateParameters::FilePath)] = files.front(); 122 m.append(params); 123 try 124 { 125 b.call_noreply(m); 126 } 127 catch (const sdbusplus::exception_t& e) 128 { 129 lg2::error("Failed to create ramoops dump, errormsg: {ERROR}", "ERROR", 130 e); 131 } 132 } 133 134 } // namespace ramoops 135 } // namespace dump 136 } // namespace phosphor 137