Changeset 98067 in vbox for trunk/src/VBox/Main
- Timestamp:
- Jan 12, 2023 11:04:34 PM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/linux/HostDnsServiceLinux.cpp
r96407 r98067 67 67 class FileDescriptor 68 68 { 69 public: 70 FileDescriptor(int d = -1):fd(d){} 69 public: 70 FileDescriptor(int d = -1) 71 : fd(d) 72 {} 71 73 72 74 virtual ~FileDescriptor() { … … 77 79 int fileDescriptor() const {return fd;} 78 80 79 81 protected: 80 82 int fd; 81 83 }; 82 84 83 85 84 class AutoNotify :public FileDescriptor85 { 86 86 class AutoNotify : public FileDescriptor 87 { 88 public: 87 89 AutoNotify() 88 90 { … … 119 121 int HostDnsServiceLinux::monitorThreadProc(void) 120 122 { 123 /* 124 * inotify initialization 125 * 126 * Note! Ignoring failures here is safe, because poll will ignore entires 127 * with negative fd values. 128 */ 121 129 AutoNotify a; 122 130 int wd[2]; 131 wd[0] = inotify_add_watch(a.fileDescriptor(), 132 g_ResolvConfFullPath.c_str(), IN_CLOSE_WRITE | IN_DELETE_SELF); 133 134 /* If /etc/resolv.conf exists we want to listen for movements: because 135 # mv /etc/resolv.conf ... 136 won't arm IN_DELETE_SELF on wd[0] instead it will fire IN_MOVE_FROM on wd[1]. 137 138 Because on some distributions /etc/resolv.conf is a symlink, wd[0] can't detect 139 deletion, it's recognizible on directory level (wd[1]) only. */ 140 wd[1] = inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(), 141 wd[0] == -1 ? IN_MOVED_TO | IN_CREATE : IN_MOVED_FROM | IN_DELETE); 142 143 /* 144 * Create a socket pair for signalling shutdown via (see monitorThreadShutdown). 145 */ 123 146 int rc = socketpair(AF_LOCAL, SOCK_DGRAM, 0, g_DnsMonitorStop); 124 147 AssertMsgReturn(rc == 0, ("socketpair: failed (%d: %s)\n", errno, strerror(errno)), E_FAIL); 125 148 149 /* automatic cleanup tricks */ 126 150 FileDescriptor stopper0(g_DnsMonitorStop[0]); 127 151 FileDescriptor stopper1(g_DnsMonitorStop[1]); 128 152 153 /* 154 * poll initialization: 155 */ 129 156 pollfd polls[2]; 130 157 RT_ZERO(polls); … … 138 165 onMonitorThreadInitDone(); 139 166 140 int wd[2]; 141 wd[0] = wd[1] = -1; 142 /* inotify inialization */ 143 wd[0] = inotify_add_watch(a.fileDescriptor(), 144 g_ResolvConfFullPath.c_str(), IN_CLOSE_WRITE|IN_DELETE_SELF); 145 146 /** 147 * If /etc/resolv.conf exists we want to listen for movements: because 148 * # mv /etc/resolv.conf ... 149 * won't arm IN_DELETE_SELF on wd[0] instead it will fire IN_MOVE_FROM on wd[1]. 150 * 151 * Because on some distributions /etc/resolv.conf is link, wd[0] can't detect deletion, 152 * it's recognizible on directory level (wd[1]) only. 153 */ 154 wd[1] = inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(), 155 wd[0] == -1 ? IN_MOVED_TO|IN_CREATE : IN_MOVED_FROM|IN_DELETE); 156 157 struct InotifyEventWithName combo; 158 while(true) 167 /* 168 * The monitoring loop. 169 */ 170 for (;;) 159 171 { 160 rc = poll(polls, 2, -1);172 rc = poll(polls, RT_ELEMENTS(polls), -1 /*infinite timeout*/); 161 173 if (rc == -1) 162 174 continue; 163 175 164 AssertMsgReturn( ((polls[0].revents & (POLLERR|POLLNVAL)) == 0) 165 && ((polls[1].revents & (POLLERR|POLLNVAL)) == 0), 166 ("Debug Me"), VERR_INTERNAL_ERROR); 176 AssertMsgReturn( (polls[0].revents & (POLLERR | POLLNVAL)) == 0 177 && (polls[1].revents & (POLLERR | POLLNVAL)) == 0, ("Debug Me"), VERR_INTERNAL_ERROR); 167 178 168 179 if (polls[1].revents & POLLIN) … … 171 182 if (polls[0].revents & POLLIN) 172 183 { 184 /* 185 * Read the notification event. 186 */ 187 /** @todo r=bird: This is buggy in that it somehow assumes we'll only get 188 * one event here. But since we're waiting on two different DELETE 189 * events for both a specific file and its parent directory, we're likely 190 * to get two DELETE events at the same time. */ 191 struct InotifyEventWithName combo; 173 192 RT_ZERO(combo); 174 ssize_t r = read(polls[0].fd, static_cast<void *>(&combo), sizeof(combo)); 193 combo.e.wd = -42; /* avoid confusion on the offchance that wd[0] or wd[1] is zero. */ 194 195 ssize_t r = read(polls[0].fd, &combo, sizeof(combo)); 175 196 RT_NOREF(r); 176 197 … … 178 199 { 179 200 if (combo.e.mask & IN_CLOSE_WRITE) 180 {181 201 readResolvConf(); 182 }183 202 else if (combo.e.mask & IN_DELETE_SELF) 184 203 { 185 204 inotify_rm_watch(a.fileDescriptor(), wd[0]); /* removes file watcher */ 186 inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(), 187 IN_MOVED_TO|IN_CREATE); /* alter folder watcher */ 205 int wd2 = inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(), 206 IN_MOVED_TO|IN_CREATE); /* alter folder watcher */ 207 Assert(wd2 == wd[1]); RT_NOREF(wd2); /* ASSUMES wd[1] will be updated */ 188 208 } 189 209 else if (combo.e.mask & IN_IGNORED) 190 {191 210 wd[0] = -1; /* we want receive any events on this watch */ 192 }193 211 else 194 212 { 195 /* *213 /* 196 214 * It shouldn't happen, in release we will just ignore in debug 197 215 * we will have to chance to look at into inotify_event … … 202 220 else if (combo.e.wd == wd[1]) 203 221 { 204 if ( combo.e.mask & IN_MOVED_FROM 205 || combo.e.mask & IN_DELETE) 222 if (combo.e.mask & (IN_DELETE | IN_MOVED_FROM)) 206 223 { 207 224 if (g_ResolvConf == combo.e.name) 208 225 { 209 /* *210 * Our file has been moved so we should change watching mode.226 /* 227 * Our file has been moved or deleted so we should change watching mode. 211 228 */ 212 229 inotify_rm_watch(a.fileDescriptor(), wd[0]); 213 230 wd[1] = inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(), 214 IN_MOVED_TO |IN_CREATE);231 IN_MOVED_TO | IN_CREATE); 215 232 AssertMsg(wd[1] != -1, 216 233 ("It shouldn't happen, further investigation is needed\n")); … … 219 236 else 220 237 { 221 AssertMsg(combo.e.mask & (IN_MOVED_TO|IN_CREATE), 222 ("%RX32 event isn't expected, we are waiting for IN_MOVED|IN_CREATE\n", 223 combo.e.mask)); 238 AssertMsg(combo.e.mask & (IN_MOVED_TO | IN_CREATE), 239 ("%RX32 event isn't expected, we are waiting for IN_MOVED|IN_CREATE\n", combo.e.mask)); 224 240 if (g_ResolvConf == combo.e.name) 225 241 { 226 242 AssertMsg(wd[0] == -1, ("We haven't removed file watcher first\n")); 227 243 228 /* alter folder watcher*/ 229 wd[1] = inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(), 230 IN_MOVED_FROM|IN_DELETE); 244 /* alter folder watcher: */ 245 wd[1] = inotify_add_watch(a.fileDescriptor(), 246 g_EtcFolder.c_str(), 247 IN_MOVED_FROM | IN_DELETE); 231 248 AssertMsg(wd[1] != -1, ("It shouldn't happen.\n")); 232 249
Note:
See TracChangeset
for help on using the changeset viewer.