From a8e3b557757286dcd7f81cab93c7b1da691ca84e Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Wed, 6 Apr 2016 12:24:34 +0100 Subject: [PATCH 1/5] vsudd: include fd in vsock File object name (used in logs) Signed-off-by: Ian Campbell --- alpine/packages/vsudd/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alpine/packages/vsudd/main.go b/alpine/packages/vsudd/main.go index b974a81ba..3e5733c0a 100644 --- a/alpine/packages/vsudd/main.go +++ b/alpine/packages/vsudd/main.go @@ -99,7 +99,7 @@ func main() { } func handleOne(connid int, fd int) { - vsock := os.NewFile(uintptr(fd), "vsock connection") + vsock := os.NewFile(uintptr(fd), fmt.Sprintf("vsock:%d", fd)) log.Println(connid, "Accepted connection on fd", fd) defer syscall.Close(fd) From d82a23a39982d2ac233904501dab879b5c1dd462 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 7 Apr 2016 17:38:11 +0100 Subject: [PATCH 2/5] vsudd: Log the peer's port number Signed-off-by: Ian Campbell --- alpine/packages/vsudd/main.go | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/alpine/packages/vsudd/main.go b/alpine/packages/vsudd/main.go index 3e5733c0a..35fd1380c 100644 --- a/alpine/packages/vsudd/main.go +++ b/alpine/packages/vsudd/main.go @@ -22,8 +22,8 @@ int bind_sockaddr_vm(int fd, const struct sockaddr_vm *sa_vm) { int connect_sockaddr_vm(int fd, const struct sockaddr_vm *sa_vm) { return connect(fd, (const struct sockaddr*)sa_vm, sizeof(*sa_vm)); } -int accept_vm(int fd) { - return accept(fd, 0, 0); +int accept_vm(int fd, struct sockaddr_vm *sa_vm, socklen_t *sa_vm_len) { + return accept4(fd, (struct sockaddr *)sa_vm, sa_vm_len, 0); } */ import "C" @@ -89,18 +89,22 @@ func main() { connid := 0 for { + var accept_sa C.struct_sockaddr_vm + var accept_sa_len C.socklen_t + connid++ - fd, err := C.accept_vm(C.int(accept_fd)) + accept_sa_len = C.sizeof_struct_sockaddr_vm + fd, err := C.accept_vm(C.int(accept_fd), &accept_sa, &accept_sa_len) if err != nil { log.Fatalln("Error accepting connection", err) } - go handleOne(connid, int(fd)) + go handleOne(connid, int(fd), uint(accept_sa.svm_cid), uint(accept_sa.svm_port)) } } -func handleOne(connid int, fd int) { +func handleOne(connid int, fd int, cid, port uint) { vsock := os.NewFile(uintptr(fd), fmt.Sprintf("vsock:%d", fd)) - log.Println(connid, "Accepted connection on fd", fd) + log.Printf("%d Accepted connection on fd %d from %08x.%08x", connid, fd, cid, port) defer syscall.Close(fd) From 777ddec6b8c8414e0e72d59ed381d6c0cc01d6d1 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 7 Apr 2016 17:38:56 +0100 Subject: [PATCH 3/5] vsudd: Bind to VSOCK_CID_ANY rather than "3" This is equivalent to binding to 0.0.0.0 rather than a specific IP address. Signed-off-by: Ian Campbell --- alpine/packages/vsudd/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alpine/packages/vsudd/main.go b/alpine/packages/vsudd/main.go index 35fd1380c..5b0118895 100644 --- a/alpine/packages/vsudd/main.go +++ b/alpine/packages/vsudd/main.go @@ -73,7 +73,7 @@ func main() { sa := C.struct_sockaddr_vm{} sa.svm_family = AF_VSOCK sa.svm_port = C.uint(port) - sa.svm_cid = 3 + sa.svm_cid = VSOCK_CID_ANY if ret := C.bind_sockaddr_vm(C.int(accept_fd), &sa); ret != 0 { log.Fatal(fmt.Sprintf("failed bind vsock connection to %08x.%08x, returned %d", sa.svm_cid, sa.svm_port, ret)) From 113ca08caedcfba1be151349d75a33d1a64a7fe3 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 7 Apr 2016 17:40:14 +0100 Subject: [PATCH 4/5] vsudd: Log as we Close both sockets (via defer) Signed-off-by: Ian Campbell --- alpine/packages/vsudd/main.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/alpine/packages/vsudd/main.go b/alpine/packages/vsudd/main.go index 5b0118895..75b22a45a 100644 --- a/alpine/packages/vsudd/main.go +++ b/alpine/packages/vsudd/main.go @@ -106,7 +106,12 @@ func handleOne(connid int, fd int, cid, port uint) { vsock := os.NewFile(uintptr(fd), fmt.Sprintf("vsock:%d", fd)) log.Printf("%d Accepted connection on fd %d from %08x.%08x", connid, fd, cid, port) - defer syscall.Close(fd) + defer func() { + log.Println(connid, "Closing vsock", fd) + if err := syscall.Close(fd) ; err != nil { + log.Println(connid, "Error closing", fd ":", err) + } + }() var docker *net.UnixConn var err error @@ -119,13 +124,18 @@ func handleOne(connid int, fd int, cid, port uint) { } time.Sleep(50 * time.Millisecond) } - defer docker.Close() - if err != nil { // If the forwarding program has broken then close and continue log.Println(connid, "Failed to connect to Unix domain socket after 10s", sock, err) return } + defer func() { + log.Println(connid, "Closing docker", docker) + if err := docker.Close() ; err != nil { + log.Println(connid, "Error closing", docker, ":", err) + } + }() + log.Println(connid, "Connected to docker", docker) w := make(chan int64) go func() { From dad42c8dc40d1b90fff6a47d00d8237f57d161b5 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 7 Apr 2016 17:40:41 +0100 Subject: [PATCH 5/5] vsudd: Close via the File vsock not the raw fd. Otherwise the underlying gets closed twice, once by the File's finalizer (which occurs at whichever point vsock appears no longer used) and another time by the syscall.Close(), which leads to EBADF. The various syscall.shutdown can also suffer from this if the File happens to get finalized first, but the reference in the defer'd function now keeps the File alive until we are truly done with the socket. This seems to resolve the random stalls and failures seen in "make test". Signed-off-by: Ian Campbell --- alpine/packages/vsudd/main.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/alpine/packages/vsudd/main.go b/alpine/packages/vsudd/main.go index 75b22a45a..1dc535fa1 100644 --- a/alpine/packages/vsudd/main.go +++ b/alpine/packages/vsudd/main.go @@ -107,9 +107,9 @@ func handleOne(connid int, fd int, cid, port uint) { log.Printf("%d Accepted connection on fd %d from %08x.%08x", connid, fd, cid, port) defer func() { - log.Println(connid, "Closing vsock", fd) - if err := syscall.Close(fd) ; err != nil { - log.Println(connid, "Error closing", fd ":", err) + log.Println(connid, "Closing vsock", vsock) + if err := vsock.Close() ; err != nil { + log.Println(connid, "Error closing", vsock, ":", err) } }()