diff options
author | Arnon Gilboa <agilboa@redhat.com> | 2011-12-26 12:52:10 +0200 |
---|---|---|
committer | Arnon Gilboa <agilboa@redhat.com> | 2011-12-28 16:27:18 +0200 |
commit | 56f7f3f1d5ef6f28f58f3a3ed17957d0ad88411e (patch) | |
tree | e3aeabbdc6b49f194cffddad928ce0116ba2cd78 | |
parent | 017482d779ed087326f40d6379a990de5d65234d (diff) |
vdservice: fix vdagent first launch (during startup) failure handling rhbz#750037
In case of agent launch failure: if connection state is not active(*), wait for
agent launch on the next session connection. Otherwise, the service is stopped.
(*) The failure was due to system startup timings and logon settings, causing
the first agent instance lifetime (before session connect) to be too short to
connect the service.
-rw-r--r-- | vdservice/vdservice.cpp | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/vdservice/vdservice.cpp b/vdservice/vdservice.cpp index beb1fe3..29f4c9a 100644 --- a/vdservice/vdservice.cpp +++ b/vdservice/vdservice.cpp @@ -443,6 +443,7 @@ VOID WINAPI VDService::main(DWORD argc, TCHAR* argv[]) #ifndef DEBUG_VDSERVICE SetServiceStatus(s->_status_handle, status); #endif //DEBUG_VDSERVICE + vd_printf("***Service stopped***"); } VDIPort *create_virtio_vdi_port() @@ -466,6 +467,7 @@ bool VDService::init_vdi_port() } delete _vdi_port; } + _vdi_port = NULL; return false; } @@ -474,6 +476,9 @@ bool VDService::execute() SECURITY_ATTRIBUTES sec_attr; SECURITY_DESCRIPTOR* sec_desr; HANDLE pipe; + INT* con_state = NULL; + bool con_state_active = false; + DWORD bytes; sec_desr = (SECURITY_DESCRIPTOR*)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); InitializeSecurityDescriptor(sec_desr, SECURITY_DESCRIPTOR_REVISION); @@ -495,16 +500,35 @@ bool VDService::execute() _session_id = WTSGetActiveConsoleSessionId(); if (_session_id == 0xFFFFFFFF) { vd_printf("WTSGetActiveConsoleSessionId() failed"); - CloseHandle(pipe); - return false; + _running = false; } - if (!launch_agent()) { - CloseHandle(pipe); - return false; + vd_printf("Active console session id: %u", _session_id); + if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, _session_id, + WTSConnectState, (LPTSTR *)&con_state, &bytes)) { + vd_printf("Connect state: %d", *con_state); + con_state_active = (*con_state == WTSActive); + WTSFreeMemory(con_state); + } + if (_running && !launch_agent()) { + // In case of agent launch failure: if connection state is not active(*), wait for agent + // launch on the next session connection. Otherwise, the service is stopped. + // (*) The failure was due to system startup timings and logon settings, causing the first + // agent instance lifetime (before session connect) to be too short to connect the service. + _running = !con_state_active && (GetLastError() != ERROR_FILE_NOT_FOUND); + if (_running) { + vd_printf("Failed launching vdagent instance, waiting for session connection"); + } + while (_running && !_pipe_connected) { + if (WaitForSingleObject(_control_event, INFINITE) == WAIT_OBJECT_0) { + handle_control_event(); + } + } } - - if (!init_vdi_port()) { + if (_running && !init_vdi_port()) { vd_printf("Failed to create VDIPort instance"); + _running = false; + } + if (!_running) { CloseHandle(pipe); return false; } @@ -952,7 +976,9 @@ bool VDService::restart_agent(bool normal_restart) } _last_agent_restart_time = time; ret = true; - read_pipe(); + if (_vdi_port) { + read_pipe(); + } } MUTEX_UNLOCK(_agent_mutex); return ret; |