blob: 9ee2ed6c04709f224ed41dac5e1b2a8c1e9481f3 [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"
Oliver Brewka9d6459e2025-08-27 13:39:15 +020027#include "utils/eventlog_utils.hpp"
Ed Tanous5b904292024-04-16 11:10:17 -070028#include "utils/json_utils.hpp"
Oliver Brewkaff35df92025-08-26 08:21:30 +020029#include "utils/log_services_utils.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080030#include "utils/time_utils.hpp"
Ed Tanous1da66f72018-07-27 16:13:37 -070031
Ed Tanousd7857202025-01-28 15:32:26 -080032#include <asm-generic/errno.h>
33#include <systemd/sd-bus.h>
Asmitha Karunanithi8e317782020-12-10 03:35:05 -060034#include <tinyxml2.h>
Adriana Kobylak400fd1f2021-01-29 09:01:30 -060035#include <unistd.h>
Jason M. Billse1f26342018-07-18 12:12:00 -070036
Ed Tanousd7857202025-01-28 15:32:26 -080037#include <boost/beast/http/field.hpp>
38#include <boost/beast/http/status.hpp>
Ed Tanous07c8c202022-07-11 10:08:08 -070039#include <boost/beast/http/verb.hpp>
Jason M. Bills1ddcf012019-11-26 14:59:21 -080040#include <boost/system/linux_error.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070041#include <boost/url/format.hpp>
Ed Tanousd7857202025-01-28 15:32:26 -080042#include <boost/url/url.hpp>
43#include <sdbusplus/message.hpp>
44#include <sdbusplus/message/native_types.hpp>
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020045#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050046
Ed Tanousd7857202025-01-28 15:32:26 -080047#include <algorithm>
George Liu7a1dbc42022-12-07 16:03:22 +080048#include <array>
Ed Tanousd7857202025-01-28 15:32:26 -080049#include <chrono>
Ed Tanousd7857202025-01-28 15:32:26 -080050#include <cstdint>
James Feist4418c7f2019-04-15 11:09:15 -070051#include <filesystem>
Ed Tanousd7857202025-01-28 15:32:26 -080052#include <format>
Ed Tanousd7857202025-01-28 15:32:26 -080053#include <functional>
Ed Tanous18f8f602023-07-18 10:07:23 -070054#include <iterator>
Ed Tanousd7857202025-01-28 15:32:26 -080055#include <memory>
Xiaochao Ma75710de2021-01-21 17:56:02 +080056#include <optional>
Ed Tanous3544d2a2023-08-06 18:12:20 -070057#include <ranges>
Ed Tanous26702d02021-11-03 15:02:33 -070058#include <span>
Ed Tanous18f8f602023-07-18 10:07:23 -070059#include <string>
Jason M. Billscd225da2019-05-08 15:31:57 -070060#include <string_view>
Ed Tanousd7857202025-01-28 15:32:26 -080061#include <utility>
Ed Tanousabf2add2019-01-22 16:40:12 -080062#include <variant>
Ed Tanousd7857202025-01-28 15:32:26 -080063#include <vector>
Ed Tanous1da66f72018-07-27 16:13:37 -070064
65namespace redfish
66{
67
Patrick Williams89492a12023-05-10 07:51:34 -050068constexpr const char* crashdumpObject = "com.intel.crashdump";
69constexpr const char* crashdumpPath = "/com/intel/crashdump";
70constexpr const char* crashdumpInterface = "com.intel.crashdump";
71constexpr const char* deleteAllInterface =
Jason M. Bills5b61b5e2019-10-16 10:59:02 -070072 "xyz.openbmc_project.Collection.DeleteAll";
Patrick Williams89492a12023-05-10 07:51:34 -050073constexpr const char* crashdumpOnDemandInterface =
Jason M. Bills424c4172019-03-21 13:50:33 -070074 "com.intel.crashdump.OnDemand";
Patrick Williams89492a12023-05-10 07:51:34 -050075constexpr const char* crashdumpTelemetryInterface =
Kenny L. Ku6eda7682020-06-19 09:48:36 -070076 "com.intel.crashdump.Telemetry";
Ed Tanous1da66f72018-07-27 16:13:37 -070077
Asmitha Karunanithi8e317782020-12-10 03:35:05 -060078enum class DumpCreationProgress
79{
80 DUMP_CREATE_SUCCESS,
81 DUMP_CREATE_FAILED,
82 DUMP_CREATE_INPROGRESS
83};
84
Ed Tanous18f8f602023-07-18 10:07:23 -070085inline std::string getDumpPath(std::string_view dumpType)
86{
87 std::string dbusDumpPath = "/xyz/openbmc_project/dump/";
88 std::ranges::transform(dumpType, std::back_inserter(dbusDumpPath),
89 bmcweb::asciiToLower);
90
91 return dbusDumpPath;
92}
93
Patrick Williams504af5a2025-02-03 14:29:03 -050094inline log_entry::OriginatorTypes mapDbusOriginatorTypeToRedfish(
95 const std::string& originatorType)
Asmitha Karunanithi68dd0752022-11-15 11:33:46 -060096{
97 if (originatorType ==
98 "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Client")
99 {
100 return log_entry::OriginatorTypes::Client;
101 }
102 if (originatorType ==
103 "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Internal")
104 {
105 return log_entry::OriginatorTypes::Internal;
106 }
107 if (originatorType ==
108 "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.SupportingService")
109 {
110 return log_entry::OriginatorTypes::SupportingService;
111 }
112 return log_entry::OriginatorTypes::Invalid;
113}
114
Claire Weinanaefe3782022-07-15 19:17:19 -0700115inline void parseDumpEntryFromDbusObject(
Jiaqing Zhao2d613eb2022-08-15 16:03:00 +0800116 const dbus::utility::ManagedObjectType::value_type& object,
Claire Weinanc6fecda2022-07-15 10:43:25 -0700117 std::string& dumpStatus, uint64_t& size, uint64_t& timestampUs,
Asmitha Karunanithi68dd0752022-11-15 11:33:46 -0600118 std::string& originatorId, log_entry::OriginatorTypes& originatorType,
Claire Weinanaefe3782022-07-15 19:17:19 -0700119 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
120{
121 for (const auto& interfaceMap : object.second)
122 {
123 if (interfaceMap.first == "xyz.openbmc_project.Common.Progress")
124 {
125 for (const auto& propertyMap : interfaceMap.second)
126 {
127 if (propertyMap.first == "Status")
128 {
129 const auto* status =
130 std::get_if<std::string>(&propertyMap.second);
131 if (status == nullptr)
132 {
133 messages::internalError(asyncResp->res);
134 break;
135 }
136 dumpStatus = *status;
137 }
138 }
139 }
140 else if (interfaceMap.first == "xyz.openbmc_project.Dump.Entry")
141 {
142 for (const auto& propertyMap : interfaceMap.second)
143 {
144 if (propertyMap.first == "Size")
145 {
146 const auto* sizePtr =
147 std::get_if<uint64_t>(&propertyMap.second);
148 if (sizePtr == nullptr)
149 {
150 messages::internalError(asyncResp->res);
151 break;
152 }
153 size = *sizePtr;
154 break;
155 }
156 }
157 }
158 else if (interfaceMap.first == "xyz.openbmc_project.Time.EpochTime")
159 {
160 for (const auto& propertyMap : interfaceMap.second)
161 {
162 if (propertyMap.first == "Elapsed")
163 {
164 const uint64_t* usecsTimeStamp =
165 std::get_if<uint64_t>(&propertyMap.second);
166 if (usecsTimeStamp == nullptr)
167 {
168 messages::internalError(asyncResp->res);
169 break;
170 }
Claire Weinanc6fecda2022-07-15 10:43:25 -0700171 timestampUs = *usecsTimeStamp;
Claire Weinanaefe3782022-07-15 19:17:19 -0700172 break;
173 }
174 }
175 }
Asmitha Karunanithi68dd0752022-11-15 11:33:46 -0600176 else if (interfaceMap.first ==
177 "xyz.openbmc_project.Common.OriginatedBy")
178 {
179 for (const auto& propertyMap : interfaceMap.second)
180 {
181 if (propertyMap.first == "OriginatorId")
182 {
183 const std::string* id =
184 std::get_if<std::string>(&propertyMap.second);
185 if (id == nullptr)
186 {
187 messages::internalError(asyncResp->res);
188 break;
189 }
190 originatorId = *id;
191 }
192
193 if (propertyMap.first == "OriginatorType")
194 {
195 const std::string* type =
196 std::get_if<std::string>(&propertyMap.second);
197 if (type == nullptr)
198 {
199 messages::internalError(asyncResp->res);
200 break;
201 }
202
203 originatorType = mapDbusOriginatorTypeToRedfish(*type);
204 if (originatorType == log_entry::OriginatorTypes::Invalid)
205 {
206 messages::internalError(asyncResp->res);
207 break;
208 }
209 }
210 }
211 }
Claire Weinanaefe3782022-07-15 19:17:19 -0700212 }
213}
214
Nan Zhou21ab4042022-06-26 23:07:40 +0000215static std::string getDumpEntriesPath(const std::string& dumpType)
Claire Weinanfdd26902022-03-01 14:18:25 -0800216{
217 std::string entriesPath;
218
219 if (dumpType == "BMC")
220 {
Ed Tanous253f11b2024-05-16 09:38:31 -0700221 entriesPath =
222 std::format("/redfish/v1/Managers/{}/LogServices/Dump/Entries/",
223 BMCWEB_REDFISH_MANAGER_URI_NAME);
Claire Weinanfdd26902022-03-01 14:18:25 -0800224 }
225 else if (dumpType == "FaultLog")
226 {
Ed Tanous253f11b2024-05-16 09:38:31 -0700227 entriesPath =
228 std::format("/redfish/v1/Managers/{}/LogServices/FaultLog/Entries/",
229 BMCWEB_REDFISH_MANAGER_URI_NAME);
Claire Weinanfdd26902022-03-01 14:18:25 -0800230 }
231 else if (dumpType == "System")
232 {
Ed Tanous253f11b2024-05-16 09:38:31 -0700233 entriesPath =
234 std::format("/redfish/v1/Systems/{}/LogServices/Dump/Entries/",
235 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Claire Weinanfdd26902022-03-01 14:18:25 -0800236 }
237 else
238 {
Ed Tanous62598e32023-07-17 17:06:25 -0700239 BMCWEB_LOG_ERROR("getDumpEntriesPath() invalid dump type: {}",
240 dumpType);
Claire Weinanfdd26902022-03-01 14:18:25 -0800241 }
242
243 // Returns empty string on error
244 return entriesPath;
245}
246
Patrick Williams504af5a2025-02-03 14:29:03 -0500247inline void getDumpEntryCollection(
248 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
249 const std::string& dumpType)
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500250{
Claire Weinanfdd26902022-03-01 14:18:25 -0800251 std::string entriesPath = getDumpEntriesPath(dumpType);
252 if (entriesPath.empty())
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500253 {
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500254 messages::internalError(asyncResp->res);
255 return;
256 }
257
George Liu5eb468d2023-06-20 17:03:24 +0800258 sdbusplus::message::object_path path("/xyz/openbmc_project/dump");
259 dbus::utility::getManagedObjects(
260 "xyz.openbmc_project.Dump.Manager", path,
Claire Weinanfdd26902022-03-01 14:18:25 -0800261 [asyncResp, entriesPath,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800262 dumpType](const boost::system::error_code& ec,
George Liu5eb468d2023-06-20 17:03:24 +0800263 const dbus::utility::ManagedObjectType& objects) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400264 if (ec)
265 {
266 BMCWEB_LOG_ERROR("DumpEntry resp_handler got error {}", ec);
267 messages::internalError(asyncResp->res);
268 return;
269 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700270
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400271 // Remove ending slash
272 std::string odataIdStr = entriesPath;
273 if (!odataIdStr.empty())
274 {
275 odataIdStr.pop_back();
276 }
Claire Weinanfdd26902022-03-01 14:18:25 -0800277
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400278 asyncResp->res.jsonValue["@odata.type"] =
279 "#LogEntryCollection.LogEntryCollection";
280 asyncResp->res.jsonValue["@odata.id"] = std::move(odataIdStr);
281 asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entries";
282 asyncResp->res.jsonValue["Description"] =
283 "Collection of " + dumpType + " Dump Entries";
Claire Weinanfdd26902022-03-01 14:18:25 -0800284
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400285 nlohmann::json::array_t entriesArray;
286 std::string dumpEntryPath = getDumpPath(dumpType) + "/entry/";
Ed Tanous002d39b2022-05-31 08:59:27 -0700287
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400288 dbus::utility::ManagedObjectType resp(objects);
289 std::ranges::sort(resp, [](const auto& l, const auto& r) {
290 return AlphanumLess<std::string>()(l.first.filename(),
291 r.first.filename());
292 });
293
294 for (auto& object : resp)
295 {
296 if (object.first.str.find(dumpEntryPath) == std::string::npos)
297 {
298 continue;
299 }
300 uint64_t timestampUs = 0;
301 uint64_t size = 0;
302 std::string dumpStatus;
303 std::string originatorId;
304 log_entry::OriginatorTypes originatorType =
305 log_entry::OriginatorTypes::Internal;
306 nlohmann::json::object_t thisEntry;
307
308 std::string entryID = object.first.filename();
309 if (entryID.empty())
310 {
311 continue;
312 }
313
314 parseDumpEntryFromDbusObject(object, dumpStatus, size,
315 timestampUs, originatorId,
316 originatorType, asyncResp);
317
318 if (dumpStatus !=
319 "xyz.openbmc_project.Common.Progress.OperationStatus.Completed" &&
320 !dumpStatus.empty())
321 {
322 // Dump status is not Complete, no need to enumerate
323 continue;
324 }
325
326 thisEntry["@odata.type"] = "#LogEntry.v1_11_0.LogEntry";
327 thisEntry["@odata.id"] = entriesPath + entryID;
328 thisEntry["Id"] = entryID;
329 thisEntry["EntryType"] = "Event";
330 thisEntry["Name"] = dumpType + " Dump Entry";
331 thisEntry["Created"] =
332 redfish::time_utils::getDateTimeUintUs(timestampUs);
333
334 if (!originatorId.empty())
335 {
336 thisEntry["Originator"] = originatorId;
337 thisEntry["OriginatorType"] = originatorType;
338 }
339
340 if (dumpType == "BMC")
341 {
342 thisEntry["DiagnosticDataType"] = "Manager";
343 thisEntry["AdditionalDataURI"] =
344 entriesPath + entryID + "/attachment";
345 thisEntry["AdditionalDataSizeBytes"] = size;
346 }
347 else if (dumpType == "System")
348 {
349 thisEntry["DiagnosticDataType"] = "OEM";
350 thisEntry["OEMDiagnosticDataType"] = "System";
351 thisEntry["AdditionalDataURI"] =
352 entriesPath + entryID + "/attachment";
353 thisEntry["AdditionalDataSizeBytes"] = size;
354 }
355 entriesArray.emplace_back(std::move(thisEntry));
356 }
357 asyncResp->res.jsonValue["Members@odata.count"] =
358 entriesArray.size();
359 asyncResp->res.jsonValue["Members"] = std::move(entriesArray);
Ed Tanous002d39b2022-05-31 08:59:27 -0700360 });
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500361}
362
Patrick Williams504af5a2025-02-03 14:29:03 -0500363inline void getDumpEntryById(
364 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
365 const std::string& entryID, const std::string& dumpType)
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500366{
Claire Weinanfdd26902022-03-01 14:18:25 -0800367 std::string entriesPath = getDumpEntriesPath(dumpType);
368 if (entriesPath.empty())
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500369 {
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500370 messages::internalError(asyncResp->res);
371 return;
372 }
373
George Liu5eb468d2023-06-20 17:03:24 +0800374 sdbusplus::message::object_path path("/xyz/openbmc_project/dump");
375 dbus::utility::getManagedObjects(
376 "xyz.openbmc_project.Dump.Manager", path,
Claire Weinanfdd26902022-03-01 14:18:25 -0800377 [asyncResp, entryID, dumpType,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800378 entriesPath](const boost::system::error_code& ec,
Ed Tanous02cad962022-06-30 16:50:15 -0700379 const dbus::utility::ManagedObjectType& resp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400380 if (ec)
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500381 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400382 BMCWEB_LOG_ERROR("DumpEntry resp_handler got error {}", ec);
383 messages::internalError(asyncResp->res);
384 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700385 }
386
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400387 bool foundDumpEntry = false;
388 std::string dumpEntryPath = getDumpPath(dumpType) + "/entry/";
Ed Tanous002d39b2022-05-31 08:59:27 -0700389
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400390 for (const auto& objectPath : resp)
Ed Tanous002d39b2022-05-31 08:59:27 -0700391 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400392 if (objectPath.first.str != dumpEntryPath + entryID)
393 {
394 continue;
395 }
396
397 foundDumpEntry = true;
398 uint64_t timestampUs = 0;
399 uint64_t size = 0;
400 std::string dumpStatus;
401 std::string originatorId;
402 log_entry::OriginatorTypes originatorType =
403 log_entry::OriginatorTypes::Internal;
404
405 parseDumpEntryFromDbusObject(objectPath, dumpStatus, size,
406 timestampUs, originatorId,
407 originatorType, asyncResp);
408
409 if (dumpStatus !=
410 "xyz.openbmc_project.Common.Progress.OperationStatus.Completed" &&
411 !dumpStatus.empty())
412 {
413 // Dump status is not Complete
414 // return not found until status is changed to Completed
415 messages::resourceNotFound(asyncResp->res,
416 dumpType + " dump", entryID);
417 return;
418 }
419
420 asyncResp->res.jsonValue["@odata.type"] =
421 "#LogEntry.v1_11_0.LogEntry";
422 asyncResp->res.jsonValue["@odata.id"] = entriesPath + entryID;
423 asyncResp->res.jsonValue["Id"] = entryID;
424 asyncResp->res.jsonValue["EntryType"] = "Event";
425 asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entry";
426 asyncResp->res.jsonValue["Created"] =
427 redfish::time_utils::getDateTimeUintUs(timestampUs);
428
429 if (!originatorId.empty())
430 {
431 asyncResp->res.jsonValue["Originator"] = originatorId;
432 asyncResp->res.jsonValue["OriginatorType"] = originatorType;
433 }
434
435 if (dumpType == "BMC")
436 {
437 asyncResp->res.jsonValue["DiagnosticDataType"] = "Manager";
438 asyncResp->res.jsonValue["AdditionalDataURI"] =
439 entriesPath + entryID + "/attachment";
440 asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size;
441 }
442 else if (dumpType == "System")
443 {
444 asyncResp->res.jsonValue["DiagnosticDataType"] = "OEM";
445 asyncResp->res.jsonValue["OEMDiagnosticDataType"] =
446 "System";
447 asyncResp->res.jsonValue["AdditionalDataURI"] =
448 entriesPath + entryID + "/attachment";
449 asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size;
450 }
451 }
452 if (!foundDumpEntry)
453 {
454 BMCWEB_LOG_WARNING("Can't find Dump Entry {}", entryID);
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200455 messages::resourceNotFound(asyncResp->res, dumpType + " dump",
456 entryID);
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500457 return;
458 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400459 });
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500460}
461
zhanghch058d1b46d2021-04-01 11:18:24 +0800462inline void deleteDumpEntry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Stanley Chu98782562020-11-04 16:10:24 +0800463 const std::string& entryID,
Asmitha Karunanithib47452b2020-09-25 02:02:19 -0500464 const std::string& dumpType)
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500465{
Patrick Williams5a39f772023-10-20 11:20:21 -0500466 auto respHandler = [asyncResp,
467 entryID](const boost::system::error_code& ec) {
Ed Tanous62598e32023-07-17 17:06:25 -0700468 BMCWEB_LOG_DEBUG("Dump Entry doDelete callback: Done");
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500469 if (ec)
470 {
George Liu3de8d8b2021-03-22 17:49:39 +0800471 if (ec.value() == EBADR)
472 {
473 messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
474 return;
475 }
Ed Tanous62598e32023-07-17 17:06:25 -0700476 BMCWEB_LOG_ERROR(
477 "Dump (DBus) doDelete respHandler got error {} entryID={}", ec,
478 entryID);
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500479 messages::internalError(asyncResp->res);
480 return;
481 }
482 };
Ed Tanous18f8f602023-07-18 10:07:23 -0700483
Ed Tanous177612a2025-02-14 15:16:09 -0800484 dbus::utility::async_method_call(
485 asyncResp, respHandler, "xyz.openbmc_project.Dump.Manager",
Ed Tanous18f8f602023-07-18 10:07:23 -0700486 std::format("{}/entry/{}", getDumpPath(dumpType), entryID),
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500487 "xyz.openbmc_project.Object.Delete", "Delete");
488}
Carson Labrado168d1b12023-03-27 17:04:46 +0000489
Patrick Williams504af5a2025-02-03 14:29:03 -0500490inline void downloadDumpEntry(
491 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
492 const std::string& entryID, const std::string& dumpType)
Carson Labrado168d1b12023-03-27 17:04:46 +0000493{
494 if (dumpType != "BMC")
495 {
496 BMCWEB_LOG_WARNING("Can't find Dump Entry {}", entryID);
497 messages::resourceNotFound(asyncResp->res, dumpType + " dump", entryID);
498 return;
499 }
500
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400501 std::string dumpEntryPath =
502 std::format("{}/entry/{}", getDumpPath(dumpType), entryID);
Carson Labrado168d1b12023-03-27 17:04:46 +0000503
504 auto downloadDumpEntryHandler =
505 [asyncResp, entryID,
506 dumpType](const boost::system::error_code& ec,
507 const sdbusplus::message::unix_fd& unixfd) {
Oliver Brewkaff35df92025-08-26 08:21:30 +0200508 log_services_utils::downloadEntryCallback(asyncResp, entryID,
509 dumpType, ec, unixfd);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400510 };
Carson Labrado168d1b12023-03-27 17:04:46 +0000511
Ed Tanous177612a2025-02-14 15:16:09 -0800512 dbus::utility::async_method_call(
513 asyncResp, std::move(downloadDumpEntryHandler),
514 "xyz.openbmc_project.Dump.Manager", dumpEntryPath,
515 "xyz.openbmc_project.Dump.Entry", "GetFileHandle");
Carson Labrado168d1b12023-03-27 17:04:46 +0000516}
517
Patrick Williams504af5a2025-02-03 14:29:03 -0500518inline DumpCreationProgress mapDbusStatusToDumpProgress(
519 const std::string& status)
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500520{
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600521 if (status ==
522 "xyz.openbmc_project.Common.Progress.OperationStatus.Failed" ||
523 status == "xyz.openbmc_project.Common.Progress.OperationStatus.Aborted")
524 {
525 return DumpCreationProgress::DUMP_CREATE_FAILED;
526 }
527 if (status ==
528 "xyz.openbmc_project.Common.Progress.OperationStatus.Completed")
529 {
530 return DumpCreationProgress::DUMP_CREATE_SUCCESS;
531 }
532 return DumpCreationProgress::DUMP_CREATE_INPROGRESS;
533}
534
Patrick Williams504af5a2025-02-03 14:29:03 -0500535inline DumpCreationProgress getDumpCompletionStatus(
536 const dbus::utility::DBusPropertiesMap& values)
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600537{
538 for (const auto& [key, val] : values)
539 {
540 if (key == "Status")
Ed Tanous002d39b2022-05-31 08:59:27 -0700541 {
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600542 const std::string* value = std::get_if<std::string>(&val);
543 if (value == nullptr)
544 {
Ed Tanous62598e32023-07-17 17:06:25 -0700545 BMCWEB_LOG_ERROR("Status property value is null");
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600546 return DumpCreationProgress::DUMP_CREATE_FAILED;
547 }
548 return mapDbusStatusToDumpProgress(*value);
549 }
550 }
551 return DumpCreationProgress::DUMP_CREATE_INPROGRESS;
552}
553
554inline std::string getDumpEntryPath(const std::string& dumpPath)
555{
556 if (dumpPath == "/xyz/openbmc_project/dump/bmc/entry")
557 {
Ed Tanous253f11b2024-05-16 09:38:31 -0700558 return std::format("/redfish/v1/Managers/{}/LogServices/Dump/Entries/",
Ed Tanous9f565092024-07-12 22:06:53 -0700559 BMCWEB_REDFISH_MANAGER_URI_NAME);
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600560 }
561 if (dumpPath == "/xyz/openbmc_project/dump/system/entry")
562 {
Ed Tanous253f11b2024-05-16 09:38:31 -0700563 return std::format("/redfish/v1/Systems/{}/LogServices/Dump/Entries/",
564 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600565 }
566 return "";
567}
568
569inline void createDumpTaskCallback(
570 task::Payload&& payload,
571 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
572 const sdbusplus::message::object_path& createdObjPath)
573{
574 const std::string dumpPath = createdObjPath.parent_path().str;
575 const std::string dumpId = createdObjPath.filename();
576
577 std::string dumpEntryPath = getDumpEntryPath(dumpPath);
578
579 if (dumpEntryPath.empty())
580 {
Ed Tanous62598e32023-07-17 17:06:25 -0700581 BMCWEB_LOG_ERROR("Invalid dump type received");
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600582 messages::internalError(asyncResp->res);
583 return;
584 }
585
Ed Tanous177612a2025-02-14 15:16:09 -0800586 dbus::utility::async_method_call(
587 asyncResp,
Ed Tanous8cb2c022024-03-27 16:31:46 -0700588 [asyncResp, payload = std::move(payload), createdObjPath,
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600589 dumpEntryPath{std::move(dumpEntryPath)},
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800590 dumpId](const boost::system::error_code& ec,
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600591 const std::string& introspectXml) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400592 if (ec)
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600593 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400594 BMCWEB_LOG_ERROR("Introspect call failed with error: {}",
595 ec.message());
596 messages::internalError(asyncResp->res);
597 return;
598 }
599
600 // Check if the created dump object has implemented Progress
601 // interface to track dump completion. If yes, fetch the "Status"
602 // property of the interface, modify the task state accordingly.
603 // Else, return task completed.
604 tinyxml2::XMLDocument doc;
605
606 doc.Parse(introspectXml.data(), introspectXml.size());
607 tinyxml2::XMLNode* pRoot = doc.FirstChildElement("node");
608 if (pRoot == nullptr)
609 {
610 BMCWEB_LOG_ERROR("XML document failed to parse");
611 messages::internalError(asyncResp->res);
612 return;
613 }
614 tinyxml2::XMLElement* interfaceNode =
615 pRoot->FirstChildElement("interface");
616
617 bool isProgressIntfPresent = false;
618 while (interfaceNode != nullptr)
619 {
620 const char* thisInterfaceName =
621 interfaceNode->Attribute("name");
622 if (thisInterfaceName != nullptr)
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600623 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400624 if (thisInterfaceName ==
625 std::string_view("xyz.openbmc_project.Common.Progress"))
626 {
627 interfaceNode =
628 interfaceNode->NextSiblingElement("interface");
629 continue;
630 }
631 isProgressIntfPresent = true;
632 break;
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600633 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400634 interfaceNode = interfaceNode->NextSiblingElement("interface");
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600635 }
636
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400637 std::shared_ptr<task::TaskData> task = task::TaskData::createTask(
638 [createdObjPath, dumpEntryPath, dumpId, isProgressIntfPresent](
639 const boost::system::error_code& ec2,
640 sdbusplus::message_t& msg,
641 const std::shared_ptr<task::TaskData>& taskData) {
642 if (ec2)
643 {
644 BMCWEB_LOG_ERROR("{}: Error in creating dump",
645 createdObjPath.str);
646 taskData->messages.emplace_back(
647 messages::internalError());
648 taskData->state = "Cancelled";
649 return task::completed;
650 }
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600651
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400652 if (isProgressIntfPresent)
653 {
654 dbus::utility::DBusPropertiesMap values;
655 std::string prop;
656 msg.read(prop, values);
657
658 DumpCreationProgress dumpStatus =
659 getDumpCompletionStatus(values);
660 if (dumpStatus ==
661 DumpCreationProgress::DUMP_CREATE_FAILED)
662 {
663 BMCWEB_LOG_ERROR("{}: Error in creating dump",
664 createdObjPath.str);
665 taskData->state = "Cancelled";
666 return task::completed;
667 }
668
669 if (dumpStatus ==
670 DumpCreationProgress::DUMP_CREATE_INPROGRESS)
671 {
672 BMCWEB_LOG_DEBUG(
673 "{}: Dump creation task is in progress",
674 createdObjPath.str);
675 return !task::completed;
676 }
677 }
678
679 nlohmann::json retMessage = messages::success();
680 taskData->messages.emplace_back(retMessage);
681
682 boost::urls::url url = boost::urls::format(
683 "/redfish/v1/Managers/{}/LogServices/Dump/Entries/{}",
684 BMCWEB_REDFISH_MANAGER_URI_NAME, dumpId);
685
686 std::string headerLoc = "Location: ";
687 headerLoc += url.buffer();
688
689 taskData->payload->httpHeaders.emplace_back(
690 std::move(headerLoc));
691
692 BMCWEB_LOG_DEBUG("{}: Dump creation task completed",
Ed Tanous62598e32023-07-17 17:06:25 -0700693 createdObjPath.str);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400694 taskData->state = "Completed";
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600695 return task::completed;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400696 },
697 "type='signal',interface='org.freedesktop.DBus.Properties',"
698 "member='PropertiesChanged',path='" +
699 createdObjPath.str + "'");
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600700
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400701 // The task timer is set to max time limit within which the
702 // requested dump will be collected.
703 task->startTimer(std::chrono::minutes(6));
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400704 task->payload.emplace(payload);
Chinmay Shripad Hegde29e2bdd2025-06-06 16:23:47 +0530705 task->populateResp(asyncResp->res);
Patrick Williams5a39f772023-10-20 11:20:21 -0500706 },
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600707 "xyz.openbmc_project.Dump.Manager", createdObjPath,
708 "org.freedesktop.DBus.Introspectable", "Introspect");
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500709}
710
zhanghch058d1b46d2021-04-01 11:18:24 +0800711inline void createDump(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
712 const crow::Request& req, const std::string& dumpType)
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500713{
Claire Weinanfdd26902022-03-01 14:18:25 -0800714 std::string dumpPath = getDumpEntriesPath(dumpType);
715 if (dumpPath.empty())
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500716 {
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500717 messages::internalError(asyncResp->res);
718 return;
719 }
720
721 std::optional<std::string> diagnosticDataType;
722 std::optional<std::string> oemDiagnosticDataType;
723
Patrick Williams504af5a2025-02-03 14:29:03 -0500724 if (!redfish::json_util::readJsonAction( //
725 req, asyncResp->res, //
726 "DiagnosticDataType", diagnosticDataType, //
Myung Baeafc474a2024-10-09 00:53:29 -0700727 "OEMDiagnosticDataType", oemDiagnosticDataType //
728 ))
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500729 {
730 return;
731 }
732
733 if (dumpType == "System")
734 {
735 if (!oemDiagnosticDataType || !diagnosticDataType)
736 {
Ed Tanous62598e32023-07-17 17:06:25 -0700737 BMCWEB_LOG_ERROR(
738 "CreateDump action parameter 'DiagnosticDataType'/'OEMDiagnosticDataType' value not found!");
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500739 messages::actionParameterMissing(
740 asyncResp->res, "CollectDiagnosticData",
741 "DiagnosticDataType & OEMDiagnosticDataType");
742 return;
743 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700744 if ((*oemDiagnosticDataType != "System") ||
745 (*diagnosticDataType != "OEM"))
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500746 {
Ed Tanous62598e32023-07-17 17:06:25 -0700747 BMCWEB_LOG_ERROR("Wrong parameter values passed");
Ed Tanousace85d62021-10-26 12:45:59 -0700748 messages::internalError(asyncResp->res);
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500749 return;
750 }
Ed Tanous253f11b2024-05-16 09:38:31 -0700751 dumpPath = std::format("/redfish/v1/Systems/{}/LogServices/Dump/",
752 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500753 }
754 else if (dumpType == "BMC")
755 {
756 if (!diagnosticDataType)
757 {
Ed Tanous62598e32023-07-17 17:06:25 -0700758 BMCWEB_LOG_ERROR(
759 "CreateDump action parameter 'DiagnosticDataType' not found!");
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500760 messages::actionParameterMissing(
761 asyncResp->res, "CollectDiagnosticData", "DiagnosticDataType");
762 return;
763 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700764 if (*diagnosticDataType != "Manager")
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500765 {
Ed Tanous62598e32023-07-17 17:06:25 -0700766 BMCWEB_LOG_ERROR(
767 "Wrong parameter value passed for 'DiagnosticDataType'");
Ed Tanousace85d62021-10-26 12:45:59 -0700768 messages::internalError(asyncResp->res);
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500769 return;
770 }
Ed Tanous253f11b2024-05-16 09:38:31 -0700771 dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/Dump/",
772 BMCWEB_REDFISH_MANAGER_URI_NAME);
Asmitha Karunanithi59075712021-10-22 01:17:41 -0500773 }
774 else
775 {
Ed Tanous62598e32023-07-17 17:06:25 -0700776 BMCWEB_LOG_ERROR("CreateDump failed. Unknown dump type");
Asmitha Karunanithi59075712021-10-22 01:17:41 -0500777 messages::internalError(asyncResp->res);
778 return;
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500779 }
780
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600781 std::vector<std::pair<std::string, std::variant<std::string, uint64_t>>>
782 createDumpParamVec;
783
Carson Labradof574a8e2023-03-22 02:26:00 +0000784 if (req.session != nullptr)
785 {
786 createDumpParamVec.emplace_back(
787 "xyz.openbmc_project.Dump.Create.CreateParameters.OriginatorId",
788 req.session->clientIp);
789 createDumpParamVec.emplace_back(
790 "xyz.openbmc_project.Dump.Create.CreateParameters.OriginatorType",
791 "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Client");
792 }
Asmitha Karunanithi68dd0752022-11-15 11:33:46 -0600793
Ed Tanous177612a2025-02-14 15:16:09 -0800794 dbus::utility::async_method_call(
795 asyncResp,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800796 [asyncResp, payload(task::Payload(req)),
797 dumpPath](const boost::system::error_code& ec,
798 const sdbusplus::message_t& msg,
799 const sdbusplus::message::object_path& objPath) mutable {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400800 if (ec)
Asmitha Karunanithi59075712021-10-22 01:17:41 -0500801 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400802 BMCWEB_LOG_ERROR("CreateDump resp_handler got error {}", ec);
803 const sd_bus_error* dbusError = msg.get_error();
804 if (dbusError == nullptr)
805 {
806 messages::internalError(asyncResp->res);
807 return;
808 }
809
810 BMCWEB_LOG_ERROR("CreateDump DBus error: {} and error msg: {}",
811 dbusError->name, dbusError->message);
812 if (std::string_view(
813 "xyz.openbmc_project.Common.Error.NotAllowed") ==
814 dbusError->name)
815 {
816 messages::resourceInStandby(asyncResp->res);
817 return;
818 }
819 if (std::string_view(
820 "xyz.openbmc_project.Dump.Create.Error.Disabled") ==
821 dbusError->name)
822 {
823 messages::serviceDisabled(asyncResp->res, dumpPath);
824 return;
825 }
826 if (std::string_view(
827 "xyz.openbmc_project.Common.Error.Unavailable") ==
828 dbusError->name)
829 {
830 messages::resourceInUse(asyncResp->res);
831 return;
832 }
833 // Other Dbus errors such as:
834 // xyz.openbmc_project.Common.Error.InvalidArgument &
835 // org.freedesktop.DBus.Error.InvalidArgs are all related to
836 // the dbus call that is made here in the bmcweb
837 // implementation and has nothing to do with the client's
838 // input in the request. Hence, returning internal error
839 // back to the client.
Asmitha Karunanithi59075712021-10-22 01:17:41 -0500840 messages::internalError(asyncResp->res);
841 return;
842 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400843 BMCWEB_LOG_DEBUG("Dump Created. Path: {}", objPath.str);
844 createDumpTaskCallback(std::move(payload), asyncResp, objPath);
845 },
Ed Tanous18f8f602023-07-18 10:07:23 -0700846 "xyz.openbmc_project.Dump.Manager", getDumpPath(dumpType),
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600847 "xyz.openbmc_project.Dump.Create", "CreateDump", createDumpParamVec);
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500848}
849
zhanghch058d1b46d2021-04-01 11:18:24 +0800850inline void clearDump(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
851 const std::string& dumpType)
Asmitha Karunanithi80319af2020-05-07 05:30:21 -0500852{
Ed Tanous177612a2025-02-14 15:16:09 -0800853 dbus::utility::async_method_call(
854 asyncResp,
Claire Weinan0d946212022-07-13 19:40:19 -0700855 [asyncResp](const boost::system::error_code& ec) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400856 if (ec)
857 {
858 BMCWEB_LOG_ERROR("clearDump resp_handler got error {}", ec);
859 messages::internalError(asyncResp->res);
860 return;
861 }
Amy Change2460462025-05-06 00:10:13 -0700862 messages::success(asyncResp->res);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400863 },
Ed Tanous18f8f602023-07-18 10:07:23 -0700864 "xyz.openbmc_project.Dump.Manager", getDumpPath(dumpType),
Claire Weinan0d946212022-07-13 19:40:19 -0700865 "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
Asmitha Karunanithi80319af2020-05-07 05:30:21 -0500866}
867
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400868inline void parseCrashdumpParameters(
869 const dbus::utility::DBusPropertiesMap& params, std::string& filename,
870 std::string& timestamp, std::string& logfile)
Johnathan Mantey043a0532020-03-10 17:15:28 -0700871{
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200872 const std::string* filenamePtr = nullptr;
873 const std::string* timestampPtr = nullptr;
874 const std::string* logfilePtr = nullptr;
875
876 const bool success = sdbusplus::unpackPropertiesNoThrow(
877 dbus_utils::UnpackErrorPrinter(), params, "Timestamp", timestampPtr,
878 "Filename", filenamePtr, "Log", logfilePtr);
879
880 if (!success)
Johnathan Mantey043a0532020-03-10 17:15:28 -0700881 {
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200882 return;
883 }
884
885 if (filenamePtr != nullptr)
886 {
887 filename = *filenamePtr;
888 }
889
890 if (timestampPtr != nullptr)
891 {
892 timestamp = *timestampPtr;
893 }
894
895 if (logfilePtr != nullptr)
896 {
897 logfile = *logfilePtr;
Johnathan Mantey043a0532020-03-10 17:15:28 -0700898 }
899}
900
Oliver Brewkaf8ae8872025-10-13 19:05:29 +0200901inline void handleSystemsLogServiceCollectionGet(
902 crow::App& app, const crow::Request& req,
903 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
904 const std::string& systemName)
Ed Tanous1da66f72018-07-27 16:13:37 -0700905{
Oliver Brewkaf8ae8872025-10-13 19:05:29 +0200906 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
907 {
908 return;
909 }
910 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
911 {
912 // Option currently returns no systems. TBD
913 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
914 systemName);
915 return;
916 }
917 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
918 {
919 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
920 systemName);
921 return;
922 }
923
924 // Collections don't include the static data added by SubRoute
925 // because it has a duplicate entry for members
926 asyncResp->res.jsonValue["@odata.type"] =
927 "#LogServiceCollection.LogServiceCollection";
928 asyncResp->res.jsonValue["@odata.id"] = std::format(
929 "/redfish/v1/Systems/{}/LogServices", BMCWEB_REDFISH_SYSTEM_URI_NAME);
930 asyncResp->res.jsonValue["Name"] = "System Log Services Collection";
931 asyncResp->res.jsonValue["Description"] =
932 "Collection of LogServices for this Computer System";
933 nlohmann::json& logServiceArray = asyncResp->res.jsonValue["Members"];
934 logServiceArray = nlohmann::json::array();
Oliver Brewka43feb5c2025-09-24 12:52:14 +0200935
936 if constexpr (BMCWEB_REDFISH_EVENTLOG_LOCATION == "systems" &&
937 !BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
938 {
939 nlohmann::json::object_t eventLog;
940 eventLog["@odata.id"] =
941 std::format("/redfish/v1/Systems/{}/LogServices/EventLog",
942 BMCWEB_REDFISH_SYSTEM_URI_NAME);
943 logServiceArray.emplace_back(std::move(eventLog));
944 }
945
Oliver Brewkaf8ae8872025-10-13 19:05:29 +0200946 if constexpr (BMCWEB_REDFISH_DUMP_LOG)
947 {
948 nlohmann::json::object_t dumpLog;
949 dumpLog["@odata.id"] =
950 std::format("/redfish/v1/Systems/{}/LogServices/Dump",
951 BMCWEB_REDFISH_SYSTEM_URI_NAME);
952 logServiceArray.emplace_back(std::move(dumpLog));
953 }
954
955 if constexpr (BMCWEB_REDFISH_CPU_LOG)
956 {
957 nlohmann::json::object_t crashdump;
958 crashdump["@odata.id"] =
959 std::format("/redfish/v1/Systems/{}/LogServices/Crashdump",
960 BMCWEB_REDFISH_SYSTEM_URI_NAME);
961 logServiceArray.emplace_back(std::move(crashdump));
962 }
963
964 if constexpr (BMCWEB_REDFISH_HOST_LOGGER)
965 {
966 nlohmann::json::object_t hostlogger;
967 hostlogger["@odata.id"] =
968 std::format("/redfish/v1/Systems/{}/LogServices/HostLogger",
969 BMCWEB_REDFISH_SYSTEM_URI_NAME);
970 logServiceArray.emplace_back(std::move(hostlogger));
971 }
972 asyncResp->res.jsonValue["Members@odata.count"] = logServiceArray.size();
973
974 constexpr std::array<std::string_view, 1> interfaces = {
975 "xyz.openbmc_project.State.Boot.PostCode"};
976 dbus::utility::getSubTreePaths(
977 "/", 0, interfaces,
978 [asyncResp](
979 const boost::system::error_code& ec,
980 const dbus::utility::MapperGetSubTreePathsResponse& subtreePath) {
981 if (ec)
Ed Tanous002d39b2022-05-31 08:59:27 -0700982 {
Oliver Brewkaf8ae8872025-10-13 19:05:29 +0200983 BMCWEB_LOG_ERROR("{}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -0700984 return;
985 }
Ed Tanous45ca1b82022-03-25 13:07:27 -0700986
Oliver Brewkaf8ae8872025-10-13 19:05:29 +0200987 for (const auto& pathStr : subtreePath)
Ed Tanous002d39b2022-05-31 08:59:27 -0700988 {
Oliver Brewkaf8ae8872025-10-13 19:05:29 +0200989 if (pathStr.find("PostCode") != std::string::npos)
990 {
991 nlohmann::json& logServiceArrayLocal =
992 asyncResp->res.jsonValue["Members"];
993 nlohmann::json::object_t member;
994 member["@odata.id"] = std::format(
995 "/redfish/v1/Systems/{}/LogServices/PostCodes",
996 BMCWEB_REDFISH_SYSTEM_URI_NAME);
997
998 logServiceArrayLocal.emplace_back(std::move(member));
999
1000 asyncResp->res.jsonValue["Members@odata.count"] =
1001 logServiceArrayLocal.size();
1002 return;
1003 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001004 }
Ed Tanous45ca1b82022-03-25 13:07:27 -07001005 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001006}
1007
Oliver Brewkaf8ae8872025-10-13 19:05:29 +02001008inline void handleManagersLogServicesCollectionGet(
Claire Weinanfdd26902022-03-01 14:18:25 -08001009 crow::App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001010 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1011 const std::string& managerId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001012{
1013 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1014 {
1015 return;
1016 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001017
1018 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1019 {
1020 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1021 return;
1022 }
1023
Claire Weinanfdd26902022-03-01 14:18:25 -08001024 // Collections don't include the static data added by SubRoute
1025 // because it has a duplicate entry for members
1026 asyncResp->res.jsonValue["@odata.type"] =
1027 "#LogServiceCollection.LogServiceCollection";
Ed Tanous253f11b2024-05-16 09:38:31 -07001028 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
1029 "/redfish/v1/Managers/{}/LogServices", BMCWEB_REDFISH_MANAGER_URI_NAME);
Claire Weinanfdd26902022-03-01 14:18:25 -08001030 asyncResp->res.jsonValue["Name"] = "Open BMC Log Services Collection";
1031 asyncResp->res.jsonValue["Description"] =
1032 "Collection of LogServices for this Manager";
1033 nlohmann::json& logServiceArray = asyncResp->res.jsonValue["Members"];
1034 logServiceArray = nlohmann::json::array();
1035
Ed Tanous25b54db2024-04-17 15:40:31 -07001036 if constexpr (BMCWEB_REDFISH_BMC_JOURNAL)
1037 {
1038 nlohmann::json::object_t journal;
Ed Tanous253f11b2024-05-16 09:38:31 -07001039 journal["@odata.id"] =
1040 boost::urls::format("/redfish/v1/Managers/{}/LogServices/Journal",
1041 BMCWEB_REDFISH_MANAGER_URI_NAME);
Ed Tanous25b54db2024-04-17 15:40:31 -07001042 logServiceArray.emplace_back(std::move(journal));
1043 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001044
Oliver Brewka43feb5c2025-09-24 12:52:14 +02001045 if constexpr (BMCWEB_REDFISH_EVENTLOG_LOCATION == "managers")
1046 {
1047 nlohmann::json::object_t eventLog;
1048 eventLog["@odata.id"] =
1049 boost::urls::format("/redfish/v1/Managers/{}/LogServices/EventLog",
1050 BMCWEB_REDFISH_MANAGER_URI_NAME);
1051 logServiceArray.emplace_back(std::move(eventLog));
1052 }
1053
Claire Weinanfdd26902022-03-01 14:18:25 -08001054 asyncResp->res.jsonValue["Members@odata.count"] = logServiceArray.size();
1055
Ed Tanous25b54db2024-04-17 15:40:31 -07001056 if constexpr (BMCWEB_REDFISH_DUMP_LOG)
1057 {
1058 constexpr std::array<std::string_view, 1> interfaces = {
1059 "xyz.openbmc_project.Collection.DeleteAll"};
1060 dbus::utility::getSubTreePaths(
1061 "/xyz/openbmc_project/dump", 0, interfaces,
1062 [asyncResp](const boost::system::error_code& ec,
1063 const dbus::utility::MapperGetSubTreePathsResponse&
1064 subTreePaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001065 if (ec)
Ed Tanous25b54db2024-04-17 15:40:31 -07001066 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001067 BMCWEB_LOG_ERROR(
Oliver Brewkaf8ae8872025-10-13 19:05:29 +02001068 "handleManagersLogServicesCollectionGet respHandler got error {}",
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001069 ec);
1070 // Assume that getting an error simply means there are no
1071 // dump LogServices. Return without adding any error
1072 // response.
1073 return;
Ed Tanous25b54db2024-04-17 15:40:31 -07001074 }
Ed Tanous25b54db2024-04-17 15:40:31 -07001075
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001076 nlohmann::json& logServiceArrayLocal =
1077 asyncResp->res.jsonValue["Members"];
1078
1079 for (const std::string& path : subTreePaths)
1080 {
1081 if (path == "/xyz/openbmc_project/dump/bmc")
1082 {
1083 nlohmann::json::object_t member;
1084 member["@odata.id"] = boost::urls::format(
1085 "/redfish/v1/Managers/{}/LogServices/Dump",
1086 BMCWEB_REDFISH_MANAGER_URI_NAME);
1087 logServiceArrayLocal.emplace_back(std::move(member));
1088 }
1089 else if (path == "/xyz/openbmc_project/dump/faultlog")
1090 {
1091 nlohmann::json::object_t member;
1092 member["@odata.id"] = boost::urls::format(
1093 "/redfish/v1/Managers/{}/LogServices/FaultLog",
1094 BMCWEB_REDFISH_MANAGER_URI_NAME);
1095 logServiceArrayLocal.emplace_back(std::move(member));
1096 }
1097 }
1098
1099 asyncResp->res.jsonValue["Members@odata.count"] =
1100 logServiceArrayLocal.size();
1101 });
Ed Tanous25b54db2024-04-17 15:40:31 -07001102 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001103}
1104
Oliver Brewkaa93a2932025-10-10 00:53:02 +02001105inline void handleSystemsEventLogServiceGet(
1106 crow::App& app, const crow::Request& req,
1107 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1108 const std::string& systemName)
1109{
1110 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1111 {
1112 return;
1113 }
1114 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1115 {
1116 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1117 systemName);
1118 return;
1119 }
1120 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1121 {
1122 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1123 systemName);
1124 return;
1125 }
1126 eventlog_utils::handleSystemsAndManagersEventLogServiceGet(
1127 asyncResp, eventlog_utils::LogServiceParent::Systems);
1128}
1129
Oliver Brewka43feb5c2025-09-24 12:52:14 +02001130inline void handleManagersEventLogServiceGet(
1131
1132 crow::App& app, const crow::Request& req,
1133 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1134 const std::string& managerId)
1135{
1136 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1137 {
1138 return;
1139 }
1140 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1141 {
1142 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1143 return;
1144 }
1145 eventlog_utils::handleSystemsAndManagersEventLogServiceGet(
1146 asyncResp, eventlog_utils::LogServiceParent::Managers);
1147}
1148
Patrick Williams504af5a2025-02-03 14:29:03 -05001149inline void getDumpServiceInfo(
1150 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1151 const std::string& dumpType)
Claire Weinanfdd26902022-03-01 14:18:25 -08001152{
1153 std::string dumpPath;
Ed Tanous539d8c62024-06-19 14:38:27 -07001154 log_service::OverWritePolicy overWritePolicy =
1155 log_service::OverWritePolicy::Invalid;
Claire Weinanfdd26902022-03-01 14:18:25 -08001156 bool collectDiagnosticDataSupported = false;
1157
1158 if (dumpType == "BMC")
1159 {
Ed Tanous253f11b2024-05-16 09:38:31 -07001160 dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/Dump",
1161 BMCWEB_REDFISH_MANAGER_URI_NAME);
Ed Tanous539d8c62024-06-19 14:38:27 -07001162 overWritePolicy = log_service::OverWritePolicy::WrapsWhenFull;
Claire Weinanfdd26902022-03-01 14:18:25 -08001163 collectDiagnosticDataSupported = true;
1164 }
1165 else if (dumpType == "FaultLog")
1166 {
Ed Tanous253f11b2024-05-16 09:38:31 -07001167 dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/FaultLog",
1168 BMCWEB_REDFISH_MANAGER_URI_NAME);
Ed Tanous539d8c62024-06-19 14:38:27 -07001169 overWritePolicy = log_service::OverWritePolicy::Unknown;
Claire Weinanfdd26902022-03-01 14:18:25 -08001170 collectDiagnosticDataSupported = false;
1171 }
1172 else if (dumpType == "System")
1173 {
Ed Tanous253f11b2024-05-16 09:38:31 -07001174 dumpPath = std::format("/redfish/v1/Systems/{}/LogServices/Dump",
1175 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanous539d8c62024-06-19 14:38:27 -07001176 overWritePolicy = log_service::OverWritePolicy::WrapsWhenFull;
Claire Weinanfdd26902022-03-01 14:18:25 -08001177 collectDiagnosticDataSupported = true;
1178 }
1179 else
1180 {
Ed Tanous62598e32023-07-17 17:06:25 -07001181 BMCWEB_LOG_ERROR("getDumpServiceInfo() invalid dump type: {}",
1182 dumpType);
Claire Weinanfdd26902022-03-01 14:18:25 -08001183 messages::internalError(asyncResp->res);
1184 return;
1185 }
1186
1187 asyncResp->res.jsonValue["@odata.id"] = dumpPath;
1188 asyncResp->res.jsonValue["@odata.type"] = "#LogService.v1_2_0.LogService";
1189 asyncResp->res.jsonValue["Name"] = "Dump LogService";
1190 asyncResp->res.jsonValue["Description"] = dumpType + " Dump LogService";
1191 asyncResp->res.jsonValue["Id"] = std::filesystem::path(dumpPath).filename();
Ed Tanous539d8c62024-06-19 14:38:27 -07001192 asyncResp->res.jsonValue["OverWritePolicy"] = overWritePolicy;
Claire Weinanfdd26902022-03-01 14:18:25 -08001193
1194 std::pair<std::string, std::string> redfishDateTimeOffset =
Ed Tanous2b829372022-08-03 14:22:34 -07001195 redfish::time_utils::getDateTimeOffsetNow();
Claire Weinanfdd26902022-03-01 14:18:25 -08001196 asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
1197 asyncResp->res.jsonValue["DateTimeLocalOffset"] =
1198 redfishDateTimeOffset.second;
1199
1200 asyncResp->res.jsonValue["Entries"]["@odata.id"] = dumpPath + "/Entries";
Claire Weinanfdd26902022-03-01 14:18:25 -08001201
1202 if (collectDiagnosticDataSupported)
1203 {
1204 asyncResp->res.jsonValue["Actions"]["#LogService.CollectDiagnosticData"]
1205 ["target"] =
1206 dumpPath + "/Actions/LogService.CollectDiagnosticData";
1207 }
Claire Weinan0d946212022-07-13 19:40:19 -07001208
Corey Ethington08fad5d2025-07-31 12:14:27 -04001209 etag_utils::setEtagOmitDateTimeHandler(asyncResp);
1210
Claire Weinan0d946212022-07-13 19:40:19 -07001211 constexpr std::array<std::string_view, 1> interfaces = {deleteAllInterface};
1212 dbus::utility::getSubTreePaths(
1213 "/xyz/openbmc_project/dump", 0, interfaces,
1214 [asyncResp, dumpType, dumpPath](
1215 const boost::system::error_code& ec,
1216 const dbus::utility::MapperGetSubTreePathsResponse& subTreePaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001217 if (ec)
Claire Weinan0d946212022-07-13 19:40:19 -07001218 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001219 BMCWEB_LOG_ERROR("getDumpServiceInfo respHandler got error {}",
1220 ec);
1221 // Assume that getting an error simply means there are no dump
1222 // LogServices. Return without adding any error response.
1223 return;
Claire Weinan0d946212022-07-13 19:40:19 -07001224 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001225 std::string dbusDumpPath = getDumpPath(dumpType);
1226 for (const std::string& path : subTreePaths)
1227 {
1228 if (path == dbusDumpPath)
1229 {
1230 asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]
1231 ["target"] =
1232 dumpPath + "/Actions/LogService.ClearLog";
1233 break;
1234 }
1235 }
1236 });
Claire Weinanfdd26902022-03-01 14:18:25 -08001237}
1238
1239inline void handleLogServicesDumpServiceGet(
1240 crow::App& app, const std::string& dumpType, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001241 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1242 const std::string& managerId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001243{
1244 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1245 {
1246 return;
1247 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001248
1249 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1250 {
1251 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1252 return;
1253 }
1254
Claire Weinanfdd26902022-03-01 14:18:25 -08001255 getDumpServiceInfo(asyncResp, dumpType);
1256}
1257
Ed Tanous22d268c2022-05-19 09:39:07 -07001258inline void handleLogServicesDumpServiceComputerSystemGet(
1259 crow::App& app, const crow::Request& req,
1260 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1261 const std::string& chassisId)
1262{
1263 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1264 {
1265 return;
1266 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001267 if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous22d268c2022-05-19 09:39:07 -07001268 {
1269 messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
1270 return;
1271 }
1272 getDumpServiceInfo(asyncResp, "System");
1273}
1274
Claire Weinanfdd26902022-03-01 14:18:25 -08001275inline void handleLogServicesDumpEntriesCollectionGet(
1276 crow::App& app, const std::string& dumpType, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001277 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1278 const std::string& managerId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001279{
1280 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1281 {
1282 return;
1283 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001284
1285 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1286 {
1287 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1288 return;
1289 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001290 getDumpEntryCollection(asyncResp, dumpType);
1291}
1292
Ed Tanous22d268c2022-05-19 09:39:07 -07001293inline void handleLogServicesDumpEntriesCollectionComputerSystemGet(
1294 crow::App& app, const crow::Request& req,
1295 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1296 const std::string& chassisId)
1297{
1298 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1299 {
1300 return;
1301 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001302 if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous22d268c2022-05-19 09:39:07 -07001303 {
1304 messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
1305 return;
1306 }
1307 getDumpEntryCollection(asyncResp, "System");
1308}
1309
Claire Weinanfdd26902022-03-01 14:18:25 -08001310inline void handleLogServicesDumpEntryGet(
1311 crow::App& app, const std::string& dumpType, const crow::Request& req,
1312 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous253f11b2024-05-16 09:38:31 -07001313 const std::string& managerId, const std::string& dumpId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001314{
1315 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1316 {
1317 return;
1318 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001319 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1320 {
1321 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1322 return;
1323 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001324 getDumpEntryById(asyncResp, dumpId, dumpType);
1325}
Carson Labrado168d1b12023-03-27 17:04:46 +00001326
Ed Tanous22d268c2022-05-19 09:39:07 -07001327inline void handleLogServicesDumpEntryComputerSystemGet(
1328 crow::App& app, const crow::Request& req,
1329 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1330 const std::string& chassisId, const std::string& dumpId)
1331{
1332 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1333 {
1334 return;
1335 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001336 if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous22d268c2022-05-19 09:39:07 -07001337 {
1338 messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
1339 return;
1340 }
1341 getDumpEntryById(asyncResp, dumpId, "System");
1342}
Claire Weinanfdd26902022-03-01 14:18:25 -08001343
1344inline void handleLogServicesDumpEntryDelete(
1345 crow::App& app, const std::string& dumpType, const crow::Request& req,
1346 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous253f11b2024-05-16 09:38:31 -07001347 const std::string& managerId, const std::string& dumpId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001348{
1349 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1350 {
1351 return;
1352 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001353
1354 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1355 {
1356 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1357 return;
1358 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001359 deleteDumpEntry(asyncResp, dumpId, dumpType);
1360}
1361
Ed Tanous22d268c2022-05-19 09:39:07 -07001362inline void handleLogServicesDumpEntryComputerSystemDelete(
1363 crow::App& app, const crow::Request& req,
1364 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1365 const std::string& chassisId, const std::string& dumpId)
1366{
1367 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1368 {
1369 return;
1370 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001371 if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous22d268c2022-05-19 09:39:07 -07001372 {
1373 messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
1374 return;
1375 }
1376 deleteDumpEntry(asyncResp, dumpId, "System");
1377}
1378
Carson Labrado168d1b12023-03-27 17:04:46 +00001379inline void handleLogServicesDumpEntryDownloadGet(
1380 crow::App& app, const std::string& dumpType, const crow::Request& req,
1381 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous253f11b2024-05-16 09:38:31 -07001382 const std::string& managerId, const std::string& dumpId)
Carson Labrado168d1b12023-03-27 17:04:46 +00001383{
1384 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1385 {
1386 return;
1387 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001388
1389 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1390 {
1391 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1392 return;
1393 }
Carson Labrado168d1b12023-03-27 17:04:46 +00001394 downloadDumpEntry(asyncResp, dumpId, dumpType);
1395}
1396
Claire Weinanfdd26902022-03-01 14:18:25 -08001397inline void handleLogServicesDumpCollectDiagnosticDataPost(
1398 crow::App& app, const std::string& dumpType, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001399 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1400 const std::string& managerId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001401{
1402 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1403 {
1404 return;
1405 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001406 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1407 {
1408 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1409 return;
1410 }
1411
Claire Weinanfdd26902022-03-01 14:18:25 -08001412 createDump(asyncResp, req, dumpType);
1413}
1414
Ed Tanous22d268c2022-05-19 09:39:07 -07001415inline void handleLogServicesDumpCollectDiagnosticDataComputerSystemPost(
1416 crow::App& app, const crow::Request& req,
1417 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001418 const std::string& systemName)
Ed Tanous22d268c2022-05-19 09:39:07 -07001419{
1420 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1421 {
1422 return;
1423 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001424
Ed Tanous25b54db2024-04-17 15:40:31 -07001425 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous22d268c2022-05-19 09:39:07 -07001426 {
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001427 // Option currently returns no systems. TBD
1428 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1429 systemName);
1430 return;
1431 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001432 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001433 {
1434 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1435 systemName);
Ed Tanous22d268c2022-05-19 09:39:07 -07001436 return;
1437 }
1438 createDump(asyncResp, req, "System");
1439}
1440
Claire Weinanfdd26902022-03-01 14:18:25 -08001441inline void handleLogServicesDumpClearLogPost(
1442 crow::App& app, const std::string& dumpType, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001443 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1444 const std::string& managerId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001445{
1446 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1447 {
1448 return;
1449 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001450
1451 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1452 {
1453 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1454 return;
1455 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001456 clearDump(asyncResp, dumpType);
1457}
1458
Ed Tanous22d268c2022-05-19 09:39:07 -07001459inline void handleLogServicesDumpClearLogComputerSystemPost(
1460 crow::App& app, const crow::Request& req,
1461 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001462 const std::string& systemName)
Ed Tanous22d268c2022-05-19 09:39:07 -07001463{
1464 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1465 {
1466 return;
1467 }
Ed Tanous25b54db2024-04-17 15:40:31 -07001468 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous22d268c2022-05-19 09:39:07 -07001469 {
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001470 // Option currently returns no systems. TBD
1471 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1472 systemName);
1473 return;
1474 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001475 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001476 {
1477 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1478 systemName);
Ed Tanous22d268c2022-05-19 09:39:07 -07001479 return;
1480 }
1481 clearDump(asyncResp, "System");
1482}
1483
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001484inline void requestRoutesBMCDumpService(App& app)
1485{
Ed Tanous253f11b2024-05-16 09:38:31 -07001486 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/Dump/")
Ed Tanoused398212021-06-09 17:05:54 -07001487 .privileges(redfish::privileges::getLogService)
Claire Weinanfdd26902022-03-01 14:18:25 -08001488 .methods(boost::beast::http::verb::get)(std::bind_front(
1489 handleLogServicesDumpServiceGet, std::ref(app), "BMC"));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001490}
1491
1492inline void requestRoutesBMCDumpEntryCollection(App& app)
1493{
Ed Tanous253f11b2024-05-16 09:38:31 -07001494 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/")
Ed Tanoused398212021-06-09 17:05:54 -07001495 .privileges(redfish::privileges::getLogEntryCollection)
Claire Weinanfdd26902022-03-01 14:18:25 -08001496 .methods(boost::beast::http::verb::get)(std::bind_front(
1497 handleLogServicesDumpEntriesCollectionGet, std::ref(app), "BMC"));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001498}
1499
1500inline void requestRoutesBMCDumpEntry(App& app)
1501{
1502 BMCWEB_ROUTE(app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001503 "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001504 .privileges(redfish::privileges::getLogEntry)
Claire Weinanfdd26902022-03-01 14:18:25 -08001505 .methods(boost::beast::http::verb::get)(std::bind_front(
1506 handleLogServicesDumpEntryGet, std::ref(app), "BMC"));
1507
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001508 BMCWEB_ROUTE(app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001509 "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001510 .privileges(redfish::privileges::deleteLogEntry)
Claire Weinanfdd26902022-03-01 14:18:25 -08001511 .methods(boost::beast::http::verb::delete_)(std::bind_front(
1512 handleLogServicesDumpEntryDelete, std::ref(app), "BMC"));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001513}
1514
Carson Labrado168d1b12023-03-27 17:04:46 +00001515inline void requestRoutesBMCDumpEntryDownload(App& app)
1516{
1517 BMCWEB_ROUTE(
1518 app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001519 "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/<str>/attachment/")
Carson Labrado168d1b12023-03-27 17:04:46 +00001520 .privileges(redfish::privileges::getLogEntry)
1521 .methods(boost::beast::http::verb::get)(std::bind_front(
1522 handleLogServicesDumpEntryDownloadGet, std::ref(app), "BMC"));
1523}
1524
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001525inline void requestRoutesBMCDumpCreate(App& app)
1526{
George Liu0fda0f12021-11-16 10:06:17 +08001527 BMCWEB_ROUTE(
1528 app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001529 "/redfish/v1/Managers/<str>/LogServices/Dump/Actions/LogService.CollectDiagnosticData/")
Ed Tanoused398212021-06-09 17:05:54 -07001530 .privileges(redfish::privileges::postLogService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001531 .methods(boost::beast::http::verb::post)(
Claire Weinanfdd26902022-03-01 14:18:25 -08001532 std::bind_front(handleLogServicesDumpCollectDiagnosticDataPost,
1533 std::ref(app), "BMC"));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001534}
1535
1536inline void requestRoutesBMCDumpClear(App& app)
1537{
George Liu0fda0f12021-11-16 10:06:17 +08001538 BMCWEB_ROUTE(
1539 app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001540 "/redfish/v1/Managers/<str>/LogServices/Dump/Actions/LogService.ClearLog/")
Ed Tanoused398212021-06-09 17:05:54 -07001541 .privileges(redfish::privileges::postLogService)
Claire Weinanfdd26902022-03-01 14:18:25 -08001542 .methods(boost::beast::http::verb::post)(std::bind_front(
1543 handleLogServicesDumpClearLogPost, std::ref(app), "BMC"));
1544}
1545
1546inline void requestRoutesFaultLogDumpService(App& app)
1547{
Ed Tanous253f11b2024-05-16 09:38:31 -07001548 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/FaultLog/")
Claire Weinanfdd26902022-03-01 14:18:25 -08001549 .privileges(redfish::privileges::getLogService)
1550 .methods(boost::beast::http::verb::get)(std::bind_front(
1551 handleLogServicesDumpServiceGet, std::ref(app), "FaultLog"));
1552}
1553
1554inline void requestRoutesFaultLogDumpEntryCollection(App& app)
1555{
Ed Tanous253f11b2024-05-16 09:38:31 -07001556 BMCWEB_ROUTE(app,
1557 "/redfish/v1/Managers/<str>/LogServices/FaultLog/Entries/")
Claire Weinanfdd26902022-03-01 14:18:25 -08001558 .privileges(redfish::privileges::getLogEntryCollection)
1559 .methods(boost::beast::http::verb::get)(
1560 std::bind_front(handleLogServicesDumpEntriesCollectionGet,
1561 std::ref(app), "FaultLog"));
1562}
1563
1564inline void requestRoutesFaultLogDumpEntry(App& app)
1565{
Ed Tanous253f11b2024-05-16 09:38:31 -07001566 BMCWEB_ROUTE(
1567 app, "/redfish/v1/Managers/<str>/LogServices/FaultLog/Entries/<str>/")
Claire Weinanfdd26902022-03-01 14:18:25 -08001568 .privileges(redfish::privileges::getLogEntry)
1569 .methods(boost::beast::http::verb::get)(std::bind_front(
1570 handleLogServicesDumpEntryGet, std::ref(app), "FaultLog"));
1571
Ed Tanous253f11b2024-05-16 09:38:31 -07001572 BMCWEB_ROUTE(
1573 app, "/redfish/v1/Managers/<str>/LogServices/FaultLog/Entries/<str>/")
Claire Weinanfdd26902022-03-01 14:18:25 -08001574 .privileges(redfish::privileges::deleteLogEntry)
1575 .methods(boost::beast::http::verb::delete_)(std::bind_front(
1576 handleLogServicesDumpEntryDelete, std::ref(app), "FaultLog"));
1577}
1578
1579inline void requestRoutesFaultLogDumpClear(App& app)
1580{
1581 BMCWEB_ROUTE(
1582 app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001583 "/redfish/v1/Managers/<str>/LogServices/FaultLog/Actions/LogService.ClearLog/")
Claire Weinanfdd26902022-03-01 14:18:25 -08001584 .privileges(redfish::privileges::postLogService)
1585 .methods(boost::beast::http::verb::post)(std::bind_front(
1586 handleLogServicesDumpClearLogPost, std::ref(app), "FaultLog"));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001587}
1588
1589inline void requestRoutesSystemDumpService(App& app)
1590{
Ed Tanous22d268c2022-05-19 09:39:07 -07001591 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Dump/")
Ed Tanoused398212021-06-09 17:05:54 -07001592 .privileges(redfish::privileges::getLogService)
Claire Weinan6ab9ad52022-08-12 18:20:17 -07001593 .methods(boost::beast::http::verb::get)(std::bind_front(
Ed Tanous22d268c2022-05-19 09:39:07 -07001594 handleLogServicesDumpServiceComputerSystemGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001595}
1596
1597inline void requestRoutesSystemDumpEntryCollection(App& app)
1598{
Ed Tanous22d268c2022-05-19 09:39:07 -07001599 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/")
Ed Tanoused398212021-06-09 17:05:54 -07001600 .privileges(redfish::privileges::getLogEntryCollection)
Ed Tanous22d268c2022-05-19 09:39:07 -07001601 .methods(boost::beast::http::verb::get)(std::bind_front(
1602 handleLogServicesDumpEntriesCollectionComputerSystemGet,
1603 std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001604}
1605
1606inline void requestRoutesSystemDumpEntry(App& app)
1607{
1608 BMCWEB_ROUTE(app,
Ed Tanous22d268c2022-05-19 09:39:07 -07001609 "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001610 .privileges(redfish::privileges::getLogEntry)
Claire Weinan6ab9ad52022-08-12 18:20:17 -07001611 .methods(boost::beast::http::verb::get)(std::bind_front(
Ed Tanous22d268c2022-05-19 09:39:07 -07001612 handleLogServicesDumpEntryComputerSystemGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001613
1614 BMCWEB_ROUTE(app,
Ed Tanous22d268c2022-05-19 09:39:07 -07001615 "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001616 .privileges(redfish::privileges::deleteLogEntry)
Claire Weinan6ab9ad52022-08-12 18:20:17 -07001617 .methods(boost::beast::http::verb::delete_)(std::bind_front(
Ed Tanous22d268c2022-05-19 09:39:07 -07001618 handleLogServicesDumpEntryComputerSystemDelete, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001619}
1620
1621inline void requestRoutesSystemDumpCreate(App& app)
1622{
George Liu0fda0f12021-11-16 10:06:17 +08001623 BMCWEB_ROUTE(
1624 app,
Ed Tanous22d268c2022-05-19 09:39:07 -07001625 "/redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.CollectDiagnosticData/")
Abhishek Patelfff6a4d2021-07-21 11:29:45 -05001626 .privileges(redfish::privileges::
1627 postLogServiceSubOverComputerSystemLogServiceCollection)
Ed Tanous22d268c2022-05-19 09:39:07 -07001628 .methods(boost::beast::http::verb::post)(std::bind_front(
1629 handleLogServicesDumpCollectDiagnosticDataComputerSystemPost,
1630 std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001631}
1632
1633inline void requestRoutesSystemDumpClear(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.ClearLog/")
Abhishek Patelfff6a4d2021-07-21 11:29:45 -05001638 .privileges(redfish::privileges::
1639 postLogServiceSubOverComputerSystemLogServiceCollection)
Claire Weinan6ab9ad52022-08-12 18:20:17 -07001640 .methods(boost::beast::http::verb::post)(std::bind_front(
Ed Tanous22d268c2022-05-19 09:39:07 -07001641 handleLogServicesDumpClearLogComputerSystemPost, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001642}
1643
1644inline void requestRoutesCrashdumpService(App& app)
1645{
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001646 /**
1647 * Functions triggers appropriate requests on DBus
1648 */
Ed Tanous22d268c2022-05-19 09:39:07 -07001649 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Crashdump/")
Myung Bae50d9f382025-06-13 09:40:18 -04001650 .privileges(redfish::privileges::getLogService)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001651 .methods(
1652 boost::beast::http::verb::
1653 get)([&app](const crow::Request& req,
1654 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1655 const std::string& systemName) {
1656 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1657 {
1658 return;
1659 }
1660 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1661 {
1662 // Option currently returns no systems. TBD
1663 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1664 systemName);
1665 return;
1666 }
1667 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1668 {
1669 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1670 systemName);
1671 return;
1672 }
Ed Tanous22d268c2022-05-19 09:39:07 -07001673
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001674 // Copy over the static data to include the entries added by
1675 // SubRoute
1676 asyncResp->res.jsonValue["@odata.id"] =
1677 std::format("/redfish/v1/Systems/{}/LogServices/Crashdump",
1678 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1679 asyncResp->res.jsonValue["@odata.type"] =
1680 "#LogService.v1_2_0.LogService";
1681 asyncResp->res.jsonValue["Name"] = "Open BMC Oem Crashdump Service";
1682 asyncResp->res.jsonValue["Description"] = "Oem Crashdump Service";
1683 asyncResp->res.jsonValue["Id"] = "Crashdump";
1684 asyncResp->res.jsonValue["OverWritePolicy"] =
1685 log_service::OverWritePolicy::WrapsWhenFull;
1686 asyncResp->res.jsonValue["MaxNumberOfRecords"] = 3;
Tejas Patil7c8c4052021-06-04 17:43:14 +05301687
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001688 std::pair<std::string, std::string> redfishDateTimeOffset =
1689 redfish::time_utils::getDateTimeOffsetNow();
1690 asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
1691 asyncResp->res.jsonValue["DateTimeLocalOffset"] =
1692 redfishDateTimeOffset.second;
Tejas Patil7c8c4052021-06-04 17:43:14 +05301693
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001694 asyncResp->res.jsonValue["Entries"]["@odata.id"] = std::format(
1695 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries",
1696 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1697 asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]
1698 ["target"] = std::format(
1699 "/redfish/v1/Systems/{}/LogServices/Crashdump/Actions/LogService.ClearLog",
1700 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1701 asyncResp->res
1702 .jsonValue["Actions"]["#LogService.CollectDiagnosticData"]
1703 ["target"] = std::format(
1704 "/redfish/v1/Systems/{}/LogServices/Crashdump/Actions/LogService.CollectDiagnosticData",
1705 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Corey Ethington08fad5d2025-07-31 12:14:27 -04001706
1707 etag_utils::setEtagOmitDateTimeHandler(asyncResp);
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001708 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001709}
1710
Ed Tanous8e4736b2025-08-19 10:14:02 -07001711inline void requestRoutesCrashdumpClear(App& app)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001712{
George Liu0fda0f12021-11-16 10:06:17 +08001713 BMCWEB_ROUTE(
1714 app,
Ed Tanous22d268c2022-05-19 09:39:07 -07001715 "/redfish/v1/Systems/<str>/LogServices/Crashdump/Actions/LogService.ClearLog/")
Myung Bae50d9f382025-06-13 09:40:18 -04001716 .privileges(redfish::privileges::
1717 postLogServiceSubOverComputerSystemLogServiceCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001718 .methods(boost::beast::http::verb::post)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07001719 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07001720 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1721 const std::string& systemName) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001722 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1723 {
1724 return;
1725 }
1726 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1727 {
1728 // Option currently returns no systems. TBD
1729 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1730 systemName);
1731 return;
1732 }
1733 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1734 {
1735 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1736 systemName);
1737 return;
1738 }
Ed Tanous177612a2025-02-14 15:16:09 -08001739 dbus::utility::async_method_call(
1740 asyncResp,
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001741 [asyncResp](const boost::system::error_code& ec,
1742 const std::string&) {
1743 if (ec)
1744 {
1745 messages::internalError(asyncResp->res);
1746 return;
1747 }
1748 messages::success(asyncResp->res);
1749 },
1750 crashdumpObject, crashdumpPath, deleteAllInterface,
1751 "DeleteAll");
1752 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001753}
Jason M. Bills5b61b5e2019-10-16 10:59:02 -07001754
Patrick Williams504af5a2025-02-03 14:29:03 -05001755inline void logCrashdumpEntry(
1756 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1757 const std::string& logID, nlohmann::json& logEntryJson)
Jason M. Billse855dd22019-10-08 11:37:48 -07001758{
Johnathan Mantey043a0532020-03-10 17:15:28 -07001759 auto getStoredLogCallback =
Ed Tanousb9d36b42022-02-26 21:42:46 -08001760 [asyncResp, logID,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001761 &logEntryJson](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001762 const dbus::utility::DBusPropertiesMap& params) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001763 if (ec)
1764 {
1765 BMCWEB_LOG_DEBUG("failed to get log ec: {}", ec.message());
1766 if (ec.value() ==
1767 boost::system::linux_error::bad_request_descriptor)
1768 {
1769 messages::resourceNotFound(asyncResp->res, "LogEntry",
1770 logID);
1771 }
1772 else
1773 {
1774 messages::internalError(asyncResp->res);
1775 }
1776 return;
1777 }
1778
1779 std::string timestamp{};
1780 std::string filename{};
1781 std::string logfile{};
1782 parseCrashdumpParameters(params, filename, timestamp, logfile);
1783
1784 if (filename.empty() || timestamp.empty())
Jason M. Bills1ddcf012019-11-26 14:59:21 -08001785 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001786 messages::resourceNotFound(asyncResp->res, "LogEntry", logID);
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001787 return;
1788 }
1789
1790 std::string crashdumpURI =
1791 std::format(
1792 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries/",
1793 BMCWEB_REDFISH_SYSTEM_URI_NAME) +
1794 logID + "/" + filename;
1795 nlohmann::json::object_t logEntry;
1796 logEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
1797 logEntry["@odata.id"] = boost::urls::format(
1798 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries/{}",
1799 BMCWEB_REDFISH_SYSTEM_URI_NAME, logID);
1800 logEntry["Name"] = "CPU Crashdump";
1801 logEntry["Id"] = logID;
1802 logEntry["EntryType"] = log_entry::LogEntryType::Oem;
1803 logEntry["AdditionalDataURI"] = std::move(crashdumpURI);
1804 logEntry["DiagnosticDataType"] = "OEM";
1805 logEntry["OEMDiagnosticDataType"] = "PECICrashdump";
1806 logEntry["Created"] = std::move(timestamp);
1807
1808 // If logEntryJson references an array of LogEntry resources
1809 // ('Members' list), then push this as a new entry, otherwise set it
1810 // directly
1811 if (logEntryJson.is_array())
1812 {
1813 logEntryJson.push_back(logEntry);
1814 asyncResp->res.jsonValue["Members@odata.count"] =
1815 logEntryJson.size();
Jason M. Bills2b20ef62022-01-06 15:48:07 -08001816 }
1817 else
1818 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001819 logEntryJson.update(logEntry);
Jason M. Bills2b20ef62022-01-06 15:48:07 -08001820 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001821 };
Ed Tanousdeae6a72024-11-11 21:58:57 -08001822 dbus::utility::getAllProperties(
1823 crashdumpObject, crashdumpPath + std::string("/") + logID,
1824 crashdumpInterface, std::move(getStoredLogCallback));
Jason M. Billse855dd22019-10-08 11:37:48 -07001825}
1826
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001827inline void requestRoutesCrashdumpEntryCollection(App& app)
Ed Tanous1da66f72018-07-27 16:13:37 -07001828{
Ed Tanous1da66f72018-07-27 16:13:37 -07001829 /**
1830 * Functions triggers appropriate requests on DBus
1831 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001832 BMCWEB_ROUTE(app,
Ed Tanous22d268c2022-05-19 09:39:07 -07001833 "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/")
Myung Bae50d9f382025-06-13 09:40:18 -04001834 .privileges(redfish::privileges::getLogEntryCollection)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001835 .methods(
1836 boost::beast::http::verb::
1837 get)([&app](const crow::Request& req,
1838 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1839 const std::string& systemName) {
1840 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous45ca1b82022-03-25 13:07:27 -07001841 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001842 return;
Ed Tanous45ca1b82022-03-25 13:07:27 -07001843 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001844 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous002d39b2022-05-31 08:59:27 -07001845 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001846 // Option currently returns no systems. TBD
1847 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1848 systemName);
1849 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07001850 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001851 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1852 {
1853 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1854 systemName);
1855 return;
1856 }
1857
1858 constexpr std::array<std::string_view, 1> interfaces = {
1859 crashdumpInterface};
1860 dbus::utility::getSubTreePaths(
1861 "/", 0, interfaces,
1862 [asyncResp](const boost::system::error_code& ec,
1863 const std::vector<std::string>& resp) {
1864 if (ec)
1865 {
1866 if (ec.value() !=
1867 boost::system::errc::no_such_file_or_directory)
1868 {
1869 BMCWEB_LOG_DEBUG("failed to get entries ec: {}",
1870 ec.message());
1871 messages::internalError(asyncResp->res);
1872 return;
1873 }
1874 }
1875 asyncResp->res.jsonValue["@odata.type"] =
1876 "#LogEntryCollection.LogEntryCollection";
1877 asyncResp->res.jsonValue["@odata.id"] = std::format(
1878 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries",
1879 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1880 asyncResp->res.jsonValue["Name"] =
1881 "Open BMC Crashdump Entries";
1882 asyncResp->res.jsonValue["Description"] =
1883 "Collection of Crashdump Entries";
1884 asyncResp->res.jsonValue["Members"] =
1885 nlohmann::json::array();
1886 asyncResp->res.jsonValue["Members@odata.count"] = 0;
1887
1888 for (const std::string& path : resp)
1889 {
1890 const sdbusplus::message::object_path objPath(path);
1891 // Get the log ID
1892 std::string logID = objPath.filename();
1893 if (logID.empty())
1894 {
1895 continue;
1896 }
1897 // Add the log entry to the array
1898 logCrashdumpEntry(asyncResp, logID,
1899 asyncResp->res.jsonValue["Members"]);
1900 }
1901 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001902 });
1903}
Ed Tanous1da66f72018-07-27 16:13:37 -07001904
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001905inline void requestRoutesCrashdumpEntry(App& app)
Ed Tanous1da66f72018-07-27 16:13:37 -07001906{
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001907 BMCWEB_ROUTE(
Ed Tanous22d268c2022-05-19 09:39:07 -07001908 app, "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/<str>/")
Myung Bae50d9f382025-06-13 09:40:18 -04001909 .privileges(redfish::privileges::getLogEntry)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001910 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07001911 [&app](const crow::Request& req,
1912 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous22d268c2022-05-19 09:39:07 -07001913 const std::string& systemName, const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001914 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1915 {
1916 return;
1917 }
1918 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1919 {
1920 // Option currently returns no systems. TBD
1921 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1922 systemName);
1923 return;
1924 }
1925 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1926 {
1927 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1928 systemName);
1929 return;
1930 }
1931 const std::string& logID = param;
1932 logCrashdumpEntry(asyncResp, logID, asyncResp->res.jsonValue);
1933 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001934}
Ed Tanous1da66f72018-07-27 16:13:37 -07001935
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001936inline void requestRoutesCrashdumpFile(App& app)
1937{
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001938 BMCWEB_ROUTE(
1939 app,
Ed Tanous22d268c2022-05-19 09:39:07 -07001940 "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/<str>/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001941 .privileges(redfish::privileges::getLogEntry)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001942 .methods(boost::beast::http::verb::get)(
Nan Zhoua4ce1142022-08-02 18:45:25 +00001943 [](const crow::Request& req,
1944 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous22d268c2022-05-19 09:39:07 -07001945 const std::string& systemName, const std::string& logID,
1946 const std::string& fileName) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001947 // Do not call getRedfishRoute here since the crashdump file is
1948 // not a Redfish resource.
Ed Tanous22d268c2022-05-19 09:39:07 -07001949
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001950 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1951 {
1952 // Option currently returns no systems. TBD
1953 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1954 systemName);
1955 return;
1956 }
1957 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1958 {
1959 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1960 systemName);
1961 return;
1962 }
Ed Tanous22d268c2022-05-19 09:39:07 -07001963
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001964 auto getStoredLogCallback =
1965 [asyncResp, logID, fileName,
1966 url(boost::urls::url(req.url()))](
1967 const boost::system::error_code& ec,
1968 const std::vector<std::pair<
1969 std::string, dbus::utility::DbusVariantType>>&
1970 resp) {
1971 if (ec)
1972 {
1973 BMCWEB_LOG_DEBUG("failed to get log ec: {}",
1974 ec.message());
1975 messages::internalError(asyncResp->res);
1976 return;
1977 }
Jason M. Bills8e6c0992021-03-11 16:26:53 -08001978
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001979 std::string dbusFilename{};
1980 std::string dbusTimestamp{};
1981 std::string dbusFilepath{};
Jason M. Bills8e6c0992021-03-11 16:26:53 -08001982
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001983 parseCrashdumpParameters(resp, dbusFilename,
1984 dbusTimestamp, dbusFilepath);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001985
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001986 if (dbusFilename.empty() || dbusTimestamp.empty() ||
1987 dbusFilepath.empty())
1988 {
1989 messages::resourceNotFound(asyncResp->res,
1990 "LogEntry", logID);
1991 return;
1992 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001993
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001994 // Verify the file name parameter is correct
1995 if (fileName != dbusFilename)
1996 {
1997 messages::resourceNotFound(asyncResp->res,
1998 "LogEntry", logID);
1999 return;
2000 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002001
Myung Baed51c61b2024-09-13 10:35:34 -05002002 if (asyncResp->res.openFile(dbusFilepath) !=
2003 crow::OpenCode::Success)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002004 {
2005 messages::resourceNotFound(asyncResp->res,
2006 "LogEntry", logID);
2007 return;
2008 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002009
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002010 // Configure this to be a file download when accessed
2011 // from a browser
2012 asyncResp->res.addHeader(
2013 boost::beast::http::field::content_disposition,
2014 "attachment");
2015 };
Ed Tanousdeae6a72024-11-11 21:58:57 -08002016 dbus::utility::getAllProperties(
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002017 *crow::connections::systemBus, crashdumpObject,
2018 crashdumpPath + std::string("/") + logID,
2019 crashdumpInterface, std::move(getStoredLogCallback));
2020 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002021}
2022
Jason M. Billsc5a4c822022-01-06 15:51:23 -08002023enum class OEMDiagnosticType
2024{
2025 onDemand,
2026 telemetry,
2027 invalid,
2028};
2029
Ed Tanous26ccae32023-02-16 10:28:44 -08002030inline OEMDiagnosticType getOEMDiagnosticType(std::string_view oemDiagStr)
Jason M. Billsc5a4c822022-01-06 15:51:23 -08002031{
2032 if (oemDiagStr == "OnDemand")
2033 {
2034 return OEMDiagnosticType::onDemand;
2035 }
2036 if (oemDiagStr == "Telemetry")
2037 {
2038 return OEMDiagnosticType::telemetry;
2039 }
2040
2041 return OEMDiagnosticType::invalid;
2042}
2043
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002044inline void requestRoutesCrashdumpCollect(App& app)
2045{
George Liu0fda0f12021-11-16 10:06:17 +08002046 BMCWEB_ROUTE(
2047 app,
Ed Tanous22d268c2022-05-19 09:39:07 -07002048 "/redfish/v1/Systems/<str>/LogServices/Crashdump/Actions/LogService.CollectDiagnosticData/")
Myung Bae50d9f382025-06-13 09:40:18 -04002049 .privileges(redfish::privileges::
2050 postLogServiceSubOverComputerSystemLogServiceCollection)
Ed Tanous002d39b2022-05-31 08:59:27 -07002051 .methods(boost::beast::http::verb::post)(
2052 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07002053 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2054 const std::string& systemName) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002055 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07002056 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002057 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002058 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002059
2060 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous002d39b2022-05-31 08:59:27 -07002061 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002062 // Option currently returns no systems. TBD
2063 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2064 systemName);
2065 return;
2066 }
2067 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2068 {
2069 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2070 systemName);
2071 return;
2072 }
2073
2074 std::string diagnosticDataType;
2075 std::string oemDiagnosticDataType;
Patrick Williams504af5a2025-02-03 14:29:03 -05002076 if (!redfish::json_util::readJsonAction( //
2077 req, asyncResp->res, //
2078 "DiagnosticDataType", diagnosticDataType, //
Myung Baeafc474a2024-10-09 00:53:29 -07002079 "OEMDiagnosticDataType", oemDiagnosticDataType //
2080 ))
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002081 {
2082 return;
2083 }
2084
2085 if (diagnosticDataType != "OEM")
2086 {
2087 BMCWEB_LOG_ERROR(
2088 "Only OEM DiagnosticDataType supported for Crashdump");
2089 messages::actionParameterValueFormatError(
2090 asyncResp->res, diagnosticDataType,
2091 "DiagnosticDataType", "CollectDiagnosticData");
2092 return;
2093 }
2094
2095 OEMDiagnosticType oemDiagType =
2096 getOEMDiagnosticType(oemDiagnosticDataType);
2097
2098 std::string iface;
2099 std::string method;
2100 std::string taskMatchStr;
2101 if (oemDiagType == OEMDiagnosticType::onDemand)
2102 {
2103 iface = crashdumpOnDemandInterface;
2104 method = "GenerateOnDemandLog";
2105 taskMatchStr =
2106 "type='signal',"
2107 "interface='org.freedesktop.DBus.Properties',"
2108 "member='PropertiesChanged',"
2109 "arg0namespace='com.intel.crashdump'";
2110 }
2111 else if (oemDiagType == OEMDiagnosticType::telemetry)
2112 {
2113 iface = crashdumpTelemetryInterface;
2114 method = "GenerateTelemetryLog";
2115 taskMatchStr =
2116 "type='signal',"
2117 "interface='org.freedesktop.DBus.Properties',"
2118 "member='PropertiesChanged',"
2119 "arg0namespace='com.intel.crashdump'";
Ed Tanous002d39b2022-05-31 08:59:27 -07002120 }
2121 else
2122 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002123 BMCWEB_LOG_ERROR("Unsupported OEMDiagnosticDataType: {}",
2124 oemDiagnosticDataType);
2125 messages::actionParameterValueFormatError(
2126 asyncResp->res, oemDiagnosticDataType,
2127 "OEMDiagnosticDataType", "CollectDiagnosticData");
2128 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002129 }
Ed Tanous1da66f72018-07-27 16:13:37 -07002130
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002131 auto collectCrashdumpCallback =
2132 [asyncResp, payload(task::Payload(req)),
2133 taskMatchStr](const boost::system::error_code& ec,
2134 const std::string&) mutable {
2135 if (ec)
2136 {
2137 if (ec.value() ==
2138 boost::system::errc::operation_not_supported)
2139 {
2140 messages::resourceInStandby(asyncResp->res);
2141 }
2142 else if (ec.value() == boost::system::errc::
2143 device_or_resource_busy)
2144 {
2145 messages::serviceTemporarilyUnavailable(
2146 asyncResp->res, "60");
2147 }
2148 else
2149 {
2150 messages::internalError(asyncResp->res);
2151 }
2152 return;
2153 }
2154 std::shared_ptr<task::TaskData> task =
2155 task::TaskData::createTask(
2156 [](const boost::system::error_code& ec2,
2157 sdbusplus::message_t&,
2158 const std::shared_ptr<task::TaskData>&
2159 taskData) {
2160 if (!ec2)
2161 {
2162 taskData->messages.emplace_back(
2163 messages::taskCompletedOK(
2164 std::to_string(
2165 taskData->index)));
2166 taskData->state = "Completed";
2167 }
2168 return task::completed;
2169 },
2170 taskMatchStr);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002171
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002172 task->startTimer(std::chrono::minutes(5));
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002173 task->payload.emplace(std::move(payload));
Chinmay Shripad Hegde29e2bdd2025-06-06 16:23:47 +05302174 task->populateResp(asyncResp->res);
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002175 };
2176
Ed Tanous177612a2025-02-14 15:16:09 -08002177 dbus::utility::async_method_call(
2178 asyncResp, std::move(collectCrashdumpCallback),
2179 crashdumpObject, crashdumpPath, iface, method);
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002180 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002181}
Oliver Brewkaa93a2932025-10-10 00:53:02 +02002182
Oliver Brewkaf8ae8872025-10-13 19:05:29 +02002183inline void requestRoutesSystemsLogServiceCollection(App& app)
2184{
2185 /**
2186 * Functions triggers appropriate requests on DBus
2187 */
2188 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/")
2189 .privileges(redfish::privileges::getLogServiceCollection)
2190 .methods(boost::beast::http::verb::get)(std::bind_front(
2191 handleSystemsLogServiceCollectionGet, std::ref(app)));
2192}
2193
2194inline void requestRoutesManagersLogServiceCollection(App& app)
2195{
2196 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/")
2197 .privileges(redfish::privileges::getLogServiceCollection)
2198 .methods(boost::beast::http::verb::get)(std::bind_front(
2199 handleManagersLogServicesCollectionGet, std::ref(app)));
2200}
2201
Oliver Brewkaa93a2932025-10-10 00:53:02 +02002202inline void requestRoutesSystemsEventLogService(App& app)
2203{
2204 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/")
2205 .privileges(redfish::privileges::getLogService)
2206 .methods(boost::beast::http::verb::get)(
2207 std::bind_front(handleSystemsEventLogServiceGet, std::ref(app)));
2208}
2209
Oliver Brewka43feb5c2025-09-24 12:52:14 +02002210inline void requestRoutesManagersEventLogService(App& app)
2211{
2212 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/EventLog/")
2213 .privileges(redfish::privileges::getLogService)
2214 .methods(boost::beast::http::verb::get)(
2215 std::bind_front(handleManagersEventLogServiceGet, std::ref(app)));
2216}
Ed Tanous1da66f72018-07-27 16:13:37 -07002217} // namespace redfish