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