1 #pragma once 2 3 #include <systemd/sd-event.h> 4 #include <unistd.h> 5 6 #include <functional> 7 #include <memory> 8 9 namespace openpower 10 { 11 namespace software 12 { 13 namespace updater 14 { 15 16 /* Need a custom deleter for freeing up sd_event_source */ 17 struct EventSourceDeleter 18 { 19 void operator()(sd_event_source* eventSource) const 20 { 21 eventSource = sd_event_source_unref(eventSource); 22 } 23 }; 24 using EventSourcePtr = std::unique_ptr<sd_event_source, EventSourceDeleter>; 25 26 /** @struct CustomFd 27 * 28 * RAII wrapper for file descriptor. 29 */ 30 struct CustomFd 31 { 32 public: 33 CustomFd() = delete; 34 CustomFd(const CustomFd&) = delete; 35 CustomFd& operator=(const CustomFd&) = delete; 36 CustomFd(CustomFd&&) = delete; 37 CustomFd& operator=(CustomFd&&) = delete; 38 39 /** @brief Saves File descriptor and uses it to do file operation 40 * 41 * @param[in] fd - File descriptor 42 */ 43 CustomFd(int fd) : fd(fd) 44 { 45 } 46 47 ~CustomFd() 48 { 49 if (fd >= 0) 50 { 51 close(fd); 52 } 53 } 54 55 int operator()() const 56 { 57 return fd; 58 } 59 60 private: 61 /** @brief File descriptor */ 62 int fd = -1; 63 }; 64 65 /** @class Watch 66 * 67 * @brief Adds inotify watch on PNOR symlinks file to monitor for changes in 68 * "running" PNOR version 69 * 70 * The inotify watch is hooked up with sd-event, so that on call back, 71 * appropriate actions related to a change in the "running" PNOR version 72 * can be taken. 73 */ 74 class Watch 75 { 76 public: 77 /** @brief ctor - hook inotify watch with sd-event 78 * 79 * @param[in] loop - sd-event object 80 * @param[in] functionalCallback - The callback function for updating 81 * the functional associations. 82 */ 83 Watch(sd_event* loop, 84 std::function<void(const std::string&)> functionalCallback); 85 86 Watch(const Watch&) = delete; 87 Watch& operator=(const Watch&) = delete; 88 Watch(Watch&&) = delete; 89 Watch& operator=(Watch&&) = delete; 90 91 /** @brief dtor - remove inotify watch 92 */ 93 ~Watch(); 94 95 private: 96 /** @brief sd-event callback 97 * 98 * @param[in] s - event source, floating (unused) in our case 99 * @param[in] fd - inotify fd 100 * @param[in] revents - events that matched for fd 101 * @param[in] userdata - pointer to Watch object 102 * @returns 0 on success, -1 on fail 103 */ 104 static int callback(sd_event_source* s, int fd, uint32_t revents, 105 void* userdata); 106 107 /** initialize an inotify instance and returns file descriptor */ 108 int inotifyInit(); 109 110 /** @brief PNOR symlink file watch descriptor */ 111 int wd = -1; 112 113 /** @brief event source */ 114 EventSourcePtr eventSource; 115 116 /** @brief The callback function for updating the 117 functional associations. */ 118 std::function<void(std::string&)> functionalCallback; 119 120 /** @brief inotify file descriptor */ 121 CustomFd fd; 122 }; 123 124 } // namespace updater 125 } // namespace software 126 } // namespace openpower 127