Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-8]: src Pull up following revision(s) (requested by mlelstv in ti...



details:   https://anonhg.NetBSD.org/src/rev/241ab06b96d1
branches:  netbsd-8
changeset: 850866:241ab06b96d1
user:      snj <snj%NetBSD.org@localhost>
date:      Tue Jul 25 01:43:37 2017 +0000

description:
Pull up following revision(s) (requested by mlelstv in ticket #138):
        usr.bin/systat/iostat.c: revision 1.38
        usr.bin/systat/vmstat.c: revision 1.82
        usr.bin/vmstat/drvstats.c: revision 1.11
        usr.bin/vmstat/drvstats.h: revision 1.5
        usr.bin/vmstat/vmstat.c: revision 1.217
        usr.sbin/iostat/iostat.c: revision 1.65
Use I/O timestamps to compute disk statistics for better precision.
Disk statistics are collected in a fixed size array, that got corrupted
when a disk was detached. Adapt by skipping entries of detached disks
and detect reused disknames at the array end.
--
Use I/O timestamps to compute disk statistics for better precisison.

diffstat:

 usr.bin/systat/iostat.c   |  30 +++++++++------
 usr.bin/systat/vmstat.c   |  21 +++++++---
 usr.bin/vmstat/drvstats.c |  87 +++++++++++++++++++++++++++++++++++++---------
 usr.bin/vmstat/drvstats.h |   9 ++--
 usr.bin/vmstat/vmstat.c   |  13 ++++--
 usr.sbin/iostat/iostat.c  |  64 +++++++++++++++++++++++----------
 6 files changed, 159 insertions(+), 65 deletions(-)

diffs (truncated from 573 to 300 lines):

diff -r 2b1d52cfed9b -r 241ab06b96d1 usr.bin/systat/iostat.c
--- a/usr.bin/systat/iostat.c   Tue Jul 25 01:41:29 2017 +0000
+++ b/usr.bin/systat/iostat.c   Tue Jul 25 01:43:37 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: iostat.c,v 1.37 2009/04/13 23:20:27 lukem Exp $        */
+/*     $NetBSD: iostat.c,v 1.37.38.1 2017/07/25 01:43:37 snj Exp $     */
 
 /*
  * Copyright (c) 1980, 1992, 1993
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "@(#)iostat.c   8.1 (Berkeley) 6/6/93";
 #endif
-__RCSID("$NetBSD: iostat.c,v 1.37 2009/04/13 23:20:27 lukem Exp $");
+__RCSID("$NetBSD: iostat.c,v 1.37.38.1 2017/07/25 01:43:37 snj Exp $");
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -46,7 +46,7 @@
 #include "drvstats.h"
 
 static  int linesperregion;
-static  double etime;
+static double etime;
 static  int numbers = 0;               /* default display bar graphs */
 static  int secs = 0;                  /* default seconds shown */
 static  int read_write = 0;            /* default read/write shown */
@@ -252,9 +252,15 @@
 static int
 stats(int row, int col, int dn)
 {
-       double atime, rwords, wwords;
+       double atime, dtime, rwords, wwords;
        uint64_t rxfer;
 
+       /* elapsed time for disk stats */
+       dtime = etime;
+       if (cur.timestamp[dn].tv_sec || cur.timestamp[dn].tv_usec)
+               dtime = (double)cur.timestamp[dn].tv_sec +
+                       ((double)cur.timestamp[dn].tv_usec / (double)1000000);
+
        /* time busy in disk activity */
        atime = (double)cur.time[dn].tv_sec +
                ((double)cur.time[dn].tv_usec / (double)1000000);
@@ -269,30 +275,30 @@
        }
        if (numbers) {
                mvwprintw(wnd, row, col, "%5.0f%4.0f",
-                   rwords / etime, rxfer / etime);
+                   rwords / dtime, rxfer / dtime);
                if (secs)
-                       wprintw(wnd, "%5.1f", atime / etime);
+                       wprintw(wnd, "%5.1f", atime / dtime);
                if (read_write)
                        wprintw(wnd, " %5.0f%4.0f",
-                           wwords / etime, cur.wxfer[dn] / etime);
+                           wwords / dtime, cur.wxfer[dn] / dtime);
                return (row);
        }
 
        wmove(wnd, row++, col);
-       histogram(rwords / etime, 50, 0.5);
+       histogram(rwords / dtime, 50, 0.5);
        wmove(wnd, row++, col);
-       histogram(rxfer / etime, 50, 0.5);
+       histogram(rxfer / dtime, 50, 0.5);
        if (read_write) {
                wmove(wnd, row++, col);
-               histogram(wwords / etime, 50, 0.5);
+               histogram(wwords / dtime, 50, 0.5);
                wmove(wnd, row++, col);
-               histogram(cur.wxfer[dn] / etime, 50, 0.5);
+               histogram(cur.wxfer[dn] / dtime, 50, 0.5);
        }
 
        if (secs) {
                wmove(wnd, row++, col);
                atime *= 1000;  /* In milliseconds */
-               histogram(atime / etime, 50, 0.5);
+               histogram(atime / dtime, 50, 0.5);
        }
        return (row);
 }
diff -r 2b1d52cfed9b -r 241ab06b96d1 usr.bin/systat/vmstat.c
--- a/usr.bin/systat/vmstat.c   Tue Jul 25 01:41:29 2017 +0000
+++ b/usr.bin/systat/vmstat.c   Tue Jul 25 01:43:37 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: vmstat.c,v 1.81 2014/12/24 20:01:22 dennis Exp $       */
+/*     $NetBSD: vmstat.c,v 1.81.8.1 2017/07/25 01:43:37 snj Exp $      */
 
 /*-
  * Copyright (c) 1983, 1989, 1992, 1993
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "@(#)vmstat.c   8.2 (Berkeley) 1/12/94";
 #endif
-__RCSID("$NetBSD: vmstat.c,v 1.81 2014/12/24 20:01:22 dennis Exp $");
+__RCSID("$NetBSD: vmstat.c,v 1.81.8.1 2017/07/25 01:43:37 snj Exp $");
 #endif /* not lint */
 
 /*
@@ -827,24 +827,31 @@
 static void
 dinfo(int dn, int r, int c)
 {
-       double atime;
+       double atime, dtime;
 #define ADV if (disk_horiz) r++; else c += DISKCOLWIDTH
 
+       /* elapsed time for disk stats */
+       dtime = etime;
+       if (cur.timestamp[dn].tv_sec || cur.timestamp[dn].tv_usec) {
+               dtime = (double)cur.timestamp[dn].tv_sec +
+                       ((double)cur.timestamp[dn].tv_usec / (double)1000000);
+       }
+
        mvprintw(r, c, "%*.*s", DISKCOLWIDTH, DISKCOLWIDTH, dr_name[dn]);
        ADV;
 
-       putint((int)(cur.seek[dn]/etime+0.5), r, c, DISKCOLWIDTH);
+       putint((int)(cur.seek[dn]/dtime+0.5), r, c, DISKCOLWIDTH);
        ADV;
-       putint((int)((cur.rxfer[dn]+cur.wxfer[dn])/etime+0.5),
+       putint((int)((cur.rxfer[dn]+cur.wxfer[dn])/dtime+0.5),
            r, c, DISKCOLWIDTH);
        ADV;
-       puthumanint((cur.rbytes[dn] + cur.wbytes[dn]) / etime + 0.5,
+       puthumanint((cur.rbytes[dn] + cur.wbytes[dn]) / dtime + 0.5,
                    r, c, DISKCOLWIDTH);
        ADV;
 
        /* time busy in disk activity */
        atime = cur.time[dn].tv_sec + cur.time[dn].tv_usec / 1000000.0;
-       atime = atime * 100.0 / etime;
+       atime = atime * 100.0 / dtime;
        if (atime >= 100)
                putint(100, r, c, DISKCOLWIDTH);
        else
diff -r 2b1d52cfed9b -r 241ab06b96d1 usr.bin/vmstat/drvstats.c
--- a/usr.bin/vmstat/drvstats.c Tue Jul 25 01:41:29 2017 +0000
+++ b/usr.bin/vmstat/drvstats.c Tue Jul 25 01:43:37 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: drvstats.c,v 1.10 2017/03/05 23:07:12 mlelstv Exp $    */
+/*     $NetBSD: drvstats.c,v 1.10.4.1 2017/07/25 01:43:37 snj Exp $    */
 
 /*
  * Copyright (c) 1996 John M. Vinopal
@@ -97,6 +97,31 @@
                if (!cur.select[i])
                        continue;
 
+               /*
+                * When a drive is replaced with one of the same
+                * name, the previous statistics are invalid. Try
+                * to detect this by validating counters and timestamp
+                */
+               if ((cur.rxfer[i] == 0 && cur.wxfer[i] == 0)
+                   || cur.rxfer[i] - last.rxfer[i] > INT64_MAX
+                   || cur.wxfer[i] - last.wxfer[i] > INT64_MAX
+                   || cur.seek[i] - last.seek[i] > INT64_MAX
+                   || (cur.timestamp[i].tv_sec == 0 &&
+                       cur.timestamp[i].tv_usec == 0)) {
+
+                       last.rxfer[i] = cur.rxfer[i];
+                       last.wxfer[i] = cur.wxfer[i];
+                       last.seek[i] = cur.seek[i];
+                       last.rbytes[i] = cur.rbytes[i];
+                       last.wbytes[i] = cur.wbytes[i];
+
+                       timerclear(&last.wait[i]);
+                       timerclear(&last.time[i]);
+                       timerclear(&last.waitsum[i]);
+                       timerclear(&last.busysum[i]);
+                       timerclear(&last.timestamp[i]);
+               }
+
                /* Delta Values. */
                SWAP(rxfer[i]);
                SWAP(wxfer[i]);
@@ -108,6 +133,7 @@
                DELTA(time[i]);
                DELTA(waitsum[i]);
                DELTA(busysum[i]);
+               DELTA(timestamp[i]);
        }
 }
 
@@ -151,7 +177,7 @@
 void
 drvreadstats(void)
 {
-       size_t          size, i;
+       size_t          size, i, j, count;
        int             mib[3];
 
        mib[0] = CTL_HW;
@@ -161,27 +187,46 @@
        size = ndrive * sizeof(struct io_sysctl);
        if (sysctl(mib, 3, drives, &size, NULL, 0) < 0)
                err(1, "sysctl hw.iostats failed");
+       /* recalculate array length */
+       count = size / sizeof(struct io_sysctl);
 
-#define COPYF(x,k) cur.x[k] = drives[k].x
-#define COPYT(x,k) do {                                                        \
-               cur.x[k].tv_sec = drives[k].x##_sec;                    \
-               cur.x[k].tv_usec = drives[k].x##_usec;                  \
+#define COPYF(x,k,l) cur.x[k] = drives[l].x
+#define COPYT(x,k,l) do {                                              \
+               cur.x[k].tv_sec = drives[l].x##_sec;                    \
+               cur.x[k].tv_usec = drives[l].x##_usec;                  \
 } while (/* CONSTCOND */0)
 
-       for (i = 0; i < ndrive; i++) {
+       for (i = 0, j = 0; i < ndrive && j < count; i++) {
+
+               /*
+                * skip removed entries
+                *
+                * we cannot detect entries replaced with
+                * devices of the same name (e.g. unplug/replug).
+                */
+               if (strcmp(cur.name[i], drives[j].name)) {
+                       cur.select[i] = 0;
+                       continue;
+               }
 
-               COPYF(rxfer, i);
-               COPYF(wxfer, i);
-               COPYF(seek, i);
-               COPYF(rbytes, i);
-               COPYF(wbytes, i);
+               COPYF(rxfer, i, j);
+               COPYF(wxfer, i, j);
+               COPYF(seek, i, j);
+               COPYF(rbytes, i, j);
+               COPYF(wbytes, i, j);
 
-               COPYT(wait, i);
-               COPYT(time, i);
-               COPYT(waitsum, i);
-               COPYT(busysum, i);
+               COPYT(wait, i, j);
+               COPYT(time, i, j);
+               COPYT(waitsum, i, j);
+               COPYT(busysum, i, j);
+               COPYT(timestamp, i, j);
+
+               ++j;
        }
 
+       /* shrink table to new size */
+       ndrive = j;
+
        mib[0] = CTL_KERN;
        mib[1] = KERN_TKSTAT;
        mib[2] = KERN_TKSTAT_NIN;
@@ -295,6 +340,7 @@
        cur.wait = calloc(ndrive, sizeof(struct timeval));
        cur.waitsum = calloc(ndrive, sizeof(struct timeval));
        cur.busysum = calloc(ndrive, sizeof(struct timeval));
+       cur.timestamp = calloc(ndrive, sizeof(struct timeval));
        cur.rxfer = calloc(ndrive, sizeof(u_int64_t));
        cur.wxfer = calloc(ndrive, sizeof(u_int64_t));
        cur.seek = calloc(ndrive, sizeof(u_int64_t));
@@ -304,6 +350,7 @@
        last.wait = calloc(ndrive, sizeof(struct timeval));
        last.waitsum = calloc(ndrive, sizeof(struct timeval));
        last.busysum = calloc(ndrive, sizeof(struct timeval));
+       last.timestamp = calloc(ndrive, sizeof(struct timeval));
        last.rxfer = calloc(ndrive, sizeof(u_int64_t));
        last.wxfer = calloc(ndrive, sizeof(u_int64_t));
        last.seek = calloc(ndrive, sizeof(u_int64_t));
@@ -314,11 +361,13 @@
 
        if (cur.time == NULL || cur.wait == NULL ||
            cur.waitsum == NULL || cur.busysum == NULL ||
+           cur.timestamp == NULL ||
            cur.rxfer == NULL || cur.wxfer == NULL ||
            cur.seek == NULL || cur.rbytes == NULL ||
            cur.wbytes == NULL ||
            last.time == NULL || last.wait == NULL ||
            last.waitsum == NULL || last.busysum == NULL ||
+           last.timestamp == NULL ||
            last.rxfer == NULL || last.wxfer == NULL ||
            last.seek == NULL || last.rbytes == NULL ||
            last.wbytes == NULL ||
@@ -335,8 +384,12 @@
        mib[2] = sizeof(struct io_sysctl);
        if (sysctl(mib, 3, drives, &size, NULL, 0) == -1)
                err(1, "sysctl hw.iostats failed");
+       /* Recalculate array length */
+       ndrive = size / sizeof(struct io_sysctl);
        for (i = 0; i < ndrive; i++) {
-               cur.name[i] = drives[i].name;
+               cur.name[i] = strndup(drives[i].name, sizeof(drives[i].name));
+               if (cur.name[i] == NULL)
+                       errx(1, "Memory allocation failure");
                cur.select[i] = selected;
        }



Home | Main Index | Thread Index | Old Index