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