Fcntl, lockf, which is better to use to lock files?

Look for information on the advantages and disadvantages of both fcntl and lockf for locking files. For example, what is better to use for portability? I am currently encoding a linux daemon and wondering what is best suited to provide mutual exclusion.

+43
c linux file locking
Feb 22 '09 at 18:01
source share
5 answers

What is the difference between lockf and fcntl:

On many systems, the library routine lockf() is just a wrapper around fcntl() . That is, lockf offers a subset of the functions that fcntl does.

Source

But on some locking systems, fcntl and lockf completely independent.

Source

Since it is implementation dependent, be sure to use the same convention. Therefore, either always use lockf from both processes, or always use fcntl. There is a good chance that they will be interchangeable, but it is safer to use the same one.

Which one you choose does not matter.




Some notes on mandatory and advisory locks:

Unix / linux locking is advisory by default, which means that other processes do not need to follow the established locking rules. Therefore, it doesn’t matter how you block if your cooperative processes also use the same convention.

Linux supports mandatory locking, but only if your file system is mounted with the option turned on and special file attributes set. You can use mount -o mand to mount the file system and set the file attributes gx,g+s to enable mandatory locks, then use fcntl or lockf . For more information on how mandatory locks work, see here .

Note that locks do not apply to a single file, but to an inode. This means that 2 file names that point to the same file data will have the same lock status.

On Windows, on the other hand, you can actively open a file, and this will completely block other processes. Even if they want it. Ie, locks are required. The same goes for Windows and file locks. Any process with an open file with the appropriate access can block part of the file, and no other process can access this part.




How forced locks work on Linux:

As for mandatory locks, if a process locks a region of a file with a read lock, then other processes are allowed to read, but not write to this region. If a process locks a region of a file with write lock, then other processes are not allowed to read or write to the file. What happens when a process is not allowed to access part of the file depends on whether O_NONBLOCK is O_NONBLOCK or not. If the lock is set, it will wait for the operation to complete. If the lock is not set, you will receive an EAGAIN error EAGAIN .




NFS Warning:

Be careful if you use lock commands on an NFS mount. The behavior is undefined, and the implementation varies widely, whether to use only local locking or to support remote locking.

+58
Feb 22 '09 at 18:11
source share

Both interfaces are part of the POSIX standard, and both interfaces are currently available on most systems (I just checked Linux, FreeBSD, Mac OS X, and Solaris). Therefore, choose the one that best suits your requirements and uses it.

One word of caution: it is unspecified what happens when one process locks a file using fcntl and another lockf. On most systems, these are equivalent operations (actually under Linux, lockf is implemented on top of fcntl), but POSIX says that their interaction is undefined. So, if you are interacting with another process that uses one of two interfaces, select the same one.

Others write that locks are only advisory: you are responsible for checking if the region is blocked. Also, do not use stdio functions if you want to use lock functions.

+10
Feb 22 '09 at 18:25
source share

In this case, your main problem (that is, when " encodes the Linux daemon and wonders what is best suited to use to provide mutual exclusion )):

  • Will the locked file be local or can it be on NFS?
    • eg. can a user trick you into creating and blocking a pid daemon file on NFS?
  • how the lock will behave when fork ing, or when the daemon process terminates with extreme prejudice, for example. kill -9 ?

The flock and fcntl commands behave differently in both cases.

My recommendation would be to use fcntl . You can refer to the article on file locking on Wikipedia for an in-depth discussion of the problems associated with both solutions:

Both flock and fcntl have quirks that are occasionally puzzle programmers from other operating systems. Whether it becomes blocking work with network file systems, such as NFS, is an implementation dependent. On BSD systems, successful non-ops are successful. On Linux, before 2.6.12 Flock calls in NFS files will only act locally. Kernel 2.6.12 and above make flock calls to NFS files using POSIX byte range lock. These locks will be visible to other NFS clients that implement fcntl () / POSIX. 1 Updates blocking and reduces the release of the old block before applying the new block. If an application lowers exclusivity to lock a shared lock, and another application is blocked waiting for an exclusive lock, the last application will receive an exclusive lock and the first application will be blocked. All fcntl locks associated with a file for this process are removed when any file descriptor for this file is closed by this process, even if a lock has never been requested for this file descriptor. Also, fcntl locks are not inherited by a child process. The close semantics of fcntl are difficult for applications that call libraries of routines that can access files.

+9
Feb 22 '09 at 18:26
source share

Recently, I ran into a problem when using fcntl and flock, and I felt that I had to report it here, as searching for any of them shows this page at the top on both.

Please note that BSD locks, as indicated above, are advisory . For those who do not know OSX (darwin), is BSD. This must be remembered when opening a file for writing.

To use fcntl / flock, you must first open the file and get its identifier. However, if you open the file with "w", the file will be instantly reset. . If your process cannot get the lock because the file is being used elsewhere, it will most likely return, leaving the file as 0kb. The process in which it was blocked will now detect that the file has disappeared from under it, usually disastrous results occur.

To fix this, when using file locking, never open the β€œw” file, but open β€œa” instead to add. Then, if the lock is successfully obtained, you can safely clear the file as "w", i.e.

fseek (fileHandle, 0, SEEK_SET); // go to the beginning

ftruncate (fileno ((FILE *) fileHandle), 0); // clear it

It was an unpleasant lesson for me.

+6
Sep 17 '14 at 2:31
source share

Since you only encode a daemon that uses it for mutual exclusion, they are equivalent, after all, your application should only be compatible with itself.

The trick with file locking mechanisms should be consistent - use one and stick to it. Separating them is a bad idea.

I assume that the file system will be local - if it is not, then all bets are disabled, NFS / other network file systems handle the lock with varying degrees of efficiency (in some cases not)

+1
Feb 22 '09 at 18:08
source share



All Articles