blob: c44e52fd3be6dd6141bc5a4ccb4dc550d3eadb48 [file] [log] [blame]
Andrew Geisslere426b582020-05-28 12:40:55 -05001#include "systemd_target_signal.hpp"
2
Andrew Geissler234a3172019-08-09 14:30:02 -05003#include <phosphor-logging/elog-errors.hpp>
Andrew Geissler8ffdb262021-09-20 15:25:19 -05004#include <phosphor-logging/lg2.hpp>
Andrew Geisslere426b582020-05-28 12:40:55 -05005#include <sdbusplus/exception.hpp>
Andrew Geissler234a3172019-08-09 14:30:02 -05006#include <sdbusplus/server/manager.hpp>
7#include <sdeventplus/event.hpp>
Andrew Geissler234a3172019-08-09 14:30:02 -05008#include <xyz/openbmc_project/Common/error.hpp>
9
10namespace phosphor
11{
12namespace state
13{
14namespace manager
15{
16
17using phosphor::logging::elog;
Andrew Geissler8ffdb262021-09-20 15:25:19 -050018PHOSPHOR_LOG2_USING;
19
Andrew Geissler234a3172019-08-09 14:30:02 -050020using sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
21
Andrew Geissler8ffdb262021-09-20 15:25:19 -050022void SystemdTargetLogging::logError(const std::string& errorLog,
Andrew Geisslere6841032022-02-11 10:31:50 -060023 const std::string& result,
24 const std::string& unit)
Andrew Geissler234a3172019-08-09 14:30:02 -050025{
26 auto method = this->bus.new_method_call(
27 "xyz.openbmc_project.Logging", "/xyz/openbmc_project/logging",
28 "xyz.openbmc_project.Logging.Create", "Create");
29 // Signature is ssa{ss}
Andrew Geissler8ffdb262021-09-20 15:25:19 -050030 method.append(errorLog);
Andrew Geissler234a3172019-08-09 14:30:02 -050031 method.append("xyz.openbmc_project.Logging.Entry.Level.Critical");
Andrew Geisslere6841032022-02-11 10:31:50 -060032 method.append(std::array<std::pair<std::string, std::string>, 2>(
33 {std::pair<std::string, std::string>({"SYSTEMD_RESULT", result}),
34 std::pair<std::string, std::string>({"SYSTEMD_UNIT", unit})}));
Andrew Geissler234a3172019-08-09 14:30:02 -050035 try
36 {
37 this->bus.call_noreply(method);
38 }
Patrick Williams0a675212021-09-02 09:49:43 -050039 catch (const sdbusplus::exception::exception& e)
Andrew Geissler234a3172019-08-09 14:30:02 -050040 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -050041 error("Failed to create systemd target error, error:{ERROR_MSG}, "
42 "result:{RESULT}, exception:{ERROR}",
43 "ERROR_MSG", errorLog, "RESULT", result, "ERROR", e);
Andrew Geissler234a3172019-08-09 14:30:02 -050044 }
45}
46
Andrew Geisslerf3870c62022-02-10 16:15:28 -060047const std::string SystemdTargetLogging::processError(const std::string& unit,
48 const std::string& result)
Andrew Geissler234a3172019-08-09 14:30:02 -050049{
50 auto targetEntry = this->targetData.find(unit);
51 if (targetEntry != this->targetData.end())
52 {
53 // Check if its result matches any of our monitored errors
54 if (std::find(targetEntry->second.errorsToMonitor.begin(),
55 targetEntry->second.errorsToMonitor.end(),
56 result) != targetEntry->second.errorsToMonitor.end())
57 {
Andrew Geisslerad65b2d2021-09-21 12:53:29 -050058 info(
59 "Monitored systemd unit has hit an error, unit:{UNIT}, result:{RESULT}",
60 "UNIT", unit, "RESULT", result);
Andrew Geisslerf3870c62022-02-10 16:15:28 -060061 return (targetEntry->second.errorToLog);
Andrew Geissler234a3172019-08-09 14:30:02 -050062 }
63 }
Andrew Geisslerf3870c62022-02-10 16:15:28 -060064
65 // Check if it's in our list of services to monitor
66 if (std::find(this->serviceData.begin(), this->serviceData.end(), unit) !=
67 this->serviceData.end())
68 {
69 if (result == "failed")
70 {
71 info(
72 "Monitored systemd service has hit an error, unit:{UNIT}, result:{RESULT}",
73 "UNIT", unit, "RESULT", result);
74 return (std::string{
75 "xyz.openbmc_project.State.Error.CriticalServiceFailure"});
76 }
77 }
78
79 return (std::string{});
Andrew Geissler234a3172019-08-09 14:30:02 -050080}
81
82void SystemdTargetLogging::systemdUnitChange(sdbusplus::message::message& msg)
83{
84 uint32_t id;
85 sdbusplus::message::object_path objPath;
86 std::string unit{};
87 std::string result{};
88
89 msg.read(id, objPath, unit, result);
90
91 // In most cases it will just be success, in which case just return
92 if (result != "done")
93 {
Andrew Geisslerf3870c62022-02-10 16:15:28 -060094 const std::string error = processError(unit, result);
Andrew Geissler234a3172019-08-09 14:30:02 -050095
96 // If this is a monitored error then log it
Andrew Geisslerf3870c62022-02-10 16:15:28 -060097 if (!error.empty())
Andrew Geissler234a3172019-08-09 14:30:02 -050098 {
Andrew Geisslere6841032022-02-11 10:31:50 -060099 logError(error, result, unit);
Andrew Geissler234a3172019-08-09 14:30:02 -0500100 }
101 }
102 return;
103}
104
Andrew Geissler38605ee2019-11-11 16:01:56 -0600105void SystemdTargetLogging::processNameChangeSignal(
106 sdbusplus::message::message& msg)
107{
108 std::string name; // well-known
109 std::string old_owner; // unique-name
110 std::string new_owner; // unique-name
111
112 msg.read(name, old_owner, new_owner);
113
114 // Looking for systemd to be on dbus so we can call it
115 if (name == "org.freedesktop.systemd1")
116 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500117 info("org.freedesktop.systemd1 is now on dbus");
Andrew Geissler38605ee2019-11-11 16:01:56 -0600118 subscribeToSystemdSignals();
119 }
120 return;
121}
122
Andrew Geissler234a3172019-08-09 14:30:02 -0500123void SystemdTargetLogging::subscribeToSystemdSignals()
124{
125 auto method = this->bus.new_method_call(
126 "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
127 "org.freedesktop.systemd1.Manager", "Subscribe");
128
129 try
130 {
131 this->bus.call(method);
132 }
Patrick Williams0a675212021-09-02 09:49:43 -0500133 catch (const sdbusplus::exception::exception& e)
Andrew Geissler234a3172019-08-09 14:30:02 -0500134 {
Andrew Geissler38605ee2019-11-11 16:01:56 -0600135 // If error indicates systemd is not on dbus yet then do nothing.
136 // The systemdNameChangeSignals callback will detect when it is on
137 // dbus and then call this function again
138 const std::string noDbus("org.freedesktop.DBus.Error.ServiceUnknown");
139 if (noDbus == e.name())
140 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500141 info("org.freedesktop.systemd1 not on dbus yet");
Andrew Geissler38605ee2019-11-11 16:01:56 -0600142 }
143 else
144 {
Andrew Geissler8ffdb262021-09-20 15:25:19 -0500145 error("Failed to subscribe to systemd signals: {ERROR}", "ERROR",
146 e);
Andrew Geissler38605ee2019-11-11 16:01:56 -0600147 elog<InternalFailure>();
148 }
149 return;
Andrew Geissler234a3172019-08-09 14:30:02 -0500150 }
151
Andrew Geissler38605ee2019-11-11 16:01:56 -0600152 // Call destructor on match callback since application is now subscribed to
153 // systemd signals
154 this->systemdNameOwnedChangedSignal.~match();
155
Andrew Geissler234a3172019-08-09 14:30:02 -0500156 return;
157}
158
159} // namespace manager
160} // namespace state
161} // namespace phosphor