LINUX.ORG.RU

[СИ] readdir()

 


0

1

[СИ] readdir()

Язык СИ
ОС UNIX

Вопрос.
Что случится, если во время чтения каталога
(readdir()) этот каталог изменится?

Кто знает прошу ответить.


Пояснение откуда взялся вопрос.

Имеется самодельный копировщик каталога (сырой).
Он рекурсивно обходит дерево и копирует
всё на другой сервер. Использую функцию
readdir(). Каталог большой:
десятки тысяч файлов и общая длина
десятки Гб.

Файлы могут меняться прямо в процессе
копирования (но не слишком часто).
Какой либо синхронизации между копировщиком
и процессами, меняющими файлы, нет.
Но и требования не очень жесткие.
Достаточно скопировать цельный файл, каким он
был до изменения, или после изменения.

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

Затем еще раз эти немногие проверить на дату,
и так до полного удовлетворения.
Учитывая не частое изменение файлов, такой
алгоритм можно считать практически конечным.

Я уже было торжествовал победу, но тут сообразил,
что меняться-то могут не только файлы, но и
каталоги. И я не знаю, как поведёт себя функция
readdir() при этом. Пропустить несколько
только что созданных файлов допускается.
Не беда, если файлы скопированы, а вскоре
их удалили.
Но не случится ли тут чего похуже?


Ответ на: комментарий от xcreatepixmap

Спасибо.
Я не знал inotify.
Ищу теперь Free-Bsd аналог (kqueue).

Вот думаю как это моей задаче поможет.
Получаю весть о изменении каталога,
и что делать? Перечитывать и копировать весь
каталог заново? Это много.
Вот прочитаю еще как устроен файл-каталог
и как он меняется. Как мне помнится, запись
там идет не обязательно к концу файла, а удаление
меткой «удален». Если безнадежно, то
может быть копировать его в другой файл.
Так больше шансов получить «мгновенную»
фотографию каталога. А потом уж работать
с этой фотографией.
Задача из простой становится менее простой
и более громоздкой.

oleg_2
() автор топика
Ответ на: комментарий от oleg_2

>Перечитывать
да

и копировать весь каталог заново? Это много.

только diff же.

anon_666
()
Ответ на: комментарий от xcreatepixmap

anon_666 «только diff»
Я не уверен, но предполагаю, что
при изменении каталога порядок записей
в нем может изменится. Я как узнаю diff,
не придется ли для этого вести список
уже скопированного (а первоначально это
не предполагалось) и далее при чтении
сравнивать, не скопировано ли это раньше.


xcreatepixmap «узнает о новых файлах»
Да. Я еще не пользовался никогда inotify,
который Вы подсказали, или его Eree-Bsd аналогом.
Но сейчас меня больше заботит не то, как узнать,
а что делать, если узнаю.

oleg_2
() автор топика

И все же.

Что случится, если во время чтения каталога (readdir()) этот каталог изменится? POSIX на эту тему что-нибудь обещает?

Manhunt ★★★★★
()
Ответ на: И все же. от Manhunt

Directory entries represent files; files may be removed from a directory or added to a directory asynchronously to the operation of readdir().

If a file is removed from or added to the directory after the most recent call to opendir() or rewinddir(), whether a subsequent call to readdir() returns an entry for that file is unspecified.

Manhunt ★★★★★
()
Ответ на: комментарий от Begemoth

первая мысль была такой же :)

ТС, ты уверен что тебе нужно что-то писать? ты rsync уже пробовал? если пробовал, то чем он тебе не подходит?

Cy6erBr4in ★★★
()
Ответ на: комментарий от oleg_2

>Я как узнаю diff, не придется ли для этого вести список уже скопированного (а первоначально это не предполагалось) и далее при чтении сравнивать, не скопировано ли это раньше.

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

И не переизобретай rsync же, правильно говорят.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.