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
2962337a92SDhruvaraj Subhashchandran     std::time_t timeStamp = std::time(nullptr);
3062337a92SDhruvaraj Subhashchandran 
31*583ebc09SDhruvaraj Subhashchandran     // If there is an entry with invalid id update that.
32*583ebc09SDhruvaraj Subhashchandran     // If there a completed one with same source id ignore it
33*583ebc09SDhruvaraj Subhashchandran     // if there is no invalid id, create new entry
34*583ebc09SDhruvaraj Subhashchandran     openpower::dump::resource::Entry* upEntry = NULL;
3562337a92SDhruvaraj Subhashchandran     for (auto& entry : entries)
3662337a92SDhruvaraj Subhashchandran     {
37341d683dSDhruvaraj Subhashchandran         openpower::dump::resource::Entry* resEntry =
38341d683dSDhruvaraj Subhashchandran             dynamic_cast<openpower::dump::resource::Entry*>(entry.second.get());
39*583ebc09SDhruvaraj Subhashchandran 
40*583ebc09SDhruvaraj Subhashchandran         // If there is already a completed entry with input source id then
41*583ebc09SDhruvaraj Subhashchandran         // ignore this notification.
42*583ebc09SDhruvaraj Subhashchandran         if ((resEntry->sourceDumpId() == dumpId) &&
43*583ebc09SDhruvaraj Subhashchandran             (resEntry->status() == phosphor::dump::OperationStatus::Completed))
4462337a92SDhruvaraj Subhashchandran         {
45*583ebc09SDhruvaraj Subhashchandran             log<level::INFO>(
46*583ebc09SDhruvaraj Subhashchandran                 fmt::format("Resource dump entry with source dump id({}) is "
47*583ebc09SDhruvaraj Subhashchandran                             "already present with entry id({})",
48*583ebc09SDhruvaraj Subhashchandran                             dumpId, resEntry->getDumpId())
49*583ebc09SDhruvaraj Subhashchandran                     .c_str());
5062337a92SDhruvaraj Subhashchandran             return;
5162337a92SDhruvaraj Subhashchandran         }
52*583ebc09SDhruvaraj Subhashchandran 
53*583ebc09SDhruvaraj Subhashchandran         // Save the first entry with INVALID_SOURCE_ID
54*583ebc09SDhruvaraj Subhashchandran         // but continue in the loop to make sure the
55*583ebc09SDhruvaraj Subhashchandran         // new entry is not duplicate
56*583ebc09SDhruvaraj Subhashchandran         if ((resEntry->status() ==
57*583ebc09SDhruvaraj Subhashchandran              phosphor::dump::OperationStatus::InProgress) &&
58*583ebc09SDhruvaraj Subhashchandran             (resEntry->sourceDumpId() == INVALID_SOURCE_ID) &&
59*583ebc09SDhruvaraj Subhashchandran             (upEntry == NULL))
60*583ebc09SDhruvaraj Subhashchandran         {
61*583ebc09SDhruvaraj Subhashchandran             upEntry = resEntry;
6262337a92SDhruvaraj Subhashchandran         }
63*583ebc09SDhruvaraj Subhashchandran     }
64*583ebc09SDhruvaraj Subhashchandran     if (upEntry != NULL)
65*583ebc09SDhruvaraj Subhashchandran     {
66*583ebc09SDhruvaraj Subhashchandran         log<level::INFO>(
67*583ebc09SDhruvaraj Subhashchandran             fmt::format("Resource Dump Notify: Updating dumpId({}) "
68*583ebc09SDhruvaraj Subhashchandran                         "with source Id({}) Size({})",
69*583ebc09SDhruvaraj Subhashchandran                         upEntry->getDumpId(), dumpId, size)
70*583ebc09SDhruvaraj Subhashchandran                 .c_str());
71*583ebc09SDhruvaraj Subhashchandran         upEntry->update(timeStamp, size, dumpId);
72*583ebc09SDhruvaraj Subhashchandran         return;
73*583ebc09SDhruvaraj Subhashchandran     }
74*583ebc09SDhruvaraj Subhashchandran 
7562337a92SDhruvaraj Subhashchandran     // Get the id
7662337a92SDhruvaraj Subhashchandran     auto id = lastEntryId + 1;
7762337a92SDhruvaraj Subhashchandran     auto idString = std::to_string(id);
783fc6df48SJayanth Othayoth     auto objPath = std::filesystem::path(baseEntryPath) / idString;
7962337a92SDhruvaraj Subhashchandran 
8062337a92SDhruvaraj Subhashchandran     try
8162337a92SDhruvaraj Subhashchandran     {
82*583ebc09SDhruvaraj Subhashchandran         log<level::INFO>(fmt::format("Resouce Dump Notify: creating new dump "
83*583ebc09SDhruvaraj Subhashchandran                                      "entry dumpId({}) Id({}) Size({})",
84*583ebc09SDhruvaraj Subhashchandran                                      id, dumpId, size)
85*583ebc09SDhruvaraj Subhashchandran                              .c_str());
8662337a92SDhruvaraj Subhashchandran         entries.insert(std::make_pair(
8762337a92SDhruvaraj Subhashchandran             id, std::make_unique<resource::Entry>(
8862337a92SDhruvaraj Subhashchandran                     bus, objPath.c_str(), id, timeStamp, size, dumpId,
8962337a92SDhruvaraj Subhashchandran                     std::string(), std::string(),
9062337a92SDhruvaraj Subhashchandran                     phosphor::dump::OperationStatus::Completed, *this)));
9162337a92SDhruvaraj Subhashchandran     }
9262337a92SDhruvaraj Subhashchandran     catch (const std::invalid_argument& e)
9362337a92SDhruvaraj Subhashchandran     {
94858fbb2eSGeorge Liu         log<level::ERR>(fmt::format("Error in creating resource dump entry, "
95858fbb2eSGeorge Liu                                     "errormsg({}),OBJECTPATH({}),ID({}),"
96858fbb2eSGeorge Liu                                     "TIMESTAMP({}),SIZE({}),SOURCEID({})",
97363af249SGeorge Liu                                     e.what(), objPath.c_str(), id, timeStamp,
98363af249SGeorge Liu                                     size, dumpId)
99858fbb2eSGeorge Liu                             .c_str());
10062337a92SDhruvaraj Subhashchandran         report<InternalFailure>();
10162337a92SDhruvaraj Subhashchandran         return;
10262337a92SDhruvaraj Subhashchandran     }
10362337a92SDhruvaraj Subhashchandran     lastEntryId++;
10462337a92SDhruvaraj Subhashchandran }
10562337a92SDhruvaraj Subhashchandran 
10662337a92SDhruvaraj Subhashchandran sdbusplus::message::object_path
107ddc3366eSDhruvaraj Subhashchandran     Manager::createDump(phosphor::dump::DumpCreateParams params)
10862337a92SDhruvaraj Subhashchandran {
10962337a92SDhruvaraj Subhashchandran 
11062337a92SDhruvaraj Subhashchandran     using NotAllowed =
11162337a92SDhruvaraj Subhashchandran         sdbusplus::xyz::openbmc_project::Common::Error::NotAllowed;
11262337a92SDhruvaraj Subhashchandran     using Reason = xyz::openbmc_project::Common::NotAllowed::REASON;
11362337a92SDhruvaraj Subhashchandran 
11462337a92SDhruvaraj Subhashchandran     // Allow creating resource dump only when the host is up.
11562337a92SDhruvaraj Subhashchandran     if (!phosphor::dump::isHostRunning())
11662337a92SDhruvaraj Subhashchandran     {
11762337a92SDhruvaraj Subhashchandran         elog<NotAllowed>(
11862337a92SDhruvaraj Subhashchandran             Reason("Resource dump can be initiated only when the host is up"));
11962337a92SDhruvaraj Subhashchandran         return std::string();
12062337a92SDhruvaraj Subhashchandran     }
121ddc3366eSDhruvaraj Subhashchandran 
122ddc3366eSDhruvaraj Subhashchandran     using InvalidArgument =
123ddc3366eSDhruvaraj Subhashchandran         sdbusplus::xyz::openbmc_project::Common::Error::InvalidArgument;
124ddc3366eSDhruvaraj Subhashchandran     using Argument = xyz::openbmc_project::Common::InvalidArgument;
12562337a92SDhruvaraj Subhashchandran     using CreateParameters =
12662337a92SDhruvaraj Subhashchandran         sdbusplus::com::ibm::Dump::server::Create::CreateParameters;
12762337a92SDhruvaraj Subhashchandran 
12862337a92SDhruvaraj Subhashchandran     auto id = lastEntryId + 1;
12962337a92SDhruvaraj Subhashchandran     auto idString = std::to_string(id);
1303fc6df48SJayanth Othayoth     auto objPath = std::filesystem::path(baseEntryPath) / idString;
13162337a92SDhruvaraj Subhashchandran     std::time_t timeStamp = std::time(nullptr);
13262337a92SDhruvaraj Subhashchandran 
133ddc3366eSDhruvaraj Subhashchandran     std::string vspString;
134ddc3366eSDhruvaraj Subhashchandran     auto iter = params.find(
135ddc3366eSDhruvaraj Subhashchandran         sdbusplus::com::ibm::Dump::server::Create::
136ddc3366eSDhruvaraj Subhashchandran             convertCreateParametersToString(CreateParameters::VSPString));
137ddc3366eSDhruvaraj Subhashchandran     if (iter == params.end())
138ddc3366eSDhruvaraj Subhashchandran     {
139ddc3366eSDhruvaraj Subhashchandran         // Host will generate a default dump if no resource selector string
140ddc3366eSDhruvaraj Subhashchandran         // is provided. The default dump will be a non-disruptive system dump.
141ddc3366eSDhruvaraj Subhashchandran         log<level::INFO>(
142ddc3366eSDhruvaraj Subhashchandran             "VSP string is not provided, a non-disruptive system dump will be "
143ddc3366eSDhruvaraj Subhashchandran             "generated by the host");
144ddc3366eSDhruvaraj Subhashchandran     }
145ddc3366eSDhruvaraj Subhashchandran     else
146ddc3366eSDhruvaraj Subhashchandran     {
147ddc3366eSDhruvaraj Subhashchandran         try
148ddc3366eSDhruvaraj Subhashchandran         {
149ddc3366eSDhruvaraj Subhashchandran             vspString = std::get<std::string>(iter->second);
150ddc3366eSDhruvaraj Subhashchandran         }
151ddc3366eSDhruvaraj Subhashchandran         catch (const std::bad_variant_access& e)
152ddc3366eSDhruvaraj Subhashchandran         {
153ddc3366eSDhruvaraj Subhashchandran             // Exception will be raised if the input is not string
154ddc3366eSDhruvaraj Subhashchandran             log<level::ERR>(
155ddc3366eSDhruvaraj Subhashchandran                 fmt::format("An invalid  vsp string is passed errormsg({})",
156ddc3366eSDhruvaraj Subhashchandran                             e.what())
157ddc3366eSDhruvaraj Subhashchandran                     .c_str());
158ddc3366eSDhruvaraj Subhashchandran             elog<InvalidArgument>(Argument::ARGUMENT_NAME("VSP_STRING"),
159ddc3366eSDhruvaraj Subhashchandran                                   Argument::ARGUMENT_VALUE("INVALID INPUT"));
160ddc3366eSDhruvaraj Subhashchandran         }
161ddc3366eSDhruvaraj Subhashchandran     }
162ddc3366eSDhruvaraj Subhashchandran 
163ddc3366eSDhruvaraj Subhashchandran     std::string pwd;
164ddc3366eSDhruvaraj Subhashchandran     iter = params.find(
165ddc3366eSDhruvaraj Subhashchandran         sdbusplus::com::ibm::Dump::server::Create::
166ddc3366eSDhruvaraj Subhashchandran             convertCreateParametersToString(CreateParameters::Password));
167ddc3366eSDhruvaraj Subhashchandran     if (iter == params.end())
168ddc3366eSDhruvaraj Subhashchandran     {
169ddc3366eSDhruvaraj Subhashchandran         log<level::ERR>("Required argument password is missing");
170ddc3366eSDhruvaraj Subhashchandran         elog<InvalidArgument>(Argument::ARGUMENT_NAME("PASSOWORD"),
171ddc3366eSDhruvaraj Subhashchandran                               Argument::ARGUMENT_VALUE("MISSING"));
172ddc3366eSDhruvaraj Subhashchandran     }
173ddc3366eSDhruvaraj Subhashchandran 
174ddc3366eSDhruvaraj Subhashchandran     try
175ddc3366eSDhruvaraj Subhashchandran     {
176ddc3366eSDhruvaraj Subhashchandran         pwd = std::get<std::string>(iter->second);
177ddc3366eSDhruvaraj Subhashchandran     }
178ddc3366eSDhruvaraj Subhashchandran     catch (const std::bad_variant_access& e)
179ddc3366eSDhruvaraj Subhashchandran     {
180ddc3366eSDhruvaraj Subhashchandran         // Exception will be raised if the input is not string
181ddc3366eSDhruvaraj Subhashchandran         log<level::ERR>(
182ddc3366eSDhruvaraj Subhashchandran             fmt::format("An invalid password string is passed errormsg({})",
183ddc3366eSDhruvaraj Subhashchandran                         e.what())
184ddc3366eSDhruvaraj Subhashchandran                 .c_str());
185ddc3366eSDhruvaraj Subhashchandran         elog<InvalidArgument>(Argument::ARGUMENT_NAME("PASSWORD"),
186ddc3366eSDhruvaraj Subhashchandran                               Argument::ARGUMENT_VALUE("INVALID INPUT"));
187ddc3366eSDhruvaraj Subhashchandran     }
18862337a92SDhruvaraj Subhashchandran 
18962337a92SDhruvaraj Subhashchandran     try
19062337a92SDhruvaraj Subhashchandran     {
19162337a92SDhruvaraj Subhashchandran         entries.insert(std::make_pair(
19262337a92SDhruvaraj Subhashchandran             id, std::make_unique<resource::Entry>(
19362337a92SDhruvaraj Subhashchandran                     bus, objPath.c_str(), id, timeStamp, 0, INVALID_SOURCE_ID,
19462337a92SDhruvaraj Subhashchandran                     vspString, pwd, phosphor::dump::OperationStatus::InProgress,
19562337a92SDhruvaraj Subhashchandran                     *this)));
19662337a92SDhruvaraj Subhashchandran     }
19762337a92SDhruvaraj Subhashchandran     catch (const std::invalid_argument& e)
19862337a92SDhruvaraj Subhashchandran     {
199858fbb2eSGeorge Liu         log<level::ERR>(
200858fbb2eSGeorge Liu             fmt::format(
201858fbb2eSGeorge Liu                 "Error in creating resource dump "
202858fbb2eSGeorge Liu                 "entry,errormsg({}),OBJECTPATH({}), VSPSTRING({}), ID({})",
203363af249SGeorge Liu                 e.what(), objPath.c_str(), vspString, id)
204858fbb2eSGeorge Liu                 .c_str());
20562337a92SDhruvaraj Subhashchandran         elog<InternalFailure>();
20662337a92SDhruvaraj Subhashchandran         return std::string();
20762337a92SDhruvaraj Subhashchandran     }
20862337a92SDhruvaraj Subhashchandran     lastEntryId++;
20962337a92SDhruvaraj Subhashchandran     return objPath.string();
21062337a92SDhruvaraj Subhashchandran }
21162337a92SDhruvaraj Subhashchandran 
21262337a92SDhruvaraj Subhashchandran } // namespace resource
21362337a92SDhruvaraj Subhashchandran } // namespace dump
214341d683dSDhruvaraj Subhashchandran } // namespace openpower
215