[Spice-devel] [PATCH vdagent-win 1/1] vdservice: fix vdagent first launch (during startup) failure handling rhbz#750037

Arnon Gilboa agilboa at redhat.com
Mon Dec 26 02:58:32 PST 2011


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.
---
 vdservice/vdservice.cpp |   43 ++++++++++++++++++++++++++++++++++---------
 1 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/vdservice/vdservice.cpp b/vdservice/vdservice.cpp
index beb1fe3..ea02254 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()
@@ -474,6 +475,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 +499,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 +975,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;
-- 
1.7.4.1



More information about the Spice-devel mailing list