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