blob: 571ced5da2eb21c6c71525c62c91d2f2e0a6111e [file] [log] [blame]
Jayanth Othayotha320c7c2017-06-14 07:17:21 -05001#include <unistd.h>
Jayanth Othayothbcb174b2017-07-02 06:29:24 -05002#include <sys/inotify.h>
Jayanth Othayotha320c7c2017-06-14 07:17:21 -05003
4#include <phosphor-logging/elog-errors.hpp>
5
6#include "dump_manager.hpp"
7#include "dump_internal.hpp"
8#include "xyz/openbmc_project/Common/error.hpp"
9#include "config.h"
10
11namespace phosphor
12{
13namespace dump
14{
15
16using namespace sdbusplus::xyz::openbmc_project::Common::Error;
17using namespace phosphor::logging;
18
19namespace internal
20{
21
22void Manager::create(
23 Type type,
24 std::vector<std::string> fullPaths)
25{
Jayanth Othayothd3273ea2017-07-12 22:55:32 -050026 dumpMgr.phosphor::dump::Manager::captureDump(type, fullPaths);
Jayanth Othayotha320c7c2017-06-14 07:17:21 -050027}
28
29} //namepsace internal
30
31uint32_t Manager::createDump()
32{
33 std::vector<std::string> paths;
34
35 return captureDump(Type::UserRequested, paths);
36}
37
38uint32_t Manager::captureDump(
39 Type type,
40 const std::vector<std::string>& fullPaths)
41{
42 pid_t pid = fork();
43
Jayanth Othayotha320c7c2017-06-14 07:17:21 -050044 if (pid == 0)
45 {
Jayanth Othayothf9009a22017-07-12 19:40:34 -050046 fs::path dumpPath(BMC_DUMP_PATH);
47
48 dumpPath /= std::to_string(lastEntryId + 1);
49 execl("/usr/bin/ffdc", "ffdc", "-d", dumpPath.c_str(), nullptr);
Jayanth Othayotha320c7c2017-06-14 07:17:21 -050050
51 //ffdc script execution is failed.
52 auto error = errno;
53 log<level::ERR>("Error occurred during ffdc function execution",
54 entry("ERRNO=%d", error));
55 elog<InternalFailure>();
56 }
57 else if (pid > 0)
58 {
59 auto rc = sd_event_add_child(eventLoop.get(),
60 nullptr,
61 pid,
62 WEXITED | WSTOPPED,
63 callback,
64 nullptr);
65 if (0 > rc)
66 {
67 // Failed to add to event loop
68 log<level::ERR>("Error occurred during the sd_event_add_child call",
69 entry("rc=%d", rc));
70 elog<InternalFailure>();
71 }
72 }
73 else
74 {
75 auto error = errno;
76 log<level::ERR>("Error occurred during fork",
77 entry("ERRNO=%d", error));
78 elog<InternalFailure>();
79 }
80
81 return ++lastEntryId;
82}
83
84void Manager::createEntry(const fs::path& file)
85{
86 // TODO openbmc/openbmc#1795
87 // Get Dump ID and Epoch time from Dump file name.
88 // Validate the Dump file name.
89 auto id = lastEntryId;
90
91 //Get Epoch time.
92 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
93 std::chrono::system_clock::now().time_since_epoch()).count();
94
95 // Entry Object path.
96 auto objPath = fs::path(OBJ_ENTRY) / std::to_string(id);
97
98 auto size = fs::file_size(file);
99
100 entries.insert(std::make_pair(id,
101 std::make_unique<Entry>(
102 bus,
103 objPath.c_str(),
104 id,
105 ms,
106 size,
107 file,
108 *this)));
109}
110
111void Manager::erase(uint32_t entryId)
112{
113 entries.erase(entryId);
114}
115
Jayanth Othayothbcb174b2017-07-02 06:29:24 -0500116void Manager::watchCallback(const UserMap& fileInfo)
117{
118 for (const auto& i : fileInfo)
119 {
Jayanth Othayoth764d1b22017-07-12 19:14:02 -0500120 // For any new dump file create dump entry object
121 // and associated inotify watch.
Jayanth Othayothbcb174b2017-07-02 06:29:24 -0500122 if (IN_CLOSE_WRITE == i.second)
123 {
Jayanth Othayoth764d1b22017-07-12 19:14:02 -0500124 removeWatch(i.first);
125
Jayanth Othayothbcb174b2017-07-02 06:29:24 -0500126 createEntry(i.first);
127 }
Jayanth Othayoth764d1b22017-07-12 19:14:02 -0500128 // Start inotify watch on newly created directory.
129 else if ((IN_CREATE == i.second) && fs::is_directory(i.first))
130 {
131 auto watchObj = std::make_unique<Watch>(
132 eventLoop,
133 IN_NONBLOCK,
134 IN_CLOSE_WRITE,
135 EPOLLIN,
136 i.first,
137 std::bind(
138 std::mem_fn(
139 &phosphor::dump::Manager::watchCallback),
140 this, std::placeholders::_1));
141
142 childWatchMap.emplace(i.first, std::move(watchObj));
143 }
144
Jayanth Othayothbcb174b2017-07-02 06:29:24 -0500145 }
146}
147
Jayanth Othayoth764d1b22017-07-12 19:14:02 -0500148void Manager::removeWatch(const fs::path& path)
149{
150 //Delete Watch entry from map.
151 childWatchMap.erase(path);
152}
153
Jayanth Othayotha320c7c2017-06-14 07:17:21 -0500154} //namespace dump
155} //namespace phosphor