From a3c43964cf994cc1315af1590155f63dc588e32c Mon Sep 17 00:00:00 2001 From: John Howard Date: Thu, 22 Oct 2015 14:01:26 -0700 Subject: [PATCH 1/2] Windows [TP4] HCSShim Revendor Signed-off-by: John Howard --- hack/vendor.sh | 2 +- .../microsoft/hcsshim/createprocess.go | 25 +++++++++++++------ .../github.com/microsoft/hcsshim/hcsshim.go | 1 + 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/hack/vendor.sh b/hack/vendor.sh index 44cf833b61..110701f372 100755 --- a/hack/vendor.sh +++ b/hack/vendor.sh @@ -14,7 +14,7 @@ clone git github.com/gorilla/context 14f550f51a clone git github.com/gorilla/mux e444e69cbd clone git github.com/kr/pty 5cf931ef8f clone git github.com/mattn/go-sqlite3 v1.1.0 -clone git github.com/microsoft/hcsshim 325e531f8c49dd78580d5fd197ddb972fa4610e7 +clone git github.com/microsoft/hcsshim de43b42b5ce14dfdcbeedb0628b0032174d89caa clone git github.com/mistifyio/go-zfs v2.1.1 clone git github.com/tchap/go-patricia v2.1.0 clone git github.com/vdemeester/shakers 3c10293ce22b900c27acad7b28656196fcc2f73b diff --git a/vendor/src/github.com/microsoft/hcsshim/createprocess.go b/vendor/src/github.com/microsoft/hcsshim/createprocess.go index d0318a84a1..be28bde4e6 100644 --- a/vendor/src/github.com/microsoft/hcsshim/createprocess.go +++ b/vendor/src/github.com/microsoft/hcsshim/createprocess.go @@ -67,7 +67,12 @@ func (p *pipe) Write(b []byte) (int, error) { // CreateProcessInComputeSystem starts a process in a container. This is invoked, for example, // as a result of docker run, docker exec, or RUN in Dockerfile. If successful, // it returns the PID of the process. -func CreateProcessInComputeSystem(id string, useStdin bool, useStdout bool, useStderr bool, params CreateProcessParams) (processid uint32, stdin io.WriteCloser, stdout io.ReadCloser, stderr io.ReadCloser, err error) { +func CreateProcessInComputeSystem(id string, useStdin bool, useStdout bool, useStderr bool, params CreateProcessParams) (uint32, io.WriteCloser, io.ReadCloser, io.ReadCloser, uint32, error) { + + var ( + stdin io.WriteCloser + stdout, stderr io.ReadCloser + ) title := "HCSShim::CreateProcessInComputeSystem" logrus.Debugf(title+" id=%s", id) @@ -78,7 +83,7 @@ func CreateProcessInComputeSystem(id string, useStdin bool, useStdout bool, useS defer dll.Release() } if err != nil { - return + return 0, nil, nil, nil, 0xFFFFFFFF, err } // Convert id to uint16 pointer for calling the procedure @@ -86,7 +91,7 @@ func CreateProcessInComputeSystem(id string, useStdin bool, useStdout bool, useS if err != nil { err = fmt.Errorf(title+" - Failed conversion of id %s to pointer %s", id, err) logrus.Error(err) - return + return 0, nil, nil, nil, 0xFFFFFFFF, err } // If we are not emulating a console, ignore any console size passed to us @@ -98,13 +103,13 @@ func CreateProcessInComputeSystem(id string, useStdin bool, useStdout bool, useS paramsJson, err := json.Marshal(params) if err != nil { err = fmt.Errorf(title+" - Failed to marshall params %v %s", params, err) - return + return 0, nil, nil, nil, 0xFFFFFFFF, err } // Convert paramsJson to uint16 pointer for calling the procedure paramsJsonp, err := syscall.UTF16PtrFromString(string(paramsJson)) if err != nil { - return + return 0, nil, nil, nil, 0xFFFFFFFF, err } // Get a POINTER to variable to take the pid outparm @@ -138,8 +143,12 @@ func CreateProcessInComputeSystem(id string, useStdin bool, useStdout bool, useS if r1 != 0 { err = fmt.Errorf(title+" - Win32 API call returned error r1=%d err=%s id=%s params=%v", r1, syscall.Errno(r1), id, params) - logrus.Error(err) - return + // Windows TP4: Hyper-V Containers may return this error with more than one + // concurrent exec. Do not log it as an error + if uint32(r1) != Win32InvalidArgument { + logrus.Error(err) + } + return 0, nil, nil, nil, uint32(r1), err } if useStdin { @@ -153,5 +162,5 @@ func CreateProcessInComputeSystem(id string, useStdin bool, useStdout bool, useS } logrus.Debugf(title+" - succeeded id=%s params=%s pid=%d", id, paramsJson, *pid) - return *pid, stdin, stdout, stderr, nil + return *pid, stdin, stdout, stderr, 0, nil } diff --git a/vendor/src/github.com/microsoft/hcsshim/hcsshim.go b/vendor/src/github.com/microsoft/hcsshim/hcsshim.go index f1d3326139..b23890aaa2 100644 --- a/vendor/src/github.com/microsoft/hcsshim/hcsshim.go +++ b/vendor/src/github.com/microsoft/hcsshim/hcsshim.go @@ -55,6 +55,7 @@ const ( Win32SystemShutdownIsInProgress = 0x8007045B // ShutdownComputeSystem: A system shutdown is in progress Win32SpecifiedPathInvalid = 0x800700A1 // ShutdownComputeSystem: The specified path is invalid Win32SystemCannotFindThePathSpecified = 0x80070003 // ShutdownComputeSystem: The system cannot find the path specified + Win32InvalidArgument = 0x80072726 // CreateProcessInComputeSystem: An invalid argument was supplied // Timeout on wait calls TimeoutInfinite = 0xFFFFFFFF From 2e56e78caf4e7cfe026ebb549e4419f1c4434817 Mon Sep 17 00:00:00 2001 From: John Howard Date: Fri, 23 Oct 2015 08:42:24 -0700 Subject: [PATCH 2/2] Windows [TP4] Trap Exec Hyper-V Cont error Signed-off-by: John Howard --- daemon/execdriver/windows/exec.go | 9 ++++++++- daemon/execdriver/windows/run.go | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/daemon/execdriver/windows/exec.go b/daemon/execdriver/windows/exec.go index 241997e2ff..85fda473a8 100644 --- a/daemon/execdriver/windows/exec.go +++ b/daemon/execdriver/windows/exec.go @@ -51,8 +51,15 @@ func (d *Driver) Exec(c *execdriver.Command, processConfig *execdriver.ProcessCo logrus.Debugln("commandLine: ", createProcessParms.CommandLine) // Start the command running in the container. - pid, stdin, stdout, stderr, err := hcsshim.CreateProcessInComputeSystem(c.ID, pipes.Stdin != nil, true, !processConfig.Tty, createProcessParms) + pid, stdin, stdout, stderr, rc, err := hcsshim.CreateProcessInComputeSystem(c.ID, pipes.Stdin != nil, true, !processConfig.Tty, createProcessParms) if err != nil { + // TODO Windows: TP4 Workaround. In Hyper-V containers, there is a limitation + // of one exec per container. This should be fixed post TP4. CreateProcessInComputeSystem + // will return a specific error which we handle here to give a good error message + // back to the user instead of an inactionable "An invalid argument was supplied" + if rc == hcsshim.Win32InvalidArgument { + return -1, fmt.Errorf("The limit of docker execs per Hyper-V container has been exceeded") + } logrus.Errorf("CreateProcessInComputeSystem() failed %s", err) return -1, err } diff --git a/daemon/execdriver/windows/run.go b/daemon/execdriver/windows/run.go index 98d8d1c921..7d03061855 100644 --- a/daemon/execdriver/windows/run.go +++ b/daemon/execdriver/windows/run.go @@ -263,7 +263,7 @@ func (d *Driver) Run(c *execdriver.Command, pipes *execdriver.Pipes, hooks execd logrus.Debugf("CommandLine: %s", createProcessParms.CommandLine) // Start the command running in the container. - pid, stdin, stdout, stderr, err := hcsshim.CreateProcessInComputeSystem(c.ID, pipes.Stdin != nil, true, !c.ProcessConfig.Tty, createProcessParms) + pid, stdin, stdout, stderr, _, err := hcsshim.CreateProcessInComputeSystem(c.ID, pipes.Stdin != nil, true, !c.ProcessConfig.Tty, createProcessParms) if err != nil { logrus.Errorf("CreateProcessInComputeSystem() failed %s", err) return execdriver.ExitStatus{ExitCode: -1}, err