Files
orbit/internal/retention/job_lock_unix.go

31 lines
828 B
Go

//go:build linux || darwin
package retention
import (
"errors"
"os"
"syscall"
)
// lockJob 的非阻塞文件锁随进程退出自动释放,不使用永不过期的“锁目录”。
func lockJob(root *os.Root) (*os.File, error) {
f, err := root.OpenFile(".lock", os.O_CREATE|os.O_RDWR|syscall.O_NOFOLLOW, 0600)
if err != nil {
return nil, err
}
info, err := f.Stat()
if err != nil || !info.Mode().IsRegular() || info.Mode().Perm()&0077 != 0 {
f.Close()
return nil, errors.New("invalid archive lock file")
}
if err := syscall.Flock(int(f.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil {
f.Close()
if errors.Is(err, syscall.EWOULDBLOCK) || errors.Is(err, syscall.EAGAIN) {
return nil, ErrArchiveBusy
}
return nil, errors.New("archive filesystem does not support locking")
}
return f, nil
}