Exercícios:
Atenção, a forma manual de gerenciamento de snapshots será usada para fins didáticos. É como aprender a multiplicação no papel para depois usar a calculadora!
1) Criar, formatar e montar um volume btrfs em arquivo de imagem no seu diretório de usuário.
mkdir testesSnapshot
cd testesSnapshot
truncate -s 200M imagem.img
mkfs.btrfs -L MeuTesteSnapshot imagem.img
mkdir imagemMontada
sudo mount -o loop imagem.img imagemMontada/
Conforme exercício 1 do Entendendo Subvolumes em BTRFS - Exercícios
2) Criar dois subvolumes: @arquivos e @snapshots
sudo btrfs subvolume create imagemMontada/@arquivos
sudo btrfs subvolume create imagemMontada/@snapshots
3) Setar o volume padrão da partição para o subvolume @arquivos
sudo btrfs subvol list ./imagemMontada
sudo btrfs subvol set-default XXX ./imagemMontada
4) Remontar com o novo volume padrão
sudo umount ./imagemMontada
sudo mount -o loop imagem.img imagemMontada/
5) Montar o subvolume @snapshots no diretório .snapshots
sudo mkdir ./imagemMontada/.snapshots
sudo mount -o loop,subvol=@snapshots imagem.img imagemMontada/.snapshots
6) Criar um arquivo no diretório imagemMontada
sudo sh -c 'echo "Primeira versão do arquivo" > ./imagemMontada/exemplo.txt'
ls -la ./imagemMontada
7) Criar o primeiro snapshot do subvolume
sudo btrfs subvol snapshot -r ./imagemMontada ./imagemMontada/.snapshots/Snap1
Nota: É recomendável que os snapshots sejam somente-leitura (opção -r) para criar mais uma camada de proteção contra alterações inadvertidas
8) Sobrescrever o conteúdo do arquivo exemplo.txt
sudo sh -c 'echo "Versão com conteúdo inesperado" > ./imagemMontada/exemplo.txt'
9) Verificar o conteúdo do arquivo padrão e do arquivo que está no snapshot
cat ./imagemMontada/exemplo.txt
cat ./imagemMontada/.snapshots/Snap1/exemplo.txt
Nota: para esse simples exemplo com apenas um arquivo, seria muito mais fácil reverter apenas esse arquivo, copiando o arquivo do snapshot para o subvolume padrão. Porém em situações práticas, centenas de arquivos são adicionados, modificados ou deletados, tornando muito difícil comparar e reverter arquivo por arquivo manualmente (mais a frente veremos que o snapper automatiza esse processo também!)
10) Rollback #1: Criar um snapshot do snapshot a ser revertido em modo leitura e gravação. Confirme os modos
sudo btrfs subv snap ./imagemMontada/.snapshots/Snap1 ./imagemMontada/.snapshots/SnapRW
sudo btrfs property get ./imagemMontada/.snapshots/Snap1
sudo btrfs property get ./imagemMontada/.snapshots/SnapRW
11) Rollback #2: Montar a árvore do BTRFS para realizar operações de movimentação de subvolumes
mkdir btrfs
sudo mount -o loop,subvolid=5 imagem.img ./btrfs/
12) Rollback #3: Renomear o subvolume @arquivos para @arquivos.old
sudo mv ./btrfs/@arquivos ./btrfs/@arquivos.old
Nota: o subvolume continua montado em imagemMontada, mas não houve erro nessa operação.
13) Rollback #4: Renomear o SnapRW para @arquivos, movendo-o de subvolume pai
sudo btrfs subv list ./btrfs
sudo mv ./btrfs/@snapshots/SnapRW/ ./btrfs/@arquivos
Nota: É importante que o subvolume seja renomeado no caso de haver referências a ele durante a inicialização (caso possua a pasta /boot) ou no /etc/fstab. Caso ele seja apenas montado como subvolume padrão em outros pontos de montagem, essa etapa de renomear o subvolume é opcional, porém recomendável. Fica um tanto estranho ter o volume padrão dentro do subvolume @snapshots e não poder deletá-lo.
14) Rollback #5: Alterar o volume padrão do sistema de arquivos para o número do novo @arquivos
sudo btrfs subv list ./btrfs
sudo btrfs subv set-default XXX ./btrfs
15) Desmonte tudo e remonte o subvolume padrão e seus snapshots (simulando o reboot do computador)
sudo umount -R ./imagemMontada
sudo umount ./btrfs
sudo mount -o loop imagem.img imagemMontada/
sudo mount -o loop,subvol=@snapshots imagem.img imagemMontada/.snapshots
Nota: a opção -R do umount desmonta todos os demais pontos de montagem recursivamente dentro do ponto de montagem especificado.
16) Compare o conteúdo dos arquivos exemplo do subvolume padrão com o do snapshot
cat ./imagemMontada/exemplo.txt
cat ./imagemMontada/.snapshots/Snap1/exemplo.txt
17) Uma vez que a operação foi completada com sucesso, poderá apagar o subvolume indesejado.
sudo mount -o loop,subvolid=5 imagem.img ./btrfs/
sudo btrfs subvol delete ./btrfs/@arquivos.old
Exercícios solucionados:
john@MintVM:~$ # 1
john@MintVM:~$ mkdir testesSnapshot
john@MintVM:~$ cd testesSnapshot
john@MintVM:~/testesSnapshot$ truncate -s 200M imagem.img
john@MintVM:~/testesSnapshot$ mkfs.btrfs -L MeuTesteSnapshot imagem.img
btrfs-progs v4.15.1
See http://btrfs.wiki.kernel.org for more information.
Label: MeuTesteSnapshot
UUID: 548770cc-7302-453d-a28a-82a0052e2278
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:~/testesSnapshot$ mkdir imagemMontada
john@MintVM:~/testesSnapshot$ sudo mount -o loop imagem.img imagemMontada/
[sudo] senha para john:
john@MintVM:~/testesSnapshot$ # 2
john@MintVM:~/testesSnapshot$ sudo btrfs subvolume create imagemMontada/@arquivos
Create subvolume 'imagemMontada/@arquivos'
john@MintVM:~/testesSnapshot$ sudo btrfs subvolume create imagemMontada/@snapshots
Create subvolume 'imagemMontada/@snapshots'
john@MintVM:~/testesSnapshot$ # 3
john@MintVM:~/testesSnapshot$ sudo btrfs subvol list ./imagemMontada
ID 256 gen 8 top level 5 path @arquivos
ID 257 gen 9 top level 5 path @snapshots
john@MintVM:~/testesSnapshot$ sudo btrfs subvol set-default 256 ./imagemMontada
john@MintVM:~/testesSnapshot$ # 4
john@MintVM:~/testesSnapshot$ sudo umount ./imagemMontada
john@MintVM:~/testesSnapshot$ sudo mount -o loop imagem.img imagemMontada/
john@MintVM:~/testesSnapshot$ # 5
john@MintVM:~/testesSnapshot$ sudo mkdir ./imagemMontada/.snapshots
john@MintVM:~/testesSnapshot$ sudo mount -o loop,subvol=@snapshots imagem.img imagemMontada/.snapshots
john@MintVM:~/testesSnapshot$ # 6
john@MintVM:~/testesSnapshot$ sudo sh -c 'echo "Primeira versão do arquivo" > ./imagemMontada/exemplo.txt'
john@MintVM:~/testesSnapshot$ ls -la ./imagemMontada
total 4
drwxr-xr-x 1 root root 42 mar 17 22:38 .
drwxr-xr-x 1 john john 46 mar 17 22:33 ..
-rw-r--r-- 1 root root 28 mar 17 22:38 exemplo.txt
drwxr-xr-x 1 root root 0 mar 17 22:33 .snapshots
john@MintVM:~/testesSnapshot$ # 7
john@MintVM:~/testesSnapshot$ sudo btrfs subvol snapshot -r ./imagemMontada ./imagemMontada/.snapshots/Snap1
Create a readonly snapshot of './imagemMontada' in './imagemMontada/.snapshots/Snap1'
john@MintVM:~/testesSnapshot$ # 8
john@MintVM:~/testesSnapshot$ sudo sh -c 'echo "Versão com conteúdo inesperado" > ./imagemMontada/exemplo.txt'
john@MintVM:~/testesSnapshot$ # 9
john@MintVM:~/testesSnapshot$ cat ./imagemMontada/exemplo.txt
Versão com conteúdo inesperado
john@MintVM:~/testesSnapshot$ cat ./imagemMontada/.snapshots/Snap1/exemplo.txt
Primeira versão do arquivo
john@MintVM:~/testesSnapshot$ # 10
john@MintVM:~/testesSnapshot$ sudo btrfs subv snap ./imagemMontada/.snapshots/Snap1 ./imagemMontada/.snapshots/SnapRW
Create a snapshot of './imagemMontada/.snapshots/Snap1' in './imagemMontada/.snapshots/SnapRW'
john@MintVM:~/testesSnapshot$ sudo btrfs property get ./imagemMontada/.snapshots/Snap1
ro=true
john@MintVM:~/testesSnapshot$ sudo btrfs property get ./imagemMontada/.snapshots/SnapRW
ro=false
john@MintVM:~/testesSnapshot$ # 11
john@MintVM:~/testesSnapshot$ mkdir btrfs
john@MintVM:~/testesSnapshot$ sudo mount -o loop,subvolid=5 imagem.img ./btrfs/
john@MintVM:~/testesSnapshot$ # 12
john@MintVM:~/testesSnapshot$ sudo mv ./btrfs/@arquivos ./btrfs/@arquivos.old
john@MintVM:~/testesSnapshot$ # 13
john@MintVM:~/testesSnapshot$ sudo btrfs subv list ./btrfs
ID 256 gen 16 top level 5 path @arquivos.old
ID 257 gen 17 top level 5 path @snapshots
ID 258 gen 17 top level 257 path @snapshots/Snap1
ID 259 gen 17 top level 257 path @snapshots/SnapRW
john@MintVM:~/testesSnapshot$ sudo mv ./btrfs/@snapshots/SnapRW/ ./btrfs/@arquivos
john@MintVM:~/testesSnapshot$ # 14
john@MintVM:~/testesSnapshot$ sudo btrfs subv list ./btrfs
ID 256 gen 16 top level 5 path @arquivos.old
ID 257 gen 19 top level 5 path @snapshots
ID 258 gen 17 top level 257 path @snapshots/Snap1
ID 259 gen 17 top level 5 path @arquivos
john@MintVM:~/testesSnapshot$ sudo btrfs subv set-default 259 ./btrfs
john@MintVM:~/testesSnapshot$ # 15
john@MintVM:~/testesSnapshot$ sudo umount -R ./imagemMontada
john@MintVM:~/testesSnapshot$ sudo umount ./btrfs
john@MintVM:~/testesSnapshot$ sudo mount -o loop imagem.img imagemMontada/
john@MintVM:~/testesSnapshot$ sudo mount -o loop,subvol=@snapshots imagem.img imagemMontada/.snapshots
john@MintVM:~/testesSnapshot$ # 16
john@MintVM:~/testesSnapshot$ cat ./imagemMontada/exemplo.txt
Primeira versão do arquivo
john@MintVM:~/testesSnapshot$ cat ./imagemMontada/.snapshots/Snap1/exemplo.txt
Primeira versão do arquivo
john@MintVM:~/testesSnapshot$ # 17
john@MintVM:~/testesSnapshot$ sudo mount -o loop,subvolid=5 imagem.img ./btrfs/
john@MintVM:~/testesSnapshot$ sudo btrfs subvol delete ./btrfs/@arquivos.old
Delete subvolume (no-commit): '/home/john/testesSnapshot/btrfs/@arquivos.old'
john@MintVM:~/testesSnapshot$