package transport

import (
	"fmt"
	"time"

	"github.com/linuxkit/virtsock/pkg/vsock"
	"github.com/sirupsen/logrus"
)

const (
	vmaddrCidHost = 2
	vmaddrCidAny  = 0xffffffff
)

// VsockTransport is an implementation of Transport which uses vsock
// sockets.
type VsockTransport struct{}

var _ Transport = &VsockTransport{}

// Dial accepts a vsock socket port number as configuration, and
// returns an unconnected VsockConnection struct.
func (t *VsockTransport) Dial(port uint32) (Connection, error) {
	// HACK: Remove loop when vsock bugs are fixed!
	// Retry 10 times because vsock.Dial can return connection time out
	// due to some underlying kernel bug.
	for i := 0; i < 10; i++ {
		logrus.Infof("vsock Dial port (%d)", port)
		conn, err := vsock.Dial(vmaddrCidHost, port)
		if err == nil {
			logrus.Infof("vsock Connect port (%d)", port)
			return conn, nil
		}

		// The virtsock wrapper eats up the syscall error, so we can't distinguish ETIMEDOUT from
		// other errors, so just sleep and try again
		time.Sleep(100 * time.Millisecond)
	}
	return nil, fmt.Errorf("failed connecting the VsockConnection: can't connect after 10 attempts")
}

package transport

import (
	"github.com/sirupsen/logrus"
	"github.com/linuxkit/virtsock/pkg/vsock"
	"github.com/pkg/errors"
)

const (
	vmaddrCidHost = 2
	vmaddrCidAny  = 0xffffffff
)

// VsockTransport is an implementation of Transport which uses vsock
// sockets.
type VsockTransport struct{}

var _ Transport = &VsockTransport{}

// Dial accepts a vsock socket port number as configuration, and
// returns an unconnected VsockConnection struct.
func (t *VsockTransport) Dial(port uint32) (Connection, error) {
	logrus.Infof("vsock Dial port (%d)", port)

	conn, err := vsock.Dial(vmaddrCidHost, port)
	if err != nil {
		return nil, errors.Wrap(err, "failed connecting the VsockConnection")
	}
	logrus.Infof("vsock Connect port (%d)", port)

	return conn, nil
}

--- 
+++ 
@@ -1,9 +1,11 @@
 package transport
 
 import (
+	"fmt"
+	"time"
+
+	"github.com/linuxkit/virtsock/pkg/vsock"
 	"github.com/sirupsen/logrus"
-	"github.com/linuxkit/virtsock/pkg/vsock"
-	"github.com/pkg/errors"
 )
 
 const (
@@ -20,13 +22,20 @@
 // Dial accepts a vsock socket port number as configuration, and
 // returns an unconnected VsockConnection struct.
 func (t *VsockTransport) Dial(port uint32) (Connection, error) {
-	logrus.Infof("vsock Dial port (%d)", port)
+	// HACK: Remove loop when vsock bugs are fixed!
+	// Retry 10 times because vsock.Dial can return connection time out
+	// due to some underlying kernel bug.
+	for i := 0; i < 10; i++ {
+		logrus.Infof("vsock Dial port (%d)", port)
+		conn, err := vsock.Dial(vmaddrCidHost, port)
+		if err == nil {
+			logrus.Infof("vsock Connect port (%d)", port)
+			return conn, nil
+		}
 
-	conn, err := vsock.Dial(vmaddrCidHost, port)
-	if err != nil {
-		return nil, errors.Wrap(err, "failed connecting the VsockConnection")
+		// The virtsock wrapper eats up the syscall error, so we can't distinguish ETIMEDOUT from
+		// other errors, so just sleep and try again
+		time.Sleep(100 * time.Millisecond)
 	}
-	logrus.Infof("vsock Connect port (%d)", port)
-
-	return conn, nil
+	return nil, fmt.Errorf("failed connecting the VsockConnection: can't connect after 10 attempts")
 }
Add a retry when connecting stdin/stdout/stderr
