簡単な例として、100MBのrawブロックデバイスを考えます。つまり、合計512760バイトの512バイトの204800ブロックです。
最初の98MB(200704ブロック)をシフトして、その前に2MB(4096ブロック)のギャップを設けることが課題です。これをインプレースで行うには、読み取られていないセクターに何も書き込まれないことが必要です。これを実現する1つの方法は、バッファーを導入することです。
$ dd if=/dev/sdj2 count=200704 | mbuffer -s 512 -b 4096 -P 100 | dd of=/dev/sdj2 seek=4096
期待されるのはmbuffer
、ライターに何かを渡す前に4096ブロックを格納することです。これにより、読み取られていない領域に何も書き込まれず、ライターがバッファーのサイズによってリーダーよりも遅れることが保証されます。バッファーは、リーダーとライターがそれらの制約内で可能な限り高速に動作できるようにする必要があります。
ただし、確実に機能するようには見えません。私は実際のデバイスを使ってみましたが、実際には機能しませんが、ファイルを使った実験は64ビットボックスでは機能しましたが、32ビットボックスでは機能しませんでした。
まず、いくつかの準備:
$ dd if=/dev/sdj2 count=200704 | md5sum
0f0727f6644dac7a6ec60ea98ffc6da9
$ dd if=/dev/sdj2 count=200704 of=testfile
これは機能しません:
$ 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
これは64ビットシステムでは機能しますが、32ビットシステムでは機能しません。
$ 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
これをどのように確実に行うことができますか?
ノート
バッファリングに関する他の質問を読みpv
、buffer
とを調べましたmbuffer
。私は後者を必要なバッファサイズでのみ動作させることができました。
中間ストレージを使用することは、常に機能する問題の明白な解決策ですが、十分なスペア容量が利用できない場合は現実的ではありません。
mbuffer
バージョン20140302でArch Linuxを実行しているプラットフォームをテストします。
mbuffer
実際に二を強制すべきdd
最初のために遅れするとあなただけのシフトの大きさをバッファするために十分なRAMが必要です。あまりにも悪いのは、dd
それが問題を排除するため、後方の順にブロックを読み込み、書き込みをサポートしていません!
-H
引数はこの機能を有効にします)。
mbuffer
するのですか?代わりdd
に、ブロックデバイスの内容全体を一度に読み取らせてみませんdd bs=102760448
か?もちろん、いずれかの方法でRAMにバッファーされます。