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