| Jayanth Othayoth | 224882b | 2017-05-04 05:46:45 -0500 | [diff] [blame] | 1 | #include "dump_entry.hpp" | 
| Jayanth Othayoth | cb65ffc | 2018-10-16 08:29:32 -0500 | [diff] [blame] | 2 |  | 
| Jayanth Othayoth | a320c7c | 2017-06-14 07:17:21 -0500 | [diff] [blame] | 3 | #include "dump_manager.hpp" | 
 | 4 |  | 
| Dhruvaraj Subhashchandran | 64f8da9 | 2021-12-08 03:48:23 -0600 | [diff] [blame] | 5 | #include <fcntl.h> | 
 | 6 |  | 
| Dhruvaraj Subhashchandran | 93f0641 | 2024-06-02 05:16:51 -0500 | [diff] [blame] | 7 | #include <nlohmann/json.hpp> | 
| Dhruvaraj Subhashchandran | 64f8da9 | 2021-12-08 03:48:23 -0600 | [diff] [blame] | 8 | #include <phosphor-logging/elog-errors.hpp> | 
 | 9 | #include <phosphor-logging/elog.hpp> | 
 | 10 | #include <phosphor-logging/lg2.hpp> | 
 | 11 | #include <sdeventplus/event.hpp> | 
 | 12 | #include <sdeventplus/source/event.hpp> | 
 | 13 | #include <xyz/openbmc_project/Common/File/error.hpp> | 
 | 14 | #include <xyz/openbmc_project/Common/error.hpp> | 
 | 15 |  | 
 | 16 | #include <cstring> | 
 | 17 |  | 
| Jayanth Othayoth | 224882b | 2017-05-04 05:46:45 -0500 | [diff] [blame] | 18 | namespace phosphor | 
 | 19 | { | 
 | 20 | namespace dump | 
 | 21 | { | 
 | 22 |  | 
| Dhruvaraj Subhashchandran | 64f8da9 | 2021-12-08 03:48:23 -0600 | [diff] [blame] | 23 | using namespace phosphor::logging; | 
 | 24 |  | 
| Jayanth Othayoth | 224882b | 2017-05-04 05:46:45 -0500 | [diff] [blame] | 25 | void Entry::delete_() | 
 | 26 | { | 
| Jayanth Othayoth | a320c7c | 2017-06-14 07:17:21 -0500 | [diff] [blame] | 27 |     // Remove Dump entry D-bus object | 
 | 28 |     parent.erase(id); | 
| Jayanth Othayoth | 224882b | 2017-05-04 05:46:45 -0500 | [diff] [blame] | 29 | } | 
 | 30 |  | 
| Dhruvaraj Subhashchandran | 64f8da9 | 2021-12-08 03:48:23 -0600 | [diff] [blame] | 31 | sdbusplus::message::unix_fd Entry::getFileHandle() | 
 | 32 | { | 
 | 33 |     using namespace sdbusplus::xyz::openbmc_project::Common::File::Error; | 
 | 34 |     using metadata = xyz::openbmc_project::Common::File::Open; | 
 | 35 |     if (file.empty()) | 
 | 36 |     { | 
 | 37 |         lg2::error("Failed to get file handle: File path is empty."); | 
 | 38 |         elog<sdbusplus::xyz::openbmc_project::Common::Error::Unavailable>(); | 
 | 39 |     } | 
 | 40 |  | 
 | 41 |     if (fdCloseEventSource) | 
 | 42 |     { | 
 | 43 |         // Return the existing file descriptor | 
 | 44 |         return fdCloseEventSource->first; | 
 | 45 |     } | 
 | 46 |  | 
 | 47 |     int fd = open(file.c_str(), O_RDONLY | O_NONBLOCK); | 
 | 48 |     if (fd == -1) | 
 | 49 |     { | 
 | 50 |         auto err = errno; | 
 | 51 |         lg2::error("Failed to open dump file: id: {ID} error: {ERRNO}", "ID", | 
 | 52 |                    id, "ERRNO", std::strerror(errno)); | 
 | 53 |         elog<Open>(metadata::ERRNO(err), metadata::PATH(file.c_str())); | 
 | 54 |     } | 
 | 55 |  | 
 | 56 |     // Create a new Defer event source for closing this fd | 
 | 57 |     sdeventplus::Event event = sdeventplus::Event::get_default(); | 
 | 58 |     auto eventSource = std::make_unique<sdeventplus::source::Defer>( | 
 | 59 |         event, [this](auto& /*source*/) { closeFD(); }); | 
 | 60 |  | 
 | 61 |     // Store the file descriptor and event source in the optional pair | 
 | 62 |     fdCloseEventSource = std::make_pair(fd, std::move(eventSource)); | 
 | 63 |  | 
 | 64 |     return fd; | 
 | 65 | } | 
 | 66 |  | 
| Dhruvaraj Subhashchandran | 93f0641 | 2024-06-02 05:16:51 -0500 | [diff] [blame] | 67 | void Entry::serialize() | 
 | 68 | { | 
 | 69 |     // Folder for serialized entry | 
 | 70 |     std::filesystem::path dir = file.parent_path() / PRESERVE; | 
 | 71 |  | 
 | 72 |     // Serialized entry file | 
 | 73 |     std::filesystem::path serializePath = dir / SERIAL_FILE; | 
 | 74 |     try | 
 | 75 |     { | 
 | 76 |         if (!std::filesystem::exists(dir)) | 
 | 77 |         { | 
 | 78 |             std::filesystem::create_directories(dir); | 
 | 79 |         } | 
 | 80 |  | 
 | 81 |         std::ofstream os(serializePath, std::ios::binary); | 
 | 82 |         if (!os.is_open()) | 
 | 83 |         { | 
 | 84 |             lg2::error("Failed to open file for serialization: {PATH} ", "PATH", | 
 | 85 |                        serializePath); | 
 | 86 |             return; | 
 | 87 |         } | 
 | 88 |         nlohmann::json j; | 
 | 89 |         j["version"] = CLASS_SERIALIZATION_VERSION; | 
 | 90 |         j["dumpId"] = id; | 
 | 91 |         j["originatorId"] = originatorId(); | 
 | 92 |         j["originatorType"] = originatorType(); | 
 | 93 |         j["startTime"] = startTime(); | 
 | 94 |  | 
 | 95 |         os << j.dump(); | 
 | 96 |     } | 
 | 97 |     catch (const std::exception& e) | 
 | 98 |     { | 
 | 99 |         lg2::error("Serialization error: {PATH} {ERROR} ", "PATH", | 
 | 100 |                    serializePath, "ERROR", e); | 
 | 101 |  | 
 | 102 |         // Remove the serialization folder if that got created | 
 | 103 |         // Ignore the error since folder may not be created | 
 | 104 |         std::error_code ec; | 
 | 105 |         std::filesystem::remove_all(dir, ec); | 
 | 106 |     } | 
 | 107 | } | 
 | 108 |  | 
 | 109 | void Entry::deserialize(const std::filesystem::path& dumpPath) | 
 | 110 | { | 
 | 111 |     try | 
 | 112 |     { | 
 | 113 |         // .preserve folder | 
 | 114 |         std::filesystem::path dir = dumpPath / PRESERVE; | 
 | 115 |         if (!std::filesystem::exists(dir)) | 
 | 116 |         { | 
 | 117 |             lg2::info("Serialization directory: {SERIAL_DIR} doesnt exist, " | 
 | 118 |                       "skip deserialization", | 
 | 119 |                       "SERIAL_DIR", dir); | 
 | 120 |             return; | 
 | 121 |         } | 
 | 122 |  | 
 | 123 |         // Serialized entry | 
 | 124 |         std::filesystem::path serializePath = dir / SERIAL_FILE; | 
 | 125 |         std::ifstream is(serializePath, std::ios::binary); | 
 | 126 |         if (!is.is_open()) | 
 | 127 |         { | 
 | 128 |             lg2::error("Failed to open file for deserialization: {PATH}", | 
 | 129 |                        "PATH", serializePath); | 
 | 130 |             return; | 
 | 131 |         } | 
 | 132 |         nlohmann::json j; | 
 | 133 |         is >> j; | 
 | 134 |  | 
 | 135 |         uint32_t version; | 
 | 136 |         j.at("version").get_to(version); | 
 | 137 |         if (version == CLASS_SERIALIZATION_VERSION) | 
 | 138 |         { | 
 | 139 |             uint32_t storedId; | 
 | 140 |             j.at("dumpId").get_to(storedId); | 
 | 141 |             if (storedId == id) | 
 | 142 |             { | 
 | 143 |                 originatorId(j["originatorId"].get<std::string>()); | 
 | 144 |                 originatorType(j["originatorType"].get<originatorTypes>()); | 
 | 145 |                 startTime(j["startTime"].get<uint64_t>()); | 
 | 146 |             } | 
 | 147 |             else | 
 | 148 |             { | 
 | 149 |                 lg2::error("The id ({ID_IN_FILE}) is not matching the dump id " | 
 | 150 |                            "({DUMPID}); skipping deserialization.", | 
 | 151 |                            "ID_IN_FILE", storedId, "DUMPID", id); | 
 | 152 |  | 
 | 153 |                 // Id is not matching, this could be due to file corruption | 
 | 154 |                 // deleting the .preserve folder. | 
 | 155 |                 // Attempt to delete the folder and ignore any error. | 
 | 156 |                 std::error_code ec; | 
 | 157 |                 std::filesystem::remove_all(dir, ec); | 
 | 158 |             } | 
 | 159 |         } | 
 | 160 |         else | 
 | 161 |         { | 
 | 162 |             lg2::error("The serialized file version and current class version" | 
 | 163 |                        "doesnt match, skip deserialization {VERSION}", | 
 | 164 |                        "VERSION", version); | 
 | 165 |         } | 
 | 166 |     } | 
 | 167 |     catch (const std::exception& e) | 
 | 168 |     { | 
 | 169 |         lg2::error("Deserialization error: {PATH}, {ERROR}", "PATH", dumpPath, | 
 | 170 |                    "ERROR", e); | 
 | 171 |     } | 
 | 172 | } | 
 | 173 |  | 
| Jayanth Othayoth | 224882b | 2017-05-04 05:46:45 -0500 | [diff] [blame] | 174 | } // namespace dump | 
| Jayanth Othayoth | cb65ffc | 2018-10-16 08:29:32 -0500 | [diff] [blame] | 175 | } // namespace phosphor |