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