Skip to content

Commit

Permalink
Add Go standard library patch to use VFORK for exec.Command().
Browse files Browse the repository at this point in the history
For more details: golang/go#5838.
  • Loading branch information
fasaxc committed Feb 27, 2017
1 parent bbb276b commit 531e527
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 0 deletions.
8 changes: 8 additions & 0 deletions Dockerfile
Expand Up @@ -18,6 +18,14 @@ RUN apk add glibc-2.23-r3.apk
# Disable cgo so that binaries we build will be fully static.
ENV CGO_ENABLED=0

# Apply patches to Go runtime and recompile.
# See https://github.com/golang/go/issues/5838 for defails of vfork patch.
COPY patches/use-clone-vfork-b7edfba429d982e3e065d637334bcc63ad49f8f9.patch \
/tmp/use-clone-vfork-b7edfba429d982e3e065d637334bcc63ad49f8f9.patch
RUN cd /usr/local/go && \
patch -p 1 < /tmp/use-clone-vfork-b7edfba429d982e3e065d637334bcc63ad49f8f9.patch
RUN go install -v -a syscall

# Recompile the standard library with cgo disabled. This prevents the standard library from being
# marked stale, causing full rebuilds every time.
RUN go install -v std
Expand Down
@@ -0,0 +1,76 @@
From b7edfba429d982e3e065d637334bcc63ad49f8f9 Mon Sep 17 00:00:00 2001
From: Richard Musiol <mail@richard-musiol.de>
Date: Fri, 29 Apr 2016 19:22:36 +0200
Subject: [PATCH] syscall: use CLONE_VFORK (WIP)

---
src/syscall/asm_linux_amd64.s | 25 +++++++++++++++++++++++++
src/syscall/exec_linux.go | 7 +++++--
src/syscall/syscall_linux_amd64.go | 2 ++
3 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/src/syscall/asm_linux_amd64.s b/src/syscall/asm_linux_amd64.s
index 6634875..a5255c1 100644
--- a/src/syscall/asm_linux_amd64.s
+++ b/src/syscall/asm_linux_amd64.s
@@ -111,6 +111,31 @@ ok2:
MOVQ $0, err+72(FP)
RET

+// func rawSyscall6PreserveRet(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2, err uintptr)
+TEXT ·rawSyscall6PreserveRet(SB),NOSPLIT,$0-80
+ MOVQ a1+8(FP), DI
+ MOVQ a2+16(FP), SI
+ MOVQ a3+24(FP), DX
+ MOVQ a4+32(FP), R10
+ MOVQ a5+40(FP), R8
+ MOVQ a6+48(FP), R9
+ MOVQ trap+0(FP), AX // syscall entry
+ POPQ R12 // preserve return address
+ SYSCALL
+ PUSHQ R12
+ CMPQ AX, $0xfffffffffffff001
+ JLS ok2
+ MOVQ $-1, r1+56(FP)
+ MOVQ $0, r2+64(FP)
+ NEGQ AX
+ MOVQ AX, err+72(FP)
+ RET
+ok2:
+ MOVQ AX, r1+56(FP)
+ MOVQ DX, r2+64(FP)
+ MOVQ $0, err+72(FP)
+ RET
+
// func gettimeofday(tv *Timeval) (err uintptr)
TEXT ·gettimeofday(SB),NOSPLIT,$0-16
MOVQ tv+0(FP), DI
diff --git a/src/syscall/exec_linux.go b/src/syscall/exec_linux.go
index e49bad7..61a72ad 100644
--- a/src/syscall/exec_linux.go
+++ b/src/syscall/exec_linux.go
@@ -94,9 +94,12 @@ func forkAndExecInChild(argv0 *byte, argv, envv []*byte, chroot, dir *byte, attr
// About to call fork.
// No more allocation or calls of non-assembly functions.
runtime_BeforeFork()
- if runtime.GOARCH == "s390x" {
+ switch {
+ case runtime.GOARCH == "amd64" && sys.Cloneflags&CLONE_NEWUSER == 0:
+ r1, _, err1 = rawSyscall6PreserveRet(SYS_CLONE, uintptr(SIGCHLD|CLONE_VFORK|CLONE_VM)|sys.Cloneflags, 0, 0, 0, 0, 0)
+ case runtime.GOARCH == "s390x":
r1, _, err1 = RawSyscall6(SYS_CLONE, 0, uintptr(SIGCHLD)|sys.Cloneflags, 0, 0, 0, 0)
- } else {
+ default:
r1, _, err1 = RawSyscall6(SYS_CLONE, uintptr(SIGCHLD)|sys.Cloneflags, 0, 0, 0, 0, 0)
}
if err1 != 0 {
diff --git a/src/syscall/syscall_linux_amd64.go b/src/syscall/syscall_linux_amd64.go
index d1bda29..cf3e5d1 100644
--- a/src/syscall/syscall_linux_amd64.go
+++ b/src/syscall/syscall_linux_amd64.go
@@ -144,3 +144,5 @@ func (msghdr *Msghdr) SetControllen(length int) {
func (cmsg *Cmsghdr) SetLen(length int) {
cmsg.Len = uint64(length)
}
+
+func rawSyscall6PreserveRet(trap, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err Errno)

0 comments on commit 531e527

Please sign in to comment.