// 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" procCreateProcessWithStdHandlesInComputeSystem = "CreateProcessWithStdHandlesInComputeSystem" 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" procGetSharedBaseImages = "GetBaseImages" procNameToGuid = "NameToGuid" // Name of the standard OLE dll oleDLLName = "Ole32.dll" // Utility functions procCoTaskMemFree = "CoTaskMemFree" // 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 // Timeout on wait calls TimeoutInfinite = 0xFFFFFFFF ) // loadAndFindFromDll finds a procedure in the given 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 loadAndFindFromDll(dllName, procedure string) (dll *syscall.DLL, proc *syscall.Proc, err error) { dll, err = syscall.LoadDLL(dllName) if err != nil { err = fmt.Errorf("Failed to load %s - error %s", dllName, err) logrus.Error(err) return } proc, err = dll.FindProc(procedure) if err != nil { err = fmt.Errorf("Failed to find %s in %s", procedure, dllName) logrus.Error(err) return } return } // loadAndFind finds a procedure in the shim DLL. func loadAndFind(procedure string) (*syscall.DLL, *syscall.Proc, error) { return loadAndFindFromDll(shimDLLName, procedure) } // 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 }