Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 3 Jan 2021 16:30:09 GMT
From:      Michael Reifenberger <mr@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 72b42d209ff5 - stable/11 - MFC r340361:
Message-ID:  <202101031630.103GU9JU069065@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/11 has been updated by mr:

URL: https://cgit.FreeBSD.org/src/commit/?id=72b42d209ff5b37c615048fb251d7bf9eb276381

commit 72b42d209ff5b37c615048fb251d7bf9eb276381
Author:     Michael Tuexen <tuexen@FreeBSD.org>
AuthorDate: 2018-11-15 17:25:32 +0000
Commit:     Michael Reifenberger <mr@FreeBSD.org>
CommitDate: 2021-01-03 16:29:50 +0000

    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
---
 usr.bin/systat/Makefile |   4 +-
 usr.bin/systat/devs.c   | 126 +++++++++++++++++++++++++--
 usr.bin/systat/devs.h   |  16 +++-
 usr.bin/systat/extern.h |   7 +-
 usr.bin/systat/fetch.c  |   9 +-
 usr.bin/systat/icmp6.c  |   9 +-
 usr.bin/systat/ifcmds.c |   2 +
 usr.bin/systat/ifstat.c | 118 ++++++++++++++++----------
 usr.bin/systat/iostat.c |  46 +++++-----
 usr.bin/systat/ip.c     |   7 +-
 usr.bin/systat/ip6.c    |   7 +-
 usr.bin/systat/main.c   |  13 +--
 usr.bin/systat/swap.c   |  17 +++-
 usr.bin/systat/sysput.c | 118 ++++++++++++++++++++++++++
 usr.bin/systat/systat.1 |   1 +
 usr.bin/systat/systat.h |   4 +
 usr.bin/systat/tcp.c    |   3 +-
 usr.bin/systat/vmstat.c | 221 +++++++++++++++++-------------------------------
 usr.bin/systat/zarc.c   | 124 ++++++++++++++++-----------
 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
*** 815 LINES SKIPPED ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202101031630.103GU9JU069065>