TL;DR
Eu tenho uma dd
imagem disk.dd
que tem várias partições. O objetivo final é reduzir o tamanho deste dd
arquivo de imagem.
Depois de excluir e recriar uma partição numerada mais alta com uma start sector offset
menor do que era antes, (ou seja, expandindo a partição para a esquerda), tenho uma partição que possui um sistema de arquivos e que primary superblock
está em algum lugar dentro dessa partição e conheço o setor em que isso primary superblock
reside.
Como posso e2fsck
esse sistema de arquivos para que ele se mova para o início da partição?
Para que depois eu possa reduzir esse sistema de arquivos resize2fs
e, em seguida, reduzir essa partição da direita, ou seja (recriando essa partição com um menor end sector offset
)
Então, vou repetir esse processo com as partições depois disso até a última partição, reduzindo efetivamente todas as partições e, portanto, reduzindo o tamanho da dd
imagem
Por favor, não sugira gparted
. Estou procurando uma solução de linha de comando
Além disso, eu sei que isso teria sido mais fácil com o LVM
. Mas este sistema legado
Versão longa
Eu tenho uma imagem dd disk.dd
que tirei usando o seguinte
dd if=/dev/sda of=/path/to/disk.dd
de um sistema que tem o seguinte layout
Disk /dev/loop15: 465.78 GiB, 500107862016 bytes, 976773168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x54093dd5
Device Boot Start End Sectors Size Id Type
/dev/loop15p1 * 2048 81922047 81920000 39.1G 83 Linux
/dev/loop15p2 81922048 143362047 61440000 29.3G 82 Linux swap / Solaris
/dev/loop15p3 143362048 163842047 20480000 9.8G 83 Linux
/dev/loop15p4 163842048 976773167 812931120 387.7G 5 Extended
/dev/loop15p5 163844096 976773119 812929024 387.7G 83 Linux
Agora, em um sistema diferente, estou acessando disk.dd
através de um dispositivo de loop usando
losetup --find --partscan disk.dd
Eu redimensionei todos os sistemas de ext4
arquivos com
resize2fs -M /dev/loopNpartX
resize2fs /dev/loopNpartX FSsize
p1
ou seja , as partições p3
ep5
Com dumpe2fs
, posso ver o logical block size
sistema de arquivos que é 4096
bytes para todos os sistemas de ext4
arquivos que, no meu caso, como mostrado acima, estão hospedados em 3 partições
Agora, se estou lendo isso verbalmente corretamente (corrija-me se estiver errado aqui)
O superbloco primário de um sistema de arquivos é " geralmente esperado " estar localizado no bloco 0
da partição
Então, eu posso despejar informações de superblock com
dumpe2fs -h -o superblock=0 -o blocksize=4096 /dev/loopNpartX
Agora é hora de reduzir as partições para reduzir o tamanho do disk.dd
arquivo
Eu tenho o block count
para cada sistema de arquivos novamente usandodumpe2fs
fdisk
funciona no physical block size
OR sectors
do dispositivo que no meu caso é 512
bytes
Então, para descobrir quantos sectors
devem ser suficientes para acomodar o sistema de arquivos, usei a seguinte fórmula
Required Sectors = ( ( Block Count + 100 ) * Logical Block Size ) / Physical Block Size
100
atuando como um buffer apenas no caso de estar faltando algo sobre a organização do sistema de arquivos que deve ser suficiente
Eu fiz isso para cada sistema de arquivos
Agora
Com lsblk -f
, recebo os UUIDs dos sistemas de arquivos existentes
Com fdisk -l
, recebo qual partição manter o boot flag
ativado
Agora, para reduzir as partições, eu as excluiria e as recriaria usandofdisk
-- Primeira partição
start sector offset = 2048
last sector offset = 2048 + "Required Sectors" for this filesystem
-- Segunda partição
A segunda partição no disco existente é swap
, então não vou reduzi-la, apenas mova-a para a esquerda
start sector offset = "last sector offset" of first partition + 1
last sector offset = "start sector offset" + Total sectors as as on existing partition
Em seguida, altero o tipo para Swap
E, em seguida, tune2fs -U
altero o UUID de volta ao que estava na dd
imagem
-- Terceira partição
start sector offset = "last sector offset" of second partition + 1
last sector offset = "start sector offset" + "Required Sectors" for this filesystem
Aqui é onde eu estou preso
Depois de expandir a terceira partição para a esquerda, esta partição tem um sistema de arquivos cujo setor inicial eu conheço (ou seja, setor com o primary superblock
)
Mas eu não sei como e2fsck
este sistema de arquivos corrigi-lo na partição para que o sistema de arquivos seja movido para a esquerda para o início da partição
Não é possível com fsck. Em um sistema de arquivos, tudo tem deslocamentos e se você alterar o setor inicial, todos esses deslocamentos serão alterados . O fsck simplesmente não tem facilidade para reescrever todos os deslocamentos para tudo (superblocos, diários, diretórios, segmentos de arquivo, etc.). E mesmo que você pudesse fazer isso, só funcionaria se o novo setor inicial se alinhasse com as estruturas internas do sistema de arquivos.
Então isso não é feito.
Em vez disso, você teria que deslocar todos os dados para a esquerda com dd (essencialmente o que o gparted faz). Somente mudando o sistema de arquivos completamente, os deslocamentos dentro dele permaneceriam intactos.
Em princípio, o comando dd poderia funcionar assim. Ele lê e grava no mesmo dispositivo, em diferentes deslocamentos. Isso só pode funcionar para deslocamento para a esquerda, portanto, buscar (gravar em) deve ser menor que pular (ler de). Todas as unidades em setores 512b (se você especificar
bs=1M
, suas partições devem estar alinhadas em MiB e todas as unidades em MiB)No entanto, isso é muito perigoso . Use-o por sua conta e risco. Reserve um tempo para fazer backup de seus dados primeiro.
Mudar para a direita seria mais complicado. Você teria que trabalhar para trás, caso contrário, você sobrescreve os dados que ainda precisam ser lidos e corrompe tudo no processo.
A única ferramenta que conheço que faz isso (mais ou menos) sem alterar os dados é o
blocks --lvmify
, que o obtém convertendo a partição do sistema de arquivos existente em LVM. Com o LVM, você pode expandir logicamente para a direita enquanto está fisicamente armazenado à esquerda. Sem o LVM, você também pode configurar um mapeamento de dispositivo linear manualmente, mas fica preso a uma solução não padrão.A abordagem mais sensata para esse tipo de problema (se você não quiser usar o gparted) seria fazer backup de todos os dados, criar novas partições e sistemas de arquivos em qualquer layout que desejar e restaurar seus dados.
Se essa imagem dd for sua abordagem para uma solução de backup, considere fazer backup de arquivos. As imagens de disco podem ser difíceis de manusear, especialmente se você quiser transformá-las posteriormente.
Se seu objetivo principal é reduzir o requisito de armazenamento do arquivo de imagem, o que você pode fazer é
fstrim
(para sistema de arquivos montado em loop - perdendo todo o espaço livre) oublkdiscard
(para partição de troca de loop - perdendo todos os dados).Desde que o sistema de arquivos que armazena a imagem suporte arquivos esparsos e perfuração, isso faria com que a imagem dd usasse menos espaço de armazenamento sem alterar qualquer layout, pois qualquer espaço livre dentro da imagem também seria liberado para o sistema de arquivos de apoio.
Da mesma forma, isso é perigoso, se você descartar as partes erradas do arquivo de imagem, o arquivo de imagem será danificado de forma irrecuperável. O simples ato de criar um dispositivo de loop para um arquivo de imagem, e montá-lo, já modifica/danifica o arquivo de imagem.
Se o disco de origem for SSD e já estiver usando fstrim regularmente e ler áreas aparadas como ZERO binário, você poderá criar uma imagem dd já esparsa em primeiro lugar usando
dd conv=sparse if=/dev/ssd of=ssd.img
. Dessa forma, qualquer área zero binária não ocuparia espaço no arquivo ssd.img. Observe queconv=sparse
pode levar a resultados corrompidos quando usado em outra direção ao restaurar para uma unidade de destino diferente de zero.