Btrfs не получает инкрементные потоки: «Файл существует»

Btrfs не получает инкрементные потоки: «Файл существует»

Для подтома btrfs у меня есть простая инкрементная резервная копия, созданная в два этапа:

btrfs send old/@ > base.btrfs
btrfs send new/@ -p old/@ > update.btrfs

Два исходных подтома представляют собой моментальные снимки, сделанные в разное время с одного и того же активно смонтированного подтома.

На целевом объекте я пытаюсь восстановить:

btrfs receive ./ < base.btrfs
btrfs receive ./ < update.btrfs

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

Предыдущая команда выполнена успешно, а последняя не выполнена:

ERROR: creating snapshot ./@ -> @ failed: File exists

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

Как применить этап обновления к цели, созданной путем восстановления начального этапа?

решение1

Вы не можете иметь (как на отправляющей стороне) несколько подтомов с одинаковым именем.

Вы можете создать mvбазовый снимок/подтом на целевой системе:

mv @ @.old
btrfs receive ./ < update.btrfs

решение2

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

Ответ состоит из двух частей.

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

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

После восстановления родителя и дочерних объектов любые родители могут быть удалены без ущерба для дочерних объектов.

Следовательно, эффективной последовательностью команд для достижения первоначальной цели будет следующая:

mkdir _tmp
btrfs receive _tmp/ < base.btrfs
btrfs receive ./ < update.btrfs
btrfs subvolume delete _tmp/@
rmdir _tmp

Весь контент дочернего потока затем будет доступен через ./@.

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

Связанный контент