Como fazer uma cópia completa do conteúdo de um sistema de arquivos btrfs? Por cópia completa, quero dizer não apenas os dados atuais , mas também subvolumes diferentes com seus snapshots , preservando idealmente suas estruturas CoW (ou seja: não duplicando blocos com o mesmo conteúdo.
Parece que uma cópia em nível de bloco (como com dd
) não é uma boa ideia, pois duplica o UUID e , aparentemente, não há uma maneira de alterá-lo facilmente .
Não encontrei nenhuma solução pronta até hoje (06/05/2016), mas resolvi o problema para meus propósitos, incluindo o manuseio Copy-on-Write. Os passos para "clone"
/source
para/target
são:Obter uma lista de subvolumes ordenados por
ogen
:btrfs subvolume list -qu --sort ogen /source
. A classificação é provavelmente suficiente para garantir que os instantâneos ou subvolumes que dependem dos anteriores sejam manipulados primeiro. Isso é importante para lidar com o Copy-on-Write, porque precisamos transferir os volumes base primeiro.Tornar todos os subvolumes somente leitura usando
btrfs property set -ts /source/some-volume ro true
.Agora, para cada subvolume da lista acima, começando no topo, faça o seguinte:
Se o volume não tiver um UUID pai (exibido como
-
) ou o UUID pai não existir mais na lista, execute:btrfs send /source/some/volume | btrfs receive /target/some/
Se o volume tiver um UUID pai que ainda exista, já o teremos transferido por causa disso
--sort ogen
e podemos usá-lo como base para evitar a duplicação de dados. Portanto, encontre o caminho do UUID pai na lista e execute:btrfs send -p /source/parent/volume/ -c /source/parent/volume/ /source/some/volume/ | btrfs receive /target/some/
(o btrfs provavelmente adivinharia o-p
argumento automaticamente, mas eu prefiro ser explícito).Depois de executar um dos comandos acima fazem o alvo e fonte de leitura e escrita de novo:
btrfs property set -ts /source/some/volume ro false; btrfs property set -ts /target/some/volume ro false
. Esta etapa pode ser ignorada se a fonte tiver sido anteriormente somente leitura.Isso deve lidar com muitos casos. Ressalvas:
Pode haver algumas complicações com relação à solicitação ao aninhar subvolumes / instantâneos.
Todo o processo é obviamente mais divertido quando roteirizado.
btrfs send
aceita vários-c
argumentos de origem de clone ( ). Pode ser vantajoso não apenas especificar o caminho do volume do pai, mas também o de qualquer ancestral ou simplesmente qualquer volume enviado anteriormente. Não fez nenhuma diferença aqui, mas pode - apenas um palpite - ajudar a evitar a duplicação de dados em alguns casos.Não tenho certeza se alguma informação meta sobre instantâneos ou subvolumes é perdida ao longo do caminho, mas praticamente tudo o que é interessante para a maioria dos casos de uso deve ser preservado.
Todo o processo me ajudou a transferir um sistema de arquivos de 800 GB com 3,8 GB usado (de acordo com
df
) para uma imagem de 10 GB com 3,8 GB usados. Transferir sem-p
e-c
teria usado cerca de 190 GB, portanto a duplicação de dados foi realmente evitada.fonte
ogen
significa?ogen
é a "geração de origem" do subvolume. Devo admitir que não compreendo completamente as diferenças ou se o uso da geração (não de origem) estaria correto, mas assumo que algum teste indicou que isso funcionou melhor (duplicação evitada). A geração parece ser atualizada ao criar snapshots com base em um subvolume, ogen não. Eu estaria interessado em ouvir sobre algumas descobertas. Provavelmente, é melhor verificar o IRC ou a lista de discussão Btrfs.Eu criei uma ferramenta python que pode fazer isso. Fiz isso porque tentei a abordagem do @Thomas Luzat tanto na minha implementação quanto na do @Johannes Ernst, e o espaço usado dobrou de 20 GB para 40 GB no procedimento de clonagem. Eu pensei que algo mais eficiente era necessário.
Considere este histórico comum do sistema de arquivos:
Com o algoritmo de Thomas, "atual" seria clonado primeiro e todos os instantâneos (sendo instantâneos de estados anteriores de "atual") usariam "atual" como origem / pai do clone. Obviamente, seria melhor basear o snap3 no snap4, snap2 no snap3, etc.
E isso é só o topo do iceberg; encontrar as "melhores" fontes de clones (em termos de economia de espaço) em um sistema de arquivos btrfs com um histórico complexo é um problema não trivial. Eu criei outras três estratégias para resolver esse problema, que parecem usar o espaço com muito mais eficiência. Na verdade, resultou no tamanho dos clones um pouco abaixo do da fonte.
Você pode ler os detalhes na página do github, se estiver interessado.
fonte
Há uma pergunta semelhante no unix.stackexchange.com que aponta para partclone.btrfs, mas não conheço detalhes específicos sobre isso.
Há também uma discussão na lista de discussão do kernel , que não parece realmente promissora ...
fonte
Com
btrfs-send
, que eu vi pela última vez, ainda havia patches experimentais flutuando na lista de discussão btrfs.fonte