1 #pragma once 2 3 #include "config.h" 4 5 #include "data_interface.hpp" 6 #include "event_logger.hpp" 7 #include "host_notifier.hpp" 8 #include "log_manager.hpp" 9 #include "paths.hpp" 10 #include "pel.hpp" 11 #include "registry.hpp" 12 #include "repository.hpp" 13 14 #include <org/open_power/Logging/PEL/server.hpp> 15 #include <sdbusplus/server.hpp> 16 #include <sdeventplus/event.hpp> 17 #include <sdeventplus/source/event.hpp> 18 19 namespace openpower 20 { 21 namespace pels 22 { 23 24 using PELInterface = sdbusplus::server::object::object< 25 sdbusplus::org::open_power::Logging::server::PEL>; 26 27 /** 28 * @brief PEL manager object 29 */ 30 class Manager : public PELInterface 31 { 32 public: 33 Manager() = delete; 34 ~Manager() = default; 35 Manager(const Manager&) = default; 36 Manager& operator=(const Manager&) = default; 37 Manager(Manager&&) = default; 38 Manager& operator=(Manager&&) = default; 39 40 /** 41 * @brief constructor 42 * 43 * @param[in] logManager - internal::Manager object 44 * @param[in] dataIface - The data interface object 45 * @param[in] creatorFunc - The function that EventLogger will 46 * use for creating event logs 47 */ 48 Manager(phosphor::logging::internal::Manager& logManager, 49 std::unique_ptr<DataInterfaceBase> dataIface, 50 EventLogger::LogFunction creatorFunc) : 51 PELInterface(logManager.getBus(), OBJ_LOGGING), 52 _logManager(logManager), _eventLogger(std::move(creatorFunc)), 53 _repo(getPELRepoPath()), 54 _registry(getMessageRegistryPath() / message::registryFileName), 55 _dataIface(std::move(dataIface)) 56 { 57 } 58 59 /** 60 * @brief constructor that enables host notification 61 * 62 * @param[in] logManager - internal::Manager object 63 * @param[in] dataIface - The data interface object 64 * @param[in] creatorFunc - The function that EventLogger will 65 * use for creating event logs 66 * @param[in] hostIface - The hostInterface object 67 */ 68 Manager(phosphor::logging::internal::Manager& logManager, 69 std::unique_ptr<DataInterfaceBase> dataIface, 70 EventLogger::LogFunction creatorFunc, 71 std::unique_ptr<HostInterface> hostIface) : 72 Manager(logManager, std::move(dataIface), std::move(creatorFunc)) 73 { 74 _hostNotifier = std::make_unique<HostNotifier>( 75 _repo, *(_dataIface.get()), std::move(hostIface)); 76 } 77 78 /** 79 * @brief Creates a PEL based on the OpenBMC event log contents. If 80 * a PEL was passed in via the RAWPEL specifier in the 81 * additionalData parameter, use that instead. 82 * 83 * @param[in] message - the event log message property 84 * @param[in] obmcLogID - the corresponding OpenBMC event log id 85 * @param[in] timestamp - the Timestamp property 86 * @param[in] severity - the event log severity 87 * @param[in] additionalData - the AdditionalData property 88 * @param[in] associations - the Associations property 89 * @param[in] ffdc - A vector of FFDC file information 90 */ 91 void create(const std::string& message, uint32_t obmcLogID, 92 uint64_t timestamp, phosphor::logging::Entry::Level severity, 93 const std::vector<std::string>& additionalData, 94 const std::vector<std::string>& associations, 95 const phosphor::logging::FFDCEntries& ffdc = 96 phosphor::logging::FFDCEntries{}); 97 98 /** 99 * @brief Erase a PEL based on its OpenBMC event log ID 100 * 101 * @param[in] obmcLogID - the corresponding OpenBMC event log id 102 */ 103 void erase(uint32_t obmcLogID); 104 105 /** @brief Says if an OpenBMC event log may not be manually deleted at this 106 * time because its corresponding PEL cannot be. 107 * 108 * There are PEL retention policies that can prohibit the manual deletion 109 * of PELs (and therefore OpenBMC event logs). 110 * 111 * @param[in] obmcLogID - the OpenBMC event log ID 112 * @return bool - true if prohibited 113 */ 114 bool isDeleteProhibited(uint32_t obmcLogID); 115 116 /** 117 * @brief Return a file descriptor to the raw PEL data 118 * 119 * Throws InvalidArgument if the PEL ID isn't found, 120 * and InternalFailure if anything else fails. 121 * 122 * @param[in] pelID - The PEL ID to get the data for 123 * 124 * @return unix_fd - File descriptor to the file that contains the PEL 125 */ 126 sdbusplus::message::unix_fd getPEL(uint32_t pelID) override; 127 128 /** 129 * @brief Returns data for the PEL corresponding to an OpenBMC 130 * event log. 131 * 132 * @param[in] obmcLogID - The OpenBMC event log ID 133 * 134 * @return vector<uint8_t> - The raw PEL data 135 */ 136 std::vector<uint8_t> getPELFromOBMCID(uint32_t obmcLogID) override; 137 138 /** 139 * @brief The D-Bus method called when a host successfully processes 140 * a PEL. 141 * 142 * This D-Bus method is called from the PLDM daemon when they get an 143 * 'Ack PEL' PLDM message from the host, which indicates the host 144 * firmware successfully sent it to the OS and this code doesn't need 145 * to send it to the host again. 146 * 147 * @param[in] pelID - The PEL ID 148 */ 149 void hostAck(uint32_t pelID) override; 150 151 /** 152 * @brief D-Bus method called when the host rejects a PEL. 153 * 154 * This D-Bus method is called from the PLDM daemon when they get an 155 * 'Ack PEL' PLDM message from the host with a payload that says 156 * something when wrong. 157 * 158 * The choices are either: 159 * * Host Full - The host's staging area is full - try again later 160 * * Malrformed PEL - The host received an invalid PEL 161 * 162 * @param[in] pelID - The PEL ID 163 * @param[in] reason - One of the above two reasons 164 */ 165 void hostReject(uint32_t pelID, RejectionReason reason) override; 166 167 /** 168 * @brief Converts the ESEL field in an OpenBMC event log to a 169 * vector of uint8_ts that just contains the PEL data. 170 * 171 * That data string looks like: "50 48 00 ab ..." 172 * 173 * Throws an exception on any failures. 174 * 175 * @param[in] esel - The ESEL string 176 * 177 * @return std::vector<uint8_t> - The contained PEL data 178 */ 179 static std::vector<uint8_t> eselToRawData(const std::string& esel); 180 181 private: 182 /** 183 * @brief Adds a received raw PEL to the PEL repository 184 * 185 * @param[in] rawPelPath - The path to the file that contains the 186 * raw PEL. 187 * @param[in] obmcLogID - the corresponding OpenBMC event log id 188 */ 189 void addRawPEL(const std::string& rawPelPath, uint32_t obmcLogID); 190 191 /** 192 * @brief Creates a PEL based on the OpenBMC event log contents. 193 * 194 * @param[in] message - The event log message property 195 * @param[in] obmcLogID - the corresponding OpenBMC event log id 196 * @param[in] timestamp - The timestamp property 197 * @param[in] severity - The event log severity 198 * @param[in] additionalData - The AdditionalData property 199 * @param[in] associations - The associations property 200 * @param[in] ffdc - A vector of FFDC file information 201 */ 202 void createPEL(const std::string& message, uint32_t obmcLogID, 203 uint64_t timestamp, phosphor::logging::Entry::Level severity, 204 const std::vector<std::string>& additionalData, 205 const std::vector<std::string>& associations, 206 const phosphor::logging::FFDCEntries& ffdc); 207 208 /** 209 * @brief Schedules a close of the file descriptor to occur from 210 * the event loop. 211 * 212 * Uses sd_event_add_defer 213 * 214 * @param[in] fd - The file descriptor to close 215 */ 216 void scheduleFDClose(int fd); 217 218 /** 219 * @brief Closes the file descriptor passed in. 220 * 221 * This is called from the event loop to close FDs returned 222 * from getPEL(). 223 * 224 * @param[in] fd - The file descriptor to close 225 * @param[in] source - The event source object used 226 */ 227 void closeFD(int fd, sdeventplus::source::EventBase& source); 228 229 /** 230 * @brief Adds a PEL to the repository given its data 231 * 232 * @param[in] pelData - The PEL to add as a vector of uint8_ts 233 * @param[in] obmcLogID - the OpenBMC event log ID 234 */ 235 void addPEL(std::vector<uint8_t>& pelData, uint32_t obmcLogID); 236 237 /** 238 * @brief Adds the PEL stored in the ESEL field of the AdditionalData 239 * property of an OpenBMC event log to the repository. 240 * 241 * @param[in] esel - The ESEL AdditionalData contents 242 * @param[in] obmcLogID - The OpenBMC event log ID 243 */ 244 void addESELPEL(const std::string& esel, uint32_t obmcLogID); 245 246 /** 247 * @brief Converts the D-Bus FFDC method argument into a data 248 * structure understood by the PEL code. 249 * 250 * @param[in] ffdc - A vector of FFDC file information 251 * 252 * @return PelFFDC - The PEL FFDC data structure 253 */ 254 PelFFDC convertToPelFFDC(const phosphor::logging::FFDCEntries& ffdc); 255 256 /** 257 * @brief Reference to phosphor-logging's Manager class 258 */ 259 phosphor::logging::internal::Manager& _logManager; 260 261 /** 262 * @brief Handles creating event logs/PELs from within 263 * the PEL extension code 264 */ 265 EventLogger _eventLogger; 266 267 /** 268 * @brief The PEL repository object 269 */ 270 Repository _repo; 271 272 /** 273 * @brief The PEL message registry object 274 */ 275 message::Registry _registry; 276 277 /** 278 * @brief The API the PEL sections use to gather data 279 */ 280 std::unique_ptr<DataInterfaceBase> _dataIface; 281 282 /** 283 * @brief The HostNotifier object used for telling the 284 * host about new PELs 285 */ 286 std::unique_ptr<HostNotifier> _hostNotifier; 287 288 /** 289 * @brief The event source for closing a PEL file descriptor after 290 * it has been returned from the getPEL D-Bus method. 291 */ 292 std::unique_ptr<sdeventplus::source::Defer> _fdCloserEventSource; 293 }; 294 295 } // namespace pels 296 } // namespace openpower 297