简体   繁体   English

如何在linux上编程从/ proc获取每秒磁盘读/写字节数?

[英]how to get disk read/write bytes per second from /proc in programming on linux?

purpose :i want to get information like iostat command can get . 目的 :我想获得像iostat命令一样的信息。

I have already known that if open /proc/diskstats or /sys/block/sdX/stat there are information that : sectors read and sectors write . 我已经知道如果打开/proc/diskstats/sys/block/sdX/stat有信息: 扇区读取扇区写入 So if i want to get read/write bytes/s ,the following formula is right ? 所以,如果我想获得读/写字节/ s,下面的公式是正确的?

read/write bytes per second : 每秒读/写字节数
(sectors read/write(now)-sectors read/write(last))*512 bytes/time interval (扇区读/写(现在) - 段读/写(最后))* 512字节/时间间隔

read /write operations per second : 每秒读/写操作
(read/write IOs(now)+read/write merges(now)-read/write IOs(last)-read/write merges(last ))/time interval (读/写IOs(现在)+读/写合并(现在)-read / write IOs(last)-read / write merges(last))/ time interval

So if i have a timer that every second control software read the information from those two files ,and then using the above formula to calculate the value .Can i get the correct answer ? 因此,如果我有一个计时器,每个第二个控制软件从这两个文件中读取信息,然后使用上面的公式来计算值。我能得到正确的答案吗?

TLDR Sector is 512 bytes ( octets ; 1 sector is 512 bytes; each bytes is 8 bits; every bit is either 0 or 1, but not superposition of them). TLDR扇区是512字节八位字节 ; 1扇区是512字节;每个字节是8位;每个位是0或1,但不是它们的叠加)。

"The standard sector size of 512 bytes for magnetic disks was established .... [dubious – discuss] " (c) wiki https://en.wikipedia.org/wiki/Disk_sector “建立了磁盘512字节的标准扇区大小...... [可疑 - 讨论] ”(c)wiki https://en.wikipedia.org/wiki/Disk_sector

How to check sector size for io statistics (in /proc ) in linux: 如何在linux中检查io统计信息的扇区大小(在/proc ):

Check how iostat tool works (it shows kilobyte per second when started as iostat 1 ) - it is part of sysstat package: 检查iostat工具如何工作(它作为iostat 1启动时显示每秒千字节数) - 它是sysstat包的一部分:

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

 * Read stats from /proc/diskstats.
void read_diskstats_stat(int curr)
...
        /* major minor name rio rmerge rsect ruse wio wmerge wsect wuse running use aveq */
        i = sscanf(line, "%u %u %s %lu %lu %lu %lu %lu %lu %lu %u %u %u %u",
               &major, &minor, dev_name,
               &rd_ios, &rd_merges_or_rd_sec, &rd_sec_or_wr_ios, &rd_ticks_or_wr_sec,
               &wr_ios, &wr_merges, &wr_sec, &wr_ticks, &ios_pgr, &tot_ticks, &rq_ticks);

        if (i == 14) {
....
            sdev.rd_sectors = rd_sec_or_wr_ios;
....
            sdev.wr_sectors = wr_sec;
....

 * @fctr    Conversion factor.
...
        if (DISPLAY_KILOBYTES(flags)) {
            printf("    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn\n");
            *fctr = 2;
        }
...
    /*       rrq/s wrq/s   r/s   w/s  rsec  wsec  rqsz  qusz await r_await w_await svctm %util */
    ... 4 columns skipped
    cprintf_f(4, 8, 2,
          S_VALUE(ioj->rd_sectors, ioi->rd_sectors, itv) / fctr,
          S_VALUE(ioj->wr_sectors, ioi->wr_sectors, itv) / fctr,

So, read sector count and divide by two to get kilobyte/s (seems like 1 sector read is 0.5 kb read; 2 sector read is 1 kb read and so on). 因此,读取扇区计数并除以2得到千字节/秒(似乎1扇区读取是0.5 kb读取; 2扇区读取是1 kb读取,依此类推)。 We can conclude that the sector is always 512 bytes . 我们可以得出结论, 扇区总是512字节 Same is stated in the doc, isn't it?: 文档中说明了相同,不是吗?:

internet search for "/proc/diskstats" -> 互联网搜索“/ proc / diskstats” - >

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

https://www.kernel.org/doc/Documentation/iostats.txt "I/O statistics fields" by ricklind from usa's ibm 来自美国的ibm的ricklind的https://www.kernel.org/doc/Documentation/iostats.txt“I / O统计字段”

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.

No info about sector size here (why?). 这里没有关于扇区大小的信息 (为什么?)。 Is the source code being the best documentation (it may be)? 源代码是最好的文档(它可能是)吗? The writer of /proc/diskstats is in kernel sources in file block/genhd.c , function diskstats_show : /proc/diskstats器位于文件block/genhd.c内核源代码中,函数diskstats_show

http://lxr.free-electrons.com/source/block/genhd.c?v=4.4#L1149 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]),

Structure sectors is defined in http://lxr.free-electrons.com/source/include/linux/genhd.h?v=4.4#L82 结构sectorshttp://lxr.free-electrons.com/source/include/linux/genhd.h?v=4.4#L82中定义

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

It is read with part_stat_read and written with __part_stat_add 它读取part_stat_read和书面__part_stat_add

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

Adding to the sectors counter ... is... at http://lxr.free-electrons.com/source/block/blk-core.c?v=4.4#L2264 添加到sectors柜台...是...在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 }

It uses hard-coded " bytes >> 9 " to compute sector size from request size in bytes (why round down??) or for human, not no-floating-point compiler, it is the same as bytes / 512 . 它使用硬编码的“ bytes >> 9 ”来计算从请求大小(以字节为单位)的扇区大小(为什么向下舍入??)或者对于人类,而不是非浮点编译器,它与bytes / 512相同。

There is also blk_rq_sectors function (unused here...) to get sector count from request, which does the same >>9 from bytes to sectors http://lxr.free-electrons.com/source/include/linux/blkdev.h?v=4.4#L853 还有blk_rq_sectors函数(这里未使用...)从请求中获取扇区计数,它从字节到扇区http://lxr.free-electrons.com/source/include/linux/blkdev执行相同的>>9 。 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 }

Authors of FS/VFS subsystem in Linux says in reply to https://lkml.org/lkml/2015/8/17/234 "Why is SECTOR_SIZE = 512 inside kernel ?" Linux中FS / VFS子系统的作者回复https://lkml.org/lkml/2015/8/17/234 “为什么内核中的SECTOR_SIZE = 512?” (2015): (2015年):

 #define SECTOR_SHIFT 9

Message https://lkml.org/lkml/2015/8/17/269 by Theodore Ts'o: Theodore Ts'o的消息https://lkml.org/lkml/2015/8/17/269

It's cast in stone. 它是一成不变的。 There are too many places all over the kernel, especially in a huge number of file systems, which assume that the sector size is 512 bytes. 整个内核中有太多的地方,特别是在大量的文件系统中,假设扇区大小为512字节。 So above the block layer, the sector size is always going to be 512. 因此,在块层之上, 扇区大小始终为512。

This is actually better for user space programs using /proc/diskstats, since they don't need to know whether a particular underlying hardware is using 512, 4k, (or if the HDD manufacturers fantasies become true 32k or 64k) sector sizes. 这对于使用/ proc / diskstats的用户空间程序来说实际上更好 ,因为他们不需要知道特定底层硬件是使用512,4k(或者如果HDD制造商幻想成为真正的32k或64k)扇区大小。

For similar reason, st_blocks in struct size is always in units of 512 bytes. 出于类似的原因,struct size中的st_blocks总是以512字节为单位。 We don't want to force userspace to have to figure out whether the underlying file system is using 1k, 2k, or 4k. 我们不希望强制用户空间必须弄清楚底层文件系统是使用1k,2k还是4k。 For that reason the units of st_blocks is always going to be 512 bytes, and this is hard-coded in the POSIX standard. 因此,st_blocks的单位总是512字节,这在POSIX标准中是硬编码的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM