私は純粋なLinuxシステムを使用しているので、利用可能なビジボックスの実装も独自のものもbusybox 1.27
ありません。output=progress
pv
pipe_progress
pv
2つの質問があります。最初のものは以下に基づいています。https://www.linux.com/training-tutorials/show-progress-when-using-dd/。USR1
シグナルを送信してdd
プロセスを「一時停止」し、dd
現在の状態を印刷してから実行中の作業を続行すると言います。運用への影響を最小限に抑えるdd
ためにベンチマークを実行しようとしています。転送されるデータが変動して転送速度が低下する時期を特定することが重要であるため、dd
毎秒現在のジョブの出力を取得したいと思います。dd
最初の質問: 「dd」は信号を受信するたびに「一時停止」されます。これは本当ですかUSR1
?
1秒ごとに一時停止すると、dd
数十ギガバイトを転送するときの作業時間が長くなります。
2番目の質問: 仮説はい最初の質問に対する答えとして、プロセスに信号を送信せずにプロセスの現在の状態を印刷できるかどうか疑問に思いますdd
。一種のリダイレクトSTDOUT
(例:2>&1)ではありませんか?
私の言葉は:
# bs with 1Mib so I can have more control on the test.
dd if=/dev/zero of=/dev/null bs=1048576 count=1024
# Printing current operation status.
sudo kill -USR1 $dd_pid
答え1
dd if=/dev/zero of=/dev/null bs=1048576 count=1024
気づくdd
データを破壊できる、少なくともbs
パラメータを使用する場合。そしてパフォーマンス上の利点特定のシステム構成に最適なブロックサイズを手動で選択する場合は、せいぜい非常に小さいです。あるいは、もっとうまくいくかもしれませんcat
が、cp
せいぜい少し遅くなるかもしれません。したがって、dd
必ずしも必要でない場合は使用しないでください。
バージョン 1.23 以降、BusyBox は以下を使用します。sendfile
read
とを使用する代わりにデータをコピーするシステムコールwrite
。ただし、:、:cat
などの通常のコピーのみcp
を使用する必要があります。サイズの正確な制御が必要なためです。したがって BusyBox ≥1.23 で 。sendfile
dd
read
write
cat
cp
dd
'dd'はUSR1信号を受信するたびに「一時停止」されます。これは本当ですか?
技術的にはそうです。信号を処理するには「一時停止」する必要があります。ただし、一時停止はいくつかのCPU命令を実行するだけです(最も費用がかかるのは進行状況出力を印刷することです)。したがって、これは何らかの方法でベンチマークを無効にしません。
ddが1秒ごとに一時停止すると、数十ギガバイトのデータを転送するときの作業時間が長くなります。
いいえ、スケールの順序が間違っています。単一のCPUスレッドに0.1%の時間を追加できます。主なコストはベンチマークのカーネル時間なので、dd
実装方法ではなく、実行したい作業に固有のものではありません。
プロセスにシグナルを送信せずにddに現在のステータスを印刷させることはできますか?
まあ…いいえ。これを行う簡単で歴史的に確立された標準的で簡単な方法がすでにあります。実装が難しい他の方法があるのはなぜですか?
Linuxでは、レプリカが到達した時点を知るための一般的な方法があります。特別なファイルに対して常に動作するわけではありませんが、コピーを実行するプログラムによっては変わりません。$pid
コピーを実行するプロセスIDと、入出力に使用されるファイル記述子を学びます。dd
fd 0から読み込み、fd 1に書き込みます。 BusyBox はcp
通常 fd 3 から読み込み、fd 4 に書き込みます。 .NETのシンボリックリンクを使用して、どのファイル記述子にどのファイルが開いているかを確認できます/proc/$pid/fd
。
$ cp /dev/zero /dev/null & pid=$!
$ readlink /proc/$pid/fd/3
/dev/zero
$ readlink /proc/$pid/fd/4
/dev/null
$n$
ファイル記述子から場所を確認できます/proc/$pid/fd/$n
。
$ cat /proc/$pid/fdinfo/4
pos: 74252288
flags: 0100001
mnt_id: 27
ただし、ファイル記述子の位置は/dev/zero
、パイプまたはソケットなどの特殊ファイルで/dev/null
更新されないことがあります。常に通常のファイルを使用して更新されます。ブロックデバイス用に更新されたかどうかはわかりません。したがって/dev/zero
、間のコピーに関する情報を提供することはできませんが、/dev/null
実際のユースケースでは機能します。
答え2
インターフェースを通して進行状況を確認することもできます/proc
。
# dd bs=1M if=/dev/mmcblk0 of=/dev/null &
# pidof dd
1358
したがって、このプロセスに関する情報は以下で確認できます/proc/1358
。
# ls -l /proc/1358/fd
total 0
lr-x------ 1 root root 64 Nov 2 09:16 0 -> /dev/mmcblk0
l-wx------ 1 root root 64 Nov 2 09:16 1 -> /dev/null
lrwx------ 1 root root 64 Nov 2 09:16 2 -> /dev/pts/0
ファイルハンドル0はですif=/dev/mmcblk0
。現在の進捗状況はどこですか?
# cat /proc/1358/fdinfo/0
pos: 2132803584
flags: 0400000
mnt_id: 17
# cat /proc/1358/fdinfo/0
pos: 2366636032
flags: 0400000
mnt_id: 17
# cat /proc/1358/fdinfo/0
pos: 2587885568
flags: 0400000
mnt_id: 17
これにより、busybox ddの場合、fdinfo pos値から進行状況を取得することもできます。
言い換えれば、USR1信号を適切に送信することは性能にほとんど影響を及ぼさない。リソースがほとんどない組み込みシステムでfdinfoをポーリングすると、同様の効果がある可能性があります。