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 20 void Entry::delete_() 21 { 22 parent.erase(id()); 23 } 24 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 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 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 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 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