Flock (): delete a locked file without a race condition?

I use flock () for an inter-process called mutexes (ie, some process may decide to block "some_name", which is implemented by locking a file called "some_name" in the temp directory:

lockfile = "/tmp/some_name.lock"; fd = open(lockfile, O_CREAT); flock(fd, LOCK_EX); do_something(); unlink(lockfile); flock(fd, LOCK_UN); 

The lock file must be deleted at some point to avoid filling the temp directory with hundreds of files.

However, there is an obvious race condition in this code; example with processes A, B and C:

 A opens file A locks file B opens file A unlinks file A unlocks file B locks file (B holds a lock on the deleted file) C opens file (a new file one is created) C locks file (two processes hold the same named mutex !) 

Is there a way to delete a lock file at some point without presenting this race condition?

+16
c flock
Jul 17 '13 at 19:46
source share
2 answers

Sorry if I answer a dead question:

After locking the file, open another copy, fstat both copies and check the inode number, for example:

 lockfile = "/tmp/some_name.lock"; while(1) { fd = open(lockfile, O_CREAT); flock(fd, LOCK_EX); fstat(fd, &st0); stat(lockfile, &st1); if(st0.st_ino == st1.st_ino) break; close(fd); } do_something(); unlink(lockfile); flock(fd, LOCK_UN); 

This prevents the race condition, because if the program has a file lock that is still in the file system, every other program that has the remaining file will have the wrong inode number.

I actually proved this in a state-machine model using the following properties:

If P_i has a handle locked in the file system, then no other process is in the critical section.

If P_i after the stat with the correct index or in the critical section, it has a handle locked in the file system.

+19
Sep 11 '13 at 15:25
source share

If you use these files only for locking and do not actually write them, I suggest that you consider the existence of the directory entry itself as an indication of the lock being held and avoid using flock in general.

To do this, you need to create an operation that creates an entry in the directory and reports an error if it already exists. On Linux and on most file systems, O_EXCL until open will work for this. But some platforms and some file systems (in particular, older NFS) do not support this. Therefore, the man page for open offers an alternative:

Portable programs that want to lock an atomic file using a lock file and should avoid NFS support for O_EXCL can create a unique file in the same file system (for example, including the host name and PID) and use link (2) to link to lock file. If link (2) returns 0, the lock will succeed. Otherwise, use stat (2) in a unique file to check if its number of links has been increased to 2, in which case the lock is also successful.

Thus, it looks like a blocking scheme, which is officially documented and, therefore, indicates a certain level of support and recommendations for best practice. But I have seen other approaches. bzr , for example, uses directories instead of symbolic links in most places. Quote from his source code :

The lock is represented on the disk by a directory of a specific name containing an information file. Blocking is done by renaming the temporary directory. We use temporary directories, because for all known transports and file systems, we believe that there is exactly one attempt to say that the lock will be successful, and the rest will fail. (There will be no files because some file systems or transports will be renamed and overwritten, which makes it difficult to determine who won.)

One drawback of the above approaches is that they will not be blocked: an unsuccessful attempt to block will result in an error, but do not wait for the lock to become available. You will need to interrogate the lock, which can be problematic in the light of disputes about the lock. In this case, you may need to further deviate from the file system approach and use third-party implementations instead. But general questions about how to make an ipc mutex have already been asked, so I suggest you look for [ipc] [mutex] and see the results, this one . By the way, these tags can be useful for your message.

+3
Jul 18 '13 at 4:55
source share



All Articles