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 */ 48 ~FFDCFile() 49 { 50 std::filesystem::remove(_name); 51 } 52 53 /** 54 * @brief Returns the file descriptor 55 * 56 * @return int - The descriptor 57 */ 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 */ 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 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> 141 addJournalEntries(FFDCFiles& fileList, const std::string& executable, 142 unsigned int lines); 143 144 private: 145 /** @brief OCC instance number. Ex, 0,1, etc */ 146 unsigned int instance; 147 148 /** @brief Stores the temporary files and file descriptors 149 * in usage. They will be cleaned up when the class 150 * is destroyed (when the application exits). 151 */ 152 std::vector<std::pair<fs::path, int>> temporaryFiles; 153 154 /** @brief When the error event is received, analyzes it 155 * and makes a callback to error handler if the 156 * content denotes an error condition 157 */ 158 void analyzeEvent() override; 159 160 /** 161 * @brief Returns an FFDCFile containing the JSON data 162 * 163 * @param[in] ffdcData - The JSON data to write to a file 164 * 165 * @return std::unique_ptr<FFDCFile> - The file object 166 */ 167 static std::unique_ptr<FFDCFile> 168 makeJsonFFDCFile(const nlohmann::json& ffdcData); 169 170 /** 171 * @brief Returns a JSON structure containing the previous N journal 172 * entries. 173 * 174 * @param[in] numLines - Number of lines of journal to retrieve 175 * @param[in] executable - name of app to collect for 176 * 177 * @return JSON object that was created 178 */ 179 static nlohmann::json getJournalEntries(int numLines, 180 std::string executable); 181 182 /** 183 * @brief Gets the realtime (wallclock) timestamp for the current journal 184 * entry. 185 * 186 * @param journal current journal entry 187 * @return timestamp as a date/time string 188 */ 189 static std::string getTimeStamp(sd_journal* journal); 190 191 /** 192 * @brief Gets the value of the specified field for the current journal 193 * entry. 194 * 195 * Returns an empty string if the current journal entry does not have the 196 * specified field. 197 * 198 * @param journal current journal entry 199 * @param field journal field name 200 * @return field value 201 */ 202 static std::string getFieldValue(sd_journal* journal, 203 const std::string& field); 204 }; 205 206 /** 207 * @class JournalCloser 208 * @brief Automatically closes the journal when the object goes out of scope. 209 */ 210 class JournalCloser 211 { 212 public: 213 // Specify which compiler-generated methods we want 214 JournalCloser() = delete; 215 JournalCloser(const JournalCloser&) = delete; 216 JournalCloser(JournalCloser&&) = delete; 217 JournalCloser& operator=(const JournalCloser&) = delete; 218 JournalCloser& operator=(JournalCloser&&) = delete; 219 220 JournalCloser(sd_journal* journal) : journal{journal} 221 {} 222 223 ~JournalCloser() 224 { 225 sd_journal_close(journal); 226 } 227 228 private: 229 sd_journal* journal{nullptr}; 230 }; 231 232 } // namespace occ 233 } // namespace open_power 234