aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Tuexen <tuexen@FreeBSD.org>2018-11-15 17:25:32 +0000
committerMichael Reifenberger <mr@FreeBSD.org>2021-01-03 16:29:50 +0000
commit72b42d209ff5b37c615048fb251d7bf9eb276381 (patch)
tree87d7950f65dde32302e1aa2f10f0bf7111d62273
parent72492c6d5385acba86425bf7244c3563426e2ac7 (diff)
downloadsrc-72b42d209ff5b37c615048fb251d7bf9eb276381.tar.gz
src-72b42d209ff5b37c615048fb251d7bf9eb276381.zip
MFC r340361:
Fix printing of 64-bit counters on 32-bit ppc platforms. Several statistic counters are uint64_t values and are printed by systat using %lu. This results in displaying wrong numbers. Use PRIu64 instead. While there, print variables of size_t using %zd. Approved by: re (gjb@) Differential Revision: https://reviews.freebsd.org/D17838 (cherry picked from commit 45e9405ea4b05926b22a743237cbfe918206db50) systat: use and correctly display 64bit counters. Following struct vmtotal changes, make systat use and correctly display 64-bit counters. Switch to humanize_number(3) to overcome homegrown arithmetics limits in pretty printing large numbers. Use 1024 as a divisor for memory fields to make it consistent with other tools and users expectations. Submitted by: Pawel Biernacki <pawel.biernacki@gmail.com> Sponsored by: Mysterious Code Ltd. PR: 2137 Differential revision: https://reviews.freebsd.org/D13105 (cherry picked from commit 90dd3e79cc4d721b17c473fdaf3ba3d6d912b138) Order declarations alphabetically. Match signess of the format and the value. Noted by: bde Sponsored by: The FreeBSD Foundation (cherry picked from commit 1b7a3d1f5ffe700203f12654cd01a08a84551b4a) MFC r340361, r345804: catch up on systat in head/ [Neither of these originally mine, but the latter commit referenced fixes an -fno-common issue and the former is a bugfix] r340361: Fix printing of 64-bit counters on 32-bit ppc platforms. Several statistic counters are uint64_t values and are printed by systat using %lu. This results in displaying wrong numbers. Use PRIu64 instead. While there, print variables of size_t using %zd. r345804: systat -zarc to display disk activities like -vm PR: 213310 (cherry picked from commit a70af2507f720c2d7f56f51a18d358123b4770a5) MFC r360919,r360929,r361084: Patch systat -zarc to display cumulative rate and round down large numbers by SI units Introduce sysputpage() to display large page size with human readable format. Using UI units allows to fit larger numbers in columns. Stop calling v_page_size - this is a value that doesn't change at runtime. Renamed WINDOW *wnd to *wd to avoid conflict with global *wnd variable. Use bit-shift to convert page size to byte. PR: 237664, 246458 Submitted by: ota@j.email.ne.jp (cherry picked from commit 65d1fd13ac2182f7ca0c223bb723fba6d780740f) MFC r363095: Handle device removal and removal+add cases to fix infinity rate. PR: 219829 Submitted by: ota@j.email.ne.jp Reported by: rezo@live.cn Differential Revision: https://reviews.freebsd.org/D25226 (cherry picked from commit 7a446028cedb13a0d2004cf6f584291a976392da) PR: 219829, 237664, 246458, 213310, 2137
-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);
}