/** * Copyright © 2017 IBM Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "resolve_errors.hpp" #include "sdbusplus.hpp" #include namespace phosphor { namespace dbus { namespace monitoring { constexpr auto LOGGING_IFACE = "xyz.openbmc_project.Logging.Entry"; constexpr auto PROPERTY_IFACE = "org.freedesktop.DBus.Properties"; constexpr auto ASSOCIATION_IFACE = "org.openbmc.Association"; constexpr auto ENDPOINTS_PROPERTY = "endpoints"; constexpr auto RESOLVED_PROPERTY = "Resolved"; using namespace phosphor::logging; using EndpointList = std::vector; using EndpointsProperty = sdbusplus::message::variant; void ResolveCallout::operator()(Context ctx) { // Resolve all errors for this callout: // 1) Read the 'endpoints' property for the callout/fault object // // 2) Follow each endpoint to its log entry // // 3) Set the Resolved property to true on the entry try { auto path = callout + "/fault"; auto busName = SDBusPlus::getBusName(path, ASSOCIATION_IFACE); if (busName.empty()) { // Just means there are no error logs with this callout return; } auto endpoints = SDBusPlus::callMethodAndRead( busName, path, PROPERTY_IFACE, "Get", ASSOCIATION_IFACE, ENDPOINTS_PROPERTY); const auto& logEntries = sdbusplus::message::variant_ns::get(endpoints); // Resolve each log entry for (const auto& logEntry : logEntries) { resolve(logEntry); } } catch (const std::exception& e) { log("Failed getting callout fault associations", entry("CALLOUT=%s", callout.c_str()), entry("ERROR=%s", e.what())); } } void ResolveCallout::resolve(const std::string& logEntry) { try { static std::string busName; if (busName.empty()) { busName = SDBusPlus::getBusName(logEntry, LOGGING_IFACE); if (busName.empty()) { return; } } sdbusplus::message::variant resolved = true; auto response = SDBusPlus::callMethod(busName, logEntry, PROPERTY_IFACE, "Set", LOGGING_IFACE, RESOLVED_PROPERTY, resolved); if (response.is_method_error()) { log( "Failed to set Resolved property on an error log entry", entry("ENTRY=%s", logEntry.c_str())); } } catch (const std::exception& e) { log("Unable to resolve error log entry", entry("ENTRY=%s", logEntry.c_str()), entry("ERROR=%s", e.what())); } } } // namespace monitoring } // namespace dbus } // namespace phosphor