blob: 0e1e79e53f0a69f7fe1515e0e0f2aa0836a7a127 [file] [log] [blame]
Zane Shelley6e365872020-10-23 22:00:05 -05001#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
10namespace util
11{
12
13namespace fs = std::filesystem;
14using 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 */
36class FFDCFile
37{
38 public:
39 // Specify which compiler-generated methods we want
Patrick Williams27dd6362023-05-10 07:51:20 -050040 FFDCFile() = delete;
41 FFDCFile(const FFDCFile&) = delete;
42 FFDCFile(FFDCFile&&) = default;
Zane Shelley6e365872020-10-23 22:00:05 -050043 FFDCFile& operator=(const FFDCFile&) = delete;
Patrick Williams27dd6362023-05-10 07:51:20 -050044 FFDCFile& operator=(FFDCFile&&) = default;
45 ~FFDCFile() = default;
Zane Shelley6e365872020-10-23 22:00:05 -050046
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 */
Zane Shelley584f1792020-11-17 10:04:08 -060068 int getFileDescriptor() const
Zane Shelley6e365872020-10-23 22:00:05 -050069 {
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
Zane Shelley584f1792020-11-17 10:04:08 -0600156using 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. */
160inline void transformFFDC(const std::vector<FFDCFile>& i_files,
161 std::vector<FFDCTuple>& o_tuples)
162{
163 o_tuples.clear();
164
Zane Shelley9faf73b2020-12-01 19:51:35 -0600165 std::transform(i_files.begin(), i_files.end(), std::back_inserter(o_tuples),
Zane Shelley584f1792020-11-17 10:04:08 -0600166 [](const auto& e) {
Patrick Williams27dd6362023-05-10 07:51:20 -0500167 return FFDCTuple(e.getFormat(), e.getSubType(), e.getVersion(),
168 sdbusplus::message::unix_fd(e.getFileDescriptor()));
169 });
Zane Shelley584f1792020-11-17 10:04:08 -0600170}
171
Zane Shelley6e365872020-10-23 22:00:05 -0500172} // namespace util