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