From dd22c1bf18ab6efd53cb8f865cd4c7d69c12e402 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 1332aef41b1239ba5885ed8a6e26225131abec1b 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 5c0fd63265893290d7ddd8729150c7d9f2b06dbf 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 057fb53a6ab882a78bded4bca23c87d26ced8e13 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 54e31f7495600ffc8d7df1bd7543b009855b6cff 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) } }()