xref: /titanic_50/usr/src/cmd/zonestat/zonestat/zonestat.c (revision 6a634c9dca3093f3922e4b7ab826d7bdf17bf78e)
1*efd4c9b6SSteve Lawrence /*
2*efd4c9b6SSteve Lawrence  * CDDL HEADER START
3*efd4c9b6SSteve Lawrence  *
4*efd4c9b6SSteve Lawrence  * The contents of this file are subject to the terms of the
5*efd4c9b6SSteve Lawrence  * Common Development and Distribution License (the "License").
6*efd4c9b6SSteve Lawrence  * You may not use this file except in compliance with the License.
7*efd4c9b6SSteve Lawrence  *
8*efd4c9b6SSteve Lawrence  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*efd4c9b6SSteve Lawrence  * or http://www.opensolaris.org/os/licensing.
10*efd4c9b6SSteve Lawrence  * See the License for the specific language governing permissions
11*efd4c9b6SSteve Lawrence  * and limitations under the License.
12*efd4c9b6SSteve Lawrence  *
13*efd4c9b6SSteve Lawrence  * When distributing Covered Code, include this CDDL HEADER in each
14*efd4c9b6SSteve Lawrence  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*efd4c9b6SSteve Lawrence  * If applicable, add the following below this CDDL HEADER, with the
16*efd4c9b6SSteve Lawrence  * fields enclosed by brackets "[]" replaced with your own identifying
17*efd4c9b6SSteve Lawrence  * information: Portions Copyright [yyyy] [name of copyright owner]
18*efd4c9b6SSteve Lawrence  *
19*efd4c9b6SSteve Lawrence  * CDDL HEADER END
20*efd4c9b6SSteve Lawrence  */
21*efd4c9b6SSteve Lawrence 
22*efd4c9b6SSteve Lawrence /*
23*efd4c9b6SSteve Lawrence  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24*efd4c9b6SSteve Lawrence  */
25*efd4c9b6SSteve Lawrence 
26*efd4c9b6SSteve Lawrence #include <alloca.h>
27*efd4c9b6SSteve Lawrence #include <assert.h>
28*efd4c9b6SSteve Lawrence #include <errno.h>
29*efd4c9b6SSteve Lawrence #include <langinfo.h>
30*efd4c9b6SSteve Lawrence #include <libintl.h>
31*efd4c9b6SSteve Lawrence #include <libscf.h>
32*efd4c9b6SSteve Lawrence #include <signal.h>
33*efd4c9b6SSteve Lawrence #include <stdarg.h>
34*efd4c9b6SSteve Lawrence #include <stdio.h>
35*efd4c9b6SSteve Lawrence #include <stdlib.h>
36*efd4c9b6SSteve Lawrence #include <strings.h>
37*efd4c9b6SSteve Lawrence #include <sys/fxpriocntl.h>
38*efd4c9b6SSteve Lawrence #include <sys/priocntl.h>
39*efd4c9b6SSteve Lawrence #include <sys/types.h>
40*efd4c9b6SSteve Lawrence #include <time.h>
41*efd4c9b6SSteve Lawrence #include <unistd.h>
42*efd4c9b6SSteve Lawrence #include <zonestat.h>
43*efd4c9b6SSteve Lawrence 
44*efd4c9b6SSteve Lawrence extern char *optarg;
45*efd4c9b6SSteve Lawrence extern int optind, opterr, optopt;
46*efd4c9b6SSteve Lawrence 
47*efd4c9b6SSteve Lawrence #define	ZSTAT_OK		0
48*efd4c9b6SSteve Lawrence #define	ZSTAT_ERROR		1
49*efd4c9b6SSteve Lawrence #define	ZSTAT_USAGE		2
50*efd4c9b6SSteve Lawrence 
51*efd4c9b6SSteve Lawrence #define	ZSTAT_UNIX_TIMESTAMP	1
52*efd4c9b6SSteve Lawrence #define	ZSTAT_ISO_TIMESTAMP	2
53*efd4c9b6SSteve Lawrence #define	ZSTAT_DATE_TIMESTAMP	3
54*efd4c9b6SSteve Lawrence 
55*efd4c9b6SSteve Lawrence #define	ZSTAT_RES_PHYSICAL_MEMORY	0x1
56*efd4c9b6SSteve Lawrence #define	ZSTAT_RES_VIRTUAL_MEMORY	0x2
57*efd4c9b6SSteve Lawrence #define	ZSTAT_RES_LOCKED_MEMORY		0x4
58*efd4c9b6SSteve Lawrence #define	ZSTAT_RES_MEMORY		0x7
59*efd4c9b6SSteve Lawrence 
60*efd4c9b6SSteve Lawrence #define	ZSTAT_RES_DEFAULT_PSET		0x10
61*efd4c9b6SSteve Lawrence #define	ZSTAT_RES_PSETS			0x20
62*efd4c9b6SSteve Lawrence #define	ZSTAT_RES_SUMMARY		0x40
63*efd4c9b6SSteve Lawrence 
64*efd4c9b6SSteve Lawrence #define	ZSTAT_RES_PROCESSES		0x100
65*efd4c9b6SSteve Lawrence #define	ZSTAT_RES_LWPS			0x200
66*efd4c9b6SSteve Lawrence #define	ZSTAT_RES_LOFI			0x400
67*efd4c9b6SSteve Lawrence #define	ZSTAT_RES_LIMITS		0x700
68*efd4c9b6SSteve Lawrence 
69*efd4c9b6SSteve Lawrence #define	ZSTAT_RES_SHM_MEMORY		0x1000
70*efd4c9b6SSteve Lawrence #define	ZSTAT_RES_SHM_IDS		0x2000
71*efd4c9b6SSteve Lawrence #define	ZSTAT_RES_SEM_IDS		0x4000
72*efd4c9b6SSteve Lawrence #define	ZSTAT_RES_MSG_IDS		0x8000
73*efd4c9b6SSteve Lawrence #define	ZSTAT_RES_SYSV			0xF000
74*efd4c9b6SSteve Lawrence 
75*efd4c9b6SSteve Lawrence #define	ZSTAT_RES_ALL			0xF777
76*efd4c9b6SSteve Lawrence 
77*efd4c9b6SSteve Lawrence #define	ZONESTAT_PHYSICAL_MEMORY	"physical-memory"
78*efd4c9b6SSteve Lawrence #define	ZONESTAT_VIRTUAL_MEMORY		"virtual-memory"
79*efd4c9b6SSteve Lawrence #define	ZONESTAT_LOCKED_MEMORY		"locked-memory"
80*efd4c9b6SSteve Lawrence #define	ZONESTAT_MEMORY			"memory"
81*efd4c9b6SSteve Lawrence 
82*efd4c9b6SSteve Lawrence #define	ZONESTAT_DEFAULT_PSET		"default-pset"
83*efd4c9b6SSteve Lawrence #define	ZONESTAT_POOL_PSET		"pool-pset"
84*efd4c9b6SSteve Lawrence #define	ZONESTAT_PSRSET_PSET		"psrset-pset"
85*efd4c9b6SSteve Lawrence #define	ZONESTAT_DEDICATED_CPU		"dedicated-cpu"
86*efd4c9b6SSteve Lawrence #define	ZONESTAT_PROCESSOR_SET		"processor-set"
87*efd4c9b6SSteve Lawrence #define	ZONESTAT_PSETS			"psets"
88*efd4c9b6SSteve Lawrence #define	ZONESTAT_SUMMARY		"summary"
89*efd4c9b6SSteve Lawrence 
90*efd4c9b6SSteve Lawrence #define	ZONESTAT_PROCESSES		"processes"
91*efd4c9b6SSteve Lawrence #define	ZONESTAT_LWPS			"lwps"
92*efd4c9b6SSteve Lawrence #define	ZONESTAT_LOFI			"lofi"
93*efd4c9b6SSteve Lawrence #define	ZONESTAT_LIMITS			"limits"
94*efd4c9b6SSteve Lawrence 
95*efd4c9b6SSteve Lawrence #define	ZONESTAT_SHM_MEMORY		"shm-memory"
96*efd4c9b6SSteve Lawrence #define	ZONESTAT_SHM_IDS		"shm-ids"
97*efd4c9b6SSteve Lawrence #define	ZONESTAT_SEM_IDS		"sem-ids"
98*efd4c9b6SSteve Lawrence #define	ZONESTAT_MSG_IDS		"msg-ids"
99*efd4c9b6SSteve Lawrence #define	ZONESTAT_SYSV			"sysv"
100*efd4c9b6SSteve Lawrence 
101*efd4c9b6SSteve Lawrence #define	ZONESTAT_ALL			"all"
102*efd4c9b6SSteve Lawrence 
103*efd4c9b6SSteve Lawrence #define	ZONESTAT_NAME_MEM_DEFAULT	"mem_default"
104*efd4c9b6SSteve Lawrence #define	ZONESTAT_NAME_VM_DEFAULT	"vm_default"
105*efd4c9b6SSteve Lawrence 
106*efd4c9b6SSteve Lawrence #define	ZONESTAT_NAME_AVERAGE		"average"
107*efd4c9b6SSteve Lawrence #define	ZONESTAT_NAME_HIGH		"high"
108*efd4c9b6SSteve Lawrence 
109*efd4c9b6SSteve Lawrence #define	ZONESTAT_NAME_RESOURCE		"resource"
110*efd4c9b6SSteve Lawrence #define	ZONESTAT_NAME_TOTAL		"total"
111*efd4c9b6SSteve Lawrence #define	ZONESTAT_NAME_SYSTEM		"system"
112*efd4c9b6SSteve Lawrence #define	ZONESTAT_NAME_ZONES		"zones"
113*efd4c9b6SSteve Lawrence #define	ZONESTAT_NAME_HEADER		"header"
114*efd4c9b6SSteve Lawrence #define	ZONESTAT_NAME_FOOTER		"footer"
115*efd4c9b6SSteve Lawrence 
116*efd4c9b6SSteve Lawrence #define	ZONESTAT_NAME_NAME		"name"
117*efd4c9b6SSteve Lawrence #define	ZONESTAT_NAME_USED		"used"
118*efd4c9b6SSteve Lawrence #define	ZONESTAT_NAME_CAP		"cap"
119*efd4c9b6SSteve Lawrence #define	ZONESTAT_NAME_PCAP		"pcap"
120*efd4c9b6SSteve Lawrence #define	ZONESTAT_NAME_SHR		"shr"
121*efd4c9b6SSteve Lawrence #define	ZONESTAT_NAME_PSHRU		"pshru"
122*efd4c9b6SSteve Lawrence #define	ZONESTAT_NAME_CPU		"cpu"
123*efd4c9b6SSteve Lawrence #define	ZONESTAT_NAME_PHYSICAL_MEMORY	ZONESTAT_PHYSICAL_MEMORY
124*efd4c9b6SSteve Lawrence #define	ZONESTAT_NAME_VIRTUAL_MEMORY	ZONESTAT_VIRTUAL_MEMORY
125*efd4c9b6SSteve Lawrence 
126*efd4c9b6SSteve Lawrence #define	ZONESTAT_NAME_SYSTEM_LIMIT	"system-limit"
127*efd4c9b6SSteve Lawrence 
128*efd4c9b6SSteve Lawrence #define	ZSTAT_REPORT_FMT_INTERVAL	0
129*efd4c9b6SSteve Lawrence #define	ZSTAT_REPORT_FMT_TOTAL		1
130*efd4c9b6SSteve Lawrence #define	ZSTAT_REPORT_FMT_AVERAGE	2
131*efd4c9b6SSteve Lawrence #define	ZSTAT_REPORT_FMT_HIGH		3
132*efd4c9b6SSteve Lawrence #define	ZSTAT_REPORT_FMT_END		4
133*efd4c9b6SSteve Lawrence 
134*efd4c9b6SSteve Lawrence #define	ZSTAT_REPORT_TEXT_INTERVAL	"interval"
135*efd4c9b6SSteve Lawrence #define	ZSTAT_REPORT_TEXT_TOTAL		"report-total"
136*efd4c9b6SSteve Lawrence #define	ZSTAT_REPORT_TEXT_AVERAGE	"report-average"
137*efd4c9b6SSteve Lawrence #define	ZSTAT_REPORT_TEXT_HIGH		"report-high"
138*efd4c9b6SSteve Lawrence #define	ZSTAT_REPORT_TEXT_END		"footer"
139*efd4c9b6SSteve Lawrence 
140*efd4c9b6SSteve Lawrence #define	ZSTAT_DURATION_INF	((int)INT_MAX)
141*efd4c9b6SSteve Lawrence #define	ZSTAT_INTERVAL_DEFAULT	((int)INT_MAX)
142*efd4c9b6SSteve Lawrence #define	ZSTAT_REPORT_END	((int)INT_MAX)
143*efd4c9b6SSteve Lawrence 
144*efd4c9b6SSteve Lawrence #define	ZSTAT_SORT_CPU		1
145*efd4c9b6SSteve Lawrence #define	ZSTAT_SORT_PHYSICAL	2
146*efd4c9b6SSteve Lawrence #define	ZSTAT_SORT_VIRTUAL	3
147*efd4c9b6SSteve Lawrence #define	ZSTAT_SORT_USED		4
148*efd4c9b6SSteve Lawrence #define	ZSTAT_SORT_CAP		5
149*efd4c9b6SSteve Lawrence #define	ZSTAT_SORT_PCAP		6
150*efd4c9b6SSteve Lawrence #define	ZSTAT_SORT_SHR		7
151*efd4c9b6SSteve Lawrence #define	ZSTAT_SORT_PSHRU	8
152*efd4c9b6SSteve Lawrence #define	ZSTAT_SORT_NAME		9
153*efd4c9b6SSteve Lawrence #define	ZSTAT_SORT_MAX		10
154*efd4c9b6SSteve Lawrence 
155*efd4c9b6SSteve Lawrence #define	ZSTAT_SUM_MIN_ZONENAME 19
156*efd4c9b6SSteve Lawrence #define	ZSTAT_SUM_HDR_FORMAT "%23s %17s %17s\n"
157*efd4c9b6SSteve Lawrence #define	ZSTAT_SUM_ZONE_FORMAT "%5s %5s %5s %5s %5s %5s %5s %5s %5s %5s\n"
158*efd4c9b6SSteve Lawrence 
159*efd4c9b6SSteve Lawrence #define	ZSTAT_CPU_MIN_PSETNAME 22
160*efd4c9b6SSteve Lawrence #define	ZSTAT_CPU_MIN_ZONENAME 36
161*efd4c9b6SSteve Lawrence #define	ZSTAT_CPU_RES_FORMAT "%13s  %11s %11s\n"
162*efd4c9b6SSteve Lawrence #define	ZSTAT_CPU_ZONE_FORMAT "%5s %5s %5s %5s %6s %5s %5s\n"
163*efd4c9b6SSteve Lawrence 
164*efd4c9b6SSteve Lawrence #define	ZSTAT_RESOURCE_MIN_RESNAME 28
165*efd4c9b6SSteve Lawrence #define	ZSTAT_RESOURCE_MIN_ZONENAME 36
166*efd4c9b6SSteve Lawrence #define	ZSTAT_RESOURCE_FORMAT "%13s\n"
167*efd4c9b6SSteve Lawrence #define	ZSTAT_RESOURCE_ZONE_FORMAT "%5s %5s %5s %5s\n"
168*efd4c9b6SSteve Lawrence 
169*efd4c9b6SSteve Lawrence #define	ZS_UINT64_STRLEN 20
170*efd4c9b6SSteve Lawrence #define	ZS_PCT_STRLEN	10
171*efd4c9b6SSteve Lawrence #define	ZS_TIME_STRLEN	20
172*efd4c9b6SSteve Lawrence #define	ZS_NAME_STRLEN	10
173*efd4c9b6SSteve Lawrence 
174*efd4c9b6SSteve Lawrence time_t g_now_time;
175*efd4c9b6SSteve Lawrence time_t g_boot_time;
176*efd4c9b6SSteve Lawrence time_t g_start_time;
177*efd4c9b6SSteve Lawrence time_t g_end_time;
178*efd4c9b6SSteve Lawrence int g_interval;
179*efd4c9b6SSteve Lawrence int g_count;
180*efd4c9b6SSteve Lawrence int g_report_count;
181*efd4c9b6SSteve Lawrence time_t g_seconds;
182*efd4c9b6SSteve Lawrence 
183*efd4c9b6SSteve Lawrence int g_resources;
184*efd4c9b6SSteve Lawrence zs_ctl_t *g_zsctl;
185*efd4c9b6SSteve Lawrence boolean_t g_quit = B_FALSE;
186*efd4c9b6SSteve Lawrence zs_zone_t **g_zone_list;
187*efd4c9b6SSteve Lawrence int g_zone_num;
188*efd4c9b6SSteve Lawrence zs_pset_zone_t **g_pz_list;
189*efd4c9b6SSteve Lawrence int g_pz_num;
190*efd4c9b6SSteve Lawrence zs_pset_t **g_pset_list;
191*efd4c9b6SSteve Lawrence int g_pset_num;
192*efd4c9b6SSteve Lawrence int g_sort_by;
193*efd4c9b6SSteve Lawrence int g_sorts[ZSTAT_SORT_MAX];
194*efd4c9b6SSteve Lawrence int g_sort_summary;
195*efd4c9b6SSteve Lawrence size_t g_max_zonename;
196*efd4c9b6SSteve Lawrence 
197*efd4c9b6SSteve Lawrence /* Storage for command line arguments. */
198*efd4c9b6SSteve Lawrence char **arg_zonenames;
199*efd4c9b6SSteve Lawrence int arg_zonename_count;
200*efd4c9b6SSteve Lawrence char **arg_resnames;
201*efd4c9b6SSteve Lawrence int arg_resname_count;
202*efd4c9b6SSteve Lawrence char **arg_restypes;
203*efd4c9b6SSteve Lawrence int arg_restype_count;
204*efd4c9b6SSteve Lawrence char ** arg_reports;
205*efd4c9b6SSteve Lawrence int arg_report_count;
206*efd4c9b6SSteve Lawrence char ** arg_sort_list;
207*efd4c9b6SSteve Lawrence int arg_sort_count;
208*efd4c9b6SSteve Lawrence char ** arg_line_list;
209*efd4c9b6SSteve Lawrence int arg_line_count;
210*efd4c9b6SSteve Lawrence 
211*efd4c9b6SSteve Lawrence time_t arg_starttime;
212*efd4c9b6SSteve Lawrence time_t arg_endtime;
213*efd4c9b6SSteve Lawrence uint_t arg_timestamp = ZSTAT_DATE_TIMESTAMP;
214*efd4c9b6SSteve Lawrence int arg_interval = 5;
215*efd4c9b6SSteve Lawrence int arg_duration = -1;
216*efd4c9b6SSteve Lawrence int arg_report = -1;
217*efd4c9b6SSteve Lawrence 
218*efd4c9b6SSteve Lawrence /* Options with or as arguments */
219*efd4c9b6SSteve Lawrence boolean_t opt_zonenames = B_FALSE;
220*efd4c9b6SSteve Lawrence boolean_t opt_resnames = B_FALSE;
221*efd4c9b6SSteve Lawrence boolean_t opt_restypes = B_FALSE;
222*efd4c9b6SSteve Lawrence boolean_t opt_start = B_FALSE;
223*efd4c9b6SSteve Lawrence boolean_t opt_end = B_FALSE;
224*efd4c9b6SSteve Lawrence boolean_t opt_in = B_FALSE;
225*efd4c9b6SSteve Lawrence boolean_t opt_out = B_FALSE;
226*efd4c9b6SSteve Lawrence boolean_t opt_timestamp = B_FALSE;
227*efd4c9b6SSteve Lawrence boolean_t opt_report = B_FALSE;
228*efd4c9b6SSteve Lawrence boolean_t opt_sort = B_FALSE;
229*efd4c9b6SSteve Lawrence 
230*efd4c9b6SSteve Lawrence boolean_t opt_report_high = B_FALSE;
231*efd4c9b6SSteve Lawrence boolean_t opt_report_total = B_FALSE;
232*efd4c9b6SSteve Lawrence boolean_t opt_report_average = B_FALSE;
233*efd4c9b6SSteve Lawrence 
234*efd4c9b6SSteve Lawrence boolean_t opt_line_resource = B_FALSE;
235*efd4c9b6SSteve Lawrence boolean_t opt_line_total = B_FALSE;
236*efd4c9b6SSteve Lawrence boolean_t opt_line_system = B_FALSE;
237*efd4c9b6SSteve Lawrence boolean_t opt_line_zones = B_FALSE;
238*efd4c9b6SSteve Lawrence boolean_t opt_line_header = B_FALSE;
239*efd4c9b6SSteve Lawrence boolean_t opt_line_any = B_FALSE;
240*efd4c9b6SSteve Lawrence 
241*efd4c9b6SSteve Lawrence /* Options without arguments */
242*efd4c9b6SSteve Lawrence boolean_t opt_quiet_intervals = B_FALSE;
243*efd4c9b6SSteve Lawrence boolean_t opt_parseable = B_FALSE;
244*efd4c9b6SSteve Lawrence boolean_t opt_debug = B_FALSE;
245*efd4c9b6SSteve Lawrence 
246*efd4c9b6SSteve Lawrence static int
zonestat_usage(boolean_t explicit)247*efd4c9b6SSteve Lawrence zonestat_usage(boolean_t explicit)
248*efd4c9b6SSteve Lawrence {
249*efd4c9b6SSteve Lawrence 	FILE *fd = explicit ? stdout : stderr;
250*efd4c9b6SSteve Lawrence 
251*efd4c9b6SSteve Lawrence 	(void) fprintf(fd, gettext("Usage:\n"));
252*efd4c9b6SSteve Lawrence 	(void) fprintf(fd,
253*efd4c9b6SSteve Lawrence "    zonestat [-z zonelist] [-r reslist] [-n namelist]\n"
254*efd4c9b6SSteve Lawrence "             [-T u | d | i] [-R reports] [-q] [-p [-P lines]] [-S cols]\n"
255*efd4c9b6SSteve Lawrence "             interval [duration [report]]\n"
256*efd4c9b6SSteve Lawrence "\n");
257*efd4c9b6SSteve Lawrence 	(void) fprintf(fd, gettext(
258*efd4c9b6SSteve Lawrence "    Options:\n"
259*efd4c9b6SSteve Lawrence "    %s    Report resources of specified types.\n"
260*efd4c9b6SSteve Lawrence "	    Valid resource types are:\n"
261*efd4c9b6SSteve Lawrence "	      \"%s\"\n"
262*efd4c9b6SSteve Lawrence "	      \"%s\"\n"
263*efd4c9b6SSteve Lawrence "	      \"%s\"\n"
264*efd4c9b6SSteve Lawrence "	      \"%s\"\n"
265*efd4c9b6SSteve Lawrence "	      \"%s\", \"%s\", \"%s\"\n"
266*efd4c9b6SSteve Lawrence "	      \"%s\", \"%s\", \"%s\", \"%s\"\n"),
267*efd4c9b6SSteve Lawrence 	    "-r",
268*efd4c9b6SSteve Lawrence 	    ZONESTAT_VIRTUAL_MEMORY, ZONESTAT_PHYSICAL_MEMORY,
269*efd4c9b6SSteve Lawrence 	    ZONESTAT_LOCKED_MEMORY, ZONESTAT_PROCESSOR_SET,
270*efd4c9b6SSteve Lawrence 	    ZONESTAT_PROCESSES, ZONESTAT_LWPS, ZONESTAT_LOFI,
271*efd4c9b6SSteve Lawrence 	    ZONESTAT_SHM_MEMORY, ZONESTAT_SHM_IDS, ZONESTAT_SEM_IDS,
272*efd4c9b6SSteve Lawrence 	    ZONESTAT_MSG_IDS);
273*efd4c9b6SSteve Lawrence 
274*efd4c9b6SSteve Lawrence 	(void) fprintf(fd, gettext(
275*efd4c9b6SSteve Lawrence "	    The following resource nicknames can also be specified:\n"
276*efd4c9b6SSteve Lawrence "	      \"%s\"\n"
277*efd4c9b6SSteve Lawrence "	      \"%s\"\n"
278*efd4c9b6SSteve Lawrence "	      \"%s\"\n"
279*efd4c9b6SSteve Lawrence "	      \"%s\"\n"
280*efd4c9b6SSteve Lawrence "	      \"%s\"\n"
281*efd4c9b6SSteve Lawrence "	      \"%s\"\n"),
282*efd4c9b6SSteve Lawrence 	    ZONESTAT_SUMMARY, ZONESTAT_MEMORY, ZONESTAT_PSETS,
283*efd4c9b6SSteve Lawrence 	    ZONESTAT_DEFAULT_PSET, ZONESTAT_LIMITS, ZONESTAT_SYSV);
284*efd4c9b6SSteve Lawrence 	(void) fprintf(fd, gettext(
285*efd4c9b6SSteve Lawrence "    %s    Report resources used by zones\n"
286*efd4c9b6SSteve Lawrence "    %s    Report resources with specific names.\n"
287*efd4c9b6SSteve Lawrence "	    Valid resource names are:\n"
288*efd4c9b6SSteve Lawrence "	      \"%s\"\n"
289*efd4c9b6SSteve Lawrence "	      \"%s\"\n"
290*efd4c9b6SSteve Lawrence "	      Name of a pool processor set\n"
291*efd4c9b6SSteve Lawrence "	      Id of a processor set created with psrset(1m)\n"
292*efd4c9b6SSteve Lawrence "	      Name of a zone using dedicated-cpu\n"),
293*efd4c9b6SSteve Lawrence 	    "-z", "-n",
294*efd4c9b6SSteve Lawrence 	    ZONESTAT_NAME_MEM_DEFAULT, ZONESTAT_NAME_VM_DEFAULT);
295*efd4c9b6SSteve Lawrence 	(void) printf(gettext(
296*efd4c9b6SSteve Lawrence "    %s    Print timestamp. Valid timestamps are:\n"
297*efd4c9b6SSteve Lawrence "	      \"%s\"\tDate as specifed by date(1) command\n"
298*efd4c9b6SSteve Lawrence "	      \"%s\"\tUnix time as returned by time(2)\n"
299*efd4c9b6SSteve Lawrence "	      \"%s\"\tISO 8601 timestamp \"%s\"\n"
300*efd4c9b6SSteve Lawrence "    %s    Print reports at end or after each report interval.\n"
301*efd4c9b6SSteve Lawrence "	    Valid reports are:\n"
302*efd4c9b6SSteve Lawrence "	      \"%s\"\tUsage of each zone\n"
303*efd4c9b6SSteve Lawrence "	      \"%s\"\tUsage of each zone while running\n"
304*efd4c9b6SSteve Lawrence "	      \"%s\"\tMaximum usage of each zone\n"
305*efd4c9b6SSteve Lawrence "    %s    Quiet.  Do not print intervals.  Only print reports.\n"
306*efd4c9b6SSteve Lawrence "    %s    Machine parseable output.\n"),
307*efd4c9b6SSteve Lawrence 	    "-T", "d", "u", "i", "YYYYMMDDThhmmssZ",
308*efd4c9b6SSteve Lawrence 	    "-R", ZONESTAT_NAME_TOTAL, ZONESTAT_NAME_AVERAGE,
309*efd4c9b6SSteve Lawrence 	    ZONESTAT_NAME_HIGH,
310*efd4c9b6SSteve Lawrence 	    "-q", "-p");
311*efd4c9b6SSteve Lawrence 
312*efd4c9b6SSteve Lawrence 	(void) printf(gettext(
313*efd4c9b6SSteve Lawrence "    %s    Select desired lines in parseable output.\n"
314*efd4c9b6SSteve Lawrence "	      \"%s\"\tLines describing each resource\n"
315*efd4c9b6SSteve Lawrence "	      \"%s\"\tTotal usage of each resource\n"
316*efd4c9b6SSteve Lawrence "	      \"%s\"\tSystem usage of each resource\n"
317*efd4c9b6SSteve Lawrence "	      \"%s\"\tPer-zone usage of each resource\n"
318*efd4c9b6SSteve Lawrence "	      \"%s\"\tHeader lines between intervals and reports\n"),
319*efd4c9b6SSteve Lawrence 	    "-P", ZONESTAT_NAME_RESOURCE, ZONESTAT_NAME_TOTAL,
320*efd4c9b6SSteve Lawrence 	    ZONESTAT_NAME_SYSTEM, ZONESTAT_NAME_ZONES, ZONESTAT_NAME_HEADER);
321*efd4c9b6SSteve Lawrence 
322*efd4c9b6SSteve Lawrence 	(void) printf(gettext(
323*efd4c9b6SSteve Lawrence "    %s    Sort output by the specified columns:\n"
324*efd4c9b6SSteve Lawrence "	      \"%s\"\tby name alphanumerically\n"
325*efd4c9b6SSteve Lawrence "	      \"%s\"\tby percent of resource used\n"
326*efd4c9b6SSteve Lawrence "	      \"%s\"\tby configured cap\n"
327*efd4c9b6SSteve Lawrence "	      \"%s\"\tby percent of cap used\n"
328*efd4c9b6SSteve Lawrence "	      \"%s\"\tby shares configured\n"
329*efd4c9b6SSteve Lawrence "	      \"%s\"\tby percent of share used\n"
330*efd4c9b6SSteve Lawrence "	      \"%s\"\tSort summary by cpu\n"
331*efd4c9b6SSteve Lawrence "	      \"%s\"\tSort summary by physical memory\n"
332*efd4c9b6SSteve Lawrence "	      \"%s\"\tSort summary by virtual memory\n"),
333*efd4c9b6SSteve Lawrence 	    "-S", ZONESTAT_NAME_NAME, ZONESTAT_NAME_USED, ZONESTAT_NAME_CAP,
334*efd4c9b6SSteve Lawrence 	    ZONESTAT_NAME_PCAP, ZONESTAT_NAME_SHR, ZONESTAT_NAME_PSHRU,
335*efd4c9b6SSteve Lawrence 	    ZONESTAT_NAME_CPU, ZONESTAT_NAME_PHYSICAL_MEMORY,
336*efd4c9b6SSteve Lawrence 	    ZONESTAT_NAME_VIRTUAL_MEMORY);
337*efd4c9b6SSteve Lawrence 
338*efd4c9b6SSteve Lawrence 	if (!explicit)
339*efd4c9b6SSteve Lawrence 		(void) fputs("\n", fd);
340*efd4c9b6SSteve Lawrence 	return (ZSTAT_USAGE);
341*efd4c9b6SSteve Lawrence }
342*efd4c9b6SSteve Lawrence 
343*efd4c9b6SSteve Lawrence /* PRINTFLIKE1 */
344*efd4c9b6SSteve Lawrence static int
zonestat_error(const char * fmt,...)345*efd4c9b6SSteve Lawrence zonestat_error(const char *fmt, ...)
346*efd4c9b6SSteve Lawrence {
347*efd4c9b6SSteve Lawrence 	va_list alist;
348*efd4c9b6SSteve Lawrence 
349*efd4c9b6SSteve Lawrence 	va_start(alist, fmt);
350*efd4c9b6SSteve Lawrence 
351*efd4c9b6SSteve Lawrence 	(void) fprintf(stderr, "zonestat: Error: ");
352*efd4c9b6SSteve Lawrence 	(void) vfprintf(stderr, fmt, alist);
353*efd4c9b6SSteve Lawrence 	(void) fprintf(stderr, "\n");
354*efd4c9b6SSteve Lawrence 	va_end(alist);
355*efd4c9b6SSteve Lawrence 	return (ZSTAT_ERROR);
356*efd4c9b6SSteve Lawrence }
357*efd4c9b6SSteve Lawrence 
358*efd4c9b6SSteve Lawrence static void
zonestat_determine_lines()359*efd4c9b6SSteve Lawrence zonestat_determine_lines()
360*efd4c9b6SSteve Lawrence {
361*efd4c9b6SSteve Lawrence 	int i;
362*efd4c9b6SSteve Lawrence 	boolean_t fail = B_FALSE;
363*efd4c9b6SSteve Lawrence 
364*efd4c9b6SSteve Lawrence 	if (arg_line_count == 0) {
365*efd4c9b6SSteve Lawrence 		opt_line_resource = B_TRUE;
366*efd4c9b6SSteve Lawrence 		opt_line_total = B_TRUE;
367*efd4c9b6SSteve Lawrence 		opt_line_system = B_TRUE;
368*efd4c9b6SSteve Lawrence 		opt_line_zones = B_TRUE;
369*efd4c9b6SSteve Lawrence 		opt_line_header = B_TRUE;
370*efd4c9b6SSteve Lawrence 	}
371*efd4c9b6SSteve Lawrence 	for (i = 0; i < arg_line_count; i++) {
372*efd4c9b6SSteve Lawrence 		if (strcmp(arg_line_list[i], ZONESTAT_NAME_RESOURCE) == 0)
373*efd4c9b6SSteve Lawrence 			opt_line_resource = B_TRUE;
374*efd4c9b6SSteve Lawrence 		else if (strcmp(arg_line_list[i], ZONESTAT_NAME_TOTAL) == 0)
375*efd4c9b6SSteve Lawrence 			opt_line_total = B_TRUE;
376*efd4c9b6SSteve Lawrence 		else if (strcmp(arg_line_list[i], ZONESTAT_NAME_SYSTEM) == 0)
377*efd4c9b6SSteve Lawrence 			opt_line_system = B_TRUE;
378*efd4c9b6SSteve Lawrence 		else if (strcmp(arg_line_list[i], ZONESTAT_NAME_ZONES) == 0)
379*efd4c9b6SSteve Lawrence 			opt_line_zones = B_TRUE;
380*efd4c9b6SSteve Lawrence 		else if (strcmp(arg_line_list[i], ZONESTAT_NAME_HEADER) == 0)
381*efd4c9b6SSteve Lawrence 			opt_line_header = B_TRUE;
382*efd4c9b6SSteve Lawrence 		else {
383*efd4c9b6SSteve Lawrence 			(void) zonestat_error(gettext("Unknown -O arg: %s"),
384*efd4c9b6SSteve Lawrence 			    arg_line_list[i]);
385*efd4c9b6SSteve Lawrence 			fail = B_TRUE;
386*efd4c9b6SSteve Lawrence 		}
387*efd4c9b6SSteve Lawrence 	}
388*efd4c9b6SSteve Lawrence 	if (fail == B_TRUE)
389*efd4c9b6SSteve Lawrence 		exit(zonestat_usage(B_FALSE));
390*efd4c9b6SSteve Lawrence }
391*efd4c9b6SSteve Lawrence 
392*efd4c9b6SSteve Lawrence static void
zonestat_determine_reports()393*efd4c9b6SSteve Lawrence zonestat_determine_reports()
394*efd4c9b6SSteve Lawrence {
395*efd4c9b6SSteve Lawrence 	int i;
396*efd4c9b6SSteve Lawrence 	boolean_t fail = B_FALSE;
397*efd4c9b6SSteve Lawrence 
398*efd4c9b6SSteve Lawrence 	for (i = 0; i < arg_report_count; i++) {
399*efd4c9b6SSteve Lawrence 		if (strcmp(arg_reports[i], ZONESTAT_NAME_TOTAL) == 0)
400*efd4c9b6SSteve Lawrence 			opt_report_total = B_TRUE;
401*efd4c9b6SSteve Lawrence 		else if (strcmp(arg_reports[i], ZONESTAT_NAME_AVERAGE) == 0)
402*efd4c9b6SSteve Lawrence 			opt_report_average = B_TRUE;
403*efd4c9b6SSteve Lawrence 		else if (strcmp(arg_reports[i], ZONESTAT_NAME_HIGH) == 0)
404*efd4c9b6SSteve Lawrence 			opt_report_high = B_TRUE;
405*efd4c9b6SSteve Lawrence 		else {
406*efd4c9b6SSteve Lawrence 			(void) zonestat_error(gettext("Unknown -R arg: %s"),
407*efd4c9b6SSteve Lawrence 			    arg_reports[i]);
408*efd4c9b6SSteve Lawrence 			fail = B_TRUE;
409*efd4c9b6SSteve Lawrence 		}
410*efd4c9b6SSteve Lawrence 	}
411*efd4c9b6SSteve Lawrence 	if (fail == B_TRUE)
412*efd4c9b6SSteve Lawrence 		exit(zonestat_usage(B_FALSE));
413*efd4c9b6SSteve Lawrence }
414*efd4c9b6SSteve Lawrence 
415*efd4c9b6SSteve Lawrence /*
416*efd4c9b6SSteve Lawrence  * Compares list of -S sort arguments to the list of known sorts.  Only
417*efd4c9b6SSteve Lawrence  * one of cpu, physical memory, and virtual memory can be specified.
418*efd4c9b6SSteve Lawrence  */
419*efd4c9b6SSteve Lawrence static void
zonestat_determine_sort()420*efd4c9b6SSteve Lawrence zonestat_determine_sort()
421*efd4c9b6SSteve Lawrence {
422*efd4c9b6SSteve Lawrence 	int i, count = 0;
423*efd4c9b6SSteve Lawrence 	boolean_t fail = B_FALSE;
424*efd4c9b6SSteve Lawrence 
425*efd4c9b6SSteve Lawrence 	if (arg_sort_count == 0) {
426*efd4c9b6SSteve Lawrence 		g_sort_summary = ZS_RESOURCE_CPU;
427*efd4c9b6SSteve Lawrence 		g_sorts[0] = ZSTAT_SORT_USED;
428*efd4c9b6SSteve Lawrence 		g_sorts[1] = ZSTAT_SORT_NAME;
429*efd4c9b6SSteve Lawrence 		arg_sort_count = 2;
430*efd4c9b6SSteve Lawrence 		return;
431*efd4c9b6SSteve Lawrence 	}
432*efd4c9b6SSteve Lawrence 
433*efd4c9b6SSteve Lawrence 	if (arg_sort_count > ZSTAT_SORT_MAX)
434*efd4c9b6SSteve Lawrence 		exit(zonestat_error(gettext(
435*efd4c9b6SSteve Lawrence 		    "Too many -S sort columns specified")));
436*efd4c9b6SSteve Lawrence 
437*efd4c9b6SSteve Lawrence 	for (i = 0; i < arg_sort_count; i++) {
438*efd4c9b6SSteve Lawrence 		if (strcmp(arg_sort_list[i], ZONESTAT_NAME_NAME) == 0)
439*efd4c9b6SSteve Lawrence 			g_sorts[count++] = ZSTAT_SORT_NAME;
440*efd4c9b6SSteve Lawrence 		else if (strcmp(arg_sort_list[i], ZONESTAT_NAME_USED) == 0)
441*efd4c9b6SSteve Lawrence 			g_sorts[count++] = ZSTAT_SORT_USED;
442*efd4c9b6SSteve Lawrence 		else if (strcmp(arg_sort_list[i], ZONESTAT_NAME_CAP) == 0)
443*efd4c9b6SSteve Lawrence 			g_sorts[count++] = ZSTAT_SORT_CAP;
444*efd4c9b6SSteve Lawrence 		else if (strcmp(arg_sort_list[i], ZONESTAT_NAME_PCAP) == 0)
445*efd4c9b6SSteve Lawrence 			g_sorts[count++] = ZSTAT_SORT_PCAP;
446*efd4c9b6SSteve Lawrence 		else if (strcmp(arg_sort_list[i], ZONESTAT_NAME_SHR) == 0)
447*efd4c9b6SSteve Lawrence 			g_sorts[count++] = ZSTAT_SORT_SHR;
448*efd4c9b6SSteve Lawrence 		else if (strcmp(arg_sort_list[i], ZONESTAT_NAME_PSHRU) == 0)
449*efd4c9b6SSteve Lawrence 			g_sorts[count++] = ZSTAT_SORT_PSHRU;
450*efd4c9b6SSteve Lawrence 		else if (strcmp(arg_sort_list[i], ZONESTAT_NAME_CPU) == 0) {
451*efd4c9b6SSteve Lawrence 			if (g_sort_summary != 0)
452*efd4c9b6SSteve Lawrence 				fail = B_TRUE;
453*efd4c9b6SSteve Lawrence 			g_sort_summary = ZS_RESOURCE_CPU;
454*efd4c9b6SSteve Lawrence 		} else if (strcmp(arg_sort_list[i],
455*efd4c9b6SSteve Lawrence 		    ZONESTAT_NAME_PHYSICAL_MEMORY) == 0) {
456*efd4c9b6SSteve Lawrence 			if (g_sort_summary != 0)
457*efd4c9b6SSteve Lawrence 				fail = B_TRUE;
458*efd4c9b6SSteve Lawrence 			g_sort_summary = ZS_RESOURCE_RAM_RSS;
459*efd4c9b6SSteve Lawrence 		} else if (strcmp(arg_sort_list[i],
460*efd4c9b6SSteve Lawrence 		    ZONESTAT_NAME_VIRTUAL_MEMORY) == 0) {
461*efd4c9b6SSteve Lawrence 			if (g_sort_summary != 0)
462*efd4c9b6SSteve Lawrence 				fail = B_TRUE;
463*efd4c9b6SSteve Lawrence 			g_sort_summary = ZS_RESOURCE_VM;
464*efd4c9b6SSteve Lawrence 		} else {
465*efd4c9b6SSteve Lawrence 			(void) zonestat_error(gettext("Unknown -S arg: %s"),
466*efd4c9b6SSteve Lawrence 			    arg_sort_list[i]);
467*efd4c9b6SSteve Lawrence 			fail = B_TRUE;
468*efd4c9b6SSteve Lawrence 		}
469*efd4c9b6SSteve Lawrence 	}
470*efd4c9b6SSteve Lawrence 	if (g_sort_summary == 0)
471*efd4c9b6SSteve Lawrence 		g_sort_summary = ZS_RESOURCE_CPU;
472*efd4c9b6SSteve Lawrence 
473*efd4c9b6SSteve Lawrence 	if (fail == B_TRUE) {
474*efd4c9b6SSteve Lawrence 		(void) zonestat_error(gettext(
475*efd4c9b6SSteve Lawrence 		    "-S: only one of \"%s\", \"%s\", or "
476*efd4c9b6SSteve Lawrence 		    "\"%s\" permitted"), "-S", ZONESTAT_NAME_CPU,
477*efd4c9b6SSteve Lawrence 		    ZONESTAT_NAME_PHYSICAL_MEMORY,
478*efd4c9b6SSteve Lawrence 		    ZONESTAT_NAME_VIRTUAL_MEMORY);
479*efd4c9b6SSteve Lawrence 		exit(zonestat_usage(B_FALSE));
480*efd4c9b6SSteve Lawrence 	}
481*efd4c9b6SSteve Lawrence }
482*efd4c9b6SSteve Lawrence 
483*efd4c9b6SSteve Lawrence typedef struct zonestat_resource_struct {
484*efd4c9b6SSteve Lawrence 	char *zr_name;
485*efd4c9b6SSteve Lawrence 	uint_t zr_flag;
486*efd4c9b6SSteve Lawrence } zonestat_resource_t;
487*efd4c9b6SSteve Lawrence 
488*efd4c9b6SSteve Lawrence 
489*efd4c9b6SSteve Lawrence /* Used to map resource name strings to resource flags */
490*efd4c9b6SSteve Lawrence zonestat_resource_t g_resource_list[] = {
491*efd4c9b6SSteve Lawrence 	ZONESTAT_PHYSICAL_MEMORY, ZSTAT_RES_PHYSICAL_MEMORY,
492*efd4c9b6SSteve Lawrence 	ZONESTAT_VIRTUAL_MEMORY, ZSTAT_RES_VIRTUAL_MEMORY,
493*efd4c9b6SSteve Lawrence 	ZONESTAT_LOCKED_MEMORY, ZSTAT_RES_LOCKED_MEMORY,
494*efd4c9b6SSteve Lawrence 	ZONESTAT_MEMORY, ZSTAT_RES_MEMORY,
495*efd4c9b6SSteve Lawrence 	ZONESTAT_PROCESSOR_SET, ZSTAT_RES_PSETS,
496*efd4c9b6SSteve Lawrence 	ZONESTAT_PSETS, ZSTAT_RES_PSETS,
497*efd4c9b6SSteve Lawrence 	ZONESTAT_DEFAULT_PSET, ZSTAT_RES_DEFAULT_PSET,
498*efd4c9b6SSteve Lawrence 	ZONESTAT_PROCESSES, ZSTAT_RES_PROCESSES,
499*efd4c9b6SSteve Lawrence 	ZONESTAT_LWPS, ZSTAT_RES_LWPS,
500*efd4c9b6SSteve Lawrence 	ZONESTAT_LOFI, ZSTAT_RES_LOFI,
501*efd4c9b6SSteve Lawrence 	ZONESTAT_LIMITS, ZSTAT_RES_LIMITS,
502*efd4c9b6SSteve Lawrence 	ZONESTAT_SHM_MEMORY, ZSTAT_RES_SHM_MEMORY,
503*efd4c9b6SSteve Lawrence 	ZONESTAT_SHM_IDS, ZSTAT_RES_SHM_IDS,
504*efd4c9b6SSteve Lawrence 	ZONESTAT_SEM_IDS, ZSTAT_RES_SEM_IDS,
505*efd4c9b6SSteve Lawrence 	ZONESTAT_MSG_IDS, ZSTAT_RES_MSG_IDS,
506*efd4c9b6SSteve Lawrence 	ZONESTAT_SYSV, ZSTAT_RES_SYSV,
507*efd4c9b6SSteve Lawrence 	ZONESTAT_SUMMARY, ZSTAT_RES_SUMMARY,
508*efd4c9b6SSteve Lawrence 	ZONESTAT_ALL, ZSTAT_RES_ALL
509*efd4c9b6SSteve Lawrence };
510*efd4c9b6SSteve Lawrence 
511*efd4c9b6SSteve Lawrence /*
512*efd4c9b6SSteve Lawrence  * Compares list of resources passed to -r to the known list of
513*efd4c9b6SSteve Lawrence  * resources.
514*efd4c9b6SSteve Lawrence  */
515*efd4c9b6SSteve Lawrence static void
zonestat_determine_resources()516*efd4c9b6SSteve Lawrence zonestat_determine_resources()
517*efd4c9b6SSteve Lawrence {
518*efd4c9b6SSteve Lawrence 	int i, j, count;
519*efd4c9b6SSteve Lawrence 	boolean_t found, fail = B_FALSE;
520*efd4c9b6SSteve Lawrence 
521*efd4c9b6SSteve Lawrence 	if (arg_restype_count == 0) {
522*efd4c9b6SSteve Lawrence 		g_resources = ZSTAT_RES_SUMMARY;
523*efd4c9b6SSteve Lawrence 		return;
524*efd4c9b6SSteve Lawrence 	}
525*efd4c9b6SSteve Lawrence 
526*efd4c9b6SSteve Lawrence 	count = sizeof (g_resource_list) / sizeof (zonestat_resource_t);
527*efd4c9b6SSteve Lawrence 
528*efd4c9b6SSteve Lawrence 	for (i = 0; i < arg_restype_count; i++) {
529*efd4c9b6SSteve Lawrence 		found = B_FALSE;
530*efd4c9b6SSteve Lawrence 		for (j = 0; j < count; j++) {
531*efd4c9b6SSteve Lawrence 			if (strcmp(arg_restypes[i], g_resource_list[j].zr_name)
532*efd4c9b6SSteve Lawrence 			    == 0) {
533*efd4c9b6SSteve Lawrence 				g_resources |= g_resource_list[j].zr_flag;
534*efd4c9b6SSteve Lawrence 				found = B_TRUE;
535*efd4c9b6SSteve Lawrence 				break;
536*efd4c9b6SSteve Lawrence 			}
537*efd4c9b6SSteve Lawrence 		}
538*efd4c9b6SSteve Lawrence 		if (found == B_FALSE) {
539*efd4c9b6SSteve Lawrence 			(void) zonestat_error(gettext("Unknown resource: %s"),
540*efd4c9b6SSteve Lawrence 			    arg_restypes[i]);
541*efd4c9b6SSteve Lawrence 			fail = B_TRUE;
542*efd4c9b6SSteve Lawrence 		}
543*efd4c9b6SSteve Lawrence 	}
544*efd4c9b6SSteve Lawrence 	if (fail == B_TRUE)
545*efd4c9b6SSteve Lawrence 		exit(zonestat_usage(B_FALSE));
546*efd4c9b6SSteve Lawrence }
547*efd4c9b6SSteve Lawrence 
548*efd4c9b6SSteve Lawrence /*
549*efd4c9b6SSteve Lawrence  * Returns 1 if the name matches one of the specified zone names.  0
550*efd4c9b6SSteve Lawrence  * otherwise.  Always matches if no zone names were specified.
551*efd4c9b6SSteve Lawrence  */
552*efd4c9b6SSteve Lawrence static int
zonestat_match_zonename(char * name)553*efd4c9b6SSteve Lawrence zonestat_match_zonename(char *name)
554*efd4c9b6SSteve Lawrence {
555*efd4c9b6SSteve Lawrence 	int i;
556*efd4c9b6SSteve Lawrence 
557*efd4c9b6SSteve Lawrence 	if (arg_zonename_count == 0)
558*efd4c9b6SSteve Lawrence 		return (1);
559*efd4c9b6SSteve Lawrence 	for (i = 0; i < arg_zonename_count; i++) {
560*efd4c9b6SSteve Lawrence 		if (strcmp(name, arg_zonenames[i]) == 0)
561*efd4c9b6SSteve Lawrence 			return (1);
562*efd4c9b6SSteve Lawrence 	}
563*efd4c9b6SSteve Lawrence 	return (0);
564*efd4c9b6SSteve Lawrence }
565*efd4c9b6SSteve Lawrence 
566*efd4c9b6SSteve Lawrence /*
567*efd4c9b6SSteve Lawrence  * compare name to base, ignoring prefix on name.
568*efd4c9b6SSteve Lawrence  */
569*efd4c9b6SSteve Lawrence static int
zonestat_match_with_prefix(char * prefix,char * name,char * base)570*efd4c9b6SSteve Lawrence zonestat_match_with_prefix(char *prefix, char *name, char *base)
571*efd4c9b6SSteve Lawrence {
572*efd4c9b6SSteve Lawrence 	size_t prefix_len;
573*efd4c9b6SSteve Lawrence 
574*efd4c9b6SSteve Lawrence 	prefix_len = strlen(prefix);
575*efd4c9b6SSteve Lawrence 	if (strncmp(name, prefix, prefix_len) == 0) {
576*efd4c9b6SSteve Lawrence 		name += prefix_len;
577*efd4c9b6SSteve Lawrence 		if (strcmp(name, base) == 0)
578*efd4c9b6SSteve Lawrence 			return (1);
579*efd4c9b6SSteve Lawrence 	}
580*efd4c9b6SSteve Lawrence 	return (0);
581*efd4c9b6SSteve Lawrence }
582*efd4c9b6SSteve Lawrence /*
583*efd4c9b6SSteve Lawrence  * Returns 1 if the resource matches one of the specified resource names.  0
584*efd4c9b6SSteve Lawrence  * otherwise.  Always matches if no resource names were specified.
585*efd4c9b6SSteve Lawrence  */
586*efd4c9b6SSteve Lawrence static int
zonestat_match_resname(char * name)587*efd4c9b6SSteve Lawrence zonestat_match_resname(char *name)
588*efd4c9b6SSteve Lawrence {
589*efd4c9b6SSteve Lawrence 	int i;
590*efd4c9b6SSteve Lawrence 
591*efd4c9b6SSteve Lawrence 	if (arg_resname_count == 0)
592*efd4c9b6SSteve Lawrence 		return (1);
593*efd4c9b6SSteve Lawrence 	for (i = 0; i < arg_resname_count; i++) {
594*efd4c9b6SSteve Lawrence 
595*efd4c9b6SSteve Lawrence 		if (strcmp(name, arg_resnames[i]) == 0)
596*efd4c9b6SSteve Lawrence 			return (1);
597*efd4c9b6SSteve Lawrence 
598*efd4c9b6SSteve Lawrence 		if (zonestat_match_with_prefix("SUNWtmp_", name,
599*efd4c9b6SSteve Lawrence 		    arg_resnames[i]))
600*efd4c9b6SSteve Lawrence 			return (1);
601*efd4c9b6SSteve Lawrence 
602*efd4c9b6SSteve Lawrence 		if (zonestat_match_with_prefix("SUNWlegacy_pset_", name,
603*efd4c9b6SSteve Lawrence 		    arg_resnames[i]))
604*efd4c9b6SSteve Lawrence 			return (1);
605*efd4c9b6SSteve Lawrence 	}
606*efd4c9b6SSteve Lawrence 	return (0);
607*efd4c9b6SSteve Lawrence }
608*efd4c9b6SSteve Lawrence 
609*efd4c9b6SSteve Lawrence /*
610*efd4c9b6SSteve Lawrence  * Format unsigned uint64_t
611*efd4c9b6SSteve Lawrence  *
612*efd4c9b6SSteve Lawrence  * 9999  9999
613*efd4c9b6SSteve Lawrence  * 99.9K 99999
614*efd4c9b6SSteve Lawrence  * 9999K 9999999
615*efd4c9b6SSteve Lawrence  * 99.9M 99999999
616*efd4c9b6SSteve Lawrence  * 9999M 9999999999
617*efd4c9b6SSteve Lawrence  * 99.9G 99999999999
618*efd4c9b6SSteve Lawrence  * 9999G 9999999999999
619*efd4c9b6SSteve Lawrence  * 99.9T 99999999999999
620*efd4c9b6SSteve Lawrence  * 9999T 9999999999999999
621*efd4c9b6SSteve Lawrence  * 99.9P 99999999999999999
622*efd4c9b6SSteve Lawrence  * 9999P 9999999999999999999
623*efd4c9b6SSteve Lawrence  * 99.9E UINT64_MAX
624*efd4c9b6SSteve Lawrence  */
625*efd4c9b6SSteve Lawrence static void
format_uint64(uint64_t val,char * str,size_t len)626*efd4c9b6SSteve Lawrence format_uint64(uint64_t val, char *str, size_t len)
627*efd4c9b6SSteve Lawrence {
628*efd4c9b6SSteve Lawrence 	uint64_t high;
629*efd4c9b6SSteve Lawrence 	uint64_t low;
630*efd4c9b6SSteve Lawrence 
631*efd4c9b6SSteve Lawrence 	if (val == UINT64_MAX) {
632*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "-");
633*efd4c9b6SSteve Lawrence 		return;
634*efd4c9b6SSteve Lawrence 	}
635*efd4c9b6SSteve Lawrence 	if (val <= 9999) {
636*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%llu", val);
637*efd4c9b6SSteve Lawrence 		return;
638*efd4c9b6SSteve Lawrence 	}
639*efd4c9b6SSteve Lawrence 	if (val <= 99999) {
640*efd4c9b6SSteve Lawrence 		high = val / 1024;
641*efd4c9b6SSteve Lawrence 		low = val * 10 / 1024 - (high * 10);
642*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%llu%1.1lluK", high, low);
643*efd4c9b6SSteve Lawrence 		return;
644*efd4c9b6SSteve Lawrence 	}
645*efd4c9b6SSteve Lawrence 	val = val / 1024;
646*efd4c9b6SSteve Lawrence 	if (val <= 9999 || opt_parseable) {
647*efd4c9b6SSteve Lawrence 		high = val;
648*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%lluK", high);
649*efd4c9b6SSteve Lawrence 		return;
650*efd4c9b6SSteve Lawrence 	}
651*efd4c9b6SSteve Lawrence 	if (val <= 99999) {
652*efd4c9b6SSteve Lawrence 		high = val / 1024;
653*efd4c9b6SSteve Lawrence 		low = val * 10 / 1024 - (high * 10);
654*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%llu.%1.1lluM", high, low);
655*efd4c9b6SSteve Lawrence 		return;
656*efd4c9b6SSteve Lawrence 	}
657*efd4c9b6SSteve Lawrence 	val = val / 1024;
658*efd4c9b6SSteve Lawrence 	if (val <= 9999) {
659*efd4c9b6SSteve Lawrence 		high = val;
660*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%lluM", high);
661*efd4c9b6SSteve Lawrence 		return;
662*efd4c9b6SSteve Lawrence 	}
663*efd4c9b6SSteve Lawrence 	if (val <= 99999) {
664*efd4c9b6SSteve Lawrence 		high = val / 1024;
665*efd4c9b6SSteve Lawrence 		low = val * 10 / 1024 - (high * 10);
666*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%llu.%1.1lluG", high, low);
667*efd4c9b6SSteve Lawrence 		return;
668*efd4c9b6SSteve Lawrence 	}
669*efd4c9b6SSteve Lawrence 	val = val / 1024;
670*efd4c9b6SSteve Lawrence 	if (val <= 9999) {
671*efd4c9b6SSteve Lawrence 		high = val;
672*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%lluG", high);
673*efd4c9b6SSteve Lawrence 		return;
674*efd4c9b6SSteve Lawrence 	}
675*efd4c9b6SSteve Lawrence 	if (val <= 99999) {
676*efd4c9b6SSteve Lawrence 		high = val / 1024;
677*efd4c9b6SSteve Lawrence 		low = val * 10 / 1024 - (high * 10);
678*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%llu.%1.1lluT", high, low);
679*efd4c9b6SSteve Lawrence 		return;
680*efd4c9b6SSteve Lawrence 	}
681*efd4c9b6SSteve Lawrence 	val = val / 1024;
682*efd4c9b6SSteve Lawrence 	if (val <= 9999) {
683*efd4c9b6SSteve Lawrence 		high = val;
684*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%lluT", high);
685*efd4c9b6SSteve Lawrence 		return;
686*efd4c9b6SSteve Lawrence 	}
687*efd4c9b6SSteve Lawrence 	if (val <= 99999) {
688*efd4c9b6SSteve Lawrence 		high = val / 1024;
689*efd4c9b6SSteve Lawrence 		low = val * 10 / 1024 - (high * 10);
690*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%llu.%1.1lluP", high, low);
691*efd4c9b6SSteve Lawrence 		return;
692*efd4c9b6SSteve Lawrence 	}
693*efd4c9b6SSteve Lawrence 	val = val / 1024;
694*efd4c9b6SSteve Lawrence 	if (val <= 9999) {
695*efd4c9b6SSteve Lawrence 		high = val;
696*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%lluP", high);
697*efd4c9b6SSteve Lawrence 		return;
698*efd4c9b6SSteve Lawrence 	}
699*efd4c9b6SSteve Lawrence 	high = val / 1024;
700*efd4c9b6SSteve Lawrence 	low = val * 10 / 1024 - (high * 10);
701*efd4c9b6SSteve Lawrence 	(void) snprintf(str, len, "%llu.%1.1lluE", high, low);
702*efd4c9b6SSteve Lawrence }
703*efd4c9b6SSteve Lawrence 
704*efd4c9b6SSteve Lawrence 
705*efd4c9b6SSteve Lawrence static void
format_pct(uint_t pct,char * str,size_t len)706*efd4c9b6SSteve Lawrence format_pct(uint_t pct, char *str, size_t len)
707*efd4c9b6SSteve Lawrence {
708*efd4c9b6SSteve Lawrence 	uint_t high;
709*efd4c9b6SSteve Lawrence 	uint_t low;
710*efd4c9b6SSteve Lawrence 
711*efd4c9b6SSteve Lawrence 	if (pct == ZS_PCT_NONE) {
712*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "-");
713*efd4c9b6SSteve Lawrence 		return;
714*efd4c9b6SSteve Lawrence 	}
715*efd4c9b6SSteve Lawrence 	/*
716*efd4c9b6SSteve Lawrence 	 * pct's are printed as one of:
717*efd4c9b6SSteve Lawrence 	 *	#.##%
718*efd4c9b6SSteve Lawrence 	 *	##.#%
719*efd4c9b6SSteve Lawrence 	 *	 ###%
720*efd4c9b6SSteve Lawrence 	 *	####%
721*efd4c9b6SSteve Lawrence 	 *
722*efd4c9b6SSteve Lawrence 	 * The value is fixed decimal.  10000 equals 100.00 percent.
723*efd4c9b6SSteve Lawrence 	 * Percents can exceed 100.00 percent.  Percents greater than
724*efd4c9b6SSteve Lawrence 	 * 9999% will exceed the 5 column width.
725*efd4c9b6SSteve Lawrence 	 */
726*efd4c9b6SSteve Lawrence 	if (pct <= 999 || opt_parseable) {
727*efd4c9b6SSteve Lawrence 		high = pct / 100;
728*efd4c9b6SSteve Lawrence 		low = pct - (high * 100);
729*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%u.%2.2u%%", high, low);
730*efd4c9b6SSteve Lawrence 	} else if (pct <= 9999) {
731*efd4c9b6SSteve Lawrence 		pct = pct / 10;
732*efd4c9b6SSteve Lawrence 		high = pct / 10;
733*efd4c9b6SSteve Lawrence 		low = pct - (high * 10);
734*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%u.%1.1u%%", high, low);
735*efd4c9b6SSteve Lawrence 	} else {
736*efd4c9b6SSteve Lawrence 		pct = pct / 100;
737*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%u%%", pct);
738*efd4c9b6SSteve Lawrence 	}
739*efd4c9b6SSteve Lawrence }
740*efd4c9b6SSteve Lawrence /*
741*efd4c9b6SSteve Lawrence  * Cpu cap is 100 times the number of cpus allocated.  It is formatted as a
742*efd4c9b6SSteve Lawrence  * decimal.  Example, a cpu-cap of 50 is 0.50 cpus.
743*efd4c9b6SSteve Lawrence  *
744*efd4c9b6SSteve Lawrence  * The cpu cap value can go up to UINT_MAX, so handle all cases even though
745*efd4c9b6SSteve Lawrence  * the higher ones are nonsense.
746*efd4c9b6SSteve Lawrence  *
747*efd4c9b6SSteve Lawrence  * Format  Max cpu-cap value for format.
748*efd4c9b6SSteve Lawrence  * 42.9M   4294967296
749*efd4c9b6SSteve Lawrence  * 9999K   999999999
750*efd4c9b6SSteve Lawrence  * 99.9K   9999999
751*efd4c9b6SSteve Lawrence  *  9999   999999
752*efd4c9b6SSteve Lawrence  * 999.9   99999
753*efd4c9b6SSteve Lawrence  *  9.99   999
754*efd4c9b6SSteve Lawrence  */
755*efd4c9b6SSteve Lawrence void
format_cpu(uint64_t cpu,char * str,size_t len)756*efd4c9b6SSteve Lawrence format_cpu(uint64_t cpu, char *str, size_t len)
757*efd4c9b6SSteve Lawrence {
758*efd4c9b6SSteve Lawrence 
759*efd4c9b6SSteve Lawrence 	uint64_t high;
760*efd4c9b6SSteve Lawrence 	uint64_t low;
761*efd4c9b6SSteve Lawrence 
762*efd4c9b6SSteve Lawrence 	/* #.## cpus */
763*efd4c9b6SSteve Lawrence 	if (cpu <= 999 || opt_parseable) {
764*efd4c9b6SSteve Lawrence 		high = cpu / 100;
765*efd4c9b6SSteve Lawrence 		low = cpu - (high * 100);
766*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%llu.%2.2llu", high, low);
767*efd4c9b6SSteve Lawrence 		return;
768*efd4c9b6SSteve Lawrence 	}
769*efd4c9b6SSteve Lawrence 	/* ##.# cpus */
770*efd4c9b6SSteve Lawrence 	if (cpu <= 99999) {
771*efd4c9b6SSteve Lawrence 		high = cpu / 100;
772*efd4c9b6SSteve Lawrence 		low = cpu - (high * 100);
773*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%llu.%1.1llu", high, low);
774*efd4c9b6SSteve Lawrence 		return;
775*efd4c9b6SSteve Lawrence 	}
776*efd4c9b6SSteve Lawrence 	/* #### cpus */
777*efd4c9b6SSteve Lawrence 	if (cpu <= 999999) {
778*efd4c9b6SSteve Lawrence 		cpu = cpu / 100;
779*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%llu", cpu);
780*efd4c9b6SSteve Lawrence 		return;
781*efd4c9b6SSteve Lawrence 	}
782*efd4c9b6SSteve Lawrence 	/* ##.#K cpus */
783*efd4c9b6SSteve Lawrence 	cpu = cpu / 1000;
784*efd4c9b6SSteve Lawrence 	if (cpu <= 99999) {
785*efd4c9b6SSteve Lawrence 		high = cpu / 100;
786*efd4c9b6SSteve Lawrence 		low = cpu - (high * 100);
787*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%llu.%1.1lluK", high, low);
788*efd4c9b6SSteve Lawrence 		return;
789*efd4c9b6SSteve Lawrence 	}
790*efd4c9b6SSteve Lawrence 	/* ####K cpus */
791*efd4c9b6SSteve Lawrence 	if (cpu <= 999999) {
792*efd4c9b6SSteve Lawrence 		cpu = cpu / 100;
793*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%lluK", cpu);
794*efd4c9b6SSteve Lawrence 		return;
795*efd4c9b6SSteve Lawrence 	}
796*efd4c9b6SSteve Lawrence 	/* ##.#M cpus */
797*efd4c9b6SSteve Lawrence 	cpu = cpu / 1000;
798*efd4c9b6SSteve Lawrence 	if (cpu <= UINT_MAX) {
799*efd4c9b6SSteve Lawrence 		high = cpu / 100;
800*efd4c9b6SSteve Lawrence 		low = cpu - (high * 100);
801*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%llu.%1.1lluM", high, low);
802*efd4c9b6SSteve Lawrence 		return;
803*efd4c9b6SSteve Lawrence 	}
804*efd4c9b6SSteve Lawrence 	(void) snprintf(str, len, "error", high, low);
805*efd4c9b6SSteve Lawrence }
806*efd4c9b6SSteve Lawrence 
807*efd4c9b6SSteve Lawrence /*
808*efd4c9b6SSteve Lawrence  * Format a timetruct as:
809*efd4c9b6SSteve Lawrence  * HH:MM:SS.SS
810*efd4c9b6SSteve Lawrence  *
811*efd4c9b6SSteve Lawrence  * Human readable format omits the fractional seconds.
812*efd4c9b6SSteve Lawrence  */
813*efd4c9b6SSteve Lawrence static void
format_ts(timestruc_t * ts,char * str,size_t len,boolean_t human_readable)814*efd4c9b6SSteve Lawrence format_ts(timestruc_t *ts, char *str, size_t len, boolean_t human_readable)
815*efd4c9b6SSteve Lawrence {
816*efd4c9b6SSteve Lawrence 	uint64_t secs, mins, hours, pct;
817*efd4c9b6SSteve Lawrence 
818*efd4c9b6SSteve Lawrence 	hours = 0;
819*efd4c9b6SSteve Lawrence 	mins = 0;
820*efd4c9b6SSteve Lawrence 
821*efd4c9b6SSteve Lawrence 	secs = ts->tv_sec;
822*efd4c9b6SSteve Lawrence 	pct = ts->tv_nsec / 1000 / 1000 / 10;
823*efd4c9b6SSteve Lawrence 	while (pct >= 100) {
824*efd4c9b6SSteve Lawrence 		pct -= 100;
825*efd4c9b6SSteve Lawrence 		secs++;
826*efd4c9b6SSteve Lawrence 	}
827*efd4c9b6SSteve Lawrence 	if (secs >= 60) {
828*efd4c9b6SSteve Lawrence 		mins = secs / 60;
829*efd4c9b6SSteve Lawrence 		secs = secs % 60;
830*efd4c9b6SSteve Lawrence 	}
831*efd4c9b6SSteve Lawrence 	if (mins >= 60) {
832*efd4c9b6SSteve Lawrence 		hours = mins / 60;
833*efd4c9b6SSteve Lawrence 		mins = mins % 60;
834*efd4c9b6SSteve Lawrence 	}
835*efd4c9b6SSteve Lawrence 	if (human_readable)
836*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%llu:%2.2llu:%2.2llu", hours,
837*efd4c9b6SSteve Lawrence 		    mins, secs);
838*efd4c9b6SSteve Lawrence 	else
839*efd4c9b6SSteve Lawrence 		(void) snprintf(str, len, "%llu-%2.2llu-%2.2llu.%2.2llu", hours,
840*efd4c9b6SSteve Lawrence 		    mins, secs, pct);
841*efd4c9b6SSteve Lawrence }
842*efd4c9b6SSteve Lawrence 
843*efd4c9b6SSteve Lawrence char *g_report_formats[] = {
844*efd4c9b6SSteve Lawrence 	ZSTAT_REPORT_TEXT_INTERVAL,
845*efd4c9b6SSteve Lawrence 	ZSTAT_REPORT_TEXT_TOTAL,
846*efd4c9b6SSteve Lawrence 	ZSTAT_REPORT_TEXT_AVERAGE,
847*efd4c9b6SSteve Lawrence 	ZSTAT_REPORT_TEXT_HIGH,
848*efd4c9b6SSteve Lawrence 	ZSTAT_REPORT_TEXT_END
849*efd4c9b6SSteve Lawrence };
850*efd4c9b6SSteve Lawrence 
851*efd4c9b6SSteve Lawrence /* Get the label for the current report type */
852*efd4c9b6SSteve Lawrence static char *
zonestat_get_plabel(int format)853*efd4c9b6SSteve Lawrence zonestat_get_plabel(int format)
854*efd4c9b6SSteve Lawrence {
855*efd4c9b6SSteve Lawrence 	if (format >= sizeof (g_report_formats) / sizeof (char *))
856*efd4c9b6SSteve Lawrence 		exit(zonestat_error(gettext(
857*efd4c9b6SSteve Lawrence 		    "Internal error, invalid report format")));
858*efd4c9b6SSteve Lawrence 
859*efd4c9b6SSteve Lawrence 	return (g_report_formats[format]);
860*efd4c9b6SSteve Lawrence }
861*efd4c9b6SSteve Lawrence 
862*efd4c9b6SSteve Lawrence #define	ZSTAT_CPULINE "----------CPU----------"
863*efd4c9b6SSteve Lawrence #define	ZSTAT_MEMLINE "----PHYSICAL-----"
864*efd4c9b6SSteve Lawrence #define	ZSTAT_VMLINE  "-----VIRTUAL-----"
865*efd4c9b6SSteve Lawrence 
866*efd4c9b6SSteve Lawrence static void
zonestat_print_summary_header(size_t namewidth,int report_fmt,uint64_t cpu,uint64_t online,uint64_t mem,uint64_t vm)867*efd4c9b6SSteve Lawrence zonestat_print_summary_header(size_t namewidth, int report_fmt, uint64_t cpu,
868*efd4c9b6SSteve Lawrence     uint64_t online, uint64_t mem, uint64_t vm)
869*efd4c9b6SSteve Lawrence {
870*efd4c9b6SSteve Lawrence 	char str_cpu[ZS_UINT64_STRLEN];
871*efd4c9b6SSteve Lawrence 	char str_online[ZS_UINT64_STRLEN];
872*efd4c9b6SSteve Lawrence 	char str_mem[ZS_UINT64_STRLEN];
873*efd4c9b6SSteve Lawrence 	char str_vm[ZS_UINT64_STRLEN];
874*efd4c9b6SSteve Lawrence 	char name_format[ZS_NAME_STRLEN];
875*efd4c9b6SSteve Lawrence 	char tot_cpu[sizeof (ZSTAT_CPULINE)];
876*efd4c9b6SSteve Lawrence 	char tot_mem[sizeof (ZSTAT_MEMLINE)];
877*efd4c9b6SSteve Lawrence 	char tot_vm[sizeof (ZSTAT_VMLINE)];
878*efd4c9b6SSteve Lawrence 
879*efd4c9b6SSteve Lawrence 	char *label;
880*efd4c9b6SSteve Lawrence 
881*efd4c9b6SSteve Lawrence 	format_uint64(cpu, str_cpu, sizeof (str_cpu));
882*efd4c9b6SSteve Lawrence 	format_uint64(online, str_online, sizeof (str_online));
883*efd4c9b6SSteve Lawrence 	format_uint64(mem, str_mem, sizeof (str_mem));
884*efd4c9b6SSteve Lawrence 	format_uint64(vm, str_vm, sizeof (str_vm));
885*efd4c9b6SSteve Lawrence 
886*efd4c9b6SSteve Lawrence 	if (opt_parseable) {
887*efd4c9b6SSteve Lawrence 		label = zonestat_get_plabel(report_fmt);
888*efd4c9b6SSteve Lawrence 		(void) printf("%s:%s:[%s]:%s:%s:%s:%s\n", label,
889*efd4c9b6SSteve Lawrence 		    ZONESTAT_SUMMARY, ZONESTAT_NAME_RESOURCE, str_cpu,
890*efd4c9b6SSteve Lawrence 		    str_online, str_mem, str_vm);
891*efd4c9b6SSteve Lawrence 		return;
892*efd4c9b6SSteve Lawrence 	}
893*efd4c9b6SSteve Lawrence 
894*efd4c9b6SSteve Lawrence 	(void) snprintf(tot_cpu, sizeof (tot_cpu), "Cpus/Online: %s/%s",
895*efd4c9b6SSteve Lawrence 	    str_cpu, str_online);
896*efd4c9b6SSteve Lawrence 
897*efd4c9b6SSteve Lawrence 	(void) snprintf(tot_mem, sizeof (tot_mem), "Physical: %s", str_mem);
898*efd4c9b6SSteve Lawrence 
899*efd4c9b6SSteve Lawrence 	(void) snprintf(tot_vm, sizeof (tot_vm), "Virtual: %s", str_vm);
900*efd4c9b6SSteve Lawrence 
901*efd4c9b6SSteve Lawrence 	/* Make first column as wide as longest zonename */
902*efd4c9b6SSteve Lawrence 	(void) snprintf(name_format, sizeof (name_format), "%%-%ds ",
903*efd4c9b6SSteve Lawrence 	    namewidth);
904*efd4c9b6SSteve Lawrence 	/* LINTED */
905*efd4c9b6SSteve Lawrence 	(void) printf(name_format, "SUMMARY");
906*efd4c9b6SSteve Lawrence 	(void) printf(ZSTAT_SUM_HDR_FORMAT, tot_cpu, tot_mem,
907*efd4c9b6SSteve Lawrence 	    tot_vm);
908*efd4c9b6SSteve Lawrence 
909*efd4c9b6SSteve Lawrence 	/* LINTED */
910*efd4c9b6SSteve Lawrence 	(void) printf(name_format, "");
911*efd4c9b6SSteve Lawrence 	(void) printf(ZSTAT_SUM_HDR_FORMAT, ZSTAT_CPULINE,
912*efd4c9b6SSteve Lawrence 	    ZSTAT_MEMLINE, ZSTAT_VMLINE);
913*efd4c9b6SSteve Lawrence 
914*efd4c9b6SSteve Lawrence 	(void) snprintf(name_format, sizeof (name_format), "%%%ds ",
915*efd4c9b6SSteve Lawrence 	    namewidth);
916*efd4c9b6SSteve Lawrence 	/* LINTED */
917*efd4c9b6SSteve Lawrence 	(void) printf(name_format, "ZONE");
918*efd4c9b6SSteve Lawrence 
919*efd4c9b6SSteve Lawrence 	(void) printf(ZSTAT_SUM_ZONE_FORMAT, "USED", "%PART", "%CAP",
920*efd4c9b6SSteve Lawrence 	    "%SHRU", "USED", "PCT", "%CAP", "USED", "PCT", "%CAP");
921*efd4c9b6SSteve Lawrence }
922*efd4c9b6SSteve Lawrence 
923*efd4c9b6SSteve Lawrence static void
zonestat_print_resource__header(size_t namelen,char * restype,char * size)924*efd4c9b6SSteve Lawrence zonestat_print_resource__header(size_t namelen, char *restype, char *size)
925*efd4c9b6SSteve Lawrence {
926*efd4c9b6SSteve Lawrence 	char name_format[ZS_NAME_STRLEN];
927*efd4c9b6SSteve Lawrence 
928*efd4c9b6SSteve Lawrence 	if (opt_parseable)
929*efd4c9b6SSteve Lawrence 		return;
930*efd4c9b6SSteve Lawrence 
931*efd4c9b6SSteve Lawrence 	(void) snprintf(name_format, sizeof (name_format), "%%-%ds ", namelen);
932*efd4c9b6SSteve Lawrence 	/* LINTED */
933*efd4c9b6SSteve Lawrence 	(void) printf(name_format, restype);
934*efd4c9b6SSteve Lawrence 	(void) printf(ZSTAT_RESOURCE_FORMAT, size);
935*efd4c9b6SSteve Lawrence }
936*efd4c9b6SSteve Lawrence 
937*efd4c9b6SSteve Lawrence static void
zonestat_print_resource_zone_header(size_t namelen)938*efd4c9b6SSteve Lawrence zonestat_print_resource_zone_header(size_t namelen)
939*efd4c9b6SSteve Lawrence {
940*efd4c9b6SSteve Lawrence 	char name_format[ZS_NAME_STRLEN];
941*efd4c9b6SSteve Lawrence 
942*efd4c9b6SSteve Lawrence 	if (opt_parseable)
943*efd4c9b6SSteve Lawrence 		return;
944*efd4c9b6SSteve Lawrence 
945*efd4c9b6SSteve Lawrence 	(void) snprintf(name_format, sizeof (name_format), "%%%ds ", namelen);
946*efd4c9b6SSteve Lawrence 	/* LINTED */
947*efd4c9b6SSteve Lawrence 	(void) printf(name_format, "ZONE");
948*efd4c9b6SSteve Lawrence 
949*efd4c9b6SSteve Lawrence 	(void) printf(ZSTAT_RESOURCE_ZONE_FORMAT, "USED", "PCT", "CAP", "%CAP");
950*efd4c9b6SSteve Lawrence }
951*efd4c9b6SSteve Lawrence 
952*efd4c9b6SSteve Lawrence static void
zonestat_print_timestamp(time_t t)953*efd4c9b6SSteve Lawrence zonestat_print_timestamp(time_t t)
954*efd4c9b6SSteve Lawrence {
955*efd4c9b6SSteve Lawrence 	static char *fmt = NULL;
956*efd4c9b6SSteve Lawrence 	int len;
957*efd4c9b6SSteve Lawrence 	char dstr[64];
958*efd4c9b6SSteve Lawrence 
959*efd4c9b6SSteve Lawrence 	/* We only need to retrieve this once per invocation */
960*efd4c9b6SSteve Lawrence 
961*efd4c9b6SSteve Lawrence 	if (arg_timestamp == ZSTAT_UNIX_TIMESTAMP) {
962*efd4c9b6SSteve Lawrence 		(void) printf("%ld", t);
963*efd4c9b6SSteve Lawrence 	} else if (arg_timestamp == ZSTAT_ISO_TIMESTAMP) {
964*efd4c9b6SSteve Lawrence 
965*efd4c9b6SSteve Lawrence 		len = strftime(dstr, sizeof (dstr), "%Y%m%dT%H%M%SZ",
966*efd4c9b6SSteve Lawrence 		    gmtime(&t));
967*efd4c9b6SSteve Lawrence 		if (len > 0)
968*efd4c9b6SSteve Lawrence 			(void) printf("%s", dstr);
969*efd4c9b6SSteve Lawrence 
970*efd4c9b6SSteve Lawrence 	} else {
971*efd4c9b6SSteve Lawrence 
972*efd4c9b6SSteve Lawrence 		if (fmt == NULL)
973*efd4c9b6SSteve Lawrence 			fmt = nl_langinfo(_DATE_FMT);
974*efd4c9b6SSteve Lawrence 
975*efd4c9b6SSteve Lawrence 		len = strftime(dstr, sizeof (dstr), fmt, localtime(&t));
976*efd4c9b6SSteve Lawrence 		if (len > 0)
977*efd4c9b6SSteve Lawrence 			(void) printf("%s", dstr);
978*efd4c9b6SSteve Lawrence 	}
979*efd4c9b6SSteve Lawrence }
980*efd4c9b6SSteve Lawrence 
981*efd4c9b6SSteve Lawrence static void
zonestat_print_summary_zone(size_t namewidth,int report_fmt,char * name,uint64_t cused,uint_t ppart,uint_t pccap,uint_t pshru,uint64_t mused,uint_t mpct,uint_t pmcap,uint64_t vused,uint_t vpct,uint_t pvcap)982*efd4c9b6SSteve Lawrence zonestat_print_summary_zone(size_t namewidth, int report_fmt, char *name,
983*efd4c9b6SSteve Lawrence     uint64_t cused, uint_t ppart, uint_t pccap, uint_t pshru, uint64_t mused,
984*efd4c9b6SSteve Lawrence     uint_t mpct, uint_t pmcap, uint64_t vused, uint_t vpct, uint_t pvcap)
985*efd4c9b6SSteve Lawrence {
986*efd4c9b6SSteve Lawrence 	char *label;
987*efd4c9b6SSteve Lawrence 
988*efd4c9b6SSteve Lawrence 	char str_cused[ZS_UINT64_STRLEN];
989*efd4c9b6SSteve Lawrence 	char str_ppart[ZS_PCT_STRLEN];
990*efd4c9b6SSteve Lawrence 	char str_pccap[ZS_PCT_STRLEN];
991*efd4c9b6SSteve Lawrence 	char str_pshru[ZS_PCT_STRLEN];
992*efd4c9b6SSteve Lawrence 	char str_mused[ZS_UINT64_STRLEN];
993*efd4c9b6SSteve Lawrence 	char str_mpct[ZS_PCT_STRLEN];
994*efd4c9b6SSteve Lawrence 	char str_pmcap[ZS_PCT_STRLEN];
995*efd4c9b6SSteve Lawrence 	char str_vused[ZS_UINT64_STRLEN];
996*efd4c9b6SSteve Lawrence 	char str_vpct[ZS_PCT_STRLEN];
997*efd4c9b6SSteve Lawrence 	char str_pvcap[ZS_PCT_STRLEN];
998*efd4c9b6SSteve Lawrence 	char name_format[ZS_NAME_STRLEN];
999*efd4c9b6SSteve Lawrence 
1000*efd4c9b6SSteve Lawrence 	format_cpu(cused, str_cused, sizeof (str_cused));
1001*efd4c9b6SSteve Lawrence 	format_pct(ppart, str_ppart, sizeof (str_ppart));
1002*efd4c9b6SSteve Lawrence 	format_pct(pccap, str_pccap, sizeof (str_pccap));
1003*efd4c9b6SSteve Lawrence 	format_pct(pshru, str_pshru, sizeof (str_pshru));
1004*efd4c9b6SSteve Lawrence 	format_uint64(mused, str_mused, sizeof (str_mused));
1005*efd4c9b6SSteve Lawrence 	format_pct(mpct, str_mpct, sizeof (str_mpct));
1006*efd4c9b6SSteve Lawrence 	format_pct(pmcap, str_pmcap, sizeof (str_pmcap));
1007*efd4c9b6SSteve Lawrence 	format_uint64(vused, str_vused, sizeof (str_vused));
1008*efd4c9b6SSteve Lawrence 	format_pct(vpct, str_vpct, sizeof (str_vpct));
1009*efd4c9b6SSteve Lawrence 	format_pct(pvcap, str_pvcap, sizeof (str_pvcap));
1010*efd4c9b6SSteve Lawrence 
1011*efd4c9b6SSteve Lawrence 	if (opt_parseable) {
1012*efd4c9b6SSteve Lawrence 		if (opt_timestamp) {
1013*efd4c9b6SSteve Lawrence 			zonestat_print_timestamp(g_now_time);
1014*efd4c9b6SSteve Lawrence 			(void) printf(":");
1015*efd4c9b6SSteve Lawrence 		}
1016*efd4c9b6SSteve Lawrence 		label = zonestat_get_plabel(report_fmt);
1017*efd4c9b6SSteve Lawrence 		(void) printf("%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s\n",
1018*efd4c9b6SSteve Lawrence 		    label, ZONESTAT_SUMMARY, name, str_cused, str_ppart,
1019*efd4c9b6SSteve Lawrence 		    str_pccap, str_pshru, str_mused, str_mpct, str_pmcap,
1020*efd4c9b6SSteve Lawrence 		    str_vused, str_vpct, str_pvcap);
1021*efd4c9b6SSteve Lawrence 		return;
1022*efd4c9b6SSteve Lawrence 	}
1023*efd4c9b6SSteve Lawrence 	(void) snprintf(name_format, sizeof (name_format), "%%%ds ",
1024*efd4c9b6SSteve Lawrence 	    namewidth);
1025*efd4c9b6SSteve Lawrence 	/* LINTED */
1026*efd4c9b6SSteve Lawrence 	(void) printf(name_format, name);
1027*efd4c9b6SSteve Lawrence 	(void) printf(ZSTAT_SUM_ZONE_FORMAT, str_cused, str_ppart,
1028*efd4c9b6SSteve Lawrence 	    str_pccap, str_pshru, str_mused, str_mpct, str_pmcap, str_vused,
1029*efd4c9b6SSteve Lawrence 	    str_vpct, str_pvcap);
1030*efd4c9b6SSteve Lawrence }
1031*efd4c9b6SSteve Lawrence 
1032*efd4c9b6SSteve Lawrence static void
zonestat_print_resource_(size_t namelen,int report_fmt,char * res,char * name,uint64_t size)1033*efd4c9b6SSteve Lawrence zonestat_print_resource_(size_t namelen, int report_fmt, char *res,
1034*efd4c9b6SSteve Lawrence     char *name, uint64_t size)
1035*efd4c9b6SSteve Lawrence {
1036*efd4c9b6SSteve Lawrence 	char strsize[ZS_UINT64_STRLEN];
1037*efd4c9b6SSteve Lawrence 	char *label;
1038*efd4c9b6SSteve Lawrence 	char name_format[ZS_NAME_STRLEN];
1039*efd4c9b6SSteve Lawrence 
1040*efd4c9b6SSteve Lawrence 	format_uint64(size, strsize, sizeof (strsize));
1041*efd4c9b6SSteve Lawrence 	if (opt_parseable) {
1042*efd4c9b6SSteve Lawrence 		if (opt_timestamp) {
1043*efd4c9b6SSteve Lawrence 			zonestat_print_timestamp(g_now_time);
1044*efd4c9b6SSteve Lawrence 			(void) printf(":");
1045*efd4c9b6SSteve Lawrence 		}
1046*efd4c9b6SSteve Lawrence 		label = zonestat_get_plabel(report_fmt);
1047*efd4c9b6SSteve Lawrence 		(void) printf("%s:%s:%s:[%s]:%s\n", label, res, name,
1048*efd4c9b6SSteve Lawrence 		    ZONESTAT_NAME_RESOURCE, strsize);
1049*efd4c9b6SSteve Lawrence 		return;
1050*efd4c9b6SSteve Lawrence 	}
1051*efd4c9b6SSteve Lawrence 
1052*efd4c9b6SSteve Lawrence 	(void) snprintf(name_format, sizeof (name_format), "%%-%ds ", namelen);
1053*efd4c9b6SSteve Lawrence 	/* LINTED */
1054*efd4c9b6SSteve Lawrence 	(void) printf(name_format, name);
1055*efd4c9b6SSteve Lawrence 	(void) printf(ZSTAT_RESOURCE_FORMAT, strsize);
1056*efd4c9b6SSteve Lawrence }
1057*efd4c9b6SSteve Lawrence 
1058*efd4c9b6SSteve Lawrence static void
zonestat_print_resource_zone(size_t namelen,int report_fmt,char * restype,char * resname,char * name,uint64_t used,uint_t pct,uint64_t cap,uint_t pctcap)1059*efd4c9b6SSteve Lawrence zonestat_print_resource_zone(size_t namelen, int report_fmt, char *restype,
1060*efd4c9b6SSteve Lawrence     char *resname, char *name, uint64_t used, uint_t pct, uint64_t cap,
1061*efd4c9b6SSteve Lawrence     uint_t pctcap)
1062*efd4c9b6SSteve Lawrence {
1063*efd4c9b6SSteve Lawrence 	char strused[ZS_UINT64_STRLEN];
1064*efd4c9b6SSteve Lawrence 	char strpct[ZS_PCT_STRLEN];
1065*efd4c9b6SSteve Lawrence 	char strcap[ZS_UINT64_STRLEN];
1066*efd4c9b6SSteve Lawrence 	char strpctcap[ZS_PCT_STRLEN];
1067*efd4c9b6SSteve Lawrence 	char name_format[ZS_NAME_STRLEN];
1068*efd4c9b6SSteve Lawrence 
1069*efd4c9b6SSteve Lawrence 	char *label;
1070*efd4c9b6SSteve Lawrence 
1071*efd4c9b6SSteve Lawrence 	format_uint64(used, strused, sizeof (strused));
1072*efd4c9b6SSteve Lawrence 	format_pct(pct, strpct, sizeof (strpct));
1073*efd4c9b6SSteve Lawrence 	if (cap == ZS_LIMIT_NONE)
1074*efd4c9b6SSteve Lawrence 		(void) strlcpy(strcap, "-", sizeof (strcap));
1075*efd4c9b6SSteve Lawrence 	else
1076*efd4c9b6SSteve Lawrence 		format_uint64(cap, strcap, sizeof (strcap));
1077*efd4c9b6SSteve Lawrence 
1078*efd4c9b6SSteve Lawrence 	if (pctcap == ZS_PCT_NONE)
1079*efd4c9b6SSteve Lawrence 		(void) strlcpy(strpctcap, "-", sizeof (strpctcap));
1080*efd4c9b6SSteve Lawrence 	else
1081*efd4c9b6SSteve Lawrence 		format_pct(pctcap, strpctcap, sizeof (strpctcap));
1082*efd4c9b6SSteve Lawrence 
1083*efd4c9b6SSteve Lawrence 	if (opt_parseable) {
1084*efd4c9b6SSteve Lawrence 		if (opt_timestamp) {
1085*efd4c9b6SSteve Lawrence 			zonestat_print_timestamp(g_now_time);
1086*efd4c9b6SSteve Lawrence 			(void) printf(":");
1087*efd4c9b6SSteve Lawrence 		}
1088*efd4c9b6SSteve Lawrence 		label = zonestat_get_plabel(report_fmt);
1089*efd4c9b6SSteve Lawrence 		(void) printf("%s:%s:%s:%s:%s:%s:%s:%s\n", label, restype,
1090*efd4c9b6SSteve Lawrence 		    resname, name, strused, strpct, strcap, strpctcap);
1091*efd4c9b6SSteve Lawrence 		return;
1092*efd4c9b6SSteve Lawrence 	}
1093*efd4c9b6SSteve Lawrence 
1094*efd4c9b6SSteve Lawrence 	(void) snprintf(name_format, sizeof (name_format), "%%%ds ", namelen);
1095*efd4c9b6SSteve Lawrence 	/* LINTED */
1096*efd4c9b6SSteve Lawrence 	(void) printf(name_format, name);
1097*efd4c9b6SSteve Lawrence 	(void) printf(ZSTAT_RESOURCE_ZONE_FORMAT, strused, strpct, strcap,
1098*efd4c9b6SSteve Lawrence 	    strpctcap);
1099*efd4c9b6SSteve Lawrence }
1100*efd4c9b6SSteve Lawrence 
1101*efd4c9b6SSteve Lawrence /*
1102*efd4c9b6SSteve Lawrence  * Not thread safe.
1103*efd4c9b6SSteve Lawrence  */
1104*efd4c9b6SSteve Lawrence static void
zonestat_qsort(void * base,size_t nel,size_t width,int (* compar)(const void *,const void *),int by)1105*efd4c9b6SSteve Lawrence zonestat_qsort(void *base, size_t nel, size_t width,
1106*efd4c9b6SSteve Lawrence     int (*compar)(const void *, const void *), int by)
1107*efd4c9b6SSteve Lawrence {
1108*efd4c9b6SSteve Lawrence 	g_sort_by = by;
1109*efd4c9b6SSteve Lawrence 	g_max_zonename = 0;
1110*efd4c9b6SSteve Lawrence 	qsort(base, nel, width, compar);
1111*efd4c9b6SSteve Lawrence }
1112*efd4c9b6SSteve Lawrence 
1113*efd4c9b6SSteve Lawrence static int
zonestat_zone_compare_resource(const void * a,const void * b)1114*efd4c9b6SSteve Lawrence zonestat_zone_compare_resource(const void *a, const void *b)
1115*efd4c9b6SSteve Lawrence {
1116*efd4c9b6SSteve Lawrence 	zs_zone_t *zonea = *(zs_zone_t **)a;
1117*efd4c9b6SSteve Lawrence 	zs_zone_t *zoneb = *(zs_zone_t **)b;
1118*efd4c9b6SSteve Lawrence 	zs_property_t *prop, *propb;
1119*efd4c9b6SSteve Lawrence 	uint64_t resa, resb;
1120*efd4c9b6SSteve Lawrence 	uint_t uinta, uintb;
1121*efd4c9b6SSteve Lawrence 	int i, res;
1122*efd4c9b6SSteve Lawrence 
1123*efd4c9b6SSteve Lawrence 	prop = alloca(zs_property_size());
1124*efd4c9b6SSteve Lawrence 	propb = alloca(zs_property_size());
1125*efd4c9b6SSteve Lawrence 
1126*efd4c9b6SSteve Lawrence 	for (i = 0; i < arg_sort_count; i++) {
1127*efd4c9b6SSteve Lawrence 
1128*efd4c9b6SSteve Lawrence 		/* Sort by order of selection */
1129*efd4c9b6SSteve Lawrence 		switch (g_sorts[i]) {
1130*efd4c9b6SSteve Lawrence 		case ZSTAT_SORT_USED:
1131*efd4c9b6SSteve Lawrence 			resa = zs_resource_used_zone_uint64(zonea, g_sort_by);
1132*efd4c9b6SSteve Lawrence 			resb = zs_resource_used_zone_uint64(zoneb, g_sort_by);
1133*efd4c9b6SSteve Lawrence 			break;
1134*efd4c9b6SSteve Lawrence 		case ZSTAT_SORT_CAP:
1135*efd4c9b6SSteve Lawrence 			resa = zs_zone_limit_uint64(zonea, g_sort_by);
1136*efd4c9b6SSteve Lawrence 			if (resa == ZS_LIMIT_NONE)
1137*efd4c9b6SSteve Lawrence 				resa = 0;
1138*efd4c9b6SSteve Lawrence 			resb = zs_zone_limit_uint64(zoneb, g_sort_by);
1139*efd4c9b6SSteve Lawrence 			if (resb == ZS_LIMIT_NONE)
1140*efd4c9b6SSteve Lawrence 				resb = 0;
1141*efd4c9b6SSteve Lawrence 			break;
1142*efd4c9b6SSteve Lawrence 		case ZSTAT_SORT_PCAP:
1143*efd4c9b6SSteve Lawrence 			uinta = zs_zone_limit_used_pct(zonea, g_sort_by);
1144*efd4c9b6SSteve Lawrence 			uintb = zs_zone_limit_used_pct(zoneb, g_sort_by);
1145*efd4c9b6SSteve Lawrence 			if (uinta == ZS_PCT_NONE)
1146*efd4c9b6SSteve Lawrence 				resa = 0;
1147*efd4c9b6SSteve Lawrence 			else
1148*efd4c9b6SSteve Lawrence 				resa = uinta;
1149*efd4c9b6SSteve Lawrence 			if (uintb == ZS_PCT_NONE)
1150*efd4c9b6SSteve Lawrence 				resb = 0;
1151*efd4c9b6SSteve Lawrence 			else
1152*efd4c9b6SSteve Lawrence 				resb = uintb;
1153*efd4c9b6SSteve Lawrence 			break;
1154*efd4c9b6SSteve Lawrence 		case ZSTAT_SORT_SHR:
1155*efd4c9b6SSteve Lawrence 			zs_zone_property(zonea, ZS_PZ_PROP_CPU_SHARES, prop);
1156*efd4c9b6SSteve Lawrence 			resa = zs_property_uint64(prop);
1157*efd4c9b6SSteve Lawrence 			if (resa == ZS_LIMIT_NONE)
1158*efd4c9b6SSteve Lawrence 				resa = 0;
1159*efd4c9b6SSteve Lawrence 			zs_zone_property(zoneb, ZS_PZ_PROP_CPU_SHARES, prop);
1160*efd4c9b6SSteve Lawrence 			resb = zs_property_uint64(prop);
1161*efd4c9b6SSteve Lawrence 			if (resb == ZS_LIMIT_NONE)
1162*efd4c9b6SSteve Lawrence 				resb = 0;
1163*efd4c9b6SSteve Lawrence 			break;
1164*efd4c9b6SSteve Lawrence 		case ZSTAT_SORT_PSHRU:
1165*efd4c9b6SSteve Lawrence 			uinta = zs_zone_limit_used_pct(zonea,
1166*efd4c9b6SSteve Lawrence 			    ZS_LIMIT_CPU_SHARES);
1167*efd4c9b6SSteve Lawrence 			uintb = zs_zone_limit_used_pct(zoneb,
1168*efd4c9b6SSteve Lawrence 			    ZS_LIMIT_CPU_SHARES);
1169*efd4c9b6SSteve Lawrence 			if (uinta == ZS_PCT_NONE)
1170*efd4c9b6SSteve Lawrence 				resa = 0;
1171*efd4c9b6SSteve Lawrence 			else
1172*efd4c9b6SSteve Lawrence 				resa = uinta;
1173*efd4c9b6SSteve Lawrence 			if (uintb == ZS_PCT_NONE)
1174*efd4c9b6SSteve Lawrence 				resb = 0;
1175*efd4c9b6SSteve Lawrence 			else
1176*efd4c9b6SSteve Lawrence 				resb = uintb;
1177*efd4c9b6SSteve Lawrence 			break;
1178*efd4c9b6SSteve Lawrence 		case ZSTAT_SORT_NAME:
1179*efd4c9b6SSteve Lawrence 			zs_zone_property(zonea, ZS_ZONE_PROP_NAME, prop);
1180*efd4c9b6SSteve Lawrence 			zs_zone_property(zoneb, ZS_ZONE_PROP_NAME, propb);
1181*efd4c9b6SSteve Lawrence 
1182*efd4c9b6SSteve Lawrence 			res = strcmp(zs_property_string(prop),
1183*efd4c9b6SSteve Lawrence 			    zs_property_string(propb));
1184*efd4c9b6SSteve Lawrence 			if (res != 0)
1185*efd4c9b6SSteve Lawrence 				return (res);
1186*efd4c9b6SSteve Lawrence 			break;
1187*efd4c9b6SSteve Lawrence 		default:
1188*efd4c9b6SSteve Lawrence 			exit(zonestat_error(gettext("Internal sort error")));
1189*efd4c9b6SSteve Lawrence 		}
1190*efd4c9b6SSteve Lawrence 		if (resa < resb)
1191*efd4c9b6SSteve Lawrence 			return (1);
1192*efd4c9b6SSteve Lawrence 		if (resb < resa)
1193*efd4c9b6SSteve Lawrence 			return (-1);
1194*efd4c9b6SSteve Lawrence 	}
1195*efd4c9b6SSteve Lawrence 	/* No difference, return 0 */
1196*efd4c9b6SSteve Lawrence 	return (0);
1197*efd4c9b6SSteve Lawrence }
1198*efd4c9b6SSteve Lawrence /*
1199*efd4c9b6SSteve Lawrence  * Sort psets.  Default pset first, then shared psets, then dedicated
1200*efd4c9b6SSteve Lawrence  * psets.
1201*efd4c9b6SSteve Lawrence  */
1202*efd4c9b6SSteve Lawrence static int
zonestat_pset_compare(const void * a,const void * b)1203*efd4c9b6SSteve Lawrence zonestat_pset_compare(const void *a, const void *b)
1204*efd4c9b6SSteve Lawrence {
1205*efd4c9b6SSteve Lawrence 	zs_pset_t *pseta = *(zs_pset_t **)a;
1206*efd4c9b6SSteve Lawrence 	zs_pset_t *psetb = *(zs_pset_t **)b;
1207*efd4c9b6SSteve Lawrence 	zs_property_t *p;
1208*efd4c9b6SSteve Lawrence 	uint_t typea, typeb;
1209*efd4c9b6SSteve Lawrence 
1210*efd4c9b6SSteve Lawrence 
1211*efd4c9b6SSteve Lawrence 	p = (zs_property_t *)alloca(zs_property_size());
1212*efd4c9b6SSteve Lawrence 	zs_pset_property(pseta, ZS_PSET_PROP_CPUTYPE, p);
1213*efd4c9b6SSteve Lawrence 	typea = zs_property_uint(p);
1214*efd4c9b6SSteve Lawrence 	zs_pset_property(psetb, ZS_PSET_PROP_CPUTYPE, p);
1215*efd4c9b6SSteve Lawrence 	typeb = zs_property_uint(p);
1216*efd4c9b6SSteve Lawrence 
1217*efd4c9b6SSteve Lawrence 	if (typea == ZS_CPUTYPE_DEFAULT_PSET)
1218*efd4c9b6SSteve Lawrence 		return (-1);
1219*efd4c9b6SSteve Lawrence 	if (typeb == ZS_CPUTYPE_DEFAULT_PSET)
1220*efd4c9b6SSteve Lawrence 		return (1);
1221*efd4c9b6SSteve Lawrence 	if (typea == ZS_CPUTYPE_POOL_PSET)
1222*efd4c9b6SSteve Lawrence 		return (-1);
1223*efd4c9b6SSteve Lawrence 	if (typeb == ZS_CPUTYPE_POOL_PSET)
1224*efd4c9b6SSteve Lawrence 		return (1);
1225*efd4c9b6SSteve Lawrence 	if (typea == ZS_CPUTYPE_PSRSET_PSET)
1226*efd4c9b6SSteve Lawrence 		return (-1);
1227*efd4c9b6SSteve Lawrence 	if (typeb == ZS_CPUTYPE_PSRSET_PSET)
1228*efd4c9b6SSteve Lawrence 		return (1);
1229*efd4c9b6SSteve Lawrence 
1230*efd4c9b6SSteve Lawrence 	return (0);
1231*efd4c9b6SSteve Lawrence }
1232*efd4c9b6SSteve Lawrence 
1233*efd4c9b6SSteve Lawrence static int
zonestat_pz_compare_usage(const void * a,const void * b)1234*efd4c9b6SSteve Lawrence zonestat_pz_compare_usage(const void *a, const void *b)
1235*efd4c9b6SSteve Lawrence {
1236*efd4c9b6SSteve Lawrence 	zs_pset_zone_t *zonea = *(zs_pset_zone_t **)a;
1237*efd4c9b6SSteve Lawrence 	zs_pset_zone_t *zoneb = *(zs_pset_zone_t **)b;
1238*efd4c9b6SSteve Lawrence 	zs_property_t *prop, *propb;
1239*efd4c9b6SSteve Lawrence 	uint64_t resa, resb;
1240*efd4c9b6SSteve Lawrence 	uint_t uinta, uintb;
1241*efd4c9b6SSteve Lawrence 	int i, res;
1242*efd4c9b6SSteve Lawrence 
1243*efd4c9b6SSteve Lawrence 	prop = alloca(zs_property_size());
1244*efd4c9b6SSteve Lawrence 	propb = alloca(zs_property_size());
1245*efd4c9b6SSteve Lawrence 
1246*efd4c9b6SSteve Lawrence 	for (i = 0; i < arg_sort_count; i++) {
1247*efd4c9b6SSteve Lawrence 
1248*efd4c9b6SSteve Lawrence 		/* Sort by order of selection */
1249*efd4c9b6SSteve Lawrence 		switch (g_sorts[i]) {
1250*efd4c9b6SSteve Lawrence 		case ZSTAT_SORT_USED:
1251*efd4c9b6SSteve Lawrence 			resa = zs_pset_zone_used_cpus(zonea);
1252*efd4c9b6SSteve Lawrence 			resb = zs_pset_zone_used_cpus(zoneb);
1253*efd4c9b6SSteve Lawrence 			break;
1254*efd4c9b6SSteve Lawrence 		case ZSTAT_SORT_CAP:
1255*efd4c9b6SSteve Lawrence 			zs_pset_zone_property(zonea, ZS_PZ_PROP_CPU_CAP,
1256*efd4c9b6SSteve Lawrence 			    prop);
1257*efd4c9b6SSteve Lawrence 			resa = zs_property_uint64(prop);
1258*efd4c9b6SSteve Lawrence 			if (resa == ZS_LIMIT_NONE)
1259*efd4c9b6SSteve Lawrence 				resa = 0;
1260*efd4c9b6SSteve Lawrence 			zs_pset_zone_property(zoneb, ZS_PZ_PROP_CPU_CAP,
1261*efd4c9b6SSteve Lawrence 			    prop);
1262*efd4c9b6SSteve Lawrence 			resb = zs_property_uint64(prop);
1263*efd4c9b6SSteve Lawrence 			if (resb == ZS_LIMIT_NONE)
1264*efd4c9b6SSteve Lawrence 				resb = 0;
1265*efd4c9b6SSteve Lawrence 			break;
1266*efd4c9b6SSteve Lawrence 		case ZSTAT_SORT_PCAP:
1267*efd4c9b6SSteve Lawrence 			uinta = zs_pset_zone_used_pct(zonea, ZS_PZ_PCT_CPU_CAP);
1268*efd4c9b6SSteve Lawrence 			uintb = zs_pset_zone_used_pct(zoneb, ZS_PZ_PCT_CPU_CAP);
1269*efd4c9b6SSteve Lawrence 			if (uinta == ZS_PCT_NONE)
1270*efd4c9b6SSteve Lawrence 				resa = 0;
1271*efd4c9b6SSteve Lawrence 			else
1272*efd4c9b6SSteve Lawrence 				resa = uinta;
1273*efd4c9b6SSteve Lawrence 			if (uintb == ZS_PCT_NONE)
1274*efd4c9b6SSteve Lawrence 				resb = 0;
1275*efd4c9b6SSteve Lawrence 			else
1276*efd4c9b6SSteve Lawrence 				resb = uintb;
1277*efd4c9b6SSteve Lawrence 			break;
1278*efd4c9b6SSteve Lawrence 		case ZSTAT_SORT_SHR:
1279*efd4c9b6SSteve Lawrence 			zs_pset_zone_property(zonea, ZS_PZ_PROP_CPU_SHARES,
1280*efd4c9b6SSteve Lawrence 			    prop);
1281*efd4c9b6SSteve Lawrence 			resa = zs_property_uint64(prop);
1282*efd4c9b6SSteve Lawrence 			if (resa == ZS_LIMIT_NONE)
1283*efd4c9b6SSteve Lawrence 				resa = 0;
1284*efd4c9b6SSteve Lawrence 			zs_pset_zone_property(zoneb, ZS_PZ_PROP_CPU_SHARES,
1285*efd4c9b6SSteve Lawrence 			    prop);
1286*efd4c9b6SSteve Lawrence 			resb = zs_property_uint64(prop);
1287*efd4c9b6SSteve Lawrence 			if (resb == ZS_LIMIT_NONE)
1288*efd4c9b6SSteve Lawrence 				resb = 0;
1289*efd4c9b6SSteve Lawrence 			break;
1290*efd4c9b6SSteve Lawrence 		case ZSTAT_SORT_PSHRU:
1291*efd4c9b6SSteve Lawrence 			uinta = zs_pset_zone_used_pct(zonea,
1292*efd4c9b6SSteve Lawrence 			    ZS_PZ_PCT_CPU_SHARES);
1293*efd4c9b6SSteve Lawrence 			uintb = zs_pset_zone_used_pct(zoneb,
1294*efd4c9b6SSteve Lawrence 			    ZS_PZ_PCT_CPU_SHARES);
1295*efd4c9b6SSteve Lawrence 			if (uinta == ZS_PCT_NONE)
1296*efd4c9b6SSteve Lawrence 				resa = 0;
1297*efd4c9b6SSteve Lawrence 			else
1298*efd4c9b6SSteve Lawrence 				resa = uinta;
1299*efd4c9b6SSteve Lawrence 			if (uintb == ZS_PCT_NONE)
1300*efd4c9b6SSteve Lawrence 				resb = 0;
1301*efd4c9b6SSteve Lawrence 			else
1302*efd4c9b6SSteve Lawrence 				resb = uintb;
1303*efd4c9b6SSteve Lawrence 			break;
1304*efd4c9b6SSteve Lawrence 		case ZSTAT_SORT_NAME:
1305*efd4c9b6SSteve Lawrence 			zs_zone_property(zs_pset_zone_get_zone(zonea),
1306*efd4c9b6SSteve Lawrence 			    ZS_ZONE_PROP_NAME, prop);
1307*efd4c9b6SSteve Lawrence 			zs_zone_property(zs_pset_zone_get_zone(zoneb),
1308*efd4c9b6SSteve Lawrence 			    ZS_ZONE_PROP_NAME, propb);
1309*efd4c9b6SSteve Lawrence 
1310*efd4c9b6SSteve Lawrence 			res = strcmp(zs_property_string(prop),
1311*efd4c9b6SSteve Lawrence 			    zs_property_string(propb));
1312*efd4c9b6SSteve Lawrence 			if (res != 0)
1313*efd4c9b6SSteve Lawrence 				return (res);
1314*efd4c9b6SSteve Lawrence 			break;
1315*efd4c9b6SSteve Lawrence 		default:
1316*efd4c9b6SSteve Lawrence 			exit(zonestat_error(gettext("Internal sort error")));
1317*efd4c9b6SSteve Lawrence 		}
1318*efd4c9b6SSteve Lawrence 		if (resa < resb)
1319*efd4c9b6SSteve Lawrence 			return (1);
1320*efd4c9b6SSteve Lawrence 		if (resb < resa)
1321*efd4c9b6SSteve Lawrence 			return (-1);
1322*efd4c9b6SSteve Lawrence 	}
1323*efd4c9b6SSteve Lawrence 	/* No difference, return 0 */
1324*efd4c9b6SSteve Lawrence 	return (0);
1325*efd4c9b6SSteve Lawrence }
1326*efd4c9b6SSteve Lawrence 
1327*efd4c9b6SSteve Lawrence 
1328*efd4c9b6SSteve Lawrence static void
zonestat_print_summary(int report_fmt,zs_usage_t * u)1329*efd4c9b6SSteve Lawrence zonestat_print_summary(int report_fmt, zs_usage_t *u)
1330*efd4c9b6SSteve Lawrence {
1331*efd4c9b6SSteve Lawrence 	int num, i;
1332*efd4c9b6SSteve Lawrence 	zs_zone_t *z;
1333*efd4c9b6SSteve Lawrence 	uint64_t cpus, online, tot_mem, tot_vm;
1334*efd4c9b6SSteve Lawrence 	uint64_t cused, mused, vused;
1335*efd4c9b6SSteve Lawrence 	uint_t ppart, pshru, pccap, mpct, pmcap, vpct, pvcap;
1336*efd4c9b6SSteve Lawrence 	char zonename[ZS_ZONENAME_MAX];
1337*efd4c9b6SSteve Lawrence 	zs_property_t *prop;
1338*efd4c9b6SSteve Lawrence 	size_t namewidth = 0, len;
1339*efd4c9b6SSteve Lawrence 
1340*efd4c9b6SSteve Lawrence 	prop = (zs_property_t *)alloca(zs_property_size());
1341*efd4c9b6SSteve Lawrence 
1342*efd4c9b6SSteve Lawrence 	zs_resource_property(u, ZS_RESOURCE_CPU, ZS_RESOURCE_PROP_CPU_TOTAL,
1343*efd4c9b6SSteve Lawrence 	    prop);
1344*efd4c9b6SSteve Lawrence 	cpus = zs_property_uint64(prop);
1345*efd4c9b6SSteve Lawrence 
1346*efd4c9b6SSteve Lawrence 	zs_resource_property(u, ZS_RESOURCE_CPU,
1347*efd4c9b6SSteve Lawrence 	    ZS_RESOURCE_PROP_CPU_ONLINE, prop);
1348*efd4c9b6SSteve Lawrence 	online = zs_property_uint64(prop);
1349*efd4c9b6SSteve Lawrence 
1350*efd4c9b6SSteve Lawrence 	tot_mem = zs_resource_total_uint64(u, ZS_RESOURCE_RAM_RSS);
1351*efd4c9b6SSteve Lawrence 	tot_vm = zs_resource_total_uint64(u, ZS_RESOURCE_VM);
1352*efd4c9b6SSteve Lawrence 
1353*efd4c9b6SSteve Lawrence again:
1354*efd4c9b6SSteve Lawrence 	num = zs_zone_list(u, g_zone_list, g_zone_num);
1355*efd4c9b6SSteve Lawrence 	if (num > g_zone_num) {
1356*efd4c9b6SSteve Lawrence 		if (g_zone_list != NULL)
1357*efd4c9b6SSteve Lawrence 			free(g_zone_list);
1358*efd4c9b6SSteve Lawrence 		g_zone_list = (zs_zone_t **) malloc(sizeof (zs_zone_t *) * num);
1359*efd4c9b6SSteve Lawrence 		g_zone_num = num;
1360*efd4c9b6SSteve Lawrence 		goto again;
1361*efd4c9b6SSteve Lawrence 	}
1362*efd4c9b6SSteve Lawrence 
1363*efd4c9b6SSteve Lawrence 	/* Find the longest zone name to set output width. */
1364*efd4c9b6SSteve Lawrence 	namewidth = ZSTAT_SUM_MIN_ZONENAME;
1365*efd4c9b6SSteve Lawrence 	for (i = 0; i < num; i++) {
1366*efd4c9b6SSteve Lawrence 		z = g_zone_list[i];
1367*efd4c9b6SSteve Lawrence 		(void) zs_zone_property(z, ZS_ZONE_PROP_NAME, prop);
1368*efd4c9b6SSteve Lawrence 		len = strlen(zs_property_string(prop));
1369*efd4c9b6SSteve Lawrence 		if (len > namewidth)
1370*efd4c9b6SSteve Lawrence 			namewidth = len;
1371*efd4c9b6SSteve Lawrence 	}
1372*efd4c9b6SSteve Lawrence 	zonestat_print_summary_header(namewidth, report_fmt, cpus, online,
1373*efd4c9b6SSteve Lawrence 	    tot_mem, tot_vm);
1374*efd4c9b6SSteve Lawrence 
1375*efd4c9b6SSteve Lawrence 	zonestat_qsort(g_zone_list, num, sizeof (zs_zone_t *),
1376*efd4c9b6SSteve Lawrence 	    zonestat_zone_compare_resource, g_sort_summary);
1377*efd4c9b6SSteve Lawrence 
1378*efd4c9b6SSteve Lawrence 	cused = zs_resource_used_uint64(u, ZS_RESOURCE_CPU, ZS_USER_ALL);
1379*efd4c9b6SSteve Lawrence 	mused = zs_resource_used_uint64(u, ZS_RESOURCE_RAM_RSS, ZS_USER_ALL);
1380*efd4c9b6SSteve Lawrence 	vused = zs_resource_used_uint64(u, ZS_RESOURCE_VM, ZS_USER_ALL);
1381*efd4c9b6SSteve Lawrence 
1382*efd4c9b6SSteve Lawrence 	ppart = zs_resource_used_pct(u, ZS_RESOURCE_CPU, ZS_USER_ALL);
1383*efd4c9b6SSteve Lawrence 	mpct = zs_resource_used_pct(u, ZS_RESOURCE_RAM_RSS, ZS_USER_ALL);
1384*efd4c9b6SSteve Lawrence 	vpct = zs_resource_used_pct(u, ZS_RESOURCE_VM, ZS_USER_ALL);
1385*efd4c9b6SSteve Lawrence 
1386*efd4c9b6SSteve Lawrence 	if (opt_line_total) {
1387*efd4c9b6SSteve Lawrence 		(void) snprintf(zonename, sizeof (zonename), "[%s]",
1388*efd4c9b6SSteve Lawrence 		    ZONESTAT_NAME_TOTAL);
1389*efd4c9b6SSteve Lawrence 		zonestat_print_summary_zone(namewidth, report_fmt, zonename,
1390*efd4c9b6SSteve Lawrence 		    cused, ppart, ZS_PCT_NONE, ZS_PCT_NONE, mused, mpct,
1391*efd4c9b6SSteve Lawrence 		    ZS_PCT_NONE, vused, vpct, ZS_PCT_NONE);
1392*efd4c9b6SSteve Lawrence 	}
1393*efd4c9b6SSteve Lawrence 	cused = zs_resource_used_uint64(u, ZS_RESOURCE_CPU, ZS_USER_KERNEL);
1394*efd4c9b6SSteve Lawrence 	mused = zs_resource_used_uint64(u, ZS_RESOURCE_RAM_RSS, ZS_USER_KERNEL);
1395*efd4c9b6SSteve Lawrence 	vused = zs_resource_used_uint64(u, ZS_RESOURCE_VM, ZS_USER_KERNEL);
1396*efd4c9b6SSteve Lawrence 
1397*efd4c9b6SSteve Lawrence 	ppart = zs_resource_used_pct(u, ZS_RESOURCE_CPU, ZS_USER_KERNEL);
1398*efd4c9b6SSteve Lawrence 	mpct = zs_resource_used_pct(u, ZS_RESOURCE_RAM_RSS, ZS_USER_KERNEL);
1399*efd4c9b6SSteve Lawrence 	vpct = zs_resource_used_pct(u, ZS_RESOURCE_VM, ZS_USER_KERNEL);
1400*efd4c9b6SSteve Lawrence 
1401*efd4c9b6SSteve Lawrence 	if (opt_line_system) {
1402*efd4c9b6SSteve Lawrence 		(void) snprintf(zonename, sizeof (zonename), "[%s]",
1403*efd4c9b6SSteve Lawrence 		    ZONESTAT_NAME_SYSTEM);
1404*efd4c9b6SSteve Lawrence 		zonestat_print_summary_zone(namewidth, report_fmt, zonename,
1405*efd4c9b6SSteve Lawrence 		    cused, ppart, ZS_PCT_NONE, ZS_PCT_NONE, mused, mpct,
1406*efd4c9b6SSteve Lawrence 		    ZS_PCT_NONE, vused, vpct, ZS_PCT_NONE);
1407*efd4c9b6SSteve Lawrence 	}
1408*efd4c9b6SSteve Lawrence 	for (i = 0; i < num; i++) {
1409*efd4c9b6SSteve Lawrence 
1410*efd4c9b6SSteve Lawrence 		z = g_zone_list[i];
1411*efd4c9b6SSteve Lawrence 
1412*efd4c9b6SSteve Lawrence 		zs_zone_property(z, ZS_ZONE_PROP_NAME, prop);
1413*efd4c9b6SSteve Lawrence 		(void) strlcpy(zonename, zs_property_string(prop),
1414*efd4c9b6SSteve Lawrence 		    sizeof (zonename));
1415*efd4c9b6SSteve Lawrence 
1416*efd4c9b6SSteve Lawrence 		cused = zs_resource_used_zone_uint64(z, ZS_RESOURCE_CPU);
1417*efd4c9b6SSteve Lawrence 		mused = zs_resource_used_zone_uint64(z, ZS_RESOURCE_RAM_RSS);
1418*efd4c9b6SSteve Lawrence 		vused = zs_resource_used_zone_uint64(z, ZS_RESOURCE_VM);
1419*efd4c9b6SSteve Lawrence 
1420*efd4c9b6SSteve Lawrence 		ppart = zs_resource_used_zone_pct(z, ZS_RESOURCE_CPU);
1421*efd4c9b6SSteve Lawrence 		mpct = zs_resource_used_zone_pct(z, ZS_RESOURCE_RAM_RSS);
1422*efd4c9b6SSteve Lawrence 		vpct = zs_resource_used_zone_pct(z, ZS_RESOURCE_VM);
1423*efd4c9b6SSteve Lawrence 
1424*efd4c9b6SSteve Lawrence 		pshru = zs_zone_limit_used_pct(z, ZS_LIMIT_CPU_SHARES);
1425*efd4c9b6SSteve Lawrence 		pccap = zs_zone_limit_used_pct(z, ZS_LIMIT_CPU);
1426*efd4c9b6SSteve Lawrence 		pmcap = zs_zone_limit_used_pct(z, ZS_LIMIT_RAM_RSS);
1427*efd4c9b6SSteve Lawrence 		pvcap = zs_zone_limit_used_pct(z, ZS_LIMIT_VM);
1428*efd4c9b6SSteve Lawrence 
1429*efd4c9b6SSteve Lawrence 		zonestat_print_summary_zone(namewidth, report_fmt, zonename,
1430*efd4c9b6SSteve Lawrence 		    cused, ppart, pccap, pshru, mused, mpct, pmcap, vused, vpct,
1431*efd4c9b6SSteve Lawrence 		    pvcap);
1432*efd4c9b6SSteve Lawrence 	}
1433*efd4c9b6SSteve Lawrence 
1434*efd4c9b6SSteve Lawrence 	if (!opt_parseable)
1435*efd4c9b6SSteve Lawrence 		(void) printf("\n");
1436*efd4c9b6SSteve Lawrence 	(void) fflush(stdout);
1437*efd4c9b6SSteve Lawrence }
1438*efd4c9b6SSteve Lawrence 
1439*efd4c9b6SSteve Lawrence static void
zonestat_print_res(int report_fmt,char * header,char * sizename,char * resname,char * name,zs_usage_t * u,int res,int limit)1440*efd4c9b6SSteve Lawrence zonestat_print_res(int report_fmt, char *header, char *sizename, char *resname,
1441*efd4c9b6SSteve Lawrence     char *name, zs_usage_t *u, int res, int limit)
1442*efd4c9b6SSteve Lawrence {
1443*efd4c9b6SSteve Lawrence 	zs_zone_t *zone;
1444*efd4c9b6SSteve Lawrence 	char zonename[ZS_ZONENAME_MAX];
1445*efd4c9b6SSteve Lawrence 	uint64_t size;
1446*efd4c9b6SSteve Lawrence 	uint64_t used;
1447*efd4c9b6SSteve Lawrence 	uint64_t cap;
1448*efd4c9b6SSteve Lawrence 	uint_t pct;
1449*efd4c9b6SSteve Lawrence 	uint_t pctcap;
1450*efd4c9b6SSteve Lawrence 	zs_property_t *prop;
1451*efd4c9b6SSteve Lawrence 	int num, i;
1452*efd4c9b6SSteve Lawrence 	size_t namelen, len;
1453*efd4c9b6SSteve Lawrence 
1454*efd4c9b6SSteve Lawrence 	prop = (zs_property_t *)alloca(zs_property_size());
1455*efd4c9b6SSteve Lawrence 
1456*efd4c9b6SSteve Lawrence 	/* See if resource matches specified resource names */
1457*efd4c9b6SSteve Lawrence 	if (zonestat_match_resname(name) == 0)
1458*efd4c9b6SSteve Lawrence 		return;
1459*efd4c9b6SSteve Lawrence 
1460*efd4c9b6SSteve Lawrence 	namelen = strlen(resname);
1461*efd4c9b6SSteve Lawrence 	if (ZSTAT_RESOURCE_MIN_RESNAME > namelen)
1462*efd4c9b6SSteve Lawrence 		namelen = ZSTAT_RESOURCE_MIN_RESNAME;
1463*efd4c9b6SSteve Lawrence 
1464*efd4c9b6SSteve Lawrence 	zonestat_print_resource__header(namelen, header, sizename);
1465*efd4c9b6SSteve Lawrence 
1466*efd4c9b6SSteve Lawrence 	size = zs_resource_total_uint64(u, res);
1467*efd4c9b6SSteve Lawrence 
1468*efd4c9b6SSteve Lawrence 	if (opt_line_resource)
1469*efd4c9b6SSteve Lawrence 		zonestat_print_resource_(namelen, report_fmt, resname, name,
1470*efd4c9b6SSteve Lawrence 		    size);
1471*efd4c9b6SSteve Lawrence 
1472*efd4c9b6SSteve Lawrence again:
1473*efd4c9b6SSteve Lawrence 	num = zs_zone_list(u, g_zone_list, g_zone_num);
1474*efd4c9b6SSteve Lawrence 	if (num > g_zone_num) {
1475*efd4c9b6SSteve Lawrence 		if (g_zone_list != NULL)
1476*efd4c9b6SSteve Lawrence 			free(g_zone_list);
1477*efd4c9b6SSteve Lawrence 		g_zone_list = (zs_zone_t **) malloc(sizeof (zs_zone_t *) * num);
1478*efd4c9b6SSteve Lawrence 		g_zone_num = num;
1479*efd4c9b6SSteve Lawrence 		goto again;
1480*efd4c9b6SSteve Lawrence 	}
1481*efd4c9b6SSteve Lawrence 	namelen = ZSTAT_RESOURCE_MIN_ZONENAME;
1482*efd4c9b6SSteve Lawrence 	for (i = 0; i < num; i++) {
1483*efd4c9b6SSteve Lawrence 		zone = g_zone_list[i];
1484*efd4c9b6SSteve Lawrence 		(void) zs_zone_property(zone, ZS_ZONE_PROP_NAME, prop);
1485*efd4c9b6SSteve Lawrence 		len = strlen(zs_property_string(prop));
1486*efd4c9b6SSteve Lawrence 		if (len > namelen)
1487*efd4c9b6SSteve Lawrence 			namelen = len;
1488*efd4c9b6SSteve Lawrence 	}
1489*efd4c9b6SSteve Lawrence 
1490*efd4c9b6SSteve Lawrence 	zonestat_print_resource_zone_header(namelen);
1491*efd4c9b6SSteve Lawrence 
1492*efd4c9b6SSteve Lawrence 	used = zs_resource_used_uint64(u, res, ZS_USER_ALL);
1493*efd4c9b6SSteve Lawrence 	pct = zs_resource_used_pct(u, res, ZS_USER_ALL);
1494*efd4c9b6SSteve Lawrence 
1495*efd4c9b6SSteve Lawrence 	if (opt_line_total) {
1496*efd4c9b6SSteve Lawrence 		(void) snprintf(zonename, sizeof (zonename), "[%s]",
1497*efd4c9b6SSteve Lawrence 		    ZONESTAT_NAME_TOTAL);
1498*efd4c9b6SSteve Lawrence 		zonestat_print_resource_zone(namelen, report_fmt, resname,
1499*efd4c9b6SSteve Lawrence 		    name, zonename, used, pct, ZS_LIMIT_NONE, ZS_PCT_NONE);
1500*efd4c9b6SSteve Lawrence 	}
1501*efd4c9b6SSteve Lawrence 	used = zs_resource_used_uint64(u, res, ZS_USER_KERNEL);
1502*efd4c9b6SSteve Lawrence 	pct = zs_resource_used_pct(u, res, ZS_USER_KERNEL);
1503*efd4c9b6SSteve Lawrence 
1504*efd4c9b6SSteve Lawrence 	if (opt_line_system) {
1505*efd4c9b6SSteve Lawrence 		(void) snprintf(zonename, sizeof (zonename), "[%s]",
1506*efd4c9b6SSteve Lawrence 		    ZONESTAT_NAME_SYSTEM);
1507*efd4c9b6SSteve Lawrence 		zonestat_print_resource_zone(namelen, report_fmt, resname, name,
1508*efd4c9b6SSteve Lawrence 		    zonename, used, pct, ZS_LIMIT_NONE, ZS_PCT_NONE);
1509*efd4c9b6SSteve Lawrence 	}
1510*efd4c9b6SSteve Lawrence 	zonestat_qsort(g_zone_list, num, sizeof (zs_zone_t *),
1511*efd4c9b6SSteve Lawrence 	    zonestat_zone_compare_resource, res);
1512*efd4c9b6SSteve Lawrence 
1513*efd4c9b6SSteve Lawrence 	for (i = 0; i < num; i++) {
1514*efd4c9b6SSteve Lawrence 
1515*efd4c9b6SSteve Lawrence 		zone = g_zone_list[i];
1516*efd4c9b6SSteve Lawrence 		zs_zone_property(zone, ZS_ZONE_PROP_NAME, prop);
1517*efd4c9b6SSteve Lawrence 		(void) strlcpy(zonename, zs_property_string(prop),
1518*efd4c9b6SSteve Lawrence 		    sizeof (zonename));
1519*efd4c9b6SSteve Lawrence 
1520*efd4c9b6SSteve Lawrence 		if (zonestat_match_zonename(zonename) == 0)
1521*efd4c9b6SSteve Lawrence 			continue;
1522*efd4c9b6SSteve Lawrence 
1523*efd4c9b6SSteve Lawrence 		used = zs_resource_used_zone_uint64(zone, res);
1524*efd4c9b6SSteve Lawrence 		pct = zs_resource_used_zone_pct(zone, res);
1525*efd4c9b6SSteve Lawrence 
1526*efd4c9b6SSteve Lawrence 		cap = zs_zone_limit_uint64(zone, limit);
1527*efd4c9b6SSteve Lawrence 		pctcap = zs_zone_limit_used_pct(zone, limit);
1528*efd4c9b6SSteve Lawrence 
1529*efd4c9b6SSteve Lawrence 		if (opt_line_zones)
1530*efd4c9b6SSteve Lawrence 			zonestat_print_resource_zone(namelen, report_fmt,
1531*efd4c9b6SSteve Lawrence 			    resname, name, zonename, used, pct, cap, pctcap);
1532*efd4c9b6SSteve Lawrence 	}
1533*efd4c9b6SSteve Lawrence 	if (!opt_parseable)
1534*efd4c9b6SSteve Lawrence 		(void) printf("\n");
1535*efd4c9b6SSteve Lawrence }
1536*efd4c9b6SSteve Lawrence 
1537*efd4c9b6SSteve Lawrence static void
zonestat_print_cpu_res_header(size_t namelen)1538*efd4c9b6SSteve Lawrence zonestat_print_cpu_res_header(size_t namelen)
1539*efd4c9b6SSteve Lawrence {
1540*efd4c9b6SSteve Lawrence 	char name_format[ZS_NAME_STRLEN];
1541*efd4c9b6SSteve Lawrence 
1542*efd4c9b6SSteve Lawrence 	if (opt_parseable)
1543*efd4c9b6SSteve Lawrence 		return;
1544*efd4c9b6SSteve Lawrence 
1545*efd4c9b6SSteve Lawrence 	(void) snprintf(name_format, sizeof (name_format), "%%-%ds ", namelen);
1546*efd4c9b6SSteve Lawrence 	/* LINTED */
1547*efd4c9b6SSteve Lawrence 	(void) printf(name_format, "PROCESSOR_SET");
1548*efd4c9b6SSteve Lawrence 	(void) printf(ZSTAT_CPU_RES_FORMAT, "TYPE", "ONLINE/CPUS", "MIN/MAX");
1549*efd4c9b6SSteve Lawrence }
1550*efd4c9b6SSteve Lawrence static void
zonestat_print_cpu_zone_header(size_t namelen)1551*efd4c9b6SSteve Lawrence zonestat_print_cpu_zone_header(size_t namelen)
1552*efd4c9b6SSteve Lawrence {
1553*efd4c9b6SSteve Lawrence 	char name_format[ZS_NAME_STRLEN];
1554*efd4c9b6SSteve Lawrence 
1555*efd4c9b6SSteve Lawrence 	if (opt_parseable)
1556*efd4c9b6SSteve Lawrence 		return;
1557*efd4c9b6SSteve Lawrence 
1558*efd4c9b6SSteve Lawrence 	(void) snprintf(name_format, sizeof (name_format), "%%%ds ", namelen);
1559*efd4c9b6SSteve Lawrence 	/* LINTED */
1560*efd4c9b6SSteve Lawrence 	(void) printf(name_format, "ZONE");
1561*efd4c9b6SSteve Lawrence 
1562*efd4c9b6SSteve Lawrence 	(void) printf(ZSTAT_CPU_ZONE_FORMAT, "USED", "PCT", "CAP",
1563*efd4c9b6SSteve Lawrence 	    "%CAP", "SHRS", "%SHR", "%SHRU");
1564*efd4c9b6SSteve Lawrence }
1565*efd4c9b6SSteve Lawrence 
1566*efd4c9b6SSteve Lawrence static void
zonestat_print_cpu_res(size_t namelen,int report_fmt,char * cputype,char * name,uint64_t online,uint64_t size,uint64_t min,uint64_t max,timestruc_t * ts)1567*efd4c9b6SSteve Lawrence zonestat_print_cpu_res(size_t namelen, int report_fmt, char *cputype,
1568*efd4c9b6SSteve Lawrence     char *name, uint64_t online, uint64_t size, uint64_t min, uint64_t max,
1569*efd4c9b6SSteve Lawrence     timestruc_t *ts)
1570*efd4c9b6SSteve Lawrence {
1571*efd4c9b6SSteve Lawrence 	char online_str[ZS_UINT64_STRLEN];
1572*efd4c9b6SSteve Lawrence 	char size_str[ZS_UINT64_STRLEN];
1573*efd4c9b6SSteve Lawrence 	char min_str[ZS_UINT64_STRLEN];
1574*efd4c9b6SSteve Lawrence 	char max_str[ZS_UINT64_STRLEN];
1575*efd4c9b6SSteve Lawrence 	char cpus_str[ZS_UINT64_STRLEN + ZS_UINT64_STRLEN + 1];
1576*efd4c9b6SSteve Lawrence 	char minmax_str[ZS_UINT64_STRLEN + ZS_UINT64_STRLEN + 1];
1577*efd4c9b6SSteve Lawrence 	char ts_str[ZS_TIME_STRLEN];
1578*efd4c9b6SSteve Lawrence 	char name_format[ZS_NAME_STRLEN];
1579*efd4c9b6SSteve Lawrence 
1580*efd4c9b6SSteve Lawrence 	char *label;
1581*efd4c9b6SSteve Lawrence 
1582*efd4c9b6SSteve Lawrence 	format_uint64(online, online_str, sizeof (online_str));
1583*efd4c9b6SSteve Lawrence 	format_uint64(size, size_str, sizeof (size_str));
1584*efd4c9b6SSteve Lawrence 	format_uint64(min, min_str, sizeof (min_str));
1585*efd4c9b6SSteve Lawrence 	format_uint64(max, max_str, sizeof (max_str));
1586*efd4c9b6SSteve Lawrence 	format_ts(ts, ts_str, sizeof (ts_str), B_FALSE);
1587*efd4c9b6SSteve Lawrence 
1588*efd4c9b6SSteve Lawrence 	if (opt_parseable) {
1589*efd4c9b6SSteve Lawrence 		if (opt_timestamp) {
1590*efd4c9b6SSteve Lawrence 			zonestat_print_timestamp(g_now_time);
1591*efd4c9b6SSteve Lawrence 			(void) printf(":");
1592*efd4c9b6SSteve Lawrence 		}
1593*efd4c9b6SSteve Lawrence 		label = zonestat_get_plabel(report_fmt);
1594*efd4c9b6SSteve Lawrence 
1595*efd4c9b6SSteve Lawrence 		(void) printf("%s:%s:%s:%s:[%s]:%s:%s:%s:%s:%s\n", label,
1596*efd4c9b6SSteve Lawrence 		    ZONESTAT_PROCESSOR_SET, cputype, name,
1597*efd4c9b6SSteve Lawrence 		    ZONESTAT_NAME_RESOURCE, online_str, size_str, min_str,
1598*efd4c9b6SSteve Lawrence 		    max_str, ts_str);
1599*efd4c9b6SSteve Lawrence 		return;
1600*efd4c9b6SSteve Lawrence 	}
1601*efd4c9b6SSteve Lawrence 
1602*efd4c9b6SSteve Lawrence 	(void) snprintf(cpus_str, sizeof (cpus_str), "%s/%s", online_str,
1603*efd4c9b6SSteve Lawrence 	    size_str);
1604*efd4c9b6SSteve Lawrence 	(void) snprintf(minmax_str, sizeof (minmax_str), "%s/%s", min_str,
1605*efd4c9b6SSteve Lawrence 	    max_str);
1606*efd4c9b6SSteve Lawrence 
1607*efd4c9b6SSteve Lawrence 	(void) snprintf(name_format, sizeof (name_format), "%%-%ds ", namelen);
1608*efd4c9b6SSteve Lawrence 	/* LINTED */
1609*efd4c9b6SSteve Lawrence 	(void) printf(name_format, name);
1610*efd4c9b6SSteve Lawrence 	(void) printf(ZSTAT_CPU_RES_FORMAT, cputype, cpus_str, minmax_str);
1611*efd4c9b6SSteve Lawrence }
1612*efd4c9b6SSteve Lawrence 
1613*efd4c9b6SSteve Lawrence static void
zonestat_print_cpu_zone(size_t namelen,int report_fmt,char * cputype,char * name,char * zonename,uint64_t used,uint_t pct,uint64_t cap,uint_t pct_cap,uint64_t shares,uint_t scheds,uint_t pct_shares,uint_t pct_shares_used,timestruc_t * ts,boolean_t report_conflict)1614*efd4c9b6SSteve Lawrence zonestat_print_cpu_zone(size_t namelen, int report_fmt, char *cputype,
1615*efd4c9b6SSteve Lawrence     char *name, char *zonename, uint64_t used, uint_t pct, uint64_t cap,
1616*efd4c9b6SSteve Lawrence     uint_t pct_cap, uint64_t shares, uint_t scheds, uint_t pct_shares,
1617*efd4c9b6SSteve Lawrence     uint_t pct_shares_used, timestruc_t *ts, boolean_t report_conflict)
1618*efd4c9b6SSteve Lawrence {
1619*efd4c9b6SSteve Lawrence 	char used_str[ZS_UINT64_STRLEN];
1620*efd4c9b6SSteve Lawrence 	char pct_str[ZS_PCT_STRLEN];
1621*efd4c9b6SSteve Lawrence 	char cap_str[ZS_UINT64_STRLEN];
1622*efd4c9b6SSteve Lawrence 	char pct_cap_str[ZS_PCT_STRLEN];
1623*efd4c9b6SSteve Lawrence 	char shares_str[ZS_UINT64_STRLEN];
1624*efd4c9b6SSteve Lawrence 	char pct_shares_str[ZS_PCT_STRLEN];
1625*efd4c9b6SSteve Lawrence 	char pct_shares_used_str[ZS_PCT_STRLEN];
1626*efd4c9b6SSteve Lawrence 	char ts_str[ZS_TIME_STRLEN];
1627*efd4c9b6SSteve Lawrence 	char name_format[ZS_NAME_STRLEN];
1628*efd4c9b6SSteve Lawrence 	char *label;
1629*efd4c9b6SSteve Lawrence 
1630*efd4c9b6SSteve Lawrence 	format_cpu(used, used_str, sizeof (used_str));
1631*efd4c9b6SSteve Lawrence 	format_pct(pct, pct_str, sizeof (pct_str));
1632*efd4c9b6SSteve Lawrence 	format_ts(ts, ts_str, sizeof (ts_str), B_FALSE);
1633*efd4c9b6SSteve Lawrence 
1634*efd4c9b6SSteve Lawrence 	if (cap == ZS_LIMIT_NONE)
1635*efd4c9b6SSteve Lawrence 		(void) strlcpy(cap_str, "-", sizeof (cap_str));
1636*efd4c9b6SSteve Lawrence 	else
1637*efd4c9b6SSteve Lawrence 		format_cpu(cap, cap_str, sizeof (cap_str));
1638*efd4c9b6SSteve Lawrence 
1639*efd4c9b6SSteve Lawrence 	if (pct_cap == ZS_PCT_NONE)
1640*efd4c9b6SSteve Lawrence 		(void) strlcpy(pct_cap_str, "-", sizeof (pct_cap_str));
1641*efd4c9b6SSteve Lawrence 	else
1642*efd4c9b6SSteve Lawrence 		format_pct(pct_cap, pct_cap_str, sizeof (pct_cap_str));
1643*efd4c9b6SSteve Lawrence 
1644*efd4c9b6SSteve Lawrence 	if ((scheds & ZS_SCHED_CONFLICT) &&
1645*efd4c9b6SSteve Lawrence 	    (!(scheds & ZS_SCHED_FSS)))
1646*efd4c9b6SSteve Lawrence 		(void) strlcpy(shares_str, "no-fss", sizeof (shares_str));
1647*efd4c9b6SSteve Lawrence 	else if (shares == ZS_LIMIT_NONE)
1648*efd4c9b6SSteve Lawrence 		(void) strlcpy(shares_str, "-", sizeof (shares_str));
1649*efd4c9b6SSteve Lawrence 	else if (shares == ZS_SHARES_UNLIMITED)
1650*efd4c9b6SSteve Lawrence 		(void) strlcpy(shares_str, "inf", sizeof (shares_str));
1651*efd4c9b6SSteve Lawrence 	else
1652*efd4c9b6SSteve Lawrence 		format_uint64(shares, shares_str, sizeof (shares_str));
1653*efd4c9b6SSteve Lawrence 
1654*efd4c9b6SSteve Lawrence 	if (pct_shares == ZS_PCT_NONE)
1655*efd4c9b6SSteve Lawrence 		(void) strlcpy(pct_shares_str, "-", sizeof (pct_shares_str));
1656*efd4c9b6SSteve Lawrence 	else
1657*efd4c9b6SSteve Lawrence 		format_pct(pct_shares, pct_shares_str,
1658*efd4c9b6SSteve Lawrence 		    sizeof (pct_shares_str));
1659*efd4c9b6SSteve Lawrence 
1660*efd4c9b6SSteve Lawrence 	if (pct_shares_used == ZS_PCT_NONE) {
1661*efd4c9b6SSteve Lawrence 		(void) strlcpy(pct_shares_used_str, "-",
1662*efd4c9b6SSteve Lawrence 		    sizeof (pct_shares_used_str));
1663*efd4c9b6SSteve Lawrence 	} else {
1664*efd4c9b6SSteve Lawrence 		format_pct(pct_shares_used, pct_shares_used_str,
1665*efd4c9b6SSteve Lawrence 		    sizeof (pct_shares_used_str));
1666*efd4c9b6SSteve Lawrence 	}
1667*efd4c9b6SSteve Lawrence 	if (opt_parseable) {
1668*efd4c9b6SSteve Lawrence 		if (opt_timestamp) {
1669*efd4c9b6SSteve Lawrence 			zonestat_print_timestamp(g_now_time);
1670*efd4c9b6SSteve Lawrence 			(void) printf(":");
1671*efd4c9b6SSteve Lawrence 		}
1672*efd4c9b6SSteve Lawrence 		label = zonestat_get_plabel(report_fmt);
1673*efd4c9b6SSteve Lawrence 
1674*efd4c9b6SSteve Lawrence 		(void) printf("%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s\n", label,
1675*efd4c9b6SSteve Lawrence 		    ZONESTAT_PROCESSOR_SET, cputype, name, zonename, used_str,
1676*efd4c9b6SSteve Lawrence 		    pct_str, cap_str, pct_cap_str, shares_str, pct_shares_str,
1677*efd4c9b6SSteve Lawrence 		    pct_shares_used_str, ts_str);
1678*efd4c9b6SSteve Lawrence 		return;
1679*efd4c9b6SSteve Lawrence 	} else {
1680*efd4c9b6SSteve Lawrence 		(void) snprintf(name_format, sizeof (name_format), "%%%ds ",
1681*efd4c9b6SSteve Lawrence 		    namelen);
1682*efd4c9b6SSteve Lawrence 		/* LINTED */
1683*efd4c9b6SSteve Lawrence 		(void) printf(name_format, zonename);
1684*efd4c9b6SSteve Lawrence 
1685*efd4c9b6SSteve Lawrence 		(void) printf(ZSTAT_CPU_ZONE_FORMAT, used_str,
1686*efd4c9b6SSteve Lawrence 		    pct_str, cap_str, pct_cap_str, shares_str, pct_shares_str,
1687*efd4c9b6SSteve Lawrence 		    pct_shares_used_str);
1688*efd4c9b6SSteve Lawrence 	}
1689*efd4c9b6SSteve Lawrence 	/* Report if zone has mix of schedulers conflicting with FSS */
1690*efd4c9b6SSteve Lawrence 	if (report_conflict && (scheds & ZS_SCHED_CONFLICT) &&
1691*efd4c9b6SSteve Lawrence 	    (scheds & ZS_SCHED_FSS)) {
1692*efd4c9b6SSteve Lawrence 		/* LINTED */
1693*efd4c9b6SSteve Lawrence 		(void) printf(name_format, "");
1694*efd4c9b6SSteve Lawrence 		(void) printf(" mixed schedulers found:");
1695*efd4c9b6SSteve Lawrence 		(void) printf(" FSS");
1696*efd4c9b6SSteve Lawrence 		if (scheds & ZS_SCHED_TS)
1697*efd4c9b6SSteve Lawrence 			(void) printf(", TS");
1698*efd4c9b6SSteve Lawrence 		if (scheds & ZS_SCHED_IA)
1699*efd4c9b6SSteve Lawrence 			(void) printf(", IA");
1700*efd4c9b6SSteve Lawrence 		if (scheds & ZS_SCHED_FX)
1701*efd4c9b6SSteve Lawrence 			(void) printf(", FX");
1702*efd4c9b6SSteve Lawrence 		(void) printf("\n");
1703*efd4c9b6SSteve Lawrence 	}
1704*efd4c9b6SSteve Lawrence }
1705*efd4c9b6SSteve Lawrence 
1706*efd4c9b6SSteve Lawrence static void
zonestat_print_pset(int report_fmt,zs_pset_t * pset,char * cputype)1707*efd4c9b6SSteve Lawrence zonestat_print_pset(int report_fmt, zs_pset_t *pset, char *cputype)
1708*efd4c9b6SSteve Lawrence {
1709*efd4c9b6SSteve Lawrence 	zs_pset_zone_t *pz;
1710*efd4c9b6SSteve Lawrence 	zs_zone_t *zone;
1711*efd4c9b6SSteve Lawrence 	uint64_t cpus;
1712*efd4c9b6SSteve Lawrence 	uint64_t size;
1713*efd4c9b6SSteve Lawrence 	uint64_t min;
1714*efd4c9b6SSteve Lawrence 	uint64_t max;
1715*efd4c9b6SSteve Lawrence 	uint_t scheds;
1716*efd4c9b6SSteve Lawrence 	uint64_t used;
1717*efd4c9b6SSteve Lawrence 	uint_t pct;
1718*efd4c9b6SSteve Lawrence 	uint64_t cap;
1719*efd4c9b6SSteve Lawrence 	uint_t pct_cap;
1720*efd4c9b6SSteve Lawrence 	uint64_t shares;
1721*efd4c9b6SSteve Lawrence 	uint_t pct_shares;
1722*efd4c9b6SSteve Lawrence 	uint_t pct_shares_used;
1723*efd4c9b6SSteve Lawrence 	char psetname[ZS_PSETNAME_MAX];
1724*efd4c9b6SSteve Lawrence 	char zonename[ZS_PSETNAME_MAX];
1725*efd4c9b6SSteve Lawrence 	char *name;
1726*efd4c9b6SSteve Lawrence 	zs_property_t *prop;
1727*efd4c9b6SSteve Lawrence 	boolean_t zone_match;
1728*efd4c9b6SSteve Lawrence 	int num, i;
1729*efd4c9b6SSteve Lawrence 	timestruc_t ts;
1730*efd4c9b6SSteve Lawrence 	size_t namelen, len;
1731*efd4c9b6SSteve Lawrence 
1732*efd4c9b6SSteve Lawrence 	prop = (zs_property_t *)alloca(zs_property_size());
1733*efd4c9b6SSteve Lawrence 
1734*efd4c9b6SSteve Lawrence 	zs_pset_property(pset, ZS_PSET_PROP_NAME, prop);
1735*efd4c9b6SSteve Lawrence 	(void) strlcpy(psetname, zs_property_string(prop), sizeof (psetname));
1736*efd4c9b6SSteve Lawrence 
1737*efd4c9b6SSteve Lawrence 	/* Check if pset contains specified zone */
1738*efd4c9b6SSteve Lawrence 	if (arg_zonename_count > 0) {
1739*efd4c9b6SSteve Lawrence 		zone_match = B_FALSE;
1740*efd4c9b6SSteve Lawrence 		for (pz = zs_pset_zone_first(pset); pz != NULL;
1741*efd4c9b6SSteve Lawrence 		    pz = zs_pset_zone_next(pset, pz)) {
1742*efd4c9b6SSteve Lawrence 			zone = zs_pset_zone_get_zone(pz);
1743*efd4c9b6SSteve Lawrence 			(void) zs_zone_property(zone, ZS_ZONE_PROP_NAME, prop);
1744*efd4c9b6SSteve Lawrence 			(void) strlcpy(zonename, zs_property_string(prop),
1745*efd4c9b6SSteve Lawrence 			    sizeof (zonename));
1746*efd4c9b6SSteve Lawrence 
1747*efd4c9b6SSteve Lawrence 			if (zonestat_match_zonename(zonename) == 1) {
1748*efd4c9b6SSteve Lawrence 				zone_match = B_TRUE;
1749*efd4c9b6SSteve Lawrence 				break;
1750*efd4c9b6SSteve Lawrence 			}
1751*efd4c9b6SSteve Lawrence 		}
1752*efd4c9b6SSteve Lawrence 		if (zone_match == B_FALSE)
1753*efd4c9b6SSteve Lawrence 			return;
1754*efd4c9b6SSteve Lawrence 	}
1755*efd4c9b6SSteve Lawrence 
1756*efd4c9b6SSteve Lawrence 	if (zonestat_match_resname(psetname) == 0)
1757*efd4c9b6SSteve Lawrence 		return;
1758*efd4c9b6SSteve Lawrence 
1759*efd4c9b6SSteve Lawrence 	zs_pset_property(pset, ZS_PSET_PROP_ONLINE, prop);
1760*efd4c9b6SSteve Lawrence 	cpus = zs_property_uint64(prop);
1761*efd4c9b6SSteve Lawrence 	zs_pset_property(pset, ZS_PSET_PROP_SIZE, prop);
1762*efd4c9b6SSteve Lawrence 	size = zs_property_uint64(prop);
1763*efd4c9b6SSteve Lawrence 	zs_pset_property(pset, ZS_PSET_PROP_MIN, prop);
1764*efd4c9b6SSteve Lawrence 	min = zs_property_uint64(prop);
1765*efd4c9b6SSteve Lawrence 	zs_pset_property(pset, ZS_PSET_PROP_MAX, prop);
1766*efd4c9b6SSteve Lawrence 	max = zs_property_uint64(prop);
1767*efd4c9b6SSteve Lawrence 	zs_pset_total_time(pset, &ts);
1768*efd4c9b6SSteve Lawrence 
1769*efd4c9b6SSteve Lawrence 	/* Strip off SUNWtmp_ from pset name */
1770*efd4c9b6SSteve Lawrence 	name = psetname;
1771*efd4c9b6SSteve Lawrence 	if (strncmp(psetname, "SUNWtmp_", strlen("SUNWtmp_")) == 0) {
1772*efd4c9b6SSteve Lawrence 		name = strchr(psetname, '_');
1773*efd4c9b6SSteve Lawrence 		name++;
1774*efd4c9b6SSteve Lawrence 	}
1775*efd4c9b6SSteve Lawrence 
1776*efd4c9b6SSteve Lawrence 	/* Strip off SUNWlegacy_pst for psrset psets */
1777*efd4c9b6SSteve Lawrence 	if (strncmp(psetname, "SUNWlegacy_pset_",
1778*efd4c9b6SSteve Lawrence 	    strlen("SUNWlegacy_pset_")) == 0) {
1779*efd4c9b6SSteve Lawrence 		name = strrchr(psetname, '_');
1780*efd4c9b6SSteve Lawrence 		name++;
1781*efd4c9b6SSteve Lawrence 	}
1782*efd4c9b6SSteve Lawrence 
1783*efd4c9b6SSteve Lawrence 	namelen = strlen(name);
1784*efd4c9b6SSteve Lawrence 	if (ZSTAT_CPU_MIN_PSETNAME > namelen)
1785*efd4c9b6SSteve Lawrence 		namelen = ZSTAT_CPU_MIN_PSETNAME;
1786*efd4c9b6SSteve Lawrence 
1787*efd4c9b6SSteve Lawrence 	zonestat_print_cpu_res_header(namelen);
1788*efd4c9b6SSteve Lawrence 
1789*efd4c9b6SSteve Lawrence 	if (opt_line_resource)
1790*efd4c9b6SSteve Lawrence 		zonestat_print_cpu_res(namelen, report_fmt, cputype, name, cpus,
1791*efd4c9b6SSteve Lawrence 		    size, min, max, &ts);
1792*efd4c9b6SSteve Lawrence 
1793*efd4c9b6SSteve Lawrence again:
1794*efd4c9b6SSteve Lawrence 	num = zs_pset_zone_list(pset, g_pz_list, g_pz_num);
1795*efd4c9b6SSteve Lawrence 	if (num > g_pz_num) {
1796*efd4c9b6SSteve Lawrence 		if (g_pz_list != NULL)
1797*efd4c9b6SSteve Lawrence 			free(g_pz_list);
1798*efd4c9b6SSteve Lawrence 		g_pz_list = (zs_pset_zone_t **)malloc(
1799*efd4c9b6SSteve Lawrence 		    sizeof (zs_pset_zone_t *) * num);
1800*efd4c9b6SSteve Lawrence 		g_pz_num = num;
1801*efd4c9b6SSteve Lawrence 		goto again;
1802*efd4c9b6SSteve Lawrence 	}
1803*efd4c9b6SSteve Lawrence 
1804*efd4c9b6SSteve Lawrence 	/* Find longest zone name in pset */
1805*efd4c9b6SSteve Lawrence 	namelen = ZSTAT_CPU_MIN_ZONENAME;
1806*efd4c9b6SSteve Lawrence 	for (i = 0; i < num; i++) {
1807*efd4c9b6SSteve Lawrence 		pz = g_pz_list[i];
1808*efd4c9b6SSteve Lawrence 		zone = zs_pset_zone_get_zone(pz);
1809*efd4c9b6SSteve Lawrence 		zs_zone_property(zone, ZS_ZONE_PROP_NAME, prop);
1810*efd4c9b6SSteve Lawrence 		len = strlen(zs_property_string(prop));
1811*efd4c9b6SSteve Lawrence 		if (len > namelen)
1812*efd4c9b6SSteve Lawrence 			namelen = len;
1813*efd4c9b6SSteve Lawrence 	}
1814*efd4c9b6SSteve Lawrence 
1815*efd4c9b6SSteve Lawrence 	qsort(g_pz_list, num, sizeof (zs_pset_zone_t *),
1816*efd4c9b6SSteve Lawrence 	    zonestat_pz_compare_usage);
1817*efd4c9b6SSteve Lawrence 
1818*efd4c9b6SSteve Lawrence 	zonestat_print_cpu_zone_header(namelen);
1819*efd4c9b6SSteve Lawrence 
1820*efd4c9b6SSteve Lawrence 	zs_pset_property(pset, ZS_PSET_PROP_CPU_SHARES, prop);
1821*efd4c9b6SSteve Lawrence 	shares = zs_property_uint64(prop);
1822*efd4c9b6SSteve Lawrence 	zs_pset_property(pset, ZS_PSET_PROP_SCHEDULERS, prop);
1823*efd4c9b6SSteve Lawrence 	scheds = zs_property_uint(prop);
1824*efd4c9b6SSteve Lawrence 
1825*efd4c9b6SSteve Lawrence 	zs_pset_used_time(pset, ZS_USER_ALL, &ts);
1826*efd4c9b6SSteve Lawrence 	used = zs_pset_used_cpus(pset, ZS_USER_ALL);
1827*efd4c9b6SSteve Lawrence 	pct = zs_pset_used_pct(pset, ZS_USER_ALL);
1828*efd4c9b6SSteve Lawrence 
1829*efd4c9b6SSteve Lawrence 	if (opt_line_total) {
1830*efd4c9b6SSteve Lawrence 		(void) snprintf(zonename, sizeof (zonename), "[%s]",
1831*efd4c9b6SSteve Lawrence 		    ZONESTAT_NAME_TOTAL);
1832*efd4c9b6SSteve Lawrence 		zonestat_print_cpu_zone(namelen, report_fmt, cputype, name,
1833*efd4c9b6SSteve Lawrence 		    zonename, used, pct, ZS_LIMIT_NONE, ZS_PCT_NONE, shares,
1834*efd4c9b6SSteve Lawrence 		    scheds, ZS_PCT_NONE, ZS_PCT_NONE, &ts, B_FALSE);
1835*efd4c9b6SSteve Lawrence 	}
1836*efd4c9b6SSteve Lawrence 	zs_pset_used_time(pset, ZS_USER_KERNEL, &ts);
1837*efd4c9b6SSteve Lawrence 	used = zs_pset_used_cpus(pset, ZS_USER_KERNEL);
1838*efd4c9b6SSteve Lawrence 	pct = zs_pset_used_pct(pset, ZS_USER_KERNEL);
1839*efd4c9b6SSteve Lawrence 
1840*efd4c9b6SSteve Lawrence 	if (opt_line_system) {
1841*efd4c9b6SSteve Lawrence 		(void) snprintf(zonename, sizeof (zonename), "[%s]",
1842*efd4c9b6SSteve Lawrence 		    ZONESTAT_NAME_SYSTEM);
1843*efd4c9b6SSteve Lawrence 		zonestat_print_cpu_zone(namelen, report_fmt, cputype, name,
1844*efd4c9b6SSteve Lawrence 		    zonename, used, pct, ZS_LIMIT_NONE, ZS_PCT_NONE,
1845*efd4c9b6SSteve Lawrence 		    ZS_LIMIT_NONE, 0, ZS_PCT_NONE, ZS_PCT_NONE, &ts, B_FALSE);
1846*efd4c9b6SSteve Lawrence 	}
1847*efd4c9b6SSteve Lawrence 	for (i = 0; i < num; i++) {
1848*efd4c9b6SSteve Lawrence 
1849*efd4c9b6SSteve Lawrence 		pz = g_pz_list[i];
1850*efd4c9b6SSteve Lawrence 		zone = zs_pset_zone_get_zone(pz);
1851*efd4c9b6SSteve Lawrence 		zs_zone_property(zone, ZS_ZONE_PROP_NAME, prop);
1852*efd4c9b6SSteve Lawrence 		(void) strlcpy(zonename, zs_property_string(prop),
1853*efd4c9b6SSteve Lawrence 		    sizeof (zonename));
1854*efd4c9b6SSteve Lawrence 
1855*efd4c9b6SSteve Lawrence 		if (zonestat_match_zonename(zonename) == 0)
1856*efd4c9b6SSteve Lawrence 			continue;
1857*efd4c9b6SSteve Lawrence 
1858*efd4c9b6SSteve Lawrence 		zs_pset_zone_property(pz, ZS_PZ_PROP_CPU_CAP, prop);
1859*efd4c9b6SSteve Lawrence 		cap = zs_property_uint64(prop);
1860*efd4c9b6SSteve Lawrence 
1861*efd4c9b6SSteve Lawrence 		zs_pset_zone_property(pz, ZS_PZ_PROP_CPU_SHARES, prop);
1862*efd4c9b6SSteve Lawrence 		shares = zs_property_uint64(prop);
1863*efd4c9b6SSteve Lawrence 		zs_pset_zone_property(pz, ZS_PZ_PROP_SCHEDULERS, prop);
1864*efd4c9b6SSteve Lawrence 		scheds = zs_property_uint(prop);
1865*efd4c9b6SSteve Lawrence 
1866*efd4c9b6SSteve Lawrence 		used = zs_pset_zone_used_cpus(pz);
1867*efd4c9b6SSteve Lawrence 		zs_pset_zone_used_time(pz, &ts);
1868*efd4c9b6SSteve Lawrence 		pct = zs_pset_zone_used_pct(pz, ZS_PZ_PCT_PSET);
1869*efd4c9b6SSteve Lawrence 		pct_cap = zs_pset_zone_used_pct(pz, ZS_PZ_PCT_CPU_CAP);
1870*efd4c9b6SSteve Lawrence 		pct_shares = zs_pset_zone_used_pct(pz, ZS_PZ_PCT_PSET_SHARES);
1871*efd4c9b6SSteve Lawrence 		pct_shares_used = zs_pset_zone_used_pct(pz,
1872*efd4c9b6SSteve Lawrence 		    ZS_PZ_PCT_CPU_SHARES);
1873*efd4c9b6SSteve Lawrence 
1874*efd4c9b6SSteve Lawrence 		if (opt_line_zones)
1875*efd4c9b6SSteve Lawrence 			zonestat_print_cpu_zone(namelen, report_fmt, cputype,
1876*efd4c9b6SSteve Lawrence 			    name, zonename, used, pct, cap, pct_cap, shares,
1877*efd4c9b6SSteve Lawrence 			    scheds, pct_shares, pct_shares_used, &ts, B_TRUE);
1878*efd4c9b6SSteve Lawrence 	}
1879*efd4c9b6SSteve Lawrence 	if (!opt_parseable)
1880*efd4c9b6SSteve Lawrence 		(void) printf("\n");
1881*efd4c9b6SSteve Lawrence }
1882*efd4c9b6SSteve Lawrence 
1883*efd4c9b6SSteve Lawrence /* ARGSUSED */
1884*efd4c9b6SSteve Lawrence static void
zonestat_quithandler(int sig)1885*efd4c9b6SSteve Lawrence zonestat_quithandler(int sig)
1886*efd4c9b6SSteve Lawrence {
1887*efd4c9b6SSteve Lawrence 	g_quit = B_TRUE;
1888*efd4c9b6SSteve Lawrence }
1889*efd4c9b6SSteve Lawrence 
1890*efd4c9b6SSteve Lawrence static void
zonestat_print_footer(int report_fmt)1891*efd4c9b6SSteve Lawrence zonestat_print_footer(int report_fmt)
1892*efd4c9b6SSteve Lawrence {
1893*efd4c9b6SSteve Lawrence 	char *label;
1894*efd4c9b6SSteve Lawrence 
1895*efd4c9b6SSteve Lawrence 	if (!opt_parseable)
1896*efd4c9b6SSteve Lawrence 		return;
1897*efd4c9b6SSteve Lawrence 
1898*efd4c9b6SSteve Lawrence 	if (opt_timestamp) {
1899*efd4c9b6SSteve Lawrence 		zonestat_print_timestamp(g_now_time);
1900*efd4c9b6SSteve Lawrence 		(void) printf(":");
1901*efd4c9b6SSteve Lawrence 	}
1902*efd4c9b6SSteve Lawrence 	label = zonestat_get_plabel(report_fmt);
1903*efd4c9b6SSteve Lawrence 	(void) printf("%s:%s:", label, ZONESTAT_NAME_FOOTER);
1904*efd4c9b6SSteve Lawrence 	zonestat_print_timestamp(g_now_time);
1905*efd4c9b6SSteve Lawrence 	(void) printf("%d:%ld\n", g_interval, g_seconds);
1906*efd4c9b6SSteve Lawrence 	(void) fflush(stdout);
1907*efd4c9b6SSteve Lawrence }
1908*efd4c9b6SSteve Lawrence 
1909*efd4c9b6SSteve Lawrence static void
zonestat_print_header(int report_fmt)1910*efd4c9b6SSteve Lawrence zonestat_print_header(int report_fmt)
1911*efd4c9b6SSteve Lawrence {
1912*efd4c9b6SSteve Lawrence 	char *label;
1913*efd4c9b6SSteve Lawrence 	timestruc_t ts;
1914*efd4c9b6SSteve Lawrence 	char string[ZS_TIME_STRLEN];
1915*efd4c9b6SSteve Lawrence 
1916*efd4c9b6SSteve Lawrence 	if (!opt_parseable) {
1917*efd4c9b6SSteve Lawrence 
1918*efd4c9b6SSteve Lawrence 		/* Human readable header */
1919*efd4c9b6SSteve Lawrence 		if (opt_timestamp) {
1920*efd4c9b6SSteve Lawrence 			zonestat_print_timestamp(g_now_time);
1921*efd4c9b6SSteve Lawrence 			(void) printf(", ");
1922*efd4c9b6SSteve Lawrence 		}
1923*efd4c9b6SSteve Lawrence 		if (report_fmt == ZSTAT_REPORT_FMT_INTERVAL) {
1924*efd4c9b6SSteve Lawrence 			ts.tv_sec = g_seconds;
1925*efd4c9b6SSteve Lawrence 			ts.tv_nsec = 0;
1926*efd4c9b6SSteve Lawrence 			format_ts(&ts, string, sizeof (string), B_TRUE);
1927*efd4c9b6SSteve Lawrence 			(void) printf("Interval: %d, Duration: %s\n", g_count,
1928*efd4c9b6SSteve Lawrence 			    string);
1929*efd4c9b6SSteve Lawrence 			(void) fflush(stdout);
1930*efd4c9b6SSteve Lawrence 			return;
1931*efd4c9b6SSteve Lawrence 		} else {
1932*efd4c9b6SSteve Lawrence 			switch (report_fmt) {
1933*efd4c9b6SSteve Lawrence 			case ZSTAT_REPORT_FMT_TOTAL:
1934*efd4c9b6SSteve Lawrence 				label = "Report: Total Usage";
1935*efd4c9b6SSteve Lawrence 				break;
1936*efd4c9b6SSteve Lawrence 			case ZSTAT_REPORT_FMT_AVERAGE:
1937*efd4c9b6SSteve Lawrence 				label = "Report: Average Usage";
1938*efd4c9b6SSteve Lawrence 				break;
1939*efd4c9b6SSteve Lawrence 			case ZSTAT_REPORT_FMT_HIGH:
1940*efd4c9b6SSteve Lawrence 				label = "Report: High Usage";
1941*efd4c9b6SSteve Lawrence 				break;
1942*efd4c9b6SSteve Lawrence 			default:
1943*efd4c9b6SSteve Lawrence 				exit(zonestat_error(gettext(
1944*efd4c9b6SSteve Lawrence 				    "Internal error, invalid header")));
1945*efd4c9b6SSteve Lawrence 			}
1946*efd4c9b6SSteve Lawrence 			/* Left are the report header formats */
1947*efd4c9b6SSteve Lawrence 			(void) printf("%s\n", label);
1948*efd4c9b6SSteve Lawrence 			(void) printf("    Start: ");
1949*efd4c9b6SSteve Lawrence 			zonestat_print_timestamp(g_start_time);
1950*efd4c9b6SSteve Lawrence 			(void) printf("\n      End: ");
1951*efd4c9b6SSteve Lawrence 			zonestat_print_timestamp(g_end_time);
1952*efd4c9b6SSteve Lawrence 			(void) printf("\n");
1953*efd4c9b6SSteve Lawrence 			ts.tv_sec = g_seconds;
1954*efd4c9b6SSteve Lawrence 			ts.tv_nsec = 0;
1955*efd4c9b6SSteve Lawrence 			format_ts(&ts, string, sizeof (string), B_TRUE);
1956*efd4c9b6SSteve Lawrence 			(void) printf("    Intervals: %d, Duration: %s\n",
1957*efd4c9b6SSteve Lawrence 			    g_count, string);
1958*efd4c9b6SSteve Lawrence 
1959*efd4c9b6SSteve Lawrence 			(void) fflush(stdout);
1960*efd4c9b6SSteve Lawrence 			return;
1961*efd4c9b6SSteve Lawrence 		}
1962*efd4c9b6SSteve Lawrence 	}
1963*efd4c9b6SSteve Lawrence 
1964*efd4c9b6SSteve Lawrence 	if (!opt_line_header)
1965*efd4c9b6SSteve Lawrence 		return;
1966*efd4c9b6SSteve Lawrence 
1967*efd4c9b6SSteve Lawrence 	/* Parseable header */
1968*efd4c9b6SSteve Lawrence 	if (opt_timestamp) {
1969*efd4c9b6SSteve Lawrence 		zonestat_print_timestamp(g_now_time);
1970*efd4c9b6SSteve Lawrence 		(void) printf(":");
1971*efd4c9b6SSteve Lawrence 	}
1972*efd4c9b6SSteve Lawrence 	label = zonestat_get_plabel(report_fmt);
1973*efd4c9b6SSteve Lawrence 
1974*efd4c9b6SSteve Lawrence 	(void) printf("%s:%s:", label, ZONESTAT_NAME_HEADER);
1975*efd4c9b6SSteve Lawrence 	if (report_fmt == ZSTAT_REPORT_FMT_INTERVAL) {
1976*efd4c9b6SSteve Lawrence 		(void) printf("since-last-interval:");
1977*efd4c9b6SSteve Lawrence 		zonestat_print_timestamp(g_now_time);
1978*efd4c9b6SSteve Lawrence 		(void) printf(":%d:%ld\n", g_count, g_seconds);
1979*efd4c9b6SSteve Lawrence 		(void) fflush(stdout);
1980*efd4c9b6SSteve Lawrence 		return;
1981*efd4c9b6SSteve Lawrence 	}
1982*efd4c9b6SSteve Lawrence 
1983*efd4c9b6SSteve Lawrence 	/* Left are the report header formats */
1984*efd4c9b6SSteve Lawrence 	zonestat_print_timestamp(g_start_time);
1985*efd4c9b6SSteve Lawrence 	(void) printf(":");
1986*efd4c9b6SSteve Lawrence 	zonestat_print_timestamp(g_end_time);
1987*efd4c9b6SSteve Lawrence 	(void) printf(":");
1988*efd4c9b6SSteve Lawrence 	(void) printf("%d:%ld\n", g_interval, g_seconds);
1989*efd4c9b6SSteve Lawrence 	(void) fflush(stdout);
1990*efd4c9b6SSteve Lawrence }
1991*efd4c9b6SSteve Lawrence 
1992*efd4c9b6SSteve Lawrence static void
zonestat_print_psets(int report_fmt,zs_usage_t * u)1993*efd4c9b6SSteve Lawrence zonestat_print_psets(int report_fmt, zs_usage_t *u)
1994*efd4c9b6SSteve Lawrence {
1995*efd4c9b6SSteve Lawrence 	zs_pset_t *pset;
1996*efd4c9b6SSteve Lawrence 	char *psettype;
1997*efd4c9b6SSteve Lawrence 	uint_t cputype, num, i;
1998*efd4c9b6SSteve Lawrence 	zs_property_t *p;
1999*efd4c9b6SSteve Lawrence 
2000*efd4c9b6SSteve Lawrence again:
2001*efd4c9b6SSteve Lawrence 	num = zs_pset_list(u, g_pset_list, g_pset_num);
2002*efd4c9b6SSteve Lawrence 	if (num > g_pset_num) {
2003*efd4c9b6SSteve Lawrence 		if (g_pset_list != NULL)
2004*efd4c9b6SSteve Lawrence 			free(g_pset_list);
2005*efd4c9b6SSteve Lawrence 		g_pset_list = (zs_pset_t **)malloc(
2006*efd4c9b6SSteve Lawrence 		    sizeof (zs_pset_t *) * num);
2007*efd4c9b6SSteve Lawrence 		g_pset_num = num;
2008*efd4c9b6SSteve Lawrence 		goto again;
2009*efd4c9b6SSteve Lawrence 	}
2010*efd4c9b6SSteve Lawrence 
2011*efd4c9b6SSteve Lawrence 	/* Sort, default pset first, then pool, psrset, and dedicated psets */
2012*efd4c9b6SSteve Lawrence 	qsort(g_pset_list, num, sizeof (zs_pset_t *), zonestat_pset_compare);
2013*efd4c9b6SSteve Lawrence 
2014*efd4c9b6SSteve Lawrence 	p = (zs_property_t *)alloca(zs_property_size());
2015*efd4c9b6SSteve Lawrence 	for (i = 0; i < num; i++) {
2016*efd4c9b6SSteve Lawrence 		pset = g_pset_list[i];
2017*efd4c9b6SSteve Lawrence 		(void) zs_pset_property(pset, ZS_PSET_PROP_CPUTYPE, p);
2018*efd4c9b6SSteve Lawrence 		cputype = zs_property_uint(p);
2019*efd4c9b6SSteve Lawrence 		if (cputype == ZS_CPUTYPE_DEFAULT_PSET &&
2020*efd4c9b6SSteve Lawrence 		    (g_resources & (ZSTAT_RES_PSETS |
2021*efd4c9b6SSteve Lawrence 		    ZSTAT_RES_DEFAULT_PSET))) {
2022*efd4c9b6SSteve Lawrence 			psettype = ZONESTAT_DEFAULT_PSET;
2023*efd4c9b6SSteve Lawrence 		} else if (cputype == ZS_CPUTYPE_POOL_PSET &&
2024*efd4c9b6SSteve Lawrence 		    (g_resources & ZSTAT_RES_PSETS)) {
2025*efd4c9b6SSteve Lawrence 			psettype = ZONESTAT_POOL_PSET;
2026*efd4c9b6SSteve Lawrence 		} else if (cputype == ZS_CPUTYPE_PSRSET_PSET &&
2027*efd4c9b6SSteve Lawrence 		    (g_resources & ZSTAT_RES_PSETS)) {
2028*efd4c9b6SSteve Lawrence 			psettype = ZONESTAT_PSRSET_PSET;
2029*efd4c9b6SSteve Lawrence 		} else if (cputype == ZS_CPUTYPE_DEDICATED &&
2030*efd4c9b6SSteve Lawrence 		    (g_resources & ZSTAT_RES_PSETS)) {
2031*efd4c9b6SSteve Lawrence 			psettype = ZONESTAT_DEDICATED_CPU;
2032*efd4c9b6SSteve Lawrence 		} else {
2033*efd4c9b6SSteve Lawrence 			continue;
2034*efd4c9b6SSteve Lawrence 		}
2035*efd4c9b6SSteve Lawrence 		zonestat_print_pset(report_fmt, pset, psettype);
2036*efd4c9b6SSteve Lawrence 	}
2037*efd4c9b6SSteve Lawrence }
2038*efd4c9b6SSteve Lawrence 
2039*efd4c9b6SSteve Lawrence static void
zonestat_print_resources(int report_fmt,zs_usage_t * usage)2040*efd4c9b6SSteve Lawrence zonestat_print_resources(int report_fmt, zs_usage_t *usage)
2041*efd4c9b6SSteve Lawrence {
2042*efd4c9b6SSteve Lawrence 	if (g_resources & ZSTAT_RES_SUMMARY)
2043*efd4c9b6SSteve Lawrence 		zonestat_print_summary(report_fmt, usage);
2044*efd4c9b6SSteve Lawrence 
2045*efd4c9b6SSteve Lawrence 	if (g_resources & ZSTAT_RES_PHYSICAL_MEMORY)
2046*efd4c9b6SSteve Lawrence 		zonestat_print_res(report_fmt, "PHYSICAL-MEMORY",
2047*efd4c9b6SSteve Lawrence 		    "SYSTEM MEMORY", ZONESTAT_PHYSICAL_MEMORY,
2048*efd4c9b6SSteve Lawrence 		    ZONESTAT_NAME_MEM_DEFAULT, usage,
2049*efd4c9b6SSteve Lawrence 		    ZS_RESOURCE_RAM_RSS, ZS_LIMIT_RAM_RSS);
2050*efd4c9b6SSteve Lawrence 	if (g_resources & ZSTAT_RES_VIRTUAL_MEMORY)
2051*efd4c9b6SSteve Lawrence 		zonestat_print_res(report_fmt, "VIRTUAL-MEMORY",
2052*efd4c9b6SSteve Lawrence 		    "SYSTEM MEMORY", ZONESTAT_VIRTUAL_MEMORY,
2053*efd4c9b6SSteve Lawrence 		    ZONESTAT_NAME_VM_DEFAULT, usage,
2054*efd4c9b6SSteve Lawrence 		    ZS_RESOURCE_VM, ZS_LIMIT_VM);
2055*efd4c9b6SSteve Lawrence 	if (g_resources & ZSTAT_RES_LOCKED_MEMORY)
2056*efd4c9b6SSteve Lawrence 		zonestat_print_res(report_fmt, "LOCKED-MEMORY", "SYSTEM MEMORY",
2057*efd4c9b6SSteve Lawrence 		    ZONESTAT_LOCKED_MEMORY, ZONESTAT_NAME_MEM_DEFAULT, usage,
2058*efd4c9b6SSteve Lawrence 		    ZS_RESOURCE_RAM_LOCKED, ZS_LIMIT_RAM_LOCKED);
2059*efd4c9b6SSteve Lawrence 
2060*efd4c9b6SSteve Lawrence 	if (g_resources & (ZSTAT_RES_PSETS | ZSTAT_RES_DEFAULT_PSET))
2061*efd4c9b6SSteve Lawrence 			zonestat_print_psets(report_fmt, usage);
2062*efd4c9b6SSteve Lawrence 
2063*efd4c9b6SSteve Lawrence 	if (g_resources & ZSTAT_RES_PROCESSES)
2064*efd4c9b6SSteve Lawrence 		zonestat_print_res(report_fmt, "PROCESSES", "SYSTEM LIMIT",
2065*efd4c9b6SSteve Lawrence 		    ZONESTAT_PROCESSES, ZONESTAT_NAME_SYSTEM_LIMIT,
2066*efd4c9b6SSteve Lawrence 		    usage, ZS_RESOURCE_PROCESSES, ZS_LIMIT_PROCESSES);
2067*efd4c9b6SSteve Lawrence 
2068*efd4c9b6SSteve Lawrence 	if (g_resources & ZSTAT_RES_LWPS)
2069*efd4c9b6SSteve Lawrence 		zonestat_print_res(report_fmt, "LWPS", "SYSTEM LIMIT",
2070*efd4c9b6SSteve Lawrence 		    ZONESTAT_LWPS, ZONESTAT_NAME_SYSTEM_LIMIT, usage,
2071*efd4c9b6SSteve Lawrence 		    ZS_RESOURCE_LWPS, ZS_LIMIT_LWPS);
2072*efd4c9b6SSteve Lawrence 	if (g_resources & ZSTAT_RES_LOFI)
2073*efd4c9b6SSteve Lawrence 		zonestat_print_res(report_fmt, "LOFI", "SYSTEM LIMIT",
2074*efd4c9b6SSteve Lawrence 		    ZONESTAT_LOFI, ZONESTAT_NAME_SYSTEM_LIMIT,
2075*efd4c9b6SSteve Lawrence 		    usage, ZS_RESOURCE_LOFI, ZS_LIMIT_LOFI);
2076*efd4c9b6SSteve Lawrence 
2077*efd4c9b6SSteve Lawrence 	if (g_resources & ZSTAT_RES_SHM_MEMORY)
2078*efd4c9b6SSteve Lawrence 		zonestat_print_res(report_fmt, "SHM_MEMORY", "SYSTEM LIMIT",
2079*efd4c9b6SSteve Lawrence 		    ZONESTAT_SHM_MEMORY, ZONESTAT_NAME_SYSTEM_LIMIT,
2080*efd4c9b6SSteve Lawrence 		    usage, ZS_RESOURCE_SHM_MEMORY, ZS_LIMIT_SHM_MEMORY);
2081*efd4c9b6SSteve Lawrence 
2082*efd4c9b6SSteve Lawrence 	if (g_resources & ZSTAT_RES_SHM_IDS)
2083*efd4c9b6SSteve Lawrence 		zonestat_print_res(report_fmt, "SHM_IDS", "SYSTEM LIMIT",
2084*efd4c9b6SSteve Lawrence 		    ZONESTAT_SHM_IDS, ZONESTAT_NAME_SYSTEM_LIMIT,
2085*efd4c9b6SSteve Lawrence 		    usage, ZS_RESOURCE_SHM_IDS, ZS_LIMIT_SHM_IDS);
2086*efd4c9b6SSteve Lawrence 
2087*efd4c9b6SSteve Lawrence 	if (g_resources & ZSTAT_RES_SEM_IDS)
2088*efd4c9b6SSteve Lawrence 		zonestat_print_res(report_fmt, "SEM_IDS", "SYSTEM LIMIT",
2089*efd4c9b6SSteve Lawrence 		    ZONESTAT_SEM_IDS, ZONESTAT_NAME_SYSTEM_LIMIT,
2090*efd4c9b6SSteve Lawrence 		    usage, ZS_RESOURCE_SEM_IDS, ZS_LIMIT_SEM_IDS);
2091*efd4c9b6SSteve Lawrence 
2092*efd4c9b6SSteve Lawrence 	if (g_resources & ZSTAT_RES_MSG_IDS)
2093*efd4c9b6SSteve Lawrence 		zonestat_print_res(report_fmt, "MSG_IDS", "SYSTEM LIMIT",
2094*efd4c9b6SSteve Lawrence 		    ZONESTAT_MSG_IDS, ZONESTAT_NAME_SYSTEM_LIMIT,
2095*efd4c9b6SSteve Lawrence 		    usage, ZS_RESOURCE_MSG_IDS, ZS_LIMIT_MSG_IDS);
2096*efd4c9b6SSteve Lawrence }
2097*efd4c9b6SSteve Lawrence 
2098*efd4c9b6SSteve Lawrence /*
2099*efd4c9b6SSteve Lawrence  * Adds comma seperated list of names to array of names
2100*efd4c9b6SSteve Lawrence  * Returns new total number of names.
2101*efd4c9b6SSteve Lawrence  */
2102*efd4c9b6SSteve Lawrence static size_t
zonestat_parse_names(char * names,char *** namelist,size_t count)2103*efd4c9b6SSteve Lawrence zonestat_parse_names(char *names, char ***namelist, size_t count)
2104*efd4c9b6SSteve Lawrence {
2105*efd4c9b6SSteve Lawrence 	size_t num, i;
2106*efd4c9b6SSteve Lawrence 	char *next, *string;
2107*efd4c9b6SSteve Lawrence 
2108*efd4c9b6SSteve Lawrence 	string = strdup(names);
2109*efd4c9b6SSteve Lawrence 	if (string == NULL)
2110*efd4c9b6SSteve Lawrence 		exit(zonestat_error(gettext("Out of Memory")));
2111*efd4c9b6SSteve Lawrence 
2112*efd4c9b6SSteve Lawrence 	/* count names, delimiting with '\0'. */
2113*efd4c9b6SSteve Lawrence 	next = string;
2114*efd4c9b6SSteve Lawrence 	num = 1;
2115*efd4c9b6SSteve Lawrence 	while ((next = strchr(next, ',')) != NULL) {
2116*efd4c9b6SSteve Lawrence 		*next++ = '\0';
2117*efd4c9b6SSteve Lawrence 		num++;
2118*efd4c9b6SSteve Lawrence 	}
2119*efd4c9b6SSteve Lawrence 
2120*efd4c9b6SSteve Lawrence 	/* Resise names array */
2121*efd4c9b6SSteve Lawrence 	*namelist = realloc(*namelist, sizeof (char *) * (num + count));
2122*efd4c9b6SSteve Lawrence 	if (*namelist == NULL)
2123*efd4c9b6SSteve Lawrence 		exit(zonestat_error(gettext("Out of Memory")));
2124*efd4c9b6SSteve Lawrence 
2125*efd4c9b6SSteve Lawrence 	/* add names to names array */
2126*efd4c9b6SSteve Lawrence 	next = string;
2127*efd4c9b6SSteve Lawrence 	for (i = 0; i < num; i++) {
2128*efd4c9b6SSteve Lawrence 		(*namelist)[count + i] = next;
2129*efd4c9b6SSteve Lawrence 		next += strlen(next) + 1;
2130*efd4c9b6SSteve Lawrence 	}
2131*efd4c9b6SSteve Lawrence 	return (count + num);
2132*efd4c9b6SSteve Lawrence }
2133*efd4c9b6SSteve Lawrence 
2134*efd4c9b6SSteve Lawrence static int
zonestat_extract_int(char * start,char * end,char ** tail)2135*efd4c9b6SSteve Lawrence zonestat_extract_int(char *start, char *end, char **tail)
2136*efd4c9b6SSteve Lawrence {
2137*efd4c9b6SSteve Lawrence 	int val;
2138*efd4c9b6SSteve Lawrence 	int save;
2139*efd4c9b6SSteve Lawrence 
2140*efd4c9b6SSteve Lawrence 	save = *end;
2141*efd4c9b6SSteve Lawrence 	*end = '\0';
2142*efd4c9b6SSteve Lawrence 	errno = 0;
2143*efd4c9b6SSteve Lawrence 	val = strtol(start, tail, 0);
2144*efd4c9b6SSteve Lawrence 	*end = save;
2145*efd4c9b6SSteve Lawrence 	if (errno != 0 || *tail == start)
2146*efd4c9b6SSteve Lawrence 		return (-1);
2147*efd4c9b6SSteve Lawrence 
2148*efd4c9b6SSteve Lawrence 	return (val);
2149*efd4c9b6SSteve Lawrence }
2150*efd4c9b6SSteve Lawrence 
2151*efd4c9b6SSteve Lawrence /*
2152*efd4c9b6SSteve Lawrence  * parses and [nh][nm][hs] notation into seconds
2153*efd4c9b6SSteve Lawrence  */
2154*efd4c9b6SSteve Lawrence static int
zonestat_parse_time(char * string,boolean_t * formatted)2155*efd4c9b6SSteve Lawrence zonestat_parse_time(char *string, boolean_t *formatted)
2156*efd4c9b6SSteve Lawrence {
2157*efd4c9b6SSteve Lawrence 	int seconds = 0;
2158*efd4c9b6SSteve Lawrence 	int minutes = 0;
2159*efd4c9b6SSteve Lawrence 	int hours = 0;
2160*efd4c9b6SSteve Lawrence 	char *this, *next, *end;
2161*efd4c9b6SSteve Lawrence 
2162*efd4c9b6SSteve Lawrence 	*formatted = B_FALSE;
2163*efd4c9b6SSteve Lawrence 
2164*efd4c9b6SSteve Lawrence 	/* Look for special tokens */
2165*efd4c9b6SSteve Lawrence 	if (strcmp("default", string) == 0)
2166*efd4c9b6SSteve Lawrence 		return (ZSTAT_INTERVAL_DEFAULT);
2167*efd4c9b6SSteve Lawrence 
2168*efd4c9b6SSteve Lawrence 	if (strcmp("inf", string) == 0)
2169*efd4c9b6SSteve Lawrence 		return (ZSTAT_DURATION_INF);
2170*efd4c9b6SSteve Lawrence 
2171*efd4c9b6SSteve Lawrence 	/* Look for hours */
2172*efd4c9b6SSteve Lawrence 	this = string;
2173*efd4c9b6SSteve Lawrence 	next = strchr(this, 'h');
2174*efd4c9b6SSteve Lawrence 	if (next != NULL) {
2175*efd4c9b6SSteve Lawrence 		if ((hours = zonestat_extract_int(this, next, &end)) == -1)
2176*efd4c9b6SSteve Lawrence 			return (-1);
2177*efd4c9b6SSteve Lawrence 
2178*efd4c9b6SSteve Lawrence 		*formatted = B_TRUE;
2179*efd4c9b6SSteve Lawrence 		this = next + 1;
2180*efd4c9b6SSteve Lawrence 		end++;
2181*efd4c9b6SSteve Lawrence 	}
2182*efd4c9b6SSteve Lawrence 
2183*efd4c9b6SSteve Lawrence 	/* Look for minutes delimiter */
2184*efd4c9b6SSteve Lawrence 	next = strrchr(this, 'm');
2185*efd4c9b6SSteve Lawrence 	if (next != NULL) {
2186*efd4c9b6SSteve Lawrence 		if ((minutes = zonestat_extract_int(this, next, &end)) == -1)
2187*efd4c9b6SSteve Lawrence 			return (-1);
2188*efd4c9b6SSteve Lawrence 
2189*efd4c9b6SSteve Lawrence 		*formatted = B_TRUE;
2190*efd4c9b6SSteve Lawrence 		this = next + 1;
2191*efd4c9b6SSteve Lawrence 		end++;
2192*efd4c9b6SSteve Lawrence 	}
2193*efd4c9b6SSteve Lawrence 
2194*efd4c9b6SSteve Lawrence 	/* Look for seconds delimiter */
2195*efd4c9b6SSteve Lawrence 	next = strrchr(this, 's');
2196*efd4c9b6SSteve Lawrence 	if (next != NULL) {
2197*efd4c9b6SSteve Lawrence 		if ((seconds = zonestat_extract_int(this, next, &end)) == -1)
2198*efd4c9b6SSteve Lawrence 			return (-1);
2199*efd4c9b6SSteve Lawrence 
2200*efd4c9b6SSteve Lawrence 		*formatted = B_TRUE;
2201*efd4c9b6SSteve Lawrence 		this = next + 1;
2202*efd4c9b6SSteve Lawrence 		end++;
2203*efd4c9b6SSteve Lawrence 	}
2204*efd4c9b6SSteve Lawrence 
2205*efd4c9b6SSteve Lawrence 	/* No delimiter found.  Treat as seconds */
2206*efd4c9b6SSteve Lawrence 	if (*formatted == B_FALSE) {
2207*efd4c9b6SSteve Lawrence 		errno = 0;
2208*efd4c9b6SSteve Lawrence 		seconds = strtol(this, &end, 0);
2209*efd4c9b6SSteve Lawrence 		if (errno != 0 || end == this)
2210*efd4c9b6SSteve Lawrence 			return (-1);
2211*efd4c9b6SSteve Lawrence 	}
2212*efd4c9b6SSteve Lawrence 
2213*efd4c9b6SSteve Lawrence 	if (*end != '\0')
2214*efd4c9b6SSteve Lawrence 		return (-1);
2215*efd4c9b6SSteve Lawrence 
2216*efd4c9b6SSteve Lawrence 	seconds += (minutes * 60);
2217*efd4c9b6SSteve Lawrence 	seconds += (hours * 60 * 60);
2218*efd4c9b6SSteve Lawrence 
2219*efd4c9b6SSteve Lawrence 	return (seconds);
2220*efd4c9b6SSteve Lawrence }
2221*efd4c9b6SSteve Lawrence 
2222*efd4c9b6SSteve Lawrence static void
zonestat_print_reports(zs_usage_set_t * set)2223*efd4c9b6SSteve Lawrence zonestat_print_reports(zs_usage_set_t *set)
2224*efd4c9b6SSteve Lawrence {
2225*efd4c9b6SSteve Lawrence 	zs_usage_t *usage_print;
2226*efd4c9b6SSteve Lawrence 
2227*efd4c9b6SSteve Lawrence 	if (opt_report_total == B_TRUE) {
2228*efd4c9b6SSteve Lawrence 		usage_print = zs_usage_set_compute(set,
2229*efd4c9b6SSteve Lawrence 		    ZS_COMPUTE_SET_TOTAL);
2230*efd4c9b6SSteve Lawrence 		zonestat_print_header(ZSTAT_REPORT_FMT_TOTAL);
2231*efd4c9b6SSteve Lawrence 		zonestat_print_resources(ZSTAT_REPORT_FMT_TOTAL, usage_print);
2232*efd4c9b6SSteve Lawrence 		zonestat_print_footer(ZSTAT_REPORT_FMT_TOTAL);
2233*efd4c9b6SSteve Lawrence 		(void) fflush(stdout);
2234*efd4c9b6SSteve Lawrence 	}
2235*efd4c9b6SSteve Lawrence 	if (opt_report_average == B_TRUE) {
2236*efd4c9b6SSteve Lawrence 		usage_print = zs_usage_set_compute(set,
2237*efd4c9b6SSteve Lawrence 		    ZS_COMPUTE_SET_AVERAGE);
2238*efd4c9b6SSteve Lawrence 		zonestat_print_header(ZSTAT_REPORT_FMT_AVERAGE);
2239*efd4c9b6SSteve Lawrence 		zonestat_print_resources(ZSTAT_REPORT_FMT_AVERAGE, usage_print);
2240*efd4c9b6SSteve Lawrence 		zonestat_print_footer(ZSTAT_REPORT_FMT_AVERAGE);
2241*efd4c9b6SSteve Lawrence 		(void) fflush(stdout);
2242*efd4c9b6SSteve Lawrence 	}
2243*efd4c9b6SSteve Lawrence 	if (opt_report_high == B_TRUE) {
2244*efd4c9b6SSteve Lawrence 		usage_print = zs_usage_set_compute(set,
2245*efd4c9b6SSteve Lawrence 		    ZS_COMPUTE_SET_HIGH);
2246*efd4c9b6SSteve Lawrence 		zonestat_print_header(ZSTAT_REPORT_FMT_HIGH);
2247*efd4c9b6SSteve Lawrence 		zonestat_print_resources(ZSTAT_REPORT_FMT_HIGH, usage_print);
2248*efd4c9b6SSteve Lawrence 		zonestat_print_footer(ZSTAT_REPORT_FMT_HIGH);
2249*efd4c9b6SSteve Lawrence 		(void) fflush(stdout);
2250*efd4c9b6SSteve Lawrence 	}
2251*efd4c9b6SSteve Lawrence }
2252*efd4c9b6SSteve Lawrence 
2253*efd4c9b6SSteve Lawrence static void
zonestat_set_fx()2254*efd4c9b6SSteve Lawrence zonestat_set_fx()
2255*efd4c9b6SSteve Lawrence {
2256*efd4c9b6SSteve Lawrence 	pcinfo_t pcinfo;
2257*efd4c9b6SSteve Lawrence 	pcparms_t pcparms;
2258*efd4c9b6SSteve Lawrence 
2259*efd4c9b6SSteve Lawrence 	(void) strlcpy(pcinfo.pc_clname, "FX", sizeof (pcinfo.pc_clname));
2260*efd4c9b6SSteve Lawrence 	if (priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo) == -1) {
2261*efd4c9b6SSteve Lawrence 		return;
2262*efd4c9b6SSteve Lawrence 	}
2263*efd4c9b6SSteve Lawrence 	pcparms.pc_cid = pcinfo.pc_cid;
2264*efd4c9b6SSteve Lawrence 	((fxparms_t *)pcparms.pc_clparms)->fx_upri = 60;
2265*efd4c9b6SSteve Lawrence 	((fxparms_t *)pcparms.pc_clparms)->fx_uprilim = 60;
2266*efd4c9b6SSteve Lawrence 	((fxparms_t *)pcparms.pc_clparms)->fx_tqsecs = 0;
2267*efd4c9b6SSteve Lawrence 	((fxparms_t *)pcparms.pc_clparms)->fx_tqnsecs = FX_NOCHANGE;
2268*efd4c9b6SSteve Lawrence 	(void) priocntl(P_PID, getpid(), PC_SETPARMS, (caddr_t)&pcparms);
2269*efd4c9b6SSteve Lawrence }
2270*efd4c9b6SSteve Lawrence 
2271*efd4c9b6SSteve Lawrence static time_t
zonestat_time()2272*efd4c9b6SSteve Lawrence zonestat_time()
2273*efd4c9b6SSteve Lawrence {
2274*efd4c9b6SSteve Lawrence 	time_t t;
2275*efd4c9b6SSteve Lawrence 
2276*efd4c9b6SSteve Lawrence 	t = time(NULL);
2277*efd4c9b6SSteve Lawrence 	if (t < 0 && g_quit == B_FALSE)
2278*efd4c9b6SSteve Lawrence 		exit(zonestat_error(gettext(
2279*efd4c9b6SSteve Lawrence 		    "Unable to fetch current time")));
2280*efd4c9b6SSteve Lawrence 
2281*efd4c9b6SSteve Lawrence 	return (t);
2282*efd4c9b6SSteve Lawrence }
2283*efd4c9b6SSteve Lawrence 
2284*efd4c9b6SSteve Lawrence int
main(int argc,char * argv[])2285*efd4c9b6SSteve Lawrence main(int argc, char *argv[])
2286*efd4c9b6SSteve Lawrence {
2287*efd4c9b6SSteve Lawrence 	int arg;
2288*efd4c9b6SSteve Lawrence 	time_t now, next, start, next_report;
2289*efd4c9b6SSteve Lawrence 	zs_usage_t *usage, *usage_last = NULL, *usage_print;
2290*efd4c9b6SSteve Lawrence 	zs_usage_set_t *set;
2291*efd4c9b6SSteve Lawrence 	boolean_t formatted;
2292*efd4c9b6SSteve Lawrence 	scf_simple_prop_t *prop;
2293*efd4c9b6SSteve Lawrence 	uint64_t *intervalp;
2294*efd4c9b6SSteve Lawrence 	char *not_responding;
2295*efd4c9b6SSteve Lawrence 
2296*efd4c9b6SSteve Lawrence 	/* Process command line options and args */
2297*efd4c9b6SSteve Lawrence 	while ((arg = getopt(argc, argv, "z:r:n:T:R:qpP:S:D?"))
2298*efd4c9b6SSteve Lawrence 	    != EOF) {
2299*efd4c9b6SSteve Lawrence 		switch (arg) {
2300*efd4c9b6SSteve Lawrence 		case 'z':
2301*efd4c9b6SSteve Lawrence 			opt_zonenames = B_TRUE;
2302*efd4c9b6SSteve Lawrence 			arg_zonename_count = zonestat_parse_names(optarg,
2303*efd4c9b6SSteve Lawrence 			    &arg_zonenames, arg_zonename_count);
2304*efd4c9b6SSteve Lawrence 			break;
2305*efd4c9b6SSteve Lawrence 		case 'r':
2306*efd4c9b6SSteve Lawrence 			arg_restype_count = zonestat_parse_names(optarg,
2307*efd4c9b6SSteve Lawrence 			    &arg_restypes, arg_restype_count);
2308*efd4c9b6SSteve Lawrence 			opt_restypes = B_TRUE;
2309*efd4c9b6SSteve Lawrence 			break;
2310*efd4c9b6SSteve Lawrence 		case 'n':
2311*efd4c9b6SSteve Lawrence 			opt_resnames = B_TRUE;
2312*efd4c9b6SSteve Lawrence 			arg_resname_count = zonestat_parse_names(optarg,
2313*efd4c9b6SSteve Lawrence 			    &arg_resnames, arg_resname_count);
2314*efd4c9b6SSteve Lawrence 			break;
2315*efd4c9b6SSteve Lawrence 		case 'R':
2316*efd4c9b6SSteve Lawrence 			opt_report = B_TRUE;
2317*efd4c9b6SSteve Lawrence 			arg_report_count = zonestat_parse_names(optarg,
2318*efd4c9b6SSteve Lawrence 			    &arg_reports, arg_report_count);
2319*efd4c9b6SSteve Lawrence 			break;
2320*efd4c9b6SSteve Lawrence 		case 'S':
2321*efd4c9b6SSteve Lawrence 			opt_sort = B_TRUE;
2322*efd4c9b6SSteve Lawrence 			arg_sort_count = zonestat_parse_names(optarg,
2323*efd4c9b6SSteve Lawrence 			    &arg_sort_list, arg_sort_count);
2324*efd4c9b6SSteve Lawrence 			break;
2325*efd4c9b6SSteve Lawrence 		case 'T':
2326*efd4c9b6SSteve Lawrence 			opt_timestamp = B_TRUE;
2327*efd4c9b6SSteve Lawrence 			if (strcmp(optarg, "u") == 0) {
2328*efd4c9b6SSteve Lawrence 				arg_timestamp = ZSTAT_UNIX_TIMESTAMP;
2329*efd4c9b6SSteve Lawrence 			} else if (strcmp(optarg, "d") == 0) {
2330*efd4c9b6SSteve Lawrence 				arg_timestamp = ZSTAT_DATE_TIMESTAMP;
2331*efd4c9b6SSteve Lawrence 			} else if (strcmp(optarg, "i") == 0) {
2332*efd4c9b6SSteve Lawrence 				arg_timestamp = ZSTAT_ISO_TIMESTAMP;
2333*efd4c9b6SSteve Lawrence 			} else {
2334*efd4c9b6SSteve Lawrence 				(void) zonestat_error(gettext(
2335*efd4c9b6SSteve Lawrence 				    "Invalid -T arg \"%s\". "
2336*efd4c9b6SSteve Lawrence 				    "Must be 'u', 'i', or 'd'."), optarg);
2337*efd4c9b6SSteve Lawrence 				return (zonestat_usage(B_FALSE));
2338*efd4c9b6SSteve Lawrence 			}
2339*efd4c9b6SSteve Lawrence 			break;
2340*efd4c9b6SSteve Lawrence 		case 'q':
2341*efd4c9b6SSteve Lawrence 			opt_quiet_intervals = B_TRUE;
2342*efd4c9b6SSteve Lawrence 			break;
2343*efd4c9b6SSteve Lawrence 		case 'p':
2344*efd4c9b6SSteve Lawrence 			opt_parseable = B_TRUE;
2345*efd4c9b6SSteve Lawrence 			break;
2346*efd4c9b6SSteve Lawrence 		case 'P':
2347*efd4c9b6SSteve Lawrence 			opt_line_any = B_TRUE;
2348*efd4c9b6SSteve Lawrence 			arg_line_count = zonestat_parse_names(optarg,
2349*efd4c9b6SSteve Lawrence 			    &arg_line_list, arg_line_count);
2350*efd4c9b6SSteve Lawrence 			break;
2351*efd4c9b6SSteve Lawrence 		case 'D':
2352*efd4c9b6SSteve Lawrence 			opt_debug = B_TRUE;
2353*efd4c9b6SSteve Lawrence 			break;
2354*efd4c9b6SSteve Lawrence 		case '?':
2355*efd4c9b6SSteve Lawrence 			return (zonestat_usage(B_TRUE));
2356*efd4c9b6SSteve Lawrence 		default:
2357*efd4c9b6SSteve Lawrence 			return (zonestat_usage(B_FALSE));
2358*efd4c9b6SSteve Lawrence 		}
2359*efd4c9b6SSteve Lawrence 	}
2360*efd4c9b6SSteve Lawrence 
2361*efd4c9b6SSteve Lawrence 	if (opt_line_any & (!opt_parseable)) {
2362*efd4c9b6SSteve Lawrence 		(void) zonestat_error(gettext("-P requires -p"));
2363*efd4c9b6SSteve Lawrence 		return (zonestat_usage(B_FALSE));
2364*efd4c9b6SSteve Lawrence 	}
2365*efd4c9b6SSteve Lawrence 
2366*efd4c9b6SSteve Lawrence 	if (opt_timestamp && arg_timestamp == ZSTAT_DATE_TIMESTAMP &&
2367*efd4c9b6SSteve Lawrence 	    opt_parseable) {
2368*efd4c9b6SSteve Lawrence 		(void) zonestat_error(gettext(
2369*efd4c9b6SSteve Lawrence 		    "-T d invalid with -p.  Use -T [u | i]"));
2370*efd4c9b6SSteve Lawrence 		return (zonestat_usage(B_FALSE));
2371*efd4c9b6SSteve Lawrence 
2372*efd4c9b6SSteve Lawrence 	}
2373*efd4c9b6SSteve Lawrence 	/* Default to ISO timetamp in parseable output */
2374*efd4c9b6SSteve Lawrence 	if (!opt_timestamp && opt_parseable)
2375*efd4c9b6SSteve Lawrence 		arg_timestamp = ZSTAT_ISO_TIMESTAMP;
2376*efd4c9b6SSteve Lawrence 
2377*efd4c9b6SSteve Lawrence 	/* Get the interval and count */
2378*efd4c9b6SSteve Lawrence 	optind++;
2379*efd4c9b6SSteve Lawrence 	if (argc >= optind) {
2380*efd4c9b6SSteve Lawrence 		if ((arg_interval = zonestat_parse_time(argv[optind - 1],
2381*efd4c9b6SSteve Lawrence 		    &formatted)) < 0 || arg_interval == 0)  {
2382*efd4c9b6SSteve Lawrence 			(void) zonestat_error(gettext(
2383*efd4c9b6SSteve Lawrence 			    "Invalid interval: \"%s\""), argv[optind - 1]);
2384*efd4c9b6SSteve Lawrence 			return (zonestat_usage(B_FALSE));
2385*efd4c9b6SSteve Lawrence 		}
2386*efd4c9b6SSteve Lawrence 	} else {
2387*efd4c9b6SSteve Lawrence 		(void) zonestat_error(gettext("Interval required."));
2388*efd4c9b6SSteve Lawrence 		return (zonestat_usage(B_FALSE));
2389*efd4c9b6SSteve Lawrence 	}
2390*efd4c9b6SSteve Lawrence 
2391*efd4c9b6SSteve Lawrence 	if (arg_interval == ZSTAT_INTERVAL_DEFAULT) {
2392*efd4c9b6SSteve Lawrence 		/* Get the configured sample interval */
2393*efd4c9b6SSteve Lawrence 		prop = scf_simple_prop_get(NULL,
2394*efd4c9b6SSteve Lawrence 		    "svc:/system/zones-monitoring:default", "config",
2395*efd4c9b6SSteve Lawrence 		    "sample_interval");
2396*efd4c9b6SSteve Lawrence 
2397*efd4c9b6SSteve Lawrence 		if (prop == NULL) {
2398*efd4c9b6SSteve Lawrence 			return (zonestat_error(gettext(
2399*efd4c9b6SSteve Lawrence 			    "Unable to fetch SMF property "
2400*efd4c9b6SSteve Lawrence 			    "\"config/sample_interval\"")));
2401*efd4c9b6SSteve Lawrence 	}
2402*efd4c9b6SSteve Lawrence 		if (scf_simple_prop_type(prop) != SCF_TYPE_COUNT) {
2403*efd4c9b6SSteve Lawrence 			return (zonestat_error(gettext("Malformed SMF property "
2404*efd4c9b6SSteve Lawrence 			    "\"config/sample_interval\".  Must be of type "
2405*efd4c9b6SSteve Lawrence 			    "\"count\"")));
2406*efd4c9b6SSteve Lawrence 	}
2407*efd4c9b6SSteve Lawrence 		intervalp = scf_simple_prop_next_count(prop);
2408*efd4c9b6SSteve Lawrence 		arg_interval = *intervalp;
2409*efd4c9b6SSteve Lawrence 		if (arg_interval == 0)
2410*efd4c9b6SSteve Lawrence 			return (zonestat_error(gettext("Malformed SMF property "
2411*efd4c9b6SSteve Lawrence 			    "\"config/sample_interval\".  Must be greater than"
2412*efd4c9b6SSteve Lawrence 			    "zero")));
2413*efd4c9b6SSteve Lawrence 
2414*efd4c9b6SSteve Lawrence 		scf_simple_prop_free(prop);
2415*efd4c9b6SSteve Lawrence 	}
2416*efd4c9b6SSteve Lawrence 	optind++;
2417*efd4c9b6SSteve Lawrence 	if (argc >= optind) {
2418*efd4c9b6SSteve Lawrence 		if ((arg_duration = zonestat_parse_time(argv[optind - 1],
2419*efd4c9b6SSteve Lawrence 		    &formatted)) < 0 || arg_duration == 0)  {
2420*efd4c9b6SSteve Lawrence 			(void) zonestat_error(gettext(
2421*efd4c9b6SSteve Lawrence 			    "Invalid duration: \"%s\""), argv[optind - 1]);
2422*efd4c9b6SSteve Lawrence 			return (zonestat_usage(B_FALSE));
2423*efd4c9b6SSteve Lawrence 		}
2424*efd4c9b6SSteve Lawrence 		/* If not formatted [nh][nm][ns], treat as count */
2425*efd4c9b6SSteve Lawrence 		if (arg_duration != ZSTAT_DURATION_INF &&
2426*efd4c9b6SSteve Lawrence 		    formatted == B_FALSE)
2427*efd4c9b6SSteve Lawrence 			arg_duration *= arg_interval;
2428*efd4c9b6SSteve Lawrence 	} else {
2429*efd4c9b6SSteve Lawrence 		arg_duration = ZSTAT_DURATION_INF;
2430*efd4c9b6SSteve Lawrence 	}
2431*efd4c9b6SSteve Lawrence 	optind++;
2432*efd4c9b6SSteve Lawrence 	if (argc >= optind) {
2433*efd4c9b6SSteve Lawrence 		if ((arg_report = zonestat_parse_time(argv[optind - 1],
2434*efd4c9b6SSteve Lawrence 		    &formatted)) < 0 || arg_report == 0)  {
2435*efd4c9b6SSteve Lawrence 			(void) zonestat_error(gettext(
2436*efd4c9b6SSteve Lawrence 			    "Invalid report period: \"%s\""), argv[optind - 1]);
2437*efd4c9b6SSteve Lawrence 			return (zonestat_usage(B_FALSE));
2438*efd4c9b6SSteve Lawrence 		}
2439*efd4c9b6SSteve Lawrence 		/* If not formatted as [nh][nm][ns] treat as count */
2440*efd4c9b6SSteve Lawrence 		if (formatted == B_FALSE)
2441*efd4c9b6SSteve Lawrence 			arg_report *= arg_interval;
2442*efd4c9b6SSteve Lawrence 	} else {
2443*efd4c9b6SSteve Lawrence 		arg_report = ZSTAT_REPORT_END;
2444*efd4c9b6SSteve Lawrence 	}
2445*efd4c9b6SSteve Lawrence 
2446*efd4c9b6SSteve Lawrence 	if (opt_quiet_intervals && (!opt_report)) {
2447*efd4c9b6SSteve Lawrence 		(void) zonestat_error(gettext("-q requires -R"));
2448*efd4c9b6SSteve Lawrence 		return (zonestat_usage(B_FALSE));
2449*efd4c9b6SSteve Lawrence 	}
2450*efd4c9b6SSteve Lawrence 
2451*efd4c9b6SSteve Lawrence 	/* Figure out what resources to report on */
2452*efd4c9b6SSteve Lawrence 	zonestat_determine_resources();
2453*efd4c9b6SSteve Lawrence 	zonestat_determine_reports();
2454*efd4c9b6SSteve Lawrence 	zonestat_determine_lines();
2455*efd4c9b6SSteve Lawrence 	zonestat_determine_sort();
2456*efd4c9b6SSteve Lawrence 
2457*efd4c9b6SSteve Lawrence 	/* Done parsing args beyond this point */
2458*efd4c9b6SSteve Lawrence 
2459*efd4c9b6SSteve Lawrence 	(void) signal(SIGINT, zonestat_quithandler);
2460*efd4c9b6SSteve Lawrence 	(void) signal(SIGTERM, zonestat_quithandler);
2461*efd4c9b6SSteve Lawrence 	(void) signal(SIGHUP, zonestat_quithandler);
2462*efd4c9b6SSteve Lawrence 
2463*efd4c9b6SSteve Lawrence 	/* Run at high priority to keep up with busy system */
2464*efd4c9b6SSteve Lawrence 	zonestat_set_fx();
2465*efd4c9b6SSteve Lawrence 
2466*efd4c9b6SSteve Lawrence 	not_responding = gettext(
2467*efd4c9b6SSteve Lawrence 	    "Zones monitoring service \"svc:/system/zones-monitoring:default\" "
2468*efd4c9b6SSteve Lawrence 	    "not enabled or responding.");
2469*efd4c9b6SSteve Lawrence 
2470*efd4c9b6SSteve Lawrence 	/* Open zone statistics */
2471*efd4c9b6SSteve Lawrence 	g_zsctl = zs_open();
2472*efd4c9b6SSteve Lawrence 	if (g_zsctl == NULL) {
2473*efd4c9b6SSteve Lawrence 		if (errno == EPERM)
2474*efd4c9b6SSteve Lawrence 			return (zonestat_error(gettext("Permission denied")));
2475*efd4c9b6SSteve Lawrence 		if (errno == EINTR || errno == ESRCH) {
2476*efd4c9b6SSteve Lawrence 			(void) zonestat_error(not_responding);
2477*efd4c9b6SSteve Lawrence 			return (3);
2478*efd4c9b6SSteve Lawrence 		}
2479*efd4c9b6SSteve Lawrence 		if (errno == ENOTSUP)
2480*efd4c9b6SSteve Lawrence 			return (zonestat_error(gettext(
2481*efd4c9b6SSteve Lawrence 			    "Mismatched zonestat version. "
2482*efd4c9b6SSteve Lawrence 			    "Re-install system/zones package.")));
2483*efd4c9b6SSteve Lawrence 
2484*efd4c9b6SSteve Lawrence 		return (zonestat_error(gettext(
2485*efd4c9b6SSteve Lawrence 		    "Unexpected error.  Unable to open zone statistics.")));
2486*efd4c9b6SSteve Lawrence 	}
2487*efd4c9b6SSteve Lawrence 	usage_last = zs_usage_read(g_zsctl);
2488*efd4c9b6SSteve Lawrence 	if (usage_last == NULL) {
2489*efd4c9b6SSteve Lawrence 		if (errno == EINTR && g_quit == B_TRUE)
2490*efd4c9b6SSteve Lawrence 			return (0);
2491*efd4c9b6SSteve Lawrence 		(void) zonestat_error(not_responding);
2492*efd4c9b6SSteve Lawrence 		return (3);
2493*efd4c9b6SSteve Lawrence 	}
2494*efd4c9b6SSteve Lawrence 	set = zs_usage_set_alloc(g_zsctl);
2495*efd4c9b6SSteve Lawrence 
2496*efd4c9b6SSteve Lawrence 	g_start_time = g_now_time = start = now = zonestat_time();
2497*efd4c9b6SSteve Lawrence 	g_interval = arg_interval;
2498*efd4c9b6SSteve Lawrence 	g_report_count = g_count = g_seconds = 0;
2499*efd4c9b6SSteve Lawrence 
2500*efd4c9b6SSteve Lawrence 	if (opt_quiet_intervals == B_FALSE && opt_parseable == B_FALSE)
2501*efd4c9b6SSteve Lawrence 		(void) printf(gettext(
2502*efd4c9b6SSteve Lawrence 		    "Collecting data for first interval...\n"));
2503*efd4c9b6SSteve Lawrence 
2504*efd4c9b6SSteve Lawrence 	for (;;) {
2505*efd4c9b6SSteve Lawrence 		time_t tosleep;
2506*efd4c9b6SSteve Lawrence 
2507*efd4c9b6SSteve Lawrence 		g_now_time = now = zonestat_time();
2508*efd4c9b6SSteve Lawrence 
2509*efd4c9b6SSteve Lawrence 		if (arg_report != ZSTAT_REPORT_END)
2510*efd4c9b6SSteve Lawrence 			next_report = start + ((g_report_count + 1) *
2511*efd4c9b6SSteve Lawrence 			    arg_report);
2512*efd4c9b6SSteve Lawrence 
2513*efd4c9b6SSteve Lawrence 		/*
2514*efd4c9b6SSteve Lawrence 		 * Sleep till next interval.
2515*efd4c9b6SSteve Lawrence 		 */
2516*efd4c9b6SSteve Lawrence 		g_count++;
2517*efd4c9b6SSteve Lawrence 		next = g_start_time + (g_count) * g_interval;
2518*efd4c9b6SSteve Lawrence 		/*
2519*efd4c9b6SSteve Lawrence 		 * Skip to next interval if due to busy system, zonestat did
2520*efd4c9b6SSteve Lawrence 		 * not complete in time.
2521*efd4c9b6SSteve Lawrence 		 */
2522*efd4c9b6SSteve Lawrence 		while (now >= g_start_time + ((g_count + 1) * g_interval))
2523*efd4c9b6SSteve Lawrence 			g_count++;
2524*efd4c9b6SSteve Lawrence 
2525*efd4c9b6SSteve Lawrence 		while (now < next) {
2526*efd4c9b6SSteve Lawrence 			/* Sleep until at next interval */
2527*efd4c9b6SSteve Lawrence 			tosleep = next - now;
2528*efd4c9b6SSteve Lawrence 			(void) sleep(tosleep);
2529*efd4c9b6SSteve Lawrence 			now = zonestat_time();
2530*efd4c9b6SSteve Lawrence 			if (g_quit == B_TRUE)
2531*efd4c9b6SSteve Lawrence 				goto interval_loop_done;
2532*efd4c9b6SSteve Lawrence 		}
2533*efd4c9b6SSteve Lawrence 
2534*efd4c9b6SSteve Lawrence 		g_seconds = now - start;
2535*efd4c9b6SSteve Lawrence 		g_now_time = now;
2536*efd4c9b6SSteve Lawrence 		if ((usage = zs_usage_read(g_zsctl)) == NULL) {
2537*efd4c9b6SSteve Lawrence 			if (errno == EINTR && g_quit == B_TRUE)
2538*efd4c9b6SSteve Lawrence 				break;
2539*efd4c9b6SSteve Lawrence 			(void) zonestat_error(not_responding);
2540*efd4c9b6SSteve Lawrence 			return (3);
2541*efd4c9b6SSteve Lawrence 		}
2542*efd4c9b6SSteve Lawrence 
2543*efd4c9b6SSteve Lawrence 		/* Compute cpu used since last interval */
2544*efd4c9b6SSteve Lawrence 		usage_print = zs_usage_compute(NULL, usage_last,
2545*efd4c9b6SSteve Lawrence 		    usage, ZS_COMPUTE_USAGE_INTERVAL);
2546*efd4c9b6SSteve Lawrence 		if (usage_print == NULL)
2547*efd4c9b6SSteve Lawrence 			(void) zonestat_error(gettext("Out of Memory"));
2548*efd4c9b6SSteve Lawrence 
2549*efd4c9b6SSteve Lawrence 
2550*efd4c9b6SSteve Lawrence 		if (opt_quiet_intervals == B_TRUE)
2551*efd4c9b6SSteve Lawrence 			goto interval_print_end;
2552*efd4c9b6SSteve Lawrence 
2553*efd4c9b6SSteve Lawrence 		zonestat_print_header(ZSTAT_REPORT_FMT_INTERVAL);
2554*efd4c9b6SSteve Lawrence 		zonestat_print_resources(ZSTAT_REPORT_FMT_INTERVAL,
2555*efd4c9b6SSteve Lawrence 		    usage_print);
2556*efd4c9b6SSteve Lawrence 		zonestat_print_footer(ZSTAT_REPORT_FMT_INTERVAL);
2557*efd4c9b6SSteve Lawrence 		(void) fflush(stdout);
2558*efd4c9b6SSteve Lawrence 
2559*efd4c9b6SSteve Lawrence interval_print_end:
2560*efd4c9b6SSteve Lawrence 		(void) zs_usage_set_add(set, usage_print);
2561*efd4c9b6SSteve Lawrence 
2562*efd4c9b6SSteve Lawrence 
2563*efd4c9b6SSteve Lawrence 		/* Print reports if they are due */
2564*efd4c9b6SSteve Lawrence 		if (opt_report && arg_report != ZSTAT_REPORT_END &&
2565*efd4c9b6SSteve Lawrence 		    now >= next_report) {
2566*efd4c9b6SSteve Lawrence 			g_end_time  = now;
2567*efd4c9b6SSteve Lawrence 			zonestat_print_reports(set);
2568*efd4c9b6SSteve Lawrence 			zs_usage_set_free(set);
2569*efd4c9b6SSteve Lawrence 			set = zs_usage_set_alloc();
2570*efd4c9b6SSteve Lawrence 			g_start_time = now;
2571*efd4c9b6SSteve Lawrence 			g_report_count++;
2572*efd4c9b6SSteve Lawrence 		}
2573*efd4c9b6SSteve Lawrence 		zs_usage_free(usage_last);
2574*efd4c9b6SSteve Lawrence 		usage_last = usage;
2575*efd4c9b6SSteve Lawrence 		if (arg_duration != ZSTAT_DURATION_INF &&
2576*efd4c9b6SSteve Lawrence 		    g_seconds >= arg_duration)
2577*efd4c9b6SSteve Lawrence 			break;
2578*efd4c9b6SSteve Lawrence 	}
2579*efd4c9b6SSteve Lawrence interval_loop_done:
2580*efd4c9b6SSteve Lawrence 
2581*efd4c9b6SSteve Lawrence 	/* Print last reports if due */
2582*efd4c9b6SSteve Lawrence 	g_end_time = g_now_time;
2583*efd4c9b6SSteve Lawrence 	if (opt_report && zs_usage_set_count(set) > 0 &&
2584*efd4c9b6SSteve Lawrence 	    (arg_report == ZSTAT_REPORT_END || now < next_report))
2585*efd4c9b6SSteve Lawrence 		zonestat_print_reports(set);
2586*efd4c9b6SSteve Lawrence 
2587*efd4c9b6SSteve Lawrence 	zs_usage_set_free(set);
2588*efd4c9b6SSteve Lawrence 	if (usage_last != NULL)
2589*efd4c9b6SSteve Lawrence 		zs_usage_free(usage_last);
2590*efd4c9b6SSteve Lawrence 
2591*efd4c9b6SSteve Lawrence 	if (g_zsctl != NULL)
2592*efd4c9b6SSteve Lawrence 		zs_close(g_zsctl);
2593*efd4c9b6SSteve Lawrence 
2594*efd4c9b6SSteve Lawrence 	return (0);
2595*efd4c9b6SSteve Lawrence }
2596