16e36587aSZane Shelley #pragma once
26e36587aSZane Shelley 
36e36587aSZane Shelley #include "util/file_descriptor.hpp"
46e36587aSZane Shelley #include "util/temporary_file.hpp"
56e36587aSZane Shelley #include "xyz/openbmc_project/Logging/Create/server.hpp"
66e36587aSZane Shelley 
76e36587aSZane Shelley #include <cstdint>
86e36587aSZane Shelley #include <filesystem>
96e36587aSZane Shelley 
106e36587aSZane Shelley namespace util
116e36587aSZane Shelley {
126e36587aSZane Shelley 
136e36587aSZane Shelley namespace fs = std::filesystem;
146e36587aSZane Shelley using FFDCFormat =
156e36587aSZane Shelley     sdbusplus::xyz::openbmc_project::Logging::server::Create::FFDCFormat;
166e36587aSZane Shelley 
176e36587aSZane Shelley /**
186e36587aSZane Shelley  * @class FFDCFile
196e36587aSZane Shelley  *
206e36587aSZane Shelley  * File that contains FFDC (first failure data capture) data.
216e36587aSZane Shelley  *
226e36587aSZane Shelley  * This class is used to store FFDC data in an error log.  The FFDC data is
236e36587aSZane Shelley  * passed to the error logging system using a file descriptor.
246e36587aSZane Shelley  *
256e36587aSZane Shelley  * The constructor creates the file and opens it for both reading and writing.
266e36587aSZane Shelley  *
276e36587aSZane Shelley  * Use getFileDescriptor() to obtain the file descriptor needed to read or write
286e36587aSZane Shelley  * data to the file.
296e36587aSZane Shelley  *
306e36587aSZane Shelley  * Use remove() to delete the file.  Otherwise the file will be deleted by the
316e36587aSZane Shelley  * destructor.
326e36587aSZane Shelley  *
336e36587aSZane Shelley  * FFDCFile objects cannot be copied, but they can be moved.  This enables them
346e36587aSZane Shelley  * to be stored in containers like std::vector.
356e36587aSZane Shelley  */
366e36587aSZane Shelley class FFDCFile
376e36587aSZane Shelley {
386e36587aSZane Shelley   public:
396e36587aSZane Shelley     // Specify which compiler-generated methods we want
406e36587aSZane Shelley     FFDCFile() = delete;
416e36587aSZane Shelley     FFDCFile(const FFDCFile&) = delete;
426e36587aSZane Shelley     FFDCFile(FFDCFile&&) = default;
436e36587aSZane Shelley     FFDCFile& operator=(const FFDCFile&) = delete;
446e36587aSZane Shelley     FFDCFile& operator=(FFDCFile&&) = default;
456e36587aSZane Shelley     ~FFDCFile() = default;
466e36587aSZane Shelley 
476e36587aSZane Shelley     /**
486e36587aSZane Shelley      * Constructor.
496e36587aSZane Shelley      *
506e36587aSZane Shelley      * Creates the file and opens it for both reading and writing.
516e36587aSZane Shelley      *
526e36587aSZane Shelley      * Throws an exception if an error occurs.
536e36587aSZane Shelley      *
546e36587aSZane Shelley      * @param format format type of the contained data
556e36587aSZane Shelley      * @param subType format subtype; used for the 'Custom' type
566e36587aSZane Shelley      * @param version version of the data format; used for the 'Custom' type
576e36587aSZane Shelley      */
586e36587aSZane Shelley     explicit FFDCFile(FFDCFormat format, uint8_t subType = 0,
596e36587aSZane Shelley                       uint8_t version = 0);
606e36587aSZane Shelley 
616e36587aSZane Shelley     /**
626e36587aSZane Shelley      * Returns the file descriptor for the file.
636e36587aSZane Shelley      *
646e36587aSZane Shelley      * The file is open for both reading and writing.
656e36587aSZane Shelley      *
666e36587aSZane Shelley      * @return file descriptor
676e36587aSZane Shelley      */
getFileDescriptor() const68584f179eSZane Shelley     int getFileDescriptor() const
696e36587aSZane Shelley     {
706e36587aSZane Shelley         // Return the integer file descriptor within the FileDescriptor object
716e36587aSZane Shelley         return descriptor();
726e36587aSZane Shelley     }
736e36587aSZane Shelley 
746e36587aSZane Shelley     /**
756e36587aSZane Shelley      * Returns the format type of the contained data.
766e36587aSZane Shelley      *
776e36587aSZane Shelley      * @return format type
786e36587aSZane Shelley      */
getFormat() const796e36587aSZane Shelley     FFDCFormat getFormat() const
806e36587aSZane Shelley     {
816e36587aSZane Shelley         return format;
826e36587aSZane Shelley     }
836e36587aSZane Shelley 
846e36587aSZane Shelley     /**
856e36587aSZane Shelley      * Returns the absolute path to the file.
866e36587aSZane Shelley      *
876e36587aSZane Shelley      * @return absolute path
886e36587aSZane Shelley      */
getPath() const896e36587aSZane Shelley     const fs::path& getPath() const
906e36587aSZane Shelley     {
916e36587aSZane Shelley         return tempFile.getPath();
926e36587aSZane Shelley     }
936e36587aSZane Shelley 
946e36587aSZane Shelley     /**
956e36587aSZane Shelley      * Returns the format subtype.
966e36587aSZane Shelley      *
976e36587aSZane Shelley      * @return subtype
986e36587aSZane Shelley      */
getSubType() const996e36587aSZane Shelley     uint8_t getSubType() const
1006e36587aSZane Shelley     {
1016e36587aSZane Shelley         return subType;
1026e36587aSZane Shelley     }
1036e36587aSZane Shelley 
1046e36587aSZane Shelley     /**
1056e36587aSZane Shelley      * Returns the version of the data format.
1066e36587aSZane Shelley      *
1076e36587aSZane Shelley      * @return version
1086e36587aSZane Shelley      */
getVersion() const1096e36587aSZane Shelley     uint8_t getVersion() const
1106e36587aSZane Shelley     {
1116e36587aSZane Shelley         return version;
1126e36587aSZane Shelley     }
1136e36587aSZane Shelley 
1146e36587aSZane Shelley     /**
1156e36587aSZane Shelley      * Closes and deletes the file.
1166e36587aSZane Shelley      *
1176e36587aSZane Shelley      * Does nothing if the file has already been removed.
1186e36587aSZane Shelley      *
1196e36587aSZane Shelley      * Throws an exception if an error occurs.
1206e36587aSZane Shelley      */
1216e36587aSZane Shelley     void remove();
1226e36587aSZane Shelley 
1236e36587aSZane Shelley   private:
1246e36587aSZane Shelley     /**
1256e36587aSZane Shelley      * Format type of the contained data.
1266e36587aSZane Shelley      */
1276e36587aSZane Shelley     FFDCFormat format{FFDCFormat::Text};
1286e36587aSZane Shelley 
1296e36587aSZane Shelley     /**
1306e36587aSZane Shelley      * Format subtype; used for the 'Custom' type.
1316e36587aSZane Shelley      */
1326e36587aSZane Shelley     uint8_t subType{0};
1336e36587aSZane Shelley 
1346e36587aSZane Shelley     /**
1356e36587aSZane Shelley      * Version of the data format; used for the 'Custom' type.
1366e36587aSZane Shelley      */
1376e36587aSZane Shelley     uint8_t version{0};
1386e36587aSZane Shelley 
1396e36587aSZane Shelley     /**
1406e36587aSZane Shelley      * Temporary file where FFDC data is stored.
1416e36587aSZane Shelley      *
1426e36587aSZane Shelley      * The TemporaryFile destructor will automatically delete the file if it was
1436e36587aSZane Shelley      * not explicitly deleted using remove().
1446e36587aSZane Shelley      */
1456e36587aSZane Shelley     TemporaryFile tempFile{};
1466e36587aSZane Shelley 
1476e36587aSZane Shelley     /**
1486e36587aSZane Shelley      * File descriptor for reading from/writing to the file.
1496e36587aSZane Shelley      *
1506e36587aSZane Shelley      * The FileDescriptor destructor will automatically close the file if it was
1516e36587aSZane Shelley      * not explicitly closed using remove().
1526e36587aSZane Shelley      */
1536e36587aSZane Shelley     FileDescriptor descriptor{};
1546e36587aSZane Shelley };
1556e36587aSZane Shelley 
156584f179eSZane Shelley using FFDCTuple =
157584f179eSZane Shelley     std::tuple<FFDCFormat, uint8_t, uint8_t, sdbusplus::message::unix_fd>;
158584f179eSZane Shelley 
159584f179eSZane Shelley /** Transforms a list of FFDC files to a list of FFDC tuples. */
transformFFDC(const std::vector<FFDCFile> & i_files,std::vector<FFDCTuple> & o_tuples)160584f179eSZane Shelley inline void transformFFDC(const std::vector<FFDCFile>& i_files,
161584f179eSZane Shelley                           std::vector<FFDCTuple>& o_tuples)
162584f179eSZane Shelley {
163584f179eSZane Shelley     o_tuples.clear();
164584f179eSZane Shelley 
1659faf73baSZane Shelley     std::transform(i_files.begin(), i_files.end(), std::back_inserter(o_tuples),
166584f179eSZane Shelley                    [](const auto& e) {
167*27dd6368SPatrick Williams         return FFDCTuple(e.getFormat(), e.getSubType(), e.getVersion(),
168584f179eSZane Shelley                          sdbusplus::message::unix_fd(e.getFileDescriptor()));
169584f179eSZane Shelley     });
170584f179eSZane Shelley }
171584f179eSZane Shelley 
1726e36587aSZane Shelley } // namespace util
173