blob: e8283718bca422cfd4cf58b1a36be599c1a63659 [file] [log] [blame]
Dhruvaraj Subhashchandranfef66a92020-09-06 13:10:59 -05001#include "config.h"
2
3#include "dump_manager_system.hpp"
4
Dhruvaraj Subhashchandran6a54d9a2020-12-17 22:24:37 -06005#include "dump_utils.hpp"
Dhruvaraj Subhashchandranad50d422022-01-18 05:54:02 -06006#include "op_dump_consts.hpp"
Dhruvaraj Subhashchandran1ddb0062022-05-06 06:21:11 -05007#include "op_dump_util.hpp"
Dhruvaraj Subhashchandranfef66a92020-09-06 13:10:59 -05008#include "system_dump_entry.hpp"
Dhruvaraj Subhashchandran6ccb50e2020-10-29 09:33:18 -05009#include "xyz/openbmc_project/Common/error.hpp"
Dhruvaraj Subhashchandranfef66a92020-09-06 13:10:59 -050010
Dhruvaraj Subhashchandran6ccb50e2020-10-29 09:33:18 -050011#include <phosphor-logging/elog-errors.hpp>
Dhruvaraj Subhashchandranfef66a92020-09-06 13:10:59 -050012#include <phosphor-logging/elog.hpp>
Dhruvaraj Subhashchandrand1f670f2023-06-05 22:19:25 -050013#include <phosphor-logging/lg2.hpp>
Dhruvaraj Subhashchandranfef66a92020-09-06 13:10:59 -050014
Dhruvaraj Subhashchandran341d6832021-01-15 06:28:04 -060015namespace openpower
Dhruvaraj Subhashchandranfef66a92020-09-06 13:10:59 -050016{
17namespace dump
18{
19namespace system
20{
21
22using namespace phosphor::logging;
Dhruvaraj Subhashchandran6ccb50e2020-10-29 09:33:18 -050023using namespace sdbusplus::xyz::openbmc_project::Common::Error;
Dhruvaraj Subhashchandranfef66a92020-09-06 13:10:59 -050024
Dhruvaraj Subhashchandranf37c5c32020-12-17 22:08:19 -060025void Manager::notify(uint32_t dumpId, uint64_t size)
Dhruvaraj Subhashchandranfef66a92020-09-06 13:10:59 -050026{
Dhruvaraj Subhashchandranfef66a92020-09-06 13:10:59 -050027 // Get the timestamp
Claire Weinanc0ab9d42022-08-17 23:01:07 -070028 uint64_t timeStamp =
29 std::chrono::duration_cast<std::chrono::microseconds>(
30 std::chrono::system_clock::now().time_since_epoch())
31 .count();
Dhruvaraj Subhashchandran6ccb50e2020-10-29 09:33:18 -050032
Dhruvaraj Subhashchandran0007b702022-02-01 03:23:14 -060033 // A system dump can be created due to a fault in the server or by a user
34 // request. A system dump by fault is first reported here, but for a
35 // user-requested dump, an entry will be created first with an invalid
36 // source id. Since only one system dump creation is allowed at a time, if
37 // there's an entry with an invalid sourceId, we will update that entry.
38 openpower::dump::system::Entry* upEntry = nullptr;
Dhruvaraj Subhashchandran6ccb50e2020-10-29 09:33:18 -050039 for (auto& entry : entries)
40 {
Dhruvaraj Subhashchandran341d6832021-01-15 06:28:04 -060041 openpower::dump::system::Entry* sysEntry =
42 dynamic_cast<openpower::dump::system::Entry*>(entry.second.get());
Dhruvaraj Subhashchandran0007b702022-02-01 03:23:14 -060043
44 // If there's already a completed entry with the input source id and
45 // size, ignore this notification
46 if ((sysEntry->sourceDumpId() == dumpId) && (sysEntry->size() == size))
Dhruvaraj Subhashchandran6ccb50e2020-10-29 09:33:18 -050047 {
Dhruvaraj Subhashchandran0007b702022-02-01 03:23:14 -060048 if (sysEntry->status() ==
49 phosphor::dump::OperationStatus::Completed)
50 {
51 lg2::info(
52 "System dump entry with source dump id:{SOURCE_ID} and "
53 "size: {SIZE} is already present with entry id:{ID}",
54 "SOURCE_ID", dumpId, "SIZE", size, "ID",
55 sysEntry->getDumpId());
56 return;
57 }
58 else
59 {
60 lg2::error("A duplicate notification for an incomplete dump "
61 "dump id: {SOURCE_ID} entry id: {ID}",
62 "SOURCE_D", dumpId, "ID", sysEntry->getDumpId());
63 upEntry = sysEntry;
64 break;
65 }
Dhruvaraj Subhashchandran6ccb50e2020-10-29 09:33:18 -050066 }
Dhruvaraj Subhashchandran0007b702022-02-01 03:23:14 -060067 else if (sysEntry->sourceDumpId() == dumpId)
68 {
69 // If the dump id is the same but the size is different, then this
70 // is a new dump. So, delete the stale entry and prepare to create a
71 // new one.
72 lg2::info("A previous dump entry found with same source id: "
73 "{SOURCE_ID}, deleting it, entry id: {DUMP_ID}",
74 "SOURCE_ID", dumpId, "DUMP_ID", sysEntry->getDumpId());
75 sysEntry->delete_();
76 // No 'break' here, as we need to continue checking other entries.
77 }
78
79 // Save the first entry with INVALID_SOURCE_ID, but continue in the loop
80 // to ensure the new entry is not a duplicate.
81 if ((sysEntry->sourceDumpId() == INVALID_SOURCE_ID) &&
82 (upEntry == nullptr))
83 {
84 upEntry = sysEntry;
85 }
86 }
87
88 if (upEntry != nullptr)
89 {
90 lg2::info(
91 "System Dump Notify: Updating dumpId:{ID} Source Id:{SOURCE_ID} "
92 "Size:{SIZE}",
93 "ID", upEntry->getDumpId(), "SOURCE_ID", dumpId, "SIZE", size);
94 upEntry->update(timeStamp, size, dumpId);
95 return;
Dhruvaraj Subhashchandran6ccb50e2020-10-29 09:33:18 -050096 }
97
Dhruvaraj Subhashchandranfef66a92020-09-06 13:10:59 -050098 // Get the id
99 auto id = lastEntryId + 1;
100 auto idString = std::to_string(id);
Jayanth Othayoth3fc6df42021-04-08 03:45:24 -0500101 auto objPath = std::filesystem::path(baseEntryPath) / idString;
Dhruvaraj Subhashchandran6ccb50e2020-10-29 09:33:18 -0500102
Asmitha Karunanithi74a1f392021-10-27 03:23:59 -0500103 // TODO: Get the originator Id, Type from the persisted file.
104 // For now replacing it with null
Dhruvaraj Subhashchandran6ccb50e2020-10-29 09:33:18 -0500105 try
106 {
Dhruvaraj Subhashchandran0007b702022-02-01 03:23:14 -0600107 lg2::info("System Dump Notify: creating new dump "
108 "entry dumpId:{ID} Source Id:{SOURCE_ID} Size:{SIZE}",
109 "ID", id, "SOURCE_ID", dumpId, "SIZE", size);
Dhruvaraj Subhashchandran6ccb50e2020-10-29 09:33:18 -0500110 entries.insert(std::make_pair(
Dhruvaraj Subhashchandrana6ab8062020-10-29 15:29:10 -0500111 id, std::make_unique<system::Entry>(
112 bus, objPath.c_str(), id, timeStamp, size, dumpId,
Asmitha Karunanithi74a1f392021-10-27 03:23:59 -0500113 phosphor::dump::OperationStatus::Completed, std::string(),
114 originatorTypes::Internal, *this)));
Dhruvaraj Subhashchandran6ccb50e2020-10-29 09:33:18 -0500115 }
116 catch (const std::invalid_argument& e)
117 {
Dhruvaraj Subhashchandrand1f670f2023-06-05 22:19:25 -0500118 lg2::error(
119 "Error in creating system dump entry, errormsg: {ERROR}, "
120 "OBJECTPATH: {OBJECT_PATH}, ID: {ID}, TIMESTAMP: {TIMESTAMP}, "
121 "SIZE: {SIZE}, SOURCEID: {SOURCE_ID}",
122 "ERROR", e, "OBJECT_PATH", objPath, "ID", id, "TIMESTAMP",
123 timeStamp, "SIZE", size, "SOURCE_ID", dumpId);
Dhruvaraj Subhashchandran6ccb50e2020-10-29 09:33:18 -0500124 report<InternalFailure>();
125 return;
126 }
Dhruvaraj Subhashchandranfef66a92020-09-06 13:10:59 -0500127 lastEntryId++;
Dhruvaraj Subhashchandran6ccb50e2020-10-29 09:33:18 -0500128 return;
Dhruvaraj Subhashchandranfef66a92020-09-06 13:10:59 -0500129}
130
Dhruvaraj Subhashchandran969f9a52020-10-30 01:42:39 -0500131sdbusplus::message::object_path
Dhruvaraj Subhashchandranddc33662021-07-19 09:28:42 -0500132 Manager::createDump(phosphor::dump::DumpCreateParams params)
Dhruvaraj Subhashchandran7040bce2020-09-16 00:50:19 -0500133{
134 constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
135 constexpr auto SYSTEMD_OBJ_PATH = "/org/freedesktop/systemd1";
136 constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
Andrew Geissler24e0c592021-01-19 16:47:27 -0600137 constexpr auto DIAG_MOD_TARGET = "obmc-host-crash@0.target";
Dhruvaraj Subhashchandran969f9a52020-10-30 01:42:39 -0500138
Asmitha Karunanithi74a1f392021-10-27 03:23:59 -0500139 if (params.size() > CREATE_DUMP_MAX_PARAMS)
Dhruvaraj Subhashchandran969f9a52020-10-30 01:42:39 -0500140 {
Dhruvaraj Subhashchandrand1f670f2023-06-05 22:19:25 -0500141 lg2::warning(
Asmitha Karunanithi74a1f392021-10-27 03:23:59 -0500142 "System dump accepts not more than 2 additional parameters");
Dhruvaraj Subhashchandran969f9a52020-10-30 01:42:39 -0500143 }
Dhruvaraj Subhashchandran1ddb0062022-05-06 06:21:11 -0500144 using Unavailable =
145 sdbusplus::xyz::openbmc_project::Common::Error::Unavailable;
146
147 if (openpower::dump::util::isSystemDumpInProgress(bus))
148 {
149 lg2::error("Another dump in progress or available to offload");
150 elog<Unavailable>();
151 }
Dhruvaraj Subhashchandran969f9a52020-10-30 01:42:39 -0500152
Dhruvaraj Subhashchandran6a54d9a2020-12-17 22:24:37 -0600153 using NotAllowed =
154 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
155 using Reason = xyz::openbmc_project::Common::NotAllowed::REASON;
156
Dhruvaraj Subhashchandran3a25e5b2022-03-22 08:06:20 -0500157 auto isHostRunning = false;
158 phosphor::dump::HostState hostState;
159 try
Dhruvaraj Subhashchandran6a54d9a2020-12-17 22:24:37 -0600160 {
Dhruvaraj Subhashchandran3a25e5b2022-03-22 08:06:20 -0500161 isHostRunning = phosphor::dump::isHostRunning();
162 hostState = phosphor::dump::getHostState();
163 }
164 catch (const std::exception& e)
165 {
166 lg2::error(
167 "System state cannot be determined, system dump is not allowed: "
168 "{ERROR}",
169 "ERROR", e);
170 return std::string();
171 }
172 bool isHostQuiesced = hostState == phosphor::dump::HostState::Quiesced;
173 // Allow creating system dump only when the host is up or quiesced
174 if (!isHostRunning && !isHostQuiesced)
175 {
176 lg2::error("System dump can be initiated only when the host is up "
177 "or quiesced");
Dhruvaraj Subhashchandran6a54d9a2020-12-17 22:24:37 -0600178 elog<NotAllowed>(
Dhruvaraj Subhashchandran3a25e5b2022-03-22 08:06:20 -0500179 Reason("System dump can be initiated only when the host is up "
180 "or quiesced"));
Dhruvaraj Subhashchandran6a54d9a2020-12-17 22:24:37 -0600181 return std::string();
182 }
183
Asmitha Karunanithi74a1f392021-10-27 03:23:59 -0500184 // Get the originator id and type from params
185 std::string originatorId;
186 originatorTypes originatorType;
187
188 phosphor::dump::extractOriginatorProperties(params, originatorId,
189 originatorType);
190
Dhruvaraj Subhashchandran7040bce2020-09-16 00:50:19 -0500191 auto b = sdbusplus::bus::new_default();
192 auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_OBJ_PATH,
193 SYSTEMD_INTERFACE, "StartUnit");
194 method.append(DIAG_MOD_TARGET); // unit to activate
195 method.append("replace");
196 bus.call_noreply(method);
Dhruvaraj Subhashchandran6ccb50e2020-10-29 09:33:18 -0500197
198 auto id = lastEntryId + 1;
199 auto idString = std::to_string(id);
Jayanth Othayoth3fc6df42021-04-08 03:45:24 -0500200 auto objPath = std::filesystem::path(baseEntryPath) / idString;
Claire Weinanc0ab9d42022-08-17 23:01:07 -0700201 uint64_t timeStamp =
202 std::chrono::duration_cast<std::chrono::microseconds>(
203 std::chrono::system_clock::now().time_since_epoch())
204 .count();
Dhruvaraj Subhashchandran6ccb50e2020-10-29 09:33:18 -0500205
206 try
207 {
208 entries.insert(std::make_pair(
Dhruvaraj Subhashchandrana6ab8062020-10-29 15:29:10 -0500209 id, std::make_unique<system::Entry>(
210 bus, objPath.c_str(), id, timeStamp, 0, INVALID_SOURCE_ID,
Asmitha Karunanithi74a1f392021-10-27 03:23:59 -0500211 phosphor::dump::OperationStatus::InProgress, originatorId,
212 originatorType, *this)));
Dhruvaraj Subhashchandran6ccb50e2020-10-29 09:33:18 -0500213 }
214 catch (const std::invalid_argument& e)
215 {
Dhruvaraj Subhashchandrand1f670f2023-06-05 22:19:25 -0500216 lg2::error("Error in creating system dump entry, errormsg: {ERROR}, "
217 "OBJECTPATH: {OBJECT_PATH}, ID: {ID}",
218 "ERROR", e, "OBJECT_PATH", objPath, "ID", id);
Dhruvaraj Subhashchandran6ccb50e2020-10-29 09:33:18 -0500219 elog<InternalFailure>();
220 return std::string();
221 }
222 lastEntryId++;
223 return objPath.string();
Dhruvaraj Subhashchandran7040bce2020-09-16 00:50:19 -0500224}
225
Dhruvaraj Subhashchandranfef66a92020-09-06 13:10:59 -0500226} // namespace system
227} // namespace dump
Dhruvaraj Subhashchandran341d6832021-01-15 06:28:04 -0600228} // namespace openpower