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 { 20 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 */ 44 explicit CustomFd(int fd) : fd(fd) 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