100MBのrawブロックデバイスを例にしてみましょう。これはそれぞれ512バイトの204,800ブロックで、合計102,760,448バイトです。
問題は、最初の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
中間リポジトリを使用することはこの問題に対する明確な解決策であり、常に機能しますが、十分な空き容量がない場合は実用的ではありません。
Arch Linuxバージョン20140302を実行するテストプラットフォームmbuffer
。
ベストアンサー1
バッファがない場合は、一度に1ブロックずつ後ろに移動できます。
for i in $(seq 100 -1 0)
do
dd if=/dev/thing of=/dev/thing \
bs=1M skip=$i seek=$(($i+2)) count=1
done
この例は、エラーチェックが不足して危険です。
通話量が多く、速度も遅かったdd
。空きメモリがある場合は、より大きなブロックサイズを使用できます。
バッファーとして、罠に気をつけて。これはいいえ100%の事前充電を保証するのに十分です。あなたが望むものは、全体的に最小限のパディングです。バッファは絶対に下がってはいけません。2M
それ以外の場合は、まだ読み取られていないデータが上書きされます。
したがって、理論的にはいかなる種類のバッファも使用できず、チェーンのみを使用できますdd
。
dd if=/dev/thing bs=1M | \
dd bs=1M iflag=fullblock | \
dd bs=1M iflag=fullblock | \
dd of=/dev/thing bs=1M seek=2
実際にはそうします。いいえ最後の項目(間に「バッファ」を含む)がすでに書き込まれているdd
間、最初の項目がデータを読み続けるという保証がないため、安定して機能します。dd
2M
中間バッファをかなり大きくすると、可能性が大幅に向上しますが、それでも依然として信頼できません。
残念ながら、私は最小限のパディング属性を持つ良いバッファプログラムを知りません。バッファ内の安全余裕が安全余裕より小さい場合は常に出力を停止できるデバイスが必要です。