Entendendo subvolumes no BTRFS

Já usei o OpenSUSE Tumbleweed por um mês e gostei das possibilidades de snapshots. O programa snapper resolve de forma definitiva a organização para deletar snapshots antigos e garimpar informações sobre alterações, inclusive com um diff como opção para visualizar diferenças entre versões de arquivo.

Porém tentei entender a lógica dos subvolumes e me perdi diversas vezes. Nessa última semana me propuz a masterizar esse assunto e como exercício alterei uma instalação do linux Mint na máquina virtual de uma instalação padrão (apenas uma partição EFI e uma EXT4) para uma instalação com suporte a snapshots usando o snapper. Quebrei o sistema diversas vezes, consertei e aprendi bastante. Não vou fazer disso um tutorial dessa transformação, mas sim condensar informações que não são corriqueiras em tutoriais sobre o assunto mas que são de fundamental importância para saber como funcionam os subvolumes. Foram pontos que eu me bati para entender.

1) Volume BTRFS sem subvolumes

Mantra: O ID de uma partição BTRFS sem subvolumes é 5! O ID do volume é 5. Por que 5? Não sei, mas é cinco. É um número mágico quando se trata de btrfs, portanto lembre-se dessa lição. O nome desse “subvolume” é especial: (FS_TREE) e eu vou chamá-lo de Árvore.

2) O que acontece quando monto uma partição btrfs sem especificar ID ou nome de subvolume?

Simples, todo volume btrfs guarda uma informação de ID-padrão, ou Default-ID. Se nenhum subvolume foi criado, essa variável guarda o ID 5. Ao montar o volume btrfs, o sistema pega o valor do id-padrão e monta o subvolume com essa id. No caso de não haver subvolumes, é montada a árvore do sistema de arquivos (FS_TREE). (Resposta continua no ITEM 5)

3) O que acontece quando eu crio um subvolume?

Primeiro, lembre-se que você cria um subvolume num sistema de arquivos que foi montado. Portanto o subvolume criado vira um filho do subvolume em questão. Se é o primeiro subvolume que você criou, ele vai ser filho do ID 5! O ID desse primeiro subvolume é geralmente algo perto de 250, mas provavelmente será referenciado pelo nome que foi escolhido. Se você voltar na pasta onde montou o btrfs, verá que apareceu um diretório com o mesmo nome do subvolume. Não se engane, aquele não é um diretório comum, é um subvolume! Para lembrar esse fato, duas abordagens são mais costumeiras:

  1. Dar nomes aos subvolumes que comecem com @, todos eles filhos da Árvore (o id 5). Assim terá na Árvore os subvolumes @rootfs, @home, @snapshots, @var_log, etc…
  2. Criar um subvolume de nome @, e criar todos os demais subvolumes dentro desse subvolume sem @ no nome. Para isso cria-se o subvolume @, depois cria-se novos subvolumes nele. Assim a referência desses subvolumes será @/home, @/.snapshots, @/usr/local . Nesse caso o subvolume pai do subvolume @/home não será o 5, mas o ID do @.

4) O que acontece quando monto uma partição btrfs especificando o nome de subvolume ou id?

Simples, no ponto de montagem especificado será montado o subvolume também especificado. Se não houver subvolume com esse ID ou nome, será retornado erro.

5) O que acontece quando monto uma partição btrfs sem especificar ID ou nome de subvolume?

O sistema irá montar o subvolume especificado no ID-Padrão. Agora que já há diversos subvolumes na partição o valor do id-padrão é importante. Você provavelmente vai querer mudar o ID-Padrão para o subvolume que escolheu ser o raiz do seu sistema operacional. Costumeiramente é o subvol @rootfs ou então o @. Assim quando o kernel montar o seu sistema de arquivos, já montará a raiz do sistema. Também não precisará alterar o seu /etc/fstab, deixando o ponto de montagem do / sem especificar subvolumes. Em sistemas que terão snapshots, também costuma-se deixar o ID-Padrão para o subvolume da atual versão dos arquivos.

6) Mas o GRUB? Como especificar o subvolume durante a inicalização?

O GRUB só vê a Árvore, ele só “monta” o ID 5. Então refira-se aos arquivos como se estivesse montando o subvolid=5. Para chamar o kernel, o comando ficará linuxefi (hd0,gpt2)/@rootfs/boot/vmlinuz options ou então linuxefi /@rootfs/boot/vmlinuz options caso já tenha especificado anteriormente a variável “root”.

  • Dica: É costume criar um ponto de montagem /btrfs/ para montar a Árvore (subvolid=5). Isso facilita a visualização de subvolumes bem como operações de movimentação (renomear) dos subvolumes.

Conteúdo disponível colaborativamente em GitHub - deleterium/TutoraisBTRFS: Tutoriais e exercícios para entender o funcionamento do sistema de arquivos BTRFS.

10 curtidas

Exercícios

1) Criar, formatar e montar um volume btrfs em arquivo de imagem no seu diretório de usuário.

mkdir testesBTRFS
cd testesBTRFS
truncate -s 200M imagem.img
mkfs.btrfs -L MinhaImagemBTRFS imagem.img
mkdir imagemMontada
sudo mount -o loop imagem.img imagemMontada/

Notas: O comando truncate somente aloca espaço no disco, portanto o conteúdo do arquivo é desconhecido. O mkfs.btrfs faz a formatação desse espaço reservado para organizar o sistema de arquivos e gravar a informação de espaço livre. Se não há esse comando instale o pacote btrfs-progs ou btrfs-tools (depende da distribuição). A opção -o loop no comando mount serve para montar arquivos como se fossem dispositivos de bloco.

2) Criar dois subvolumes, @raiz e @home.

sudo btrfs subvolume create imagemMontada/@raiz
sudo btrfs subvolu crea imagemMontada/@home

Nota: As opções do comando btrfs podem ser abreviadas desde que não causem confusão com outras opções.

3) Verificar os ID’s dos subvolumes criados

sudo btrfs subvol list ./imagemMontada

4) Qual o ID padrão do volume btrfs?

sudo btrfs subv get-default ./imagemMontada

5) Crie um diretório e copie um arquivo para dentro do imagemMontada:

mkdir ./imagemMontada/novodir
cp /etc/fstab ./imagemMontada/novodir

Nota: Saber trabalhar com permissões de arquivos é pré-requisito para esse tutorial. Caso não saiba veja a cola: sudo chown SeuUsuario imagemMontada/.

6) Liste o conteúdo da imagemMontada:

ls -la ./imagemMontada
Nota: Além do diretório criado também há “diretórios” que são subvolumes!

7) Copie um arquivo para um subvolume sem precisar montá-lo especificamente

sudo cp /etc/profile ./imagemMontada/@raiz
ls -la ./imagemMontada/@raiz

Nota: O autocompletar não funciona muito bem com o @, portanto as vezes tem que escrever tudo…

8) Monte um subvolume:

mkdir subvolumeMontado
sudo mount -o loop,subvol=@raiz imagem.img ./subvolumeMontado

Nota: A opção loop só e necessária por causa do arquivo ser imagem. Como o arquivo imagem.img já está montado, é possível também montar usando o dispositivo de bloco já configurado. O comando seria sudo mount -o subvol=@raiz /dev/loop0 ./subvolumeMontado .

9) Liste o conteúdo do subvolume Montado

ls -la ./subvolumeMontado

Nota: Veja que já está lá o arquivo que foi copiado via Árvore!

10) Altere o id-padrão do volume para o subvolume @home

sudo btrfs sub li ./imagemMontada
sudo btrfs subvolume set-default XXX ./imagemMontada

Nota: Substitua o valor XXX pelo ID mostrado pelo list.

11) Liste o id-padrão do subvolume @raiz

sudo btrfs subvolume get-default ./subvolumeMontado

Nota: Ao se alterar o ID-padrão de qualquer subvolume, será alterado o ID-padrão do volume como um todo. Da mesma forma pegar a variável id-padrão de qualquer subvolume retornará o valor do id-padrão da Árvore.

12) Desmonte tudo

sudo umount ./imagemMontada
sudo umount ./subvolumeMontado

13) Monte a imagem sem especificar subvolume e liste seu conteúdo

sudo mount -o loop imagem.img ./imagemMontada
ls -la ./imagemMontada

Nota: Como era de se esperar, foi montado o subvolume @home, que está vazio.

14) Liste os subvolumes do diretório imagemMontada

sudo btrfs subvo lis ./imagemMontada

Nota: Foram mostrados todos os subvolumes da Árvore. Talvez alguns esperassem que fosse mostrado apenas os subvolumes do subvolume @home, mas não é assim que funciona. O list sempre mostra todos os subvolumes!

15) Crie um arquivo e um subvolume no subvolume @home

sudo touch ./imagemMontada/arquivo.txt
sudo btrfs subv creat ./imagemMontada/temp-files

16) Liste o conteúdo do diretório imagemMontada

ls -la ./imagemMontada

Nota: Essa é uma estratégia que pode ser usada para snapshots, onde os subvolumes não são monitorados. Neste caso um futuro snapshot do @home não conterá os arquivos dentro do temp-files.

17) Crie mais um subvolume na Árvore, nomeado @tmp.

Nota: a árvore não está montada, então primeiro teremos que montá-la para depois criar o subvolume. Não é possível acessá-la pelo ponto de montagem imagemMontada, pois ele está montado como um subvolume e não é possível acessar volumes de hieraquia anterior a ele.

mkdir arvoreMontada
sudo mount -o loop,subvolid=5 imagem.img ./arvoreMontada
sudo btrfs subvol create ./arvoreMontada/@tmp
sudo btrfs sub list ./arvoreMontada

Nota: Número mágico 5 aparecendo aqui para montar a Árvore, pois não é possível montá-la pelo nome. Note também que com a árvore montada é possível criar subvolumes em qualquer subvolume! Outro ponto é perceber o relacionamento dos subvolumes, com o top level indicando o subvolume pai. Neste caso apenas o temp-files não é filho direto da árvore, mas sim do subvolume @home (perceba pelo id do top level)

18) Renomeie o subvolume @raiz para @rootfs

Nota: Não existe um comando específico do btrfs para renomear o volume. Porém mover o subvolume como se fosse um diretório resolve a situação. Para essas operações monte a Árvore. Mover um subvolume não altera seu ID, então se ele for o ID-padrão, continuará sendo.

mv ./arvoreMontada/@raiz ./arvoreMontada/@rootfs
sudo btrfs sub list ./arvoreMontada

19) Mova o subvolume @tmp para dentro do subvolume @home, renomeando-o para tmp

sudo mv ./arvoreMontada/@tmp ./arvoreMontada/@home
sudo mv ./arvoreMontada/@home/@tmp ./arvoreMontada/@home/tmp
sudo btrfs sub list ./arvoreMontada

Nota: Mover um subvolume para dentro de outro subvolume não altera seu ID, mas altera o subvolume pai. Veja como o top level do subvolume tmp mudou.

20) Monte o subvolume padrão e crie um arquivo de 120MB

sudo mount -o loop imagem.img ./imagemMontada
truncate -s 120M ./imagemMontada/arquivogrande.lixo
ls -la ./imagemMontada/arquivogrande.lixo

21) Crie uma cópia desse arquivo no subvolume temp-files.

cp ./imagemMontada/arquivogrande.lixo ./imagemMontada/tmp-files

Nota: Como era de se esperar, não há espaço suficiente no disco para dois arquivos de 120M, a imagem foi criada com 200MB. Porém uma das vantagens do btrfs é que ele não precisa copiar o conteúdo, ele pode apenas indicar que o mesmo conteúdo está em outro lugar do disco. Para tal usamos a opção –reflink=always ao copiar.

cp --reflink=always ./imagemMontada/arquivogrande.lixo ./imagemMontada/tmp-files

A cópia foi efetuada! Esse é o princípio de funcionamento dos snapshots, onde uma grande quantidade de arquivos parece estar duplicada, mas guardam suas referências de conteúdo.

22) Remova o arquivo do volume padrão e verifique o espaço livre:

rm ./imagemMontada/arquivogrande.lixo
df ./imagemMontada

Nota: O espaço livre não foi liberado pois o conteúdo ainda é referenciado em outro local.

23) Remova o arquivo do subvolume e verifique o espaço livre:

rm ./imagemMontada/tmp-files/arquivogrande.lixo
df ./imagemMontada

Nota: Agora sim o espaço foi liberado. Lembre-se que o espaço só será liberado quando não houver nenhuma referência ao conteúdo do arquivo. Isso pode ser fácil quando há poucos subvolumes, mas quando há 50 snapshots fica difícil. Nessa hora que os programas que auxiliam essa tarefa entram em jogo, como o snapper. Mas isso é assunto para um próximo tutorial!

Exercícios solucionados

john@MintVM:~$ # 1
john@MintVM:~$ mkdir testesBTRFS
john@MintVM:~$ cd testesBTRFS
john@MintVM:~/testesBTRFS$ truncate -s 200M imagem.img
john@MintVM:~/testesBTRFS$ mkfs.btrfs -L MinhaImagemBTRFS imagem.img
btrfs-progs v4.15.1
See http://btrfs.wiki.kernel.org for more information.

Label:              MinhaImagemBTRFS
UUID:               0e507c12-de93-4d14-be5a-c361660af3ce
Node size:          16384
Sector size:        4096
Filesystem size:    200.00MiB
Block group profiles:
  Data:             single            8.00MiB
  Metadata:         DUP              32.00MiB
  System:           DUP               8.00MiB
SSD detected:       no
Incompat features:  extref, skinny-metadata
Number of devices:  1
Devices:
   ID        SIZE  PATH
    1   200.00MiB  imagem.img

john@MintVM:~/testesBTRFS$ mkdir imagemMontada
john@MintVM:~/testesBTRFS$ sudo mount -o loop imagem.img imagemMontada/
[sudo] senha para john:     
john@MintVM:~/testesBTRFS$ # 2
john@MintVM:~/testesBTRFS$ sudo btrfs subvolume create imagemMontada/@raiz
Create subvolume 'imagemMontada/@raiz'
john@MintVM:~/testesBTRFS$ sudo btrfs subvolu crea imagemMontada/@home
Create subvolume 'imagemMontada/@home'
john@MintVM:~/testesBTRFS$ # 3
john@MintVM:~/testesBTRFS$ sudo btrfs sub list ./arvoreMontada
ID 256 gen 18 top level 5 path @raiz
ID 257 gen 25 top level 5 path @home
john@MintVM:~/testesBTRFS$ # 4
john@MintVM:~/testesBTRFS$ sudo btrfs subvolume get-default ./imagemMontada
ID 5 (FS_TREE)
john@MintVM:~/testesBTRFS$ # 5
john@MintVM:~/testesBTRFS$ mkdir ./imagemMontada/novodir
mkdir: não foi possível criar o diretório “./imagemMontada/novodir”: Permissão negada
john@MintVM:~/testesBTRFS$ ls -la ./imagemMontada/
total 16
drwxr-xr-x 1 root root 20 fev 29 10:56 .
drwxr-xr-x 1 john john 46 fev 29 10:56 ..
drwxr-xr-x 1 root root  0 fev 29 10:59 @home
drwxr-xr-x 1 root root  0 fev 29 10:59 @raiz
john@MintVM:~/testesBTRFS$ sudo chown john:john imagemMontada/.
john@MintVM:~/testesBTRFS$ ls -la ./imagemMontada/
total 16
drwxr-xr-x 1 john john 20 fev 29 10:56 .
drwxr-xr-x 1 john john 46 fev 29 10:56 ..
drwxr-xr-x 1 root root  0 fev 29 10:59 @home
drwxr-xr-x 1 root root  0 fev 29 10:59 @raiz
john@MintVM:~/testesBTRFS$ mkdir ./imagemMontada/novodir
john@MintVM:~/testesBTRFS$ cp /etc/fstab ./imagemMontada/novodir
john@MintVM:~/testesBTRFS$ # 6
john@MintVM:~/testesBTRFS$ ls -la ./imagemMontada/
total 16
drwxr-xr-x 1 john john 34 fev 29 11:04 .
drwxr-xr-x 1 john john 46 fev 29 10:56 ..
drwxr-xr-x 1 root root  0 fev 29 10:59 @home
drwxr-xr-x 1 john john  0 fev 29 11:04 novodir
drwxr-xr-x 1 root root  0 fev 29 10:59 @raiz
john@MintVM:~/testesBTRFS$ # 7
john@MintVM:~/testesBTRFS$ sudo cp /etc/profile ./imagemMontada/@raiz
john@MintVM:~/testesBTRFS$ ls -la ./imagemMontada/@raiz
total 20
drwxr-xr-x 1 root root  14 fev 29 11:16 .
drwxr-xr-x 1 john john  34 fev 29 11:04 ..
-rw-r--r-- 1 root root 581 fev 29 11:16 profile
john@MintVM:~/testesBTRFS$ # 8
john@MintVM:~/testesBTRFS$ mkdir subvolumeMontado
john@MintVM:~/testesBTRFS$ sudo mount -o loop,subvol=@raiz imagem.img ./subvolumeMontado
john@MintVM:~/testesBTRFS$ # 9
john@MintVM:~/testesBTRFS$ ls -la ./subvolumeMontado
total 8
drwxr-xr-x 1 root root  24 fev 29 11:17 .
drwxr-xr-x 1 john john  78 fev 29 11:22 ..
-rw-r--r-- 1 root root 581 fev 29 11:16 profile
john@MintVM:~/testesBTRFS$ # 10
john@MintVM:~/testesBTRFS$ sudo btrfs sub li ./imagemMontada
ID 256 gen 18 top level 5 path @raiz
ID 257 gen 10 top level 5 path @home
john@MintVM:~/testesBTRFS$ sudo btrfs subvolume set-default 257 ./imagemMontada
john@MintVM:~/testesBTRFS$ # 11
john@MintVM:~/testesBTRFS$ sudo btrfs subvolume get-default ./subvolumeMontado
ID 257 gen 10 top level 5 path @home
john@MintVM:~/testesBTRFS$ 
john@MintVM:~/testesBTRFS$ # 12
john@MintVM:~/testesBTRFS$ sudo umount ./imagemMontada
john@MintVM:~/testesBTRFS$ sudo umount ./subvolumeMontado
john@MintVM:~/testesBTRFS$ # 13
john@MintVM:~/testesBTRFS$ sudo mount -o loop imagem.img ./imagemMontada
john@MintVM:~/testesBTRFS$ ls -la ./imagemMontada
total 0
drwxr-xr-x 1 root root  0 fev 29 10:59 .
drwxr-xr-x 1 john john 78 fev 29 11:22 ..
john@MintVM:~/testesBTRFS$ # 14
john@MintVM:~/testesBTRFS$ sudo btrfs subvo lis ./imagemMontada
ID 256 gen 18 top level 5 path @raiz
ID 257 gen 10 top level 5 path @home
john@MintVM:~/testesBTRFS$ # 15
john@MintVM:~/testesBTRFS$ sudo touch ./imagemMontada/arquivo.txt
john@MintVM:~/testesBTRFS$ sudo btrfs subv creat ./imagemMontada/temp-files
Create subvolume './imagemMontada/temp-files'
john@MintVM:~/testesBTRFS$ # 16
john@MintVM:~/testesBTRFS$ ls -la ./imagemMontada
total 0
drwxr-xr-x 1 root root 42 fev 29 11:51 .
drwxr-xr-x 1 john john 78 fev 29 11:22 ..
-rw-r--r-- 1 root root  0 fev 29 11:51 arquivo.txt
drwxr-xr-x 1 root root  0 fev 29 11:51 temp-files
john@MintVM:~/testesBTRFS$ # 17
john@MintVM:~/testesBTRFS$ mkdir arvoreMontada
john@MintVM:~/testesBTRFS$ sudo mount -o loop,subvolid=5 imagem.img ./arvoreMontada
john@MintVM:~/testesBTRFS$ sudo btrfs subvol create ./arvoreMontada/@tmp
Create subvolume './arvoreMontada/@tmp'
john@MintVM:~/testesBTRFS$ sudo btrfs sub list ./arvoreMontada
ID 256 gen 18 top level 5 path @raiz
ID 257 gen 25 top level 5 path @home
ID 258 gen 24 top level 257 path @home/temp-files
ID 259 gen 26 top level 5 path @tmp
john@MintVM:~/testesBTRFS$ # 18
john@MintVM:~/testesBTRFS$ mv ./arvoreMontada/@raiz ./arvoreMontada/@rootfs
john@MintVM:~/testesBTRFS$ sudo btrfs sub list ./arvoreMontada
ID 256 gen 18 top level 5 path @rootfs
ID 257 gen 25 top level 5 path @home
ID 258 gen 24 top level 257 path @home/temp-files
ID 259 gen 26 top level 5 path @tmp
john@MintVM:~/testesBTRFS$ 
john@MintVM:~/testesBTRFS$ # 19
john@MintVM:~/testesBTRFS$ sudo mv ./arvoreMontada/@tmp ./arvoreMontada/@home
john@MintVM:~/testesBTRFS$ sudo mv ./arvoreMontada/@home/@tmp ./arvoreMontada/@home/tmp
john@MintVM:~/testesBTRFS$ sudo btrfs sub list ./arvoreMontada
ID 256 gen 28 top level 5 path @rootfs
ID 257 gen 28 top level 5 path @home
ID 258 gen 28 top level 257 path @home/temp-files
ID 259 gen 28 top level 257 path @home/tmp
john@MintVM:~/testesBTRFS$ # 20
john@MintVM:~/testesBTRFS$ sudo dd if=/dev/urandom of=./imagemMontada/arquivogrande.lixo bs=1M count=100
100+0 registros de entrada
100+0 registros de saída
104857600 bytes (105 MB, 100 MiB) copiados, 1,756 s, 59,7 MB/s
john@MintVM:~/testesBTRFS$ ls -la ./imagemMontada
total 102400
drwxr-xr-x 1 root root        62 fev 29 13:41 .
drwxr-xr-x 1 john john       104 fev 29 11:55 ..
-rw-r--r-- 1 root root 104857600 fev 29 13:41 arquivogrande.lixo
drwxr-xr-x 1 root root         0 fev 29 13:34 temp-files
drwxr-xr-x 1 root root         0 fev 29 13:34 tmp

john@MintVM:~/testesBTRFS$ # 21
john@MintVM:~/testesBTRFS$ sudo cp ./imagemMontada/arquivogrande.lixo ./imagemMontada/tmp
cp: erro de escrita de './imagemMontada/tmp/arquivogrande.lixo': Não há espaço disponível no dispositivo
john@MintVM:~/testesBTRFS$ sudo cp --reflink=always ./imagemMontada/arquivogrande.lixo ./imagemMontada/tmp
john@MintVM:~/testesBTRFS$ # 22
john@MintVM:~/testesBTRFS$ ls -laR ./imagemMontada/
./imagemMontada/:
total 204800
drwxr-xr-x 1 root root        80 fev 29 13:43 .
drwxr-xr-x 1 john john       104 fev 29 11:55 ..
-rw-r--r-- 1 root root 104857600 fev 29 13:41 arquivogrande.lixo
drwxr-xr-x 1 root root         0 fev 29 13:56 temp-files
drwxr-xr-x 1 root root        36 fev 29 13:57 tmp

./imagemMontada/temp-files:
total 0
drwxr-xr-x 1 root root  0 fev 29 13:56 .
drwxr-xr-x 1 root root 80 fev 29 13:43 ..

./imagemMontada/tmp:
total 102400
drwxr-xr-x 1 root root        36 fev 29 13:57 .
drwxr-xr-x 1 root root        80 fev 29 13:43 ..
-rw-r--r-- 1 root root 104857600 fev 29 13:58 arquivogrande.lixo
john@MintVM:~/testesBTRFS$ # 23
john@MintVM:~/testesBTRFS$ sudo btrfs filesystem usage ./imagemMontada
Overall:
    Device size:		 200.00MiB
    Device allocated:		 188.00MiB
    Device unallocated:		  12.00MiB
    Device missing:		     0.00B
    Used:			 100.59MiB
    Free (estimated):		   8.00MiB	(min: 8.00MiB)
    Data ratio:			      1.00
    Metadata ratio:		      2.00
    Global reserve:		  16.00MiB	(used: 0.00B)

Data,single: Size:108.00MiB, Used:100.00MiB
   /dev/loop0	 108.00MiB

Metadata,DUP: Size:32.00MiB, Used:288.00KiB
   /dev/loop0	  64.00MiB

System,DUP: Size:8.00MiB, Used:16.00KiB
   /dev/loop0	  16.00MiB

Unallocated:
   /dev/loop0	  12.00MiB
john@MintVM:~/testesBTRFS$ sudo btrfs filesystem du ./imagemMontada
     Total   Exclusive  Set shared  Filename
     0.00B       0.00B           -  ./imagemMontada/temp-files
 100.00MiB       0.00B           -  ./imagemMontada/tmp/arquivogrande.lixo
 100.00MiB       0.00B           -  ./imagemMontada/tmp
 100.00MiB       0.00B           -  ./imagemMontada/arquivogrande.lixo
 200.00MiB       0.00B   100.00MiB  ./imagemMontada
john@MintVM:~/testesBTRFS$ # 24
john@MintVM:~/testesBTRFS$ sudo rm ./imagemMontada/arquivogrande.lixo
john@MintVM:~/testesBTRFS$ sudo btrfs filesystem sync ./imagemMontada
john@MintVM:~/testesBTRFS$ sudo btrfs file us ./imagemMontada
Overall:
    Device size:		 200.00MiB
    Device allocated:		 188.00MiB
    Device unallocated:		  12.00MiB
    Device missing:		     0.00B
    Used:			 100.59MiB
    Free (estimated):		   8.00MiB	(min: 8.00MiB)
    Data ratio:			      1.00
    Metadata ratio:		      2.00
    Global reserve:		  16.00MiB	(used: 0.00B)

Data,single: Size:108.00MiB, Used:100.00MiB
   /dev/loop0	 108.00MiB

Metadata,DUP: Size:32.00MiB, Used:288.00KiB
   /dev/loop0	  64.00MiB

System,DUP: Size:8.00MiB, Used:16.00KiB
   /dev/loop0	  16.00MiB

Unallocated:
   /dev/loop0	  12.00MiB
john@MintVM:~/testesBTRFS$ # 25
john@MintVM:~/testesBTRFS$ sudo rm ./imagemMontada/tmp/arquivogrande.lixo
john@MintVM:~/testesBTRFS$ sudo btrfs filesystem sync ./imagemMontada
john@MintVM:~/testesBTRFS$ sudo btrfs filesystem usage ./imagemMontada
Overall:
    Device size:		 200.00MiB
    Device allocated:		  92.00MiB
    Device unallocated:		 108.00MiB
    Device missing:		     0.00B
    Used:			 384.00KiB
    Free (estimated):		 120.00MiB	(min: 66.00MiB)
    Data ratio:			      1.00
    Metadata ratio:		      2.00
    Global reserve:		  16.00MiB	(used: 32.00KiB)

Data,single: Size:12.00MiB, Used:0.00B
   /dev/loop0	  12.00MiB

Metadata,DUP: Size:32.00MiB, Used:176.00KiB
   /dev/loop0	  64.00MiB

System,DUP: Size:8.00MiB, Used:16.00KiB
   /dev/loop0	  16.00MiB

Unallocated:
   /dev/loop0	 108.00MiB
john@MintVM:~/testesBTRFS$ 
10 curtidas

Prezado @Deleterium boa noite. Muito obrigado por compartilhar conosco esse conhecimento fantástico do BTRFS, bem como nos deixar exercícios para praticarmos antes de “enfrentar” o FS.

Porém, gostaria de deixar uma dúvida: quando vou executar o item 21, não aparece nenhuma mensagem dizendo que o arquivo não pode ser copiado por causa do limite da “particição”. Ao realizar alguns testes, de alguma forma a aquela imagem.img no começo não foi truncado em 200 MB, como você sugeriu.

De alguma forma ela se expande, mas mantém o tamanho, permitindo que eu consigo criar inúmeras cópias do arquivogrande.lixo.

Quando faço a verificação com ls -la ./imagemMontada, lá estão presentes os inúmeros arquivos que copiei.

Ao checar a resolução dos exercícios (saída do seu terminal), você utiliza alguns comandos diferentes, mas acredito que não seja por causa disso que não consigo terminal.

Até achei que fosse algo relacionado ao comando truncate -s, mas acho difícil.

Poderia me ajudar nisto? Obrigado e novamente gostaria de parabenizá-lo pelo trabalho fantástico.

Possivelmente a sua distribuição está configurada para sempre fazer uma cópia por referência. Então a cópia que vc faz por padrão já é cp --reflink=always

Tente fazer a cópia com cp --reflink=never e, se for isso, vai dar erro de espaço não disponível.

Mesmo usando o comando cp --reflink=never a cópia aconteceu do mesmo jeito.

Tentei, inclusive criar um arquivo ‘imagem.img’ totalmente novo, montando-o sem alterar id-padrão, criando apenas os subvolumes @raiz, @home e o arquivo.lixo na Árvore.

Ao proceder à cópia para @home e @raiz, o arquivo (ou a referência nesse caso) foi para todos os subvolumes indicados.

Ao excluir o arquivo.lixo da Árvore e rodando o df no ./imagemMontada, o tamanho disponível automaticamente se reajustou (aumentou), o que me leva a crer que não está existindo as referências da forma como deveriam.

Para esclarecimento, estou usando o POP_OS! 22.04, em LVM, com ext4.

Porém, refazer estes exercícios 4 vezes já me renderam uma excelente noção de como funciona o BTRFS.

Obrigado.

truncate -s gera arquivos esparsos e que eu saiba BTRFS não aloca os buracos de arquivos esparsos, logo não é o ideal se vocês querem explorar diferenças entre --reflink=never/always. Provavelmente vai demorar mais, mas vocês terão mais sucesso com:

dd if=/dev/random of=./imagemMontada/arquivogrande.lixo bs=1 count=0 seek=120M
2 curtidas

Boa ideia!

Poderia ser usado o /dev/urandom que são bytes pseudo aleatórios e fica bem rápido de criar o arquivos. O /dev/random tem saída de bytes realmente aleatórios e dependem de entropia do sistema, por isso fica demorado criar arquivos grandes caso não haja um dispositivo específico (hardware) para isso no computador.

2 curtidas

Na verdade, ambos são pseudo-aleatórios, usam a mesma fonte (CSPRNG), a diferença é que /dev/urandom não da garantia de alta entropia nos dados, mas realmente é melhor usar dev/urandom nesse caso, ainda é um pouco lento, mas será 3x~4x mais rápido.

Tentarei desta forma @romulopb .

Obrigado pelas contribuições pessoal.

Informo que consegui instalar o POP_OS com o BTRFS seguindo um misto dos 2 guias a seguir do Mutschler Guide e um do Github Guide.

@Deleterium, sempre deixei “por conta do openSUSE / BtrFS / Snapper / Grub” a geração das opções de Snapshot no Grub do openSUSE.

De algum tempo para cá, o Grub do openSUSE parou de gerar aquele submenu de opções de Snapshot. – Em suma, se eu precisar carregar um Snapshot para fazer o Rollback, já não tenho como.

Você tem alguma ideia do que possa ter acontecido, para o Grub do openSUSE parar de gerar essas entradas para os Snapshots?

Pode ser um problema na distro. Ter /boot fora da partição BTRFS também impossibilita bootar de snapshots devido ao snapper e ao GRUB. O procedimento correto para restaurar a raiz do sistema costuma seguir este padrão:

supondo:
raiz do sistema → /
subvolume raiz → /@
subvolume padrão → /@/root (monta em /)
snapshot → /@/root-bkp (snapshot de /@/root no passado)

  • mover o subvolume padrão para um outro lugar
$ mv /@/root /@/root-old
  • fazer um snapshot em modo leitura e escrita do snapshot a ser restaurado, para o lugar onde estava o subvolume padrão.
$ btrfs su sn /@/root-bkp /@/root
  • tornar o novo subvolume padrão
$ btrfs su se /@/root
  • reiniciar.

Mas isso pode variar, o ideal é ver a organização que a SUSE faz e agir de acordo.

1 curtida

Pelo que lembro tem um hook para o grub adicionar os snapshots. Talvez o pacote que fornece esse arquivo tenha sido desinstalado (esses hooks ficam em /etc/grub.d/ )

Mais info aqui:

e aqui:

1 curtida

Obrigado @romulopb e @Deleterium pelas dicas!

Comecei pelos 2 links, fiz as verificações sugeridas neles, e aparentemente tudo estava ok. (só que, não, né).

Revisei no YaST2 (mais uma vez) as 2 abas “Filesystem Snapshots” e “Bootloader”, e só pude desconfiar de 1 item: – Eu tinha modificado a localização do Tema para ~/Grub/theme.txt:

(Na verdade, copiei o Tema inteiro para ~/Grub)

Por que? – Simplesmente, porque o openSUSE tem a mania de “atualizar” todos os seus arquivos de configuração – e quase toda semana eu tinha de restaurar meu arquivo (personalizado) /boot/grub2/themes/openSUSE/theme.txt.

Quase toda semana, o Tema padrão restabelece o “retângulo” minúsculo, onde só cabem 6 entradas:

A personalização que faço amplia o retângulo para aproveitar o espaço disponível na tela, e reduz o entrelinhamento vertical:

O resultado que obtenho:

E… eis, de volta, o submenu de Snapshots!

Bom, eu talvez nunca desconfiasse que todo o problema estava em usar uma cópia do Tema na minha pasta pessoal (mantidas as “propriedades” e “permissões” originais) – e só me ocorreu testar essa hipótese, depois de verificar todas as dicas e hipóteses nesses 2 links – e ver que tudo mais estava Ok.

Para lidar com a “desconfiguração semanal”, criei um bash script que restaura meus arquivos personalizados, a cada vez que vou atualiziar manualmente o Grub:

[prompt] # cat update_Grub.sh
echo "cp theme.txt /boot/grub2/themes/openSUSE/"
cp theme.txt /boot/grub2/themes/openSUSE/
echo "cp grub /etc/default/grub"
cp grub /etc/default/grub
date; time grub2-mkconfig -o /boot/grub2/grub.cfg; date

Sim, tenho certeza de que existe algum modo de evitar a “desconfiguração” semanal, mas isso exige outra pós-graduação.

Sim, esta solução ainda depende de intervenção manual – pois não soluciona os acionamentos automáticos do Grub – mas eu já tinha mesmo o hábito de intervir manualmente, após cada zypper dup.

Pelo menos, simplifiquei a intervenção manual.

1 curtida