dd no disco inteiro, mas não deseja parte vazia

33

Eu tenho um disco, digamos / dev / sda.

Aqui está o fdisk -l:

 Disk /dev/sda: 64.0 GB, 64023257088 bytes
255 heads, 63 sectors/track, 7783 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0000e4b5

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          27      209920   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              27         525     4000768    5  Extended
Partition 2 does not end on cylinder boundary.
/dev/sda5              27         353     2621440   83  Linux
/dev/sda6             353         405      416768   83  Linux
/dev/sda7             405         490      675840   83  Linux
/dev/sda8             490         525      282624   83  Linux

Preciso fazer uma imagem para armazenar em nosso servidor de arquivos para usar outros dispositivos que estamos fabricando, então quero apenas o espaço usado (apenas cerca de 4 GB). Quero manter o mbr etc ..., pois este dispositivo deve estar pronto para inicialização assim que a cópia terminar.

Alguma ideia? Eu estava usando anteriormente dd if=/dev/sda of=[//fileserver/file], mas naquela época, minha cópia principal estava em um flash ide de 4GB.

Jonathan Henson
fonte
2
Todas as respostas abaixo estão erradas, exceto @sudoer. A resposta correta é usar dd conv=sparse.
bahamat
@bahamat, não, o gzip é melhor, pois comprime os dados.
Psusi
11
Isso não é a mesma coisa que escasso.
bahamat
@ Bahamat, a pergunta não está pedindo especificamente o sprase; apenas como fazer com que a imagem ocupe menos espaço.
Psusi

Respostas:

37

Naquele dia, tive um problema semelhante com as distribuições Linux embutidas - livre-se de todo o lixo antes de comprimir a imagem.

dd if=/dev/zero of=asdf.txt. Espere até que morra. Exclua asdf.txt.

Você acabou de escrever zeros em todo o espaço livre no dispositivo.

Agora pegue uma imagem de disco e execute-a no gzip. Voila, imagem esparsa.

Provavelmente não dimensiona muito bem e pode causar problemas se você realmente precisar gravar no disco, mas ei.

Você pode levar um instantâneo rsync do disco para outro volume, zerar e, em seguida, levar a imagem do disco.

Nota: Pode ser perigoso para SSD, o usuário deve considerar esta operação antes de confirmar.

Rob Bos
fonte
se eu executá-lo no gzip, precisarei descompactá-lo antes de usá-lo? E, executando-o através do gzip, eu apenas o canalizo durante o processo de dd?
Jonathan Henson
3
Sim. dd if=sda2.gz | gunzip > /dev/sda2edd if=/dev/sda2 | gzip > sda2.gz
Rob Bos
3
"Você acabou de escrever zeros em todo o espaço livre no dispositivo". Você quer dizer partição, não dispositivo, eu acho. Então, você precisará executar esse comando com um ofcaminho para cada partição.
Jiggunjer
Se a mídia física for um SSD, agora pode pensar que todos os setores do dispositivo foram usados. Isso dará ao SSD menos setores extras para trabalhar e, possivelmente, diminuirá o desempenho como resultado. Se o driver e o firmware tiverem suporte ao TRIM, essa condição será aplicada apenas até você excluir o arquivo novamente. Se você mantiver o arquivo no lugar enquanto cria a imagem, será necessário excluir o arquivo novamente após restaurar a imagem. Isso pode ser útil se a imagem for restaurada para SSD.
kasperd
Há algumas preocupações adicionais a serem lembradas. Como esse método requer que o sistema de arquivos seja montado como leitura e gravação, existe o risco de que alterações no sistema de arquivos subjacente enquanto a cópia esteja em andamento levem a uma imagem inconsistente. Em uma ocasião, eu vi a cópia resultante ser tão inconsistente que o fsck na verdade falhava ao tentar reparar as inconsistências na cópia. Também encher o dispositivo pode causar outros processos que precisam gravar na mídia.
kasperd
17

Supondo que você deseja salvar /dev/sdXNpara /tgtfs/image.rawe você é root:

  1. mkdir /srcfs && mount /dev/sdXN /srcfs

  2. Use zerofill ou apenas: dd if=/dev/zero of=/srcfs/tmpzero.txtpara preencher blocos não utilizados com zero (aguarde o preenchimento completo do sistema de arquivos rm /srcfs/tmpzero.txt)

  3. Pegue a imagem com dd e use conv = sparse para digitar zeros rapidamente: dd conv=sparse if=/dev/sdxn of=/tgtfs/image.raw

Se você deseja usar a compactação, não precisa perfurar os zeros com dd, pois os blocos zero são altamente compressíveis:

dd if=/dev/sdxn | gz -c | dd of=/tgtfs/image.raw

PS: Observe que essa não é uma boa ideia em uma mídia de armazenamento baseada em memória flash (ou seja, seu sistema de arquivos de origem é SSD)

Sudoer
fonte
5
Essa é a resposta correta. Use dd conv=sparse.
bahamat
11
O que há de errado em fazer isso no armazenamento flash?
Dan
2
@ Dan (dependendo do design e da configuração do hardware e software) pode causar uma gravação extensa no seu SSD e reduzir sua vida útil. além do mais, não há problema em mover dados do disco antigo para o novo (ou o que o OP queria fazer), mas o backup no nível do disco / partição não é uma boa solução para backup e restauração regulares, mesmo em HDs. backup em nível de arquivo (por exemplo, copiar arquivos de um sistema de arquivos para outro) ou backup em nível de sistema de arquivos (com sistemas de arquivos como BTRFS btrfs snapshote btrfs sendferramentas) é uma solução melhor IMHO.
sudoer
Dica: Se você não tem gzno seu PATH(como eu não fiz, em GParted Live), você pode usar gzip -cem seu lugar.
XtraSimplicity
11

Use dd, com a opção de contagem.

No seu caso, você estava usando o fdisk, então eu adotarei essa abordagem. Seu "sudo fdisk -l" produziu:

    Disk /dev/sda: 64.0 GB, 64023257088 bytes
    255 heads, 63 sectors/track, 7783 cylinders
    Units = cylinders of 16065 * 512 = 8225280 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x0000e4b5

    Device Boot      Start         End      Blocks   Id  System
    /dev/sda1   *           1          27      209920   83  Linux
    Partition 1 does not end on cylinder boundary.
    /dev/sda2              27         525     4000768    5  Extended
    Partition 2 does not end on cylinder boundary.
    /dev/sda5              27         353     2621440   83  Linux
    /dev/sda6             353         405      416768   83  Linux
    /dev/sda7             405         490      675840   83  Linux
    /dev/sda8             490         525      282624   83  Linux

As duas coisas que você deve observar são: 1) o tamanho da unidade e 2) a coluna "Fim". No seu caso, você tem cilindros iguais a 8225280 bytes. Na coluna "Fim", sda8 termina em 525 (que é 525 [unidades] * 16065 * 512 = ~ 4,3 GB)

O dd pode fazer muitas coisas, como iniciar após um deslocamento ou parar após um número específico de blocos. Faremos o último usando a opção de contagem em dd. O comando apareceria da seguinte maneira:

    sudo dd if=/dev/sda of=/your_directory/image_name.iso bs=8225280 count=526

Onde -bs é o tamanho do bloco (é mais fácil usar a unidade que o fdisk usa, mas qualquer unidade o fará contanto que a opção de contagem seja declarada nessas unidades) e count seja o número de unidades que queremos copiar (observe incrementamos a contagem em 1 para capturar o último bloco).

Tom Looby
fonte
FYI: para mostrar unidades em cilindros, usefdisk -l -u=cylinders /dev/sda
xinthose
3
Por que essa não é a resposta aceita? Parece ser a opção menos invasiva, pois não modifica a fonte.
precisa saber é o seguinte
@ user33326 porque esta resposta é boa para não copiar espaço não particionado em uma unidade, não espaço não utilizado em partições, que é o que o OP se preocupa.
GDorn 8/04
8

Embora /dev/zeroo espaço livre em disco e o uso dd conv=sparse/ gz -csejam possíveis, em discos enormes com espaço vazio rodando em 100s de GBs, o processo /dev/zeroé dolorosamente lento - sem mencionar que, como outras respostas observadas, /dev/zeroum SDD até o EOF.

Aqui está o que eu fiz quando me deparei com esta situação:

  • Em um CD live do lubuntu, usado gpartedpara "reduzir" o disco para o tamanho mínimo possível, deixando o restante do espaço não alocado

  • Usado
    dd bs=1M count=<size_in_MBs> if=/dev/sdX | gzip -c --fast| dd of=/path/to/image.gz para criar a imagem compactada rapidamente (escusado será dizer que você pode pular a compactação se tiver espaço suficiente para armazenar dados brutos (ou estiver inclinado a reduzir a carga da CPU)

  • Usado
    dd if=/path/to/image.gz | gunzip -c | dd bs=1M of=/dev/sdY para copiar os dados de volta para um disco diferente
  • Usado gpartednovamente para 'expandir' a partição

Eu não tentei isso para várias partições, mas acredito que o processo acima pode ser adaptado para copiar 'partições' se a tabela de partições no disco de destino for criada primeiro e apenas os dados contidos na partição forem copiados via dd- offsets de leitura / gravação ( skip/ seekopção de dd, respectivamente) seria necessária conforme apropriado.

Ashish Chopra
fonte
11
esta é a verdadeira resposta, basta usar o countparâmetro
Gordy
7

Você não pode. ddé uma ferramenta de nível muito baixo e não tem como distinguir entre arquivos e espaço vazio.

Por outro lado, o espaço vazio comprimirá muito, muito bem; se você estiver preocupado apenas com o espaço de armazenamento, não por exemplo, o tempo de gravação, basta direcioná-lo através do gzip.

c2h5oh
fonte
7
Supondo que o espaço livre não tenha sido usado anteriormente. Você pode zerar o espaço livre primeiro para garantir que a compactação funcione conforme o esperado.
Sirex
11
Verdade. E isso apenas complica o processo e leva ainda mais tempo.
C2h5oh 16/10/12
6

Supondo que o restante da unidade esteja vazio (todos os zeros), você pode canalizar seu DD através do gzip, o que deve compactar bastante o espaço vazio. Você pode usar uma ferramenta como o zerofree para garantir que o seu espaço vazio esteja realmente em branco, para que ele seja compactado corretamente.

Se você usar uma ferramenta como partimage , clonezilla ou algumas das outras ferramentas de clonagem do linux, elas cuidariam da maior parte disso automaticamente.

Zoredache
fonte
partimage e clonezilla são realmente inteligentes o suficiente para pular a leitura do espaço livre, em vez de confiar em você para escrever zeros nele e depois fazer com que o dd ou gzip solte ou comprima os zeros depois de lê-los.
psusi
2

A resposta aceita não está certa. Eu concordo com o comentário acima. Eu uso o dd com o parâmetro count para fazer backup do meu disco regularmente. Basta substituir o BACKUP_FOLDER e a letra do seu dispositivo por "X":

Defina o último bloco usado do disco:

ct=$(fdisk -l | awk '$1 == "/dev/sdX" { print $3 }')

Em seguida, clonar o disco (excluindo o espaço vazio):

dd if=/dev/sdX bs=512 count=$ct | gzip > BACKUP_FOLDER/sdX_$(date +"%Y-%m-%d").img.gz >>"$LOG"
Aloha D
fonte