Betrachten Sie ein 100-MB-Raw-Block-Gerät als einfaches Beispiel. Das sind 204800 Blöcke mit jeweils 512 Bytes für insgesamt 102760448 Bytes.
Die Herausforderung besteht darin, die ersten 98 MB (200704 Blöcke) so zu verschieben, dass eine Lücke von 2 MB (4096 Blöcke) davor liegt. Um dies direkt zu tun, muss nichts in einen Sektor geschrieben werden, der nicht gelesen wurde. Eine Möglichkeit, dies zu erreichen, besteht darin, einen Puffer einzuführen:
$ dd if=/dev/sdj2 count=200704 | mbuffer -s 512 -b 4096 -P 100 | dd of=/dev/sdj2 seek=4096
Die Erwartung ist, dass mbuffer
4096 Blöcke gespeichert werden, bevor etwas an den Schreiber übergeben wird, wodurch sichergestellt wird, dass nichts in einen Bereich geschrieben wird, der nicht gelesen wurde, und dass der Schreiber dem Leser um die Größe des Puffers hinterherhinkt. Der Puffer sollte es dem Leser und dem Schreiber ermöglichen, innerhalb dieser Konstrianten so schnell wie möglich zu arbeiten.
Es scheint jedoch nicht zuverlässig zu funktionieren. Ich habe versucht, echte Geräte zu verwenden, aber es funktioniert nie auf ihnen, während Experimente mit einer Datei auf meiner 64-Bit-Box, aber nicht auf meiner 32-Bit-Box funktionierten.
Zunächst einige Vorbereitungen:
$ dd if=/dev/sdj2 count=200704 | md5sum
0f0727f6644dac7a6ec60ea98ffc6da9
$ dd if=/dev/sdj2 count=200704 of=testfile
Das funktioniert nicht:
$ 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
Dies funktioniert auf einem 64-Bit-System, jedoch nicht auf einem 32-Bit-System:
$ 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
Wie geht das zuverlässig?
Anmerkungen
Ich habe andere Fragen zum Puffern gelesen und angeschaut pv
, buffer
und mbuffer
. Letzteres konnte ich nur mit der erforderlichen Puffergröße zum Laufen bringen.
Die Verwendung von Intermetiate-Speicher ist eine offensichtliche Lösung für das Problem, das immer funktioniert, aber nicht praktikabel ist, wenn nicht genügend freie Kapazität verfügbar ist.
Testplattformen unter Arch Linux mit mbuffer
Version 20140302.
mbuffer
sollte tatsächlich den zweiten zwingen dd
, für den ersten zurückzubleiben, und Sie benötigen nur genügend RAM, um die Größe der Verschiebung zu puffern. Schade, dass dd
das Lesen und Schreiben von Blöcken in umgekehrter Reihenfolge nicht unterstützt wird, da dies das Problem beseitigen würde!
-H
Argument aktiviert diese Funktion).
mbuffer
überhaupt verwenden? Warum nicht stattdessendd
den gesamten Inhalt des Blockgeräts auf einmal lesen lassendd bs=102760448
? Natürlich ist es auf die eine oder andere Weise im RAM gepuffert.