blob: 7578e4d779496b7259b9012d243caa068e05f746 [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 */
Patrick Williamsd7542c82024-08-16 15:20:28 -0400140 static std::unique_ptr<FFDCFile> addJournalEntries(
141 FFDCFiles& fileList, const std::string& executable, unsigned int lines);
Chris Cain2ccc3f62022-10-05 14:40:07 -0500142
Eddie James2f9f9bb2021-09-20 14:26:31 -0500143 private:
144 /** @brief OCC instance number. Ex, 0,1, etc */
145 unsigned int instance;
146
147 /** @brief Stores the temporary files and file descriptors
148 * in usage. They will be cleaned up when the class
149 * is destroyed (when the application exits).
150 */
151 std::vector<std::pair<fs::path, int>> temporaryFiles;
152
153 /** @brief When the error event is received, analyzes it
154 * and makes a callback to error handler if the
155 * content denotes an error condition
156 */
157 void analyzeEvent() override;
Chris Cain2ccc3f62022-10-05 14:40:07 -0500158
159 /**
160 * @brief Returns an FFDCFile containing the JSON data
161 *
162 * @param[in] ffdcData - The JSON data to write to a file
163 *
164 * @return std::unique_ptr<FFDCFile> - The file object
165 */
166 static std::unique_ptr<FFDCFile>
167 makeJsonFFDCFile(const nlohmann::json& ffdcData);
168
169 /**
170 * @brief Returns a JSON structure containing the previous N journal
171 * entries.
172 *
173 * @param[in] numLines - Number of lines of journal to retrieve
174 * @param[in] executable - name of app to collect for
175 *
176 * @return JSON object that was created
177 */
178 static nlohmann::json getJournalEntries(int numLines,
179 std::string executable);
180
181 /**
182 * @brief Gets the realtime (wallclock) timestamp for the current journal
183 * entry.
184 *
185 * @param journal current journal entry
186 * @return timestamp as a date/time string
187 */
188 static std::string getTimeStamp(sd_journal* journal);
189
190 /**
191 * @brief Gets the value of the specified field for the current journal
192 * entry.
193 *
194 * Returns an empty string if the current journal entry does not have the
195 * specified field.
196 *
197 * @param journal current journal entry
198 * @param field journal field name
199 * @return field value
200 */
201 static std::string getFieldValue(sd_journal* journal,
202 const std::string& field);
203};
204
205/**
206 * @class JournalCloser
207 * @brief Automatically closes the journal when the object goes out of scope.
208 */
209class JournalCloser
210{
211 public:
212 // Specify which compiler-generated methods we want
213 JournalCloser() = delete;
214 JournalCloser(const JournalCloser&) = delete;
215 JournalCloser(JournalCloser&&) = delete;
216 JournalCloser& operator=(const JournalCloser&) = delete;
217 JournalCloser& operator=(JournalCloser&&) = delete;
218
Patrick Williamsa49c9872023-05-10 07:50:35 -0500219 JournalCloser(sd_journal* journal) : journal{journal} {}
Chris Cain2ccc3f62022-10-05 14:40:07 -0500220
221 ~JournalCloser()
222 {
223 sd_journal_close(journal);
224 }
225
226 private:
227 sd_journal* journal{nullptr};
Eddie James2f9f9bb2021-09-20 14:26:31 -0500228};
229
230} // namespace occ
231} // namespace open_power