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 /vdservice | |
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.
Diffstat (limited to 'vdservice')
-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; |