私のコマンド:
gunzip -c serial2udp.image.gz |
Sudo dd of=/dev/mmcblk0 conv=fsync,notrunc status=progress bs=4M
私の出力:
15930949632 bytes (16 GB, 15 GiB) copied, 1049 s, 15.2 MB/s
0+331128 records in
0+331128 records out
15931539456 bytes (16 GB, 15 GiB) copied, 1995.2 s, 8.0 MB/s
カード:最大30MB/sのSanDisk Ultra 32GB MicroSDHC Class 10 UHSメモリカード
配布:16.0.4 xenial with xfce
カーネルバージョン:4.13.0.37-generic
私が読んだことから、17分かかるのは妥当だと思います。ブロックサイズで遊んでも実際には大きな違いはないようです(bs = 100Mでも同様のタイムスタンプでこの動作を示します)。更新がハングし、さらに16分間の完成したレポートが生成されないのはなぜですか?
iotopは、mmcqd/0がこの時点で(99%IOで)バックグラウンドでまだ実行中であることを教えてくれるので、最後の5MBを保持しているキャッシュがどこかにあると思いますが、fsyncはそれが起こらないようにする必要があると思いましたこの時点では、iotopはddのトラフィックの交差を示していません。 ctrl-cはほとんど役に立たず、書き込み後にドライブを破損したくありません。
最後の5MBを保持しているキャッシュがどこかにあると思いますが、fsyncはそれが起こらないようにする必要があると思いました
_conv=fsync
_は、fsync
がすべてのデータを書き込んだ後、dd
を呼び出してキャッシュを書き戻すことを意味します。最後にぶら下がることはまさにそれがすることです。
出力ファイルが入力ファイルより遅い場合、dd
によって書き込まれたデータがキャッシュに蓄積される可能性があります。カーネルキャッシュは、システムRAMのかなりの部分を占めることがあります。これは、非常に誤解を招く進行情報になります。あなたの「最終的な5MB」は、dd
がどのように進捗状況を示しているかの単なる人工物でした。
システムが実際に約8 GBをキャッシュしていた場合(つまり、16 GBの書き込みデータの半分)、約32 GBのRAMが必要か、特定のカーネルオプションをいじっていたと思います。以下のlwn.netリンクを参照してください。 15分間進行状況情報を取得しないことはかなりイライラすることに同意します。
使用できる代替のdd
コマンドがあります。 dd
でより正確な進行状況を表示したい場合は、より複雑なものを受け入れる必要があるかもしれません。現実には私以外の考えがあるかもしれませんが、以下はあなたのパフォーマンスを低下させることなく機能すると思います。
_gunzip -c serial2udp.image.gz |
dd iflag=fullblock bs=4M |
Sudo dd iflag=fullblock oflag=direct conv=fsync status=progress bs=4M of=/dev/mmcblk0
_
oflag=direct iflag=fullblock
_は、完全にバイパスするため、カーネルキャッシュの蓄積を回避します。iflag=fullblock
_が必要です(たとえば、パイプから読み取り、直接IOを使用して書き込むため)。 fullblock
がないことによる影響は、dd
のもう1つの残念な複雑さです。このサイトの一部の投稿では、これを使用して、常に別のコマンドを使用することを優先する必要があると主張しています。 IOただし、直接または同期する別の方法を見つけるのは難しいです。conv=fsync
_を引き続き使用する必要があります。dd
の後に追加のgunzip
を追加して、解凍された出力をディスクの書き込みと並行してバッファリングしました。これは、_oflag=direct
_または_oflag=sync
_でのパフォーマンスを少し複雑にする問題の1つです。通常IO(non-direct、non-sync)は、カーネルキャッシュによって既にバッファーされているため、これを必要とすることは想定されていません。 4Mのライトバックキャッシュを備えたハードドライブですが、SDカードにそれほど多くの容量があるとは思いません。あるいは、_oflag=direct,sync
_を使用することもできます(_conv=fsync
_は必要ありません)。 数百メガバイトのキャッシュ を備えた奇妙な出力デバイスがある場合、これは良い進行状況の情報に役立ちます。しかし、通常、私は_oflag=sync
_をパフォーマンスへの潜在的な障壁と考えています。
2013年の記事があります https://lwn.net/Articles/572911/ は、あなたのような1分間の遅延について述べています。多くの人は、分単位のライトバックデータをキャッシュするこの機能を望ましくないと考えています。問題は、キャッシュサイズの制限が高速デバイスと低速デバイスの両方に無差別に適用されることでした。カーネルがデバイスの速度を測定することは、データの場所によって異なるため、重要ではないことに注意してください。例えば。キャッシュされた書き込みがランダムな場所に分散している場合、ハードドライブは書き込みヘッドを繰り返し移動するのに時間がかかります。
更新がハングする理由
fsync()
は、すべての範囲に適用される単一のシステムコールです。 ファイル 端末。完了する前に、ステータスの更新は返されません。
fullblock
を使用したい。 notrunc
はデバイスファイルには影響しません。
dd of=/dev/mmcblk0 iflag=fullblock status=progress bs=4M
そのようなものとしての答えではなく、より多くの診断です。パイプビューutil pv
を使用して、パイプフローのそれぞれの速度がどのようになっているかを確認します例:
pv -c -N raw serial2udp.image.gz |
gunzip |
pv -c -N uncompressed |
Sudo dd of=/dev/mmcblk0 conv=fsync,notrunc status=progress bs=4M
仮説:
.gz
ファイルは最後に最も圧縮されているか、そうでなければgunzip
に追加の作業を与えています。badblocks -nv /dev/mmcblk0