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