blob: 61bd7147ec0e1fbcbb4a9db00930179812ea6905 [file] [log] [blame]
Eddie James2f9f9bb2021-09-20 14:26:31 -05001#pragma once
2
3#include "config.h"
4
Chris Cain2ccc3f62022-10-05 14:40:07 -05005#include "file.hpp"
Eddie James2f9f9bb2021-09-20 14:26:31 -05006#include "occ_errors.hpp"
7
Chris Cain2ccc3f62022-10-05 14:40:07 -05008#include <systemd/sd-journal.h>
9
10#include <nlohmann/json.hpp>
11#include <xyz/openbmc_project/Logging/Create/server.hpp>
12
13using FFDCFormat =
14 sdbusplus::xyz::openbmc_project::Logging::server::Create::FFDCFormat;
15using FFDCFiles = std::vector<
16 std::tuple<FFDCFormat, uint8_t, uint8_t, sdbusplus::message::unix_fd>>;
17
Eddie James2f9f9bb2021-09-20 14:26:31 -050018namespace open_power
19{
20namespace occ
21{
22
Chris Cain2ccc3f62022-10-05 14:40:07 -050023/** @class FFDCFile
24 * @brief Represents a single file that will get opened when created and
25 * deleted when the object is destructed
26 */
27class 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 */
48 ~FFDCFile()
49 {
50 std::filesystem::remove(_name);
51 }
52
53 /**
54 * @brief Returns the file descriptor
55 *
56 * @return int - The descriptor
57 */
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
Eddie James2f9f9bb2021-09-20 14:26:31 -050075/** @class FFDC
76 * @brief Monitors for SBE FFDC availability
77 */
78class 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 */
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
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
Eddie James9789e712022-05-25 15:43:40 -0500119 /** @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 */
127 static void createOCCResetPEL(unsigned int instance, const char* path,
128 int err, const char* callout);
129
Chris Cain2ccc3f62022-10-05 14:40:07 -0500130 /**
131 * @brief Create a file containing the latest journal traces for the
132 * specified executable and add it to the file list.
133 *
134 * @param[in] fileList - where to add the new file
135 * @param[in] executable - name of app to collect
136 * @param[in] lines - number of journal lines to save
137 *
138 * @return std::unique_ptr<FFDCFile> - The file object
139 */
140 static std::unique_ptr<FFDCFile>
141 addJournalEntries(FFDCFiles& fileList, const std::string& executable,
142 unsigned int lines);
143
Eddie James2f9f9bb2021-09-20 14:26:31 -0500144 private:
145 /** @brief OCC instance number. Ex, 0,1, etc */
146 unsigned int instance;
147
148 /** @brief Stores the temporary files and file descriptors
149 * in usage. They will be cleaned up when the class
150 * is destroyed (when the application exits).
151 */
152 std::vector<std::pair<fs::path, int>> temporaryFiles;
153
154 /** @brief When the error event is received, analyzes it
155 * and makes a callback to error handler if the
156 * content denotes an error condition
157 */
158 void analyzeEvent() override;
Chris Cain2ccc3f62022-10-05 14:40:07 -0500159
160 /**
161 * @brief Returns an FFDCFile containing the JSON data
162 *
163 * @param[in] ffdcData - The JSON data to write to a file
164 *
165 * @return std::unique_ptr<FFDCFile> - The file object
166 */
167 static std::unique_ptr<FFDCFile>
168 makeJsonFFDCFile(const nlohmann::json& ffdcData);
169
170 /**
171 * @brief Returns a JSON structure containing the previous N journal
172 * entries.
173 *
174 * @param[in] numLines - Number of lines of journal to retrieve
175 * @param[in] executable - name of app to collect for
176 *
177 * @return JSON object that was created
178 */
179 static nlohmann::json getJournalEntries(int numLines,
180 std::string executable);
181
182 /**
183 * @brief Gets the realtime (wallclock) timestamp for the current journal
184 * entry.
185 *
186 * @param journal current journal entry
187 * @return timestamp as a date/time string
188 */
189 static std::string getTimeStamp(sd_journal* journal);
190
191 /**
192 * @brief Gets the value of the specified field for the current journal
193 * entry.
194 *
195 * Returns an empty string if the current journal entry does not have the
196 * specified field.
197 *
198 * @param journal current journal entry
199 * @param field journal field name
200 * @return field value
201 */
202 static std::string getFieldValue(sd_journal* journal,
203 const std::string& field);
204};
205
206/**
207 * @class JournalCloser
208 * @brief Automatically closes the journal when the object goes out of scope.
209 */
210class JournalCloser
211{
212 public:
213 // Specify which compiler-generated methods we want
214 JournalCloser() = delete;
215 JournalCloser(const JournalCloser&) = delete;
216 JournalCloser(JournalCloser&&) = delete;
217 JournalCloser& operator=(const JournalCloser&) = delete;
218 JournalCloser& operator=(JournalCloser&&) = delete;
219
220 JournalCloser(sd_journal* journal) : journal{journal}
221 {}
222
223 ~JournalCloser()
224 {
225 sd_journal_close(journal);
226 }
227
228 private:
229 sd_journal* journal{nullptr};
Eddie James2f9f9bb2021-09-20 14:26:31 -0500230};
231
232} // namespace occ
233} // namespace open_power