Considere um dispositivo de bloco bruto de 100 MB como um exemplo simples. Ou seja, 204800 blocos de 512 bytes cada para um total de 102760448 bytes.
O desafio é mudar os primeiros 98 MB (200704 blocos) para que haja uma diferença de 2 MB (4096 blocos) à sua frente. Fazer isso no local requer que nada seja gravado em um setor que não foi lido. Uma maneira de conseguir isso é introduzir um buffer:
$ dd if=/dev/sdj2 count=200704 | mbuffer -s 512 -b 4096 -P 100 | dd of=/dev/sdj2 seek=4096
A expectativa é que mbuffer
ele armazene 4096 blocos antes de passar qualquer coisa para o gravador, garantindo assim que nada seja gravado em uma área que não tenha sido lida e que o gravador fique atrasado no tamanho do buffer. O buffer deve permitir que o leitor e o gravador operem o mais rápido possível dentro desses constrangimentos.
No entanto, parece não funcionar de maneira confiável. Eu tentei usar dispositivos reais, mas nunca funciona neles, enquanto as experiências com um arquivo funcionavam na minha caixa de 64 bits, mas não na minha caixa de 32 bits.
Primeiro, alguma preparação:
$ dd if=/dev/sdj2 count=200704 | md5sum
0f0727f6644dac7a6ec60ea98ffc6da9
$ dd if=/dev/sdj2 count=200704 of=testfile
Isso não funciona:
$ dd if=/dev/sdj2 count=200704 | mbuffer -s 512 -b 4096 -P 100 -H | dd of=/dev/sdj2 seek=4096
summary: 98.0 MiByte in 4.4sec - average of 22.0 MiB/s
md5 hash: 3cbf1ca59a250d19573285458e320ade
Isso funciona no sistema de 64 bits, mas não no sistema de 32 bits:
$ dd if=testfile count=200704 | mbuffer -s 512 -b 4096 -P 100 -H | dd of=testfile seek=4096 conv=notrunc
summary: 98.0 MiByte in 0.9sec - average of 111 MiB/s
md5 hash: 0f0727f6644dac7a6ec60ea98ffc6da9
Como isso pode ser feito de maneira confiável?
notas
Eu li outras perguntas sobre buffering e olhei pv
, buffer
e mbuffer
. Só consegui que o último funcionasse com o tamanho de buffer necessário.
Usar o armazenamento intermediário é uma solução óbvia para o problema que sempre funciona, mas não é prático quando não há capacidade disponível suficiente disponível.
Plataformas de teste executando o Arch Linux com a mbuffer
versão 20140302.
mbuffer
fato deve forçar o segundo dd
a ficar para trás em primeiro lugar e você só precisa de RAM suficiente para armazenar em buffer o tamanho do turno. Pena dd
que não suporta blocos de leitura e gravação em ordem inversa, pois isso eliminaria o problema!
-H
argumento ativa esse recurso).
mbuffer
? Por que não fazer add
leitura de todo o conteúdo do dispositivo de bloco de uma só vezdd bs=102760448
? Obviamente, de uma forma ou de outra, é armazenado em buffer na RAM.