]> granicus.if.org Git - sysstat/commitdiff
Workaround for I/O and transfer rates statistics
authorSebastien GODARD <sysstat@users.noreply.github.com>
Fri, 1 Jul 2016 13:30:34 +0000 (15:30 +0200)
committerSebastien GODARD <sysstat@users.noreply.github.com>
Fri, 1 Jul 2016 13:30:34 +0000 (15:30 +0200)
Values displayed for I/O and transfer rates statistics (sar -b) may be
wrong if a filesystem / a device is unmounted, eg:

16:45:08          tps      rtps      wtps   bread/s   bwrtn/s
16:50:00        46.57     40.12      6.45    648.67    573.12
16:55:08    59853160524690272.00 59853160524690272.00      6.29
59853160524689824.00    135.44

This is because the total number of I/O operations is calculated as the sum
of operations for each filesystem/device mounted by the system. But if a
filesystem is unmounted, the total number of I/O operations may be lower
than its previous value, resulting in a negative number displayed by
sar. Display 0.0 in this case.
A note warning the user should probably go into the manual page too.

Signed-off-by: Sebastien GODARD <sysstat@users.noreply.github.com>
json_stats.c
pr_stats.c
rndr_stats.c
xml_stats.c

index 9b4036cee4a66895ecffdfa976dd68175c539ca0..f45254ec0b38f31b63fefa3c495fecd7d5509211 100644 (file)
@@ -435,10 +435,21 @@ __print_funct_t json_print_io_stats(struct activity *a, int curr, int tab,
                 "\"io-writes\": {"
                 "\"wtps\": %.2f, "
                 "\"bwrtn\": %.2f}}",
+                /*
+                 * If we get negative values, this is probably because
+                 * one or more devices/filesystems have been unmounted.
+                 * We display 0.0 in this case though we should rather tell
+                 * the user that the value cannot be calculated here.
+                 */
+                sic->dk_drive < sip->dk_drive ? 0.0 :
                 S_VALUE(sip->dk_drive, sic->dk_drive, itv),
-                S_VALUE(sip->dk_drive_rio,  sic->dk_drive_rio,  itv),
+                sic->dk_drive_rio < sip->dk_drive_rio ? 0.0 :
+                S_VALUE(sip->dk_drive_rio, sic->dk_drive_rio, itv),
+                sic->dk_drive_rblk < sip->dk_drive_rblk ? 0.0 :
                 S_VALUE(sip->dk_drive_rblk, sic->dk_drive_rblk, itv),
-                S_VALUE(sip->dk_drive_wio,  sic->dk_drive_wio,  itv),
+                sic->dk_drive_wio < sip->dk_drive_wio ? 0.0 :
+                S_VALUE(sip->dk_drive_wio, sic->dk_drive_wio, itv),
+                sic->dk_drive_wblk < sip->dk_drive_wblk ? 0.0 :
                 S_VALUE(sip->dk_drive_wblk, sic->dk_drive_wblk, itv));
 }
 
index 2aab2fc5489f799a79b296ace5844b718b7f882c..96b51eaa78c8b9998134d25348f69569a4f924d4 100644 (file)
@@ -386,11 +386,22 @@ __print_funct_t print_io_stats(struct activity *a, int prev, int curr,
        }
 
        printf("%-11s", timestamp[curr]);
+       /*
+        * If we get negative values, this is probably because
+        * one or more devices/filesystems have been unmounted.
+        * We display 0.0 in this case though we should rather tell
+        * the user that the value cannot be calculated here.
+        */
        cprintf_f(5, 9, 2,
-                 S_VALUE(sip->dk_drive,      sic->dk_drive,      itv),
-                 S_VALUE(sip->dk_drive_rio,  sic->dk_drive_rio,  itv),
-                 S_VALUE(sip->dk_drive_wio,  sic->dk_drive_wio,  itv),
+                 sic->dk_drive < sip->dk_drive ? 0.0 :
+                 S_VALUE(sip->dk_drive, sic->dk_drive, itv),
+                 sic->dk_drive_rio < sip->dk_drive_rio ? 0.0 :
+                 S_VALUE(sip->dk_drive_rio, sic->dk_drive_rio, itv),
+                 sic->dk_drive_wio < sip->dk_drive_wio ? 0.0 :
+                 S_VALUE(sip->dk_drive_wio, sic->dk_drive_wio, itv),
+                 sic->dk_drive_rblk < sip->dk_drive_rblk ? 0.0 :
                  S_VALUE(sip->dk_drive_rblk, sic->dk_drive_rblk, itv),
+                 sic->dk_drive_wblk < sip->dk_drive_wblk ? 0.0 :
                  S_VALUE(sip->dk_drive_wblk, sic->dk_drive_wblk, itv));
        printf("\n");
 }
index a1ad42f91a29478270fb59d8dd960a2b440d0f05..f30b668631d2bc59cefd960f66872b1204ad9279 100644 (file)
@@ -683,33 +683,44 @@ __print_funct_t render_io_stats(struct activity *a, int isdb, char *pre,
        int pt_newlin
                = (DISPLAY_HORIZONTALLY(flags) ? PT_NOFLAG : PT_NEWLIN);
 
+       /*
+        * If we get negative values, this is probably because
+        * one or more devices/filesystems have been unmounted.
+        * We display 0.0 in this case though we should rather tell
+        * the user that the value cannot be calculated here.
+        */
        render(isdb, pre, PT_NOFLAG,
               "-\ttps", NULL, NULL,
               NOVAL,
+              sic->dk_drive < sip->dk_drive ? 0.0 :
               S_VALUE(sip->dk_drive, sic->dk_drive, itv),
               NULL);
 
        render(isdb, pre, PT_NOFLAG,
               "-\trtps", NULL, NULL,
               NOVAL,
+              sic->dk_drive_rio < sip->dk_drive_rio ? 0.0 :
               S_VALUE(sip->dk_drive_rio, sic->dk_drive_rio, itv),
               NULL);
 
        render(isdb, pre, PT_NOFLAG,
               "-\twtps", NULL, NULL,
               NOVAL,
+              sic->dk_drive_wio < sip->dk_drive_wio ? 0.0 :
               S_VALUE(sip->dk_drive_wio, sic->dk_drive_wio, itv),
               NULL);
 
        render(isdb, pre, PT_NOFLAG,
               "-\tbread/s", NULL, NULL,
               NOVAL,
+              sic->dk_drive_rblk < sip->dk_drive_rblk ? 0.0 :
               S_VALUE(sip->dk_drive_rblk, sic->dk_drive_rblk, itv),
               NULL);
 
        render(isdb, pre, pt_newlin,
               "-\tbwrtn/s", NULL, NULL,
               NOVAL,
+              sic->dk_drive_wblk < sip->dk_drive_wblk ? 0.0 :
               S_VALUE(sip->dk_drive_wblk, sic->dk_drive_wblk, itv),
               NULL);
 }
index c8f399bdad2964bd57333b6e364ca6b5a41c2b52..7b57c6de06f47ea9941920f195727022b492fcc1 100644 (file)
@@ -411,15 +411,26 @@ __print_funct_t xml_print_io_stats(struct activity *a, int curr, int tab,
 
        xprintf(tab, "<io per=\"second\">");
 
+       /*
+        * If we get negative values, this is probably because
+        * one or more devices/filesystems have been unmounted.
+        * We display 0.0 in this case though we should rather tell
+        * the user that the value cannot be calculated here.
+        */
        xprintf(++tab, "<tps>%.2f</tps>",
+               sic->dk_drive < sip->dk_drive ? 0.0 :
                S_VALUE(sip->dk_drive, sic->dk_drive, itv));
 
        xprintf(tab, "<io-reads rtps=\"%.2f\" bread=\"%.2f\"/>",
-               S_VALUE(sip->dk_drive_rio,  sic->dk_drive_rio,  itv),
+               sic->dk_drive_rio < sip->dk_drive_rio ? 0.0 :
+               S_VALUE(sip->dk_drive_rio, sic->dk_drive_rio, itv),
+               sic->dk_drive_rblk < sip->dk_drive_rblk ? 0.0 :
                S_VALUE(sip->dk_drive_rblk, sic->dk_drive_rblk, itv));
 
        xprintf(tab, "<io-writes wtps=\"%.2f\" bwrtn=\"%.2f\"/>",
-               S_VALUE(sip->dk_drive_wio,  sic->dk_drive_wio,  itv),
+               sic->dk_drive_wio < sip->dk_drive_wio ? 0.0 :
+               S_VALUE(sip->dk_drive_wio, sic->dk_drive_wio, itv),
+               sic->dk_drive_wblk < sip->dk_drive_wblk ? 0.0 :
                S_VALUE(sip->dk_drive_wblk, sic->dk_drive_wblk, itv));
 
        xprintf(--tab, "</io>");