1 #include "config.h"
2 
3 #include "core_manager.hpp"
4 
5 #include <phosphor-logging/lg2.hpp>
6 #include <sdbusplus/exception.hpp>
7 
8 #include <filesystem>
9 #include <regex>
10 
11 namespace phosphor
12 {
13 namespace dump
14 {
15 namespace core
16 {
17 
18 using namespace std;
19 
20 void Manager::watchCallback(const UserMap& fileInfo)
21 {
22     vector<string> files;
23 
24     for (const auto& i : fileInfo)
25     {
26         std::filesystem::path file(i.first);
27         std::string name = file.filename();
28 
29         /*
30           As per coredump source code systemd-coredump uses below format
31           https://github.com/systemd/systemd/blob/master/src/coredump/coredump.c
32           /var/lib/systemd/coredump/core.%s.%s." SD_ID128_FORMAT_STR “
33           systemd-coredump also creates temporary file in core file path prior
34           to actual core file creation. Checking the file name format will help
35           to limit dump creation only for the new core files.
36         */
37         if ("core" == name.substr(0, name.find('.')))
38         {
39             // Consider only file name start with "core."
40             files.push_back(file);
41         }
42     }
43 
44     if (!files.empty())
45     {
46         createHelper(files);
47     }
48 }
49 
50 void Manager::createHelper(const vector<string>& files)
51 {
52     constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
53     constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
54     constexpr auto MAPPER_INTERFACE = "xyz.openbmc_project.ObjectMapper";
55     constexpr auto DUMP_CREATE_IFACE = "xyz.openbmc_project.Dump.Create";
56 
57     auto b = sdbusplus::bus::new_default();
58     auto mapper = b.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
59                                     MAPPER_INTERFACE, "GetObject");
60     mapper.append(BMC_DUMP_OBJPATH, vector<string>({DUMP_CREATE_IFACE}));
61 
62     map<string, vector<string>> mapperResponse;
63     try
64     {
65         auto mapperResponseMsg = b.call(mapper);
66         mapperResponseMsg.read(mapperResponse);
67     }
68     catch (const sdbusplus::exception_t& e)
69     {
70         lg2::error("Failed to GetObject on Dump.Create: {ERROR}", "ERROR", e);
71         return;
72     }
73     if (mapperResponse.empty())
74     {
75         lg2::error("Error reading mapper response");
76         return;
77     }
78 
79     const auto& host = mapperResponse.cbegin()->first;
80     auto m = b.new_method_call(host.c_str(), BMC_DUMP_OBJPATH,
81                                DUMP_CREATE_IFACE, "CreateDump");
82     phosphor::dump::DumpCreateParams params;
83     using CreateParameters =
84         sdbusplus::common::xyz::openbmc_project::dump::Create::CreateParameters;
85     using DumpType =
86         sdbusplus::common::xyz::openbmc_project::dump::Create::DumpType;
87     using DumpIntr = sdbusplus::common::xyz::openbmc_project::dump::Create;
88     params[DumpIntr::convertCreateParametersToString(
89         CreateParameters::DumpType)] =
90         DumpIntr::convertDumpTypeToString(DumpType::ApplicationCored);
91     params[DumpIntr::convertCreateParametersToString(
92         CreateParameters::FilePath)] = files.front();
93     m.append(params);
94     try
95     {
96         b.call_noreply(m);
97     }
98     catch (const sdbusplus::exception_t& e)
99     {
100         lg2::error("Failed to create dump: {ERROR}", "ERROR", e);
101     }
102 }
103 
104 } // namespace core
105 } // namespace dump
106 } // namespace phosphor
107