#pragma once #include "systemd_target_parser.hpp" #include #include extern bool gVerbose; namespace phosphor { namespace state { namespace manager { /** @class SystemdTargetLogging * @brief Object to monitor input systemd targets and create corresponding * input errors for on failures */ class SystemdTargetLogging { public: SystemdTargetLogging() = delete; SystemdTargetLogging(const SystemdTargetLogging&) = delete; SystemdTargetLogging& operator=(const SystemdTargetLogging&) = delete; SystemdTargetLogging(SystemdTargetLogging&&) = delete; SystemdTargetLogging& operator=(SystemdTargetLogging&&) = delete; virtual ~SystemdTargetLogging() = default; SystemdTargetLogging(const TargetErrorData& targetData, sdbusplus::bus::bus& bus) : targetData(targetData), bus(bus), systemdJobRemovedSignal( bus, sdbusplus::bus::match::rules::type::signal() + sdbusplus::bus::match::rules::member("JobRemoved") + sdbusplus::bus::match::rules::path( "/org/freedesktop/systemd1") + sdbusplus::bus::match::rules::interface( "org.freedesktop.systemd1.Manager"), std::bind(std::mem_fn(&SystemdTargetLogging::systemdUnitChange), this, std::placeholders::_1)), systemdNameOwnedChangedSignal( bus, sdbusplus::bus::match::rules::nameOwnerChanged(), std::bind( std::mem_fn(&SystemdTargetLogging::processNameChangeSignal), this, std::placeholders::_1)) {} /** * @brief subscribe to the systemd signals * * This object needs to monitor systemd target changes so it can create * the required error logs on failures * **/ void subscribeToSystemdSignals(); /** @brief Process the target fail and return error to log * * @note This is public for unit testing purposes * * @param[in] unit - The systemd unit that failed * @param[in] result - The failure code from the system unit * * @return valid pointer to error to log, otherwise nullptr */ const std::string* processError(const std::string& unit, const std::string& result); private: /** @brief Call phosphor-logging to create error * * @param[in] error - The error to log * @param[in] result - The failure code from the systemd unit */ void logError(const std::string& error, const std::string& result); /** @brief Check if systemd state change is one to monitor * * Instance specific interface to handle the detected systemd state * change * * @param[in] msg - Data associated with subscribed signal * */ void systemdUnitChange(sdbusplus::message::message& msg); /** @brief Wait for systemd to show up on dbus * * Once systemd is on dbus, this application can subscribe to systemd * signal changes * * @param[in] msg - Data associated with subscribed signal * */ void processNameChangeSignal(sdbusplus::message::message& msg); /** @brief Systemd targets to monitor and error logs to create */ const TargetErrorData& targetData; /** @brief Persistent sdbusplus DBus bus connection. */ sdbusplus::bus::bus& bus; /** @brief Used to subscribe to dbus systemd JobRemoved signals **/ sdbusplus::bus::match_t systemdJobRemovedSignal; /** @brief Used to know when systemd has registered on dbus **/ sdbusplus::bus::match_t systemdNameOwnedChangedSignal; }; } // namespace manager } // namespace state } // namespace phosphor