1 /**
2 * Copyright © 2017 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "resolve_errors.hpp"
17
18 #include "sdbusplus.hpp"
19
20 #include <phosphor-logging/lg2.hpp>
21
22 namespace phosphor
23 {
24 namespace dbus
25 {
26 namespace monitoring
27 {
28
29 constexpr auto LOGGING_IFACE = "xyz.openbmc_project.Logging.Entry";
30 constexpr auto PROPERTY_IFACE = "org.freedesktop.DBus.Properties";
31 constexpr auto ASSOCIATION_IFACE = "xyz.openbmc_project.Association";
32 constexpr auto ENDPOINTS_PROPERTY = "endpoints";
33 constexpr auto RESOLVED_PROPERTY = "Resolved";
34
35 using EndpointList = std::vector<std::string>;
36 using EndpointsProperty = std::variant<EndpointList>;
37
operator ()(Context)38 void ResolveCallout::operator()(Context /* ctx */)
39 {
40 // Resolve all errors for this callout:
41 // 1) Read the 'endpoints' property for the callout/fault object
42 //
43 // 2) Follow each endpoint to its log entry
44 //
45 // 3) Set the Resolved property to true on the entry
46
47 try
48 {
49 auto path = callout + "/fault";
50 auto busName = SDBusPlus::getBusName(path, ASSOCIATION_IFACE);
51
52 if (busName.empty())
53 {
54 // Just means there are no error logs with this callout
55 return;
56 }
57
58 auto endpoints = SDBusPlus::callMethodAndRead<EndpointsProperty>(
59 busName, path, PROPERTY_IFACE, "Get", ASSOCIATION_IFACE,
60 ENDPOINTS_PROPERTY);
61
62 const auto& logEntries = std::get<EndpointList>(endpoints);
63
64 // Resolve each log entry
65 for (const auto& logEntry : logEntries)
66 {
67 resolve(logEntry);
68 }
69 }
70 catch (const std::exception& e)
71 {
72 lg2::error("Failed getting callout fault associations: {ERROR}, {PATH}",
73 "ERROR", e, "PATH", callout);
74 }
75 }
76
resolve(const std::string & logEntry)77 void ResolveCallout::resolve(const std::string& logEntry)
78 {
79 try
80 {
81 static std::string busName;
82 if (busName.empty())
83 {
84 busName = SDBusPlus::getBusName(logEntry, LOGGING_IFACE);
85 if (busName.empty())
86 {
87 return;
88 }
89 }
90
91 std::variant<bool> resolved = true;
92
93 SDBusPlus::callMethod(busName, logEntry, PROPERTY_IFACE, "Set",
94 LOGGING_IFACE, RESOLVED_PROPERTY, resolved);
95 }
96 catch (const std::exception& e)
97 {
98 lg2::error("Unable to resolve error log entry {ENTRY}: {ERROR}",
99 "ENTRY", logEntry, "ERROR", e);
100 }
101 }
102
103 } // namespace monitoring
104 } // namespace dbus
105 } // namespace phosphor
106