1 #pragma once 2 3 #include "config.h" 4 5 #include "file.hpp" 6 #include "occ_errors.hpp" 7 8 #include <systemd/sd-journal.h> 9 10 #include <nlohmann/json.hpp> 11 #include <xyz/openbmc_project/Logging/Create/server.hpp> 12 13 using FFDCFormat = 14 sdbusplus::xyz::openbmc_project::Logging::server::Create::FFDCFormat; 15 using FFDCFiles = std::vector< 16 std::tuple<FFDCFormat, uint8_t, uint8_t, sdbusplus::message::unix_fd>>; 17 18 namespace open_power 19 { 20 namespace occ 21 { 22 23 /** @class FFDCFile 24 * @brief Represents a single file that will get opened when created and 25 * deleted when the object is destructed 26 */ 27 class FFDCFile 28 { 29 public: 30 FFDCFile() = delete; 31 FFDCFile(const FFDCFile&) = delete; 32 FFDCFile& operator=(const FFDCFile&) = delete; 33 FFDCFile(FFDCFile&&) = delete; 34 FFDCFile& operator=(FFDCFile&&) = delete; 35 36 /** 37 * @brief Constructor 38 * 39 * Opens the file and saves the descriptor 40 * 41 * @param[in] name - The filename 42 */ 43 explicit FFDCFile(const std::filesystem::path& name); 44 45 /** 46 * @brief Destructor - Deletes the file 47 */ ~FFDCFile()48 ~FFDCFile() 49 { 50 std::filesystem::remove(_name); 51 } 52 53 /** 54 * @brief Returns the file descriptor 55 * 56 * @return int - The descriptor 57 */ fd()58 int fd() 59 { 60 return _fd(); 61 } 62 63 private: 64 /** 65 * @brief The file descriptor holder 66 */ 67 FileDescriptor _fd; 68 69 /** 70 * @brief The filename 71 */ 72 const std::filesystem::path _name; 73 }; 74 75 /** @class FFDC 76 * @brief Monitors for SBE FFDC availability 77 */ 78 class FFDC : public Error 79 { 80 public: 81 FFDC() = delete; 82 FFDC(const FFDC&) = delete; 83 FFDC& operator=(const FFDC&) = delete; 84 FFDC(FFDC&&) = default; 85 FFDC& operator=(FFDC&&) = default; 86 87 /** @brief Constructs the FFDC object 88 * 89 * @param[in] event - reference to sd_event unique_ptr 90 * @param[in] file - File used by driver to communicate FFDC data 91 * @param[in] instance - OCC instance number 92 */ FFDC(EventPtr & event,const fs::path & file,unsigned int instance)93 FFDC(EventPtr& event, const fs::path& file, unsigned int instance) : 94 Error(event, file, nullptr), instance(instance) 95 { 96 // Nothing to do here. 97 } 98 ~FFDC()99 ~FFDC() 100 { 101 for (auto&& it : temporaryFiles) 102 { 103 close(it.second); 104 fs::remove(it.first); 105 } 106 } 107 108 /** @brief Helper function to create a PEL with the OpenPower DBus 109 * interface 110 * 111 * @param[in] path - the DBus error path 112 * @param[in] src6 - the SBE error SRC6 word 113 * @param[in] msg - the error message 114 * @param[in] fd - the file descriptor for any FFDC 115 */ 116 static uint32_t createPEL(const char* path, uint32_t src6, const char* msg, 117 int fd = -1); 118 119 /** @brief Helper function to create a PEL for the OCC reset with the 120 * OpenPower DBus interface 121 * 122 * @param[in] instance - the OCC instance id 123 * @param[in] path - the DBus error path 124 * @param[in] err - the error return code 125 * @param[in] callout - the PEL callout path 126 */ 127 static void createOCCResetPEL(unsigned int instance, const char* path, 128 int err, const char* callout); 129 130 /** 131 * @brief Create a file containing the latest journal traces for the 132 * specified executable and add it to the file list. 133 * 134 * @param[in] fileList - where to add the new file 135 * @param[in] executable - name of app to collect 136 * @param[in] lines - number of journal lines to save 137 * 138 * @return std::unique_ptr<FFDCFile> - The file object 139 */ 140 static std::unique_ptr<FFDCFile> addJournalEntries( 141 FFDCFiles& fileList, const std::string& executable, unsigned int lines); 142 143 private: 144 /** @brief OCC instance number. Ex, 0,1, etc */ 145 unsigned int instance; 146 147 /** @brief Stores the temporary files and file descriptors 148 * in usage. They will be cleaned up when the class 149 * is destroyed (when the application exits). 150 */ 151 std::vector<std::pair<fs::path, int>> temporaryFiles; 152 153 /** @brief When the error event is received, analyzes it 154 * and makes a callback to error handler if the 155 * content denotes an error condition 156 */ 157 void analyzeEvent() override; 158 159 /** 160 * @brief Returns an FFDCFile containing the JSON data 161 * 162 * @param[in] ffdcData - The JSON data to write to a file 163 * 164 * @return std::unique_ptr<FFDCFile> - The file object 165 */ 166 static std::unique_ptr<FFDCFile> 167 makeJsonFFDCFile(const nlohmann::json& ffdcData); 168 169 /** 170 * @brief Returns a JSON structure containing the previous N journal 171 * entries. 172 * 173 * @param[in] numLines - Number of lines of journal to retrieve 174 * @param[in] executable - name of app to collect for 175 * 176 * @return JSON object that was created 177 */ 178 static nlohmann::json getJournalEntries(int numLines, 179 std::string executable); 180 181 /** 182 * @brief Gets the realtime (wallclock) timestamp for the current journal 183 * entry. 184 * 185 * @param journal current journal entry 186 * @return timestamp as a date/time string 187 */ 188 static std::string getTimeStamp(sd_journal* journal); 189 190 /** 191 * @brief Gets the value of the specified field for the current journal 192 * entry. 193 * 194 * Returns an empty string if the current journal entry does not have the 195 * specified field. 196 * 197 * @param journal current journal entry 198 * @param field journal field name 199 * @return field value 200 */ 201 static std::string getFieldValue(sd_journal* journal, 202 const std::string& field); 203 }; 204 205 /** 206 * @class JournalCloser 207 * @brief Automatically closes the journal when the object goes out of scope. 208 */ 209 class JournalCloser 210 { 211 public: 212 // Specify which compiler-generated methods we want 213 JournalCloser() = delete; 214 JournalCloser(const JournalCloser&) = delete; 215 JournalCloser(JournalCloser&&) = delete; 216 JournalCloser& operator=(const JournalCloser&) = delete; 217 JournalCloser& operator=(JournalCloser&&) = delete; 218 JournalCloser(sd_journal * journal)219 JournalCloser(sd_journal* journal) : journal{journal} {} 220 ~JournalCloser()221 ~JournalCloser() 222 { 223 sd_journal_close(journal); 224 } 225 226 private: 227 sd_journal* journal{nullptr}; 228 }; 229 230 } // namespace occ 231 } // namespace open_power 232