1 #pragma once
2 
3 #include "config.h"
4 
5 #include "dump_entry.hpp"
6 #include "dump_utils.hpp"
7 #include "watch.hpp"
8 #include "xyz/openbmc_project/Collection/DeleteAll/server.hpp"
9 #include "xyz/openbmc_project/Dump/Internal/Create/server.hpp"
10 
11 #include <experimental/filesystem>
12 #include <sdbusplus/bus.hpp>
13 #include <sdbusplus/server/object.hpp>
14 #include <xyz/openbmc_project/Dump/Create/server.hpp>
15 
16 namespace phosphor
17 {
18 namespace dump
19 {
20 namespace internal
21 {
22 
23 class Manager;
24 
25 } // namespace internal
26 
27 using UserMap = phosphor::dump::inotify::UserMap;
28 
29 using Type =
30     sdbusplus::xyz::openbmc_project::Dump::Internal::server::Create::Type;
31 
32 using CreateIface = sdbusplus::server::object::object<
33     sdbusplus::xyz::openbmc_project::Collection::server::DeleteAll,
34     sdbusplus::xyz::openbmc_project::Dump::server::Create>;
35 
36 namespace fs = std::experimental::filesystem;
37 
38 using Watch = phosphor::dump::inotify::Watch;
39 
40 // Type to dreport type  string map
41 static const std::map<Type, std::string> TypeMap = {
42     {Type::ApplicationCored, "core"},
43     {Type::UserRequested, "user"},
44     {Type::InternalFailure, "elog"},
45     {Type::Checkstop, "checkstop"}};
46 
47 /** @class Manager
48  *  @brief OpenBMC Dump  manager implementation.
49  *  @details A concrete implementation for the
50  *  xyz.openbmc_project.Dump.Create DBus API and
51  *  xyz::openbmc_project::Collection::server::DeleteAll.
52  */
53 class Manager : public CreateIface
54 {
55     friend class internal::Manager;
56     friend class Entry;
57 
58   public:
59     Manager() = delete;
60     Manager(const Manager&) = default;
61     Manager& operator=(const Manager&) = delete;
62     Manager(Manager&&) = delete;
63     Manager& operator=(Manager&&) = delete;
64     virtual ~Manager() = default;
65 
66     /** @brief Constructor to put object onto bus at a dbus path.
67      *  @param[in] bus - Bus to attach to.
68      *  @param[in] event - Dump manager sd_event loop.
69      *  @param[in] path - Path to attach at.
70      */
71     Manager(sdbusplus::bus::bus& bus, const EventPtr& event, const char* path) :
72         CreateIface(bus, path), bus(bus), eventLoop(event.get()),
73         lastEntryId(0),
74         dumpWatch(
75             eventLoop, IN_NONBLOCK, IN_CLOSE_WRITE | IN_CREATE, EPOLLIN,
76             BMC_DUMP_PATH,
77             std::bind(std::mem_fn(&phosphor::dump::Manager::watchCallback),
78                       this, std::placeholders::_1))
79     {
80     }
81 
82     /** @brief Implementation for CreateDump
83      *  Method to create Dump.
84      *
85      *  @return id - The Dump entry id number.
86      */
87     uint32_t createDump() override;
88 
89     /** @brief Implementation of dump watch call back
90      *  @param [in] fileInfo - map of file info  path:event
91      */
92     void watchCallback(const UserMap& fileInfo);
93 
94     /** @brief Construct dump d-bus objects from their persisted
95      *        representations.
96      */
97     void restore();
98 
99   private:
100     /** @brief Create Dump entry d-bus object
101      *  @param[in] fullPath - Full path of the Dump file name
102      */
103     void createEntry(const fs::path& fullPath);
104 
105     /**  @brief Capture BMC Dump based on the Dump type.
106      *  @param[in] type - Type of the Dump.
107      *  @param[in] fullPaths - List of absolute paths to the files
108      *             to be included as part of Dump package.
109      *  @return id - The Dump entry id number.
110      */
111     uint32_t captureDump(Type type, const std::vector<std::string>& fullPaths);
112 
113     /** @brief Erase specified entry d-bus object
114      *
115      * @param[in] entryId - unique identifier of the entry
116      */
117     void erase(uint32_t entryId);
118 
119     /** @brief  Erase all BMC dump entries and  Delete all Dump files
120      * from Permanent location
121      *
122      */
123     void deleteAll() override;
124 
125     /** @brief sd_event_add_child callback
126      *
127      *  @param[in] s - event source
128      *  @param[in] si - signal info
129      *  @param[in] userdata - pointer to Watch object
130      *
131      *  @returns 0 on success, -1 on fail
132      */
133     static int callback(sd_event_source* s, const siginfo_t* si, void* userdata)
134     {
135         // No specific action required in
136         // the sd_event_add_child callback.
137         return 0;
138     }
139     /** @brief Remove specified watch object pointer from the
140      *        watch map and associated entry from the map.
141      *        @param[in] path - unique identifier of the map
142      */
143     void removeWatch(const fs::path& path);
144 
145     /** @brief Calculate per dump allowed size based on the available
146      *        size in the dump location.
147      *  @returns dump size in kilobytes.
148      */
149     size_t getAllowedSize();
150 
151     /** @brief sdbusplus DBus bus connection. */
152     sdbusplus::bus::bus& bus;
153 
154     /** @brief sdbusplus Dump event loop */
155     EventPtr eventLoop;
156 
157     /** @brief Dump Entry dbus objects map based on entry id */
158     std::map<uint32_t, std::unique_ptr<Entry>> entries;
159 
160     /** @brief Id of the last Dump entry */
161     uint32_t lastEntryId;
162 
163     /** @brief Dump main watch object */
164     Watch dumpWatch;
165 
166     /** @brief Child directory path and its associated watch object map
167      *        [path:watch object]
168      */
169     std::map<fs::path, std::unique_ptr<Watch>> childWatchMap;
170 };
171 
172 } // namespace dump
173 } // namespace phosphor
174