1 #pragma once
2 
3 #include "systemd_service_parser.hpp"
4 #include "systemd_target_parser.hpp"
5 
6 #include <sdbusplus/bus.hpp>
7 #include <sdbusplus/bus/match.hpp>
8 
9 extern bool gVerbose;
10 
11 namespace phosphor
12 {
13 namespace state
14 {
15 namespace manager
16 {
17 /** @class SystemdTargetLogging
18  *  @brief Object to monitor input systemd targets and create corresponding
19  *         input errors for on failures
20  */
21 class SystemdTargetLogging
22 {
23   public:
24     SystemdTargetLogging() = delete;
25     SystemdTargetLogging(const SystemdTargetLogging&) = delete;
26     SystemdTargetLogging& operator=(const SystemdTargetLogging&) = delete;
27     SystemdTargetLogging(SystemdTargetLogging&&) = delete;
28     SystemdTargetLogging& operator=(SystemdTargetLogging&&) = delete;
29     virtual ~SystemdTargetLogging() = default;
30 
SystemdTargetLogging(const TargetErrorData & targetData,const ServiceMonitorData & serviceData,sdbusplus::bus_t & bus)31     SystemdTargetLogging(const TargetErrorData& targetData,
32                          const ServiceMonitorData& serviceData,
33                          sdbusplus::bus_t& bus) :
34         targetData(targetData), serviceData(serviceData), bus(bus),
35         systemdJobRemovedSignal(
36             bus,
37             sdbusplus::bus::match::rules::type::signal() +
38                 sdbusplus::bus::match::rules::member("JobRemoved") +
39                 sdbusplus::bus::match::rules::path(
40                     "/org/freedesktop/systemd1") +
41                 sdbusplus::bus::match::rules::interface(
42                     "org.freedesktop.systemd1.Manager"),
43             [this](sdbusplus::message_t& m) { systemdUnitChange(m); }),
44         systemdNameOwnedChangedSignal(
45             bus, sdbusplus::bus::match::rules::nameOwnerChanged(),
__anonedb643ec0202(sdbusplus::message_t& m) 46             [this](sdbusplus::message_t& m) { processNameChangeSignal(m); })
47     {}
48 
49     /**
50      * @brief subscribe to the systemd signals
51      *
52      * This object needs to monitor systemd target changes so it can create
53      * the required error logs on failures
54      *
55      **/
56     void subscribeToSystemdSignals();
57 
58     /** @brief Process the target fail and return error to log
59      *
60      * @note This is public for unit testing purposes
61      *
62      * @param[in]  unit       - The systemd unit that failed
63      * @param[in]  result     - The failure code from the system unit
64      *
65      * @return valid pointer to error to log, otherwise nullptr
66      */
67     std::string processError(const std::string& unit,
68                              const std::string& result);
69 
70   private:
71     /** @brief Start BMC Quiesce Target to indicate critical service failure */
72     void startBmcQuiesceTarget();
73 
74     /** @brief Call phosphor-logging to create error
75      *
76      * @param[in]  error      - The error to log
77      * @param[in]  result     - The failure code from the systemd unit
78      * @param[in]  unit       - The name of the failed unit
79      */
80     void logError(const std::string& error, const std::string& result,
81                   const std::string& unit);
82 
83     /** @brief Check if systemd state change is one to monitor
84      *
85      * Instance specific interface to handle the detected systemd state
86      * change
87      *
88      * @param[in]  msg       - Data associated with subscribed signal
89      *
90      */
91     void systemdUnitChange(sdbusplus::message_t& msg);
92 
93     /** @brief Wait for systemd to show up on dbus
94      *
95      * Once systemd is on dbus, this application can subscribe to systemd
96      * signal changes
97      *
98      * @param[in]  msg       - Data associated with subscribed signal
99      *
100      */
101     void processNameChangeSignal(sdbusplus::message_t& msg);
102 
103     /** @brief Systemd targets to monitor and error logs to create */
104     const TargetErrorData& targetData;
105 
106     /** @brief Systemd targets to monitor and error logs to create */
107     const ServiceMonitorData& serviceData;
108 
109     /** @brief Persistent sdbusplus DBus bus connection. */
110     sdbusplus::bus_t& bus;
111 
112     /** @brief Used to subscribe to dbus systemd JobRemoved signals **/
113     sdbusplus::bus::match_t systemdJobRemovedSignal;
114 
115     /** @brief Used to know when systemd has registered on dbus **/
116     sdbusplus::bus::match_t systemdNameOwnedChangedSignal;
117 };
118 
119 } // namespace manager
120 } // namespace state
121 } // namespace phosphor
122