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