// 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 procCreateComputeSystem = "CreateComputeSystem" procStartComputeSystem = "StartComputeSystem" procCreateProcessInComputeSystem = "CreateProcessInComputeSystem" procWaitForProcessInComputeSystem = "WaitForProcessInComputeSystem" procShutdownComputeSystem = "ShutdownComputeSystem" procTerminateComputeSystem = "TerminateComputeSystem" procTerminateProcessInComputeSystem = "TerminateProcessInComputeSystem" procResizeConsoleInComputeSystem = "ResizeConsoleInComputeSystem" // Storage related functions in the shim DLL procLayerExists = "LayerExists" procCreateLayer = "CreateLayer" procDestroyLayer = "DestroyLayer" procActivateLayer = "ActivateLayer" procDeactivateLayer = "DeactivateLayer" procGetLayerMountPath = "GetLayerMountPath" procCopyLayer = "CopyLayer" procCreateSandboxLayer = "CreateSandboxLayer" procPrepareLayer = "PrepareLayer" procUnprepareLayer = "UnprepareLayer" procExportLayer = "ExportLayer" procImportLayer = "ImportLayer" ) // loadAndFind finds a procedure in the DLL. Note we do NOT do lazy loading as // 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. func loadAndFind(procedure string) (dll *syscall.DLL, proc *syscall.Proc, err error) { logrus.Debugf("hcsshim::loadAndFind %s", procedure) dll, err = syscall.LoadDLL(shimDLLName) if err != nil { err = fmt.Errorf("Failed to load %s - error %s", shimDLLName, err) logrus.Error(err) return nil, nil, err } proc, err = dll.FindProc(procedure) if err != nil { err = fmt.Errorf("Failed to find %s in %s", procedure, shimDLLName) logrus.Error(err) return nil, nil, err } return dll, proc, nil } // 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 }