Como alguém pode reler a imagem com dd para que ela corresponda a uma que você acabou de escrever?

4

Tenho uma imagem de ~ 1 GB que estou gravando em um cartão SD de 8 GB por meio da ferramenta dd . Gostaria de verificar se ele foi escrito sem corrupção, lendo-o de volta e comparando seu hash com o original.

Obviamente, quando eu o leio de volta via dd , o tamanho da imagem resultante corresponde ao tamanho do meu cartão SD, portanto, verificar se os hashes são inúteis.

Acredito que de alguma forma eu deveria interpretar a saída da chamada escrita para configurar os parâmetros skip / count para lê-lo corretamente.

Comando que usei para escrever minha imagem:

> sudo dd if=my.img of=/dev/sdc bs=1M 
8+50581 records in
8+50581 records out
3947888640 bytes (3.9 GB) copied, 108.701 s, 36.3 MB/s

Comando que costumava ler minha imagem:

> sudo dd if=/dev/sdc of=same_as_my.img
15523840+0 records in
15523840+0 records out
7948206080 bytes (7.9 GB) copied, 285.175 s, 27.9 MB/s
    
por Kentzo 08.07.2015 / 01:24

6 respostas

4

Determine o tamanho da imagem, por exemplo, com \ls -l my.img (não ls -lh , que lhe daria um tamanho aproximado; \ls protege contra um alias como ls='ls -h' ) ou com stat -c %s my.img .

Se você quiser verificar a cópia contra o original apenas desta vez, basta comparar os arquivos. Usar hashes é inútil para uma comparação única, só tornaria as coisas mais lentas e exigiria mais comandos. O comando cmp compara arquivos binários. Você precisa passar o arquivo de imagem e a parte correspondente do cartão SD. Use head para extrair o início do cartão SD.

</dev/sdc head -c "$(stat -c %s my.img)" | cmp - my.img

Se você deseja realizar muitas comparações, os hashes são úteis, porque você só precisa ler cada instância uma vez para calcular seu hash. Qualquer hash serve, pois você está preocupado com a corrupção de dados. Se você precisava verificar se um arquivo não foi modificado por razões de segurança, então cksum e md5sum não seriam adequados, você deve usar sha256sum ou sha512sum .

md5sum <my.img >my.img.md5sum
</dev/sdc head -c "$(stat -c %s my.img)" | md5sum >sd-copy.md5sum
cmp my.img.md5sum sd-copy.md5sum

Observe o redirecionamento de entrada no primeiro comando; isso garante que o arquivo de soma de verificação não contenha nomes de arquivos, para que você possa comparar os arquivos de soma de verificação. Se você tiver um arquivo de soma de verificação e uma cópia para verificar, poderá fazer a verificação diretamente com

</dev/sdc head -c "$(stat -c %s my.img)" | md5sum -c my.img.md5sum

Ah, e não use dd , é lento (ou, na melhor das hipóteses, não é mais rápido) e não detecta erros de cópia.

    
por 08.07.2015 / 02:53
1

O que fizemos foi md5um da partição real. Ele não permite exatamente a soma de verificação da imagem com o disco, mas se você tiver alguns discos (como nós), você poderá estabelecer a soma de verificação 'adequada'.

Por exemplo, no nosso caso, as partições são assim:

$ sudo fdisk -l /dev/sdc
Disk /dev/sdc: 7948 MB, 7948206080 bytes
245 heads, 62 sectors/track, 1021 cylinders, total 15523840 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

   Device Boot      Start         End      Blocks   Id  System
/dev/sdc1            8192      122879       57344    c  W95 FAT32 (LBA)
/dev/sdc2          122880     7710719     3793920   83  Linux

Podemos então simplesmente gerar um hash na (s) partição (ões) com:

$ sudo md5sum /dev/sdc2

Isso, no entanto, pressupõe o seguinte:

  • Você tem vários cartões SD que podem ser testados com
  • Você não monta o cartão SD antes de executar o hash

Além disso, lembre-se de que você não pode verificar o disco inteiro (por exemplo, '/ dev / sdc' no exemplo acima), pois isso dará um hash diferente com base nas propriedades do cartão SD.

    
por 10.07.2015 / 17:46
0

md5sum seria uma boa solução aqui, para comparar o valor do arquivo de imagem com o do cartão SD.

    
por 08.07.2015 / 01:28
0

Você está escrevendo para um sistema de arquivos no cartão SD? Ou diretamente? Você precisa contar se quiser limitar o tempo de execução dos dados comparados?

dd deve informar quantos bytes foram copiados.

Isso precisa ser capturado e usado com bs = x e count = y apropriados. Isso é para evitar o hash de lixo em uma dica de cluster.

EDITAR

capture a saída, esta é a linha que você quer, use grep para bytes.

254033920 bytes (254 MB) copied, 1.198 s, 212 MB/s

então (desculpe verbosidade e backticks).

# original dd
dd if=/path/to/file of=/dev/sdc 2> tempfile
# get bytes
CNT='cat tempfile | grep bytes | cut -d' ' -f1'
# copy it back by byte
dd bs=1 count=$CNT if=/dev/sdc of=/path/to/copy 

Isto será lento, então (e eu não vou fazer isso aqui), você precisa calcular o tamanho ideal de blocos, e o número de múltiplos inteiros para ler primeiro, e depois obter o resto com um salto / busca.

Mas uma abordagem melhor seria ler um número arredondado de blocos e executar o hash em um comprimento truncado, o objeto não é para ler todo o dispositivo, se não for necessário.

    
por 08.07.2015 / 01:58
0
sudo sh -c '
     dd bs=64k if="$1" of="$2"
     ! cmp -- "$1" "$2" 2>&1 |
       grep -qvF "EOF on $1"
' -- my.img /dev/sdc

cmp irá comparar dois arquivos byte para byte e retornar com base em se eles são idênticos ou não. Se uma for menor do que a outra, mas ambos os arquivos forem idênticos para toda a extensão do arquivo mais curto, então cmp retornará 1 e reportará EOF on <shorter file>... para stderr. Se ambos os arquivos forem idênticos, cmp retornará 0 e não reportará absolutamente nada, mas se eles diferirem de outra forma, cmp retornará 1 e informará sobre o byte onde eles diferem. Assim, a declaração acima retornará 1 para qualquer cmp run que produza qualquer linha de saída em stdout ou stderr que não corresponda a EOF on $1 ou 0 caso contrário.

    
por 08.07.2015 / 02:51
0

IMO, a melhor maneira (mais fácil) de fazer isso é quando usar o dd, use um tamanho de byte (bs =) que pode ser dividido igualmente em seu arquivo de origem. Isso resulta em um número inteiro de gravações em bloco. Então você pode reverter o processo (leia de volta), garantindo que o número exato de bytes sejam lidos por nós, bs = e count = no comando read - e canalizá-lo através do programa de soma de verificação.

Exemplo:

ls

-rw-rw-r-- 1 1006632960 myfile.iso

Gere uma soma de verificação:

sha256sum myfile.iso

8012fcba8bf71a7dd9e8179af40bce0fec57bb84b7426e4de807130ada63243d myfile.iso

O tamanho do arquivo 1006632960 é divisível por 512. Então, usando o dd:

sudo dd if=myfile bs=512b of=/dev/sdi

resulta nesta saída:

3840+0 records in

3840+0 records out

O +0 é a parte importante aqui. Se você vir algo diferente de +0, você precisa de um bytesize diferente no seu comando dd.

Em seguida, para verificar os resultados, use este comando:

sudo dd if=/dev/sdi bs=512b count=3840 | sha256sum

e a saída corresponde ao sha256sum anterior, o que significa que é uma boa cópia:

3840+0 records in

3840+0 records out

1006632960 bytes (1.0 GB, 960 MiB) copied, 14.788 s, 68.1 MB/s

8012fcba8bf71a7dd9e8179af40bce0fec57bb84b7426e4de807130ada63243d -

A parte mais difícil é obter o bytesize correto. Depois de ter isso, o resto é fácil.

    
por 22.07.2016 / 20:26