iostat -x
(Ich habe eine alte Version des Quellcodes verwendet, um dies zu schreiben, bevor ich es realisierte) zeigt Informationen von /proc/diskstats
an (hier dokumentiert) und /proc/stat
(für CPU-Zeiten siehe man proc(5)) (und ein paar andere, aber das ist für das Verständnis nicht wichtig).
Sie können die relevanten Codeausschnitte in der Antwort von osgx sehen, aber ich konnte sie isoliert nicht verstehen, daher hier eine ausführliche Erklärung:
%util = blkio.ticks / deltams * 100%
deltams
ist die seit dem letzten Schnappschuss verstrichene Zeit in ms. Es verwendet CPU-Statistiken von/proc/stat
vermutlich, weil es bessere Ergebnisse liefert, als sich auf die Systemzeit zu verlassen, aber ich weiß es nicht genau. (Nebenbemerkung:Aus irgendeinem Grund werden die Zeiten durchHZ
geteilt , während die Dokumentation besagt, dass es sich inUSER_HZ
befindet , das verstehe ich nicht.)-
blkio.ticks
ist "Anzahl der Millisekunden, die für I/Os aufgewendet werden", von/proc/diskstats
Dokumente:Field 9 -- # of I/Os currently in progress The only field that should go to zero. Incremented as requests are given to appropriate struct request_queue and decremented as they finish. Field 10 -- # of milliseconds spent doing I/Os This field increases so long as field 9 is nonzero.
Das heißt, ich verstehe, dass
ticks
ist die Anzahl der Ticks, während der eine E/A-Anforderung (für dieses Gerät) ausgeführt wurde, multipliziert mit der Dauer zwischen den Ticks.
Also %util = 100%
bedeutet, dass jedes Mal, wenn der Kernel nachsah (ich schätze, es sind 1000 Mal pro Sekunde bei modernen Kerneln, siehe "HZ"), eine I/O-Anfrage im Gange war.
Hier ist ein Auszug aus einem anderen Post auf iostat:
[%util is] Wie viel Zeit hatte das Speichergerät ausstehende Arbeit (war ausgelastet).
In richtigen RAID-Umgebungen ist es eher „wie viel Zeit hatte mindestens eine Festplatte im RAID-Verbund etwas zu tun“. Ich schließe hier absichtlich jede Art von Cache aus – wenn eine Anfrage vom Cache bedient werden kann, ist die Wahrscheinlichkeit ziemlich vernachlässigbar, dass sie im Gegensatz zu anderen Werten in %util angezeigt wird.
Was das auch bedeutet – das RAID-Subsystem kann von 6,25 % (eine Platte erledigt die Arbeit) bis 100 % (alle ausgelastet) ausgelastet werden. Das ist ziemlich viel Einblick in den Einzelwert von '100 %', nicht wahr?
%util
heißt busy im Quellcode von iostat:https://code.google.com/p/tester-higkoo/source/browse/trunk/Tools/iostat/iostat.c#380
Beschäftigt wird als Prozentverhältnis von Ticks
gezählt bis deltams
, begrenzt auf 100 %
busy = 100.0 * blkio.ticks / deltams; /* percentage! */
if (busy > 100.0) busy = 100.0;
DeltaMS ist die Summe der Systemlast für den Zeitraum (Benutzerzeit + Systemzeit + Leerlaufzeit + iowait)/ ncpu.
double deltams = 1000.0 *
((new_cpu.user + new_cpu.system +
new_cpu.idle + new_cpu.iowait) -
(old_cpu.user + old_cpu.system +
old_cpu.idle + old_cpu.iowait)) / ncpu / HZ;
Zecken - ist der Time of requests in queue
für den Zeitraum
blkio.ticks = new_blkio[p].ticks
- old_blkio[p].ticks;
In neueren Versionen von sysstat ist der Code etwas anders:http://sources.debian.net/src/sysstat/10.2.0-1/iostat.c#L959
/* rrq/s wrq/s r/s w/s rsec wsec rqsz qusz await r_await w_await svctm %util */
printf(" %8.2f %8.2f %7.2f %7.2f %8.2f %8.2f %8.2f %8.2f %7.2f %7.2f %7.2f %6.2f %6.2f\n",
...
/*
* Again: Ticks in milliseconds.
* In the case of a device group (option -g), shi->used is the number of
* devices in the group. Else shi->used equals 1.
*/
shi->used ? xds.util / 10.0 / (double) shi->used
: xds.util / 10.0); /* shi->used should never be null here */
xds wird in compute_ext_disk_stats(&sdc, &sdp, itv, &xds);
gefüllt http://sources.debian.net/src/sysstat/10.2.0-1/common.c?hl=679#L679
/*
* Macros used to display statistics values.
*
* HZ is 1024 on IA64 and % should be normalized to 100.
*/
#define S_VALUE(m,n,p) (((double) ((n) - (m))) / (p) * HZ)
xds->util = S_VALUE(sdp->tot_ticks, sdc->tot_ticks, itv);
Und da ist das Füllen von tot_ticks von iostat.c
* @ioi Current sample statistics.
* @ioj Previous sample statistics.
* @itv Interval of time.
...
sdc.tot_ticks = ioi->tot_ticks;
sdp.tot_ticks = ioj->tot_ticks;
tot_ticks
werden aus "sysfs stat for current block device or partition gelesen " in read_sysfs_file_stat
(iostat.c:487) und ioi
und ioj
sind aktueller und früherer Stand.