Motivation

  • Libvirt metadata locking
    • chown(2), setfilecon(3)
    • XATTRs to store original owner/context
    • Not atomic, need to mutually exclude with other daemons

  • DB locking files on update
    • Lock only those parts of file that need updating

  • PID files

Current state

Lock types

  • Advisory
    • BSD locks

    • POSIX lock

    • Open File Description locks

  • Mandatory

BSD locks

int fd = open("/some/path", O_RDWR);
flock(fd, LOCK_EX);
  • Associated with file description
  • Shared or exclusive lock



Except:
  • Always lock the entire file
  • Not POSIX (even though widely available)
  • No atomic lock promotion
  • On older Linux NOP returning success
  • On newer Linux silently converted to POSIX lock for NFS

POSIX locks

int fd = open("/some/path", O_RDWR);
struct flock fl = {
    .l_type = F_WRLCK,
    .l_whence = SEEK_SET,
    .l_start = 1,
    .l_len = 2,
};

fcntl(fd, F_SETLKW, &fl);
  • Associated with [i-node, pid]
  • Ranges
  • Kernel detects & prevents deadlocks
  • Read or write lock
  • Works across NFS

POSIX locks

Except:
  • Not shared across fork(2)
  • Doesn't work on SMB
  • close(2) releases lock
    • The lock acquired through one FD might be released by another thread through different FD
    • Workaround: reimplement open(2) & close(2)
    • Not possible if linking with some other library (/etc/passwd, getpwent(3))
    • Hardlinks
  • struct flock

POSIX locks

int fd = open("/some/path", O_RDWR);
lockf(fd, F_LOCK, len);
  • Just a fancy wrapper over fcntl(fd, F_SETLK, ...)

Open File Description locks

int fd = open("/some/path", O_RDWR);
struct flock fl = {
    .l_type = F_WRLCK,
    .l_whence = SEEK_SET,
    .l_start = 1,
    .l_len = 2,
};

fcntl(fd, F_OFD_SETLK, &fl);
  • Associated with file description
  • Ranges
  • Kernel detects & prevents deadlocks
  • Read or write lock
  • Works across NFS
  • Safe around close(2)

Mandatory locking

Do not use it!




Really, don't.

Solution?

  • Libvirt
    • POSIX locks
    • fork(2) & auditing

  • sqlite
    • POSIX locks
    • Reimplemented open, close & pthread locks

  • PID files
    • BSD locks

Thank You!

mprivozn@redhat.com