Den Fortschritt von dd ohne USR1 prüfen?

Den Fortschritt von dd ohne USR1 prüfen?

Ich verwende ein busybox 1.27reines Linux-System, daher ist output=progressweder eine eigene Implementierung von Busybox noch von ihm selbst verfügbar.pvpipe_progresspv

Ich habe zwei Fragen. Die erste basiert aufhttps://www.linux.com/training-tutorials/show-progress-when-using-dd/. Es heißt, dass durch das Senden des USR1Signals ddder Prozess „angehalten“ wird und ddnach dem Ausdrucken des aktuellen Status mit der gerade ausgeführten Arbeit fortgefahren wird. Ich versuche, einige Benchmarktests durchzuführen, dddaher möchte ich den Vorgang so wenig wie möglich beeinflussen dd. Ich möchte jede Sekunde eine Ausgabe des aktuellen Vorgangs erhalten, da die durchlaufenden Daten ddschwanken und es mir wichtig ist, zu erkennen, wann die Übertragungsrate sinkt.

Erste Frage: Stimmt es, dass „dd“ jedes Mal „pausiert“, wenn es ein USR1Signal empfängt?

Wenn ddjede Sekunde eine Pause erfolgt, verlängert sich die Dauer des Vorgangs um Stunden, wenn Dutzende Gigabyte übertragen werden.

Zweite Frage: AngenommenJaals Antwort auf die erste Frage würde ich gerne wissen, ob es möglich ist, ddden aktuellen Status auszudrucken, ohne ein Signal an den Prozess zu senden, vielleicht eine Art Umleitung STDOUT(wie 2>&1)?

Ich beziehe mich auf Folgendes:

# 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 

Antwort1

dd if=/dev/zero of=/dev/null bs=1048576 count=1024

Beachten Sie, dassddkann Daten verfälschen, mindestensbei Verwendung des bsParameters. Undseinen Leistungsvorteilist bestenfalls klein, wenn Sie eine optimale Blockgröße für Ihre spezielle Systemkonfiguration auswählen: catoder cpkann besser sein und ist höchstens nur geringfügig langsamer. Verwenden Sie es also nicht, ddwenn es nicht unbedingt sein muss.

Beachten Sie, dass BusyBox seit Version 1.23 diesendfileSystemaufruf zum Kopieren von Daten, anstatt readund zu verwenden write. Nur einfache Kopien wie catund cpverwenden sendfilejedoch / , da eine genaue Kontrolle über die Größen erforderlich ist. Daher sind und mit BusyBox ≥1,23 ddsehr wahrscheinlich schneller als .readwritecatcpdd

Stimmt es, dass „dd“ jedes Mal „pausiert“, wenn es ein USR1-Signal empfängt?

Technisch gesehen muss es „pausieren“, um das Signal zu verarbeiten. Die Pause besteht jedoch nur aus ein paar CPU-Anweisungen (der bei weitem aufwändigste Teil ist das Drucken der Fortschrittsausgabe). Dies macht Ihren Benchmark also in keiner Weise ungültig.

Wenn dd jede Sekunde pausiert, verlängere ich die Dauer des Vorgangs um Stunden, wenn Dutzende Gigabyte übertragen werden.

Nein, Sie haben die Größenordnungen falsch angegeben. Sie werden vielleicht 0,1 % der Zeit für einen Single-CPU-Thread hinzufügen. Die Hauptkosten entstehen durch die Kernelzeit für das Benchmarking-Programm, nicht durch . ddEs hängt also von dem ab, was Sie tun möchten, und nicht von der Art und Weise, wie Sie es implementieren.

wenn es möglich ist, dd dazu zu bringen, seinen aktuellen Status auszudrucken, ohne ein Signal an den Prozess zu senden

Nein, nein. Es gibt bereits eine einfache, historisch etablierte, standardmäßige und einfache Möglichkeit, dies zu tun. Warum sollte es eine andere Möglichkeit geben, die schwieriger umzusetzen wäre?


Unter Linux gibt es eine allgemeine Methode, um den Punkt zu ermitteln, den eine Kopie erreicht hat. Dies hängt nicht davon ab, welches Programm die Kopie durchführt, obwohl es bei speziellen Dateien nicht immer funktioniert. Finden Sie die Prozess-ID heraus, $piddie die Kopie durchführt, und welche Dateideskriptoren es für die Eingabe und Ausgabe verwendet. ddliest von fd 0 und schreibt in fd 1. BusyBox cpliest normalerweise von fd 3 und schreibt in fd 4. Sie können anhand der symbolischen Links in überprüfen, welche Datei in welchem ​​Dateideskriptor geöffnet ist /proc/$pid/fd.

$ cp /dev/zero /dev/null & pid=$!
$ readlink /proc/$pid/fd/3
/dev/zero
$ readlink /proc/$pid/fd/4
/dev/null

Und Sie können die Position im Dateideskriptor $n$in überprüfen /proc/$pid/fd/$n.

$ cat /proc/$pid/fdinfo/4
pos:    74252288
flags:  0100001
mnt_id: 27

Beachten Sie jedoch, dass die Position des Dateideskriptors möglicherweise nicht mit speziellen Dateien wie /dev/zero, /dev/null, Pipes oder Sockets aktualisiert wird. Sie wird immer mit regulären Dateien aktualisiert. Ich weiß nicht, ob sie für Blockgeräte aktualisiert wird. Daher wird sie Ihnen wahrscheinlich keine Informationen zum Kopieren zwischen /dev/zeround geben /dev/null, aber in Ihrem tatsächlichen Anwendungsfall könnte sie funktionieren.

Antwort2

Den Fortschritt können Sie zudem über die /procSchnittstelle abfragen.

# dd bs=1M if=/dev/mmcblk0 of=/dev/null &
# pidof dd
1358

Informationen zu diesem Vorgang finden Sie hier /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

Dateihandle 0 ist das if=/dev/mmcblk0, wie steht es nun mit dem Fortschritt?

# 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

Auf diese Weise können Sie für Busybox DD den Fortschritt auch aus seinem Fdinfo-Pos-Wert ableiten.

Das Senden des USR1-Signals in Maßen sollte jedoch nur minimale Auswirkungen auf die Leistung haben. Auf einem eingebetteten System mit wenigen Ressourcen könnte das Abfragen von fdinfo ebenso gute Auswirkungen haben.

verwandte Informationen