Cópia binária dd

Uma imagem binária é uma cópia bia a bit do conteúdo de uma mídia, contendo os dados e todas as estruturas lógicas, como a tabela de partições. Essa imagem permite que o conteúdo da mídia (incluindo os arquivos deletados) sejam armazenados, copiados e restaurados posteriormente em outra mídia.

É uma estratégia muito útil para guardar a informação sem alterações nem se preocupar em instalar o sistema operacional e configurações tudo de novo. No entanto, a imagem sempre possui exatamente o mesmo tamanho da mídia original. Ou seja, um HD de 80 GB resultará em uma imagem de também 80 GB, mesmo que ele possua apenas 5 GB ocupados.

O Linux possui um utilitário padrão para realizar cópias binárias de mídias, partições ou mesmo arquivos: o dd. O comando sempre é chamado recebendo como argumentos a entrada de dados (if, de input flow) e a saída de dados (of, de output flow).

Veja esse exemplo do comando dd para copiar um cartão SD instalado como dispositivo “/dev/sdb” (com duas partições) para um único arquivo de imagem ISO:

root@pc:~# dd if=/dev/sdb of=imagem.iso

Se quiser apensa copiar a partição “/dev/sdb1” para uma imagem ISO:

root@pc:~# dd if=/dev/sdb1 of=imagem1.iso

O inverso do processo acima se dá pelo seguinte comando:

root@pc:~# dd if=imagem1.iso of=/dev/sdb1

Se quiser gravar o conteúdo de um CD em um arquivo ISO (com algumas opções extras, como exibição de progresso da cópia):

dd if=/dev/cdrom of=imagem.iso bs=4M status=progress

Uma opção muito utilizada é a “bs” (Byte Size), que indica a taxa de bytes enviados por vez. O padrão é 512 bytes, mas pode ser alterado para diferentes valores: bs=1024, bs=512K (aqui em KB), bs=1M (aqui em MB), etc. O que determina o tamanho ideal de BS são questões de hardware. Veja esse exemplo de script para testar diferentes velocidade e ver qual é a melhor (baseado nesse link):

#!/bin/bash
# Script para estimar velocidade

TEST_FILE_SIZE=134217728
#INPUT=/dev/zero
#OUTPUT=${1:-dd_obs_testfile}
INPUT=/dev/sdb
OUTPUT=/dev/sdc

i=0
bs_name=( 512b 1K 2K 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M )
for BS in 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288 1048576 2097152 4194304 8388608; do
	# Calculando número de segmentos requeridos para a cópia
	COUNT=$(($TEST_FILE_SIZE / $BS))
	# Limpando o cache do kernel para garantir um teste mais preciso
	[ $EUID -eq 0 ] && [ -e /proc/sys/vm/drop_caches ] &&a echo 3 > /proc/sys/vm/drop_caches
	echo "Testando tamanho de bloco (BS) = $BS"
	DD_RESULT=$(dd if=$INPUT of=$OUTPUT bs=$BS count=$COUNT 2>&1 1>/dev/null)
	TRANSFER_RATE=$(echo $DD_RESULT | \grep --only-matching -E '[0-9.]+ ([MGk]?B|bytes)/s(ec)?')
	echo "${bs_name[$i]} : $TRANSFER_RATE"
	i=$((i+1))
done

O comando dd no script também conta com as opções “count” (que limita o número de blocos a serem copiados) e “conv” (converte o arquivo conforme os argumentos informados, separados por vírgula). Dentre os argumentos de “conv”, estão “sync” e “noerror”, que basicamente permitem copiar um bloco de informação mantendo o tamanho (através da inclusão de zeros, em caso de erro na leitura) e sem interrupção no caso de haver erro.

Como as cópias demoram um tempo razoável, é interessante acompanhar o procedimento. O comando dd não tem uma saída visual, então é preciso fazer alguns truques.

1) Abra outro terminal, e digite o seguinte comando:

sudo kill -USR1 $(pgrep ^dd)

Volte para o terminal onde está ocorrendo a cópia e estará impressa a quantidade de dados copiados e a velocidade da cópia. Caso seja necessário, verifique o PID e coloque manualmente após o “-USR1”.

2) Utilize o dialog para exibir uma interface gráfica, e o comando pv (acrônimo para Pipe Viewer, que recebe a saída de um comando via pipe e formata os dados conforme as flags que você indicar) – instaláveis através do comando “sudo apt-get install dialog pv”. O comando final segue na última linha do script abaixo (as variáveis de entrada e saída foram definidas nas linhas acima para facilitar a intervenção):

#!/bin/bash
# Script para realizar cópia binária com saída gráfica

INPUT=/dev/sdb
OUTPUT=/dev/sdc
(pv -n $INPUT | dd of=$OUTPUT bs=1M conv=sync,noerror) 2>&1 | dialog --gauge "Executando comando dd (clonando midia)..." 10 70 0

Quando terminar a cópia, o comando libera o terminal novamente.

Caso necessite fazer alguma alteração na imagem, você deverá montá-la em um diretório (lembre-se de criar o diretório):

$ sudo mount -o loop imagem2.iso /media/temp

Trabalhe normalmente nele como se fosse um disco físico. Todas as alterações são gravadas diretamente. Depois basta desmontar o volume usando “sudo umount /media/temp”.

One comment

Leave a Reply

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.