aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/systat/Makefile4
-rw-r--r--usr.bin/systat/devs.c126
-rw-r--r--usr.bin/systat/devs.h16
-rw-r--r--usr.bin/systat/extern.h7
-rw-r--r--usr.bin/systat/fetch.c9
-rw-r--r--usr.bin/systat/icmp6.c9
-rw-r--r--usr.bin/systat/ifcmds.c2
-rw-r--r--usr.bin/systat/ifstat.c118
-rw-r--r--usr.bin/systat/iostat.c46
-rw-r--r--usr.bin/systat/ip.c7
-rw-r--r--usr.bin/systat/ip6.c7
-rw-r--r--usr.bin/systat/main.c13
-rw-r--r--usr.bin/systat/swap.c17
-rw-r--r--usr.bin/systat/sysput.c118
-rw-r--r--usr.bin/systat/systat.11
-rw-r--r--usr.bin/systat/systat.h4
-rw-r--r--usr.bin/systat/tcp.c3
-rw-r--r--usr.bin/systat/vmstat.c221
-rw-r--r--usr.bin/systat/zarc.c124
19 files changed, 548 insertions, 304 deletions
diff --git a/usr.bin/systat/Makefile b/usr.bin/systat/Makefile
index f0de9fbaeecf..ca3f7ed72ce4 100644
--- a/usr.bin/systat/Makefile
+++ b/usr.bin/systat/Makefile
@@ -4,7 +4,7 @@
.include <src.opts.mk>
PROG= systat
-SRCS= cmds.c cmdtab.c devs.c fetch.c iostat.c keyboard.c main.c \
+SRCS= cmds.c cmdtab.c devs.c fetch.c iostat.c keyboard.c main.c sysput.c \
netcmds.c netstat.c pigs.c swap.c icmp.c \
mode.c ip.c sctp.c tcp.c zarc.c \
vmstat.c convtbl.c ifcmds.c ifstat.c
@@ -16,6 +16,6 @@ CFLAGS+= -DINET6
WARNS?= 1
-LIBADD= ncursesw m devstat kvm
+LIBADD= ncursesw m devstat kvm util
.include <bsd.prog.mk>
diff --git a/usr.bin/systat/devs.c b/usr.bin/systat/devs.c
index 3c74fb7690e3..6c0461fd531f 100644
--- a/usr.bin/systat/devs.c
+++ b/usr.bin/systat/devs.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 1998 Kenneth D. Merry.
+ * 2015 Yoshihiro Ota
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -67,7 +68,6 @@ static const char sccsid[] = "@(#)disks.c 8.1 (Berkeley) 6/6/93";
#include <sys/resource.h>
#include <ctype.h>
-#include <devstat.h>
#include <err.h>
#include <stdlib.h>
#include <string.h>
@@ -82,6 +82,8 @@ typedef enum {
DS_MATCHTYPE_PATTERN
} last_match_type;
+struct statinfo cur_dev, last_dev, run_dev;
+
last_match_type last_type;
struct device_selection *dev_select;
long generation;
@@ -99,10 +101,8 @@ static int dsselect(const char *args, devstat_select_mode select_mode,
int maxshowdevs, struct statinfo *s1);
int
-dsinit(int maxshowdevs, struct statinfo *s1, struct statinfo *s2 __unused,
- struct statinfo *s3 __unused)
+dsinit(int maxshowdevs)
{
-
/*
* Make sure that the userland devstat version matches the kernel
* devstat version. If not, exit and print a message informing
@@ -111,6 +111,18 @@ dsinit(int maxshowdevs, struct statinfo *s1, struct statinfo *s2 __unused,
if (devstat_checkversion(NULL) < 0)
errx(1, "%s", devstat_errbuf);
+ if( cur_dev.dinfo ) // init was alreay ran
+ return(1);
+
+ if ((num_devices = devstat_getnumdevs(NULL)) < 0) {
+ warnx("%s", devstat_errbuf);
+ return(0);
+ }
+
+ cur_dev.dinfo = calloc(1, sizeof(struct devinfo));
+ last_dev.dinfo = calloc(1, sizeof(struct devinfo));
+ run_dev.dinfo = calloc(1, sizeof(struct devinfo));
+
generation = 0;
num_devices = 0;
num_selected = 0;
@@ -118,11 +130,11 @@ dsinit(int maxshowdevs, struct statinfo *s1, struct statinfo *s2 __unused,
select_generation = 0;
last_type = DS_MATCHTYPE_NONE;
- if (devstat_getdevs(NULL, s1) == -1)
+ if (devstat_getdevs(NULL, &cur_dev) == -1)
errx(1, "%s", devstat_errbuf);
- num_devices = s1->dinfo->numdevs;
- generation = s1->dinfo->generation;
+ num_devices = cur_dev.dinfo->numdevs;
+ generation = cur_dev.dinfo->generation;
dev_select = NULL;
@@ -132,13 +144,31 @@ dsinit(int maxshowdevs, struct statinfo *s1, struct statinfo *s2 __unused,
* or 1. If we get back -1, though, there is an error.
*/
if (devstat_selectdevs(&dev_select, &num_selected, &num_selections,
- &select_generation, generation, s1->dinfo->devices, num_devices,
+ &select_generation, generation, cur_dev.dinfo->devices, num_devices,
NULL, 0, NULL, 0, DS_SELECT_ADD, maxshowdevs, 0) == -1)
errx(1, "%d %s", __LINE__, devstat_errbuf);
return(1);
}
+
+void
+dsgetinfo(struct statinfo* dev)
+{
+ switch (devstat_getdevs(NULL, dev)) {
+ case -1:
+ errx(1, "%s", devstat_errbuf);
+ break;
+ case 1:
+ num_devices = dev->dinfo->numdevs;
+ generation = dev->dinfo->generation;
+ cmdkre("refresh", NULL);
+ break;
+ default:
+ break;
+ }
+}
+
int
dscmd(const char *cmd, const char *args, int maxshowdevs, struct statinfo *s1)
{
@@ -319,3 +349,83 @@ dsselect(const char *args, devstat_select_mode select_mode, int maxshowdevs,
}
return(1);
}
+
+
+void
+dslabel(int maxdrives, int diskcol, int diskrow)
+{
+ int i, j;
+
+ mvprintw(diskrow, diskcol, "Disks");
+ mvprintw(diskrow + 1, diskcol, "KB/t");
+ mvprintw(diskrow + 2, diskcol, "tps");
+ mvprintw(diskrow + 3, diskcol, "MB/s");
+ mvprintw(diskrow + 4, diskcol, "%%busy");
+ /*
+ * For now, we don't support a fourth disk statistic. So there's
+ * no point in providing a label for it. If someone can think of a
+ * fourth useful disk statistic, there is room to add it.
+ */
+ /* mvprintw(diskrow + 4, diskcol, " msps"); */
+ j = 0;
+ for (i = 0; i < num_devices && j < maxdrives; i++)
+ if (dev_select[i].selected) {
+ char tmpstr[80];
+ sprintf(tmpstr, "%s%d", dev_select[i].device_name,
+ dev_select[i].unit_number);
+ mvprintw(diskrow, diskcol + 5 + 6 * j,
+ " %5.5s", tmpstr);
+ j++;
+ }
+}
+
+static void
+dsshow2(int diskcol, int diskrow, int dn, int lc, struct statinfo *now, struct statinfo *then)
+{
+ long double transfers_per_second;
+ long double kb_per_transfer, mb_per_second;
+ long double elapsed_time, device_busy;
+ int di;
+
+ di = dev_select[dn].position;
+
+ if (then != NULL) {
+ /* Calculate relative to previous sample */
+ elapsed_time = now->snap_time - then->snap_time;
+ } else {
+ /* Calculate relative to device creation */
+ elapsed_time = now->snap_time - devstat_compute_etime(
+ &now->dinfo->devices[di].creation_time, NULL);
+ }
+
+ if (devstat_compute_statistics(&now->dinfo->devices[di], then ?
+ &then->dinfo->devices[di] : NULL, elapsed_time,
+ DSM_KB_PER_TRANSFER, &kb_per_transfer,
+ DSM_TRANSFERS_PER_SECOND, &transfers_per_second,
+ DSM_MB_PER_SECOND, &mb_per_second,
+ DSM_BUSY_PCT, &device_busy,
+ DSM_NONE) != 0)
+ errx(1, "%s", devstat_errbuf);
+
+ lc = diskcol + lc * 6;
+ putlongdouble(kb_per_transfer, diskrow + 1, lc, 5, 2, 0);
+ putlongdouble(transfers_per_second, diskrow + 2, lc, 5, 0, 0);
+ putlongdouble(mb_per_second, diskrow + 3, lc, 5, 2, 0);
+ putlongdouble(device_busy, diskrow + 4, lc, 5, 0, 0);
+}
+
+static void
+dsshow3(int diskcol, int diskrow, int dn, int lc, struct statinfo *now, struct statinfo *then)
+{
+ dsshow2(diskcol, diskrow, dn, lc, now, then);
+}
+
+void
+dsshow(int maxdrives, int diskcol, int diskrow, struct statinfo *now, struct statinfo *then)
+{
+ int i, lc;
+
+ for (i = 0, lc = 0; i < num_devices && lc < maxdrives; i++)
+ if (dev_select[i].selected)
+ dsshow3(diskcol, diskrow, i, ++lc, now, then);
+}
diff --git a/usr.bin/systat/devs.h b/usr.bin/systat/devs.h
index b25cc962bb21..cbedd844290e 100644
--- a/usr.bin/systat/devs.h
+++ b/usr.bin/systat/devs.h
@@ -2,6 +2,7 @@
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 1998 David E. O'Brien
+ * 2015 Yoshihiro Ota
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,5 +29,18 @@
* $FreeBSD$
*/
-int dsinit(int, struct statinfo *, struct statinfo *, struct statinfo *);
+#ifndef DEVS_H
+#define DEVS_H
+
+#include <devstat.h>
+
+int dsinit(int);
+void dsgetinfo(struct statinfo *);
int dscmd(const char *, const char *, int, struct statinfo *);
+
+void dslabel(int, int, int);
+void dsshow(int, int, int, struct statinfo *, struct statinfo *);
+
+extern struct statinfo cur_dev, last_dev, run_dev;
+
+#endif
diff --git a/usr.bin/systat/extern.h b/usr.bin/systat/extern.h
index 272eead74c01..c36255e531b4 100644
--- a/usr.bin/systat/extern.h
+++ b/usr.bin/systat/extern.h
@@ -163,6 +163,11 @@ void showtcp(void);
void status(void);
void suspend(int);
char *sysctl_dynread(const char *, size_t *);
+void sysputpage(WINDOW* , int, int, int, uint64_t, int);
+void sysputspaces(WINDOW* , int, int, int);
+void sysputstrs(WINDOW* , int, int, int);
+void sysputuint64(WINDOW* , int, int, int, uint64_t, int);
+void sysputwuint64(WINDOW* , int, int, int, uint64_t, int);
#define SYSTAT_CMD(name) \
void close ## name(WINDOW *); \
@@ -174,4 +179,4 @@ char *sysctl_dynread(const char *, size_t *);
void show ## name(void)
SYSTAT_CMD( zarc );
-SYSTAT_CMD ( sctp );
+SYSTAT_CMD( sctp );
diff --git a/usr.bin/systat/fetch.c b/usr.bin/systat/fetch.c
index d159e51c1e79..4cd9af64b43d 100644
--- a/usr.bin/systat/fetch.c
+++ b/usr.bin/systat/fetch.c
@@ -58,17 +58,18 @@ kvm_ckread(void *a, void *b, int l)
return (1);
}
-void getsysctl(const char *name, void *ptr, size_t len)
+void
+getsysctl(const char *name, void *ptr, size_t len)
{
size_t nlen = len;
+
if (sysctlbyname(name, ptr, &nlen, NULL, 0) != 0) {
error("sysctl(%s...) failed: %s", name,
strerror(errno));
}
if (nlen != len) {
- error("sysctl(%s...) expected %lu, got %lu", name,
- (unsigned long)len, (unsigned long)nlen);
- }
+ error("sysctl(%s...) expected %zu, got %zu", name, len, nlen);
+ }
}
/*
diff --git a/usr.bin/systat/icmp6.c b/usr.bin/systat/icmp6.c
index 2a3bbb70289c..4260179b5689 100644
--- a/usr.bin/systat/icmp6.c
+++ b/usr.bin/systat/icmp6.c
@@ -48,6 +48,7 @@ static char sccsid[] = "@(#)mbufs.c 8.1 (Berkeley) 6/6/93";
#include <netinet/in.h>
#include <netinet/icmp6.h>
+#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <paths.h>
@@ -171,7 +172,7 @@ void
showicmp6(void)
{
struct icmp6stat stats;
- u_long totalin, totalout;
+ uint64_t totalin, totalout;
int i;
memset(&stats, 0, sizeof stats);
@@ -182,11 +183,11 @@ showicmp6(void)
}
totalin += stats.icp6s_badcode + stats.icp6s_badlen +
stats.icp6s_checksum + stats.icp6s_tooshort;
- mvwprintw(wnd, 1, 0, "%9lu", totalin);
- mvwprintw(wnd, 1, 35, "%9lu", totalout);
+ mvwprintw(wnd, 1, 0, "%9"PRIu64, totalin);
+ mvwprintw(wnd, 1, 35, "%9"PRIu64, totalout);
#define DO(stat, row, col) \
- mvwprintw(wnd, row, col, "%9lu", stats.stat)
+ mvwprintw(wnd, row, col, "%9"PRIu64, stats.stat)
DO(icp6s_badcode, 2, 0);
DO(icp6s_badlen, 3, 0);
diff --git a/usr.bin/systat/ifcmds.c b/usr.bin/systat/ifcmds.c
index f5091603d0e9..5336075f7472 100644
--- a/usr.bin/systat/ifcmds.c
+++ b/usr.bin/systat/ifcmds.c
@@ -74,6 +74,8 @@ ifcmd(const char *cmd, const char *args)
}
} else if (prefix(cmd, "pps"))
showpps = !showpps;
+ else
+ return (0);
return (1);
}
diff --git a/usr.bin/systat/ifstat.c b/usr.bin/systat/ifstat.c
index 4c174c0b89e1..37ea81ba558c 100644
--- a/usr.bin/systat/ifstat.c
+++ b/usr.bin/systat/ifstat.c
@@ -36,6 +36,7 @@
#include <net/if.h>
#include <net/if_mib.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <err.h>
@@ -66,7 +67,8 @@ SLIST_HEAD(, if_stat_disp) displist;
struct if_stat {
SLIST_ENTRY(if_stat) link;
- char if_name[IF_NAMESIZE];
+ char display_name[IF_NAMESIZE];
+ char dev_name[IFNAMSIZ]; /* copied from ifmibdata */
struct ifmibdata if_mib;
struct timeval tv;
struct timeval tv_lastchanged;
@@ -80,7 +82,7 @@ struct if_stat {
uint64_t if_out_pps_peak;
u_int if_row; /* Index into ifmib sysctl */
int if_ypos; /* -1 if not being displayed */
- u_int display;
+ bool display;
u_int match;
};
@@ -90,11 +92,13 @@ extern int showpps;
extern int needsort;
static int needclear = 0;
+static bool displayall = false;
-static void right_align_string(struct if_stat *);
-static void getifmibdata(const int, struct ifmibdata *);
+static void format_device_name(struct if_stat *);
+static int getifmibdata(const int, struct ifmibdata *);
static void sort_interface_list(void);
static u_int getifnum(void);
+static void clearifstat(void);
#define IFSTAT_ERR(n, s) do { \
putchar('\014'); \
@@ -164,7 +168,7 @@ static u_int getifnum(void);
} while (0)
#define PUTNAME(p) do { \
- mvprintw(p->if_ypos, 0, "%s", p->if_name); \
+ mvprintw(p->if_ypos, 0, "%s", p->display_name); \
mvprintw(p->if_ypos, col2-3, "%s", (const char *)"in"); \
mvprintw(p->if_ypos+1, col2-3, "%s", (const char *)"out"); \
} while (0)
@@ -213,7 +217,7 @@ showifstat(void)
SLIST_FOREACH(ifp, &curlist, link) {
if (ifp->if_ypos < LINES - 3 && ifp->if_ypos != -1)
- if (ifp->display == 0 || ifp->match == 0) {
+ if (!ifp->display || ifp->match == 0) {
wmove(wnd, ifp->if_ypos, 0);
wclrtoeol(wnd);
wmove(wnd, ifp->if_ypos + 1, 0);
@@ -234,7 +238,7 @@ int
initifstat(void)
{
struct if_stat *p = NULL;
- u_int n = 0, i = 0;
+ u_int n, i;
n = getifnum();
if (n <= 0)
@@ -246,18 +250,21 @@ initifstat(void)
p = (struct if_stat *)calloc(1, sizeof(struct if_stat));
if (p == NULL)
IFSTAT_ERR(1, "out of memory");
- SLIST_INSERT_HEAD(&curlist, p, link);
p->if_row = i+1;
- getifmibdata(p->if_row, &p->if_mib);
- right_align_string(p);
+ if (getifmibdata(p->if_row, &p->if_mib) == -1) {
+ free(p);
+ continue;
+ }
+ SLIST_INSERT_HEAD(&curlist, p, link);
+ format_device_name(p);
p->match = 1;
/*
* Initially, we only display interfaces that have
- * received some traffic.
+ * received some traffic unless display-all is on.
*/
- if (p->if_mib.ifmd_data.ifi_ibytes != 0)
- p->display = 1;
+ if (displayall || p->if_mib.ifmd_data.ifi_ibytes != 0)
+ p->display = true;
}
sort_interface_list();
@@ -268,13 +275,13 @@ initifstat(void)
void
fetchifstat(void)
{
- struct if_stat *ifp = NULL;
+ struct if_stat *ifp = NULL, *temp_var;
struct timeval tv, new_tv, old_tv;
double elapsed = 0.0;
uint64_t new_inb, new_outb, old_inb, old_outb = 0;
uint64_t new_inp, new_outp, old_inp, old_outp = 0;
- SLIST_FOREACH(ifp, &curlist, link) {
+ SLIST_FOREACH_SAFE(ifp, &curlist, link, temp_var) {
/*
* Grab a copy of the old input/output values before we
* call getifmibdata().
@@ -286,7 +293,22 @@ fetchifstat(void)
ifp->tv_lastchanged = ifp->if_mib.ifmd_data.ifi_lastchange;
(void)gettimeofday(&new_tv, NULL);
- (void)getifmibdata(ifp->if_row, &ifp->if_mib);
+ if (getifmibdata(ifp->if_row, &ifp->if_mib) == -1 ) {
+ /* if a device was removed */
+ SLIST_REMOVE(&curlist, ifp, if_stat, link);
+ free(ifp);
+ needsort = 1;
+ clearifstat();
+ } else if (strcmp(ifp->dev_name, ifp->if_mib.ifmd_name) != 0 ) {
+ /* a device was removed and another one was added */
+ format_device_name(ifp);
+ /* clear to the current value for the new device */
+ old_inb = ifp->if_mib.ifmd_data.ifi_ibytes;
+ old_outb = ifp->if_mib.ifmd_data.ifi_obytes;
+ old_inp = ifp->if_mib.ifmd_data.ifi_ipackets;
+ old_outp = ifp->if_mib.ifmd_data.ifi_opackets;
+ needsort = 1;
+ }
new_inb = ifp->if_mib.ifmd_data.ifi_ibytes;
new_outb = ifp->if_mib.ifmd_data.ifi_obytes;
@@ -294,8 +316,8 @@ fetchifstat(void)
new_outp = ifp->if_mib.ifmd_data.ifi_opackets;
/* Display interface if it's received some traffic. */
- if (new_inb > 0 && old_inb == 0) {
- ifp->display = 1;
+ if (!ifp->display && new_inb > 0 && old_inb == 0) {
+ ifp->display = true;
needsort = 1;
}
@@ -350,28 +372,18 @@ fetchifstat(void)
/*
* We want to right justify our interface names against the first column
* (first sixteen or so characters), so we need to do some alignment.
+ * We save original name so that we can find a same spot is take by a
+ * different device.
*/
static void
-right_align_string(struct if_stat *ifp)
+format_device_name(struct if_stat *ifp)
{
- int str_len = 0, pad_len = 0;
- char *newstr = NULL, *ptr = NULL;
-
- if (ifp == NULL || ifp->if_mib.ifmd_name == NULL)
- return;
- else {
- /* string length + '\0' */
- str_len = strlen(ifp->if_mib.ifmd_name)+1;
- pad_len = IF_NAMESIZE-(str_len);
-
- newstr = ifp->if_name;
- ptr = newstr + pad_len;
- (void)memset((void *)newstr, (int)' ', IF_NAMESIZE);
- (void)strncpy(ptr, (const char *)&ifp->if_mib.ifmd_name,
- str_len);
- }
- return;
+ if (ifp != NULL ) {
+ snprintf(ifp->display_name, IF_NAMESIZE, "%*s", IF_NAMESIZE-1,
+ ifp->if_mib.ifmd_name);
+ strcpy(ifp->dev_name, ifp->if_mib.ifmd_name);
+ }
}
static int
@@ -460,9 +472,10 @@ getifnum(void)
return (data);
}
-static void
+static int
getifmibdata(int row, struct ifmibdata *data)
{
+ int ret = 0;
size_t datalen = 0;
static int name[] = { CTL_NET,
PF_LINK,
@@ -473,9 +486,12 @@ getifmibdata(int row, struct ifmibdata *data)
datalen = sizeof(*data);
name[4] = row;
- if ((sysctl(name, 6, (void *)data, (size_t *)&datalen, (void *)NULL,
- (size_t)0) != 0) && (errno != ENOENT))
+ ret = sysctl(name, 6, (void *)data, (size_t *)&datalen, (void *)NULL,
+ (size_t)0);
+ if ((ret != 0) && (errno != ENOENT))
IFSTAT_ERR(2, "sysctl error getting interface data");
+
+ return (ret);
}
int
@@ -486,13 +502,23 @@ cmdifstat(const char *cmd, const char *args)
retval = ifcmd(cmd, args);
/* ifcmd() returns 1 on success */
if (retval == 1) {
- if (needclear) {
- showifstat();
- refresh();
- werase(wnd);
- labelifstat();
- needclear = 0;
- }
+ if (needclear)
+ clearifstat();
+ }
+ else if (prefix(cmd, "all")) {
+ retval = 1;
+ displayall = true;
}
return (retval);
}
+
+static void
+clearifstat(void)
+{
+
+ showifstat();
+ refresh();
+ werase(wnd);
+ labelifstat();
+ needclear = 0;
+}
diff --git a/usr.bin/systat/iostat.c b/usr.bin/systat/iostat.c
index fa275ebbbf2a..28cc40b9c760 100644
--- a/usr.bin/systat/iostat.c
+++ b/usr.bin/systat/iostat.c
@@ -77,8 +77,6 @@ static const char sccsid[] = "@(#)iostat.c 8.1 (Berkeley) 6/6/93";
#include "extern.h"
#include "devs.h"
-struct statinfo cur, last;
-
static int linesperregion;
static double etime;
static int numbers = 0; /* default display bar graphs */
@@ -109,17 +107,11 @@ closeiostat(WINDOW *w)
int
initiostat(void)
{
- if ((num_devices = devstat_getnumdevs(NULL)) < 0)
- return(0);
-
- cur.dinfo = calloc(1, sizeof(struct devinfo));
- last.dinfo = calloc(1, sizeof(struct devinfo));
-
/*
* This value for maxshowdevs (100) is bogus. I'm not sure exactly
* how to calculate it, though.
*/
- if (dsinit(100, &cur, &last, NULL) != 1)
+ if (dsinit(7) != 1)
return(0);
return(1);
@@ -131,17 +123,17 @@ fetchiostat(void)
struct devinfo *tmp_dinfo;
size_t len;
- len = sizeof(cur.cp_time);
- if (sysctlbyname("kern.cp_time", &cur.cp_time, &len, NULL, 0)
- || len != sizeof(cur.cp_time)) {
+ len = sizeof(cur_dev.cp_time);
+ if (sysctlbyname("kern.cp_time", &cur_dev.cp_time, &len, NULL, 0)
+ || len != sizeof(cur_dev.cp_time)) {
perror("kern.cp_time");
exit (1);
}
- tmp_dinfo = last.dinfo;
- last.dinfo = cur.dinfo;
- cur.dinfo = tmp_dinfo;
+ tmp_dinfo = last_dev.dinfo;
+ last_dev.dinfo = cur_dev.dinfo;
+ cur_dev.dinfo = tmp_dinfo;
- last.snap_time = cur.snap_time;
+ last_dev.snap_time = cur_dev.snap_time;
/*
* Here what we want to do is refresh our device stats.
@@ -150,7 +142,7 @@ fetchiostat(void)
* the selection process again, in case a device that we
* were previously displaying has gone away.
*/
- switch (devstat_getdevs(NULL, &cur)) {
+ switch (devstat_getdevs(NULL, &cur_dev)) {
case -1:
errx(1, "%s", devstat_errbuf);
break;
@@ -160,8 +152,8 @@ fetchiostat(void)
default:
break;
}
- num_devices = cur.dinfo->numdevs;
- generation = cur.dinfo->generation;
+ num_devices = cur_dev.dinfo->numdevs;
+ generation = cur_dev.dinfo->generation;
}
@@ -258,11 +250,11 @@ showiostat(void)
long t;
int i, row, _col;
-#define X(fld) t = cur.fld[i]; cur.fld[i] -= last.fld[i]; last.fld[i] = t
+#define X(fld) t = cur_dev.fld[i]; cur_dev.fld[i] -= last_dev.fld[i]; last_dev.fld[i] = t
etime = 0;
for(i = 0; i < CPUSTATES; i++) {
X(cp_time);
- etime += cur.cp_time[i];
+ etime += cur_dev.cp_time[i];
}
if (etime == 0.0)
etime = 1.0;
@@ -311,10 +303,10 @@ devstats(int row, int _col, int dn)
di = dev_select[dn].position;
- busy_seconds = cur.snap_time - last.snap_time;
+ busy_seconds = cur_dev.snap_time - last_dev.snap_time;
- if (devstat_compute_statistics(&cur.dinfo->devices[di],
- &last.dinfo->devices[di], busy_seconds,
+ if (devstat_compute_statistics(&cur_dev.dinfo->devices[di],
+ &last_dev.dinfo->devices[di], busy_seconds,
DSM_KB_PER_TRANSFER, &kb_per_transfer,
DSM_TRANSFERS_PER_SECOND, &transfers_per_second,
DSM_MB_PER_SECOND, &mb_per_second, DSM_NONE) != 0)
@@ -347,12 +339,12 @@ stat1(int row, int o)
dtime = 0.0;
for (i = 0; i < CPUSTATES; i++)
- dtime += cur.cp_time[i];
+ dtime += cur_dev.cp_time[i];
if (dtime == 0.0)
dtime = 1.0;
wmove(wnd, row, INSET);
#define CPUSCALE 0.5
- histogram(100.0 * cur.cp_time[o] / dtime, 50, CPUSCALE);
+ histogram(100.0 * cur_dev.cp_time[o] / dtime, 50, CPUSCALE);
}
static void
@@ -386,7 +378,7 @@ cmdiostat(const char *cmd, const char *args)
numbers = 1;
else if (prefix(cmd, "bars"))
numbers = 0;
- else if (!dscmd(cmd, args, 100, &cur))
+ else if (!dscmd(cmd, args, 100, &cur_dev))
return (0);
wclear(wnd);
labeliostat();
diff --git a/usr.bin/systat/ip.c b/usr.bin/systat/ip.c
index 8e12a6a0b0b8..471ae2648133 100644
--- a/usr.bin/systat/ip.c
+++ b/usr.bin/systat/ip.c
@@ -51,6 +51,7 @@ static const char sccsid[] = "@(#)mbufs.c 8.1 (Berkeley) 6/6/93";
#include <netinet/udp.h>
#include <netinet/udp_var.h>
+#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <paths.h>
@@ -201,16 +202,16 @@ void
showip(void)
{
struct stat stats;
- u_long totalout;
+ uint64_t totalout;
domode(&stats);
totalout = stats.i.ips_forward + stats.i.ips_localout;
#define DO(stat, row, col) \
- mvwprintw(wnd, row, col, "%9lu", stats.stat)
+ mvwprintw(wnd, row, col, "%9"PRIu64, stats.stat)
DO(i.ips_total, 1, 0);
- mvwprintw(wnd, 1, 35, "%9lu", totalout);
+ mvwprintw(wnd, 1, 35, "%9"PRIu64, totalout);
DO(i.ips_badsum, 2, 0);
DO(i.ips_localout, 2, 35);
DO(i.ips_tooshort, 3, 0);
diff --git a/usr.bin/systat/ip6.c b/usr.bin/systat/ip6.c
index 5d2c2103cf45..f5b943801211 100644
--- a/usr.bin/systat/ip6.c
+++ b/usr.bin/systat/ip6.c
@@ -50,6 +50,7 @@ static const char sccsid[] = "@(#)mbufs.c 8.1 (Berkeley) 6/6/93";
#include <netinet/ip.h>
#include <netinet6/ip6_var.h>
+#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <paths.h>
@@ -188,16 +189,16 @@ void
showip6(void)
{
struct ip6stat stats;
- u_long totalout;
+ uint64_t totalout;
domode(&stats);
totalout = stats.ip6s_forward + stats.ip6s_localout;
#define DO(stat, row, col) \
- mvwprintw(wnd, row, col, "%9lu", stats.stat)
+ mvwprintw(wnd, row, col, "%9"PRIu64, stats.stat)
DO(ip6s_total, 1, 0);
- mvwprintw(wnd, 1, 35, "%9lu", totalout);
+ mvwprintw(wnd, 1, 35, "%9"PRIu64, totalout);
DO(ip6s_tooshort, 2, 0);
DO(ip6s_localout, 2, 35);
DO(ip6s_toosmall, 3, 0);
diff --git a/usr.bin/systat/main.c b/usr.bin/systat/main.c
index 74195f606aec..983d319f464f 100644
--- a/usr.bin/systat/main.c
+++ b/usr.bin/systat/main.c
@@ -293,17 +293,8 @@ display(void)
GETSYSCTL("kstat.zfs.misc.arcstats.l2_hdr_size", arc[5]);
GETSYSCTL("kstat.zfs.misc.arcstats.other_size", arc[6]);
wmove(wload, 0, 0); wclrtoeol(wload);
- for (i = 0 ; i < nitems(arc); i++) {
- if (arc[i] > 10llu * 1024 * 1024 * 1024 ) {
- wprintw(wload, "%7lluG", arc[i] >> 30);
- }
- else if (arc[i] > 10 * 1024 * 1024 ) {
- wprintw(wload, "%7lluM", arc[i] >> 20);
- }
- else {
- wprintw(wload, "%7lluK", arc[i] >> 10);
- }
- }
+ for (i = 0 ; i < nitems(arc); i++)
+ sysputuint64(wload, 0, i*8+2, 6, arc[i], 0);
}
}
(*curcmd->c_refresh)();
diff --git a/usr.bin/systat/swap.c b/usr.bin/systat/swap.c
index 01d4ed0378fe..bb84187c8944 100644
--- a/usr.bin/systat/swap.c
+++ b/usr.bin/systat/swap.c
@@ -1,6 +1,7 @@
/*-
* Copyright (c) 1980, 1992, 1993
* The Regents of the University of California. All rights reserved.
+ * Copyright (c) 2017 Yoshihiro Ota
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -53,6 +54,7 @@ static const char sccsid[] = "@(#)swap.c 8.3 (Berkeley) 4/29/95";
#include "systat.h"
#include "extern.h"
+#include "devs.h"
static char *header;
static long blocksize;
@@ -133,13 +135,15 @@ initswap(void)
oulen = ulen;
once = 1;
+
+ dsinit(12);
+
return (1);
}
void
fetchswap(void)
{
-
okvnsw = kvnsw;
if ((kvnsw = kvm_getswapinfo(kd, kvmsw, NSWAP, 0)) < 0) {
error("systat: kvm_getswapinfo failed");
@@ -149,6 +153,15 @@ fetchswap(void)
odlen = dlen;
oulen = ulen;
calclens();
+
+ struct devinfo *tmp_dinfo;
+
+ tmp_dinfo = last_dev.dinfo;
+ last_dev.dinfo = cur_dev.dinfo;
+ cur_dev.dinfo = tmp_dinfo;
+
+ last_dev.snap_time = cur_dev.snap_time;
+ dsgetinfo( &cur_dev );
}
void
@@ -174,6 +187,7 @@ labelswap(void)
name = kvmsw[i].ksw_devname;
mvwprintw(wnd, i + 1, 0, "%*s", -dlen, name);
}
+ dslabel(12, 0, 18);
}
void
@@ -213,4 +227,5 @@ showswap(void)
waddch(wnd, 'X');
wclrtoeol(wnd);
}
+ dsshow(12, 0, 18, &cur_dev, &last_dev);
}
diff --git a/usr.bin/systat/sysput.c b/usr.bin/systat/sysput.c
new file mode 100644
index 000000000000..31c9127a83b7
--- /dev/null
+++ b/usr.bin/systat/sysput.c
@@ -0,0 +1,118 @@
+/*-
+ * Copyright (c) 2019 Yoshihiro Ota
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <sys/sysctl.h>
+
+#include <inttypes.h>
+#include <string.h>
+#include <err.h>
+#include <libutil.h>
+
+#include "systat.h"
+#include "extern.h"
+
+void
+sysputspaces(WINDOW *wd, int row, int col, int width)
+{
+ static char str40[] = " ";
+
+ mvwaddstr(wd, row, col, str40 + sizeof(str40) - width - 1);
+}
+
+void
+sysputstrs(WINDOW *wd, int row, int col, int width)
+{
+ static char str40[] = "****************************************";
+
+ mvwaddstr(wnd, row, col, str40 + sizeof(str40) - width - 1);
+}
+
+void
+sysputuint64(WINDOW *wd, int row, int col, int width, uint64_t val, int flags)
+{
+ char unit, *ptr, *start, wrtbuf[width + width + 1];
+ int len;
+
+ unit = 0;
+ start = wrtbuf;
+ flags |= HN_NOSPACE;
+
+ if (val > INT64_MAX)
+ goto error;
+ else
+ len = humanize_number(&wrtbuf[width], width + 1, val, "",
+ HN_AUTOSCALE, flags);
+ if (len < 0)
+ goto error;
+ else if (len < width)
+ memset(wrtbuf + len, ' ', width - len);
+ start += len;
+
+ mvwaddstr(wd, row, col, start);
+ return;
+
+error:
+ sysputstrs(wd, row, col, width);
+}
+
+void
+sysputwuint64(WINDOW *wd, int row, int col, int width, uint64_t val, int flags)
+{
+ if(val == 0)
+ sysputspaces(wd, row, col, width);
+ else
+ sysputuint64(wd, row, col, width, val, flags);
+}
+
+static int
+calc_page_shift()
+{
+ u_int page_size;
+ int shifts;
+
+ shifts = 0;
+ GETSYSCTL("vm.stats.vm.v_page_size", page_size);
+ for(; page_size > 1; page_size >>= 1)
+ shifts++;
+ return shifts;
+}
+
+void
+sysputpage(WINDOW *wd, int row, int col, int width, uint64_t pages, int flags)
+{
+ static int shifts = 0;
+
+ if (shifts == 0)
+ shifts = calc_page_shift();
+ pages <<= shifts;
+ sysputuint64(wd, row, col, width, pages, flags);
+}
diff --git a/usr.bin/systat/systat.1 b/usr.bin/systat/systat.1
index 4a0e833e0a90..9e2dd9bf7428 100644
--- a/usr.bin/systat/systat.1
+++ b/usr.bin/systat/systat.1
@@ -680,6 +680,7 @@ in Silicon Graphics'
system.
.Sh BUGS
Certain displays presume a minimum of 80 characters per line.
+Ifstat does not detect new interfaces.
The
.Ic vmstat
display looks out of place because it is (it was added in as
diff --git a/usr.bin/systat/systat.h b/usr.bin/systat/systat.h
index ebd409e217ae..b2adddc1eb98 100644
--- a/usr.bin/systat/systat.h
+++ b/usr.bin/systat/systat.h
@@ -66,3 +66,7 @@ extern int use_kvm;
#define NVAL(indx) namelist[(indx)].n_value
#define NPTR(indx) (void *)NVAL((indx))
#define NREAD(indx, buf, len) kvm_ckread(NPTR((indx)), (buf), (len))
+
+extern void putint(int, int, int, int);
+extern void putfloat(double, int, int, int, int, int);
+extern void putlongdouble(long double, int, int, int, int, int);
diff --git a/usr.bin/systat/tcp.c b/usr.bin/systat/tcp.c
index c9e8e9ae1821..e27638f4b9af 100644
--- a/usr.bin/systat/tcp.c
+++ b/usr.bin/systat/tcp.c
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
+#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <paths.h>
@@ -234,7 +235,7 @@ showtcp(void)
domode(&stats);
#define DO(stat, row, col) \
- mvwprintw(wnd, row, col, "%12lu", stats.stat)
+ mvwprintw(wnd, row, col, "%12"PRIu64, stats.stat)
#define L(row, stat) DO(stat, row, 0)
#define R(row, stat) DO(stat, row, 38)
L(1, tcps_connattempt); R(1, tcps_sndtotal);
diff --git a/usr.bin/systat/vmstat.c b/usr.bin/systat/vmstat.c
index 25f79d7e9308..ff4dbfcc2869 100644
--- a/usr.bin/systat/vmstat.c
+++ b/usr.bin/systat/vmstat.c
@@ -55,6 +55,7 @@ static const char sccsid[] = "@(#)vmstat.c 8.2 (Berkeley) 1/12/94";
#include <err.h>
#include <errno.h>
#include <langinfo.h>
+#include <libutil.h>
#include <nlist.h>
#include <paths.h>
#include <signal.h>
@@ -63,7 +64,6 @@ static const char sccsid[] = "@(#)vmstat.c 8.2 (Berkeley) 1/12/94";
#include <time.h>
#include <unistd.h>
#include <utmpx.h>
-#include <devstat.h>
#include "systat.h"
#include "extern.h"
#include "devs.h"
@@ -102,7 +102,6 @@ static struct Info {
/*
* Distribution of page usages.
*/
- u_int v_page_size; /* page size in bytes */
u_int v_free_count; /* number of pages free */
u_int v_wire_count; /* number of pages wired down */
u_int v_active_count; /* number of pages active */
@@ -122,22 +121,20 @@ static struct Info {
static u_long kmem_size;
static u_int v_page_count;
-struct statinfo cur, last, run;
#define total s.Total
#define nchtotal s.nchstats
#define oldnchtotal s1.nchstats
static enum state { BOOT, TIME, RUN } state = TIME;
+enum divisor { IEC = 0, SI = HN_DIVISOR_1000 };
static void allocinfo(struct Info *);
static void copyinfo(struct Info *, struct Info *);
static float cputime(int);
-static void dinfo(int, int, struct statinfo *, struct statinfo *);
+static void do_putuint64(uint64_t, int, int, int, int);
static void getinfo(struct Info *);
-static void putint(int, int, int, int);
-static void putfloat(double, int, int, int, int, int);
-static void putlongdouble(long double, int, int, int, int, int);
+static void putuint64(uint64_t, int, int, int);
static int ucount(void);
static int ncpu;
@@ -173,15 +170,15 @@ closekre(WINDOW *w)
#define STATCOL 0
#define MEMROW 2 /* uses 4 rows and 45 cols */
#define MEMCOL 0
-#define PAGEROW 2 /* uses 4 rows and 30 cols */
+#define PAGEROW 1 /* uses 4 rows and 30 cols */
#define PAGECOL 47
-#define INTSROW 6 /* uses all rows to bottom and 16 cols */
+#define INTSROW 5 /* uses all rows to bottom and 16 cols */
#define INTSCOL 64
#define PROCSROW 6 /* uses 3 rows and 19 cols */
#define PROCSCOL 0
#define GENSTATROW 7 /* uses 2 rows and 29 cols */
#define GENSTATCOL 21
-#define VMSTATROW 7 /* uses 17 rows and 12-14 cols */
+#define VMSTATROW 5 /* uses 17 rows and 12-14 cols */
#define VMSTATCOL 49 /* actually 50-51 for some fields */
#define GRAPHROW 10 /* uses 3 rows and 49-51 cols */
#define GRAPHCOL 0
@@ -203,16 +200,7 @@ initkre(void)
int i;
size_t sz;
- if ((num_devices = devstat_getnumdevs(NULL)) < 0) {
- warnx("%s", devstat_errbuf);
- return(0);
- }
-
- cur.dinfo = calloc(1, sizeof(struct devinfo));
- last.dinfo = calloc(1, sizeof(struct devinfo));
- run.dinfo = calloc(1, sizeof(struct devinfo));
-
- if (dsinit(MAXDRIVES, &cur, &last, &run) != 1)
+ if (dsinit(MAXDRIVES) != 1)
return(0);
if (nintr == 0) {
@@ -313,7 +301,7 @@ labelkre(void)
clear();
mvprintw(STATROW, STATCOL + 6, "users Load");
mvprintw(STATROW + 1, STATCOL + 3, "Mem usage: %%Phy %%Kmem");
- mvprintw(MEMROW, MEMCOL, "Mem: KB REAL VIRTUAL");
+ mvprintw(MEMROW, MEMCOL, "Mem: REAL VIRTUAL");
mvprintw(MEMROW + 1, MEMCOL, " Tot Share Tot Share");
mvprintw(MEMROW + 2, MEMCOL, "Act");
mvprintw(MEMROW + 3, MEMCOL, "All");
@@ -365,27 +353,7 @@ labelkre(void)
mvprintw(NAMEIROW, NAMEICOL, "Namei Name-cache Dir-cache");
mvprintw(NAMEIROW + 1, NAMEICOL,
" Calls hits %% hits %%");
- mvprintw(DISKROW, DISKCOL, "Disks");
- mvprintw(DISKROW + 1, DISKCOL, "KB/t");
- mvprintw(DISKROW + 2, DISKCOL, "tps");
- mvprintw(DISKROW + 3, DISKCOL, "MB/s");
- mvprintw(DISKROW + 4, DISKCOL, "%%busy");
- /*
- * For now, we don't support a fourth disk statistic. So there's
- * no point in providing a label for it. If someone can think of a
- * fourth useful disk statistic, there is room to add it.
- */
- /* mvprintw(DISKROW + 4, DISKCOL, " msps"); */
- j = 0;
- for (i = 0; i < num_devices && j < MAXDRIVES; i++)
- if (dev_select[i].selected) {
- char tmpstr[80];
- sprintf(tmpstr, "%s%d", dev_select[i].device_name,
- dev_select[i].unit_number);
- mvprintw(DISKROW, DISKCOL + 5 + 6 * j,
- " %5.5s", tmpstr);
- j++;
- }
+ dslabel(MAXDRIVES, DISKCOL, DISKROW);
for (i = 0; i < nintr; i++) {
if (intrloc[i] == 0)
@@ -395,14 +363,14 @@ labelkre(void)
}
#define X(fld) {t=s.fld[i]; s.fld[i]-=s1.fld[i]; if(state==TIME) s1.fld[i]=t;}
-#define Q(fld) {t=cur.fld[i]; cur.fld[i]-=last.fld[i]; if(state==TIME) last.fld[i]=t;}
+#define Q(fld) {t=cur_dev.fld[i]; cur_dev.fld[i]-=last_dev.fld[i]; if(state==TIME) last_dev.fld[i]=t;}
#define Y(fld) {t = s.fld; s.fld -= s1.fld; if(state == TIME) s1.fld = t;}
#define Z(fld) {t = s.nchstats.fld; s.nchstats.fld -= s1.nchstats.fld; \
if(state == TIME) s1.nchstats.fld = t;}
#define PUTRATE(fld, l, c, w) \
do { \
Y(fld); \
- putint((int)((float)s.fld/etime + 0.5), l, c, w); \
+ sysputwuint64(wnd, l, c, w, (s.fld/etime + 0.5), 0); \
} while (0)
#define MAXFAIL 5
@@ -483,21 +451,20 @@ showkre(void)
putfloat(avenrun[1], STATROW, STATCOL + 26, 5, 2, 0);
putfloat(avenrun[2], STATROW, STATCOL + 32, 5, 2, 0);
mvaddstr(STATROW, STATCOL + 55, buf);
-#define pgtokb(pg) ((pg) * (s.v_page_size / 1024))
putfloat(100.0 * (v_page_count - total.t_free) / v_page_count,
STATROW + 1, STATCOL + 15, 2, 0, 1);
putfloat(100.0 * s.v_kmem_map_size / kmem_size,
STATROW + 1, STATCOL + 22, 2, 0, 1);
- putint(pgtokb(total.t_arm), MEMROW + 2, MEMCOL + 4, 7);
- putint(pgtokb(total.t_armshr), MEMROW + 2, MEMCOL + 12, 7);
- putint(pgtokb(total.t_avm), MEMROW + 2, MEMCOL + 20, 8);
- putint(pgtokb(total.t_avmshr), MEMROW + 2, MEMCOL + 29, 8);
- putint(pgtokb(total.t_rm), MEMROW + 3, MEMCOL + 4, 7);
- putint(pgtokb(total.t_rmshr), MEMROW + 3, MEMCOL + 12, 7);
- putint(pgtokb(total.t_vm), MEMROW + 3, MEMCOL + 20, 8);
- putint(pgtokb(total.t_vmshr), MEMROW + 3, MEMCOL + 29, 8);
- putint(pgtokb(total.t_free), MEMROW + 2, MEMCOL + 38, 7);
+ sysputpage(wnd, MEMROW + 2, MEMCOL + 4, 7, total.t_arm, 0);
+ sysputpage(wnd, MEMROW + 2, MEMCOL + 12, 7, total.t_armshr, 0);
+ sysputpage(wnd, MEMROW + 2, MEMCOL + 20, 8, total.t_avm, 0);
+ sysputpage(wnd, MEMROW + 2, MEMCOL + 29, 8, total.t_avmshr, 0);
+ sysputpage(wnd, MEMROW + 3, MEMCOL + 4, 7, total.t_rm, 0);
+ sysputpage(wnd, MEMROW + 3, MEMCOL + 12, 7, total.t_rmshr, 0);
+ sysputpage(wnd, MEMROW + 3, MEMCOL + 20, 8, total.t_vm, 0);
+ sysputpage(wnd, MEMROW + 3, MEMCOL + 29, 8, total.t_vmshr, 0);
+ sysputpage(wnd, MEMROW + 2, MEMCOL + 38, 7, total.t_free, 0);
putint(total.t_rq - 1, PROCSROW + 2, PROCSCOL, 3);
putint(total.t_pw, PROCSROW + 2, PROCSCOL + 4, 3);
putint(total.t_dw, PROCSROW + 2, PROCSCOL + 8, 3);
@@ -516,13 +483,13 @@ showkre(void)
PUTRATE(v_pdwakeups, VMSTATROW + 9, VMSTATCOL, 8);
PUTRATE(v_pdpages, VMSTATROW + 10, VMSTATCOL, 8);
PUTRATE(v_intrans, VMSTATROW + 11, VMSTATCOL, 8);
- putint(pgtokb(s.v_wire_count), VMSTATROW + 12, VMSTATCOL, 8);
- putint(pgtokb(s.v_active_count), VMSTATROW + 13, VMSTATCOL, 8);
- putint(pgtokb(s.v_inactive_count), VMSTATROW + 14, VMSTATCOL, 8);
- putint(pgtokb(s.v_laundry_count), VMSTATROW + 15, VMSTATCOL, 8);
- putint(pgtokb(s.v_free_count), VMSTATROW + 16, VMSTATCOL, 8);
+ sysputpage(wnd, VMSTATROW + 12, VMSTATCOL + 2, 8 - 2, s.v_wire_count, 0);
+ sysputpage(wnd, VMSTATROW + 13, VMSTATCOL + 2, 8 - 2, s.v_active_count, 0);
+ sysputpage(wnd, VMSTATROW + 14, VMSTATCOL + 2, 8 - 2, s.v_inactive_count, 0);
+ sysputpage(wnd, VMSTATROW + 15, VMSTATCOL + 2, 8 - 2, s.v_laundry_count, 0);
+ sysputpage(wnd, VMSTATROW + 16, VMSTATCOL + 2, 8 - 2, s.v_free_count, 0);
if (LINES - 1 > VMSTATROW + 17)
- putint(s.bufspace / 1024, VMSTATROW + 17, VMSTATCOL, 8);
+ sysputuint64(wnd, VMSTATROW + 17, VMSTATCOL + 2, 8 - 2, s.bufspace, 0);
PUTRATE(v_vnodein, PAGEROW + 2, PAGECOL + 6, 5);
PUTRATE(v_vnodeout, PAGEROW + 2, PAGECOL + 12, 5);
PUTRATE(v_swapin, PAGEROW + 2, PAGECOL + 19, 5);
@@ -537,20 +504,17 @@ showkre(void)
PUTRATE(v_intr, GENSTATROW + 1, GENSTATCOL + 15, 4);
PUTRATE(v_soft, GENSTATROW + 1, GENSTATCOL + 20, 4);
PUTRATE(v_vm_faults, GENSTATROW + 1, GENSTATCOL + 25, 4);
- for (i = 0, lc = 0; i < num_devices && lc < MAXDRIVES; i++)
- if (dev_select[i].selected) {
- switch(state) {
- case TIME:
- dinfo(i, ++lc, &cur, &last);
- break;
- case RUN:
- dinfo(i, ++lc, &cur, &run);
- break;
- case BOOT:
- dinfo(i, ++lc, &cur, NULL);
- break;
- }
- }
+ switch(state) {
+ case TIME:
+ dsshow(MAXDRIVES, DISKCOL, DISKROW, &cur_dev, &last_dev);
+ break;
+ case RUN:
+ dsshow(MAXDRIVES, DISKCOL, DISKROW, &cur_dev, &run_dev);
+ break;
+ case BOOT:
+ dsshow(MAXDRIVES, DISKCOL, DISKROW, &cur_dev, NULL);
+ break;
+ }
putint(s.numdirtybuffers, VNSTATROW, VNSTATCOL, 7);
putint(s.desiredvnodes, VNSTATROW + 1, VNSTATCOL, 7);
putint(s.numvnodes, VNSTATROW + 2, VNSTATCOL, 7);
@@ -576,14 +540,14 @@ cmdkre(const char *cmd, const char *args)
if (prefix(cmd, "run")) {
retval = 1;
copyinfo(&s2, &s1);
- switch (devstat_getdevs(NULL, &run)) {
+ switch (devstat_getdevs(NULL, &run_dev)) {
case -1:
errx(1, "%s", devstat_errbuf);
break;
case 1:
- num_devices = run.dinfo->numdevs;
- generation = run.dinfo->generation;
- retval = dscmd("refresh", NULL, MAXDRIVES, &cur);
+ num_devices = run_dev.dinfo->numdevs;
+ generation = run_dev.dinfo->generation;
+ retval = dscmd("refresh", NULL, MAXDRIVES, &cur_dev);
if (retval == 2)
labelkre();
break;
@@ -606,14 +570,14 @@ cmdkre(const char *cmd, const char *args)
retval = 1;
if (state == RUN) {
getinfo(&s1);
- switch (devstat_getdevs(NULL, &run)) {
+ switch (devstat_getdevs(NULL, &run_dev)) {
case -1:
errx(1, "%s", devstat_errbuf);
break;
case 1:
- num_devices = run.dinfo->numdevs;
- generation = run.dinfo->generation;
- retval = dscmd("refresh",NULL, MAXDRIVES, &cur);
+ num_devices = run_dev.dinfo->numdevs;
+ generation = run_dev.dinfo->generation;
+ retval = dscmd("refresh",NULL, MAXDRIVES, &cur_dev);
if (retval == 2)
labelkre();
break;
@@ -623,7 +587,7 @@ cmdkre(const char *cmd, const char *args)
}
return (retval);
}
- retval = dscmd(cmd, args, MAXDRIVES, &cur);
+ retval = dscmd(cmd, args, MAXDRIVES, &cur_dev);
if (retval == 2)
labelkre();
@@ -661,11 +625,26 @@ cputime(int indx)
return (s.time[indx] * 100.0 / lt);
}
-static void
+void
putint(int n, int l, int lc, int w)
{
+
+ do_putuint64(n, l, lc, w, SI);
+}
+
+static void
+putuint64(uint64_t n, int l, int lc, int w)
+{
+
+ do_putuint64(n, l, lc, w, IEC);
+}
+
+static void
+do_putuint64(uint64_t n, int l, int lc, int w, int div)
+{
int snr;
char b[128];
+ char buf[128];
move(l, lc);
#ifdef DEBUG
@@ -678,11 +657,12 @@ putint(int n, int l, int lc, int w)
addch(' ');
return;
}
- snr = snprintf(b, sizeof(b), "%*d", w, n);
- if (snr != w)
- snr = snprintf(b, sizeof(b), "%*dk", w - 1, n / 1000);
- if (snr != w)
- snr = snprintf(b, sizeof(b), "%*dM", w - 1, n / 1000000);
+ snr = snprintf(b, sizeof(b), "%*ju", w, (uintmax_t)n);
+ if (snr != w) {
+ humanize_number(buf, w, n, "", HN_AUTOSCALE,
+ HN_NOSPACE | HN_DECIMAL | div);
+ snr = snprintf(b, sizeof(b), "%*s", w, buf);
+ }
if (snr != w) {
while (w-- > 0)
addch('*');
@@ -691,7 +671,7 @@ putint(int n, int l, int lc, int w)
addstr(b);
}
-static void
+void
putfloat(double f, int l, int lc, int w, int d, int nz)
{
int snr;
@@ -723,7 +703,7 @@ putfloat(double f, int l, int lc, int w, int d, int nz)
addstr(b);
}
-static void
+void
putlongdouble(long double f, int l, int lc, int w, int d, int nz)
{
int snr;
@@ -763,7 +743,7 @@ getinfo(struct Info *ls)
int mib[2];
GETSYSCTL("kern.cp_time", ls->time);
- GETSYSCTL("kern.cp_time", cur.cp_time);
+ GETSYSCTL("kern.cp_time", cur_dev.cp_time);
GETSYSCTL("vm.stats.sys.v_swtch", ls->v_swtch);
GETSYSCTL("vm.stats.sys.v_trap", ls->v_trap);
GETSYSCTL("vm.stats.sys.v_syscall", ls->v_syscall);
@@ -789,7 +769,6 @@ getinfo(struct Info *ls)
GETSYSCTL("vm.stats.vm.v_dfree", ls->v_dfree);
GETSYSCTL("vm.stats.vm.v_pfree", ls->v_pfree);
GETSYSCTL("vm.stats.vm.v_tfree", ls->v_tfree);
- GETSYSCTL("vm.stats.vm.v_page_size", ls->v_page_size);
GETSYSCTL("vm.stats.vm.v_free_count", ls->v_free_count);
GETSYSCTL("vm.stats.vm.v_wire_count", ls->v_wire_count);
GETSYSCTL("vm.stats.vm.v_active_count", ls->v_active_count);
@@ -816,23 +795,12 @@ getinfo(struct Info *ls)
size != sizeof(ncpu))
ncpu = 1;
- tmp_dinfo = last.dinfo;
- last.dinfo = cur.dinfo;
- cur.dinfo = tmp_dinfo;
+ tmp_dinfo = last_dev.dinfo;
+ last_dev.dinfo = cur_dev.dinfo;
+ cur_dev.dinfo = tmp_dinfo;
- last.snap_time = cur.snap_time;
- switch (devstat_getdevs(NULL, &cur)) {
- case -1:
- errx(1, "%s", devstat_errbuf);
- break;
- case 1:
- num_devices = cur.dinfo->numdevs;
- generation = cur.dinfo->generation;
- cmdkre("refresh", NULL);
- break;
- default:
- break;
- }
+ last_dev.snap_time = cur_dev.snap_time;
+ dsgetinfo(&cur_dev);
}
static void
@@ -859,38 +827,3 @@ copyinfo(struct Info *from, struct Info *to)
bcopy(from->intrcnt, to->intrcnt = intrcnt, nintr * sizeof (int));
}
-
-static void
-dinfo(int dn, int lc, struct statinfo *now, struct statinfo *then)
-{
- long double transfers_per_second;
- long double kb_per_transfer, mb_per_second;
- long double elapsed_time, device_busy;
- int di;
-
- di = dev_select[dn].position;
-
- if (then != NULL) {
- /* Calculate relative to previous sample */
- elapsed_time = now->snap_time - then->snap_time;
- } else {
- /* Calculate relative to device creation */
- elapsed_time = now->snap_time - devstat_compute_etime(
- &now->dinfo->devices[di].creation_time, NULL);
- }
-
- if (devstat_compute_statistics(&now->dinfo->devices[di], then ?
- &then->dinfo->devices[di] : NULL, elapsed_time,
- DSM_KB_PER_TRANSFER, &kb_per_transfer,
- DSM_TRANSFERS_PER_SECOND, &transfers_per_second,
- DSM_MB_PER_SECOND, &mb_per_second,
- DSM_BUSY_PCT, &device_busy,
- DSM_NONE) != 0)
- errx(1, "%s", devstat_errbuf);
-
- lc = DISKCOL + lc * 6;
- putlongdouble(kb_per_transfer, DISKROW + 1, lc, 5, 2, 0);
- putlongdouble(transfers_per_second, DISKROW + 2, lc, 5, 0, 0);
- putlongdouble(mb_per_second, DISKROW + 3, lc, 5, 2, 0);
- putlongdouble(device_busy, DISKROW + 4, lc, 5, 0, 0);
-}
diff --git a/usr.bin/systat/zarc.c b/usr.bin/systat/zarc.c
index 2a6606f9d8fb..7b65faf5ec4a 100644
--- a/usr.bin/systat/zarc.c
+++ b/usr.bin/systat/zarc.c
@@ -1,6 +1,5 @@
/*-
- * Copyright (c) 2014
- * The Regents of the University of California. All rights reserved.
+ * Copyright (c) 2014 - 2017, 2019 Yoshihiro Ota
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,12 +32,16 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/sysctl.h>
+#include <inttypes.h>
#include <string.h>
+#include <err.h>
+#include <libutil.h>
#include "systat.h"
#include "extern.h"
+#include "devs.h"
-struct zfield{
+struct zfield {
uint64_t arcstats;
uint64_t arcstats_demand_data;
uint64_t arcstats_demand_metadata;
@@ -54,18 +57,25 @@ static struct zarcstats {
struct zfield misses;
} curstat, initstat, oldstat;
+struct zarcrates {
+ struct zfield current;
+ struct zfield total;
+};
+
static void
getinfo(struct zarcstats *ls);
WINDOW *
openzarc(void)
{
- return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0));
+
+ return (subwin(stdscr, LINES - 3 - 1, 0, MAINWIN_ROW, 0));
}
void
closezarc(WINDOW *w)
{
+
if (w == NULL)
return;
wclear(w);
@@ -76,38 +86,42 @@ closezarc(WINDOW *w)
void
labelzarc(void)
{
+ int row = 1;
+
wmove(wnd, 0, 0); wclrtoeol(wnd);
- mvwprintw(wnd, 0, 31+1, "%4.4s %7.7s %7.7s %12.12s %12.12s",
- "rate", "hits", "misses", "total hits", "total misses");
-#define L(row, str) mvwprintw(wnd, row, 5, str); \
- mvwprintw(wnd, row, 31, ":"); \
- mvwprintw(wnd, row, 31+4, "%%")
- L(1, "arcstats");
- L(2, "arcstats.demand_data");
- L(3, "arcstats.demand_metadata");
- L(4, "arcstats.prefetch_data");
- L(5, "arcstats.prefetch_metadata");
- L(6, "zfetchstats");
- L(7, "arcstats.l2");
- L(8, "vdev_cache_stats");
+ mvwprintw(wnd, 0, 31+1, "%4.4s %6.6s %6.6s | Total %4.4s %6.6s %6.6s",
+ "Rate", "Hits", "Misses", "Rate", "Hits", "Misses");
+#define L(str) mvwprintw(wnd, row++, 5, \
+ "%-26.26s: %% | %%", #str)
+ L(arcstats);
+ L(arcstats.demand_data);
+ L(arcstats.demand_metadata);
+ L(arcstats.prefetch_data);
+ L(arcstats.prefetch_metadata);
+ L(zfetchstats);
+ L(arcstats.l2);
+ L(vdev_cache_stats);
#undef L
+ dslabel(12, 0, 18);
}
-static int calc(uint64_t hits, uint64_t misses)
+static int
+calc_rate(uint64_t hits, uint64_t misses)
{
- if( hits )
- return 100 * hits / ( hits + misses );
+ if(hits)
+ return 100 * hits / (hits + misses);
else
return 0;
}
static void
-domode(struct zarcstats *delta, struct zarcstats *rate)
+domode(struct zarcstats *delta, struct zarcrates *rate)
{
#define DO(stat) \
delta->hits.stat = (curstat.hits.stat - oldstat.hits.stat); \
delta->misses.stat = (curstat.misses.stat - oldstat.misses.stat); \
- rate->hits.stat = calc(delta->hits.stat, delta->misses.stat)
+ rate->current.stat = calc_rate(delta->hits.stat, delta->misses.stat); \
+ rate->total.stat = calc_rate(curstat.hits.stat, curstat.misses.stat)
DO(arcstats);
DO(arcstats_demand_data);
DO(arcstats_demand_metadata);
@@ -130,56 +144,69 @@ domode(struct zarcstats *delta, struct zarcstats *rate)
void
showzarc(void)
{
- struct zarcstats delta, rate;
-
- memset(&delta, 0, sizeof delta);
- memset(&rate, 0, sizeof rate);
+ int row = 1;
+ struct zarcstats delta = {};
+ struct zarcrates rate = {};
domode(&delta, &rate);
-#define DO(stat, row, col, fmt) \
- mvwprintw(wnd, row, col, fmt, stat)
-#define R(row, stat) DO(rate.hits.stat, row, 31+1, "%3lu")
-#define H(row, stat) DO(delta.hits.stat, row, 31+1+5, "%7lu"); \
- DO(curstat.hits.stat, row, 31+1+5+8+8, "%12lu")
-#define M(row, stat) DO(delta.misses.stat, row, 31+1+5+8, "%7lu"); \
- DO(curstat.misses.stat, row, 31+1+5+8+8+13, "%12lu")
-#define E(row, stat) R(row, stat); H(row, stat); M(row, stat);
- E(1, arcstats);
- E(2, arcstats_demand_data);
- E(3, arcstats_demand_metadata);
- E(4, arcstats_prefetch_data);
- E(5, arcstats_prefetch_metadata);
- E(6, zfetchstats);
- E(7, arcstats_l2);
- E(8, vdev_cache_stats);
+#define DO(stat, col, width) \
+ sysputuint64(wnd, row, col, width, stat, HN_DIVISOR_1000)
+#define RATES(stat) mvwprintw(wnd, row, 31+1, "%3"PRIu64, rate.current.stat);\
+ mvwprintw(wnd, row, 31+1+5+7+7+8, "%3"PRIu64, rate.total.stat)
+#define HITS(stat) DO(delta.hits.stat, 31+1+5, 6); \
+ DO(curstat.hits.stat, 31+1+5+7+7+8+5, 6)
+#define MISSES(stat) DO(delta.misses.stat, 31+1+5+7, 6); \
+ DO(curstat.misses.stat, 31+1+5+7+7+8+5+7, 6)
+#define E(stat) RATES(stat); HITS(stat); MISSES(stat); ++row
+ E(arcstats);
+ E(arcstats_demand_data);
+ E(arcstats_demand_metadata);
+ E(arcstats_prefetch_data);
+ E(arcstats_prefetch_metadata);
+ E(zfetchstats);
+ E(arcstats_l2);
+ E(vdev_cache_stats);
#undef DO
#undef E
-#undef M
-#undef H
-#undef R
+#undef MISSES
+#undef HITS
+#undef RATES
+ dsshow(12, 0, 18, &cur_dev, &last_dev);
}
int
initzarc(void)
{
+ dsinit(12);
getinfo(&initstat);
curstat = oldstat = initstat;
+
return 1;
}
void
resetzarc(void)
{
+
initzarc();
}
static void
getinfo(struct zarcstats *ls)
{
- size_t size = sizeof( ls->hits.arcstats );
- if ( sysctlbyname("kstat.zfs.misc.arcstats.hits",
- &ls->hits.arcstats, &size, NULL, 0 ) != 0 )
+ struct devinfo *tmp_dinfo;
+
+ tmp_dinfo = last_dev.dinfo;
+ last_dev.dinfo = cur_dev.dinfo;
+ cur_dev.dinfo = tmp_dinfo;
+
+ last_dev.snap_time = cur_dev.snap_time;
+ dsgetinfo(&cur_dev);
+
+ size_t size = sizeof(ls->hits.arcstats);
+ if (sysctlbyname("kstat.zfs.misc.arcstats.hits",
+ &ls->hits.arcstats, &size, NULL, 0) != 0)
return;
GETSYSCTL("kstat.zfs.misc.arcstats.misses",
ls->misses.arcstats);
@@ -216,6 +243,7 @@ getinfo(struct zarcstats *ls)
void
fetchzarc(void)
{
+
oldstat = curstat;
getinfo(&curstat);
}