- Timestamp:
- Jan 28, 2014 7:29:52 PM (11 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/Makefile.kmk
r50202 r50263 389 389 $(if $(VBOX_WITH_XPCOM),src-server/xpcom/server.cpp,) 390 390 391 ifn1of ($(KBUILD_TARGET), win darwin) 392 VBoxSVC_SOURCES += $(PATH_ROOT)/src/VBox/Devices/Network/slirp/resolv_conf_parser.c 393 endif 394 391 395 VBoxSVC_SOURCES.darwin = \ 392 396 src-server/darwin/iokit.cpp \ -
trunk/src/VBox/Main/src-server/HostDnsService.cpp
r49818 r50263 83 83 struct HostDnsMonitor::Data 84 84 { 85 Data(bool aThreaded):fThreaded(aThreaded){} 86 85 87 std::vector<PCHostDnsMonitorProxy> proxies; 86 88 HostDnsInformation info; 89 const bool fThreaded; 90 RTTHREAD hMonitoringThread; 91 RTSEMEVENT hDnsInitEvent; 87 92 }; 88 93 … … 112 117 113 118 114 HostDnsMonitor::HostDnsMonitor( )119 HostDnsMonitor::HostDnsMonitor(bool fThreaded) 115 120 : m(NULL) 116 121 { 122 m = new HostDnsMonitor::Data(fThreaded); 117 123 } 118 124 … … 201 207 HRESULT HostDnsMonitor::init() 202 208 { 203 m = new HostDnsMonitor::Data(); 209 if (m->fThreaded) 210 { 211 int rc = RTSemEventCreate(&m->hDnsInitEvent); 212 AssertRCReturn(rc, E_FAIL); 213 214 rc = RTThreadCreate(&m->hMonitoringThread, 215 HostDnsMonitor::threadMonitoringRoutine, 216 this, 128 * _1K, RTTHREADTYPE_IO, 0, "dns-monitor"); 217 AssertRCReturn(rc, E_FAIL); 218 219 RTSemEventWait(m->hDnsInitEvent, RT_INDEFINITE_WAIT); 220 } 204 221 return S_OK; 205 222 } 206 223 224 225 void HostDnsMonitor::monitorThreadInitializationDone() 226 { 227 RTSemEventSignal(m->hDnsInitEvent); 228 } 229 230 231 int HostDnsMonitor::threadMonitoringRoutine(RTTHREAD, void *pvUser) 232 { 233 HostDnsMonitor *pThis = static_cast<HostDnsMonitor *>(pvUser); 234 return pThis->monitorWorker(); 235 } 207 236 208 237 /* HostDnsMonitorProxy */ -
trunk/src/VBox/Main/src-server/HostDnsService.h
r49718 r50263 47 47 { 48 48 public: 49 ALock(const Lockee *l);49 explicit ALock(const Lockee *l); 50 50 ~ALock(); 51 51 … … 75 75 void releaseMonitorProxy(PCHostDnsMonitorProxy) const; 76 76 const HostDnsInformation &getInfo() const; 77 /* @note: method will wait till client call 78 HostDnsService::monitorThreadInitializationDone() */ 77 79 virtual HRESULT init(); 78 80 79 81 protected: 82 explicit HostDnsMonitor(bool fThreaded = false); 83 virtual ~HostDnsMonitor(); 84 80 85 void notifyAll() const; 81 86 void setInfo(const HostDnsInformation &); 82 HostDnsMonitor(); 83 virtual ~HostDnsMonitor(); 87 88 /* this function used only if HostDnsMonitor::HostDnsMonitor(true) */ 89 void monitorThreadInitializationDone(); 90 virtual void monitorThreadShutdown() = 0; 91 virtual int monitorWorker() = 0; 84 92 85 93 private: 86 94 HostDnsMonitor(const HostDnsMonitor &); 87 95 HostDnsMonitor& operator= (const HostDnsMonitor &); 96 static int threadMonitoringRoutine(RTTHREAD, void *); 88 97 89 98 public: … … 97 106 class HostDnsMonitorProxy : public Lockee 98 107 { 99 public:108 public: 100 109 HostDnsMonitorProxy(); 101 110 ~HostDnsMonitorProxy(); … … 109 118 bool operator==(PCHostDnsMonitorProxy&); 110 119 111 private:120 private: 112 121 void updateInfo(); 113 122 114 private:123 private: 115 124 struct Data; 116 125 Data *m; … … 125 134 HRESULT init(); 126 135 127 private: 136 protected: 137 virtual void monitorThreadShutdown(); 138 virtual int monitorWorker(); 139 140 private: 128 141 HRESULT updateInfo(); 129 142 static void hostDnsServiceStoreCallback(void *store, void *arrayRef, void *info); 143 struct Data; 144 Data *m; 130 145 }; 131 146 # endif … … 133 148 class HostDnsServiceWin : public HostDnsMonitor 134 149 { 135 public:150 public: 136 151 HostDnsServiceWin(); 137 152 ~HostDnsServiceWin(); 138 153 HRESULT init(); 139 154 140 private: 155 protected: 156 virtual void monitorThreadShutdown(); 157 virtual int monitorWorker(); 158 159 private: 141 160 void strList2List(std::vector<std::string>& lst, char *strLst); 142 161 HRESULT updateInfo(); 162 163 private: 164 struct Data; 165 Data *m; 143 166 }; 144 167 # endif … … 147 170 { 148 171 public: 149 HostDnsServiceResolvConf() :m(NULL) {}172 explicit HostDnsServiceResolvConf(bool fThreaded = false) : HostDnsMonitor(fThreaded), m(NULL) {} 150 173 virtual ~HostDnsServiceResolvConf(); 151 174 virtual HRESULT init(const char *aResolvConfFileName); 152 const std::string& resolvConf() ;175 const std::string& resolvConf() const; 153 176 154 177 protected: 155 178 HRESULT readResolvConf(); 179 /* While not all hosts supports Hosts DNS change notifiaction 180 * default implementation offers return VERR_IGNORE. 181 */ 182 virtual void monitorThreadShutdown() {} 183 virtual int monitorWorker() {return VERR_IGNORED;} 156 184 157 185 protected: … … 175 203 { 176 204 public: 177 HostDnsServiceLinux(){} 178 ~HostDnsServiceLinux(); 179 HRESULT init() {return init("/etc/resolv.conf");} 180 HRESULT init(const char *aResolvConfFileName); 181 182 static int hostMonitoringRoutine(RTTHREAD ThreadSelf, void *pvUser); 205 HostDnsServiceLinux():HostDnsServiceResolvConf(true){} 206 virtual ~HostDnsServiceLinux(); 207 virtual HRESULT init(){ return HostDnsServiceResolvConf::init("/etc/resolv.conf");} 208 209 protected: 210 virtual void monitorThreadShutdown(); 211 virtual int monitorWorker(); 183 212 }; 184 213 -
trunk/src/VBox/Main/src-server/HostDnsServiceResolvConf.cpp
r50213 r50263 25 25 26 26 #include "HostDnsService.h" 27 #include "../../Devices/Network/slirp/resolv_conf_parser.h" 27 28 28 29 … … 34 35 }; 35 36 36 const std::string &HostDnsServiceResolvConf::resolvConf()37 const std::string& HostDnsServiceResolvConf::resolvConf() const 37 38 { 38 39 return m->resolvConfFilename; 39 40 } 40 41 41 static int fileGets(RTFILE File, void *pvBuf, size_t cbBufSize, size_t *pcbRead)42 {43 size_t cbRead;44 char bTest;45 int rc = VERR_NO_MEMORY;46 char *pu8Buf = (char *)pvBuf;47 *pcbRead = 0;48 49 while ( RT_SUCCESS(rc = RTFileRead(File, &bTest, 1, &cbRead))50 && (pu8Buf - (char *)pvBuf) >= 051 && (size_t)(pu8Buf - (char *)pvBuf) < cbBufSize)52 {53 if (cbRead == 0)54 return VERR_EOF;55 56 if (bTest == '\r' || bTest == '\n')57 {58 *pu8Buf = 0;59 return VINF_SUCCESS;60 }61 *pu8Buf = bTest;62 pu8Buf++;63 (*pcbRead)++;64 }65 return rc;66 }67 42 68 43 HostDnsServiceResolvConf::~HostDnsServiceResolvConf() … … 77 52 HRESULT HostDnsServiceResolvConf::init(const char *aResolvConfFileName) 78 53 { 54 m = new Data(aResolvConfFileName); 55 79 56 HostDnsMonitor::init(); 80 57 81 m = new Data(aResolvConfFileName);82 58 readResolvConf(); 83 59 … … 85 61 } 86 62 63 87 64 HRESULT HostDnsServiceResolvConf::readResolvConf() 88 65 { 89 char buff[256]; 90 char buff2[256]; 91 int cNameserversFound = 0; 92 bool fWarnTooManyDnsServers = false; 93 struct in_addr tmp_addr; 94 size_t bytes; 66 struct rcp_state st; 67 68 st.rcps_flags = RCPSF_NO_STR2IPCONV; 69 int rc = rcp_parse(&st, m->resolvConfFilename.c_str()); 70 if (rc == -1) 71 return S_OK; 72 95 73 HostDnsInformation info; 96 RTFILE resolvConfFile; 74 for (unsigned i = 0; i != st.rcps_num_nameserver; ++i) 75 { 76 AssertBreak(st.rcps_str_nameserver[i]); 77 info.servers.push_back(st.rcps_str_nameserver[i]); 78 } 79 80 if (st.rcps_domain) 81 info.domain = st.rcps_domain; 97 82 98 int rc = RTFileOpen(&resolvConfFile, m->resolvConfFilename.c_str(), 99 RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE); 100 AssertRCReturn(rc, E_FAIL); 101 102 while ( RT_SUCCESS(rc = fileGets(resolvConfFile, buff, sizeof(buff), &bytes)) 103 && rc != VERR_EOF) 83 for (unsigned i = 0; i != st.rcps_num_searchlist; ++i) 104 84 { 105 if ( cNameserversFound == 4 106 && !fWarnTooManyDnsServers 107 && sscanf(buff, "nameserver%*[ \t]%255s", buff2) == 1) 108 { 109 fWarnTooManyDnsServers = true; 110 LogRel(("NAT: too many nameservers registered.\n")); 111 } 112 if ( sscanf(buff, "nameserver%*[ \t]%255s", buff2) == 1 113 && cNameserversFound < 4) /* Unix doesn't accept more than 4 name servers*/ 114 { 115 if (!inet_aton(buff2, &tmp_addr)) 116 continue; 117 118 info.servers.push_back(std::string(buff2)); 119 120 cNameserversFound++; 121 } 122 if ( !strncmp(buff, "domain", 6) 123 || !strncmp(buff, "search", 6)) 124 { 125 char *tok; 126 char *saveptr; 127 128 tok = strtok_r(&buff[6], " \t\n", &saveptr); 129 130 if (tok != NULL) 131 info.domain = std::string(tok); 132 } 85 AssertBreak(st.rcps_searchlist[i]); 86 info.searchList.push_back(st.rcps_searchlist[i]); 133 87 } 134 135 RTFileClose(resolvConfFile);136 137 88 setInfo(info); 138 89 -
trunk/src/VBox/Main/src-server/darwin/HostDnsServiceDarwin.cpp
r50213 r50263 32 32 33 33 34 35 SCDynamicStoreRef g_store; 36 CFRunLoopSourceRef g_DnsWatcher; 37 CFRunLoopRef g_RunLoopRef; 38 RTTHREAD g_DnsMonitoringThread; 39 RTSEMEVENT g_DnsInitEvent; 34 struct HostDnsServiceDarwin::Data 35 { 36 SCDynamicStoreRef m_store; 37 CFRunLoopSourceRef m_DnsWatcher; 38 CFRunLoopRef m_RunLoopRef; 39 CFRunLoopSourceRef m_Stopper; 40 bool m_fStop; 41 RTSEMEVENT m_evtStop; 42 static void performShutdownCallback(void *); 43 }; 44 40 45 41 46 static const CFStringRef kStateNetworkGlobalDNSKey = CFSTR("State:/Network/Global/DNS"); 42 47 43 static int hostMonitoringRoutine(RTTHREAD ThreadSelf, void *pvUser) 44 { 45 NOREF(ThreadSelf); 46 NOREF(pvUser); 47 g_RunLoopRef = CFRunLoopGetCurrent(); 48 AssertReturn(g_RunLoopRef, VERR_INTERNAL_ERROR); 49 50 CFRetain(g_RunLoopRef); 48 49 HostDnsServiceDarwin::HostDnsServiceDarwin():HostDnsMonitor(true),m(NULL) 50 { 51 m = new HostDnsServiceDarwin::Data(); 52 } 53 54 55 HostDnsServiceDarwin::~HostDnsServiceDarwin() 56 { 57 if (!m) 58 return; 59 60 monitorThreadShutdown(); 61 62 CFRelease(m->m_RunLoopRef); 63 64 CFRelease(m->m_DnsWatcher); 65 66 CFRelease(m->m_store); 67 68 RTSemEventDestroy(m->m_evtStop); 69 70 delete m; 71 m = NULL; 72 } 73 74 75 void HostDnsServiceDarwin::hostDnsServiceStoreCallback(void *, void *, void *info) 76 { 77 HostDnsServiceDarwin *pThis = (HostDnsServiceDarwin *)info; 78 79 ALock l(pThis); 80 pThis->updateInfo(); 81 pThis->notifyAll(); 82 } 83 84 85 HRESULT HostDnsServiceDarwin::init() 86 { 87 SCDynamicStoreContext ctx; 88 RT_ZERO(ctx); 89 90 ctx.info = this; 91 92 m->m_store = SCDynamicStoreCreate(NULL, CFSTR("org.virtualbox.VBoxSVC"), 93 (SCDynamicStoreCallBack)HostDnsServiceDarwin::hostDnsServiceStoreCallback, 94 &ctx); 95 AssertReturn(m->m_store, E_FAIL); 96 97 m->m_DnsWatcher = SCDynamicStoreCreateRunLoopSource(NULL, m->m_store, 0); 98 if (!m->m_DnsWatcher) 99 return E_OUTOFMEMORY; 100 101 int rc = RTSemEventCreate(&m->m_evtStop); 102 AssertRCReturn(rc, E_FAIL); 103 104 CFRunLoopSourceContext sctx; 105 RT_ZERO(sctx); 106 sctx.perform = HostDnsServiceDarwin::Data::performShutdownCallback; 107 m->m_Stopper = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &sctx); 108 AssertReturn(m->m_Stopper, E_FAIL); 109 110 HRESULT hrc = HostDnsMonitor::init(); 111 AssertComRCReturn(hrc, hrc); 112 113 return updateInfo(); 114 } 115 116 117 void HostDnsServiceDarwin::monitorThreadShutdown() 118 { 119 ALock l(this); 120 if (!m->m_fStop) 121 { 122 CFRunLoopSourceSignal(m->m_Stopper); 123 CFRunLoopWakeUp(m->m_RunLoopRef); 124 125 RTSemEventWait(m->m_evtStop, RT_INDEFINITE_WAIT); 126 } 127 } 128 129 130 int HostDnsServiceDarwin::monitorWorker() 131 { 132 m->m_RunLoopRef = CFRunLoopGetCurrent(); 133 AssertReturn(m->m_RunLoopRef, VERR_INTERNAL_ERROR); 134 135 CFRetain(m->m_RunLoopRef); 51 136 52 137 CFArrayRef watchingArrayRef = CFArrayCreate(NULL, … … 55 140 if (!watchingArrayRef) 56 141 { 57 CFRelease( g_DnsWatcher);142 CFRelease(m->m_DnsWatcher); 58 143 return E_OUTOFMEMORY; 59 144 } 60 145 61 if(SCDynamicStoreSetNotificationKeys( g_store, watchingArrayRef, NULL))62 CFRunLoopAddSource(CFRunLoopGetCurrent(), g_DnsWatcher, kCFRunLoopCommonModes);146 if(SCDynamicStoreSetNotificationKeys(m->m_store, watchingArrayRef, NULL)) 147 CFRunLoopAddSource(CFRunLoopGetCurrent(), m->m_DnsWatcher, kCFRunLoopCommonModes); 63 148 64 149 CFRelease(watchingArrayRef); 65 150 66 RTSemEventSignal(g_DnsInitEvent); 67 68 CFRunLoopRun(); 69 70 CFRelease(g_RunLoopRef); 151 monitorThreadInitializationDone(); 152 153 while (!m->m_fStop) 154 { 155 CFRunLoopRun(); 156 } 157 158 CFRelease(m->m_RunLoopRef); 159 160 /* We're notifying stopper thread. */ 161 RTSemEventSignal(m->m_evtStop); 71 162 72 163 return VINF_SUCCESS; … … 74 165 75 166 76 HostDnsServiceDarwin::HostDnsServiceDarwin(){}77 78 79 HostDnsServiceDarwin::~HostDnsServiceDarwin()80 {81 if (g_RunLoopRef)82 CFRunLoopStop(g_RunLoopRef);83 84 CFRelease(g_DnsWatcher);85 86 CFRelease(g_store);87 }88 89 90 void HostDnsServiceDarwin::hostDnsServiceStoreCallback(void *arg0, void *arg1, void *info)91 {92 HostDnsServiceDarwin *pThis = (HostDnsServiceDarwin *)info;93 94 NOREF(arg0); /* SCDynamicStore */95 NOREF(arg1); /* CFArrayRef */96 97 ALock l(pThis);98 pThis->updateInfo();99 pThis->notifyAll();100 }101 102 103 HRESULT HostDnsServiceDarwin::init()104 {105 SCDynamicStoreContext ctx;106 RT_ZERO(ctx);107 108 ctx.info = this;109 110 g_store = SCDynamicStoreCreate(NULL, CFSTR("org.virtualbox.VBoxSVC"),111 (SCDynamicStoreCallBack)HostDnsServiceDarwin::hostDnsServiceStoreCallback,112 &ctx);113 AssertReturn(g_store, E_FAIL);114 115 g_DnsWatcher = SCDynamicStoreCreateRunLoopSource(NULL, g_store, 0);116 if (!g_DnsWatcher)117 return E_OUTOFMEMORY;118 119 HRESULT hrc = HostDnsMonitor::init();120 AssertComRCReturn(hrc, hrc);121 122 int rc = RTSemEventCreate(&g_DnsInitEvent);123 AssertRCReturn(rc, E_FAIL);124 125 rc = RTThreadCreate(&g_DnsMonitoringThread, hostMonitoringRoutine,126 this, 128 * _1K, RTTHREADTYPE_IO, 0, "dns-monitor");127 AssertRCReturn(rc, E_FAIL);128 129 RTSemEventWait(g_DnsInitEvent, RT_INDEFINITE_WAIT);130 return updateInfo();131 }132 133 134 167 HRESULT HostDnsServiceDarwin::updateInfo() 135 168 { 136 CFPropertyListRef propertyRef = SCDynamicStoreCopyValue( g_store,169 CFPropertyListRef propertyRef = SCDynamicStoreCopyValue(m->m_store, 137 170 kStateNetworkGlobalDNSKey); 138 171 /** … … 216 249 return S_OK; 217 250 } 251 252 void HostDnsServiceDarwin::Data::performShutdownCallback(void *info) 253 { 254 HostDnsServiceDarwin::Data *pThis = static_cast<HostDnsServiceDarwin::Data *>(info); 255 pThis->m_fStop = true; 256 } -
trunk/src/VBox/Main/src-server/linux/HostDnsServiceLinux.cpp
r49460 r50263 33 33 #include <fcntl.h> 34 34 35 #include <linux/limits.h> 36 35 37 #include <sys/inotify.h> 36 38 #include <sys/types.h> … … 42 44 43 45 44 static RTTHREAD g_DnsMonitoringThread;45 static RTSEMEVENT g_DnsInitEvent;46 46 static int g_DnsMonitorStop[2]; 47 48 static const std::string g_EtcFolder = "/etc"; 49 static const std::string g_ResolvConf = "resolv.conf"; 50 static const std::string g_ResolvConfFullPath = "/etc/resolv.conf"; 47 51 48 52 class FileDescriptor … … 71 75 AssertReturnVoid(FileDescriptor::fd != -1); 72 76 } 73 74 77 }; 75 78 76 77 class AutoWatcher:public FileDescriptor 78 { 79 public: 80 AutoWatcher(const AutoNotify& notifier, const std::string& filename, uint32_t mask = IN_CLOSE_WRITE) 81 :name(filename) 82 { 83 nfd = notifier.fileDescriptor(); 84 fd = inotify_add_watch(nfd, name.c_str(), mask); 85 AssertMsgReturnVoid(fd != -1, ("failed to add watcher %s\n", name.c_str())); 86 87 int opt = fcntl(fd, F_GETFL); 88 opt |= O_NONBLOCK; 89 fcntl(fd, F_SETFL, opt); 90 } 91 92 ~AutoWatcher() 93 { 94 int rc = inotify_rm_watch(nfd, fd); 95 AssertMsgReturnVoid(rc != -1, ("Can't detach watcher %d from %d (%d: %s)\n", nfd, fd, 96 errno, strerror(errno))); 97 } 98 99 private: 100 std::string name; 101 int nfd; 79 struct InotifyEventWithName 80 { 81 struct inotify_event e; 82 char name[NAME_MAX]; 102 83 }; 103 84 104 105 85 HostDnsServiceLinux::~HostDnsServiceLinux() 106 86 { 107 send(g_DnsMonitorStop[0], "", 1, 0);87 monitorThreadShutdown(); 108 88 } 109 89 110 90 111 int HostDnsServiceLinux:: hostMonitoringRoutine(RTTHREAD ThreadSelf, void *pvUser)112 { 113 NOREF(ThreadSelf); 91 int HostDnsServiceLinux::monitorWorker() 92 { 93 114 94 AutoNotify a; 115 HostDnsServiceLinux *dns = static_cast<HostDnsServiceLinux *>(pvUser);116 AutoWatcher w(a, std::string(dns->resolvConf().c_str()));117 95 118 96 int rc = socketpair(AF_LOCAL, SOCK_DGRAM, 0, g_DnsMonitorStop); … … 131 109 polls[1].events = POLLIN; 132 110 133 RTSemEventSignal(g_DnsInitEvent); 134 111 monitorThreadInitializationDone(); 112 113 int wd[2]; 114 wd[0] = wd[1] = -1; 115 /* inotify inialization */ 116 wd[0] = inotify_add_watch(a.fileDescriptor(), 117 g_ResolvConfFullPath.c_str(), IN_CLOSE_WRITE|IN_DELETE_SELF); 118 119 /** 120 * If /etc/resolv.conf exists we want to listen for movements: because 121 * # mv /etc/resolv.conf ... 122 * won't arm IN_DELETE_SELF on wd[0] instead it will fire IN_MOVE_FROM on wd[1]. 123 * 124 * Because on some distributions /etc/resolv.conf is link, wd[0] can't detect deletion, 125 * it's recognizible on directory level (wd[1]) only. 126 */ 127 wd[1] = inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(), 128 wd[0] == -1 ? IN_MOVED_TO|IN_CREATE : IN_MOVED_FROM|IN_DELETE); 129 130 struct InotifyEventWithName combo; 135 131 while(true) 136 132 { … … 148 144 if (polls[0].revents & POLLIN) 149 145 { 150 dns->readResolvConf(); 151 /* notifyAll() takes required locks */ 152 dns->notifyAll(); 153 154 polls[0].revents = 0; 155 156 inotify_event ev; 157 rc = read(a.fileDescriptor(), static_cast<void *>(&ev), sizeof(ev)); 158 AssertMsg(rc == sizeof(ev) && ev.wd == w.fileDescriptor(), ("Hmm, debug me")); 146 RT_ZERO(combo); 147 ssize_t r = read(polls[0].fd, static_cast<void *>(&combo), sizeof(combo)); 148 149 if (combo.e.wd == wd[0]) 150 { 151 if (combo.e.mask & IN_CLOSE_WRITE) 152 { 153 readResolvConf(); 154 /* notifyAll() takes required locks */ 155 notifyAll(); 156 } 157 else if (combo.e.mask & IN_DELETE_SELF) 158 { 159 inotify_rm_watch(a.fileDescriptor(), wd[0]); /* removes file watcher */ 160 inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(), 161 IN_MOVED_TO|IN_CREATE); /* alter folder watcher */ 162 } 163 else if (combo.e.mask & IN_IGNORED) 164 { 165 wd[0] = -1; /* we want receive any events on this watch */ 166 } 167 else 168 { 169 /** 170 * It shouldn't happen, in release we will just ignore in debug 171 * we will have to chance to look at into inotify_event 172 */ 173 AssertMsgFailed(("Debug Me!!!")); 174 } 175 } 176 else if (combo.e.wd == wd[1]) 177 { 178 if ( combo.e.mask & IN_MOVED_FROM 179 || combo.e.mask & IN_DELETE) 180 { 181 if (g_ResolvConf == combo.e.name) 182 { 183 /** 184 * Our file has been moved so we should change watching mode. 185 */ 186 inotify_rm_watch(a.fileDescriptor(), wd[0]); 187 wd[1] = inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(), 188 IN_MOVED_TO|IN_CREATE); 189 AssertMsg(wd[1] != -1, 190 ("It shouldn't happen, further investigation is needed\n")); 191 } 192 } 193 else 194 { 195 AssertMsg(combo.e.mask & (IN_MOVED_TO|IN_CREATE), 196 ("%RX32 event isn't expected, we are waiting for IN_MOVED|IN_CREATE\n", 197 combo.e.mask)); 198 if (g_ResolvConf == combo.e.name) 199 { 200 AssertMsg(wd[0] == -1, ("We haven't removed file watcher first\n")); 201 202 /* alter folder watcher*/ 203 wd[1] = inotify_add_watch(a.fileDescriptor(), g_EtcFolder.c_str(), 204 IN_MOVED_FROM|IN_DELETE); 205 AssertMsg(wd[1] != -1, ("It shouldn't happen.\n")); 206 207 wd[0] = inotify_add_watch(a.fileDescriptor(), 208 g_ResolvConfFullPath.c_str(), 209 IN_CLOSE_WRITE | IN_DELETE_SELF); 210 AssertMsg(wd[0] != -1, ("Adding watcher to file (%s) has been failed!\n", 211 g_ResolvConfFullPath.c_str())); 212 213 /* Notify our listeners */ 214 readResolvConf(); 215 notifyAll(); 216 217 } 218 } 219 } 220 else 221 { 222 /* It shouldn't happen */ 223 AssertMsgFailed(("Shouldn't happen! Please debug me!")); 224 } 159 225 } 160 226 } … … 162 228 163 229 164 HRESULT HostDnsServiceLinux::init(const char *aResolvConfFileName) 165 { 166 HRESULT hrc = HostDnsServiceResolvConf::init(aResolvConfFileName); 167 AssertComRCReturnRC(hrc); 168 169 int rc = RTSemEventCreate(&g_DnsInitEvent); 170 AssertRCReturn(rc, E_FAIL); 171 172 rc = RTThreadCreate(&g_DnsMonitoringThread, HostDnsServiceLinux::hostMonitoringRoutine, 173 this, 128 * _1K, RTTHREADTYPE_IO, 0, "dns-monitor"); 174 AssertRCReturn(rc, E_FAIL); 175 176 RTSemEventWait(g_DnsInitEvent, RT_INDEFINITE_WAIT); 177 178 return S_OK; 230 void HostDnsServiceLinux::monitorThreadShutdown() 231 { 232 send(g_DnsMonitorStop[0], "", 1, 0); 179 233 } -
trunk/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp
r49445 r50263 13 13 #include "../HostDnsService.h" 14 14 15 static HKEY g_hKeyTcpipParameters; 16 17 HostDnsServiceWin::HostDnsServiceWin() 18 { 19 RegOpenKeyEx(HKEY_LOCAL_MACHINE, 20 TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"), 21 0, KEY_READ, &g_hKeyTcpipParameters); 15 struct HostDnsServiceWin::Data 16 { 17 HostDnsServiceWin::Data(){} 18 HKEY hKeyTcpipParameters; 19 #define DATA_DNS_UPDATE_EVENT 0 20 #define DATA_SHUTDOWN_EVENT 1 21 #define DATA_MAX_EVENT 2 22 HANDLE haDataEvent[DATA_MAX_EVENT]; 23 }; 24 25 static inline int registerNotification(const HKEY& hKey, HANDLE& hEvent) 26 { 27 LONG lrc = RegNotifyChangeKeyValue(hKey, 28 TRUE, 29 REG_NOTIFY_CHANGE_LAST_SET, 30 hEvent, 31 TRUE); 32 AssertMsgReturn(lrc == ERROR_SUCCESS, 33 ("Failed to register event on the key. Please debug me!"), 34 VERR_INTERNAL_ERROR); 35 36 return VINF_SUCCESS; 37 } 38 39 HostDnsServiceWin::HostDnsServiceWin():HostDnsMonitor(true), m(NULL) 40 { 41 m = new Data(); 42 43 m->haDataEvent[DATA_DNS_UPDATE_EVENT] = CreateEvent(NULL, 44 TRUE, FALSE, NULL); 45 AssertReleaseMsg(m->haDataEvent[DATA_DNS_UPDATE_EVENT], 46 ("Failed to create event for DNS event (%d)\n", GetLastError())); 47 48 m->haDataEvent[DATA_SHUTDOWN_EVENT] = CreateEvent(NULL, 49 TRUE, FALSE, NULL); 50 AssertReleaseMsg(m->haDataEvent[DATA_SHUTDOWN_EVENT], 51 ("Failed to create event for Shutdown signal (%d)\n", GetLastError())); 52 53 LONG lrc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, 54 TEXT("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters"), 55 0, KEY_READ|KEY_NOTIFY, &m->hKeyTcpipParameters); 56 AssertReleaseMsg(lrc == ERROR_SUCCESS, 57 ("Failed to open Registry Key for read and update notifications (%d)\n", 58 GetLastError())); 22 59 } 23 60 … … 25 62 HostDnsServiceWin::~HostDnsServiceWin() 26 63 { 27 if ( !g_hKeyTcpipParameters)64 if (m && !m->hKeyTcpipParameters) 28 65 { 29 RegCloseKey(g_hKeyTcpipParameters); 30 g_hKeyTcpipParameters = 0; 66 RegCloseKey(m->hKeyTcpipParameters); 67 m->hKeyTcpipParameters = 0; 68 69 CloseHandle(m->haDataEvent[DATA_DNS_UPDATE_EVENT]); 70 CloseHandle(m->haDataEvent[DATA_SHUTDOWN_EVENT]); 71 72 delete m; 73 74 m = NULL; 31 75 } 32 76 } … … 39 83 40 84 return updateInfo(); 85 } 86 87 88 void HostDnsServiceWin::monitorThreadShutdown() 89 { 90 SetEvent(m->haDataEvent[DATA_SHUTDOWN_EVENT]); 91 } 92 93 94 int HostDnsServiceWin::monitorWorker() 95 { 96 registerNotification(m->hKeyTcpipParameters, 97 m->haDataEvent[DATA_DNS_UPDATE_EVENT]); 98 99 monitorThreadInitializationDone(); 100 101 DWORD dwRc; 102 while (true) 103 { 104 dwRc = WaitForMultipleObjects(DATA_MAX_EVENT, 105 m->haDataEvent, 106 FALSE, 107 INFINITE); 108 AssertMsgReturn(dwRc != WAIT_FAILED, 109 ("WaitForMultipleObjects failed (%d) to wait! Please debug", 110 GetLastError()), VERR_INTERNAL_ERROR); 111 112 if ((dwRc - WAIT_OBJECT_0) == DATA_DNS_UPDATE_EVENT) 113 { 114 updateInfo(); 115 notifyAll(); 116 ResetEvent(m->haDataEvent[DATA_DNS_UPDATE_EVENT]); 117 registerNotification(m->hKeyTcpipParameters, 118 m->haDataEvent[DATA_DNS_UPDATE_EVENT]); 119 120 } 121 else if ((dwRc - WAIT_OBJECT_0) == DATA_SHUTDOWN_EVENT) 122 { 123 break; 124 } 125 else 126 { 127 AssertMsgFailedReturn( 128 ("WaitForMultipleObjects returns out of bound index %d. Please debug!", 129 dwRc), 130 VERR_INTERNAL_ERROR); 131 } 132 } 133 return VINF_SUCCESS; 41 134 } 42 135 … … 62 155 DWORD cbKeyData = sizeof(keyData); 63 156 64 hrc = RegEnumValueA( g_hKeyTcpipParameters, regIndex, keyName, &cbKeyName, 0,157 hrc = RegEnumValueA(m->hKeyTcpipParameters, regIndex, keyName, &cbKeyName, 0, 65 158 &keyType, keyData, &cbKeyData); 66 159 if ( hrc == ERROR_SUCCESS … … 113 206 114 207 115 116 208 void HostDnsServiceWin::strList2List(std::vector<std::string>& lst, char *strLst) 117 209 {
Note:
See TracChangeset
for help on using the changeset viewer.