1 #include "elog_entry.hpp"
2
3 #include "elog_serialize.hpp"
4 #include "extensions.hpp"
5 #include "log_manager.hpp"
6 #include "paths.hpp"
7
8 #include <fcntl.h>
9 #include <unistd.h>
10
11 #include <phosphor-logging/lg2.hpp>
12 #include <xyz/openbmc_project/Common/File/error.hpp>
13
14 namespace phosphor
15 {
16 namespace logging
17 {
18
19 // TODO Add interfaces to handle the error log id numbering
20
delete_()21 void Entry::delete_()
22 {
23 parent.erase(id());
24 }
25
resolved(bool value)26 bool Entry::resolved(bool value)
27 {
28 auto current =
29 sdbusplus::server::xyz::openbmc_project::logging::Entry::resolved();
30 if (value != current)
31 {
32 // Resolve operation will be prohibited if delete operation is
33 // prohibited.
34 for (auto& func : Extensions::getDeleteProhibitedFunctions())
35 {
36 try
37 {
38 bool prohibited = false;
39 func(id(), prohibited);
40
41 if (prohibited)
42 {
43 throw sdbusplus::xyz::openbmc_project::Common::Error::
44 Unavailable();
45 }
46 }
47 catch (const sdbusplus::xyz::openbmc_project::Common::Error::
48 Unavailable& e)
49 {
50 throw;
51 }
52 catch (const std::exception& e)
53 {
54 lg2::error("An extension's deleteProhibited function threw an "
55 "exception: {ERROR}",
56 "ERROR", e);
57 }
58 }
59 value ? associations({}) : associations(assocs);
60 current =
61 sdbusplus::server::xyz::openbmc_project::logging::Entry::resolved(
62 value);
63
64 uint64_t ms = std::chrono::duration_cast<std::chrono::milliseconds>(
65 std::chrono::system_clock::now().time_since_epoch())
66 .count();
67 updateTimestamp(ms);
68
69 serialize(*this);
70 }
71
72 return current;
73 }
74
eventId(std::string value)75 std::string Entry::eventId(std::string value)
76 {
77 auto current =
78 sdbusplus::server::xyz::openbmc_project::logging::Entry::eventId();
79 if (value != current)
80 {
81 current =
82 sdbusplus::server::xyz::openbmc_project::logging::Entry::eventId(
83 value);
84 serialize(*this);
85 }
86
87 return current;
88 }
89
resolution(std::string value)90 std::string Entry::resolution(std::string value)
91 {
92 auto current =
93 sdbusplus::server::xyz::openbmc_project::logging::Entry::resolution();
94 if (value != current)
95 {
96 current =
97 sdbusplus::server::xyz::openbmc_project::logging::Entry::resolution(
98 value);
99 serialize(*this);
100 }
101
102 return current;
103 }
104
getEntry()105 sdbusplus::message::unix_fd Entry::getEntry()
106 {
107 int fd = open(path().c_str(), O_RDONLY | O_NONBLOCK);
108 if (fd == -1)
109 {
110 auto e = errno;
111 lg2::error("Failed to open Entry File ERRNO={ERRNO}, PATH={PATH}",
112 "ERRNO", e, "PATH", path());
113 throw sdbusplus::xyz::openbmc_project::Common::File::Error::Open();
114 }
115
116 // Schedule the fd to be closed by sdbusplus when it sends it back over
117 // D-Bus.
118 sdeventplus::Event event = sdeventplus::Event::get_default();
119 fdCloseEventSource = std::make_unique<sdeventplus::source::Defer>(
120 event, std::bind(std::mem_fn(&Entry::closeFD), this, fd,
121 std::placeholders::_1));
122
123 return fd;
124 }
125
closeFD(int fd,sdeventplus::source::EventBase &)126 void Entry::closeFD(int fd, sdeventplus::source::EventBase& /*source*/)
127 {
128 close(fd);
129 fdCloseEventSource.reset();
130 }
131
132 } // namespace logging
133 } // namespace phosphor
134