Bladeren bron

Merge pull request #23444 from Microsoft/RevendorHcsshim

Update vendored hcsshim to v0.3.4
Sebastiaan van Stijn 9 jaren geleden
bovenliggende
commit
bf0e2cb1b6

+ 1 - 1
hack/vendor.sh

@@ -43,7 +43,7 @@ esac
 
 # the following lines are in sorted order, FYI
 clone git github.com/Azure/go-ansiterm 388960b655244e76e24c75f48631564eaefade62
-clone git github.com/Microsoft/hcsshim v0.3.2
+clone git github.com/Microsoft/hcsshim v0.3.4
 clone git github.com/Microsoft/go-winio v0.3.4
 clone git github.com/Sirupsen/logrus v0.10.0 # logrus is a common dependency among multiple deps
 clone git github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a

+ 15 - 11
vendor/src/github.com/Microsoft/hcsshim/callback.go

@@ -1,7 +1,6 @@
 package hcsshim
 
 import (
-	"errors"
 	"sync"
 	"syscall"
 )
@@ -26,14 +25,6 @@ var (
 	// Common notifications
 	hcsNotificationInvalid           hcsNotification = 0x00000000
 	hcsNotificationServiceDisconnect hcsNotification = 0x01000000
-
-	// ErrUnexpectedContainerExit is the error returned when a container exits while waiting for
-	// a different expected notification
-	ErrUnexpectedContainerExit = errors.New("unexpected container exit")
-
-	// ErrUnexpectedProcessAbort is the error returned when communication with the compute service
-	// is lost while waiting for a notification
-	ErrUnexpectedProcessAbort = errors.New("lost communication with compute service")
 )
 
 type hcsNotification uint32
@@ -58,6 +49,15 @@ func newChannels() notificationChannels {
 	channels[hcsNotificationServiceDisconnect] = make(notificationChannel, 1)
 	return channels
 }
+func closeChannels(channels notificationChannels) {
+	close(channels[hcsNotificationSystemExited])
+	close(channels[hcsNotificationSystemCreateCompleted])
+	close(channels[hcsNotificationSystemStartCompleted])
+	close(channels[hcsNotificationSystemPauseCompleted])
+	close(channels[hcsNotificationSystemResumeCompleted])
+	close(channels[hcsNotificationProcessExited])
+	close(channels[hcsNotificationServiceDisconnect])
+}
 
 func notificationWatcher(notificationType hcsNotification, callbackNumber uintptr, notificationStatus uintptr, notificationData *uint16) uintptr {
 	var result error
@@ -66,10 +66,14 @@ func notificationWatcher(notificationType hcsNotification, callbackNumber uintpt
 	}
 
 	callbackMapLock.RLock()
-	channels := callbackMap[callbackNumber].channels
+	context := callbackMap[callbackNumber]
 	callbackMapLock.RUnlock()
 
-	channels[notificationType] <- result
+	if context == nil {
+		return 0
+	}
+
+	context.channels[notificationType] <- result
 
 	return 0
 }

+ 61 - 90
vendor/src/github.com/Microsoft/hcsshim/container.go

@@ -13,11 +13,11 @@ import (
 
 var (
 	defaultTimeout = time.Minute * 4
-
-	// ErrTimeout is an error encountered when waiting on a notification times out
-	ErrTimeout = errors.New("hcsshim: timeout waiting for notification")
 )
 
+const pendingUpdatesQuery = `{ "PropertyTypes" : ["PendingUpdates"]}`
+
+// ContainerError is an error encountered in HCS
 type ContainerError struct {
 	Container *container
 	Operation string
@@ -71,9 +71,7 @@ func CreateContainer(id string, c *ContainerConfig) (Container, error) {
 
 		if createError == nil || createError == ErrVmcomputeOperationPending {
 			if err := container.registerCallback(); err != nil {
-				err := &ContainerError{Container: container, Operation: operation, Err: err}
-				logrus.Error(err)
-				return nil, err
+				return nil, makeContainerError(container, operation, "", err)
 			}
 		}
 	} else {
@@ -82,12 +80,7 @@ func CreateContainer(id string, c *ContainerConfig) (Container, error) {
 
 	err = processAsyncHcsResult(createError, resultp, container.callbackNumber, hcsNotificationSystemCreateCompleted, &defaultTimeout)
 	if err != nil {
-		if err == ErrTimeout || err == ErrUnexpectedProcessAbort || err == ErrUnexpectedContainerExit {
-			return nil, err
-		}
-		err := &ContainerError{Container: container, Operation: operation, ExtraInfo: configuration, Err: err}
-		logrus.Error(err)
-		return nil, err
+		return nil, makeContainerError(container, operation, configuration, err)
 	}
 
 	logrus.Debugf(title+" succeeded id=%s handle=%d", id, container.handle)
@@ -112,9 +105,7 @@ func OpenContainer(id string) (Container, error) {
 	err := hcsOpenComputeSystem(id, &handle, &resultp)
 	err = processHcsResult(err, resultp)
 	if err != nil {
-		err = &ContainerError{Container: container, Operation: operation, Err: err}
-		logrus.Error(err)
-		return nil, err
+		return nil, makeContainerError(container, operation, "", err)
 	}
 
 	container.handle = handle
@@ -134,12 +125,7 @@ func (container *container) Start() error {
 	err := hcsStartComputeSystemTP5(container.handle, nil, &resultp)
 	err = processAsyncHcsResult(err, resultp, container.callbackNumber, hcsNotificationSystemStartCompleted, &defaultTimeout)
 	if err != nil {
-		if err == ErrTimeout || err == ErrUnexpectedProcessAbort || err == ErrUnexpectedContainerExit {
-			return err
-		}
-		err := &ContainerError{Container: container, Operation: operation, Err: err}
-		logrus.Error(err)
-		return err
+		return makeContainerError(container, operation, "", err)
 	}
 
 	logrus.Debugf(title+" succeeded id=%s", container.id)
@@ -160,9 +146,7 @@ func (container *container) Shutdown() error {
 		if err == ErrVmcomputeOperationPending {
 			return ErrVmcomputeOperationPending
 		}
-		err = &ContainerError{Container: container, Operation: operation, Err: err}
-		logrus.Error(err)
-		return err
+		return makeContainerError(container, operation, "", err)
 	}
 
 	logrus.Debugf(title+" succeeded id=%s", container.id)
@@ -183,9 +167,7 @@ func (container *container) Terminate() error {
 		if err == ErrVmcomputeOperationPending {
 			return ErrVmcomputeOperationPending
 		}
-		err = &ContainerError{Container: container, Operation: operation, Err: err}
-		logrus.Error(err)
-		return err
+		return makeContainerError(container, operation, "", err)
 	}
 
 	logrus.Debugf(title+" succeeded id=%s", container.id)
@@ -201,19 +183,12 @@ func (container *container) Wait() error {
 	if hcsCallbacksSupported {
 		err := waitForNotification(container.callbackNumber, hcsNotificationSystemExited, nil)
 		if err != nil {
-			if err == ErrUnexpectedProcessAbort || err == ErrUnexpectedContainerExit {
-				return err
-			}
-			err := &ContainerError{Container: container, Operation: operation, Err: err}
-			logrus.Error(err)
-			return err
+			return makeContainerError(container, operation, "", err)
 		}
 	} else {
 		_, err := container.waitTimeoutInternal(syscall.INFINITE)
 		if err != nil {
-			err := &ContainerError{Container: container, Operation: operation, Err: err}
-			logrus.Error(err)
-			return err
+			return makeContainerError(container, operation, "", err)
 		}
 	}
 
@@ -235,21 +210,14 @@ func (container *container) WaitTimeout(timeout time.Duration) error {
 	if hcsCallbacksSupported {
 		err := waitForNotification(container.callbackNumber, hcsNotificationSystemExited, &timeout)
 		if err != nil {
-			if err == ErrTimeout || err == ErrUnexpectedProcessAbort || err == ErrUnexpectedContainerExit {
-				return err
-			}
-			err := &ContainerError{Container: container, Operation: operation, Err: err}
-			logrus.Error(err)
-			return err
+			return makeContainerError(container, operation, "", err)
 		}
 	} else {
 		finished, err := waitTimeoutHelper(container, timeout)
 		if !finished {
 			return ErrTimeout
 		} else if err != nil {
-			err := &ContainerError{Container: container, Operation: operation, Err: err}
-			logrus.Error(err)
-			return err
+			return makeContainerError(container, operation, "", err)
 		}
 	}
 
@@ -273,12 +241,12 @@ func (container *container) hcsWait(timeout uint32) (bool, error) {
 	return waitForSingleObject(exitEvent, timeout)
 }
 
-func (container *container) properties() (*containerProperties, error) {
+func (container *container) properties(query string) (*containerProperties, error) {
 	var (
 		resultp     *uint16
 		propertiesp *uint16
 	)
-	err := hcsGetComputeSystemProperties(container.handle, "", &propertiesp, &resultp)
+	err := hcsGetComputeSystemProperties(container.handle, query, &propertiesp, &resultp)
 	err = processHcsResult(err, resultp)
 	if err != nil {
 		return nil, err
@@ -302,11 +270,9 @@ func (container *container) HasPendingUpdates() (bool, error) {
 	operation := "HasPendingUpdates"
 	title := "HCSShim::Container::" + operation
 	logrus.Debugf(title+" id=%s", container.id)
-	properties, err := container.properties()
+	properties, err := container.properties(pendingUpdatesQuery)
 	if err != nil {
-		err := &ContainerError{Container: container, Operation: operation, Err: err}
-		logrus.Error(err)
-		return false, err
+		return false, makeContainerError(container, operation, "", err)
 	}
 
 	logrus.Debugf(title+" succeeded id=%s", container.id)
@@ -323,12 +289,7 @@ func (container *container) Pause() error {
 	err := hcsPauseComputeSystemTP5(container.handle, nil, &resultp)
 	err = processAsyncHcsResult(err, resultp, container.callbackNumber, hcsNotificationSystemPauseCompleted, &defaultTimeout)
 	if err != nil {
-		if err == ErrTimeout || err == ErrUnexpectedProcessAbort || err == ErrUnexpectedContainerExit {
-			return err
-		}
-		err := &ContainerError{Container: container, Operation: operation, Err: err}
-		logrus.Error(err)
-		return err
+		return makeContainerError(container, operation, "", err)
 	}
 
 	logrus.Debugf(title+" succeeded id=%s", container.id)
@@ -347,12 +308,7 @@ func (container *container) Resume() error {
 	err := hcsResumeComputeSystemTP5(container.handle, nil, &resultp)
 	err = processAsyncHcsResult(err, resultp, container.callbackNumber, hcsNotificationSystemResumeCompleted, &defaultTimeout)
 	if err != nil {
-		if err == ErrTimeout || err == ErrUnexpectedProcessAbort || err == ErrUnexpectedContainerExit {
-			return err
-		}
-		err := &ContainerError{Container: container, Operation: operation, Err: err}
-		logrus.Error(err)
-		return err
+		return makeContainerError(container, operation, "", err)
 	}
 
 	logrus.Debugf(title+" succeeded id=%s", container.id)
@@ -386,9 +342,7 @@ func (container *container) CreateProcess(c *ProcessConfig) (Process, error) {
 	err = hcsCreateProcess(container.handle, configuration, &processInfo, &processHandle, &resultp)
 	err = processHcsResult(err, resultp)
 	if err != nil {
-		err = &ContainerError{Container: container, Operation: operation, ExtraInfo: configuration, Err: err}
-		logrus.Error(err)
-		return nil, err
+		return nil, makeContainerError(container, operation, configuration, err)
 	}
 
 	process := &process{
@@ -404,9 +358,7 @@ func (container *container) CreateProcess(c *ProcessConfig) (Process, error) {
 
 	if hcsCallbacksSupported {
 		if err := process.registerCallback(); err != nil {
-			err = &ContainerError{Container: container, Operation: operation, Err: err}
-			logrus.Error(err)
-			return nil, err
+			return nil, makeContainerError(container, operation, "", err)
 		}
 	}
 
@@ -428,9 +380,7 @@ func (container *container) OpenProcess(pid int) (Process, error) {
 	err := hcsOpenProcess(container.handle, uint32(pid), &processHandle, &resultp)
 	err = processHcsResult(err, resultp)
 	if err != nil {
-		err = &ContainerError{Container: container, Operation: operation, Err: err}
-		logrus.Error(err)
-		return nil, err
+		return nil, makeContainerError(container, operation, "", err)
 	}
 
 	process := &process{
@@ -440,9 +390,7 @@ func (container *container) OpenProcess(pid int) (Process, error) {
 	}
 
 	if err := process.registerCallback(); err != nil {
-		err = &ContainerError{Container: container, Operation: operation, Err: err}
-		logrus.Error(err)
-		return nil, err
+		return nil, makeContainerError(container, operation, "", err)
 	}
 
 	logrus.Debugf(title+" succeeded id=%s processid=%s", container.id, process.processID)
@@ -463,16 +411,12 @@ func (container *container) Close() error {
 
 	if hcsCallbacksSupported {
 		if err := container.unregisterCallback(); err != nil {
-			err = &ContainerError{Container: container, Operation: operation, Err: err}
-			logrus.Error(err)
-			return err
+			return makeContainerError(container, operation, "", err)
 		}
 	}
 
 	if err := hcsCloseComputeSystem(container.handle); err != nil {
-		err = &ContainerError{Container: container, Operation: operation, Err: err}
-		logrus.Error(err)
-		return err
+		return makeContainerError(container, operation, "", err)
 	}
 
 	container.handle = 0
@@ -487,16 +431,15 @@ func closeContainer(container *container) {
 }
 
 func (container *container) registerCallback() error {
-	callbackMapLock.Lock()
-	defer callbackMapLock.Unlock()
-
-	callbackNumber := nextCallback
-	nextCallback++
-
 	context := &notifcationWatcherContext{
 		channels: newChannels(),
 	}
+
+	callbackMapLock.Lock()
+	callbackNumber := nextCallback
+	nextCallback++
 	callbackMap[callbackNumber] = context
+	callbackMapLock.Unlock()
 
 	var callbackHandle hcsCallback
 	err := hcsRegisterComputeSystemCallback(container.handle, notificationWatcherCallback, callbackNumber, &callbackHandle)
@@ -512,21 +455,32 @@ func (container *container) registerCallback() error {
 func (container *container) unregisterCallback() error {
 	callbackNumber := container.callbackNumber
 
-	callbackMapLock.Lock()
-	defer callbackMapLock.Unlock()
+	callbackMapLock.RLock()
+	context := callbackMap[callbackNumber]
+	callbackMapLock.RUnlock()
 
-	handle := callbackMap[callbackNumber].handle
+	if context == nil {
+		return nil
+	}
+
+	handle := context.handle
 
 	if handle == 0 {
 		return nil
 	}
 
+	// hcsUnregisterComputeSystemCallback has its own syncronization
+	// to wait for all callbacks to complete. We must NOT hold the callbackMapLock.
 	err := hcsUnregisterComputeSystemCallback(handle)
 	if err != nil {
 		return err
 	}
 
+	closeChannels(context.channels)
+
+	callbackMapLock.Lock()
 	callbackMap[callbackNumber] = nil
+	callbackMapLock.Unlock()
 
 	handle = 0
 
@@ -558,3 +512,20 @@ func (e *ContainerError) Error() string {
 
 	return s
 }
+
+func makeContainerError(container *container, operation string, extraInfo string, err error) error {
+	// Don't wrap errors created in hcsshim
+	if err == ErrTimeout ||
+		err == ErrUnexpectedProcessAbort ||
+		err == ErrUnexpectedContainerExit ||
+		err == ErrHandleClose ||
+		err == ErrInvalidProcessState ||
+		err == ErrInvalidNotificationType ||
+		err == ErrVmcomputeOperationPending {
+		return err
+	}
+
+	containerError := &ContainerError{Container: container, Operation: operation, ExtraInfo: extraInfo, Err: err}
+	logrus.Error(containerError)
+	return containerError
+}

+ 23 - 0
vendor/src/github.com/Microsoft/hcsshim/interface.go

@@ -1,10 +1,33 @@
 package hcsshim
 
 import (
+	"errors"
 	"io"
 	"time"
 )
 
+var (
+	// ErrInvalidNotificationType is an error encountered when an invalid notification type is used
+	ErrInvalidNotificationType = errors.New("hcsshim: invalid notification type")
+
+	// ErrTimeout is an error encountered when waiting on a notification times out
+	ErrTimeout = errors.New("hcsshim: timeout waiting for notification")
+
+	// ErrHandleClose is an error returned when the handle generating the notification being waited on has been closed
+	ErrHandleClose = errors.New("hcsshim: the handle generating this notification has been closed")
+
+	// ErrInvalidProcessState is an error encountered when the process is not in a valid state for the requested operation
+	ErrInvalidProcessState = errors.New("the process is in an invalid state for the attempted operation")
+
+	// ErrUnexpectedContainerExit is the error returned when a container exits while waiting for
+	// a different expected notification
+	ErrUnexpectedContainerExit = errors.New("unexpected container exit")
+
+	// ErrUnexpectedProcessAbort is the error returned when communication with the compute service
+	// is lost while waiting for a notification
+	ErrUnexpectedProcessAbort = errors.New("lost communication with compute service")
+)
+
 // ProcessConfig is used as both the input of Container.CreateProcess
 // and to convert the parameters to JSON for passing onto the HCS
 type ProcessConfig struct {

+ 50 - 55
vendor/src/github.com/Microsoft/hcsshim/process.go

@@ -11,13 +11,10 @@ import (
 	"github.com/Sirupsen/logrus"
 )
 
-var (
-	ErrInvalidProcessState = errors.New("the process is in an invalid state for the attempted operation")
-)
-
 type ProcessError struct {
 	Process   *process
 	Operation string
+	ExtraInfo string
 	Err       error
 }
 
@@ -85,9 +82,7 @@ func (process *process) Kill() error {
 	if err == ErrVmcomputeOperationPending {
 		return ErrVmcomputeOperationPending
 	} else if err != nil {
-		err := &ProcessError{Operation: operation, Process: process, Err: err}
-		logrus.Error(err)
-		return err
+		return makeProcessError(process, operation, "", err)
 	}
 
 	logrus.Debugf(title+" succeeded processid=%d", process.processID)
@@ -103,19 +98,12 @@ func (process *process) Wait() error {
 	if hcsCallbacksSupported {
 		err := waitForNotification(process.callbackNumber, hcsNotificationProcessExited, nil)
 		if err != nil {
-			if err == ErrUnexpectedProcessAbort || err == ErrUnexpectedContainerExit {
-				return err
-			}
-			err := &ProcessError{Operation: operation, Process: process, Err: err}
-			logrus.Error(err)
-			return err
+			return makeProcessError(process, operation, "", err)
 		}
 	} else {
 		_, err := process.waitTimeoutInternal(syscall.INFINITE)
 		if err != nil {
-			err := &ProcessError{Operation: operation, Process: process, Err: err}
-			logrus.Error(err)
-			return err
+			return makeProcessError(process, operation, "", err)
 		}
 	}
 
@@ -133,21 +121,14 @@ func (process *process) WaitTimeout(timeout time.Duration) error {
 	if hcsCallbacksSupported {
 		err := waitForNotification(process.callbackNumber, hcsNotificationProcessExited, &timeout)
 		if err != nil {
-			if err == ErrTimeout || err == ErrUnexpectedProcessAbort || err == ErrUnexpectedContainerExit {
-				return err
-			}
-			err := &ProcessError{Operation: operation, Process: process, Err: err}
-			logrus.Error(err)
-			return err
+			return makeProcessError(process, operation, "", err)
 		}
 	} else {
 		finished, err := waitTimeoutHelper(process, timeout)
 		if !finished {
 			return ErrTimeout
 		} else if err != nil {
-			err := &ProcessError{Operation: operation, Process: process, Err: err}
-			logrus.Error(err)
-			return err
+			return makeProcessError(process, operation, "", err)
 		}
 	}
 
@@ -183,9 +164,7 @@ func (process *process) ExitCode() (int, error) {
 
 	properties, err := process.properties()
 	if err != nil {
-		err := &ProcessError{Operation: operation, Process: process, Err: err}
-		logrus.Error(err)
-		return 0, err
+		return 0, makeProcessError(process, operation, "", err)
 	}
 
 	if properties.Exited == false {
@@ -221,9 +200,7 @@ func (process *process) ResizeConsole(width, height uint16) error {
 	err = hcsModifyProcess(process.handle, modifyRequestStr, &resultp)
 	err = processHcsResult(err, resultp)
 	if err != nil {
-		err := &ProcessError{Operation: operation, Process: process, Err: err}
-		logrus.Error(err)
-		return err
+		return makeProcessError(process, operation, "", err)
 	}
 
 	logrus.Debugf(title+" succeeded processid=%d", process.processID)
@@ -242,9 +219,7 @@ func (process *process) properties() (*processStatus, error) {
 	err := hcsGetProcessProperties(process.handle, &propertiesp, &resultp)
 	err = processHcsResult(err, resultp)
 	if err != nil {
-		err := &ProcessError{Operation: operation, Process: process, Err: err}
-		logrus.Error(err)
-		return nil, err
+		return nil, makeProcessError(process, operation, "", err)
 	}
 
 	if propertiesp == nil {
@@ -279,9 +254,7 @@ func (process *process) Stdio() (io.WriteCloser, io.ReadCloser, io.ReadCloser, e
 		err := hcsGetProcessInfo(process.handle, &processInfo, &resultp)
 		err = processHcsResult(err, resultp)
 		if err != nil {
-			err = &ProcessError{Operation: operation, Process: process, Err: err}
-			logrus.Error(err)
-			return nil, nil, nil, err
+			return nil, nil, nil, makeProcessError(process, operation, "", err)
 		}
 
 		stdIn, stdOut, stdErr = processInfo.StdInput, processInfo.StdOutput, processInfo.StdError
@@ -327,9 +300,7 @@ func (process *process) CloseStdin() error {
 	err = hcsModifyProcess(process.handle, modifyRequestStr, &resultp)
 	err = processHcsResult(err, resultp)
 	if err != nil {
-		err = &ProcessError{Operation: operation, Process: process, Err: err}
-		logrus.Error(err)
-		return err
+		return makeProcessError(process, operation, "", err)
 	}
 
 	logrus.Debugf(title+" succeeded processid=%d", process.processID)
@@ -350,16 +321,12 @@ func (process *process) Close() error {
 
 	if hcsCallbacksSupported {
 		if err := process.unregisterCallback(); err != nil {
-			err = &ProcessError{Operation: operation, Process: process, Err: err}
-			logrus.Error(err)
-			return err
+			return makeProcessError(process, operation, "", err)
 		}
 	}
 
 	if err := hcsCloseProcess(process.handle); err != nil {
-		err = &ProcessError{Operation: operation, Process: process, Err: err}
-		logrus.Error(err)
-		return err
+		return makeProcessError(process, operation, "", err)
 	}
 
 	process.handle = 0
@@ -374,16 +341,15 @@ func closeProcess(process *process) {
 }
 
 func (process *process) registerCallback() error {
-	callbackMapLock.Lock()
-	defer callbackMapLock.Unlock()
-
-	callbackNumber := nextCallback
-	nextCallback++
-
 	context := &notifcationWatcherContext{
 		channels: newChannels(),
 	}
+
+	callbackMapLock.Lock()
+	callbackNumber := nextCallback
+	nextCallback++
 	callbackMap[callbackNumber] = context
+	callbackMapLock.Unlock()
 
 	var callbackHandle hcsCallback
 	err := hcsRegisterProcessCallback(process.handle, notificationWatcherCallback, callbackNumber, &callbackHandle)
@@ -399,20 +365,32 @@ func (process *process) registerCallback() error {
 func (process *process) unregisterCallback() error {
 	callbackNumber := process.callbackNumber
 
-	callbackMapLock.Lock()
-	defer callbackMapLock.Unlock()
-	handle := callbackMap[callbackNumber].handle
+	callbackMapLock.RLock()
+	context := callbackMap[callbackNumber]
+	callbackMapLock.RUnlock()
+
+	if context == nil {
+		return nil
+	}
+
+	handle := context.handle
 
 	if handle == 0 {
 		return nil
 	}
 
+	// hcsUnregisterProcessCallback has its own syncronization
+	// to wait for all callbacks to complete. We must NOT hold the callbackMapLock.
 	err := hcsUnregisterProcessCallback(handle)
 	if err != nil {
 		return err
 	}
 
+	closeChannels(context.channels)
+
+	callbackMapLock.Lock()
 	callbackMap[callbackNumber] = nil
+	callbackMapLock.Unlock()
 
 	handle = 0
 
@@ -444,3 +422,20 @@ func (e *ProcessError) Error() string {
 
 	return s
 }
+
+func makeProcessError(process *process, operation string, extraInfo string, err error) error {
+	// Don't wrap errors created in hcsshim
+	if err == ErrTimeout ||
+		err == ErrUnexpectedProcessAbort ||
+		err == ErrUnexpectedContainerExit ||
+		err == ErrHandleClose ||
+		err == ErrInvalidProcessState ||
+		err == ErrInvalidNotificationType ||
+		err == ErrVmcomputeOperationPending {
+		return err
+	}
+
+	processError := &ProcessError{Process: process, Operation: operation, ExtraInfo: extraInfo, Err: err}
+	logrus.Error(processError)
+	return processError
+}

+ 25 - 8
vendor/src/github.com/Microsoft/hcsshim/waithelper.go

@@ -65,6 +65,7 @@ func waitForNotification(callbackNumber uintptr, expectedNotification hcsNotific
 	expectedChannel := channels[expectedNotification]
 	if expectedChannel == nil {
 		logrus.Errorf("unknown notification type in waitForNotification %x", expectedNotification)
+		return ErrInvalidNotificationType
 	}
 
 	if timeout != nil {
@@ -72,38 +73,54 @@ func waitForNotification(callbackNumber uintptr, expectedNotification hcsNotific
 		defer timer.Stop()
 
 		select {
-		case err := <-expectedChannel:
+		case err, ok := <-expectedChannel:
+			if !ok {
+				return ErrHandleClose
+			}
 			return err
-		case err := <-channels[hcsNotificationSystemExited]:
+		case err, ok := <-channels[hcsNotificationSystemExited]:
+			if !ok {
+				return ErrHandleClose
+			}
 			// If the expected notification is hcsNotificationSystemExited which of the two selects
 			// chosen is random. Return the raw error if hcsNotificationSystemExited is expected
 			if channels[hcsNotificationSystemExited] == expectedChannel {
 				return err
 			}
 			return ErrUnexpectedContainerExit
-		case err := <-channels[hcsNotificationServiceDisconnect]:
+		case _, ok := <-channels[hcsNotificationServiceDisconnect]:
+			if !ok {
+				return ErrHandleClose
+			}
 			// hcsNotificationServiceDisconnect should never be an expected notification
 			// it does not need the same handling as hcsNotificationSystemExited
-			logrus.Error(err)
 			return ErrUnexpectedProcessAbort
 		case <-timer.C:
 			return ErrTimeout
 		}
 	}
 	select {
-	case err := <-expectedChannel:
+	case err, ok := <-expectedChannel:
+		if !ok {
+			return ErrHandleClose
+		}
 		return err
-	case err := <-channels[hcsNotificationSystemExited]:
+	case err, ok := <-channels[hcsNotificationSystemExited]:
+		if !ok {
+			return ErrHandleClose
+		}
 		// If the expected notification is hcsNotificationSystemExited which of the two selects
 		// chosen is random. Return the raw error if hcsNotificationSystemExited is expected
 		if channels[hcsNotificationSystemExited] == expectedChannel {
 			return err
 		}
 		return ErrUnexpectedContainerExit
-	case err := <-channels[hcsNotificationServiceDisconnect]:
+	case _, ok := <-channels[hcsNotificationServiceDisconnect]:
+		if !ok {
+			return ErrHandleClose
+		}
 		// hcsNotificationServiceDisconnect should never be an expected notification
 		// it does not need the same handling as hcsNotificationSystemExited
-		logrus.Error(err)
 		return ErrUnexpectedProcessAbort
 	}
 }