From 5d3efa188a27fa3b515e5d447460cd446c189f53 Mon Sep 17 00:00:00 2001 From: Sebastien GODARD Date: Fri, 1 Jul 2016 15:30:34 +0200 Subject: [PATCH] Workaround for I/O and transfer rates statistics 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 --- json_stats.c | 15 +++++++++++++-- pr_stats.c | 17 ++++++++++++++--- rndr_stats.c | 11 +++++++++++ xml_stats.c | 15 +++++++++++++-- 4 files changed, 51 insertions(+), 7 deletions(-) diff --git a/json_stats.c b/json_stats.c index 9b4036c..f45254e 100644 --- a/json_stats.c +++ b/json_stats.c @@ -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)); } diff --git a/pr_stats.c b/pr_stats.c index 2aab2fc..96b51ea 100644 --- a/pr_stats.c +++ b/pr_stats.c @@ -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"); } diff --git a/rndr_stats.c b/rndr_stats.c index a1ad42f..f30b668 100644 --- a/rndr_stats.c +++ b/rndr_stats.c @@ -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); } diff --git a/xml_stats.c b/xml_stats.c index c8f399b..7b57c6d 100644 --- a/xml_stats.c +++ b/xml_stats.c @@ -411,15 +411,26 @@ __print_funct_t xml_print_io_stats(struct activity *a, int curr, int tab, xprintf(tab, ""); + /* + * 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, "%.2f", + sic->dk_drive < sip->dk_drive ? 0.0 : S_VALUE(sip->dk_drive, sic->dk_drive, itv)); xprintf(tab, "", - 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, "", - 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, ""); -- 2.49.0