1 #pragma once
2 
3 #include "dump_utils.hpp"
4 #include "sbe_consts.hpp"
5 
6 #include <sys/wait.h>
7 #include <unistd.h>
8 
9 #include <phosphor-logging/lg2.hpp>
10 #include <sdbusplus/bus.hpp>
11 #include <sdbusplus/bus/match.hpp>
12 #include <xyz/openbmc_project/Common/Progress/common.hpp>
13 #include <xyz/openbmc_project/Dump/Entry/System/common.hpp>
14 
15 #include <iostream>
16 #include <string>
17 #include <variant>
18 
19 namespace openpower::dump
20 {
21 
22 using PropertyMap = std::map<std::string, std::variant<uint32_t, std::string>>;
23 using InterfaceMap = std::map<std::string, PropertyMap>;
24 
25 /**
26  * @class DumpMonitor
27  * @brief Monitors DBus signals for dump creation and handles them.
28  */
29 class DumpMonitor
30 {
31   public:
32     /**
33      * @brief Constructor for DumpMonitor.
34      * Initializes the DBus connection and signal match for monitoring dump
35      * creation.
36      */
37     DumpMonitor() :
38         bus(sdbusplus::bus::new_default()),
39         match(bus,
40               sdbusplus::bus::match::rules::interfacesAdded(
41                   "/xyz/openbmc_project/dump") +
42                   sdbusplus::bus::match::rules::sender(
43                       "xyz.openbmc_project.Dump.Manager"),
44               [this](sdbusplus::message_t& msg) { handleDBusSignal(msg); })
45     {}
46 
47     /**
48      * @brief Runs the monitor to continuously listen for DBus signals.
49      */
50     void run()
51     {
52         bus.process_loop();
53     }
54 
55   private:
56     /* @brief sdbusplus handler for a bus to use */
57     sdbusplus::bus_t bus;
58 
59     /* @brief Monitores dump interfaces */
60     const std::vector<std::string> monitoredInterfaces = {
61         "com.ibm.Dump.Entry.Hardware", "com.ibm.Dump.Entry.Hostboot",
62         "com.ibm.Dump.Entry.SBE", "xyz.openbmc_project.Dump.Entry.System"};
63 
64     /* @brief InterfaceAdded match */
65     sdbusplus::bus::match_t match;
66 
67     /**
68      * @brief Handles the received DBus signal for dump creation.
69      * @param[in] msg - The DBus message received.
70      */
71     void handleDBusSignal(sdbusplus::message_t& msg);
72 
73     /**
74      * @brief Checks if the dump creation is in progress.
75      * @param[in] interfaces - The map of interfaces and their properties.
76      * @return True if the dump is in progress, false otherwise.
77      */
78     inline bool isInProgress(const InterfaceMap& interfaces)
79     {
80         using namespace sdbusplus::common::xyz::openbmc_project::common;
81         auto progressIt = interfaces.find(Progress::interface);
82         if (progressIt != interfaces.end())
83         {
84             auto statusIt = progressIt->second.find("Status");
85             if (statusIt != progressIt->second.end())
86             {
87                 std::string status = std::get<std::string>(statusIt->second);
88                 return status == Progress::convertOperationStatusToString(
89                                      Progress::OperationStatus::InProgress);
90             }
91         }
92         return false;
93     }
94 
95     /**
96      * @brief Executes the script to collect the dump.
97      * @param[in] path - The object path of the dump entry.
98      * @param[in] properties - The properties of the dump entry.
99      */
100     void executeCollectionScript(const sdbusplus::message::object_path& path,
101                                  const PropertyMap& properties);
102 
103     /**
104      * @brief Updates the progress status of the dump.
105      * @param[in] path - The object path of the dump entry.
106      * @param[in] status - The status to be set.
107      */
108     void updateProgressStatus(const std::string& path,
109                               const std::string& status);
110 
111     /**
112      * @brief Gets the dump type from the dump ID.
113      * @param[in] id - The dump ID.
114      * @return The dump type.
115      */
116     inline uint32_t getDumpTypeFromId(uint32_t id)
117     {
118         using namespace openpower::dump::SBE;
119         uint8_t type = (id >> 28) & 0xF;
120         if (type == 0)
121         {
122             return SBE_DUMP_TYPE_HARDWARE;
123         }
124         else if (type == 2)
125         {
126             return SBE_DUMP_TYPE_HOSTBOOT;
127         }
128         else if (type == 3)
129         {
130             return SBE_DUMP_TYPE_SBE;
131         }
132         else if (type == 4)
133         {
134             return SBE_DUMP_TYPE_MSBE;
135         }
136         return 0;
137     }
138 
139     /**
140      * @brief Initiates the dump collection process based on the given interface
141      *        and properties.
142      *
143      * @param[in] path The object path of the dump entry.
144      * @param[in] intf The interface type of the dump entry.
145      * @param[in] properties The properties of the dump entry.
146      */
147     void initiateDumpCollection(const std::string& path,
148                                 const std::string& intf,
149                                 const PropertyMap& properties);
150 
151     /**
152      * @brief Initiates a memory-preserving reboot by starting the
153      *        appropriate systemd unit.
154      */
155     void startMpReboot(const sdbusplus::message::object_path& objectPath);
156 };
157 
158 } // namespace openpower::dump
159