Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 2 Apr 2019 14:01:03 +0000 (UTC)
From:      Michael Reifenberger <mr@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r345804 - head/usr.bin/systat
Message-ID:  <201904021401.x32E13Fi092699@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mr
Date: Tue Apr  2 14:01:03 2019
New Revision: 345804
URL: https://svnweb.freebsd.org/changeset/base/345804

Log:
  systat -zarc to display disk activities like -vm
  
  PR:		213310
  Submitted by:	ota
  MFH:		4 weeks
  Differential Revision:	https://reviews.freebsd.org/D18726

Modified:
  head/usr.bin/systat/devs.c
  head/usr.bin/systat/devs.h
  head/usr.bin/systat/iostat.c
  head/usr.bin/systat/swap.c
  head/usr.bin/systat/systat.h
  head/usr.bin/systat/vmstat.c
  head/usr.bin/systat/zarc.c

Modified: head/usr.bin/systat/devs.c
==============================================================================
--- head/usr.bin/systat/devs.c	Tue Apr  2 13:59:04 2019	(r345803)
+++ head/usr.bin/systat/devs.c	Tue Apr  2 14:01:03 2019	(r345804)
@@ -2,6 +2,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  *
  * Copyright (c) 1998 Kenneth D. Merry.
+ *               2015 Yoshihiro Ota
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -69,7 +70,6 @@ static const char sccsid[] = "@(#)disks.c	8.1 (Berkele
 #include <sys/resource.h>
 
 #include <ctype.h>
-#include <devstat.h>
 #include <err.h>
 #include <stdlib.h>
 #include <string.h>
@@ -84,6 +84,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;
@@ -101,10 +103,8 @@ static int dsselect(const char *args, devstat_select_m
 		    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
@@ -113,6 +113,18 @@ dsinit(int maxshowdevs, struct statinfo *s1, struct st
 	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;
@@ -120,11 +132,11 @@ dsinit(int maxshowdevs, struct statinfo *s1, struct st
 	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;
 
@@ -134,13 +146,31 @@ dsinit(int maxshowdevs, struct statinfo *s1, struct st
 	 * 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)
 {
@@ -330,4 +360,84 @@ dsselect(const char *args, devstat_select_mode select_
 			return(2);
 	}
 	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);
 }

Modified: head/usr.bin/systat/devs.h
==============================================================================
--- head/usr.bin/systat/devs.h	Tue Apr  2 13:59:04 2019	(r345803)
+++ head/usr.bin/systat/devs.h	Tue Apr  2 14:01:03 2019	(r345804)
@@ -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

Modified: head/usr.bin/systat/iostat.c
==============================================================================
--- head/usr.bin/systat/iostat.c	Tue Apr  2 13:59:04 2019	(r345803)
+++ head/usr.bin/systat/iostat.c	Tue Apr  2 14:01:03 2019	(r345804)
@@ -79,8 +79,6 @@ static const char sccsid[] = "@(#)iostat.c	8.1 (Berkel
 #include "extern.h"
 #include "devs.h"
 
-struct statinfo cur, last;
-
 static  int linesperregion;
 static  double etime;
 static  int numbers = 0;		/* default display bar graphs */
@@ -111,17 +109,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);
@@ -133,17 +125,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.
@@ -152,7 +144,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;
@@ -162,8 +154,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;
 
 }
 
@@ -260,11 +252,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;
@@ -313,10 +305,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)
@@ -349,12 +341,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
@@ -388,7 +380,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();

Modified: head/usr.bin/systat/swap.c
==============================================================================
--- head/usr.bin/systat/swap.c	Tue Apr  2 13:59:04 2019	(r345803)
+++ head/usr.bin/systat/swap.c	Tue Apr  2 14:01:03 2019	(r345804)
@@ -3,6 +3,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
@@ -55,6 +56,7 @@ static const char sccsid[] = "@(#)swap.c	8.3 (Berkeley
 
 #include "systat.h"
 #include "extern.h"
+#include "devs.h"
 
 kvm_t	*kd;
 
@@ -137,13 +139,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");
@@ -153,6 +157,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
@@ -178,6 +191,7 @@ labelswap(void)
 			name = kvmsw[i].ksw_devname;
 		mvwprintw(wnd, i + 1, 0, "%*s", -dlen, name);
 	}
+	dslabel(12, 0, 18);
 }
 
 void
@@ -217,4 +231,5 @@ showswap(void)
 			waddch(wnd, 'X');
 		wclrtoeol(wnd);
 	}
+	dsshow(12, 0, 18, &cur_dev, &last_dev);
 }

Modified: head/usr.bin/systat/systat.h
==============================================================================
--- head/usr.bin/systat/systat.h	Tue Apr  2 13:59:04 2019	(r345803)
+++ head/usr.bin/systat/systat.h	Tue Apr  2 14:01:03 2019	(r345804)
@@ -68,3 +68,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);

Modified: head/usr.bin/systat/vmstat.c
==============================================================================
--- head/usr.bin/systat/vmstat.c	Tue Apr  2 13:59:04 2019	(r345803)
+++ head/usr.bin/systat/vmstat.c	Tue Apr  2 14:01:03 2019	(r345804)
@@ -66,7 +66,6 @@ static const char sccsid[] = "@(#)vmstat.c	8.2 (Berkel
 #include <time.h>
 #include <unistd.h>
 #include <utmpx.h>
-#include <devstat.h>
 #include "systat.h"
 #include "extern.h"
 #include "devs.h"
@@ -125,7 +124,6 @@ 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
@@ -137,13 +135,9 @@ 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 putuint64(uint64_t, int, int, int);
-static void putfloat(double, int, int, int, int, int);
-static void putlongdouble(long double, int, int, int, int, int);
 static int ucount(void);
 
 static	int ncpu;
@@ -209,18 +203,9 @@ initkre(void)
 	int i;
 	size_t sz;
 
-	if ((num_devices = devstat_getnumdevs(NULL)) < 0) {
-		warnx("%s", devstat_errbuf);
+	if (dsinit(MAXDRIVES) != 1)
 		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)
-		return(0);
-
 	if (nintr == 0) {
 		if (sysctlbyname("hw.intrcnt", NULL, &sz, NULL, 0) == -1) {
 			error("sysctl(hw.intrcnt...) failed: %s",
@@ -371,27 +356,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)
@@ -401,7 +366,7 @@ 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;}
@@ -543,20 +508,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);
@@ -582,14 +544,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;
@@ -612,14 +574,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;
@@ -629,7 +591,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();
@@ -667,7 +629,7 @@ cputime(int indx)
 	return (s.time[indx] * 100.0 / lt);
 }
 
-static void
+void
 putint(int n, int l, int lc, int w)
 {
 
@@ -713,7 +675,7 @@ do_putuint64(uint64_t n, int l, int lc, int w, int div
 	addstr(b);
 }
 
-static void
+void
 putfloat(double f, int l, int lc, int w, int d, int nz)
 {
 	int snr;
@@ -745,7 +707,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;
@@ -785,7 +747,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);
@@ -838,23 +800,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
@@ -880,39 +831,4 @@ copyinfo(struct Info *from, struct Info *to)
 	*to = *from;
 
 	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);
 }

Modified: head/usr.bin/systat/zarc.c
==============================================================================
--- head/usr.bin/systat/zarc.c	Tue Apr  2 13:59:04 2019	(r345803)
+++ head/usr.bin/systat/zarc.c	Tue Apr  2 14:01:03 2019	(r345804)
@@ -1,6 +1,5 @@
 /*-
- * Copyright (c) 2014
- *	The Regents of the University of California.  All rights reserved.
+ * Copyright (c) 2014 - 2017 Yoshihiro Ota
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -33,11 +32,14 @@ __FBSDID("$FreeBSD$");
 #include <sys/types.h>
 #include <sys/sysctl.h>
 
+/* #include <stdlib.h> */
 #include <inttypes.h>
 #include <string.h>
+#include <err.h>
 
 #include "systat.h"
 #include "extern.h"
+#include "devs.h"
 
 struct zfield{
 	uint64_t arcstats;
@@ -77,21 +79,23 @@ 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); \
+#define L(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, row, 31+4, "%%"); ++row
+	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)
@@ -131,6 +135,7 @@ domode(struct zarcstats *delta, struct zarcstats *rate
 void
 showzarc(void)
 {
+	int row = 1;
 	struct zarcstats delta, rate;
 
 	memset(&delta, 0, sizeof delta);
@@ -138,34 +143,37 @@ showzarc(void)
 
 	domode(&delta, &rate);
 
-#define DO(stat, row, col, fmt) \
+#define DO(stat, col, fmt) \
 	mvwprintw(wnd, row, col, fmt, stat)
-#define	R(row, stat) DO(rate.hits.stat, row, 31+1, "%3"PRIu64)
-#define	H(row, stat) DO(delta.hits.stat, row, 31+1+5, "%7"PRIu64); \
-	DO(curstat.hits.stat, row, 31+1+5+8+8, "%12"PRIu64)
-#define	M(row, stat) DO(delta.misses.stat, row, 31+1+5+8, "%7"PRIu64); \
-	DO(curstat.misses.stat, row, 31+1+5+8+8+13, "%12"PRIu64)
-#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	R(stat) DO(rate.hits.stat, 31+1, "%3"PRIu64)
+#define	H(stat) DO(delta.hits.stat, 31+1+5, "%7"PRIu64); \
+	DO(curstat.hits.stat, 31+1+5+8+8, "%12"PRIu64)
+#define	M(stat) DO(delta.misses.stat, 31+1+5+8, "%7"PRIu64); \
+	DO(curstat.misses.stat, 31+1+5+8+8+13, "%12"PRIu64)
+#define	E(stat) R(stat); H(stat); M(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
+	dsshow(12, 0, 18, &cur_dev, &last_dev);
 }
 
 int
 initzarc(void)
 {
+	dsinit(12);
 	getinfo(&initstat);
 	curstat = oldstat = initstat;
+
 	return 1;
 }
 
@@ -178,6 +186,15 @@ resetzarc(void)
 static void
 getinfo(struct zarcstats *ls)
 {
+	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 )



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