blob: 015360cf7c1effc4d9e287b3786dbc18571cc49d [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"
Spencer Kub7028eb2021-10-26 15:27:35 +080018#include "human_sort.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080019#include "logging.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080020#include "query.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080021#include "registries/privilege_registry.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080022#include "str_utility.hpp"
James Feist46229572020-02-19 15:11:58 -080023#include "task.hpp"
Ed Tanous5b904292024-04-16 11:10:17 -070024#include "task_messages.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080025#include "utils/dbus_utils.hpp"
Corey Ethington08fad5d2025-07-31 12:14:27 -040026#include "utils/etag_utils.hpp"
Ed Tanous5b904292024-04-16 11:10:17 -070027#include "utils/json_utils.hpp"
Oliver Brewkaff35df92025-08-26 08:21:30 +020028#include "utils/log_services_utils.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080029#include "utils/time_utils.hpp"
Ed Tanous1da66f72018-07-27 16:13:37 -070030
Ed Tanousd7857202025-01-28 15:32:26 -080031#include <asm-generic/errno.h>
32#include <systemd/sd-bus.h>
Asmitha Karunanithi8e317782020-12-10 03:35:05 -060033#include <tinyxml2.h>
Adriana Kobylak400fd1f2021-01-29 09:01:30 -060034#include <unistd.h>
Jason M. Billse1f26342018-07-18 12:12:00 -070035
Ed Tanousd7857202025-01-28 15:32:26 -080036#include <boost/beast/http/field.hpp>
37#include <boost/beast/http/status.hpp>
Ed Tanous07c8c202022-07-11 10:08:08 -070038#include <boost/beast/http/verb.hpp>
Jason M. Bills1ddcf012019-11-26 14:59:21 -080039#include <boost/system/linux_error.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070040#include <boost/url/format.hpp>
Ed Tanousd7857202025-01-28 15:32:26 -080041#include <boost/url/url.hpp>
42#include <sdbusplus/message.hpp>
43#include <sdbusplus/message/native_types.hpp>
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020044#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050045
Ed Tanousd7857202025-01-28 15:32:26 -080046#include <algorithm>
George Liu7a1dbc42022-12-07 16:03:22 +080047#include <array>
Ed Tanousd7857202025-01-28 15:32:26 -080048#include <chrono>
Ed Tanousd7857202025-01-28 15:32:26 -080049#include <cstdint>
James Feist4418c7f2019-04-15 11:09:15 -070050#include <filesystem>
Ed Tanousd7857202025-01-28 15:32:26 -080051#include <format>
Ed Tanousd7857202025-01-28 15:32:26 -080052#include <functional>
Ed Tanous18f8f602023-07-18 10:07:23 -070053#include <iterator>
Ed Tanousd7857202025-01-28 15:32:26 -080054#include <memory>
Xiaochao Ma75710de2021-01-21 17:56:02 +080055#include <optional>
Ed Tanous3544d2a2023-08-06 18:12:20 -070056#include <ranges>
Ed Tanous26702d02021-11-03 15:02:33 -070057#include <span>
Ed Tanous18f8f602023-07-18 10:07:23 -070058#include <string>
Jason M. Billscd225da2019-05-08 15:31:57 -070059#include <string_view>
Ed Tanousd7857202025-01-28 15:32:26 -080060#include <utility>
Ed Tanousabf2add2019-01-22 16:40:12 -080061#include <variant>
Ed Tanousd7857202025-01-28 15:32:26 -080062#include <vector>
Ed Tanous1da66f72018-07-27 16:13:37 -070063
64namespace redfish
65{
66
Patrick Williams89492a12023-05-10 07:51:34 -050067constexpr const char* crashdumpObject = "com.intel.crashdump";
68constexpr const char* crashdumpPath = "/com/intel/crashdump";
69constexpr const char* crashdumpInterface = "com.intel.crashdump";
70constexpr const char* deleteAllInterface =
Jason M. Bills5b61b5e2019-10-16 10:59:02 -070071 "xyz.openbmc_project.Collection.DeleteAll";
Patrick Williams89492a12023-05-10 07:51:34 -050072constexpr const char* crashdumpOnDemandInterface =
Jason M. Bills424c4172019-03-21 13:50:33 -070073 "com.intel.crashdump.OnDemand";
Patrick Williams89492a12023-05-10 07:51:34 -050074constexpr const char* crashdumpTelemetryInterface =
Kenny L. Ku6eda7682020-06-19 09:48:36 -070075 "com.intel.crashdump.Telemetry";
Ed Tanous1da66f72018-07-27 16:13:37 -070076
Asmitha Karunanithi8e317782020-12-10 03:35:05 -060077enum class DumpCreationProgress
78{
79 DUMP_CREATE_SUCCESS,
80 DUMP_CREATE_FAILED,
81 DUMP_CREATE_INPROGRESS
82};
83
Ed Tanous18f8f602023-07-18 10:07:23 -070084inline std::string getDumpPath(std::string_view dumpType)
85{
86 std::string dbusDumpPath = "/xyz/openbmc_project/dump/";
87 std::ranges::transform(dumpType, std::back_inserter(dbusDumpPath),
88 bmcweb::asciiToLower);
89
90 return dbusDumpPath;
91}
92
Patrick Williams504af5a2025-02-03 14:29:03 -050093inline log_entry::OriginatorTypes mapDbusOriginatorTypeToRedfish(
94 const std::string& originatorType)
Asmitha Karunanithi68dd0752022-11-15 11:33:46 -060095{
96 if (originatorType ==
97 "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Client")
98 {
99 return log_entry::OriginatorTypes::Client;
100 }
101 if (originatorType ==
102 "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Internal")
103 {
104 return log_entry::OriginatorTypes::Internal;
105 }
106 if (originatorType ==
107 "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.SupportingService")
108 {
109 return log_entry::OriginatorTypes::SupportingService;
110 }
111 return log_entry::OriginatorTypes::Invalid;
112}
113
Claire Weinanaefe3782022-07-15 19:17:19 -0700114inline void parseDumpEntryFromDbusObject(
Jiaqing Zhao2d613eb2022-08-15 16:03:00 +0800115 const dbus::utility::ManagedObjectType::value_type& object,
Claire Weinanc6fecda2022-07-15 10:43:25 -0700116 std::string& dumpStatus, uint64_t& size, uint64_t& timestampUs,
Asmitha Karunanithi68dd0752022-11-15 11:33:46 -0600117 std::string& originatorId, log_entry::OriginatorTypes& originatorType,
Claire Weinanaefe3782022-07-15 19:17:19 -0700118 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
119{
120 for (const auto& interfaceMap : object.second)
121 {
122 if (interfaceMap.first == "xyz.openbmc_project.Common.Progress")
123 {
124 for (const auto& propertyMap : interfaceMap.second)
125 {
126 if (propertyMap.first == "Status")
127 {
128 const auto* status =
129 std::get_if<std::string>(&propertyMap.second);
130 if (status == nullptr)
131 {
132 messages::internalError(asyncResp->res);
133 break;
134 }
135 dumpStatus = *status;
136 }
137 }
138 }
139 else if (interfaceMap.first == "xyz.openbmc_project.Dump.Entry")
140 {
141 for (const auto& propertyMap : interfaceMap.second)
142 {
143 if (propertyMap.first == "Size")
144 {
145 const auto* sizePtr =
146 std::get_if<uint64_t>(&propertyMap.second);
147 if (sizePtr == nullptr)
148 {
149 messages::internalError(asyncResp->res);
150 break;
151 }
152 size = *sizePtr;
153 break;
154 }
155 }
156 }
157 else if (interfaceMap.first == "xyz.openbmc_project.Time.EpochTime")
158 {
159 for (const auto& propertyMap : interfaceMap.second)
160 {
161 if (propertyMap.first == "Elapsed")
162 {
163 const uint64_t* usecsTimeStamp =
164 std::get_if<uint64_t>(&propertyMap.second);
165 if (usecsTimeStamp == nullptr)
166 {
167 messages::internalError(asyncResp->res);
168 break;
169 }
Claire Weinanc6fecda2022-07-15 10:43:25 -0700170 timestampUs = *usecsTimeStamp;
Claire Weinanaefe3782022-07-15 19:17:19 -0700171 break;
172 }
173 }
174 }
Asmitha Karunanithi68dd0752022-11-15 11:33:46 -0600175 else if (interfaceMap.first ==
176 "xyz.openbmc_project.Common.OriginatedBy")
177 {
178 for (const auto& propertyMap : interfaceMap.second)
179 {
180 if (propertyMap.first == "OriginatorId")
181 {
182 const std::string* id =
183 std::get_if<std::string>(&propertyMap.second);
184 if (id == nullptr)
185 {
186 messages::internalError(asyncResp->res);
187 break;
188 }
189 originatorId = *id;
190 }
191
192 if (propertyMap.first == "OriginatorType")
193 {
194 const std::string* type =
195 std::get_if<std::string>(&propertyMap.second);
196 if (type == nullptr)
197 {
198 messages::internalError(asyncResp->res);
199 break;
200 }
201
202 originatorType = mapDbusOriginatorTypeToRedfish(*type);
203 if (originatorType == log_entry::OriginatorTypes::Invalid)
204 {
205 messages::internalError(asyncResp->res);
206 break;
207 }
208 }
209 }
210 }
Claire Weinanaefe3782022-07-15 19:17:19 -0700211 }
212}
213
Nan Zhou21ab4042022-06-26 23:07:40 +0000214static std::string getDumpEntriesPath(const std::string& dumpType)
Claire Weinanfdd26902022-03-01 14:18:25 -0800215{
216 std::string entriesPath;
217
218 if (dumpType == "BMC")
219 {
Ed Tanous253f11b2024-05-16 09:38:31 -0700220 entriesPath =
221 std::format("/redfish/v1/Managers/{}/LogServices/Dump/Entries/",
222 BMCWEB_REDFISH_MANAGER_URI_NAME);
Claire Weinanfdd26902022-03-01 14:18:25 -0800223 }
224 else if (dumpType == "FaultLog")
225 {
Ed Tanous253f11b2024-05-16 09:38:31 -0700226 entriesPath =
227 std::format("/redfish/v1/Managers/{}/LogServices/FaultLog/Entries/",
228 BMCWEB_REDFISH_MANAGER_URI_NAME);
Claire Weinanfdd26902022-03-01 14:18:25 -0800229 }
230 else if (dumpType == "System")
231 {
Ed Tanous253f11b2024-05-16 09:38:31 -0700232 entriesPath =
233 std::format("/redfish/v1/Systems/{}/LogServices/Dump/Entries/",
234 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Claire Weinanfdd26902022-03-01 14:18:25 -0800235 }
236 else
237 {
Ed Tanous62598e32023-07-17 17:06:25 -0700238 BMCWEB_LOG_ERROR("getDumpEntriesPath() invalid dump type: {}",
239 dumpType);
Claire Weinanfdd26902022-03-01 14:18:25 -0800240 }
241
242 // Returns empty string on error
243 return entriesPath;
244}
245
Patrick Williams504af5a2025-02-03 14:29:03 -0500246inline void getDumpEntryCollection(
247 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
248 const std::string& dumpType)
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500249{
Claire Weinanfdd26902022-03-01 14:18:25 -0800250 std::string entriesPath = getDumpEntriesPath(dumpType);
251 if (entriesPath.empty())
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500252 {
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500253 messages::internalError(asyncResp->res);
254 return;
255 }
256
George Liu5eb468d2023-06-20 17:03:24 +0800257 sdbusplus::message::object_path path("/xyz/openbmc_project/dump");
258 dbus::utility::getManagedObjects(
259 "xyz.openbmc_project.Dump.Manager", path,
Claire Weinanfdd26902022-03-01 14:18:25 -0800260 [asyncResp, entriesPath,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800261 dumpType](const boost::system::error_code& ec,
George Liu5eb468d2023-06-20 17:03:24 +0800262 const dbus::utility::ManagedObjectType& objects) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400263 if (ec)
264 {
265 BMCWEB_LOG_ERROR("DumpEntry resp_handler got error {}", ec);
266 messages::internalError(asyncResp->res);
267 return;
268 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700269
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400270 // Remove ending slash
271 std::string odataIdStr = entriesPath;
272 if (!odataIdStr.empty())
273 {
274 odataIdStr.pop_back();
275 }
Claire Weinanfdd26902022-03-01 14:18:25 -0800276
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400277 asyncResp->res.jsonValue["@odata.type"] =
278 "#LogEntryCollection.LogEntryCollection";
279 asyncResp->res.jsonValue["@odata.id"] = std::move(odataIdStr);
280 asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entries";
281 asyncResp->res.jsonValue["Description"] =
282 "Collection of " + dumpType + " Dump Entries";
Claire Weinanfdd26902022-03-01 14:18:25 -0800283
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400284 nlohmann::json::array_t entriesArray;
285 std::string dumpEntryPath = getDumpPath(dumpType) + "/entry/";
Ed Tanous002d39b2022-05-31 08:59:27 -0700286
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400287 dbus::utility::ManagedObjectType resp(objects);
288 std::ranges::sort(resp, [](const auto& l, const auto& r) {
289 return AlphanumLess<std::string>()(l.first.filename(),
290 r.first.filename());
291 });
292
293 for (auto& object : resp)
294 {
295 if (object.first.str.find(dumpEntryPath) == std::string::npos)
296 {
297 continue;
298 }
299 uint64_t timestampUs = 0;
300 uint64_t size = 0;
301 std::string dumpStatus;
302 std::string originatorId;
303 log_entry::OriginatorTypes originatorType =
304 log_entry::OriginatorTypes::Internal;
305 nlohmann::json::object_t thisEntry;
306
307 std::string entryID = object.first.filename();
308 if (entryID.empty())
309 {
310 continue;
311 }
312
313 parseDumpEntryFromDbusObject(object, dumpStatus, size,
314 timestampUs, originatorId,
315 originatorType, asyncResp);
316
317 if (dumpStatus !=
318 "xyz.openbmc_project.Common.Progress.OperationStatus.Completed" &&
319 !dumpStatus.empty())
320 {
321 // Dump status is not Complete, no need to enumerate
322 continue;
323 }
324
325 thisEntry["@odata.type"] = "#LogEntry.v1_11_0.LogEntry";
326 thisEntry["@odata.id"] = entriesPath + entryID;
327 thisEntry["Id"] = entryID;
328 thisEntry["EntryType"] = "Event";
329 thisEntry["Name"] = dumpType + " Dump Entry";
330 thisEntry["Created"] =
331 redfish::time_utils::getDateTimeUintUs(timestampUs);
332
333 if (!originatorId.empty())
334 {
335 thisEntry["Originator"] = originatorId;
336 thisEntry["OriginatorType"] = originatorType;
337 }
338
339 if (dumpType == "BMC")
340 {
341 thisEntry["DiagnosticDataType"] = "Manager";
342 thisEntry["AdditionalDataURI"] =
343 entriesPath + entryID + "/attachment";
344 thisEntry["AdditionalDataSizeBytes"] = size;
345 }
346 else if (dumpType == "System")
347 {
348 thisEntry["DiagnosticDataType"] = "OEM";
349 thisEntry["OEMDiagnosticDataType"] = "System";
350 thisEntry["AdditionalDataURI"] =
351 entriesPath + entryID + "/attachment";
352 thisEntry["AdditionalDataSizeBytes"] = size;
353 }
354 entriesArray.emplace_back(std::move(thisEntry));
355 }
356 asyncResp->res.jsonValue["Members@odata.count"] =
357 entriesArray.size();
358 asyncResp->res.jsonValue["Members"] = std::move(entriesArray);
Ed Tanous002d39b2022-05-31 08:59:27 -0700359 });
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500360}
361
Patrick Williams504af5a2025-02-03 14:29:03 -0500362inline void getDumpEntryById(
363 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
364 const std::string& entryID, const std::string& dumpType)
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500365{
Claire Weinanfdd26902022-03-01 14:18:25 -0800366 std::string entriesPath = getDumpEntriesPath(dumpType);
367 if (entriesPath.empty())
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500368 {
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500369 messages::internalError(asyncResp->res);
370 return;
371 }
372
George Liu5eb468d2023-06-20 17:03:24 +0800373 sdbusplus::message::object_path path("/xyz/openbmc_project/dump");
374 dbus::utility::getManagedObjects(
375 "xyz.openbmc_project.Dump.Manager", path,
Claire Weinanfdd26902022-03-01 14:18:25 -0800376 [asyncResp, entryID, dumpType,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800377 entriesPath](const boost::system::error_code& ec,
Ed Tanous02cad962022-06-30 16:50:15 -0700378 const dbus::utility::ManagedObjectType& resp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400379 if (ec)
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500380 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400381 BMCWEB_LOG_ERROR("DumpEntry resp_handler got error {}", ec);
382 messages::internalError(asyncResp->res);
383 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700384 }
385
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400386 bool foundDumpEntry = false;
387 std::string dumpEntryPath = getDumpPath(dumpType) + "/entry/";
Ed Tanous002d39b2022-05-31 08:59:27 -0700388
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400389 for (const auto& objectPath : resp)
Ed Tanous002d39b2022-05-31 08:59:27 -0700390 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400391 if (objectPath.first.str != dumpEntryPath + entryID)
392 {
393 continue;
394 }
395
396 foundDumpEntry = true;
397 uint64_t timestampUs = 0;
398 uint64_t size = 0;
399 std::string dumpStatus;
400 std::string originatorId;
401 log_entry::OriginatorTypes originatorType =
402 log_entry::OriginatorTypes::Internal;
403
404 parseDumpEntryFromDbusObject(objectPath, dumpStatus, size,
405 timestampUs, originatorId,
406 originatorType, asyncResp);
407
408 if (dumpStatus !=
409 "xyz.openbmc_project.Common.Progress.OperationStatus.Completed" &&
410 !dumpStatus.empty())
411 {
412 // Dump status is not Complete
413 // return not found until status is changed to Completed
414 messages::resourceNotFound(asyncResp->res,
415 dumpType + " dump", entryID);
416 return;
417 }
418
419 asyncResp->res.jsonValue["@odata.type"] =
420 "#LogEntry.v1_11_0.LogEntry";
421 asyncResp->res.jsonValue["@odata.id"] = entriesPath + entryID;
422 asyncResp->res.jsonValue["Id"] = entryID;
423 asyncResp->res.jsonValue["EntryType"] = "Event";
424 asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entry";
425 asyncResp->res.jsonValue["Created"] =
426 redfish::time_utils::getDateTimeUintUs(timestampUs);
427
428 if (!originatorId.empty())
429 {
430 asyncResp->res.jsonValue["Originator"] = originatorId;
431 asyncResp->res.jsonValue["OriginatorType"] = originatorType;
432 }
433
434 if (dumpType == "BMC")
435 {
436 asyncResp->res.jsonValue["DiagnosticDataType"] = "Manager";
437 asyncResp->res.jsonValue["AdditionalDataURI"] =
438 entriesPath + entryID + "/attachment";
439 asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size;
440 }
441 else if (dumpType == "System")
442 {
443 asyncResp->res.jsonValue["DiagnosticDataType"] = "OEM";
444 asyncResp->res.jsonValue["OEMDiagnosticDataType"] =
445 "System";
446 asyncResp->res.jsonValue["AdditionalDataURI"] =
447 entriesPath + entryID + "/attachment";
448 asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size;
449 }
450 }
451 if (!foundDumpEntry)
452 {
453 BMCWEB_LOG_WARNING("Can't find Dump Entry {}", entryID);
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200454 messages::resourceNotFound(asyncResp->res, dumpType + " dump",
455 entryID);
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500456 return;
457 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400458 });
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500459}
460
zhanghch058d1b46d2021-04-01 11:18:24 +0800461inline void deleteDumpEntry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Stanley Chu98782562020-11-04 16:10:24 +0800462 const std::string& entryID,
Asmitha Karunanithib47452b2020-09-25 02:02:19 -0500463 const std::string& dumpType)
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500464{
Patrick Williams5a39f772023-10-20 11:20:21 -0500465 auto respHandler = [asyncResp,
466 entryID](const boost::system::error_code& ec) {
Ed Tanous62598e32023-07-17 17:06:25 -0700467 BMCWEB_LOG_DEBUG("Dump Entry doDelete callback: Done");
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500468 if (ec)
469 {
George Liu3de8d8b2021-03-22 17:49:39 +0800470 if (ec.value() == EBADR)
471 {
472 messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
473 return;
474 }
Ed Tanous62598e32023-07-17 17:06:25 -0700475 BMCWEB_LOG_ERROR(
476 "Dump (DBus) doDelete respHandler got error {} entryID={}", ec,
477 entryID);
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500478 messages::internalError(asyncResp->res);
479 return;
480 }
481 };
Ed Tanous18f8f602023-07-18 10:07:23 -0700482
Ed Tanous177612a2025-02-14 15:16:09 -0800483 dbus::utility::async_method_call(
484 asyncResp, respHandler, "xyz.openbmc_project.Dump.Manager",
Ed Tanous18f8f602023-07-18 10:07:23 -0700485 std::format("{}/entry/{}", getDumpPath(dumpType), entryID),
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500486 "xyz.openbmc_project.Object.Delete", "Delete");
487}
Carson Labrado168d1b12023-03-27 17:04:46 +0000488
Patrick Williams504af5a2025-02-03 14:29:03 -0500489inline void downloadDumpEntry(
490 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
491 const std::string& entryID, const std::string& dumpType)
Carson Labrado168d1b12023-03-27 17:04:46 +0000492{
493 if (dumpType != "BMC")
494 {
495 BMCWEB_LOG_WARNING("Can't find Dump Entry {}", entryID);
496 messages::resourceNotFound(asyncResp->res, dumpType + " dump", entryID);
497 return;
498 }
499
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400500 std::string dumpEntryPath =
501 std::format("{}/entry/{}", getDumpPath(dumpType), entryID);
Carson Labrado168d1b12023-03-27 17:04:46 +0000502
503 auto downloadDumpEntryHandler =
504 [asyncResp, entryID,
505 dumpType](const boost::system::error_code& ec,
506 const sdbusplus::message::unix_fd& unixfd) {
Oliver Brewkaff35df92025-08-26 08:21:30 +0200507 log_services_utils::downloadEntryCallback(asyncResp, entryID,
508 dumpType, ec, unixfd);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400509 };
Carson Labrado168d1b12023-03-27 17:04:46 +0000510
Ed Tanous177612a2025-02-14 15:16:09 -0800511 dbus::utility::async_method_call(
512 asyncResp, std::move(downloadDumpEntryHandler),
513 "xyz.openbmc_project.Dump.Manager", dumpEntryPath,
514 "xyz.openbmc_project.Dump.Entry", "GetFileHandle");
Carson Labrado168d1b12023-03-27 17:04:46 +0000515}
516
Patrick Williams504af5a2025-02-03 14:29:03 -0500517inline DumpCreationProgress mapDbusStatusToDumpProgress(
518 const std::string& status)
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500519{
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600520 if (status ==
521 "xyz.openbmc_project.Common.Progress.OperationStatus.Failed" ||
522 status == "xyz.openbmc_project.Common.Progress.OperationStatus.Aborted")
523 {
524 return DumpCreationProgress::DUMP_CREATE_FAILED;
525 }
526 if (status ==
527 "xyz.openbmc_project.Common.Progress.OperationStatus.Completed")
528 {
529 return DumpCreationProgress::DUMP_CREATE_SUCCESS;
530 }
531 return DumpCreationProgress::DUMP_CREATE_INPROGRESS;
532}
533
Patrick Williams504af5a2025-02-03 14:29:03 -0500534inline DumpCreationProgress getDumpCompletionStatus(
535 const dbus::utility::DBusPropertiesMap& values)
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600536{
537 for (const auto& [key, val] : values)
538 {
539 if (key == "Status")
Ed Tanous002d39b2022-05-31 08:59:27 -0700540 {
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600541 const std::string* value = std::get_if<std::string>(&val);
542 if (value == nullptr)
543 {
Ed Tanous62598e32023-07-17 17:06:25 -0700544 BMCWEB_LOG_ERROR("Status property value is null");
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600545 return DumpCreationProgress::DUMP_CREATE_FAILED;
546 }
547 return mapDbusStatusToDumpProgress(*value);
548 }
549 }
550 return DumpCreationProgress::DUMP_CREATE_INPROGRESS;
551}
552
553inline std::string getDumpEntryPath(const std::string& dumpPath)
554{
555 if (dumpPath == "/xyz/openbmc_project/dump/bmc/entry")
556 {
Ed Tanous253f11b2024-05-16 09:38:31 -0700557 return std::format("/redfish/v1/Managers/{}/LogServices/Dump/Entries/",
Ed Tanous9f565092024-07-12 22:06:53 -0700558 BMCWEB_REDFISH_MANAGER_URI_NAME);
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600559 }
560 if (dumpPath == "/xyz/openbmc_project/dump/system/entry")
561 {
Ed Tanous253f11b2024-05-16 09:38:31 -0700562 return std::format("/redfish/v1/Systems/{}/LogServices/Dump/Entries/",
563 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600564 }
565 return "";
566}
567
568inline void createDumpTaskCallback(
569 task::Payload&& payload,
570 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
571 const sdbusplus::message::object_path& createdObjPath)
572{
573 const std::string dumpPath = createdObjPath.parent_path().str;
574 const std::string dumpId = createdObjPath.filename();
575
576 std::string dumpEntryPath = getDumpEntryPath(dumpPath);
577
578 if (dumpEntryPath.empty())
579 {
Ed Tanous62598e32023-07-17 17:06:25 -0700580 BMCWEB_LOG_ERROR("Invalid dump type received");
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600581 messages::internalError(asyncResp->res);
582 return;
583 }
584
Ed Tanous177612a2025-02-14 15:16:09 -0800585 dbus::utility::async_method_call(
586 asyncResp,
Ed Tanous8cb2c022024-03-27 16:31:46 -0700587 [asyncResp, payload = std::move(payload), createdObjPath,
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600588 dumpEntryPath{std::move(dumpEntryPath)},
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800589 dumpId](const boost::system::error_code& ec,
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600590 const std::string& introspectXml) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400591 if (ec)
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600592 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400593 BMCWEB_LOG_ERROR("Introspect call failed with error: {}",
594 ec.message());
595 messages::internalError(asyncResp->res);
596 return;
597 }
598
599 // Check if the created dump object has implemented Progress
600 // interface to track dump completion. If yes, fetch the "Status"
601 // property of the interface, modify the task state accordingly.
602 // Else, return task completed.
603 tinyxml2::XMLDocument doc;
604
605 doc.Parse(introspectXml.data(), introspectXml.size());
606 tinyxml2::XMLNode* pRoot = doc.FirstChildElement("node");
607 if (pRoot == nullptr)
608 {
609 BMCWEB_LOG_ERROR("XML document failed to parse");
610 messages::internalError(asyncResp->res);
611 return;
612 }
613 tinyxml2::XMLElement* interfaceNode =
614 pRoot->FirstChildElement("interface");
615
616 bool isProgressIntfPresent = false;
617 while (interfaceNode != nullptr)
618 {
619 const char* thisInterfaceName =
620 interfaceNode->Attribute("name");
621 if (thisInterfaceName != nullptr)
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600622 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400623 if (thisInterfaceName ==
624 std::string_view("xyz.openbmc_project.Common.Progress"))
625 {
626 interfaceNode =
627 interfaceNode->NextSiblingElement("interface");
628 continue;
629 }
630 isProgressIntfPresent = true;
631 break;
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600632 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400633 interfaceNode = interfaceNode->NextSiblingElement("interface");
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600634 }
635
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400636 std::shared_ptr<task::TaskData> task = task::TaskData::createTask(
637 [createdObjPath, dumpEntryPath, dumpId, isProgressIntfPresent](
638 const boost::system::error_code& ec2,
639 sdbusplus::message_t& msg,
640 const std::shared_ptr<task::TaskData>& taskData) {
641 if (ec2)
642 {
643 BMCWEB_LOG_ERROR("{}: Error in creating dump",
644 createdObjPath.str);
645 taskData->messages.emplace_back(
646 messages::internalError());
647 taskData->state = "Cancelled";
648 return task::completed;
649 }
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600650
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400651 if (isProgressIntfPresent)
652 {
653 dbus::utility::DBusPropertiesMap values;
654 std::string prop;
655 msg.read(prop, values);
656
657 DumpCreationProgress dumpStatus =
658 getDumpCompletionStatus(values);
659 if (dumpStatus ==
660 DumpCreationProgress::DUMP_CREATE_FAILED)
661 {
662 BMCWEB_LOG_ERROR("{}: Error in creating dump",
663 createdObjPath.str);
664 taskData->state = "Cancelled";
665 return task::completed;
666 }
667
668 if (dumpStatus ==
669 DumpCreationProgress::DUMP_CREATE_INPROGRESS)
670 {
671 BMCWEB_LOG_DEBUG(
672 "{}: Dump creation task is in progress",
673 createdObjPath.str);
674 return !task::completed;
675 }
676 }
677
678 nlohmann::json retMessage = messages::success();
679 taskData->messages.emplace_back(retMessage);
680
681 boost::urls::url url = boost::urls::format(
682 "/redfish/v1/Managers/{}/LogServices/Dump/Entries/{}",
683 BMCWEB_REDFISH_MANAGER_URI_NAME, dumpId);
684
685 std::string headerLoc = "Location: ";
686 headerLoc += url.buffer();
687
688 taskData->payload->httpHeaders.emplace_back(
689 std::move(headerLoc));
690
691 BMCWEB_LOG_DEBUG("{}: Dump creation task completed",
Ed Tanous62598e32023-07-17 17:06:25 -0700692 createdObjPath.str);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400693 taskData->state = "Completed";
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600694 return task::completed;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400695 },
696 "type='signal',interface='org.freedesktop.DBus.Properties',"
697 "member='PropertiesChanged',path='" +
698 createdObjPath.str + "'");
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600699
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400700 // The task timer is set to max time limit within which the
701 // requested dump will be collected.
702 task->startTimer(std::chrono::minutes(6));
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400703 task->payload.emplace(payload);
Chinmay Shripad Hegde29e2bdd2025-06-06 16:23:47 +0530704 task->populateResp(asyncResp->res);
Patrick Williams5a39f772023-10-20 11:20:21 -0500705 },
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600706 "xyz.openbmc_project.Dump.Manager", createdObjPath,
707 "org.freedesktop.DBus.Introspectable", "Introspect");
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500708}
709
zhanghch058d1b46d2021-04-01 11:18:24 +0800710inline void createDump(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
711 const crow::Request& req, const std::string& dumpType)
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500712{
Claire Weinanfdd26902022-03-01 14:18:25 -0800713 std::string dumpPath = getDumpEntriesPath(dumpType);
714 if (dumpPath.empty())
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500715 {
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500716 messages::internalError(asyncResp->res);
717 return;
718 }
719
720 std::optional<std::string> diagnosticDataType;
721 std::optional<std::string> oemDiagnosticDataType;
722
Patrick Williams504af5a2025-02-03 14:29:03 -0500723 if (!redfish::json_util::readJsonAction( //
724 req, asyncResp->res, //
725 "DiagnosticDataType", diagnosticDataType, //
Myung Baeafc474a2024-10-09 00:53:29 -0700726 "OEMDiagnosticDataType", oemDiagnosticDataType //
727 ))
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500728 {
729 return;
730 }
731
732 if (dumpType == "System")
733 {
734 if (!oemDiagnosticDataType || !diagnosticDataType)
735 {
Ed Tanous62598e32023-07-17 17:06:25 -0700736 BMCWEB_LOG_ERROR(
737 "CreateDump action parameter 'DiagnosticDataType'/'OEMDiagnosticDataType' value not found!");
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500738 messages::actionParameterMissing(
739 asyncResp->res, "CollectDiagnosticData",
740 "DiagnosticDataType & OEMDiagnosticDataType");
741 return;
742 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700743 if ((*oemDiagnosticDataType != "System") ||
744 (*diagnosticDataType != "OEM"))
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500745 {
Ed Tanous62598e32023-07-17 17:06:25 -0700746 BMCWEB_LOG_ERROR("Wrong parameter values passed");
Ed Tanousace85d62021-10-26 12:45:59 -0700747 messages::internalError(asyncResp->res);
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500748 return;
749 }
Ed Tanous253f11b2024-05-16 09:38:31 -0700750 dumpPath = std::format("/redfish/v1/Systems/{}/LogServices/Dump/",
751 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500752 }
753 else if (dumpType == "BMC")
754 {
755 if (!diagnosticDataType)
756 {
Ed Tanous62598e32023-07-17 17:06:25 -0700757 BMCWEB_LOG_ERROR(
758 "CreateDump action parameter 'DiagnosticDataType' not found!");
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500759 messages::actionParameterMissing(
760 asyncResp->res, "CollectDiagnosticData", "DiagnosticDataType");
761 return;
762 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700763 if (*diagnosticDataType != "Manager")
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500764 {
Ed Tanous62598e32023-07-17 17:06:25 -0700765 BMCWEB_LOG_ERROR(
766 "Wrong parameter value passed for 'DiagnosticDataType'");
Ed Tanousace85d62021-10-26 12:45:59 -0700767 messages::internalError(asyncResp->res);
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500768 return;
769 }
Ed Tanous253f11b2024-05-16 09:38:31 -0700770 dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/Dump/",
771 BMCWEB_REDFISH_MANAGER_URI_NAME);
Asmitha Karunanithi59075712021-10-22 01:17:41 -0500772 }
773 else
774 {
Ed Tanous62598e32023-07-17 17:06:25 -0700775 BMCWEB_LOG_ERROR("CreateDump failed. Unknown dump type");
Asmitha Karunanithi59075712021-10-22 01:17:41 -0500776 messages::internalError(asyncResp->res);
777 return;
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500778 }
779
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600780 std::vector<std::pair<std::string, std::variant<std::string, uint64_t>>>
781 createDumpParamVec;
782
Carson Labradof574a8e2023-03-22 02:26:00 +0000783 if (req.session != nullptr)
784 {
785 createDumpParamVec.emplace_back(
786 "xyz.openbmc_project.Dump.Create.CreateParameters.OriginatorId",
787 req.session->clientIp);
788 createDumpParamVec.emplace_back(
789 "xyz.openbmc_project.Dump.Create.CreateParameters.OriginatorType",
790 "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Client");
791 }
Asmitha Karunanithi68dd0752022-11-15 11:33:46 -0600792
Ed Tanous177612a2025-02-14 15:16:09 -0800793 dbus::utility::async_method_call(
794 asyncResp,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800795 [asyncResp, payload(task::Payload(req)),
796 dumpPath](const boost::system::error_code& ec,
797 const sdbusplus::message_t& msg,
798 const sdbusplus::message::object_path& objPath) mutable {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400799 if (ec)
Asmitha Karunanithi59075712021-10-22 01:17:41 -0500800 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400801 BMCWEB_LOG_ERROR("CreateDump resp_handler got error {}", ec);
802 const sd_bus_error* dbusError = msg.get_error();
803 if (dbusError == nullptr)
804 {
805 messages::internalError(asyncResp->res);
806 return;
807 }
808
809 BMCWEB_LOG_ERROR("CreateDump DBus error: {} and error msg: {}",
810 dbusError->name, dbusError->message);
811 if (std::string_view(
812 "xyz.openbmc_project.Common.Error.NotAllowed") ==
813 dbusError->name)
814 {
815 messages::resourceInStandby(asyncResp->res);
816 return;
817 }
818 if (std::string_view(
819 "xyz.openbmc_project.Dump.Create.Error.Disabled") ==
820 dbusError->name)
821 {
822 messages::serviceDisabled(asyncResp->res, dumpPath);
823 return;
824 }
825 if (std::string_view(
826 "xyz.openbmc_project.Common.Error.Unavailable") ==
827 dbusError->name)
828 {
829 messages::resourceInUse(asyncResp->res);
830 return;
831 }
832 // Other Dbus errors such as:
833 // xyz.openbmc_project.Common.Error.InvalidArgument &
834 // org.freedesktop.DBus.Error.InvalidArgs are all related to
835 // the dbus call that is made here in the bmcweb
836 // implementation and has nothing to do with the client's
837 // input in the request. Hence, returning internal error
838 // back to the client.
Asmitha Karunanithi59075712021-10-22 01:17:41 -0500839 messages::internalError(asyncResp->res);
840 return;
841 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400842 BMCWEB_LOG_DEBUG("Dump Created. Path: {}", objPath.str);
843 createDumpTaskCallback(std::move(payload), asyncResp, objPath);
844 },
Ed Tanous18f8f602023-07-18 10:07:23 -0700845 "xyz.openbmc_project.Dump.Manager", getDumpPath(dumpType),
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600846 "xyz.openbmc_project.Dump.Create", "CreateDump", createDumpParamVec);
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500847}
848
zhanghch058d1b46d2021-04-01 11:18:24 +0800849inline void clearDump(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
850 const std::string& dumpType)
Asmitha Karunanithi80319af2020-05-07 05:30:21 -0500851{
Ed Tanous177612a2025-02-14 15:16:09 -0800852 dbus::utility::async_method_call(
853 asyncResp,
Claire Weinan0d946212022-07-13 19:40:19 -0700854 [asyncResp](const boost::system::error_code& ec) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400855 if (ec)
856 {
857 BMCWEB_LOG_ERROR("clearDump resp_handler got error {}", ec);
858 messages::internalError(asyncResp->res);
859 return;
860 }
Amy Change2460462025-05-06 00:10:13 -0700861 messages::success(asyncResp->res);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400862 },
Ed Tanous18f8f602023-07-18 10:07:23 -0700863 "xyz.openbmc_project.Dump.Manager", getDumpPath(dumpType),
Claire Weinan0d946212022-07-13 19:40:19 -0700864 "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
Asmitha Karunanithi80319af2020-05-07 05:30:21 -0500865}
866
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400867inline void parseCrashdumpParameters(
868 const dbus::utility::DBusPropertiesMap& params, std::string& filename,
869 std::string& timestamp, std::string& logfile)
Johnathan Mantey043a0532020-03-10 17:15:28 -0700870{
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200871 const std::string* filenamePtr = nullptr;
872 const std::string* timestampPtr = nullptr;
873 const std::string* logfilePtr = nullptr;
874
875 const bool success = sdbusplus::unpackPropertiesNoThrow(
876 dbus_utils::UnpackErrorPrinter(), params, "Timestamp", timestampPtr,
877 "Filename", filenamePtr, "Log", logfilePtr);
878
879 if (!success)
Johnathan Mantey043a0532020-03-10 17:15:28 -0700880 {
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200881 return;
882 }
883
884 if (filenamePtr != nullptr)
885 {
886 filename = *filenamePtr;
887 }
888
889 if (timestampPtr != nullptr)
890 {
891 timestamp = *timestampPtr;
892 }
893
894 if (logfilePtr != nullptr)
895 {
896 logfile = *logfilePtr;
Johnathan Mantey043a0532020-03-10 17:15:28 -0700897 }
898}
899
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700900inline void requestRoutesSystemLogServiceCollection(App& app)
Ed Tanous1da66f72018-07-27 16:13:37 -0700901{
Jason M. Billsc4bf6372018-11-05 13:48:27 -0800902 /**
903 * Functions triggers appropriate requests on DBus
904 */
Ed Tanous22d268c2022-05-19 09:39:07 -0700905 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/")
Ed Tanoused398212021-06-09 17:05:54 -0700906 .privileges(redfish::privileges::getLogServiceCollection)
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400907 .methods(
908 boost::beast::http::verb::
909 get)([&app](const crow::Request& req,
910 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
911 const std::string& systemName) {
912 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700913 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400914 return;
915 }
916 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
917 {
918 // Option currently returns no systems. TBD
919 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
920 systemName);
921 return;
922 }
923 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
924 {
925 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
926 systemName);
Ed Tanous002d39b2022-05-31 08:59:27 -0700927 return;
928 }
Ed Tanous45ca1b82022-03-25 13:07:27 -0700929
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400930 // Collections don't include the static data added by SubRoute
931 // because it has a duplicate entry for members
932 asyncResp->res.jsonValue["@odata.type"] =
933 "#LogServiceCollection.LogServiceCollection";
934 asyncResp->res.jsonValue["@odata.id"] =
935 std::format("/redfish/v1/Systems/{}/LogServices",
936 BMCWEB_REDFISH_SYSTEM_URI_NAME);
937 asyncResp->res.jsonValue["Name"] = "System Log Services Collection";
938 asyncResp->res.jsonValue["Description"] =
939 "Collection of LogServices for this Computer System";
940 nlohmann::json& logServiceArray =
941 asyncResp->res.jsonValue["Members"];
942 logServiceArray = nlohmann::json::array();
943 nlohmann::json::object_t eventLog;
944 eventLog["@odata.id"] =
945 std::format("/redfish/v1/Systems/{}/LogServices/EventLog",
946 BMCWEB_REDFISH_SYSTEM_URI_NAME);
947 logServiceArray.emplace_back(std::move(eventLog));
948 if constexpr (BMCWEB_REDFISH_DUMP_LOG)
Ed Tanous002d39b2022-05-31 08:59:27 -0700949 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400950 nlohmann::json::object_t dumpLog;
951 dumpLog["@odata.id"] =
952 std::format("/redfish/v1/Systems/{}/LogServices/Dump",
953 BMCWEB_REDFISH_SYSTEM_URI_NAME);
954 logServiceArray.emplace_back(std::move(dumpLog));
Ed Tanous002d39b2022-05-31 08:59:27 -0700955 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400956
957 if constexpr (BMCWEB_REDFISH_CPU_LOG)
958 {
959 nlohmann::json::object_t crashdump;
960 crashdump["@odata.id"] =
961 std::format("/redfish/v1/Systems/{}/LogServices/Crashdump",
962 BMCWEB_REDFISH_SYSTEM_URI_NAME);
963 logServiceArray.emplace_back(std::move(crashdump));
964 }
965
966 if constexpr (BMCWEB_REDFISH_HOST_LOGGER)
967 {
968 nlohmann::json::object_t hostlogger;
969 hostlogger["@odata.id"] =
970 std::format("/redfish/v1/Systems/{}/LogServices/HostLogger",
971 BMCWEB_REDFISH_SYSTEM_URI_NAME);
972 logServiceArray.emplace_back(std::move(hostlogger));
973 }
974 asyncResp->res.jsonValue["Members@odata.count"] =
975 logServiceArray.size();
976
977 constexpr std::array<std::string_view, 1> interfaces = {
978 "xyz.openbmc_project.State.Boot.PostCode"};
979 dbus::utility::getSubTreePaths(
980 "/", 0, interfaces,
981 [asyncResp](const boost::system::error_code& ec,
982 const dbus::utility::MapperGetSubTreePathsResponse&
983 subtreePath) {
984 if (ec)
985 {
986 BMCWEB_LOG_ERROR("{}", ec);
987 return;
988 }
989
990 for (const auto& pathStr : subtreePath)
991 {
992 if (pathStr.find("PostCode") != std::string::npos)
993 {
994 nlohmann::json& logServiceArrayLocal =
995 asyncResp->res.jsonValue["Members"];
996 nlohmann::json::object_t member;
997 member["@odata.id"] = std::format(
998 "/redfish/v1/Systems/{}/LogServices/PostCodes",
999 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1000
1001 logServiceArrayLocal.emplace_back(
1002 std::move(member));
1003
1004 asyncResp->res.jsonValue["Members@odata.count"] =
1005 logServiceArrayLocal.size();
1006 return;
1007 }
1008 }
1009 });
Ed Tanous45ca1b82022-03-25 13:07:27 -07001010 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001011}
1012
1013inline void requestRoutesEventLogService(App& app)
1014{
Ed Tanous22d268c2022-05-19 09:39:07 -07001015 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/")
Ed Tanoused398212021-06-09 17:05:54 -07001016 .privileges(redfish::privileges::getLogService)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001017 .methods(
1018 boost::beast::http::verb::
1019 get)([&app](const crow::Request& req,
1020 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1021 const std::string& systemName) {
1022 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1023 {
1024 return;
1025 }
1026 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1027 {
1028 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1029 systemName);
1030 return;
1031 }
1032 asyncResp->res.jsonValue["@odata.id"] =
1033 std::format("/redfish/v1/Systems/{}/LogServices/EventLog",
1034 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1035 asyncResp->res.jsonValue["@odata.type"] =
1036 "#LogService.v1_2_0.LogService";
1037 asyncResp->res.jsonValue["Name"] = "Event Log Service";
1038 asyncResp->res.jsonValue["Description"] =
1039 "System Event Log Service";
1040 asyncResp->res.jsonValue["Id"] = "EventLog";
1041 asyncResp->res.jsonValue["OverWritePolicy"] =
1042 log_service::OverWritePolicy::WrapsWhenFull;
Tejas Patil7c8c4052021-06-04 17:43:14 +05301043
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001044 std::pair<std::string, std::string> redfishDateTimeOffset =
1045 redfish::time_utils::getDateTimeOffsetNow();
Tejas Patil7c8c4052021-06-04 17:43:14 +05301046
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001047 asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
1048 asyncResp->res.jsonValue["DateTimeLocalOffset"] =
1049 redfishDateTimeOffset.second;
Tejas Patil7c8c4052021-06-04 17:43:14 +05301050
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001051 asyncResp->res.jsonValue["Entries"]["@odata.id"] = std::format(
1052 "/redfish/v1/Systems/{}/LogServices/EventLog/Entries",
Ed Tanous20fa6a22024-05-20 18:02:58 -07001053 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001054 asyncResp->res
1055 .jsonValue["Actions"]["#LogService.ClearLog"]["target"]
1056
1057 = std::format(
1058 "/redfish/v1/Systems/{}/LogServices/EventLog/Actions/LogService.ClearLog",
1059 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Corey Ethington08fad5d2025-07-31 12:14:27 -04001060
1061 etag_utils::setEtagOmitDateTimeHandler(asyncResp);
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001062 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001063}
1064
Claire Weinandd72e872022-08-15 14:20:06 -07001065inline void handleBMCLogServicesCollectionGet(
Claire Weinanfdd26902022-03-01 14:18:25 -08001066 crow::App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001067 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1068 const std::string& managerId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001069{
1070 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1071 {
1072 return;
1073 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001074
1075 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1076 {
1077 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1078 return;
1079 }
1080
Claire Weinanfdd26902022-03-01 14:18:25 -08001081 // Collections don't include the static data added by SubRoute
1082 // because it has a duplicate entry for members
1083 asyncResp->res.jsonValue["@odata.type"] =
1084 "#LogServiceCollection.LogServiceCollection";
Ed Tanous253f11b2024-05-16 09:38:31 -07001085 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
1086 "/redfish/v1/Managers/{}/LogServices", BMCWEB_REDFISH_MANAGER_URI_NAME);
Claire Weinanfdd26902022-03-01 14:18:25 -08001087 asyncResp->res.jsonValue["Name"] = "Open BMC Log Services Collection";
1088 asyncResp->res.jsonValue["Description"] =
1089 "Collection of LogServices for this Manager";
1090 nlohmann::json& logServiceArray = asyncResp->res.jsonValue["Members"];
1091 logServiceArray = nlohmann::json::array();
1092
Ed Tanous25b54db2024-04-17 15:40:31 -07001093 if constexpr (BMCWEB_REDFISH_BMC_JOURNAL)
1094 {
1095 nlohmann::json::object_t journal;
Ed Tanous253f11b2024-05-16 09:38:31 -07001096 journal["@odata.id"] =
1097 boost::urls::format("/redfish/v1/Managers/{}/LogServices/Journal",
1098 BMCWEB_REDFISH_MANAGER_URI_NAME);
Ed Tanous25b54db2024-04-17 15:40:31 -07001099 logServiceArray.emplace_back(std::move(journal));
1100 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001101
1102 asyncResp->res.jsonValue["Members@odata.count"] = logServiceArray.size();
1103
Ed Tanous25b54db2024-04-17 15:40:31 -07001104 if constexpr (BMCWEB_REDFISH_DUMP_LOG)
1105 {
1106 constexpr std::array<std::string_view, 1> interfaces = {
1107 "xyz.openbmc_project.Collection.DeleteAll"};
1108 dbus::utility::getSubTreePaths(
1109 "/xyz/openbmc_project/dump", 0, interfaces,
1110 [asyncResp](const boost::system::error_code& ec,
1111 const dbus::utility::MapperGetSubTreePathsResponse&
1112 subTreePaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001113 if (ec)
Ed Tanous25b54db2024-04-17 15:40:31 -07001114 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001115 BMCWEB_LOG_ERROR(
1116 "handleBMCLogServicesCollectionGet respHandler got error {}",
1117 ec);
1118 // Assume that getting an error simply means there are no
1119 // dump LogServices. Return without adding any error
1120 // response.
1121 return;
Ed Tanous25b54db2024-04-17 15:40:31 -07001122 }
Ed Tanous25b54db2024-04-17 15:40:31 -07001123
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001124 nlohmann::json& logServiceArrayLocal =
1125 asyncResp->res.jsonValue["Members"];
1126
1127 for (const std::string& path : subTreePaths)
1128 {
1129 if (path == "/xyz/openbmc_project/dump/bmc")
1130 {
1131 nlohmann::json::object_t member;
1132 member["@odata.id"] = boost::urls::format(
1133 "/redfish/v1/Managers/{}/LogServices/Dump",
1134 BMCWEB_REDFISH_MANAGER_URI_NAME);
1135 logServiceArrayLocal.emplace_back(std::move(member));
1136 }
1137 else if (path == "/xyz/openbmc_project/dump/faultlog")
1138 {
1139 nlohmann::json::object_t member;
1140 member["@odata.id"] = boost::urls::format(
1141 "/redfish/v1/Managers/{}/LogServices/FaultLog",
1142 BMCWEB_REDFISH_MANAGER_URI_NAME);
1143 logServiceArrayLocal.emplace_back(std::move(member));
1144 }
1145 }
1146
1147 asyncResp->res.jsonValue["Members@odata.count"] =
1148 logServiceArrayLocal.size();
1149 });
Ed Tanous25b54db2024-04-17 15:40:31 -07001150 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001151}
1152
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001153inline void requestRoutesBMCLogServiceCollection(App& app)
1154{
Ed Tanous253f11b2024-05-16 09:38:31 -07001155 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/")
Gunnar Millsad89dcf2021-07-30 14:40:11 -05001156 .privileges(redfish::privileges::getLogServiceCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001157 .methods(boost::beast::http::verb::get)(
Claire Weinandd72e872022-08-15 14:20:06 -07001158 std::bind_front(handleBMCLogServicesCollectionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001159}
Ed Tanous1da66f72018-07-27 16:13:37 -07001160
Patrick Williams504af5a2025-02-03 14:29:03 -05001161inline void getDumpServiceInfo(
1162 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1163 const std::string& dumpType)
Claire Weinanfdd26902022-03-01 14:18:25 -08001164{
1165 std::string dumpPath;
Ed Tanous539d8c62024-06-19 14:38:27 -07001166 log_service::OverWritePolicy overWritePolicy =
1167 log_service::OverWritePolicy::Invalid;
Claire Weinanfdd26902022-03-01 14:18:25 -08001168 bool collectDiagnosticDataSupported = false;
1169
1170 if (dumpType == "BMC")
1171 {
Ed Tanous253f11b2024-05-16 09:38:31 -07001172 dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/Dump",
1173 BMCWEB_REDFISH_MANAGER_URI_NAME);
Ed Tanous539d8c62024-06-19 14:38:27 -07001174 overWritePolicy = log_service::OverWritePolicy::WrapsWhenFull;
Claire Weinanfdd26902022-03-01 14:18:25 -08001175 collectDiagnosticDataSupported = true;
1176 }
1177 else if (dumpType == "FaultLog")
1178 {
Ed Tanous253f11b2024-05-16 09:38:31 -07001179 dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/FaultLog",
1180 BMCWEB_REDFISH_MANAGER_URI_NAME);
Ed Tanous539d8c62024-06-19 14:38:27 -07001181 overWritePolicy = log_service::OverWritePolicy::Unknown;
Claire Weinanfdd26902022-03-01 14:18:25 -08001182 collectDiagnosticDataSupported = false;
1183 }
1184 else if (dumpType == "System")
1185 {
Ed Tanous253f11b2024-05-16 09:38:31 -07001186 dumpPath = std::format("/redfish/v1/Systems/{}/LogServices/Dump",
1187 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanous539d8c62024-06-19 14:38:27 -07001188 overWritePolicy = log_service::OverWritePolicy::WrapsWhenFull;
Claire Weinanfdd26902022-03-01 14:18:25 -08001189 collectDiagnosticDataSupported = true;
1190 }
1191 else
1192 {
Ed Tanous62598e32023-07-17 17:06:25 -07001193 BMCWEB_LOG_ERROR("getDumpServiceInfo() invalid dump type: {}",
1194 dumpType);
Claire Weinanfdd26902022-03-01 14:18:25 -08001195 messages::internalError(asyncResp->res);
1196 return;
1197 }
1198
1199 asyncResp->res.jsonValue["@odata.id"] = dumpPath;
1200 asyncResp->res.jsonValue["@odata.type"] = "#LogService.v1_2_0.LogService";
1201 asyncResp->res.jsonValue["Name"] = "Dump LogService";
1202 asyncResp->res.jsonValue["Description"] = dumpType + " Dump LogService";
1203 asyncResp->res.jsonValue["Id"] = std::filesystem::path(dumpPath).filename();
Ed Tanous539d8c62024-06-19 14:38:27 -07001204 asyncResp->res.jsonValue["OverWritePolicy"] = overWritePolicy;
Claire Weinanfdd26902022-03-01 14:18:25 -08001205
1206 std::pair<std::string, std::string> redfishDateTimeOffset =
Ed Tanous2b829372022-08-03 14:22:34 -07001207 redfish::time_utils::getDateTimeOffsetNow();
Claire Weinanfdd26902022-03-01 14:18:25 -08001208 asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
1209 asyncResp->res.jsonValue["DateTimeLocalOffset"] =
1210 redfishDateTimeOffset.second;
1211
1212 asyncResp->res.jsonValue["Entries"]["@odata.id"] = dumpPath + "/Entries";
Claire Weinanfdd26902022-03-01 14:18:25 -08001213
1214 if (collectDiagnosticDataSupported)
1215 {
1216 asyncResp->res.jsonValue["Actions"]["#LogService.CollectDiagnosticData"]
1217 ["target"] =
1218 dumpPath + "/Actions/LogService.CollectDiagnosticData";
1219 }
Claire Weinan0d946212022-07-13 19:40:19 -07001220
Corey Ethington08fad5d2025-07-31 12:14:27 -04001221 etag_utils::setEtagOmitDateTimeHandler(asyncResp);
1222
Claire Weinan0d946212022-07-13 19:40:19 -07001223 constexpr std::array<std::string_view, 1> interfaces = {deleteAllInterface};
1224 dbus::utility::getSubTreePaths(
1225 "/xyz/openbmc_project/dump", 0, interfaces,
1226 [asyncResp, dumpType, dumpPath](
1227 const boost::system::error_code& ec,
1228 const dbus::utility::MapperGetSubTreePathsResponse& subTreePaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001229 if (ec)
Claire Weinan0d946212022-07-13 19:40:19 -07001230 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001231 BMCWEB_LOG_ERROR("getDumpServiceInfo respHandler got error {}",
1232 ec);
1233 // Assume that getting an error simply means there are no dump
1234 // LogServices. Return without adding any error response.
1235 return;
Claire Weinan0d946212022-07-13 19:40:19 -07001236 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001237 std::string dbusDumpPath = getDumpPath(dumpType);
1238 for (const std::string& path : subTreePaths)
1239 {
1240 if (path == dbusDumpPath)
1241 {
1242 asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]
1243 ["target"] =
1244 dumpPath + "/Actions/LogService.ClearLog";
1245 break;
1246 }
1247 }
1248 });
Claire Weinanfdd26902022-03-01 14:18:25 -08001249}
1250
1251inline void handleLogServicesDumpServiceGet(
1252 crow::App& app, const std::string& dumpType, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001253 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1254 const std::string& managerId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001255{
1256 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1257 {
1258 return;
1259 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001260
1261 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1262 {
1263 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1264 return;
1265 }
1266
Claire Weinanfdd26902022-03-01 14:18:25 -08001267 getDumpServiceInfo(asyncResp, dumpType);
1268}
1269
Ed Tanous22d268c2022-05-19 09:39:07 -07001270inline void handleLogServicesDumpServiceComputerSystemGet(
1271 crow::App& app, const crow::Request& req,
1272 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1273 const std::string& chassisId)
1274{
1275 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1276 {
1277 return;
1278 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001279 if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous22d268c2022-05-19 09:39:07 -07001280 {
1281 messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
1282 return;
1283 }
1284 getDumpServiceInfo(asyncResp, "System");
1285}
1286
Claire Weinanfdd26902022-03-01 14:18:25 -08001287inline void handleLogServicesDumpEntriesCollectionGet(
1288 crow::App& app, const std::string& dumpType, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001289 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1290 const std::string& managerId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001291{
1292 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1293 {
1294 return;
1295 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001296
1297 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1298 {
1299 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1300 return;
1301 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001302 getDumpEntryCollection(asyncResp, dumpType);
1303}
1304
Ed Tanous22d268c2022-05-19 09:39:07 -07001305inline void handleLogServicesDumpEntriesCollectionComputerSystemGet(
1306 crow::App& app, const crow::Request& req,
1307 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1308 const std::string& chassisId)
1309{
1310 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1311 {
1312 return;
1313 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001314 if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous22d268c2022-05-19 09:39:07 -07001315 {
1316 messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
1317 return;
1318 }
1319 getDumpEntryCollection(asyncResp, "System");
1320}
1321
Claire Weinanfdd26902022-03-01 14:18:25 -08001322inline void handleLogServicesDumpEntryGet(
1323 crow::App& app, const std::string& dumpType, const crow::Request& req,
1324 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous253f11b2024-05-16 09:38:31 -07001325 const std::string& managerId, const std::string& dumpId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001326{
1327 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1328 {
1329 return;
1330 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001331 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1332 {
1333 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1334 return;
1335 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001336 getDumpEntryById(asyncResp, dumpId, dumpType);
1337}
Carson Labrado168d1b12023-03-27 17:04:46 +00001338
Ed Tanous22d268c2022-05-19 09:39:07 -07001339inline void handleLogServicesDumpEntryComputerSystemGet(
1340 crow::App& app, const crow::Request& req,
1341 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1342 const std::string& chassisId, const std::string& dumpId)
1343{
1344 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1345 {
1346 return;
1347 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001348 if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous22d268c2022-05-19 09:39:07 -07001349 {
1350 messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
1351 return;
1352 }
1353 getDumpEntryById(asyncResp, dumpId, "System");
1354}
Claire Weinanfdd26902022-03-01 14:18:25 -08001355
1356inline void handleLogServicesDumpEntryDelete(
1357 crow::App& app, const std::string& dumpType, const crow::Request& req,
1358 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous253f11b2024-05-16 09:38:31 -07001359 const std::string& managerId, const std::string& dumpId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001360{
1361 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1362 {
1363 return;
1364 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001365
1366 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1367 {
1368 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1369 return;
1370 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001371 deleteDumpEntry(asyncResp, dumpId, dumpType);
1372}
1373
Ed Tanous22d268c2022-05-19 09:39:07 -07001374inline void handleLogServicesDumpEntryComputerSystemDelete(
1375 crow::App& app, const crow::Request& req,
1376 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1377 const std::string& chassisId, const std::string& dumpId)
1378{
1379 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1380 {
1381 return;
1382 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001383 if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous22d268c2022-05-19 09:39:07 -07001384 {
1385 messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
1386 return;
1387 }
1388 deleteDumpEntry(asyncResp, dumpId, "System");
1389}
1390
Carson Labrado168d1b12023-03-27 17:04:46 +00001391inline void handleLogServicesDumpEntryDownloadGet(
1392 crow::App& app, const std::string& dumpType, const crow::Request& req,
1393 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous253f11b2024-05-16 09:38:31 -07001394 const std::string& managerId, const std::string& dumpId)
Carson Labrado168d1b12023-03-27 17:04:46 +00001395{
1396 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1397 {
1398 return;
1399 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001400
1401 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1402 {
1403 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1404 return;
1405 }
Carson Labrado168d1b12023-03-27 17:04:46 +00001406 downloadDumpEntry(asyncResp, dumpId, dumpType);
1407}
1408
Claire Weinanfdd26902022-03-01 14:18:25 -08001409inline void handleLogServicesDumpCollectDiagnosticDataPost(
1410 crow::App& app, const std::string& dumpType, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001411 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1412 const std::string& managerId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001413{
1414 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1415 {
1416 return;
1417 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001418 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1419 {
1420 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1421 return;
1422 }
1423
Claire Weinanfdd26902022-03-01 14:18:25 -08001424 createDump(asyncResp, req, dumpType);
1425}
1426
Ed Tanous22d268c2022-05-19 09:39:07 -07001427inline void handleLogServicesDumpCollectDiagnosticDataComputerSystemPost(
1428 crow::App& app, const crow::Request& req,
1429 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001430 const std::string& systemName)
Ed Tanous22d268c2022-05-19 09:39:07 -07001431{
1432 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1433 {
1434 return;
1435 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001436
Ed Tanous25b54db2024-04-17 15:40:31 -07001437 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous22d268c2022-05-19 09:39:07 -07001438 {
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001439 // Option currently returns no systems. TBD
1440 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1441 systemName);
1442 return;
1443 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001444 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001445 {
1446 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1447 systemName);
Ed Tanous22d268c2022-05-19 09:39:07 -07001448 return;
1449 }
1450 createDump(asyncResp, req, "System");
1451}
1452
Claire Weinanfdd26902022-03-01 14:18:25 -08001453inline void handleLogServicesDumpClearLogPost(
1454 crow::App& app, const std::string& dumpType, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001455 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1456 const std::string& managerId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001457{
1458 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1459 {
1460 return;
1461 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001462
1463 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1464 {
1465 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1466 return;
1467 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001468 clearDump(asyncResp, dumpType);
1469}
1470
Ed Tanous22d268c2022-05-19 09:39:07 -07001471inline void handleLogServicesDumpClearLogComputerSystemPost(
1472 crow::App& app, const crow::Request& req,
1473 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001474 const std::string& systemName)
Ed Tanous22d268c2022-05-19 09:39:07 -07001475{
1476 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1477 {
1478 return;
1479 }
Ed Tanous25b54db2024-04-17 15:40:31 -07001480 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous22d268c2022-05-19 09:39:07 -07001481 {
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001482 // Option currently returns no systems. TBD
1483 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1484 systemName);
1485 return;
1486 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001487 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001488 {
1489 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1490 systemName);
Ed Tanous22d268c2022-05-19 09:39:07 -07001491 return;
1492 }
1493 clearDump(asyncResp, "System");
1494}
1495
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001496inline void requestRoutesBMCDumpService(App& app)
1497{
Ed Tanous253f11b2024-05-16 09:38:31 -07001498 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/Dump/")
Ed Tanoused398212021-06-09 17:05:54 -07001499 .privileges(redfish::privileges::getLogService)
Claire Weinanfdd26902022-03-01 14:18:25 -08001500 .methods(boost::beast::http::verb::get)(std::bind_front(
1501 handleLogServicesDumpServiceGet, std::ref(app), "BMC"));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001502}
1503
1504inline void requestRoutesBMCDumpEntryCollection(App& app)
1505{
Ed Tanous253f11b2024-05-16 09:38:31 -07001506 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/")
Ed Tanoused398212021-06-09 17:05:54 -07001507 .privileges(redfish::privileges::getLogEntryCollection)
Claire Weinanfdd26902022-03-01 14:18:25 -08001508 .methods(boost::beast::http::verb::get)(std::bind_front(
1509 handleLogServicesDumpEntriesCollectionGet, std::ref(app), "BMC"));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001510}
1511
1512inline void requestRoutesBMCDumpEntry(App& app)
1513{
1514 BMCWEB_ROUTE(app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001515 "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001516 .privileges(redfish::privileges::getLogEntry)
Claire Weinanfdd26902022-03-01 14:18:25 -08001517 .methods(boost::beast::http::verb::get)(std::bind_front(
1518 handleLogServicesDumpEntryGet, std::ref(app), "BMC"));
1519
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001520 BMCWEB_ROUTE(app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001521 "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001522 .privileges(redfish::privileges::deleteLogEntry)
Claire Weinanfdd26902022-03-01 14:18:25 -08001523 .methods(boost::beast::http::verb::delete_)(std::bind_front(
1524 handleLogServicesDumpEntryDelete, std::ref(app), "BMC"));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001525}
1526
Carson Labrado168d1b12023-03-27 17:04:46 +00001527inline void requestRoutesBMCDumpEntryDownload(App& app)
1528{
1529 BMCWEB_ROUTE(
1530 app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001531 "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/<str>/attachment/")
Carson Labrado168d1b12023-03-27 17:04:46 +00001532 .privileges(redfish::privileges::getLogEntry)
1533 .methods(boost::beast::http::verb::get)(std::bind_front(
1534 handleLogServicesDumpEntryDownloadGet, std::ref(app), "BMC"));
1535}
1536
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001537inline void requestRoutesBMCDumpCreate(App& app)
1538{
George Liu0fda0f12021-11-16 10:06:17 +08001539 BMCWEB_ROUTE(
1540 app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001541 "/redfish/v1/Managers/<str>/LogServices/Dump/Actions/LogService.CollectDiagnosticData/")
Ed Tanoused398212021-06-09 17:05:54 -07001542 .privileges(redfish::privileges::postLogService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001543 .methods(boost::beast::http::verb::post)(
Claire Weinanfdd26902022-03-01 14:18:25 -08001544 std::bind_front(handleLogServicesDumpCollectDiagnosticDataPost,
1545 std::ref(app), "BMC"));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001546}
1547
1548inline void requestRoutesBMCDumpClear(App& app)
1549{
George Liu0fda0f12021-11-16 10:06:17 +08001550 BMCWEB_ROUTE(
1551 app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001552 "/redfish/v1/Managers/<str>/LogServices/Dump/Actions/LogService.ClearLog/")
Ed Tanoused398212021-06-09 17:05:54 -07001553 .privileges(redfish::privileges::postLogService)
Claire Weinanfdd26902022-03-01 14:18:25 -08001554 .methods(boost::beast::http::verb::post)(std::bind_front(
1555 handleLogServicesDumpClearLogPost, std::ref(app), "BMC"));
1556}
1557
1558inline void requestRoutesFaultLogDumpService(App& app)
1559{
Ed Tanous253f11b2024-05-16 09:38:31 -07001560 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/FaultLog/")
Claire Weinanfdd26902022-03-01 14:18:25 -08001561 .privileges(redfish::privileges::getLogService)
1562 .methods(boost::beast::http::verb::get)(std::bind_front(
1563 handleLogServicesDumpServiceGet, std::ref(app), "FaultLog"));
1564}
1565
1566inline void requestRoutesFaultLogDumpEntryCollection(App& app)
1567{
Ed Tanous253f11b2024-05-16 09:38:31 -07001568 BMCWEB_ROUTE(app,
1569 "/redfish/v1/Managers/<str>/LogServices/FaultLog/Entries/")
Claire Weinanfdd26902022-03-01 14:18:25 -08001570 .privileges(redfish::privileges::getLogEntryCollection)
1571 .methods(boost::beast::http::verb::get)(
1572 std::bind_front(handleLogServicesDumpEntriesCollectionGet,
1573 std::ref(app), "FaultLog"));
1574}
1575
1576inline void requestRoutesFaultLogDumpEntry(App& app)
1577{
Ed Tanous253f11b2024-05-16 09:38:31 -07001578 BMCWEB_ROUTE(
1579 app, "/redfish/v1/Managers/<str>/LogServices/FaultLog/Entries/<str>/")
Claire Weinanfdd26902022-03-01 14:18:25 -08001580 .privileges(redfish::privileges::getLogEntry)
1581 .methods(boost::beast::http::verb::get)(std::bind_front(
1582 handleLogServicesDumpEntryGet, std::ref(app), "FaultLog"));
1583
Ed Tanous253f11b2024-05-16 09:38:31 -07001584 BMCWEB_ROUTE(
1585 app, "/redfish/v1/Managers/<str>/LogServices/FaultLog/Entries/<str>/")
Claire Weinanfdd26902022-03-01 14:18:25 -08001586 .privileges(redfish::privileges::deleteLogEntry)
1587 .methods(boost::beast::http::verb::delete_)(std::bind_front(
1588 handleLogServicesDumpEntryDelete, std::ref(app), "FaultLog"));
1589}
1590
1591inline void requestRoutesFaultLogDumpClear(App& app)
1592{
1593 BMCWEB_ROUTE(
1594 app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001595 "/redfish/v1/Managers/<str>/LogServices/FaultLog/Actions/LogService.ClearLog/")
Claire Weinanfdd26902022-03-01 14:18:25 -08001596 .privileges(redfish::privileges::postLogService)
1597 .methods(boost::beast::http::verb::post)(std::bind_front(
1598 handleLogServicesDumpClearLogPost, std::ref(app), "FaultLog"));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001599}
1600
1601inline void requestRoutesSystemDumpService(App& app)
1602{
Ed Tanous22d268c2022-05-19 09:39:07 -07001603 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Dump/")
Ed Tanoused398212021-06-09 17:05:54 -07001604 .privileges(redfish::privileges::getLogService)
Claire Weinan6ab9ad52022-08-12 18:20:17 -07001605 .methods(boost::beast::http::verb::get)(std::bind_front(
Ed Tanous22d268c2022-05-19 09:39:07 -07001606 handleLogServicesDumpServiceComputerSystemGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001607}
1608
1609inline void requestRoutesSystemDumpEntryCollection(App& app)
1610{
Ed Tanous22d268c2022-05-19 09:39:07 -07001611 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/")
Ed Tanoused398212021-06-09 17:05:54 -07001612 .privileges(redfish::privileges::getLogEntryCollection)
Ed Tanous22d268c2022-05-19 09:39:07 -07001613 .methods(boost::beast::http::verb::get)(std::bind_front(
1614 handleLogServicesDumpEntriesCollectionComputerSystemGet,
1615 std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001616}
1617
1618inline void requestRoutesSystemDumpEntry(App& app)
1619{
1620 BMCWEB_ROUTE(app,
Ed Tanous22d268c2022-05-19 09:39:07 -07001621 "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001622 .privileges(redfish::privileges::getLogEntry)
Claire Weinan6ab9ad52022-08-12 18:20:17 -07001623 .methods(boost::beast::http::verb::get)(std::bind_front(
Ed Tanous22d268c2022-05-19 09:39:07 -07001624 handleLogServicesDumpEntryComputerSystemGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001625
1626 BMCWEB_ROUTE(app,
Ed Tanous22d268c2022-05-19 09:39:07 -07001627 "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001628 .privileges(redfish::privileges::deleteLogEntry)
Claire Weinan6ab9ad52022-08-12 18:20:17 -07001629 .methods(boost::beast::http::verb::delete_)(std::bind_front(
Ed Tanous22d268c2022-05-19 09:39:07 -07001630 handleLogServicesDumpEntryComputerSystemDelete, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001631}
1632
1633inline void requestRoutesSystemDumpCreate(App& app)
1634{
George Liu0fda0f12021-11-16 10:06:17 +08001635 BMCWEB_ROUTE(
1636 app,
Ed Tanous22d268c2022-05-19 09:39:07 -07001637 "/redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.CollectDiagnosticData/")
Abhishek Patelfff6a4d2021-07-21 11:29:45 -05001638 .privileges(redfish::privileges::
1639 postLogServiceSubOverComputerSystemLogServiceCollection)
Ed Tanous22d268c2022-05-19 09:39:07 -07001640 .methods(boost::beast::http::verb::post)(std::bind_front(
1641 handleLogServicesDumpCollectDiagnosticDataComputerSystemPost,
1642 std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001643}
1644
1645inline void requestRoutesSystemDumpClear(App& app)
1646{
George Liu0fda0f12021-11-16 10:06:17 +08001647 BMCWEB_ROUTE(
1648 app,
Ed Tanous22d268c2022-05-19 09:39:07 -07001649 "/redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.ClearLog/")
Abhishek Patelfff6a4d2021-07-21 11:29:45 -05001650 .privileges(redfish::privileges::
1651 postLogServiceSubOverComputerSystemLogServiceCollection)
Claire Weinan6ab9ad52022-08-12 18:20:17 -07001652 .methods(boost::beast::http::verb::post)(std::bind_front(
Ed Tanous22d268c2022-05-19 09:39:07 -07001653 handleLogServicesDumpClearLogComputerSystemPost, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001654}
1655
1656inline void requestRoutesCrashdumpService(App& app)
1657{
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001658 /**
1659 * Functions triggers appropriate requests on DBus
1660 */
Ed Tanous22d268c2022-05-19 09:39:07 -07001661 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Crashdump/")
Myung Bae50d9f382025-06-13 09:40:18 -04001662 .privileges(redfish::privileges::getLogService)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001663 .methods(
1664 boost::beast::http::verb::
1665 get)([&app](const crow::Request& req,
1666 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1667 const std::string& systemName) {
1668 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1669 {
1670 return;
1671 }
1672 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1673 {
1674 // Option currently returns no systems. TBD
1675 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1676 systemName);
1677 return;
1678 }
1679 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1680 {
1681 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1682 systemName);
1683 return;
1684 }
Ed Tanous22d268c2022-05-19 09:39:07 -07001685
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001686 // Copy over the static data to include the entries added by
1687 // SubRoute
1688 asyncResp->res.jsonValue["@odata.id"] =
1689 std::format("/redfish/v1/Systems/{}/LogServices/Crashdump",
1690 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1691 asyncResp->res.jsonValue["@odata.type"] =
1692 "#LogService.v1_2_0.LogService";
1693 asyncResp->res.jsonValue["Name"] = "Open BMC Oem Crashdump Service";
1694 asyncResp->res.jsonValue["Description"] = "Oem Crashdump Service";
1695 asyncResp->res.jsonValue["Id"] = "Crashdump";
1696 asyncResp->res.jsonValue["OverWritePolicy"] =
1697 log_service::OverWritePolicy::WrapsWhenFull;
1698 asyncResp->res.jsonValue["MaxNumberOfRecords"] = 3;
Tejas Patil7c8c4052021-06-04 17:43:14 +05301699
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001700 std::pair<std::string, std::string> redfishDateTimeOffset =
1701 redfish::time_utils::getDateTimeOffsetNow();
1702 asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
1703 asyncResp->res.jsonValue["DateTimeLocalOffset"] =
1704 redfishDateTimeOffset.second;
Tejas Patil7c8c4052021-06-04 17:43:14 +05301705
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001706 asyncResp->res.jsonValue["Entries"]["@odata.id"] = std::format(
1707 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries",
1708 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1709 asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]
1710 ["target"] = std::format(
1711 "/redfish/v1/Systems/{}/LogServices/Crashdump/Actions/LogService.ClearLog",
1712 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1713 asyncResp->res
1714 .jsonValue["Actions"]["#LogService.CollectDiagnosticData"]
1715 ["target"] = std::format(
1716 "/redfish/v1/Systems/{}/LogServices/Crashdump/Actions/LogService.CollectDiagnosticData",
1717 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Corey Ethington08fad5d2025-07-31 12:14:27 -04001718
1719 etag_utils::setEtagOmitDateTimeHandler(asyncResp);
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001720 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001721}
1722
Ed Tanous8e4736b2025-08-19 10:14:02 -07001723inline void requestRoutesCrashdumpClear(App& app)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001724{
George Liu0fda0f12021-11-16 10:06:17 +08001725 BMCWEB_ROUTE(
1726 app,
Ed Tanous22d268c2022-05-19 09:39:07 -07001727 "/redfish/v1/Systems/<str>/LogServices/Crashdump/Actions/LogService.ClearLog/")
Myung Bae50d9f382025-06-13 09:40:18 -04001728 .privileges(redfish::privileges::
1729 postLogServiceSubOverComputerSystemLogServiceCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001730 .methods(boost::beast::http::verb::post)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07001731 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07001732 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1733 const std::string& systemName) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001734 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1735 {
1736 return;
1737 }
1738 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1739 {
1740 // Option currently returns no systems. TBD
1741 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1742 systemName);
1743 return;
1744 }
1745 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1746 {
1747 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1748 systemName);
1749 return;
1750 }
Ed Tanous177612a2025-02-14 15:16:09 -08001751 dbus::utility::async_method_call(
1752 asyncResp,
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001753 [asyncResp](const boost::system::error_code& ec,
1754 const std::string&) {
1755 if (ec)
1756 {
1757 messages::internalError(asyncResp->res);
1758 return;
1759 }
1760 messages::success(asyncResp->res);
1761 },
1762 crashdumpObject, crashdumpPath, deleteAllInterface,
1763 "DeleteAll");
1764 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001765}
Jason M. Bills5b61b5e2019-10-16 10:59:02 -07001766
Patrick Williams504af5a2025-02-03 14:29:03 -05001767inline void logCrashdumpEntry(
1768 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1769 const std::string& logID, nlohmann::json& logEntryJson)
Jason M. Billse855dd22019-10-08 11:37:48 -07001770{
Johnathan Mantey043a0532020-03-10 17:15:28 -07001771 auto getStoredLogCallback =
Ed Tanousb9d36b42022-02-26 21:42:46 -08001772 [asyncResp, logID,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001773 &logEntryJson](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001774 const dbus::utility::DBusPropertiesMap& params) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001775 if (ec)
1776 {
1777 BMCWEB_LOG_DEBUG("failed to get log ec: {}", ec.message());
1778 if (ec.value() ==
1779 boost::system::linux_error::bad_request_descriptor)
1780 {
1781 messages::resourceNotFound(asyncResp->res, "LogEntry",
1782 logID);
1783 }
1784 else
1785 {
1786 messages::internalError(asyncResp->res);
1787 }
1788 return;
1789 }
1790
1791 std::string timestamp{};
1792 std::string filename{};
1793 std::string logfile{};
1794 parseCrashdumpParameters(params, filename, timestamp, logfile);
1795
1796 if (filename.empty() || timestamp.empty())
Jason M. Bills1ddcf012019-11-26 14:59:21 -08001797 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001798 messages::resourceNotFound(asyncResp->res, "LogEntry", logID);
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001799 return;
1800 }
1801
1802 std::string crashdumpURI =
1803 std::format(
1804 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries/",
1805 BMCWEB_REDFISH_SYSTEM_URI_NAME) +
1806 logID + "/" + filename;
1807 nlohmann::json::object_t logEntry;
1808 logEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
1809 logEntry["@odata.id"] = boost::urls::format(
1810 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries/{}",
1811 BMCWEB_REDFISH_SYSTEM_URI_NAME, logID);
1812 logEntry["Name"] = "CPU Crashdump";
1813 logEntry["Id"] = logID;
1814 logEntry["EntryType"] = log_entry::LogEntryType::Oem;
1815 logEntry["AdditionalDataURI"] = std::move(crashdumpURI);
1816 logEntry["DiagnosticDataType"] = "OEM";
1817 logEntry["OEMDiagnosticDataType"] = "PECICrashdump";
1818 logEntry["Created"] = std::move(timestamp);
1819
1820 // If logEntryJson references an array of LogEntry resources
1821 // ('Members' list), then push this as a new entry, otherwise set it
1822 // directly
1823 if (logEntryJson.is_array())
1824 {
1825 logEntryJson.push_back(logEntry);
1826 asyncResp->res.jsonValue["Members@odata.count"] =
1827 logEntryJson.size();
Jason M. Bills2b20ef62022-01-06 15:48:07 -08001828 }
1829 else
1830 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001831 logEntryJson.update(logEntry);
Jason M. Bills2b20ef62022-01-06 15:48:07 -08001832 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001833 };
Ed Tanousdeae6a72024-11-11 21:58:57 -08001834 dbus::utility::getAllProperties(
1835 crashdumpObject, crashdumpPath + std::string("/") + logID,
1836 crashdumpInterface, std::move(getStoredLogCallback));
Jason M. Billse855dd22019-10-08 11:37:48 -07001837}
1838
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001839inline void requestRoutesCrashdumpEntryCollection(App& app)
Ed Tanous1da66f72018-07-27 16:13:37 -07001840{
Ed Tanous1da66f72018-07-27 16:13:37 -07001841 /**
1842 * Functions triggers appropriate requests on DBus
1843 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001844 BMCWEB_ROUTE(app,
Ed Tanous22d268c2022-05-19 09:39:07 -07001845 "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/")
Myung Bae50d9f382025-06-13 09:40:18 -04001846 .privileges(redfish::privileges::getLogEntryCollection)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001847 .methods(
1848 boost::beast::http::verb::
1849 get)([&app](const crow::Request& req,
1850 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1851 const std::string& systemName) {
1852 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous45ca1b82022-03-25 13:07:27 -07001853 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001854 return;
Ed Tanous45ca1b82022-03-25 13:07:27 -07001855 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001856 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous002d39b2022-05-31 08:59:27 -07001857 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001858 // Option currently returns no systems. TBD
1859 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1860 systemName);
1861 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07001862 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001863 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1864 {
1865 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1866 systemName);
1867 return;
1868 }
1869
1870 constexpr std::array<std::string_view, 1> interfaces = {
1871 crashdumpInterface};
1872 dbus::utility::getSubTreePaths(
1873 "/", 0, interfaces,
1874 [asyncResp](const boost::system::error_code& ec,
1875 const std::vector<std::string>& resp) {
1876 if (ec)
1877 {
1878 if (ec.value() !=
1879 boost::system::errc::no_such_file_or_directory)
1880 {
1881 BMCWEB_LOG_DEBUG("failed to get entries ec: {}",
1882 ec.message());
1883 messages::internalError(asyncResp->res);
1884 return;
1885 }
1886 }
1887 asyncResp->res.jsonValue["@odata.type"] =
1888 "#LogEntryCollection.LogEntryCollection";
1889 asyncResp->res.jsonValue["@odata.id"] = std::format(
1890 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries",
1891 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1892 asyncResp->res.jsonValue["Name"] =
1893 "Open BMC Crashdump Entries";
1894 asyncResp->res.jsonValue["Description"] =
1895 "Collection of Crashdump Entries";
1896 asyncResp->res.jsonValue["Members"] =
1897 nlohmann::json::array();
1898 asyncResp->res.jsonValue["Members@odata.count"] = 0;
1899
1900 for (const std::string& path : resp)
1901 {
1902 const sdbusplus::message::object_path objPath(path);
1903 // Get the log ID
1904 std::string logID = objPath.filename();
1905 if (logID.empty())
1906 {
1907 continue;
1908 }
1909 // Add the log entry to the array
1910 logCrashdumpEntry(asyncResp, logID,
1911 asyncResp->res.jsonValue["Members"]);
1912 }
1913 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001914 });
1915}
Ed Tanous1da66f72018-07-27 16:13:37 -07001916
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001917inline void requestRoutesCrashdumpEntry(App& app)
Ed Tanous1da66f72018-07-27 16:13:37 -07001918{
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001919 BMCWEB_ROUTE(
Ed Tanous22d268c2022-05-19 09:39:07 -07001920 app, "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/<str>/")
Myung Bae50d9f382025-06-13 09:40:18 -04001921 .privileges(redfish::privileges::getLogEntry)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001922 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07001923 [&app](const crow::Request& req,
1924 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous22d268c2022-05-19 09:39:07 -07001925 const std::string& systemName, const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001926 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1927 {
1928 return;
1929 }
1930 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1931 {
1932 // Option currently returns no systems. TBD
1933 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1934 systemName);
1935 return;
1936 }
1937 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1938 {
1939 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1940 systemName);
1941 return;
1942 }
1943 const std::string& logID = param;
1944 logCrashdumpEntry(asyncResp, logID, asyncResp->res.jsonValue);
1945 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001946}
Ed Tanous1da66f72018-07-27 16:13:37 -07001947
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001948inline void requestRoutesCrashdumpFile(App& app)
1949{
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001950 BMCWEB_ROUTE(
1951 app,
Ed Tanous22d268c2022-05-19 09:39:07 -07001952 "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/<str>/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001953 .privileges(redfish::privileges::getLogEntry)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001954 .methods(boost::beast::http::verb::get)(
Nan Zhoua4ce1142022-08-02 18:45:25 +00001955 [](const crow::Request& req,
1956 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous22d268c2022-05-19 09:39:07 -07001957 const std::string& systemName, const std::string& logID,
1958 const std::string& fileName) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001959 // Do not call getRedfishRoute here since the crashdump file is
1960 // not a Redfish resource.
Ed Tanous22d268c2022-05-19 09:39:07 -07001961
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001962 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1963 {
1964 // Option currently returns no systems. TBD
1965 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1966 systemName);
1967 return;
1968 }
1969 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1970 {
1971 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1972 systemName);
1973 return;
1974 }
Ed Tanous22d268c2022-05-19 09:39:07 -07001975
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001976 auto getStoredLogCallback =
1977 [asyncResp, logID, fileName,
1978 url(boost::urls::url(req.url()))](
1979 const boost::system::error_code& ec,
1980 const std::vector<std::pair<
1981 std::string, dbus::utility::DbusVariantType>>&
1982 resp) {
1983 if (ec)
1984 {
1985 BMCWEB_LOG_DEBUG("failed to get log ec: {}",
1986 ec.message());
1987 messages::internalError(asyncResp->res);
1988 return;
1989 }
Jason M. Bills8e6c0992021-03-11 16:26:53 -08001990
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001991 std::string dbusFilename{};
1992 std::string dbusTimestamp{};
1993 std::string dbusFilepath{};
Jason M. Bills8e6c0992021-03-11 16:26:53 -08001994
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001995 parseCrashdumpParameters(resp, dbusFilename,
1996 dbusTimestamp, dbusFilepath);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001997
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001998 if (dbusFilename.empty() || dbusTimestamp.empty() ||
1999 dbusFilepath.empty())
2000 {
2001 messages::resourceNotFound(asyncResp->res,
2002 "LogEntry", logID);
2003 return;
2004 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002005
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002006 // Verify the file name parameter is correct
2007 if (fileName != dbusFilename)
2008 {
2009 messages::resourceNotFound(asyncResp->res,
2010 "LogEntry", logID);
2011 return;
2012 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002013
Myung Baed51c61b2024-09-13 10:35:34 -05002014 if (asyncResp->res.openFile(dbusFilepath) !=
2015 crow::OpenCode::Success)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002016 {
2017 messages::resourceNotFound(asyncResp->res,
2018 "LogEntry", logID);
2019 return;
2020 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002021
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002022 // Configure this to be a file download when accessed
2023 // from a browser
2024 asyncResp->res.addHeader(
2025 boost::beast::http::field::content_disposition,
2026 "attachment");
2027 };
Ed Tanousdeae6a72024-11-11 21:58:57 -08002028 dbus::utility::getAllProperties(
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002029 *crow::connections::systemBus, crashdumpObject,
2030 crashdumpPath + std::string("/") + logID,
2031 crashdumpInterface, std::move(getStoredLogCallback));
2032 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002033}
2034
Jason M. Billsc5a4c822022-01-06 15:51:23 -08002035enum class OEMDiagnosticType
2036{
2037 onDemand,
2038 telemetry,
2039 invalid,
2040};
2041
Ed Tanous26ccae32023-02-16 10:28:44 -08002042inline OEMDiagnosticType getOEMDiagnosticType(std::string_view oemDiagStr)
Jason M. Billsc5a4c822022-01-06 15:51:23 -08002043{
2044 if (oemDiagStr == "OnDemand")
2045 {
2046 return OEMDiagnosticType::onDemand;
2047 }
2048 if (oemDiagStr == "Telemetry")
2049 {
2050 return OEMDiagnosticType::telemetry;
2051 }
2052
2053 return OEMDiagnosticType::invalid;
2054}
2055
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002056inline void requestRoutesCrashdumpCollect(App& app)
2057{
George Liu0fda0f12021-11-16 10:06:17 +08002058 BMCWEB_ROUTE(
2059 app,
Ed Tanous22d268c2022-05-19 09:39:07 -07002060 "/redfish/v1/Systems/<str>/LogServices/Crashdump/Actions/LogService.CollectDiagnosticData/")
Myung Bae50d9f382025-06-13 09:40:18 -04002061 .privileges(redfish::privileges::
2062 postLogServiceSubOverComputerSystemLogServiceCollection)
Ed Tanous002d39b2022-05-31 08:59:27 -07002063 .methods(boost::beast::http::verb::post)(
2064 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07002065 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2066 const std::string& systemName) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002067 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07002068 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002069 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002070 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002071
2072 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous002d39b2022-05-31 08:59:27 -07002073 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002074 // Option currently returns no systems. TBD
2075 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2076 systemName);
2077 return;
2078 }
2079 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2080 {
2081 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2082 systemName);
2083 return;
2084 }
2085
2086 std::string diagnosticDataType;
2087 std::string oemDiagnosticDataType;
Patrick Williams504af5a2025-02-03 14:29:03 -05002088 if (!redfish::json_util::readJsonAction( //
2089 req, asyncResp->res, //
2090 "DiagnosticDataType", diagnosticDataType, //
Myung Baeafc474a2024-10-09 00:53:29 -07002091 "OEMDiagnosticDataType", oemDiagnosticDataType //
2092 ))
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002093 {
2094 return;
2095 }
2096
2097 if (diagnosticDataType != "OEM")
2098 {
2099 BMCWEB_LOG_ERROR(
2100 "Only OEM DiagnosticDataType supported for Crashdump");
2101 messages::actionParameterValueFormatError(
2102 asyncResp->res, diagnosticDataType,
2103 "DiagnosticDataType", "CollectDiagnosticData");
2104 return;
2105 }
2106
2107 OEMDiagnosticType oemDiagType =
2108 getOEMDiagnosticType(oemDiagnosticDataType);
2109
2110 std::string iface;
2111 std::string method;
2112 std::string taskMatchStr;
2113 if (oemDiagType == OEMDiagnosticType::onDemand)
2114 {
2115 iface = crashdumpOnDemandInterface;
2116 method = "GenerateOnDemandLog";
2117 taskMatchStr =
2118 "type='signal',"
2119 "interface='org.freedesktop.DBus.Properties',"
2120 "member='PropertiesChanged',"
2121 "arg0namespace='com.intel.crashdump'";
2122 }
2123 else if (oemDiagType == OEMDiagnosticType::telemetry)
2124 {
2125 iface = crashdumpTelemetryInterface;
2126 method = "GenerateTelemetryLog";
2127 taskMatchStr =
2128 "type='signal',"
2129 "interface='org.freedesktop.DBus.Properties',"
2130 "member='PropertiesChanged',"
2131 "arg0namespace='com.intel.crashdump'";
Ed Tanous002d39b2022-05-31 08:59:27 -07002132 }
2133 else
2134 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002135 BMCWEB_LOG_ERROR("Unsupported OEMDiagnosticDataType: {}",
2136 oemDiagnosticDataType);
2137 messages::actionParameterValueFormatError(
2138 asyncResp->res, oemDiagnosticDataType,
2139 "OEMDiagnosticDataType", "CollectDiagnosticData");
2140 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002141 }
Ed Tanous1da66f72018-07-27 16:13:37 -07002142
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002143 auto collectCrashdumpCallback =
2144 [asyncResp, payload(task::Payload(req)),
2145 taskMatchStr](const boost::system::error_code& ec,
2146 const std::string&) mutable {
2147 if (ec)
2148 {
2149 if (ec.value() ==
2150 boost::system::errc::operation_not_supported)
2151 {
2152 messages::resourceInStandby(asyncResp->res);
2153 }
2154 else if (ec.value() == boost::system::errc::
2155 device_or_resource_busy)
2156 {
2157 messages::serviceTemporarilyUnavailable(
2158 asyncResp->res, "60");
2159 }
2160 else
2161 {
2162 messages::internalError(asyncResp->res);
2163 }
2164 return;
2165 }
2166 std::shared_ptr<task::TaskData> task =
2167 task::TaskData::createTask(
2168 [](const boost::system::error_code& ec2,
2169 sdbusplus::message_t&,
2170 const std::shared_ptr<task::TaskData>&
2171 taskData) {
2172 if (!ec2)
2173 {
2174 taskData->messages.emplace_back(
2175 messages::taskCompletedOK(
2176 std::to_string(
2177 taskData->index)));
2178 taskData->state = "Completed";
2179 }
2180 return task::completed;
2181 },
2182 taskMatchStr);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002183
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002184 task->startTimer(std::chrono::minutes(5));
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002185 task->payload.emplace(std::move(payload));
Chinmay Shripad Hegde29e2bdd2025-06-06 16:23:47 +05302186 task->populateResp(asyncResp->res);
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002187 };
2188
Ed Tanous177612a2025-02-14 15:16:09 -08002189 dbus::utility::async_method_call(
2190 asyncResp, std::move(collectCrashdumpCallback),
2191 crashdumpObject, crashdumpPath, iface, method);
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002192 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002193}
Ed Tanous1da66f72018-07-27 16:13:37 -07002194} // namespace redfish