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*a0c724d3SPatrick Williams return FFDCTuple(
168*a0c724d3SPatrick Williams e.getFormat(), e.getSubType(), e.getVersion(),
169584f179eSZane Shelley sdbusplus::message::unix_fd(e.getFileDescriptor()));
170584f179eSZane Shelley });
171584f179eSZane Shelley }
172584f179eSZane Shelley
1736e36587aSZane Shelley } // namespace util
174