blob: ecb8272eedf94f051b423c300cc4980d466dd4ee [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
3// SPDX-FileCopyrightText: Copyright 2018 Intel Corporation
Ed Tanous1da66f72018-07-27 16:13:37 -07004#pragma once
5
Ed Tanousd7857202025-01-28 15:32:26 -08006#include "bmcweb_config.h"
7
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08008#include "app.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -08009#include "async_resp.hpp"
10#include "dbus_singleton.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080011#include "dbus_utility.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080012#include "error_messages.hpp"
Asmitha Karunanithi68dd0752022-11-15 11:33:46 -060013#include "generated/enums/log_entry.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -070014#include "generated/enums/log_service.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080015#include "http_body.hpp"
16#include "http_request.hpp"
17#include "http_response.hpp"
George Liu647b3cd2021-07-05 12:43:56 +080018#include "http_utility.hpp"
Spencer Kub7028eb2021-10-26 15:27:35 +080019#include "human_sort.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080020#include "logging.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080021#include "query.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080022#include "registries/privilege_registry.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080023#include "str_utility.hpp"
James Feist46229572020-02-19 15:11:58 -080024#include "task.hpp"
Ed Tanous5b904292024-04-16 11:10:17 -070025#include "task_messages.hpp"
Alexander Hansen262dcc12024-09-19 12:04:03 +020026#include "utils/dbus_event_log_entry.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080027#include "utils/dbus_utils.hpp"
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
Gunnar Mills1214b7e2020-06-04 10:11:30 -050085inline std::string translateSeverityDbusToRedfish(const std::string& s)
Andrew Geisslercb92c032018-08-17 07:56:14 -070086{
Ed Tanousd4d25792020-09-29 15:15:03 -070087 if ((s == "xyz.openbmc_project.Logging.Entry.Level.Alert") ||
88 (s == "xyz.openbmc_project.Logging.Entry.Level.Critical") ||
89 (s == "xyz.openbmc_project.Logging.Entry.Level.Emergency") ||
90 (s == "xyz.openbmc_project.Logging.Entry.Level.Error"))
Andrew Geisslercb92c032018-08-17 07:56:14 -070091 {
92 return "Critical";
93 }
Ed Tanous3174e4d2020-10-07 11:41:22 -070094 if ((s == "xyz.openbmc_project.Logging.Entry.Level.Debug") ||
95 (s == "xyz.openbmc_project.Logging.Entry.Level.Informational") ||
96 (s == "xyz.openbmc_project.Logging.Entry.Level.Notice"))
Andrew Geisslercb92c032018-08-17 07:56:14 -070097 {
98 return "OK";
99 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700100 if (s == "xyz.openbmc_project.Logging.Entry.Level.Warning")
Andrew Geisslercb92c032018-08-17 07:56:14 -0700101 {
102 return "Warning";
103 }
104 return "";
105}
106
Abhishek Patel9017faf2021-09-14 22:48:55 -0500107inline std::optional<bool> getProviderNotifyAction(const std::string& notify)
108{
109 std::optional<bool> notifyAction;
110 if (notify == "xyz.openbmc_project.Logging.Entry.Notify.Notify")
111 {
112 notifyAction = true;
113 }
114 else if (notify == "xyz.openbmc_project.Logging.Entry.Notify.Inhibit")
115 {
116 notifyAction = false;
117 }
118
119 return notifyAction;
120}
121
Ed Tanous18f8f602023-07-18 10:07:23 -0700122inline std::string getDumpPath(std::string_view dumpType)
123{
124 std::string dbusDumpPath = "/xyz/openbmc_project/dump/";
125 std::ranges::transform(dumpType, std::back_inserter(dbusDumpPath),
126 bmcweb::asciiToLower);
127
128 return dbusDumpPath;
129}
130
Patrick Williams504af5a2025-02-03 14:29:03 -0500131inline log_entry::OriginatorTypes mapDbusOriginatorTypeToRedfish(
132 const std::string& originatorType)
Asmitha Karunanithi68dd0752022-11-15 11:33:46 -0600133{
134 if (originatorType ==
135 "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Client")
136 {
137 return log_entry::OriginatorTypes::Client;
138 }
139 if (originatorType ==
140 "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Internal")
141 {
142 return log_entry::OriginatorTypes::Internal;
143 }
144 if (originatorType ==
145 "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.SupportingService")
146 {
147 return log_entry::OriginatorTypes::SupportingService;
148 }
149 return log_entry::OriginatorTypes::Invalid;
150}
151
Claire Weinanaefe3782022-07-15 19:17:19 -0700152inline void parseDumpEntryFromDbusObject(
Jiaqing Zhao2d613eb2022-08-15 16:03:00 +0800153 const dbus::utility::ManagedObjectType::value_type& object,
Claire Weinanc6fecda2022-07-15 10:43:25 -0700154 std::string& dumpStatus, uint64_t& size, uint64_t& timestampUs,
Asmitha Karunanithi68dd0752022-11-15 11:33:46 -0600155 std::string& originatorId, log_entry::OriginatorTypes& originatorType,
Claire Weinanaefe3782022-07-15 19:17:19 -0700156 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
157{
158 for (const auto& interfaceMap : object.second)
159 {
160 if (interfaceMap.first == "xyz.openbmc_project.Common.Progress")
161 {
162 for (const auto& propertyMap : interfaceMap.second)
163 {
164 if (propertyMap.first == "Status")
165 {
166 const auto* status =
167 std::get_if<std::string>(&propertyMap.second);
168 if (status == nullptr)
169 {
170 messages::internalError(asyncResp->res);
171 break;
172 }
173 dumpStatus = *status;
174 }
175 }
176 }
177 else if (interfaceMap.first == "xyz.openbmc_project.Dump.Entry")
178 {
179 for (const auto& propertyMap : interfaceMap.second)
180 {
181 if (propertyMap.first == "Size")
182 {
183 const auto* sizePtr =
184 std::get_if<uint64_t>(&propertyMap.second);
185 if (sizePtr == nullptr)
186 {
187 messages::internalError(asyncResp->res);
188 break;
189 }
190 size = *sizePtr;
191 break;
192 }
193 }
194 }
195 else if (interfaceMap.first == "xyz.openbmc_project.Time.EpochTime")
196 {
197 for (const auto& propertyMap : interfaceMap.second)
198 {
199 if (propertyMap.first == "Elapsed")
200 {
201 const uint64_t* usecsTimeStamp =
202 std::get_if<uint64_t>(&propertyMap.second);
203 if (usecsTimeStamp == nullptr)
204 {
205 messages::internalError(asyncResp->res);
206 break;
207 }
Claire Weinanc6fecda2022-07-15 10:43:25 -0700208 timestampUs = *usecsTimeStamp;
Claire Weinanaefe3782022-07-15 19:17:19 -0700209 break;
210 }
211 }
212 }
Asmitha Karunanithi68dd0752022-11-15 11:33:46 -0600213 else if (interfaceMap.first ==
214 "xyz.openbmc_project.Common.OriginatedBy")
215 {
216 for (const auto& propertyMap : interfaceMap.second)
217 {
218 if (propertyMap.first == "OriginatorId")
219 {
220 const std::string* id =
221 std::get_if<std::string>(&propertyMap.second);
222 if (id == nullptr)
223 {
224 messages::internalError(asyncResp->res);
225 break;
226 }
227 originatorId = *id;
228 }
229
230 if (propertyMap.first == "OriginatorType")
231 {
232 const std::string* type =
233 std::get_if<std::string>(&propertyMap.second);
234 if (type == nullptr)
235 {
236 messages::internalError(asyncResp->res);
237 break;
238 }
239
240 originatorType = mapDbusOriginatorTypeToRedfish(*type);
241 if (originatorType == log_entry::OriginatorTypes::Invalid)
242 {
243 messages::internalError(asyncResp->res);
244 break;
245 }
246 }
247 }
248 }
Claire Weinanaefe3782022-07-15 19:17:19 -0700249 }
250}
251
Nan Zhou21ab4042022-06-26 23:07:40 +0000252static std::string getDumpEntriesPath(const std::string& dumpType)
Claire Weinanfdd26902022-03-01 14:18:25 -0800253{
254 std::string entriesPath;
255
256 if (dumpType == "BMC")
257 {
Ed Tanous253f11b2024-05-16 09:38:31 -0700258 entriesPath =
259 std::format("/redfish/v1/Managers/{}/LogServices/Dump/Entries/",
260 BMCWEB_REDFISH_MANAGER_URI_NAME);
Claire Weinanfdd26902022-03-01 14:18:25 -0800261 }
262 else if (dumpType == "FaultLog")
263 {
Ed Tanous253f11b2024-05-16 09:38:31 -0700264 entriesPath =
265 std::format("/redfish/v1/Managers/{}/LogServices/FaultLog/Entries/",
266 BMCWEB_REDFISH_MANAGER_URI_NAME);
Claire Weinanfdd26902022-03-01 14:18:25 -0800267 }
268 else if (dumpType == "System")
269 {
Ed Tanous253f11b2024-05-16 09:38:31 -0700270 entriesPath =
271 std::format("/redfish/v1/Systems/{}/LogServices/Dump/Entries/",
272 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Claire Weinanfdd26902022-03-01 14:18:25 -0800273 }
274 else
275 {
Ed Tanous62598e32023-07-17 17:06:25 -0700276 BMCWEB_LOG_ERROR("getDumpEntriesPath() invalid dump type: {}",
277 dumpType);
Claire Weinanfdd26902022-03-01 14:18:25 -0800278 }
279
280 // Returns empty string on error
281 return entriesPath;
282}
283
Patrick Williams504af5a2025-02-03 14:29:03 -0500284inline void getDumpEntryCollection(
285 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
286 const std::string& dumpType)
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500287{
Claire Weinanfdd26902022-03-01 14:18:25 -0800288 std::string entriesPath = getDumpEntriesPath(dumpType);
289 if (entriesPath.empty())
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500290 {
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500291 messages::internalError(asyncResp->res);
292 return;
293 }
294
George Liu5eb468d2023-06-20 17:03:24 +0800295 sdbusplus::message::object_path path("/xyz/openbmc_project/dump");
296 dbus::utility::getManagedObjects(
297 "xyz.openbmc_project.Dump.Manager", path,
Claire Weinanfdd26902022-03-01 14:18:25 -0800298 [asyncResp, entriesPath,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800299 dumpType](const boost::system::error_code& ec,
George Liu5eb468d2023-06-20 17:03:24 +0800300 const dbus::utility::ManagedObjectType& objects) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400301 if (ec)
302 {
303 BMCWEB_LOG_ERROR("DumpEntry resp_handler got error {}", ec);
304 messages::internalError(asyncResp->res);
305 return;
306 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700307
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400308 // Remove ending slash
309 std::string odataIdStr = entriesPath;
310 if (!odataIdStr.empty())
311 {
312 odataIdStr.pop_back();
313 }
Claire Weinanfdd26902022-03-01 14:18:25 -0800314
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400315 asyncResp->res.jsonValue["@odata.type"] =
316 "#LogEntryCollection.LogEntryCollection";
317 asyncResp->res.jsonValue["@odata.id"] = std::move(odataIdStr);
318 asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entries";
319 asyncResp->res.jsonValue["Description"] =
320 "Collection of " + dumpType + " Dump Entries";
Claire Weinanfdd26902022-03-01 14:18:25 -0800321
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400322 nlohmann::json::array_t entriesArray;
323 std::string dumpEntryPath = getDumpPath(dumpType) + "/entry/";
Ed Tanous002d39b2022-05-31 08:59:27 -0700324
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400325 dbus::utility::ManagedObjectType resp(objects);
326 std::ranges::sort(resp, [](const auto& l, const auto& r) {
327 return AlphanumLess<std::string>()(l.first.filename(),
328 r.first.filename());
329 });
330
331 for (auto& object : resp)
332 {
333 if (object.first.str.find(dumpEntryPath) == std::string::npos)
334 {
335 continue;
336 }
337 uint64_t timestampUs = 0;
338 uint64_t size = 0;
339 std::string dumpStatus;
340 std::string originatorId;
341 log_entry::OriginatorTypes originatorType =
342 log_entry::OriginatorTypes::Internal;
343 nlohmann::json::object_t thisEntry;
344
345 std::string entryID = object.first.filename();
346 if (entryID.empty())
347 {
348 continue;
349 }
350
351 parseDumpEntryFromDbusObject(object, dumpStatus, size,
352 timestampUs, originatorId,
353 originatorType, asyncResp);
354
355 if (dumpStatus !=
356 "xyz.openbmc_project.Common.Progress.OperationStatus.Completed" &&
357 !dumpStatus.empty())
358 {
359 // Dump status is not Complete, no need to enumerate
360 continue;
361 }
362
363 thisEntry["@odata.type"] = "#LogEntry.v1_11_0.LogEntry";
364 thisEntry["@odata.id"] = entriesPath + entryID;
365 thisEntry["Id"] = entryID;
366 thisEntry["EntryType"] = "Event";
367 thisEntry["Name"] = dumpType + " Dump Entry";
368 thisEntry["Created"] =
369 redfish::time_utils::getDateTimeUintUs(timestampUs);
370
371 if (!originatorId.empty())
372 {
373 thisEntry["Originator"] = originatorId;
374 thisEntry["OriginatorType"] = originatorType;
375 }
376
377 if (dumpType == "BMC")
378 {
379 thisEntry["DiagnosticDataType"] = "Manager";
380 thisEntry["AdditionalDataURI"] =
381 entriesPath + entryID + "/attachment";
382 thisEntry["AdditionalDataSizeBytes"] = size;
383 }
384 else if (dumpType == "System")
385 {
386 thisEntry["DiagnosticDataType"] = "OEM";
387 thisEntry["OEMDiagnosticDataType"] = "System";
388 thisEntry["AdditionalDataURI"] =
389 entriesPath + entryID + "/attachment";
390 thisEntry["AdditionalDataSizeBytes"] = size;
391 }
392 entriesArray.emplace_back(std::move(thisEntry));
393 }
394 asyncResp->res.jsonValue["Members@odata.count"] =
395 entriesArray.size();
396 asyncResp->res.jsonValue["Members"] = std::move(entriesArray);
Ed Tanous002d39b2022-05-31 08:59:27 -0700397 });
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500398}
399
Patrick Williams504af5a2025-02-03 14:29:03 -0500400inline void getDumpEntryById(
401 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
402 const std::string& entryID, const std::string& dumpType)
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500403{
Claire Weinanfdd26902022-03-01 14:18:25 -0800404 std::string entriesPath = getDumpEntriesPath(dumpType);
405 if (entriesPath.empty())
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500406 {
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500407 messages::internalError(asyncResp->res);
408 return;
409 }
410
George Liu5eb468d2023-06-20 17:03:24 +0800411 sdbusplus::message::object_path path("/xyz/openbmc_project/dump");
412 dbus::utility::getManagedObjects(
413 "xyz.openbmc_project.Dump.Manager", path,
Claire Weinanfdd26902022-03-01 14:18:25 -0800414 [asyncResp, entryID, dumpType,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800415 entriesPath](const boost::system::error_code& ec,
Ed Tanous02cad962022-06-30 16:50:15 -0700416 const dbus::utility::ManagedObjectType& resp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400417 if (ec)
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500418 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400419 BMCWEB_LOG_ERROR("DumpEntry resp_handler got error {}", ec);
420 messages::internalError(asyncResp->res);
421 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700422 }
423
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400424 bool foundDumpEntry = false;
425 std::string dumpEntryPath = getDumpPath(dumpType) + "/entry/";
Ed Tanous002d39b2022-05-31 08:59:27 -0700426
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400427 for (const auto& objectPath : resp)
Ed Tanous002d39b2022-05-31 08:59:27 -0700428 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400429 if (objectPath.first.str != dumpEntryPath + entryID)
430 {
431 continue;
432 }
433
434 foundDumpEntry = true;
435 uint64_t timestampUs = 0;
436 uint64_t size = 0;
437 std::string dumpStatus;
438 std::string originatorId;
439 log_entry::OriginatorTypes originatorType =
440 log_entry::OriginatorTypes::Internal;
441
442 parseDumpEntryFromDbusObject(objectPath, dumpStatus, size,
443 timestampUs, originatorId,
444 originatorType, asyncResp);
445
446 if (dumpStatus !=
447 "xyz.openbmc_project.Common.Progress.OperationStatus.Completed" &&
448 !dumpStatus.empty())
449 {
450 // Dump status is not Complete
451 // return not found until status is changed to Completed
452 messages::resourceNotFound(asyncResp->res,
453 dumpType + " dump", entryID);
454 return;
455 }
456
457 asyncResp->res.jsonValue["@odata.type"] =
458 "#LogEntry.v1_11_0.LogEntry";
459 asyncResp->res.jsonValue["@odata.id"] = entriesPath + entryID;
460 asyncResp->res.jsonValue["Id"] = entryID;
461 asyncResp->res.jsonValue["EntryType"] = "Event";
462 asyncResp->res.jsonValue["Name"] = dumpType + " Dump Entry";
463 asyncResp->res.jsonValue["Created"] =
464 redfish::time_utils::getDateTimeUintUs(timestampUs);
465
466 if (!originatorId.empty())
467 {
468 asyncResp->res.jsonValue["Originator"] = originatorId;
469 asyncResp->res.jsonValue["OriginatorType"] = originatorType;
470 }
471
472 if (dumpType == "BMC")
473 {
474 asyncResp->res.jsonValue["DiagnosticDataType"] = "Manager";
475 asyncResp->res.jsonValue["AdditionalDataURI"] =
476 entriesPath + entryID + "/attachment";
477 asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size;
478 }
479 else if (dumpType == "System")
480 {
481 asyncResp->res.jsonValue["DiagnosticDataType"] = "OEM";
482 asyncResp->res.jsonValue["OEMDiagnosticDataType"] =
483 "System";
484 asyncResp->res.jsonValue["AdditionalDataURI"] =
485 entriesPath + entryID + "/attachment";
486 asyncResp->res.jsonValue["AdditionalDataSizeBytes"] = size;
487 }
488 }
489 if (!foundDumpEntry)
490 {
491 BMCWEB_LOG_WARNING("Can't find Dump Entry {}", entryID);
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200492 messages::resourceNotFound(asyncResp->res, dumpType + " dump",
493 entryID);
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500494 return;
495 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400496 });
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500497}
498
zhanghch058d1b46d2021-04-01 11:18:24 +0800499inline void deleteDumpEntry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Stanley Chu98782562020-11-04 16:10:24 +0800500 const std::string& entryID,
Asmitha Karunanithib47452b2020-09-25 02:02:19 -0500501 const std::string& dumpType)
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500502{
Patrick Williams5a39f772023-10-20 11:20:21 -0500503 auto respHandler = [asyncResp,
504 entryID](const boost::system::error_code& ec) {
Ed Tanous62598e32023-07-17 17:06:25 -0700505 BMCWEB_LOG_DEBUG("Dump Entry doDelete callback: Done");
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500506 if (ec)
507 {
George Liu3de8d8b2021-03-22 17:49:39 +0800508 if (ec.value() == EBADR)
509 {
510 messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
511 return;
512 }
Ed Tanous62598e32023-07-17 17:06:25 -0700513 BMCWEB_LOG_ERROR(
514 "Dump (DBus) doDelete respHandler got error {} entryID={}", ec,
515 entryID);
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500516 messages::internalError(asyncResp->res);
517 return;
518 }
519 };
Ed Tanous18f8f602023-07-18 10:07:23 -0700520
Ed Tanous177612a2025-02-14 15:16:09 -0800521 dbus::utility::async_method_call(
522 asyncResp, respHandler, "xyz.openbmc_project.Dump.Manager",
Ed Tanous18f8f602023-07-18 10:07:23 -0700523 std::format("{}/entry/{}", getDumpPath(dumpType), entryID),
Asmitha Karunanithi5cb1dd22020-05-07 04:35:02 -0500524 "xyz.openbmc_project.Object.Delete", "Delete");
525}
Carson Labrado168d1b12023-03-27 17:04:46 +0000526
Patrick Williams504af5a2025-02-03 14:29:03 -0500527inline void downloadDumpEntry(
528 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
529 const std::string& entryID, const std::string& dumpType)
Carson Labrado168d1b12023-03-27 17:04:46 +0000530{
531 if (dumpType != "BMC")
532 {
533 BMCWEB_LOG_WARNING("Can't find Dump Entry {}", entryID);
534 messages::resourceNotFound(asyncResp->res, dumpType + " dump", entryID);
535 return;
536 }
537
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400538 std::string dumpEntryPath =
539 std::format("{}/entry/{}", getDumpPath(dumpType), entryID);
Carson Labrado168d1b12023-03-27 17:04:46 +0000540
541 auto downloadDumpEntryHandler =
542 [asyncResp, entryID,
543 dumpType](const boost::system::error_code& ec,
544 const sdbusplus::message::unix_fd& unixfd) {
Oliver Brewkaff35df92025-08-26 08:21:30 +0200545 log_services_utils::downloadEntryCallback(asyncResp, entryID,
546 dumpType, ec, unixfd);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400547 };
Carson Labrado168d1b12023-03-27 17:04:46 +0000548
Ed Tanous177612a2025-02-14 15:16:09 -0800549 dbus::utility::async_method_call(
550 asyncResp, std::move(downloadDumpEntryHandler),
551 "xyz.openbmc_project.Dump.Manager", dumpEntryPath,
552 "xyz.openbmc_project.Dump.Entry", "GetFileHandle");
Carson Labrado168d1b12023-03-27 17:04:46 +0000553}
554
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400555inline void downloadEventLogEntry(
556 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
557 const std::string& systemName, const std::string& entryID,
558 const std::string& dumpType)
Carson Labrado168d1b12023-03-27 17:04:46 +0000559{
Ed Tanous25b54db2024-04-17 15:40:31 -0700560 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Carson Labrado168d1b12023-03-27 17:04:46 +0000561 {
562 // Option currently returns no systems. TBD
563 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
564 systemName);
565 return;
566 }
Ed Tanous253f11b2024-05-16 09:38:31 -0700567 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Carson Labrado168d1b12023-03-27 17:04:46 +0000568 {
569 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
570 systemName);
571 return;
572 }
573
574 std::string entryPath =
575 sdbusplus::message::object_path("/xyz/openbmc_project/logging/entry") /
576 entryID;
577
578 auto downloadEventLogEntryHandler =
579 [asyncResp, entryID,
580 dumpType](const boost::system::error_code& ec,
581 const sdbusplus::message::unix_fd& unixfd) {
Oliver Brewkaff35df92025-08-26 08:21:30 +0200582 log_services_utils::downloadEntryCallback(asyncResp, entryID,
583 dumpType, ec, unixfd);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400584 };
Carson Labrado168d1b12023-03-27 17:04:46 +0000585
Ed Tanous177612a2025-02-14 15:16:09 -0800586 dbus::utility::async_method_call(
587 asyncResp, std::move(downloadEventLogEntryHandler),
588 "xyz.openbmc_project.Logging", entryPath,
589 "xyz.openbmc_project.Logging.Entry", "GetEntry");
Carson Labrado168d1b12023-03-27 17:04:46 +0000590}
591
Patrick Williams504af5a2025-02-03 14:29:03 -0500592inline DumpCreationProgress mapDbusStatusToDumpProgress(
593 const std::string& status)
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500594{
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600595 if (status ==
596 "xyz.openbmc_project.Common.Progress.OperationStatus.Failed" ||
597 status == "xyz.openbmc_project.Common.Progress.OperationStatus.Aborted")
598 {
599 return DumpCreationProgress::DUMP_CREATE_FAILED;
600 }
601 if (status ==
602 "xyz.openbmc_project.Common.Progress.OperationStatus.Completed")
603 {
604 return DumpCreationProgress::DUMP_CREATE_SUCCESS;
605 }
606 return DumpCreationProgress::DUMP_CREATE_INPROGRESS;
607}
608
Patrick Williams504af5a2025-02-03 14:29:03 -0500609inline DumpCreationProgress getDumpCompletionStatus(
610 const dbus::utility::DBusPropertiesMap& values)
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600611{
612 for (const auto& [key, val] : values)
613 {
614 if (key == "Status")
Ed Tanous002d39b2022-05-31 08:59:27 -0700615 {
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600616 const std::string* value = std::get_if<std::string>(&val);
617 if (value == nullptr)
618 {
Ed Tanous62598e32023-07-17 17:06:25 -0700619 BMCWEB_LOG_ERROR("Status property value is null");
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600620 return DumpCreationProgress::DUMP_CREATE_FAILED;
621 }
622 return mapDbusStatusToDumpProgress(*value);
623 }
624 }
625 return DumpCreationProgress::DUMP_CREATE_INPROGRESS;
626}
627
628inline std::string getDumpEntryPath(const std::string& dumpPath)
629{
630 if (dumpPath == "/xyz/openbmc_project/dump/bmc/entry")
631 {
Ed Tanous253f11b2024-05-16 09:38:31 -0700632 return std::format("/redfish/v1/Managers/{}/LogServices/Dump/Entries/",
Ed Tanous9f565092024-07-12 22:06:53 -0700633 BMCWEB_REDFISH_MANAGER_URI_NAME);
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600634 }
635 if (dumpPath == "/xyz/openbmc_project/dump/system/entry")
636 {
Ed Tanous253f11b2024-05-16 09:38:31 -0700637 return std::format("/redfish/v1/Systems/{}/LogServices/Dump/Entries/",
638 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600639 }
640 return "";
641}
642
643inline void createDumpTaskCallback(
644 task::Payload&& payload,
645 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
646 const sdbusplus::message::object_path& createdObjPath)
647{
648 const std::string dumpPath = createdObjPath.parent_path().str;
649 const std::string dumpId = createdObjPath.filename();
650
651 std::string dumpEntryPath = getDumpEntryPath(dumpPath);
652
653 if (dumpEntryPath.empty())
654 {
Ed Tanous62598e32023-07-17 17:06:25 -0700655 BMCWEB_LOG_ERROR("Invalid dump type received");
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600656 messages::internalError(asyncResp->res);
657 return;
658 }
659
Ed Tanous177612a2025-02-14 15:16:09 -0800660 dbus::utility::async_method_call(
661 asyncResp,
Ed Tanous8cb2c022024-03-27 16:31:46 -0700662 [asyncResp, payload = std::move(payload), createdObjPath,
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600663 dumpEntryPath{std::move(dumpEntryPath)},
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800664 dumpId](const boost::system::error_code& ec,
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600665 const std::string& introspectXml) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400666 if (ec)
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600667 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400668 BMCWEB_LOG_ERROR("Introspect call failed with error: {}",
669 ec.message());
670 messages::internalError(asyncResp->res);
671 return;
672 }
673
674 // Check if the created dump object has implemented Progress
675 // interface to track dump completion. If yes, fetch the "Status"
676 // property of the interface, modify the task state accordingly.
677 // Else, return task completed.
678 tinyxml2::XMLDocument doc;
679
680 doc.Parse(introspectXml.data(), introspectXml.size());
681 tinyxml2::XMLNode* pRoot = doc.FirstChildElement("node");
682 if (pRoot == nullptr)
683 {
684 BMCWEB_LOG_ERROR("XML document failed to parse");
685 messages::internalError(asyncResp->res);
686 return;
687 }
688 tinyxml2::XMLElement* interfaceNode =
689 pRoot->FirstChildElement("interface");
690
691 bool isProgressIntfPresent = false;
692 while (interfaceNode != nullptr)
693 {
694 const char* thisInterfaceName =
695 interfaceNode->Attribute("name");
696 if (thisInterfaceName != nullptr)
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600697 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400698 if (thisInterfaceName ==
699 std::string_view("xyz.openbmc_project.Common.Progress"))
700 {
701 interfaceNode =
702 interfaceNode->NextSiblingElement("interface");
703 continue;
704 }
705 isProgressIntfPresent = true;
706 break;
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600707 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400708 interfaceNode = interfaceNode->NextSiblingElement("interface");
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600709 }
710
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400711 std::shared_ptr<task::TaskData> task = task::TaskData::createTask(
712 [createdObjPath, dumpEntryPath, dumpId, isProgressIntfPresent](
713 const boost::system::error_code& ec2,
714 sdbusplus::message_t& msg,
715 const std::shared_ptr<task::TaskData>& taskData) {
716 if (ec2)
717 {
718 BMCWEB_LOG_ERROR("{}: Error in creating dump",
719 createdObjPath.str);
720 taskData->messages.emplace_back(
721 messages::internalError());
722 taskData->state = "Cancelled";
723 return task::completed;
724 }
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600725
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400726 if (isProgressIntfPresent)
727 {
728 dbus::utility::DBusPropertiesMap values;
729 std::string prop;
730 msg.read(prop, values);
731
732 DumpCreationProgress dumpStatus =
733 getDumpCompletionStatus(values);
734 if (dumpStatus ==
735 DumpCreationProgress::DUMP_CREATE_FAILED)
736 {
737 BMCWEB_LOG_ERROR("{}: Error in creating dump",
738 createdObjPath.str);
739 taskData->state = "Cancelled";
740 return task::completed;
741 }
742
743 if (dumpStatus ==
744 DumpCreationProgress::DUMP_CREATE_INPROGRESS)
745 {
746 BMCWEB_LOG_DEBUG(
747 "{}: Dump creation task is in progress",
748 createdObjPath.str);
749 return !task::completed;
750 }
751 }
752
753 nlohmann::json retMessage = messages::success();
754 taskData->messages.emplace_back(retMessage);
755
756 boost::urls::url url = boost::urls::format(
757 "/redfish/v1/Managers/{}/LogServices/Dump/Entries/{}",
758 BMCWEB_REDFISH_MANAGER_URI_NAME, dumpId);
759
760 std::string headerLoc = "Location: ";
761 headerLoc += url.buffer();
762
763 taskData->payload->httpHeaders.emplace_back(
764 std::move(headerLoc));
765
766 BMCWEB_LOG_DEBUG("{}: Dump creation task completed",
Ed Tanous62598e32023-07-17 17:06:25 -0700767 createdObjPath.str);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400768 taskData->state = "Completed";
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600769 return task::completed;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400770 },
771 "type='signal',interface='org.freedesktop.DBus.Properties',"
772 "member='PropertiesChanged',path='" +
773 createdObjPath.str + "'");
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600774
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400775 // The task timer is set to max time limit within which the
776 // requested dump will be collected.
777 task->startTimer(std::chrono::minutes(6));
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400778 task->payload.emplace(payload);
Chinmay Shripad Hegde29e2bdd2025-06-06 16:23:47 +0530779 task->populateResp(asyncResp->res);
Patrick Williams5a39f772023-10-20 11:20:21 -0500780 },
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600781 "xyz.openbmc_project.Dump.Manager", createdObjPath,
782 "org.freedesktop.DBus.Introspectable", "Introspect");
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500783}
784
zhanghch058d1b46d2021-04-01 11:18:24 +0800785inline void createDump(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
786 const crow::Request& req, const std::string& dumpType)
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500787{
Claire Weinanfdd26902022-03-01 14:18:25 -0800788 std::string dumpPath = getDumpEntriesPath(dumpType);
789 if (dumpPath.empty())
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500790 {
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500791 messages::internalError(asyncResp->res);
792 return;
793 }
794
795 std::optional<std::string> diagnosticDataType;
796 std::optional<std::string> oemDiagnosticDataType;
797
Patrick Williams504af5a2025-02-03 14:29:03 -0500798 if (!redfish::json_util::readJsonAction( //
799 req, asyncResp->res, //
800 "DiagnosticDataType", diagnosticDataType, //
Myung Baeafc474a2024-10-09 00:53:29 -0700801 "OEMDiagnosticDataType", oemDiagnosticDataType //
802 ))
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500803 {
804 return;
805 }
806
807 if (dumpType == "System")
808 {
809 if (!oemDiagnosticDataType || !diagnosticDataType)
810 {
Ed Tanous62598e32023-07-17 17:06:25 -0700811 BMCWEB_LOG_ERROR(
812 "CreateDump action parameter 'DiagnosticDataType'/'OEMDiagnosticDataType' value not found!");
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500813 messages::actionParameterMissing(
814 asyncResp->res, "CollectDiagnosticData",
815 "DiagnosticDataType & OEMDiagnosticDataType");
816 return;
817 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700818 if ((*oemDiagnosticDataType != "System") ||
819 (*diagnosticDataType != "OEM"))
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500820 {
Ed Tanous62598e32023-07-17 17:06:25 -0700821 BMCWEB_LOG_ERROR("Wrong parameter values passed");
Ed Tanousace85d62021-10-26 12:45:59 -0700822 messages::internalError(asyncResp->res);
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500823 return;
824 }
Ed Tanous253f11b2024-05-16 09:38:31 -0700825 dumpPath = std::format("/redfish/v1/Systems/{}/LogServices/Dump/",
826 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500827 }
828 else if (dumpType == "BMC")
829 {
830 if (!diagnosticDataType)
831 {
Ed Tanous62598e32023-07-17 17:06:25 -0700832 BMCWEB_LOG_ERROR(
833 "CreateDump action parameter 'DiagnosticDataType' not found!");
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500834 messages::actionParameterMissing(
835 asyncResp->res, "CollectDiagnosticData", "DiagnosticDataType");
836 return;
837 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700838 if (*diagnosticDataType != "Manager")
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500839 {
Ed Tanous62598e32023-07-17 17:06:25 -0700840 BMCWEB_LOG_ERROR(
841 "Wrong parameter value passed for 'DiagnosticDataType'");
Ed Tanousace85d62021-10-26 12:45:59 -0700842 messages::internalError(asyncResp->res);
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500843 return;
844 }
Ed Tanous253f11b2024-05-16 09:38:31 -0700845 dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/Dump/",
846 BMCWEB_REDFISH_MANAGER_URI_NAME);
Asmitha Karunanithi59075712021-10-22 01:17:41 -0500847 }
848 else
849 {
Ed Tanous62598e32023-07-17 17:06:25 -0700850 BMCWEB_LOG_ERROR("CreateDump failed. Unknown dump type");
Asmitha Karunanithi59075712021-10-22 01:17:41 -0500851 messages::internalError(asyncResp->res);
852 return;
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500853 }
854
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600855 std::vector<std::pair<std::string, std::variant<std::string, uint64_t>>>
856 createDumpParamVec;
857
Carson Labradof574a8e2023-03-22 02:26:00 +0000858 if (req.session != nullptr)
859 {
860 createDumpParamVec.emplace_back(
861 "xyz.openbmc_project.Dump.Create.CreateParameters.OriginatorId",
862 req.session->clientIp);
863 createDumpParamVec.emplace_back(
864 "xyz.openbmc_project.Dump.Create.CreateParameters.OriginatorType",
865 "xyz.openbmc_project.Common.OriginatedBy.OriginatorTypes.Client");
866 }
Asmitha Karunanithi68dd0752022-11-15 11:33:46 -0600867
Ed Tanous177612a2025-02-14 15:16:09 -0800868 dbus::utility::async_method_call(
869 asyncResp,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800870 [asyncResp, payload(task::Payload(req)),
871 dumpPath](const boost::system::error_code& ec,
872 const sdbusplus::message_t& msg,
873 const sdbusplus::message::object_path& objPath) mutable {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400874 if (ec)
Asmitha Karunanithi59075712021-10-22 01:17:41 -0500875 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400876 BMCWEB_LOG_ERROR("CreateDump resp_handler got error {}", ec);
877 const sd_bus_error* dbusError = msg.get_error();
878 if (dbusError == nullptr)
879 {
880 messages::internalError(asyncResp->res);
881 return;
882 }
883
884 BMCWEB_LOG_ERROR("CreateDump DBus error: {} and error msg: {}",
885 dbusError->name, dbusError->message);
886 if (std::string_view(
887 "xyz.openbmc_project.Common.Error.NotAllowed") ==
888 dbusError->name)
889 {
890 messages::resourceInStandby(asyncResp->res);
891 return;
892 }
893 if (std::string_view(
894 "xyz.openbmc_project.Dump.Create.Error.Disabled") ==
895 dbusError->name)
896 {
897 messages::serviceDisabled(asyncResp->res, dumpPath);
898 return;
899 }
900 if (std::string_view(
901 "xyz.openbmc_project.Common.Error.Unavailable") ==
902 dbusError->name)
903 {
904 messages::resourceInUse(asyncResp->res);
905 return;
906 }
907 // Other Dbus errors such as:
908 // xyz.openbmc_project.Common.Error.InvalidArgument &
909 // org.freedesktop.DBus.Error.InvalidArgs are all related to
910 // the dbus call that is made here in the bmcweb
911 // implementation and has nothing to do with the client's
912 // input in the request. Hence, returning internal error
913 // back to the client.
Asmitha Karunanithi59075712021-10-22 01:17:41 -0500914 messages::internalError(asyncResp->res);
915 return;
916 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400917 BMCWEB_LOG_DEBUG("Dump Created. Path: {}", objPath.str);
918 createDumpTaskCallback(std::move(payload), asyncResp, objPath);
919 },
Ed Tanous18f8f602023-07-18 10:07:23 -0700920 "xyz.openbmc_project.Dump.Manager", getDumpPath(dumpType),
Asmitha Karunanithi8e317782020-12-10 03:35:05 -0600921 "xyz.openbmc_project.Dump.Create", "CreateDump", createDumpParamVec);
Asmitha Karunanithia43be802020-05-07 05:05:36 -0500922}
923
zhanghch058d1b46d2021-04-01 11:18:24 +0800924inline void clearDump(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
925 const std::string& dumpType)
Asmitha Karunanithi80319af2020-05-07 05:30:21 -0500926{
Ed Tanous177612a2025-02-14 15:16:09 -0800927 dbus::utility::async_method_call(
928 asyncResp,
Claire Weinan0d946212022-07-13 19:40:19 -0700929 [asyncResp](const boost::system::error_code& ec) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400930 if (ec)
931 {
932 BMCWEB_LOG_ERROR("clearDump resp_handler got error {}", ec);
933 messages::internalError(asyncResp->res);
934 return;
935 }
Amy Change2460462025-05-06 00:10:13 -0700936 messages::success(asyncResp->res);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400937 },
Ed Tanous18f8f602023-07-18 10:07:23 -0700938 "xyz.openbmc_project.Dump.Manager", getDumpPath(dumpType),
Claire Weinan0d946212022-07-13 19:40:19 -0700939 "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
Asmitha Karunanithi80319af2020-05-07 05:30:21 -0500940}
941
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400942inline void parseCrashdumpParameters(
943 const dbus::utility::DBusPropertiesMap& params, std::string& filename,
944 std::string& timestamp, std::string& logfile)
Johnathan Mantey043a0532020-03-10 17:15:28 -0700945{
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200946 const std::string* filenamePtr = nullptr;
947 const std::string* timestampPtr = nullptr;
948 const std::string* logfilePtr = nullptr;
949
950 const bool success = sdbusplus::unpackPropertiesNoThrow(
951 dbus_utils::UnpackErrorPrinter(), params, "Timestamp", timestampPtr,
952 "Filename", filenamePtr, "Log", logfilePtr);
953
954 if (!success)
Johnathan Mantey043a0532020-03-10 17:15:28 -0700955 {
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200956 return;
957 }
958
959 if (filenamePtr != nullptr)
960 {
961 filename = *filenamePtr;
962 }
963
964 if (timestampPtr != nullptr)
965 {
966 timestamp = *timestampPtr;
967 }
968
969 if (logfilePtr != nullptr)
970 {
971 logfile = *logfilePtr;
Johnathan Mantey043a0532020-03-10 17:15:28 -0700972 }
973}
974
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700975inline void requestRoutesSystemLogServiceCollection(App& app)
Ed Tanous1da66f72018-07-27 16:13:37 -0700976{
Jason M. Billsc4bf6372018-11-05 13:48:27 -0800977 /**
978 * Functions triggers appropriate requests on DBus
979 */
Ed Tanous22d268c2022-05-19 09:39:07 -0700980 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/")
Ed Tanoused398212021-06-09 17:05:54 -0700981 .privileges(redfish::privileges::getLogServiceCollection)
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400982 .methods(
983 boost::beast::http::verb::
984 get)([&app](const crow::Request& req,
985 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
986 const std::string& systemName) {
987 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700988 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400989 return;
990 }
991 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
992 {
993 // Option currently returns no systems. TBD
994 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
995 systemName);
996 return;
997 }
998 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
999 {
1000 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1001 systemName);
Ed Tanous002d39b2022-05-31 08:59:27 -07001002 return;
1003 }
Ed Tanous45ca1b82022-03-25 13:07:27 -07001004
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001005 // Collections don't include the static data added by SubRoute
1006 // because it has a duplicate entry for members
1007 asyncResp->res.jsonValue["@odata.type"] =
1008 "#LogServiceCollection.LogServiceCollection";
1009 asyncResp->res.jsonValue["@odata.id"] =
1010 std::format("/redfish/v1/Systems/{}/LogServices",
1011 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1012 asyncResp->res.jsonValue["Name"] = "System Log Services Collection";
1013 asyncResp->res.jsonValue["Description"] =
1014 "Collection of LogServices for this Computer System";
1015 nlohmann::json& logServiceArray =
1016 asyncResp->res.jsonValue["Members"];
1017 logServiceArray = nlohmann::json::array();
1018 nlohmann::json::object_t eventLog;
1019 eventLog["@odata.id"] =
1020 std::format("/redfish/v1/Systems/{}/LogServices/EventLog",
1021 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1022 logServiceArray.emplace_back(std::move(eventLog));
1023 if constexpr (BMCWEB_REDFISH_DUMP_LOG)
Ed Tanous002d39b2022-05-31 08:59:27 -07001024 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001025 nlohmann::json::object_t dumpLog;
1026 dumpLog["@odata.id"] =
1027 std::format("/redfish/v1/Systems/{}/LogServices/Dump",
1028 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1029 logServiceArray.emplace_back(std::move(dumpLog));
Ed Tanous002d39b2022-05-31 08:59:27 -07001030 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001031
1032 if constexpr (BMCWEB_REDFISH_CPU_LOG)
1033 {
1034 nlohmann::json::object_t crashdump;
1035 crashdump["@odata.id"] =
1036 std::format("/redfish/v1/Systems/{}/LogServices/Crashdump",
1037 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1038 logServiceArray.emplace_back(std::move(crashdump));
1039 }
1040
1041 if constexpr (BMCWEB_REDFISH_HOST_LOGGER)
1042 {
1043 nlohmann::json::object_t hostlogger;
1044 hostlogger["@odata.id"] =
1045 std::format("/redfish/v1/Systems/{}/LogServices/HostLogger",
1046 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1047 logServiceArray.emplace_back(std::move(hostlogger));
1048 }
1049 asyncResp->res.jsonValue["Members@odata.count"] =
1050 logServiceArray.size();
1051
1052 constexpr std::array<std::string_view, 1> interfaces = {
1053 "xyz.openbmc_project.State.Boot.PostCode"};
1054 dbus::utility::getSubTreePaths(
1055 "/", 0, interfaces,
1056 [asyncResp](const boost::system::error_code& ec,
1057 const dbus::utility::MapperGetSubTreePathsResponse&
1058 subtreePath) {
1059 if (ec)
1060 {
1061 BMCWEB_LOG_ERROR("{}", ec);
1062 return;
1063 }
1064
1065 for (const auto& pathStr : subtreePath)
1066 {
1067 if (pathStr.find("PostCode") != std::string::npos)
1068 {
1069 nlohmann::json& logServiceArrayLocal =
1070 asyncResp->res.jsonValue["Members"];
1071 nlohmann::json::object_t member;
1072 member["@odata.id"] = std::format(
1073 "/redfish/v1/Systems/{}/LogServices/PostCodes",
1074 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1075
1076 logServiceArrayLocal.emplace_back(
1077 std::move(member));
1078
1079 asyncResp->res.jsonValue["Members@odata.count"] =
1080 logServiceArrayLocal.size();
1081 return;
1082 }
1083 }
1084 });
Ed Tanous45ca1b82022-03-25 13:07:27 -07001085 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001086}
1087
1088inline void requestRoutesEventLogService(App& app)
1089{
Ed Tanous22d268c2022-05-19 09:39:07 -07001090 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/")
Ed Tanoused398212021-06-09 17:05:54 -07001091 .privileges(redfish::privileges::getLogService)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001092 .methods(
1093 boost::beast::http::verb::
1094 get)([&app](const crow::Request& req,
1095 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1096 const std::string& systemName) {
1097 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1098 {
1099 return;
1100 }
1101 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1102 {
1103 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1104 systemName);
1105 return;
1106 }
1107 asyncResp->res.jsonValue["@odata.id"] =
1108 std::format("/redfish/v1/Systems/{}/LogServices/EventLog",
1109 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1110 asyncResp->res.jsonValue["@odata.type"] =
1111 "#LogService.v1_2_0.LogService";
1112 asyncResp->res.jsonValue["Name"] = "Event Log Service";
1113 asyncResp->res.jsonValue["Description"] =
1114 "System Event Log Service";
1115 asyncResp->res.jsonValue["Id"] = "EventLog";
1116 asyncResp->res.jsonValue["OverWritePolicy"] =
1117 log_service::OverWritePolicy::WrapsWhenFull;
Tejas Patil7c8c4052021-06-04 17:43:14 +05301118
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001119 std::pair<std::string, std::string> redfishDateTimeOffset =
1120 redfish::time_utils::getDateTimeOffsetNow();
Tejas Patil7c8c4052021-06-04 17:43:14 +05301121
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001122 asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
1123 asyncResp->res.jsonValue["DateTimeLocalOffset"] =
1124 redfishDateTimeOffset.second;
Tejas Patil7c8c4052021-06-04 17:43:14 +05301125
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001126 asyncResp->res.jsonValue["Entries"]["@odata.id"] = std::format(
1127 "/redfish/v1/Systems/{}/LogServices/EventLog/Entries",
Ed Tanous20fa6a22024-05-20 18:02:58 -07001128 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001129 asyncResp->res
1130 .jsonValue["Actions"]["#LogService.ClearLog"]["target"]
1131
1132 = std::format(
1133 "/redfish/v1/Systems/{}/LogServices/EventLog/Actions/LogService.ClearLog",
1134 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1135 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001136}
1137
Myung Bae7f3726a2025-04-26 15:17:23 -05001138inline void fillEventLogLogEntryFromDbusLogEntry(
1139 const DbusEventLogEntry& entry, nlohmann::json& objectToFillOut)
Ed Tanous898f2aa2024-08-07 12:18:22 -07001140{
Ed Tanous898f2aa2024-08-07 12:18:22 -07001141 objectToFillOut["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
1142 objectToFillOut["@odata.id"] = boost::urls::format(
1143 "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/{}",
Alexander Hansen262dcc12024-09-19 12:04:03 +02001144 BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(entry.Id));
Ed Tanous898f2aa2024-08-07 12:18:22 -07001145 objectToFillOut["Name"] = "System Event Log Entry";
Alexander Hansen262dcc12024-09-19 12:04:03 +02001146 objectToFillOut["Id"] = std::to_string(entry.Id);
1147 objectToFillOut["Message"] = entry.Message;
1148 objectToFillOut["Resolved"] = entry.Resolved;
1149 std::optional<bool> notifyAction =
1150 getProviderNotifyAction(entry.ServiceProviderNotify);
Ed Tanous898f2aa2024-08-07 12:18:22 -07001151 if (notifyAction)
1152 {
1153 objectToFillOut["ServiceProviderNotified"] = *notifyAction;
1154 }
Alexander Hansen262dcc12024-09-19 12:04:03 +02001155 if ((entry.Resolution != nullptr) && !entry.Resolution->empty())
Ed Tanous898f2aa2024-08-07 12:18:22 -07001156 {
Alexander Hansen262dcc12024-09-19 12:04:03 +02001157 objectToFillOut["Resolution"] = *entry.Resolution;
Ed Tanous898f2aa2024-08-07 12:18:22 -07001158 }
1159 objectToFillOut["EntryType"] = "Event";
Alexander Hansen262dcc12024-09-19 12:04:03 +02001160 objectToFillOut["Severity"] =
1161 translateSeverityDbusToRedfish(entry.Severity);
Ed Tanous898f2aa2024-08-07 12:18:22 -07001162 objectToFillOut["Created"] =
Alexander Hansen262dcc12024-09-19 12:04:03 +02001163 redfish::time_utils::getDateTimeUintMs(entry.Timestamp);
Ed Tanous898f2aa2024-08-07 12:18:22 -07001164 objectToFillOut["Modified"] =
Alexander Hansen262dcc12024-09-19 12:04:03 +02001165 redfish::time_utils::getDateTimeUintMs(entry.UpdateTimestamp);
1166 if (entry.Path != nullptr)
Ed Tanous898f2aa2024-08-07 12:18:22 -07001167 {
1168 objectToFillOut["AdditionalDataURI"] = boost::urls::format(
1169 "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/{}/attachment",
Alexander Hansen262dcc12024-09-19 12:04:03 +02001170 BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(entry.Id));
Ed Tanous898f2aa2024-08-07 12:18:22 -07001171 }
1172}
1173
Ed Tanousb7290962024-08-07 11:09:51 -07001174inline void afterLogEntriesGetManagedObjects(
1175 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1176 const boost::system::error_code& ec,
1177 const dbus::utility::ManagedObjectType& resp)
1178{
1179 if (ec)
1180 {
1181 // TODO Handle for specific error code
1182 BMCWEB_LOG_ERROR("getLogEntriesIfaceData resp_handler got error {}",
1183 ec);
1184 messages::internalError(asyncResp->res);
1185 return;
1186 }
1187 nlohmann::json::array_t entriesArray;
1188 for (const auto& objectPath : resp)
1189 {
Ed Tanous898f2aa2024-08-07 12:18:22 -07001190 dbus::utility::DBusPropertiesMap propsFlattened;
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001191 auto isEntry =
1192 std::ranges::find_if(objectPath.second, [](const auto& object) {
1193 return object.first == "xyz.openbmc_project.Logging.Entry";
1194 });
Ed Tanous898f2aa2024-08-07 12:18:22 -07001195 if (isEntry == objectPath.second.end())
Ed Tanousb7290962024-08-07 11:09:51 -07001196 {
1197 continue;
1198 }
Myung Bae7f3726a2025-04-26 15:17:23 -05001199
Ed Tanous898f2aa2024-08-07 12:18:22 -07001200 for (const auto& interfaceMap : objectPath.second)
Ed Tanousb7290962024-08-07 11:09:51 -07001201 {
Ed Tanous898f2aa2024-08-07 12:18:22 -07001202 for (const auto& propertyMap : interfaceMap.second)
Ed Tanousb7290962024-08-07 11:09:51 -07001203 {
Ed Tanous898f2aa2024-08-07 12:18:22 -07001204 propsFlattened.emplace_back(propertyMap.first,
1205 propertyMap.second);
Ed Tanousb7290962024-08-07 11:09:51 -07001206 }
1207 }
Myung Bae7f3726a2025-04-26 15:17:23 -05001208 std::optional<DbusEventLogEntry> optEntry =
1209 fillDbusEventLogEntryFromPropertyMap(propsFlattened);
1210
1211 if (!optEntry.has_value())
Igor Kanyuka90896602025-03-13 08:52:38 +00001212 {
Myung Bae7f3726a2025-04-26 15:17:23 -05001213 messages::internalError(asyncResp->res);
Igor Kanyuka90896602025-03-13 08:52:38 +00001214 return;
1215 }
Myung Bae7f3726a2025-04-26 15:17:23 -05001216 fillEventLogLogEntryFromDbusLogEntry(*optEntry,
1217 entriesArray.emplace_back());
Ed Tanousb7290962024-08-07 11:09:51 -07001218 }
Ed Tanous898f2aa2024-08-07 12:18:22 -07001219
Igor Kanyuka90896602025-03-13 08:52:38 +00001220 redfish::json_util::sortJsonArrayByKey(entriesArray, "Id");
Ed Tanousb7290962024-08-07 11:09:51 -07001221 asyncResp->res.jsonValue["Members@odata.count"] = entriesArray.size();
1222 asyncResp->res.jsonValue["Members"] = std::move(entriesArray);
1223}
1224
Alexander Hansen599b9af2024-08-06 15:11:57 +02001225inline void dBusEventLogEntryCollection(
1226 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1227{
1228 // Collections don't include the static data added by SubRoute
1229 // because it has a duplicate entry for members
1230 asyncResp->res.jsonValue["@odata.type"] =
1231 "#LogEntryCollection.LogEntryCollection";
1232 asyncResp->res.jsonValue["@odata.id"] =
1233 std::format("/redfish/v1/Systems/{}/LogServices/EventLog/Entries",
1234 BMCWEB_REDFISH_SYSTEM_URI_NAME);
1235 asyncResp->res.jsonValue["Name"] = "System Event Log Entries";
1236 asyncResp->res.jsonValue["Description"] =
1237 "Collection of System Event Log Entries";
1238
1239 // DBus implementation of EventLog/Entries
1240 // Make call to Logging Service to find all log entry objects
1241 sdbusplus::message::object_path path("/xyz/openbmc_project/logging");
1242 dbus::utility::getManagedObjects(
1243 "xyz.openbmc_project.Logging", path,
1244 [asyncResp](const boost::system::error_code& ec,
1245 const dbus::utility::ManagedObjectType& resp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001246 afterLogEntriesGetManagedObjects(asyncResp, ec, resp);
1247 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001248}
1249
1250inline void requestRoutesDBusEventLogEntryCollection(App& app)
1251{
Ed Tanous22d268c2022-05-19 09:39:07 -07001252 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/")
Ed Tanoused398212021-06-09 17:05:54 -07001253 .privileges(redfish::privileges::getLogEntryCollection)
Ed Tanous002d39b2022-05-31 08:59:27 -07001254 .methods(boost::beast::http::verb::get)(
1255 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07001256 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1257 const std::string& systemName) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001258 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1259 {
1260 return;
1261 }
1262 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1263 {
1264 // Option currently returns no systems. TBD
1265 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1266 systemName);
1267 return;
1268 }
1269 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1270 {
1271 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1272 systemName);
1273 return;
1274 }
1275 dBusEventLogEntryCollection(asyncResp);
1276 });
Alexander Hansen599b9af2024-08-06 15:11:57 +02001277}
Ed Tanous22d268c2022-05-19 09:39:07 -07001278
Myung Baec6b7cae2025-06-05 15:46:57 -05001279inline void afterDBusEventLogEntryGet(
1280 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1281 const std::string& entryID, const boost::system::error_code& ec,
1282 const dbus::utility::DBusPropertiesMap& resp)
1283{
1284 if (ec.value() == EBADR)
1285 {
1286 messages::resourceNotFound(asyncResp->res, "EventLogEntry", entryID);
1287 return;
1288 }
1289 if (ec)
1290 {
1291 BMCWEB_LOG_ERROR("EventLogEntry (DBus) resp_handler got error {}", ec);
1292 messages::internalError(asyncResp->res);
1293 return;
1294 }
1295
Myung Bae7f3726a2025-04-26 15:17:23 -05001296 std::optional<DbusEventLogEntry> optEntry =
1297 fillDbusEventLogEntryFromPropertyMap(resp);
1298
1299 if (!optEntry.has_value())
1300 {
1301 messages::internalError(asyncResp->res);
1302 return;
1303 }
1304
1305 fillEventLogLogEntryFromDbusLogEntry(*optEntry, asyncResp->res.jsonValue);
Myung Baec6b7cae2025-06-05 15:46:57 -05001306}
1307
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001308inline void dBusEventLogEntryGet(
1309 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::string entryID)
Alexander Hansen599b9af2024-08-06 15:11:57 +02001310{
1311 dbus::utility::escapePathForDbus(entryID);
Ed Tanous002d39b2022-05-31 08:59:27 -07001312
Alexander Hansen599b9af2024-08-06 15:11:57 +02001313 // DBus implementation of EventLog/Entries
1314 // Make call to Logging Service to find all log entry objects
Ed Tanousdeae6a72024-11-11 21:58:57 -08001315 dbus::utility::getAllProperties(
1316 "xyz.openbmc_project.Logging",
Alexander Hansen599b9af2024-08-06 15:11:57 +02001317 "/xyz/openbmc_project/logging/entry/" + entryID, "",
Myung Baec6b7cae2025-06-05 15:46:57 -05001318 std::bind_front(afterDBusEventLogEntryGet, asyncResp, entryID));
Alexander Hansen599b9af2024-08-06 15:11:57 +02001319}
1320
Patrick Williams504af5a2025-02-03 14:29:03 -05001321inline void dBusEventLogEntryPatch(
1322 const crow::Request& req,
1323 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1324 const std::string& entryId)
Alexander Hansen599b9af2024-08-06 15:11:57 +02001325{
1326 std::optional<bool> resolved;
1327
1328 if (!json_util::readJsonPatch(req, asyncResp->res, "Resolved", resolved))
1329 {
1330 return;
1331 }
1332 BMCWEB_LOG_DEBUG("Set Resolved");
1333
1334 setDbusProperty(asyncResp, "Resolved", "xyz.openbmc_project.Logging",
1335 "/xyz/openbmc_project/logging/entry/" + entryId,
1336 "xyz.openbmc_project.Logging.Entry", "Resolved",
1337 resolved.value_or(false));
1338}
1339
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001340inline void dBusEventLogEntryDelete(
1341 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::string entryID)
Alexander Hansen599b9af2024-08-06 15:11:57 +02001342{
1343 BMCWEB_LOG_DEBUG("Do delete single event entries.");
1344
1345 dbus::utility::escapePathForDbus(entryID);
1346
1347 // Process response from Logging service.
1348 auto respHandler = [asyncResp,
1349 entryID](const boost::system::error_code& ec) {
1350 BMCWEB_LOG_DEBUG("EventLogEntry (DBus) doDelete callback: Done");
1351 if (ec)
1352 {
1353 if (ec.value() == EBADR)
Ed Tanous45ca1b82022-03-25 13:07:27 -07001354 {
Alexander Hansen599b9af2024-08-06 15:11:57 +02001355 messages::resourceNotFound(asyncResp->res, "LogEntry", entryID);
Ed Tanous45ca1b82022-03-25 13:07:27 -07001356 return;
1357 }
Alexander Hansen599b9af2024-08-06 15:11:57 +02001358 // TODO Handle for specific error code
1359 BMCWEB_LOG_ERROR(
1360 "EventLogEntry (DBus) doDelete respHandler got error {}", ec);
1361 asyncResp->res.result(
1362 boost::beast::http::status::internal_server_error);
1363 return;
1364 }
Abhishek Patel9017faf2021-09-14 22:48:55 -05001365
Alexander Hansen599b9af2024-08-06 15:11:57 +02001366 asyncResp->res.result(boost::beast::http::status::ok);
1367 };
1368
1369 // Make call to Logging service to request Delete Log
Ed Tanous177612a2025-02-14 15:16:09 -08001370 dbus::utility::async_method_call(
1371 asyncResp, respHandler, "xyz.openbmc_project.Logging",
Alexander Hansen599b9af2024-08-06 15:11:57 +02001372 "/xyz/openbmc_project/logging/entry/" + entryID,
1373 "xyz.openbmc_project.Object.Delete", "Delete");
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001374}
Xiaochao Ma75710de2021-01-21 17:56:02 +08001375
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001376inline void requestRoutesDBusEventLogEntry(App& app)
Adriana Kobylak400fd1f2021-01-29 09:01:30 -06001377{
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001378 BMCWEB_ROUTE(
Ed Tanous22d268c2022-05-19 09:39:07 -07001379 app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001380 .privileges(redfish::privileges::getLogEntry)
Ed Tanous002d39b2022-05-31 08:59:27 -07001381 .methods(boost::beast::http::verb::get)(
1382 [&app](const crow::Request& req,
1383 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous898f2aa2024-08-07 12:18:22 -07001384 const std::string& systemName, const std::string& entryId) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001385 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1386 {
1387 return;
1388 }
1389 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1390 {
1391 // Option currently returns no systems. TBD
1392 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1393 systemName);
1394 return;
1395 }
1396 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1397 {
1398 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1399 systemName);
1400 return;
1401 }
Ed Tanous22d268c2022-05-19 09:39:07 -07001402
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001403 dBusEventLogEntryGet(asyncResp, entryId);
1404 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001405
1406 BMCWEB_ROUTE(
Ed Tanous22d268c2022-05-19 09:39:07 -07001407 app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001408 .privileges(redfish::privileges::patchLogEntry)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001409 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07001410 [&app](const crow::Request& req,
1411 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous22d268c2022-05-19 09:39:07 -07001412 const std::string& systemName, const std::string& entryId) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001413 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1414 {
1415 return;
1416 }
1417 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1418 {
1419 // Option currently returns no systems. TBD
1420 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1421 systemName);
1422 return;
1423 }
1424 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1425 {
1426 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1427 systemName);
1428 return;
1429 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001430
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001431 dBusEventLogEntryPatch(req, asyncResp, entryId);
1432 });
Adriana Kobylak400fd1f2021-01-29 09:01:30 -06001433
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001434 BMCWEB_ROUTE(
Ed Tanous22d268c2022-05-19 09:39:07 -07001435 app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/")
Abhishek Patelfff6a4d2021-07-21 11:29:45 -05001436 .privileges(
1437 redfish::privileges::
1438 deleteLogEntrySubOverComputerSystemLogServiceCollectionLogServiceLogEntryCollection)
Ed Tanous002d39b2022-05-31 08:59:27 -07001439 .methods(boost::beast::http::verb::delete_)(
1440 [&app](const crow::Request& req,
1441 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous22d268c2022-05-19 09:39:07 -07001442 const std::string& systemName, const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001443 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1444 {
1445 return;
1446 }
1447 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1448 {
1449 // Option currently returns no systems. TBD
1450 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1451 systemName);
1452 return;
1453 }
1454 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
1455 {
1456 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1457 systemName);
1458 return;
1459 }
1460 dBusEventLogEntryDelete(asyncResp, param);
1461 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001462}
1463
Claire Weinandd72e872022-08-15 14:20:06 -07001464inline void handleBMCLogServicesCollectionGet(
Claire Weinanfdd26902022-03-01 14:18:25 -08001465 crow::App& app, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001466 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1467 const std::string& managerId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001468{
1469 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1470 {
1471 return;
1472 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001473
1474 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1475 {
1476 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1477 return;
1478 }
1479
Claire Weinanfdd26902022-03-01 14:18:25 -08001480 // Collections don't include the static data added by SubRoute
1481 // because it has a duplicate entry for members
1482 asyncResp->res.jsonValue["@odata.type"] =
1483 "#LogServiceCollection.LogServiceCollection";
Ed Tanous253f11b2024-05-16 09:38:31 -07001484 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
1485 "/redfish/v1/Managers/{}/LogServices", BMCWEB_REDFISH_MANAGER_URI_NAME);
Claire Weinanfdd26902022-03-01 14:18:25 -08001486 asyncResp->res.jsonValue["Name"] = "Open BMC Log Services Collection";
1487 asyncResp->res.jsonValue["Description"] =
1488 "Collection of LogServices for this Manager";
1489 nlohmann::json& logServiceArray = asyncResp->res.jsonValue["Members"];
1490 logServiceArray = nlohmann::json::array();
1491
Ed Tanous25b54db2024-04-17 15:40:31 -07001492 if constexpr (BMCWEB_REDFISH_BMC_JOURNAL)
1493 {
1494 nlohmann::json::object_t journal;
Ed Tanous253f11b2024-05-16 09:38:31 -07001495 journal["@odata.id"] =
1496 boost::urls::format("/redfish/v1/Managers/{}/LogServices/Journal",
1497 BMCWEB_REDFISH_MANAGER_URI_NAME);
Ed Tanous25b54db2024-04-17 15:40:31 -07001498 logServiceArray.emplace_back(std::move(journal));
1499 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001500
1501 asyncResp->res.jsonValue["Members@odata.count"] = logServiceArray.size();
1502
Ed Tanous25b54db2024-04-17 15:40:31 -07001503 if constexpr (BMCWEB_REDFISH_DUMP_LOG)
1504 {
1505 constexpr std::array<std::string_view, 1> interfaces = {
1506 "xyz.openbmc_project.Collection.DeleteAll"};
1507 dbus::utility::getSubTreePaths(
1508 "/xyz/openbmc_project/dump", 0, interfaces,
1509 [asyncResp](const boost::system::error_code& ec,
1510 const dbus::utility::MapperGetSubTreePathsResponse&
1511 subTreePaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001512 if (ec)
Ed Tanous25b54db2024-04-17 15:40:31 -07001513 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001514 BMCWEB_LOG_ERROR(
1515 "handleBMCLogServicesCollectionGet respHandler got error {}",
1516 ec);
1517 // Assume that getting an error simply means there are no
1518 // dump LogServices. Return without adding any error
1519 // response.
1520 return;
Ed Tanous25b54db2024-04-17 15:40:31 -07001521 }
Ed Tanous25b54db2024-04-17 15:40:31 -07001522
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001523 nlohmann::json& logServiceArrayLocal =
1524 asyncResp->res.jsonValue["Members"];
1525
1526 for (const std::string& path : subTreePaths)
1527 {
1528 if (path == "/xyz/openbmc_project/dump/bmc")
1529 {
1530 nlohmann::json::object_t member;
1531 member["@odata.id"] = boost::urls::format(
1532 "/redfish/v1/Managers/{}/LogServices/Dump",
1533 BMCWEB_REDFISH_MANAGER_URI_NAME);
1534 logServiceArrayLocal.emplace_back(std::move(member));
1535 }
1536 else if (path == "/xyz/openbmc_project/dump/faultlog")
1537 {
1538 nlohmann::json::object_t member;
1539 member["@odata.id"] = boost::urls::format(
1540 "/redfish/v1/Managers/{}/LogServices/FaultLog",
1541 BMCWEB_REDFISH_MANAGER_URI_NAME);
1542 logServiceArrayLocal.emplace_back(std::move(member));
1543 }
1544 }
1545
1546 asyncResp->res.jsonValue["Members@odata.count"] =
1547 logServiceArrayLocal.size();
1548 });
Ed Tanous25b54db2024-04-17 15:40:31 -07001549 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001550}
1551
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001552inline void requestRoutesBMCLogServiceCollection(App& app)
1553{
Ed Tanous253f11b2024-05-16 09:38:31 -07001554 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/")
Gunnar Millsad89dcf2021-07-30 14:40:11 -05001555 .privileges(redfish::privileges::getLogServiceCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001556 .methods(boost::beast::http::verb::get)(
Claire Weinandd72e872022-08-15 14:20:06 -07001557 std::bind_front(handleBMCLogServicesCollectionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001558}
Ed Tanous1da66f72018-07-27 16:13:37 -07001559
Patrick Williams504af5a2025-02-03 14:29:03 -05001560inline void getDumpServiceInfo(
1561 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1562 const std::string& dumpType)
Claire Weinanfdd26902022-03-01 14:18:25 -08001563{
1564 std::string dumpPath;
Ed Tanous539d8c62024-06-19 14:38:27 -07001565 log_service::OverWritePolicy overWritePolicy =
1566 log_service::OverWritePolicy::Invalid;
Claire Weinanfdd26902022-03-01 14:18:25 -08001567 bool collectDiagnosticDataSupported = false;
1568
1569 if (dumpType == "BMC")
1570 {
Ed Tanous253f11b2024-05-16 09:38:31 -07001571 dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/Dump",
1572 BMCWEB_REDFISH_MANAGER_URI_NAME);
Ed Tanous539d8c62024-06-19 14:38:27 -07001573 overWritePolicy = log_service::OverWritePolicy::WrapsWhenFull;
Claire Weinanfdd26902022-03-01 14:18:25 -08001574 collectDiagnosticDataSupported = true;
1575 }
1576 else if (dumpType == "FaultLog")
1577 {
Ed Tanous253f11b2024-05-16 09:38:31 -07001578 dumpPath = std::format("/redfish/v1/Managers/{}/LogServices/FaultLog",
1579 BMCWEB_REDFISH_MANAGER_URI_NAME);
Ed Tanous539d8c62024-06-19 14:38:27 -07001580 overWritePolicy = log_service::OverWritePolicy::Unknown;
Claire Weinanfdd26902022-03-01 14:18:25 -08001581 collectDiagnosticDataSupported = false;
1582 }
1583 else if (dumpType == "System")
1584 {
Ed Tanous253f11b2024-05-16 09:38:31 -07001585 dumpPath = std::format("/redfish/v1/Systems/{}/LogServices/Dump",
1586 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanous539d8c62024-06-19 14:38:27 -07001587 overWritePolicy = log_service::OverWritePolicy::WrapsWhenFull;
Claire Weinanfdd26902022-03-01 14:18:25 -08001588 collectDiagnosticDataSupported = true;
1589 }
1590 else
1591 {
Ed Tanous62598e32023-07-17 17:06:25 -07001592 BMCWEB_LOG_ERROR("getDumpServiceInfo() invalid dump type: {}",
1593 dumpType);
Claire Weinanfdd26902022-03-01 14:18:25 -08001594 messages::internalError(asyncResp->res);
1595 return;
1596 }
1597
1598 asyncResp->res.jsonValue["@odata.id"] = dumpPath;
1599 asyncResp->res.jsonValue["@odata.type"] = "#LogService.v1_2_0.LogService";
1600 asyncResp->res.jsonValue["Name"] = "Dump LogService";
1601 asyncResp->res.jsonValue["Description"] = dumpType + " Dump LogService";
1602 asyncResp->res.jsonValue["Id"] = std::filesystem::path(dumpPath).filename();
Ed Tanous539d8c62024-06-19 14:38:27 -07001603 asyncResp->res.jsonValue["OverWritePolicy"] = overWritePolicy;
Claire Weinanfdd26902022-03-01 14:18:25 -08001604
1605 std::pair<std::string, std::string> redfishDateTimeOffset =
Ed Tanous2b829372022-08-03 14:22:34 -07001606 redfish::time_utils::getDateTimeOffsetNow();
Claire Weinanfdd26902022-03-01 14:18:25 -08001607 asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
1608 asyncResp->res.jsonValue["DateTimeLocalOffset"] =
1609 redfishDateTimeOffset.second;
1610
1611 asyncResp->res.jsonValue["Entries"]["@odata.id"] = dumpPath + "/Entries";
Claire Weinanfdd26902022-03-01 14:18:25 -08001612
1613 if (collectDiagnosticDataSupported)
1614 {
1615 asyncResp->res.jsonValue["Actions"]["#LogService.CollectDiagnosticData"]
1616 ["target"] =
1617 dumpPath + "/Actions/LogService.CollectDiagnosticData";
1618 }
Claire Weinan0d946212022-07-13 19:40:19 -07001619
1620 constexpr std::array<std::string_view, 1> interfaces = {deleteAllInterface};
1621 dbus::utility::getSubTreePaths(
1622 "/xyz/openbmc_project/dump", 0, interfaces,
1623 [asyncResp, dumpType, dumpPath](
1624 const boost::system::error_code& ec,
1625 const dbus::utility::MapperGetSubTreePathsResponse& subTreePaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001626 if (ec)
Claire Weinan0d946212022-07-13 19:40:19 -07001627 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001628 BMCWEB_LOG_ERROR("getDumpServiceInfo respHandler got error {}",
1629 ec);
1630 // Assume that getting an error simply means there are no dump
1631 // LogServices. Return without adding any error response.
1632 return;
Claire Weinan0d946212022-07-13 19:40:19 -07001633 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001634 std::string dbusDumpPath = getDumpPath(dumpType);
1635 for (const std::string& path : subTreePaths)
1636 {
1637 if (path == dbusDumpPath)
1638 {
1639 asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]
1640 ["target"] =
1641 dumpPath + "/Actions/LogService.ClearLog";
1642 break;
1643 }
1644 }
1645 });
Claire Weinanfdd26902022-03-01 14:18:25 -08001646}
1647
1648inline void handleLogServicesDumpServiceGet(
1649 crow::App& app, const std::string& dumpType, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001650 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1651 const std::string& managerId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001652{
1653 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1654 {
1655 return;
1656 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001657
1658 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1659 {
1660 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1661 return;
1662 }
1663
Claire Weinanfdd26902022-03-01 14:18:25 -08001664 getDumpServiceInfo(asyncResp, dumpType);
1665}
1666
Ed Tanous22d268c2022-05-19 09:39:07 -07001667inline void handleLogServicesDumpServiceComputerSystemGet(
1668 crow::App& app, const crow::Request& req,
1669 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1670 const std::string& chassisId)
1671{
1672 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1673 {
1674 return;
1675 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001676 if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous22d268c2022-05-19 09:39:07 -07001677 {
1678 messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
1679 return;
1680 }
1681 getDumpServiceInfo(asyncResp, "System");
1682}
1683
Claire Weinanfdd26902022-03-01 14:18:25 -08001684inline void handleLogServicesDumpEntriesCollectionGet(
1685 crow::App& app, const std::string& dumpType, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001686 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1687 const std::string& managerId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001688{
1689 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1690 {
1691 return;
1692 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001693
1694 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1695 {
1696 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1697 return;
1698 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001699 getDumpEntryCollection(asyncResp, dumpType);
1700}
1701
Ed Tanous22d268c2022-05-19 09:39:07 -07001702inline void handleLogServicesDumpEntriesCollectionComputerSystemGet(
1703 crow::App& app, const crow::Request& req,
1704 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1705 const std::string& chassisId)
1706{
1707 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1708 {
1709 return;
1710 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001711 if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous22d268c2022-05-19 09:39:07 -07001712 {
1713 messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
1714 return;
1715 }
1716 getDumpEntryCollection(asyncResp, "System");
1717}
1718
Claire Weinanfdd26902022-03-01 14:18:25 -08001719inline void handleLogServicesDumpEntryGet(
1720 crow::App& app, const std::string& dumpType, const crow::Request& req,
1721 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous253f11b2024-05-16 09:38:31 -07001722 const std::string& managerId, const std::string& dumpId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001723{
1724 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1725 {
1726 return;
1727 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001728 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1729 {
1730 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1731 return;
1732 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001733 getDumpEntryById(asyncResp, dumpId, dumpType);
1734}
Carson Labrado168d1b12023-03-27 17:04:46 +00001735
Ed Tanous22d268c2022-05-19 09:39:07 -07001736inline void handleLogServicesDumpEntryComputerSystemGet(
1737 crow::App& app, const crow::Request& req,
1738 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1739 const std::string& chassisId, const std::string& dumpId)
1740{
1741 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1742 {
1743 return;
1744 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001745 if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous22d268c2022-05-19 09:39:07 -07001746 {
1747 messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
1748 return;
1749 }
1750 getDumpEntryById(asyncResp, dumpId, "System");
1751}
Claire Weinanfdd26902022-03-01 14:18:25 -08001752
1753inline void handleLogServicesDumpEntryDelete(
1754 crow::App& app, const std::string& dumpType, const crow::Request& req,
1755 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous253f11b2024-05-16 09:38:31 -07001756 const std::string& managerId, const std::string& dumpId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001757{
1758 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1759 {
1760 return;
1761 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001762
1763 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1764 {
1765 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1766 return;
1767 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001768 deleteDumpEntry(asyncResp, dumpId, dumpType);
1769}
1770
Ed Tanous22d268c2022-05-19 09:39:07 -07001771inline void handleLogServicesDumpEntryComputerSystemDelete(
1772 crow::App& app, const crow::Request& req,
1773 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1774 const std::string& chassisId, const std::string& dumpId)
1775{
1776 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1777 {
1778 return;
1779 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001780 if (chassisId != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous22d268c2022-05-19 09:39:07 -07001781 {
1782 messages::resourceNotFound(asyncResp->res, "ComputerSystem", chassisId);
1783 return;
1784 }
1785 deleteDumpEntry(asyncResp, dumpId, "System");
1786}
1787
Carson Labrado168d1b12023-03-27 17:04:46 +00001788inline void handleLogServicesDumpEntryDownloadGet(
1789 crow::App& app, const std::string& dumpType, const crow::Request& req,
1790 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous253f11b2024-05-16 09:38:31 -07001791 const std::string& managerId, const std::string& dumpId)
Carson Labrado168d1b12023-03-27 17:04:46 +00001792{
1793 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1794 {
1795 return;
1796 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001797
1798 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1799 {
1800 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1801 return;
1802 }
Carson Labrado168d1b12023-03-27 17:04:46 +00001803 downloadDumpEntry(asyncResp, dumpId, dumpType);
1804}
1805
1806inline void handleDBusEventLogEntryDownloadGet(
1807 crow::App& app, const std::string& dumpType, const crow::Request& req,
1808 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1809 const std::string& systemName, const std::string& entryID)
1810{
1811 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1812 {
1813 return;
1814 }
1815 if (!http_helpers::isContentTypeAllowed(
1816 req.getHeaderValue("Accept"),
1817 http_helpers::ContentType::OctetStream, true))
1818 {
1819 asyncResp->res.result(boost::beast::http::status::bad_request);
1820 return;
1821 }
1822 downloadEventLogEntry(asyncResp, systemName, entryID, dumpType);
1823}
1824
Claire Weinanfdd26902022-03-01 14:18:25 -08001825inline void handleLogServicesDumpCollectDiagnosticDataPost(
1826 crow::App& app, const std::string& dumpType, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001827 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1828 const std::string& managerId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001829{
1830 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1831 {
1832 return;
1833 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001834 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1835 {
1836 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1837 return;
1838 }
1839
Claire Weinanfdd26902022-03-01 14:18:25 -08001840 createDump(asyncResp, req, dumpType);
1841}
1842
Ed Tanous22d268c2022-05-19 09:39:07 -07001843inline void handleLogServicesDumpCollectDiagnosticDataComputerSystemPost(
1844 crow::App& app, const crow::Request& req,
1845 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001846 const std::string& systemName)
Ed Tanous22d268c2022-05-19 09:39:07 -07001847{
1848 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1849 {
1850 return;
1851 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001852
Ed Tanous25b54db2024-04-17 15:40:31 -07001853 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous22d268c2022-05-19 09:39:07 -07001854 {
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001855 // Option currently returns no systems. TBD
1856 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1857 systemName);
1858 return;
1859 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001860 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001861 {
1862 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1863 systemName);
Ed Tanous22d268c2022-05-19 09:39:07 -07001864 return;
1865 }
1866 createDump(asyncResp, req, "System");
1867}
1868
Claire Weinanfdd26902022-03-01 14:18:25 -08001869inline void handleLogServicesDumpClearLogPost(
1870 crow::App& app, const std::string& dumpType, const crow::Request& req,
Ed Tanous253f11b2024-05-16 09:38:31 -07001871 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1872 const std::string& managerId)
Claire Weinanfdd26902022-03-01 14:18:25 -08001873{
1874 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1875 {
1876 return;
1877 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001878
1879 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
1880 {
1881 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
1882 return;
1883 }
Claire Weinanfdd26902022-03-01 14:18:25 -08001884 clearDump(asyncResp, dumpType);
1885}
1886
Ed Tanous22d268c2022-05-19 09:39:07 -07001887inline void handleLogServicesDumpClearLogComputerSystemPost(
1888 crow::App& app, const crow::Request& req,
1889 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001890 const std::string& systemName)
Ed Tanous22d268c2022-05-19 09:39:07 -07001891{
1892 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1893 {
1894 return;
1895 }
Ed Tanous25b54db2024-04-17 15:40:31 -07001896 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous22d268c2022-05-19 09:39:07 -07001897 {
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001898 // Option currently returns no systems. TBD
1899 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1900 systemName);
1901 return;
1902 }
Ed Tanous253f11b2024-05-16 09:38:31 -07001903 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous7f3e84a2022-12-28 16:22:54 -08001904 {
1905 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1906 systemName);
Ed Tanous22d268c2022-05-19 09:39:07 -07001907 return;
1908 }
1909 clearDump(asyncResp, "System");
1910}
1911
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001912inline void requestRoutesBMCDumpService(App& app)
1913{
Ed Tanous253f11b2024-05-16 09:38:31 -07001914 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/Dump/")
Ed Tanoused398212021-06-09 17:05:54 -07001915 .privileges(redfish::privileges::getLogService)
Claire Weinanfdd26902022-03-01 14:18:25 -08001916 .methods(boost::beast::http::verb::get)(std::bind_front(
1917 handleLogServicesDumpServiceGet, std::ref(app), "BMC"));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001918}
1919
1920inline void requestRoutesBMCDumpEntryCollection(App& app)
1921{
Ed Tanous253f11b2024-05-16 09:38:31 -07001922 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/")
Ed Tanoused398212021-06-09 17:05:54 -07001923 .privileges(redfish::privileges::getLogEntryCollection)
Claire Weinanfdd26902022-03-01 14:18:25 -08001924 .methods(boost::beast::http::verb::get)(std::bind_front(
1925 handleLogServicesDumpEntriesCollectionGet, std::ref(app), "BMC"));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001926}
1927
1928inline void requestRoutesBMCDumpEntry(App& app)
1929{
1930 BMCWEB_ROUTE(app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001931 "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001932 .privileges(redfish::privileges::getLogEntry)
Claire Weinanfdd26902022-03-01 14:18:25 -08001933 .methods(boost::beast::http::verb::get)(std::bind_front(
1934 handleLogServicesDumpEntryGet, std::ref(app), "BMC"));
1935
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001936 BMCWEB_ROUTE(app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001937 "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07001938 .privileges(redfish::privileges::deleteLogEntry)
Claire Weinanfdd26902022-03-01 14:18:25 -08001939 .methods(boost::beast::http::verb::delete_)(std::bind_front(
1940 handleLogServicesDumpEntryDelete, std::ref(app), "BMC"));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001941}
1942
Carson Labrado168d1b12023-03-27 17:04:46 +00001943inline void requestRoutesBMCDumpEntryDownload(App& app)
1944{
1945 BMCWEB_ROUTE(
1946 app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001947 "/redfish/v1/Managers/<str>/LogServices/Dump/Entries/<str>/attachment/")
Carson Labrado168d1b12023-03-27 17:04:46 +00001948 .privileges(redfish::privileges::getLogEntry)
1949 .methods(boost::beast::http::verb::get)(std::bind_front(
1950 handleLogServicesDumpEntryDownloadGet, std::ref(app), "BMC"));
1951}
1952
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001953inline void requestRoutesBMCDumpCreate(App& app)
1954{
George Liu0fda0f12021-11-16 10:06:17 +08001955 BMCWEB_ROUTE(
1956 app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001957 "/redfish/v1/Managers/<str>/LogServices/Dump/Actions/LogService.CollectDiagnosticData/")
Ed Tanoused398212021-06-09 17:05:54 -07001958 .privileges(redfish::privileges::postLogService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001959 .methods(boost::beast::http::verb::post)(
Claire Weinanfdd26902022-03-01 14:18:25 -08001960 std::bind_front(handleLogServicesDumpCollectDiagnosticDataPost,
1961 std::ref(app), "BMC"));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07001962}
1963
1964inline void requestRoutesBMCDumpClear(App& app)
1965{
George Liu0fda0f12021-11-16 10:06:17 +08001966 BMCWEB_ROUTE(
1967 app,
Ed Tanous253f11b2024-05-16 09:38:31 -07001968 "/redfish/v1/Managers/<str>/LogServices/Dump/Actions/LogService.ClearLog/")
Ed Tanoused398212021-06-09 17:05:54 -07001969 .privileges(redfish::privileges::postLogService)
Claire Weinanfdd26902022-03-01 14:18:25 -08001970 .methods(boost::beast::http::verb::post)(std::bind_front(
1971 handleLogServicesDumpClearLogPost, std::ref(app), "BMC"));
1972}
1973
Carson Labrado168d1b12023-03-27 17:04:46 +00001974inline void requestRoutesDBusEventLogEntryDownload(App& app)
1975{
1976 BMCWEB_ROUTE(
1977 app,
Ravi Teja9e9d99d2023-11-08 05:33:59 -06001978 "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/attachment/")
Carson Labrado168d1b12023-03-27 17:04:46 +00001979 .privileges(redfish::privileges::getLogEntry)
1980 .methods(boost::beast::http::verb::get)(std::bind_front(
1981 handleDBusEventLogEntryDownloadGet, std::ref(app), "System"));
1982}
1983
Claire Weinanfdd26902022-03-01 14:18:25 -08001984inline void requestRoutesFaultLogDumpService(App& app)
1985{
Ed Tanous253f11b2024-05-16 09:38:31 -07001986 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/LogServices/FaultLog/")
Claire Weinanfdd26902022-03-01 14:18:25 -08001987 .privileges(redfish::privileges::getLogService)
1988 .methods(boost::beast::http::verb::get)(std::bind_front(
1989 handleLogServicesDumpServiceGet, std::ref(app), "FaultLog"));
1990}
1991
1992inline void requestRoutesFaultLogDumpEntryCollection(App& app)
1993{
Ed Tanous253f11b2024-05-16 09:38:31 -07001994 BMCWEB_ROUTE(app,
1995 "/redfish/v1/Managers/<str>/LogServices/FaultLog/Entries/")
Claire Weinanfdd26902022-03-01 14:18:25 -08001996 .privileges(redfish::privileges::getLogEntryCollection)
1997 .methods(boost::beast::http::verb::get)(
1998 std::bind_front(handleLogServicesDumpEntriesCollectionGet,
1999 std::ref(app), "FaultLog"));
2000}
2001
2002inline void requestRoutesFaultLogDumpEntry(App& app)
2003{
Ed Tanous253f11b2024-05-16 09:38:31 -07002004 BMCWEB_ROUTE(
2005 app, "/redfish/v1/Managers/<str>/LogServices/FaultLog/Entries/<str>/")
Claire Weinanfdd26902022-03-01 14:18:25 -08002006 .privileges(redfish::privileges::getLogEntry)
2007 .methods(boost::beast::http::verb::get)(std::bind_front(
2008 handleLogServicesDumpEntryGet, std::ref(app), "FaultLog"));
2009
Ed Tanous253f11b2024-05-16 09:38:31 -07002010 BMCWEB_ROUTE(
2011 app, "/redfish/v1/Managers/<str>/LogServices/FaultLog/Entries/<str>/")
Claire Weinanfdd26902022-03-01 14:18:25 -08002012 .privileges(redfish::privileges::deleteLogEntry)
2013 .methods(boost::beast::http::verb::delete_)(std::bind_front(
2014 handleLogServicesDumpEntryDelete, std::ref(app), "FaultLog"));
2015}
2016
2017inline void requestRoutesFaultLogDumpClear(App& app)
2018{
2019 BMCWEB_ROUTE(
2020 app,
Ed Tanous253f11b2024-05-16 09:38:31 -07002021 "/redfish/v1/Managers/<str>/LogServices/FaultLog/Actions/LogService.ClearLog/")
Claire Weinanfdd26902022-03-01 14:18:25 -08002022 .privileges(redfish::privileges::postLogService)
2023 .methods(boost::beast::http::verb::post)(std::bind_front(
2024 handleLogServicesDumpClearLogPost, std::ref(app), "FaultLog"));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002025}
2026
2027inline void requestRoutesSystemDumpService(App& app)
2028{
Ed Tanous22d268c2022-05-19 09:39:07 -07002029 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Dump/")
Ed Tanoused398212021-06-09 17:05:54 -07002030 .privileges(redfish::privileges::getLogService)
Claire Weinan6ab9ad52022-08-12 18:20:17 -07002031 .methods(boost::beast::http::verb::get)(std::bind_front(
Ed Tanous22d268c2022-05-19 09:39:07 -07002032 handleLogServicesDumpServiceComputerSystemGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002033}
2034
2035inline void requestRoutesSystemDumpEntryCollection(App& app)
2036{
Ed Tanous22d268c2022-05-19 09:39:07 -07002037 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/")
Ed Tanoused398212021-06-09 17:05:54 -07002038 .privileges(redfish::privileges::getLogEntryCollection)
Ed Tanous22d268c2022-05-19 09:39:07 -07002039 .methods(boost::beast::http::verb::get)(std::bind_front(
2040 handleLogServicesDumpEntriesCollectionComputerSystemGet,
2041 std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002042}
2043
2044inline void requestRoutesSystemDumpEntry(App& app)
2045{
2046 BMCWEB_ROUTE(app,
Ed Tanous22d268c2022-05-19 09:39:07 -07002047 "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07002048 .privileges(redfish::privileges::getLogEntry)
Claire Weinan6ab9ad52022-08-12 18:20:17 -07002049 .methods(boost::beast::http::verb::get)(std::bind_front(
Ed Tanous22d268c2022-05-19 09:39:07 -07002050 handleLogServicesDumpEntryComputerSystemGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002051
2052 BMCWEB_ROUTE(app,
Ed Tanous22d268c2022-05-19 09:39:07 -07002053 "/redfish/v1/Systems/<str>/LogServices/Dump/Entries/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07002054 .privileges(redfish::privileges::deleteLogEntry)
Claire Weinan6ab9ad52022-08-12 18:20:17 -07002055 .methods(boost::beast::http::verb::delete_)(std::bind_front(
Ed Tanous22d268c2022-05-19 09:39:07 -07002056 handleLogServicesDumpEntryComputerSystemDelete, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002057}
2058
2059inline void requestRoutesSystemDumpCreate(App& app)
2060{
George Liu0fda0f12021-11-16 10:06:17 +08002061 BMCWEB_ROUTE(
2062 app,
Ed Tanous22d268c2022-05-19 09:39:07 -07002063 "/redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.CollectDiagnosticData/")
Abhishek Patelfff6a4d2021-07-21 11:29:45 -05002064 .privileges(redfish::privileges::
2065 postLogServiceSubOverComputerSystemLogServiceCollection)
Ed Tanous22d268c2022-05-19 09:39:07 -07002066 .methods(boost::beast::http::verb::post)(std::bind_front(
2067 handleLogServicesDumpCollectDiagnosticDataComputerSystemPost,
2068 std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002069}
2070
2071inline void requestRoutesSystemDumpClear(App& app)
2072{
George Liu0fda0f12021-11-16 10:06:17 +08002073 BMCWEB_ROUTE(
2074 app,
Ed Tanous22d268c2022-05-19 09:39:07 -07002075 "/redfish/v1/Systems/<str>/LogServices/Dump/Actions/LogService.ClearLog/")
Abhishek Patelfff6a4d2021-07-21 11:29:45 -05002076 .privileges(redfish::privileges::
2077 postLogServiceSubOverComputerSystemLogServiceCollection)
Claire Weinan6ab9ad52022-08-12 18:20:17 -07002078 .methods(boost::beast::http::verb::post)(std::bind_front(
Ed Tanous22d268c2022-05-19 09:39:07 -07002079 handleLogServicesDumpClearLogComputerSystemPost, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002080}
2081
2082inline void requestRoutesCrashdumpService(App& app)
2083{
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002084 /**
2085 * Functions triggers appropriate requests on DBus
2086 */
Ed Tanous22d268c2022-05-19 09:39:07 -07002087 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/Crashdump/")
Myung Bae50d9f382025-06-13 09:40:18 -04002088 .privileges(redfish::privileges::getLogService)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002089 .methods(
2090 boost::beast::http::verb::
2091 get)([&app](const crow::Request& req,
2092 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2093 const std::string& systemName) {
2094 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2095 {
2096 return;
2097 }
2098 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
2099 {
2100 // Option currently returns no systems. TBD
2101 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2102 systemName);
2103 return;
2104 }
2105 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2106 {
2107 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2108 systemName);
2109 return;
2110 }
Ed Tanous22d268c2022-05-19 09:39:07 -07002111
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002112 // Copy over the static data to include the entries added by
2113 // SubRoute
2114 asyncResp->res.jsonValue["@odata.id"] =
2115 std::format("/redfish/v1/Systems/{}/LogServices/Crashdump",
2116 BMCWEB_REDFISH_SYSTEM_URI_NAME);
2117 asyncResp->res.jsonValue["@odata.type"] =
2118 "#LogService.v1_2_0.LogService";
2119 asyncResp->res.jsonValue["Name"] = "Open BMC Oem Crashdump Service";
2120 asyncResp->res.jsonValue["Description"] = "Oem Crashdump Service";
2121 asyncResp->res.jsonValue["Id"] = "Crashdump";
2122 asyncResp->res.jsonValue["OverWritePolicy"] =
2123 log_service::OverWritePolicy::WrapsWhenFull;
2124 asyncResp->res.jsonValue["MaxNumberOfRecords"] = 3;
Tejas Patil7c8c4052021-06-04 17:43:14 +05302125
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002126 std::pair<std::string, std::string> redfishDateTimeOffset =
2127 redfish::time_utils::getDateTimeOffsetNow();
2128 asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
2129 asyncResp->res.jsonValue["DateTimeLocalOffset"] =
2130 redfishDateTimeOffset.second;
Tejas Patil7c8c4052021-06-04 17:43:14 +05302131
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002132 asyncResp->res.jsonValue["Entries"]["@odata.id"] = std::format(
2133 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries",
2134 BMCWEB_REDFISH_SYSTEM_URI_NAME);
2135 asyncResp->res.jsonValue["Actions"]["#LogService.ClearLog"]
2136 ["target"] = std::format(
2137 "/redfish/v1/Systems/{}/LogServices/Crashdump/Actions/LogService.ClearLog",
2138 BMCWEB_REDFISH_SYSTEM_URI_NAME);
2139 asyncResp->res
2140 .jsonValue["Actions"]["#LogService.CollectDiagnosticData"]
2141 ["target"] = std::format(
2142 "/redfish/v1/Systems/{}/LogServices/Crashdump/Actions/LogService.CollectDiagnosticData",
2143 BMCWEB_REDFISH_SYSTEM_URI_NAME);
2144 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002145}
2146
Ed Tanous8e4736b2025-08-19 10:14:02 -07002147inline void requestRoutesCrashdumpClear(App& app)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002148{
George Liu0fda0f12021-11-16 10:06:17 +08002149 BMCWEB_ROUTE(
2150 app,
Ed Tanous22d268c2022-05-19 09:39:07 -07002151 "/redfish/v1/Systems/<str>/LogServices/Crashdump/Actions/LogService.ClearLog/")
Myung Bae50d9f382025-06-13 09:40:18 -04002152 .privileges(redfish::privileges::
2153 postLogServiceSubOverComputerSystemLogServiceCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002154 .methods(boost::beast::http::verb::post)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07002155 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07002156 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2157 const std::string& systemName) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002158 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2159 {
2160 return;
2161 }
2162 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
2163 {
2164 // Option currently returns no systems. TBD
2165 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2166 systemName);
2167 return;
2168 }
2169 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2170 {
2171 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2172 systemName);
2173 return;
2174 }
Ed Tanous177612a2025-02-14 15:16:09 -08002175 dbus::utility::async_method_call(
2176 asyncResp,
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002177 [asyncResp](const boost::system::error_code& ec,
2178 const std::string&) {
2179 if (ec)
2180 {
2181 messages::internalError(asyncResp->res);
2182 return;
2183 }
2184 messages::success(asyncResp->res);
2185 },
2186 crashdumpObject, crashdumpPath, deleteAllInterface,
2187 "DeleteAll");
2188 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002189}
Jason M. Bills5b61b5e2019-10-16 10:59:02 -07002190
Patrick Williams504af5a2025-02-03 14:29:03 -05002191inline void logCrashdumpEntry(
2192 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2193 const std::string& logID, nlohmann::json& logEntryJson)
Jason M. Billse855dd22019-10-08 11:37:48 -07002194{
Johnathan Mantey043a0532020-03-10 17:15:28 -07002195 auto getStoredLogCallback =
Ed Tanousb9d36b42022-02-26 21:42:46 -08002196 [asyncResp, logID,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002197 &logEntryJson](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002198 const dbus::utility::DBusPropertiesMap& params) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002199 if (ec)
2200 {
2201 BMCWEB_LOG_DEBUG("failed to get log ec: {}", ec.message());
2202 if (ec.value() ==
2203 boost::system::linux_error::bad_request_descriptor)
2204 {
2205 messages::resourceNotFound(asyncResp->res, "LogEntry",
2206 logID);
2207 }
2208 else
2209 {
2210 messages::internalError(asyncResp->res);
2211 }
2212 return;
2213 }
2214
2215 std::string timestamp{};
2216 std::string filename{};
2217 std::string logfile{};
2218 parseCrashdumpParameters(params, filename, timestamp, logfile);
2219
2220 if (filename.empty() || timestamp.empty())
Jason M. Bills1ddcf012019-11-26 14:59:21 -08002221 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002222 messages::resourceNotFound(asyncResp->res, "LogEntry", logID);
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002223 return;
2224 }
2225
2226 std::string crashdumpURI =
2227 std::format(
2228 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries/",
2229 BMCWEB_REDFISH_SYSTEM_URI_NAME) +
2230 logID + "/" + filename;
2231 nlohmann::json::object_t logEntry;
2232 logEntry["@odata.type"] = "#LogEntry.v1_9_0.LogEntry";
2233 logEntry["@odata.id"] = boost::urls::format(
2234 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries/{}",
2235 BMCWEB_REDFISH_SYSTEM_URI_NAME, logID);
2236 logEntry["Name"] = "CPU Crashdump";
2237 logEntry["Id"] = logID;
2238 logEntry["EntryType"] = log_entry::LogEntryType::Oem;
2239 logEntry["AdditionalDataURI"] = std::move(crashdumpURI);
2240 logEntry["DiagnosticDataType"] = "OEM";
2241 logEntry["OEMDiagnosticDataType"] = "PECICrashdump";
2242 logEntry["Created"] = std::move(timestamp);
2243
2244 // If logEntryJson references an array of LogEntry resources
2245 // ('Members' list), then push this as a new entry, otherwise set it
2246 // directly
2247 if (logEntryJson.is_array())
2248 {
2249 logEntryJson.push_back(logEntry);
2250 asyncResp->res.jsonValue["Members@odata.count"] =
2251 logEntryJson.size();
Jason M. Bills2b20ef62022-01-06 15:48:07 -08002252 }
2253 else
2254 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002255 logEntryJson.update(logEntry);
Jason M. Bills2b20ef62022-01-06 15:48:07 -08002256 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002257 };
Ed Tanousdeae6a72024-11-11 21:58:57 -08002258 dbus::utility::getAllProperties(
2259 crashdumpObject, crashdumpPath + std::string("/") + logID,
2260 crashdumpInterface, std::move(getStoredLogCallback));
Jason M. Billse855dd22019-10-08 11:37:48 -07002261}
2262
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002263inline void requestRoutesCrashdumpEntryCollection(App& app)
Ed Tanous1da66f72018-07-27 16:13:37 -07002264{
Ed Tanous1da66f72018-07-27 16:13:37 -07002265 /**
2266 * Functions triggers appropriate requests on DBus
2267 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002268 BMCWEB_ROUTE(app,
Ed Tanous22d268c2022-05-19 09:39:07 -07002269 "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/")
Myung Bae50d9f382025-06-13 09:40:18 -04002270 .privileges(redfish::privileges::getLogEntryCollection)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002271 .methods(
2272 boost::beast::http::verb::
2273 get)([&app](const crow::Request& req,
2274 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2275 const std::string& systemName) {
2276 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous45ca1b82022-03-25 13:07:27 -07002277 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002278 return;
Ed Tanous45ca1b82022-03-25 13:07:27 -07002279 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002280 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous002d39b2022-05-31 08:59:27 -07002281 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002282 // Option currently returns no systems. TBD
2283 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2284 systemName);
2285 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002286 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002287 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2288 {
2289 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2290 systemName);
2291 return;
2292 }
2293
2294 constexpr std::array<std::string_view, 1> interfaces = {
2295 crashdumpInterface};
2296 dbus::utility::getSubTreePaths(
2297 "/", 0, interfaces,
2298 [asyncResp](const boost::system::error_code& ec,
2299 const std::vector<std::string>& resp) {
2300 if (ec)
2301 {
2302 if (ec.value() !=
2303 boost::system::errc::no_such_file_or_directory)
2304 {
2305 BMCWEB_LOG_DEBUG("failed to get entries ec: {}",
2306 ec.message());
2307 messages::internalError(asyncResp->res);
2308 return;
2309 }
2310 }
2311 asyncResp->res.jsonValue["@odata.type"] =
2312 "#LogEntryCollection.LogEntryCollection";
2313 asyncResp->res.jsonValue["@odata.id"] = std::format(
2314 "/redfish/v1/Systems/{}/LogServices/Crashdump/Entries",
2315 BMCWEB_REDFISH_SYSTEM_URI_NAME);
2316 asyncResp->res.jsonValue["Name"] =
2317 "Open BMC Crashdump Entries";
2318 asyncResp->res.jsonValue["Description"] =
2319 "Collection of Crashdump Entries";
2320 asyncResp->res.jsonValue["Members"] =
2321 nlohmann::json::array();
2322 asyncResp->res.jsonValue["Members@odata.count"] = 0;
2323
2324 for (const std::string& path : resp)
2325 {
2326 const sdbusplus::message::object_path objPath(path);
2327 // Get the log ID
2328 std::string logID = objPath.filename();
2329 if (logID.empty())
2330 {
2331 continue;
2332 }
2333 // Add the log entry to the array
2334 logCrashdumpEntry(asyncResp, logID,
2335 asyncResp->res.jsonValue["Members"]);
2336 }
2337 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002338 });
2339}
Ed Tanous1da66f72018-07-27 16:13:37 -07002340
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002341inline void requestRoutesCrashdumpEntry(App& app)
Ed Tanous1da66f72018-07-27 16:13:37 -07002342{
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002343 BMCWEB_ROUTE(
Ed Tanous22d268c2022-05-19 09:39:07 -07002344 app, "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/<str>/")
Myung Bae50d9f382025-06-13 09:40:18 -04002345 .privileges(redfish::privileges::getLogEntry)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002346 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07002347 [&app](const crow::Request& req,
2348 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous22d268c2022-05-19 09:39:07 -07002349 const std::string& systemName, const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002350 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2351 {
2352 return;
2353 }
2354 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
2355 {
2356 // Option currently returns no systems. TBD
2357 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2358 systemName);
2359 return;
2360 }
2361 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2362 {
2363 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2364 systemName);
2365 return;
2366 }
2367 const std::string& logID = param;
2368 logCrashdumpEntry(asyncResp, logID, asyncResp->res.jsonValue);
2369 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002370}
Ed Tanous1da66f72018-07-27 16:13:37 -07002371
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002372inline void requestRoutesCrashdumpFile(App& app)
2373{
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002374 BMCWEB_ROUTE(
2375 app,
Ed Tanous22d268c2022-05-19 09:39:07 -07002376 "/redfish/v1/Systems/<str>/LogServices/Crashdump/Entries/<str>/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07002377 .privileges(redfish::privileges::getLogEntry)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002378 .methods(boost::beast::http::verb::get)(
Nan Zhoua4ce1142022-08-02 18:45:25 +00002379 [](const crow::Request& req,
2380 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous22d268c2022-05-19 09:39:07 -07002381 const std::string& systemName, const std::string& logID,
2382 const std::string& fileName) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002383 // Do not call getRedfishRoute here since the crashdump file is
2384 // not a Redfish resource.
Ed Tanous22d268c2022-05-19 09:39:07 -07002385
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002386 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
2387 {
2388 // Option currently returns no systems. TBD
2389 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2390 systemName);
2391 return;
2392 }
2393 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2394 {
2395 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2396 systemName);
2397 return;
2398 }
Ed Tanous22d268c2022-05-19 09:39:07 -07002399
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002400 auto getStoredLogCallback =
2401 [asyncResp, logID, fileName,
2402 url(boost::urls::url(req.url()))](
2403 const boost::system::error_code& ec,
2404 const std::vector<std::pair<
2405 std::string, dbus::utility::DbusVariantType>>&
2406 resp) {
2407 if (ec)
2408 {
2409 BMCWEB_LOG_DEBUG("failed to get log ec: {}",
2410 ec.message());
2411 messages::internalError(asyncResp->res);
2412 return;
2413 }
Jason M. Bills8e6c0992021-03-11 16:26:53 -08002414
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002415 std::string dbusFilename{};
2416 std::string dbusTimestamp{};
2417 std::string dbusFilepath{};
Jason M. Bills8e6c0992021-03-11 16:26:53 -08002418
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002419 parseCrashdumpParameters(resp, dbusFilename,
2420 dbusTimestamp, dbusFilepath);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002421
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002422 if (dbusFilename.empty() || dbusTimestamp.empty() ||
2423 dbusFilepath.empty())
2424 {
2425 messages::resourceNotFound(asyncResp->res,
2426 "LogEntry", logID);
2427 return;
2428 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002429
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002430 // Verify the file name parameter is correct
2431 if (fileName != dbusFilename)
2432 {
2433 messages::resourceNotFound(asyncResp->res,
2434 "LogEntry", logID);
2435 return;
2436 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002437
Myung Baed51c61b2024-09-13 10:35:34 -05002438 if (asyncResp->res.openFile(dbusFilepath) !=
2439 crow::OpenCode::Success)
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002440 {
2441 messages::resourceNotFound(asyncResp->res,
2442 "LogEntry", logID);
2443 return;
2444 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002445
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002446 // Configure this to be a file download when accessed
2447 // from a browser
2448 asyncResp->res.addHeader(
2449 boost::beast::http::field::content_disposition,
2450 "attachment");
2451 };
Ed Tanousdeae6a72024-11-11 21:58:57 -08002452 dbus::utility::getAllProperties(
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002453 *crow::connections::systemBus, crashdumpObject,
2454 crashdumpPath + std::string("/") + logID,
2455 crashdumpInterface, std::move(getStoredLogCallback));
2456 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002457}
2458
Jason M. Billsc5a4c822022-01-06 15:51:23 -08002459enum class OEMDiagnosticType
2460{
2461 onDemand,
2462 telemetry,
2463 invalid,
2464};
2465
Ed Tanous26ccae32023-02-16 10:28:44 -08002466inline OEMDiagnosticType getOEMDiagnosticType(std::string_view oemDiagStr)
Jason M. Billsc5a4c822022-01-06 15:51:23 -08002467{
2468 if (oemDiagStr == "OnDemand")
2469 {
2470 return OEMDiagnosticType::onDemand;
2471 }
2472 if (oemDiagStr == "Telemetry")
2473 {
2474 return OEMDiagnosticType::telemetry;
2475 }
2476
2477 return OEMDiagnosticType::invalid;
2478}
2479
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002480inline void requestRoutesCrashdumpCollect(App& app)
2481{
George Liu0fda0f12021-11-16 10:06:17 +08002482 BMCWEB_ROUTE(
2483 app,
Ed Tanous22d268c2022-05-19 09:39:07 -07002484 "/redfish/v1/Systems/<str>/LogServices/Crashdump/Actions/LogService.CollectDiagnosticData/")
Myung Bae50d9f382025-06-13 09:40:18 -04002485 .privileges(redfish::privileges::
2486 postLogServiceSubOverComputerSystemLogServiceCollection)
Ed Tanous002d39b2022-05-31 08:59:27 -07002487 .methods(boost::beast::http::verb::post)(
2488 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07002489 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2490 const std::string& systemName) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002491 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07002492 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002493 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002494 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002495
2496 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous002d39b2022-05-31 08:59:27 -07002497 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002498 // Option currently returns no systems. TBD
2499 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2500 systemName);
2501 return;
2502 }
2503 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2504 {
2505 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2506 systemName);
2507 return;
2508 }
2509
2510 std::string diagnosticDataType;
2511 std::string oemDiagnosticDataType;
Patrick Williams504af5a2025-02-03 14:29:03 -05002512 if (!redfish::json_util::readJsonAction( //
2513 req, asyncResp->res, //
2514 "DiagnosticDataType", diagnosticDataType, //
Myung Baeafc474a2024-10-09 00:53:29 -07002515 "OEMDiagnosticDataType", oemDiagnosticDataType //
2516 ))
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002517 {
2518 return;
2519 }
2520
2521 if (diagnosticDataType != "OEM")
2522 {
2523 BMCWEB_LOG_ERROR(
2524 "Only OEM DiagnosticDataType supported for Crashdump");
2525 messages::actionParameterValueFormatError(
2526 asyncResp->res, diagnosticDataType,
2527 "DiagnosticDataType", "CollectDiagnosticData");
2528 return;
2529 }
2530
2531 OEMDiagnosticType oemDiagType =
2532 getOEMDiagnosticType(oemDiagnosticDataType);
2533
2534 std::string iface;
2535 std::string method;
2536 std::string taskMatchStr;
2537 if (oemDiagType == OEMDiagnosticType::onDemand)
2538 {
2539 iface = crashdumpOnDemandInterface;
2540 method = "GenerateOnDemandLog";
2541 taskMatchStr =
2542 "type='signal',"
2543 "interface='org.freedesktop.DBus.Properties',"
2544 "member='PropertiesChanged',"
2545 "arg0namespace='com.intel.crashdump'";
2546 }
2547 else if (oemDiagType == OEMDiagnosticType::telemetry)
2548 {
2549 iface = crashdumpTelemetryInterface;
2550 method = "GenerateTelemetryLog";
2551 taskMatchStr =
2552 "type='signal',"
2553 "interface='org.freedesktop.DBus.Properties',"
2554 "member='PropertiesChanged',"
2555 "arg0namespace='com.intel.crashdump'";
Ed Tanous002d39b2022-05-31 08:59:27 -07002556 }
2557 else
2558 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002559 BMCWEB_LOG_ERROR("Unsupported OEMDiagnosticDataType: {}",
2560 oemDiagnosticDataType);
2561 messages::actionParameterValueFormatError(
2562 asyncResp->res, oemDiagnosticDataType,
2563 "OEMDiagnosticDataType", "CollectDiagnosticData");
2564 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002565 }
Ed Tanous1da66f72018-07-27 16:13:37 -07002566
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002567 auto collectCrashdumpCallback =
2568 [asyncResp, payload(task::Payload(req)),
2569 taskMatchStr](const boost::system::error_code& ec,
2570 const std::string&) mutable {
2571 if (ec)
2572 {
2573 if (ec.value() ==
2574 boost::system::errc::operation_not_supported)
2575 {
2576 messages::resourceInStandby(asyncResp->res);
2577 }
2578 else if (ec.value() == boost::system::errc::
2579 device_or_resource_busy)
2580 {
2581 messages::serviceTemporarilyUnavailable(
2582 asyncResp->res, "60");
2583 }
2584 else
2585 {
2586 messages::internalError(asyncResp->res);
2587 }
2588 return;
2589 }
2590 std::shared_ptr<task::TaskData> task =
2591 task::TaskData::createTask(
2592 [](const boost::system::error_code& ec2,
2593 sdbusplus::message_t&,
2594 const std::shared_ptr<task::TaskData>&
2595 taskData) {
2596 if (!ec2)
2597 {
2598 taskData->messages.emplace_back(
2599 messages::taskCompletedOK(
2600 std::to_string(
2601 taskData->index)));
2602 taskData->state = "Completed";
2603 }
2604 return task::completed;
2605 },
2606 taskMatchStr);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002607
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002608 task->startTimer(std::chrono::minutes(5));
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002609 task->payload.emplace(std::move(payload));
Chinmay Shripad Hegde29e2bdd2025-06-06 16:23:47 +05302610 task->populateResp(asyncResp->res);
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002611 };
2612
Ed Tanous177612a2025-02-14 15:16:09 -08002613 dbus::utility::async_method_call(
2614 asyncResp, std::move(collectCrashdumpCallback),
2615 crashdumpObject, crashdumpPath, iface, method);
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002616 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002617}
Kenny L. Ku6eda7682020-06-19 09:48:36 -07002618
Alexander Hansen599b9af2024-08-06 15:11:57 +02002619inline void dBusLogServiceActionsClear(
2620 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2621{
2622 BMCWEB_LOG_DEBUG("Do delete all entries.");
2623
2624 // Process response from Logging service.
2625 auto respHandler = [asyncResp](const boost::system::error_code& ec) {
2626 BMCWEB_LOG_DEBUG("doClearLog resp_handler callback: Done");
2627 if (ec)
2628 {
2629 // TODO Handle for specific error code
2630 BMCWEB_LOG_ERROR("doClearLog resp_handler got error {}", ec);
2631 asyncResp->res.result(
2632 boost::beast::http::status::internal_server_error);
2633 return;
2634 }
2635
Amy Change2460462025-05-06 00:10:13 -07002636 messages::success(asyncResp->res);
Alexander Hansen599b9af2024-08-06 15:11:57 +02002637 };
2638
2639 // Make call to Logging service to request Clear Log
Ed Tanous177612a2025-02-14 15:16:09 -08002640 dbus::utility::async_method_call(
2641 asyncResp, respHandler, "xyz.openbmc_project.Logging",
Alexander Hansen599b9af2024-08-06 15:11:57 +02002642 "/xyz/openbmc_project/logging",
2643 "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll");
2644}
2645
Andrew Geisslercb92c032018-08-17 07:56:14 -07002646/**
2647 * DBusLogServiceActionsClear class supports POST method for ClearLog action.
2648 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002649inline void requestRoutesDBusLogServiceActionsClear(App& app)
Andrew Geisslercb92c032018-08-17 07:56:14 -07002650{
Andrew Geisslercb92c032018-08-17 07:56:14 -07002651 /**
2652 * Function handles POST method request.
2653 * The Clear Log actions does not require any parameter.The action deletes
2654 * all entries found in the Entries collection for this Log Service.
2655 */
Andrew Geisslercb92c032018-08-17 07:56:14 -07002656
George Liu0fda0f12021-11-16 10:06:17 +08002657 BMCWEB_ROUTE(
2658 app,
Ed Tanous22d268c2022-05-19 09:39:07 -07002659 "/redfish/v1/Systems/<str>/LogServices/EventLog/Actions/LogService.ClearLog/")
Abhishek Patelfff6a4d2021-07-21 11:29:45 -05002660 .privileges(redfish::privileges::
2661 postLogServiceSubOverComputerSystemLogServiceCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002662 .methods(boost::beast::http::verb::post)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07002663 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07002664 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2665 const std::string& systemName) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002666 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2667 {
2668 return;
2669 }
2670 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
2671 {
2672 // Option currently returns no systems. TBD
2673 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2674 systemName);
2675 return;
2676 }
2677 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
2678 {
2679 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2680 systemName);
2681 return;
2682 }
2683 dBusLogServiceActionsClear(asyncResp);
2684 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002685}
ZhikuiRena3316fc2020-01-29 14:58:08 -08002686
Ed Tanous1da66f72018-07-27 16:13:37 -07002687} // namespace redfish