USR1 なしで dd の進行状況を確認しますか?

USR1 なしで dd の進行状況を確認しますか?

私は Linuxbusybox 1.27のみのシステムを使用しているためoutput=progress、busybox 独自の実装は利用できません。また、busybox 自体の実装もpvありpipe_progressませんpv

質問が2つあります。1つ目はhttps://www.linux.com/training-tutorials/show-progress-when-using-dd/USR1信号を送信するとddプロセスが「一時停止」され、dd現在のステータスを印刷した後、実行していたジョブが続行されます。 でベンチマーク テストをいくつか実行しようとしているので、操作ddへの影響を最小限に抑えたいと考えていますdd。通過するデータは変動しており、転送速度が落ちたときにそれを認識することが重要であるため、現在の操作の出力を 1 秒ごとに取得し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が、ではサイズを正確に制御する必要があるため、 /を使用する必要があります。そのため、BusyBox ≥ 1.23 では、やは よりも高速である可能性が非常に高くなります。cpsendfileddreadwritecatcpdd

'dd' が USR1 信号を受信するたびに「一時停止」するのは本当ですか?

技術的には、信号を処理するために「一時停止」する必要があります。ただし、一時停止は CPU 命令の数だけに限られます (最もコストがかかる部分は、進行状況の出力を印刷することです)。したがって、これによってベンチマークが無効になることはありません。

dd が毎秒一時停止すると、数十ギガバイトが転送されているときに操作に何時間もかかることになります。

いいえ、桁数が間違っています。単一 CPU スレッドでは、おそらく 0.1% の時間が追加されるでしょう。主なコストは、ベンチマーク プログラムのカーネル時間であり、 ではありません。ddしたがって、これは、実装方法ではなく、実行したい内容に内在するものです。

プロセスにシグナルを送信せずにddに現在のステータスを印刷させることが可能かどうか

いいえ、そうではありません。すでに、単純で、歴史的に確立された、標準的で簡単な方法があります。なぜ、実装がより難しい別の方法があるのでしょうか?


Linux では、コピーが到達したポイントを知るための一般的な方法があります。コピーを実行しているプログラムには依存しませんが、特殊なファイルでは必ずしも機能するとは限りません。$pidコピーを実行しているプロセス ID と、入力および出力に使用しているファイル記述子を調べます。fd dd0 から読み取り、fd 1 に書き込みます。BusyBox はcp通常、fd 3 から読み取り、fd 4 に書き込みます。のシンボリック リンクを通じて、どのファイルがどのファイル記述子で開かれているかを確認できます/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 をポーリングすると、同様の影響が出る可能性があります。

関連情報