xref: /openbmc/openpower-debug-collector/watchdog/watchdog_handler.cpp (revision 1ac6162de47ecf1648e477f21b89b6182fa91f02)
1 #include <phosphor-logging/log.hpp>
2 #include <sdbusplus/bus.hpp>
3 #include <sdbusplus/bus/match.hpp>
4 #include <watchdog_dbus.hpp>
5 #include <watchdog_handler.hpp>
6 #include <watchdog_logging.hpp>
7 
8 namespace watchdog
9 {
10 namespace dump
11 {
12 
13 using namespace phosphor::logging;
14 
15 /**
16  * @brief Callback for dump request properties change signal monitor
17  *
18  * @param msg - dbus message from the dbus match infrastructure
19  * @param path - the object path we are monitoring
20  * @param inProgress - used to break out of our dbus wait loop
21  * @return Always non-zero indicating no error, no cascading callbacks
22  */
23 uint dumpStatusChanged(sdbusplus::message::message& msg, std::string path,
24                        bool& inProgress)
25 {
26     // reply (msg) will be a property change message
27     std::string interface;
28     std::map<std::string, std::variant<std::string, uint8_t>> property;
29     msg.read(interface, property);
30 
31     // looking for property Status changes
32     std::string propertyType = "Status";
33     auto dumpStatus = property.find(propertyType);
34 
35     if (dumpStatus != property.end())
36     {
37         const std::string* status =
38             std::get_if<std::string>(&(dumpStatus->second));
39 
40         if ((nullptr != status) && ("xyz.openbmc_project.Common.Progress."
41                                     "OperationStatus.InProgress" != *status))
42         {
43             // dump is done, trace some info and change in progress flag
44             log<level::INFO>(path.c_str());
45             log<level::INFO>((*status).c_str());
46             inProgress = false;
47         }
48     }
49 
50     return 1; // non-negative return code for successful callback
51 }
52 
53 /**
54  * @brief Register a callback for dump progress status changes
55  *
56  * @param path - the object path of the dump to monitor
57  * @param timeout - timeout - timeout interval in seconds
58  */
59 void monitorDump(const std::string& path, const uint32_t timeout)
60 {
61     bool inProgress = true; // callback will update this
62 
63     // setup the signal match rules and callback
64     std::string matchInterface = "xyz.openbmc_project.Common.Progress";
65     auto bus = sdbusplus::bus::new_system();
66 
67     std::unique_ptr<sdbusplus::bus::match_t> match =
68         std::make_unique<sdbusplus::bus::match_t>(
69             bus,
70             sdbusplus::bus::match::rules::propertiesChanged(
71                 path.c_str(), matchInterface.c_str()),
72             [&](auto& msg) {
73                 return dumpStatusChanged(msg, path, inProgress);
74             });
75 
76     // wait for dump status to be completed (complete == true)
77     // or until timeout interval
78     log<level::INFO>("hbdump requested");
79     bool timedOut = false;
80     uint32_t secondsCount = 0;
81     while ((true == inProgress) && !timedOut)
82     {
83         bus.wait(std::chrono::seconds(1));
84         bus.process_discard();
85 
86         if (++secondsCount == timeout)
87         {
88             timedOut = true;
89         }
90     }
91 
92     if (timedOut)
93     {
94         log<level::ERR>("hbdump dump progress status did not change to "
95                         "complete within the timeout interval, exiting...");
96     }
97     else
98     {
99         log<level::INFO>("hbdump completed");
100     }
101 }
102 
103 void requestDump(const uint32_t logId, const uint32_t timeout)
104 {
105     constexpr auto path = "/org/openpower/dump";
106     constexpr auto interface = "xyz.openbmc_project.Dump.Create";
107     constexpr auto function = "CreateDump";
108 
109     sdbusplus::message::message method;
110 
111     if (0 == dbusMethod(path, interface, function, method))
112     {
113         try
114         {
115             // dbus call arguments
116             std::map<std::string, std::variant<std::string, uint64_t>>
117                 createParams;
118             createParams["com.ibm.Dump.Create.CreateParameters.DumpType"] =
119                 "com.ibm.Dump.Create.DumpType.Hostboot";
120             createParams["com.ibm.Dump.Create.CreateParameters.ErrorLogId"] =
121                 uint64_t(logId);
122             method.append(createParams);
123 
124             // using system dbus
125             auto bus = sdbusplus::bus::new_system();
126             auto response = bus.call(method);
127 
128             // reply will be type dbus::ObjectPath
129             sdbusplus::message::object_path reply;
130             response.read(reply);
131 
132             // monitor dump progress
133             monitorDump(reply, timeout);
134         }
135         catch (const sdbusplus::exception::SdBusError& e)
136         {
137             log<level::ERR>("Error in requestDump",
138                             entry("ERROR=%s", e.what()));
139         }
140     }
141 }
142 
143 } // namespace dump
144 } // namespace watchdog
145