Como faço para converter uma imagem de disco do Linux em um arquivo esparso?

12

Eu tenho um monte de imagens de disco, feitas com ddrescue, em uma partição EXT, e quero reduzir o tamanho delas sem perder dados, enquanto ainda é montável.

Como posso preencher o espaço vazio no sistema de arquivos da imagem com zeros e depois converter o arquivo em um arquivo esparso para que esse espaço vazio não seja realmente armazenado no disco?

Por exemplo:

> du -s --si --apparent-size Jimage.image 
120G Jimage.image
> du -s --si Jimage.image 
121G Jimage.image

No entanto, na verdade, ele tem apenas 50 G de dados reais; portanto, a segunda medição deve ser muito menor.

Isso supostamente preencherá o espaço vazio com zeros:

cat /dev/zero > zero.file
rm zero.file

Mas se os arquivos esparsos forem manipulados de forma transparente , ele poderá realmente criar um arquivo esparso sem gravar nada no disco virtual, ironicamente, impedindo-me de transformar a imagem do disco virtual em um arquivo esparso. :) faz?

Nota: Por algum motivo, sudo dd if=/dev/zero of=./zero.filefunciona quando catnão está em uma imagem de disco montada.

endólito
fonte
2
Gravar zeros em um arquivo não criará um arquivo esparso. É um conceito diferente. Quando você procura / lê um arquivo esparso quando o sistema operacional descobre que o bloco de dados não está realmente lá (a lista de bloqueios está vazia para dados nessa região), ele (o sistema operacional) automaticamente preenche magicamente o buffer de leitura com zero bytes.
hotei
Nota: sudo cat /dev/zero > zero.filenão funciona porque o seu bash (executando como você, não como root) faz o redirecionamento antes de executar o sudocomando. Veja unix.stackexchange.com/questions/1416/…
Fritz

Respostas:

19

Primeiro, os arquivos esparsos são manipulados de forma transparente apenas se você procurar, e não se você escrever zeros.

Para deixar mais claro, o exemplo da Wikipedia

dd if=/dev/zero of=sparse-file bs=1k count=0 seek=5120

se não escrever qualquer zeros, ele vai abrir o arquivo de saída, procure (pular) 5MB e, em seguida, escrever de zero zero (ou seja, nada). Este comando ( não da Wikipedia)

dd if=/dev/zero of=sparse-file bs=1k count=5120

irá gravar 5MB de zeros e não criará um arquivo esparso!

Como conseqüência, um arquivo que já não é esparso não será magicamente esparso mais tarde.

Segundo, para criar um arquivo com muitos zeros esparsos, é necessário cp- lo

cp --sparse=always original sparsefile

ou você também pode usar a opção tar 's ou rsync ' s --sparse.

mihi
fonte
1
Segundo a Wikipedia, escrever zeros com dd criará um arquivo esparso. Você pode explicar o que "procurar" significa?
endolith 31/07/10
1
E o gato então? Não há nada na página de manual sobre arquivos esparsos, então suponho que cat /dev/zero > zero.fileesteja perfeitamente correto preencher espaço em branco com zeros?
Ludwig Weinzierl
2
@endolith: Atualizei minha resposta para esclarecer qual é a diferença ddpara escrever zeros ou procurar.
mihi
2
@Ludwig Weinzierl: Sim, esse catcomando preencherá todo o seu disco (ou pelo menos a quantidade não reservada para raiz ou por cotas) com zeros "reais" e não criará arquivos esparsos.
mihi
1
@ endolith você vai precisar de espaço extra, sim. mas como você pode compactar o tarball, precisará apenas de espaço para o arquivo original e de uma versão compactada do arquivo esparso.
mihi
12

Talvez a maneira mais fácil de sparsify um arquivo no local seria usar o fallocateutilitário da seguinte maneira:

fallocate -v --dig-holes {file_name}

O fallocate (1) é fornecido pelo pacote util-linux no Debian .

Onlyjob
fonte
1
Por alguma razão, fallocate --dig-holesresultou no arquivo 103GiB do original 299GiB, enquanto cp --sparse=alwaysme deu 93GiB - todos com a mesma soma SHA1 (tamanhos verificados via du -B1Gvs du --apparent-size -B1G). Então, fallocateparece dar resultados inferiores.
Ruslan
3

Editando minha resposta para completude:

  1. Coloque um balão no espaço FS vazio com zeros (AVISO: isso altera a imagem do disco):

losetup --partscan --find --show disk.img

Suponha que ele fornece / dev / loop1 como disco e existe apenas uma partição; caso contrário, precisamos repetir isso para todas as partições com FS montável (ignore a partição de troca etc.).

mkdir -p /mnt/tmp mount /dev/loop1p1 /mnt/tmp dd if=/dev/zero of=/mnt/tmp/tempfile

Deixe terminar com falha com o ENOSPC.

/bin/rm -f /mnt/tmp/tempfile umount /mnt/tmp losetup -d /dev/loop1

  1. Copie para uma imagem esparsa:

'dd' tem uma opção para converter um arquivo com zeros em um arquivo esparso:

dd if=disk.img of=disk-sparse.img conv=sparse

Lam Das
fonte
1
Sim, essa opção não é do momento em que o OP pediu. Este foi mais de "deixar uma migalha de pão para outros pesquisadores" ... :-)
Lam Das
1
dependendo do tipo de sistema de arquivos, zerofreepode ser mais rápido do que montar e gravar zeros no sistema de arquivos e diminuir a imagem do disco se já contiver muitos zeros.
mihi
2

Você quer dizer que sua imagem criada pelo ddrescue tem, digamos, 50 GB e, na realidade, algo muito menos seria suficiente?

Se for esse o caso, você não pode simplesmente criar uma nova imagem com o dd:

dd if=/dev/zero of=some_image.img bs=1M count=20000

e crie um sistema de arquivos nele:

mkfsofyourchoice some_image.img

basta montar a imagem e copiar tudo, desde a imagem antiga para a nova? Isso funcionaria para você?

Janne Pikkarainen
fonte
2

O PartImage pode criar imagens de disco que armazenam apenas os blocos usados ​​de um sistema de arquivos, reduzindo drasticamente o espaço necessário ignorando os blocos não utilizados. Eu não acho que você pode montar diretamente as imagens resultantes, mas indo:

image -> partimage -> image -> cp --sparse=alway

Deve produzir o que você deseja (pode até ser possível manter o último passo, ainda não tentei).

Grumbel
fonte
1
Infelizmente, as imagens criadas pela partimage não são montáveis ​​sem expandi-las novamente, tornando-as adequadas apenas para fins de arquivamento.
Perkins
0

Agora existe uma ferramenta chamada virt-sparsify que fará isso. Ele preenche o espaço vazio com zeros e copia a imagem em um arquivo esparso. No entanto, é necessário instalar muitas dependências.

endólito
fonte
-2

Eu suspeito que você precisará de um programa personalizado escrito para essa especificação, se é REALMENTE o que você deseja fazer. Mas é ...?

Se você realmente tem muitas áreas totalmente zero, qualquer boa ferramenta de compactação reduzirá significativamente. E tentar gravar arquivos esparsos não funcionará em todos os casos. Se bem me lembro, até arquivos esparsos ocupam pelo menos 1 bloco de armazenamento de saída, onde o bloco de entrada contém QUALQUER bit que não seja zero. Por exemplo - digamos que você tenha um arquivo com uma média de até 1 bit diferente de zero por bloco de 512 bytes - ele não pode ser gravado "escassamente". A propósito, você não perderá dados se compactar o arquivo com zip, bzip, bzip2 ou p7zip. Eles não são como compactação mpeg ou jpeg com perdas.

Por outro lado, se você precisar fazer leituras aleatórias de busca no arquivo, a compactação poderá ser mais problemática do que vale a pena e você voltará à gravação esparsa. Um programador C ou C ++ competente deve ser capaz de escrever algo assim em uma hora ou menos.

hotei
fonte
Interessante - um voto negativo ainda noto que não há refutação do que escrevi. Se for preciso, mas inútil, não é um motivo para votar. Se não é preciso e não é útil, então merece.
hotei
Vejo em outro lugar que o OP tinha uma pergunta relacionada à montagem de imagens compactadas. Estou assumindo que esta é uma continuação desse segmento. Sabendo que agora posso ver por que minha sugestão de compressão não foi aceita. Um simples programa em C ainda é uma maneira fácil de criar arquivos esparsos. MAS - o sistema operacional (não especificado) permitirá que você monte um ISO escasso. Tão exigente quanto o montador ISO do Ubuntu é que não tenho 100% de certeza de que isso também funcionará ... mas, de qualquer forma, boa sorte.
hotei
4
por que reinventar a roda? cp --sparse=alwaysfaz o trabalho bem
mihi
@mihi: É uma boa ideia. Eu não conhecia a opção esparsa, pois ela não está disponível nos sabores do BSD ( freebsd.org/cgi/… ) e nunca tive o requisito de procurar em uma página de manual do Linux para cp (até hoje).
hotei
Uma maneira de ter suas imagens compactadas e montá-las também é simplesmente armazená-las em um sistema de arquivos que suporte compactação nativa. Torna a recuperação de dados horrível se você tiver uma falha na unidade, mas é para isso que servem os backups, certo?
Perkins