Como redimensionar o arquivo img criado com o dd?

19

Eu tenho uma imagem DD de um cartão SD de 4GB que possui duas partições, essas duas partições estão usando apenas cerca de 800 MB e, como tal, desejo reduzir o tamanho da imagem.

Alguém sabe como remover o "espaço livre" do arquivo img?

A_Porcupine
fonte
você pode adicionar qual é o resultado desejado. ou seja: imagem de volta para o cartão, para armazenar em CD.
22413 Wayne

Respostas:

8

Primeiro, verifique se o espaço livre está realmente vazio e se não há sobras de arquivos excluídos. A maneira mais fácil de conseguir isso é criar um arquivo enorme no disco, contendo apenas bytes nulos, e excluí-lo.

# losetup --find --partscan foo.img
# lsblk
NAME      MAJ:MIN RM    SIZE RO TYPE MOUNTPOINT
loop0       7:0    0   4096M  0 loop 
├─loop0p1 259:0    0   2048M  0 loop 
└─loop0p2 259:1    0   2048M  0 loop 
# for part in /dev/loop0p*; do
    mount $part /mnt
    dd if=/dev/zero of=/mnt/filler conv=fsync bs=1M
    rm /mnt/filler
    umount /mnt
  done
dd: error writing ‘/mnt/filler’: No space left on device
dd: error writing ‘/mnt/filler’: No space left on device
# losetup --detach /dev/loop0

Em seguida, comprima-o com uma ferramenta como gzipou xz. Mesmo nos níveis mais baixos de compactação, uma longa série de zeros compactará bem:

# ls -s
4096M foo.img
# gzip foo.img
# ls -s
11M foo.img.gz

Observe que você deve descompactar a imagem ao gravá-la novamente em disco. Isso descompactará 'live':

# cat foo.img.gz | gunzip | dd of=/dev/sda

Observe que o dispositivo de saída (sda) deve ter tamanho suficiente para caber na imagem original ; caso contrário, os dados serão perdidos ou corrompidos.


Um método alternativo, se você quiser continuar usando a imagem - por exemplo, com uma máquina virtual - é converter a imagem bruta em um dos formatos de imagem usados ​​pelo software de virtualização; por exemplo, qcow2 para Qemu, VDI para VirtualBox ou VMDK para VMware.

Observe que isso ainda exige que você prepare a imagem limpando o espaço livre usando o método acima.

# qemu-img convert -f raw -O qcow2 foo.img foo.qcow

# qemu-img convert -f raw -O vmdk foo.img foo.vmdk

Mas se ele for gravado em um disco real novamente, você precisará convertê-lo novamente em uma imagem não processada.

user1686
fonte
11
como você pode ter certeza de que todos os arquivos atualmente armazenados nas partições não estão fisicamente espalhados no disco?
Valerio Santinelli
porque suponho que os arquivos não sejam gravados seqüencialmente no disco e, se um arquivo estiver no final do armazenamento, quando eu reduzir o tamanho, perderei o conteúdo desse arquivo.
Valerio Santinelli
Porque o OP está perguntando como reduzir uma imagem de disco sem perder dados. Se você truncar uma imagem em um determinado tamanho, não poderá ter certeza de que os dados serão preservados.
Valerio Santinelli
@ValerioSantinelli: Onde exatamente sugiro truncar a imagem?
user1686
11
@ValerioSantinelli: Usando a ferramenta de redimensionamento de sistema de arquivos apropriada para o seu sistema de arquivos, por exemplo, resize2fsou ntfsresize(o Linux não possui ferramenta para FAT), antes de gravá-la no dispositivo menor, ou criando um novo sistema de arquivos e copiando apenas os arquivos.
user1686
22

Usar resize2fsé muito, muito mais fácil

resize2fs -M xxx.img

você será solicitado a e2fsck primeiro - então:

e2fsck -f -y xxx.img

(a imagem NÃO deve ser montada!)

Nota: isso só funcionará se a imagem for de uma única partição, se for um dispositivo de bloco inteiro com várias partições, veja a resposta acima ...

Serge Wagner
fonte
Apenas uma observação: para várias partições, use losetup --find --partscan xxx.imgpara configurar o arquivo de imagem como um dispositivo de loop. depois corra lsblkpara encontrar as partições do dispositivo de loop.
Yihui Xiong
Parece que não funciona para a imagem ISO que contém o sistema operacional. Após o redimensionamento, o sistema não inicializa.
SR
@SR sistema operacional Linux?
Rolf
11
Essa é uma resposta muito boa, mas resize2fsé apenas para extNpartições de tipo. Outros tipos de partições exigirão outras ferramentas.
Rolf
2

Eu também tentei com o qemu-img e funcionou como um encanto:

qemu-img resize test.img 2G

Estamos redimensionando o test.imgpara torná-lo 2G (2GB).

Funcionou perfeitamente para mim.

Phil Roggenbuck
fonte
11
Impressionante, funcionou perfeitamente para mim também, comprimindo uma imagem Raspbian. funcionando perfeitamente!
Ffleandro 19/03/19
Bem, tudo está funcionando, no entanto, após a inicialização, a execução df -hmostra o tamanho original. Como isso é possível?
Ffleandro 19/03/19
Aparentemente, o qemu-img não faz a tabela de partição, então como comprime o .img?
ffleandro 19/03/19
Posso redimensionar um disco .img para 1M, o que definitivamente quebra a imagem do disco. Alguma idéia para tornar o redimensionamento mais seguro?
Lesca
1

Eu usei a abordagem gparted com o meu computador Ubuntu 16.10:

1) Mapeie o arquivo img para a próxima partição de loop disponível com losetup, conforme descrito nas postagens anteriores, como acima

2) Verifique com lsblkqual unidade de loop seu arquivo de imagem está mapeado, por exemplo/dev/loop0

3) Executar sudo gparted /dev/loop0

4) Reduza as partições do loop, conforme apropriado; certifique-se de desmontar essas partições.

5) Execute fdisk /dev/loop0, depois insira p, isso mostrará o tamanho do bloco e o número final do bloco das várias partições.

6) Execute dd if=/dev/loop0 of=shrunk_image_file.img, aplicar a esse comando opções bs=[BlockSize]e count=[EndBlockNumberOfLastLoopPartition+1]e você terá uma encolhida e arquivo de imagem rightsized.

VeryNoob
fonte