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 
10858fbb2eSGeorge Liu #include <fmt/core.h>
11858fbb2eSGeorge Liu 
1262337a92SDhruvaraj Subhashchandran #include <phosphor-logging/elog-errors.hpp>
1362337a92SDhruvaraj Subhashchandran #include <phosphor-logging/elog.hpp>
1462337a92SDhruvaraj Subhashchandran 
15341d683dSDhruvaraj Subhashchandran namespace openpower
1662337a92SDhruvaraj Subhashchandran {
1762337a92SDhruvaraj Subhashchandran namespace dump
1862337a92SDhruvaraj Subhashchandran {
1962337a92SDhruvaraj Subhashchandran namespace resource
2062337a92SDhruvaraj Subhashchandran {
2162337a92SDhruvaraj Subhashchandran 
2262337a92SDhruvaraj Subhashchandran using namespace phosphor::logging;
2362337a92SDhruvaraj Subhashchandran using InternalFailure =
2462337a92SDhruvaraj Subhashchandran     sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
2562337a92SDhruvaraj Subhashchandran 
2662337a92SDhruvaraj Subhashchandran void Manager::notify(uint32_t dumpId, uint64_t size)
2762337a92SDhruvaraj Subhashchandran {
2862337a92SDhruvaraj Subhashchandran     // Get the timestamp
29*c0ab9d43SClaire Weinan     uint64_t timeStamp =
30*c0ab9d43SClaire Weinan         std::chrono::duration_cast<std::chrono::microseconds>(
31*c0ab9d43SClaire Weinan             std::chrono::system_clock::now().time_since_epoch())
32*c0ab9d43SClaire Weinan             .count();
3362337a92SDhruvaraj Subhashchandran 
34583ebc09SDhruvaraj Subhashchandran     // If there is an entry with invalid id update that.
35583ebc09SDhruvaraj Subhashchandran     // If there a completed one with same source id ignore it
36583ebc09SDhruvaraj Subhashchandran     // if there is no invalid id, create new entry
37583ebc09SDhruvaraj Subhashchandran     openpower::dump::resource::Entry* upEntry = NULL;
3862337a92SDhruvaraj Subhashchandran     for (auto& entry : entries)
3962337a92SDhruvaraj Subhashchandran     {
40341d683dSDhruvaraj Subhashchandran         openpower::dump::resource::Entry* resEntry =
41341d683dSDhruvaraj Subhashchandran             dynamic_cast<openpower::dump::resource::Entry*>(entry.second.get());
42583ebc09SDhruvaraj Subhashchandran 
43583ebc09SDhruvaraj Subhashchandran         // If there is already a completed entry with input source id then
44583ebc09SDhruvaraj Subhashchandran         // ignore this notification.
45583ebc09SDhruvaraj Subhashchandran         if ((resEntry->sourceDumpId() == dumpId) &&
46583ebc09SDhruvaraj Subhashchandran             (resEntry->status() == phosphor::dump::OperationStatus::Completed))
4762337a92SDhruvaraj Subhashchandran         {
48583ebc09SDhruvaraj Subhashchandran             log<level::INFO>(
49583ebc09SDhruvaraj Subhashchandran                 fmt::format("Resource dump entry with source dump id({}) is "
50583ebc09SDhruvaraj Subhashchandran                             "already present with entry id({})",
51583ebc09SDhruvaraj Subhashchandran                             dumpId, resEntry->getDumpId())
52583ebc09SDhruvaraj Subhashchandran                     .c_str());
5362337a92SDhruvaraj Subhashchandran             return;
5462337a92SDhruvaraj Subhashchandran         }
55583ebc09SDhruvaraj Subhashchandran 
56583ebc09SDhruvaraj Subhashchandran         // Save the first entry with INVALID_SOURCE_ID
57583ebc09SDhruvaraj Subhashchandran         // but continue in the loop to make sure the
58583ebc09SDhruvaraj Subhashchandran         // new entry is not duplicate
59583ebc09SDhruvaraj Subhashchandran         if ((resEntry->status() ==
60583ebc09SDhruvaraj Subhashchandran              phosphor::dump::OperationStatus::InProgress) &&
61583ebc09SDhruvaraj Subhashchandran             (resEntry->sourceDumpId() == INVALID_SOURCE_ID) &&
62583ebc09SDhruvaraj Subhashchandran             (upEntry == NULL))
63583ebc09SDhruvaraj Subhashchandran         {
64583ebc09SDhruvaraj Subhashchandran             upEntry = resEntry;
6562337a92SDhruvaraj Subhashchandran         }
66583ebc09SDhruvaraj Subhashchandran     }
67583ebc09SDhruvaraj Subhashchandran     if (upEntry != NULL)
68583ebc09SDhruvaraj Subhashchandran     {
69583ebc09SDhruvaraj Subhashchandran         log<level::INFO>(
70583ebc09SDhruvaraj Subhashchandran             fmt::format("Resource Dump Notify: Updating dumpId({}) "
71583ebc09SDhruvaraj Subhashchandran                         "with source Id({}) Size({})",
72583ebc09SDhruvaraj Subhashchandran                         upEntry->getDumpId(), dumpId, size)
73583ebc09SDhruvaraj Subhashchandran                 .c_str());
74583ebc09SDhruvaraj Subhashchandran         upEntry->update(timeStamp, size, dumpId);
75583ebc09SDhruvaraj Subhashchandran         return;
76583ebc09SDhruvaraj Subhashchandran     }
77583ebc09SDhruvaraj Subhashchandran 
7862337a92SDhruvaraj Subhashchandran     // Get the id
7962337a92SDhruvaraj Subhashchandran     auto id = lastEntryId + 1;
8062337a92SDhruvaraj Subhashchandran     auto idString = std::to_string(id);
813fc6df48SJayanth Othayoth     auto objPath = std::filesystem::path(baseEntryPath) / idString;
8262337a92SDhruvaraj Subhashchandran 
8362337a92SDhruvaraj Subhashchandran     try
8462337a92SDhruvaraj Subhashchandran     {
85583ebc09SDhruvaraj Subhashchandran         log<level::INFO>(fmt::format("Resouce Dump Notify: creating new dump "
86583ebc09SDhruvaraj Subhashchandran                                      "entry dumpId({}) Id({}) Size({})",
87583ebc09SDhruvaraj Subhashchandran                                      id, dumpId, size)
88583ebc09SDhruvaraj Subhashchandran                              .c_str());
8962337a92SDhruvaraj Subhashchandran         entries.insert(std::make_pair(
9062337a92SDhruvaraj Subhashchandran             id, std::make_unique<resource::Entry>(
9162337a92SDhruvaraj Subhashchandran                     bus, objPath.c_str(), id, timeStamp, size, dumpId,
9262337a92SDhruvaraj Subhashchandran                     std::string(), std::string(),
9362337a92SDhruvaraj Subhashchandran                     phosphor::dump::OperationStatus::Completed, *this)));
9462337a92SDhruvaraj Subhashchandran     }
9562337a92SDhruvaraj Subhashchandran     catch (const std::invalid_argument& e)
9662337a92SDhruvaraj Subhashchandran     {
97858fbb2eSGeorge Liu         log<level::ERR>(fmt::format("Error in creating resource dump entry, "
98858fbb2eSGeorge Liu                                     "errormsg({}),OBJECTPATH({}),ID({}),"
99858fbb2eSGeorge Liu                                     "TIMESTAMP({}),SIZE({}),SOURCEID({})",
100363af249SGeorge Liu                                     e.what(), objPath.c_str(), id, timeStamp,
101363af249SGeorge Liu                                     size, dumpId)
102858fbb2eSGeorge Liu                             .c_str());
10362337a92SDhruvaraj Subhashchandran         report<InternalFailure>();
10462337a92SDhruvaraj Subhashchandran         return;
10562337a92SDhruvaraj Subhashchandran     }
10662337a92SDhruvaraj Subhashchandran     lastEntryId++;
10762337a92SDhruvaraj Subhashchandran }
10862337a92SDhruvaraj Subhashchandran 
10962337a92SDhruvaraj Subhashchandran sdbusplus::message::object_path
110ddc3366eSDhruvaraj Subhashchandran     Manager::createDump(phosphor::dump::DumpCreateParams params)
11162337a92SDhruvaraj Subhashchandran {
11262337a92SDhruvaraj Subhashchandran 
11362337a92SDhruvaraj Subhashchandran     using NotAllowed =
11462337a92SDhruvaraj Subhashchandran         sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
11562337a92SDhruvaraj Subhashchandran     using Reason = xyz::openbmc_project::Common::NotAllowed::REASON;
11662337a92SDhruvaraj Subhashchandran 
11762337a92SDhruvaraj Subhashchandran     // Allow creating resource dump only when the host is up.
11862337a92SDhruvaraj Subhashchandran     if (!phosphor::dump::isHostRunning())
11962337a92SDhruvaraj Subhashchandran     {
12062337a92SDhruvaraj Subhashchandran         elog<NotAllowed>(
12162337a92SDhruvaraj Subhashchandran             Reason("Resource dump can be initiated only when the host is up"));
12262337a92SDhruvaraj Subhashchandran         return std::string();
12362337a92SDhruvaraj Subhashchandran     }
124ddc3366eSDhruvaraj Subhashchandran 
125ddc3366eSDhruvaraj Subhashchandran     using InvalidArgument =
126ddc3366eSDhruvaraj Subhashchandran         sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument;
127ddc3366eSDhruvaraj Subhashchandran     using Argument = xyz::openbmc_project::Common::InvalidArgument;
12862337a92SDhruvaraj Subhashchandran     using CreateParameters =
12962337a92SDhruvaraj Subhashchandran         sdbusplus::com::ibm::Dump::server::Create::CreateParameters;
13062337a92SDhruvaraj Subhashchandran 
13162337a92SDhruvaraj Subhashchandran     auto id = lastEntryId + 1;
13262337a92SDhruvaraj Subhashchandran     auto idString = std::to_string(id);
1333fc6df48SJayanth Othayoth     auto objPath = std::filesystem::path(baseEntryPath) / idString;
134*c0ab9d43SClaire Weinan     uint64_t timeStamp =
135*c0ab9d43SClaire Weinan         std::chrono::duration_cast<std::chrono::microseconds>(
136*c0ab9d43SClaire Weinan             std::chrono::system_clock::now().time_since_epoch())
137*c0ab9d43SClaire Weinan             .count();
13862337a92SDhruvaraj Subhashchandran 
139ddc3366eSDhruvaraj Subhashchandran     std::string vspString;
140ddc3366eSDhruvaraj Subhashchandran     auto iter = params.find(
141ddc3366eSDhruvaraj Subhashchandran         sdbusplus::com::ibm::Dump::server::Create::
142ddc3366eSDhruvaraj Subhashchandran             convertCreateParametersToString(CreateParameters::VSPString));
143ddc3366eSDhruvaraj Subhashchandran     if (iter == params.end())
144ddc3366eSDhruvaraj Subhashchandran     {
145ddc3366eSDhruvaraj Subhashchandran         // Host will generate a default dump if no resource selector string
146ddc3366eSDhruvaraj Subhashchandran         // is provided. The default dump will be a non-disruptive system dump.
147ddc3366eSDhruvaraj Subhashchandran         log<level::INFO>(
148ddc3366eSDhruvaraj Subhashchandran             "VSP string is not provided, a non-disruptive system dump will be "
149ddc3366eSDhruvaraj Subhashchandran             "generated by the host");
150ddc3366eSDhruvaraj Subhashchandran     }
151ddc3366eSDhruvaraj Subhashchandran     else
152ddc3366eSDhruvaraj Subhashchandran     {
153ddc3366eSDhruvaraj Subhashchandran         try
154ddc3366eSDhruvaraj Subhashchandran         {
155ddc3366eSDhruvaraj Subhashchandran             vspString = std::get<std::string>(iter->second);
156ddc3366eSDhruvaraj Subhashchandran         }
157ddc3366eSDhruvaraj Subhashchandran         catch (const std::bad_variant_access& e)
158ddc3366eSDhruvaraj Subhashchandran         {
159ddc3366eSDhruvaraj Subhashchandran             // Exception will be raised if the input is not string
160ddc3366eSDhruvaraj Subhashchandran             log<level::ERR>(
161ddc3366eSDhruvaraj Subhashchandran                 fmt::format("An invalid  vsp string is passed errormsg({})",
162ddc3366eSDhruvaraj Subhashchandran                             e.what())
163ddc3366eSDhruvaraj Subhashchandran                     .c_str());
164ddc3366eSDhruvaraj Subhashchandran             elog<InvalidArgument>(Argument::ARGUMENT_NAME("VSP_STRING"),
165ddc3366eSDhruvaraj Subhashchandran                                   Argument::ARGUMENT_VALUE("INVALID INPUT"));
166ddc3366eSDhruvaraj Subhashchandran         }
167ddc3366eSDhruvaraj Subhashchandran     }
168ddc3366eSDhruvaraj Subhashchandran 
169ddc3366eSDhruvaraj Subhashchandran     std::string pwd;
170ddc3366eSDhruvaraj Subhashchandran     iter = params.find(
171ddc3366eSDhruvaraj Subhashchandran         sdbusplus::com::ibm::Dump::server::Create::
172ddc3366eSDhruvaraj Subhashchandran             convertCreateParametersToString(CreateParameters::Password));
173ddc3366eSDhruvaraj Subhashchandran     if (iter == params.end())
174ddc3366eSDhruvaraj Subhashchandran     {
175a5097b9eSDhruvaraj Subhashchandran         log<level::INFO>("Password is not provided for resource dump");
176ddc3366eSDhruvaraj Subhashchandran     }
177a5097b9eSDhruvaraj Subhashchandran     else
178a5097b9eSDhruvaraj Subhashchandran     {
179ddc3366eSDhruvaraj Subhashchandran         try
180ddc3366eSDhruvaraj Subhashchandran         {
181ddc3366eSDhruvaraj Subhashchandran             pwd = std::get<std::string>(iter->second);
182ddc3366eSDhruvaraj Subhashchandran         }
183ddc3366eSDhruvaraj Subhashchandran         catch (const std::bad_variant_access& e)
184ddc3366eSDhruvaraj Subhashchandran         {
185ddc3366eSDhruvaraj Subhashchandran             // Exception will be raised if the input is not string
186ddc3366eSDhruvaraj Subhashchandran             log<level::ERR>(
187ddc3366eSDhruvaraj Subhashchandran                 fmt::format("An invalid password string is passed errormsg({})",
188ddc3366eSDhruvaraj Subhashchandran                             e.what())
189ddc3366eSDhruvaraj Subhashchandran                     .c_str());
190ddc3366eSDhruvaraj Subhashchandran             elog<InvalidArgument>(Argument::ARGUMENT_NAME("PASSWORD"),
191ddc3366eSDhruvaraj Subhashchandran                                   Argument::ARGUMENT_VALUE("INVALID INPUT"));
192ddc3366eSDhruvaraj Subhashchandran         }
193a5097b9eSDhruvaraj Subhashchandran     }
19462337a92SDhruvaraj Subhashchandran 
19562337a92SDhruvaraj Subhashchandran     try
19662337a92SDhruvaraj Subhashchandran     {
19762337a92SDhruvaraj Subhashchandran         entries.insert(std::make_pair(
19862337a92SDhruvaraj Subhashchandran             id, std::make_unique<resource::Entry>(
19962337a92SDhruvaraj Subhashchandran                     bus, objPath.c_str(), id, timeStamp, 0, INVALID_SOURCE_ID,
20062337a92SDhruvaraj Subhashchandran                     vspString, pwd, phosphor::dump::OperationStatus::InProgress,
20162337a92SDhruvaraj Subhashchandran                     *this)));
20262337a92SDhruvaraj Subhashchandran     }
20362337a92SDhruvaraj Subhashchandran     catch (const std::invalid_argument& e)
20462337a92SDhruvaraj Subhashchandran     {
205858fbb2eSGeorge Liu         log<level::ERR>(
206858fbb2eSGeorge Liu             fmt::format(
207858fbb2eSGeorge Liu                 "Error in creating resource dump "
208858fbb2eSGeorge Liu                 "entry,errormsg({}),OBJECTPATH({}), VSPSTRING({}), ID({})",
209363af249SGeorge Liu                 e.what(), objPath.c_str(), vspString, id)
210858fbb2eSGeorge Liu                 .c_str());
21162337a92SDhruvaraj Subhashchandran         elog<InternalFailure>();
21262337a92SDhruvaraj Subhashchandran         return std::string();
21362337a92SDhruvaraj Subhashchandran     }
21462337a92SDhruvaraj Subhashchandran     lastEntryId++;
21562337a92SDhruvaraj Subhashchandran     return objPath.string();
21662337a92SDhruvaraj Subhashchandran }
21762337a92SDhruvaraj Subhashchandran 
21862337a92SDhruvaraj Subhashchandran } // namespace resource
21962337a92SDhruvaraj Subhashchandran } // namespace dump
220341d683dSDhruvaraj Subhashchandran } // namespace openpower
221