From: VMware, Inc <> Date: Mon, 20 Dec 2010 22:13:22 +0000 (-0800) Subject: Make VSOCK reset connection during connect on QP detach X-Git-Tag: 2010.12.19-339835~20 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e15ecaec78f2f1c1ad68fa23dce9959aac4d0204;p=thirdparty%2Fopen-vm-tools.git Make VSOCK reset connection during connect on QP detach 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 --- diff --git a/open-vm-tools/modules/linux/vsock/linux/af_vsock.c b/open-vm-tools/modules/linux/vsock/linux/af_vsock.c index 650536b5a..3ee995464 100644 --- a/open-vm-tools/modules/linux/vsock/linux/af_vsock.c +++ b/open-vm-tools/modules/linux/vsock/linux/af_vsock.c @@ -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) {