zonestat.c revision efd4c9b63ad77503c101fc6c2ed8ba96c9d52964
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
*/
#include <alloca.h>
#include <assert.h>
#include <errno.h>
#include <langinfo.h>
#include <libintl.h>
#include <libscf.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/fxpriocntl.h>
#include <sys/priocntl.h>
#include <time.h>
#include <unistd.h>
#include <zonestat.h>
extern char *optarg;
#define ZSTAT_OK 0
#define ZSTAT_ERROR 1
#define ZSTAT_USAGE 2
#define ZSTAT_UNIX_TIMESTAMP 1
#define ZSTAT_ISO_TIMESTAMP 2
#define ZSTAT_DATE_TIMESTAMP 3
#define ZSTAT_RES_PHYSICAL_MEMORY 0x1
#define ZSTAT_RES_VIRTUAL_MEMORY 0x2
#define ZSTAT_RES_LOCKED_MEMORY 0x4
#define ZSTAT_RES_MEMORY 0x7
#define ZSTAT_RES_DEFAULT_PSET 0x10
#define ZSTAT_RES_PSETS 0x20
#define ZSTAT_RES_SUMMARY 0x40
#define ZSTAT_RES_PROCESSES 0x100
#define ZSTAT_RES_LWPS 0x200
#define ZSTAT_RES_LOFI 0x400
#define ZSTAT_RES_LIMITS 0x700
#define ZSTAT_RES_SHM_MEMORY 0x1000
#define ZSTAT_RES_SHM_IDS 0x2000
#define ZSTAT_RES_SEM_IDS 0x4000
#define ZSTAT_RES_MSG_IDS 0x8000
#define ZSTAT_RES_SYSV 0xF000
#define ZSTAT_RES_ALL 0xF777
#define ZONESTAT_PHYSICAL_MEMORY "physical-memory"
#define ZONESTAT_VIRTUAL_MEMORY "virtual-memory"
#define ZONESTAT_LOCKED_MEMORY "locked-memory"
#define ZONESTAT_MEMORY "memory"
#define ZONESTAT_DEFAULT_PSET "default-pset"
#define ZONESTAT_POOL_PSET "pool-pset"
#define ZONESTAT_PSRSET_PSET "psrset-pset"
#define ZONESTAT_DEDICATED_CPU "dedicated-cpu"
#define ZONESTAT_PROCESSOR_SET "processor-set"
#define ZONESTAT_PSETS "psets"
#define ZONESTAT_SUMMARY "summary"
#define ZONESTAT_PROCESSES "processes"
#define ZONESTAT_LWPS "lwps"
#define ZONESTAT_LOFI "lofi"
#define ZONESTAT_LIMITS "limits"
#define ZONESTAT_SHM_MEMORY "shm-memory"
#define ZONESTAT_SHM_IDS "shm-ids"
#define ZONESTAT_SEM_IDS "sem-ids"
#define ZONESTAT_MSG_IDS "msg-ids"
#define ZONESTAT_SYSV "sysv"
#define ZONESTAT_ALL "all"
#define ZONESTAT_NAME_MEM_DEFAULT "mem_default"
#define ZONESTAT_NAME_VM_DEFAULT "vm_default"
#define ZONESTAT_NAME_AVERAGE "average"
#define ZONESTAT_NAME_HIGH "high"
#define ZONESTAT_NAME_RESOURCE "resource"
#define ZONESTAT_NAME_TOTAL "total"
#define ZONESTAT_NAME_SYSTEM "system"
#define ZONESTAT_NAME_ZONES "zones"
#define ZONESTAT_NAME_HEADER "header"
#define ZONESTAT_NAME_FOOTER "footer"
#define ZONESTAT_NAME_NAME "name"
#define ZONESTAT_NAME_USED "used"
#define ZONESTAT_NAME_CAP "cap"
#define ZONESTAT_NAME_PCAP "pcap"
#define ZONESTAT_NAME_SHR "shr"
#define ZONESTAT_NAME_PSHRU "pshru"
#define ZONESTAT_NAME_CPU "cpu"
#define ZONESTAT_NAME_SYSTEM_LIMIT "system-limit"
#define ZSTAT_REPORT_FMT_INTERVAL 0
#define ZSTAT_REPORT_FMT_TOTAL 1
#define ZSTAT_REPORT_FMT_AVERAGE 2
#define ZSTAT_REPORT_FMT_HIGH 3
#define ZSTAT_REPORT_FMT_END 4
#define ZSTAT_REPORT_TEXT_INTERVAL "interval"
#define ZSTAT_REPORT_TEXT_TOTAL "report-total"
#define ZSTAT_REPORT_TEXT_AVERAGE "report-average"
#define ZSTAT_REPORT_TEXT_HIGH "report-high"
#define ZSTAT_REPORT_TEXT_END "footer"
#define ZSTAT_DURATION_INF ((int)INT_MAX)
#define ZSTAT_INTERVAL_DEFAULT ((int)INT_MAX)
#define ZSTAT_REPORT_END ((int)INT_MAX)
#define ZSTAT_SORT_CPU 1
#define ZSTAT_SORT_PHYSICAL 2
#define ZSTAT_SORT_VIRTUAL 3
#define ZSTAT_SORT_USED 4
#define ZSTAT_SORT_CAP 5
#define ZSTAT_SORT_PCAP 6
#define ZSTAT_SORT_SHR 7
#define ZSTAT_SORT_PSHRU 8
#define ZSTAT_SORT_NAME 9
#define ZSTAT_SORT_MAX 10
#define ZSTAT_SUM_MIN_ZONENAME 19
#define ZSTAT_SUM_HDR_FORMAT "%23s %17s %17s\n"
#define ZSTAT_SUM_ZONE_FORMAT "%5s %5s %5s %5s %5s %5s %5s %5s %5s %5s\n"
#define ZSTAT_CPU_MIN_PSETNAME 22
#define ZSTAT_CPU_MIN_ZONENAME 36
#define ZSTAT_CPU_RES_FORMAT "%13s %11s %11s\n"
#define ZSTAT_CPU_ZONE_FORMAT "%5s %5s %5s %5s %6s %5s %5s\n"
#define ZSTAT_RESOURCE_MIN_RESNAME 28
#define ZSTAT_RESOURCE_MIN_ZONENAME 36
#define ZSTAT_RESOURCE_FORMAT "%13s\n"
#define ZSTAT_RESOURCE_ZONE_FORMAT "%5s %5s %5s %5s\n"
#define ZS_UINT64_STRLEN 20
#define ZS_PCT_STRLEN 10
#define ZS_TIME_STRLEN 20
#define ZS_NAME_STRLEN 10
int g_interval;
int g_count;
int g_report_count;
int g_resources;
int g_zone_num;
int g_pz_num;
int g_pset_num;
int g_sort_by;
int g_sorts[ZSTAT_SORT_MAX];
int g_sort_summary;
/* Storage for command line arguments. */
char **arg_zonenames;
int arg_zonename_count;
char **arg_resnames;
int arg_resname_count;
char **arg_restypes;
int arg_restype_count;
char ** arg_reports;
int arg_report_count;
char ** arg_sort_list;
int arg_sort_count;
char ** arg_line_list;
int arg_line_count;
int arg_interval = 5;
int arg_duration = -1;
int arg_report = -1;
/* Options with or as arguments */
/* Options without arguments */
static int
{
" zonestat [-z zonelist] [-r reslist] [-n namelist]\n"
" [-T u | d | i] [-R reports] [-q] [-p [-P lines]] [-S cols]\n"
" interval [duration [report]]\n"
"\n");
" Options:\n"
" %s Report resources of specified types.\n"
" Valid resource types are:\n"
" \"%s\"\n"
" \"%s\"\n"
" \"%s\"\n"
" \"%s\"\n"
" \"%s\", \"%s\", \"%s\"\n"
" \"%s\", \"%s\", \"%s\", \"%s\"\n"),
"-r",
" The following resource nicknames can also be specified:\n"
" \"%s\"\n"
" \"%s\"\n"
" \"%s\"\n"
" \"%s\"\n"
" \"%s\"\n"
" \"%s\"\n"),
" %s Report resources used by zones\n"
" %s Report resources with specific names.\n"
" Valid resource names are:\n"
" \"%s\"\n"
" \"%s\"\n"
" Name of a pool processor set\n"
" Id of a processor set created with psrset(1m)\n"
" Name of a zone using dedicated-cpu\n"),
"-z", "-n",
" %s Print timestamp. Valid timestamps are:\n"
" \"%s\"\tDate as specifed by date(1) command\n"
" \"%s\"\tUnix time as returned by time(2)\n"
" \"%s\"\tISO 8601 timestamp \"%s\"\n"
" %s Print reports at end or after each report interval.\n"
" Valid reports are:\n"
" \"%s\"\tUsage of each zone\n"
" \"%s\"\tUsage of each zone while running\n"
" \"%s\"\tMaximum usage of each zone\n"
" %s Quiet. Do not print intervals. Only print reports.\n"
" %s Machine parseable output.\n"),
"-T", "d", "u", "i", "YYYYMMDDThhmmssZ",
"-q", "-p");
" %s Select desired lines in parseable output.\n"
" \"%s\"\tLines describing each resource\n"
" \"%s\"\tTotal usage of each resource\n"
" \"%s\"\tSystem usage of each resource\n"
" \"%s\"\tPer-zone usage of each resource\n"
" \"%s\"\tHeader lines between intervals and reports\n"),
" %s Sort output by the specified columns:\n"
" \"%s\"\tby name alphanumerically\n"
" \"%s\"\tby percent of resource used\n"
" \"%s\"\tby configured cap\n"
" \"%s\"\tby percent of cap used\n"
" \"%s\"\tby shares configured\n"
" \"%s\"\tby percent of share used\n"
" \"%s\"\tSort summary by cpu\n"
" \"%s\"\tSort summary by physical memory\n"
" \"%s\"\tSort summary by virtual memory\n"),
if (!explicit)
return (ZSTAT_USAGE);
}
/* PRINTFLIKE1 */
static int
zonestat_error(const char *fmt, ...)
{
return (ZSTAT_ERROR);
}
static void
{
int i;
if (arg_line_count == 0) {
}
for (i = 0; i < arg_line_count; i++) {
else {
arg_line_list[i]);
}
}
}
static void
{
int i;
for (i = 0; i < arg_report_count; i++) {
else {
arg_reports[i]);
}
}
}
/*
* Compares list of -S sort arguments to the list of known sorts. Only
* one of cpu, physical memory, and virtual memory can be specified.
*/
static void
{
int i, count = 0;
if (arg_sort_count == 0) {
g_sorts[0] = ZSTAT_SORT_USED;
arg_sort_count = 2;
return;
}
if (arg_sort_count > ZSTAT_SORT_MAX)
"Too many -S sort columns specified")));
for (i = 0; i < arg_sort_count; i++) {
if (g_sort_summary != 0)
} else if (strcmp(arg_sort_list[i],
ZONESTAT_NAME_PHYSICAL_MEMORY) == 0) {
if (g_sort_summary != 0)
} else if (strcmp(arg_sort_list[i],
ZONESTAT_NAME_VIRTUAL_MEMORY) == 0) {
if (g_sort_summary != 0)
} else {
arg_sort_list[i]);
}
}
if (g_sort_summary == 0)
(void) zonestat_error(gettext(
"-S: only one of \"%s\", \"%s\", or "
}
}
typedef struct zonestat_resource_struct {
char *zr_name;
/* Used to map resource name strings to resource flags */
};
/*
* Compares list of resources passed to -r to the known list of
* resources.
*/
static void
{
int i, j, count;
if (arg_restype_count == 0) {
return;
}
for (i = 0; i < arg_restype_count; i++) {
for (j = 0; j < count; j++) {
== 0) {
break;
}
}
arg_restypes[i]);
}
}
}
/*
* Returns 1 if the name matches one of the specified zone names. 0
* otherwise. Always matches if no zone names were specified.
*/
static int
zonestat_match_zonename(char *name)
{
int i;
if (arg_zonename_count == 0)
return (1);
for (i = 0; i < arg_zonename_count; i++) {
return (1);
}
return (0);
}
/*
* compare name to base, ignoring prefix on name.
*/
static int
{
name += prefix_len;
return (1);
}
return (0);
}
/*
* Returns 1 if the resource matches one of the specified resource names. 0
* otherwise. Always matches if no resource names were specified.
*/
static int
zonestat_match_resname(char *name)
{
int i;
if (arg_resname_count == 0)
return (1);
for (i = 0; i < arg_resname_count; i++) {
return (1);
arg_resnames[i]))
return (1);
arg_resnames[i]))
return (1);
}
return (0);
}
/*
* Format unsigned uint64_t
*
* 9999 9999
* 99.9K 99999
* 9999K 9999999
* 99.9M 99999999
* 9999M 9999999999
* 99.9G 99999999999
* 9999G 9999999999999
* 99.9T 99999999999999
* 9999T 9999999999999999
* 99.9P 99999999999999999
* 9999P 9999999999999999999
* 99.9E UINT64_MAX
*/
static void
{
if (val == UINT64_MAX) {
return;
}
if (val <= 9999) {
return;
}
if (val <= 99999) {
return;
}
return;
}
if (val <= 99999) {
return;
}
if (val <= 9999) {
return;
}
if (val <= 99999) {
return;
}
if (val <= 9999) {
return;
}
if (val <= 99999) {
return;
}
if (val <= 9999) {
return;
}
if (val <= 99999) {
return;
}
if (val <= 9999) {
return;
}
}
static void
{
if (pct == ZS_PCT_NONE) {
return;
}
/*
* pct's are printed as one of:
* #.##%
* ##.#%
* ###%
* ####%
*
* The value is fixed decimal. 10000 equals 100.00 percent.
* Percents can exceed 100.00 percent. Percents greater than
* 9999% will exceed the 5 column width.
*/
} else if (pct <= 9999) {
} else {
}
}
/*
* Cpu cap is 100 times the number of cpus allocated. It is formatted as a
* decimal. Example, a cpu-cap of 50 is 0.50 cpus.
*
* The cpu cap value can go up to UINT_MAX, so handle all cases even though
* the higher ones are nonsense.
*
* Format Max cpu-cap value for format.
* 42.9M 4294967296
* 9999K 999999999
* 99.9K 9999999
* 9999 999999
* 999.9 99999
* 9.99 999
*/
void
{
/* #.## cpus */
return;
}
/* ##.# cpus */
if (cpu <= 99999) {
return;
}
/* #### cpus */
if (cpu <= 999999) {
return;
}
/* ##.#K cpus */
if (cpu <= 99999) {
return;
}
/* ####K cpus */
if (cpu <= 999999) {
return;
}
/* ##.#M cpus */
return;
}
}
/*
* Format a timetruct as:
* HH:MM:SS.SS
*
* Human readable format omits the fractional seconds.
*/
static void
{
hours = 0;
mins = 0;
while (pct >= 100) {
pct -= 100;
secs++;
}
if (secs >= 60) {
}
if (mins >= 60) {
}
if (human_readable)
else
}
char *g_report_formats[] = {
};
/* Get the label for the current report type */
static char *
{
if (format >= sizeof (g_report_formats) / sizeof (char *))
"Internal error, invalid report format")));
return (g_report_formats[format]);
}
#define ZSTAT_CPULINE "----------CPU----------"
#define ZSTAT_MEMLINE "----PHYSICAL-----"
#define ZSTAT_VMLINE "-----VIRTUAL-----"
static void
{
char str_cpu[ZS_UINT64_STRLEN];
char str_online[ZS_UINT64_STRLEN];
char str_mem[ZS_UINT64_STRLEN];
char str_vm[ZS_UINT64_STRLEN];
char name_format[ZS_NAME_STRLEN];
char tot_cpu[sizeof (ZSTAT_CPULINE)];
char tot_mem[sizeof (ZSTAT_MEMLINE)];
char tot_vm[sizeof (ZSTAT_VMLINE)];
char *label;
if (opt_parseable) {
return;
}
/* Make first column as wide as longest zonename */
/* LINTED */
tot_vm);
/* LINTED */
/* LINTED */
"%SHRU", "USED", "PCT", "%CAP", "USED", "PCT", "%CAP");
}
static void
{
char name_format[ZS_NAME_STRLEN];
if (opt_parseable)
return;
/* LINTED */
}
static void
{
char name_format[ZS_NAME_STRLEN];
if (opt_parseable)
return;
/* LINTED */
}
static void
{
int len;
char dstr[64];
/* We only need to retrieve this once per invocation */
if (arg_timestamp == ZSTAT_UNIX_TIMESTAMP) {
(void) printf("%ld", t);
} else if (arg_timestamp == ZSTAT_ISO_TIMESTAMP) {
gmtime(&t));
if (len > 0)
} else {
if (len > 0)
}
}
static void
{
char *label;
char str_cused[ZS_UINT64_STRLEN];
char str_ppart[ZS_PCT_STRLEN];
char str_pccap[ZS_PCT_STRLEN];
char str_pshru[ZS_PCT_STRLEN];
char str_mused[ZS_UINT64_STRLEN];
char str_mpct[ZS_PCT_STRLEN];
char str_pmcap[ZS_PCT_STRLEN];
char str_vused[ZS_UINT64_STRLEN];
char str_vpct[ZS_PCT_STRLEN];
char str_pvcap[ZS_PCT_STRLEN];
char name_format[ZS_NAME_STRLEN];
if (opt_parseable) {
if (opt_timestamp) {
(void) printf(":");
}
(void) printf("%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s:%s\n",
return;
}
/* LINTED */
}
static void
{
char strsize[ZS_UINT64_STRLEN];
char *label;
char name_format[ZS_NAME_STRLEN];
if (opt_parseable) {
if (opt_timestamp) {
(void) printf(":");
}
return;
}
/* LINTED */
}
static void
{
char strused[ZS_UINT64_STRLEN];
char strpct[ZS_PCT_STRLEN];
char strcap[ZS_UINT64_STRLEN];
char strpctcap[ZS_PCT_STRLEN];
char name_format[ZS_NAME_STRLEN];
char *label;
if (cap == ZS_LIMIT_NONE)
else
if (pctcap == ZS_PCT_NONE)
else
if (opt_parseable) {
if (opt_timestamp) {
(void) printf(":");
}
return;
}
/* LINTED */
}
/*
* Not thread safe.
*/
static void
{
g_max_zonename = 0;
}
static int
zonestat_zone_compare_resource(const void *a, const void *b)
{
int i, res;
for (i = 0; i < arg_sort_count; i++) {
/* Sort by order of selection */
switch (g_sorts[i]) {
case ZSTAT_SORT_USED:
break;
case ZSTAT_SORT_CAP:
if (resa == ZS_LIMIT_NONE)
resa = 0;
if (resb == ZS_LIMIT_NONE)
resb = 0;
break;
case ZSTAT_SORT_PCAP:
if (uinta == ZS_PCT_NONE)
resa = 0;
else
if (uintb == ZS_PCT_NONE)
resb = 0;
else
break;
case ZSTAT_SORT_SHR:
if (resa == ZS_LIMIT_NONE)
resa = 0;
if (resb == ZS_LIMIT_NONE)
resb = 0;
break;
case ZSTAT_SORT_PSHRU:
if (uinta == ZS_PCT_NONE)
resa = 0;
else
if (uintb == ZS_PCT_NONE)
resb = 0;
else
break;
case ZSTAT_SORT_NAME:
if (res != 0)
return (res);
break;
default:
}
return (1);
return (-1);
}
/* No difference, return 0 */
return (0);
}
/*
* Sort psets. Default pset first, then shared psets, then dedicated
* psets.
*/
static int
zonestat_pset_compare(const void *a, const void *b)
{
zs_property_t *p;
typea = zs_property_uint(p);
typeb = zs_property_uint(p);
if (typea == ZS_CPUTYPE_DEFAULT_PSET)
return (-1);
if (typeb == ZS_CPUTYPE_DEFAULT_PSET)
return (1);
if (typea == ZS_CPUTYPE_POOL_PSET)
return (-1);
if (typeb == ZS_CPUTYPE_POOL_PSET)
return (1);
if (typea == ZS_CPUTYPE_PSRSET_PSET)
return (-1);
if (typeb == ZS_CPUTYPE_PSRSET_PSET)
return (1);
return (0);
}
static int
zonestat_pz_compare_usage(const void *a, const void *b)
{
int i, res;
for (i = 0; i < arg_sort_count; i++) {
/* Sort by order of selection */
switch (g_sorts[i]) {
case ZSTAT_SORT_USED:
break;
case ZSTAT_SORT_CAP:
prop);
if (resa == ZS_LIMIT_NONE)
resa = 0;
prop);
if (resb == ZS_LIMIT_NONE)
resb = 0;
break;
case ZSTAT_SORT_PCAP:
if (uinta == ZS_PCT_NONE)
resa = 0;
else
if (uintb == ZS_PCT_NONE)
resb = 0;
else
break;
case ZSTAT_SORT_SHR:
prop);
if (resa == ZS_LIMIT_NONE)
resa = 0;
prop);
if (resb == ZS_LIMIT_NONE)
resb = 0;
break;
case ZSTAT_SORT_PSHRU:
if (uinta == ZS_PCT_NONE)
resa = 0;
else
if (uintb == ZS_PCT_NONE)
resb = 0;
else
break;
case ZSTAT_SORT_NAME:
if (res != 0)
return (res);
break;
default:
}
return (1);
return (-1);
}
/* No difference, return 0 */
return (0);
}
static void
{
int num, i;
zs_zone_t *z;
char zonename[ZS_ZONENAME_MAX];
prop);
if (num > g_zone_num) {
if (g_zone_list != NULL)
g_zone_num = num;
goto again;
}
/* Find the longest zone name to set output width. */
for (i = 0; i < num; i++) {
z = g_zone_list[i];
}
if (opt_line_total) {
}
if (opt_line_system) {
}
for (i = 0; i < num; i++) {
z = g_zone_list[i];
sizeof (zonename));
pvcap);
}
if (!opt_parseable)
(void) printf("\n");
}
static void
{
char zonename[ZS_ZONENAME_MAX];
int num, i;
/* See if resource matches specified resource names */
if (zonestat_match_resname(name) == 0)
return;
if (opt_line_resource)
size);
if (num > g_zone_num) {
if (g_zone_list != NULL)
g_zone_num = num;
goto again;
}
for (i = 0; i < num; i++) {
zone = g_zone_list[i];
}
if (opt_line_total) {
}
if (opt_line_system) {
}
for (i = 0; i < num; i++) {
zone = g_zone_list[i];
sizeof (zonename));
if (zonestat_match_zonename(zonename) == 0)
continue;
if (opt_line_zones)
}
if (!opt_parseable)
(void) printf("\n");
}
static void
{
char name_format[ZS_NAME_STRLEN];
if (opt_parseable)
return;
/* LINTED */
}
static void
{
char name_format[ZS_NAME_STRLEN];
if (opt_parseable)
return;
/* LINTED */
"%CAP", "SHRS", "%SHR", "%SHRU");
}
static void
{
char online_str[ZS_UINT64_STRLEN];
char size_str[ZS_UINT64_STRLEN];
char min_str[ZS_UINT64_STRLEN];
char max_str[ZS_UINT64_STRLEN];
char ts_str[ZS_TIME_STRLEN];
char name_format[ZS_NAME_STRLEN];
char *label;
if (opt_parseable) {
if (opt_timestamp) {
(void) printf(":");
}
return;
}
size_str);
max_str);
/* LINTED */
}
static void
{
char used_str[ZS_UINT64_STRLEN];
char pct_str[ZS_PCT_STRLEN];
char cap_str[ZS_UINT64_STRLEN];
char pct_cap_str[ZS_PCT_STRLEN];
char shares_str[ZS_UINT64_STRLEN];
char pct_shares_str[ZS_PCT_STRLEN];
char pct_shares_used_str[ZS_PCT_STRLEN];
char ts_str[ZS_TIME_STRLEN];
char name_format[ZS_NAME_STRLEN];
char *label;
if (cap == ZS_LIMIT_NONE)
else
if (pct_cap == ZS_PCT_NONE)
else
if ((scheds & ZS_SCHED_CONFLICT) &&
(!(scheds & ZS_SCHED_FSS)))
else if (shares == ZS_LIMIT_NONE)
else if (shares == ZS_SHARES_UNLIMITED)
else
if (pct_shares == ZS_PCT_NONE)
else
sizeof (pct_shares_str));
if (pct_shares_used == ZS_PCT_NONE) {
sizeof (pct_shares_used_str));
} else {
sizeof (pct_shares_used_str));
}
if (opt_parseable) {
if (opt_timestamp) {
(void) printf(":");
}
return;
} else {
namelen);
/* LINTED */
}
/* Report if zone has mix of schedulers conflicting with FSS */
(scheds & ZS_SCHED_FSS)) {
/* LINTED */
(void) printf(" mixed schedulers found:");
(void) printf(" FSS");
if (scheds & ZS_SCHED_TS)
(void) printf(", TS");
if (scheds & ZS_SCHED_IA)
(void) printf(", IA");
if (scheds & ZS_SCHED_FX)
(void) printf(", FX");
(void) printf("\n");
}
}
static void
{
char psetname[ZS_PSETNAME_MAX];
char zonename[ZS_PSETNAME_MAX];
char *name;
int num, i;
/* Check if pset contains specified zone */
if (arg_zonename_count > 0) {
sizeof (zonename));
zone_match = B_TRUE;
break;
}
}
if (zone_match == B_FALSE)
return;
}
if (zonestat_match_resname(psetname) == 0)
return;
/* Strip off SUNWtmp_ from pset name */
name++;
}
/* Strip off SUNWlegacy_pst for psrset psets */
strlen("SUNWlegacy_pset_")) == 0) {
name++;
}
if (ZSTAT_CPU_MIN_PSETNAME > namelen)
if (opt_line_resource)
sizeof (zs_pset_zone_t *) * num);
goto again;
}
/* Find longest zone name in pset */
for (i = 0; i < num; i++) {
}
if (opt_line_total) {
}
if (opt_line_system) {
}
for (i = 0; i < num; i++) {
sizeof (zonename));
if (zonestat_match_zonename(zonename) == 0)
continue;
if (opt_line_zones)
}
if (!opt_parseable)
(void) printf("\n");
}
/* ARGSUSED */
static void
zonestat_quithandler(int sig)
{
}
static void
{
char *label;
if (!opt_parseable)
return;
if (opt_timestamp) {
(void) printf(":");
}
}
static void
{
char *label;
char string[ZS_TIME_STRLEN];
if (!opt_parseable) {
/* Human readable header */
if (opt_timestamp) {
(void) printf(", ");
}
if (report_fmt == ZSTAT_REPORT_FMT_INTERVAL) {
string);
return;
} else {
switch (report_fmt) {
case ZSTAT_REPORT_FMT_TOTAL:
label = "Report: Total Usage";
break;
case ZSTAT_REPORT_FMT_AVERAGE:
label = "Report: Average Usage";
break;
case ZSTAT_REPORT_FMT_HIGH:
label = "Report: High Usage";
break;
default:
"Internal error, invalid header")));
}
/* Left are the report header formats */
(void) printf(" Start: ");
(void) printf("\n End: ");
(void) printf("\n");
(void) printf(" Intervals: %d, Duration: %s\n",
return;
}
}
if (!opt_line_header)
return;
/* Parseable header */
if (opt_timestamp) {
(void) printf(":");
}
if (report_fmt == ZSTAT_REPORT_FMT_INTERVAL) {
(void) printf("since-last-interval:");
return;
}
/* Left are the report header formats */
(void) printf(":");
(void) printf(":");
}
static void
{
char *psettype;
zs_property_t *p;
if (num > g_pset_num) {
if (g_pset_list != NULL)
g_pset_num = num;
goto again;
}
/* Sort, default pset first, then pool, psrset, and dedicated psets */
for (i = 0; i < num; i++) {
pset = g_pset_list[i];
cputype = zs_property_uint(p);
if (cputype == ZS_CPUTYPE_DEFAULT_PSET &&
(g_resources & (ZSTAT_RES_PSETS |
} else if (cputype == ZS_CPUTYPE_POOL_PSET &&
(g_resources & ZSTAT_RES_PSETS)) {
} else if (cputype == ZS_CPUTYPE_PSRSET_PSET &&
(g_resources & ZSTAT_RES_PSETS)) {
} else if (cputype == ZS_CPUTYPE_DEDICATED &&
(g_resources & ZSTAT_RES_PSETS)) {
} else {
continue;
}
}
}
static void
{
if (g_resources & ZSTAT_RES_SUMMARY)
"SYSTEM MEMORY", ZONESTAT_PHYSICAL_MEMORY,
"SYSTEM MEMORY", ZONESTAT_VIRTUAL_MEMORY,
if (g_resources & ZSTAT_RES_PROCESSES)
if (g_resources & ZSTAT_RES_LWPS)
if (g_resources & ZSTAT_RES_LOFI)
if (g_resources & ZSTAT_RES_SHM_MEMORY)
if (g_resources & ZSTAT_RES_SHM_IDS)
if (g_resources & ZSTAT_RES_SEM_IDS)
if (g_resources & ZSTAT_RES_MSG_IDS)
}
/*
* Adds comma seperated list of names to array of names
* Returns new total number of names.
*/
static size_t
{
/* count names, delimiting with '\0'. */
num = 1;
*next++ = '\0';
num++;
}
/* Resise names array */
/* add names to names array */
for (i = 0; i < num; i++) {
}
}
static int
{
int val;
int save;
*end = '\0';
errno = 0;
return (-1);
return (val);
}
/*
* parses and [nh][nm][hs] notation into seconds
*/
static int
{
int seconds = 0;
int minutes = 0;
int hours = 0;
/* Look for special tokens */
return (ZSTAT_INTERVAL_DEFAULT);
return (ZSTAT_DURATION_INF);
/* Look for hours */
return (-1);
end++;
}
/* Look for minutes delimiter */
return (-1);
end++;
}
/* Look for seconds delimiter */
return (-1);
end++;
}
/* No delimiter found. Treat as seconds */
errno = 0;
return (-1);
}
if (*end != '\0')
return (-1);
return (seconds);
}
static void
{
if (opt_report_total == B_TRUE) {
}
if (opt_report_average == B_TRUE) {
}
if (opt_report_high == B_TRUE) {
}
}
static void
{
return;
}
}
static time_t
{
time_t t;
"Unable to fetch current time")));
return (t);
}
int
{
int arg;
char *not_responding;
/* Process command line options and args */
!= EOF) {
switch (arg) {
case 'z':
break;
case 'r':
break;
case 'n':
break;
case 'R':
opt_report = B_TRUE;
break;
case 'S':
break;
case 'T':
} else {
(void) zonestat_error(gettext(
"Invalid -T arg \"%s\". "
"Must be 'u', 'i', or 'd'."), optarg);
return (zonestat_usage(B_FALSE));
}
break;
case 'q':
break;
case 'p':
break;
case 'P':
break;
case 'D':
break;
case '?':
return (zonestat_usage(B_TRUE));
default:
return (zonestat_usage(B_FALSE));
}
}
if (opt_line_any & (!opt_parseable)) {
return (zonestat_usage(B_FALSE));
}
(void) zonestat_error(gettext(
"-T d invalid with -p. Use -T [u | i]"));
return (zonestat_usage(B_FALSE));
}
/* Default to ISO timetamp in parseable output */
if (!opt_timestamp && opt_parseable)
/* Get the interval and count */
optind++;
&formatted)) < 0 || arg_interval == 0) {
(void) zonestat_error(gettext(
return (zonestat_usage(B_FALSE));
}
} else {
return (zonestat_usage(B_FALSE));
}
if (arg_interval == ZSTAT_INTERVAL_DEFAULT) {
/* Get the configured sample interval */
"svc:/system/zones-monitoring:default", "config",
"sample_interval");
return (zonestat_error(gettext(
"Unable to fetch SMF property "
"\"config/sample_interval\"")));
}
"\"config/sample_interval\". Must be of type "
"\"count\"")));
}
if (arg_interval == 0)
"\"config/sample_interval\". Must be greater than"
"zero")));
}
optind++;
&formatted)) < 0 || arg_duration == 0) {
(void) zonestat_error(gettext(
return (zonestat_usage(B_FALSE));
}
/* If not formatted [nh][nm][ns], treat as count */
if (arg_duration != ZSTAT_DURATION_INF &&
} else {
}
optind++;
&formatted)) < 0 || arg_report == 0) {
(void) zonestat_error(gettext(
return (zonestat_usage(B_FALSE));
}
/* If not formatted as [nh][nm][ns] treat as count */
} else {
}
if (opt_quiet_intervals && (!opt_report)) {
return (zonestat_usage(B_FALSE));
}
/* Figure out what resources to report on */
/* Done parsing args beyond this point */
/* Run at high priority to keep up with busy system */
"Zones monitoring service \"svc:/system/zones-monitoring:default\" "
"not enabled or responding.");
/* Open zone statistics */
(void) zonestat_error(not_responding);
return (3);
}
return (zonestat_error(gettext(
"Mismatched zonestat version. "
return (zonestat_error(gettext(
"Unexpected error. Unable to open zone statistics.")));
}
if (usage_last == NULL) {
return (0);
(void) zonestat_error(not_responding);
return (3);
}
"Collecting data for first interval...\n"));
for (;;) {
if (arg_report != ZSTAT_REPORT_END)
/*
* Sleep till next interval.
*/
g_count++;
/*
* Skip to next interval if due to busy system, zonestat did
* not complete in time.
*/
g_count++;
/* Sleep until at next interval */
now = zonestat_time();
goto interval_loop_done;
}
g_now_time = now;
break;
(void) zonestat_error(not_responding);
return (3);
}
/* Compute cpu used since last interval */
if (usage_print == NULL)
if (opt_quiet_intervals == B_TRUE)
goto interval_print_end;
/* Print reports if they are due */
now >= next_report) {
g_end_time = now;
set = zs_usage_set_alloc();
g_start_time = now;
}
usage_last = usage;
if (arg_duration != ZSTAT_DURATION_INF &&
break;
}
/* Print last reports if due */
if (usage_last != NULL)
return (0);
}