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