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