]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
Make VSOCK reset connection during connect on QP detach
authorVMware, Inc <>
Mon, 20 Dec 2010 22:13:22 +0000 (14:13 -0800)
committerMarcelo Vanzin <mvanzin@vmware.com>
Mon, 20 Dec 2010 22:13:22 +0000 (14:13 -0800)
If the peer of a stream connection detaches from an already
allocated queue pair while the connection state is still
"connecting", we should treat it as a reset. The peer may
detach for a number of reasons, the two primary ones are 1)
the VM got killed, 2) the QP busmem invalidation failed.

This case is already handled by the common code, but not the
linux specific implementation.

This change also resets the VMCI datagram handle allocated by
the stream sockets to VMCI_INVALID_HANDLE when it is
destroyed, since the validity of the handle is used to
determine whether we should call destroy on the handle when
the module is unloaded.

Signed-off-by: Marcelo Vanzin <mvanzin@vmware.com>
open-vm-tools/modules/linux/vsock/linux/af_vsock.c

index 650536b5ad45828d58d76bec2a1e3485e68ea124..3ee995464c363cd2a40b1f31f074ef11ba5791b6 100644 (file)
@@ -1177,6 +1177,20 @@ VSockVmciHandleDetach(struct sock *sk) // IN
        * queue.
        */
       if (VSockVmciStreamHasData(vsk) <= 0) {
+         if (sk->sk_state == SS_CONNECTING) {
+            /*
+             * The peer may detach from a queue pair while we are
+             * still in the connecting state, i.e., if the peer VM is
+             * killed after attaching to a queue pair, but before we
+             * complete the handshake. In that case, we treat the
+             * detach event like a reset.
+             */
+
+            sk->sk_state = SS_UNCONNECTED;
+            sk->sk_err = ECONNRESET;
+            sk->sk_error_report(sk);
+            return;
+         }
          sk->sk_state = SS_UNCONNECTED;
       }
       sk->sk_state_change(sk);
@@ -3118,6 +3132,7 @@ error:
 
    if (!VMCI_HANDLE_INVALID(vmciStreamHandle)) {
       VMCIDatagram_DestroyHnd(vmciStreamHandle);
+      vmciStreamHandle = VMCI_INVALID_HANDLE;
    }
    return err;
 }
@@ -3153,6 +3168,7 @@ VSockVmciUnregisterAddressFamily(void)
       if (VMCIDatagram_DestroyHnd(vmciStreamHandle) != VMCI_SUCCESS) {
          Warning("Could not destroy VMCI datagram handle.\n");
       }
+      vmciStreamHandle = VMCI_INVALID_HANDLE;
    }
 
    if (qpResumedSubId != VMCI_INVALID_ID) {