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