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