17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5f5cd957fSRobert Harris  * Common Development and Distribution License (the "License").
6f5cd957fSRobert Harris  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
2226fd7700SKrishnendu Sadhukhan - Sun Microsystems  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate /*
277c478bd9Sstevel@tonic-gate  * poolstat - report active pool statistics
287c478bd9Sstevel@tonic-gate  */
297c478bd9Sstevel@tonic-gate #include <stdio.h>
307c478bd9Sstevel@tonic-gate #include <unistd.h>
317c478bd9Sstevel@tonic-gate #include <stdlib.h>
327c478bd9Sstevel@tonic-gate #include <unistd.h>
337c478bd9Sstevel@tonic-gate #include <locale.h>
347c478bd9Sstevel@tonic-gate #include <string.h>
357c478bd9Sstevel@tonic-gate #include <ctype.h>
367c478bd9Sstevel@tonic-gate #include <limits.h>
377c478bd9Sstevel@tonic-gate #include <errno.h>
385c5f1371SRichard Lowe #include <stddef.h>
397c478bd9Sstevel@tonic-gate 
407c478bd9Sstevel@tonic-gate #include <pool.h>
417c478bd9Sstevel@tonic-gate #include "utils.h"
427c478bd9Sstevel@tonic-gate #include "poolstat.h"
437c478bd9Sstevel@tonic-gate #include "poolstat_utils.h"
4426fd7700SKrishnendu Sadhukhan - Sun Microsystems #include "statcommon.h"
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate #ifndef	TEXT_DOMAIN
477c478bd9Sstevel@tonic-gate #define	TEXT_DOMAIN	"SYS_TEST"
487c478bd9Sstevel@tonic-gate #endif
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate #define	addrof(s)  ((char **)&(s))
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate /* verify if a field is printable in respect of the current option flags */
537c478bd9Sstevel@tonic-gate #define	PRINTABLE(i)	((lf->plf_ffs[(i)].pff_prt & D_FIELD) || \
547c478bd9Sstevel@tonic-gate 	(lf->plf_ffs[(i)].pff_prt & X_FIELD))
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate typedef int (* formatter) (char *, int, int, poolstat_field_format_t *, char *);
577c478bd9Sstevel@tonic-gate 
5826fd7700SKrishnendu Sadhukhan - Sun Microsystems static uint_t timestamp_fmt = NODATE;
5926fd7700SKrishnendu Sadhukhan - Sun Microsystems 
607c478bd9Sstevel@tonic-gate /* available field formatters	*/
617c478bd9Sstevel@tonic-gate static int default_f(char *, int, int, poolstat_field_format_t *, char *);
627c478bd9Sstevel@tonic-gate static int bigno_f(char *, int, int, poolstat_field_format_t *, char *);
637c478bd9Sstevel@tonic-gate static int used_stat_f(char *, int, int, poolstat_field_format_t *, char *);
647c478bd9Sstevel@tonic-gate static int header_f(char *, int, int, poolstat_field_format_t *, char *);
657c478bd9Sstevel@tonic-gate 
667c478bd9Sstevel@tonic-gate /* statistics bags used to collect data from various provider	*/
677c478bd9Sstevel@tonic-gate static statistic_bag_t 	pool_sbag_s;
687c478bd9Sstevel@tonic-gate static statistic_bag_t 	pset_sbag_s;
697c478bd9Sstevel@tonic-gate static statistic_bag_t 	*pool_sbag = &pool_sbag_s;
707c478bd9Sstevel@tonic-gate static statistic_bag_t 	*pset_sbag = &pset_sbag_s;
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate /* formatter objects for pset, defined in a default printing sequence	*/
737c478bd9Sstevel@tonic-gate static poolstat_field_format_t pset_ffs[] = {
747c478bd9Sstevel@tonic-gate 	/* prt flags,name,header,type,width,minwidth,offset,formatter	*/
757c478bd9Sstevel@tonic-gate 	{ DX_FIELD, "id", "id", LL, 3, 1, addrof(pool_sbag),
767c478bd9Sstevel@tonic-gate 		offsetof(statistic_bag_t, sb_sysid),
777c478bd9Sstevel@tonic-gate 		(formatter)default_f },
787c478bd9Sstevel@tonic-gate 	{ DX_FIELD, "pool", "pool", STR, 20, 14, addrof(pool_sbag),
797c478bd9Sstevel@tonic-gate 		offsetof(statistic_bag_t, sb_name),
807c478bd9Sstevel@tonic-gate 		(formatter)default_f },
817c478bd9Sstevel@tonic-gate 	{ DX_FIELD, "type", "type", STR, 4, 5, addrof(pset_sbag),
827c478bd9Sstevel@tonic-gate 		offsetof(statistic_bag_t, sb_type),
837c478bd9Sstevel@tonic-gate 		(formatter)default_f },
847c478bd9Sstevel@tonic-gate 	{ D_FIELD, "rid", "rid", LL, 3, 1, addrof(pset_sbag_s.bag),
857c478bd9Sstevel@tonic-gate 		offsetof(pset_statistic_bag_t, pset_sb_sysid),
867c478bd9Sstevel@tonic-gate 		(formatter)default_f },
877c478bd9Sstevel@tonic-gate 	{ DX_FIELD, "rset", "rset", STR, 20, 14, addrof(pset_sbag),
887c478bd9Sstevel@tonic-gate 		offsetof(statistic_bag_t, sb_name),
897c478bd9Sstevel@tonic-gate 		(formatter)default_f },
907c478bd9Sstevel@tonic-gate 	{ DX_FIELD, "min", "min", ULL, 4, 1, addrof(pset_sbag_s.bag),
917c478bd9Sstevel@tonic-gate 		offsetof(pset_statistic_bag_t, pset_sb_min),
927c478bd9Sstevel@tonic-gate 		(formatter)bigno_f },
937c478bd9Sstevel@tonic-gate 	{ DX_FIELD, "max", "max", ULL, 4, 1, addrof(pset_sbag_s.bag),
947c478bd9Sstevel@tonic-gate 		offsetof(pset_statistic_bag_t, pset_sb_max),
957c478bd9Sstevel@tonic-gate 		(formatter)bigno_f },
967c478bd9Sstevel@tonic-gate 	{ DX_FIELD, "size", "size", ULL, 4, 1, addrof(pset_sbag_s.bag),
977c478bd9Sstevel@tonic-gate 		offsetof(pset_statistic_bag_t, pset_sb_size),
987c478bd9Sstevel@tonic-gate 		(formatter)default_f },
997c478bd9Sstevel@tonic-gate 	{ DX_FIELD, "used", "used", FL, 4, -1, addrof(pset_sbag_s.bag),
1007c478bd9Sstevel@tonic-gate 		offsetof(pset_statistic_bag_t, pset_sb_used),
1017c478bd9Sstevel@tonic-gate 		(formatter)used_stat_f },
1027c478bd9Sstevel@tonic-gate 	{ DX_FIELD, "load", "load", FL, 4, -1, addrof(pset_sbag_s.bag),
1037c478bd9Sstevel@tonic-gate 		offsetof(pset_statistic_bag_t, pset_sb_load),
1047c478bd9Sstevel@tonic-gate 		(formatter)default_f }
1057c478bd9Sstevel@tonic-gate };
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate /* formatter objects for pool, defined in a default printing sequence	*/
1087c478bd9Sstevel@tonic-gate static poolstat_field_format_t pool_ffs[] = {
1097c478bd9Sstevel@tonic-gate 	/* prt flags,name,header,type,width,minwidth,offset,formatter	*/
1107c478bd9Sstevel@tonic-gate 	{ D_FIELD, "id", "id", LL, 3, 1, addrof(pool_sbag),
1117c478bd9Sstevel@tonic-gate 		offsetof(statistic_bag_t, sb_sysid),
1127c478bd9Sstevel@tonic-gate 		(formatter)default_f },
1137c478bd9Sstevel@tonic-gate 	{ D_FIELD, "pool", "pool", STR, 20, 13, addrof(pool_sbag),
1147c478bd9Sstevel@tonic-gate 		offsetof(statistic_bag_t, sb_name),
1157c478bd9Sstevel@tonic-gate 		(formatter)default_f },
1167c478bd9Sstevel@tonic-gate 	{ D_FIELD, "p_size", "size", ULL, 4, 1, addrof(pset_sbag_s.bag),
1177c478bd9Sstevel@tonic-gate 		offsetof(pset_statistic_bag_t, pset_sb_size),
1187c478bd9Sstevel@tonic-gate 		(formatter)default_f },
1197c478bd9Sstevel@tonic-gate 	{ D_FIELD, "p_used", "used", FL, 4, -1, addrof(pset_sbag_s.bag),
1207c478bd9Sstevel@tonic-gate 		offsetof(pset_statistic_bag_t, pset_sb_used),
1217c478bd9Sstevel@tonic-gate 		(formatter)default_f },
1227c478bd9Sstevel@tonic-gate 	{ D_FIELD, "p_load", "load", FL, 4, -1, addrof(pset_sbag_s.bag),
1237c478bd9Sstevel@tonic-gate 		offsetof(pset_statistic_bag_t, pset_sb_load),
1247c478bd9Sstevel@tonic-gate 		(formatter)default_f },
1257c478bd9Sstevel@tonic-gate };
1267c478bd9Sstevel@tonic-gate 
1277c478bd9Sstevel@tonic-gate /* lists with formatter objects, one for each statistics field */
1287c478bd9Sstevel@tonic-gate static poolstat_line_format_t   pool_lf; /* formatting list in default mode */
1297c478bd9Sstevel@tonic-gate static poolstat_line_format_t   pset_lf; /* formatting list for psets    */
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate /* name of pools to be shown */
1327c478bd9Sstevel@tonic-gate static poolstat_list_element_t	*pnames;
1337c478bd9Sstevel@tonic-gate /*
1347c478bd9Sstevel@tonic-gate  * type of resources to be shown, currently we only have one type 'pset'
1357c478bd9Sstevel@tonic-gate  * but, poolstat can be extended to handle new upcoming resource types.
1367c478bd9Sstevel@tonic-gate  */
1377c478bd9Sstevel@tonic-gate static poolstat_list_element_t   *rtypes;
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate /* a handle to the pool configuration	*/
1407c478bd9Sstevel@tonic-gate static pool_conf_t *conf;
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate /* option flags		*/
1437c478bd9Sstevel@tonic-gate static int 	rflag;
1447c478bd9Sstevel@tonic-gate static int 	pflag;
1457c478bd9Sstevel@tonic-gate static int 	oflag;
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate /* operands	*/
1487c478bd9Sstevel@tonic-gate static int 	interval = 0;	/* update interval	*/
1497c478bd9Sstevel@tonic-gate static long 	count    = 1; 	/* one run		*/
1507c478bd9Sstevel@tonic-gate 
1517c478bd9Sstevel@tonic-gate /* data structure handlers	*/
1527c478bd9Sstevel@tonic-gate static poolstat_list_element_t *
1537c478bd9Sstevel@tonic-gate 	create_prt_sequence_list(char *, poolstat_line_format_t *);
1547c478bd9Sstevel@tonic-gate static poolstat_list_element_t *
1557c478bd9Sstevel@tonic-gate 	create_args_list(char *, poolstat_list_element_t *, const char *);
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate /* statistics update function	*/
1587c478bd9Sstevel@tonic-gate static void sa_update(statistic_bag_t *, int);
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate /* statistics printing function	*/
1617c478bd9Sstevel@tonic-gate static void prt_pool_stats(poolstat_list_element_t *);
1627c478bd9Sstevel@tonic-gate 
163430755dfSToomas Soome static void usage(void) __NORETURN;
164430755dfSToomas Soome 
1657c478bd9Sstevel@tonic-gate static void
usage(void)1667c478bd9Sstevel@tonic-gate usage(void)
1677c478bd9Sstevel@tonic-gate {
1687c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, gettext(
1697c478bd9Sstevel@tonic-gate "Usage:\n"
17026fd7700SKrishnendu Sadhukhan - Sun Microsystems "poolstat [-p pool-list] [-r rset-list] [-T d|u] [interval [count]]\n"
17126fd7700SKrishnendu Sadhukhan - Sun Microsystems "poolstat [-p pool-list] [-o format -r rset-list] [-T d|u] [interval [count]]\n"
1727c478bd9Sstevel@tonic-gate "  \'pool-list\' is a space-separated list of pool IDs or names\n"
1737c478bd9Sstevel@tonic-gate "  \'rset-list\' is \'all\' or \'pset\'\n"
1747c478bd9Sstevel@tonic-gate "  \'format\' for all resource types is one or more of:\n"
1757c478bd9Sstevel@tonic-gate "\tid pool type rid rset min max size used load\n"));
1767c478bd9Sstevel@tonic-gate 	(void) exit(E_USAGE);
1777c478bd9Sstevel@tonic-gate }
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate static int
Atoi(char * p,int * errp)1807c478bd9Sstevel@tonic-gate Atoi(char *p, int *errp)
1817c478bd9Sstevel@tonic-gate {
1827c478bd9Sstevel@tonic-gate 	int i;
1837c478bd9Sstevel@tonic-gate 	char *q;
1847c478bd9Sstevel@tonic-gate 	errno = 0;
1857c478bd9Sstevel@tonic-gate 	i = strtol(p, &q, 10);
1867c478bd9Sstevel@tonic-gate 	if (errno != 0 || q == p || *q != '\0')
1877c478bd9Sstevel@tonic-gate 		*errp = -1;
1887c478bd9Sstevel@tonic-gate 	else
1897c478bd9Sstevel@tonic-gate 		*errp = 0;
1907c478bd9Sstevel@tonic-gate 	return (i);
1917c478bd9Sstevel@tonic-gate }
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate int
main(int argc,char * argv[])1947c478bd9Sstevel@tonic-gate main(int argc, char *argv[])
1957c478bd9Sstevel@tonic-gate {
196*ef150c2bSRichard Lowe 	int		c;
1977c478bd9Sstevel@tonic-gate 	int 		error = 0;
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate 	(void) getpname(argv[0]);
2007c478bd9Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
2017c478bd9Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
2027c478bd9Sstevel@tonic-gate 
2037c478bd9Sstevel@tonic-gate 	/* pset_sbag_s is used to collect pset statistics   */
2047c478bd9Sstevel@tonic-gate 	pset_sbag_s.sb_type = PSET_TYPE_NAME;
2057c478bd9Sstevel@tonic-gate 	pset_sbag_s.bag	= ZALLOC(sizeof (pset_statistic_bag_t));
2067c478bd9Sstevel@tonic-gate 	pool_sbag_s.sb_type = POOL_TYPE_NAME;
2077c478bd9Sstevel@tonic-gate 
2087c478bd9Sstevel@tonic-gate 	pset_lf.plf_ffs = pset_ffs;
2097c478bd9Sstevel@tonic-gate 	pset_lf.plf_ff_len = sizeof (pset_ffs) /
210f5cd957fSRobert Harris 	    sizeof (poolstat_field_format_t);
2117c478bd9Sstevel@tonic-gate 	pool_lf.plf_ffs = pool_ffs;
2127c478bd9Sstevel@tonic-gate 	pool_lf.plf_ff_len = sizeof (pool_ffs) /
213f5cd957fSRobert Harris 	    sizeof (poolstat_field_format_t);
214f5cd957fSRobert Harris 
215f5cd957fSRobert Harris 	/* Don't let buffering interfere with piped output. */
216f5cd957fSRobert Harris 	(void) setvbuf(stdout, NULL, _IOLBF, 0);
2177c478bd9Sstevel@tonic-gate 
21826fd7700SKrishnendu Sadhukhan - Sun Microsystems 	while ((c = getopt(argc, argv, ":p:r:o:T:")) != EOF) {
2197c478bd9Sstevel@tonic-gate 		switch (c) {
2207c478bd9Sstevel@tonic-gate 		case 'p':	/* pool name specification	*/
2217c478bd9Sstevel@tonic-gate 			pflag++;
2227c478bd9Sstevel@tonic-gate 			pnames = create_args_list(optarg, pnames,
223f5cd957fSRobert Harris 			    " \t");
2247c478bd9Sstevel@tonic-gate 			break;
2257c478bd9Sstevel@tonic-gate 		case 'r': {	/* resource type 		*/
2267c478bd9Sstevel@tonic-gate 			rflag++;
2277c478bd9Sstevel@tonic-gate 			rtypes = create_args_list(optarg, rtypes,
228f5cd957fSRobert Harris 			    " \t,");
2297c478bd9Sstevel@tonic-gate 			break;
2307c478bd9Sstevel@tonic-gate 			}
2317c478bd9Sstevel@tonic-gate 		case 'o': { 	/* format specification		*/
2327c478bd9Sstevel@tonic-gate 			oflag++;
2337c478bd9Sstevel@tonic-gate 			if (create_prt_sequence_list(optarg, &pset_lf) == NULL)
2347c478bd9Sstevel@tonic-gate 				usage();
2357c478bd9Sstevel@tonic-gate 			break;
2367c478bd9Sstevel@tonic-gate 			}
23726fd7700SKrishnendu Sadhukhan - Sun Microsystems 		case 'T':
23826fd7700SKrishnendu Sadhukhan - Sun Microsystems 			if (optarg) {
23926fd7700SKrishnendu Sadhukhan - Sun Microsystems 				if (*optarg == 'u')
24026fd7700SKrishnendu Sadhukhan - Sun Microsystems 					timestamp_fmt = UDATE;
24126fd7700SKrishnendu Sadhukhan - Sun Microsystems 				else if (*optarg == 'd')
24226fd7700SKrishnendu Sadhukhan - Sun Microsystems 					timestamp_fmt = DDATE;
24326fd7700SKrishnendu Sadhukhan - Sun Microsystems 				else
24426fd7700SKrishnendu Sadhukhan - Sun Microsystems 					usage();
24526fd7700SKrishnendu Sadhukhan - Sun Microsystems 			} else {
24626fd7700SKrishnendu Sadhukhan - Sun Microsystems 					usage();
24726fd7700SKrishnendu Sadhukhan - Sun Microsystems 			}
24826fd7700SKrishnendu Sadhukhan - Sun Microsystems 			break;
2497c478bd9Sstevel@tonic-gate 		case ':': {
2507c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr,
251f5cd957fSRobert Harris 			    gettext(ERR_OPTION_ARGS), optopt);
2527c478bd9Sstevel@tonic-gate 			usage();
2537c478bd9Sstevel@tonic-gate 			/*NOTREACHED*/
2547c478bd9Sstevel@tonic-gate 			}
2557c478bd9Sstevel@tonic-gate 		default:
2567c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext(ERR_OPTION), optopt);
2577c478bd9Sstevel@tonic-gate 			usage();
2587c478bd9Sstevel@tonic-gate 			/*NOTREACHED*/
2597c478bd9Sstevel@tonic-gate 		}
2607c478bd9Sstevel@tonic-gate 	}
2617c478bd9Sstevel@tonic-gate 
2627c478bd9Sstevel@tonic-gate 	/* get operands	*/
2637c478bd9Sstevel@tonic-gate 	if (argc > optind) {
2647c478bd9Sstevel@tonic-gate 		if ((interval = Atoi(argv[optind++], &error)) < 1 || error != 0)
2657c478bd9Sstevel@tonic-gate 			usage();
2667c478bd9Sstevel@tonic-gate 		count = -1;
2677c478bd9Sstevel@tonic-gate 	}
2687c478bd9Sstevel@tonic-gate 	if (argc > optind) {
2697c478bd9Sstevel@tonic-gate 		if ((count = Atoi(argv[optind++], &error)) < 1 || error != 0)
2707c478bd9Sstevel@tonic-gate 			usage();
2717c478bd9Sstevel@tonic-gate 	}
2727c478bd9Sstevel@tonic-gate 	/* check for extra options/operands	*/
2737c478bd9Sstevel@tonic-gate 	if (argc > optind)
2747c478bd9Sstevel@tonic-gate 		usage();
2757c478bd9Sstevel@tonic-gate 
2767c478bd9Sstevel@tonic-gate 	/* check options	*/
2777c478bd9Sstevel@tonic-gate 	if (oflag && !rflag)
2787c478bd9Sstevel@tonic-gate 		usage();
2797c478bd9Sstevel@tonic-gate 
2807c478bd9Sstevel@tonic-gate 	/* global initializations	*/
2817c478bd9Sstevel@tonic-gate 	if (!oflag) {
2827c478bd9Sstevel@tonic-gate 		/* create the default print sequences	*/
2837c478bd9Sstevel@tonic-gate 		(void) create_prt_sequence_list(NULL, &pool_lf);
2847c478bd9Sstevel@tonic-gate 		(void) create_prt_sequence_list(NULL, &pset_lf);
2857c478bd9Sstevel@tonic-gate 	}
2867c478bd9Sstevel@tonic-gate 
2877c478bd9Sstevel@tonic-gate 	if (rtypes == NULL || strcmp(rtypes->ple_obj, "all") == 0) {
2887c478bd9Sstevel@tonic-gate 		/* crate a default resource list	*/
2897c478bd9Sstevel@tonic-gate 		FREE(rtypes);
2907c478bd9Sstevel@tonic-gate 		rtypes = create_args_list("pset", NULL, " \t,");
2917c478bd9Sstevel@tonic-gate 	}
2927c478bd9Sstevel@tonic-gate 
2937c478bd9Sstevel@tonic-gate 	if ((conf = pool_conf_alloc()) == NULL)
2947c478bd9Sstevel@tonic-gate 		die(gettext(ERR_NOMEM));
2957c478bd9Sstevel@tonic-gate 	if (pool_conf_open(conf, pool_dynamic_location(), PO_RDONLY)
296f5cd957fSRobert Harris 	    != PO_SUCCESS)
2977c478bd9Sstevel@tonic-gate 		die(gettext(ERR_OPEN_DYNAMIC), get_errstr());
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate 	/* initialize statistic adapters	*/
3007c478bd9Sstevel@tonic-gate 	sa_libpool_init(conf);
3017c478bd9Sstevel@tonic-gate 	sa_kstat_init(NULL);
3027c478bd9Sstevel@tonic-gate 
3037c478bd9Sstevel@tonic-gate 	/* collect and print out statistics	*/
3047c478bd9Sstevel@tonic-gate 	while (count-- != 0) {
3057c478bd9Sstevel@tonic-gate 		sa_update(pool_sbag, SA_REFRESH);
30626fd7700SKrishnendu Sadhukhan - Sun Microsystems 		if (timestamp_fmt != NODATE)
30726fd7700SKrishnendu Sadhukhan - Sun Microsystems 			print_timestamp(timestamp_fmt);
3087c478bd9Sstevel@tonic-gate 		if (pool_sbag->sb_changed & POU_POOL)
3097c478bd9Sstevel@tonic-gate 				(void) printf(
3107c478bd9Sstevel@tonic-gate 				"<<State change>>\n");
3117c478bd9Sstevel@tonic-gate 		prt_pool_stats(pnames);
3127c478bd9Sstevel@tonic-gate 		if (count != 0) {
3137c478bd9Sstevel@tonic-gate 			(void) sleep(interval);
3147c478bd9Sstevel@tonic-gate 			if (rflag)
3157c478bd9Sstevel@tonic-gate 				(void) printf("\n");
3167c478bd9Sstevel@tonic-gate 		}
3177c478bd9Sstevel@tonic-gate 	}
3187c478bd9Sstevel@tonic-gate 
3197c478bd9Sstevel@tonic-gate 	return (E_PO_SUCCESS);
3207c478bd9Sstevel@tonic-gate }
3217c478bd9Sstevel@tonic-gate 
3227c478bd9Sstevel@tonic-gate /*
3237c478bd9Sstevel@tonic-gate  * Take the arguments and create/append a string list to the 'le' list.
3247c478bd9Sstevel@tonic-gate  */
3257c478bd9Sstevel@tonic-gate static poolstat_list_element_t  *
create_args_list(char * arg,poolstat_list_element_t * le,const char * delim)3267c478bd9Sstevel@tonic-gate create_args_list(char *arg, poolstat_list_element_t  *le, const char *delim)
3277c478bd9Sstevel@tonic-gate {
3287c478bd9Sstevel@tonic-gate 	poolstat_list_element_t *head = le;
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate 	while (arg != NULL && *arg != '\0') {
3317c478bd9Sstevel@tonic-gate 		char *name = arg;
3327c478bd9Sstevel@tonic-gate 		arg = strpbrk(arg, delim);
3337c478bd9Sstevel@tonic-gate 		if (arg != NULL) {
3347c478bd9Sstevel@tonic-gate 			*arg++ = '\0';
3357c478bd9Sstevel@tonic-gate 		}
3367c478bd9Sstevel@tonic-gate 		if (le == NULL) {
3377c478bd9Sstevel@tonic-gate 			/* create first element */
3387c478bd9Sstevel@tonic-gate 			NEW0(le);
3397c478bd9Sstevel@tonic-gate 			head = le;
3407c478bd9Sstevel@tonic-gate 		} else {
3417c478bd9Sstevel@tonic-gate 			/* find last and append	*/
3427c478bd9Sstevel@tonic-gate 			while (le->ple_next != NULL)
3437c478bd9Sstevel@tonic-gate 				le = le->ple_next;
3447c478bd9Sstevel@tonic-gate 			NEW0(le->ple_next);
3457c478bd9Sstevel@tonic-gate 			le = le->ple_next;
3467c478bd9Sstevel@tonic-gate 		}
3477c478bd9Sstevel@tonic-gate 		le->ple_obj = (void *)name;
3487c478bd9Sstevel@tonic-gate 	}
3497c478bd9Sstevel@tonic-gate 
3507c478bd9Sstevel@tonic-gate 	return (head);
3517c478bd9Sstevel@tonic-gate }
3527c478bd9Sstevel@tonic-gate 
3537c478bd9Sstevel@tonic-gate /*
3547c478bd9Sstevel@tonic-gate  * Take the arguments to the -o option, and create a format field list in order
3557c478bd9Sstevel@tonic-gate  * specified by 'arg'.
3567c478bd9Sstevel@tonic-gate  * If 'arg' is NULL a list in a default printing order is created.
3577c478bd9Sstevel@tonic-gate  */
3587c478bd9Sstevel@tonic-gate static poolstat_list_element_t *
create_prt_sequence_list(char * arg,poolstat_line_format_t * lf)3597c478bd9Sstevel@tonic-gate create_prt_sequence_list(char *arg, poolstat_line_format_t *lf)
3607c478bd9Sstevel@tonic-gate {
3617c478bd9Sstevel@tonic-gate 	/*
3627c478bd9Sstevel@tonic-gate 	 * Create a default print sequence. It is the sequence defined
3637c478bd9Sstevel@tonic-gate 	 * statically in the format list. At the same time mark the fields
3647c478bd9Sstevel@tonic-gate 	 * printable according to the current option settings.
3657c478bd9Sstevel@tonic-gate 	 */
3667c478bd9Sstevel@tonic-gate 	if (arg == NULL) {
3677c478bd9Sstevel@tonic-gate 		int	i;
3687c478bd9Sstevel@tonic-gate 		NEW0(lf->plf_prt_seq);
3697c478bd9Sstevel@tonic-gate 		lf->plf_ffs[0].pff_prt |= PRINTABLE(0) ? PABLE_FIELD : 0;
3707c478bd9Sstevel@tonic-gate 		lf->plf_last = lf->plf_prt_seq;
3717c478bd9Sstevel@tonic-gate 		lf->plf_last->ple_obj = &(lf->plf_ffs[0]);
3727c478bd9Sstevel@tonic-gate 		for (i = 1; i < lf->plf_ff_len; i++) {
3737c478bd9Sstevel@tonic-gate 			lf->plf_ffs[i].pff_prt |=
374f5cd957fSRobert Harris 			    PRINTABLE(i) ? PABLE_FIELD : 0;
3757c478bd9Sstevel@tonic-gate 			NEW0(lf->plf_last->ple_next);
3767c478bd9Sstevel@tonic-gate 			lf->plf_last = lf->plf_last->ple_next;
3777c478bd9Sstevel@tonic-gate 			lf->plf_last->ple_obj = &(lf->plf_ffs[i]);
3787c478bd9Sstevel@tonic-gate 		}
3797c478bd9Sstevel@tonic-gate 		return (lf->plf_prt_seq);
3807c478bd9Sstevel@tonic-gate 	}
3817c478bd9Sstevel@tonic-gate 
3827c478bd9Sstevel@tonic-gate 	while (arg != NULL && *arg != '\0') {
3837c478bd9Sstevel@tonic-gate 		poolstat_field_format_t *ff;	/* current format field */
3847c478bd9Sstevel@tonic-gate 		int 	ffIdx;	/* format field index	    */
3857c478bd9Sstevel@tonic-gate 		char 	*name;	/* name of field	    */
3867c478bd9Sstevel@tonic-gate 		int	n; 	/* no. of chars to strip    */
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate 		n = strspn(arg, " ,\t\r\v\f\n");
3897c478bd9Sstevel@tonic-gate 		arg += n;	/* strip multiples separator	*/
3907c478bd9Sstevel@tonic-gate 		name = arg;
3917c478bd9Sstevel@tonic-gate 
3927c478bd9Sstevel@tonic-gate 		if (strlen(name) < 1)
3937c478bd9Sstevel@tonic-gate 			break;
3947c478bd9Sstevel@tonic-gate 
3957c478bd9Sstevel@tonic-gate 		if ((arg = strpbrk(arg, " ,\t\r\v\f\n")) != NULL)
3967c478bd9Sstevel@tonic-gate 			*arg++ = '\0';
3977c478bd9Sstevel@tonic-gate 
3987c478bd9Sstevel@tonic-gate 		/* search for a named format field */
3997c478bd9Sstevel@tonic-gate 		for (ffIdx = 0; ffIdx < lf->plf_ff_len; ffIdx++) {
4007c478bd9Sstevel@tonic-gate 			ff = lf->plf_ffs + ffIdx;
4017c478bd9Sstevel@tonic-gate 			if (strcmp(ff->pff_name, name) == 0) {
4027c478bd9Sstevel@tonic-gate 				ff->pff_prt |= PABLE_FIELD;
4037c478bd9Sstevel@tonic-gate 				break;
4047c478bd9Sstevel@tonic-gate 			}
4057c478bd9Sstevel@tonic-gate 		}
4067c478bd9Sstevel@tonic-gate 		/* if the name wasn't found	*/
4077c478bd9Sstevel@tonic-gate 		if (ffIdx == lf->plf_ff_len) {
4087c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext(ERR_UNSUPP_STAT_FIELD),
409f5cd957fSRobert Harris 			    name);
4107c478bd9Sstevel@tonic-gate 			usage();
4117c478bd9Sstevel@tonic-gate 		}
4127c478bd9Sstevel@tonic-gate 		if (lf->plf_last == NULL) {
413f5cd957fSRobert Harris 			/* create first print handle */
414f5cd957fSRobert Harris 			NEW0(lf->plf_prt_seq);
415f5cd957fSRobert Harris 			lf->plf_last = lf->plf_prt_seq;
4167c478bd9Sstevel@tonic-gate 		} else {
417f5cd957fSRobert Harris 			NEW0(lf->plf_last->ple_next);
418f5cd957fSRobert Harris 			lf->plf_last = lf->plf_last->ple_next;
4197c478bd9Sstevel@tonic-gate 		}
4207c478bd9Sstevel@tonic-gate 		lf->plf_last->ple_obj = ff; 	/* refer to the format field */
4217c478bd9Sstevel@tonic-gate 	}
4227c478bd9Sstevel@tonic-gate 
4237c478bd9Sstevel@tonic-gate 	return (lf->plf_prt_seq);
4247c478bd9Sstevel@tonic-gate }
4257c478bd9Sstevel@tonic-gate 
4267c478bd9Sstevel@tonic-gate /* update the statistic data by adapters	*/
4277c478bd9Sstevel@tonic-gate static void
sa_update(statistic_bag_t * sbag,int flags)4287c478bd9Sstevel@tonic-gate sa_update(statistic_bag_t *sbag, int flags)
4297c478bd9Sstevel@tonic-gate {
4307c478bd9Sstevel@tonic-gate 	sa_libpool_update(sbag, flags);
4317c478bd9Sstevel@tonic-gate 	sa_kstat_update(sbag, flags);
4327c478bd9Sstevel@tonic-gate }
4337c478bd9Sstevel@tonic-gate 
4347c478bd9Sstevel@tonic-gate /*
4357c478bd9Sstevel@tonic-gate  * Format one statistic field and put it into the 'str' buffer. 'ff' contains
4367c478bd9Sstevel@tonic-gate  * the field formatting parameters. Return the number of used bytes.
4377c478bd9Sstevel@tonic-gate  */
4387c478bd9Sstevel@tonic-gate static int
default_f(char * str,int pos,int left,poolstat_field_format_t * ff,char * data)4397c478bd9Sstevel@tonic-gate default_f(char *str, int pos, int left, poolstat_field_format_t *ff, char *data)
4407c478bd9Sstevel@tonic-gate {
4417c478bd9Sstevel@tonic-gate 	int  used;
4427c478bd9Sstevel@tonic-gate 
4437c478bd9Sstevel@tonic-gate 	switch (ff->pff_type) {
4447c478bd9Sstevel@tonic-gate 	case LL: {
4457c478bd9Sstevel@tonic-gate 			int64_t v;
4467c478bd9Sstevel@tonic-gate 			v = *((int64_t *)(void *)(data + ff->pff_offset));
4477c478bd9Sstevel@tonic-gate 			used = snprintf(str + pos, left, "%*.*lld",
4487c478bd9Sstevel@tonic-gate 			    ff->pff_width, ff->pff_minwidth, v);
4497c478bd9Sstevel@tonic-gate 		}
4507c478bd9Sstevel@tonic-gate 		break;
4517c478bd9Sstevel@tonic-gate 	case ULL: {
4527c478bd9Sstevel@tonic-gate 			uint64_t v;
4537c478bd9Sstevel@tonic-gate 			v = *((uint64_t *)(void *)(data + ff->pff_offset));
4547c478bd9Sstevel@tonic-gate 			used = snprintf(str + pos, left, "%*.*llu",
4557c478bd9Sstevel@tonic-gate 			    ff->pff_width, ff->pff_minwidth, v);
4567c478bd9Sstevel@tonic-gate 		};
4577c478bd9Sstevel@tonic-gate 		break;
4587c478bd9Sstevel@tonic-gate 	case FL: {
4597c478bd9Sstevel@tonic-gate 			int	pw = 0;
4607c478bd9Sstevel@tonic-gate 			double v = *((double *)(void *)(data + ff->pff_offset));
4617c478bd9Sstevel@tonic-gate 			if (v < 10) {
4627c478bd9Sstevel@tonic-gate 				pw = ff->pff_width - 2;
4637c478bd9Sstevel@tonic-gate 			} else if (v < 100) {
4647c478bd9Sstevel@tonic-gate 				pw = ff->pff_width - 3;
4657c478bd9Sstevel@tonic-gate 			} else if (v < 1000) {
4667c478bd9Sstevel@tonic-gate 				pw = ff->pff_width - 4;
4677c478bd9Sstevel@tonic-gate 			}
4687c478bd9Sstevel@tonic-gate 			if (pw < 0)
4697c478bd9Sstevel@tonic-gate 				pw = 0;
4707c478bd9Sstevel@tonic-gate 			used = snprintf(str + pos, left, "%*.*f",
471f5cd957fSRobert Harris 			    ff->pff_width, pw, v);
4727c478bd9Sstevel@tonic-gate 		};
4737c478bd9Sstevel@tonic-gate 		break;
4747c478bd9Sstevel@tonic-gate 	case STR: {
4757c478bd9Sstevel@tonic-gate 			char 	*v;
4767c478bd9Sstevel@tonic-gate 			int 	sl;
4777c478bd9Sstevel@tonic-gate 			v = *((char **)(void *)(data + ff->pff_offset));
4787c478bd9Sstevel@tonic-gate 			sl = strlen(v);
4797c478bd9Sstevel@tonic-gate 			/* truncate if it doesn't fit	*/
4807c478bd9Sstevel@tonic-gate 			if (sl > ff->pff_width) {
4817c478bd9Sstevel@tonic-gate 				char *cp = v +  ff->pff_width - 1;
4827c478bd9Sstevel@tonic-gate 				if (ff->pff_width < 4)
4837c478bd9Sstevel@tonic-gate 					die(gettext(ERR_STATS_FORMAT),
4847c478bd9Sstevel@tonic-gate 					    ff->pff_header);
4857c478bd9Sstevel@tonic-gate 				*cp-- = 0;
4867c478bd9Sstevel@tonic-gate 				*cp-- = '.';
4877c478bd9Sstevel@tonic-gate 				*cp-- = '.';
4887c478bd9Sstevel@tonic-gate 				*cp-- = '.';
4897c478bd9Sstevel@tonic-gate 			}
4907c478bd9Sstevel@tonic-gate 			used = snprintf(str + pos, left, "%-*s", ff->pff_width,
4917c478bd9Sstevel@tonic-gate 			    v);
4927c478bd9Sstevel@tonic-gate 		}
4937c478bd9Sstevel@tonic-gate 		break;
4947c478bd9Sstevel@tonic-gate 	}
4957c478bd9Sstevel@tonic-gate 
4967c478bd9Sstevel@tonic-gate 	return (used);
4977c478bd9Sstevel@tonic-gate }
4987c478bd9Sstevel@tonic-gate 
4997c478bd9Sstevel@tonic-gate /* format big numbers */
5007c478bd9Sstevel@tonic-gate static int
bigno_f(char * str,int pos,int left,poolstat_field_format_t * ff,char * data)5017c478bd9Sstevel@tonic-gate bigno_f(char *str, int pos, int left, poolstat_field_format_t *ff, char *data)
5027c478bd9Sstevel@tonic-gate {
5037c478bd9Sstevel@tonic-gate 	uint64_t v;
5047c478bd9Sstevel@tonic-gate 	char	tag;
5057c478bd9Sstevel@tonic-gate 	int	pw = ff->pff_width - 4;
5067c478bd9Sstevel@tonic-gate 	double 	pv;
5077c478bd9Sstevel@tonic-gate 	int  	used;
5087c478bd9Sstevel@tonic-gate 
5097c478bd9Sstevel@tonic-gate 	v = *((uint64_t *)(void *)(data + ff->pff_offset));
5107c478bd9Sstevel@tonic-gate 	/*
5117c478bd9Sstevel@tonic-gate 	 * the max value can be ULONG_MAX, which is formatted as:
5127c478bd9Sstevel@tonic-gate 	 * E  P   T   G   M   K
5137c478bd9Sstevel@tonic-gate 	 * 18 446 744 073 709 551 615
5147c478bd9Sstevel@tonic-gate 	 * As a result ULONG_MAX is displayed as 18E
5157c478bd9Sstevel@tonic-gate 	 */
5167c478bd9Sstevel@tonic-gate 	pv = v;
5177c478bd9Sstevel@tonic-gate 	if (v < 1000) {
5187c478bd9Sstevel@tonic-gate 		pw = 0;
5197c478bd9Sstevel@tonic-gate 	} else if (v < KILO * 10) {
5207c478bd9Sstevel@tonic-gate 		pv = (double)v / KILO;
5217c478bd9Sstevel@tonic-gate 		tag = 'K';
5227c478bd9Sstevel@tonic-gate 	} else if (v < KILO * 100) {
5237c478bd9Sstevel@tonic-gate 		pv = (double)v / KILO;
5247c478bd9Sstevel@tonic-gate 		tag = 'K'; pw -= 1;
5257c478bd9Sstevel@tonic-gate 	} else if (v < KILO * 1000) {
5267c478bd9Sstevel@tonic-gate 		pv = (double)v / KILO;
5277c478bd9Sstevel@tonic-gate 		tag = 'K'; pw -= 2;
5287c478bd9Sstevel@tonic-gate 	} else if (v < MEGA * 10) {
5297c478bd9Sstevel@tonic-gate 		pv = (double)v / MEGA;
5307c478bd9Sstevel@tonic-gate 		tag = 'M';
5317c478bd9Sstevel@tonic-gate 	} else if (v < MEGA * 100) {
5327c478bd9Sstevel@tonic-gate 		pv = (double)v / MEGA;
5337c478bd9Sstevel@tonic-gate 		tag = 'M'; pw -= 1;
5347c478bd9Sstevel@tonic-gate 	} else if (v < MEGA * 1000) {
5357c478bd9Sstevel@tonic-gate 		pv = (double)v / MEGA;
5367c478bd9Sstevel@tonic-gate 		tag = 'M'; pw -= 2;
5377c478bd9Sstevel@tonic-gate 	} else if (v < GIGA * 10) {
5387c478bd9Sstevel@tonic-gate 		pv = (double)v / GIGA;
5397c478bd9Sstevel@tonic-gate 		tag = 'G';
5407c478bd9Sstevel@tonic-gate 	} else if (v < GIGA * 100) {
5417c478bd9Sstevel@tonic-gate 		pv = (double)v / GIGA;
5427c478bd9Sstevel@tonic-gate 		tag = 'G'; pw -= 1;
5437c478bd9Sstevel@tonic-gate 	} else if (v < GIGA * 1000) {
5447c478bd9Sstevel@tonic-gate 		pv = (double)v / GIGA;
5457c478bd9Sstevel@tonic-gate 		tag = 'G'; pw -= 2;
5467c478bd9Sstevel@tonic-gate 	} else if (v < TERA * 10) {
5477c478bd9Sstevel@tonic-gate 		pv = (double)v / TERA;
5487c478bd9Sstevel@tonic-gate 		tag = 'T';
5497c478bd9Sstevel@tonic-gate 	} else if (v < TERA * 100) {
5507c478bd9Sstevel@tonic-gate 		pv = (double)v / TERA;
5517c478bd9Sstevel@tonic-gate 		tag = 'T'; pw -= 1;
5527c478bd9Sstevel@tonic-gate 	} else if (v < TERA * 1000) {
5537c478bd9Sstevel@tonic-gate 		pv = (double)v / TERA;
5547c478bd9Sstevel@tonic-gate 		tag = 'T'; pw -= 2;
5557c478bd9Sstevel@tonic-gate 	} else if (v < PETA * 10) {
5567c478bd9Sstevel@tonic-gate 		pv = (double)v / PETA;
5577c478bd9Sstevel@tonic-gate 		tag = 'P';
5587c478bd9Sstevel@tonic-gate 	} else if (v < PETA * 100) {
5597c478bd9Sstevel@tonic-gate 		pv = (double)v / PETA;
5607c478bd9Sstevel@tonic-gate 		tag = 'P'; pw -= 1;
5617c478bd9Sstevel@tonic-gate 	} else if (v < PETA * 1000) {
5627c478bd9Sstevel@tonic-gate 		pv = (double)v / PETA;
5637c478bd9Sstevel@tonic-gate 		tag = 'P'; pw -= 2;
5647c478bd9Sstevel@tonic-gate 	} else if (v < EXA * 10) {
5657c478bd9Sstevel@tonic-gate 		pv = (double)v / EXA;
5667c478bd9Sstevel@tonic-gate 		tag = 'E';
5677c478bd9Sstevel@tonic-gate 	} else if (v < EXA * 100) {
5687c478bd9Sstevel@tonic-gate 		pv = (double)v / EXA;
5697c478bd9Sstevel@tonic-gate 		tag = 'E'; pw -= 1;
5707c478bd9Sstevel@tonic-gate 	} else {
5717c478bd9Sstevel@tonic-gate 		pv = (double)v / EXA;
5727c478bd9Sstevel@tonic-gate 		tag = 'E'; pw -= 2;
5737c478bd9Sstevel@tonic-gate 	}
5747c478bd9Sstevel@tonic-gate 	if (pw < 0)
5757c478bd9Sstevel@tonic-gate 		pw = 0;
5767c478bd9Sstevel@tonic-gate 	if (v < 1000)
5777c478bd9Sstevel@tonic-gate 		used = snprintf(str + pos, left, "%*.*f",
578f5cd957fSRobert Harris 		    ff->pff_width, pw, pv);
5797c478bd9Sstevel@tonic-gate 	else
5807c478bd9Sstevel@tonic-gate 		used = snprintf(str + pos, left, "%*.*f%c",
581f5cd957fSRobert Harris 		    ff->pff_width - 1, pw, pv, tag);
5827c478bd9Sstevel@tonic-gate 
5837c478bd9Sstevel@tonic-gate 	return (used);
5847c478bd9Sstevel@tonic-gate }
5857c478bd9Sstevel@tonic-gate 
5867c478bd9Sstevel@tonic-gate /* format usage statistic, if configuration has changed print '-'. */
5877c478bd9Sstevel@tonic-gate static int
used_stat_f(char * str,int pos,int left,poolstat_field_format_t * ff,char * data)5887c478bd9Sstevel@tonic-gate used_stat_f(char *str, int pos, int left, poolstat_field_format_t *ff,
5897c478bd9Sstevel@tonic-gate 	char *data)
5907c478bd9Sstevel@tonic-gate {
5917c478bd9Sstevel@tonic-gate 	int	pw = 0;
5927c478bd9Sstevel@tonic-gate 	double v = *((double *)(void *)(data + ff->pff_offset));
5937c478bd9Sstevel@tonic-gate 	int  	used;
5947c478bd9Sstevel@tonic-gate 
5957c478bd9Sstevel@tonic-gate 	if (pool_sbag->sb_changed & POU_POOL) {
5967c478bd9Sstevel@tonic-gate 		used = snprintf(str + pos, left, "%*c", ff->pff_width, '-');
5977c478bd9Sstevel@tonic-gate 	} else {
5987c478bd9Sstevel@tonic-gate 		if (v < 10) {
599f5cd957fSRobert Harris 			pw = ff->pff_width - 2;
6007c478bd9Sstevel@tonic-gate 		} else if (v < 100) {
601f5cd957fSRobert Harris 			pw = ff->pff_width - 3;
6027c478bd9Sstevel@tonic-gate 		} else if (v < 1000) {
603f5cd957fSRobert Harris 			pw = ff->pff_width - 4;
6047c478bd9Sstevel@tonic-gate 		}
6057c478bd9Sstevel@tonic-gate 		if (pw < 0)
606f5cd957fSRobert Harris 			pw = 0;
6077c478bd9Sstevel@tonic-gate 		used = snprintf(str + pos, left, "%*.*f",
6087c478bd9Sstevel@tonic-gate 		    ff->pff_width, pw, v);
6097c478bd9Sstevel@tonic-gate 	}
6107c478bd9Sstevel@tonic-gate 	return (used);
6117c478bd9Sstevel@tonic-gate }
6127c478bd9Sstevel@tonic-gate 
6137c478bd9Sstevel@tonic-gate /*
6147c478bd9Sstevel@tonic-gate  * Format one header field and put it into the 'str' buffer.
6157c478bd9Sstevel@tonic-gate  */
6167c478bd9Sstevel@tonic-gate /*ARGSUSED*/
6177c478bd9Sstevel@tonic-gate static int
header_f(char * str,int pos,int left,poolstat_field_format_t * ff,char * data)6187c478bd9Sstevel@tonic-gate header_f(char *str, int pos, int left, poolstat_field_format_t *ff, char *data)
6197c478bd9Sstevel@tonic-gate {
6207c478bd9Sstevel@tonic-gate 	int  used = 0;
6217c478bd9Sstevel@tonic-gate 
6227c478bd9Sstevel@tonic-gate 	if (ff->pff_type == STR)
6237c478bd9Sstevel@tonic-gate 		/* strings are left justified	*/
6247c478bd9Sstevel@tonic-gate 		used = snprintf(str + pos, left, "%-*s",
625f5cd957fSRobert Harris 		    ff->pff_width, ff->pff_header);
6267c478bd9Sstevel@tonic-gate 	else
6277c478bd9Sstevel@tonic-gate 		used = snprintf(str + pos, left, "%*s",
628f5cd957fSRobert Harris 		    ff->pff_width, ff->pff_header);
6297c478bd9Sstevel@tonic-gate 	return (used);
6307c478bd9Sstevel@tonic-gate }
6317c478bd9Sstevel@tonic-gate 
6327c478bd9Sstevel@tonic-gate /*
6337c478bd9Sstevel@tonic-gate  * Print one statistic line according to the definitions in 'lf'.
6347c478bd9Sstevel@tonic-gate  */
6357c478bd9Sstevel@tonic-gate static void
prt_stat_line(poolstat_line_format_t * lf)6367c478bd9Sstevel@tonic-gate prt_stat_line(poolstat_line_format_t *lf)
6377c478bd9Sstevel@tonic-gate {
6387c478bd9Sstevel@tonic-gate 	poolstat_list_element_t *le; 	/* list element in the print sequence */
6397c478bd9Sstevel@tonic-gate 	char 	*line;
6407c478bd9Sstevel@tonic-gate 	int 	pos	= 0;		/* position in the printed line	*/
6417c478bd9Sstevel@tonic-gate 	int 	len 	= MAXLINE;	/* the length of the line	*/
6427c478bd9Sstevel@tonic-gate 	int	left 	= len;		/* chars left to use in the line */
6437c478bd9Sstevel@tonic-gate 
6447c478bd9Sstevel@tonic-gate 	line = ZALLOC(len);
6457c478bd9Sstevel@tonic-gate 	for (le = lf->plf_prt_seq; le; le = le->ple_next) {
6467c478bd9Sstevel@tonic-gate 		int used;
6477c478bd9Sstevel@tonic-gate 		poolstat_field_format_t *ff =
648f5cd957fSRobert Harris 		    (poolstat_field_format_t *)le->ple_obj;
6497c478bd9Sstevel@tonic-gate 		/* if the filed is marked to be printed	*/
6507c478bd9Sstevel@tonic-gate 		if (ff->pff_prt & PABLE_FIELD) {
6517c478bd9Sstevel@tonic-gate 			if (((used = ff->pff_format(line, pos, left, ff,
6527c478bd9Sstevel@tonic-gate 			    *ff->pff_data_ptr)) + 1) >= left) {
6537c478bd9Sstevel@tonic-gate 				/* if field doesn't fit allocate new space */
6547c478bd9Sstevel@tonic-gate 				len += used + MAXLINE;
6557c478bd9Sstevel@tonic-gate 				left += used + MAXLINE;
6567c478bd9Sstevel@tonic-gate 				line = REALLOC(line, len);
6577c478bd9Sstevel@tonic-gate 				if (((used = ff->pff_format(line, pos, left, ff,
6587c478bd9Sstevel@tonic-gate 				    *ff->pff_data_ptr)) + 1) >= left)
6597c478bd9Sstevel@tonic-gate 					die(gettext(ERR_STATS_FORMAT), line);
6607c478bd9Sstevel@tonic-gate 			}
6617c478bd9Sstevel@tonic-gate 			left -= used;
6627c478bd9Sstevel@tonic-gate 			pos += used;
6637c478bd9Sstevel@tonic-gate 			if (le->ple_next != NULL) {
6647c478bd9Sstevel@tonic-gate 				/* separate columns with a space */
6657c478bd9Sstevel@tonic-gate 				line[pos++] = ' ';
6667c478bd9Sstevel@tonic-gate 				left--;
6677c478bd9Sstevel@tonic-gate 			}
6687c478bd9Sstevel@tonic-gate 		}
6697c478bd9Sstevel@tonic-gate 	}
6707c478bd9Sstevel@tonic-gate 
6717c478bd9Sstevel@tonic-gate 	(void) printf("%s\n", line);
6727c478bd9Sstevel@tonic-gate 	FREE(line);
6737c478bd9Sstevel@tonic-gate }
6747c478bd9Sstevel@tonic-gate 
6757c478bd9Sstevel@tonic-gate /*
6767c478bd9Sstevel@tonic-gate  * Print a statistics header line for a given resource type.
6777c478bd9Sstevel@tonic-gate  */
6787c478bd9Sstevel@tonic-gate static void
prt_stat_hd(const char * type)6797c478bd9Sstevel@tonic-gate prt_stat_hd(const char *type)
6807c478bd9Sstevel@tonic-gate {
6817c478bd9Sstevel@tonic-gate 	poolstat_line_format_t	*lf;	/* line format	*/
6827c478bd9Sstevel@tonic-gate 	poolstat_list_element_t *le; 	/* list element in the print sequence */
6837c478bd9Sstevel@tonic-gate 	char 	*line;
6847c478bd9Sstevel@tonic-gate 	int 	pos	= 0;		/* position in the printed line	 */
6857c478bd9Sstevel@tonic-gate 	int 	len 	= MAXLINE;	/* the length of the line	 */
6867c478bd9Sstevel@tonic-gate 	int	left 	= len;		/* chars left to use in the line */
6877c478bd9Sstevel@tonic-gate 
6887c478bd9Sstevel@tonic-gate 	if (strcmp(type, POOL_TYPE_NAME) == 0) {
6897c478bd9Sstevel@tonic-gate 		/* pool format needs an extra header	*/
6907c478bd9Sstevel@tonic-gate 		(void) printf("%*s\n", 19 + 15, "pset");
6917c478bd9Sstevel@tonic-gate 		lf = &pool_lf;
6927c478bd9Sstevel@tonic-gate 	} else if (strcmp(type, PSET_TYPE_NAME) == 0) {
6937c478bd9Sstevel@tonic-gate 		lf = &pset_lf;
6947c478bd9Sstevel@tonic-gate 	} else {
6957c478bd9Sstevel@tonic-gate 		die(gettext(ERR_UNSUPP_RTYPE), type);
6967c478bd9Sstevel@tonic-gate 	}
6977c478bd9Sstevel@tonic-gate 	line = ZALLOC(len);
6987c478bd9Sstevel@tonic-gate 	for (le = lf->plf_prt_seq; le; le = le->ple_next) {
6997c478bd9Sstevel@tonic-gate 		int used;	/* used chars in line	*/
7007c478bd9Sstevel@tonic-gate 		poolstat_field_format_t *ff =
701f5cd957fSRobert Harris 		    (poolstat_field_format_t *)le->ple_obj;
7027c478bd9Sstevel@tonic-gate 		/* if the filed is marked to be printed	*/
7037c478bd9Sstevel@tonic-gate 		if (ff->pff_prt& PABLE_FIELD) {
7047c478bd9Sstevel@tonic-gate 			if (((used = header_f(line, pos, left, ff, NULL)) + 1)
7057c478bd9Sstevel@tonic-gate 			    >= left) {
7067c478bd9Sstevel@tonic-gate 				/* if field doesn't fit allocate new space */
7077c478bd9Sstevel@tonic-gate 				len += used + MAXLINE;
7087c478bd9Sstevel@tonic-gate 				left += used + MAXLINE;
7097c478bd9Sstevel@tonic-gate 				line = REALLOC(line, len);
7107c478bd9Sstevel@tonic-gate 				if (((used = header_f(line, pos, left, ff,
7117c478bd9Sstevel@tonic-gate 				    NULL)) + 1) >= left)
7127c478bd9Sstevel@tonic-gate 					die(gettext(ERR_STATS_FORMAT), line);
7137c478bd9Sstevel@tonic-gate 			}
7147c478bd9Sstevel@tonic-gate 			left -= used;
7157c478bd9Sstevel@tonic-gate 			pos += used;
7167c478bd9Sstevel@tonic-gate 			if (le->ple_next != NULL) {
7177c478bd9Sstevel@tonic-gate 				/* separate columns with a space */
7187c478bd9Sstevel@tonic-gate 				line[pos++] = ' ';
7197c478bd9Sstevel@tonic-gate 				left--;
7207c478bd9Sstevel@tonic-gate 			}
7217c478bd9Sstevel@tonic-gate 		}
7227c478bd9Sstevel@tonic-gate 	}
7237c478bd9Sstevel@tonic-gate 
7247c478bd9Sstevel@tonic-gate 	/* only header line with non space characters should be printed */
7257c478bd9Sstevel@tonic-gate 	pos = 0;
7267c478bd9Sstevel@tonic-gate 	while (*(line + pos) != '\n') {
7277c478bd9Sstevel@tonic-gate 		if (!isspace(*(line + pos))) {
728f5cd957fSRobert Harris 			(void) printf("%s\n", line);
7297c478bd9Sstevel@tonic-gate 
730f5cd957fSRobert Harris 			break;
7317c478bd9Sstevel@tonic-gate 		}
7327c478bd9Sstevel@tonic-gate 		pos++;
7337c478bd9Sstevel@tonic-gate 	}
7347c478bd9Sstevel@tonic-gate 	FREE(line);
7357c478bd9Sstevel@tonic-gate }
7367c478bd9Sstevel@tonic-gate 
7377c478bd9Sstevel@tonic-gate /*
7387c478bd9Sstevel@tonic-gate  * Create a pool value instance and set its name to 'name'.
7397c478bd9Sstevel@tonic-gate  */
7407c478bd9Sstevel@tonic-gate static pool_value_t *
create_pool_value(const char * name)7417c478bd9Sstevel@tonic-gate create_pool_value(const char *name)
7427c478bd9Sstevel@tonic-gate {
7437c478bd9Sstevel@tonic-gate 	pool_value_t *pval;
7447c478bd9Sstevel@tonic-gate 
7457c478bd9Sstevel@tonic-gate 	if ((pval = pool_value_alloc()) == NULL) {
7467c478bd9Sstevel@tonic-gate 		return (NULL);
7477c478bd9Sstevel@tonic-gate 	}
7487c478bd9Sstevel@tonic-gate 	if (pool_value_set_name(pval, name) != PO_SUCCESS) {
7497c478bd9Sstevel@tonic-gate 		pool_value_free(pval);
7507c478bd9Sstevel@tonic-gate 		return (NULL);
7517c478bd9Sstevel@tonic-gate 	}
7527c478bd9Sstevel@tonic-gate 
7537c478bd9Sstevel@tonic-gate 	return (pval);
7547c478bd9Sstevel@tonic-gate }
7557c478bd9Sstevel@tonic-gate 
7567c478bd9Sstevel@tonic-gate /*
7577c478bd9Sstevel@tonic-gate  * Find all resources of type 'rtype'.
7587c478bd9Sstevel@tonic-gate  * If 'pool_name' is defined find all resources bound to this pool.
7597c478bd9Sstevel@tonic-gate  */
7607c478bd9Sstevel@tonic-gate static pool_resource_t **
get_resources(const char * pool_name,const char * rtype,uint_t * nelem)7617c478bd9Sstevel@tonic-gate get_resources(const char *pool_name, const char *rtype, uint_t *nelem)
7627c478bd9Sstevel@tonic-gate {
7637c478bd9Sstevel@tonic-gate 	pool_resource_t **resources = NULL;
7647c478bd9Sstevel@tonic-gate 	pool_value_t 	*pvals[] = { NULL, NULL, NULL};
7657c478bd9Sstevel@tonic-gate 	pool_value_t 	*pv_sys_id;
7667c478bd9Sstevel@tonic-gate 	pool_value_t 	*pv_name;
7677c478bd9Sstevel@tonic-gate 	char		*name_prop; /* set name property	*/
7687c478bd9Sstevel@tonic-gate 
7697c478bd9Sstevel@tonic-gate 	if (strcmp(rtype, PSET_TYPE_NAME) == 0) {
7707c478bd9Sstevel@tonic-gate 		if ((pv_sys_id = create_pool_value(PSET_SYSID)) == NULL)
7717c478bd9Sstevel@tonic-gate 			goto on_error;
7727c478bd9Sstevel@tonic-gate 		name_prop = PSET_NAME;
7737c478bd9Sstevel@tonic-gate 	} else {
7747c478bd9Sstevel@tonic-gate 		die(gettext(ERR_UNSUPP_RTYPE), rtype);
7757c478bd9Sstevel@tonic-gate 	}
7767c478bd9Sstevel@tonic-gate 
7777c478bd9Sstevel@tonic-gate 	if ((pvals[0] = create_pool_value("type")) == NULL)
7787c478bd9Sstevel@tonic-gate 		goto on_error;
7797c478bd9Sstevel@tonic-gate 	if ((pool_value_set_string(pvals[0], rtype)) == -1)
7807c478bd9Sstevel@tonic-gate 		goto on_error;
7817c478bd9Sstevel@tonic-gate 
7827c478bd9Sstevel@tonic-gate 	if ((pv_name = create_pool_value(name_prop)) == NULL)
7837c478bd9Sstevel@tonic-gate 		goto on_error;
7847c478bd9Sstevel@tonic-gate 
7857c478bd9Sstevel@tonic-gate 	if (pool_name != NULL) {
7867c478bd9Sstevel@tonic-gate 		/* collect resources associated to 'pool_name'	*/
7877c478bd9Sstevel@tonic-gate 		pool_t 	*pool;
7887c478bd9Sstevel@tonic-gate 		if ((pool = pool_get_pool(conf, pool_name)) == NULL)
7897c478bd9Sstevel@tonic-gate 			die(gettext(ERR_STATS_POOL_N), pool_name);
7907c478bd9Sstevel@tonic-gate 		if ((resources = pool_query_pool_resources(
791f5cd957fSRobert Harris 		    conf, pool, nelem, pvals)) == NULL)
7927c478bd9Sstevel@tonic-gate 			goto on_error;
7937c478bd9Sstevel@tonic-gate 	} else {
7947c478bd9Sstevel@tonic-gate 		/* collect all resources  */
7957c478bd9Sstevel@tonic-gate 		if ((resources =
796f5cd957fSRobert Harris 		    pool_query_resources(conf, nelem, pvals)) == NULL)
7977c478bd9Sstevel@tonic-gate 			goto on_error;
7987c478bd9Sstevel@tonic-gate 	}
7997c478bd9Sstevel@tonic-gate 
8007c478bd9Sstevel@tonic-gate 	if (pv_name != NULL)
8017c478bd9Sstevel@tonic-gate 		pool_value_free(pv_name);
8027c478bd9Sstevel@tonic-gate 	if (pv_sys_id != NULL)
8037c478bd9Sstevel@tonic-gate 		pool_value_free(pv_sys_id);
8047c478bd9Sstevel@tonic-gate 	if (pvals[0] != NULL)
8057c478bd9Sstevel@tonic-gate 		pool_value_free(pvals[0]);
8067c478bd9Sstevel@tonic-gate 
8077c478bd9Sstevel@tonic-gate 	return (resources);
8087c478bd9Sstevel@tonic-gate on_error:
8097c478bd9Sstevel@tonic-gate 	die(gettext(ERR_STATS_RES), get_errstr());
8107c478bd9Sstevel@tonic-gate 	/*NOTREACHED*/
8117c478bd9Sstevel@tonic-gate }
8127c478bd9Sstevel@tonic-gate 
8137c478bd9Sstevel@tonic-gate /*
8147c478bd9Sstevel@tonic-gate  * Print statistics for all resources of type 'rtype' passed in 'resources'.
8157c478bd9Sstevel@tonic-gate  */
8167c478bd9Sstevel@tonic-gate static void
prt_resource_stats_by_type(pool_resource_t ** resources,const char * rtype)8177c478bd9Sstevel@tonic-gate prt_resource_stats_by_type(pool_resource_t **resources, const char *rtype)
8187c478bd9Sstevel@tonic-gate {
8197c478bd9Sstevel@tonic-gate 	int		i;
8207c478bd9Sstevel@tonic-gate 	pool_elem_t	*elem;
8217c478bd9Sstevel@tonic-gate 	pool_value_t 	*pv_name;
8227c478bd9Sstevel@tonic-gate 	char		*name_prop;
8237c478bd9Sstevel@tonic-gate 
8247c478bd9Sstevel@tonic-gate 	poolstat_line_format_t	*lf;
8257c478bd9Sstevel@tonic-gate 	statistic_bag_t		*sbag;
8267c478bd9Sstevel@tonic-gate 
8277c478bd9Sstevel@tonic-gate 	if (strcmp(rtype, PSET_TYPE_NAME) == 0) {
8287c478bd9Sstevel@tonic-gate 		name_prop = PSET_NAME;
8297c478bd9Sstevel@tonic-gate 		lf = &pset_lf;
8307c478bd9Sstevel@tonic-gate 		sbag = pset_sbag;
8317c478bd9Sstevel@tonic-gate 	} else {
8327c478bd9Sstevel@tonic-gate 		die(gettext(ERR_UNSUPP_RTYPE), rtype);
8337c478bd9Sstevel@tonic-gate 	}
8347c478bd9Sstevel@tonic-gate 
8357c478bd9Sstevel@tonic-gate 	if ((pv_name = create_pool_value(name_prop)) == NULL)
8367c478bd9Sstevel@tonic-gate 		goto on_error;
8377c478bd9Sstevel@tonic-gate 
8387c478bd9Sstevel@tonic-gate 	/* collect and print statistics for the given resources	*/
8397c478bd9Sstevel@tonic-gate 	for (i = 0; resources[i] != NULL; i++) {
8407c478bd9Sstevel@tonic-gate 		if ((elem = pool_resource_to_elem(conf, resources[i])) == NULL)
8417c478bd9Sstevel@tonic-gate 			goto on_error;
8427c478bd9Sstevel@tonic-gate 		if (pool_get_property(conf, elem, name_prop, pv_name) == -1)
8437c478bd9Sstevel@tonic-gate 			goto on_error;
8447c478bd9Sstevel@tonic-gate 		if (pool_value_get_string(pv_name, &sbag->sb_name) == -1)
8457c478bd9Sstevel@tonic-gate 			goto on_error;
8467c478bd9Sstevel@tonic-gate 		sa_update(sbag, 0);
8477c478bd9Sstevel@tonic-gate 
8487c478bd9Sstevel@tonic-gate 		prt_stat_line(lf);
8497c478bd9Sstevel@tonic-gate 	}
8507c478bd9Sstevel@tonic-gate 
8517c478bd9Sstevel@tonic-gate 	if (pv_name != NULL)
8527c478bd9Sstevel@tonic-gate 		pool_value_free(pv_name);
8537c478bd9Sstevel@tonic-gate 	return;
8547c478bd9Sstevel@tonic-gate on_error:
8557c478bd9Sstevel@tonic-gate 	die(gettext(ERR_STATS_RES), get_errstr());
8567c478bd9Sstevel@tonic-gate }
8577c478bd9Sstevel@tonic-gate 
8587c478bd9Sstevel@tonic-gate /*
8597c478bd9Sstevel@tonic-gate  * Update statistics for all resources of type 'rtype' pased in 'resources'.
8607c478bd9Sstevel@tonic-gate  */
8617c478bd9Sstevel@tonic-gate static void
update_resource_stats(pool_resource_t * resource,const char * rtype)8627c478bd9Sstevel@tonic-gate update_resource_stats(pool_resource_t *resource, const char *rtype)
8637c478bd9Sstevel@tonic-gate {
8647c478bd9Sstevel@tonic-gate 	pool_elem_t	*elem;
8657c478bd9Sstevel@tonic-gate 	pool_value_t 	*pv_name;
8667c478bd9Sstevel@tonic-gate 	char		*name_prop; 		/* set name property	*/
8677c478bd9Sstevel@tonic-gate 
8687c478bd9Sstevel@tonic-gate 	statistic_bag_t	*sbag;
8697c478bd9Sstevel@tonic-gate 
8707c478bd9Sstevel@tonic-gate 	if (strcmp(rtype, PSET_TYPE_NAME) == 0) {
8717c478bd9Sstevel@tonic-gate 		name_prop = PSET_NAME;
8727c478bd9Sstevel@tonic-gate 		sbag 	= pset_sbag;
8737c478bd9Sstevel@tonic-gate 	} else {
8747c478bd9Sstevel@tonic-gate 		die(gettext(ERR_UNSUPP_RTYPE), rtype);
8757c478bd9Sstevel@tonic-gate 	}
8767c478bd9Sstevel@tonic-gate 
8777c478bd9Sstevel@tonic-gate 	if ((pv_name = create_pool_value(name_prop)) == NULL)
8787c478bd9Sstevel@tonic-gate 		goto on_error;
8797c478bd9Sstevel@tonic-gate 
8807c478bd9Sstevel@tonic-gate 	if ((elem = pool_resource_to_elem(conf, resource)) == NULL)
8817c478bd9Sstevel@tonic-gate 		goto on_error;
8827c478bd9Sstevel@tonic-gate 	if (pool_get_property(conf, elem, name_prop, pv_name) == -1)
8837c478bd9Sstevel@tonic-gate 		goto on_error;
8847c478bd9Sstevel@tonic-gate 	if (pool_value_get_string(pv_name, &sbag->sb_name) == -1)
8857c478bd9Sstevel@tonic-gate 		goto on_error;
8867c478bd9Sstevel@tonic-gate 	sa_update(sbag, 0);
8877c478bd9Sstevel@tonic-gate 
8887c478bd9Sstevel@tonic-gate 	if (pv_name != NULL)
8897c478bd9Sstevel@tonic-gate 		pool_value_free(pv_name);
8907c478bd9Sstevel@tonic-gate 	return;
8917c478bd9Sstevel@tonic-gate 
8927c478bd9Sstevel@tonic-gate on_error:
8937c478bd9Sstevel@tonic-gate 	die(gettext(ERR_STATS_RES), get_errstr());
8947c478bd9Sstevel@tonic-gate }
8957c478bd9Sstevel@tonic-gate 
8967c478bd9Sstevel@tonic-gate /*
8977c478bd9Sstevel@tonic-gate  * For each pool in the configuration print statistics of associated resources.
8987c478bd9Sstevel@tonic-gate  * If the pool name list 'pn' is defined, only print resources of pools
8997c478bd9Sstevel@tonic-gate  * specified in the list. The list can specify the pool name or its system id.
9007c478bd9Sstevel@tonic-gate  */
9017c478bd9Sstevel@tonic-gate static void
prt_pool_stats(poolstat_list_element_t * pn)9027c478bd9Sstevel@tonic-gate prt_pool_stats(poolstat_list_element_t *pn)
9037c478bd9Sstevel@tonic-gate {
9047c478bd9Sstevel@tonic-gate 	uint_t 		nelem;
9057c478bd9Sstevel@tonic-gate 	pool_elem_t	*elem;
9067c478bd9Sstevel@tonic-gate 	int		i;
9077c478bd9Sstevel@tonic-gate 	int 		error;
9087c478bd9Sstevel@tonic-gate 	pool_t 		**pools = NULL;
9097c478bd9Sstevel@tonic-gate 	pool_value_t 	*pvals[] = { NULL, NULL };
9107c478bd9Sstevel@tonic-gate 	pool_value_t 	*pv_name = NULL;
9117c478bd9Sstevel@tonic-gate 	pool_value_t 	*pv_sys_id = NULL;
9127c478bd9Sstevel@tonic-gate 	statistic_bag_t	*sbag = pool_sbag;
9137c478bd9Sstevel@tonic-gate 	poolstat_list_element_t 	*rtype;
9147c478bd9Sstevel@tonic-gate 	pool_resource_t **resources;
9157c478bd9Sstevel@tonic-gate 
9167c478bd9Sstevel@tonic-gate 	if ((pv_sys_id = create_pool_value(POOL_SYSID)) == NULL)
9177c478bd9Sstevel@tonic-gate 		goto on_error;
9187c478bd9Sstevel@tonic-gate 	if ((pv_name = create_pool_value(POOL_NAME)) == NULL)
9197c478bd9Sstevel@tonic-gate 		goto on_error;
9207c478bd9Sstevel@tonic-gate 
9217c478bd9Sstevel@tonic-gate 	if (pn == NULL) {
9227c478bd9Sstevel@tonic-gate 		/* collect all pools	*/
9237c478bd9Sstevel@tonic-gate 		if ((pools = pool_query_pools(conf, &nelem, NULL)) == NULL)
9247c478bd9Sstevel@tonic-gate 			goto on_error;
9257c478bd9Sstevel@tonic-gate 	} else {
9267c478bd9Sstevel@tonic-gate 		/*
9277c478bd9Sstevel@tonic-gate 		 * collect pools specified in the 'pn' list.
9287c478bd9Sstevel@tonic-gate 		 * 'poolid' the pool identifier can be a pool name or sys_id.
9297c478bd9Sstevel@tonic-gate 		 */
9307c478bd9Sstevel@tonic-gate 		poolstat_list_element_t	*poolid;
9317c478bd9Sstevel@tonic-gate 		for (poolid = pn, i = 1; poolid; poolid = poolid->ple_next)
9327c478bd9Sstevel@tonic-gate 			i++;
9337c478bd9Sstevel@tonic-gate 		pools = ZALLOC(sizeof (pool_t *) * (i + 1));
9347c478bd9Sstevel@tonic-gate 		for (poolid = pn, i = 0; poolid;
935f5cd957fSRobert Harris 		    poolid = poolid->ple_next, i++) {
9367c478bd9Sstevel@tonic-gate 			pool_t **pool;
9377c478bd9Sstevel@tonic-gate 			int64_t sysid = Atoi(poolid->ple_obj, &error);
9387c478bd9Sstevel@tonic-gate 			if (error == 0) {
9397c478bd9Sstevel@tonic-gate 				/* the pool is identified by sys_id	*/
9407c478bd9Sstevel@tonic-gate 				pool_value_set_int64(pv_sys_id, sysid);
9417c478bd9Sstevel@tonic-gate 				pvals[0] = pv_sys_id;
9427c478bd9Sstevel@tonic-gate 				pool = pool_query_pools(conf, &nelem, pvals);
9437c478bd9Sstevel@tonic-gate 			} else {
9447c478bd9Sstevel@tonic-gate 				if (pool_value_set_string(pv_name,
9457c478bd9Sstevel@tonic-gate 				    poolid->ple_obj) == -1)
9467c478bd9Sstevel@tonic-gate 					die(gettext(ERR_NOMEM));
9477c478bd9Sstevel@tonic-gate 				pvals[0] = pv_name;
9487c478bd9Sstevel@tonic-gate 				pool = pool_query_pools(conf, &nelem, pvals);
9497c478bd9Sstevel@tonic-gate 			}
9507c478bd9Sstevel@tonic-gate 			if (pool == NULL)
9517c478bd9Sstevel@tonic-gate 				die(gettext(ERR_STATS_POOL_N), poolid->ple_obj);
9527c478bd9Sstevel@tonic-gate 			pools[i] = pool[0];
9537c478bd9Sstevel@tonic-gate 			FREE(pool);
9547c478bd9Sstevel@tonic-gate 		}
9557c478bd9Sstevel@tonic-gate 	}
9567c478bd9Sstevel@tonic-gate 
9577c478bd9Sstevel@tonic-gate 	/* print statistic for all pools found		*/
9587c478bd9Sstevel@tonic-gate 	if (!rflag) {
9597c478bd9Sstevel@tonic-gate 		/* print the common resource header 	*/
9607c478bd9Sstevel@tonic-gate 		prt_stat_hd(POOL_TYPE_NAME);
9617c478bd9Sstevel@tonic-gate 
9627c478bd9Sstevel@tonic-gate 		/* print statistics for the resources bound to the pools */
9637c478bd9Sstevel@tonic-gate 		for (i = 0; pools[i] != NULL; i++) {
9647c478bd9Sstevel@tonic-gate 			elem = pool_to_elem(conf, pools[i]);
9657c478bd9Sstevel@tonic-gate 			if (pool_get_property(conf, elem, POOL_NAME, pv_name)
966f5cd957fSRobert Harris 			    == -1)
9677c478bd9Sstevel@tonic-gate 				goto on_error;
9687c478bd9Sstevel@tonic-gate 			if (pool_value_get_string(pv_name, &sbag->sb_name) != 0)
9697c478bd9Sstevel@tonic-gate 				goto on_error;
9707c478bd9Sstevel@tonic-gate 			if (pool_get_property(
971f5cd957fSRobert Harris 			    conf, elem, "pool.sys_id", pv_sys_id) == -1)
9727c478bd9Sstevel@tonic-gate 				goto on_error;
9737c478bd9Sstevel@tonic-gate 			if (pool_value_get_int64(
974f5cd957fSRobert Harris 			    pv_sys_id, &sbag->sb_sysid) != 0)
9757c478bd9Sstevel@tonic-gate 				goto on_error;
9767c478bd9Sstevel@tonic-gate 
9777c478bd9Sstevel@tonic-gate 			for (rtype = rtypes; rtype; rtype = rtype->ple_next) {
9787c478bd9Sstevel@tonic-gate 				resources = get_resources(
979f5cd957fSRobert Harris 				    sbag->sb_name, rtype->ple_obj, &nelem);
9807c478bd9Sstevel@tonic-gate 				update_resource_stats(*resources,
981f5cd957fSRobert Harris 				    rtype->ple_obj);
9827c478bd9Sstevel@tonic-gate 				FREE(resources);
9837c478bd9Sstevel@tonic-gate 			}
9847c478bd9Sstevel@tonic-gate 			prt_stat_line(&pool_lf);
9857c478bd9Sstevel@tonic-gate 		}
9867c478bd9Sstevel@tonic-gate 	} else {
9877c478bd9Sstevel@tonic-gate 		/* print statistic for all resource types defined in rtypes */
9887c478bd9Sstevel@tonic-gate 		for (rtype = rtypes; rtype; rtype = rtype->ple_next) {
9897c478bd9Sstevel@tonic-gate 			prt_stat_hd(rtype->ple_obj);
9907c478bd9Sstevel@tonic-gate 			for (i = 0; pools[i] != NULL; i++) {
9917c478bd9Sstevel@tonic-gate 				elem = pool_to_elem(conf, pools[i]);
9927c478bd9Sstevel@tonic-gate 				if (pool_get_property(
993f5cd957fSRobert Harris 				    conf, elem, POOL_NAME, pv_name) == -1)
9947c478bd9Sstevel@tonic-gate 					goto on_error;
9957c478bd9Sstevel@tonic-gate 				if (pool_value_get_string(
996f5cd957fSRobert Harris 				    pv_name, &sbag->sb_name) != 0)
9977c478bd9Sstevel@tonic-gate 					goto on_error;
9987c478bd9Sstevel@tonic-gate 				if (pool_get_property(
999f5cd957fSRobert Harris 				    conf, elem, POOL_SYSID, pv_sys_id) == -1)
10007c478bd9Sstevel@tonic-gate 					goto on_error;
10017c478bd9Sstevel@tonic-gate 				if (pool_value_get_int64(
1002f5cd957fSRobert Harris 				    pv_sys_id, &sbag->sb_sysid) != 0)
10037c478bd9Sstevel@tonic-gate 					goto on_error;
10047c478bd9Sstevel@tonic-gate 				resources = get_resources(
1005f5cd957fSRobert Harris 				    sbag->sb_name, rtype->ple_obj, &nelem);
10067c478bd9Sstevel@tonic-gate 				if (resources == NULL)
10077c478bd9Sstevel@tonic-gate 					continue;
10087c478bd9Sstevel@tonic-gate 				update_resource_stats(
10097c478bd9Sstevel@tonic-gate 				    *resources, rtype->ple_obj);
10107c478bd9Sstevel@tonic-gate 				prt_resource_stats_by_type(resources,
10117c478bd9Sstevel@tonic-gate 				    rtype->ple_obj);
10127c478bd9Sstevel@tonic-gate 				FREE(resources);
10137c478bd9Sstevel@tonic-gate 			}
10147c478bd9Sstevel@tonic-gate 		}
10157c478bd9Sstevel@tonic-gate 	}
10167c478bd9Sstevel@tonic-gate 
10177c478bd9Sstevel@tonic-gate 	FREE(pools);
10187c478bd9Sstevel@tonic-gate 	if (pv_name != NULL)
10197c478bd9Sstevel@tonic-gate 		pool_value_free(pv_name);
10207c478bd9Sstevel@tonic-gate 	if (pv_sys_id != NULL)
10217c478bd9Sstevel@tonic-gate 		pool_value_free(pv_sys_id);
10227c478bd9Sstevel@tonic-gate 
10237c478bd9Sstevel@tonic-gate 	return;
10247c478bd9Sstevel@tonic-gate on_error:
10257c478bd9Sstevel@tonic-gate 	die(gettext(ERR_STATS_POOL), get_errstr());
10267c478bd9Sstevel@tonic-gate }
1027