Преглед на файлове

Merge pull request #37778 from Microsoft/jjh/vendorhcsshim

Revendor Microsoft/hcsshim @v0.7.3
Sebastiaan van Stijn преди 6 години
родител
ревизия
738994f77d

+ 1 - 1
vendor.conf

@@ -1,6 +1,6 @@
 # the following lines are in sorted order, FYI
 github.com/Azure/go-ansiterm d6e3b3328b783f23731bc4d058875b0371ff8109
-github.com/Microsoft/hcsshim 44c060121b68e8bdc40b411beba551f3b4ee9e55
+github.com/Microsoft/hcsshim v0.7.3
 github.com/Microsoft/go-winio v0.4.11
 github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
 github.com/go-check/check 4ed411733c5785b40214c70bce814c3a3a689609 https://github.com/cpuguy83/check.git

+ 47 - 0
vendor/github.com/Microsoft/hcsshim/internal/guid/guid.go

@@ -2,10 +2,16 @@ package guid
 
 import (
 	"crypto/rand"
+	"encoding/json"
 	"fmt"
 	"io"
+	"strconv"
+	"strings"
 )
 
+var _ = (json.Marshaler)(&GUID{})
+var _ = (json.Unmarshaler)(&GUID{})
+
 type GUID [16]byte
 
 func New() GUID {
@@ -20,3 +26,44 @@ func New() GUID {
 func (g GUID) String() string {
 	return fmt.Sprintf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x-%02x", g[3], g[2], g[1], g[0], g[5], g[4], g[7], g[6], g[8:10], g[10:])
 }
+
+func FromString(s string) GUID {
+	if len(s) != 36 {
+		panic(fmt.Sprintf("invalid GUID length: %d", len(s)))
+	}
+	if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' {
+		panic("invalid GUID format")
+	}
+	indexOrder := [16]int{
+		0, 2, 4, 6,
+		9, 11,
+		14, 16,
+		19, 21,
+		24, 26, 28, 30, 32, 34,
+	}
+	byteOrder := [16]int{
+		3, 2, 1, 0,
+		5, 4,
+		7, 6,
+		8, 9,
+		10, 11, 12, 13, 14, 15,
+	}
+	var g GUID
+	for i, x := range indexOrder {
+		b, err := strconv.ParseInt(s[x:x+2], 16, 16)
+		if err != nil {
+			panic(err)
+		}
+		g[byteOrder[i]] = byte(b)
+	}
+	return g
+}
+
+func (g GUID) MarshalJSON() ([]byte, error) {
+	return json.Marshal(g.String())
+}
+
+func (g *GUID) UnmarshalJSON(data []byte) error {
+	*g = FromString(strings.Trim(string(data), "\""))
+	return nil
+}

+ 7 - 0
vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go

@@ -2,6 +2,7 @@ package hcs
 
 import (
 	"encoding/json"
+	"fmt"
 	"io"
 	"sync"
 	"syscall"
@@ -83,7 +84,10 @@ func (process *Process) Kill() error {
 	}
 
 	var resultp *uint16
+	completed := false
+	go syscallWatcher(fmt.Sprintf("TerminateProcess %s: %d", process.SystemID(), process.Pid()), &completed)
 	err := hcsTerminateProcess(process.handle, &resultp)
+	completed = true
 	events := processHcsResult(resultp)
 	if err != nil {
 		return makeProcessError(process, operation, err, events)
@@ -177,7 +181,10 @@ func (process *Process) Properties() (*ProcessStatus, error) {
 		resultp     *uint16
 		propertiesp *uint16
 	)
+	completed := false
+	go syscallWatcher(fmt.Sprintf("GetProcessProperties %s: %d", process.SystemID(), process.Pid()), &completed)
 	err := hcsGetProcessProperties(process.handle, &propertiesp, &resultp)
+	completed = true
 	events := processHcsResult(resultp)
 	if err != nil {
 		return nil, makeProcessError(process, operation, err, events)

+ 43 - 5
vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go

@@ -2,6 +2,7 @@ package hcs
 
 import (
 	"encoding/json"
+	"fmt"
 	"os"
 	"strconv"
 	"sync"
@@ -63,7 +64,10 @@ func CreateComputeSystem(id string, hcsDocumentInterface interface{}) (*System,
 		resultp  *uint16
 		identity syscall.Handle
 	)
+	completed := false
+	go syscallWatcher(fmt.Sprintf("CreateCompleteSystem %s: %s", id, hcsDocument), &completed)
 	createError := hcsCreateComputeSystem(id, hcsDocument, identity, &computeSystem.handle, &resultp)
+	completed = true
 
 	if createError == nil || IsPending(createError) {
 		if err := computeSystem.registerCallback(); err != nil {
@@ -74,7 +78,7 @@ func CreateComputeSystem(id string, hcsDocumentInterface interface{}) (*System,
 		}
 	}
 
-	events, err := processAsyncHcsResult(createError, resultp, computeSystem.callbackNumber, hcsNotificationSystemCreateCompleted, &timeout.Duration)
+	events, err := processAsyncHcsResult(createError, resultp, computeSystem.callbackNumber, hcsNotificationSystemCreateCompleted, &timeout.SystemCreate)
 	if err != nil {
 		if err == ErrTimeout {
 			// Terminate the compute system if it still exists. We're okay to
@@ -135,7 +139,10 @@ func GetComputeSystems(q schema1.ComputeSystemQuery) ([]schema1.ContainerPropert
 		resultp         *uint16
 		computeSystemsp *uint16
 	)
+	completed := false
+	go syscallWatcher(fmt.Sprintf("GetComputeSystems %s:", query), &completed)
 	err = hcsEnumerateComputeSystems(query, &computeSystemsp, &resultp)
+	completed = true
 	events := processHcsResult(resultp)
 	if err != nil {
 		return nil, &HcsError{Op: operation, Err: err, Events: events}
@@ -192,8 +199,11 @@ func (computeSystem *System) Start() error {
 	}
 
 	var resultp *uint16
+	completed := false
+	go syscallWatcher(fmt.Sprintf("StartComputeSystem %s:", computeSystem.ID()), &completed)
 	err := hcsStartComputeSystem(computeSystem.handle, "", &resultp)
-	events, err := processAsyncHcsResult(err, resultp, computeSystem.callbackNumber, hcsNotificationSystemStartCompleted, &timeout.Duration)
+	completed = true
+	events, err := processAsyncHcsResult(err, resultp, computeSystem.callbackNumber, hcsNotificationSystemStartCompleted, &timeout.SystemStart)
 	if err != nil {
 		return makeSystemError(computeSystem, "Start", "", err, events)
 	}
@@ -219,7 +229,10 @@ func (computeSystem *System) Shutdown() error {
 	}
 
 	var resultp *uint16
+	completed := false
+	go syscallWatcher(fmt.Sprintf("ShutdownComputeSystem %s:", computeSystem.ID()), &completed)
 	err := hcsShutdownComputeSystem(computeSystem.handle, "", &resultp)
+	completed = true
 	events := processHcsResult(resultp)
 	if err != nil {
 		return makeSystemError(computeSystem, "Shutdown", "", err, events)
@@ -242,7 +255,10 @@ func (computeSystem *System) Terminate() error {
 	}
 
 	var resultp *uint16
+	completed := false
+	go syscallWatcher(fmt.Sprintf("TerminateComputeSystem %s:", computeSystem.ID()), &completed)
 	err := hcsTerminateComputeSystem(computeSystem.handle, "", &resultp)
+	completed = true
 	events := processHcsResult(resultp)
 	if err != nil {
 		return makeSystemError(computeSystem, "Terminate", "", err, events)
@@ -291,7 +307,10 @@ func (computeSystem *System) Properties(types ...schema1.PropertyType) (*schema1
 	}
 
 	var resultp, propertiesp *uint16
+	completed := false
+	go syscallWatcher(fmt.Sprintf("GetComputeSystemProperties %s:", computeSystem.ID()), &completed)
 	err = hcsGetComputeSystemProperties(computeSystem.handle, string(queryj), &propertiesp, &resultp)
+	completed = true
 	events := processHcsResult(resultp)
 	if err != nil {
 		return nil, makeSystemError(computeSystem, "Properties", "", err, events)
@@ -320,8 +339,11 @@ func (computeSystem *System) Pause() error {
 	}
 
 	var resultp *uint16
+	completed := false
+	go syscallWatcher(fmt.Sprintf("PauseComputeSystem %s:", computeSystem.ID()), &completed)
 	err := hcsPauseComputeSystem(computeSystem.handle, "", &resultp)
-	events, err := processAsyncHcsResult(err, resultp, computeSystem.callbackNumber, hcsNotificationSystemPauseCompleted, &timeout.Duration)
+	completed = true
+	events, err := processAsyncHcsResult(err, resultp, computeSystem.callbackNumber, hcsNotificationSystemPauseCompleted, &timeout.SystemPause)
 	if err != nil {
 		return makeSystemError(computeSystem, "Pause", "", err, events)
 	}
@@ -342,8 +364,11 @@ func (computeSystem *System) Resume() error {
 	}
 
 	var resultp *uint16
+	completed := false
+	go syscallWatcher(fmt.Sprintf("ResumeComputeSystem %s:", computeSystem.ID()), &completed)
 	err := hcsResumeComputeSystem(computeSystem.handle, "", &resultp)
-	events, err := processAsyncHcsResult(err, resultp, computeSystem.callbackNumber, hcsNotificationSystemResumeCompleted, &timeout.Duration)
+	completed = true
+	events, err := processAsyncHcsResult(err, resultp, computeSystem.callbackNumber, hcsNotificationSystemResumeCompleted, &timeout.SystemResume)
 	if err != nil {
 		return makeSystemError(computeSystem, "Resume", "", err, events)
 	}
@@ -375,7 +400,10 @@ func (computeSystem *System) CreateProcess(c interface{}) (*Process, error) {
 	configuration := string(configurationb)
 	logrus.Debugf(title+" config=%s", configuration)
 
+	completed := false
+	go syscallWatcher(fmt.Sprintf("CreateProcess %s: %s", computeSystem.ID(), configuration), &completed)
 	err = hcsCreateProcess(computeSystem.handle, configuration, &processInfo, &processHandle, &resultp)
+	completed = true
 	events := processHcsResult(resultp)
 	if err != nil {
 		return nil, makeSystemError(computeSystem, "CreateProcess", configuration, err, events)
@@ -415,7 +443,10 @@ func (computeSystem *System) OpenProcess(pid int) (*Process, error) {
 		return nil, makeSystemError(computeSystem, "OpenProcess", "", ErrAlreadyClosed, nil)
 	}
 
+	completed := false
+	go syscallWatcher(fmt.Sprintf("OpenProcess %s: %d", computeSystem.ID(), pid), &completed)
 	err := hcsOpenProcess(computeSystem.handle, uint32(pid), &processHandle, &resultp)
+	completed = true
 	events := processHcsResult(resultp)
 	if err != nil {
 		return nil, makeSystemError(computeSystem, "OpenProcess", "", err, events)
@@ -451,7 +482,11 @@ func (computeSystem *System) Close() error {
 		return makeSystemError(computeSystem, "Close", "", err, nil)
 	}
 
-	if err := hcsCloseComputeSystem(computeSystem.handle); err != nil {
+	completed := false
+	go syscallWatcher(fmt.Sprintf("CloseComputeSystem %s:", computeSystem.ID()), &completed)
+	err := hcsCloseComputeSystem(computeSystem.handle)
+	completed = true
+	if err != nil {
 		return makeSystemError(computeSystem, "Close", "", err, nil)
 	}
 
@@ -537,7 +572,10 @@ func (computeSystem *System) Modify(config interface{}) error {
 	logrus.Debugf(title + " " + requestString)
 
 	var resultp *uint16
+	completed := false
+	go syscallWatcher(fmt.Sprintf("ModifyComputeSystem %s: %s", computeSystem.ID(), requestString), &completed)
 	err = hcsModifyComputeSystem(computeSystem.handle, requestString, &resultp)
+	completed = true
 	events := processHcsResult(resultp)
 	if err != nil {
 		return makeSystemError(computeSystem, "Modify", requestString, err, events)

+ 30 - 0
vendor/github.com/Microsoft/hcsshim/internal/hcs/watcher.go

@@ -0,0 +1,30 @@
+package hcs
+
+import (
+	"time"
+
+	"github.com/Microsoft/hcsshim/internal/timeout"
+	"github.com/sirupsen/logrus"
+)
+
+// syscallWatcher is used as a very simple goroutine around calls into
+// the platform. In some cases, we have seen HCS APIs not returning due to
+// various bugs, and the goroutine making the syscall ends up not returning,
+// prior to its async callback. By spinning up a syscallWatcher, it allows
+// us to at least log a warning if a syscall doesn't complete in a reasonable
+// amount of time.
+//
+// Usage is:
+//
+// completed := false
+// go syscallWatcher("some description", &completed)
+// <syscall>
+// completed = true
+//
+func syscallWatcher(description string, syscallCompleted *bool) {
+	time.Sleep(timeout.SyscallWatcher)
+	if *syscallCompleted {
+		return
+	}
+	logrus.Warnf("%s: Did not complete within %s. This may indicate a platform issue. If it appears to be making no forward progress, obtain the stacks and see is there is a syscall stuck in the platform API for a significant length of time.", description, timeout.SyscallWatcher)
+}

+ 1 - 1
vendor/github.com/Microsoft/hcsshim/internal/interop/zsyscall_windows.go

@@ -1,4 +1,4 @@
-// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
+// Code generated by 'go generate'; DO NOT EDIT.
 
 package interop
 

+ 1 - 1
vendor/github.com/Microsoft/hcsshim/internal/safefile/zsyscall_windows.go

@@ -1,4 +1,4 @@
-// MACHINE GENERATED BY 'go generate' COMMAND; DO NOT EDIT
+// Code generated by 'go generate'; DO NOT EDIT.
 
 package safefile
 

+ 53 - 9
vendor/github.com/Microsoft/hcsshim/internal/timeout/timeout.go

@@ -6,21 +6,65 @@ import (
 	"time"
 )
 
-// Duration is the default time to wait for various operations.
-// - Waiting for async notifications from HCS
-// - Waiting for processes to launch through
-// - Waiting to copy data to/from a launched processes stdio pipes.
-//
-// This can be overridden through environment variable `HCS_TIMEOUT_SECONDS`
+var (
+	// defaultTimeout is the timeout for most operations that is not overridden.
+	defaultTimeout = 4 * time.Minute
 
-var Duration = 4 * time.Minute
+	// defaultTimeoutTestdRetry is the retry loop timeout for testd to respond
+	// for a disk to come online in LCOW.
+	defaultTimeoutTestdRetry = 5 * time.Second
+)
+
+// External variables for HCSShim consumers to use.
+var (
+	// SystemCreate is the timeout for creating a compute system
+	SystemCreate time.Duration = defaultTimeout
+
+	// SystemStart is the timeout for starting a compute system
+	SystemStart time.Duration = defaultTimeout
+
+	// SystemPause is the timeout for pausing a compute system
+	SystemPause time.Duration = defaultTimeout
+
+	// SystemResume is the timeout for resuming a compute system
+	SystemResume time.Duration = defaultTimeout
+
+	// SyscallWatcher is the timeout before warning of a potential stuck platform syscall.
+	SyscallWatcher time.Duration = defaultTimeout
+
+	// Tar2VHD is the timeout for the tar2vhd operation to complete
+	Tar2VHD time.Duration = defaultTimeout
+
+	// ExternalCommandToStart is the timeout for external commands to start
+	ExternalCommandToStart = defaultTimeout
+
+	// ExternalCommandToComplete is the timeout for external commands to complete.
+	// Generally this means copying data from their stdio pipes.
+	ExternalCommandToComplete = defaultTimeout
+
+	// TestDRetryLoop is the timeout for testd retry loop when onlining a SCSI disk in LCOW
+	TestDRetryLoop = defaultTimeoutTestdRetry
+)
 
 func init() {
-	envTimeout := os.Getenv("HCSSHIM_TIMEOUT_SECONDS")
+	SystemCreate = durationFromEnvironment("HCSSHIM_TIMEOUT_SYSTEMCREATE", SystemCreate)
+	SystemStart = durationFromEnvironment("HCSSHIM_TIMEOUT_SYSTEMSTART", SystemStart)
+	SystemPause = durationFromEnvironment("HCSSHIM_TIMEOUT_SYSTEMPAUSE", SystemPause)
+	SystemResume = durationFromEnvironment("HCSSHIM_TIMEOUT_SYSTEMRESUME", SystemResume)
+	SyscallWatcher = durationFromEnvironment("HCSSHIM_TIMEOUT_SYSCALLWATCHER", SyscallWatcher)
+	Tar2VHD = durationFromEnvironment("HCSSHIM_TIMEOUT_TAR2VHD", Tar2VHD)
+	ExternalCommandToStart = durationFromEnvironment("HCSSHIM_TIMEOUT_EXTERNALCOMMANDSTART", ExternalCommandToStart)
+	ExternalCommandToComplete = durationFromEnvironment("HCSSHIM_TIMEOUT_EXTERNALCOMMANDCOMPLETE", ExternalCommandToComplete)
+	TestDRetryLoop = durationFromEnvironment("HCSSHIM_TIMEOUT_TESTDRETRYLOOP", TestDRetryLoop)
+}
+
+func durationFromEnvironment(env string, defaultValue time.Duration) time.Duration {
+	envTimeout := os.Getenv(env)
 	if len(envTimeout) > 0 {
 		e, err := strconv.Atoi(envTimeout)
 		if err == nil && e > 0 {
-			Duration = time.Second * time.Duration(e)
+			return time.Second * time.Duration(e)
 		}
 	}
+	return defaultValue
 }