Атоми c копировать в c - PullRequest
       145

Атоми c копировать в c

0 голосов
/ 06 августа 2020

Я пытаюсь реализовать версию c копирования atomi при записи. У меня есть определенные условия, при выполнении которых будет сделана копия исходного файла.

Я реализовал что-то вроде этого псевдокода.

//write operations//
if(some condition)
   //create a temp file//
   rename(srcfile, copied-version)
   rename(tmpfile, srcfile) 

проблема с этим logi c:

Жесткие ссылки. Я хочу перенести Hardlink из скопированной версии в новый srcfile.

Ответы [ 2 ]

0 голосов
/ 07 августа 2020

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

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

Подробнее см. man 2 fcntl Сдаёт в аренду и Управляющие сигналы разделы. У процесса должен быть тот же владелец, что и у файла, или возможность CAP_LEASE (обычно предоставляется процессу через возможности файловой системы). Процессы суперпользователя (запущенные как root) имеют такую ​​возможность по умолчанию.

Идея состоит в том, что, когда процесс хочет внести в файл изменения «atomi c», он получает аренду на запись в файл . Это будет успешным только в том случае, если ни один другой процесс не открыл файл. Если другой процесс пытается открыть файл, владелец аренды получает сигнал и имеет время перерыва в аренде (обычно около минуты) понизить аренду (или просто закрыть файл); в это время открыватель заблокируется.

Обратите внимание, что нет возможности отклонить открыватель. Ситуация такова, что открывающая программа уже имеет дескриптор базового inode (поэтому проверки доступа и разрешение имени файла уже произошли); просто ядро ​​не вернет его в процесс пользовательского пространства до того, как аренда будет освобождена или разорвана.

Однако ваш владелец аренды может создать копию текущего содержимого во временный файл, получив запись арендовать и это, а затем переименовать его по имени целевого файла. Таким образом, каждый (набор) открывателей получает дескриптор содержимого файла, каким оно было во время открытия; если они внесут какие-либо изменения, они будут «частными» и не будут отражены в исходном файле. Поскольку на базовый индексный дескриптор больше не ссылаются никакие имена файлов, когда они (последний процесс, открывший его) закрывают его, индексный дескриптор удаляется, а хранилище возвращается обратно файловой системе. Страничный кеш Linux также очень хорошо кэширует такие обращения, поэтому во многих случаях «файл временной копии» никогда даже не попадает на фактический носитель (за исключением случаев нехватки памяти, то есть памяти, необходимой для целей, не связанных с кешированием страниц).

Чистая модификация atomi c не требует каких-либо копий или переименований, только удерживает аренду на время набора записей, которые должны появиться atomi c для читателей.

Обратите внимание, что использование аренды для записи обычно блокируется до тех пор, пока ни один из других процессов не перестанет открывать файл, поэтому время, в которое может произойти такое обновление atomi c на основе аренды, ограничено и не гарантируется, что будет всегда доступно. (Например, у вас может быть ленивый процесс, который просто держит файл открытым и иногда опрашивает его. Если у вас есть такие процессы, этот подход, основанный на аренде, не будет работать, как и подход копирования-переименования. )

Кроме того, аренда работает только с локальными файлами.

Если вам нужна атомарность на основе записей, просто используйте блокировки записей на основе fcntl, и пусть все считыватели принимают блокировку чтения для региона они хотят получить доступ атомарно, и все писатели устанавливают блокировку записи для обновляемой области, поскольку блокировки записи носят рекомендательный характер (т. е. не блокируют чтение или запись, а блокируют только другие записи).

0 голосов
/ 06 августа 2020

Вы не можете.

Жесткие ссылки - это однонаправленные указатели. Таким образом, вы не можете изменять или удалять другие жесткие ссылки, о которых вы явно не знаете. Все, что вы можете сделать, это записать данные в один и тот же файл, и это не atomi c.

Это правило применяется единообразно как к haslinks, так и к файловым дескрипторам . Это означает, что вы не можете изменять контент, на который указывает неизвестная жесткая ссылка, и не изменять контент, на который указывает другой процесс с тем же открытым файлом.

Это эффективно мешает вам от модификации файла, на которую указывает неизвестная жесткая ссылка.

Если у вас есть контроль над каждым процессом, который может изменять эти файлы или получать к ним доступ (если они изменяются только программами, которые вы написали), тогда вы можете использовать flock () для передачи сигналов другие процессы, в которых используется файл. Это не сработает, если файл хранится в удаленной файловой системе NFS, но обычно должно работать в противном случае.

...