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 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::message& 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::message& 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::bus& 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