É possível pausar dd, trocar o destino para um disco maior e depois continuar?

4

Estou copiando uma unidade para um arquivo, mas subestimei a quantidade de espaço que ela ocuparia. Portanto, estou ficando sem espaço na unidade de destino e não quero abortar o processo (ele está sendo executado há algum tempo em uma unidade danificada).

É claro que posso pausar dd usando CTRL-Z, e gostaria de trocar a unidade de destino por uma maior e copiar o arquivo para a unidade maior, depois retomar o dd. Alguma idéia de como realizar isso?

dd if=/dev/sdc conv=sync,noerror bs=64M | gzip -c -9 > /media/extD/drive.img.gz

EDIT: para aqueles que mencionam o ddrescue como sendo uma ferramenta melhor para usar, você está certo. No entanto, por alguma razão, o ddrescue continuou a vomitar e a errar comigo, enquanto o dd simplesmente andava sem reclamar.

    
por Logos 17.08.2016 / 02:53

2 respostas

3

É possível, mas meio doloroso.

Primeiro, saiba que dd imprime sua posição atual em uma cópia (bytes copiados), se enviado ao sinal USR1 . então encontre o PID de dd , usando ps ou algo como pidof ou pgrep (não POSIX e não em todos os sistemas unix-y IIRC ).

Um comando ps que funciona para mim (também usando awk , em um ambiente debian ):

ps aux|awk '/dd/ {print $2}'|grep -v awk

grep -v awk é necessário para evitar que o PID de awk também seja impresso.

Tendo o PID de dd , envie o sinal USR1 :

kill -USR1 [pid of dd]

a janela do console dd está sendo executada, imprimirá quantos bytes serão copiados. Agora você pode matar dd para real (ctrl + c, kill -9 , whatever). Eu não me lembro se dd informa seu progresso em abortar se for morto dessa forma em POSIX , então envie primeiro o sinal USR1 .

dd pode ter copiado mais alguns bytes desde que você o parou, então execute:

head -c [number of bytes reported copied from dd] > \
     /path/to/drive/you/are/moving/to/filename.bin

para colocar uma cópia truncada no disco de destino. Em vez do número exato de bytes, você pode querer escolher algo divisível pelo tamanho do bloco desejado, para acelerar a transferência quando retomar a cópia. Apenas anote tudo o que você escolher e verifique se está apenas truncando e não aumentando a imagem.

Depois de copiá-lo para a nova unidade, execute:

dd if=/dev/sdc bs=64M skip=[truncated size divided by block size, e.g. 64000000] \
   of=/path/to/part2

Se você tiver espaço para o restante da imagem no disco original menor, exclua a imagem não truncada que você copiou para o novo disco em parte 1 para liberar espaço e tenha dd saída para esse disco em seu lugar. Quando a transferência estiver completa, você pode executar

cat /path/to/part2 >> /path/to/part1

para adicionar parte 2 ao final da parte 1 , criando uma imagem de disco completa! Note que você precisará de pelo menos o espaço livre no disco em que a parte 1 está localizada para que toda a parte dois seja anexada a ela.

Se você não se importar em fazer toda a transferência, eu faria cat /dev/sdc | gzip -c - > /path/to/imagefile.img.gz para criar um arquivo comprimido gzip. Isso pode ser gravado em uma partição do disco rígido com algo como zcat /path/to/imagefile.img.gz > /dev/sdX .

[copiado do meu comentário para a resposta]

adicionalmente, eu acho (mas não me lembro ao certo) que dd escreve para stdout if of = não é especificado. Se isso for verdade, você pode pular escrevendo part2 para um arquivo separado e usar:

dd bs=64M skip=[skip-block-count] if=/dev/sdc >> /path/to/part1

A @MatijaNalis sugeriu, com razão, usar dd_rescue ou ddrescue (dois programas diferentes que realizam a mesma tarefa) para copiar a imagem do disco. Eu faria isso se sua partição / unidade tivesse setores errôneos ou outras falhas de hardware.

    
por 17.08.2016 / 06:35
0

Você não pode pausar o processo e retomá-lo depois de mover o arquivo em outra unidade¹. No entanto, você não precisa fazer isso. Apenas mate o processo dd , faça sua transferência de arquivos e inicie um novo processo de cópia para o restante dos dados.

Para ver onde a primeira parte pára, execute gzip -l /media/extD/drive.img.gz . O número "não compactado" é o número de bytes que foram copiados e é o deslocamento em que você precisa iniciar o novo processo de cópia.

Para copiar o resto dos dados, diga dd para começar naquele deslocamento NNNN .

dd if=/dev/sdc conv=sync,noerror,iflag=skip_bytes,skip=NNNN bs=64M |
gzip -c -9 >> /media/extE/drive.img.gz

Eu não recomendo usar dd para copiar dados. Ao contrário de uma lenda comum, não há mágica em dd que permita o acesso a discos: a mágica é toda em /dev/sdc . Além disso dd pode perder dados silenciosamente - Eu acho que com os sinalizadores conv=sync,noerror ele apenas substitui alguns dados por zeros, então todos os dados copiados com sucesso acabam no local certo, mas por sua conta e risco.

Para copiar uma imagem de disco de um disco de trabalho, use apenas cp ou cat . Para copiar uma parte, tail -c +$((start_offset+1)) | head -c $bytes_to_copy .

Para recuperar dados de um disco com falha, use ddrescue . O Ddrescue é esperto em pular dados ilegíveis e acompanha o que foi lido com sucesso. Faz múltiplos passes; Com discos rígidos com falha, deixar a unidade descansar um pouco e tentar novamente pode permitir que você recupere tudo, mesmo que alguns setores estejam ilegíveis na primeira tentativa.

O ddrescue pode usar sua cópia parcial existente e completá-la , mas você terá que mantê-lo descompactado.

¹ Na verdade, você pode, com ptrace - anexar ao processo um depurador, pausá-lo, atualizar suas estruturas de dados internas para apontar para o novo arquivo, retomar. Mas mesmo se você estivesse familiarizado com a forma de fazer isso, seria mais complicado do que a solução direta com o acréscimo.

    
por 18.08.2016 / 03:17

Tags