Перемещение каталога атомарно

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

rm -rf alpha
mv bravo alpha

Команда mv является атомарной, но комната-rf не. Существует ли простой путь в ударе для атомной замены альфы браво? В противном случае есть ли сложный путь?

ПРИЛОЖЕНИЕ:

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

35
задан paxdiablo 21 November 2008 в 01:08
поделиться

10 ответов

Можно сделать это при использовании символьных ссылок:

Скажем, альфа является символьной ссылкой на каталог alpha_1, и Вы хотите переключить символьную ссылку для указания на alpha_2. Вот то, на что это похоже перед переключателем:

$ ls -l
lrwxrwxrwx alpha -> alpha_1
drwxr-xr-x alpha_1
drwxr-xr-x alpha_2

, Чтобы заставить альфу относиться к alpha_2, используйте ln - NSF:

$ ln -nsf alpha_2 alpha
$ ls -l
lrwxrwxrwx alpha -> alpha_2
drwxr-xr-x alpha_1
drwxr-xr-x alpha_2

Теперь можно удалить старый каталог:

$ rm -rf alpha_1

Примечание, что это не на самом деле полностью атомарная операция, но это действительно происходит очень быстро, так как "ln" управляют, и расцепляет и затем сразу воссоздает символьную ссылку. Можно проверить это поведение с strace:

$ strace ln -nsf alpha_2 alpha
...
symlink("alpha_2", "alpha")             = -1 EEXIST (File exists)
unlink("alpha")                         = 0
symlink("alpha_2", "alpha")             = 0
...

можно повторить эту процедуру, как желаемый: например, когда у Вас есть новая версия, alpha_3:

$ ln -nsf alpha_3 alpha
$ rm -rf alpha_2
17
ответ дан 27 November 2019 в 06:37
поделиться

Почему не делают Вас, просто делают что-то как:

rm -rf alpha/*
mv bravo/* alpha/
rm -rf bravo/

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

-2
ответ дан 27 November 2019 в 06:37
поделиться

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

0
ответ дан 27 November 2019 в 06:37
поделиться

Я не полагаю, что существует любой атомарный способ сделать это. Ваш лучший выбор состоит в том, чтобы сделать что-то вроде этого:

mv alpha delme
mv bravo alpha
rm -rf delme
0
ответ дан 27 November 2019 в 06:37
поделиться

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

семафорный подход Oddthinking является единственным способом пойти.

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

1
ответ дан 27 November 2019 в 06:37
поделиться

Даже при доступе к inodes непосредственно все еще не было бы никакого способа атомарно подкачать значения inode в пространстве пользователя.

1
ответ дан 27 November 2019 в 06:37
поделиться

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

Так, если создание и удаление файла операции являются атомарными:

1) создают файл, названный "семафором".

2), Если и только если это успешно (никакой конфликт с существующим файлом), сделайте операцию (или альфа процесса, или переместите каталог, в зависимости от процесса)

3) семафор комнаты.

6
ответ дан 27 November 2019 в 06:37
поделиться

Если Вы имеете в виду атомарный через обе операции, я не верю так. Самое близкое было бы:

mv alpha delta
mv bravo alpha
rm -rf delta

, но это все еще имело бы маленькое окно, где альфа не существовала.

Для уменьшения вероятности чего-либо пытающегося использовать альфу, в то время как это не там Вы, мог (если у Вас есть полномочия):

nice --20 ( mv alpha delta ; mv bravo alpha )
rm -rf delta

, который провернет Ваш приоритет процесса существенно, в то время как эти mv операции происходят.

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

6
ответ дан 27 November 2019 в 06:37
поделиться

Раздел документации SQLite Блокировка файлов и параллелизм в SQLite версии 3 имеет хорошо написанное описание протокол расширенной блокировки для управления одновременным чтением, эксклюзивной записью и откатом после сбоя. Некоторые из этих идей применимы и здесь.

4
ответ дан 27 November 2019 в 06:37
поделиться

mv и ln могут использоваться для атомарных операций. Я использовал ln (1) для атомарного развертывания веб-приложений.

Правильный способ заменить символическую ссылку - использовать ln -nsf

ln -nsf <target> <link_name>

, например,

$ mkdir dir1
$ mkdir dir2
$ ln -s dir1 mylink
$ ls -l mylink
lrwxrwxrwx  1 phil phil 4 Nov 16 14:45 mylink -> dir1
$ ln -nsf dir2 mylink
$ ls -l mylink
lrwxrwxrwx  1 phil phil 4 Nov 16 14:46 mylink -> dir2
0
ответ дан 27 November 2019 в 06:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: