regulators: Implement D-Bus error logging
Implemented the DBusErrorLogging class. This class creates error logs
using the D-Bus CreateWithFFDCFiles method.
Updated the abstract base class, ErrorLogging, to have the correct
virtual method parameters. The methods were previously defined with no
parameters as a temporary measure.
Also updated the MockErrorLogging class to have the correct virtual
method parameters.
Tested:
* Verified that all the log*Error() methods create an error log of the
correct type.
* Verified that created error logs have the expected:
* property/field values
* callouts with associated VPD
* User Data sections containing debug data stored in FFDC files
* Tested where creating an FFDC file fails.
* Tested where calling CreateWithFFDCFiles method fails.
* Tested where removing an FFDC file fails.
* Verified that if a failure occurs, it is written to the system
journal but does not result in a second error log (since that could
lead to an infinite loop).
* Verified that temporary FFDC files are removed even if creating the
error log fails.
Full Test Plan:
* https://gist.github.com/smccarney/60ecbc018c55a5d13661bda8ee256d61
Signed-off-by: Shawn McCarney <shawnmm@us.ibm.com>
Change-Id: I2837fc68dfbad2d89193a147222f1c51d9b1aad3
diff --git a/phosphor-regulators/src/error_logging.hpp b/phosphor-regulators/src/error_logging.hpp
index ddd3b94..d1a5879 100644
--- a/phosphor-regulators/src/error_logging.hpp
+++ b/phosphor-regulators/src/error_logging.hpp
@@ -15,11 +15,26 @@
*/
#pragma once
+#include "ffdc_file.hpp"
+#include "journal.hpp"
+#include "xyz/openbmc_project/Logging/Create/server.hpp"
+#include "xyz/openbmc_project/Logging/Entry/server.hpp"
+
#include <sdbusplus/bus.hpp>
+#include <cstdint>
+#include <map>
+#include <string>
+#include <tuple>
+#include <vector>
+
namespace phosphor::power::regulators
{
+using namespace sdbusplus::xyz::openbmc_project::Logging::server;
+using FFDCTuple =
+ std::tuple<FFDCFormat, uint8_t, uint8_t, sdbusplus::message::unix_fd>;
+
/**
* @class ErrorLogging
*
@@ -38,13 +53,78 @@
ErrorLogging& operator=(ErrorLogging&&) = delete;
virtual ~ErrorLogging() = default;
- // TODO: The following are stubs. Add parameters and doxygen later.
- virtual void logConfigFileError() = 0;
- virtual void logDBusError() = 0;
- virtual void logI2CError() = 0;
- virtual void logInternalError() = 0;
- virtual void logPMBusError() = 0;
- virtual void logWriteVerificationError() = 0;
+ /**
+ * Log a regulators configuration file error.
+ *
+ * This error is logged when the regulators configuration file could not be
+ * found, could not be read, or had invalid contents.
+ *
+ * @param severity severity level
+ * @param journal system journal
+ */
+ virtual void logConfigFileError(Entry::Level severity,
+ Journal& journal) = 0;
+
+ /**
+ * Log a D-Bus error.
+ *
+ * This error is logged when D-Bus communication fails.
+ *
+ * @param severity severity level
+ * @param journal system journal
+ */
+ virtual void logDBusError(Entry::Level severity, Journal& journal) = 0;
+
+ /**
+ * Log an I2C communication error.
+ *
+ * @param severity severity level
+ * @param journal system journal
+ * @param bus I2C bus in the form "/dev/i2c-X", where X is the 0-based bus
+ * number
+ * @param addr 7 bit I2C address
+ * @param errorNumber errno value from the failed I2C operation
+ */
+ virtual void logI2CError(Entry::Level severity, Journal& journal,
+ const std::string& bus, uint8_t addr,
+ int errorNumber) = 0;
+
+ /**
+ * Log an internal firmware error.
+ *
+ * @param severity severity level
+ * @param journal system journal
+ */
+ virtual void logInternalError(Entry::Level severity, Journal& journal) = 0;
+
+ /**
+ * Log a PMBus error.
+ *
+ * This error is logged when the I2C communication was successful, but the
+ * PMBus value read is invalid or unsupported.
+ *
+ * @param severity severity level
+ * @param journal system journal
+ * @param inventoryPath D-Bus inventory path of the device where the error
+ * occurred
+ */
+ virtual void logPMBusError(Entry::Level severity, Journal& journal,
+ const std::string& inventoryPath) = 0;
+
+ /**
+ * Log a write verification error.
+ *
+ * This error is logged when a device register is written, read back, and
+ * the two values do not match. This is also called a read-back error.
+ *
+ * @param severity severity level
+ * @param journal system journal
+ * @param inventoryPath D-Bus inventory path of the device where the error
+ * occurred
+ */
+ virtual void
+ logWriteVerificationError(Entry::Level severity, Journal& journal,
+ const std::string& inventoryPath) = 0;
};
/**
@@ -72,17 +152,113 @@
{
}
- // TODO: The following are stubs. Add parameters, implementation, and
- // doxygen later.
- virtual void logConfigFileError(){};
- virtual void logDBusError(){};
- virtual void logI2CError(){};
- virtual void logInternalError(){};
- virtual void logPMBusError(){};
- virtual void logWriteVerificationError(){};
+ /** @copydoc ErrorLogging::logConfigFileError() */
+ virtual void logConfigFileError(Entry::Level severity,
+ Journal& journal) override;
+
+ /** @copydoc ErrorLogging::logDBusError() */
+ virtual void logDBusError(Entry::Level severity, Journal& journal) override;
+
+ /** @copydoc ErrorLogging::logI2CError() */
+ virtual void logI2CError(Entry::Level severity, Journal& journal,
+ const std::string& bus, uint8_t addr,
+ int errorNumber) override;
+
+ /** @copydoc ErrorLogging::logInternalError() */
+ virtual void logInternalError(Entry::Level severity,
+ Journal& journal) override;
+
+ /** @copydoc ErrorLogging::logPMBusError() */
+ virtual void logPMBusError(Entry::Level severity, Journal& journal,
+ const std::string& inventoryPath) override;
+
+ /** @copydoc ErrorLogging::logWriteVerificationError() */
+ virtual void
+ logWriteVerificationError(Entry::Level severity, Journal& journal,
+ const std::string& inventoryPath) override;
private:
/**
+ * Create an FFDCFile object containing the specified lines of text data.
+ *
+ * Throws an exception if an error occurs.
+ *
+ * @param lines lines of text data to write to file
+ * @return FFDCFile object
+ */
+ FFDCFile createFFDCFile(const std::vector<std::string>& lines);
+
+ /**
+ * Create FFDCFile objects containing debug data to store in the error log.
+ *
+ * If an error occurs, the error is written to the journal but an exception
+ * is not thrown.
+ *
+ * @param journal system journal
+ * @return vector of FFDCFile objects
+ */
+ std::vector<FFDCFile> createFFDCFiles(Journal& journal);
+
+ /**
+ * Create FFDCTuple objects corresponding to the specified FFDC files.
+ *
+ * The D-Bus method to create an error log requires a vector of tuples to
+ * pass in the FFDC file information.
+ *
+ * @param files FFDC files
+ * @return vector of FFDCTuple objects
+ */
+ std::vector<FFDCTuple> createFFDCTuples(std::vector<FFDCFile>& files);
+
+ /**
+ * Returns the absolute form of the specified inventory path.
+ *
+ * The inventory paths in the JSON configuration file are relative. Add the
+ * the necessary prefix to make the path absolute.
+ *
+ * @param inventoryPath relative D-Bus inventory path
+ * @return absolute D-Bus inventory path
+ */
+ std::string getAbsoluteInventoryPath(const std::string& inventoryPath)
+ {
+ std::string absPath = "/xyz/openbmc_project/inventory";
+ if ((!inventoryPath.empty()) && (inventoryPath.front() != '/'))
+ {
+ absPath += '/';
+ }
+ absPath += inventoryPath;
+ return absPath;
+ }
+
+ /**
+ * Logs an error using the D-Bus CreateWithFFDCFiles method.
+ *
+ * If logging fails, a message is written to the journal but an exception is
+ * not thrown.
+ *
+ * @param message Message property of the error log entry
+ * @param severity Severity property of the error log entry
+ * @param additionalData AdditionalData property of the error log entry
+ * @param journal system journal
+ */
+ void logError(const std::string& message, Entry::Level severity,
+ std::map<std::string, std::string>& additionalData,
+ Journal& journal);
+
+ /**
+ * Removes the specified FFDC files from the file system.
+ *
+ * Also clears the specified vector, removing the FFDCFile objects.
+ *
+ * If an error occurs, the error is written to the journal but an exception
+ * is not thrown.
+ *
+ * @param files FFDC files to remove
+ * @param journal system journal
+ */
+ void removeFFDCFiles(std::vector<FFDCFile>& files, Journal& journal);
+
+ /**
* D-Bus bus object.
*/
sdbusplus::bus::bus& bus;