hcsshim.go 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // Shim for the Host Compute Service (HCS) to manage Windows Server
  2. // containers and Hyper-V containers.
  3. package hcsshim
  4. import (
  5. "fmt"
  6. "syscall"
  7. "unsafe"
  8. "github.com/Sirupsen/logrus"
  9. )
  10. //go:generate go run mksyscall_windows.go -output zhcsshim.go hcsshim.go
  11. //sys coTaskMemFree(buffer unsafe.Pointer) = ole32.CoTaskMemFree
  12. //sys SetCurrentThreadCompartmentId(compartmentId uint32) (hr error) = iphlpapi.SetCurrentThreadCompartmentId
  13. //sys activateLayer(info *driverInfo, id string) (hr error) = vmcompute.ActivateLayer?
  14. //sys copyLayer(info *driverInfo, srcId string, dstId string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.CopyLayer?
  15. //sys createLayer(info *driverInfo, id string, parent string) (hr error) = vmcompute.CreateLayer?
  16. //sys createSandboxLayer(info *driverInfo, id string, parent string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.CreateSandboxLayer?
  17. //sys expandSandboxSize(info *driverInfo, id string, size uint64) (hr error) = vmcompute.ExpandSandboxSize?
  18. //sys deactivateLayer(info *driverInfo, id string) (hr error) = vmcompute.DeactivateLayer?
  19. //sys destroyLayer(info *driverInfo, id string) (hr error) = vmcompute.DestroyLayer?
  20. //sys exportLayer(info *driverInfo, id string, path string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.ExportLayer?
  21. //sys getLayerMountPath(info *driverInfo, id string, length *uintptr, buffer *uint16) (hr error) = vmcompute.GetLayerMountPath?
  22. //sys getBaseImages(buffer **uint16) (hr error) = vmcompute.GetBaseImages?
  23. //sys importLayer(info *driverInfo, id string, path string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.ImportLayer?
  24. //sys layerExists(info *driverInfo, id string, exists *uint32) (hr error) = vmcompute.LayerExists?
  25. //sys nameToGuid(name string, guid *GUID) (hr error) = vmcompute.NameToGuid?
  26. //sys prepareLayer(info *driverInfo, id string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.PrepareLayer?
  27. //sys unprepareLayer(info *driverInfo, id string) (hr error) = vmcompute.UnprepareLayer?
  28. //sys processBaseImage(path string) (hr error) = vmcompute.ProcessBaseImage?
  29. //sys processUtilityImage(path string) (hr error) = vmcompute.ProcessUtilityImage?
  30. //sys importLayerBegin(info *driverInfo, id string, descriptors []WC_LAYER_DESCRIPTOR, context *uintptr) (hr error) = vmcompute.ImportLayerBegin?
  31. //sys importLayerNext(context uintptr, fileName string, fileInfo *winio.FileBasicInfo) (hr error) = vmcompute.ImportLayerNext?
  32. //sys importLayerWrite(context uintptr, buffer []byte) (hr error) = vmcompute.ImportLayerWrite?
  33. //sys importLayerEnd(context uintptr) (hr error) = vmcompute.ImportLayerEnd?
  34. //sys exportLayerBegin(info *driverInfo, id string, descriptors []WC_LAYER_DESCRIPTOR, context *uintptr) (hr error) = vmcompute.ExportLayerBegin?
  35. //sys exportLayerNext(context uintptr, fileName **uint16, fileInfo *winio.FileBasicInfo, fileSize *int64, deleted *uint32) (hr error) = vmcompute.ExportLayerNext?
  36. //sys exportLayerRead(context uintptr, buffer []byte, bytesRead *uint32) (hr error) = vmcompute.ExportLayerRead?
  37. //sys exportLayerEnd(context uintptr) (hr error) = vmcompute.ExportLayerEnd?
  38. //sys hcsEnumerateComputeSystems(query string, computeSystems **uint16, result **uint16) (hr error) = vmcompute.HcsEnumerateComputeSystems?
  39. //sys hcsCreateComputeSystem(id string, configuration string, identity syscall.Handle, computeSystem *hcsSystem, result **uint16) (hr error) = vmcompute.HcsCreateComputeSystem?
  40. //sys hcsOpenComputeSystem(id string, computeSystem *hcsSystem, result **uint16) (hr error) = vmcompute.HcsOpenComputeSystem?
  41. //sys hcsCloseComputeSystem(computeSystem hcsSystem) (hr error) = vmcompute.HcsCloseComputeSystem?
  42. //sys hcsStartComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsStartComputeSystem?
  43. //sys hcsShutdownComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsShutdownComputeSystem?
  44. //sys hcsTerminateComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsTerminateComputeSystem?
  45. //sys hcsPauseComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsPauseComputeSystem?
  46. //sys hcsResumeComputeSystem(computeSystem hcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsResumeComputeSystem?
  47. //sys hcsGetComputeSystemProperties(computeSystem hcsSystem, propertyQuery string, properties **uint16, result **uint16) (hr error) = vmcompute.HcsGetComputeSystemProperties?
  48. //sys hcsModifyComputeSystem(computeSystem hcsSystem, configuration string, result **uint16) (hr error) = vmcompute.HcsModifyComputeSystem?
  49. //sys hcsRegisterComputeSystemCallback(computeSystem hcsSystem, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) = vmcompute.HcsRegisterComputeSystemCallback?
  50. //sys hcsUnregisterComputeSystemCallback(callbackHandle hcsCallback) (hr error) = vmcompute.HcsUnregisterComputeSystemCallback?
  51. //sys hcsCreateProcess(computeSystem hcsSystem, processParameters string, processInformation *hcsProcessInformation, process *hcsProcess, result **uint16) (hr error) = vmcompute.HcsCreateProcess?
  52. //sys hcsOpenProcess(computeSystem hcsSystem, pid uint32, process *hcsProcess, result **uint16) (hr error) = vmcompute.HcsOpenProcess?
  53. //sys hcsCloseProcess(process hcsProcess) (hr error) = vmcompute.HcsCloseProcess?
  54. //sys hcsTerminateProcess(process hcsProcess, result **uint16) (hr error) = vmcompute.HcsTerminateProcess?
  55. //sys hcsGetProcessInfo(process hcsProcess, processInformation *hcsProcessInformation, result **uint16) (hr error) = vmcompute.HcsGetProcessInfo?
  56. //sys hcsGetProcessProperties(process hcsProcess, processProperties **uint16, result **uint16) (hr error) = vmcompute.HcsGetProcessProperties?
  57. //sys hcsModifyProcess(process hcsProcess, settings string, result **uint16) (hr error) = vmcompute.HcsModifyProcess?
  58. //sys hcsGetServiceProperties(propertyQuery string, properties **uint16, result **uint16) (hr error) = vmcompute.HcsGetServiceProperties?
  59. //sys hcsRegisterProcessCallback(process hcsProcess, callback uintptr, context uintptr, callbackHandle *hcsCallback) (hr error) = vmcompute.HcsRegisterProcessCallback?
  60. //sys hcsUnregisterProcessCallback(callbackHandle hcsCallback) (hr error) = vmcompute.HcsUnregisterProcessCallback?
  61. //sys hcsModifyServiceSettings(settings string, result **uint16) (hr error) = vmcompute.HcsModifyServiceSettings?
  62. //sys _hnsCall(method string, path string, object string, response **uint16) (hr error) = vmcompute.HNSCall?
  63. const (
  64. // Specific user-visible exit codes
  65. WaitErrExecFailed = 32767
  66. ERROR_GEN_FAILURE = syscall.Errno(31)
  67. ERROR_SHUTDOWN_IN_PROGRESS = syscall.Errno(1115)
  68. WSAEINVAL = syscall.Errno(10022)
  69. // Timeout on wait calls
  70. TimeoutInfinite = 0xFFFFFFFF
  71. )
  72. type HcsError struct {
  73. title string
  74. rest string
  75. Err error
  76. }
  77. type hcsSystem syscall.Handle
  78. type hcsProcess syscall.Handle
  79. type hcsCallback syscall.Handle
  80. type hcsProcessInformation struct {
  81. ProcessId uint32
  82. Reserved uint32
  83. StdInput syscall.Handle
  84. StdOutput syscall.Handle
  85. StdError syscall.Handle
  86. }
  87. func makeError(err error, title, rest string) error {
  88. // Pass through DLL errors directly since they do not originate from HCS.
  89. if _, ok := err.(*syscall.DLLError); ok {
  90. return err
  91. }
  92. return &HcsError{title, rest, err}
  93. }
  94. func makeErrorf(err error, title, format string, a ...interface{}) error {
  95. return makeError(err, title, fmt.Sprintf(format, a...))
  96. }
  97. func win32FromError(err error) uint32 {
  98. if herr, ok := err.(*HcsError); ok {
  99. return win32FromError(herr.Err)
  100. }
  101. if code, ok := err.(syscall.Errno); ok {
  102. return uint32(code)
  103. }
  104. return uint32(ERROR_GEN_FAILURE)
  105. }
  106. func win32FromHresult(hr uintptr) uintptr {
  107. if hr&0x1fff0000 == 0x00070000 {
  108. return hr & 0xffff
  109. }
  110. return hr
  111. }
  112. func (e *HcsError) Error() string {
  113. s := e.title
  114. if len(s) > 0 && s[len(s)-1] != ' ' {
  115. s += " "
  116. }
  117. s += fmt.Sprintf("failed in Win32: %s (0x%x)", e.Err, win32FromError(e.Err))
  118. if e.rest != "" {
  119. if e.rest[0] != ' ' {
  120. s += " "
  121. }
  122. s += e.rest
  123. }
  124. return s
  125. }
  126. func convertAndFreeCoTaskMemString(buffer *uint16) string {
  127. str := syscall.UTF16ToString((*[1 << 30]uint16)(unsafe.Pointer(buffer))[:])
  128. coTaskMemFree(unsafe.Pointer(buffer))
  129. return str
  130. }
  131. func convertAndFreeCoTaskMemBytes(buffer *uint16) []byte {
  132. return []byte(convertAndFreeCoTaskMemString(buffer))
  133. }
  134. func processHcsResult(err error, resultp *uint16) error {
  135. if resultp != nil {
  136. result := convertAndFreeCoTaskMemString(resultp)
  137. logrus.Debugf("Result: %s", result)
  138. }
  139. return err
  140. }