lock

package
v0.0.0-...-ba09d25 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 29, 2021 License: Apache-2.0, MIT Imports: 8 Imported by: 0

Documentation

Overview

Package lock is the API for POSIX-style advisory regional file locks and BSD-style full file locks.

Callers needing to enforce these types of locks, like sys_fcntl, can call LockRegion and UnlockRegion on a thread-safe set of Locks. Locks are specific to a unique file (unique device/inode pair) and for this reason should not be shared between files.

A Lock has a set of holders identified by UniqueID. Normally this is the pid of the thread attempting to acquire the lock.

Since these are advisory locks, they do not need to be integrated into Reads/Writes and for this reason there is no way to *check* if a lock is held. One can only attempt to take a lock or unlock an existing lock.

A Lock in a set of Locks is typed: it is either a read lock with any number of readers and no writer, or a write lock with no readers.

As expected from POSIX, any attempt to acquire a write lock on a file region when there already exits a write lock held by a different uid will fail. Any attempt to acquire a write lock on a file region when there is more than one reader will fail. Any attempt to acquire a read lock on a file region when there is already a writer will fail.

In special cases, a read lock may be upgraded to a write lock and a write lock can be downgraded to a read lock. This can only happen if:

  • read lock upgrade to write lock: There can be only one reader and the reader must be the same as the requested write lock holder.

  • write lock downgrade to read lock: The writer must be the same as the requested read lock holder.

UnlockRegion always succeeds. If LockRegion fails the caller should normally interpret this as "try again later".

Index

Constants

View Source
const LockEOF = math.MaxUint64

LockEOF is the maximal possible end of a regional file lock.

A BSD-style full file lock can be represented as a regional file lock from offset 0 to LockEOF.

Variables

This section is empty.

Functions

This section is empty.

Types

type Lock

type Lock struct {
	// Readers are the set of read lock holders identified by UniqueID.
	// If len(Readers) > 0 then Writer must be nil.
	Readers map[UniqueID]OwnerInfo

	// Writer holds the writer unique ID. It's nil if there are no writers.
	Writer UniqueID

	// WriterInfo describes the writer. It is only meaningful if Writer != nil.
	WriterInfo OwnerInfo
}

Lock is a regional file lock. It consists of either a single writer or a set of readers.

A Lock may be upgraded from a read lock to a write lock only if there is a single reader and that reader has the same uid as the write lock.

A Lock may be downgraded from a write lock to a read lock only if the write lock's uid is the same as the read lock.

Accesses to Lock are synchronized through the Locks object to which it belongs.

+stateify savable

type LockType

type LockType int

LockType is a type of regional file lock.

const (
	// ReadLock describes a POSIX regional file lock to be taken
	// read only.  There may be multiple of these locks on a single
	// file region as long as there is no writer lock on the same
	// region.
	ReadLock LockType = iota

	// WriteLock describes a POSIX regional file lock to be taken
	// write only.  There may be only a single holder of this lock
	// and no read locks.
	WriteLock
)

type Locks

type Locks struct {
	// contains filtered or unexported fields
}

Locks is a thread-safe wrapper around a LockSet.

+stateify savable

func (*Locks) EventRegister

func (l *Locks) EventRegister(e *waiter.Entry) error

EventRegister implements waiter.Waitable.EventRegister.

func (*Locks) EventUnregister

func (l *Locks) EventUnregister(e *waiter.Entry)

EventUnregister implements waiter.Waitable.EventUnregister.

func (*Locks) LockRegion

func (l *Locks) LockRegion(ctx context.Context, uid UniqueID, ownerPID int32, t LockType, r LockRange, block bool) error

LockRegion attempts to acquire a typed lock for the uid on a region of a file. Returns nil if successful in locking the region, otherwise an appropriate error is returned.

func (*Locks) LockRegionVFS1

func (l *Locks) LockRegionVFS1(ctx context.Context, uid UniqueID, t LockType, r LockRange, block bool) error

LockRegionVFS1 is a wrapper around LockRegion for VFS1, which does not implement F_GETLK (and does not care about storing PIDs as a result).

TODO(gvisor.dev/issue/1624): Delete.

func (*Locks) Readiness

func (l *Locks) Readiness(waiter.EventMask) waiter.EventMask

Readiness always returns zero.

func (*Locks) TestRegion

func (l *Locks) TestRegion(ctx context.Context, uid UniqueID, t LockType, r LockRange) linux.Flock

TestRegion checks whether the lock holder identified by uid can hold a lock of type t on range r. It returns a Flock struct representing this information as the F_GETLK fcntl does.

Note that the PID returned in the flock structure is relative to the root PID namespace. It needs to be converted to the caller's PID namespace before returning to userspace.

TODO(gvisor.dev/issue/5264): we don't support OFD locks through fcntl, which would return a struct with pid = -1.

func (*Locks) UnlockRegion

func (l *Locks) UnlockRegion(uid UniqueID, r LockRange)

UnlockRegion attempts to release a lock for the uid on a region of a file. This operation is always successful, even if there did not exist a lock on the requested region held by uid in the first place.

type OwnerInfo

type OwnerInfo struct {
	// PID is the process ID of the lock owner.
	PID int32
}

OwnerInfo describes the owner of a lock.

TODO(gvisor.dev/issue/5264): We may need to add other fields in the future (e.g., Linux's file_lock.fl_flags to support open file-descriptor locks).

+stateify savable

type UniqueID

type UniqueID interface{}

UniqueID is a unique identifier of the holder of a regional file lock.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL