Michael Sweetser
Michael Sweetser

Reputation: 69

Lockfiles in Bash: Text file busy when running two copies at once

I have a Bash script that needs to lock a file for exclusive read/write while it runs. During this time, any other copies of the same script running should hang until the lock is released (which should be pretty quickly).

#!/bin/bash

trap "rm -f /tmp/.lock; exit" 0 1 2 3 15

(
    flock -x 100 

    # Stuff happens here...

) 100>/tmp.lock

This works, somewhat. But not in these conditions:

  1. Start script copy #1
  2. Start script copy #2
  3. End script copy #1 before script copy #2 does

At this point, I get the error:

rm: cannot remove '/tmp/.lock': Text file busy

I assume I'm totally wrong on how I'm cleaning things up with the trap, so any help would be much appreciated. Thanks!

Upvotes: 0

Views: 1483

Answers (1)

Charles Duffy
Charles Duffy

Reputation: 295618

DO NOT EVER try to "clean up" flock-style lockfiles whenever it is possible that any program holding that lock could be running or attempting to run.

Keep in mind that locks are held on inodes, not filenames. Deleting a directory entry decouples the inode previously at that location from its name, allowing that name to then refer to a different inode.

Consider the following scenario:

  1. Program A holds a lock.
  2. Program B opens the lockfile and tries to grab a lock on it, blocking until Program A is done with the lock.
  3. Program A finishes; closes the lock; and deletes the lockfile.
  4. Program B still holds a handle on the deleted lockfile. As Program A closed the lock (or exited, releasing its file handle and thus its lock), Program B is able to continue running, holding that handle as its lock.
  5. Program C tries to grab the lock. Even though Program B is still running, because the lockfile Program B holds a handle on was deleted by Program A, Program C is allowed to run concurrently.
  6. Program B exits, deleting the lockfile that Program C created, while Program C is still running.

Flock-file lockfiles should be considered mappings from filesystem namespace into file-locking namespace. These mappings do not need to be, and should not be, "cleaned up". You may wish to consider whether your operating system's filesystem hierarchy standard provides a places for such files to live, such as /var/lock, or somewhere on tmpfs (where "cleanup" will happen implicitly -- and safely -- on reboot).

Upvotes: 5

Related Questions