How can I determine what process has a file open in Linux?

On most Linux systems lsof NAME does the job:

fin@r2d2:~$ lsof /home/fin
COMMAND   PID USER   FD   TYPE DEVICE SIZE    NODE NAME
bash    21310  fin  cwd    DIR    8,1 4096 5054467 /home/fin
lsof    21320  fin  cwd    DIR    8,1 4096 5054467 /home/fin
lsof    21321  fin  cwd    DIR    8,1 4096 5054467 /home/fin
fin@r2d2:~$

You can also use fuser for this:

~> less .vimrc
# put in background
~> fuser .vimrc
.vimrc:              28135
~> ps 28135
  PID TTY      STAT   TIME COMMAND
28135 pts/36   T      0:00 less .vimrc

Having a file open is not a lock because, if each process has to check whether the file is open first and not proceed if it is or create/open it if it isn't, then two processes could quite well check simultaneously, both find that it isn't open, then both create or open it.

To use a file as a lock, the check-and-lock operation has to be a single uninterruptable operation. You can achieve this in a Unix filesystem by creating a file with read-only mode and removing it to unlock. If the file exists (and is read only) the file creation will fail, so you get check-and-lock in a single atomic operation.

If your locking process is a shell script that will be running as a daemon, you can get this effect by using umask, a per-process setting that sets the permissions that new files are created with:

oldumask=$(umask)
umask 222   # create files unwritable to owner too
if echo $$ > /var/lock/foo
then
    : locking succeeded
else
    : locking failed
fi
umask $oldumask
This also writes the owning process' PID into the file, which solves your other problem: cat /var/lock/foo
As regards the specific question "Which processes have this file open?", this can be useful when you want to unmount a filesystem but can't because some process has a file open in it. If you don't have those commands available, you can ask /proc as root:

ls -l /proc/*/cwd | grep '/var/lock/foo$'

or, as a mortal user:

ls -l /proc/*/cwd 2>/dev/null | grep '/var/lock/foo$'

Tags:

Linux