2015-05-27 16:15:14 -04:00
|
|
|
// Shim for the Host Compute Service (HSC) to manage Windows Server
|
|
|
|
// containers and Hyper-V containers.
|
|
|
|
|
|
|
|
package hcsshim
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"syscall"
|
|
|
|
"unsafe"
|
|
|
|
|
|
|
|
"github.com/Sirupsen/logrus"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
// Name of the shim DLL for access to the HCS
|
|
|
|
shimDLLName = "vmcompute.dll"
|
|
|
|
|
|
|
|
// Container related functions in the shim DLL
|
2015-07-18 20:15:02 -04:00
|
|
|
procCreateComputeSystem = "CreateComputeSystem"
|
|
|
|
procStartComputeSystem = "StartComputeSystem"
|
|
|
|
procCreateProcessWithStdHandlesInComputeSystem = "CreateProcessWithStdHandlesInComputeSystem"
|
|
|
|
procWaitForProcessInComputeSystem = "WaitForProcessInComputeSystem"
|
|
|
|
procShutdownComputeSystem = "ShutdownComputeSystem"
|
|
|
|
procTerminateComputeSystem = "TerminateComputeSystem"
|
|
|
|
procTerminateProcessInComputeSystem = "TerminateProcessInComputeSystem"
|
|
|
|
procResizeConsoleInComputeSystem = "ResizeConsoleInComputeSystem"
|
2015-05-27 16:15:14 -04:00
|
|
|
|
|
|
|
// Storage related functions in the shim DLL
|
2015-07-16 15:07:20 -04:00
|
|
|
procLayerExists = "LayerExists"
|
|
|
|
procCreateLayer = "CreateLayer"
|
|
|
|
procDestroyLayer = "DestroyLayer"
|
|
|
|
procActivateLayer = "ActivateLayer"
|
|
|
|
procDeactivateLayer = "DeactivateLayer"
|
|
|
|
procGetLayerMountPath = "GetLayerMountPath"
|
|
|
|
procCopyLayer = "CopyLayer"
|
|
|
|
procCreateSandboxLayer = "CreateSandboxLayer"
|
|
|
|
procPrepareLayer = "PrepareLayer"
|
|
|
|
procUnprepareLayer = "UnprepareLayer"
|
|
|
|
procExportLayer = "ExportLayer"
|
|
|
|
procImportLayer = "ImportLayer"
|
|
|
|
procGetSharedBaseImages = "GetBaseImages"
|
2015-07-18 20:15:02 -04:00
|
|
|
procNameToGuid = "NameToGuid"
|
2015-07-16 15:07:20 -04:00
|
|
|
|
|
|
|
// Name of the standard OLE dll
|
|
|
|
oleDLLName = "Ole32.dll"
|
|
|
|
|
|
|
|
// Utility functions
|
|
|
|
procCoTaskMemFree = "CoTaskMemFree"
|
2015-10-12 19:34:03 -04:00
|
|
|
|
|
|
|
// Specific user-visible exit codes
|
|
|
|
WaitErrExecFailed = 32767
|
|
|
|
|
|
|
|
// Known Win32 RC values which should be trapped
|
|
|
|
Win32PipeHasBeenEnded = 0x8007006d // WaitForProcessInComputeSystem: The pipe has been ended
|
|
|
|
Win32SystemShutdownIsInProgress = 0x8007045B // ShutdownComputeSystem: A system shutdown is in progress
|
|
|
|
Win32SpecifiedPathInvalid = 0x800700A1 // ShutdownComputeSystem: The specified path is invalid
|
|
|
|
Win32SystemCannotFindThePathSpecified = 0x80070003 // ShutdownComputeSystem: The system cannot find the path specified
|
2015-10-22 17:01:26 -04:00
|
|
|
Win32InvalidArgument = 0x80072726 // CreateProcessInComputeSystem: An invalid argument was supplied
|
2015-10-12 19:34:03 -04:00
|
|
|
|
|
|
|
// Timeout on wait calls
|
|
|
|
TimeoutInfinite = 0xFFFFFFFF
|
2015-05-27 16:15:14 -04:00
|
|
|
)
|
|
|
|
|
2015-07-16 15:07:20 -04:00
|
|
|
// loadAndFindFromDll finds a procedure in the given DLL. Note we do NOT do lazy loading as
|
2015-05-27 16:15:14 -04:00
|
|
|
// go is particularly unfriendly in the case of a mismatch. By that - it panics
|
|
|
|
// if a function can't be found. By explicitly loading, we can control error
|
|
|
|
// handling gracefully without the daemon terminating.
|
2015-07-16 15:07:20 -04:00
|
|
|
func loadAndFindFromDll(dllName, procedure string) (dll *syscall.DLL, proc *syscall.Proc, err error) {
|
|
|
|
dll, err = syscall.LoadDLL(dllName)
|
2015-05-27 16:15:14 -04:00
|
|
|
if err != nil {
|
2015-07-16 15:07:20 -04:00
|
|
|
err = fmt.Errorf("Failed to load %s - error %s", dllName, err)
|
2015-05-27 16:15:14 -04:00
|
|
|
logrus.Error(err)
|
2015-07-16 15:07:20 -04:00
|
|
|
return
|
2015-05-27 16:15:14 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
proc, err = dll.FindProc(procedure)
|
|
|
|
if err != nil {
|
2015-07-16 15:07:20 -04:00
|
|
|
err = fmt.Errorf("Failed to find %s in %s", procedure, dllName)
|
2015-05-27 16:15:14 -04:00
|
|
|
logrus.Error(err)
|
2015-07-16 15:07:20 -04:00
|
|
|
return
|
2015-05-27 16:15:14 -04:00
|
|
|
}
|
|
|
|
|
2015-07-16 15:07:20 -04:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// loadAndFind finds a procedure in the shim DLL.
|
|
|
|
func loadAndFind(procedure string) (*syscall.DLL, *syscall.Proc, error) {
|
|
|
|
|
|
|
|
return loadAndFindFromDll(shimDLLName, procedure)
|
2015-05-27 16:15:14 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// use is a no-op, but the compiler cannot see that it is.
|
|
|
|
// Calling use(p) ensures that p is kept live until that point.
|
|
|
|
/*
|
|
|
|
//go:noescape
|
|
|
|
func use(p unsafe.Pointer)
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Alternate without using //go:noescape and asm.s
|
|
|
|
var temp unsafe.Pointer
|
|
|
|
|
|
|
|
func use(p unsafe.Pointer) {
|
|
|
|
temp = p
|
|
|
|
}
|