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$