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