162337a92SDhruvaraj Subhashchandran #include "config.h"
262337a92SDhruvaraj Subhashchandran 
362337a92SDhruvaraj Subhashchandran #include "dump_manager_resource.hpp"
462337a92SDhruvaraj Subhashchandran 
562337a92SDhruvaraj Subhashchandran #include "dump_utils.hpp"
6ad50d422SDhruvaraj Subhashchandran #include "op_dump_consts.hpp"
762337a92SDhruvaraj Subhashchandran #include "resource_dump_entry.hpp"
862337a92SDhruvaraj Subhashchandran #include "xyz/openbmc_project/Common/error.hpp"
962337a92SDhruvaraj Subhashchandran 
1062337a92SDhruvaraj Subhashchandran #include <phosphor-logging/elog-errors.hpp>
1162337a92SDhruvaraj Subhashchandran #include <phosphor-logging/elog.hpp>
12*d1f670feSDhruvaraj Subhashchandran #include <phosphor-logging/lg2.hpp>
1362337a92SDhruvaraj Subhashchandran 
14341d683dSDhruvaraj Subhashchandran namespace openpower
1562337a92SDhruvaraj Subhashchandran {
1662337a92SDhruvaraj Subhashchandran namespace dump
1762337a92SDhruvaraj Subhashchandran {
1862337a92SDhruvaraj Subhashchandran namespace resource
1962337a92SDhruvaraj Subhashchandran {
2062337a92SDhruvaraj Subhashchandran 
2162337a92SDhruvaraj Subhashchandran using namespace phosphor::logging;
2262337a92SDhruvaraj Subhashchandran using InternalFailure =
2362337a92SDhruvaraj Subhashchandran     sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
2462337a92SDhruvaraj Subhashchandran 
notify(uint32_t dumpId,uint64_t size)2562337a92SDhruvaraj Subhashchandran void Manager::notify(uint32_t dumpId, uint64_t size)
2662337a92SDhruvaraj Subhashchandran {
2762337a92SDhruvaraj Subhashchandran     // Get the timestamp
28c0ab9d43SClaire Weinan     uint64_t timeStamp =
29c0ab9d43SClaire Weinan         std::chrono::duration_cast<std::chrono::microseconds>(
30c0ab9d43SClaire Weinan             std::chrono::system_clock::now().time_since_epoch())
31c0ab9d43SClaire Weinan             .count();
3262337a92SDhruvaraj Subhashchandran 
33583ebc09SDhruvaraj Subhashchandran     // If there is an entry with invalid id update that.
34583ebc09SDhruvaraj Subhashchandran     // If there a completed one with same source id ignore it
35583ebc09SDhruvaraj Subhashchandran     // if there is no invalid id, create new entry
36583ebc09SDhruvaraj Subhashchandran     openpower::dump::resource::Entry* upEntry = NULL;
3762337a92SDhruvaraj Subhashchandran     for (auto& entry : entries)
3862337a92SDhruvaraj Subhashchandran     {
39341d683dSDhruvaraj Subhashchandran         openpower::dump::resource::Entry* resEntry =
40341d683dSDhruvaraj Subhashchandran             dynamic_cast<openpower::dump::resource::Entry*>(entry.second.get());
41583ebc09SDhruvaraj Subhashchandran 
42583ebc09SDhruvaraj Subhashchandran         // If there is already a completed entry with input source id then
43583ebc09SDhruvaraj Subhashchandran         // ignore this notification.
44583ebc09SDhruvaraj Subhashchandran         if ((resEntry->sourceDumpId() == dumpId) &&
45583ebc09SDhruvaraj Subhashchandran             (resEntry->status() == phosphor::dump::OperationStatus::Completed))
4662337a92SDhruvaraj Subhashchandran         {
47*d1f670feSDhruvaraj Subhashchandran             lg2::info("Resource dump entry with source dump id: {DUMP_ID} "
48*d1f670feSDhruvaraj Subhashchandran                       "is already present with entry id: {ENTRY_ID}",
49*d1f670feSDhruvaraj Subhashchandran                       "DUMP_ID", dumpId, "ENTRY_ID", resEntry->getDumpId());
5062337a92SDhruvaraj Subhashchandran             return;
5162337a92SDhruvaraj Subhashchandran         }
52583ebc09SDhruvaraj Subhashchandran 
53583ebc09SDhruvaraj Subhashchandran         // Save the first entry with INVALID_SOURCE_ID
54583ebc09SDhruvaraj Subhashchandran         // but continue in the loop to make sure the
55583ebc09SDhruvaraj Subhashchandran         // new entry is not duplicate
56583ebc09SDhruvaraj Subhashchandran         if ((resEntry->status() ==
57583ebc09SDhruvaraj Subhashchandran              phosphor::dump::OperationStatus::InProgress) &&
58583ebc09SDhruvaraj Subhashchandran             (resEntry->sourceDumpId() == INVALID_SOURCE_ID) &&
59583ebc09SDhruvaraj Subhashchandran             (upEntry == NULL))
60583ebc09SDhruvaraj Subhashchandran         {
61583ebc09SDhruvaraj Subhashchandran             upEntry = resEntry;
6262337a92SDhruvaraj Subhashchandran         }
63583ebc09SDhruvaraj Subhashchandran     }
64583ebc09SDhruvaraj Subhashchandran     if (upEntry != NULL)
65583ebc09SDhruvaraj Subhashchandran     {
66*d1f670feSDhruvaraj Subhashchandran         lg2::info("Resource Dump Notify: Updating dumpId: {DUMP_ID} with "
67*d1f670feSDhruvaraj Subhashchandran                   "source Id: {SOURCE_ID} Size: {SIZE}",
68*d1f670feSDhruvaraj Subhashchandran                   "DUMP_ID", upEntry->getDumpId(), "SOURCE_ID", dumpId, "SIZE",
69*d1f670feSDhruvaraj Subhashchandran                   size);
70583ebc09SDhruvaraj Subhashchandran         upEntry->update(timeStamp, size, dumpId);
71583ebc09SDhruvaraj Subhashchandran         return;
72583ebc09SDhruvaraj Subhashchandran     }
73583ebc09SDhruvaraj Subhashchandran 
7462337a92SDhruvaraj Subhashchandran     // Get the id
7562337a92SDhruvaraj Subhashchandran     auto id = lastEntryId + 1;
7662337a92SDhruvaraj Subhashchandran     auto idString = std::to_string(id);
773fc6df48SJayanth Othayoth     auto objPath = std::filesystem::path(baseEntryPath) / idString;
7862337a92SDhruvaraj Subhashchandran 
7974a1f39cSAsmitha Karunanithi     // TODO: Get the originator Id, type from the persisted file.
8074a1f39cSAsmitha Karunanithi     // For now replacing it with null
8174a1f39cSAsmitha Karunanithi 
8262337a92SDhruvaraj Subhashchandran     try
8362337a92SDhruvaraj Subhashchandran     {
84*d1f670feSDhruvaraj Subhashchandran         lg2::info(
85*d1f670feSDhruvaraj Subhashchandran             "Resouce Dump Notify: creating new dump entry dumpId: {DUMP_ID} "
86*d1f670feSDhruvaraj Subhashchandran             "Id: {ID} Size: {SIZE}",
87*d1f670feSDhruvaraj Subhashchandran             "DUMP_ID", id, "ID", dumpId, "SIZE", size);
8862337a92SDhruvaraj Subhashchandran         entries.insert(std::make_pair(
8962337a92SDhruvaraj Subhashchandran             id, std::make_unique<resource::Entry>(
9062337a92SDhruvaraj Subhashchandran                     bus, objPath.c_str(), id, timeStamp, size, dumpId,
9162337a92SDhruvaraj Subhashchandran                     std::string(), std::string(),
9274a1f39cSAsmitha Karunanithi                     phosphor::dump::OperationStatus::Completed, std::string(),
9374a1f39cSAsmitha Karunanithi                     originatorTypes::Internal, *this)));
9462337a92SDhruvaraj Subhashchandran     }
9562337a92SDhruvaraj Subhashchandran     catch (const std::invalid_argument& e)
9662337a92SDhruvaraj Subhashchandran     {
97*d1f670feSDhruvaraj Subhashchandran         lg2::error(
98*d1f670feSDhruvaraj Subhashchandran             "Error in creating resource dump entry, errormsg: {ERROR}, "
99*d1f670feSDhruvaraj Subhashchandran             "OBJECTPATH: {OBJECT_PATH}, ID: {ID}, TIMESTAMP: {TIMESTAMP}, "
100*d1f670feSDhruvaraj Subhashchandran             "SIZE: {SIZE}, SOURCEID: {SOURCE_ID}",
101*d1f670feSDhruvaraj Subhashchandran             "ERROR", e, "OBJECT_PATH", objPath, "ID", id, "TIMESTAMP",
102*d1f670feSDhruvaraj Subhashchandran             timeStamp, "SIZE", size, "SOURCE_ID", dumpId);
10362337a92SDhruvaraj Subhashchandran         report<InternalFailure>();
10462337a92SDhruvaraj Subhashchandran         return;
10562337a92SDhruvaraj Subhashchandran     }
10662337a92SDhruvaraj Subhashchandran     lastEntryId++;
10762337a92SDhruvaraj Subhashchandran }
10862337a92SDhruvaraj Subhashchandran 
10962337a92SDhruvaraj Subhashchandran sdbusplus::message::object_path
createDump(phosphor::dump::DumpCreateParams params)110ddc3366eSDhruvaraj Subhashchandran     Manager::createDump(phosphor::dump::DumpCreateParams params)
11162337a92SDhruvaraj Subhashchandran {
11262337a92SDhruvaraj Subhashchandran     using NotAllowed =
11362337a92SDhruvaraj Subhashchandran         sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
11462337a92SDhruvaraj Subhashchandran     using Reason = xyz::openbmc_project::Common::NotAllowed::REASON;
11562337a92SDhruvaraj Subhashchandran 
11662337a92SDhruvaraj Subhashchandran     // Allow creating resource dump only when the host is up.
11762337a92SDhruvaraj Subhashchandran     if (!phosphor::dump::isHostRunning())
11862337a92SDhruvaraj Subhashchandran     {
11962337a92SDhruvaraj Subhashchandran         elog<NotAllowed>(
12062337a92SDhruvaraj Subhashchandran             Reason("Resource dump can be initiated only when the host is up"));
12162337a92SDhruvaraj Subhashchandran         return std::string();
12262337a92SDhruvaraj Subhashchandran     }
123ddc3366eSDhruvaraj Subhashchandran 
124ddc3366eSDhruvaraj Subhashchandran     using InvalidArgument =
125ddc3366eSDhruvaraj Subhashchandran         sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument;
126ddc3366eSDhruvaraj Subhashchandran     using Argument = xyz::openbmc_project::Common::InvalidArgument;
12762337a92SDhruvaraj Subhashchandran     using CreateParameters =
12862337a92SDhruvaraj Subhashchandran         sdbusplus::com::ibm::Dump::server::Create::CreateParameters;
12962337a92SDhruvaraj Subhashchandran 
13062337a92SDhruvaraj Subhashchandran     auto id = lastEntryId + 1;
13162337a92SDhruvaraj Subhashchandran     auto idString = std::to_string(id);
1323fc6df48SJayanth Othayoth     auto objPath = std::filesystem::path(baseEntryPath) / idString;
133c0ab9d43SClaire Weinan     uint64_t timeStamp =
134c0ab9d43SClaire Weinan         std::chrono::duration_cast<std::chrono::microseconds>(
135c0ab9d43SClaire Weinan             std::chrono::system_clock::now().time_since_epoch())
136c0ab9d43SClaire Weinan             .count();
13762337a92SDhruvaraj Subhashchandran 
138ddc3366eSDhruvaraj Subhashchandran     std::string vspString;
139ddc3366eSDhruvaraj Subhashchandran     auto iter = params.find(
140ddc3366eSDhruvaraj Subhashchandran         sdbusplus::com::ibm::Dump::server::Create::
141ddc3366eSDhruvaraj Subhashchandran             convertCreateParametersToString(CreateParameters::VSPString));
142ddc3366eSDhruvaraj Subhashchandran     if (iter == params.end())
143ddc3366eSDhruvaraj Subhashchandran     {
144ddc3366eSDhruvaraj Subhashchandran         // Host will generate a default dump if no resource selector string
145ddc3366eSDhruvaraj Subhashchandran         // is provided. The default dump will be a non-disruptive system dump.
146*d1f670feSDhruvaraj Subhashchandran         lg2::info(
147ddc3366eSDhruvaraj Subhashchandran             "VSP string is not provided, a non-disruptive system dump will be "
148ddc3366eSDhruvaraj Subhashchandran             "generated by the host");
149ddc3366eSDhruvaraj Subhashchandran     }
150ddc3366eSDhruvaraj Subhashchandran     else
151ddc3366eSDhruvaraj Subhashchandran     {
152ddc3366eSDhruvaraj Subhashchandran         try
153ddc3366eSDhruvaraj Subhashchandran         {
154ddc3366eSDhruvaraj Subhashchandran             vspString = std::get<std::string>(iter->second);
155ddc3366eSDhruvaraj Subhashchandran         }
156ddc3366eSDhruvaraj Subhashchandran         catch (const std::bad_variant_access& e)
157ddc3366eSDhruvaraj Subhashchandran         {
158ddc3366eSDhruvaraj Subhashchandran             // Exception will be raised if the input is not string
159*d1f670feSDhruvaraj Subhashchandran             lg2::error("An invalid vsp string is passed, errormsg: {ERROR}",
160*d1f670feSDhruvaraj Subhashchandran                        "ERROR", e);
161ddc3366eSDhruvaraj Subhashchandran             elog<InvalidArgument>(Argument::ARGUMENT_NAME("VSP_STRING"),
162ddc3366eSDhruvaraj Subhashchandran                                   Argument::ARGUMENT_VALUE("INVALID INPUT"));
163ddc3366eSDhruvaraj Subhashchandran         }
164ddc3366eSDhruvaraj Subhashchandran     }
165ddc3366eSDhruvaraj Subhashchandran 
166ddc3366eSDhruvaraj Subhashchandran     std::string pwd;
167ddc3366eSDhruvaraj Subhashchandran     iter = params.find(
168ddc3366eSDhruvaraj Subhashchandran         sdbusplus::com::ibm::Dump::server::Create::
169ddc3366eSDhruvaraj Subhashchandran             convertCreateParametersToString(CreateParameters::Password));
170ddc3366eSDhruvaraj Subhashchandran     if (iter == params.end())
171ddc3366eSDhruvaraj Subhashchandran     {
172*d1f670feSDhruvaraj Subhashchandran         lg2::info("Password is not provided for resource dump");
173ddc3366eSDhruvaraj Subhashchandran     }
174a5097b9eSDhruvaraj Subhashchandran     else
175a5097b9eSDhruvaraj Subhashchandran     {
176ddc3366eSDhruvaraj Subhashchandran         try
177ddc3366eSDhruvaraj Subhashchandran         {
178ddc3366eSDhruvaraj Subhashchandran             pwd = std::get<std::string>(iter->second);
179ddc3366eSDhruvaraj Subhashchandran         }
180ddc3366eSDhruvaraj Subhashchandran         catch (const std::bad_variant_access& e)
181ddc3366eSDhruvaraj Subhashchandran         {
182ddc3366eSDhruvaraj Subhashchandran             // Exception will be raised if the input is not string
183*d1f670feSDhruvaraj Subhashchandran             lg2::error(
184*d1f670feSDhruvaraj Subhashchandran                 "An invalid password string is passed, errormsg: {ERROR}",
185*d1f670feSDhruvaraj Subhashchandran                 "ERROR", e);
186ddc3366eSDhruvaraj Subhashchandran             elog<InvalidArgument>(Argument::ARGUMENT_NAME("PASSWORD"),
187ddc3366eSDhruvaraj Subhashchandran                                   Argument::ARGUMENT_VALUE("INVALID INPUT"));
188ddc3366eSDhruvaraj Subhashchandran         }
189a5097b9eSDhruvaraj Subhashchandran     }
19062337a92SDhruvaraj Subhashchandran 
19174a1f39cSAsmitha Karunanithi     // Get the originator id and type from params
19274a1f39cSAsmitha Karunanithi     std::string originatorId;
19374a1f39cSAsmitha Karunanithi     originatorTypes originatorType;
19474a1f39cSAsmitha Karunanithi 
19574a1f39cSAsmitha Karunanithi     phosphor::dump::extractOriginatorProperties(params, originatorId,
19674a1f39cSAsmitha Karunanithi                                                 originatorType);
19774a1f39cSAsmitha Karunanithi 
19862337a92SDhruvaraj Subhashchandran     try
19962337a92SDhruvaraj Subhashchandran     {
20062337a92SDhruvaraj Subhashchandran         entries.insert(std::make_pair(
20162337a92SDhruvaraj Subhashchandran             id, std::make_unique<resource::Entry>(
20262337a92SDhruvaraj Subhashchandran                     bus, objPath.c_str(), id, timeStamp, 0, INVALID_SOURCE_ID,
20362337a92SDhruvaraj Subhashchandran                     vspString, pwd, phosphor::dump::OperationStatus::InProgress,
20474a1f39cSAsmitha Karunanithi                     originatorId, originatorType, *this)));
20562337a92SDhruvaraj Subhashchandran     }
20662337a92SDhruvaraj Subhashchandran     catch (const std::invalid_argument& e)
20762337a92SDhruvaraj Subhashchandran     {
208*d1f670feSDhruvaraj Subhashchandran         lg2::error(
209*d1f670feSDhruvaraj Subhashchandran             "Error in creating resource dump entry, errormsg: {ERROR}, "
210*d1f670feSDhruvaraj Subhashchandran             "OBJECTPATH: {OBJECT_PATH}, VSPSTRING: {VSP_STRING}, ID: {ID}",
211*d1f670feSDhruvaraj Subhashchandran             "ERROR", e, "OBJECT_PATH", objPath, "VSP_STRING", vspString, "ID",
212*d1f670feSDhruvaraj Subhashchandran             id);
21362337a92SDhruvaraj Subhashchandran         elog<InternalFailure>();
21462337a92SDhruvaraj Subhashchandran         return std::string();
21562337a92SDhruvaraj Subhashchandran     }
21662337a92SDhruvaraj Subhashchandran     lastEntryId++;
21762337a92SDhruvaraj Subhashchandran     return objPath.string();
21862337a92SDhruvaraj Subhashchandran }
21962337a92SDhruvaraj Subhashchandran 
22062337a92SDhruvaraj Subhashchandran } // namespace resource
22162337a92SDhruvaraj Subhashchandran } // namespace dump
222341d683dSDhruvaraj Subhashchandran } // namespace openpower
223