blob: adb12c188b659c200f7297f9e974c8f3cedada25 [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
3// SPDX-FileCopyrightText: Copyright 2018 Intel Corporation
Ed Tanous1da66f72018-07-27 16:13:37 -07004#pragma once
5
Ed Tanousd7857202025-01-28 15:32:26 -08006#include "bmcweb_config.h"
7
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08008#include "app.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -08009#include "async_resp.hpp"
10#include "dbus_singleton.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080011#include "dbus_utility.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080012#include "error_messages.hpp"
Asmitha Karunanithi68dd0752022-11-15 11:33:46 -060013#include "generated/enums/log_entry.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -070014#include "generated/enums/log_service.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080015#include "http_body.hpp"
16#include "http_request.hpp"
17#include "http_response.hpp"
George Liu647b3cd2021-07-05 12:43:56 +080018#include "http_utility.hpp"
Spencer Kub7028eb2021-10-26 15:27:35 +080019#include "human_sort.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080020#include "logging.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080021#include "query.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080022#include "registries/privilege_registry.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080023#include "str_utility.hpp"
James Feist46229572020-02-19 15:11:58 -080024#include "task.hpp"
Ed Tanous5b904292024-04-16 11:10:17 -070025#include "task_messages.hpp"
Alexander Hansen262dcc12024-09-19 12:04:03 +020026#include "utils/dbus_event_log_entry.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080027#include "utils/dbus_utils.hpp"
Corey Ethington08fad5d2025-07-31 12:14:27 -040028#include "utils/etag_utils.hpp"
Ed Tanous5b904292024-04-16 11:10:17 -070029#include "utils/json_utils.hpp"
Oliver Brewkaff35df92025-08-26 08:21:30 +020030#include "utils/log_services_utils.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080031#include "utils/time_utils.hpp"
Ed Tanous1da66f72018-07-27 16:13:37 -070032
Ed Tanousd7857202025-01-28 15:32:26 -080033#include <asm-generic/errno.h>
34#include <systemd/sd-bus.h>
Asmitha Karunanithi8e317782020-12-10 03:35:05 -060035#include <tinyxml2.h>
Adriana Kobylak400fd1f2021-01-29 09:01:30 -060036#include <unistd.h>
Jason M. Billse1f26342018-07-18 12:12:00 -070037
Ed Tanousd7857202025-01-28 15:32:26 -080038#include <boost/beast/http/field.hpp>
39#include <boost/beast/http/status.hpp>
Ed Tanous07c8c202022-07-11 10:08:08 -070040#include <boost/beast/http/verb.hpp>
Jason M. Bills1ddcf012019-11-26 14:59:21 -080041#include <boost/system/linux_error.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070042#include <boost/url/format.hpp>
Ed Tanousd7857202025-01-28 15:32:26 -080043#include <boost/url/url.hpp>
44#include <sdbusplus/message.hpp>
45#include <sdbusplus/message/native_types.hpp>
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020046#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050047
Ed Tanousd7857202025-01-28 15:32:26 -080048#include <algorithm>
George Liu7a1dbc42022-12-07 16:03:22 +080049#include <array>
Ed Tanousd7857202025-01-28 15:32:26 -080050#include <chrono>
Ed Tanousd7857202025-01-28 15:32:26 -080051#include <cstdint>
James Feist4418c7f2019-04-15 11:09:15 -070052#include <filesystem>
Ed Tanousd7857202025-01-28 15:32:26 -080053#include <format>
Ed Tanousd7857202025-01-28 15:32:26 -080054#include <functional>
Ed Tanous18f8f602023-07-18 10:07:23 -070055#include <iterator>
Ed Tanousd7857202025-01-28 15:32:26 -080056#include <memory>
Xiaochao Ma75710de2021-01-21 17:56:02 +080057#include <optional>
Ed Tanous3544d2a2023-08-06 18:12:20 -070058#include <ranges>
Ed Tanous26702d02021-11-03 15:02:33 -070059#include <span>
Ed Tanous18f8f602023-07-18 10:07:23 -070060#include <string>
Jason M. Billscd225da2019-05-08 15:31:57 -070061#include <string_view>
Ed Tanousd7857202025-01-28 15:32:26 -080062#include <utility>
Ed Tanousabf2add2019-01-22 16:40:12 -080063#include <variant>
Ed Tanousd7857202025-01-28 15:32:26 -080064#include <vector>
Ed Tanous1da66f72018-07-27 16:13:37 -070065
66namespace redfish
67{
68
Patrick Williams89492a12023-05-10 07:51:34 -050069constexpr const char* crashdumpObject = "com.intel.crashdump";
70constexpr const char* crashdumpPath = "/com/intel/crashdump";
71constexpr const char* crashdumpInterface = "com.intel.crashdump";
72constexpr const char* deleteAllInterface =
Jason M. Bills5b61b5e2019-10-16 10:59:02 -070073 "xyz.openbmc_project.Collection.DeleteAll";
Patrick Williams89492a12023-05-10 07:51:34 -050074constexpr const char* crashdumpOnDemandInterface =
Jason M. Bills424c4172019-03-21 13:50:33 -070075 "com.intel.crashdump.OnDemand";
Patrick Williams89492a12023-05-10 07:51:34 -050076constexpr const char* crashdumpTelemetryInterface =
Kenny L. Ku6eda7682020-06-19 09:48:36 -070077 "com.intel.crashdump.Telemetry";
Ed Tanous1da66f72018-07-27 16:13:37 -070078
Asmitha Karunanithi8e317782020-12-10 03:35:05 -060079enum class DumpCreationProgress
80{
81 DUMP_CREATE_SUCCESS,
82 DUMP_CREATE_FAILED,
83 DUMP_CREATE_INPROGRESS
84};
85
Gunnar Mills1214b7e2020-06-04 10:11:30 -050086inline std::string translateSeverityDbusToRedfish(const std::string& s)
Andrew Geisslercb92c032018-08-17 07:56:14 -070087{
Ed Tanousd4d25792020-09-29 15:15:03 -070088 if ((s == "xyz.openbmc_project.Logging.Entry.Level.Alert") ||
89 (s == "xyz.openbmc_project.Logging.Entry.Level.Critical") ||
90 (s == "xyz.openbmc_project.Logging.Entry.Level.Emergency") ||
91 (s == "xyz.openbmc_project.Logging.Entry.Level.Error"))
Andrew Geisslercb92c032018-08-17 07:56:14 -070092 {
93 return "Critical";
94 }
Ed Tanous3174e4d2020-10-07 11:41:22 -070095 if ((s == "xyz.openbmc_project.Logging.Entry.Level.Debug") ||
96 (s == "xyz.openbmc_project.Logging.Entry.Level.Informational") ||
97 (s == "xyz.openbmc_project.Logging.Entry.Level.Notice"))
Andrew Geisslercb92c032018-08-17 07:56:14 -070098 {
99 return "OK";
100 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700101 if (s == "xyz.openbmc_project.Logging.Entry.Level.Warning")
Andrew Geisslercb92c032018-08-17 07:56:14 -0700102 {
103 return "Warning";
104 }
105 return "";
106}
107
Abhishek Patel9017faf2021-09-14 22:48:55 -0500108inline std::optional<bool> getProviderNotifyAction(const std::string& notify)
109{
110 std::optional<bool> notifyAction;
111 if (notify == "xyz.openbmc_project.Logging.Entry.Notify.Notify")
112 {
113 notifyAction = true;
114 }
115 else if (notify == "xyz.openbmc_project.Logging.Entry.Notify.Inhibit")
116 {
117 notifyAction = false;
118 }
119
120 return notifyAction;
121}
122
Ed Tanous18f8f602023-07-18 10:07:23 -0700123inline std::string getDumpPath(std::string_view dumpType)
124{
125 std::string dbusDumpPath = "/xyz/openbmc_project/dump/";
126 std::ranges::transform(dumpType, std::back_inserter(dbusDumpPath),
127 bmcweb::asciiToLower);
128
129 return dbusDumpPath;
130}
131
Patrick Williams504af5a2025-02-03 14:29:03 -0500132inline log_entry::OriginatorTypes mapDbusOriginatorTypeToRedfish(
133 const std::string& originatorType)
Asmitha Karunanithi68dd0752022-11-15 11:33:46 -0600134{
135 if (originatorType ==
136 "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Client")
137 {
138 return log_entry::OriginatorTypes::Client;
139 }
140 if (originatorType ==
141 "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Internal")
142 {
143 return log_entry::OriginatorTypes::Internal;
144 }
145 if (originatorType ==
146 "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.SupportingService")
147 {
148 return log_entry::OriginatorTypes::SupportingService;
149 }
150 return log_entry::OriginatorTypes::Invalid;
151}
152
Claire Weinanaefe3782022-07-15 19:17:19 -0700153inline void parseDumpEntryFromDbusObject(
Jiaqing Zhao2d613eb2022-08-15 16:03:00 +0800154 const dbus::utility::ManagedObjectType::value_type& object,
Claire Weinanc6fecda2022-07-15 10:43:25 -0700155 std::string& dumpStatus, uint64_t& size, uint64_t& timestampUs,
Asmitha Karunanithi68dd0752022-11-15 11:33:46 -0600156 std::string& originatorId, log_entry::OriginatorTypes& originatorType,
Claire Weinanaefe3782022-07-15 19:17:19 -0700157 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
158{
159 for (const auto& interfaceMap : object.second)
160 {
161 if (interfaceMap.first == "xyz.openbmc_project.Common.Progress")
162 {
163 for (const auto& propertyMap : interfaceMap.second)
164 {
165 if (propertyMap.first == "Status")
166 {
167 const auto* status =
168 std::get_if<std::string>(&propertyMap.second);
169 if (status == nullptr)
170 {
171 messages::internalError(asyncResp->res);
172 break;
173 }
174 dumpStatus = *status;
175 }
176 }
177 }
178 else if (interfaceMap.first == "xyz.openbmc_project.Dump.Entry")
179 {
180 for (const auto& propertyMap : interfaceMap.second)
181 {
182 if (propertyMap.first == "Size")
183 {
184 const auto* sizePtr =
185 std::get_if<uint64_t>(&propertyMap.second);
186 if (sizePtr == nullptr)
187 {
188 messages::internalError(asyncResp->res);
189 break;
190 }
191 size = *sizePtr;
192 break;
193 }
194 }
195 }
196 else if (interfaceMap.first == "xyz.openbmc_project.Time.EpochTime")
197 {
198 for (const auto& propertyMap : interfaceMap.second)
199 {
200 if (propertyMap.first == "Elapsed")
201 {
202 const uint64_t* usecsTimeStamp =
203 std::get_if<uint64_t>(&propertyMap.second);
204 if (usecsTimeStamp == nullptr)
205 {
206 messages::internalError(asyncResp->res);
207 break;
208 }
Claire Weinanc6fecda2022-07-15 10:43:25 -0700209 timestampUs = *usecsTimeStamp;
Claire Weinanaefe3782022-07-15 19:17:19 -0700210 break;
211 }
212 }
213 }
Asmitha Karunanithi68dd0752022-11-15 11:33:46 -0600214 else if (interfaceMap.first ==
215 "xyz.openbmc_project.Common.OriginatedBy")
216 {
217 for (const auto& propertyMap : interfaceMap.second)
218 {
219 if (propertyMap.first == "OriginatorId")
220 {
221 const std::string* id =
222 std::get_if<std::string>(&propertyMap.second);
223 if (id == nullptr)
224 {
225 messages::internalError(asyncResp->res);
226 break;
227 }
228 originatorId = *id;
229 }
230
231 if (propertyMap.first == "OriginatorType")
232 {
233 const std::string* type =
234 std::get_if<std::string>(&propertyMap.second);
235 if (type == nullptr)
236 {
237 messages::internalError(asyncResp->res);
238 break;
239 }
240
241 originatorType = mapDbusOriginatorTypeToRedfish(*type);
242 if (originatorType == log_entry::OriginatorTypes::Invalid)
243 {
244 messages::internalError(asyncResp->res);
245 break;
246 }
247 }
248 }
249 }
Claire Weinanaefe3782022-07-15 19:17:19 -0700250 }
251}
252
Nan Zhou21ab4042022-06-26 23:07:40 +0000253static std::string getDumpEntriesPath(const std::string& dumpType)
Claire Weinanfdd26902022-03-01 14:18:25 -0800254{
255 std::string entriesPath;
256
257 if (dumpType == "BMC")
258 {
Ed Tanous253f11b2024-05-16 09:38:31 -0700259 entriesPath =
260 std::format("/redfish/v1/Managers/{}/LogServices/Dump/Entries/",
261 BMCWEB_REDFISH_MANAGER_URI_NAME);
Claire Weinanfdd26902022-03-01 14:18:25 -0800262 }
263 else if (dumpType == "FaultLog")
264 {
Ed Tanous253f11b2024-05-16 09:38:31 -0700265 entriesPath =
266 std::format("/redfish/v1/Managers/{}/LogServices/FaultLog/Entries/",
267 BMCWEB_REDFISH_MANAGER_URI_NAME);
Claire Weinanfdd26902022-03-01 14:18:25 -0800268 }
269 else if (dumpType == "System")
270 {
Ed Tanous253f11b2024-05-16 09:38:31 -0700271 entriesPath =
272 std::format("/redfish/v1/Systems/{}/LogServices/Dump/Entries/",
273 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Claire Weinanfdd26902022-03-01 14:18:25 -0800274 }
275 else
276 {
Ed Tanous62598e32023-07-17 17:06:25 -0700277 BMCWEB_LOG_ERROR("getDumpEntriesPath() invalid dump type: {}",
278 dumpType);
Claire Weinanfdd26902022-03-01 14:18:25 -0800279 }
280
281 // Returns empty string on error
282 return entriesPath;
283}
284
Patrick Williams504af5a2025-02-03 14:29:03 -0500285inline void getDumpEntryCollection(
286 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
287 const std::string& dumpType)
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500288{
Claire Weinanfdd26902022-03-01 14:18:25 -0800289 std::string entriesPath = getDumpEntriesPath(dumpType);
290 if (entriesPath.empty())
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500291 {
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500292 messages::internalError(asyncResp->res);
293 return;
294 }
295
George Liu5eb468d2023-06-20 17:03:24 +0800296 sdbusplus::message::object_path path("/xyz/openbmc_project/dump");
297 dbus::utility::getManagedObjects(
298 "xyz.openbmc_project.Dump.Manager", path,
Claire Weinanfdd26902022-03-01 14:18:25 -0800299 [asyncResp, entriesPath,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800300 dumpType](const boost::system::error_code& ec,
George Liu5eb468d2023-06-20 17:03:24 +0800301 const dbus::utility::ManagedObjectType& objects) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400302 if (ec)
303 {
304 BMCWEB_LOG_ERROR("DumpEntry resp_handler got error {}", ec);
305 messages::internalError(asyncResp->res);
306 return;
307 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700308
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400309 // Remove ending slash
310 std::string odataIdStr = entriesPath;
311 if (!odataIdStr.empty())
312 {
313 odataIdStr.pop_back();
314 }
Claire Weinanfdd26902022-03-01 14:18:25 -0800315
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400316 asyncResp->res.jsonValue["@odata.type"] =
317 "#LogEntryCollection.LogEntryCollection";
318 asyncResp->res.jsonValue["@odata.id"] = std::move(odataIdStr);
319 asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entries";
320 asyncResp->res.jsonValue["Description"] =
321 "Collection of " + dumpType + " Dump Entries";
Claire Weinanfdd26902022-03-01 14:18:25 -0800322
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400323 nlohmann::json::array_t entriesArray;
324 std::string dumpEntryPath = getDumpPath(dumpType) + "/entry/";
Ed Tanous002d39b2022-05-31 08:59:27 -0700325
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400326 dbus::utility::ManagedObjectType resp(objects);
327 std::ranges::sort(resp, [](const auto& l, const auto& r) {
328 return AlphanumLess<std::string>()(l.first.filename(),
329 r.first.filename());
330 });
331
332 for (auto& object : resp)
333 {
334 if (object.first.str.find(dumpEntryPath) == std::string::npos)
335 {
336 continue;
337 }
338 uint64_t timestampUs = 0;
339 uint64_t size = 0;
340 std::string dumpStatus;
341 std::string originatorId;
342 log_entry::OriginatorTypes originatorType =
343 log_entry::OriginatorTypes::Internal;
344 nlohmann::json::object_t thisEntry;
345
346 std::string entryID = object.first.filename();
347 if (entryID.empty())
348 {
349 continue;
350 }
351
352 parseDumpEntryFromDbusObject(object, dumpStatus, size,
353 timestampUs, originatorId,
354 originatorType, asyncResp);
355
356 if (dumpStatus !=
357 "xyz.openbmc_project.Common.Progress.OperationStatus.Completed" &&
358 !dumpStatus.empty())
359 {
360 // Dump status is not Complete, no need to enumerate
361 continue;
362 }
363
364 thisEntry["@odata.type"] = "#LogEntry.v1_11_0.LogEntry";
365 thisEntry["@odata.id"] = entriesPath + entryID;
366 thisEntry["Id"] = entryID;
367 thisEntry["EntryType"] = "Event";
368 thisEntry["Name"] = dumpType + " Dump Entry";
369 thisEntry["Created"] =
370 redfish::time_utils::getDateTimeUintUs(timestampUs);
371
372 if (!originatorId.empty())
373 {
374 thisEntry["Originator"] = originatorId;
375 thisEntry["OriginatorType"] = originatorType;
376 }
377
378 if (dumpType == "BMC")
379 {
380 thisEntry["DiagnosticDataType"] = "Manager";
381 thisEntry["AdditionalDataURI"] =
382 entriesPath + entryID + "/attachment";
383 thisEntry["AdditionalDataSizeBytes"] = size;
384 }
385 else if (dumpType == "System")
386 {
387 thisEntry["DiagnosticDataType"] = "OEM";
388 thisEntry["OEMDiagnosticDataType"] = "System";
389 thisEntry["AdditionalDataURI"] =
390 entriesPath + entryID + "/attachment";
391 thisEntry["AdditionalDataSizeBytes"] = size;
392 }
393 entriesArray.emplace_back(std::move(thisEntry));
394 }
395 asyncResp->res.jsonValue["Members@odata.count"] =
396 entriesArray.size();
397 asyncResp->res.jsonValue["Members"] = std::move(entriesArray);
Ed Tanous002d39b2022-05-31 08:59:27 -0700398 });
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500399}
400
Patrick Williams504af5a2025-02-03 14:29:03 -0500401inline void getDumpEntryById(
402 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
403 const std::string& entryID, const std::string& dumpType)
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500404{
Claire Weinanfdd26902022-03-01 14:18:25 -0800405 std::string entriesPath = getDumpEntriesPath(dumpType);
406 if (entriesPath.empty())
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500407 {
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500408 messages::internalError(asyncResp->res);
409 return;
410 }
411
George Liu5eb468d2023-06-20 17:03:24 +0800412 sdbusplus::message::object_path path("/xyz/openbmc_project/dump");
413 dbus::utility::getManagedObjects(
414 "xyz.openbmc_project.Dump.Manager", path,
Claire Weinanfdd26902022-03-01 14:18:25 -0800415 [asyncResp, entryID, dumpType,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800416 entriesPath](const boost::system::error_code& ec,
Ed Tanous02cad962022-06-30 16:50:15 -0700417 const dbus::utility::ManagedObjectType& resp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400418 if (ec)
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500419 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400420 BMCWEB_LOG_ERROR("DumpEntry resp_handler got error {}", ec);
421 messages::internalError(asyncResp->res);
422 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700423 }
424
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400425 bool foundDumpEntry = false;
426 std::string dumpEntryPath = getDumpPath(dumpType) + "/entry/";
Ed Tanous002d39b2022-05-31 08:59:27 -0700427
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400428 for (const auto& objectPath : resp)
Ed Tanous002d39b2022-05-31 08:59:27 -0700429 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400430 if (objectPath.first.str != dumpEntryPath + entryID)
431 {
432 continue;
433 }
434
435 foundDumpEntry = true;
436 uint64_t timestampUs = 0;
437 uint64_t size = 0;
438 std::string dumpStatus;
439 std::string originatorId;
440 log_entry::OriginatorTypes originatorType =
441 log_entry::OriginatorTypes::Internal;
442
443 parseDumpEntryFromDbusObject(objectPath, dumpStatus, size,
444 timestampUs, originatorId,
445 originatorType, asyncResp);
446
447 if (dumpStatus !=
448 "xyz.openbmc_project.Common.Progress.OperationStatus.Completed" &&
449 !dumpStatus.empty())
450 {
451 // Dump status is not Complete
452 // return not found until status is changed to Completed
453 messages::resourceNotFound(asyncResp->res,
454 dumpType + " dump", entryID);
455 return;
456 }
457
458 asyncResp->res.jsonValue["@odata.type"] =
459 "#LogEntry.v1_11_0.LogEntry";
460 asyncResp->res.jsonValue["@odata.id"] = entriesPath + entryID;
461 asyncResp->res.jsonValue["Id"] = entryID;
462 asyncResp->res.jsonValue["EntryType"] = "Event";
463 asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entry";
464 asyncResp->res.jsonValue["Created"] =
465 redfish::time_utils::getDateTimeUintUs(timestampUs);
466
467 if (!originatorId.empty())
468 {
469 asyncResp->res.jsonValue["Originator"] = originatorId;
470 asyncResp->res.jsonValue["OriginatorType"] = originatorType;
471 }
472
473 if (dumpType == "BMC")
474 {
475 asyncResp->res.jsonValue["DiagnosticDataType"] = "Manager";
476 asyncResp->res.jsonValue["AdditionalDataURI"] =
477 entriesPath + entryID + "/attachment";
478 asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size;
479 }
480 else if (dumpType == "System")
481 {
482 asyncResp->res.jsonValue["DiagnosticDataType"] = "OEM";
483 asyncResp->res.jsonValue["OEMDiagnosticDataType"] =
484 "System";
485 asyncResp->res.jsonValue["AdditionalDataURI"] =
486 entriesPath + entryID + "/attachment";
487 asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size;
488 }
489 }
490 if (!foundDumpEntry)
491 {
492 BMCWEB_LOG_WARNING("Can't find Dump Entry {}", entryID);
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200493 messages::resourceNotFound(asyncResp->res, dumpType + " dump",
494 entryID);
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500495 return;
496 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400497 });
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500498}
499
zhanghch058d1b46d2021-04-01 11:18:24 +0800500inline void deleteDumpEntry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Stanley Chu98782562020-11-04 16:10:24 +0800501 const std::string& entryID,
Asmitha Karunanithib47452b2020-09-25 02:02:19 -0500502 const std::string& dumpType)
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500503{
Patrick Williams5a39f772023-10-20 11:20:21 -0500504 auto respHandler = [asyncResp,
505 entryID](const boost::system::error_code& ec) {
Ed Tanous62598e32023-07-17 17:06:25 -0700506 BMCWEB_LOG_DEBUG("Dump Entry doDelete callback: Done");
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500507 if (ec)
508 {
George Liu3de8d8b2021-03-22 17:49:39 +0800509 if (ec.value() == EBADR)
510 {
511 messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
512 return;
513 }
Ed Tanous62598e32023-07-17 17:06:25 -0700514 BMCWEB_LOG_ERROR(
515 "Dump (DBus) doDelete respHandler got error {} entryID={}", ec,
516 entryID);
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500517 messages::internalError(asyncResp->res);
518 return;
519 }
520 };
Ed Tanous18f8f602023-07-18 10:07:23 -0700521
Ed Tanous177612a2025-02-14 15:16:09 -0800522 dbus::utility::async_method_call(
523 asyncResp, respHandler, "xyz.openbmc_project.Dump.Manager",
Ed Tanous18f8f602023-07-18 10:07:23 -0700524 std::format("{}/entry/{}", getDumpPath(dumpType), entryID),
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500525 "xyz.openbmc_project.Object.Delete", "Delete");
526}
Carson Labrado168d1b12023-03-27 17:04:46 +0000527
Patrick Williams504af5a2025-02-03 14:29:03 -0500528inline void downloadDumpEntry(
529 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
530 const std::string& entryID, const std::string& dumpType)
Carson Labrado168d1b12023-03-27 17:04:46 +0000531{
532 if (dumpType != "BMC")
533 {
534 BMCWEB_LOG_WARNING("Can't find Dump Entry {}", entryID);
535 messages::resourceNotFound(asyncResp->res, dumpType + " dump", entryID);
536 return;
537 }
538
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400539 std::string dumpEntryPath =
540 std::format("{}/entry/{}", getDumpPath(dumpType), entryID);
Carson Labrado168d1b12023-03-27 17:04:46 +0000541
542 auto downloadDumpEntryHandler =
543 [asyncResp, entryID,
544 dumpType](const boost::system::error_code& ec,
545 const sdbusplus::message::unix_fd& unixfd) {
Oliver Brewkaff35df92025-08-26 08:21:30 +0200546 log_services_utils::downloadEntryCallback(asyncResp, entryID,
547 dumpType, ec, unixfd);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400548 };
Carson Labrado168d1b12023-03-27 17:04:46 +0000549
Ed Tanous177612a2025-02-14 15:16:09 -0800550 dbus::utility::async_method_call(
551 asyncResp, std::move(downloadDumpEntryHandler),
552 "xyz.openbmc_project.Dump.Manager", dumpEntryPath,
553 "xyz.openbmc_project.Dump.Entry", "GetFileHandle");
Carson Labrado168d1b12023-03-27 17:04:46 +0000554}
555
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400556inline void downloadEventLogEntry(
557 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
558 const std::string& systemName, const std::string& entryID,
559 const std::string& dumpType)
Carson Labrado168d1b12023-03-27 17:04:46 +0000560{
Ed Tanous25b54db2024-04-17 15:40:31 -0700561 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Carson Labrado168d1b12023-03-27 17:04:46 +0000562 {
563 // Option currently returns no systems. TBD
564 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
565 systemName);
566 return;
567 }
Ed Tanous253f11b2024-05-16 09:38:31 -0700568 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Carson Labrado168d1b12023-03-27 17:04:46 +0000569 {
570 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
571 systemName);
572 return;
573 }
574
575 std::string entryPath =
576 sdbusplus::message::object_path("/xyz/openbmc_project/logging/entry") /
577 entryID;
578
579 auto downloadEventLogEntryHandler =
580 [asyncResp, entryID,
581 dumpType](const boost::system::error_code& ec,
582 const sdbusplus::message::unix_fd& unixfd) {
Oliver Brewkaff35df92025-08-26 08:21:30 +0200583 log_services_utils::downloadEntryCallback(asyncResp, entryID,
584 dumpType, ec, unixfd);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400585 };
Carson Labrado168d1b12023-03-27 17:04:46 +0000586
Ed Tanous177612a2025-02-14 15:16:09 -0800587 dbus::utility::async_method_call(
588 asyncResp, std::move(downloadEventLogEntryHandler),
589 "xyz.openbmc_project.Logging", entryPath,
590 "xyz.openbmc_project.Logging.Entry", "GetEntry");
Carson Labrado168d1b12023-03-27 17:04:46 +0000591}
592
Patrick Williams504af5a2025-02-03 14:29:03 -0500593inline DumpCreationProgress mapDbusStatusToDumpProgress(
594 const std::string& status)
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500595{
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600596 if (status ==
597 "xyz.openbmc_project.Common.Progress.OperationStatus.Failed" ||
598 status == "xyz.openbmc_project.Common.Progress.OperationStatus.Aborted")
599 {
600 return DumpCreationProgress::DUMP_CREATE_FAILED;
601 }
602 if (status ==
603 "xyz.openbmc_project.Common.Progress.OperationStatus.Completed")
604 {
605 return DumpCreationProgress::DUMP_CREATE_SUCCESS;
606 }
607 return DumpCreationProgress::DUMP_CREATE_INPROGRESS;
608}
609
Patrick Williams504af5a2025-02-03 14:29:03 -0500610inline DumpCreationProgress getDumpCompletionStatus(
611 const dbus::utility::DBusPropertiesMap& values)
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600612{
613 for (const auto& [key, val] : values)
614 {
615 if (key == "Status")
Ed Tanous002d39b2022-05-31 08:59:27 -0700616 {
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600617 const std::string* value = std::get_if<std::string>(&val);
618 if (value == nullptr)
619 {
Ed Tanous62598e32023-07-17 17:06:25 -0700620 BMCWEB_LOG_ERROR("Status property value is null");
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600621 return DumpCreationProgress::DUMP_CREATE_FAILED;
622 }
623 return mapDbusStatusToDumpProgress(*value);
624 }
625 }
626 return DumpCreationProgress::DUMP_CREATE_INPROGRESS;
627}
628
629inline std::string getDumpEntryPath(const std::string& dumpPath)
630{
631 if (dumpPath == "/xyz/openbmc_project/dump/bmc/entry")
632 {
Ed Tanous253f11b2024-05-16 09:38:31 -0700633 return std::format("/redfish/v1/Managers/{}/LogServices/Dump/Entries/",
Ed Tanous9f565092024-07-12 22:06:53 -0700634 BMCWEB_REDFISH_MANAGER_URI_NAME);
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600635 }
636 if (dumpPath == "/xyz/openbmc_project/dump/system/entry")
637 {
Ed Tanous253f11b2024-05-16 09:38:31 -0700638 return std::format("/redfish/v1/Systems/{}/LogServices/Dump/Entries/",
639 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600640 }
641 return "";
642}
643
644inline void createDumpTaskCallback(
645 task::Payload&& payload,
646 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
647 const sdbusplus::message::object_path& createdObjPath)
648{
649 const std::string dumpPath = createdObjPath.parent_path().str;
650 const std::string dumpId = createdObjPath.filename();
651
652 std::string dumpEntryPath = getDumpEntryPath(dumpPath);
653
654 if (dumpEntryPath.empty())
655 {
Ed Tanous62598e32023-07-17 17:06:25 -0700656 BMCWEB_LOG_ERROR("Invalid dump type received");
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600657 messages::internalError(asyncResp->res);
658 return;
659 }
660
Ed Tanous177612a2025-02-14 15:16:09 -0800661 dbus::utility::async_method_call(
662 asyncResp,
Ed Tanous8cb2c022024-03-27 16:31:46 -0700663 [asyncResp, payload = std::move(payload), createdObjPath,
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600664 dumpEntryPath{std::move(dumpEntryPath)},
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800665 dumpId](const boost::system::error_code& ec,
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600666 const std::string& introspectXml) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400667 if (ec)
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600668 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400669 BMCWEB_LOG_ERROR("Introspect call failed with error: {}",
670 ec.message());
671 messages::internalError(asyncResp->res);
672 return;
673 }
674
675 // Check if the created dump object has implemented Progress
676 // interface to track dump completion. If yes, fetch the "Status"
677 // property of the interface, modify the task state accordingly.
678 // Else, return task completed.
679 tinyxml2::XMLDocument doc;
680
681 doc.Parse(introspectXml.data(), introspectXml.size());
682 tinyxml2::XMLNode* pRoot = doc.FirstChildElement("node");
683 if (pRoot == nullptr)
684 {
685 BMCWEB_LOG_ERROR("XML document failed to parse");
686 messages::internalError(asyncResp->res);
687 return;
688 }
689 tinyxml2::XMLElement* interfaceNode =
690 pRoot->FirstChildElement("interface");
691
692 bool isProgressIntfPresent = false;
693 while (interfaceNode != nullptr)
694 {
695 const char* thisInterfaceName =
696 interfaceNode->Attribute("name");
697 if (thisInterfaceName != nullptr)
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600698 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400699 if (thisInterfaceName ==
700 std::string_view("xyz.openbmc_project.Common.Progress"))
701 {
702 interfaceNode =
703 interfaceNode->NextSiblingElement("interface");
704 continue;
705 }
706 isProgressIntfPresent = true;
707 break;
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600708 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400709 interfaceNode = interfaceNode->NextSiblingElement("interface");
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600710 }
711
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400712 std::shared_ptr<task::TaskData> task = task::TaskData::createTask(
713 [createdObjPath, dumpEntryPath, dumpId, isProgressIntfPresent](
714 const boost::system::error_code& ec2,
715 sdbusplus::message_t& msg,
716 const std::shared_ptr<task::TaskData>& taskData) {
717 if (ec2)
718 {
719 BMCWEB_LOG_ERROR("{}: Error in creating dump",
720 createdObjPath.str);
721 taskData->messages.emplace_back(
722 messages::internalError());
723 taskData->state = "Cancelled";
724 return task::completed;
725 }
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600726
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400727 if (isProgressIntfPresent)
728 {
729 dbus::utility::DBusPropertiesMap values;
730 std::string prop;
731 msg.read(prop, values);
732
733 DumpCreationProgress dumpStatus =
734 getDumpCompletionStatus(values);
735 if (dumpStatus ==
736 DumpCreationProgress::DUMP_CREATE_FAILED)
737 {
738 BMCWEB_LOG_ERROR("{}: Error in creating dump",
739 createdObjPath.str);
740 taskData->state = "Cancelled";
741 return task::completed;
742 }
743
744 if (dumpStatus ==
745 DumpCreationProgress::DUMP_CREATE_INPROGRESS)
746 {
747 BMCWEB_LOG_DEBUG(
748 "{}: Dump creation task is in progress",
749 createdObjPath.str);
750 return !task::completed;
751 }
752 }
753
754 nlohmann::json retMessage = messages::success();
755 taskData->messages.emplace_back(retMessage);
756
757 boost::urls::url url = boost::urls::format(
758 "/redfish/v1/Managers/{}/LogServices/Dump/Entries/{}",
759 BMCWEB_REDFISH_MANAGER_URI_NAME, dumpId);
760
761 std::string headerLoc = "Location: ";
762 headerLoc += url.buffer();
763
764 taskData->payload->httpHeaders.emplace_back(
765 std::move(headerLoc));
766
767 BMCWEB_LOG_DEBUG("{}: Dump creation task completed",
Ed Tanous62598e32023-07-17 17:06:25 -0700768 createdObjPath.str);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400769 taskData->state = "Completed";
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600770 return task::completed;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400771 },
772 "type='signal',interface='org.freedesktop.DBus.Properties',"
773 "member='PropertiesChanged',path='" +
774 createdObjPath.str + "'");
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600775
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400776 // The task timer is set to max time limit within which the
777 // requested dump will be collected.
778 task->startTimer(std::chrono::minutes(6));
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400779 task->payload.emplace(payload);
Chinmay Shripad Hegde29e2bdd2025-06-06 16:23:47 +0530780 task->populateResp(asyncResp->res);
Patrick Williams5a39f772023-10-20 11:20:21 -0500781 },
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600782 "xyz.openbmc_project.Dump.Manager", createdObjPath,
783 "org.freedesktop.DBus.Introspectable", "Introspect");
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500784}
785
zhanghch058d1b46d2021-04-01 11:18:24 +0800786inline void createDump(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
787 const crow::Request& req, const std::string& dumpType)
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500788{
Claire Weinanfdd26902022-03-01 14:18:25 -0800789 std::string dumpPath = getDumpEntriesPath(dumpType);
790 if (dumpPath.empty())
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500791 {
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500792 messages::internalError(asyncResp->res);
793 return;
794 }
795
796 std::optional<std::string> diagnosticDataType;
797 std::optional<std::string> oemDiagnosticDataType;
798
Patrick Williams504af5a2025-02-03 14:29:03 -0500799 if (!redfish::json_util::readJsonAction( //
800 req, asyncResp->res, //
801 "DiagnosticDataType", diagnosticDataType, //
Myung Baeafc474a2024-10-09 00:53:29 -0700802 "OEMDiagnosticDataType", oemDiagnosticDataType //
803 ))
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500804 {
805 return;
806 }
807
808 if (dumpType == "System")
809 {
810 if (!oemDiagnosticDataType || !diagnosticDataType)
811 {
Ed Tanous62598e32023-07-17 17:06:25 -0700812 BMCWEB_LOG_ERROR(
813 "CreateDump action parameter 'DiagnosticDataType'/'OEMDiagnosticDataType' value not found!");
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500814 messages::actionParameterMissing(
815 asyncResp->res, "CollectDiagnosticData",
816 "DiagnosticDataType & OEMDiagnosticDataType");
817 return;
818 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700819 if ((*oemDiagnosticDataType != "System") ||
820 (*diagnosticDataType != "OEM"))
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500821 {
Ed Tanous62598e32023-07-17 17:06:25 -0700822 BMCWEB_LOG_ERROR("Wrong parameter values passed");
Ed Tanousace85d62021-10-26 12:45:59 -0700823 messages::internalError(asyncResp->res);
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500824 return;
825 }
Ed Tanous253f11b2024-05-16 09:38:31 -0700826 dumpPath = std::format("/redfish/v1/Systems/{}/LogServices/Dump/",
827 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500828 }
829 else if (dumpType == "BMC")
830 {
831 if (!diagnosticDataType)
832 {
Ed Tanous62598e32023-07-17 17:06:25 -0700833 BMCWEB_LOG_ERROR(
834 "CreateDump action parameter 'DiagnosticDataType' not found!");
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500835 messages::actionParameterMissing(
836 asyncResp->res, "CollectDiagnosticData", "DiagnosticDataType");
837 return;
838 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700839 if (*diagnosticDataType != "Manager")
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500840 {
Ed Tanous62598e32023-07-17 17:06:25 -0700841 BMCWEB_LOG_ERROR(
842 "Wrong parameter value passed for 'DiagnosticDataType'");
Ed Tanousace85d62021-10-26 12:45:59 -0700843 messages::internalError(asyncResp->res);
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500844 return;
845 }
Ed Tanous253f11b2024-05-16 09:38:31 -0700846 dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/Dump/",
847 BMCWEB_REDFISH_MANAGER_URI_NAME);
Asmitha Karunanithi59075712021-10-22 01:17:41 -0500848 }
849 else
850 {
Ed Tanous62598e32023-07-17 17:06:25 -0700851 BMCWEB_LOG_ERROR("CreateDump failed. Unknown dump type");
Asmitha Karunanithi59075712021-10-22 01:17:41 -0500852 messages::internalError(asyncResp->res);
853 return;
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500854 }
855
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600856 std::vector<std::pair<std::string, std::variant<std::string, uint64_t>>>
857 createDumpParamVec;
858
Carson Labradof574a8e2023-03-22 02:26:00 +0000859 if (req.session != nullptr)
860 {
861 createDumpParamVec.emplace_back(
862 "xyz.openbmc_project.Dump.Create.CreateParameters.OriginatorId",
863 req.session->clientIp);
864 createDumpParamVec.emplace_back(
865 "xyz.openbmc_project.Dump.Create.CreateParameters.OriginatorType",
866 "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Client");
867 }
Asmitha Karunanithi68dd0752022-11-15 11:33:46 -0600868
Ed Tanous177612a2025-02-14 15:16:09 -0800869 dbus::utility::async_method_call(
870 asyncResp,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800871 [asyncResp, payload(task::Payload(req)),
872 dumpPath](const boost::system::error_code& ec,
873 const sdbusplus::message_t& msg,
874 const sdbusplus::message::object_path& objPath) mutable {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400875 if (ec)
Asmitha Karunanithi59075712021-10-22 01:17:41 -0500876 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400877 BMCWEB_LOG_ERROR("CreateDump resp_handler got error {}", ec);
878 const sd_bus_error* dbusError = msg.get_error();
879 if (dbusError == nullptr)
880 {
881 messages::internalError(asyncResp->res);
882 return;
883 }
884
885 BMCWEB_LOG_ERROR("CreateDump DBus error: {} and error msg: {}",
886 dbusError->name, dbusError->message);
887 if (std::string_view(
888 "xyz.openbmc_project.Common.Error.NotAllowed") ==
889 dbusError->name)
890 {
891 messages::resourceInStandby(asyncResp->res);
892 return;
893 }
894 if (std::string_view(
895 "xyz.openbmc_project.Dump.Create.Error.Disabled") ==
896 dbusError->name)
897 {
898 messages::serviceDisabled(asyncResp->res, dumpPath);
899 return;
900 }
901 if (std::string_view(
902 "xyz.openbmc_project.Common.Error.Unavailable") ==
903 dbusError->name)
904 {
905 messages::resourceInUse(asyncResp->res);
906 return;
907 }
908 // Other Dbus errors such as:
909 // xyz.openbmc_project.Common.Error.InvalidArgument &
910 // org.freedesktop.DBus.Error.InvalidArgs are all related to
911 // the dbus call that is made here in the bmcweb
912 // implementation and has nothing to do with the client's
913 // input in the request. Hence, returning internal error
914 // back to the client.
Asmitha Karunanithi59075712021-10-22 01:17:41 -0500915 messages::internalError(asyncResp->res);
916 return;
917 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400918 BMCWEB_LOG_DEBUG("Dump Created. Path: {}", objPath.str);
919 createDumpTaskCallback(std::move(payload), asyncResp, objPath);
920 },
Ed Tanous18f8f602023-07-18 10:07:23 -0700921 "xyz.openbmc_project.Dump.Manager", getDumpPath(dumpType),
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600922 "xyz.openbmc_project.Dump.Create", "CreateDump", createDumpParamVec);
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500923}
924
zhanghch058d1b46d2021-04-01 11:18:24 +0800925inline void clearDump(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
926 const std::string& dumpType)
Asmitha Karunanithi80319af2020-05-07 05:30:21 -0500927{
Ed Tanous177612a2025-02-14 15:16:09 -0800928 dbus::utility::async_method_call(
929 asyncResp,
Claire Weinan0d946212022-07-13 19:40:19 -0700930 [asyncResp](const boost::system::error_code& ec) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400931 if (ec)
932 {
933 BMCWEB_LOG_ERROR("clearDump resp_handler got error {}", ec);
934 messages::internalError(asyncResp->res);
935 return;
936 }
Amy Change2460462025-05-06 00:10:13 -0700937 messages::success(asyncResp->res);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400938 },
Ed Tanous18f8f602023-07-18 10:07:23 -0700939 "xyz.openbmc_project.Dump.Manager", getDumpPath(dumpType),
Claire Weinan0d946212022-07-13 19:40:19 -0700940 "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
Asmitha Karunanithi80319af2020-05-07 05:30:21 -0500941}
942
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400943inline void parseCrashdumpParameters(
944 const dbus::utility::DBusPropertiesMap& params, std::string& filename,
945 std::string& timestamp, std::string& logfile)
Johnathan Mantey043a0532020-03-10 17:15:28 -0700946{
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200947 const std::string* filenamePtr = nullptr;
948 const std::string* timestampPtr = nullptr;
949 const std::string* logfilePtr = nullptr;
950
951 const bool success = sdbusplus::unpackPropertiesNoThrow(
952 dbus_utils::UnpackErrorPrinter(), params, "Timestamp", timestampPtr,
953 "Filename", filenamePtr, "Log", logfilePtr);
954
955 if (!success)
Johnathan Mantey043a0532020-03-10 17:15:28 -0700956 {
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200957 return;
958 }
959
960 if (filenamePtr != nullptr)
961 {
962 filename = *filenamePtr;
963 }
964
965 if (timestampPtr != nullptr)
966 {
967 timestamp = *timestampPtr;
968 }
969
970 if (logfilePtr != nullptr)
971 {
972 logfile = *logfilePtr;
Johnathan Mantey043a0532020-03-10 17:15:28 -0700973 }
974}
975
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700976inline void requestRoutesSystemLogServiceCollection(App& app)
Ed Tanous1da66f72018-07-27 16:13:37 -0700977{
Jason M. Billsc4bf6372018-11-05 13:48:27 -0800978 /**
979 * Functions triggers appropriate requests on DBus
980 */
Ed Tanous22d268c2022-05-19 09:39:07 -0700981 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/")
Ed Tanoused398212021-06-09 17:05:54 -0700982 .privileges(redfish::privileges::getLogServiceCollection)
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400983 .methods(
984 boost::beast::http::verb::
985 get)([&app](const crow::Request& req,
986 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
987 const std::string& systemName) {
988 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700989 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400990 return;
991 }
992 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
993 {
994 // Option currently returns no systems. TBD
995 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
996 systemName);
997 return;
998 }
999 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1000 {
1001 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1002 systemName);
Ed Tanous002d39b2022-05-31 08:59:27 -07001003 return;
1004 }
Ed Tanous45ca1b82022-03-25 13:07:27 -07001005
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001006 // Collections don't include the static data added by SubRoute
1007 // because it has a duplicate entry for members
1008 asyncResp->res.jsonValue["@odata.type"] =
1009 "#LogServiceCollection.LogServiceCollection";
1010 asyncResp->res.jsonValue["@odata.id"] =
1011 std::format("/redfish/v1/Systems/{}/LogServices",
1012 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1013 asyncResp->res.jsonValue["Name"] = "System Log Services Collection";
1014 asyncResp->res.jsonValue["Description"] =
1015 "Collection of LogServices for this Computer System";
1016 nlohmann::json& logServiceArray =
1017 asyncResp->res.jsonValue["Members"];
1018 logServiceArray = nlohmann::json::array();
1019 nlohmann::json::object_t eventLog;
1020 eventLog["@odata.id"] =
1021 std::format("/redfish/v1/Systems/{}/LogServices/EventLog",
1022 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1023 logServiceArray.emplace_back(std::move(eventLog));
1024 if constexpr (BMCWEB_REDFISH_DUMP_LOG)
Ed Tanous002d39b2022-05-31 08:59:27 -07001025 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001026 nlohmann::json::object_t dumpLog;
1027 dumpLog["@odata.id"] =
1028 std::format("/redfish/v1/Systems/{}/LogServices/Dump",
1029 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1030 logServiceArray.emplace_back(std::move(dumpLog));
Ed Tanous002d39b2022-05-31 08:59:27 -07001031 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001032
1033 if constexpr (BMCWEB_REDFISH_CPU_LOG)
1034 {
1035 nlohmann::json::object_t crashdump;
1036 crashdump["@odata.id"] =
1037 std::format("/redfish/v1/Systems/{}/LogServices/Crashdump",
1038 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1039 logServiceArray.emplace_back(std::move(crashdump));
1040 }
1041
1042 if constexpr (BMCWEB_REDFISH_HOST_LOGGER)
1043 {
1044 nlohmann::json::object_t hostlogger;
1045 hostlogger["@odata.id"] =
1046 std::format("/redfish/v1/Systems/{}/LogServices/HostLogger",
1047 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1048 logServiceArray.emplace_back(std::move(hostlogger));
1049 }
1050 asyncResp->res.jsonValue["Members@odata.count"] =
1051 logServiceArray.size();
1052
1053 constexpr std::array<std::string_view, 1> interfaces = {
1054 "xyz.openbmc_project.State.Boot.PostCode"};
1055 dbus::utility::getSubTreePaths(
1056 "/", 0, interfaces,
1057 [asyncResp](const boost::system::error_code& ec,
1058 const dbus::utility::MapperGetSubTreePathsResponse&
1059 subtreePath) {
1060 if (ec)
1061 {
1062 BMCWEB_LOG_ERROR("{}", ec);
1063 return;
1064 }
1065
1066 for (const auto& pathStr : subtreePath)
1067 {
1068 if (pathStr.find("PostCode") != std::string::npos)
1069 {
1070 nlohmann::json& logServiceArrayLocal =
1071 asyncResp->res.jsonValue["Members"];
1072 nlohmann::json::object_t member;
1073 member["@odata.id"] = std::format(
1074 "/redfish/v1/Systems/{}/LogServices/PostCodes",
1075 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1076
1077 logServiceArrayLocal.emplace_back(
1078 std::move(member));
1079
1080 asyncResp->res.jsonValue["Members@odata.count"] =
1081 logServiceArrayLocal.size();
1082 return;
1083 }
1084 }
1085 });
Ed Tanous45ca1b82022-03-25 13:07:27 -07001086 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001087}
1088
1089inline void requestRoutesEventLogService(App& app)
1090{
Ed Tanous22d268c2022-05-19 09:39:07 -07001091 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/")
Ed Tanoused398212021-06-09 17:05:54 -07001092 .privileges(redfish::privileges::getLogService)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001093 .methods(
1094 boost::beast::http::verb::
1095 get)([&app](const crow::Request& req,
1096 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1097 const std::string& systemName) {
1098 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1099 {
1100 return;
1101 }
1102 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1103 {
1104 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1105 systemName);
1106 return;
1107 }
1108 asyncResp->res.jsonValue["@odata.id"] =
1109 std::format("/redfish/v1/Systems/{}/LogServices/EventLog",
1110 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1111 asyncResp->res.jsonValue["@odata.type"] =
1112 "#LogService.v1_2_0.LogService";
1113 asyncResp->res.jsonValue["Name"] = "Event Log Service";
1114 asyncResp->res.jsonValue["Description"] =
1115 "System Event Log Service";
1116 asyncResp->res.jsonValue["Id"] = "EventLog";
1117 asyncResp->res.jsonValue["OverWritePolicy"] =
1118 log_service::OverWritePolicy::WrapsWhenFull;
Tejas Patil7c8c4052021-06-04 17:43:14 +05301119
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001120 std::pair<std::string, std::string> redfishDateTimeOffset =
1121 redfish::time_utils::getDateTimeOffsetNow();
Tejas Patil7c8c4052021-06-04 17:43:14 +05301122
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001123 asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
1124 asyncResp->res.jsonValue["DateTimeLocalOffset"] =
1125 redfishDateTimeOffset.second;
Tejas Patil7c8c4052021-06-04 17:43:14 +05301126
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001127 asyncResp->res.jsonValue["Entries"]["@odata.id"] = std::format(
1128 "/redfish/v1/Systems/{}/LogServices/EventLog/Entries",
Ed Tanous20fa6a22024-05-20 18:02:58 -07001129 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001130 asyncResp->res
1131 .jsonValue["Actions"]["#LogService.ClearLog"]["target"]
1132
1133 = std::format(
1134 "/redfish/v1/Systems/{}/LogServices/EventLog/Actions/LogService.ClearLog",
1135 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Corey Ethington08fad5d2025-07-31 12:14:27 -04001136
1137 etag_utils::setEtagOmitDateTimeHandler(asyncResp);
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001138 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001139}
1140
Myung Bae7f3726a2025-04-26 15:17:23 -05001141inline void fillEventLogLogEntryFromDbusLogEntry(
1142 const DbusEventLogEntry& entry, nlohmann::json& objectToFillOut)
Ed Tanous898f2aa2024-08-07 12:18:22 -07001143{
Ed Tanous898f2aa2024-08-07 12:18:22 -07001144 objectToFillOut["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
1145 objectToFillOut["@odata.id"] = boost::urls::format(
1146 "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/{}",
Alexander Hansen262dcc12024-09-19 12:04:03 +02001147 BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(entry.Id));
Ed Tanous898f2aa2024-08-07 12:18:22 -07001148 objectToFillOut["Name"] = "System Event Log Entry";
Alexander Hansen262dcc12024-09-19 12:04:03 +02001149 objectToFillOut["Id"] = std::to_string(entry.Id);
1150 objectToFillOut["Message"] = entry.Message;
1151 objectToFillOut["Resolved"] = entry.Resolved;
1152 std::optional<bool> notifyAction =
1153 getProviderNotifyAction(entry.ServiceProviderNotify);
Ed Tanous898f2aa2024-08-07 12:18:22 -07001154 if (notifyAction)
1155 {
1156 objectToFillOut["ServiceProviderNotified"] = *notifyAction;
1157 }
Alexander Hansen262dcc12024-09-19 12:04:03 +02001158 if ((entry.Resolution != nullptr) && !entry.Resolution->empty())
Ed Tanous898f2aa2024-08-07 12:18:22 -07001159 {
Alexander Hansen262dcc12024-09-19 12:04:03 +02001160 objectToFillOut["Resolution"] = *entry.Resolution;
Ed Tanous898f2aa2024-08-07 12:18:22 -07001161 }
1162 objectToFillOut["EntryType"] = "Event";
Alexander Hansen262dcc12024-09-19 12:04:03 +02001163 objectToFillOut["Severity"] =
1164 translateSeverityDbusToRedfish(entry.Severity);
Ed Tanous898f2aa2024-08-07 12:18:22 -07001165 objectToFillOut["Created"] =
Alexander Hansen262dcc12024-09-19 12:04:03 +02001166 redfish::time_utils::getDateTimeUintMs(entry.Timestamp);
Ed Tanous898f2aa2024-08-07 12:18:22 -07001167 objectToFillOut["Modified"] =
Alexander Hansen262dcc12024-09-19 12:04:03 +02001168 redfish::time_utils::getDateTimeUintMs(entry.UpdateTimestamp);
1169 if (entry.Path != nullptr)
Ed Tanous898f2aa2024-08-07 12:18:22 -07001170 {
1171 objectToFillOut["AdditionalDataURI"] = boost::urls::format(
1172 "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/{}/attachment",
Alexander Hansen262dcc12024-09-19 12:04:03 +02001173 BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(entry.Id));
Ed Tanous898f2aa2024-08-07 12:18:22 -07001174 }
1175}
1176
Ed Tanousb7290962024-08-07 11:09:51 -07001177inline void afterLogEntriesGetManagedObjects(
1178 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1179 const boost::system::error_code& ec,
1180 const dbus::utility::ManagedObjectType& resp)
1181{
1182 if (ec)
1183 {
1184 // TODO Handle for specific error code
1185 BMCWEB_LOG_ERROR("getLogEntriesIfaceData resp_handler got error {}",
1186 ec);
1187 messages::internalError(asyncResp->res);
1188 return;
1189 }
1190 nlohmann::json::array_t entriesArray;
1191 for (const auto& objectPath : resp)
1192 {
Ed Tanous898f2aa2024-08-07 12:18:22 -07001193 dbus::utility::DBusPropertiesMap propsFlattened;
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001194 auto isEntry =
1195 std::ranges::find_if(objectPath.second, [](const auto& object) {
1196 return object.first == "xyz.openbmc_project.Logging.Entry";
1197 });
Ed Tanous898f2aa2024-08-07 12:18:22 -07001198 if (isEntry == objectPath.second.end())
Ed Tanousb7290962024-08-07 11:09:51 -07001199 {
1200 continue;
1201 }
Myung Bae7f3726a2025-04-26 15:17:23 -05001202
Ed Tanous898f2aa2024-08-07 12:18:22 -07001203 for (const auto& interfaceMap : objectPath.second)
Ed Tanousb7290962024-08-07 11:09:51 -07001204 {
Ed Tanous898f2aa2024-08-07 12:18:22 -07001205 for (const auto& propertyMap : interfaceMap.second)
Ed Tanousb7290962024-08-07 11:09:51 -07001206 {
Ed Tanous898f2aa2024-08-07 12:18:22 -07001207 propsFlattened.emplace_back(propertyMap.first,
1208 propertyMap.second);
Ed Tanousb7290962024-08-07 11:09:51 -07001209 }
1210 }
Myung Bae7f3726a2025-04-26 15:17:23 -05001211 std::optional<DbusEventLogEntry> optEntry =
1212 fillDbusEventLogEntryFromPropertyMap(propsFlattened);
1213
1214 if (!optEntry.has_value())
Igor Kanyuka90896602025-03-13 08:52:38 +00001215 {
Myung Bae7f3726a2025-04-26 15:17:23 -05001216 messages::internalError(asyncResp->res);
Igor Kanyuka90896602025-03-13 08:52:38 +00001217 return;
1218 }
Myung Bae7f3726a2025-04-26 15:17:23 -05001219 fillEventLogLogEntryFromDbusLogEntry(*optEntry,
1220 entriesArray.emplace_back());
Ed Tanousb7290962024-08-07 11:09:51 -07001221 }
Ed Tanous898f2aa2024-08-07 12:18:22 -07001222
Igor Kanyuka90896602025-03-13 08:52:38 +00001223 redfish::json_util::sortJsonArrayByKey(entriesArray, "Id");
Ed Tanousb7290962024-08-07 11:09:51 -07001224 asyncResp->res.jsonValue["Members@odata.count"] = entriesArray.size();
1225 asyncResp->res.jsonValue["Members"] = std::move(entriesArray);
1226}
1227
Alexander Hansen599b9af2024-08-06 15:11:57 +02001228inline void dBusEventLogEntryCollection(
1229 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1230{
1231 // Collections don't include the static data added by SubRoute
1232 // because it has a duplicate entry for members
1233 asyncResp->res.jsonValue["@odata.type"] =
1234 "#LogEntryCollection.LogEntryCollection";
1235 asyncResp->res.jsonValue["@odata.id"] =
1236 std::format("/redfish/v1/Systems/{}/LogServices/EventLog/Entries",
1237 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1238 asyncResp->res.jsonValue["Name"] = "System Event Log Entries";
1239 asyncResp->res.jsonValue["Description"] =
1240 "Collection of System Event Log Entries";
1241
1242 // DBus implementation of EventLog/Entries
1243 // Make call to Logging Service to find all log entry objects
1244 sdbusplus::message::object_path path("/xyz/openbmc_project/logging");
1245 dbus::utility::getManagedObjects(
1246 "xyz.openbmc_project.Logging", path,
1247 [asyncResp](const boost::system::error_code& ec,
1248 const dbus::utility::ManagedObjectType& resp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001249 afterLogEntriesGetManagedObjects(asyncResp, ec, resp);
1250 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001251}
1252
1253inline void requestRoutesDBusEventLogEntryCollection(App& app)
1254{
Ed Tanous22d268c2022-05-19 09:39:07 -07001255 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/")
Ed Tanoused398212021-06-09 17:05:54 -07001256 .privileges(redfish::privileges::getLogEntryCollection)
Ed Tanous002d39b2022-05-31 08:59:27 -07001257 .methods(boost::beast::http::verb::get)(
1258 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07001259 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1260 const std::string& systemName) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001261 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1262 {
1263 return;
1264 }
1265 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1266 {
1267 // Option currently returns no systems. TBD
1268 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1269 systemName);
1270 return;
1271 }
1272 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1273 {
1274 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1275 systemName);
1276 return;
1277 }
1278 dBusEventLogEntryCollection(asyncResp);
1279 });
Alexander Hansen599b9af2024-08-06 15:11:57 +02001280}
Ed Tanous22d268c2022-05-19 09:39:07 -07001281
Myung Baec6b7cae2025-06-05 15:46:57 -05001282inline void afterDBusEventLogEntryGet(
1283 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1284 const std::string& entryID, const boost::system::error_code& ec,
1285 const dbus::utility::DBusPropertiesMap& resp)
1286{
1287 if (ec.value() == EBADR)
1288 {
1289 messages::resourceNotFound(asyncResp->res, "EventLogEntry", entryID);
1290 return;
1291 }
1292 if (ec)
1293 {
1294 BMCWEB_LOG_ERROR("EventLogEntry (DBus) resp_handler got error {}", ec);
1295 messages::internalError(asyncResp->res);
1296 return;
1297 }
1298
Myung Bae7f3726a2025-04-26 15:17:23 -05001299 std::optional<DbusEventLogEntry> optEntry =
1300 fillDbusEventLogEntryFromPropertyMap(resp);
1301
1302 if (!optEntry.has_value())
1303 {
1304 messages::internalError(asyncResp->res);
1305 return;
1306 }
1307
1308 fillEventLogLogEntryFromDbusLogEntry(*optEntry, asyncResp->res.jsonValue);
Myung Baec6b7cae2025-06-05 15:46:57 -05001309}
1310
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001311inline void dBusEventLogEntryGet(
1312 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::string entryID)
Alexander Hansen599b9af2024-08-06 15:11:57 +02001313{
1314 dbus::utility::escapePathForDbus(entryID);
Ed Tanous002d39b2022-05-31 08:59:27 -07001315
Alexander Hansen599b9af2024-08-06 15:11:57 +02001316 // DBus implementation of EventLog/Entries
1317 // Make call to Logging Service to find all log entry objects
Ed Tanousdeae6a72024-11-11 21:58:57 -08001318 dbus::utility::getAllProperties(
1319 "xyz.openbmc_project.Logging",
Alexander Hansen599b9af2024-08-06 15:11:57 +02001320 "/xyz/openbmc_project/logging/entry/" + entryID, "",
Myung Baec6b7cae2025-06-05 15:46:57 -05001321 std::bind_front(afterDBusEventLogEntryGet, asyncResp, entryID));
Alexander Hansen599b9af2024-08-06 15:11:57 +02001322}
1323
Patrick Williams504af5a2025-02-03 14:29:03 -05001324inline void dBusEventLogEntryPatch(
1325 const crow::Request& req,
1326 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1327 const std::string& entryId)
Alexander Hansen599b9af2024-08-06 15:11:57 +02001328{
1329 std::optional<bool> resolved;
1330
1331 if (!json_util::readJsonPatch(req, asyncResp->res, "Resolved", resolved))
1332 {
1333 return;
1334 }
1335 BMCWEB_LOG_DEBUG("Set Resolved");
1336
1337 setDbusProperty(asyncResp, "Resolved", "xyz.openbmc_project.Logging",
1338 "/xyz/openbmc_project/logging/entry/" + entryId,
1339 "xyz.openbmc_project.Logging.Entry", "Resolved",
1340 resolved.value_or(false));
1341}
1342
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001343inline void dBusEventLogEntryDelete(
1344 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::string entryID)
Alexander Hansen599b9af2024-08-06 15:11:57 +02001345{
1346 BMCWEB_LOG_DEBUG("Do delete single event entries.");
1347
1348 dbus::utility::escapePathForDbus(entryID);
1349
1350 // Process response from Logging service.
1351 auto respHandler = [asyncResp,
1352 entryID](const boost::system::error_code& ec) {
1353 BMCWEB_LOG_DEBUG("EventLogEntry (DBus) doDelete callback: Done");
1354 if (ec)
1355 {
1356 if (ec.value() == EBADR)
Ed Tanous45ca1b82022-03-25 13:07:27 -07001357 {
Alexander Hansen599b9af2024-08-06 15:11:57 +02001358 messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
Ed Tanous45ca1b82022-03-25 13:07:27 -07001359 return;
1360 }
Alexander Hansen599b9af2024-08-06 15:11:57 +02001361 // TODO Handle for specific error code
1362 BMCWEB_LOG_ERROR(
1363 "EventLogEntry (DBus) doDelete respHandler got error {}", ec);
1364 asyncResp->res.result(
1365 boost::beast::http::status::internal_server_error);
1366 return;
1367 }
Abhishek Patel9017faf2021-09-14 22:48:55 -05001368
Alexander Hansen599b9af2024-08-06 15:11:57 +02001369 asyncResp->res.result(boost::beast::http::status::ok);
1370 };
1371
1372 // Make call to Logging service to request Delete Log
Ed Tanous177612a2025-02-14 15:16:09 -08001373 dbus::utility::async_method_call(
1374 asyncResp, respHandler, "xyz.openbmc_project.Logging",
Alexander Hansen599b9af2024-08-06 15:11:57 +02001375 "/xyz/openbmc_project/logging/entry/" + entryID,
1376 "xyz.openbmc_project.Object.Delete", "Delete");
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001377}
Xiaochao Ma75710de2021-01-21 17:56:02 +08001378
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001379inline void requestRoutesDBusEventLogEntry(App& app)
Adriana Kobylak400fd1f2021-01-29 09:01:30 -06001380{
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001381 BMCWEB_ROUTE(
Ed Tanous22d268c2022-05-19 09:39:07 -07001382 app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001383 .privileges(redfish::privileges::getLogEntry)
Ed Tanous002d39b2022-05-31 08:59:27 -07001384 .methods(boost::beast::http::verb::get)(
1385 [&app](const crow::Request& req,
1386 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous898f2aa2024-08-07 12:18:22 -07001387 const std::string& systemName, const std::string& entryId) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001388 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1389 {
1390 return;
1391 }
1392 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1393 {
1394 // Option currently returns no systems. TBD
1395 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1396 systemName);
1397 return;
1398 }
1399 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1400 {
1401 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1402 systemName);
1403 return;
1404 }
Ed Tanous22d268c2022-05-19 09:39:07 -07001405
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001406 dBusEventLogEntryGet(asyncResp, entryId);
1407 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001408
1409 BMCWEB_ROUTE(
Ed Tanous22d268c2022-05-19 09:39:07 -07001410 app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001411 .privileges(redfish::privileges::patchLogEntry)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001412 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07001413 [&app](const crow::Request& req,
1414 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous22d268c2022-05-19 09:39:07 -07001415 const std::string& systemName, const std::string& entryId) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001416 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1417 {
1418 return;
1419 }
1420 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1421 {
1422 // Option currently returns no systems. TBD
1423 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1424 systemName);
1425 return;
1426 }
1427 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1428 {
1429 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1430 systemName);
1431 return;
1432 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001433
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001434 dBusEventLogEntryPatch(req, asyncResp, entryId);
1435 });
Adriana Kobylak400fd1f2021-01-29 09:01:30 -06001436
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001437 BMCWEB_ROUTE(
Ed Tanous22d268c2022-05-19 09:39:07 -07001438 app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
Abhishek Patelfff6a4d2021-07-21 11:29:45 -05001439 .privileges(
1440 redfish::privileges::
1441 deleteLogEntrySubOverComputerSystemLogServiceCollectionLogServiceLogEntryCollection)
Ed Tanous002d39b2022-05-31 08:59:27 -07001442 .methods(boost::beast::http::verb::delete_)(
1443 [&app](const crow::Request& req,
1444 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous22d268c2022-05-19 09:39:07 -07001445 const std::string& systemName, const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001446 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1447 {
1448 return;
1449 }
1450 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1451 {
1452 // Option currently returns no systems. TBD
1453 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1454 systemName);
1455 return;
1456 }
1457 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1458 {
1459 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1460 systemName);
1461 return;
1462 }
1463 dBusEventLogEntryDelete(asyncResp, param);
1464 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001465}
1466
Claire Weinandd72e872022-08-15 14:20:06 -07001467inline void handleBMCLogServicesCollectionGet(
Claire Weinanfdd26902022-03-01 14:18:25 -08001468 crow::App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001469 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1470 const std::string& managerId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001471{
1472 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1473 {
1474 return;
1475 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001476
1477 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1478 {
1479 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1480 return;
1481 }
1482
Claire Weinanfdd26902022-03-01 14:18:25 -08001483 // Collections don't include the static data added by SubRoute
1484 // because it has a duplicate entry for members
1485 asyncResp->res.jsonValue["@odata.type"] =
1486 "#LogServiceCollection.LogServiceCollection";
Ed Tanous253f11b2024-05-16 09:38:31 -07001487 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
1488 "/redfish/v1/Managers/{}/LogServices", BMCWEB_REDFISH_MANAGER_URI_NAME);
Claire Weinanfdd26902022-03-01 14:18:25 -08001489 asyncResp->res.jsonValue["Name"] = "Open BMC Log Services Collection";
1490 asyncResp->res.jsonValue["Description"] =
1491 "Collection of LogServices for this Manager";
1492 nlohmann::json& logServiceArray = asyncResp->res.jsonValue["Members"];
1493 logServiceArray = nlohmann::json::array();
1494
Ed Tanous25b54db2024-04-17 15:40:31 -07001495 if constexpr (BMCWEB_REDFISH_BMC_JOURNAL)
1496 {
1497 nlohmann::json::object_t journal;
Ed Tanous253f11b2024-05-16 09:38:31 -07001498 journal["@odata.id"] =
1499 boost::urls::format("/redfish/v1/Managers/{}/LogServices/Journal",
1500 BMCWEB_REDFISH_MANAGER_URI_NAME);
Ed Tanous25b54db2024-04-17 15:40:31 -07001501 logServiceArray.emplace_back(std::move(journal));
1502 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001503
1504 asyncResp->res.jsonValue["Members@odata.count"] = logServiceArray.size();
1505
Ed Tanous25b54db2024-04-17 15:40:31 -07001506 if constexpr (BMCWEB_REDFISH_DUMP_LOG)
1507 {
1508 constexpr std::array<std::string_view, 1> interfaces = {
1509 "xyz.openbmc_project.Collection.DeleteAll"};
1510 dbus::utility::getSubTreePaths(
1511 "/xyz/openbmc_project/dump", 0, interfaces,
1512 [asyncResp](const boost::system::error_code& ec,
1513 const dbus::utility::MapperGetSubTreePathsResponse&
1514 subTreePaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001515 if (ec)
Ed Tanous25b54db2024-04-17 15:40:31 -07001516 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001517 BMCWEB_LOG_ERROR(
1518 "handleBMCLogServicesCollectionGet respHandler got error {}",
1519 ec);
1520 // Assume that getting an error simply means there are no
1521 // dump LogServices. Return without adding any error
1522 // response.
1523 return;
Ed Tanous25b54db2024-04-17 15:40:31 -07001524 }
Ed Tanous25b54db2024-04-17 15:40:31 -07001525
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001526 nlohmann::json& logServiceArrayLocal =
1527 asyncResp->res.jsonValue["Members"];
1528
1529 for (const std::string& path : subTreePaths)
1530 {
1531 if (path == "/xyz/openbmc_project/dump/bmc")
1532 {
1533 nlohmann::json::object_t member;
1534 member["@odata.id"] = boost::urls::format(
1535 "/redfish/v1/Managers/{}/LogServices/Dump",
1536 BMCWEB_REDFISH_MANAGER_URI_NAME);
1537 logServiceArrayLocal.emplace_back(std::move(member));
1538 }
1539 else if (path == "/xyz/openbmc_project/dump/faultlog")
1540 {
1541 nlohmann::json::object_t member;
1542 member["@odata.id"] = boost::urls::format(
1543 "/redfish/v1/Managers/{}/LogServices/FaultLog",
1544 BMCWEB_REDFISH_MANAGER_URI_NAME);
1545 logServiceArrayLocal.emplace_back(std::move(member));
1546 }
1547 }
1548
1549 asyncResp->res.jsonValue["Members@odata.count"] =
1550 logServiceArrayLocal.size();
1551 });
Ed Tanous25b54db2024-04-17 15:40:31 -07001552 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001553}
1554
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001555inline void requestRoutesBMCLogServiceCollection(App& app)
1556{
Ed Tanous253f11b2024-05-16 09:38:31 -07001557 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/")
Gunnar Millsad89dcf2021-07-30 14:40:11 -05001558 .privileges(redfish::privileges::getLogServiceCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001559 .methods(boost::beast::http::verb::get)(
Claire Weinandd72e872022-08-15 14:20:06 -07001560 std::bind_front(handleBMCLogServicesCollectionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001561}
Ed Tanous1da66f72018-07-27 16:13:37 -07001562
Patrick Williams504af5a2025-02-03 14:29:03 -05001563inline void getDumpServiceInfo(
1564 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1565 const std::string& dumpType)
Claire Weinanfdd26902022-03-01 14:18:25 -08001566{
1567 std::string dumpPath;
Ed Tanous539d8c62024-06-19 14:38:27 -07001568 log_service::OverWritePolicy overWritePolicy =
1569 log_service::OverWritePolicy::Invalid;
Claire Weinanfdd26902022-03-01 14:18:25 -08001570 bool collectDiagnosticDataSupported = false;
1571
1572 if (dumpType == "BMC")
1573 {
Ed Tanous253f11b2024-05-16 09:38:31 -07001574 dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/Dump",
1575 BMCWEB_REDFISH_MANAGER_URI_NAME);
Ed Tanous539d8c62024-06-19 14:38:27 -07001576 overWritePolicy = log_service::OverWritePolicy::WrapsWhenFull;
Claire Weinanfdd26902022-03-01 14:18:25 -08001577 collectDiagnosticDataSupported = true;
1578 }
1579 else if (dumpType == "FaultLog")
1580 {
Ed Tanous253f11b2024-05-16 09:38:31 -07001581 dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/FaultLog",
1582 BMCWEB_REDFISH_MANAGER_URI_NAME);
Ed Tanous539d8c62024-06-19 14:38:27 -07001583 overWritePolicy = log_service::OverWritePolicy::Unknown;
Claire Weinanfdd26902022-03-01 14:18:25 -08001584 collectDiagnosticDataSupported = false;
1585 }
1586 else if (dumpType == "System")
1587 {
Ed Tanous253f11b2024-05-16 09:38:31 -07001588 dumpPath = std::format("/redfish/v1/Systems/{}/LogServices/Dump",
1589 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanous539d8c62024-06-19 14:38:27 -07001590 overWritePolicy = log_service::OverWritePolicy::WrapsWhenFull;
Claire Weinanfdd26902022-03-01 14:18:25 -08001591 collectDiagnosticDataSupported = true;
1592 }
1593 else
1594 {
Ed Tanous62598e32023-07-17 17:06:25 -07001595 BMCWEB_LOG_ERROR("getDumpServiceInfo() invalid dump type: {}",
1596 dumpType);
Claire Weinanfdd26902022-03-01 14:18:25 -08001597 messages::internalError(asyncResp->res);
1598 return;
1599 }
1600
1601 asyncResp->res.jsonValue["@odata.id"] = dumpPath;
1602 asyncResp->res.jsonValue["@odata.type"] = "#LogService.v1_2_0.LogService";
1603 asyncResp->res.jsonValue["Name"] = "Dump LogService";
1604 asyncResp->res.jsonValue["Description"] = dumpType + " Dump LogService";
1605 asyncResp->res.jsonValue["Id"] = std::filesystem::path(dumpPath).filename();
Ed Tanous539d8c62024-06-19 14:38:27 -07001606 asyncResp->res.jsonValue["OverWritePolicy"] = overWritePolicy;
Claire Weinanfdd26902022-03-01 14:18:25 -08001607
1608 std::pair<std::string, std::string> redfishDateTimeOffset =
Ed Tanous2b829372022-08-03 14:22:34 -07001609 redfish::time_utils::getDateTimeOffsetNow();
Claire Weinanfdd26902022-03-01 14:18:25 -08001610 asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
1611 asyncResp->res.jsonValue["DateTimeLocalOffset"] =
1612 redfishDateTimeOffset.second;
1613
1614 asyncResp->res.jsonValue["Entries"]["@odata.id"] = dumpPath + "/Entries";
Claire Weinanfdd26902022-03-01 14:18:25 -08001615
1616 if (collectDiagnosticDataSupported)
1617 {
1618 asyncResp->res.jsonValue["Actions"]["#LogService.CollectDiagnosticData"]
1619 ["target"] =
1620 dumpPath + "/Actions/LogService.CollectDiagnosticData";
1621 }
Claire Weinan0d946212022-07-13 19:40:19 -07001622
Corey Ethington08fad5d2025-07-31 12:14:27 -04001623 etag_utils::setEtagOmitDateTimeHandler(asyncResp);
1624
Claire Weinan0d946212022-07-13 19:40:19 -07001625 constexpr std::array<std::string_view, 1> interfaces = {deleteAllInterface};
1626 dbus::utility::getSubTreePaths(
1627 "/xyz/openbmc_project/dump", 0, interfaces,
1628 [asyncResp, dumpType, dumpPath](
1629 const boost::system::error_code& ec,
1630 const dbus::utility::MapperGetSubTreePathsResponse& subTreePaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001631 if (ec)
Claire Weinan0d946212022-07-13 19:40:19 -07001632 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001633 BMCWEB_LOG_ERROR("getDumpServiceInfo respHandler got error {}",
1634 ec);
1635 // Assume that getting an error simply means there are no dump
1636 // LogServices. Return without adding any error response.
1637 return;
Claire Weinan0d946212022-07-13 19:40:19 -07001638 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001639 std::string dbusDumpPath = getDumpPath(dumpType);
1640 for (const std::string& path : subTreePaths)
1641 {
1642 if (path == dbusDumpPath)
1643 {
1644 asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]
1645 ["target"] =
1646 dumpPath + "/Actions/LogService.ClearLog";
1647 break;
1648 }
1649 }
1650 });
Claire Weinanfdd26902022-03-01 14:18:25 -08001651}
1652
1653inline void handleLogServicesDumpServiceGet(
1654 crow::App& app, const std::string& dumpType, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001655 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1656 const std::string& managerId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001657{
1658 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1659 {
1660 return;
1661 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001662
1663 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1664 {
1665 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1666 return;
1667 }
1668
Claire Weinanfdd26902022-03-01 14:18:25 -08001669 getDumpServiceInfo(asyncResp, dumpType);
1670}
1671
Ed Tanous22d268c2022-05-19 09:39:07 -07001672inline void handleLogServicesDumpServiceComputerSystemGet(
1673 crow::App& app, const crow::Request& req,
1674 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1675 const std::string& chassisId)
1676{
1677 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1678 {
1679 return;
1680 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001681 if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous22d268c2022-05-19 09:39:07 -07001682 {
1683 messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
1684 return;
1685 }
1686 getDumpServiceInfo(asyncResp, "System");
1687}
1688
Claire Weinanfdd26902022-03-01 14:18:25 -08001689inline void handleLogServicesDumpEntriesCollectionGet(
1690 crow::App& app, const std::string& dumpType, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001691 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1692 const std::string& managerId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001693{
1694 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1695 {
1696 return;
1697 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001698
1699 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1700 {
1701 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1702 return;
1703 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001704 getDumpEntryCollection(asyncResp, dumpType);
1705}
1706
Ed Tanous22d268c2022-05-19 09:39:07 -07001707inline void handleLogServicesDumpEntriesCollectionComputerSystemGet(
1708 crow::App& app, const crow::Request& req,
1709 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1710 const std::string& chassisId)
1711{
1712 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1713 {
1714 return;
1715 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001716 if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous22d268c2022-05-19 09:39:07 -07001717 {
1718 messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
1719 return;
1720 }
1721 getDumpEntryCollection(asyncResp, "System");
1722}
1723
Claire Weinanfdd26902022-03-01 14:18:25 -08001724inline void handleLogServicesDumpEntryGet(
1725 crow::App& app, const std::string& dumpType, const crow::Request& req,
1726 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous253f11b2024-05-16 09:38:31 -07001727 const std::string& managerId, const std::string& dumpId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001728{
1729 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1730 {
1731 return;
1732 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001733 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1734 {
1735 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1736 return;
1737 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001738 getDumpEntryById(asyncResp, dumpId, dumpType);
1739}
Carson Labrado168d1b12023-03-27 17:04:46 +00001740
Ed Tanous22d268c2022-05-19 09:39:07 -07001741inline void handleLogServicesDumpEntryComputerSystemGet(
1742 crow::App& app, const crow::Request& req,
1743 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1744 const std::string& chassisId, const std::string& dumpId)
1745{
1746 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1747 {
1748 return;
1749 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001750 if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous22d268c2022-05-19 09:39:07 -07001751 {
1752 messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
1753 return;
1754 }
1755 getDumpEntryById(asyncResp, dumpId, "System");
1756}
Claire Weinanfdd26902022-03-01 14:18:25 -08001757
1758inline void handleLogServicesDumpEntryDelete(
1759 crow::App& app, const std::string& dumpType, const crow::Request& req,
1760 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous253f11b2024-05-16 09:38:31 -07001761 const std::string& managerId, const std::string& dumpId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001762{
1763 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1764 {
1765 return;
1766 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001767
1768 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1769 {
1770 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1771 return;
1772 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001773 deleteDumpEntry(asyncResp, dumpId, dumpType);
1774}
1775
Ed Tanous22d268c2022-05-19 09:39:07 -07001776inline void handleLogServicesDumpEntryComputerSystemDelete(
1777 crow::App& app, const crow::Request& req,
1778 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1779 const std::string& chassisId, const std::string& dumpId)
1780{
1781 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1782 {
1783 return;
1784 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001785 if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous22d268c2022-05-19 09:39:07 -07001786 {
1787 messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
1788 return;
1789 }
1790 deleteDumpEntry(asyncResp, dumpId, "System");
1791}
1792
Carson Labrado168d1b12023-03-27 17:04:46 +00001793inline void handleLogServicesDumpEntryDownloadGet(
1794 crow::App& app, const std::string& dumpType, const crow::Request& req,
1795 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous253f11b2024-05-16 09:38:31 -07001796 const std::string& managerId, const std::string& dumpId)
Carson Labrado168d1b12023-03-27 17:04:46 +00001797{
1798 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1799 {
1800 return;
1801 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001802
1803 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1804 {
1805 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1806 return;
1807 }
Carson Labrado168d1b12023-03-27 17:04:46 +00001808 downloadDumpEntry(asyncResp, dumpId, dumpType);
1809}
1810
1811inline void handleDBusEventLogEntryDownloadGet(
1812 crow::App& app, const std::string& dumpType, const crow::Request& req,
1813 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1814 const std::string& systemName, const std::string& entryID)
1815{
1816 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1817 {
1818 return;
1819 }
1820 if (!http_helpers::isContentTypeAllowed(
1821 req.getHeaderValue("Accept"),
1822 http_helpers::ContentType::OctetStream, true))
1823 {
1824 asyncResp->res.result(boost::beast::http::status::bad_request);
1825 return;
1826 }
1827 downloadEventLogEntry(asyncResp, systemName, entryID, dumpType);
1828}
1829
Claire Weinanfdd26902022-03-01 14:18:25 -08001830inline void handleLogServicesDumpCollectDiagnosticDataPost(
1831 crow::App& app, const std::string& dumpType, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001832 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1833 const std::string& managerId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001834{
1835 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1836 {
1837 return;
1838 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001839 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1840 {
1841 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1842 return;
1843 }
1844
Claire Weinanfdd26902022-03-01 14:18:25 -08001845 createDump(asyncResp, req, dumpType);
1846}
1847
Ed Tanous22d268c2022-05-19 09:39:07 -07001848inline void handleLogServicesDumpCollectDiagnosticDataComputerSystemPost(
1849 crow::App& app, const crow::Request& req,
1850 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001851 const std::string& systemName)
Ed Tanous22d268c2022-05-19 09:39:07 -07001852{
1853 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1854 {
1855 return;
1856 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001857
Ed Tanous25b54db2024-04-17 15:40:31 -07001858 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous22d268c2022-05-19 09:39:07 -07001859 {
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001860 // Option currently returns no systems. TBD
1861 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1862 systemName);
1863 return;
1864 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001865 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001866 {
1867 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1868 systemName);
Ed Tanous22d268c2022-05-19 09:39:07 -07001869 return;
1870 }
1871 createDump(asyncResp, req, "System");
1872}
1873
Claire Weinanfdd26902022-03-01 14:18:25 -08001874inline void handleLogServicesDumpClearLogPost(
1875 crow::App& app, const std::string& dumpType, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001876 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1877 const std::string& managerId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001878{
1879 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1880 {
1881 return;
1882 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001883
1884 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1885 {
1886 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1887 return;
1888 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001889 clearDump(asyncResp, dumpType);
1890}
1891
Ed Tanous22d268c2022-05-19 09:39:07 -07001892inline void handleLogServicesDumpClearLogComputerSystemPost(
1893 crow::App& app, const crow::Request& req,
1894 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001895 const std::string& systemName)
Ed Tanous22d268c2022-05-19 09:39:07 -07001896{
1897 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1898 {
1899 return;
1900 }
Ed Tanous25b54db2024-04-17 15:40:31 -07001901 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous22d268c2022-05-19 09:39:07 -07001902 {
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001903 // Option currently returns no systems. TBD
1904 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1905 systemName);
1906 return;
1907 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001908 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001909 {
1910 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1911 systemName);
Ed Tanous22d268c2022-05-19 09:39:07 -07001912 return;
1913 }
1914 clearDump(asyncResp, "System");
1915}
1916
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001917inline void requestRoutesBMCDumpService(App& app)
1918{
Ed Tanous253f11b2024-05-16 09:38:31 -07001919 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/Dump/")
Ed Tanoused398212021-06-09 17:05:54 -07001920 .privileges(redfish::privileges::getLogService)
Claire Weinanfdd26902022-03-01 14:18:25 -08001921 .methods(boost::beast::http::verb::get)(std::bind_front(
1922 handleLogServicesDumpServiceGet, std::ref(app), "BMC"));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001923}
1924
1925inline void requestRoutesBMCDumpEntryCollection(App& app)
1926{
Ed Tanous253f11b2024-05-16 09:38:31 -07001927 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/")
Ed Tanoused398212021-06-09 17:05:54 -07001928 .privileges(redfish::privileges::getLogEntryCollection)
Claire Weinanfdd26902022-03-01 14:18:25 -08001929 .methods(boost::beast::http::verb::get)(std::bind_front(
1930 handleLogServicesDumpEntriesCollectionGet, std::ref(app), "BMC"));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001931}
1932
1933inline void requestRoutesBMCDumpEntry(App& app)
1934{
1935 BMCWEB_ROUTE(app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001936 "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001937 .privileges(redfish::privileges::getLogEntry)
Claire Weinanfdd26902022-03-01 14:18:25 -08001938 .methods(boost::beast::http::verb::get)(std::bind_front(
1939 handleLogServicesDumpEntryGet, std::ref(app), "BMC"));
1940
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001941 BMCWEB_ROUTE(app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001942 "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001943 .privileges(redfish::privileges::deleteLogEntry)
Claire Weinanfdd26902022-03-01 14:18:25 -08001944 .methods(boost::beast::http::verb::delete_)(std::bind_front(
1945 handleLogServicesDumpEntryDelete, std::ref(app), "BMC"));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001946}
1947
Carson Labrado168d1b12023-03-27 17:04:46 +00001948inline void requestRoutesBMCDumpEntryDownload(App& app)
1949{
1950 BMCWEB_ROUTE(
1951 app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001952 "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/<str>/attachment/")
Carson Labrado168d1b12023-03-27 17:04:46 +00001953 .privileges(redfish::privileges::getLogEntry)
1954 .methods(boost::beast::http::verb::get)(std::bind_front(
1955 handleLogServicesDumpEntryDownloadGet, std::ref(app), "BMC"));
1956}
1957
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001958inline void requestRoutesBMCDumpCreate(App& app)
1959{
George Liu0fda0f12021-11-16 10:06:17 +08001960 BMCWEB_ROUTE(
1961 app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001962 "/redfish/v1/Managers/<str>/LogServices/Dump/Actions/LogService.CollectDiagnosticData/")
Ed Tanoused398212021-06-09 17:05:54 -07001963 .privileges(redfish::privileges::postLogService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001964 .methods(boost::beast::http::verb::post)(
Claire Weinanfdd26902022-03-01 14:18:25 -08001965 std::bind_front(handleLogServicesDumpCollectDiagnosticDataPost,
1966 std::ref(app), "BMC"));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001967}
1968
1969inline void requestRoutesBMCDumpClear(App& app)
1970{
George Liu0fda0f12021-11-16 10:06:17 +08001971 BMCWEB_ROUTE(
1972 app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001973 "/redfish/v1/Managers/<str>/LogServices/Dump/Actions/LogService.ClearLog/")
Ed Tanoused398212021-06-09 17:05:54 -07001974 .privileges(redfish::privileges::postLogService)
Claire Weinanfdd26902022-03-01 14:18:25 -08001975 .methods(boost::beast::http::verb::post)(std::bind_front(
1976 handleLogServicesDumpClearLogPost, std::ref(app), "BMC"));
1977}
1978
Carson Labrado168d1b12023-03-27 17:04:46 +00001979inline void requestRoutesDBusEventLogEntryDownload(App& app)
1980{
1981 BMCWEB_ROUTE(
1982 app,
Ravi Teja9e9d99d2023-11-08 05:33:59 -06001983 "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/attachment/")
Carson Labrado168d1b12023-03-27 17:04:46 +00001984 .privileges(redfish::privileges::getLogEntry)
1985 .methods(boost::beast::http::verb::get)(std::bind_front(
1986 handleDBusEventLogEntryDownloadGet, std::ref(app), "System"));
1987}
1988
Claire Weinanfdd26902022-03-01 14:18:25 -08001989inline void requestRoutesFaultLogDumpService(App& app)
1990{
Ed Tanous253f11b2024-05-16 09:38:31 -07001991 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/FaultLog/")
Claire Weinanfdd26902022-03-01 14:18:25 -08001992 .privileges(redfish::privileges::getLogService)
1993 .methods(boost::beast::http::verb::get)(std::bind_front(
1994 handleLogServicesDumpServiceGet, std::ref(app), "FaultLog"));
1995}
1996
1997inline void requestRoutesFaultLogDumpEntryCollection(App& app)
1998{
Ed Tanous253f11b2024-05-16 09:38:31 -07001999 BMCWEB_ROUTE(app,
2000 "/redfish/v1/Managers/<str>/LogServices/FaultLog/Entries/")
Claire Weinanfdd26902022-03-01 14:18:25 -08002001 .privileges(redfish::privileges::getLogEntryCollection)
2002 .methods(boost::beast::http::verb::get)(
2003 std::bind_front(handleLogServicesDumpEntriesCollectionGet,
2004 std::ref(app), "FaultLog"));
2005}
2006
2007inline void requestRoutesFaultLogDumpEntry(App& app)
2008{
Ed Tanous253f11b2024-05-16 09:38:31 -07002009 BMCWEB_ROUTE(
2010 app, "/redfish/v1/Managers/<str>/LogServices/FaultLog/Entries/<str>/")
Claire Weinanfdd26902022-03-01 14:18:25 -08002011 .privileges(redfish::privileges::getLogEntry)
2012 .methods(boost::beast::http::verb::get)(std::bind_front(
2013 handleLogServicesDumpEntryGet, std::ref(app), "FaultLog"));
2014
Ed Tanous253f11b2024-05-16 09:38:31 -07002015 BMCWEB_ROUTE(
2016 app, "/redfish/v1/Managers/<str>/LogServices/FaultLog/Entries/<str>/")
Claire Weinanfdd26902022-03-01 14:18:25 -08002017 .privileges(redfish::privileges::deleteLogEntry)
2018 .methods(boost::beast::http::verb::delete_)(std::bind_front(
2019 handleLogServicesDumpEntryDelete, std::ref(app), "FaultLog"));
2020}
2021
2022inline void requestRoutesFaultLogDumpClear(App& app)
2023{
2024 BMCWEB_ROUTE(
2025 app,
Ed Tanous253f11b2024-05-16 09:38:31 -07002026 "/redfish/v1/Managers/<str>/LogServices/FaultLog/Actions/LogService.ClearLog/")
Claire Weinanfdd26902022-03-01 14:18:25 -08002027 .privileges(redfish::privileges::postLogService)
2028 .methods(boost::beast::http::verb::post)(std::bind_front(
2029 handleLogServicesDumpClearLogPost, std::ref(app), "FaultLog"));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002030}
2031
2032inline void requestRoutesSystemDumpService(App& app)
2033{
Ed Tanous22d268c2022-05-19 09:39:07 -07002034 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Dump/")
Ed Tanoused398212021-06-09 17:05:54 -07002035 .privileges(redfish::privileges::getLogService)
Claire Weinan6ab9ad52022-08-12 18:20:17 -07002036 .methods(boost::beast::http::verb::get)(std::bind_front(
Ed Tanous22d268c2022-05-19 09:39:07 -07002037 handleLogServicesDumpServiceComputerSystemGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002038}
2039
2040inline void requestRoutesSystemDumpEntryCollection(App& app)
2041{
Ed Tanous22d268c2022-05-19 09:39:07 -07002042 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/")
Ed Tanoused398212021-06-09 17:05:54 -07002043 .privileges(redfish::privileges::getLogEntryCollection)
Ed Tanous22d268c2022-05-19 09:39:07 -07002044 .methods(boost::beast::http::verb::get)(std::bind_front(
2045 handleLogServicesDumpEntriesCollectionComputerSystemGet,
2046 std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002047}
2048
2049inline void requestRoutesSystemDumpEntry(App& app)
2050{
2051 BMCWEB_ROUTE(app,
Ed Tanous22d268c2022-05-19 09:39:07 -07002052 "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07002053 .privileges(redfish::privileges::getLogEntry)
Claire Weinan6ab9ad52022-08-12 18:20:17 -07002054 .methods(boost::beast::http::verb::get)(std::bind_front(
Ed Tanous22d268c2022-05-19 09:39:07 -07002055 handleLogServicesDumpEntryComputerSystemGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002056
2057 BMCWEB_ROUTE(app,
Ed Tanous22d268c2022-05-19 09:39:07 -07002058 "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07002059 .privileges(redfish::privileges::deleteLogEntry)
Claire Weinan6ab9ad52022-08-12 18:20:17 -07002060 .methods(boost::beast::http::verb::delete_)(std::bind_front(
Ed Tanous22d268c2022-05-19 09:39:07 -07002061 handleLogServicesDumpEntryComputerSystemDelete, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002062}
2063
2064inline void requestRoutesSystemDumpCreate(App& app)
2065{
George Liu0fda0f12021-11-16 10:06:17 +08002066 BMCWEB_ROUTE(
2067 app,
Ed Tanous22d268c2022-05-19 09:39:07 -07002068 "/redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.CollectDiagnosticData/")
Abhishek Patelfff6a4d2021-07-21 11:29:45 -05002069 .privileges(redfish::privileges::
2070 postLogServiceSubOverComputerSystemLogServiceCollection)
Ed Tanous22d268c2022-05-19 09:39:07 -07002071 .methods(boost::beast::http::verb::post)(std::bind_front(
2072 handleLogServicesDumpCollectDiagnosticDataComputerSystemPost,
2073 std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002074}
2075
2076inline void requestRoutesSystemDumpClear(App& app)
2077{
George Liu0fda0f12021-11-16 10:06:17 +08002078 BMCWEB_ROUTE(
2079 app,
Ed Tanous22d268c2022-05-19 09:39:07 -07002080 "/redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.ClearLog/")
Abhishek Patelfff6a4d2021-07-21 11:29:45 -05002081 .privileges(redfish::privileges::
2082 postLogServiceSubOverComputerSystemLogServiceCollection)
Claire Weinan6ab9ad52022-08-12 18:20:17 -07002083 .methods(boost::beast::http::verb::post)(std::bind_front(
Ed Tanous22d268c2022-05-19 09:39:07 -07002084 handleLogServicesDumpClearLogComputerSystemPost, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002085}
2086
2087inline void requestRoutesCrashdumpService(App& app)
2088{
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002089 /**
2090 * Functions triggers appropriate requests on DBus
2091 */
Ed Tanous22d268c2022-05-19 09:39:07 -07002092 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Crashdump/")
Myung Bae50d9f382025-06-13 09:40:18 -04002093 .privileges(redfish::privileges::getLogService)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002094 .methods(
2095 boost::beast::http::verb::
2096 get)([&app](const crow::Request& req,
2097 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2098 const std::string& systemName) {
2099 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2100 {
2101 return;
2102 }
2103 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
2104 {
2105 // Option currently returns no systems. TBD
2106 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2107 systemName);
2108 return;
2109 }
2110 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2111 {
2112 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2113 systemName);
2114 return;
2115 }
Ed Tanous22d268c2022-05-19 09:39:07 -07002116
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002117 // Copy over the static data to include the entries added by
2118 // SubRoute
2119 asyncResp->res.jsonValue["@odata.id"] =
2120 std::format("/redfish/v1/Systems/{}/LogServices/Crashdump",
2121 BMCWEB_REDFISH_SYSTEM_URI_NAME);
2122 asyncResp->res.jsonValue["@odata.type"] =
2123 "#LogService.v1_2_0.LogService";
2124 asyncResp->res.jsonValue["Name"] = "Open BMC Oem Crashdump Service";
2125 asyncResp->res.jsonValue["Description"] = "Oem Crashdump Service";
2126 asyncResp->res.jsonValue["Id"] = "Crashdump";
2127 asyncResp->res.jsonValue["OverWritePolicy"] =
2128 log_service::OverWritePolicy::WrapsWhenFull;
2129 asyncResp->res.jsonValue["MaxNumberOfRecords"] = 3;
Tejas Patil7c8c4052021-06-04 17:43:14 +05302130
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002131 std::pair<std::string, std::string> redfishDateTimeOffset =
2132 redfish::time_utils::getDateTimeOffsetNow();
2133 asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
2134 asyncResp->res.jsonValue["DateTimeLocalOffset"] =
2135 redfishDateTimeOffset.second;
Tejas Patil7c8c4052021-06-04 17:43:14 +05302136
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002137 asyncResp->res.jsonValue["Entries"]["@odata.id"] = std::format(
2138 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries",
2139 BMCWEB_REDFISH_SYSTEM_URI_NAME);
2140 asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]
2141 ["target"] = std::format(
2142 "/redfish/v1/Systems/{}/LogServices/Crashdump/Actions/LogService.ClearLog",
2143 BMCWEB_REDFISH_SYSTEM_URI_NAME);
2144 asyncResp->res
2145 .jsonValue["Actions"]["#LogService.CollectDiagnosticData"]
2146 ["target"] = std::format(
2147 "/redfish/v1/Systems/{}/LogServices/Crashdump/Actions/LogService.CollectDiagnosticData",
2148 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Corey Ethington08fad5d2025-07-31 12:14:27 -04002149
2150 etag_utils::setEtagOmitDateTimeHandler(asyncResp);
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002151 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002152}
2153
Ed Tanous8e4736b2025-08-19 10:14:02 -07002154inline void requestRoutesCrashdumpClear(App& app)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002155{
George Liu0fda0f12021-11-16 10:06:17 +08002156 BMCWEB_ROUTE(
2157 app,
Ed Tanous22d268c2022-05-19 09:39:07 -07002158 "/redfish/v1/Systems/<str>/LogServices/Crashdump/Actions/LogService.ClearLog/")
Myung Bae50d9f382025-06-13 09:40:18 -04002159 .privileges(redfish::privileges::
2160 postLogServiceSubOverComputerSystemLogServiceCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002161 .methods(boost::beast::http::verb::post)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07002162 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07002163 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2164 const std::string& systemName) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002165 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2166 {
2167 return;
2168 }
2169 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
2170 {
2171 // Option currently returns no systems. TBD
2172 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2173 systemName);
2174 return;
2175 }
2176 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2177 {
2178 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2179 systemName);
2180 return;
2181 }
Ed Tanous177612a2025-02-14 15:16:09 -08002182 dbus::utility::async_method_call(
2183 asyncResp,
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002184 [asyncResp](const boost::system::error_code& ec,
2185 const std::string&) {
2186 if (ec)
2187 {
2188 messages::internalError(asyncResp->res);
2189 return;
2190 }
2191 messages::success(asyncResp->res);
2192 },
2193 crashdumpObject, crashdumpPath, deleteAllInterface,
2194 "DeleteAll");
2195 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002196}
Jason M. Bills5b61b5e2019-10-16 10:59:02 -07002197
Patrick Williams504af5a2025-02-03 14:29:03 -05002198inline void logCrashdumpEntry(
2199 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2200 const std::string& logID, nlohmann::json& logEntryJson)
Jason M. Billse855dd22019-10-08 11:37:48 -07002201{
Johnathan Mantey043a0532020-03-10 17:15:28 -07002202 auto getStoredLogCallback =
Ed Tanousb9d36b42022-02-26 21:42:46 -08002203 [asyncResp, logID,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002204 &logEntryJson](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002205 const dbus::utility::DBusPropertiesMap& params) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002206 if (ec)
2207 {
2208 BMCWEB_LOG_DEBUG("failed to get log ec: {}", ec.message());
2209 if (ec.value() ==
2210 boost::system::linux_error::bad_request_descriptor)
2211 {
2212 messages::resourceNotFound(asyncResp->res, "LogEntry",
2213 logID);
2214 }
2215 else
2216 {
2217 messages::internalError(asyncResp->res);
2218 }
2219 return;
2220 }
2221
2222 std::string timestamp{};
2223 std::string filename{};
2224 std::string logfile{};
2225 parseCrashdumpParameters(params, filename, timestamp, logfile);
2226
2227 if (filename.empty() || timestamp.empty())
Jason M. Bills1ddcf012019-11-26 14:59:21 -08002228 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002229 messages::resourceNotFound(asyncResp->res, "LogEntry", logID);
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002230 return;
2231 }
2232
2233 std::string crashdumpURI =
2234 std::format(
2235 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries/",
2236 BMCWEB_REDFISH_SYSTEM_URI_NAME) +
2237 logID + "/" + filename;
2238 nlohmann::json::object_t logEntry;
2239 logEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
2240 logEntry["@odata.id"] = boost::urls::format(
2241 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries/{}",
2242 BMCWEB_REDFISH_SYSTEM_URI_NAME, logID);
2243 logEntry["Name"] = "CPU Crashdump";
2244 logEntry["Id"] = logID;
2245 logEntry["EntryType"] = log_entry::LogEntryType::Oem;
2246 logEntry["AdditionalDataURI"] = std::move(crashdumpURI);
2247 logEntry["DiagnosticDataType"] = "OEM";
2248 logEntry["OEMDiagnosticDataType"] = "PECICrashdump";
2249 logEntry["Created"] = std::move(timestamp);
2250
2251 // If logEntryJson references an array of LogEntry resources
2252 // ('Members' list), then push this as a new entry, otherwise set it
2253 // directly
2254 if (logEntryJson.is_array())
2255 {
2256 logEntryJson.push_back(logEntry);
2257 asyncResp->res.jsonValue["Members@odata.count"] =
2258 logEntryJson.size();
Jason M. Bills2b20ef62022-01-06 15:48:07 -08002259 }
2260 else
2261 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002262 logEntryJson.update(logEntry);
Jason M. Bills2b20ef62022-01-06 15:48:07 -08002263 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002264 };
Ed Tanousdeae6a72024-11-11 21:58:57 -08002265 dbus::utility::getAllProperties(
2266 crashdumpObject, crashdumpPath + std::string("/") + logID,
2267 crashdumpInterface, std::move(getStoredLogCallback));
Jason M. Billse855dd22019-10-08 11:37:48 -07002268}
2269
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002270inline void requestRoutesCrashdumpEntryCollection(App& app)
Ed Tanous1da66f72018-07-27 16:13:37 -07002271{
Ed Tanous1da66f72018-07-27 16:13:37 -07002272 /**
2273 * Functions triggers appropriate requests on DBus
2274 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002275 BMCWEB_ROUTE(app,
Ed Tanous22d268c2022-05-19 09:39:07 -07002276 "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/")
Myung Bae50d9f382025-06-13 09:40:18 -04002277 .privileges(redfish::privileges::getLogEntryCollection)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002278 .methods(
2279 boost::beast::http::verb::
2280 get)([&app](const crow::Request& req,
2281 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2282 const std::string& systemName) {
2283 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous45ca1b82022-03-25 13:07:27 -07002284 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002285 return;
Ed Tanous45ca1b82022-03-25 13:07:27 -07002286 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002287 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous002d39b2022-05-31 08:59:27 -07002288 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002289 // Option currently returns no systems. TBD
2290 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2291 systemName);
2292 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002293 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002294 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2295 {
2296 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2297 systemName);
2298 return;
2299 }
2300
2301 constexpr std::array<std::string_view, 1> interfaces = {
2302 crashdumpInterface};
2303 dbus::utility::getSubTreePaths(
2304 "/", 0, interfaces,
2305 [asyncResp](const boost::system::error_code& ec,
2306 const std::vector<std::string>& resp) {
2307 if (ec)
2308 {
2309 if (ec.value() !=
2310 boost::system::errc::no_such_file_or_directory)
2311 {
2312 BMCWEB_LOG_DEBUG("failed to get entries ec: {}",
2313 ec.message());
2314 messages::internalError(asyncResp->res);
2315 return;
2316 }
2317 }
2318 asyncResp->res.jsonValue["@odata.type"] =
2319 "#LogEntryCollection.LogEntryCollection";
2320 asyncResp->res.jsonValue["@odata.id"] = std::format(
2321 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries",
2322 BMCWEB_REDFISH_SYSTEM_URI_NAME);
2323 asyncResp->res.jsonValue["Name"] =
2324 "Open BMC Crashdump Entries";
2325 asyncResp->res.jsonValue["Description"] =
2326 "Collection of Crashdump Entries";
2327 asyncResp->res.jsonValue["Members"] =
2328 nlohmann::json::array();
2329 asyncResp->res.jsonValue["Members@odata.count"] = 0;
2330
2331 for (const std::string& path : resp)
2332 {
2333 const sdbusplus::message::object_path objPath(path);
2334 // Get the log ID
2335 std::string logID = objPath.filename();
2336 if (logID.empty())
2337 {
2338 continue;
2339 }
2340 // Add the log entry to the array
2341 logCrashdumpEntry(asyncResp, logID,
2342 asyncResp->res.jsonValue["Members"]);
2343 }
2344 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002345 });
2346}
Ed Tanous1da66f72018-07-27 16:13:37 -07002347
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002348inline void requestRoutesCrashdumpEntry(App& app)
Ed Tanous1da66f72018-07-27 16:13:37 -07002349{
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002350 BMCWEB_ROUTE(
Ed Tanous22d268c2022-05-19 09:39:07 -07002351 app, "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/<str>/")
Myung Bae50d9f382025-06-13 09:40:18 -04002352 .privileges(redfish::privileges::getLogEntry)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002353 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07002354 [&app](const crow::Request& req,
2355 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous22d268c2022-05-19 09:39:07 -07002356 const std::string& systemName, const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002357 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2358 {
2359 return;
2360 }
2361 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
2362 {
2363 // Option currently returns no systems. TBD
2364 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2365 systemName);
2366 return;
2367 }
2368 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2369 {
2370 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2371 systemName);
2372 return;
2373 }
2374 const std::string& logID = param;
2375 logCrashdumpEntry(asyncResp, logID, asyncResp->res.jsonValue);
2376 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002377}
Ed Tanous1da66f72018-07-27 16:13:37 -07002378
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002379inline void requestRoutesCrashdumpFile(App& app)
2380{
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002381 BMCWEB_ROUTE(
2382 app,
Ed Tanous22d268c2022-05-19 09:39:07 -07002383 "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/<str>/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07002384 .privileges(redfish::privileges::getLogEntry)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002385 .methods(boost::beast::http::verb::get)(
Nan Zhoua4ce1142022-08-02 18:45:25 +00002386 [](const crow::Request& req,
2387 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous22d268c2022-05-19 09:39:07 -07002388 const std::string& systemName, const std::string& logID,
2389 const std::string& fileName) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002390 // Do not call getRedfishRoute here since the crashdump file is
2391 // not a Redfish resource.
Ed Tanous22d268c2022-05-19 09:39:07 -07002392
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002393 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
2394 {
2395 // Option currently returns no systems. TBD
2396 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2397 systemName);
2398 return;
2399 }
2400 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2401 {
2402 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2403 systemName);
2404 return;
2405 }
Ed Tanous22d268c2022-05-19 09:39:07 -07002406
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002407 auto getStoredLogCallback =
2408 [asyncResp, logID, fileName,
2409 url(boost::urls::url(req.url()))](
2410 const boost::system::error_code& ec,
2411 const std::vector<std::pair<
2412 std::string, dbus::utility::DbusVariantType>>&
2413 resp) {
2414 if (ec)
2415 {
2416 BMCWEB_LOG_DEBUG("failed to get log ec: {}",
2417 ec.message());
2418 messages::internalError(asyncResp->res);
2419 return;
2420 }
Jason M. Bills8e6c0992021-03-11 16:26:53 -08002421
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002422 std::string dbusFilename{};
2423 std::string dbusTimestamp{};
2424 std::string dbusFilepath{};
Jason M. Bills8e6c0992021-03-11 16:26:53 -08002425
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002426 parseCrashdumpParameters(resp, dbusFilename,
2427 dbusTimestamp, dbusFilepath);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002428
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002429 if (dbusFilename.empty() || dbusTimestamp.empty() ||
2430 dbusFilepath.empty())
2431 {
2432 messages::resourceNotFound(asyncResp->res,
2433 "LogEntry", logID);
2434 return;
2435 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002436
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002437 // Verify the file name parameter is correct
2438 if (fileName != dbusFilename)
2439 {
2440 messages::resourceNotFound(asyncResp->res,
2441 "LogEntry", logID);
2442 return;
2443 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002444
Myung Baed51c61b2024-09-13 10:35:34 -05002445 if (asyncResp->res.openFile(dbusFilepath) !=
2446 crow::OpenCode::Success)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002447 {
2448 messages::resourceNotFound(asyncResp->res,
2449 "LogEntry", logID);
2450 return;
2451 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002452
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002453 // Configure this to be a file download when accessed
2454 // from a browser
2455 asyncResp->res.addHeader(
2456 boost::beast::http::field::content_disposition,
2457 "attachment");
2458 };
Ed Tanousdeae6a72024-11-11 21:58:57 -08002459 dbus::utility::getAllProperties(
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002460 *crow::connections::systemBus, crashdumpObject,
2461 crashdumpPath + std::string("/") + logID,
2462 crashdumpInterface, std::move(getStoredLogCallback));
2463 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002464}
2465
Jason M. Billsc5a4c822022-01-06 15:51:23 -08002466enum class OEMDiagnosticType
2467{
2468 onDemand,
2469 telemetry,
2470 invalid,
2471};
2472
Ed Tanous26ccae32023-02-16 10:28:44 -08002473inline OEMDiagnosticType getOEMDiagnosticType(std::string_view oemDiagStr)
Jason M. Billsc5a4c822022-01-06 15:51:23 -08002474{
2475 if (oemDiagStr == "OnDemand")
2476 {
2477 return OEMDiagnosticType::onDemand;
2478 }
2479 if (oemDiagStr == "Telemetry")
2480 {
2481 return OEMDiagnosticType::telemetry;
2482 }
2483
2484 return OEMDiagnosticType::invalid;
2485}
2486
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002487inline void requestRoutesCrashdumpCollect(App& app)
2488{
George Liu0fda0f12021-11-16 10:06:17 +08002489 BMCWEB_ROUTE(
2490 app,
Ed Tanous22d268c2022-05-19 09:39:07 -07002491 "/redfish/v1/Systems/<str>/LogServices/Crashdump/Actions/LogService.CollectDiagnosticData/")
Myung Bae50d9f382025-06-13 09:40:18 -04002492 .privileges(redfish::privileges::
2493 postLogServiceSubOverComputerSystemLogServiceCollection)
Ed Tanous002d39b2022-05-31 08:59:27 -07002494 .methods(boost::beast::http::verb::post)(
2495 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07002496 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2497 const std::string& systemName) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002498 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07002499 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002500 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002501 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002502
2503 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous002d39b2022-05-31 08:59:27 -07002504 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002505 // Option currently returns no systems. TBD
2506 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2507 systemName);
2508 return;
2509 }
2510 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2511 {
2512 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2513 systemName);
2514 return;
2515 }
2516
2517 std::string diagnosticDataType;
2518 std::string oemDiagnosticDataType;
Patrick Williams504af5a2025-02-03 14:29:03 -05002519 if (!redfish::json_util::readJsonAction( //
2520 req, asyncResp->res, //
2521 "DiagnosticDataType", diagnosticDataType, //
Myung Baeafc474a2024-10-09 00:53:29 -07002522 "OEMDiagnosticDataType", oemDiagnosticDataType //
2523 ))
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002524 {
2525 return;
2526 }
2527
2528 if (diagnosticDataType != "OEM")
2529 {
2530 BMCWEB_LOG_ERROR(
2531 "Only OEM DiagnosticDataType supported for Crashdump");
2532 messages::actionParameterValueFormatError(
2533 asyncResp->res, diagnosticDataType,
2534 "DiagnosticDataType", "CollectDiagnosticData");
2535 return;
2536 }
2537
2538 OEMDiagnosticType oemDiagType =
2539 getOEMDiagnosticType(oemDiagnosticDataType);
2540
2541 std::string iface;
2542 std::string method;
2543 std::string taskMatchStr;
2544 if (oemDiagType == OEMDiagnosticType::onDemand)
2545 {
2546 iface = crashdumpOnDemandInterface;
2547 method = "GenerateOnDemandLog";
2548 taskMatchStr =
2549 "type='signal',"
2550 "interface='org.freedesktop.DBus.Properties',"
2551 "member='PropertiesChanged',"
2552 "arg0namespace='com.intel.crashdump'";
2553 }
2554 else if (oemDiagType == OEMDiagnosticType::telemetry)
2555 {
2556 iface = crashdumpTelemetryInterface;
2557 method = "GenerateTelemetryLog";
2558 taskMatchStr =
2559 "type='signal',"
2560 "interface='org.freedesktop.DBus.Properties',"
2561 "member='PropertiesChanged',"
2562 "arg0namespace='com.intel.crashdump'";
Ed Tanous002d39b2022-05-31 08:59:27 -07002563 }
2564 else
2565 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002566 BMCWEB_LOG_ERROR("Unsupported OEMDiagnosticDataType: {}",
2567 oemDiagnosticDataType);
2568 messages::actionParameterValueFormatError(
2569 asyncResp->res, oemDiagnosticDataType,
2570 "OEMDiagnosticDataType", "CollectDiagnosticData");
2571 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002572 }
Ed Tanous1da66f72018-07-27 16:13:37 -07002573
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002574 auto collectCrashdumpCallback =
2575 [asyncResp, payload(task::Payload(req)),
2576 taskMatchStr](const boost::system::error_code& ec,
2577 const std::string&) mutable {
2578 if (ec)
2579 {
2580 if (ec.value() ==
2581 boost::system::errc::operation_not_supported)
2582 {
2583 messages::resourceInStandby(asyncResp->res);
2584 }
2585 else if (ec.value() == boost::system::errc::
2586 device_or_resource_busy)
2587 {
2588 messages::serviceTemporarilyUnavailable(
2589 asyncResp->res, "60");
2590 }
2591 else
2592 {
2593 messages::internalError(asyncResp->res);
2594 }
2595 return;
2596 }
2597 std::shared_ptr<task::TaskData> task =
2598 task::TaskData::createTask(
2599 [](const boost::system::error_code& ec2,
2600 sdbusplus::message_t&,
2601 const std::shared_ptr<task::TaskData>&
2602 taskData) {
2603 if (!ec2)
2604 {
2605 taskData->messages.emplace_back(
2606 messages::taskCompletedOK(
2607 std::to_string(
2608 taskData->index)));
2609 taskData->state = "Completed";
2610 }
2611 return task::completed;
2612 },
2613 taskMatchStr);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002614
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002615 task->startTimer(std::chrono::minutes(5));
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002616 task->payload.emplace(std::move(payload));
Chinmay Shripad Hegde29e2bdd2025-06-06 16:23:47 +05302617 task->populateResp(asyncResp->res);
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002618 };
2619
Ed Tanous177612a2025-02-14 15:16:09 -08002620 dbus::utility::async_method_call(
2621 asyncResp, std::move(collectCrashdumpCallback),
2622 crashdumpObject, crashdumpPath, iface, method);
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002623 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002624}
Kenny L. Ku6eda7682020-06-19 09:48:36 -07002625
Alexander Hansen599b9af2024-08-06 15:11:57 +02002626inline void dBusLogServiceActionsClear(
2627 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2628{
2629 BMCWEB_LOG_DEBUG("Do delete all entries.");
2630
2631 // Process response from Logging service.
2632 auto respHandler = [asyncResp](const boost::system::error_code& ec) {
2633 BMCWEB_LOG_DEBUG("doClearLog resp_handler callback: Done");
2634 if (ec)
2635 {
2636 // TODO Handle for specific error code
2637 BMCWEB_LOG_ERROR("doClearLog resp_handler got error {}", ec);
2638 asyncResp->res.result(
2639 boost::beast::http::status::internal_server_error);
2640 return;
2641 }
2642
Amy Change2460462025-05-06 00:10:13 -07002643 messages::success(asyncResp->res);
Alexander Hansen599b9af2024-08-06 15:11:57 +02002644 };
2645
2646 // Make call to Logging service to request Clear Log
Ed Tanous177612a2025-02-14 15:16:09 -08002647 dbus::utility::async_method_call(
2648 asyncResp, respHandler, "xyz.openbmc_project.Logging",
Alexander Hansen599b9af2024-08-06 15:11:57 +02002649 "/xyz/openbmc_project/logging",
2650 "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
2651}
2652
Andrew Geisslercb92c032018-08-17 07:56:14 -07002653/**
2654 * DBusLogServiceActionsClear class supports POST method for ClearLog action.
2655 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002656inline void requestRoutesDBusLogServiceActionsClear(App& app)
Andrew Geisslercb92c032018-08-17 07:56:14 -07002657{
Andrew Geisslercb92c032018-08-17 07:56:14 -07002658 /**
2659 * Function handles POST method request.
2660 * The Clear Log actions does not require any parameter.The action deletes
2661 * all entries found in the Entries collection for this Log Service.
2662 */
Andrew Geisslercb92c032018-08-17 07:56:14 -07002663
George Liu0fda0f12021-11-16 10:06:17 +08002664 BMCWEB_ROUTE(
2665 app,
Ed Tanous22d268c2022-05-19 09:39:07 -07002666 "/redfish/v1/Systems/<str>/LogServices/EventLog/Actions/LogService.ClearLog/")
Abhishek Patelfff6a4d2021-07-21 11:29:45 -05002667 .privileges(redfish::privileges::
2668 postLogServiceSubOverComputerSystemLogServiceCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002669 .methods(boost::beast::http::verb::post)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07002670 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07002671 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2672 const std::string& systemName) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002673 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2674 {
2675 return;
2676 }
2677 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
2678 {
2679 // Option currently returns no systems. TBD
2680 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2681 systemName);
2682 return;
2683 }
2684 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2685 {
2686 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2687 systemName);
2688 return;
2689 }
2690 dBusLogServiceActionsClear(asyncResp);
2691 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002692}
ZhikuiRena3316fc2020-01-29 14:58:08 -08002693
Ed Tanous1da66f72018-07-27 16:13:37 -07002694} // namespace redfish