From 71fab476ce356f12e636e9469bea19595765df5e Mon Sep 17 00:00:00 2001 From: Shane McDonald Date: Thu, 13 May 2021 11:39:50 -0400 Subject: [PATCH] Ensure that status lockfile is closed before trying to release work For context, see: - https://github.com/ansible/receptor/pull/319 - https://github.com/ansible/awx/issues/9961 --- pkg/workceptor/interfaces.go | 1 + pkg/workceptor/workunitbase.go | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/pkg/workceptor/interfaces.go b/pkg/workceptor/interfaces.go index 9332913ce..b351444a1 100644 --- a/pkg/workceptor/interfaces.go +++ b/pkg/workceptor/interfaces.go @@ -31,4 +31,5 @@ type StatusFileData struct { StdoutSize int64 WorkType string ExtraData interface{} + LockFile *lockedfile.File } diff --git a/pkg/workceptor/workunitbase.go b/pkg/workceptor/workunitbase.go index cc570cb5d..8452295b2 100644 --- a/pkg/workceptor/workunitbase.go +++ b/pkg/workceptor/workunitbase.go @@ -114,6 +114,7 @@ func (bwu *BaseWorkUnit) StdoutFileName() string { func (sfd *StatusFileData) lockStatusFile(filename string) (*lockedfile.File, error) { lockFileName := filename + ".lock" lockFile, err := lockedfile.OpenFile(lockFileName, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600) + sfd.LockFile = lockFile if err != nil { return nil, err } @@ -123,6 +124,7 @@ func (sfd *StatusFileData) lockStatusFile(filename string) (*lockedfile.File, er // unlockStatusFile releases the lock on the status file func (sfd *StatusFileData) unlockStatusFile(filename string, lockFile *lockedfile.File) { err := lockFile.Close() + sfd.LockFile = nil if err != nil { logger.Error("Error closing %s.lock: %s", filename, err) } @@ -366,8 +368,14 @@ func (bwu *BaseWorkUnit) UnredactedStatus() *StatusFileData { func (bwu *BaseWorkUnit) Release(force bool) error { bwu.statusLock.Lock() defer bwu.statusLock.Unlock() + if bwu.status.LockFile != nil { + // There seems to be a race condition with the `defer`s that + // handle closing this lockfile. + bwu.status.LockFile.Close() + } err := os.RemoveAll(bwu.UnitDir()) if err != nil && !force { + logger.Error("Error when releasing work: %s\n", err) return err } bwu.w.activeUnitsLock.Lock()