1919f71c6SClaire Weinan #include "config.h"
2919f71c6SClaire Weinan 
3919f71c6SClaire Weinan #include "dump_manager_faultlog.hpp"
4919f71c6SClaire Weinan 
5*74a1f39cSAsmitha Karunanithi #include "dump_utils.hpp"
6919f71c6SClaire Weinan #include "faultlog_dump_entry.hpp"
7919f71c6SClaire Weinan 
8919f71c6SClaire Weinan #include <fmt/core.h>
9919f71c6SClaire Weinan 
10919f71c6SClaire Weinan #include <phosphor-logging/elog-errors.hpp>
11919f71c6SClaire Weinan #include <phosphor-logging/elog.hpp>
12919f71c6SClaire Weinan #include <xyz/openbmc_project/Common/File/error.hpp>
13919f71c6SClaire Weinan #include <xyz/openbmc_project/Common/error.hpp>
14919f71c6SClaire Weinan 
15919f71c6SClaire Weinan #include <filesystem>
16919f71c6SClaire Weinan #include <fstream>
17919f71c6SClaire Weinan #include <iostream>
18919f71c6SClaire Weinan #include <string>
19919f71c6SClaire Weinan 
20919f71c6SClaire Weinan namespace phosphor
21919f71c6SClaire Weinan {
22919f71c6SClaire Weinan namespace dump
23919f71c6SClaire Weinan {
24919f71c6SClaire Weinan namespace faultlog
25919f71c6SClaire Weinan {
26919f71c6SClaire Weinan 
27919f71c6SClaire Weinan using namespace phosphor::logging;
28919f71c6SClaire Weinan using namespace sdbusplus::xyz::openbmc_project::Common::Error;
29919f71c6SClaire Weinan using namespace sdbusplus::xyz::openbmc_project::Common::File::Error;
30919f71c6SClaire Weinan using ErrnoOpen = xyz::openbmc_project::Common::File::Open::ERRNO;
31919f71c6SClaire Weinan using PathOpen = xyz::openbmc_project::Common::File::Open::PATH;
32919f71c6SClaire Weinan 
33919f71c6SClaire Weinan sdbusplus::message::object_path
34919f71c6SClaire Weinan     Manager::createDump(phosphor::dump::DumpCreateParams params)
35919f71c6SClaire Weinan {
36919f71c6SClaire Weinan     log<level::INFO>("In dump_manager_fault.cpp createDump");
37919f71c6SClaire Weinan 
38919f71c6SClaire Weinan     // Currently we ignore the parameters.
39919f71c6SClaire Weinan     // TODO phosphor-debug-collector/issues/22: Check parameter values and
40919f71c6SClaire Weinan     // exit early if we don't receive the expected parameters
41919f71c6SClaire Weinan     if (params.empty())
42919f71c6SClaire Weinan     {
43919f71c6SClaire Weinan         log<level::INFO>("No additional parameters received");
44919f71c6SClaire Weinan     }
45919f71c6SClaire Weinan     else
46919f71c6SClaire Weinan     {
47919f71c6SClaire Weinan         log<level::INFO>("Got additional parameters");
48919f71c6SClaire Weinan     }
49919f71c6SClaire Weinan 
50*74a1f39cSAsmitha Karunanithi     // Get the originator id and type from params
51*74a1f39cSAsmitha Karunanithi     std::string originatorId;
52*74a1f39cSAsmitha Karunanithi     originatorTypes originatorType;
53*74a1f39cSAsmitha Karunanithi 
54*74a1f39cSAsmitha Karunanithi     phosphor::dump::extractOriginatorProperties(params, originatorId,
55*74a1f39cSAsmitha Karunanithi                                                 originatorType);
56*74a1f39cSAsmitha Karunanithi 
57919f71c6SClaire Weinan     // Get the id
58919f71c6SClaire Weinan     auto id = lastEntryId + 1;
59919f71c6SClaire Weinan     auto idString = std::to_string(id);
60919f71c6SClaire Weinan     auto objPath = std::filesystem::path(baseEntryPath) / idString;
61919f71c6SClaire Weinan 
62919f71c6SClaire Weinan     std::filesystem::path faultLogFilePath(std::string(FAULTLOG_DUMP_PATH) +
63919f71c6SClaire Weinan                                            idString);
64919f71c6SClaire Weinan     std::ofstream faultLogFile;
65919f71c6SClaire Weinan 
66919f71c6SClaire Weinan     errno = 0;
67919f71c6SClaire Weinan 
68919f71c6SClaire Weinan     faultLogFile.open(faultLogFilePath,
69919f71c6SClaire Weinan                       std::ofstream::out | std::fstream::trunc);
70919f71c6SClaire Weinan 
71919f71c6SClaire Weinan     if (faultLogFile.is_open())
72919f71c6SClaire Weinan     {
73919f71c6SClaire Weinan         log<level::INFO>("faultLogFile is open");
74919f71c6SClaire Weinan 
75919f71c6SClaire Weinan         faultLogFile << "This is faultlog file #" << idString << " at "
76919f71c6SClaire Weinan                      << std::string(FAULTLOG_DUMP_PATH) + idString << std::endl;
77919f71c6SClaire Weinan 
78919f71c6SClaire Weinan         faultLogFile.close();
79919f71c6SClaire Weinan     }
80919f71c6SClaire Weinan     else
81919f71c6SClaire Weinan     {
82919f71c6SClaire Weinan         log<level::ERR>(fmt::format("Failed to open fault log file at {}, "
83919f71c6SClaire Weinan                                     "errno({}), strerror(\"{}\"), "
84919f71c6SClaire Weinan                                     "OBJECTPATH({}), ID({})",
85919f71c6SClaire Weinan                                     faultLogFilePath.c_str(), errno,
86919f71c6SClaire Weinan                                     strerror(errno), objPath.c_str(), id)
87919f71c6SClaire Weinan                             .c_str());
88919f71c6SClaire Weinan         elog<Open>(ErrnoOpen(errno), PathOpen(objPath.c_str()));
89919f71c6SClaire Weinan     }
90919f71c6SClaire Weinan 
91919f71c6SClaire Weinan     try
92919f71c6SClaire Weinan     {
93919f71c6SClaire Weinan         log<level::INFO>("dump_manager_faultlog.cpp: add faultlog entry");
94919f71c6SClaire Weinan 
95919f71c6SClaire Weinan         uint64_t timestamp =
96919f71c6SClaire Weinan             std::chrono::duration_cast<std::chrono::microseconds>(
97919f71c6SClaire Weinan                 std::chrono::system_clock::now().time_since_epoch())
98919f71c6SClaire Weinan                 .count();
99919f71c6SClaire Weinan 
100*74a1f39cSAsmitha Karunanithi         entries.insert(
101*74a1f39cSAsmitha Karunanithi             std::make_pair(id, std::make_unique<faultlog::Entry>(
102919f71c6SClaire Weinan                                    bus, objPath.c_str(), id, timestamp,
103*74a1f39cSAsmitha Karunanithi                                    std::filesystem::file_size(faultLogFilePath),
104*74a1f39cSAsmitha Karunanithi                                    faultLogFilePath,
105*74a1f39cSAsmitha Karunanithi                                    phosphor::dump::OperationStatus::Completed,
106*74a1f39cSAsmitha Karunanithi                                    originatorId, originatorType, *this)));
107919f71c6SClaire Weinan     }
108919f71c6SClaire Weinan     catch (const std::invalid_argument& e)
109919f71c6SClaire Weinan     {
110919f71c6SClaire Weinan         log<level::ERR>(fmt::format("Error in creating dump entry, "
111919f71c6SClaire Weinan                                     "errormsg({}), OBJECTPATH({}), ID({})",
112919f71c6SClaire Weinan                                     e.what(), objPath.c_str(), id)
113919f71c6SClaire Weinan                             .c_str());
114919f71c6SClaire Weinan         elog<InternalFailure>();
115919f71c6SClaire Weinan     }
116919f71c6SClaire Weinan 
117919f71c6SClaire Weinan     lastEntryId++;
118919f71c6SClaire Weinan 
119919f71c6SClaire Weinan     log<level::INFO>("End of dump_manager_faultlog.cpp createDump");
120919f71c6SClaire Weinan     return objPath.string();
121919f71c6SClaire Weinan }
122919f71c6SClaire Weinan 
123919f71c6SClaire Weinan } // namespace faultlog
124919f71c6SClaire Weinan } // namespace dump
125919f71c6SClaire Weinan } // namespace phosphor
126