inotify не вызывает DELETE_SELF, если существует открытый файл-fd

Я пытаюсь отслеживать каталог с помощью inotify и регистрируюсь на ВСЕ события. Теперь у меня есть требование в моем проекте отслеживать любые операции MOVE_SELF, выполняемые в каталоге, чтобы я мог определить, в какое новое место перемещен отслеживаемый каталог. Для этого я сохраняю ссылку на открытый файловый дескриптор (int fd) отслеживаемого каталога, и когда я получаю MOVE_SELF, я пытаюсь получить новый путь, используя:

//code to store a reference of file-descrptor of the monitored sirectory
fd = open(watchPath.c_str(), O_RDONLY)    


//code to learn the new location of the moved directory
char fdpath[4096];
char path[4096];

sprintf(fdpath, "/proc/self/fd/%d", fd);
ssize_t sz = readlink(fdpath, path, sizeof(path) - 1); //Path will contain the new location after the move happens

Но побочным эффектом этого является то, что в случае удаления каталога я не получаю событие DELETE_SELF, потому что у меня все еще есть открытый дескриптор файла. Может ли кто-нибудь предложить мне, как обойти эту проблему?

Спасибо, - Сандип


person Sandeep    schedule 19.09.2013    source источник
comment
где вы вызываете inotify_add_watch?   -  person Sam Miller    schedule 19.09.2013
comment
inotify_add_watch вызывается после функции init(), и я обязательно регистрируюсь для всех событий, особенно IN_DELETE и IN_DELETE_SELF. Я действительно трачу много времени, но не могу понять, почему IN_DELETE_SELF не пойман. Надеюсь, что получу ответ.   -  person Sandeep    schedule 22.09.2013


Ответы (1)


На случай, если кто-то столкнется с этой проблемой: это определенно ожидаемое поведение. Inotify не отслеживает «файлы», он отслеживает «файловые объекты» (иначе иноды). Индекс не удаляется ядром до тех пор, пока все дескрипторы открытых файлов, указывающие на него, не будут закрыты.

По этой же причине IN_DELETE/IN_DELETE_SELF не срабатывает, если вы удаляете одну из нескольких жестких ссылок на файл (поскольку жесткие ссылки имеют один и тот же индексный дескриптор).

Вы можете частично обойти проблему с жесткими ссылками, подписавшись на событие IN_ATTRIB: оно срабатывает, когда счетчик ссылок на индексный дескриптор изменяется (например, когда одна из жестких ссылок удаляется), поэтому вы можете использовать его, чтобы проверить, существует ли еще файл на старый путь.

Что касается проблемы с «открытыми дескрипторами» — мне неизвестны обходные пути. Лично мне просто все равно. Что делать, если ваша программа временно десинхронизируется с содержимым диска? Даже если бы inotify был полностью безупречен, вам все равно время от времени приходилось бы выполнять повторную синхронизацию из-за переполнения очереди и гонки событий.

person user1643723    schedule 27.12.2016