Использование переименования для безопасной перезаписи общего файла в Linux

Вот настройка: у меня есть общий файл (назовем его status.csv), который читается многими процессами (назовем их потребителями) только для чтения. У меня есть один производитель, который периодически обновляет status.csv, создавая временный файл, записывая в него данные и используя обсуждаемую здесь функцию C:

http://www.gnu.org/software/libc/manual/html_node/Renaming-Files.html

переименовать временный файл (эффективно перезаписать) в status.csv, чтобы потребители могли обрабатывать новые данные. Он хочет попробовать и гарантировать (насколько это возможно в мире Linux), что потребители не получат искаженный / поврежденный / наполовину старый / наполовину новый файл status.csv (я хочу, чтобы они получили либо все старые данные или все новое). Кажется, я не могу гарантировать это, прочитав описание переименования: кажется, что оно само по себе является атомарным действием переименования, но я хочу знать, если у потребителя уже открыт файл status.csv, он продолжит читать то же самое файл, каким он был при его открытии, даже если файл был переименован / перезаписан производителем в середине этой операции чтения.

Я попытался создать прототип, полагая, что потребители получат какой-то тип ошибки или половину старого / наполовину нового файла, но, похоже, он всегда будет в том состоянии, в котором он был, когда он был открыт потребителем, даже если его несколько раз переименовывали / перезаписывали.

Кстати, эти процессы выполняются на одной машине (RHEL 6).

Спасибо!

1 ответ

Решение

В Linux и аналогичных системах, если процесс имеет открытый файл и файл удаляется, сам файл остается восстановленным до тех пор, пока все процессы не закроют его. Все, что происходит немедленно, - это то, что запись каталога удаляется, и ее нельзя открыть снова.

То же самое происходит, если переименование используется для замены открытого файла. Старый дескриптор файла по-прежнему сохраняет старый файл открытым. Тем не менее, новые открытия увидят новый файл.

Поэтому, чтобы ваши пользователи увидели новый файл, они должны закрыть и снова открыть файл.

Примечание. Ваши потребители могут определить, был ли файл заменен с помощью stat(2) позвонить. Если либо st_dev или же st_ino записи (или оба) были изменены, затем файл был заменен и должен быть закрыт и открыт заново. Вот как tail -F работает.

Другие вопросы по тегам