Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 Nov 2002 09:40:21 -0800 (PST)
From:      Nadav Eiron <nadav+freebsd@TheEirons.org>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   bin/45486: Support for human readble (-h/-H) output in swapinfo(8)
Message-ID:  <200211191740.gAJHeLl9018150@piglet.theeirons.org>

next in thread | raw e-mail | index | archive | help

>Number:         45486
>Category:       bin
>Synopsis:       Support for human readble (-h/-H) output in swapinfo(8)
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue Nov 19 09:40:01 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Nadav Eiron
>Release:        FreeBSD 4.5-STABLE i386
>Organization:
>Environment:
System: FreeBSD piglet.TheEirons.org 4.5-STABLE FreeBSD 4.5-STABLE #1: Sat Apr 6 16:43:10 PST 2002 nadav@piglet.TheEirons.org:/disk0f/obj/usr/src/sys/PIGLET i386
Patches are included both for 4-STABLE and 5-CURRENT

	
>Description:
pstat -s (a.k.a. swapindo) doesn't have an option to display "human readble"
formatted sizes, similar to df -h or df -H
	
>How-To-Repeat:
swapinfo
Now try to figure out whether you have 200MB or 2GB of swap :-)
	
>Fix:
The .shar archive below contains patches (to be applied in src/usr.sbin/pstat)
for both 4-STABLE and 5-CURRENT.

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	pstat_current.diff
#	pstat_stable.diff
#
echo x - pstat_current.diff
sed 's/^X//' >pstat_current.diff << 'END-of-pstat_current.diff'
XIndex: Makefile
X===================================================================
XRCS file: /home/ncvs/src/usr.sbin/pstat/Makefile,v
Xretrieving revision 1.11
Xdiff -r1.11 Makefile
X12c12
X< LDADD=	-lkvm
X---
X> LDADD=	-lkvm -lm
XIndex: pstat.8
X===================================================================
XRCS file: /home/ncvs/src/usr.sbin/pstat/pstat.8,v
Xretrieving revision 1.38
Xdiff -r1.38 pstat.8
X51c51
X< .Op Fl Tfknst
X---
X> .Op Fl HTfhknst
X56c56
X< .Op Fl k
X---
X> .Op Fl Hhk
X69a70,72
X> .Fl H,
X> .Fl h,
X> and
X71c74
X< option is legal.
X---
X> options are legal.
X80a84,91
X> .It Fl H
X> "Human-readable" output of device sizes.  Use unit suffixes: Byte,
X> Kilobyte, Megabyte, Gigabyte, Terabyte and Petabyte in order to reduce
X> the number of digits to three or less using base 10 for sizes.
X> .It Fl h
X> "Human-readable" output of device sizes.  Use unit suffixes: Byte,
X> Kilobyte, Megabyte, Gigabyte, Terabyte and Petabyte in order to reduce
X> the number of digits to three or less using base 2 for sizes.
XIndex: pstat.c
X===================================================================
XRCS file: /home/ncvs/src/usr.sbin/pstat/pstat.c,v
Xretrieving revision 1.78
Xdiff -r1.78 pstat.c
X72a73
X> #include <math.h>
X96a98
X> static int	hflag;
X109a112,136
X> #define UNITS_SI 1
X> #define UNITS_2 2
X> 
X> #define KILO_SZ(n) (n)
X> #define MEGA_SZ(n) ((n) * (n))
X> #define GIGA_SZ(n) ((n) * (n) * (n))
X> #define TERA_SZ(n) ((n) * (n) * (n) * (n))
X> #define PETA_SZ(n) ((n) * (n) * (n) * (n) * (n))
X> 
X> #define KILO_2_SZ (KILO_SZ(1024ULL))
X> #define MEGA_2_SZ (MEGA_SZ(1024ULL))
X> #define GIGA_2_SZ (GIGA_SZ(1024ULL))
X> #define TERA_2_SZ (TERA_SZ(1024ULL))
X> #define PETA_2_SZ (PETA_SZ(1024ULL))
X> 
X> #define KILO_SI_SZ (KILO_SZ(1000ULL))
X> #define MEGA_SI_SZ (MEGA_SZ(1000ULL))
X> #define GIGA_SI_SZ (GIGA_SZ(1000ULL))
X> #define TERA_SI_SZ (TERA_SZ(1000ULL))
X> #define PETA_SI_SZ (PETA_SZ(1000ULL))
X> 
X> static unsigned long long vals_si [] = {1, KILO_SI_SZ, MEGA_SI_SZ, GIGA_SI_SZ, TERA_SI_SZ, PETA_SI_SZ};
X> static unsigned long long vals_base2[] = {1, KILO_2_SZ, MEGA_2_SZ, GIGA_2_SZ, TERA_2_SZ, PETA_2_SZ};
X> static unsigned long long *valp;
X> 
X127,128c154,155
X< 		opts = "kM:N:";
X< 		usagestr = "swapinfo [-k] [-M core] [-N system]";
X---
X> 		opts = "hHkM:N:";
X> 		usagestr = "swapinfo [-hHk] [-M core] [-N system]";
X130,131c157,158
X< 		opts = "TM:N:fknst";
X< 		usagestr = "pstat [-Tfknst] [-M core] [-N system]";
X---
X> 		opts = "TM:N:fHhknst";
X> 		usagestr = "pstat [-TfhHknst] [-M core] [-N system]";
X138a166,173
X> 		case 'H':
X> 			hflag = UNITS_SI;
X> 			valp = vals_si;
X> 			break;
X> 		case 'h':
X> 			hflag = UNITS_2;
X> 			valp = vals_base2;
X> 			break;
X140a176
X> 			hflag=0;
X462a499,502
X> typedef enum { NONE, KILO, MEGA, GIGA, TERA, PETA, UNIT_MAX } unit_t;
X> 
X> static unit_t unitp [] = { NONE, KILO, MEGA, GIGA, TERA, PETA };
X> 
X466a507,549
X> /*
X>  * Output in "human-readable" format.  Uses 3 digits max and puts
X>  * unit suffixes at the end.  Makes output compact and easy to read,
X>  * especially on huge disks.
X>  * Shamelessly copied from df(1)
X>  *
X>  */
X> static unit_t
X> unit_adjust(double *val)
X> {
X> 	double abval;
X> 	unit_t unit;
X> 	unsigned int unit_sz;
X> 
X> 	abval = fabs(*val);
X> 
X> 	unit_sz = abval ? ilogb(abval) / 10 : 0;
X> 
X> 	if (unit_sz >= UNIT_MAX) {
X> 		unit = NONE;
X> 	} else {
X> 		unit = unitp[unit_sz];
X> 		*val /= (double)valp[unit_sz];
X> 	}
X> 
X> 	return (unit);
X> }
X> 
X> static void
X> prthumanval(int width,double bytes)
X> {
X> 
X> 	unit_t unit;
X> 	unit = unit_adjust(&bytes);
X> 
X> 	if (bytes == 0)
X> 		(void)printf("%*sB ", width-1, "0");
X> 	else if (bytes > 10)
X> 		(void)printf("%*.0f%c ", width-1, bytes, "BKMGTPE"[unit]);
X> 	else
X> 		(void)printf("%*.1f%c ", width-1, bytes, "BKMGTPE"[unit]);
X> }
X> 
X474a558,559
X> 	if (hflag)
X> 		header = "Size";
X494,499c579,597
X< 		(void)printf("%-15s %*d ",
X< 		    ksw->ksw_devname, (int)hlen,
X< 		    CONVERT(ksw->ksw_total));
X< 		(void)printf("%8d %8d %5.0f%%    %s\n",
X< 		    CONVERT(ksw->ksw_used),
X< 		    CONVERT(ksw->ksw_total - ksw->ksw_used),
X---
X> 		(void)printf("%-15s ",
X> 			     ksw->ksw_devname);
X> 		if (hflag) {
X> 			prthumanval((int)hlen,pagesize * ksw->ksw_total);
X> 			prthumanval(8,pagesize * ksw->ksw_used);
X> 			prthumanval(8,pagesize * (ksw->ksw_total - ksw->ksw_used));
X> 		} else {
X> 			(void)printf(
X> 				     "%*d ",
X> 				     (int)hlen,
X> 				     CONVERT(ksw->ksw_total)
X> 				     );
X> 			(void)printf(
X> 				     "%8d %8d ",
X> 				     CONVERT(ksw->ksw_used),
X> 				     CONVERT(ksw->ksw_total - ksw->ksw_used)
X> 				     );
X> 		}
X> 		(void)printf("%5.0f%%    %s\n",
X520,524c618,630
X< 		(void)printf("%-15s %*d %8d %8d %5.0f%%\n",
X< 		    "Total", (int)hlen, CONVERT(swtot.ksw_total),
X< 		    CONVERT(swtot.ksw_used),
X< 		    CONVERT(swtot.ksw_total - swtot.ksw_used),
X< 		    (swtot.ksw_used * 100.0) / swtot.ksw_total);
X---
X> 		(void)printf("%-15s ",
X> 			     "Total");
X> 		if (hflag) {
X> 			prthumanval((int)hlen,pagesize * swtot.ksw_total);
X> 			prthumanval(8,pagesize * swtot.ksw_used);
X> 			prthumanval(8,pagesize * (swtot.ksw_total - swtot.ksw_used));
X> 		} else {
X> 			(void)printf("%*d %8d %8d %5.0f%%\n",
X> 				     (int)hlen, CONVERT(swtot.ksw_total),
X> 				     CONVERT(swtot.ksw_used),
X> 				     CONVERT(swtot.ksw_total - swtot.ksw_used),
X> 				     (swtot.ksw_used * 100.0) / swtot.ksw_total);
X> 		}
END-of-pstat_current.diff
echo x - pstat_stable.diff
sed 's/^X//' >pstat_stable.diff << 'END-of-pstat_stable.diff'
XIndex: Makefile
X===================================================================
XRCS file: /home/ncvs/src/usr.sbin/pstat/Makefile,v
Xretrieving revision 1.5.6.1
Xdiff -r1.5.6.1 Makefile
X9c9
X< LDADD=	-lkvm
X---
X> LDADD=	-lkvm -lm
XIndex: pstat.8
X===================================================================
XRCS file: /home/ncvs/src/usr.sbin/pstat/pstat.8,v
Xretrieving revision 1.19.2.10
Xdiff -r1.19.2.10 pstat.8
X44c44
X< .Op Fl Tfknst
X---
X> .Op Fl HTfhknst
X49c49
X< .Op Fl k
X---
X> .Op Fl Hhk
X61a62,64
X> .Fl H,
X> .Fl h,
X> and
X63c66
X< option is legal.
X---
X> options are legal.
X72a76,83
X> .It Fl H
X> "Human-readable" output of device sizes.  Use unit suffixes: Byte,
X> Kilobyte, Megabyte, Gigabyte, Terabyte and Petabyte in order to reduce
X> the number of digits to three or less using base 10 for sizes.
X> .It Fl h
X> "Human-readable" output of device sizes.  Use unit suffixes: Byte,
X> Kilobyte, Megabyte, Gigabyte, Terabyte and Petabyte in order to reduce
X> the number of digits to three or less using base 2 for sizes.
XIndex: pstat.c
X===================================================================
XRCS file: /home/ncvs/src/usr.sbin/pstat/pstat.c,v
Xretrieving revision 1.49.2.5
Xdiff -r1.49.2.5 pstat.c
X78a79
X> #include <math.h>
X132a134
X> int	hflag;
X194a197,225
X> #define UNITS_SI 1
X> #define UNITS_2 2
X> 
X> #define KILO_SZ(n) (n)
X> #define MEGA_SZ(n) ((n) * (n))
X> #define GIGA_SZ(n) ((n) * (n) * (n))
X> #define TERA_SZ(n) ((n) * (n) * (n) * (n))
X> #define PETA_SZ(n) ((n) * (n) * (n) * (n) * (n))
X> 
X> #define KILO_2_SZ (KILO_SZ(1024ULL))
X> #define MEGA_2_SZ (MEGA_SZ(1024ULL))
X> #define GIGA_2_SZ (GIGA_SZ(1024ULL))
X> #define TERA_2_SZ (TERA_SZ(1024ULL))
X> #define PETA_2_SZ (PETA_SZ(1024ULL))
X> 
X> #define KILO_SI_SZ (KILO_SZ(1000ULL))
X> #define MEGA_SI_SZ (MEGA_SZ(1000ULL))
X> #define GIGA_SI_SZ (GIGA_SZ(1000ULL))
X> #define TERA_SI_SZ (TERA_SZ(1000ULL))
X> #define PETA_SI_SZ (PETA_SZ(1000ULL))
X> 
X> unsigned long long vals_si [] = {1, KILO_SI_SZ, MEGA_SI_SZ, GIGA_SI_SZ, TERA_SI_SZ, PETA_SI_SZ};
X> unsigned long long vals_base2[] = {1, KILO_2_SZ, MEGA_2_SZ, GIGA_2_SZ, TERA_2_SZ, PETA_2_SZ};
X> unsigned long long *valp;
X> 
X> typedef enum { NONE, KILO, MEGA, GIGA, TERA, PETA, UNIT_MAX } unit_t;
X> 
X> unit_t unitp [] = { NONE, KILO, MEGA, GIGA, TERA, PETA };
X> 
X217a249,250
X> unit_t	  unit_adjust(double *);
X> void	prthumanval(int width,double bytes);
X238,239c271,272
X< 		opts = "kM:N:";
X< 		usagestr = "swapinfo [-k] [-M core] [-N system]";
X---
X> 		opts = "hHkM:N:";
X> 		usagestr = "swapinfo [-hHk] [-M core] [-N system]";
X241,242c274,275
X< 		opts = "TM:N:fiknstv";
X< 		usagestr = "pstat [-Tfknst] [-M core] [-N system]";
X---
X> 		opts = "TM:N:fhHiknstv";
X> 		usagestr = "pstat [-TfhHknst] [-M core] [-N system]";
X249a283,290
X> 		case 'H':
X> 			hflag = UNITS_SI;
X> 			valp = vals_si;
X> 			break;
X> 		case 'h':
X> 			hflag = UNITS_2;
X> 			valp = vals_base2;
X> 			break;
X251a293
X> 			hflag=0;
X1018a1061
X> 	if (hflag) header = "  Size";
X1024a1068,1086
X> 		        (void)printf(
X> 				     "%-15s ",
X> 				     kswap[i].ksw_devname);
X> 			if (hflag) {
X> 				prthumanval(hlen,pagesize * kswap[i].ksw_total);
X> 				prthumanval(8,pagesize * kswap[i].ksw_used);
X> 				prthumanval(8,pagesize * (kswap[i].ksw_total - kswap[i].ksw_used));
X> 			} else {
X> 				(void)printf(
X> 					     "%*d ",
X> 					     hlen,
X> 					     CONVERT(kswap[i].ksw_total)
X> 					     );
X> 				(void)printf(
X> 					     "%8d %8d ",
X> 					     CONVERT(kswap[i].ksw_used),
X> 					     CONVERT(kswap[i].ksw_total - kswap[i].ksw_used)
X> 					     );
X> 			}
X1026,1039c1088,1093
X< 			    "%-15s %*d ",
X< 			    kswap[i].ksw_devname,
X< 			    hlen,
X< 			    CONVERT(kswap[i].ksw_total)
X< 			);
X< 			(void)printf(
X< 			    "%8d %8d %5.0f%%    %s\n",
X< 			    CONVERT(kswap[i].ksw_used),
X< 			    CONVERT(kswap[i].ksw_total - kswap[i].ksw_used),
X< 			    (double)kswap[i].ksw_used * 100.0 /
X< 				(double)kswap[i].ksw_total,
X< 			    (kswap[i].ksw_flags & SW_SEQUENTIAL) ?
X< 				"Sequential" : "Interleaved"
X< 			);
X---
X> 				     "%5.0f%%    %s\n",
X> 				     (double)kswap[i].ksw_used * 100.0 /
X> 				     (double)kswap[i].ksw_total,
X> 				     (kswap[i].ksw_flags & SW_SEQUENTIAL) ?
X> 				     "Sequential" : "Interleaved"
X> 				     );
X1053,1061c1107,1153
X< 		    "%-15s %*d %8d %8d %5.0f%%\n",
X< 		    "Total",
X< 		    hlen, 
X< 		    CONVERT(kswap[n].ksw_total),
X< 		    CONVERT(kswap[n].ksw_used),
X< 		    CONVERT(kswap[n].ksw_total - kswap[n].ksw_used),
X< 		    (double)kswap[n].ksw_used * 100.0 /
X< 			(double)kswap[n].ksw_total
X< 		);
X---
X> 			     "%-15s ","Total");
X> 		if (hflag) {
X> 			prthumanval(hlen,pagesize * kswap[n].ksw_total);
X> 			prthumanval(8,pagesize * kswap[n].ksw_used);
X> 			prthumanval(8,pagesize * (kswap[n].ksw_total - kswap[n].ksw_used));
X> 		} else {
X> 			(void)printf(
X> 				     "%*d ",
X> 				     hlen,
X> 				     CONVERT(kswap[n].ksw_total)
X> 				     );
X> 			(void)printf(
X> 				     "%8d %8d ",
X> 				     CONVERT(kswap[n].ksw_used),
X> 				     CONVERT(kswap[n].ksw_total - kswap[n].ksw_used)
X> 				     );
X> 		}
X> 		(void)printf(
X> 			     "%5.0f%%\n",
X> 			     (double)kswap[n].ksw_used * 100.0 /
X> 			     (double)kswap[n].ksw_total);
X> 	}
X> }
X> 
X> /*
X>  * Output in "human-readable" format.  Uses 3 digits max and puts
X>  * unit suffixes at the end.  Makes output compact and easy to read,
X>  * especially on huge disks.
X>  * Shamelessly copied from df(1)
X>  *
X>  */
X> unit_t
X> unit_adjust(double *val)
X> {
X> 	double abval;
X> 	unit_t unit;
X> 	unsigned int unit_sz;
X> 
X> 	abval = fabs(*val);
X> 
X> 	unit_sz = abval ? ilogb(abval) / 10 : 0;
X> 
X> 	if (unit_sz >= UNIT_MAX) {
X> 		unit = NONE;
X> 	} else {
X> 		unit = unitp[unit_sz];
X> 		*val /= (double)valp[unit_sz];
X1062a1155,1171
X> 
X> 	return (unit);
X> }
X> 
X> void
X> prthumanval(int width,double bytes)
X> {
X> 
X> 	unit_t unit;
X> 	unit = unit_adjust(&bytes);
X> 
X> 	if (bytes == 0)
X> 		(void)printf("%*sB ", width-1, "0");
X> 	else if (bytes > 10)
X> 		(void)printf("%*.0f%c ", width-1, bytes, "BKMGTPE"[unit]);
X> 	else
X> 		(void)printf("%*.1f%c ", width-1, bytes, "BKMGTPE"[unit]);
END-of-pstat_stable.diff
exit

	


>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




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