1 #pragma once
2 
3 #include <list>
4 #include <sdbusplus/bus.hpp>
5 #include <phosphor-logging/log.hpp>
6 #include "elog_entry.hpp"
7 #include "xyz/openbmc_project/Logging/Internal/Manager/server.hpp"
8 #include "xyz/openbmc_project/Collection/DeleteAll/server.hpp"
9 
10 namespace phosphor
11 {
12 namespace logging
13 {
14 
15 extern const std::map<std::string,std::vector<std::string>> g_errMetaMap;
16 extern const std::map<std::string,level> g_errLevelMap;
17 
18 using DeleteAllIface = sdbusplus::server::object::object <
19                        sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll >;
20 
21 namespace details
22 {
23 
24 template <typename T>
25 using ServerObject = typename sdbusplus::server::object::object<T>;
26 
27 using ManagerIface =
28     sdbusplus::xyz::openbmc_project::Logging::Internal::server::Manager;
29 
30 } // namespace details
31 
32 namespace internal
33 {
34 
35 /** @class Manager
36  *  @brief OpenBMC logging manager implementation.
37  *  @details A concrete implementation for the
38  *  xyz.openbmc_project.Logging.Internal.Manager DBus API.
39  */
40 class Manager : public details::ServerObject<details::ManagerIface>
41 {
42     public:
43         Manager() = delete;
44         Manager(const Manager&) = delete;
45         Manager& operator=(const Manager&) = delete;
46         Manager(Manager&&) = delete;
47         Manager& operator=(Manager&&) = delete;
48         virtual ~Manager() = default;
49 
50         /** @brief Constructor to put object onto bus at a dbus path.
51          *  @param[in] bus - Bus to attach to.
52          *  @param[in] path - Path to attach at.
53          */
54         Manager(sdbusplus::bus::bus& bus, const char* objPath) :
55                 details::ServerObject<details::ManagerIface>(bus, objPath),
56                 busLog(bus),
57                 entryId(0),
58                 fwVersion(readFWVersion()) {};
59 
60         /*
61          * @fn commit()
62          * @brief sd_bus Commit method implementation callback.
63          * @details Create an error/event log based on transaction id and
64          *          error message.
65          * @param[in] transactionId - Unique identifier of the journal entries
66          *                            to be committed.
67          * @param[in] errMsg - The error exception message associated with the
68          *                     error log to be committed.
69          */
70         void commit(uint64_t transactionId, std::string errMsg) override;
71 
72         /*
73          * @fn commit()
74          * @brief sd_bus CommitWithLvl method implementation callback.
75          * @details Create an error/event log based on transaction id and
76          *          error message.
77          * @param[in] transactionId - Unique identifier of the journal entries
78          *                            to be committed.
79          * @param[in] errMsg - The error exception message associated with the
80          *                     error log to be committed.
81          * @param[in] errLvl - level of the error
82          */
83         void commitWithLvl(uint64_t transactionId, std::string errMsg,
84                            uint32_t errLvl) override;
85 
86         /** @brief Erase specified entry d-bus object
87          *
88          * @param[in] entryId - unique identifier of the entry
89          */
90         void erase(uint32_t entryId);
91 
92         /** @brief Construct error d-bus objects from their persisted
93          *         representations.
94          */
95         void restore();
96 
97         /** @brief  Erase all error log entries
98          *
99          */
100         void eraseAll()
101         {
102             auto iter = entries.begin();
103             while (iter != entries.end())
104             {
105                 auto entry = iter->first;
106                 ++iter;
107                 erase(entry);
108             }
109         }
110 
111     private:
112         /*
113          * @fn _commit()
114          * @brief commit() helper
115          * @param[in] transactionId - Unique identifier of the journal entries
116          *                            to be committed.
117          * @param[in] errMsg - The error exception message associated with the
118          *                     error log to be committed.
119          * @param[in] errLvl - level of the error
120          */
121         void _commit(uint64_t transactionId, std::string&& errMsg,
122                      Entry::Level errLvl);
123 
124         /** @brief Call metadata handler(s), if any. Handlers may create
125          *         associations.
126          *  @param[in] errorName - name of the error
127          *  @param[in] additionalData - list of metadata (in key=value format)
128          *  @param[out] objects - list of error's association objects
129          */
130         void processMetadata(const std::string& errorName,
131                              const std::vector<std::string>& additionalData,
132                              AssociationList& objects) const;
133 
134         /** @brief Synchronize unwritten journal messages to disk.
135          *  @details This is the same implementation as the systemd command
136          *  "journalctl --sync".
137          */
138         void journalSync();
139 
140         /** @brief Reads the BMC code level
141          *
142          *  @return std::string - the version string
143          */
144         static std::string readFWVersion();
145 
146         /** @brief Persistent sdbusplus DBus bus connection. */
147         sdbusplus::bus::bus& busLog;
148 
149         /** @brief Persistent map of Entry dbus objects and their ID */
150         std::map<uint32_t, std::unique_ptr<Entry>> entries;
151 
152         /** @brief List of error ids for high severity errors */
153         std::list<uint32_t> realErrors;
154 
155         /** @brief List of error ids for Info(and below) severity */
156         std::list<uint32_t> infoErrors;
157 
158         /** @brief Id of last error log entry */
159         uint32_t entryId;
160 
161         /** @brief The BMC firmware version */
162         const std::string fwVersion;
163 };
164 
165 } //namespace internal
166 
167 /** @class Manager
168  *  @brief Implementation for delete all error log entries.
169  *  @details A concrete implementation for the
170  *  xyz.openbmc_project.Collection.DeleteAll
171  */
172 class Manager : public DeleteAllIface
173 {
174     public:
175         Manager() = delete;
176         Manager(const Manager&) = delete;
177         Manager& operator=(const Manager&) = delete;
178         Manager(Manager&&) = delete;
179         Manager& operator=(Manager&&) = delete;
180         virtual ~Manager() = default;
181 
182         /** @brief Constructor to put object onto bus at a dbus path.
183          *         Defer signal registration (pass true for deferSignal to the
184          *         base class) until after the properties are set.
185          *  @param[in] bus - Bus to attach to.
186          *  @param[in] path - Path to attach at.
187          *  @param[in] manager - Reference to internal manager object.
188          */
189         Manager(sdbusplus::bus::bus& bus,
190                    const std::string& path,
191                    internal::Manager& manager) :
192             DeleteAllIface(bus, path.c_str(), true),
193             manager(manager) {};
194 
195         /** @brief Delete all d-bus objects.
196          */
197         void deleteAll()
198         {
199             manager.eraseAll();
200         }
201     private:
202         /** @brief This is a reference to manager object */
203         internal::Manager& manager;
204 };
205 
206 } // namespace logging
207 } // namespace phosphor
208