]> granicus.if.org Git - sysstat/commitdiff
Make sysstat disk counters consistent with those from latest kernel (3.5).
authorSebastien <seb@kluane.home>
Thu, 19 Jul 2012 19:18:06 +0000 (21:18 +0200)
committerSebastien <seb@kluane.home>
Thu, 19 Jul 2012 19:18:06 +0000 (21:18 +0200)
Changed the type of some disk counters to keep in sync with latest 3.5
kernel.
This breaks the compatibility with older sar data files format for disk
activity.

Mail from Peter Schiffer (pschiffe@redhat.com) 15/02/2012:

I am sending you next patch. I've updated reading /proc/diskstats and
/sys/block/<disk>/stat files in iostat.c and rd_stats.c source files
according to latest kernel (3.2.6).

Problem was, that in case of very high I/O operations, sar -d and iostat
outputted overflowed values:

sar -d output:
09:20:01 PM       DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz
await     svctm     %util
09:50:01 PM      sdb1   2986.02      0.05  34704.99     11.62   3355.91
1137.22      0.28     84.49
09:55:01 PM      sdb1   3284.08      0.21  32884.03     10.01   4556.98
1386.29      0.27     88.31
10:00:01 PM      sdb1   3260.33      0.19  31497.61      9.66
61474802782539.38
18855397092136.58      0.27     87.60
10:05:01 PM      sdb1   3373.57      0.08  32028.26      9.49   6069.53
1799.10      0.27     89.86

What do you think about the patch?

CHANGES
activity.c
iostat.c
iostat.h
rd_stats.c
rd_stats.h

diff --git a/CHANGES b/CHANGES
index 2c493b7d720c43f304f2459ba836c5667271caaa..d2fd2ad70393548d99911893e831b2718fa8d415 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,9 +1,13 @@
 Changes:
 
 xxxx/xx/xx: Version 10.1.1 - Sebastien Godard (sysstat <at> orange.fr)
+       * Added option -[0-9]+ to sar to show data of that days ago.
        * [Peter Schiffer]: Persistent device names support added to
          sar and iostat (option -j).
-       * Added option -[0-9]+ to sar to show data of that days ago.
+       * [Peter Schiffer]: Make sysstat disk counters consistent
+         with those from latest kernel (3.5). Warning: This breaks
+         compatibility with older sar data files format for disk
+         activity.
        * [Peter Schiffer]: sar: Use /sys/dev/block/major:minor links
          to determine devices real name.
        * [Peter Schiffer]: Various cosmetic changes in manual pages
index 32c1e46983de7612fdb393a6321ca03f3aacc2b4..c73bca35dbbccd14941820cdfc3c0d2475ee7e43 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * activity.c: Define system activities available for sar/sadc.
- * (C) 1999-2011 by Sebastien GODARD (sysstat <at> orange.fr)
+ * (C) 1999-2012 by Sebastien GODARD (sysstat <at> orange.fr)
  *
  ***************************************************************************
  * This program is free software; you can redistribute it and/or modify it *
@@ -227,7 +227,7 @@ struct activity paging_act = {
 struct activity io_act = {
        .id             = A_IO,
        .options        = AO_COLLECTED,
-       .magic          = ACTIVITY_MAGIC_BASE,
+       .magic          = ACTIVITY_MAGIC_BASE + 1,
        .group          = G_DEFAULT,
 #ifdef SOURCE_SADC
        .f_count        = NULL,
@@ -384,7 +384,7 @@ struct activity serial_act = {
 struct activity disk_act = {
        .id             = A_DISK,
        .options        = AO_NULL,
-       .magic          = ACTIVITY_MAGIC_BASE,
+       .magic          = ACTIVITY_MAGIC_BASE + 1,
        .group          = G_DISK,
 #ifdef SOURCE_SADC
        .f_count        = wrap_get_disk_nr,
index 28a169b8d89f2ff45d682615913bb8e8da3097b0..deefa170e6faef22eb0fdd36222e55c52b564e24 100644 (file)
--- a/iostat.c
+++ b/iostat.c
@@ -497,15 +497,15 @@ int read_sysfs_file_stat(int curr, char *filename, char *dev_name)
        FILE *fp;
        struct io_stats sdev;
        int i;
-       unsigned long rd_ios, rd_merges_or_rd_sec, rd_ticks_or_wr_sec, wr_ios;
-       unsigned long ios_pgr, tot_ticks, rq_ticks, wr_merges, wr_ticks;
-       unsigned long long rd_sec_or_wr_ios, wr_sec;
+       unsigned int ios_pgr, tot_ticks, rq_ticks, wr_ticks;
+       unsigned long rd_ios, rd_merges_or_rd_sec, wr_ios, wr_merges;
+       unsigned long rd_sec_or_wr_ios, wr_sec, rd_ticks_or_wr_sec;
 
        /* Try to read given stat file */
        if ((fp = fopen(filename, "r")) == NULL)
                return 0;
        
-       i = fscanf(fp, "%lu %lu %llu %lu %lu %lu %llu %lu %lu %lu %lu",
+       i = fscanf(fp, "%lu %lu %lu %lu %lu %lu %lu %u %u %u %u",
                   &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);
 
@@ -514,7 +514,7 @@ int read_sysfs_file_stat(int curr, char *filename, char *dev_name)
                sdev.rd_ios     = rd_ios;
                sdev.rd_merges  = rd_merges_or_rd_sec;
                sdev.rd_sectors = rd_sec_or_wr_ios;
-               sdev.rd_ticks   = rd_ticks_or_wr_sec;
+               sdev.rd_ticks   = (unsigned int) rd_ticks_or_wr_sec;
                sdev.wr_ios     = wr_ios;
                sdev.wr_merges  = wr_merges;
                sdev.wr_sectors = wr_sec;
@@ -689,9 +689,9 @@ void read_diskstats_stat(int curr)
        char *dm_name;
        struct io_stats sdev;
        int i;
+       unsigned int ios_pgr, tot_ticks, rq_ticks, wr_ticks;
        unsigned long rd_ios, rd_merges_or_rd_sec, rd_ticks_or_wr_sec, wr_ios;
-       unsigned long ios_pgr, tot_ticks, rq_ticks, wr_merges, wr_ticks;
-       unsigned long long rd_sec_or_wr_ios, wr_sec;
+       unsigned long wr_merges, rd_sec_or_wr_ios, wr_sec;
        char *ioc_dname;
        unsigned int major, minor;
 
@@ -704,7 +704,7 @@ void read_diskstats_stat(int curr)
        while (fgets(line, 256, fp) != NULL) {
 
                /* major minor name rio rmerge rsect ruse wio wmerge wsect wuse running use aveq */
-               i = sscanf(line, "%u %u %s %lu %lu %llu %lu %lu %lu %llu %lu %lu %lu %lu",
+               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);
@@ -717,7 +717,7 @@ void read_diskstats_stat(int curr)
                        sdev.rd_ios     = rd_ios;
                        sdev.rd_merges  = rd_merges_or_rd_sec;
                        sdev.rd_sectors = rd_sec_or_wr_ios;
-                       sdev.rd_ticks   = rd_ticks_or_wr_sec;
+                       sdev.rd_ticks   = (unsigned int) rd_ticks_or_wr_sec;
                        sdev.wr_ios     = wr_ios;
                        sdev.wr_merges  = wr_merges;
                        sdev.wr_sectors = wr_sec;
@@ -1158,10 +1158,10 @@ void write_stats(int curr, struct tm *rectime)
 #ifdef DEBUG
                                if (DISPLAY_DEBUG(flags)) {
                                        /* Debug output */
-                                       fprintf(stderr, "name=%s itv=%llu fctr=%d ioi{ rd_sectors=%llu "
-                                                       "wr_sectors=%llu rd_ios=%lu rd_merges=%lu rd_ticks=%lu "
-                                                       "wr_ios=%lu wr_merges=%lu wr_ticks=%lu ios_pgr=%lu tot_ticks=%lu "
-                                                       "rq_ticks=%lu dk_drive=%lu dk_drive_rblk=%lu dk_drive_wblk=%lu }\n",
+                                       fprintf(stderr, "name=%s itv=%llu fctr=%d ioi{ rd_sectors=%lu "
+                                                       "wr_sectors=%lu rd_ios=%lu rd_merges=%lu rd_ticks=%u "
+                                                       "wr_ios=%lu wr_merges=%lu wr_ticks=%u ios_pgr=%u tot_ticks=%u "
+                                                       "rq_ticks=%u }\n",
                                                shi->name,
                                                itv,
                                                fctr,
@@ -1175,10 +1175,7 @@ void write_stats(int curr, struct tm *rectime)
                                                ioi->wr_ticks,
                                                ioi->ios_pgr,
                                                ioi->tot_ticks,
-                                               ioi->rq_ticks,
-                                               ioi->dk_drive,
-                                               ioi->dk_drive_rblk,
-                                               ioi->dk_drive_wblk
+                                               ioi->rq_ticks
                                                );
                                }
 #endif
index 281689d44de59079c41e68721406d4fa6abe4eed..e01f058742a17c2c5057ec4b3cf6fb38efd5a1bd 100644 (file)
--- a/iostat.h
+++ b/iostat.h
  * The number of structures allocated corresponds to the number of devices
  * present in the system, plus a preallocation number to handle those
  * that can be registered dynamically.
- * The number of devices is found by using /sys filesystem (if mounted),
- * or the number of "disk_io:" entries in /proc/stat (2.4 kernels),
- * else the default value is 4 (for old kernels, which maintained stats
- * for the first four devices in /proc/stat).
+ * The number of devices is found by using /sys filesystem (if mounted).
  * For each io_stats structure allocated corresponds a io_hdr_stats structure.
  * A io_stats structure is considered as unused or "free" (containing no stats
  * for a particular device) if the 'major' field of the io_hdr_stats
  */
 struct io_stats {
        /* # of sectors read */
-       unsigned long long rd_sectors   __attribute__ ((aligned (8)));
+       unsigned long rd_sectors        __attribute__ ((aligned (8)));
        /* # of sectors written */
-       unsigned long long wr_sectors   __attribute__ ((packed));
+       unsigned long wr_sectors        __attribute__ ((packed));
        /* # of read operations issued to the device */
        unsigned long rd_ios            __attribute__ ((packed));
        /* # of read requests merged */
        unsigned long rd_merges         __attribute__ ((packed));
-       /* Time of read requests in queue */
-       unsigned long rd_ticks          __attribute__ ((packed));
        /* # of write operations issued to the device */
        unsigned long wr_ios            __attribute__ ((packed));
        /* # of write requests merged */
        unsigned long wr_merges         __attribute__ ((packed));
+       /* Time of read requests in queue */
+       unsigned int  rd_ticks          __attribute__ ((packed));
        /* Time of write requests in queue */
-       unsigned long wr_ticks          __attribute__ ((packed));
+       unsigned int  wr_ticks          __attribute__ ((packed));
        /* # of I/Os in progress */
-       unsigned long ios_pgr           __attribute__ ((packed));
+       unsigned int  ios_pgr           __attribute__ ((packed));
        /* # of ticks total (for this device) for I/O */
-       unsigned long tot_ticks         __attribute__ ((packed));
+       unsigned int  tot_ticks         __attribute__ ((packed));
        /* # of ticks requests spent in queue */
-       unsigned long rq_ticks          __attribute__ ((packed));
-       /* # of I/O done since last reboot */
-       unsigned long dk_drive          __attribute__ ((packed));
-       /* # of blocks read */
-       unsigned long dk_drive_rblk     __attribute__ ((packed));
-       /* # of blocks written */
-       unsigned long dk_drive_wblk     __attribute__ ((packed));
+       unsigned int  rq_ticks          __attribute__ ((packed));
 };
 
 #define IO_STATS_SIZE  (sizeof(struct io_stats))
index 7da6b7064185fe8bb0c85c0872198e6f73b49774..1a07d7c58e290770bf75d1b0b0231c12ba8fa9c0 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * rd_stats.c: Read system statistics
- * (C) 1999-2011 by Sebastien GODARD (sysstat <at> orange.fr)
+ * (C) 1999-2012 by Sebastien GODARD (sysstat <at> orange.fr)
  *
  ***************************************************************************
  * This program is free software; you can redistribute it and/or modify it *
@@ -472,15 +472,14 @@ void read_diskstats_io(struct stats_io *st_io)
        char line[256];
        char dev_name[MAX_NAME_LEN];
        unsigned int major, minor;
-       unsigned long rd_ios, wr_ios;
-       unsigned long long rd_sec, wr_sec;
+       unsigned long rd_ios, wr_ios, rd_sec, wr_sec;
 
        if ((fp = fopen(DISKSTATS, "r")) == NULL)
                return;
 
        while (fgets(line, 256, fp) != NULL) {
 
-               if (sscanf(line, "%u %u %s %lu %*u %llu %*u %lu %*u %llu",
+               if (sscanf(line, "%u %u %s %lu %*u %lu %*u %lu %*u %lu",
                           &major, &minor, dev_name,
                           &rd_ios, &rd_sec, &wr_ios, &wr_sec) == 7) {
                        
@@ -491,9 +490,9 @@ void read_diskstats_io(struct stats_io *st_io)
                                 */
                                st_io->dk_drive      += rd_ios + wr_ios;
                                st_io->dk_drive_rio  += rd_ios;
-                               st_io->dk_drive_rblk += (unsigned int) rd_sec;
+                               st_io->dk_drive_rblk += rd_sec;
                                st_io->dk_drive_wio  += wr_ios;
-                               st_io->dk_drive_wblk += (unsigned int) wr_sec;
+                               st_io->dk_drive_wblk += wr_sec;
                        }
                }
        }
@@ -522,18 +521,16 @@ void read_diskstats_disk(struct stats_disk *st_disk, int nbr, int read_part)
        char dev_name[MAX_NAME_LEN];
        int dsk = 0;
        struct stats_disk *st_disk_i;
-       unsigned int major, minor;
-       unsigned long rd_ios, wr_ios, rd_ticks, wr_ticks;
-       unsigned long tot_ticks, rq_ticks;
-       unsigned long long rd_sec, wr_sec;
+       unsigned int major, minor, rd_ticks, wr_ticks, tot_ticks, rq_ticks;
+       unsigned long rd_ios, wr_ios, rd_sec, wr_sec;
 
        if ((fp = fopen(DISKSTATS, "r")) == NULL)
                return;
 
        while ((fgets(line, 256, fp) != NULL) && (dsk < nbr)) {
 
-               if (sscanf(line, "%u %u %s %lu %*u %llu %lu %lu %*u %llu"
-                          " %lu %*u %lu %lu",
+               if (sscanf(line, "%u %u %s %lu %*u %lu %u %lu %*u %lu"
+                          " %u %*u %u %u",
                           &major, &minor, dev_name,
                           &rd_ios, &rd_sec, &rd_ticks, &wr_ios, &wr_sec, &wr_ticks,
                           &tot_ticks, &rq_ticks) == 11) {
index 23f854fc7478f02e255919f1031ed9c6cd07adc4..defe91ca92dd8b6193fe331d754b36e849cb3ef4 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * rd_stats.h: Include file used to read system statistics
- * (C) 1999-2011 by Sebastien Godard (sysstat <at> orange.fr)
+ * (C) 1999-2012 by Sebastien Godard (sysstat <at> orange.fr)
  */
 
 #ifndef _RD_STATS_H
@@ -137,11 +137,11 @@ struct stats_paging {
 
 /* Structure for I/O and transfer rate statistics */
 struct stats_io {
-       unsigned int  dk_drive                  __attribute__ ((aligned (4)));
-       unsigned int  dk_drive_rio              __attribute__ ((packed));
-       unsigned int  dk_drive_wio              __attribute__ ((packed));
-       unsigned int  dk_drive_rblk             __attribute__ ((packed));
-       unsigned int  dk_drive_wblk             __attribute__ ((packed));
+       unsigned long long dk_drive             __attribute__ ((aligned (16)));
+       unsigned long long dk_drive_rio         __attribute__ ((packed));
+       unsigned long long dk_drive_wio         __attribute__ ((packed));
+       unsigned long long dk_drive_rblk        __attribute__ ((packed));
+       unsigned long long dk_drive_wblk        __attribute__ ((packed));
 };
 
 #define STATS_IO_SIZE  (sizeof(struct stats_io))
@@ -203,15 +203,15 @@ struct stats_serial {
 
 /* Structure for block devices statistics */
 struct stats_disk {
-       unsigned long long rd_sect      __attribute__ ((aligned (16)));
-       unsigned long long wr_sect      __attribute__ ((aligned (16)));
-       unsigned long rd_ticks          __attribute__ ((aligned (16)));
-       unsigned long wr_ticks          __attribute__ ((aligned (8)));
-       unsigned long tot_ticks         __attribute__ ((aligned (8)));
-       unsigned long rq_ticks          __attribute__ ((aligned (8)));
-       unsigned long nr_ios            __attribute__ ((aligned (8)));
-       unsigned int  major             __attribute__ ((aligned (8)));
-       unsigned int  minor             __attribute__ ((packed));
+       unsigned long long nr_ios       __attribute__ ((aligned (16)));
+       unsigned long rd_sect           __attribute__ ((aligned (16)));
+       unsigned long wr_sect           __attribute__ ((aligned (8)));
+       unsigned int rd_ticks           __attribute__ ((aligned (8)));
+       unsigned int wr_ticks           __attribute__ ((packed));
+       unsigned int tot_ticks          __attribute__ ((packed));
+       unsigned int rq_ticks           __attribute__ ((packed));
+       unsigned int major              __attribute__ ((packed));
+       unsigned int minor              __attribute__ ((packed));
 };
 
 #define STATS_DISK_SIZE        (sizeof(struct stats_disk))