overview
File locking is a mutual-exclusion mechanism to ensure a file can be read/written by muliple processes in a safe way.
The interceding update problem
The interceding update is a typical race condition problem in a concurrent system. Let’s see an example to understand the problem better.
Let’s say we have a balance.dat file storing the balance of an account, and it has an initial value of “100”. Our concurrent system has two processes to update the balance value:
- Process A: reads the current value, substracts 20 and saves the result back to the file.
- Process B: reads the current value, adds 80 and writes the result back into the file.
Obviously, after the execution of two processes, we are expects the file has value: 100 - 20 + 80 = 160.
However, an interdecing update problem may occur in this problem:
- Process A reads the file’s current value(100), and prepares to do further calculation.
- Process B now reads the same file and gets the current balance(100).
- Process A calculates 100 - 20 and saves the result 80 back to the file
- Process B doesn’t know the balance has been updated since its last read. So it will still use the stale value 100 to calculate 100 + 80 and write the result 180 to the file.
As a result, we have 180 in the balance.dat file instead of the expected value of 160.
File locking in Linux
File locking is a mechanism to restrict access to a file among muliple processes. It allows only one process to access the file in a specific time, thus avoiding the interceding update problem.
Linux supports two kinds of the file locks: advisory locks and mandatory locks.
Advisory lock
Advisory locking is not an enforced locking scheme. It will work only if the partipating processes are cooperating by explicityly acquiring locks. Otherwise, advisory locks will be ignored if a process is not aware of locks at all.
System call flock is an advisory lock.
Mandaroty locking
Before we start looking at mandaroty file locking, we should keep in mind that Linx implementation of mandaroty locking is unreliable.
Unlike advisory locking, mandatory locking doesn’t require any cooperation between the paricipating processes. Once a mandatory lock is avrivated on a file, the operating system prevents other processes from reading or writing the file.
To enable mandatory file locking in Linux, two requirements must be satisfield.
- we must mount the file system with the mand option (mount -o mand FILESYSTEM MOUNT_POINT)
- we must turn on the set-group-ID bit and turn off the group-execute bit for the files we are about to lock (chmod g+s,g-x FILE)
Inspect all locks in a system
the lslocks command
We can use this command to see all the currently locked files in the system.
/proc/locks
It is a file in the procfs virtual file system. The file holds all current file locks, the lslocks command relies on this file to generate the list, too.
Introduction to flock command
flock command is also provided by the util-linux package.
exmaple
We create a simple shell script a.sh to simulate process A:
Now let’s start process A to test:
Through the output, we can see the flock command first acquired a lock on the file balance.dat, then the update_balance.sh script read and updated the file.
During its run, we can check the lock information via the lslocks command:
The output shows that the flock command is holding a WRITE lock on the entire file /tmp/test/balance.dat
reference
- File locking.hpp
- man 2 flock
- man 2 readlink
- file hard link