package hcs import ( "context" "github.com/Microsoft/hcsshim/internal/logfields" "github.com/Microsoft/hcsshim/internal/timeout" "github.com/sirupsen/logrus" ) // syscallWatcher is used as a very simple goroutine around calls into // the platform. In some cases, we have seen HCS APIs not returning due to // various bugs, and the goroutine making the syscall ends up not returning, // prior to its async callback. By spinning up a syscallWatcher, it allows // us to at least log a warning if a syscall doesn't complete in a reasonable // amount of time. // // Usage is: // // syscallWatcher(logContext, func() { // err = (args...) // }) // func syscallWatcher(logContext logrus.Fields, syscallLambda func()) { ctx, cancel := context.WithTimeout(context.Background(), timeout.SyscallWatcher) defer cancel() go watchFunc(ctx, logContext) syscallLambda() } func watchFunc(ctx context.Context, logContext logrus.Fields) { select { case <-ctx.Done(): if ctx.Err() != context.Canceled { logrus.WithFields(logContext). WithField(logfields.Timeout, timeout.SyscallWatcher). 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.") } } }