Узнать, сколько раз открывался файл?

Узнать, сколько раз открывался файл?

Хорошо, вот вам задачка: как узнать, сколько раз конкретный файл был открыт (в любом режиме) любым/всеми процессами, запущенными в данный момент на машине Linux? То есть, сколько файловых дескрипторов, глобально (или в пределах пространства имен/контейнера, неважно) используются для ссылки на конкретный файл/инод?

Один из способов выяснить это, вероятно, будет использовать lsof и подсчитать, сколько раз в его выводе появляется указанное имя файла. Но это кажется неэлегантным, и в любом случае мне нужно что-то вроде этого программно, на C.

Редактировать: или, может быть, похожий, но другой вопрос, который также был бы полезен: открывается ли какой-либо конкретный файл (случайный файл в файловой системе, чтобы не было прикрепленных обработчиков и ожидания чего-либо) каким-либо процессом (возможно, за исключением этого)?

решение1

Для текущих открытых файлов, если вы работаете в Linux, вам придется просмотреть stat()все /proc/*/fd/*файлы и сравнить номера инодов; а также прочитать все /proc/*/maps(и также сравнить номера инодов).

Проверьте флаги /proc/*/fdinfo/*(нужна относительно свежая версия Linux) и второй столбец, /proc/*/mapsчтобы узнать, открыт ли файл в режиме чтения или записи (или в обоих режимах, или с добавлением...).

решение2

Я думаю, что вы хотите прикрепить обработчик событий файловой системы к файлу, inotifyэто выход. Есть инструмент командной строки, а также API C. Я не эксперт по его использованию, я только несколько минут возился с инструментом командной строки, поэтому я не буду пытаться предоставить какие-либо примеры кода, но вы можете найти много информации в поиске Google.

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

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

Он будет предоставлять уведомления для (из страницы руководства выше):

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 (*).

Связанный контент