|
@@ -26,8 +26,9 @@ type ContainerError struct {
|
|
|
}
|
|
|
|
|
|
type container struct {
|
|
|
- handle hcsSystem
|
|
|
- id string
|
|
|
+ handle hcsSystem
|
|
|
+ id string
|
|
|
+ callbackNumber uintptr
|
|
|
}
|
|
|
|
|
|
type containerProperties struct {
|
|
@@ -47,7 +48,6 @@ type containerProperties struct {
|
|
|
func CreateContainer(id string, c *ContainerConfig) (Container, error) {
|
|
|
operation := "CreateContainer"
|
|
|
title := "HCSShim::" + operation
|
|
|
- logrus.Debugf(title+" id=%s", id)
|
|
|
|
|
|
container := &container{
|
|
|
id: id,
|
|
@@ -59,21 +59,28 @@ func CreateContainer(id string, c *ContainerConfig) (Container, error) {
|
|
|
}
|
|
|
|
|
|
configuration := string(configurationb)
|
|
|
+ logrus.Debugf(title+" id=%s config=%s", id, configuration)
|
|
|
|
|
|
var (
|
|
|
- handle hcsSystem
|
|
|
resultp *uint16
|
|
|
createError error
|
|
|
)
|
|
|
if hcsCallbacksSupported {
|
|
|
var identity syscall.Handle
|
|
|
- createError = hcsCreateComputeSystem(id, configuration, identity, &handle, &resultp)
|
|
|
+ createError = hcsCreateComputeSystem(id, configuration, identity, &container.handle, &resultp)
|
|
|
+
|
|
|
+ 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
|
|
|
+ }
|
|
|
+ }
|
|
|
} else {
|
|
|
- createError = hcsCreateComputeSystemTP5(id, configuration, &handle, &resultp)
|
|
|
+ createError = hcsCreateComputeSystemTP5(id, configuration, &container.handle, &resultp)
|
|
|
}
|
|
|
- container.handle = handle
|
|
|
|
|
|
- err = processAsyncHcsResult(container, createError, resultp, hcsNotificationSystemCreateCompleted, &defaultTimeout)
|
|
|
+ err = processAsyncHcsResult(createError, resultp, container.callbackNumber, hcsNotificationSystemCreateCompleted, &defaultTimeout)
|
|
|
if err != nil {
|
|
|
err := &ContainerError{Container: container, Operation: operation, ExtraInfo: configuration, Err: err}
|
|
|
logrus.Error(err)
|
|
@@ -122,7 +129,7 @@ func (container *container) Start() error {
|
|
|
|
|
|
var resultp *uint16
|
|
|
err := hcsStartComputeSystemTP5(container.handle, nil, &resultp)
|
|
|
- err = processAsyncHcsResult(container, err, resultp, hcsNotificationSystemStartCompleted, &defaultTimeout)
|
|
|
+ err = processAsyncHcsResult(err, resultp, container.callbackNumber, hcsNotificationSystemStartCompleted, &defaultTimeout)
|
|
|
if err != nil {
|
|
|
err := &ContainerError{Container: container, Operation: operation, Err: err}
|
|
|
logrus.Error(err)
|
|
@@ -186,7 +193,7 @@ func (container *container) Wait() error {
|
|
|
logrus.Debugf(title+" id=%s", container.id)
|
|
|
|
|
|
if hcsCallbacksSupported {
|
|
|
- err := registerAndWaitForCallback(container, hcsNotificationSystemExited)
|
|
|
+ err := waitForNotification(container.callbackNumber, hcsNotificationSystemExited, nil)
|
|
|
if err != nil {
|
|
|
err := &ContainerError{Container: container, Operation: operation, Err: err}
|
|
|
logrus.Error(err)
|
|
@@ -217,7 +224,7 @@ func (container *container) WaitTimeout(timeout time.Duration) error {
|
|
|
logrus.Debugf(title+" id=%s", container.id)
|
|
|
|
|
|
if hcsCallbacksSupported {
|
|
|
- err := registerAndWaitForCallbackTimeout(container, hcsNotificationSystemExited, timeout)
|
|
|
+ err := waitForNotification(container.callbackNumber, hcsNotificationSystemExited, &timeout)
|
|
|
if err == ErrTimeout {
|
|
|
return ErrTimeout
|
|
|
} else if err != nil {
|
|
@@ -304,7 +311,7 @@ func (container *container) Pause() error {
|
|
|
|
|
|
var resultp *uint16
|
|
|
err := hcsPauseComputeSystemTP5(container.handle, nil, &resultp)
|
|
|
- err = processAsyncHcsResult(container, err, resultp, hcsNotificationSystemPauseCompleted, &defaultTimeout)
|
|
|
+ err = processAsyncHcsResult(err, resultp, container.callbackNumber, hcsNotificationSystemPauseCompleted, &defaultTimeout)
|
|
|
if err != nil {
|
|
|
err := &ContainerError{Container: container, Operation: operation, Err: err}
|
|
|
logrus.Error(err)
|
|
@@ -325,7 +332,7 @@ func (container *container) Resume() error {
|
|
|
)
|
|
|
|
|
|
err := hcsResumeComputeSystemTP5(container.handle, nil, &resultp)
|
|
|
- err = processAsyncHcsResult(container, err, resultp, hcsNotificationSystemResumeCompleted, &defaultTimeout)
|
|
|
+ err = processAsyncHcsResult(err, resultp, container.callbackNumber, hcsNotificationSystemResumeCompleted, &defaultTimeout)
|
|
|
if err != nil {
|
|
|
err := &ContainerError{Container: container, Operation: operation, Err: err}
|
|
|
logrus.Error(err)
|
|
@@ -340,7 +347,6 @@ func (container *container) Resume() error {
|
|
|
func (container *container) CreateProcess(c *ProcessConfig) (Process, error) {
|
|
|
operation := "CreateProcess"
|
|
|
title := "HCSShim::Container::" + operation
|
|
|
- logrus.Debugf(title+" id=%s", container.id)
|
|
|
var (
|
|
|
processInfo hcsProcessInformation
|
|
|
processHandle hcsProcess
|
|
@@ -359,6 +365,7 @@ func (container *container) CreateProcess(c *ProcessConfig) (Process, error) {
|
|
|
}
|
|
|
|
|
|
configuration := string(configurationb)
|
|
|
+ logrus.Debugf(title+" id=%s config=%s", container.id, configuration)
|
|
|
|
|
|
err = hcsCreateProcess(container.handle, configuration, &processInfo, &processHandle, &resultp)
|
|
|
err = processHcsResult(err, resultp)
|
|
@@ -379,6 +386,14 @@ 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
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
logrus.Debugf(title+" succeeded id=%s processid=%s", container.id, process.processID)
|
|
|
runtime.SetFinalizer(process, closeProcess)
|
|
|
return process, nil
|
|
@@ -408,6 +423,12 @@ func (container *container) OpenProcess(pid int) (Process, error) {
|
|
|
container: container,
|
|
|
}
|
|
|
|
|
|
+ if err := process.registerCallback(); err != nil {
|
|
|
+ err = &ContainerError{Container: container, Operation: operation, Err: err}
|
|
|
+ logrus.Error(err)
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
logrus.Debugf(title+" succeeded id=%s processid=%s", container.id, process.processID)
|
|
|
runtime.SetFinalizer(process, closeProcess)
|
|
|
return process, nil
|
|
@@ -424,6 +445,14 @@ func (container *container) Close() error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
+ if hcsCallbacksSupported {
|
|
|
+ if err := container.unregisterCallback(); err != nil {
|
|
|
+ err = &ContainerError{Container: container, Operation: operation, Err: err}
|
|
|
+ logrus.Error(err)
|
|
|
+ return err
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
if err := hcsCloseComputeSystem(container.handle); err != nil {
|
|
|
err = &ContainerError{Container: container, Operation: operation, Err: err}
|
|
|
logrus.Error(err)
|
|
@@ -441,7 +470,7 @@ func closeContainer(container *container) {
|
|
|
container.Close()
|
|
|
}
|
|
|
|
|
|
-func (container *container) registerCallback(expectedNotification hcsNotification) (uintptr, error) {
|
|
|
+func (container *container) registerCallback() error {
|
|
|
callbackMapLock.Lock()
|
|
|
defer callbackMapLock.Unlock()
|
|
|
|
|
@@ -449,22 +478,24 @@ func (container *container) registerCallback(expectedNotification hcsNotificatio
|
|
|
nextCallback++
|
|
|
|
|
|
context := ¬ifcationWatcherContext{
|
|
|
- expectedNotification: expectedNotification,
|
|
|
- channel: make(chan error, 1),
|
|
|
+ channels: newChannels(),
|
|
|
}
|
|
|
callbackMap[callbackNumber] = context
|
|
|
|
|
|
var callbackHandle hcsCallback
|
|
|
err := hcsRegisterComputeSystemCallback(container.handle, notificationWatcherCallback, callbackNumber, &callbackHandle)
|
|
|
if err != nil {
|
|
|
- return 0, err
|
|
|
+ return err
|
|
|
}
|
|
|
context.handle = callbackHandle
|
|
|
+ container.callbackNumber = callbackNumber
|
|
|
|
|
|
- return callbackNumber, nil
|
|
|
+ return nil
|
|
|
}
|
|
|
|
|
|
-func (container *container) unregisterCallback(callbackNumber uintptr) error {
|
|
|
+func (container *container) unregisterCallback() error {
|
|
|
+ callbackNumber := container.callbackNumber
|
|
|
+
|
|
|
callbackMapLock.Lock()
|
|
|
defer callbackMapLock.Unlock()
|
|
|
|