Considera un dispositivo a blocchi non elaborati da 100 MB come semplice esempio. Sono 204800 blocchi di 512 byte ciascuno per un totale di 102760448 byte.
La sfida è quella di spostare i primi 98 MB (200704 blocchi) in modo che vi sia uno spazio vuoto di 2 MB (4096 blocchi) davanti. Per fare questo sul posto è necessario che nulla sia scritto in un settore che non è stato letto. Un modo per raggiungere questo obiettivo è introdurre un buffer:
$ dd if=/dev/sdj2 count=200704 | mbuffer -s 512 -b 4096 -P 100 | dd of=/dev/sdj2 seek=4096
L'aspettativa è che mbuffer
memorizzerà 4096 blocchi prima di passare qualsiasi cosa allo scrittore, assicurando così che nulla sia scritto in un'area che non è stata letta e che lo scrittore è in ritardo del lettore per le dimensioni del buffer. Il buffer dovrebbe consentire al lettore e allo scrittore di operare il più velocemente possibile all'interno di tali costrutti.
Tuttavia, non sembra funzionare in modo affidabile. Ho provato a utilizzare dispositivi reali ma non funziona mai su di essi, mentre gli esperimenti con un file hanno funzionato sulla mia casella a 64 bit ma non sulla mia casella a 32 bit.
Innanzitutto, alcuni preparativi:
$ dd if=/dev/sdj2 count=200704 | md5sum
0f0727f6644dac7a6ec60ea98ffc6da9
$ dd if=/dev/sdj2 count=200704 of=testfile
Questo non funziona:
$ 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
Funziona su un sistema a 64 bit ma non su un sistema a 32 bit:
$ 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
Come può essere fatto in modo affidabile?
Appunti
Ho letto altre domande sul buffering e ho guardato pv
, buffer
e mbuffer
. Potevo solo far funzionare quest'ultimo con la dimensione del buffer richiesta.
L'uso della memoria intermedia è una soluzione ovvia al problema che funziona sempre, ma non è pratico quando non è disponibile una capacità di riserva sufficiente.
Piattaforme di prova che eseguono Arch Linux con la mbuffer
versione 20140302.
mbuffer
realtà dovrebbe forzare il secondo dd
ad essere in ritardo per il primo e avete solo bisogno di abbastanza RAM per tamponare la dimensione dello spostamento. Peccato dd
che non supporti la lettura e la scrittura di blocchi in ordine inverso poiché ciò eliminerebbe il problema!
-H
argomento abilita questa funzione).
mbuffer
? Perché non invece faredd
leggere l'intero contenuto del dispositivo a blocchi in una volta sola usandodd bs=102760448
? Certo, in un modo o nell'altro è bufferizzato nella RAM.