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