1 #pragma once 2 3 #include <experimental/any> 4 #include <experimental/filesystem> 5 #include <map> 6 #include <sdbusplus/bus.hpp> 7 #include "config.h" 8 #include "dbus.hpp" 9 #include "interfaces.hpp" 10 #ifdef USE_POLICY_INTERFACE 11 #include "policy_table.hpp" 12 #endif 13 14 namespace ibm 15 { 16 namespace logging 17 { 18 19 /** 20 * @class Manager 21 * 22 * This class hosts IBM specific interfaces for the error logging 23 * entry objects. It watches for interfaces added and removed 24 * signals to know when to create and delete objects. Handling the 25 * xyz.openbmc_project.Logging service going away is done at the 26 * systemd service level where this app will be stopped too. 27 */ 28 class Manager 29 { 30 public: 31 Manager() = delete; 32 ~Manager() = default; 33 Manager(const Manager&) = delete; 34 Manager& operator=(const Manager&) = delete; 35 Manager(Manager&&) = delete; 36 Manager& operator=(Manager&&) = delete; 37 38 /** 39 * Constructor 40 * 41 * @param[in] bus - the D-Bus bus object 42 */ 43 explicit Manager(sdbusplus::bus::bus& bus); 44 45 private: 46 using EntryID = uint32_t; 47 using InterfaceMap = std::map<InterfaceType, std::experimental::any>; 48 using EntryMap = std::map<EntryID, InterfaceMap>; 49 50 using ObjectList = std::vector<std::experimental::any>; 51 using InterfaceMapMulti = std::map<InterfaceType, ObjectList>; 52 using EntryMapMulti = std::map<EntryID, InterfaceMapMulti>; 53 54 /** 55 * Deletes the entry and any child entries with 56 * the specified ID. 57 * 58 * @param[in] id - the entry ID 59 */ 60 void erase(EntryID id); 61 62 /** 63 * The callback for an interfaces added signal 64 * 65 * Creates the IBM interfaces for the log entry 66 * that was just created. 67 * 68 * @param[in] msg - the sdbusplus message 69 */ 70 void interfaceAdded(sdbusplus::message::message& msg); 71 72 /** 73 * The callback for an interfaces removed signal 74 * 75 * Removes the IBM interfaces for the log entry 76 * that was just removed. 77 * 78 * @param[in] msg - the sdbusplus message 79 */ 80 void interfaceRemoved(sdbusplus::message::message& msg); 81 82 /** 83 * Creates the IBM interfaces for all existing error log 84 * entries. 85 */ 86 void createAll(); 87 88 /** 89 * Creates the IBM interface(s) for a single new error log. 90 * 91 * Any interfaces that require serialization will be created 92 * and serialized here. 93 * 94 * @param[in] objectPath - object path of the error log 95 * @param[in] interfaces - map of all interfaces and properties 96 * on a phosphor-logging error log 97 */ 98 void create(const std::string& objectPath, 99 const DbusInterfaceMap& interfaces); 100 101 /** 102 * Creates the IBM interface(s) for a single error log after 103 * the application is restarted. 104 * 105 * Interfaces that were persisted will be restored from their 106 * previously saved filesystem data. 107 * 108 * @param[in] objectPath - object path of the error log 109 * @param[in] interfaces - map of all interfaces and properties 110 * on a phosphor-logging error log 111 */ 112 void createWithRestore(const std::string& objectPath, 113 const DbusInterfaceMap& interfaces); 114 115 /** 116 * Creates the IBM interfaces for a single error log that 117 * do not persist across app restarts. 118 * 119 * @param[in] objectPath - object path of the error log 120 * @param[in] interfaces - map of all interfaces and properties 121 * on a phosphor-logging error log 122 */ 123 void createObject(const std::string& objectPath, 124 const DbusInterfaceMap& interfaces); 125 126 /** 127 * Returns the error log timestamp property value from 128 * the passed in map of all interfaces and property names/values 129 * on an error log D-Bus object. 130 * 131 * @param[in] interfaces - map of all interfaces and properties 132 * on a phosphor-logging error log. 133 * 134 * @return uint64_t - the timestamp 135 */ 136 uint64_t getLogTimestamp(const DbusInterfaceMap& interfaces); 137 138 /** 139 * Returns the filesystem directory to use for persisting 140 * information about a particular error log. 141 * 142 * @param[in] id - the error log ID 143 * @return path - the directory path 144 */ 145 std::experimental::filesystem::path getSaveDir(EntryID id); 146 147 /** 148 * Returns the directory to use to save the callout information in 149 * 150 * @param[in] id - the error log ID 151 * 152 * @return path - the directory path 153 */ 154 std::experimental::filesystem::path getCalloutSaveDir(EntryID id); 155 156 /** 157 * Returns the D-Bus object path to use for a callout D-Bus object. 158 * 159 * @param[in] objectPath - the object path for the error log 160 * @param[in] calloutNum - the callout instance number 161 * 162 * @return path - the object path to use for a callout object 163 */ 164 std::string getCalloutObjectPath(const std::string& objectPath, 165 uint32_t calloutNum); 166 167 /** 168 * Creates the IBM policy interface for a single error log 169 * and saves it in the list of interfaces. 170 * 171 * @param[in] objectPath - object path of the error log 172 * @param[in] properties - the xyz.openbmc_project.Logging.Entry 173 * properties 174 */ 175 #ifdef USE_POLICY_INTERFACE 176 void createPolicyInterface(const std::string& objectPath, 177 const DbusPropertyMap& properties); 178 #endif 179 180 /** 181 * Creates D-Bus objects for any callouts in an error log 182 * that map to an inventory object with an Asset interface. 183 * 184 * The created object will also host the Asset interface. 185 * 186 * A callout object path would look like: 187 * /xyz/openbmc_project/logging/entry/5/callouts/0. 188 * 189 * Any objects created are serialized so the asset information 190 * can always be restored. 191 * 192 * @param[in] objectPath - object path of the error log 193 * @param[in] interfaces - map of all interfaces and properties 194 * on a phosphor-logging error log. 195 */ 196 void createCalloutObjects(const std::string& objectPath, 197 const DbusInterfaceMap& interfaces); 198 199 /** 200 * Restores callout objects for a particular error log that 201 * have previously been saved by reading their data out of 202 * the filesystem using Cereal. 203 * 204 * @param[in] objectPath - object path of the error log 205 * @param[in] interfaces - map of all interfaces and properties 206 * on a phosphor-logging error log. 207 */ 208 void restoreCalloutObjects(const std::string& objectPath, 209 const DbusInterfaceMap& interfaces); 210 211 /** 212 * Returns the entry ID for a log 213 * 214 * @param[in] objectPath - the object path of the log 215 * 216 * @return uint32_t - the ID 217 */ 218 inline uint32_t getEntryID(const std::string& objectPath) 219 { 220 std::experimental::filesystem::path path(objectPath); 221 return std::stoul(path.filename()); 222 } 223 224 /** 225 * Adds an interface object to the entries map 226 * 227 * @param[in] objectPath - the object path of the log 228 * @param[in] type - the interface type being added 229 * @param[in] object - the interface object 230 */ 231 void addInterface(const std::string& objectPath, InterfaceType type, 232 std::experimental::any& object); 233 234 /** 235 * Adds an interface to a child object, which is an object that 236 * relates to the main ...logging/entry/X object but has a different path. 237 * The object is stored in the childEntries map. 238 * 239 * There can be multiple instances of a child object per type per 240 * logging object. 241 * 242 * @param[in] objectPath - the object path of the log 243 * @param[in] type - the interface type being added. 244 * @param[in] object - the interface object 245 */ 246 void addChildInterface(const std::string& objectPath, InterfaceType type, 247 std::experimental::any& object); 248 249 /** 250 * The sdbusplus bus object 251 */ 252 sdbusplus::bus::bus& bus; 253 254 /** 255 * The match object for interfacesAdded 256 */ 257 sdbusplus::bus::match_t addMatch; 258 259 /** 260 * The match object for interfacesRemoved 261 */ 262 sdbusplus::bus::match_t removeMatch; 263 264 /** 265 * A map of the error log IDs to their IBM interface objects. 266 * There may be multiple interfaces per ID. 267 */ 268 EntryMap entries; 269 270 /** 271 * A map of the error log IDs to their interface objects which 272 * are children of the logging objects. 273 * 274 * These objects have the same lifespan as their parent objects. 275 * 276 * There may be multiple interfaces per ID, and also multiple 277 * interface instances per interface type. 278 */ 279 EntryMapMulti childEntries; 280 281 #ifdef USE_POLICY_INTERFACE 282 /** 283 * The class the wraps the IBM error logging policy table. 284 */ 285 policy::Table policies; 286 #endif 287 }; 288 } 289 } 290