5

Ok, here's a brain puzzle: how can I find out how many times a particular file has been opened (in any mode) by any / all processes currently running on a Linux machine? I.e. how many file descriptors, globally (or within a namespace / container, doesn't matter) are in use referencing a particular file / inode?

One way of finding this out would probably be using lsof and counting how many times does the filename in question appears in its output. But that seems inelegant, and in any case, I'd need something like this programatically, in C.

Edit: or maybe a similar but different question, which would also be helpful: is a particular file (a random file on the file system, so no attaching handlers and waiting for something to happen) opened at all, by any process (possibly excluding this one)?

  • 1
    Do you also need to count closed file descriptors? I mean, if process foo has opened file bar and then closed it, should it be counted? In other words, do you need to know how many processes are currently holding the file open or how many have opened it in general? – terdon Apr 17 '17 at 14:49
  • How does lsof do it when given a single filename? – Andrew Henle Apr 18 '17 at 10:05
  • I'm really only interested in the currently open file descriptors. Actually, to be precise, I'm interested in just the number of processes which have this file opened either for reading or writing. – Ivan Voras Apr 18 '17 at 15:19
3

For the currently open files, if on Linux, you'd have to stat() all the /proc/*/fd/* files and compare inode numbers; and read all the /proc/*/maps (and also compare inode numbers).

Check the flags in /proc/*/fdinfo/* (need a relatively recent version of Linux) and the second column in /proc/*/maps for whether the file is open in read or write mode (or both, or with append...).

  • I'm pretty sure that's how lsof does it. – Andrew Henle Apr 19 '17 at 10:56
2

I think you want to attach a file-system event handler to the file, inotify is the way to go. There's a command line tool as well as a C api. I'm no expert on using it, I've only mucked with the command line tool for a few minutes, so I won't try to provide any code examples, but you can find lots of info on google searches.

https://www.ibm.com/developerworks/library/l-inotify/

https://linux.die.net/man/7/inotify

It'll provide notifications for (from the man page above):

IN_ACCESS
File was accessed (read) (*).

IN_ATTRIB
Metadata changed, e.g., permissions, timestamps, extended attributes, link count (since Linux 2.6.25), UID, GID, etc. (*).

IN_CLOSE_WRITE
File opened for writing was closed (*).

IN_CLOSE_NOWRITE
File not opened for writing was closed (*).

IN_CREATE
File/directory created in watched directory (*).

IN_DELETE
File/directory deleted from watched directory (*).

IN_DELETE_SELF
Watched file/directory was itself deleted.

IN_MODIFY
File was modified (*).

IN_MOVE_SELF
Watched file/directory was itself moved.

IN_MOVED_FROM
File moved out of watched directory (*).

IN_MOVED_TO
File moved into watched directory (*).

IN_OPEN
File was opened (*).
  • But will inotify work if a process calls dup() to duplicate an an already-open file descriptor? If not, it will miss processes that read/write to files via redirected stdin/stdout. – Andrew Henle Apr 18 '17 at 10:07
  • Hmmm, that would work only from the point in time when the event handler was attached forwards, not for random files at random times, right? – Ivan Voras Apr 18 '17 at 15:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.