xref: /openbmc/ibm-logging/manager.hpp (revision 4afb6f844031fbc2c2fe9a2b40bed5dfe7924ca4)
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