Changeset 77993 in vbox
- Timestamp:
- Apr 3, 2019 3:11:36 PM (6 years ago)
- Location:
- trunk/src/VBox/Main/src-server
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/HostDnsService.cpp
r77984 r77993 131 131 } 132 132 133 /* static */ 133 134 HostDnsServiceBase *HostDnsServiceBase::createHostDnsMonitor(void) 134 135 { … … 154 155 } 155 156 156 void HostDnsServiceBase::shutdown(void)157 {158 monitorThreadShutdown();159 int rc = RTThreadWait(m->hMonitorThread, 5000, NULL);160 AssertRCSuccess(rc);161 }162 163 164 void HostDnsServiceBase::setInfo(const HostDnsInformation &info)165 {166 if (m->pProxy != NULL)167 m->pProxy->notify(info);168 }169 170 157 HRESULT HostDnsServiceBase::init(HostDnsMonitorProxy *pProxy) 171 158 { 159 LogRel(("HostDnsMonitor: initializing\n")); 160 161 AssertPtrReturn(pProxy, E_POINTER); 172 162 m->pProxy = pProxy; 173 163 174 164 if (m->fThreaded) 175 165 { 166 LogRel2(("HostDnsMonitor: starting thread ...\n")); 167 176 168 int rc = RTSemEventCreate(&m->hMonitorThreadEvent); 177 169 AssertRCReturn(rc, E_FAIL); 178 170 179 171 rc = RTThreadCreate(&m->hMonitorThread, 180 HostDnsServiceBase::threadMonitor ingRoutine,172 HostDnsServiceBase::threadMonitorProc, 181 173 this, 128 * _1K, RTTHREADTYPE_IO, 182 174 RTTHREADFLAGS_WAITABLE, "dns-monitor"); … … 184 176 185 177 RTSemEventWait(m->hMonitorThreadEvent, RT_INDEFINITE_WAIT); 186 } 178 179 LogRel2(("HostDnsMonitor: thread started\n")); 180 } 181 187 182 return S_OK; 183 } 184 185 void HostDnsServiceBase::uninit(void) 186 { 187 LogRel(("HostDnsMonitor: shutting down ...\n")); 188 189 if (m->fThreaded) 190 { 191 LogRel2(("HostDnsMonitor: waiting for thread ...\n")); 192 193 const RTMSINTERVAL uTimeoutMs = 30 * 1000; /* 30s */ 194 195 monitorThreadShutdown(uTimeoutMs); 196 197 int rc = RTThreadWait(m->hMonitorThread, uTimeoutMs, NULL); 198 if (RT_FAILURE(rc)) 199 LogRel(("HostDnsMonitor: waiting for thread failed with rc=%Rrc\n", rc)); 200 } 201 202 LogRel(("HostDnsMonitor: shut down\n")); 203 } 204 205 void HostDnsServiceBase::setInfo(const HostDnsInformation &info) 206 { 207 if (m->pProxy != NULL) 208 m->pProxy->notify(info); 188 209 } 189 210 … … 247 268 } 248 269 249 void HostDnsServiceBase::monitorThreadInitializationDone(void) 250 { 270 void HostDnsServiceBase::onMonitorThreadInitDone(void) 271 { 272 if (!m->fThreaded) /* If non-threaded, bail out, nothing to do here. */ 273 return; 274 251 275 RTSemEventSignal(m->hMonitorThreadEvent); 252 276 } 253 277 254 DECLCALLBACK(int) HostDnsServiceBase::threadMonitor ingRoutine(RTTHREAD, void *pvUser)278 DECLCALLBACK(int) HostDnsServiceBase::threadMonitorProc(RTTHREAD, void *pvUser) 255 279 { 256 280 HostDnsServiceBase *pThis = static_cast<HostDnsServiceBase *>(pvUser); 257 return pThis->monitorWorker(); 281 AssertPtrReturn(pThis, VERR_INVALID_POINTER); 282 return pThis->monitorThreadProc(); 258 283 } 259 284 260 285 /* HostDnsMonitorProxy */ 261 286 HostDnsMonitorProxy::HostDnsMonitorProxy() 262 : m(NULL)287 : m(NULL) 263 288 { 264 289 } … … 266 291 HostDnsMonitorProxy::~HostDnsMonitorProxy() 267 292 { 268 Assert(!m); 269 } 270 271 void HostDnsMonitorProxy::init(VirtualBox* aParent) 272 { 273 HostDnsServiceBase *pMonitor = HostDnsServiceBase::createHostDnsMonitor(); 274 m = new HostDnsMonitorProxy::Data(pMonitor, aParent); 275 m->pMonitorImpl->init(this); 293 uninit(); 294 } 295 296 HRESULT HostDnsMonitorProxy::init(VirtualBox* aParent) 297 { 298 AssertMsgReturn(m == NULL, ("DNS monitor proxy already initialized\n"), E_FAIL); 299 300 HostDnsServiceBase *pMonitorImpl = HostDnsServiceBase::createHostDnsMonitor(); 301 AssertPtrReturn(pMonitorImpl, E_OUTOFMEMORY); 302 303 Assert(m == NULL); /* Paranoia. */ 304 m = new HostDnsMonitorProxy::Data(pMonitorImpl, aParent); 305 AssertPtrReturn(m, E_OUTOFMEMORY); 306 307 return m->pMonitorImpl->init(this); 276 308 } 277 309 … … 280 312 if (m) 281 313 { 282 m->pMonitorImpl->shutdown(); 314 m->pMonitorImpl->uninit(); 315 283 316 delete m; 284 317 m = NULL; … … 288 321 void HostDnsMonitorProxy::notify(const HostDnsInformation &info) 289 322 { 290 bool fNotify = updateInfo(info);323 const bool fNotify = updateInfo(info); 291 324 if (fNotify) 292 325 m->pVirtualBox->i_onHostNameResolutionConfigurationChange(); … … 334 367 bool HostDnsMonitorProxy::updateInfo(const HostDnsInformation &info) 335 368 { 336 LogRel(("HostDnsMonitor: :updateInfo\n"));369 LogRel(("HostDnsMonitor: updating information\n")); 337 370 RTCLock grab(m_LockMtx); 338 371 -
trunk/src/VBox/Main/src-server/HostDnsService.h
r77985 r77993 49 49 50 50 /** 51 * This class supposed to be a real DNS monitor object it should be singleton, 52 * it lifecycle starts and ends together with VBoxSVC. 51 * Base class for host DNS service implementations. 52 * This class supposed to be a real DNS monitor object as a singleton, 53 * so it lifecycle starts and ends together with VBoxSVC. 53 54 */ 54 55 class HostDnsServiceBase … … 59 60 60 61 static HostDnsServiceBase *createHostDnsMonitor(void); 61 void shutdown(); 62 63 public: 62 64 63 65 /* @note: method will wait till client call … … 65 67 virtual HRESULT init(HostDnsMonitorProxy *pProxy); 66 68 69 void uninit(void); 70 67 71 protected: 68 72 … … 73 77 74 78 /* this function used only if HostDnsMonitor::HostDnsMonitor(true) */ 75 void monitorThreadInitializationDone(); 76 virtual void monitorThreadShutdown() = 0; 77 virtual int monitorWorker() = 0; 78 79 private: 80 81 static DECLCALLBACK(int) threadMonitoringRoutine(RTTHREAD, void *); 79 void onMonitorThreadInitDone(); 80 81 public: 82 83 virtual int monitorThreadShutdown(RTMSINTERVAL uTimeoutMs) 84 { 85 RT_NOREF(uTimeoutMs); AssertFailed(); return VERR_NOT_IMPLEMENTED; 86 } 87 88 virtual int monitorThreadProc(void) { AssertFailed(); return VERR_NOT_IMPLEMENTED; } 89 90 private: 91 92 static DECLCALLBACK(int) threadMonitorProc(RTTHREAD, void *); 82 93 83 94 protected: … … 103 114 public: 104 115 105 voidinit(VirtualBox *virtualbox);106 void uninit( );116 HRESULT init(VirtualBox *virtualbox); 117 void uninit(void); 107 118 void notify(const HostDnsInformation &info); 108 119 … … 113 124 private: 114 125 115 void pollGlobalExtraData( );126 void pollGlobalExtraData(void); 116 127 bool updateInfo(const HostDnsInformation &info); 117 128 … … 133 144 public: 134 145 135 virtual HRESULT init(HostDnsMonitorProxy *pProxy); 136 137 protected: 138 139 virtual void monitorThreadShutdown(); 140 virtual int monitorWorker(); 146 HRESULT init(HostDnsMonitorProxy *pProxy); 147 void uninit(void); 148 149 protected: 150 151 int monitorThreadShutdown(RTMSINTERVAL uTimeoutMs); 152 int monitorThreadProc(void); 141 153 142 154 private: … … 157 169 public: 158 170 159 virtual HRESULT init(HostDnsMonitorProxy *pProxy); 160 161 protected: 162 163 virtual void monitorThreadShutdown(); 164 virtual int monitorWorker(); 165 166 private: 167 168 HRESULT updateInfo(); 169 170 private: 171 HRESULT init(HostDnsMonitorProxy *pProxy); 172 void uninit(void); 173 174 protected: 175 176 int monitorThreadShutdown(RTMSINTERVAL uTimeoutMs); 177 int monitorThreadProc(void); 178 179 private: 180 181 HRESULT updateInfo(void); 182 183 private: 184 171 185 struct Data; 172 186 Data *m; … … 184 198 public: 185 199 186 virtual HRESULT init(HostDnsMonitorProxy *pProxy, const char *aResolvConfFileName); 187 const std::string& resolvConf() const; 188 189 protected: 190 191 HRESULT readResolvConf(); 192 /* While not all hosts supports Hosts DNS change notifiaction 193 * default implementation offers return VERR_IGNORE. 194 */ 195 virtual void monitorThreadShutdown() {} 196 virtual int monitorWorker() {return VERR_IGNORED;} 200 HRESULT init(HostDnsMonitorProxy *pProxy, const char *aResolvConfFileName); 201 void uninit(void); 202 203 const std::string& getResolvConf(void) const; 204 205 protected: 206 207 HRESULT readResolvConf(void); 197 208 198 209 protected: … … 209 220 public: 210 221 211 HostDnsServiceSolaris() {}212 virtual ~HostDnsServiceSolaris() {}222 HostDnsServiceSolaris() {} 223 virtual ~HostDnsServiceSolaris() {} 213 224 214 225 public: … … 225 236 public: 226 237 227 HostDnsServiceLinux() : HostDnsServiceResolvConf(true) {} 228 virtual ~HostDnsServiceLinux(); 229 230 public: 231 232 virtual HRESULT init(HostDnsMonitorProxy *pProxy) { 233 return HostDnsServiceResolvConf::init(pProxy, "/etc/resolv.conf"); 234 } 235 236 protected: 237 238 virtual void monitorThreadShutdown(); 239 virtual int monitorWorker(); 238 HostDnsServiceLinux() : HostDnsServiceResolvConf(true) {} 239 virtual ~HostDnsServiceLinux(); 240 241 public: 242 243 HRESULT init(HostDnsMonitorProxy *pProxy); 244 void uninit(void); 245 protected: 246 247 int monitorThreadShutdown(RTMSINTERVAL uTimeoutMs); 248 int monitorThreadProc(void); 240 249 }; 241 250 … … 251 260 public: 252 261 253 virtual HRESULT init(HostDnsMonitorProxy *pProxy) { 262 virtual HRESULT init(HostDnsMonitorProxy *pProxy) 263 { 254 264 return HostDnsServiceResolvConf::init(pProxy, "/etc/resolv.conf"); 255 265 } … … 268 278 269 279 /* XXX: \\MPTN\\ETC should be taken from environment variable ETC */ 270 virtual HRESULT init(HostDnsMonitorProxy *pProxy) { 280 virtual HRESULT init(HostDnsMonitorProxy *pProxy) 281 { 271 282 return HostDnsServiceResolvConf::init(pProxy, "\\MPTN\\ETC\\RESOLV2"); 272 283 } -
trunk/src/VBox/Main/src-server/HostDnsServiceResolvConf.cpp
r77984 r77993 55 55 }; 56 56 57 const std::string& HostDnsServiceResolvConf::resolvConf(void) const58 {59 return m->resolvConfFilename;60 }61 62 63 57 HostDnsServiceResolvConf::~HostDnsServiceResolvConf() 64 58 { … … 72 66 HRESULT HostDnsServiceResolvConf::init(HostDnsMonitorProxy *pProxy, const char *aResolvConfFileName) 73 67 { 68 HRESULT hr = HostDnsServiceBase::init(pProxy); 69 AssertComRCReturn(hr, hr); 70 74 71 m = new Data(aResolvConfFileName); 72 AssertPtrReturn(m, E_OUTOFMEMORY); 75 73 76 HostDnsServiceBase::init(pProxy); 74 return readResolvConf(); 75 } 77 76 78 readResolvConf(); 77 void HostDnsServiceResolvConf::uninit(void) 78 { 79 if (m) 80 { 81 delete m; 82 m = NULL; 83 } 79 84 80 return S_OK; 85 HostDnsServiceBase::uninit(); 86 } 87 88 const std::string& HostDnsServiceResolvConf::getResolvConf(void) const 89 { 90 return m->resolvConfFilename; 81 91 } 82 92 -
trunk/src/VBox/Main/src-server/darwin/HostDnsServiceDarwin.cpp
r77984 r77993 52 52 53 53 HostDnsServiceDarwin::HostDnsServiceDarwin() 54 : HostDnsServiceBase(true )54 : HostDnsServiceBase(true /* fThreaded */) 55 55 , m(NULL) 56 56 { … … 90 90 HRESULT HostDnsServiceDarwin::init(HostDnsMonitorProxy *pProxy) 91 91 { 92 HRESULT hrc = HostDnsServiceBase::init(pProxy); 93 AssertComRCReturn(hrc, hrc); 94 92 95 SCDynamicStoreContext ctx; 93 96 RT_ZERO(ctx); … … 113 116 AssertReturn(m->m_Stopper, E_FAIL); 114 117 115 HRESULT hrc = HostDnsServiceBase::init(pProxy);116 AssertComRCReturn(hrc, hrc);117 118 118 return updateInfo(); 119 119 } … … 134 134 135 135 136 int HostDnsServiceDarwin::monitor Worker(void)136 int HostDnsServiceDarwin::monitorThreadProc(void) 137 137 { 138 138 m->m_RunLoopRef = CFRunLoopGetCurrent(); … … 155 155 CFRelease(watchingArrayRef); 156 156 157 monitorThreadInitializationDone();157 onMonitorThreadInitDone(); 158 158 159 159 while (!ASMAtomicReadBool(&m->m_fStop)) -
trunk/src/VBox/Main/src-server/linux/HostDnsServiceLinux.cpp
r77984 r77993 90 90 HostDnsServiceLinux::~HostDnsServiceLinux() 91 91 { 92 monitorThreadShutdown(); 93 } 94 95 96 int HostDnsServiceLinux::monitorWorker(void) 97 { 98 92 } 93 94 HRESULT HostDnsServiceLinux::init(HostDnsMonitorProxy *pProxy) 95 { 96 return HostDnsServiceResolvConf::init(pProxy, "/etc/resolv.conf"); 97 } 98 99 int HostDnsServiceLinux::monitorThreadShutdown(RTMSINTERVAL uTimeoutMs) 100 { 101 RT_NOREF(uTimeoutMs); 102 103 send(g_DnsMonitorStop[0], "", 1, 0); 104 105 /** @todo r=andy Do we have to wait for something here? Can this fail? */ 106 return VINF_SUCCESS; 107 } 108 109 int HostDnsServiceLinux::monitorThreadProc(void) 110 { 99 111 AutoNotify a; 100 112 … … 114 126 polls[1].events = POLLIN; 115 127 116 monitorThreadInitializationDone();128 onMonitorThreadInitDone(); 117 129 118 130 int wd[2]; … … 229 241 } 230 242 231 232 void HostDnsServiceLinux::monitorThreadShutdown()233 {234 send(g_DnsMonitorStop[0], "", 1, 0);235 } -
trunk/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp
r77985 r77993 42 42 #include <vector> 43 43 44 static inline int registerNotification(const HKEY& hKey, HANDLE& hEvent); 45 static void appendTokenizedStrings(std::vector<std::string> &vecStrings, const std::string &strToAppend, char chDelim = ' '); 46 44 47 struct HostDnsServiceWin::Data 45 48 { … … 86 89 } 87 90 88 89 91 HRESULT HostDnsServiceWin::init(HostDnsMonitorProxy *pProxy) 90 92 { … … 92 94 return E_FAIL; 93 95 94 { 95 bool res = true; 96 LONG lrc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 97 L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", 98 0, 99 KEY_READ|KEY_NOTIFY, 100 &m->hKeyTcpipParameters); 101 if (lrc != ERROR_SUCCESS) 102 { 103 LogRel(("HostDnsServiceWin: failed to open key Tcpip\\Parameters (error %d)\n", lrc)); 104 res = false; 105 } 106 else 107 { 108 for (size_t i = 0; i < DATA_MAX_EVENT; ++i) 109 { 110 HANDLE h; 111 112 if (i == DATA_TIMER) 113 h = CreateWaitableTimer(NULL, FALSE, NULL); 114 else 115 h = CreateEvent(NULL, TRUE, FALSE, NULL); 116 117 if (h == NULL) 118 { 119 LogRel(("HostDnsServiceWin: failed to create event (error %d)\n", GetLastError())); 120 res = false; 121 break; 122 } 123 124 m->haDataEvent[i] = h; 125 } 126 } 127 if(!res) 128 return E_FAIL; 129 } 96 bool fRc = true; 97 LONG lRc = RegOpenKeyExW(HKEY_LOCAL_MACHINE, 98 L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters", 99 0, 100 KEY_READ|KEY_NOTIFY, 101 &m->hKeyTcpipParameters); 102 if (lRc != ERROR_SUCCESS) 103 { 104 LogRel(("HostDnsServiceWin: failed to open key Tcpip\\Parameters (error %d)\n", lRc)); 105 fRc = false; 106 } 107 else 108 { 109 for (size_t i = 0; i < DATA_MAX_EVENT; ++i) 110 { 111 HANDLE h; 112 113 if (i == DATA_TIMER) 114 h = CreateWaitableTimer(NULL, FALSE, NULL); 115 else 116 h = CreateEvent(NULL, TRUE, FALSE, NULL); 117 118 if (h == NULL) 119 { 120 LogRel(("HostDnsServiceWin: failed to create event (error %d)\n", GetLastError())); 121 fRc = false; 122 break; 123 } 124 125 m->haDataEvent[i] = h; 126 } 127 } 128 129 if (!fRc) 130 return E_FAIL; 130 131 131 132 HRESULT hrc = HostDnsServiceBase::init(pProxy); … … 136 137 } 137 138 138 139 void HostDnsServiceWin::monitorThreadShutdown() 140 { 141 Assert(m != NULL); 139 void HostDnsServiceWin::uninit(void) 140 { 141 HostDnsServiceBase::uninit(); 142 } 143 144 int HostDnsServiceWin::monitorThreadShutdown(RTMSINTERVAL uTimeoutMs) 145 { 146 RT_NOREF(uTimeoutMs); 147 148 AssertPtr(m); 142 149 SetEvent(m->haDataEvent[DATA_SHUTDOWN_EVENT]); 143 } 144 145 146 static inline int registerNotification(const HKEY& hKey, HANDLE& hEvent) 147 { 148 LONG lrc = RegNotifyChangeKeyValue(hKey, 149 TRUE, 150 REG_NOTIFY_CHANGE_LAST_SET, 151 hEvent, 152 TRUE); 153 AssertMsgReturn(lrc == ERROR_SUCCESS, 154 ("Failed to register event on the key. Please debug me!"), 155 VERR_INTERNAL_ERROR); 150 /** @todo r=andy Wait for thread? Check rc here. Timeouts? */ 156 151 157 152 return VINF_SUCCESS; 158 153 } 159 154 160 161 int HostDnsServiceWin::monitorWorker() 155 int HostDnsServiceWin::monitorThreadProc(void) 162 156 { 163 157 Assert(m != NULL); … … 166 160 m->haDataEvent[DATA_DNS_UPDATE_EVENT]); 167 161 168 monitorThreadInitializationDone();162 onMonitorThreadInitDone(); 169 163 170 164 for (;;) … … 226 220 } 227 221 228 229 void vappend(std::vector<std::string> &v, const std::string &s, char sep = ' ')230 {231 if (s.empty())232 return;233 234 std::istringstream stream(s);235 std::string substr;236 237 while (std::getline(stream, substr, sep))238 {239 if (substr.empty())240 continue;241 242 if (std::find(v.cbegin(), v.cend(), substr) != v.cend())243 continue;244 245 v.push_back(substr);246 }247 }248 249 250 222 HRESULT HostDnsServiceWin::updateInfo(void) 251 223 { … … 257 229 std::string strDomain; 258 230 std::string strSearchList; /* NB: comma separated, no spaces */ 259 260 231 261 232 /* … … 321 292 /* statically configured search list */ 322 293 if (!strSearchList.empty()) 323 { 324 vappend(info.searchList, strSearchList, ','); 325 } 326 294 appendTokenizedStrings(info.searchList, strSearchList, ','); 327 295 328 296 /* … … 457 425 LogRel2(("HostDnsServiceWin: ... suffix = \"%s\"\n", pszDnsSuffix)); 458 426 459 vappend(info.searchList, pszDnsSuffix);427 appendTokenizedStrings(info.searchList, pszDnsSuffix); 460 428 RTStrFree(pszDnsSuffix); 461 429 } … … 475 443 return S_OK; 476 444 } 445 446 static inline int registerNotification(const HKEY& hKey, HANDLE& hEvent) 447 { 448 LONG lrc = RegNotifyChangeKeyValue(hKey, 449 TRUE, 450 REG_NOTIFY_CHANGE_LAST_SET, 451 hEvent, 452 TRUE); 453 AssertMsgReturn(lrc == ERROR_SUCCESS, 454 ("Failed to register event on the key. Please debug me!"), 455 VERR_INTERNAL_ERROR); 456 457 return VINF_SUCCESS; 458 } 459 460 static void appendTokenizedStrings(std::vector<std::string> &vecStrings, const std::string &strToAppend, char chDelim /* = ' ' */) 461 { 462 if (strToAppend.empty()) 463 return; 464 465 std::istringstream stream(strToAppend); 466 std::string substr; 467 468 while (std::getline(stream, substr, chDelim)) 469 { 470 if (substr.empty()) 471 continue; 472 473 if (std::find(vecStrings.cbegin(), vecStrings.cend(), substr) != vecStrings.cend()) 474 continue; 475 476 vecStrings.push_back(substr); 477 } 478 } 479
Note:
See TracChangeset
for help on using the changeset viewer.