package vmcompute
import (
gcontext "context"
"syscall"
"time"
"github.com/Microsoft/hcsshim/internal/interop"
"github.com/Microsoft/hcsshim/internal/log"
"github.com/Microsoft/hcsshim/internal/logfields"
"github.com/Microsoft/hcsshim/internal/oc"
"github.com/Microsoft/hcsshim/internal/timeout"
"go.opencensus.io/trace"
)
//go:generate go run ../../mksyscall_windows.go -output zsyscall_windows.go vmcompute.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 hcsModifyServiceSettings(settings string, result **uint16) (hr error) = vmcompute.HcsModifyServiceSettings?
//sys hcsRegisterComputeSystemCallback(computeSystem HcsSystem, callback uintptr, context uintptr, callbackHandle *HcsCallback) (hr error) = vmcompute.HcsRegisterComputeSystemCallback?
//sys hcsUnregisterComputeSystemCallback(callbackHandle HcsCallback) (hr error) = vmcompute.HcsUnregisterComputeSystemCallback?
//sys hcsSaveComputeSystem(computeSystem HcsSystem, options string, result **uint16) (hr error) = vmcompute.HcsSaveComputeSystem?
//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.HcsSignalProcess?
//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?
// errVmcomputeOperationPending is an error encountered when the operation is being completed asynchronously
const errVmcomputeOperationPending = syscall . Errno ( 0xC0370103 )
// HcsSystem is the handle associated with a created compute system.
type HcsSystem syscall . Handle
// HcsProcess is the handle associated with a created process in a compute
// system.
type HcsProcess syscall . Handle
// HcsCallback is the handle associated with the function to call when events
// occur.
type HcsCallback syscall . Handle
// HcsProcessInformation is the structure used when creating or getting process
// info.
type HcsProcessInformation struct {
// ProcessId is the pid of the created process.
ProcessId uint32
reserved uint32
// StdInput is the handle associated with the stdin of the process.
StdInput syscall . Handle
// StdOutput is the handle associated with the stdout of the process.
StdOutput syscall . Handle
// StdError is the handle associated with the stderr of the process.
StdError syscall . Handle
}
func execute ( ctx gcontext . Context , timeout time . Duration , f func ( ) error ) error {
if timeout > 0 {
var cancel gcontext . CancelFunc
ctx , cancel = gcontext . WithTimeout ( ctx , timeout )
defer cancel ( )
}
done := make ( chan error , 1 )
go func ( ) {
done <- f ( )
} ( )
select {
case <- ctx . Done ( ) :
if ctx . Err ( ) == gcontext . DeadlineExceeded {
log . G ( ctx ) . WithField ( logfields . Timeout , timeout ) .
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." )
}
return ctx . Err ( )
case err := <- done :
return err
}
}
func HcsEnumerateComputeSystems ( ctx gcontext . Context , query string ) ( computeSystems , result string , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsEnumerateComputeSystems" )
defer span . End ( )
defer func ( ) {
if result != "" {
span . AddAttributes ( trace . StringAttribute ( "result" , result ) )
}
oc . SetSpanStatus ( span , hr )
} ( )
span . AddAttributes ( trace . StringAttribute ( "query" , query ) )
return computeSystems , result , execute ( ctx , timeout . SyscallWatcher , func ( ) error {
var (
computeSystemsp * uint16
resultp * uint16
)
err := hcsEnumerateComputeSystems ( query , & computeSystemsp , & resultp )
if computeSystemsp != nil {
computeSystems = interop . ConvertAndFreeCoTaskMemString ( computeSystemsp )
}
if resultp != nil {
result = interop . ConvertAndFreeCoTaskMemString ( resultp )
}
return err
} )
}
func HcsCreateComputeSystem ( ctx gcontext . Context , id string , configuration string , identity syscall . Handle ) ( computeSystem HcsSystem , result string , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsCreateComputeSystem" )
defer span . End ( )
defer func ( ) {
if result != "" {
span . AddAttributes ( trace . StringAttribute ( "result" , result ) )
}
if hr != errVmcomputeOperationPending {
oc . SetSpanStatus ( span , hr )
}
} ( )
span . AddAttributes (
trace . StringAttribute ( "id" , id ) ,
trace . StringAttribute ( "configuration" , configuration ) )
return computeSystem , result , execute ( ctx , timeout . SystemCreate , func ( ) error {
var resultp * uint16
err := hcsCreateComputeSystem ( id , configuration , identity , & computeSystem , & resultp )
if resultp != nil {
result = interop . ConvertAndFreeCoTaskMemString ( resultp )
}
return err
} )
}
func HcsOpenComputeSystem ( ctx gcontext . Context , id string ) ( computeSystem HcsSystem , result string , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsOpenComputeSystem" )
defer span . End ( )
defer func ( ) {
if result != "" {
span . AddAttributes ( trace . StringAttribute ( "result" , result ) )
}
oc . SetSpanStatus ( span , hr )
} ( )
return computeSystem , result , execute ( ctx , timeout . SyscallWatcher , func ( ) error {
var resultp * uint16
err := hcsOpenComputeSystem ( id , & computeSystem , & resultp )
if resultp != nil {
result = interop . ConvertAndFreeCoTaskMemString ( resultp )
}
return err
} )
}
func HcsCloseComputeSystem ( ctx gcontext . Context , computeSystem HcsSystem ) ( hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsCloseComputeSystem" )
defer span . End ( )
defer func ( ) { oc . SetSpanStatus ( span , hr ) } ( )
return execute ( ctx , timeout . SyscallWatcher , func ( ) error {
return hcsCloseComputeSystem ( computeSystem )
} )
}
func HcsStartComputeSystem ( ctx gcontext . Context , computeSystem HcsSystem , options string ) ( result string , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsStartComputeSystem" )
defer span . End ( )
defer func ( ) {
if result != "" {
span . AddAttributes ( trace . StringAttribute ( "result" , result ) )
}
if hr != errVmcomputeOperationPending {
oc . SetSpanStatus ( span , hr )
}
} ( )
span . AddAttributes ( trace . StringAttribute ( "options" , options ) )
return result , execute ( ctx , timeout . SystemStart , func ( ) error {
var resultp * uint16
err := hcsStartComputeSystem ( computeSystem , options , & resultp )
if resultp != nil {
result = interop . ConvertAndFreeCoTaskMemString ( resultp )
}
return err
} )
}
func HcsShutdownComputeSystem ( ctx gcontext . Context , computeSystem HcsSystem , options string ) ( result string , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsShutdownComputeSystem" )
defer span . End ( )
defer func ( ) {
if result != "" {
span . AddAttributes ( trace . StringAttribute ( "result" , result ) )
}
if hr != errVmcomputeOperationPending {
oc . SetSpanStatus ( span , hr )
}
} ( )
span . AddAttributes ( trace . StringAttribute ( "options" , options ) )
return result , execute ( ctx , timeout . SyscallWatcher , func ( ) error {
var resultp * uint16
err := hcsShutdownComputeSystem ( computeSystem , options , & resultp )
if resultp != nil {
result = interop . ConvertAndFreeCoTaskMemString ( resultp )
}
return err
} )
}
func HcsTerminateComputeSystem ( ctx gcontext . Context , computeSystem HcsSystem , options string ) ( result string , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsTerminateComputeSystem" )
defer span . End ( )
defer func ( ) {
if result != "" {
span . AddAttributes ( trace . StringAttribute ( "result" , result ) )
}
if hr != errVmcomputeOperationPending {
oc . SetSpanStatus ( span , hr )
}
} ( )
span . AddAttributes ( trace . StringAttribute ( "options" , options ) )
return result , execute ( ctx , timeout . SyscallWatcher , func ( ) error {
var resultp * uint16
err := hcsTerminateComputeSystem ( computeSystem , options , & resultp )
if resultp != nil {
result = interop . ConvertAndFreeCoTaskMemString ( resultp )
}
return err
} )
}
func HcsPauseComputeSystem ( ctx gcontext . Context , computeSystem HcsSystem , options string ) ( result string , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsPauseComputeSystem" )
defer span . End ( )
defer func ( ) {
if result != "" {
span . AddAttributes ( trace . StringAttribute ( "result" , result ) )
}
if hr != errVmcomputeOperationPending {
oc . SetSpanStatus ( span , hr )
}
} ( )
span . AddAttributes ( trace . StringAttribute ( "options" , options ) )
return result , execute ( ctx , timeout . SystemPause , func ( ) error {
var resultp * uint16
err := hcsPauseComputeSystem ( computeSystem , options , & resultp )
if resultp != nil {
result = interop . ConvertAndFreeCoTaskMemString ( resultp )
}
return err
} )
}
func HcsResumeComputeSystem ( ctx gcontext . Context , computeSystem HcsSystem , options string ) ( result string , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsResumeComputeSystem" )
defer span . End ( )
defer func ( ) {
if result != "" {
span . AddAttributes ( trace . StringAttribute ( "result" , result ) )
}
if hr != errVmcomputeOperationPending {
oc . SetSpanStatus ( span , hr )
}
} ( )
span . AddAttributes ( trace . StringAttribute ( "options" , options ) )
return result , execute ( ctx , timeout . SystemResume , func ( ) error {
var resultp * uint16
err := hcsResumeComputeSystem ( computeSystem , options , & resultp )
if resultp != nil {
result = interop . ConvertAndFreeCoTaskMemString ( resultp )
}
return err
} )
}
func HcsGetComputeSystemProperties ( ctx gcontext . Context , computeSystem HcsSystem , propertyQuery string ) ( properties , result string , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsGetComputeSystemProperties" )
defer span . End ( )
defer func ( ) {
if result != "" {
span . AddAttributes ( trace . StringAttribute ( "result" , result ) )
}
oc . SetSpanStatus ( span , hr )
} ( )
span . AddAttributes ( trace . StringAttribute ( "propertyQuery" , propertyQuery ) )
return properties , result , execute ( ctx , timeout . SyscallWatcher , func ( ) error {
var (
propertiesp * uint16
resultp * uint16
)
err := hcsGetComputeSystemProperties ( computeSystem , propertyQuery , & propertiesp , & resultp )
if propertiesp != nil {
properties = interop . ConvertAndFreeCoTaskMemString ( propertiesp )
}
if resultp != nil {
result = interop . ConvertAndFreeCoTaskMemString ( resultp )
}
return err
} )
}
func HcsModifyComputeSystem ( ctx gcontext . Context , computeSystem HcsSystem , configuration string ) ( result string , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsModifyComputeSystem" )
defer span . End ( )
defer func ( ) {
if result != "" {
span . AddAttributes ( trace . StringAttribute ( "result" , result ) )
}
oc . SetSpanStatus ( span , hr )
} ( )
span . AddAttributes ( trace . StringAttribute ( "configuration" , configuration ) )
return result , execute ( ctx , timeout . SyscallWatcher , func ( ) error {
var resultp * uint16
err := hcsModifyComputeSystem ( computeSystem , configuration , & resultp )
if resultp != nil {
result = interop . ConvertAndFreeCoTaskMemString ( resultp )
}
return err
} )
}
func HcsModifyServiceSettings ( ctx gcontext . Context , settings string ) ( result string , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsModifyServiceSettings" )
defer span . End ( )
defer func ( ) {
if result != "" {
span . AddAttributes ( trace . StringAttribute ( "result" , result ) )
}
oc . SetSpanStatus ( span , hr )
} ( )
span . AddAttributes ( trace . StringAttribute ( "settings" , settings ) )
return result , execute ( ctx , timeout . SyscallWatcher , func ( ) error {
var resultp * uint16
err := hcsModifyServiceSettings ( settings , & resultp )
if resultp != nil {
result = interop . ConvertAndFreeCoTaskMemString ( resultp )
}
return err
} )
}
func HcsRegisterComputeSystemCallback ( ctx gcontext . Context , computeSystem HcsSystem , callback uintptr , context uintptr ) ( callbackHandle HcsCallback , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsRegisterComputeSystemCallback" )
defer span . End ( )
defer func ( ) { oc . SetSpanStatus ( span , hr ) } ( )
return callbackHandle , execute ( ctx , timeout . SyscallWatcher , func ( ) error {
return hcsRegisterComputeSystemCallback ( computeSystem , callback , context , & callbackHandle )
} )
}
func HcsUnregisterComputeSystemCallback ( ctx gcontext . Context , callbackHandle HcsCallback ) ( hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsUnregisterComputeSystemCallback" )
defer span . End ( )
defer func ( ) { oc . SetSpanStatus ( span , hr ) } ( )
return execute ( ctx , timeout . SyscallWatcher , func ( ) error {
return hcsUnregisterComputeSystemCallback ( callbackHandle )
} )
}
func HcsCreateProcess ( ctx gcontext . Context , computeSystem HcsSystem , processParameters string ) ( processInformation HcsProcessInformation , process HcsProcess , result string , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsCreateProcess" )
defer span . End ( )
defer func ( ) {
if result != "" {
span . AddAttributes ( trace . StringAttribute ( "result" , result ) )
}
oc . SetSpanStatus ( span , hr )
} ( )
span . AddAttributes ( trace . StringAttribute ( "processParameters" , processParameters ) )
return processInformation , process , result , execute ( ctx , timeout . SyscallWatcher , func ( ) error {
var resultp * uint16
err := hcsCreateProcess ( computeSystem , processParameters , & processInformation , & process , & resultp )
if resultp != nil {
result = interop . ConvertAndFreeCoTaskMemString ( resultp )
}
return err
} )
}
func HcsOpenProcess ( ctx gcontext . Context , computeSystem HcsSystem , pid uint32 ) ( process HcsProcess , result string , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsOpenProcess" )
defer span . End ( )
defer func ( ) {
if result != "" {
span . AddAttributes ( trace . StringAttribute ( "result" , result ) )
}
oc . SetSpanStatus ( span , hr )
} ( )
span . AddAttributes ( trace . Int64Attribute ( "pid" , int64 ( pid ) ) )
return process , result , execute ( ctx , timeout . SyscallWatcher , func ( ) error {
var resultp * uint16
err := hcsOpenProcess ( computeSystem , pid , & process , & resultp )
if resultp != nil {
result = interop . ConvertAndFreeCoTaskMemString ( resultp )
}
return err
} )
}
func HcsCloseProcess ( ctx gcontext . Context , process HcsProcess ) ( hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsCloseProcess" )
defer span . End ( )
defer func ( ) { oc . SetSpanStatus ( span , hr ) } ( )
return execute ( ctx , timeout . SyscallWatcher , func ( ) error {
return hcsCloseProcess ( process )
} )
}
func HcsTerminateProcess ( ctx gcontext . Context , process HcsProcess ) ( result string , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsTerminateProcess" )
defer span . End ( )
defer func ( ) {
if result != "" {
span . AddAttributes ( trace . StringAttribute ( "result" , result ) )
}
oc . SetSpanStatus ( span , hr )
} ( )
return result , execute ( ctx , timeout . SyscallWatcher , func ( ) error {
var resultp * uint16
err := hcsTerminateProcess ( process , & resultp )
if resultp != nil {
result = interop . ConvertAndFreeCoTaskMemString ( resultp )
}
return err
} )
}
func HcsSignalProcess ( ctx gcontext . Context , process HcsProcess , options string ) ( result string , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsSignalProcess" )
defer span . End ( )
defer func ( ) {
if result != "" {
span . AddAttributes ( trace . StringAttribute ( "result" , result ) )
}
oc . SetSpanStatus ( span , hr )
} ( )
span . AddAttributes ( trace . StringAttribute ( "options" , options ) )
return result , execute ( ctx , timeout . SyscallWatcher , func ( ) error {
var resultp * uint16
err := hcsSignalProcess ( process , options , & resultp )
if resultp != nil {
result = interop . ConvertAndFreeCoTaskMemString ( resultp )
}
return err
} )
}
func HcsGetProcessInfo ( ctx gcontext . Context , process HcsProcess ) ( processInformation HcsProcessInformation , result string , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsGetProcessInfo" )
defer span . End ( )
defer func ( ) {
if result != "" {
span . AddAttributes ( trace . StringAttribute ( "result" , result ) )
}
oc . SetSpanStatus ( span , hr )
} ( )
return processInformation , result , execute ( ctx , timeout . SyscallWatcher , func ( ) error {
var resultp * uint16
err := hcsGetProcessInfo ( process , & processInformation , & resultp )
if resultp != nil {
result = interop . ConvertAndFreeCoTaskMemString ( resultp )
}
return err
} )
}
func HcsGetProcessProperties ( ctx gcontext . Context , process HcsProcess ) ( processProperties , result string , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsGetProcessProperties" )
defer span . End ( )
defer func ( ) {
if result != "" {
span . AddAttributes ( trace . StringAttribute ( "result" , result ) )
}
oc . SetSpanStatus ( span , hr )
} ( )
return processProperties , result , execute ( ctx , timeout . SyscallWatcher , func ( ) error {
var (
processPropertiesp * uint16
resultp * uint16
)
err := hcsGetProcessProperties ( process , & processPropertiesp , & resultp )
if processPropertiesp != nil {
processProperties = interop . ConvertAndFreeCoTaskMemString ( processPropertiesp )
}
if resultp != nil {
result = interop . ConvertAndFreeCoTaskMemString ( resultp )
}
return err
} )
}
func HcsModifyProcess ( ctx gcontext . Context , process HcsProcess , settings string ) ( result string , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsModifyProcess" )
defer span . End ( )
defer func ( ) {
if result != "" {
span . AddAttributes ( trace . StringAttribute ( "result" , result ) )
}
oc . SetSpanStatus ( span , hr )
} ( )
span . AddAttributes ( trace . StringAttribute ( "settings" , settings ) )
return result , execute ( ctx , timeout . SyscallWatcher , func ( ) error {
var resultp * uint16
err := hcsModifyProcess ( process , settings , & resultp )
if resultp != nil {
result = interop . ConvertAndFreeCoTaskMemString ( resultp )
}
return err
} )
}
func HcsGetServiceProperties ( ctx gcontext . Context , propertyQuery string ) ( properties , result string , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsGetServiceProperties" )
defer span . End ( )
defer func ( ) {
if result != "" {
span . AddAttributes ( trace . StringAttribute ( "result" , result ) )
}
oc . SetSpanStatus ( span , hr )
} ( )
span . AddAttributes ( trace . StringAttribute ( "propertyQuery" , propertyQuery ) )
return properties , result , execute ( ctx , timeout . SyscallWatcher , func ( ) error {
var (
propertiesp * uint16
resultp * uint16
)
err := hcsGetServiceProperties ( propertyQuery , & propertiesp , & resultp )
if propertiesp != nil {
properties = interop . ConvertAndFreeCoTaskMemString ( propertiesp )
}
if resultp != nil {
result = interop . ConvertAndFreeCoTaskMemString ( resultp )
}
return err
} )
}
func HcsRegisterProcessCallback ( ctx gcontext . Context , process HcsProcess , callback uintptr , context uintptr ) ( callbackHandle HcsCallback , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsRegisterProcessCallback" )
defer span . End ( )
defer func ( ) { oc . SetSpanStatus ( span , hr ) } ( )
return callbackHandle , execute ( ctx , timeout . SyscallWatcher , func ( ) error {
return hcsRegisterProcessCallback ( process , callback , context , & callbackHandle )
} )
}
func HcsUnregisterProcessCallback ( ctx gcontext . Context , callbackHandle HcsCallback ) ( hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsUnregisterProcessCallback" )
defer span . End ( )
defer func ( ) { oc . SetSpanStatus ( span , hr ) } ( )
return execute ( ctx , timeout . SyscallWatcher , func ( ) error {
return hcsUnregisterProcessCallback ( callbackHandle )
} )
}
func HcsSaveComputeSystem ( ctx gcontext . Context , computeSystem HcsSystem , options string ) ( result string , hr error ) {
ctx , span := trace . StartSpan ( ctx , "HcsSaveComputeSystem" )
defer span . End ( )
defer func ( ) {
if result != "" {
span . AddAttributes ( trace . StringAttribute ( "result" , result ) )
}
if hr != errVmcomputeOperationPending {
oc . SetSpanStatus ( span , hr )
}
} ( )
return result , execute ( ctx , timeout . SyscallWatcher , func ( ) error {
var resultp * uint16
err := hcsSaveComputeSystem ( computeSystem , options , & resultp )
if resultp != nil {
result = interop . ConvertAndFreeCoTaskMemString ( resultp )
}
return err
} )
}