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