Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

flock vs lockf on Linux

Tags:

c

linux

locking

If lockf is used with a 0 offset, what are differences between flock and lockf when used in exclusive mode, if any?

I'm asking because I'm reading code that conditionally compiles in either of these 2 functions based on platform and I want to understand possible reasons why.

like image 575
Dan McGrath Avatar asked Mar 14 '14 15:03

Dan McGrath


People also ask

What is flock in Linux?

Introduction to flock Command The flock command is also provided by the util-linux package. This utility allows us to manage advisory file locks in shell scripts or on the command line. The basic usage syntax is: flock FILE_TO_LOCK COMMAND.

How do you use Lockf?

You can use the lockf() function to lock a section of a file, using advisory-mode locks. If other threads call lockf() to try to lock the locked file section, those calls either return an error value or block until the section becomes unlocked. All the locks for a process are removed when the process terminates.

What is the use of fcntl function?

The fcntl() function provides for control over open files. The fildes argument is a file descriptor. The available values for cmd are defined in the header <fcntl.


2 Answers

The practical difference between flock() and lockf() is in the semantics (behaviour with respect to closing and passing), applicability over NFS and other shared filesystems, and whether the advisory locks are visible to other processes using fcntl() locks or not.

The library you're using simply has logic to pick the desired semantics based on the current platform.

If the semantics (behaviour over descriptor passing, forking, etc.) is acceptable, you should prefer lockf()/fcntl() locks over flock() locks in Linux, simply because the former works on NFS etc. filesystems, whereas the latter does not. (On BSDs and Mac OS X, I believe you need to explicitly use fcntl(), instead.)


In Linux, lockf() is just a wrapper around fcntl(), while flock() locks are separate (and will only work on local filesystems, not on e.g. NFS mounts on kernels prior to 2.6.12). That is, one process can have an advisory exclusive flock() lock on a file, while another process has an advisory exclusive fcntl() lock on that same file. Both are advisory locks, but they do not interact.

On Mac OS X and FreeBSD, lockf()/flock()/fcntl() locks all interact, although developers are recommended to use only one of the interfaces in an application. However, only fcntl() locks work on NFS mounts (and, obviously, only if both NFS client and server have been configured to support record locks, which is surprisingly rare in e.g. web hosting environments; a huge cause of headaches for some web (framework) developers).

POSIX does not explicitly specify how lockf()/flock()/fcntl() locks should interact, and there have been differences in the past. Now, the situation has calmed down a bit, and one can approximately say that

  1. fcntl() locks are the most reliable

    Across architectures, they have the best chance of working right on e.g. shared filesystems -- NFS and CIFS mounts, for example.

  2. Most often, lockf() is implemented as "shorthand" for fcntl()

    The other alternative, as "shorthand" for flock(), is possible, but nowadays rare.

  3. fcntl() and flock() have different semantics wrt. inheritance and automatic releases

    fcntl() locks are preserved across an exec(), but not inherited across a fork(). The locks are released when the owning process closes any descriptor referring to the same file.

    In Linux, FreeBSD, and MAc OS X, flock() locks are coupled with the open file descriptor: passing the descriptor also passes the lock. (The man pages state that "the lock is on the file, not on the file descriptor". This is not a contradiction. It just means that the lock applies to the file. It is still coupled to the descriptor, in such a way that duplicating the descriptor also passes the same lock, too.) Therefore, it is possible that multiple processes have the same exclusive advisory flock() lock on the same file at the same time, if they obtained the descriptor from the originator after the flock() call.

File locking is surprisingly complicated issue. I have personally had best results by simply sticking to fcntl() locking. The semantics wrt. fcntl() locks are not the easiest to work with, and in certain cases can be frankly infuriating; it's just that I've found it to yield the best -- most reliable, most portable, least surprising -- results.

like image 172
Nominal Animal Avatar answered Oct 13 '22 21:10

Nominal Animal


The most likely reason for the conditional compilation is that neither of the two functions is available on every platform.

like image 42
NPE Avatar answered Oct 13 '22 19:10

NPE