1 #pragma once 2 3 #include "util/file_descriptor.hpp" 4 #include "util/temporary_file.hpp" 5 #include "xyz/openbmc_project/Logging/Create/server.hpp" 6 7 #include <cstdint> 8 #include <filesystem> 9 10 namespace util 11 { 12 13 namespace fs = std::filesystem; 14 using FFDCFormat = 15 sdbusplus::xyz::openbmc_project::Logging::server::Create::FFDCFormat; 16 17 /** 18 * @class FFDCFile 19 * 20 * File that contains FFDC (first failure data capture) data. 21 * 22 * This class is used to store FFDC data in an error log. The FFDC data is 23 * passed to the error logging system using a file descriptor. 24 * 25 * The constructor creates the file and opens it for both reading and writing. 26 * 27 * Use getFileDescriptor() to obtain the file descriptor needed to read or write 28 * data to the file. 29 * 30 * Use remove() to delete the file. Otherwise the file will be deleted by the 31 * destructor. 32 * 33 * FFDCFile objects cannot be copied, but they can be moved. This enables them 34 * to be stored in containers like std::vector. 35 */ 36 class FFDCFile 37 { 38 public: 39 // Specify which compiler-generated methods we want 40 FFDCFile() = delete; 41 FFDCFile(const FFDCFile&) = delete; 42 FFDCFile(FFDCFile&&) = default; 43 FFDCFile& operator=(const FFDCFile&) = delete; 44 FFDCFile& operator=(FFDCFile&&) = default; 45 ~FFDCFile() = default; 46 47 /** 48 * Constructor. 49 * 50 * Creates the file and opens it for both reading and writing. 51 * 52 * Throws an exception if an error occurs. 53 * 54 * @param format format type of the contained data 55 * @param subType format subtype; used for the 'Custom' type 56 * @param version version of the data format; used for the 'Custom' type 57 */ 58 explicit FFDCFile(FFDCFormat format, uint8_t subType = 0, 59 uint8_t version = 0); 60 61 /** 62 * Returns the file descriptor for the file. 63 * 64 * The file is open for both reading and writing. 65 * 66 * @return file descriptor 67 */ 68 int getFileDescriptor() const 69 { 70 // Return the integer file descriptor within the FileDescriptor object 71 return descriptor(); 72 } 73 74 /** 75 * Returns the format type of the contained data. 76 * 77 * @return format type 78 */ 79 FFDCFormat getFormat() const 80 { 81 return format; 82 } 83 84 /** 85 * Returns the absolute path to the file. 86 * 87 * @return absolute path 88 */ 89 const fs::path& getPath() const 90 { 91 return tempFile.getPath(); 92 } 93 94 /** 95 * Returns the format subtype. 96 * 97 * @return subtype 98 */ 99 uint8_t getSubType() const 100 { 101 return subType; 102 } 103 104 /** 105 * Returns the version of the data format. 106 * 107 * @return version 108 */ 109 uint8_t getVersion() const 110 { 111 return version; 112 } 113 114 /** 115 * Closes and deletes the file. 116 * 117 * Does nothing if the file has already been removed. 118 * 119 * Throws an exception if an error occurs. 120 */ 121 void remove(); 122 123 private: 124 /** 125 * Format type of the contained data. 126 */ 127 FFDCFormat format{FFDCFormat::Text}; 128 129 /** 130 * Format subtype; used for the 'Custom' type. 131 */ 132 uint8_t subType{0}; 133 134 /** 135 * Version of the data format; used for the 'Custom' type. 136 */ 137 uint8_t version{0}; 138 139 /** 140 * Temporary file where FFDC data is stored. 141 * 142 * The TemporaryFile destructor will automatically delete the file if it was 143 * not explicitly deleted using remove(). 144 */ 145 TemporaryFile tempFile{}; 146 147 /** 148 * File descriptor for reading from/writing to the file. 149 * 150 * The FileDescriptor destructor will automatically close the file if it was 151 * not explicitly closed using remove(). 152 */ 153 FileDescriptor descriptor{}; 154 }; 155 156 using FFDCTuple = 157 std::tuple<FFDCFormat, uint8_t, uint8_t, sdbusplus::message::unix_fd>; 158 159 /** Transforms a list of FFDC files to a list of FFDC tuples. */ 160 inline void transformFFDC(const std::vector<FFDCFile>& i_files, 161 std::vector<FFDCTuple>& o_tuples) 162 { 163 o_tuples.clear(); 164 165 std::transform(i_files.begin(), i_files.end(), std::back_inserter(o_tuples), 166 [](const auto& e) { 167 return FFDCTuple( 168 e.getFormat(), e.getSubType(), e.getVersion(), 169 sdbusplus::message::unix_fd(e.getFileDescriptor())); 170 }); 171 } 172 173 } // namespace util 174