summaryrefslogtreecommitdiff
path: root/vdservice
diff options
context:
space:
mode:
authorArnon Gilboa <agilboa@redhat.com>2011-12-26 12:52:10 +0200
committerArnon Gilboa <agilboa@redhat.com>2011-12-28 16:27:18 +0200
commit56f7f3f1d5ef6f28f58f3a3ed17957d0ad88411e (patch)
treee3aeabbdc6b49f194cffddad928ce0116ba2cd78 /vdservice
parent017482d779ed087326f40d6379a990de5d65234d (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.cpp42
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;