2016-05-16 16 views
4

Zweck: Ich möchte Informationen wie iostat Befehl erhalten können.Wie bekomme ich Lese-/Schreibbytes pro Sekunde von/proc in der Programmierung auf Linux?

ich bereits gewusst haben, dass, wenn offen /proc/diskstats oder /sys/block/sdX/stat dort Informationen sind folgende: Sektoren lesen und Sektoren schreiben. Also, wenn ich Lese/Schreib-Bytes/s bekommen möchte, ist die folgende Formel richtig?

Lese/Schreib-Bytes pro Sekunde:
(Sektoren lesen/schreiben (jetzt) ​​-Klassen-Lese/Schreib (lesen)) · 512 Byte/Zeitintervall

Lese-/Schreiboperationen pro zweiter:
/Zeitintervall

Also, wenn ich (lesen/schreiben IOs (jetzt) ​​+ Lese/schreib-Merges (jetzt) ​​-Lesen/schreiben IOs (letzter) -Lesen/Merges (letztes) schreiben) Habe einen Timer an diesem Abend ry second control software liest die Informationen aus diesen beiden Dateien ein und verwendet dann die obige Formel, um den Wert zu berechnen. Kann ich die richtige Antwort bekommen?

+0

Mögliche Duplikat [Berechnung Disk Read/Write in Linux mit C++] (http://stackoverflow.com/questions/14525390/calculating-disk-read-write-in-linux-with-c) – Schore

Antwort

7

TLDR Sector ist 512 Bytes (octets; 1-Sektor 512 Bytes, wobei jedes Byte 8 Bits, jedes Bit entweder 0 oder 1, aber nicht Überlagerung von ihnen).

"Die Standard-Sektorgröße von 512 Byte für Magnetplatten hergestellt wurde .... [zweifelhaft - besprechen]" (c) Wiki https://en.wikipedia.org/wiki/Disk_sector

Wie Sektorgröße für io Statistiken überprüfen (in /proc) in linux:

prüfen, wie iostat Tool funktioniert (es zeigt Kilobyte pro Sekunde, wenn sie als iostat 1 gestartet) - es ist Teil des sysstat Paket ist:

https://github.com/sysstat/sysstat/blob/master/iostat.c

Also lesen Sektor Anzahl und dividiere durch zwei Kilobyte/s (scheint wie 1 Sektor lesen ist 0,5 kb lesen; 2 Sektor lesen ist 1 kb lesen und so weiter). Wir können daraus schließen, dass der Sektor immer 512 Bytes ist. Gleiche ist in der doc erwähnt, ist es nicht ?:

Internet-Suche nach "/ proc/diskstats" ->

https://www.kernel.org/doc/Documentation/ABI/testing/procfs-diskstats ->

https://www.kernel.org/doc/Documentation/iostats.txt "I/O-Statistiken Felder" von ricklind aus usa IBMs

Field 3 -- # of sectors read 
    This is the total number of sectors read successfully. 

Field 7 -- # of sectors written 
    This is the total number of sectors written successfully. 

Keine Information über Sektorgröße hier (warum?). Ist der Quellcode die beste Dokumentation (möglicherweise)?Der Verfasser /proc/diskstats ist in Kernel-Quellen in der Datei block/genhd.c funktionieren diskstats_show:

http://lxr.free-electrons.com/source/block/genhd.c?v=4.4#L1149

1170     seq_printf(seqf, "%4d %7d %s %lu %lu %lu " 
1171       "%u %lu %lu %lu %u %u %u %u\n", 
... 
1176       part_stat_read(hd, sectors[READ]), 
... 
1180       part_stat_read(hd, sectors[WRITE]), 

Struktur sectors in http://lxr.free-electrons.com/source/include/linux/genhd.h?v=4.4#L82 definiert ist

82 struct disk_stats { 
83   unsigned long sectors[2];  /* READs and WRITEs */ 

Es wird gelesen mit part_stat_read und geschrieben mit __part_stat_add

http://lxr.free-electrons.com/source/include/linux/genhd.h?v=4.4#L307

zum sectors Zähler hinzugefügt ... ... wird bei http://lxr.free-electrons.com/source/block/blk-core.c?v=4.4#L2264

2264 void blk_account_io_completion(struct request *req, unsigned int bytes) 
2265 { 
2266   if (blk_do_io_stat(req)) { 
2267     const int rw = rq_data_dir(req); 
2268     struct hd_struct *part; 
2269     int cpu; 
2270 
2271     cpu = part_stat_lock(); 
2272     part = req->part; 
2273     part_stat_add(cpu, part, sectors[rw], bytes >> 9); 
2274     part_stat_unlock(); 
2275   } 
2276 } 

Es nutzt hartcodiert "bytes >> 9" Sektorgröße von Anforderungsgröße in Bytes zu berechnen (warum Abrundungs ​​??) oder für den menschlichen, nicht No-Floating-Point-Compiler, ist es das gleiche wie bytes/512.

Es gibt auch blk_rq_sectors Funktion (ungenutzt hier ...) Sektorenzählregisters von Anfrage zu bekommen, die die gleiche >>9 von Bytes Sektoren tut http://lxr.free-electrons.com/source/include/linux/blkdev.h?v=4.4#L853

841 static inline unsigned int blk_rq_bytes(const struct request *rq) 
842 { 
843   return rq->__data_len; 
844 } 

853 static inline unsigned int blk_rq_sectors(const struct request *rq) 
854 { 
855   return blk_rq_bytes(rq) >> 9; 
856 } 

Autoren von FS/VFS-Subsystem in Linux sagt als Antwort auf https://lkml.org/lkml/2015/8/17/234 "Warum ist SECTOR_SIZE = 512 im Kernel?" (2015):

#define SECTOR_SHIFT 9 

Nachricht https://lkml.org/lkml/2015/8/17/269 von Theodore Ts'o:

Es ist in Stein gemeißelt. Es gibt zu viele Orte überall im Kernel, vor allem in einer großen Anzahl von Dateisystemen, die davon ausgehen, dass die Sektorgröße 512 Bytes ist. So oberhalb der Sperrschicht, die Sektorgröße wird immer 512.

Dies ist eigentlich besser für Userspace-Programme werden mit /proc/diskstats, da sie müssen nicht wissen, ob ein insbesondere zugrunde liegenden Hardware verwendet 512, 4k, (oder wenn die HDD-Hersteller Phantasien wahr werden 32k oder 64k) Sektorgrößen.

Aus demselben Grund ist st_blocks in Strukturgröße immer in Einheiten von 512 Bytes. Wir wollen Userspace nicht zwingen herauszufinden, ob das zugrunde liegende Dateisystem 1k, 2k oder 4k verwendet. Aus diesem Grund die Einheiten von st_blocks wird immer 512 Bytes, und dies ist im POSIX-Standard fest codiert.

+1

Hmm , warum teilt Iostat den Wert durch 2, nicht multipliziert ('s_value()/fctr')? – osgx

+0

@osgx, gibt es Zähler von read_sectors: zum Beispiel wurden in 1 Sekunde 54 Sektoren gelesen, jeder von 512 Bytes.Um also Kilobyte pro Sekunde zu erhalten, sollten wir read_sectors in read_kilobytes konvertieren; Sektor ist 512 Byte, Kilobyte ist 1024 Byte, also Kilobyte ist 2 Sektoren lang. Wenn wir s_value (read_sectors) durch 2 teilen, erhalten wir 27 Kilobytes pro Sekunde, also wird fctr korrekt verwendet. – osgx

+0

Diese Antwort wurde auf eine so vollständige und tiefe Art und Weise beantwortet, dass ich meine Suche nur beenden kann. VIELEN DANK! –