xref: /openbmc/phosphor-debug-collector/ramoops_manager.cpp (revision ceba1f07c434d8d766e9f12f6adc26170d22ec1a)
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