blob: 93ce98c67486760dbe55fdf0142a98a43cee6472 [file] [log] [blame]
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -06001#include "config.h"
2
3#include "dump_manager_resource.hpp"
4
5#include "dump_utils.hpp"
Dhruvaraj Subhashchandranad50d422022-01-18 05:54:02 -06006#include "op_dump_consts.hpp"
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -06007#include "resource_dump_entry.hpp"
8#include "xyz/openbmc_project/Common/error.hpp"
9
George Liu858fbb22021-07-01 12:25:44 +080010#include <fmt/core.h>
11
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -060012#include <phosphor-logging/elog-errors.hpp>
13#include <phosphor-logging/elog.hpp>
14
Dhruvaraj Subhashchandran341d6832021-01-15 06:28:04 -060015namespace openpower
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -060016{
17namespace dump
18{
19namespace resource
20{
21
22using namespace phosphor::logging;
23using InternalFailure =
24 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
25
26void Manager::notify(uint32_t dumpId, uint64_t size)
27{
28 // Get the timestamp
Claire Weinanc0ab9d42022-08-17 23:01:07 -070029 uint64_t timeStamp =
30 std::chrono::duration_cast<std::chrono::microseconds>(
31 std::chrono::system_clock::now().time_since_epoch())
32 .count();
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -060033
Dhruvaraj Subhashchandran583ebc02022-02-01 03:02:35 -060034 // If there is an entry with invalid id update that.
35 // If there a completed one with same source id ignore it
36 // if there is no invalid id, create new entry
37 openpower::dump::resource::Entry* upEntry = NULL;
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -060038 for (auto& entry : entries)
39 {
Dhruvaraj Subhashchandran341d6832021-01-15 06:28:04 -060040 openpower::dump::resource::Entry* resEntry =
41 dynamic_cast<openpower::dump::resource::Entry*>(entry.second.get());
Dhruvaraj Subhashchandran583ebc02022-02-01 03:02:35 -060042
43 // If there is already a completed entry with input source id then
44 // ignore this notification.
45 if ((resEntry->sourceDumpId() == dumpId) &&
46 (resEntry->status() == phosphor::dump::OperationStatus::Completed))
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -060047 {
Dhruvaraj Subhashchandran583ebc02022-02-01 03:02:35 -060048 log<level::INFO>(
49 fmt::format("Resource dump entry with source dump id({}) is "
50 "already present with entry id({})",
51 dumpId, resEntry->getDumpId())
52 .c_str());
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -060053 return;
54 }
Dhruvaraj Subhashchandran583ebc02022-02-01 03:02:35 -060055
56 // Save the first entry with INVALID_SOURCE_ID
57 // but continue in the loop to make sure the
58 // new entry is not duplicate
59 if ((resEntry->status() ==
60 phosphor::dump::OperationStatus::InProgress) &&
61 (resEntry->sourceDumpId() == INVALID_SOURCE_ID) &&
62 (upEntry == NULL))
63 {
64 upEntry = resEntry;
65 }
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -060066 }
Dhruvaraj Subhashchandran583ebc02022-02-01 03:02:35 -060067 if (upEntry != NULL)
68 {
69 log<level::INFO>(
70 fmt::format("Resource Dump Notify: Updating dumpId({}) "
71 "with source Id({}) Size({})",
72 upEntry->getDumpId(), dumpId, size)
73 .c_str());
74 upEntry->update(timeStamp, size, dumpId);
75 return;
76 }
77
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -060078 // Get the id
79 auto id = lastEntryId + 1;
80 auto idString = std::to_string(id);
Jayanth Othayoth3fc6df42021-04-08 03:45:24 -050081 auto objPath = std::filesystem::path(baseEntryPath) / idString;
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -060082
Asmitha Karunanithi74a1f392021-10-27 03:23:59 -050083 // TODO: Get the originator Id, type from the persisted file.
84 // For now replacing it with null
85
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -060086 try
87 {
Dhruvaraj Subhashchandran583ebc02022-02-01 03:02:35 -060088 log<level::INFO>(fmt::format("Resouce Dump Notify: creating new dump "
89 "entry dumpId({}) Id({}) Size({})",
90 id, dumpId, size)
91 .c_str());
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -060092 entries.insert(std::make_pair(
93 id, std::make_unique<resource::Entry>(
94 bus, objPath.c_str(), id, timeStamp, size, dumpId,
95 std::string(), std::string(),
Asmitha Karunanithi74a1f392021-10-27 03:23:59 -050096 phosphor::dump::OperationStatus::Completed, std::string(),
97 originatorTypes::Internal, *this)));
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -060098 }
99 catch (const std::invalid_argument& e)
100 {
George Liu858fbb22021-07-01 12:25:44 +0800101 log<level::ERR>(fmt::format("Error in creating resource dump entry, "
102 "errormsg({}),OBJECTPATH({}),ID({}),"
103 "TIMESTAMP({}),SIZE({}),SOURCEID({})",
George Liu363af242021-07-16 17:52:36 +0800104 e.what(), objPath.c_str(), id, timeStamp,
105 size, dumpId)
George Liu858fbb22021-07-01 12:25:44 +0800106 .c_str());
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -0600107 report<InternalFailure>();
108 return;
109 }
110 lastEntryId++;
111}
112
113sdbusplus::message::object_path
Dhruvaraj Subhashchandranddc33662021-07-19 09:28:42 -0500114 Manager::createDump(phosphor::dump::DumpCreateParams params)
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -0600115{
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -0600116 using NotAllowed =
117 sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
118 using Reason = xyz::openbmc_project::Common::NotAllowed::REASON;
119
120 // Allow creating resource dump only when the host is up.
121 if (!phosphor::dump::isHostRunning())
122 {
123 elog<NotAllowed>(
124 Reason("Resource dump can be initiated only when the host is up"));
125 return std::string();
126 }
Dhruvaraj Subhashchandranddc33662021-07-19 09:28:42 -0500127
128 using InvalidArgument =
129 sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument;
130 using Argument = xyz::openbmc_project::Common::InvalidArgument;
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -0600131 using CreateParameters =
132 sdbusplus::com::ibm::Dump::server::Create::CreateParameters;
133
134 auto id = lastEntryId + 1;
135 auto idString = std::to_string(id);
Jayanth Othayoth3fc6df42021-04-08 03:45:24 -0500136 auto objPath = std::filesystem::path(baseEntryPath) / idString;
Claire Weinanc0ab9d42022-08-17 23:01:07 -0700137 uint64_t timeStamp =
138 std::chrono::duration_cast<std::chrono::microseconds>(
139 std::chrono::system_clock::now().time_since_epoch())
140 .count();
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -0600141
Dhruvaraj Subhashchandranddc33662021-07-19 09:28:42 -0500142 std::string vspString;
143 auto iter = params.find(
144 sdbusplus::com::ibm::Dump::server::Create::
145 convertCreateParametersToString(CreateParameters::VSPString));
146 if (iter == params.end())
147 {
148 // Host will generate a default dump if no resource selector string
149 // is provided. The default dump will be a non-disruptive system dump.
150 log<level::INFO>(
151 "VSP string is not provided, a non-disruptive system dump will be "
152 "generated by the host");
153 }
154 else
155 {
156 try
157 {
158 vspString = std::get<std::string>(iter->second);
159 }
160 catch (const std::bad_variant_access& e)
161 {
162 // Exception will be raised if the input is not string
163 log<level::ERR>(
164 fmt::format("An invalid vsp string is passed errormsg({})",
165 e.what())
166 .c_str());
167 elog<InvalidArgument>(Argument::ARGUMENT_NAME("VSP_STRING"),
168 Argument::ARGUMENT_VALUE("INVALID INPUT"));
169 }
170 }
171
172 std::string pwd;
173 iter = params.find(
174 sdbusplus::com::ibm::Dump::server::Create::
175 convertCreateParametersToString(CreateParameters::Password));
176 if (iter == params.end())
177 {
Dhruvaraj Subhashchandrana5097b92022-03-08 12:33:41 -0600178 log<level::INFO>("Password is not provided for resource dump");
Dhruvaraj Subhashchandranddc33662021-07-19 09:28:42 -0500179 }
Dhruvaraj Subhashchandrana5097b92022-03-08 12:33:41 -0600180 else
Dhruvaraj Subhashchandranddc33662021-07-19 09:28:42 -0500181 {
Dhruvaraj Subhashchandrana5097b92022-03-08 12:33:41 -0600182 try
183 {
184 pwd = std::get<std::string>(iter->second);
185 }
186 catch (const std::bad_variant_access& e)
187 {
188 // Exception will be raised if the input is not string
189 log<level::ERR>(
190 fmt::format("An invalid password string is passed errormsg({})",
191 e.what())
192 .c_str());
193 elog<InvalidArgument>(Argument::ARGUMENT_NAME("PASSWORD"),
194 Argument::ARGUMENT_VALUE("INVALID INPUT"));
195 }
Dhruvaraj Subhashchandranddc33662021-07-19 09:28:42 -0500196 }
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -0600197
Asmitha Karunanithi74a1f392021-10-27 03:23:59 -0500198 // Get the originator id and type from params
199 std::string originatorId;
200 originatorTypes originatorType;
201
202 phosphor::dump::extractOriginatorProperties(params, originatorId,
203 originatorType);
204
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -0600205 try
206 {
207 entries.insert(std::make_pair(
208 id, std::make_unique<resource::Entry>(
209 bus, objPath.c_str(), id, timeStamp, 0, INVALID_SOURCE_ID,
210 vspString, pwd, phosphor::dump::OperationStatus::InProgress,
Asmitha Karunanithi74a1f392021-10-27 03:23:59 -0500211 originatorId, originatorType, *this)));
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -0600212 }
213 catch (const std::invalid_argument& e)
214 {
George Liu858fbb22021-07-01 12:25:44 +0800215 log<level::ERR>(
216 fmt::format(
217 "Error in creating resource dump "
218 "entry,errormsg({}),OBJECTPATH({}), VSPSTRING({}), ID({})",
George Liu363af242021-07-16 17:52:36 +0800219 e.what(), objPath.c_str(), vspString, id)
George Liu858fbb22021-07-01 12:25:44 +0800220 .c_str());
Dhruvaraj Subhashchandran62337a92020-11-22 21:24:30 -0600221 elog<InternalFailure>();
222 return std::string();
223 }
224 lastEntryId++;
225 return objPath.string();
226}
227
228} // namespace resource
229} // namespace dump
Dhruvaraj Subhashchandran341d6832021-01-15 06:28:04 -0600230} // namespace openpower