summaryrefslogtreecommitdiff
path: root/vendor/github.com/Microsoft/hcsshim/internal/hcs
diff options
context:
space:
mode:
authorValentin Rothberg <rothberg@redhat.com>2019-01-08 14:52:57 +0100
committerValentin Rothberg <rothberg@redhat.com>2019-01-11 13:38:11 +0100
commitbd40dcfc2bc7c9014ea1f33482fb63aacbcdfe87 (patch)
tree5f06e4e289f16d9164d692590a3fe6541b5384cf /vendor/github.com/Microsoft/hcsshim/internal/hcs
parent545f24421247c9f6251a634764db3f8f8070a812 (diff)
downloadpodman-bd40dcfc2bc7c9014ea1f33482fb63aacbcdfe87.tar.gz
podman-bd40dcfc2bc7c9014ea1f33482fb63aacbcdfe87.tar.bz2
podman-bd40dcfc2bc7c9014ea1f33482fb63aacbcdfe87.zip
vendor: update everything
* If possible, update each dependency to the latest available version. * Use releases over commit IDs and avoid vendoring branches. Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
Diffstat (limited to 'vendor/github.com/Microsoft/hcsshim/internal/hcs')
-rw-r--r--vendor/github.com/Microsoft/hcsshim/internal/hcs/callback.go88
-rw-r--r--vendor/github.com/Microsoft/hcsshim/internal/hcs/cgo.go7
-rw-r--r--vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go284
-rw-r--r--vendor/github.com/Microsoft/hcsshim/internal/hcs/hcs.go48
-rw-r--r--vendor/github.com/Microsoft/hcsshim/internal/hcs/log.go15
-rw-r--r--vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go465
-rw-r--r--vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go667
-rw-r--r--vendor/github.com/Microsoft/hcsshim/internal/hcs/utils.go33
-rw-r--r--vendor/github.com/Microsoft/hcsshim/internal/hcs/waithelper.go63
-rw-r--r--vendor/github.com/Microsoft/hcsshim/internal/hcs/watcher.go33
-rw-r--r--vendor/github.com/Microsoft/hcsshim/internal/hcs/zsyscall_windows.go462
11 files changed, 2165 insertions, 0 deletions
diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/callback.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/callback.go
new file mode 100644
index 000000000..5119c2555
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/callback.go
@@ -0,0 +1,88 @@
+package hcs
+
+import (
+ "sync"
+ "syscall"
+
+ "github.com/Microsoft/hcsshim/internal/interop"
+ "github.com/sirupsen/logrus"
+)
+
+var (
+ nextCallback uintptr
+ callbackMap = map[uintptr]*notifcationWatcherContext{}
+ callbackMapLock = sync.RWMutex{}
+
+ notificationWatcherCallback = syscall.NewCallback(notificationWatcher)
+
+ // Notifications for HCS_SYSTEM handles
+ hcsNotificationSystemExited hcsNotification = 0x00000001
+ hcsNotificationSystemCreateCompleted hcsNotification = 0x00000002
+ hcsNotificationSystemStartCompleted hcsNotification = 0x00000003
+ hcsNotificationSystemPauseCompleted hcsNotification = 0x00000004
+ hcsNotificationSystemResumeCompleted hcsNotification = 0x00000005
+
+ // Notifications for HCS_PROCESS handles
+ hcsNotificationProcessExited hcsNotification = 0x00010000
+
+ // Common notifications
+ hcsNotificationInvalid hcsNotification = 0x00000000
+ hcsNotificationServiceDisconnect hcsNotification = 0x01000000
+)
+
+type hcsNotification uint32
+type notificationChannel chan error
+
+type notifcationWatcherContext struct {
+ channels notificationChannels
+ handle hcsCallback
+}
+
+type notificationChannels map[hcsNotification]notificationChannel
+
+func newChannels() notificationChannels {
+ channels := make(notificationChannels)
+
+ channels[hcsNotificationSystemExited] = make(notificationChannel, 1)
+ channels[hcsNotificationSystemCreateCompleted] = make(notificationChannel, 1)
+ channels[hcsNotificationSystemStartCompleted] = make(notificationChannel, 1)
+ channels[hcsNotificationSystemPauseCompleted] = make(notificationChannel, 1)
+ channels[hcsNotificationSystemResumeCompleted] = make(notificationChannel, 1)
+ channels[hcsNotificationProcessExited] = make(notificationChannel, 1)
+ 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
+ if int32(notificationStatus) < 0 {
+ result = interop.Win32FromHresult(notificationStatus)
+ }
+
+ callbackMapLock.RLock()
+ context := callbackMap[callbackNumber]
+ callbackMapLock.RUnlock()
+
+ if context == nil {
+ return 0
+ }
+
+ if channel, ok := context.channels[notificationType]; ok {
+ channel <- result
+ } else {
+ logrus.WithFields(logrus.Fields{
+ "notification-type": notificationType,
+ }).Warn("Received a callback of an unsupported type")
+ }
+
+ return 0
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/cgo.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/cgo.go
new file mode 100644
index 000000000..3669c34aa
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/cgo.go
@@ -0,0 +1,7 @@
+package hcs
+
+import "C"
+
+// This import is needed to make the library compile as CGO because HCSSHIM
+// only works with CGO due to callbacks from HCS comming back from a C thread
+// which is not supported without CGO. See https://github.com/golang/go/issues/10973
diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go
new file mode 100644
index 000000000..6368b5717
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/errors.go
@@ -0,0 +1,284 @@
+package hcs
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "syscall"
+
+ "github.com/Microsoft/hcsshim/internal/interop"
+ "github.com/Microsoft/hcsshim/internal/logfields"
+ "github.com/sirupsen/logrus"
+)
+
+var (
+ // ErrComputeSystemDoesNotExist is an error encountered when the container being operated on no longer exists
+ ErrComputeSystemDoesNotExist = syscall.Errno(0xc037010e)
+
+ // ErrElementNotFound is an error encountered when the object being referenced does not exist
+ ErrElementNotFound = syscall.Errno(0x490)
+
+ // ErrElementNotFound is an error encountered when the object being referenced does not exist
+ ErrNotSupported = syscall.Errno(0x32)
+
+ // ErrInvalidData is an error encountered when the request being sent to hcs is invalid/unsupported
+ // decimal -2147024883 / hex 0x8007000d
+ ErrInvalidData = syscall.Errno(0xd)
+
+ // ErrHandleClose is an error encountered when the handle generating the notification being waited on has been closed
+ ErrHandleClose = errors.New("hcsshim: the handle generating this notification has been closed")
+
+ // ErrAlreadyClosed is an error encountered when using a handle that has been closed by the Close method
+ ErrAlreadyClosed = errors.New("hcsshim: the handle has already been closed")
+
+ // ErrInvalidNotificationType is an error encountered when an invalid notification type is used
+ ErrInvalidNotificationType = errors.New("hcsshim: invalid notification type")
+
+ // 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")
+
+ // ErrTimeout is an error encountered when waiting on a notification times out
+ ErrTimeout = errors.New("hcsshim: timeout waiting for notification")
+
+ // ErrUnexpectedContainerExit is the error encountered when a container exits while waiting for
+ // a different expected notification
+ ErrUnexpectedContainerExit = errors.New("unexpected container exit")
+
+ // ErrUnexpectedProcessAbort is the error encountered when communication with the compute service
+ // is lost while waiting for a notification
+ ErrUnexpectedProcessAbort = errors.New("lost communication with compute service")
+
+ // ErrUnexpectedValue is an error encountered when hcs returns an invalid value
+ ErrUnexpectedValue = errors.New("unexpected value returned from hcs")
+
+ // ErrVmcomputeAlreadyStopped is an error encountered when a shutdown or terminate request is made on a stopped container
+ ErrVmcomputeAlreadyStopped = syscall.Errno(0xc0370110)
+
+ // ErrVmcomputeOperationPending is an error encountered when the operation is being completed asynchronously
+ ErrVmcomputeOperationPending = syscall.Errno(0xC0370103)
+
+ // ErrVmcomputeOperationInvalidState is an error encountered when the compute system is not in a valid state for the requested operation
+ ErrVmcomputeOperationInvalidState = syscall.Errno(0xc0370105)
+
+ // ErrProcNotFound is an error encountered when the the process cannot be found
+ ErrProcNotFound = syscall.Errno(0x7f)
+
+ // ErrVmcomputeOperationAccessIsDenied is an error which can be encountered when enumerating compute systems in RS1/RS2
+ // builds when the underlying silo might be in the process of terminating. HCS was fixed in RS3.
+ ErrVmcomputeOperationAccessIsDenied = syscall.Errno(0x5)
+
+ // ErrVmcomputeInvalidJSON is an error encountered when the compute system does not support/understand the messages sent by management
+ ErrVmcomputeInvalidJSON = syscall.Errno(0xc037010d)
+
+ // ErrVmcomputeUnknownMessage is an error encountered guest compute system doesn't support the message
+ ErrVmcomputeUnknownMessage = syscall.Errno(0xc037010b)
+
+ // ErrNotSupported is an error encountered when hcs doesn't support the request
+ ErrPlatformNotSupported = errors.New("unsupported platform request")
+)
+
+type ErrorEvent struct {
+ Message string `json:"Message,omitempty"` // Fully formated error message
+ StackTrace string `json:"StackTrace,omitempty"` // Stack trace in string form
+ Provider string `json:"Provider,omitempty"`
+ EventID uint16 `json:"EventId,omitempty"`
+ Flags uint32 `json:"Flags,omitempty"`
+ Source string `json:"Source,omitempty"`
+ //Data []EventData `json:"Data,omitempty"` // Omit this as HCS doesn't encode this well. It's more confusing to include. It is however logged in debug mode (see processHcsResult function)
+}
+
+type hcsResult struct {
+ Error int32
+ ErrorMessage string
+ ErrorEvents []ErrorEvent `json:"ErrorEvents,omitempty"`
+}
+
+func (ev *ErrorEvent) String() string {
+ evs := "[Event Detail: " + ev.Message
+ if ev.StackTrace != "" {
+ evs += " Stack Trace: " + ev.StackTrace
+ }
+ if ev.Provider != "" {
+ evs += " Provider: " + ev.Provider
+ }
+ if ev.EventID != 0 {
+ evs = fmt.Sprintf("%s EventID: %d", evs, ev.EventID)
+ }
+ if ev.Flags != 0 {
+ evs = fmt.Sprintf("%s flags: %d", evs, ev.Flags)
+ }
+ if ev.Source != "" {
+ evs += " Source: " + ev.Source
+ }
+ evs += "]"
+ return evs
+}
+
+func processHcsResult(resultp *uint16) []ErrorEvent {
+ if resultp != nil {
+ resultj := interop.ConvertAndFreeCoTaskMemString(resultp)
+ logrus.WithField(logfields.JSON, resultj).
+ Debug("HCS Result")
+ result := &hcsResult{}
+ if err := json.Unmarshal([]byte(resultj), result); err != nil {
+ logrus.WithFields(logrus.Fields{
+ logfields.JSON: resultj,
+ logrus.ErrorKey: err,
+ }).Warning("Could not unmarshal HCS result")
+ return nil
+ }
+ return result.ErrorEvents
+ }
+ return nil
+}
+
+type HcsError struct {
+ Op string
+ Err error
+ Events []ErrorEvent
+}
+
+func (e *HcsError) Error() string {
+ s := e.Op + ": " + e.Err.Error()
+ for _, ev := range e.Events {
+ s += "\n" + ev.String()
+ }
+ return s
+}
+
+// ProcessError is an error encountered in HCS during an operation on a Process object
+type ProcessError struct {
+ SystemID string
+ Pid int
+ Op string
+ Err error
+ Events []ErrorEvent
+}
+
+// SystemError is an error encountered in HCS during an operation on a Container object
+type SystemError struct {
+ ID string
+ Op string
+ Err error
+ Extra string
+ Events []ErrorEvent
+}
+
+func (e *SystemError) Error() string {
+ s := e.Op + " " + e.ID + ": " + e.Err.Error()
+ for _, ev := range e.Events {
+ s += "\n" + ev.String()
+ }
+ if e.Extra != "" {
+ s += "\n(extra info: " + e.Extra + ")"
+ }
+ return s
+}
+
+func makeSystemError(system *System, op string, extra string, err error, events []ErrorEvent) error {
+ // Don't double wrap errors
+ if _, ok := err.(*SystemError); ok {
+ return err
+ }
+ return &SystemError{
+ ID: system.ID(),
+ Op: op,
+ Extra: extra,
+ Err: err,
+ Events: events,
+ }
+}
+
+func (e *ProcessError) Error() string {
+ s := fmt.Sprintf("%s %s:%d: %s", e.Op, e.SystemID, e.Pid, e.Err.Error())
+ for _, ev := range e.Events {
+ s += "\n" + ev.String()
+ }
+ return s
+}
+
+func makeProcessError(process *Process, op string, err error, events []ErrorEvent) error {
+ // Don't double wrap errors
+ if _, ok := err.(*ProcessError); ok {
+ return err
+ }
+ return &ProcessError{
+ Pid: process.Pid(),
+ SystemID: process.SystemID(),
+ Op: op,
+ Err: err,
+ Events: events,
+ }
+}
+
+// IsNotExist checks if an error is caused by the Container or Process not existing.
+// Note: Currently, ErrElementNotFound can mean that a Process has either
+// already exited, or does not exist. Both IsAlreadyStopped and IsNotExist
+// will currently return true when the error is ErrElementNotFound or ErrProcNotFound.
+func IsNotExist(err error) bool {
+ err = getInnerError(err)
+ return err == ErrComputeSystemDoesNotExist ||
+ err == ErrElementNotFound ||
+ err == ErrProcNotFound
+}
+
+// IsAlreadyClosed checks if an error is caused by the Container or Process having been
+// already closed by a call to the Close() method.
+func IsAlreadyClosed(err error) bool {
+ err = getInnerError(err)
+ return err == ErrAlreadyClosed
+}
+
+// IsPending returns a boolean indicating whether the error is that
+// the requested operation is being completed in the background.
+func IsPending(err error) bool {
+ err = getInnerError(err)
+ return err == ErrVmcomputeOperationPending
+}
+
+// IsTimeout returns a boolean indicating whether the error is caused by
+// a timeout waiting for the operation to complete.
+func IsTimeout(err error) bool {
+ err = getInnerError(err)
+ return err == ErrTimeout
+}
+
+// IsAlreadyStopped returns a boolean indicating whether the error is caused by
+// a Container or Process being already stopped.
+// Note: Currently, ErrElementNotFound can mean that a Process has either
+// already exited, or does not exist. Both IsAlreadyStopped and IsNotExist
+// will currently return true when the error is ErrElementNotFound or ErrProcNotFound.
+func IsAlreadyStopped(err error) bool {
+ err = getInnerError(err)
+ return err == ErrVmcomputeAlreadyStopped ||
+ err == ErrElementNotFound ||
+ err == ErrProcNotFound
+}
+
+// IsNotSupported returns a boolean indicating whether the error is caused by
+// unsupported platform requests
+// Note: Currently Unsupported platform requests can be mean either
+// ErrVmcomputeInvalidJSON, ErrInvalidData, ErrNotSupported or ErrVmcomputeUnknownMessage
+// is thrown from the Platform
+func IsNotSupported(err error) bool {
+ err = getInnerError(err)
+ // If Platform doesn't recognize or support the request sent, below errors are seen
+ return err == ErrVmcomputeInvalidJSON ||
+ err == ErrInvalidData ||
+ err == ErrNotSupported ||
+ err == ErrVmcomputeUnknownMessage
+}
+
+func getInnerError(err error) error {
+ switch pe := err.(type) {
+ case nil:
+ return nil
+ case *HcsError:
+ err = pe.Err
+ case *SystemError:
+ err = pe.Err
+ case *ProcessError:
+ err = pe.Err
+ }
+ return err
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/hcs.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/hcs.go
new file mode 100644
index 000000000..b0d49cbcf
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/hcs.go
@@ -0,0 +1,48 @@
+// Shim for the Host Compute Service (HCS) to manage Windows Server
+// containers and Hyper-V containers.
+
+package hcs
+
+import (
+ "syscall"
+)
+
+//go:generate go run ../../mksyscall_windows.go -output zsyscall_windows.go hcs.go
+
+//sys hcsEnumerateComputeSystems(query string, computeSystems **uint16, result **uint16) (hr error) = vmcompute.HcsEnumerateComputeSystems?
+//sys hcsCreateComputeSystem(id string, configuration string, identity syscall.Handle, computeSystem *hcsSystem, result **uint16) (hr error) = vmcompute.HcsCreateComputeSystem?
+//sys hcsOpenComputeSystem(id string, computeSystem *hcsSystem, result **uint16) (hr error) = vmcompute.HcsOpenComputeSystem?
+//sys hcsCloseComputeSystem(computeSystem hcsSystem) (hr error) = vmcompute.HcsCloseComputeSystem?
+//sys hcsStartComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsStartComputeSystem?
+//sys hcsShutdownComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsShutdownComputeSystem?
+//sys hcsTerminateComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsTerminateComputeSystem?
+//sys hcsPauseComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsPauseComputeSystem?
+//sys hcsResumeComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsResumeComputeSystem?
+//sys hcsGetComputeSystemProperties(computeSystem hcsSystem, propertyQuery string, properties **uint16, result **uint16) (hr error) = vmcompute.HcsGetComputeSystemProperties?
+//sys hcsModifyComputeSystem(computeSystem hcsSystem, configuration string, result **uint16) (hr error) = vmcompute.HcsModifyComputeSystem?
+//sys hcsRegisterComputeSystemCallback(computeSystem hcsSystem, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) = vmcompute.HcsRegisterComputeSystemCallback?
+//sys hcsUnregisterComputeSystemCallback(callbackHandle hcsCallback) (hr error) = vmcompute.HcsUnregisterComputeSystemCallback?
+
+//sys hcsCreateProcess(computeSystem hcsSystem, processParameters string, processInformation *hcsProcessInformation, process *hcsProcess, result **uint16) (hr error) = vmcompute.HcsCreateProcess?
+//sys hcsOpenProcess(computeSystem hcsSystem, pid uint32, process *hcsProcess, result **uint16) (hr error) = vmcompute.HcsOpenProcess?
+//sys hcsCloseProcess(process hcsProcess) (hr error) = vmcompute.HcsCloseProcess?
+//sys hcsTerminateProcess(process hcsProcess, result **uint16) (hr error) = vmcompute.HcsTerminateProcess?
+//sys hcsSignalProcess(process hcsProcess, options string, result **uint16) (hr error) = vmcompute.HcsTerminateProcess?
+//sys hcsGetProcessInfo(process hcsProcess, processInformation *hcsProcessInformation, result **uint16) (hr error) = vmcompute.HcsGetProcessInfo?
+//sys hcsGetProcessProperties(process hcsProcess, processProperties **uint16, result **uint16) (hr error) = vmcompute.HcsGetProcessProperties?
+//sys hcsModifyProcess(process hcsProcess, settings string, result **uint16) (hr error) = vmcompute.HcsModifyProcess?
+//sys hcsGetServiceProperties(propertyQuery string, properties **uint16, result **uint16) (hr error) = vmcompute.HcsGetServiceProperties?
+//sys hcsRegisterProcessCallback(process hcsProcess, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) = vmcompute.HcsRegisterProcessCallback?
+//sys hcsUnregisterProcessCallback(callbackHandle hcsCallback) (hr error) = vmcompute.HcsUnregisterProcessCallback?
+
+type hcsSystem syscall.Handle
+type hcsProcess syscall.Handle
+type hcsCallback syscall.Handle
+
+type hcsProcessInformation struct {
+ ProcessId uint32
+ Reserved uint32
+ StdInput syscall.Handle
+ StdOutput syscall.Handle
+ StdError syscall.Handle
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/log.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/log.go
new file mode 100644
index 000000000..90d164e35
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/log.go
@@ -0,0 +1,15 @@
+package hcs
+
+import "github.com/sirupsen/logrus"
+
+func logOperationBegin(ctx logrus.Fields, msg string) {
+ logrus.WithFields(ctx).Debug(msg)
+}
+
+func logOperationEnd(ctx logrus.Fields, msg string, err error) {
+ if err == nil {
+ logrus.WithFields(ctx).Debug(msg)
+ } else {
+ logrus.WithFields(ctx).WithError(err).Error(msg)
+ }
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go
new file mode 100644
index 000000000..42598cf2f
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/process.go
@@ -0,0 +1,465 @@
+package hcs
+
+import (
+ "encoding/json"
+ "io"
+ "sync"
+ "syscall"
+ "time"
+
+ "github.com/Microsoft/hcsshim/internal/guestrequest"
+ "github.com/Microsoft/hcsshim/internal/interop"
+ "github.com/Microsoft/hcsshim/internal/logfields"
+ "github.com/sirupsen/logrus"
+)
+
+// ContainerError is an error encountered in HCS
+type Process struct {
+ handleLock sync.RWMutex
+ handle hcsProcess
+ processID int
+ system *System
+ cachedPipes *cachedPipes
+ callbackNumber uintptr
+
+ logctx logrus.Fields
+}
+
+func newProcess(process hcsProcess, processID int, computeSystem *System) *Process {
+ return &Process{
+ handle: process,
+ processID: processID,
+ system: computeSystem,
+ logctx: logrus.Fields{
+ logfields.HCSOperation: "",
+ logfields.ContainerID: computeSystem.ID(),
+ logfields.ProcessID: processID,
+ },
+ }
+}
+
+type cachedPipes struct {
+ stdIn syscall.Handle
+ stdOut syscall.Handle
+ stdErr syscall.Handle
+}
+
+type processModifyRequest struct {
+ Operation string
+ ConsoleSize *consoleSize `json:",omitempty"`
+ CloseHandle *closeHandle `json:",omitempty"`
+}
+
+type consoleSize struct {
+ Height uint16
+ Width uint16
+}
+
+type closeHandle struct {
+ Handle string
+}
+
+type ProcessStatus struct {
+ ProcessID uint32
+ Exited bool
+ ExitCode uint32
+ LastWaitResult int32
+}
+
+const (
+ stdIn string = "StdIn"
+ stdOut string = "StdOut"
+ stdErr string = "StdErr"
+)
+
+const (
+ modifyConsoleSize string = "ConsoleSize"
+ modifyCloseHandle string = "CloseHandle"
+)
+
+// Pid returns the process ID of the process within the container.
+func (process *Process) Pid() int {
+ return process.processID
+}
+
+// SystemID returns the ID of the process's compute system.
+func (process *Process) SystemID() string {
+ return process.system.ID()
+}
+
+func (process *Process) logOperationBegin(operation string) {
+ process.logctx[logfields.HCSOperation] = operation
+ logOperationBegin(
+ process.logctx,
+ "hcsshim::Process - Begin Operation")
+}
+
+func (process *Process) logOperationEnd(err error) {
+ var result string
+ if err == nil {
+ result = "Success"
+ } else {
+ result = "Error"
+ }
+
+ logOperationEnd(
+ process.logctx,
+ "hcsshim::Process - End Operation - "+result,
+ err)
+ process.logctx[logfields.HCSOperation] = ""
+}
+
+// Signal signals the process with `options`.
+func (process *Process) Signal(options guestrequest.SignalProcessOptions) (err error) {
+ process.handleLock.RLock()
+ defer process.handleLock.RUnlock()
+
+ operation := "hcsshim::Process::Signal"
+ process.logOperationBegin(operation)
+ defer process.logOperationEnd(err)
+
+ if process.handle == 0 {
+ return makeProcessError(process, operation, ErrAlreadyClosed, nil)
+ }
+
+ optionsb, err := json.Marshal(options)
+ if err != nil {
+ return err
+ }
+
+ optionsStr := string(optionsb)
+
+ var resultp *uint16
+ completed := false
+ go syscallWatcher(process.logctx, &completed)
+ err = hcsSignalProcess(process.handle, optionsStr, &resultp)
+ completed = true
+ events := processHcsResult(resultp)
+ if err != nil {
+ return makeProcessError(process, operation, err, events)
+ }
+
+ return nil
+}
+
+// Kill signals the process to terminate but does not wait for it to finish terminating.
+func (process *Process) Kill() (err error) {
+ process.handleLock.RLock()
+ defer process.handleLock.RUnlock()
+
+ operation := "hcsshim::Process::Kill"
+ process.logOperationBegin(operation)
+ defer process.logOperationEnd(err)
+
+ if process.handle == 0 {
+ return makeProcessError(process, operation, ErrAlreadyClosed, nil)
+ }
+
+ var resultp *uint16
+ completed := false
+ go syscallWatcher(process.logctx, &completed)
+ err = hcsTerminateProcess(process.handle, &resultp)
+ completed = true
+ events := processHcsResult(resultp)
+ if err != nil {
+ return makeProcessError(process, operation, err, events)
+ }
+
+ return nil
+}
+
+// Wait waits for the process to exit.
+func (process *Process) Wait() (err error) {
+ operation := "hcsshim::Process::Wait"
+ process.logOperationBegin(operation)
+ defer process.logOperationEnd(err)
+
+ err = waitForNotification(process.callbackNumber, hcsNotificationProcessExited, nil)
+ if err != nil {
+ return makeProcessError(process, operation, err, nil)
+ }
+
+ return nil
+}
+
+// WaitTimeout waits for the process to exit or the duration to elapse. It returns
+// false if timeout occurs.
+func (process *Process) WaitTimeout(timeout time.Duration) (err error) {
+ operation := "hcssshim::Process::WaitTimeout"
+ process.logOperationBegin(operation)
+ defer process.logOperationEnd(err)
+
+ err = waitForNotification(process.callbackNumber, hcsNotificationProcessExited, &timeout)
+ if err != nil {
+ return makeProcessError(process, operation, err, nil)
+ }
+
+ return nil
+}
+
+// ResizeConsole resizes the console of the process.
+func (process *Process) ResizeConsole(width, height uint16) (err error) {
+ process.handleLock.RLock()
+ defer process.handleLock.RUnlock()
+
+ operation := "hcsshim::Process::ResizeConsole"
+ process.logOperationBegin(operation)
+ defer process.logOperationEnd(err)
+
+ if process.handle == 0 {
+ return makeProcessError(process, operation, ErrAlreadyClosed, nil)
+ }
+
+ modifyRequest := processModifyRequest{
+ Operation: modifyConsoleSize,
+ ConsoleSize: &consoleSize{
+ Height: height,
+ Width: width,
+ },
+ }
+
+ modifyRequestb, err := json.Marshal(modifyRequest)
+ if err != nil {
+ return err
+ }
+
+ modifyRequestStr := string(modifyRequestb)
+
+ var resultp *uint16
+ err = hcsModifyProcess(process.handle, modifyRequestStr, &resultp)
+ events := processHcsResult(resultp)
+ if err != nil {
+ return makeProcessError(process, operation, err, events)
+ }
+
+ return nil
+}
+
+func (process *Process) Properties() (_ *ProcessStatus, err error) {
+ process.handleLock.RLock()
+ defer process.handleLock.RUnlock()
+
+ operation := "hcsshim::Process::Properties"
+ process.logOperationBegin(operation)
+ defer process.logOperationEnd(err)
+
+ if process.handle == 0 {
+ return nil, makeProcessError(process, operation, ErrAlreadyClosed, nil)
+ }
+
+ var (
+ resultp *uint16
+ propertiesp *uint16
+ )
+ completed := false
+ go syscallWatcher(process.logctx, &completed)
+ err = hcsGetProcessProperties(process.handle, &propertiesp, &resultp)
+ completed = true
+ events := processHcsResult(resultp)
+ if err != nil {
+ return nil, makeProcessError(process, operation, err, events)
+ }
+
+ if propertiesp == nil {
+ return nil, ErrUnexpectedValue
+ }
+ propertiesRaw := interop.ConvertAndFreeCoTaskMemBytes(propertiesp)
+
+ properties := &ProcessStatus{}
+ if err := json.Unmarshal(propertiesRaw, properties); err != nil {
+ return nil, makeProcessError(process, operation, err, nil)
+ }
+
+ return properties, nil
+}
+
+// ExitCode returns the exit code of the process. The process must have
+// already terminated.
+func (process *Process) ExitCode() (_ int, err error) {
+ operation := "hcsshim::Process::ExitCode"
+ process.logOperationBegin(operation)
+ defer process.logOperationEnd(err)
+
+ properties, err := process.Properties()
+ if err != nil {
+ return 0, makeProcessError(process, operation, err, nil)
+ }
+
+ if properties.Exited == false {
+ return 0, makeProcessError(process, operation, ErrInvalidProcessState, nil)
+ }
+
+ if properties.LastWaitResult != 0 {
+ return 0, makeProcessError(process, operation, syscall.Errno(properties.LastWaitResult), nil)
+ }
+
+ return int(properties.ExitCode), nil
+}
+
+// Stdio returns the stdin, stdout, and stderr pipes, respectively. Closing
+// these pipes does not close the underlying pipes; it should be possible to
+// call this multiple times to get multiple interfaces.
+func (process *Process) Stdio() (_ io.WriteCloser, _ io.ReadCloser, _ io.ReadCloser, err error) {
+ process.handleLock.RLock()
+ defer process.handleLock.RUnlock()
+
+ operation := "hcsshim::Process::Stdio"
+ process.logOperationBegin(operation)
+ defer process.logOperationEnd(err)
+
+ if process.handle == 0 {
+ return nil, nil, nil, makeProcessError(process, operation, ErrAlreadyClosed, nil)
+ }
+
+ var stdIn, stdOut, stdErr syscall.Handle
+
+ if process.cachedPipes == nil {
+ var (
+ processInfo hcsProcessInformation
+ resultp *uint16
+ )
+ err = hcsGetProcessInfo(process.handle, &processInfo, &resultp)
+ events := processHcsResult(resultp)
+ if err != nil {
+ return nil, nil, nil, makeProcessError(process, operation, err, events)
+ }
+
+ stdIn, stdOut, stdErr = processInfo.StdInput, processInfo.StdOutput, processInfo.StdError
+ } else {
+ // Use cached pipes
+ stdIn, stdOut, stdErr = process.cachedPipes.stdIn, process.cachedPipes.stdOut, process.cachedPipes.stdErr
+
+ // Invalidate the cache
+ process.cachedPipes = nil
+ }
+
+ pipes, err := makeOpenFiles([]syscall.Handle{stdIn, stdOut, stdErr})
+ if err != nil {
+ return nil, nil, nil, makeProcessError(process, operation, err, nil)
+ }
+
+ return pipes[0], pipes[1], pipes[2], nil
+}
+
+// CloseStdin closes the write side of the stdin pipe so that the process is
+// notified on the read side that there is no more data in stdin.
+func (process *Process) CloseStdin() (err error) {
+ process.handleLock.RLock()
+ defer process.handleLock.RUnlock()
+
+ operation := "hcsshim::Process::CloseStdin"
+ process.logOperationBegin(operation)
+ defer process.logOperationEnd(err)
+
+ if process.handle == 0 {
+ return makeProcessError(process, operation, ErrAlreadyClosed, nil)
+ }
+
+ modifyRequest := processModifyRequest{
+ Operation: modifyCloseHandle,
+ CloseHandle: &closeHandle{
+ Handle: stdIn,
+ },
+ }
+
+ modifyRequestb, err := json.Marshal(modifyRequest)
+ if err != nil {
+ return err
+ }
+
+ modifyRequestStr := string(modifyRequestb)
+
+ var resultp *uint16
+ err = hcsModifyProcess(process.handle, modifyRequestStr, &resultp)
+ events := processHcsResult(resultp)
+ if err != nil {
+ return makeProcessError(process, operation, err, events)
+ }
+
+ return nil
+}
+
+// Close cleans up any state associated with the process but does not kill
+// or wait on it.
+func (process *Process) Close() (err error) {
+ process.handleLock.Lock()
+ defer process.handleLock.Unlock()
+
+ operation := "hcsshim::Process::Close"
+ process.logOperationBegin(operation)
+ defer process.logOperationEnd(err)
+
+ // Don't double free this
+ if process.handle == 0 {
+ return nil
+ }
+
+ if err = process.unregisterCallback(); err != nil {
+ return makeProcessError(process, operation, err, nil)
+ }
+
+ if err = hcsCloseProcess(process.handle); err != nil {
+ return makeProcessError(process, operation, err, nil)
+ }
+
+ process.handle = 0
+
+ return nil
+}
+
+func (process *Process) registerCallback() error {
+ context := &notifcationWatcherContext{
+ channels: newChannels(),
+ }
+
+ callbackMapLock.Lock()
+ callbackNumber := nextCallback
+ nextCallback++
+ callbackMap[callbackNumber] = context
+ callbackMapLock.Unlock()
+
+ var callbackHandle hcsCallback
+ err := hcsRegisterProcessCallback(process.handle, notificationWatcherCallback, callbackNumber, &callbackHandle)
+ if err != nil {
+ return err
+ }
+ context.handle = callbackHandle
+ process.callbackNumber = callbackNumber
+
+ return nil
+}
+
+func (process *Process) unregisterCallback() error {
+ callbackNumber := process.callbackNumber
+
+ 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
+
+ return nil
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go
new file mode 100644
index 000000000..2629380fd
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/system.go
@@ -0,0 +1,667 @@
+package hcs
+
+import (
+ "encoding/json"
+ "os"
+ "strconv"
+ "sync"
+ "syscall"
+ "time"
+
+ "github.com/Microsoft/hcsshim/internal/interop"
+ "github.com/Microsoft/hcsshim/internal/logfields"
+ "github.com/Microsoft/hcsshim/internal/schema1"
+ "github.com/Microsoft/hcsshim/internal/timeout"
+ "github.com/sirupsen/logrus"
+)
+
+// currentContainerStarts is used to limit the number of concurrent container
+// starts.
+var currentContainerStarts containerStarts
+
+type containerStarts struct {
+ maxParallel int
+ inProgress int
+ sync.Mutex
+}
+
+func init() {
+ mpsS := os.Getenv("HCSSHIM_MAX_PARALLEL_START")
+ if len(mpsS) > 0 {
+ mpsI, err := strconv.Atoi(mpsS)
+ if err != nil || mpsI < 0 {
+ return
+ }
+ currentContainerStarts.maxParallel = mpsI
+ }
+}
+
+type System struct {
+ handleLock sync.RWMutex
+ handle hcsSystem
+ id string
+ callbackNumber uintptr
+
+ logctx logrus.Fields
+}
+
+func newSystem(id string) *System {
+ return &System{
+ id: id,
+ logctx: logrus.Fields{
+ logfields.HCSOperation: "",
+ logfields.ContainerID: id,
+ },
+ }
+}
+
+func (computeSystem *System) logOperationBegin(operation string) {
+ computeSystem.logctx[logfields.HCSOperation] = operation
+ logOperationBegin(
+ computeSystem.logctx,
+ "hcsshim::ComputeSystem - Begin Operation")
+}
+
+func (computeSystem *System) logOperationEnd(err error) {
+ var result string
+ if err == nil {
+ result = "Success"
+ } else {
+ result = "Error"
+ }
+
+ logOperationEnd(
+ computeSystem.logctx,
+ "hcsshim::ComputeSystem - End Operation - "+result,
+ err)
+ computeSystem.logctx[logfields.HCSOperation] = ""
+}
+
+// CreateComputeSystem creates a new compute system with the given configuration but does not start it.
+func CreateComputeSystem(id string, hcsDocumentInterface interface{}) (_ *System, err error) {
+ operation := "hcsshim::CreateComputeSystem"
+
+ computeSystem := newSystem(id)
+ computeSystem.logOperationBegin(operation)
+ defer computeSystem.logOperationEnd(err)
+
+ hcsDocumentB, err := json.Marshal(hcsDocumentInterface)
+ if err != nil {
+ return nil, err
+ }
+
+ hcsDocument := string(hcsDocumentB)
+
+ logrus.WithFields(computeSystem.logctx).
+ WithField(logfields.JSON, hcsDocument).
+ Debug("HCS ComputeSystem Document")
+
+ var (
+ resultp *uint16
+ identity syscall.Handle
+ )
+ completed := false
+ go syscallWatcher(computeSystem.logctx, &completed)
+ createError := hcsCreateComputeSystem(id, hcsDocument, identity, &computeSystem.handle, &resultp)
+ completed = true
+
+ if createError == nil || IsPending(createError) {
+ if err = computeSystem.registerCallback(); err != nil {
+ // Terminate the compute system if it still exists. We're okay to
+ // ignore a failure here.
+ computeSystem.Terminate()
+ return nil, makeSystemError(computeSystem, operation, "", err, nil)
+ }
+ }
+
+ 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
+ // ignore a failure here.
+ computeSystem.Terminate()
+ }
+ return nil, makeSystemError(computeSystem, operation, hcsDocument, err, events)
+ }
+
+ return computeSystem, nil
+}
+
+// OpenComputeSystem opens an existing compute system by ID.
+func OpenComputeSystem(id string) (_ *System, err error) {
+ operation := "hcsshim::OpenComputeSystem"
+
+ computeSystem := newSystem(id)
+ computeSystem.logOperationBegin(operation)
+ defer computeSystem.logOperationEnd(err)
+
+ var (
+ handle hcsSystem
+ resultp *uint16
+ )
+ err = hcsOpenComputeSystem(id, &handle, &resultp)
+ events := processHcsResult(resultp)
+ if err != nil {
+ return nil, makeSystemError(computeSystem, operation, "", err, events)
+ }
+
+ computeSystem.handle = handle
+
+ if err = computeSystem.registerCallback(); err != nil {
+ return nil, makeSystemError(computeSystem, operation, "", err, nil)
+ }
+
+ return computeSystem, nil
+}
+
+// GetComputeSystems gets a list of the compute systems on the system that match the query
+func GetComputeSystems(q schema1.ComputeSystemQuery) (_ []schema1.ContainerProperties, err error) {
+ operation := "hcsshim::GetComputeSystems"
+ fields := logrus.Fields{
+ logfields.HCSOperation: operation,
+ }
+ logOperationBegin(
+ fields,
+ "hcsshim::ComputeSystem - Begin Operation")
+
+ defer func() {
+ var result string
+ if err == nil {
+ result = "Success"
+ } else {
+ result = "Error"
+ }
+
+ logOperationEnd(
+ fields,
+ "hcsshim::ComputeSystem - End Operation - "+result,
+ err)
+ }()
+
+ queryb, err := json.Marshal(q)
+ if err != nil {
+ return nil, err
+ }
+
+ query := string(queryb)
+
+ logrus.WithFields(fields).
+ WithField(logfields.JSON, query).
+ Debug("HCS ComputeSystem Query")
+
+ var (
+ resultp *uint16
+ computeSystemsp *uint16
+ )
+ completed := false
+ go syscallWatcher(fields, &completed)
+ err = hcsEnumerateComputeSystems(query, &computeSystemsp, &resultp)
+ completed = true
+ events := processHcsResult(resultp)
+ if err != nil {
+ return nil, &HcsError{Op: operation, Err: err, Events: events}
+ }
+
+ if computeSystemsp == nil {
+ return nil, ErrUnexpectedValue
+ }
+ computeSystemsRaw := interop.ConvertAndFreeCoTaskMemBytes(computeSystemsp)
+ computeSystems := []schema1.ContainerProperties{}
+ if err = json.Unmarshal(computeSystemsRaw, &computeSystems); err != nil {
+ return nil, err
+ }
+
+ return computeSystems, nil
+}
+
+// Start synchronously starts the computeSystem.
+func (computeSystem *System) Start() (err error) {
+ computeSystem.handleLock.RLock()
+ defer computeSystem.handleLock.RUnlock()
+
+ operation := "hcsshim::ComputeSystem::Start"
+ computeSystem.logOperationBegin(operation)
+ defer computeSystem.logOperationEnd(err)
+
+ if computeSystem.handle == 0 {
+ return makeSystemError(computeSystem, "Start", "", ErrAlreadyClosed, nil)
+ }
+
+ // This is a very simple backoff-retry loop to limit the number
+ // of parallel container starts if environment variable
+ // HCSSHIM_MAX_PARALLEL_START is set to a positive integer.
+ // It should generally only be used as a workaround to various
+ // platform issues that exist between RS1 and RS4 as of Aug 2018
+ if currentContainerStarts.maxParallel > 0 {
+ for {
+ currentContainerStarts.Lock()
+ if currentContainerStarts.inProgress < currentContainerStarts.maxParallel {
+ currentContainerStarts.inProgress++
+ currentContainerStarts.Unlock()
+ break
+ }
+ if currentContainerStarts.inProgress == currentContainerStarts.maxParallel {
+ currentContainerStarts.Unlock()
+ time.Sleep(100 * time.Millisecond)
+ }
+ }
+ // Make sure we decrement the count when we are done.
+ defer func() {
+ currentContainerStarts.Lock()
+ currentContainerStarts.inProgress--
+ currentContainerStarts.Unlock()
+ }()
+ }
+
+ var resultp *uint16
+ completed := false
+ go syscallWatcher(computeSystem.logctx, &completed)
+ err = hcsStartComputeSystem(computeSystem.handle, "", &resultp)
+ completed = true
+ events, err := processAsyncHcsResult(err, resultp, computeSystem.callbackNumber, hcsNotificationSystemStartCompleted, &timeout.SystemStart)
+ if err != nil {
+ return makeSystemError(computeSystem, "Start", "", err, events)
+ }
+
+ return nil
+}
+
+// ID returns the compute system's identifier.
+func (computeSystem *System) ID() string {
+ return computeSystem.id
+}
+
+// Shutdown requests a compute system shutdown, if IsPending() on the error returned is true,
+// it may not actually be shut down until Wait() succeeds.
+func (computeSystem *System) Shutdown() (err error) {
+ computeSystem.handleLock.RLock()
+ defer computeSystem.handleLock.RUnlock()
+
+ operation := "hcsshim::ComputeSystem::Shutdown"
+ computeSystem.logOperationBegin(operation)
+ defer computeSystem.logOperationEnd(err)
+
+ if computeSystem.handle == 0 {
+ return makeSystemError(computeSystem, "Shutdown", "", ErrAlreadyClosed, nil)
+ }
+
+ var resultp *uint16
+ completed := false
+ go syscallWatcher(computeSystem.logctx, &completed)
+ err = hcsShutdownComputeSystem(computeSystem.handle, "", &resultp)
+ completed = true
+ events := processHcsResult(resultp)
+ if err != nil {
+ return makeSystemError(computeSystem, "Shutdown", "", err, events)
+ }
+
+ return nil
+}
+
+// Terminate requests a compute system terminate, if IsPending() on the error returned is true,
+// it may not actually be shut down until Wait() succeeds.
+func (computeSystem *System) Terminate() (err error) {
+ computeSystem.handleLock.RLock()
+ defer computeSystem.handleLock.RUnlock()
+
+ operation := "hcsshim::ComputeSystem::Terminate"
+ computeSystem.logOperationBegin(operation)
+ defer computeSystem.logOperationEnd(err)
+
+ if computeSystem.handle == 0 {
+ return makeSystemError(computeSystem, "Terminate", "", ErrAlreadyClosed, nil)
+ }
+
+ var resultp *uint16
+ completed := false
+ go syscallWatcher(computeSystem.logctx, &completed)
+ err = hcsTerminateComputeSystem(computeSystem.handle, "", &resultp)
+ completed = true
+ events := processHcsResult(resultp)
+ if err != nil {
+ return makeSystemError(computeSystem, "Terminate", "", err, events)
+ }
+
+ return nil
+}
+
+// Wait synchronously waits for the compute system to shutdown or terminate.
+func (computeSystem *System) Wait() (err error) {
+ operation := "hcsshim::ComputeSystem::Wait"
+ computeSystem.logOperationBegin(operation)
+ defer computeSystem.logOperationEnd(err)
+
+ err = waitForNotification(computeSystem.callbackNumber, hcsNotificationSystemExited, nil)
+ if err != nil {
+ return makeSystemError(computeSystem, "Wait", "", err, nil)
+ }
+
+ return nil
+}
+
+// WaitTimeout synchronously waits for the compute system to terminate or the duration to elapse.
+// If the timeout expires, IsTimeout(err) == true
+func (computeSystem *System) WaitTimeout(timeout time.Duration) (err error) {
+ operation := "hcsshim::ComputeSystem::WaitTimeout"
+ computeSystem.logOperationBegin(operation)
+ defer computeSystem.logOperationEnd(err)
+
+ err = waitForNotification(computeSystem.callbackNumber, hcsNotificationSystemExited, &timeout)
+ if err != nil {
+ return makeSystemError(computeSystem, "WaitTimeout", "", err, nil)
+ }
+
+ return nil
+}
+
+func (computeSystem *System) Properties(types ...schema1.PropertyType) (_ *schema1.ContainerProperties, err error) {
+ computeSystem.handleLock.RLock()
+ defer computeSystem.handleLock.RUnlock()
+
+ operation := "hcsshim::ComputeSystem::Properties"
+ computeSystem.logOperationBegin(operation)
+ defer computeSystem.logOperationEnd(err)
+
+ queryj, err := json.Marshal(schema1.PropertyQuery{types})
+ if err != nil {
+ return nil, makeSystemError(computeSystem, "Properties", "", err, nil)
+ }
+
+ logrus.WithFields(computeSystem.logctx).
+ WithField(logfields.JSON, queryj).
+ Debug("HCS ComputeSystem Properties Query")
+
+ var resultp, propertiesp *uint16
+ completed := false
+ go syscallWatcher(computeSystem.logctx, &completed)
+ err = hcsGetComputeSystemProperties(computeSystem.handle, string(queryj), &propertiesp, &resultp)
+ completed = true
+ events := processHcsResult(resultp)
+ if err != nil {
+ return nil, makeSystemError(computeSystem, "Properties", "", err, events)
+ }
+
+ if propertiesp == nil {
+ return nil, ErrUnexpectedValue
+ }
+ propertiesRaw := interop.ConvertAndFreeCoTaskMemBytes(propertiesp)
+ properties := &schema1.ContainerProperties{}
+ if err := json.Unmarshal(propertiesRaw, properties); err != nil {
+ return nil, makeSystemError(computeSystem, "Properties", "", err, nil)
+ }
+
+ return properties, nil
+}
+
+// Pause pauses the execution of the computeSystem. This feature is not enabled in TP5.
+func (computeSystem *System) Pause() (err error) {
+ computeSystem.handleLock.RLock()
+ defer computeSystem.handleLock.RUnlock()
+
+ operation := "hcsshim::ComputeSystem::Pause"
+ computeSystem.logOperationBegin(operation)
+ defer computeSystem.logOperationEnd(err)
+
+ if computeSystem.handle == 0 {
+ return makeSystemError(computeSystem, "Pause", "", ErrAlreadyClosed, nil)
+ }
+
+ var resultp *uint16
+ completed := false
+ go syscallWatcher(computeSystem.logctx, &completed)
+ err = hcsPauseComputeSystem(computeSystem.handle, "", &resultp)
+ completed = true
+ events, err := processAsyncHcsResult(err, resultp, computeSystem.callbackNumber, hcsNotificationSystemPauseCompleted, &timeout.SystemPause)
+ if err != nil {
+ return makeSystemError(computeSystem, "Pause", "", err, events)
+ }
+
+ return nil
+}
+
+// Resume resumes the execution of the computeSystem. This feature is not enabled in TP5.
+func (computeSystem *System) Resume() (err error) {
+ computeSystem.handleLock.RLock()
+ defer computeSystem.handleLock.RUnlock()
+
+ operation := "hcsshim::ComputeSystem::Resume"
+ computeSystem.logOperationBegin(operation)
+ defer computeSystem.logOperationEnd(err)
+
+ if computeSystem.handle == 0 {
+ return makeSystemError(computeSystem, "Resume", "", ErrAlreadyClosed, nil)
+ }
+
+ var resultp *uint16
+ completed := false
+ go syscallWatcher(computeSystem.logctx, &completed)
+ err = hcsResumeComputeSystem(computeSystem.handle, "", &resultp)
+ completed = true
+ events, err := processAsyncHcsResult(err, resultp, computeSystem.callbackNumber, hcsNotificationSystemResumeCompleted, &timeout.SystemResume)
+ if err != nil {
+ return makeSystemError(computeSystem, "Resume", "", err, events)
+ }
+
+ return nil
+}
+
+// CreateProcess launches a new process within the computeSystem.
+func (computeSystem *System) CreateProcess(c interface{}) (_ *Process, err error) {
+ computeSystem.handleLock.RLock()
+ defer computeSystem.handleLock.RUnlock()
+
+ operation := "hcsshim::ComputeSystem::CreateProcess"
+ computeSystem.logOperationBegin(operation)
+ defer computeSystem.logOperationEnd(err)
+
+ var (
+ processInfo hcsProcessInformation
+ processHandle hcsProcess
+ resultp *uint16
+ )
+
+ if computeSystem.handle == 0 {
+ return nil, makeSystemError(computeSystem, "CreateProcess", "", ErrAlreadyClosed, nil)
+ }
+
+ configurationb, err := json.Marshal(c)
+ if err != nil {
+ return nil, makeSystemError(computeSystem, "CreateProcess", "", err, nil)
+ }
+
+ configuration := string(configurationb)
+
+ logrus.WithFields(computeSystem.logctx).
+ WithField(logfields.JSON, configuration).
+ Debug("HCS ComputeSystem Process Document")
+
+ completed := false
+ go syscallWatcher(computeSystem.logctx, &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)
+ }
+
+ logrus.WithFields(computeSystem.logctx).
+ WithField(logfields.ProcessID, processInfo.ProcessId).
+ Debug("HCS ComputeSystem CreateProcess PID")
+
+ process := newProcess(processHandle, int(processInfo.ProcessId), computeSystem)
+ process.cachedPipes = &cachedPipes{
+ stdIn: processInfo.StdInput,
+ stdOut: processInfo.StdOutput,
+ stdErr: processInfo.StdError,
+ }
+
+ if err = process.registerCallback(); err != nil {
+ return nil, makeSystemError(computeSystem, "CreateProcess", "", err, nil)
+ }
+
+ return process, nil
+}
+
+// OpenProcess gets an interface to an existing process within the computeSystem.
+func (computeSystem *System) OpenProcess(pid int) (_ *Process, err error) {
+ computeSystem.handleLock.RLock()
+ defer computeSystem.handleLock.RUnlock()
+
+ // Add PID for the context of this operation
+ computeSystem.logctx[logfields.ProcessID] = pid
+ defer delete(computeSystem.logctx, logfields.ProcessID)
+
+ operation := "hcsshim::ComputeSystem::OpenProcess"
+ computeSystem.logOperationBegin(operation)
+ defer computeSystem.logOperationEnd(err)
+
+ var (
+ processHandle hcsProcess
+ resultp *uint16
+ )
+
+ if computeSystem.handle == 0 {
+ return nil, makeSystemError(computeSystem, "OpenProcess", "", ErrAlreadyClosed, nil)
+ }
+
+ completed := false
+ go syscallWatcher(computeSystem.logctx, &completed)
+ err = hcsOpenProcess(computeSystem.handle, uint32(pid), &processHandle, &resultp)
+ completed = true
+ events := processHcsResult(resultp)
+ if err != nil {
+ return nil, makeSystemError(computeSystem, "OpenProcess", "", err, events)
+ }
+
+ process := newProcess(processHandle, pid, computeSystem)
+ if err = process.registerCallback(); err != nil {
+ return nil, makeSystemError(computeSystem, "OpenProcess", "", err, nil)
+ }
+
+ return process, nil
+}
+
+// Close cleans up any state associated with the compute system but does not terminate or wait for it.
+func (computeSystem *System) Close() (err error) {
+ computeSystem.handleLock.Lock()
+ defer computeSystem.handleLock.Unlock()
+
+ operation := "hcsshim::ComputeSystem::Close"
+ computeSystem.logOperationBegin(operation)
+ defer computeSystem.logOperationEnd(err)
+
+ // Don't double free this
+ if computeSystem.handle == 0 {
+ return nil
+ }
+
+ if err = computeSystem.unregisterCallback(); err != nil {
+ return makeSystemError(computeSystem, "Close", "", err, nil)
+ }
+
+ completed := false
+ go syscallWatcher(computeSystem.logctx, &completed)
+ err = hcsCloseComputeSystem(computeSystem.handle)
+ completed = true
+ if err != nil {
+ return makeSystemError(computeSystem, "Close", "", err, nil)
+ }
+
+ computeSystem.handle = 0
+
+ return nil
+}
+
+func (computeSystem *System) registerCallback() error {
+ context := &notifcationWatcherContext{
+ channels: newChannels(),
+ }
+
+ callbackMapLock.Lock()
+ callbackNumber := nextCallback
+ nextCallback++
+ callbackMap[callbackNumber] = context
+ callbackMapLock.Unlock()
+
+ var callbackHandle hcsCallback
+ err := hcsRegisterComputeSystemCallback(computeSystem.handle, notificationWatcherCallback, callbackNumber, &callbackHandle)
+ if err != nil {
+ return err
+ }
+ context.handle = callbackHandle
+ computeSystem.callbackNumber = callbackNumber
+
+ return nil
+}
+
+func (computeSystem *System) unregisterCallback() error {
+ callbackNumber := computeSystem.callbackNumber
+
+ callbackMapLock.RLock()
+ context := callbackMap[callbackNumber]
+ callbackMapLock.RUnlock()
+
+ 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
+
+ return nil
+}
+
+// Modify the System by sending a request to HCS
+func (computeSystem *System) Modify(config interface{}) (err error) {
+ computeSystem.handleLock.RLock()
+ defer computeSystem.handleLock.RUnlock()
+
+ operation := "hcsshim::ComputeSystem::Modify"
+ computeSystem.logOperationBegin(operation)
+ defer computeSystem.logOperationEnd(err)
+
+ if computeSystem.handle == 0 {
+ return makeSystemError(computeSystem, "Modify", "", ErrAlreadyClosed, nil)
+ }
+
+ requestJSON, err := json.Marshal(config)
+ if err != nil {
+ return err
+ }
+
+ requestString := string(requestJSON)
+
+ logrus.WithFields(computeSystem.logctx).
+ WithField(logfields.JSON, requestString).
+ Debug("HCS ComputeSystem Modify Document")
+
+ var resultp *uint16
+ completed := false
+ go syscallWatcher(computeSystem.logctx, &completed)
+ err = hcsModifyComputeSystem(computeSystem.handle, requestString, &resultp)
+ completed = true
+ events := processHcsResult(resultp)
+ if err != nil {
+ return makeSystemError(computeSystem, "Modify", requestString, err, events)
+ }
+
+ return nil
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/utils.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/utils.go
new file mode 100644
index 000000000..a638677ed
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/utils.go
@@ -0,0 +1,33 @@
+package hcs
+
+import (
+ "io"
+ "syscall"
+
+ "github.com/Microsoft/go-winio"
+)
+
+// makeOpenFiles calls winio.MakeOpenFile for each handle in a slice but closes all the handles
+// if there is an error.
+func makeOpenFiles(hs []syscall.Handle) (_ []io.ReadWriteCloser, err error) {
+ fs := make([]io.ReadWriteCloser, len(hs))
+ for i, h := range hs {
+ if h != syscall.Handle(0) {
+ if err == nil {
+ fs[i], err = winio.MakeOpenFile(h)
+ }
+ if err != nil {
+ syscall.Close(h)
+ }
+ }
+ }
+ if err != nil {
+ for _, f := range fs {
+ if f != nil {
+ f.Close()
+ }
+ }
+ return nil, err
+ }
+ return fs, nil
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/waithelper.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/waithelper.go
new file mode 100644
index 000000000..91e212c57
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/waithelper.go
@@ -0,0 +1,63 @@
+package hcs
+
+import (
+ "time"
+
+ "github.com/sirupsen/logrus"
+)
+
+func processAsyncHcsResult(err error, resultp *uint16, callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) ([]ErrorEvent, error) {
+ events := processHcsResult(resultp)
+ if IsPending(err) {
+ return nil, waitForNotification(callbackNumber, expectedNotification, timeout)
+ }
+
+ return events, err
+}
+
+func waitForNotification(callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) error {
+ callbackMapLock.RLock()
+ channels := callbackMap[callbackNumber].channels
+ callbackMapLock.RUnlock()
+
+ expectedChannel := channels[expectedNotification]
+ if expectedChannel == nil {
+ logrus.Errorf("unknown notification type in waitForNotification %x", expectedNotification)
+ return ErrInvalidNotificationType
+ }
+
+ var c <-chan time.Time
+ if timeout != nil {
+ timer := time.NewTimer(*timeout)
+ c = timer.C
+ defer timer.Stop()
+ }
+
+ select {
+ case err, ok := <-expectedChannel:
+ if !ok {
+ return ErrHandleClose
+ }
+ return err
+ 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 _, ok := <-channels[hcsNotificationServiceDisconnect]:
+ if !ok {
+ return ErrHandleClose
+ }
+ // hcsNotificationServiceDisconnect should never be an expected notification
+ // it does not need the same handling as hcsNotificationSystemExited
+ return ErrUnexpectedProcessAbort
+ case <-c:
+ return ErrTimeout
+ }
+ return nil
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/watcher.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/watcher.go
new file mode 100644
index 000000000..e09dd1334
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/watcher.go
@@ -0,0 +1,33 @@
+package hcs
+
+import (
+ "time"
+
+ "github.com/Microsoft/hcsshim/internal/logfields"
+ "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(context, &completed)
+// <syscall>
+// completed = true
+//
+func syscallWatcher(context logrus.Fields, syscallCompleted *bool) {
+ time.Sleep(timeout.SyscallWatcher)
+ if *syscallCompleted {
+ return
+ }
+ logrus.WithFields(context).
+ WithField(logfields.Timeout, timeout.SyscallWatcher).
+ Warning("Syscall did not complete within operation timeout. This may indicate a platform issue. If it appears to be making no forward progress, obtain the stacks and see if there is a syscall stuck in the platform API for a significant length of time.")
+}
diff --git a/vendor/github.com/Microsoft/hcsshim/internal/hcs/zsyscall_windows.go b/vendor/github.com/Microsoft/hcsshim/internal/hcs/zsyscall_windows.go
new file mode 100644
index 000000000..877c69a14
--- /dev/null
+++ b/vendor/github.com/Microsoft/hcsshim/internal/hcs/zsyscall_windows.go
@@ -0,0 +1,462 @@
+// Code generated mksyscall_windows.exe DO NOT EDIT
+
+package hcs
+
+import (
+ "syscall"
+ "unsafe"
+
+ "github.com/Microsoft/hcsshim/internal/interop"
+ "golang.org/x/sys/windows"
+)
+
+var _ unsafe.Pointer
+
+// Do the interface allocations only once for common
+// Errno values.
+const (
+ errnoERROR_IO_PENDING = 997
+)
+
+var (
+ errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING)
+)
+
+// errnoErr returns common boxed Errno values, to prevent
+// allocations at runtime.
+func errnoErr(e syscall.Errno) error {
+ switch e {
+ case 0:
+ return nil
+ case errnoERROR_IO_PENDING:
+ return errERROR_IO_PENDING
+ }
+ // TODO: add more here, after collecting data on the common
+ // error values see on Windows. (perhaps when running
+ // all.bat?)
+ return e
+}
+
+var (
+ modvmcompute = windows.NewLazySystemDLL("vmcompute.dll")
+
+ procHcsEnumerateComputeSystems = modvmcompute.NewProc("HcsEnumerateComputeSystems")
+ procHcsCreateComputeSystem = modvmcompute.NewProc("HcsCreateComputeSystem")
+ procHcsOpenComputeSystem = modvmcompute.NewProc("HcsOpenComputeSystem")
+ procHcsCloseComputeSystem = modvmcompute.NewProc("HcsCloseComputeSystem")
+ procHcsStartComputeSystem = modvmcompute.NewProc("HcsStartComputeSystem")
+ procHcsShutdownComputeSystem = modvmcompute.NewProc("HcsShutdownComputeSystem")
+ procHcsTerminateComputeSystem = modvmcompute.NewProc("HcsTerminateComputeSystem")
+ procHcsPauseComputeSystem = modvmcompute.NewProc("HcsPauseComputeSystem")
+ procHcsResumeComputeSystem = modvmcompute.NewProc("HcsResumeComputeSystem")
+ procHcsGetComputeSystemProperties = modvmcompute.NewProc("HcsGetComputeSystemProperties")
+ procHcsModifyComputeSystem = modvmcompute.NewProc("HcsModifyComputeSystem")
+ procHcsRegisterComputeSystemCallback = modvmcompute.NewProc("HcsRegisterComputeSystemCallback")
+ procHcsUnregisterComputeSystemCallback = modvmcompute.NewProc("HcsUnregisterComputeSystemCallback")
+ procHcsCreateProcess = modvmcompute.NewProc("HcsCreateProcess")
+ procHcsOpenProcess = modvmcompute.NewProc("HcsOpenProcess")
+ procHcsCloseProcess = modvmcompute.NewProc("HcsCloseProcess")
+ procHcsTerminateProcess = modvmcompute.NewProc("HcsTerminateProcess")
+
+ procHcsGetProcessInfo = modvmcompute.NewProc("HcsGetProcessInfo")
+ procHcsGetProcessProperties = modvmcompute.NewProc("HcsGetProcessProperties")
+ procHcsModifyProcess = modvmcompute.NewProc("HcsModifyProcess")
+ procHcsGetServiceProperties = modvmcompute.NewProc("HcsGetServiceProperties")
+ procHcsRegisterProcessCallback = modvmcompute.NewProc("HcsRegisterProcessCallback")
+ procHcsUnregisterProcessCallback = modvmcompute.NewProc("HcsUnregisterProcessCallback")
+)
+
+func hcsEnumerateComputeSystems(query string, computeSystems **uint16, result **uint16) (hr error) {
+ var _p0 *uint16
+ _p0, hr = syscall.UTF16PtrFromString(query)
+ if hr != nil {
+ return
+ }
+ return _hcsEnumerateComputeSystems(_p0, computeSystems, result)
+}
+
+func _hcsEnumerateComputeSystems(query *uint16, computeSystems **uint16, result **uint16) (hr error) {
+ if hr = procHcsEnumerateComputeSystems.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall(procHcsEnumerateComputeSystems.Addr(), 3, uintptr(unsafe.Pointer(query)), uintptr(unsafe.Pointer(computeSystems)), uintptr(unsafe.Pointer(result)))
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsCreateComputeSystem(id string, configuration string, identity syscall.Handle, computeSystem *hcsSystem, result **uint16) (hr error) {
+ var _p0 *uint16
+ _p0, hr = syscall.UTF16PtrFromString(id)
+ if hr != nil {
+ return
+ }
+ var _p1 *uint16
+ _p1, hr = syscall.UTF16PtrFromString(configuration)
+ if hr != nil {
+ return
+ }
+ return _hcsCreateComputeSystem(_p0, _p1, identity, computeSystem, result)
+}
+
+func _hcsCreateComputeSystem(id *uint16, configuration *uint16, identity syscall.Handle, computeSystem *hcsSystem, result **uint16) (hr error) {
+ if hr = procHcsCreateComputeSystem.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall6(procHcsCreateComputeSystem.Addr(), 5, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(configuration)), uintptr(identity), uintptr(unsafe.Pointer(computeSystem)), uintptr(unsafe.Pointer(result)), 0)
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsOpenComputeSystem(id string, computeSystem *hcsSystem, result **uint16) (hr error) {
+ var _p0 *uint16
+ _p0, hr = syscall.UTF16PtrFromString(id)
+ if hr != nil {
+ return
+ }
+ return _hcsOpenComputeSystem(_p0, computeSystem, result)
+}
+
+func _hcsOpenComputeSystem(id *uint16, computeSystem *hcsSystem, result **uint16) (hr error) {
+ if hr = procHcsOpenComputeSystem.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall(procHcsOpenComputeSystem.Addr(), 3, uintptr(unsafe.Pointer(id)), uintptr(unsafe.Pointer(computeSystem)), uintptr(unsafe.Pointer(result)))
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsCloseComputeSystem(computeSystem hcsSystem) (hr error) {
+ if hr = procHcsCloseComputeSystem.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall(procHcsCloseComputeSystem.Addr(), 1, uintptr(computeSystem), 0, 0)
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsStartComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
+ var _p0 *uint16
+ _p0, hr = syscall.UTF16PtrFromString(options)
+ if hr != nil {
+ return
+ }
+ return _hcsStartComputeSystem(computeSystem, _p0, result)
+}
+
+func _hcsStartComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
+ if hr = procHcsStartComputeSystem.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall(procHcsStartComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsShutdownComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
+ var _p0 *uint16
+ _p0, hr = syscall.UTF16PtrFromString(options)
+ if hr != nil {
+ return
+ }
+ return _hcsShutdownComputeSystem(computeSystem, _p0, result)
+}
+
+func _hcsShutdownComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
+ if hr = procHcsShutdownComputeSystem.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall(procHcsShutdownComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsTerminateComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
+ var _p0 *uint16
+ _p0, hr = syscall.UTF16PtrFromString(options)
+ if hr != nil {
+ return
+ }
+ return _hcsTerminateComputeSystem(computeSystem, _p0, result)
+}
+
+func _hcsTerminateComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
+ if hr = procHcsTerminateComputeSystem.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall(procHcsTerminateComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsPauseComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
+ var _p0 *uint16
+ _p0, hr = syscall.UTF16PtrFromString(options)
+ if hr != nil {
+ return
+ }
+ return _hcsPauseComputeSystem(computeSystem, _p0, result)
+}
+
+func _hcsPauseComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
+ if hr = procHcsPauseComputeSystem.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall(procHcsPauseComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsResumeComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) {
+ var _p0 *uint16
+ _p0, hr = syscall.UTF16PtrFromString(options)
+ if hr != nil {
+ return
+ }
+ return _hcsResumeComputeSystem(computeSystem, _p0, result)
+}
+
+func _hcsResumeComputeSystem(computeSystem hcsSystem, options *uint16, result **uint16) (hr error) {
+ if hr = procHcsResumeComputeSystem.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall(procHcsResumeComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsGetComputeSystemProperties(computeSystem hcsSystem, propertyQuery string, properties **uint16, result **uint16) (hr error) {
+ var _p0 *uint16
+ _p0, hr = syscall.UTF16PtrFromString(propertyQuery)
+ if hr != nil {
+ return
+ }
+ return _hcsGetComputeSystemProperties(computeSystem, _p0, properties, result)
+}
+
+func _hcsGetComputeSystemProperties(computeSystem hcsSystem, propertyQuery *uint16, properties **uint16, result **uint16) (hr error) {
+ if hr = procHcsGetComputeSystemProperties.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall6(procHcsGetComputeSystemProperties.Addr(), 4, uintptr(computeSystem), uintptr(unsafe.Pointer(propertyQuery)), uintptr(unsafe.Pointer(properties)), uintptr(unsafe.Pointer(result)), 0, 0)
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsModifyComputeSystem(computeSystem hcsSystem, configuration string, result **uint16) (hr error) {
+ var _p0 *uint16
+ _p0, hr = syscall.UTF16PtrFromString(configuration)
+ if hr != nil {
+ return
+ }
+ return _hcsModifyComputeSystem(computeSystem, _p0, result)
+}
+
+func _hcsModifyComputeSystem(computeSystem hcsSystem, configuration *uint16, result **uint16) (hr error) {
+ if hr = procHcsModifyComputeSystem.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall(procHcsModifyComputeSystem.Addr(), 3, uintptr(computeSystem), uintptr(unsafe.Pointer(configuration)), uintptr(unsafe.Pointer(result)))
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsRegisterComputeSystemCallback(computeSystem hcsSystem, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) {
+ if hr = procHcsRegisterComputeSystemCallback.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall6(procHcsRegisterComputeSystemCallback.Addr(), 4, uintptr(computeSystem), uintptr(callback), uintptr(context), uintptr(unsafe.Pointer(callbackHandle)), 0, 0)
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsUnregisterComputeSystemCallback(callbackHandle hcsCallback) (hr error) {
+ if hr = procHcsUnregisterComputeSystemCallback.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall(procHcsUnregisterComputeSystemCallback.Addr(), 1, uintptr(callbackHandle), 0, 0)
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsCreateProcess(computeSystem hcsSystem, processParameters string, processInformation *hcsProcessInformation, process *hcsProcess, result **uint16) (hr error) {
+ var _p0 *uint16
+ _p0, hr = syscall.UTF16PtrFromString(processParameters)
+ if hr != nil {
+ return
+ }
+ return _hcsCreateProcess(computeSystem, _p0, processInformation, process, result)
+}
+
+func _hcsCreateProcess(computeSystem hcsSystem, processParameters *uint16, processInformation *hcsProcessInformation, process *hcsProcess, result **uint16) (hr error) {
+ if hr = procHcsCreateProcess.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall6(procHcsCreateProcess.Addr(), 5, uintptr(computeSystem), uintptr(unsafe.Pointer(processParameters)), uintptr(unsafe.Pointer(processInformation)), uintptr(unsafe.Pointer(process)), uintptr(unsafe.Pointer(result)), 0)
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsOpenProcess(computeSystem hcsSystem, pid uint32, process *hcsProcess, result **uint16) (hr error) {
+ if hr = procHcsOpenProcess.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall6(procHcsOpenProcess.Addr(), 4, uintptr(computeSystem), uintptr(pid), uintptr(unsafe.Pointer(process)), uintptr(unsafe.Pointer(result)), 0, 0)
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsCloseProcess(process hcsProcess) (hr error) {
+ if hr = procHcsCloseProcess.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall(procHcsCloseProcess.Addr(), 1, uintptr(process), 0, 0)
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsTerminateProcess(process hcsProcess, result **uint16) (hr error) {
+ if hr = procHcsTerminateProcess.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall(procHcsTerminateProcess.Addr(), 2, uintptr(process), uintptr(unsafe.Pointer(result)), 0)
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsSignalProcess(process hcsProcess, options string, result **uint16) (hr error) {
+ var _p0 *uint16
+ _p0, hr = syscall.UTF16PtrFromString(options)
+ if hr != nil {
+ return
+ }
+ return _hcsSignalProcess(process, _p0, result)
+}
+
+func _hcsSignalProcess(process hcsProcess, options *uint16, result **uint16) (hr error) {
+ if hr = procHcsTerminateProcess.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall(procHcsTerminateProcess.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(options)), uintptr(unsafe.Pointer(result)))
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsGetProcessInfo(process hcsProcess, processInformation *hcsProcessInformation, result **uint16) (hr error) {
+ if hr = procHcsGetProcessInfo.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall(procHcsGetProcessInfo.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(processInformation)), uintptr(unsafe.Pointer(result)))
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsGetProcessProperties(process hcsProcess, processProperties **uint16, result **uint16) (hr error) {
+ if hr = procHcsGetProcessProperties.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall(procHcsGetProcessProperties.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(processProperties)), uintptr(unsafe.Pointer(result)))
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsModifyProcess(process hcsProcess, settings string, result **uint16) (hr error) {
+ var _p0 *uint16
+ _p0, hr = syscall.UTF16PtrFromString(settings)
+ if hr != nil {
+ return
+ }
+ return _hcsModifyProcess(process, _p0, result)
+}
+
+func _hcsModifyProcess(process hcsProcess, settings *uint16, result **uint16) (hr error) {
+ if hr = procHcsModifyProcess.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall(procHcsModifyProcess.Addr(), 3, uintptr(process), uintptr(unsafe.Pointer(settings)), uintptr(unsafe.Pointer(result)))
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsGetServiceProperties(propertyQuery string, properties **uint16, result **uint16) (hr error) {
+ var _p0 *uint16
+ _p0, hr = syscall.UTF16PtrFromString(propertyQuery)
+ if hr != nil {
+ return
+ }
+ return _hcsGetServiceProperties(_p0, properties, result)
+}
+
+func _hcsGetServiceProperties(propertyQuery *uint16, properties **uint16, result **uint16) (hr error) {
+ if hr = procHcsGetServiceProperties.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall(procHcsGetServiceProperties.Addr(), 3, uintptr(unsafe.Pointer(propertyQuery)), uintptr(unsafe.Pointer(properties)), uintptr(unsafe.Pointer(result)))
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsRegisterProcessCallback(process hcsProcess, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) {
+ if hr = procHcsRegisterProcessCallback.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall6(procHcsRegisterProcessCallback.Addr(), 4, uintptr(process), uintptr(callback), uintptr(context), uintptr(unsafe.Pointer(callbackHandle)), 0, 0)
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}
+
+func hcsUnregisterProcessCallback(callbackHandle hcsCallback) (hr error) {
+ if hr = procHcsUnregisterProcessCallback.Find(); hr != nil {
+ return
+ }
+ r0, _, _ := syscall.Syscall(procHcsUnregisterProcessCallback.Addr(), 1, uintptr(callbackHandle), 0, 0)
+ if int32(r0) < 0 {
+ hr = interop.Win32FromHresult(r0)
+ }
+ return
+}