xref: /openbmc/openpower-occ-control/occ_ffdc.hpp (revision d7542c83b1acd145e0bbf2c1b6307911dfcebf7a)
12f9f9bbaSEddie James #pragma once
22f9f9bbaSEddie James 
32f9f9bbaSEddie James #include "config.h"
42f9f9bbaSEddie James 
52ccc3f69SChris Cain #include "file.hpp"
62f9f9bbaSEddie James #include "occ_errors.hpp"
72f9f9bbaSEddie James 
82ccc3f69SChris Cain #include <systemd/sd-journal.h>
92ccc3f69SChris Cain 
102ccc3f69SChris Cain #include <nlohmann/json.hpp>
112ccc3f69SChris Cain #include <xyz/openbmc_project/Logging/Create/server.hpp>
122ccc3f69SChris Cain 
132ccc3f69SChris Cain using FFDCFormat =
142ccc3f69SChris Cain     sdbusplus::xyz::openbmc_project::Logging::server::Create::FFDCFormat;
152ccc3f69SChris Cain using FFDCFiles = std::vector<
162ccc3f69SChris Cain     std::tuple<FFDCFormat, uint8_t, uint8_t, sdbusplus::message::unix_fd>>;
172ccc3f69SChris Cain 
182f9f9bbaSEddie James namespace open_power
192f9f9bbaSEddie James {
202f9f9bbaSEddie James namespace occ
212f9f9bbaSEddie James {
222f9f9bbaSEddie James 
232ccc3f69SChris Cain /** @class FFDCFile
242ccc3f69SChris Cain  *  @brief Represents a single file that will get opened when created and
252ccc3f69SChris Cain  *         deleted when the object is destructed
262ccc3f69SChris Cain  */
272ccc3f69SChris Cain class FFDCFile
282ccc3f69SChris Cain {
292ccc3f69SChris Cain   public:
302ccc3f69SChris Cain     FFDCFile() = delete;
312ccc3f69SChris Cain     FFDCFile(const FFDCFile&) = delete;
322ccc3f69SChris Cain     FFDCFile& operator=(const FFDCFile&) = delete;
332ccc3f69SChris Cain     FFDCFile(FFDCFile&&) = delete;
342ccc3f69SChris Cain     FFDCFile& operator=(FFDCFile&&) = delete;
352ccc3f69SChris Cain 
362ccc3f69SChris Cain     /**
372ccc3f69SChris Cain      * @brief Constructor
382ccc3f69SChris Cain      *
392ccc3f69SChris Cain      * Opens the file and saves the descriptor
402ccc3f69SChris Cain      *
412ccc3f69SChris Cain      * @param[in] name - The filename
422ccc3f69SChris Cain      */
432ccc3f69SChris Cain     explicit FFDCFile(const std::filesystem::path& name);
442ccc3f69SChris Cain 
452ccc3f69SChris Cain     /**
462ccc3f69SChris Cain      * @brief Destructor - Deletes the file
472ccc3f69SChris Cain      */
~FFDCFile()482ccc3f69SChris Cain     ~FFDCFile()
492ccc3f69SChris Cain     {
502ccc3f69SChris Cain         std::filesystem::remove(_name);
512ccc3f69SChris Cain     }
522ccc3f69SChris Cain 
532ccc3f69SChris Cain     /**
542ccc3f69SChris Cain      * @brief Returns the file descriptor
552ccc3f69SChris Cain      *
562ccc3f69SChris Cain      * @return int - The descriptor
572ccc3f69SChris Cain      */
fd()582ccc3f69SChris Cain     int fd()
592ccc3f69SChris Cain     {
602ccc3f69SChris Cain         return _fd();
612ccc3f69SChris Cain     }
622ccc3f69SChris Cain 
632ccc3f69SChris Cain   private:
642ccc3f69SChris Cain     /**
652ccc3f69SChris Cain      * @brief The file descriptor holder
662ccc3f69SChris Cain      */
672ccc3f69SChris Cain     FileDescriptor _fd;
682ccc3f69SChris Cain 
692ccc3f69SChris Cain     /**
702ccc3f69SChris Cain      * @brief The filename
712ccc3f69SChris Cain      */
722ccc3f69SChris Cain     const std::filesystem::path _name;
732ccc3f69SChris Cain };
742ccc3f69SChris Cain 
752f9f9bbaSEddie James /** @class FFDC
762f9f9bbaSEddie James  *  @brief Monitors for SBE FFDC availability
772f9f9bbaSEddie James  */
782f9f9bbaSEddie James class FFDC : public Error
792f9f9bbaSEddie James {
802f9f9bbaSEddie James   public:
812f9f9bbaSEddie James     FFDC() = delete;
822f9f9bbaSEddie James     FFDC(const FFDC&) = delete;
832f9f9bbaSEddie James     FFDC& operator=(const FFDC&) = delete;
842f9f9bbaSEddie James     FFDC(FFDC&&) = default;
852f9f9bbaSEddie James     FFDC& operator=(FFDC&&) = default;
862f9f9bbaSEddie James 
872f9f9bbaSEddie James     /** @brief Constructs the FFDC object
882f9f9bbaSEddie James      *
892f9f9bbaSEddie James      *  @param[in] event    - reference to sd_event unique_ptr
902f9f9bbaSEddie James      *  @param[in] file     - File used by driver to communicate FFDC data
912f9f9bbaSEddie James      *  @param[in] instance - OCC instance number
922f9f9bbaSEddie James      */
FFDC(EventPtr & event,const fs::path & file,unsigned int instance)932f9f9bbaSEddie James     FFDC(EventPtr& event, const fs::path& file, unsigned int instance) :
942f9f9bbaSEddie James         Error(event, file, nullptr), instance(instance)
952f9f9bbaSEddie James     {
962f9f9bbaSEddie James         // Nothing to do here.
972f9f9bbaSEddie James     }
982f9f9bbaSEddie James 
~FFDC()992f9f9bbaSEddie James     ~FFDC()
1002f9f9bbaSEddie James     {
1012f9f9bbaSEddie James         for (auto&& it : temporaryFiles)
1022f9f9bbaSEddie James         {
1032f9f9bbaSEddie James             close(it.second);
1042f9f9bbaSEddie James             fs::remove(it.first);
1052f9f9bbaSEddie James         }
1062f9f9bbaSEddie James     }
1072f9f9bbaSEddie James 
1082f9f9bbaSEddie James     /** @brief Helper function to create a PEL with the OpenPower DBus
1092f9f9bbaSEddie James      *         interface
1102f9f9bbaSEddie James      *
1112f9f9bbaSEddie James      * @param[in] path - the DBus error path
1122f9f9bbaSEddie James      * @param[in] src6 - the SBE error SRC6 word
1132f9f9bbaSEddie James      * @param[in] msg - the error message
1142f9f9bbaSEddie James      * @param[in] fd - the file descriptor for any FFDC
1152f9f9bbaSEddie James      */
1162f9f9bbaSEddie James     static uint32_t createPEL(const char* path, uint32_t src6, const char* msg,
1172f9f9bbaSEddie James                               int fd = -1);
1182f9f9bbaSEddie James 
1199789e71fSEddie James     /** @brief Helper function to create a PEL for the OCC reset with the
1209789e71fSEddie James      * OpenPower DBus interface
1219789e71fSEddie James      *
1229789e71fSEddie James      * @param[in] instance - the OCC instance id
1239789e71fSEddie James      * @param[in] path - the DBus error path
1249789e71fSEddie James      * @param[in] err - the error return code
1259789e71fSEddie James      * @param[in] callout - the PEL callout path
1269789e71fSEddie James      */
1279789e71fSEddie James     static void createOCCResetPEL(unsigned int instance, const char* path,
1289789e71fSEddie James                                   int err, const char* callout);
1299789e71fSEddie James 
1302ccc3f69SChris Cain     /**
1312ccc3f69SChris Cain      * @brief Create a file containing the latest journal traces for the
1322ccc3f69SChris Cain      *        specified executable and add it to the file list.
1332ccc3f69SChris Cain      *
1342ccc3f69SChris Cain      * @param[in] fileList     - where to add the new file
1352ccc3f69SChris Cain      * @param[in] executable   - name of app to collect
1362ccc3f69SChris Cain      * @param[in] lines        - number of journal lines to save
1372ccc3f69SChris Cain      *
1382ccc3f69SChris Cain      * @return std::unique_ptr<FFDCFile> - The file object
1392ccc3f69SChris Cain      */
140*d7542c83SPatrick Williams     static std::unique_ptr<FFDCFile> addJournalEntries(
141*d7542c83SPatrick Williams         FFDCFiles& fileList, const std::string& executable, unsigned int lines);
1422ccc3f69SChris Cain 
1432f9f9bbaSEddie James   private:
1442f9f9bbaSEddie James     /** @brief OCC instance number. Ex, 0,1, etc */
1452f9f9bbaSEddie James     unsigned int instance;
1462f9f9bbaSEddie James 
1472f9f9bbaSEddie James     /** @brief Stores the temporary files and file descriptors
1482f9f9bbaSEddie James      *         in usage. They will be cleaned up when the class
1492f9f9bbaSEddie James      *         is destroyed (when the application exits).
1502f9f9bbaSEddie James      */
1512f9f9bbaSEddie James     std::vector<std::pair<fs::path, int>> temporaryFiles;
1522f9f9bbaSEddie James 
1532f9f9bbaSEddie James     /** @brief When the error event is received, analyzes it
1542f9f9bbaSEddie James      *         and makes a callback to error handler if the
1552f9f9bbaSEddie James      *         content denotes an error condition
1562f9f9bbaSEddie James      */
1572f9f9bbaSEddie James     void analyzeEvent() override;
1582ccc3f69SChris Cain 
1592ccc3f69SChris Cain     /**
1602ccc3f69SChris Cain      * @brief Returns an FFDCFile containing the JSON data
1612ccc3f69SChris Cain      *
1622ccc3f69SChris Cain      * @param[in] ffdcData - The JSON data to write to a file
1632ccc3f69SChris Cain      *
1642ccc3f69SChris Cain      * @return std::unique_ptr<FFDCFile> - The file object
1652ccc3f69SChris Cain      */
1662ccc3f69SChris Cain     static std::unique_ptr<FFDCFile>
1672ccc3f69SChris Cain         makeJsonFFDCFile(const nlohmann::json& ffdcData);
1682ccc3f69SChris Cain 
1692ccc3f69SChris Cain     /**
1702ccc3f69SChris Cain      * @brief Returns a JSON structure containing the previous N journal
1712ccc3f69SChris Cain      * entries.
1722ccc3f69SChris Cain      *
1732ccc3f69SChris Cain      * @param[in] numLines   - Number of lines of journal to retrieve
1742ccc3f69SChris Cain      * @param[in] executable - name of app to collect for
1752ccc3f69SChris Cain      *
1762ccc3f69SChris Cain      * @return JSON object that was created
1772ccc3f69SChris Cain      */
1782ccc3f69SChris Cain     static nlohmann::json getJournalEntries(int numLines,
1792ccc3f69SChris Cain                                             std::string executable);
1802ccc3f69SChris Cain 
1812ccc3f69SChris Cain     /**
1822ccc3f69SChris Cain      * @brief Gets the realtime (wallclock) timestamp for the current journal
1832ccc3f69SChris Cain      * entry.
1842ccc3f69SChris Cain      *
1852ccc3f69SChris Cain      * @param journal current journal entry
1862ccc3f69SChris Cain      * @return timestamp as a date/time string
1872ccc3f69SChris Cain      */
1882ccc3f69SChris Cain     static std::string getTimeStamp(sd_journal* journal);
1892ccc3f69SChris Cain 
1902ccc3f69SChris Cain     /**
1912ccc3f69SChris Cain      * @brief Gets the value of the specified field for the current journal
1922ccc3f69SChris Cain      * entry.
1932ccc3f69SChris Cain      *
1942ccc3f69SChris Cain      * Returns an empty string if the current journal entry does not have the
1952ccc3f69SChris Cain      * specified field.
1962ccc3f69SChris Cain      *
1972ccc3f69SChris Cain      * @param journal current journal entry
1982ccc3f69SChris Cain      * @param field journal field name
1992ccc3f69SChris Cain      * @return field value
2002ccc3f69SChris Cain      */
2012ccc3f69SChris Cain     static std::string getFieldValue(sd_journal* journal,
2022ccc3f69SChris Cain                                      const std::string& field);
2032ccc3f69SChris Cain };
2042ccc3f69SChris Cain 
2052ccc3f69SChris Cain /**
2062ccc3f69SChris Cain  * @class JournalCloser
2072ccc3f69SChris Cain  *  @brief Automatically closes the journal when the object goes out of scope.
2082ccc3f69SChris Cain  */
2092ccc3f69SChris Cain class JournalCloser
2102ccc3f69SChris Cain {
2112ccc3f69SChris Cain   public:
2122ccc3f69SChris Cain     // Specify which compiler-generated methods we want
2132ccc3f69SChris Cain     JournalCloser() = delete;
2142ccc3f69SChris Cain     JournalCloser(const JournalCloser&) = delete;
2152ccc3f69SChris Cain     JournalCloser(JournalCloser&&) = delete;
2162ccc3f69SChris Cain     JournalCloser& operator=(const JournalCloser&) = delete;
2172ccc3f69SChris Cain     JournalCloser& operator=(JournalCloser&&) = delete;
2182ccc3f69SChris Cain 
JournalCloser(sd_journal * journal)219a49c987eSPatrick Williams     JournalCloser(sd_journal* journal) : journal{journal} {}
2202ccc3f69SChris Cain 
~JournalCloser()2212ccc3f69SChris Cain     ~JournalCloser()
2222ccc3f69SChris Cain     {
2232ccc3f69SChris Cain         sd_journal_close(journal);
2242ccc3f69SChris Cain     }
2252ccc3f69SChris Cain 
2262ccc3f69SChris Cain   private:
2272ccc3f69SChris Cain     sd_journal* journal{nullptr};
2282f9f9bbaSEddie James };
2292f9f9bbaSEddie James 
2302f9f9bbaSEddie James } // namespace occ
2312f9f9bbaSEddie James } // namespace open_power
232