8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libzonestat / common / libzonestat.c
bloba66c48d56447698d3b1d21820bc10d6c7ffdee0b
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <alloca.h>
27 #include <assert.h>
28 #include <door.h>
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <stddef.h>
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <strings.h>
35 #include <sys/mman.h>
36 #include <sys/socket.h>
37 #include <sys/stat.h>
38 #include <sys/types.h>
39 #include <unistd.h>
40 #include <zonestat.h>
41 #include <zonestat_impl.h>
43 #define ZSD_PCT_INT 10000
44 #define ZSD_PCT_DOUBLE 10000.0
46 #define ZSD_ONE_CPU 100
48 #ifndef MIN
49 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
50 #endif
51 #ifndef MAX
52 #define MAX(a, b) (((a) > (b)) ? (a) : (b))
53 #endif
55 #define ZS_MAXTS(a, b) ((b).tv_sec > (a).tv_sec || \
56 ((b).tv_sec == (a).tv_sec && (b).tv_nsec > (a).tv_nsec) ? (b) : (a))
59 /* Compute max, treating ZS_LIMIT_NONE as zero */
60 #define ZS_MAXOF(a, b) { \
61 if ((b) != ZS_LIMIT_NONE) { \
62 if ((a) == ZS_LIMIT_NONE) \
63 (a) = (b); \
64 else if ((b) > (a)) \
65 (b) = (a); \
66 } \
69 /* Add two caps together, treating ZS_LIMIT_NONE as zero */
70 #define ZS_ADD_CAP(a, b) { \
71 if ((b) != ZS_LIMIT_NONE) { \
72 if ((a) == ZS_LIMIT_NONE) \
73 (a) = (b); \
74 else \
75 (a) += (b); \
76 } \
79 #define ZS_MAXOFTS(a, b) { \
80 if ((b).tv_sec > (a).tv_sec) (a) = (b); \
81 else if ((b).tv_nsec > (a).tv_nsec) (a) = (b); }
84 * Functions for reading and manipulating resource usage.
86 static int
87 zs_connect_zonestatd()
89 int fd;
91 fd = open(ZS_DOOR_PATH, O_RDONLY);
92 return (fd);
95 static zs_zone_t *
96 zs_lookup_zone_byid(zs_usage_t *u, zoneid_t zid)
98 zs_zone_t *zone;
100 for (zone = list_head(&u->zsu_zone_list); zone != NULL;
101 zone = list_next(&u->zsu_zone_list, zone)) {
102 if (zone->zsz_id == zid)
103 return (zone);
105 return (NULL);
108 static zs_zone_t *
109 zs_lookup_zone_byname(zs_usage_t *u, char *name)
111 zs_zone_t *zone;
113 for (zone = list_head(&u->zsu_zone_list); zone != NULL;
114 zone = list_next(&u->zsu_zone_list, zone)) {
115 if (strcmp(zone->zsz_name, name) == 0)
116 return (zone);
118 return (NULL);
121 static zs_usage_t *
122 zs_usage_alloc()
124 zs_usage_t *u;
125 zs_system_t *s;
127 u = (zs_usage_t *)calloc(sizeof (zs_usage_t), 1);
128 if (u == NULL)
129 return (NULL);
131 s = (zs_system_t *)calloc(sizeof (zs_system_t), 1);
132 if (s == NULL) {
133 free(u);
134 return (NULL);
137 u->zsu_mmap = B_FALSE;
138 u->zsu_system = s;
139 list_create(&u->zsu_zone_list, sizeof (zs_zone_t),
140 offsetof(zs_zone_t, zsz_next));
141 list_create(&u->zsu_pset_list, sizeof (zs_pset_t),
142 offsetof(zs_pset_t, zsp_next));
144 return (u);
147 static void
148 zs_zone_add_usage(zs_zone_t *old, zs_zone_t *new, int func)
151 if (func == ZS_COMPUTE_USAGE_HIGH) {
153 /* Compute max of caps */
154 ZS_MAXOF(old->zsz_cpu_cap, new->zsz_cpu_cap);
155 ZS_MAXOF(old->zsz_cpu_shares, new->zsz_cpu_shares);
156 ZS_MAXOF(old->zsz_ram_cap, new->zsz_ram_cap);
157 ZS_MAXOF(old->zsz_locked_cap, new->zsz_locked_cap);
158 ZS_MAXOF(old->zsz_vm_cap, new->zsz_vm_cap);
159 ZS_MAXOF(old->zsz_processes_cap, new->zsz_processes_cap);
160 ZS_MAXOF(old->zsz_lwps_cap, new->zsz_lwps_cap);
161 ZS_MAXOF(old->zsz_shm_cap, new->zsz_shm_cap);
162 ZS_MAXOF(old->zsz_shmids_cap, new->zsz_shmids_cap);
163 ZS_MAXOF(old->zsz_semids_cap, new->zsz_semids_cap);
164 ZS_MAXOF(old->zsz_msgids_cap, new->zsz_msgids_cap);
165 ZS_MAXOF(old->zsz_lofi_cap, new->zsz_lofi_cap);
167 /* Compute max memory and limit usages */
168 ZS_MAXOF(old->zsz_usage_ram, new->zsz_usage_ram);
169 ZS_MAXOF(old->zsz_usage_locked, new->zsz_usage_locked);
170 ZS_MAXOF(old->zsz_usage_ram, new->zsz_usage_ram);
172 ZS_MAXOF(old->zsz_processes, new->zsz_processes);
173 ZS_MAXOF(old->zsz_lwps, new->zsz_lwps);
174 ZS_MAXOF(old->zsz_shm, new->zsz_shm);
175 ZS_MAXOF(old->zsz_shmids, new->zsz_shmids);
176 ZS_MAXOF(old->zsz_semids, new->zsz_semids);
177 ZS_MAXOF(old->zsz_msgids, new->zsz_msgids);
178 ZS_MAXOF(old->zsz_lofi, new->zsz_lofi);
180 ZS_MAXOF(old->zsz_cpus_online, new->zsz_cpus_online);
182 ZS_MAXOFTS(old->zsz_cpu_usage, new->zsz_cpu_usage);
183 ZS_MAXOFTS(old->zsz_pset_time, new->zsz_pset_time);
184 ZS_MAXOFTS(old->zsz_cap_time, new->zsz_cap_time);
185 ZS_MAXOFTS(old->zsz_share_time, new->zsz_share_time);
186 return;
189 ZS_ADD_CAP(old->zsz_cpu_cap, new->zsz_cpu_cap);
190 ZS_ADD_CAP(old->zsz_ram_cap, new->zsz_ram_cap);
191 ZS_ADD_CAP(old->zsz_locked_cap, new->zsz_locked_cap);
192 ZS_ADD_CAP(old->zsz_vm_cap, new->zsz_vm_cap);
193 ZS_ADD_CAP(old->zsz_processes_cap, new->zsz_processes_cap);
194 ZS_ADD_CAP(old->zsz_lwps_cap, new->zsz_lwps_cap);
195 ZS_ADD_CAP(old->zsz_shm_cap, new->zsz_shm_cap);
196 ZS_ADD_CAP(old->zsz_shmids_cap, new->zsz_shmids_cap);
197 ZS_ADD_CAP(old->zsz_semids_cap, new->zsz_semids_cap);
198 ZS_ADD_CAP(old->zsz_msgids_cap, new->zsz_msgids_cap);
199 ZS_ADD_CAP(old->zsz_lofi_cap, new->zsz_lofi_cap);
201 /* Add in memory and limit usages */
202 old->zsz_usage_ram += new->zsz_usage_ram;
203 old->zsz_usage_locked += new->zsz_usage_locked;
204 old->zsz_usage_vm += new->zsz_usage_vm;
206 old->zsz_processes += new->zsz_processes;
207 old->zsz_lwps += new->zsz_lwps;
208 old->zsz_shm += new->zsz_shm;
209 old->zsz_shmids += new->zsz_shmids;
210 old->zsz_semids += new->zsz_semids;
211 old->zsz_msgids += new->zsz_msgids;
212 old->zsz_lofi += new->zsz_lofi;
214 old->zsz_cpus_online += new->zsz_cpus_online;
215 old->zsz_cpu_shares += new->zsz_cpu_shares;
217 TIMESTRUC_ADD_TIMESTRUC(old->zsz_cpu_usage, new->zsz_cpu_usage);
218 TIMESTRUC_ADD_TIMESTRUC(old->zsz_pset_time, new->zsz_pset_time);
219 TIMESTRUC_ADD_TIMESTRUC(old->zsz_cap_time, new->zsz_cap_time);
220 TIMESTRUC_ADD_TIMESTRUC(old->zsz_share_time, new->zsz_share_time);
223 static int
224 zs_usage_compute_zones(zs_usage_t *ures, zs_usage_t *uold, zs_usage_t *unew,
225 int func)
227 zs_system_t *sres;
228 zs_zone_t *zold, *znew, *zres;
230 sres = ures->zsu_system;
232 * Walk zones, assume lists are always sorted the same. Include
233 * all zones that exist in the new usage.
235 zold = list_head(&uold->zsu_zone_list);
236 znew = list_head(&unew->zsu_zone_list);
238 while (zold != NULL && znew != NULL) {
240 int cmp;
242 cmp = strcmp(zold->zsz_name, znew->zsz_name);
243 if (cmp > 0) {
245 * Old interval does not contain zone in new
246 * interval. Zone is new. Add zone to result.
248 if (ures != unew) {
249 zres = (zs_zone_t *)calloc(sizeof (zs_zone_t),
251 if (zres == NULL)
252 return (-1);
253 *zres = *znew;
255 zres->zsz_system = sres;
256 list_link_init(&zres->zsz_next);
257 zres->zsz_intervals = 0;
258 if (ures == uold)
259 list_insert_before(&uold->zsu_zone_list,
260 zold, zres);
261 else
262 list_insert_tail(&ures->zsu_zone_list,
263 zres);
265 } else {
266 zres = znew;
269 if (func == ZS_COMPUTE_USAGE_AVERAGE)
270 zres->zsz_intervals++;
272 znew = list_next(&unew->zsu_zone_list, znew);
273 continue;
275 } else if (cmp < 0) {
277 * Start interval contains zones that is not in the
278 * end interval. This zone is gone. Leave zone in
279 * old usage, but do not add it to result usage
281 zold = list_next(&uold->zsu_zone_list, zold);
282 continue;
285 /* Zone is in both start and end interval. Compute interval */
286 if (ures == uold) {
287 zres = zold;
288 } else if (ures == unew) {
289 zres = znew;
290 } else {
291 /* add zone to new usage */
292 zres = (zs_zone_t *)calloc(sizeof (zs_zone_t), 1);
293 if (zres == NULL)
294 return (-1);
295 *zres = *znew;
296 zres->zsz_system = sres;
297 list_insert_tail(&ures->zsu_zone_list, zres);
299 if (func == ZS_COMPUTE_USAGE_AVERAGE)
300 zres->zsz_intervals++;
301 if (func == ZS_COMPUTE_USAGE_INTERVAL) {
303 * If zone is in the old interval, but has been
304 * rebooted, don't subtract its old interval usage
306 if (zres->zsz_hrstart > uold->zsu_hrtime) {
307 znew = list_next(&unew->zsu_zone_list, znew);
308 zold = list_next(&uold->zsu_zone_list, zold);
309 continue;
311 TIMESTRUC_DELTA(zres->zsz_cpu_usage,
312 znew->zsz_cpu_usage, zold->zsz_cpu_usage);
313 TIMESTRUC_DELTA(zres->zsz_cap_time, znew->zsz_cap_time,
314 zold->zsz_cap_time);
315 TIMESTRUC_DELTA(zres->zsz_share_time,
316 znew->zsz_share_time, zold->zsz_share_time);
317 TIMESTRUC_DELTA(zres->zsz_pset_time,
318 znew->zsz_pset_time, zold->zsz_pset_time);
319 } else {
320 zs_zone_add_usage(zres, znew, func);
322 znew = list_next(&unew->zsu_zone_list, znew);
323 zold = list_next(&uold->zsu_zone_list, zold);
326 if (ures == unew)
327 return (0);
329 /* Add in any remaining zones in the new interval */
330 while (znew != NULL) {
331 zres = (zs_zone_t *)calloc(sizeof (zs_zone_t), 1);
332 if (zres == NULL)
333 return (-1);
334 *zres = *znew;
335 zres->zsz_system = sres;
336 if (func == ZS_COMPUTE_USAGE_AVERAGE)
337 zres->zsz_intervals++;
338 if (ures == uold)
339 list_insert_tail(&uold->zsu_zone_list, zres);
340 else
341 list_insert_tail(&ures->zsu_zone_list, zres);
343 znew = list_next(&unew->zsu_zone_list, znew);
345 return (0);
348 static void
349 zs_pset_zone_add_usage(zs_pset_zone_t *old, zs_pset_zone_t *new, int func)
351 if (func == ZS_COMPUTE_USAGE_HIGH) {
352 ZS_MAXOF(old->zspz_cpu_shares, new->zspz_cpu_shares);
353 ZS_MAXOFTS(old->zspz_cpu_usage, new->zspz_cpu_usage);
354 return;
356 old->zspz_cpu_shares += new->zspz_cpu_shares;
357 TIMESTRUC_ADD_TIMESTRUC(old->zspz_cpu_usage, new->zspz_cpu_usage);
360 static int
361 zs_usage_compute_pset_usage(zs_usage_t *uold, zs_usage_t *ures,
362 zs_pset_t *pres, zs_pset_t *pold, zs_pset_t *pnew, int func)
364 zs_pset_zone_t *puold, *punew, *pures;
367 * Walk psets usages, assume lists are always sorted the same. Include
368 * all pset usages that exist in the new pset.
370 if (pold == NULL)
371 puold = NULL;
372 else
373 puold = list_head(&pold->zsp_usage_list);
374 punew = list_head(&pnew->zsp_usage_list);
376 while (puold != NULL && punew != NULL) {
378 int cmp;
380 cmp = strcmp(puold->zspz_zone->zsz_name,
381 punew->zspz_zone->zsz_name);
382 if (cmp > 0) {
384 * Old interval does not contain usage new
385 * interval. Usage is new.
387 if (pres != pnew) {
388 pures = (zs_pset_zone_t *)malloc(
389 sizeof (zs_pset_zone_t));
390 if (pures == NULL)
391 return (-1);
392 *pures = *punew;
394 pures->zspz_pset = pres;
395 pures->zspz_zone = zs_lookup_zone_byname(ures,
396 punew->zspz_zone->zsz_name);
397 assert(pures->zspz_zone != NULL);
398 pures->zspz_intervals = 0;
399 if (pres == pold)
400 list_insert_before(
401 &pold->zsp_usage_list, puold,
402 pures);
403 else
404 list_insert_tail(&pres->zsp_usage_list,
405 pures);
406 } else {
407 pures = punew;
409 if (func == ZS_COMPUTE_USAGE_AVERAGE)
410 pures->zspz_intervals++;
411 else if (func == ZS_COMPUTE_USAGE_TOTAL) {
412 /* Add pset's time so far to the zone usage */
413 TIMESTRUC_ADD_TIMESTRUC(
414 pures->zspz_zone->zsz_pset_time,
415 pres->zsp_total_time);
416 pures->zspz_zone->zsz_cpus_online +=
417 pres->zsp_online;
420 punew = list_next(&pnew->zsp_usage_list, punew);
421 continue;
422 } else if (cmp < 0) {
425 * Old interval contains pset_zone that is not in the
426 * new interval. This zone is no longer using the
427 * pset. Leave pset_zone in old interval, but do not
428 * add it to result usage.
430 * For total utilization, add pset time to zone that
431 * has run in this pset before.
433 if (func == ZS_COMPUTE_USAGE_TOTAL) {
434 /* Add new pset time to the zone usage */
435 TIMESTRUC_ADD_TIMESTRUC(
436 puold->zspz_zone->zsz_pset_time,
437 pnew->zsp_total_time);
438 puold->zspz_zone->zsz_cpus_online +=
439 pnew->zsp_online;
441 puold = list_next(&pold->zsp_usage_list, puold);
442 continue;
445 * Zone is using pset in both start and end interval. Compute
446 * interval
448 if (pres == pold) {
449 pures = puold;
450 } else if (pres == pnew) {
451 pures = punew;
452 } else {
453 pures = (zs_pset_zone_t *)malloc(
454 sizeof (zs_pset_zone_t));
455 if (pures == NULL)
456 return (-1);
457 *pures = *punew;
458 pures->zspz_pset = pres;
459 pures->zspz_zone = zs_lookup_zone_byname(ures,
460 punew->zspz_zone->zsz_name);
461 assert(pures->zspz_zone != NULL);
462 list_insert_tail(&pres->zsp_usage_list, pures);
464 if (func == ZS_COMPUTE_USAGE_AVERAGE)
465 pures->zspz_intervals++;
467 if (func == ZS_COMPUTE_USAGE_INTERVAL) {
469 * If pset usage has been destroyed and re-created
470 * since start interval, don't subtract the start
471 * interval.
473 if (punew->zspz_hrstart > uold->zsu_hrtime) {
474 punew = list_next(&pnew->zsp_usage_list, punew);
475 puold = list_next(&pold->zsp_usage_list, puold);
476 continue;
478 TIMESTRUC_DELTA(pures->zspz_cpu_usage,
479 punew->zspz_cpu_usage, puold->zspz_cpu_usage);
480 } else {
481 zs_pset_zone_add_usage(pures, punew, func);
483 punew = list_next(&pnew->zsp_usage_list, punew);
484 puold = list_next(&pold->zsp_usage_list, puold);
486 if (func == ZS_COMPUTE_USAGE_TOTAL) {
487 while (puold != NULL) {
488 TIMESTRUC_ADD_TIMESTRUC(
489 puold->zspz_zone->zsz_pset_time,
490 pnew->zsp_total_time);
491 puold->zspz_zone->zsz_cpus_online +=
492 pnew->zsp_online;
493 puold = list_next(&pold->zsp_usage_list, puold);
497 /* No need to add new pset zone usages if result pset is new pset */
498 if (pres == pnew)
499 return (0);
501 /* Add in any remaining new psets in the new interval */
502 while (punew != NULL) {
503 pures = (zs_pset_zone_t *)calloc(sizeof (zs_pset_zone_t), 1);
504 if (pures == NULL)
505 return (-1);
506 *pures = *punew;
507 pures->zspz_pset = pres;
508 pures->zspz_zone = zs_lookup_zone_byname(ures,
509 punew->zspz_zone->zsz_name);
510 assert(pures->zspz_zone != NULL);
511 if (func == ZS_COMPUTE_USAGE_AVERAGE)
512 pures->zspz_intervals++;
513 if (pres == pold)
514 list_insert_tail(&pold->zsp_usage_list, pures);
515 else
516 list_insert_tail(&pres->zsp_usage_list, pures);
518 punew = list_next(&pnew->zsp_usage_list, punew);
520 return (0);
523 static void
524 zs_pset_add_usage(zs_pset_t *old, zs_pset_t *new, int func)
527 if (func == ZS_COMPUTE_USAGE_HIGH) {
528 ZS_MAXOF(old->zsp_online, new->zsp_online);
529 ZS_MAXOF(old->zsp_size, new->zsp_size);
530 ZS_MAXOF(old->zsp_min, new->zsp_min);
531 ZS_MAXOF(old->zsp_max, new->zsp_max);
532 ZS_MAXOF(old->zsp_importance, new->zsp_importance);
533 ZS_MAXOF(old->zsp_cpu_shares, new->zsp_cpu_shares);
534 ZS_MAXOFTS(old->zsp_total_time, new->zsp_total_time);
535 ZS_MAXOFTS(old->zsp_usage_kern, new->zsp_usage_kern);
536 ZS_MAXOFTS(old->zsp_usage_zones, new->zsp_usage_zones);
537 return;
539 old->zsp_online += new->zsp_online;
540 old->zsp_size += new->zsp_size;
541 old->zsp_min += new->zsp_min;
542 old->zsp_max += new->zsp_max;
543 old->zsp_importance += new->zsp_importance;
544 old->zsp_cpu_shares += new->zsp_cpu_shares;
545 TIMESTRUC_ADD_TIMESTRUC(old->zsp_total_time, new->zsp_total_time);
546 TIMESTRUC_ADD_TIMESTRUC(old->zsp_usage_kern, new->zsp_usage_kern);
547 TIMESTRUC_ADD_TIMESTRUC(old->zsp_usage_zones, new->zsp_usage_zones);
550 static int
551 zs_usage_compute_psets(zs_usage_t *ures, zs_usage_t *uold, zs_usage_t *unew,
552 int func)
554 zs_pset_t *pold, *pnew, *pres;
557 * Walk psets, assume lists are always sorted the same. Include
558 * all psets that exist at the end of the interval.
560 pold = list_head(&uold->zsu_pset_list);
561 pnew = list_head(&unew->zsu_pset_list);
563 while (pold != NULL && pnew != NULL) {
565 int cmp;
567 cmp = strcmp(pold->zsp_name, pnew->zsp_name);
568 if (cmp > 0) {
570 * Old interval does not contain pset in new
571 * interval. Pset is new.
573 if (ures != unew) {
574 pres = (zs_pset_t *)malloc(sizeof (zs_pset_t));
575 if (pres == NULL)
576 return (-1);
577 *pres = *pnew;
578 pres->zsp_intervals = 0;
579 list_create(&pres->zsp_usage_list,
580 sizeof (zs_pset_zone_t),
581 offsetof(zs_pset_zone_t, zspz_next));
583 if (ures == uold)
584 list_insert_before(&uold->zsu_pset_list,
585 pold, pres);
586 else
587 list_insert_tail(&ures->zsu_pset_list,
588 pres);
590 } else {
591 pres = pnew;
593 if (zs_usage_compute_pset_usage(uold, ures, pres,
594 NULL, pnew, func) != 0)
595 return (-1);
597 if (func == ZS_COMPUTE_USAGE_AVERAGE ||
598 func == ZS_COMPUTE_USAGE_TOTAL)
599 pres->zsp_intervals++;
600 pnew = list_next(&unew->zsu_pset_list, pnew);
601 continue;
603 } else if (cmp < 0) {
605 * Start interval contains psets that is not in the
606 * end interval. This pset is gone. Leave pset in
607 * old usage, but do not add it to result usage.
609 pold = list_next(&uold->zsu_pset_list, pold);
610 continue;
613 /* Pset is in both start and end interval. Compute interval */
614 if (ures == uold) {
615 pres = pold;
616 } else if (ures == unew) {
617 pres = pnew;
618 } else {
619 pres = (zs_pset_t *)calloc(sizeof (zs_pset_t), 1);
620 if (pres == NULL)
621 return (-1);
623 *pres = *pnew;
624 list_create(&pres->zsp_usage_list,
625 sizeof (zs_pset_zone_t),
626 offsetof(zs_pset_zone_t, zspz_next));
627 list_insert_tail(&ures->zsu_pset_list, pres);
629 if (func == ZS_COMPUTE_USAGE_AVERAGE ||
630 func == ZS_COMPUTE_USAGE_TOTAL)
631 pres->zsp_intervals++;
632 if (func == ZS_COMPUTE_USAGE_INTERVAL) {
634 * If pset as been destroyed and re-created since start
635 * interval, don't subtract the start interval.
637 if (pnew->zsp_hrstart > uold->zsu_hrtime) {
638 goto usages;
640 TIMESTRUC_DELTA(pres->zsp_total_time,
641 pnew->zsp_total_time, pold->zsp_total_time);
643 TIMESTRUC_DELTA(pres->zsp_usage_kern,
644 pnew->zsp_usage_kern, pold->zsp_usage_kern);
645 TIMESTRUC_DELTA(pres->zsp_usage_zones,
646 pnew->zsp_usage_zones, pold->zsp_usage_zones);
647 } else {
648 zs_pset_add_usage(pres, pnew, func);
650 usages:
651 if (zs_usage_compute_pset_usage(uold, ures, pres, pold,
652 pnew, func) != 0)
653 return (-1);
655 pnew = list_next(&unew->zsu_pset_list, pnew);
656 pold = list_next(&uold->zsu_pset_list, pold);
659 if (ures == unew)
660 return (0);
662 /* Add in any remaining psets in the new interval */
663 while (pnew != NULL) {
664 pres = (zs_pset_t *)calloc(sizeof (zs_pset_t), 1);
665 if (pres == NULL)
666 return (-1);
667 *pres = *pnew;
668 list_create(&pres->zsp_usage_list,
669 sizeof (zs_pset_zone_t),
670 offsetof(zs_pset_zone_t, zspz_next));
671 if (func == ZS_COMPUTE_USAGE_AVERAGE ||
672 func == ZS_COMPUTE_USAGE_TOTAL)
673 pres->zsp_intervals++;
674 if (ures == uold)
675 list_insert_tail(&uold->zsu_pset_list, pres);
676 else
677 list_insert_tail(&ures->zsu_pset_list, pres);
679 if (zs_usage_compute_pset_usage(uold, ures, pres, NULL,
680 pnew, func) != 0)
681 return (-1);
683 pnew = list_next(&unew->zsu_pset_list, pnew);
685 return (0);
688 static int
689 zs_zone_name(zs_zone_t *zone, char *name, size_t len)
691 return (strlcpy(name, zone->zsz_name, len));
694 static zoneid_t
695 zs_zone_id(zs_zone_t *zone)
697 return (zone->zsz_id);
700 static uint_t
701 zs_zone_iptype(zs_zone_t *zone)
703 return (zone->zsz_iptype);
706 static uint_t
707 zs_zone_cputype(zs_zone_t *zone)
709 return (zone->zsz_cputype);
712 static int
713 zs_zone_poolname(zs_zone_t *zone, char *name, size_t len)
715 return (strlcpy(name, zone->zsz_pool, len));
718 static int
719 zs_zone_psetname(zs_zone_t *zone, char *name, size_t len)
721 return (strlcpy(name, zone->zsz_pset, len));
724 static uint_t
725 zs_zone_schedulers(zs_zone_t *zone)
727 return (zone->zsz_scheds);
730 static uint64_t
731 zs_ts_used_scale(timestruc_t *total, timestruc_t *used, uint64_t scale,
732 boolean_t cap_at_100)
734 double dtotal, dused, pct, dscale;
736 /* If no time yet, treat as zero */
737 if (total->tv_sec == 0 && total->tv_nsec == 0)
738 return (0);
740 dtotal = (double)total->tv_sec +
741 ((double)total->tv_nsec / (double)NANOSEC);
742 dused = (double)used->tv_sec +
743 ((double)used->tv_nsec / (double)NANOSEC);
745 dscale = (double)scale;
746 pct = dused / dtotal * dscale;
747 if (cap_at_100 && pct > dscale)
748 pct = dscale;
750 return ((uint_t)pct);
754 * Convert total and used time into percent used.
756 static uint_t
757 zs_ts_used_pct(timestruc_t *total, timestruc_t *used, boolean_t cap_at_100)
759 return ((uint_t)zs_ts_used_scale(total, used, ZSD_PCT_INT, cap_at_100));
763 * Convert total and used time, plus number of cpus, into number of cpus
764 * used, where 100 equals 1 cpu used.
766 static uint64_t
767 zs_ts_used_cpus(timestruc_t *total, timestruc_t *used, uint_t ncpus,
768 boolean_t cap_at_100)
770 return (zs_ts_used_scale(total, used, ncpus * ZSD_ONE_CPU, cap_at_100));
773 static uint64_t
774 zs_zone_cpu_shares(zs_zone_t *zone)
776 /* No processes found in FSS */
777 if ((zone->zsz_scheds & ZS_SCHED_FSS) == 0)
778 return (ZS_LIMIT_NONE);
780 return (zone->zsz_cpu_shares);
783 static uint64_t
784 zs_zone_cpu_cap(zs_zone_t *zone)
786 return (zone->zsz_cpu_cap);
789 static uint64_t
790 zs_zone_cpu_cap_used(zs_zone_t *zone)
792 if (zone->zsz_cpu_cap == ZS_LIMIT_NONE)
793 return (ZS_LIMIT_NONE);
795 return (zs_ts_used_cpus(&zone->zsz_cap_time, &zone->zsz_cpu_usage,
796 zone->zsz_cpus_online, B_TRUE));
799 static uint64_t
800 zs_zone_cpu_shares_used(zs_zone_t *zone)
802 if (zone->zsz_cpu_shares == ZS_LIMIT_NONE)
803 return (ZS_LIMIT_NONE);
805 if (zone->zsz_cpu_shares == ZS_SHARES_UNLIMITED)
806 return (ZS_LIMIT_NONE);
808 if ((zone->zsz_scheds & ZS_SCHED_FSS) == 0)
809 return (ZS_LIMIT_NONE);
811 return (zs_ts_used_scale(&zone->zsz_share_time, &zone->zsz_cpu_usage,
812 zone->zsz_cpu_shares, B_FALSE));
815 static void
816 zs_zone_cpu_cap_time(zs_zone_t *zone, timestruc_t *ts)
818 *ts = zone->zsz_cap_time;
821 static void
822 zs_zone_cpu_share_time(zs_zone_t *zone, timestruc_t *ts)
824 *ts = zone->zsz_share_time;
827 static void
828 zs_zone_cpu_cap_time_used(zs_zone_t *zone, timestruc_t *ts)
830 *ts = zone->zsz_cpu_usage;
833 static void
834 zs_zone_cpu_share_time_used(zs_zone_t *zone, timestruc_t *ts)
836 *ts = zone->zsz_cpu_usage;
840 static uint64_t
841 zs_uint64_used_scale(uint64_t total, uint64_t used, uint64_t scale,
842 boolean_t cap_at_100)
844 double dtotal, dused, pct, dscale;
846 /* If no time yet, treat as zero */
847 if (total == 0)
848 return (0);
850 dtotal = (double)total;
851 dused = (double)used;
853 dscale = (double)scale;
854 pct = dused / dtotal * dscale;
855 if (cap_at_100 && pct > dscale)
856 pct = dscale;
858 return ((uint64_t)pct);
862 * Convert a total and used value into a percent used.
864 static uint_t
865 zs_uint64_used_pct(uint64_t total, uint64_t used, boolean_t cap_at_100)
867 return ((uint_t)zs_uint64_used_scale(total, used, ZSD_PCT_INT,
868 cap_at_100));
871 static uint_t
872 zs_zone_cpu_cap_pct(zs_zone_t *zone)
874 if (zone->zsz_cpu_cap == ZS_LIMIT_NONE)
875 return (ZS_PCT_NONE);
877 return (zs_ts_used_pct(&zone->zsz_cap_time, &zone->zsz_cpu_usage,
878 B_TRUE));
881 static uint_t
882 zs_zone_cpu_shares_pct(zs_zone_t *zone)
884 if (zone->zsz_cpu_shares == ZS_LIMIT_NONE)
885 return (ZS_PCT_NONE);
887 if (zone->zsz_cpu_shares == ZS_SHARES_UNLIMITED)
888 return (ZS_PCT_NONE);
890 if ((zone->zsz_scheds & ZS_SCHED_FSS) == 0)
891 return (ZS_PCT_NONE);
893 return (zs_ts_used_pct(&zone->zsz_share_time, &zone->zsz_cpu_usage,
894 B_FALSE));
897 static uint64_t
898 zs_zone_physical_memory_cap(zs_zone_t *zone)
900 return (zone->zsz_ram_cap);
903 static uint64_t
904 zs_zone_virtual_memory_cap(zs_zone_t *zone)
906 return (zone->zsz_vm_cap);
909 static uint64_t
910 zs_zone_locked_memory_cap(zs_zone_t *zone)
912 return (zone->zsz_locked_cap);
915 static uint64_t
916 zs_zone_physical_memory_cap_used(zs_zone_t *zone)
918 if (zone->zsz_ram_cap == ZS_LIMIT_NONE)
919 return (ZS_LIMIT_NONE);
921 return (zone->zsz_usage_ram);
924 static uint64_t
925 zs_zone_virtual_memory_cap_used(zs_zone_t *zone)
927 if (zone->zsz_vm_cap == ZS_LIMIT_NONE)
928 return (ZS_LIMIT_NONE);
930 return (zone->zsz_usage_vm);
933 static uint64_t
934 zs_zone_locked_memory_cap_used(zs_zone_t *zone)
936 if (zone->zsz_locked_cap == ZS_LIMIT_NONE)
937 return (ZS_LIMIT_NONE);
939 return (zone->zsz_usage_locked);
942 static int
943 zs_pset_name(zs_pset_t *pset, char *name, size_t len)
945 return (strlcpy(name, pset->zsp_name, len));
948 static psetid_t
949 zs_pset_id(zs_pset_t *pset)
951 return (pset->zsp_id);
954 static uint64_t
955 zs_pset_size(zs_pset_t *pset)
957 return (pset->zsp_size);
960 static uint64_t
961 zs_pset_online(zs_pset_t *pset)
963 return (pset->zsp_online);
966 uint64_t
967 zs_pset_min(zs_pset_t *pset)
969 return (pset->zsp_min);
972 uint64_t
973 zs_pset_max(zs_pset_t *pset)
975 return (pset->zsp_max);
978 static uint_t
979 zs_pset_schedulers(zs_pset_t *pset)
981 return (pset->zsp_scheds);
984 static uint_t
985 zs_pset_zone_schedulers(zs_pset_zone_t *pz)
987 return (pz->zspz_scheds);
990 static uint64_t
991 zs_pset_cpu_shares(zs_pset_t *pset)
993 if (!(pset->zsp_scheds & ZS_SCHED_FSS))
994 return (ZS_LIMIT_NONE);
996 return (pset->zsp_cpu_shares);
999 static uint64_t
1000 zs_pset_zone_cpu_shares(zs_pset_zone_t *pz)
1002 if (!(pz->zspz_scheds & ZS_SCHED_FSS))
1003 return (ZS_LIMIT_NONE);
1005 return (pz->zspz_cpu_shares);
1008 static uint_t
1009 zs_pset_cputype(zs_pset_t *pset)
1011 return (pset->zsp_cputype);
1014 static void
1015 zs_pset_usage_all(zs_pset_t *pset, timestruc_t *ts)
1017 timestruc_t tot;
1019 tot = pset->zsp_usage_kern;
1020 TIMESTRUC_ADD_TIMESTRUC(tot, pset->zsp_usage_zones);
1021 *ts = tot;
1024 static void
1025 zs_pset_usage_idle(zs_pset_t *pset, timestruc_t *ts)
1027 timestruc_t tot, time, idle;
1029 tot = pset->zsp_usage_kern;
1030 TIMESTRUC_ADD_TIMESTRUC(tot, pset->zsp_usage_zones);
1031 time = pset->zsp_total_time;
1032 TIMESTRUC_DELTA(idle, time, tot);
1033 *ts = idle;
1036 static void
1037 zs_pset_usage_kernel(zs_pset_t *pset, timestruc_t *ts)
1039 *ts = pset->zsp_usage_kern;
1042 static void
1043 zs_pset_usage_zones(zs_pset_t *pset, timestruc_t *ts)
1045 *ts = pset->zsp_usage_zones;
1048 static uint_t
1049 zs_pset_usage_all_pct(zs_pset_t *pset)
1051 timestruc_t tot;
1053 tot = pset->zsp_usage_kern;
1054 TIMESTRUC_ADD_TIMESTRUC(tot, pset->zsp_usage_zones);
1056 return (zs_ts_used_pct(&pset->zsp_total_time, &tot, B_TRUE));
1059 static uint_t
1060 zs_pset_usage_idle_pct(zs_pset_t *pset)
1062 timestruc_t tot, idle;
1064 tot = pset->zsp_usage_kern;
1065 TIMESTRUC_ADD_TIMESTRUC(tot, pset->zsp_usage_zones);
1066 TIMESTRUC_DELTA(idle, pset->zsp_total_time, tot);
1068 return (zs_ts_used_pct(&pset->zsp_total_time, &idle, B_TRUE));
1071 static uint_t
1072 zs_pset_usage_kernel_pct(zs_pset_t *pset)
1074 return (zs_ts_used_pct(&pset->zsp_total_time, &pset->zsp_usage_kern,
1075 B_TRUE));
1078 static uint_t
1079 zs_pset_usage_zones_pct(zs_pset_t *pset)
1081 return (zs_ts_used_pct(&pset->zsp_total_time, &pset->zsp_usage_zones,
1082 B_TRUE));
1085 static uint_t
1086 zs_pset_usage_all_cpus(zs_pset_t *pset)
1088 timestruc_t tot;
1090 tot = pset->zsp_usage_kern;
1091 TIMESTRUC_ADD_TIMESTRUC(tot, pset->zsp_usage_zones);
1092 return (zs_ts_used_cpus(&pset->zsp_total_time, &tot, pset->zsp_online,
1093 B_TRUE));
1096 static uint_t
1097 zs_pset_usage_idle_cpus(zs_pset_t *pset)
1099 timestruc_t tot, idle;
1101 tot = pset->zsp_usage_kern;
1102 TIMESTRUC_ADD_TIMESTRUC(tot, pset->zsp_usage_zones);
1103 TIMESTRUC_DELTA(idle, pset->zsp_total_time, tot);
1105 return (zs_ts_used_cpus(&pset->zsp_total_time, &tot, pset->zsp_online,
1106 B_TRUE));
1109 static uint_t
1110 zs_pset_usage_kernel_cpus(zs_pset_t *pset)
1112 return (zs_ts_used_cpus(&pset->zsp_total_time, &pset->zsp_usage_kern,
1113 pset->zsp_online, B_TRUE));
1116 static uint64_t
1117 zs_pset_usage_zones_cpus(zs_pset_t *pset)
1119 return (zs_ts_used_cpus(&pset->zsp_total_time, &pset->zsp_usage_zones,
1120 pset->zsp_online, B_TRUE));
1123 static void
1124 zs_pset_zone_usage_time(zs_pset_zone_t *pz, timestruc_t *t)
1126 *t = pz->zspz_cpu_usage;
1129 static uint_t
1130 zs_pset_zone_usage_cpus(zs_pset_zone_t *pz)
1132 return (zs_ts_used_cpus(&pz->zspz_pset->zsp_total_time,
1133 &pz->zspz_cpu_usage, pz->zspz_pset->zsp_online, B_TRUE));
1136 static uint_t
1137 zs_pset_zone_usage_pct_pset(zs_pset_zone_t *pz)
1139 return (zs_ts_used_pct(&pz->zspz_pset->zsp_total_time,
1140 &pz->zspz_cpu_usage, B_TRUE));
1143 static uint64_t
1144 zs_pset_zone_cpu_cap(zs_pset_zone_t *pz)
1146 return (pz->zspz_zone->zsz_cpu_cap);
1149 static uint_t
1150 zs_pset_zone_usage_pct_cpu_cap(zs_pset_zone_t *pz)
1152 zs_zone_t *zone = pz->zspz_zone;
1154 if (zone->zsz_cpu_cap == ZS_LIMIT_NONE) {
1155 return (ZS_PCT_NONE);
1157 return (zs_ts_used_pct(&zone->zsz_cap_time,
1158 &pz->zspz_cpu_usage, B_TRUE));
1162 * Return the fraction of total shares for a pset allocated to the zone.
1164 static uint_t
1165 zs_pset_zone_usage_pct_pset_shares(zs_pset_zone_t *pz)
1167 zs_pset_t *pset = pz->zspz_pset;
1169 if (!(pz->zspz_scheds & ZS_SCHED_FSS))
1170 return (ZS_PCT_NONE);
1172 if (pz->zspz_cpu_shares == ZS_LIMIT_NONE)
1173 return (ZS_PCT_NONE);
1175 if (pz->zspz_cpu_shares == ZS_SHARES_UNLIMITED)
1176 return (ZS_PCT_NONE);
1178 if (pz->zspz_pset->zsp_cpu_shares == 0)
1179 return (0);
1181 if (pz->zspz_cpu_shares == 0)
1182 return (0);
1184 return (zs_uint64_used_pct(pset->zsp_cpu_shares, pz->zspz_cpu_shares,
1185 B_TRUE));
1189 * Of a zones shares, what percent of cpu time is it using. For instance,
1190 * if a zone has 50% of shares, and is using 50% of the cpu time, then it is
1191 * using 100% of its share.
1193 static uint_t
1194 zs_pset_zone_usage_pct_cpu_shares(zs_pset_zone_t *pz)
1196 timestruc_t tot, time;
1197 double sharefactor;
1198 double total;
1199 double used;
1200 double pct;
1202 if (!(pz->zspz_scheds & ZS_SCHED_FSS))
1203 return (ZS_PCT_NONE);
1205 if (pz->zspz_cpu_shares == ZS_LIMIT_NONE)
1206 return (ZS_PCT_NONE);
1208 if (pz->zspz_cpu_shares == ZS_SHARES_UNLIMITED)
1209 return (ZS_PCT_NONE);
1211 if (pz->zspz_cpu_shares == 0)
1212 return (ZS_PCT_NONE);
1214 sharefactor = (double)zs_pset_zone_usage_pct_pset_shares(pz);
1216 /* Common scaling function won't do sharefactor. */
1217 time = pz->zspz_pset->zsp_total_time;
1218 tot = pz->zspz_cpu_usage;
1220 total = (double)time.tv_sec +
1221 ((double)time.tv_nsec / (double)NANOSEC);
1222 total = total * (sharefactor / ZSD_PCT_DOUBLE);
1223 used = (double)tot.tv_sec +
1224 ((double)tot.tv_nsec / (double)NANOSEC);
1226 pct = used / total * ZSD_PCT_DOUBLE;
1227 /* Allow percent of share used to exceed 100% */
1228 return ((uint_t)pct);
1231 static void
1232 zs_cpu_total_time(zs_usage_t *usage, timestruc_t *ts)
1234 *ts = usage->zsu_system->zss_cpu_total_time;
1237 static void
1238 zs_cpu_usage_all(zs_usage_t *usage, timestruc_t *ts)
1240 timestruc_t tot;
1242 tot.tv_sec = 0;
1243 tot.tv_nsec = 0;
1244 TIMESTRUC_ADD_TIMESTRUC(tot, usage->zsu_system->zss_cpu_usage_kern);
1245 TIMESTRUC_ADD_TIMESTRUC(tot, usage->zsu_system->zss_cpu_usage_zones);
1246 *ts = tot;
1249 static void
1250 zs_cpu_usage_idle(zs_usage_t *usage, timestruc_t *ts)
1252 timestruc_t tot, time, idle;
1254 tot.tv_sec = 0;
1255 tot.tv_nsec = 0;
1256 tot = usage->zsu_system->zss_cpu_usage_kern;
1257 TIMESTRUC_ADD_TIMESTRUC(tot, usage->zsu_system->zss_cpu_usage_zones);
1258 time = usage->zsu_system->zss_cpu_total_time;
1259 TIMESTRUC_DELTA(idle, time, tot);
1260 *ts = idle;
1263 static uint_t
1264 zs_cpu_usage_all_pct(zs_usage_t *usage)
1266 timestruc_t tot;
1268 tot = usage->zsu_system->zss_cpu_usage_kern;
1269 TIMESTRUC_ADD_TIMESTRUC(tot, usage->zsu_system->zss_cpu_usage_zones);
1271 return (zs_ts_used_pct(&usage->zsu_system->zss_cpu_total_time,
1272 &tot, B_TRUE));
1276 static uint_t
1277 zs_cpu_usage_idle_pct(zs_usage_t *usage)
1279 timestruc_t tot, idle;
1281 tot = usage->zsu_system->zss_cpu_usage_kern;
1282 TIMESTRUC_ADD_TIMESTRUC(tot, usage->zsu_system->zss_cpu_usage_zones);
1283 TIMESTRUC_DELTA(idle, usage->zsu_system->zss_cpu_total_time, tot);
1285 return (zs_ts_used_pct(&usage->zsu_system->zss_cpu_total_time,
1286 &idle, B_TRUE));
1289 static void
1290 zs_cpu_usage_kernel(zs_usage_t *usage, timestruc_t *ts)
1292 *ts = usage->zsu_system->zss_cpu_usage_kern;
1295 static uint_t
1296 zs_cpu_usage_kernel_pct(zs_usage_t *usage)
1298 return (zs_ts_used_pct(&usage->zsu_system->zss_cpu_total_time,
1299 &usage->zsu_system->zss_cpu_usage_kern, B_TRUE));
1302 static void
1303 zs_cpu_usage_zones(zs_usage_t *usage, timestruc_t *ts)
1305 *ts = usage->zsu_system->zss_cpu_usage_zones;
1309 static uint_t
1310 zs_cpu_usage_zones_pct(zs_usage_t *usage)
1312 return (zs_ts_used_pct(&usage->zsu_system->zss_cpu_total_time,
1313 &usage->zsu_system->zss_cpu_usage_zones, B_TRUE));
1317 static void
1318 zs_cpu_usage_zone(zs_zone_t *zone, timestruc_t *ts)
1320 *ts = zone->zsz_cpu_usage;
1323 static uint64_t
1324 zs_cpu_total_cpu(zs_usage_t *usage)
1326 return (usage->zsu_system->zss_ncpus_online * ZSD_ONE_CPU);
1329 static uint64_t
1330 zs_cpu_usage_all_cpu(zs_usage_t *usage)
1332 timestruc_t tot;
1334 tot = usage->zsu_system->zss_cpu_usage_kern;
1335 TIMESTRUC_ADD_TIMESTRUC(tot, usage->zsu_system->zss_cpu_usage_zones);
1337 return (zs_ts_used_cpus(&usage->zsu_system->zss_cpu_total_time,
1338 &tot, usage->zsu_system->zss_ncpus_online, B_TRUE));
1341 static uint64_t
1342 zs_cpu_usage_idle_cpu(zs_usage_t *usage)
1344 timestruc_t tot, idle;
1346 tot = usage->zsu_system->zss_cpu_usage_kern;
1347 TIMESTRUC_ADD_TIMESTRUC(tot, usage->zsu_system->zss_cpu_usage_zones);
1348 TIMESTRUC_DELTA(idle, usage->zsu_system->zss_cpu_total_time, tot);
1350 return (zs_ts_used_cpus(&usage->zsu_system->zss_cpu_total_time,
1351 &idle, usage->zsu_system->zss_ncpus_online, B_TRUE));
1354 static uint64_t
1355 zs_cpu_usage_kernel_cpu(zs_usage_t *usage)
1357 return (zs_ts_used_cpus(&usage->zsu_system->zss_cpu_total_time,
1358 &usage->zsu_system->zss_cpu_usage_kern,
1359 usage->zsu_system->zss_ncpus_online, B_TRUE));
1362 static uint64_t
1363 zs_cpu_usage_zones_cpu(zs_usage_t *usage)
1365 return (zs_ts_used_cpus(&usage->zsu_system->zss_cpu_total_time,
1366 &usage->zsu_system->zss_cpu_usage_kern,
1367 usage->zsu_system->zss_ncpus_online, B_TRUE));
1370 static uint64_t
1371 zs_cpu_usage_zone_cpu(zs_zone_t *zone)
1373 return (zs_ts_used_cpus(&zone->zsz_pset_time, &zone->zsz_cpu_usage,
1374 zone->zsz_cpus_online, B_TRUE));
1377 static uint_t
1378 zs_cpu_usage_zone_pct(zs_zone_t *zone)
1380 return (zs_ts_used_pct(&zone->zsz_pset_time, &zone->zsz_cpu_usage,
1381 B_TRUE));
1384 static uint64_t
1385 zs_physical_memory_total(zs_usage_t *usage)
1387 return (usage->zsu_system->zss_ram_total);
1391 static uint64_t
1392 zs_physical_memory_usage_all(zs_usage_t *usage)
1394 return (usage->zsu_system->zss_ram_kern +
1395 usage->zsu_system->zss_ram_zones);
1398 static uint_t
1399 zs_physical_memory_usage_all_pct(zs_usage_t *usage)
1401 zs_system_t *system = usage->zsu_system;
1403 return (zs_uint64_used_pct(system->zss_ram_total,
1404 (system->zss_ram_kern + system->zss_ram_zones), B_TRUE));
1407 static uint64_t
1408 zs_physical_memory_usage_free(zs_usage_t *usage)
1410 return (usage->zsu_system->zss_ram_total -
1411 (usage->zsu_system->zss_ram_kern +
1412 usage->zsu_system->zss_ram_zones));
1415 static uint_t
1416 zs_physical_memory_usage_free_pct(zs_usage_t *usage)
1418 return (ZSD_PCT_INT - zs_physical_memory_usage_all_pct(usage));
1421 static uint64_t
1422 zs_physical_memory_usage_kernel(zs_usage_t *usage)
1424 return (usage->zsu_system->zss_ram_kern);
1427 static uint_t
1428 zs_physical_memory_usage_kernel_pct(zs_usage_t *usage)
1430 zs_system_t *system = usage->zsu_system;
1432 return (zs_uint64_used_pct(system->zss_ram_total,
1433 system->zss_ram_kern, B_TRUE));
1436 static uint64_t
1437 zs_physical_memory_usage_zones(zs_usage_t *usage)
1439 return (usage->zsu_system->zss_ram_zones);
1442 static uint_t
1443 zs_physical_memory_usage_zones_pct(zs_usage_t *usage)
1445 zs_system_t *system = usage->zsu_system;
1447 return (zs_uint64_used_pct(system->zss_ram_total,
1448 system->zss_ram_zones, B_TRUE));
1451 static uint64_t
1452 zs_physical_memory_usage_zone(zs_zone_t *zone)
1454 return (zone->zsz_usage_ram);
1457 static uint_t
1458 zs_physical_memory_usage_zone_pct(zs_zone_t *zone)
1460 zs_system_t *system = zone->zsz_system;
1462 return (zs_uint64_used_pct(system->zss_ram_total,
1463 zone->zsz_usage_ram, B_TRUE));
1466 static uint_t
1467 zs_zone_physical_memory_cap_pct(zs_zone_t *zone)
1469 if (zone->zsz_ram_cap == ZS_LIMIT_NONE)
1470 return (ZS_PCT_NONE);
1472 if (zone->zsz_ram_cap == 0) {
1473 return (0);
1476 /* Allow ram cap to exeed 100% */
1477 return (zs_uint64_used_pct(zone->zsz_ram_cap,
1478 zone->zsz_usage_ram, B_FALSE));
1480 static uint64_t
1481 zs_virtual_memory_total(zs_usage_t *usage)
1483 return (usage->zsu_system->zss_vm_total);
1486 static uint64_t
1487 zs_virtual_memory_usage_all(zs_usage_t *usage)
1489 return (usage->zsu_system->zss_vm_kern +
1490 usage->zsu_system->zss_vm_zones);
1492 static uint64_t
1493 zs_virtual_memory_usage_free(zs_usage_t *usage)
1495 return (usage->zsu_system->zss_vm_total -
1496 (usage->zsu_system->zss_vm_kern +
1497 usage->zsu_system->zss_vm_zones));
1499 static uint_t
1500 zs_virtual_memory_usage_all_pct(zs_usage_t *usage)
1502 zs_system_t *system = usage->zsu_system;
1504 return (zs_uint64_used_pct(system->zss_vm_total,
1505 (system->zss_vm_kern + system->zss_vm_zones), B_TRUE));
1509 static uint_t
1510 zs_virtual_memory_usage_free_pct(zs_usage_t *usage)
1512 return (ZSD_PCT_INT - zs_virtual_memory_usage_all_pct(usage));
1515 static uint64_t
1516 zs_virtual_memory_usage_kernel(zs_usage_t *usage)
1518 return (usage->zsu_system->zss_vm_kern);
1521 static uint_t
1522 zs_virtual_memory_usage_kernel_pct(zs_usage_t *usage)
1524 zs_system_t *system = usage->zsu_system;
1526 return (zs_uint64_used_pct(system->zss_vm_total,
1527 system->zss_vm_kern, B_TRUE));
1530 static uint64_t
1531 zs_virtual_memory_usage_zones(zs_usage_t *usage)
1533 return (usage->zsu_system->zss_vm_zones);
1536 static uint_t
1537 zs_virtual_memory_usage_zones_pct(zs_usage_t *usage)
1539 zs_system_t *system = usage->zsu_system;
1541 return (zs_uint64_used_pct(system->zss_vm_total,
1542 system->zss_vm_zones, B_TRUE));
1545 static uint64_t
1546 zs_virtual_memory_usage_zone(zs_zone_t *zone)
1548 return (zone->zsz_usage_vm);
1551 static uint_t
1552 zs_virtual_memory_usage_zone_pct(zs_zone_t *zone)
1554 zs_system_t *system = zone->zsz_system;
1556 return (zs_uint64_used_pct(system->zss_vm_total,
1557 zone->zsz_usage_vm, B_TRUE));
1561 static uint_t
1562 zs_zone_virtual_memory_cap_pct(zs_zone_t *zone)
1564 if (zone->zsz_vm_cap == ZS_LIMIT_NONE)
1565 return (ZS_PCT_NONE);
1567 if (zone->zsz_vm_cap == 0)
1568 return (0);
1570 return (zs_uint64_used_pct(zone->zsz_vm_cap,
1571 zone->zsz_usage_vm, B_TRUE));
1574 static uint64_t
1575 zs_locked_memory_total(zs_usage_t *usage)
1577 return (usage->zsu_system->zss_ram_total);
1580 static uint64_t
1581 zs_locked_memory_usage_all(zs_usage_t *usage)
1583 return (usage->zsu_system->zss_locked_kern +
1584 usage->zsu_system->zss_locked_zones);
1586 static uint64_t
1587 zs_locked_memory_usage_free(zs_usage_t *usage)
1589 return (usage->zsu_system->zss_ram_total -
1590 (usage->zsu_system->zss_locked_kern +
1591 usage->zsu_system->zss_locked_zones));
1594 static uint_t
1595 zs_locked_memory_usage_all_pct(zs_usage_t *usage)
1597 zs_system_t *system = usage->zsu_system;
1599 return (zs_uint64_used_pct(system->zss_ram_total,
1600 (system->zss_locked_kern + system->zss_locked_zones), B_TRUE));
1603 static uint_t
1604 zs_locked_memory_usage_free_pct(zs_usage_t *usage)
1606 return (ZSD_PCT_INT - zs_locked_memory_usage_all_pct(usage));
1610 static uint64_t
1611 zs_locked_memory_usage_kernel(zs_usage_t *usage)
1613 return (usage->zsu_system->zss_locked_kern);
1616 static uint_t
1617 zs_locked_memory_usage_kernel_pct(zs_usage_t *usage)
1619 zs_system_t *system = usage->zsu_system;
1621 return (zs_uint64_used_pct(system->zss_ram_total,
1622 system->zss_locked_kern, B_TRUE));
1625 static uint64_t
1626 zs_locked_memory_usage_zones(zs_usage_t *usage)
1628 return (usage->zsu_system->zss_locked_zones);
1631 static uint_t
1632 zs_locked_memory_usage_zones_pct(zs_usage_t *usage)
1634 zs_system_t *system = usage->zsu_system;
1636 return (zs_uint64_used_pct(system->zss_ram_total,
1637 system->zss_locked_zones, B_TRUE));
1640 static uint64_t
1641 zs_locked_memory_usage_zone(zs_zone_t *zone)
1643 return (zone->zsz_usage_locked);
1646 static uint_t
1647 zs_locked_memory_usage_zone_pct(zs_zone_t *zone)
1649 zs_system_t *system = zone->zsz_system;
1651 return (zs_uint64_used_pct(system->zss_ram_total,
1652 zone->zsz_usage_locked, B_TRUE));
1655 static uint_t
1656 zs_zone_locked_memory_cap_pct(zs_zone_t *zone)
1658 if (zone->zsz_locked_cap == ZS_LIMIT_NONE)
1659 return (ZS_PCT_NONE);
1661 if (zone->zsz_locked_cap == 0)
1662 return (0);
1664 return (zs_uint64_used_pct(zone->zsz_locked_cap,
1665 zone->zsz_usage_locked, B_TRUE));
1668 static uint64_t
1669 zs_disk_swap_total(zs_usage_t *usage)
1671 return (usage->zsu_system->zss_swap_total);
1674 static uint64_t
1675 zs_disk_swap_usage_all(zs_usage_t *usage)
1677 return (usage->zsu_system->zss_swap_used);
1680 static uint_t
1681 zs_disk_swap_usage_all_pct(zs_usage_t *usage)
1683 return (zs_uint64_used_pct(usage->zsu_system->zss_swap_total,
1684 usage->zsu_system->zss_swap_used, B_TRUE));
1687 static uint64_t
1688 zs_disk_swap_usage_free(zs_usage_t *usage)
1690 return (usage->zsu_system->zss_swap_total -
1691 usage->zsu_system->zss_swap_used);
1694 static uint_t
1695 zs_disk_swap_usage_free_pct(zs_usage_t *usage)
1697 return (ZSD_PCT_INT - zs_disk_swap_usage_all_pct(usage));
1700 static uint64_t
1701 zs_processes_total(zs_usage_t *usage)
1703 return (usage->zsu_system->zss_processes_max);
1706 static uint64_t
1707 zs_lwps_total(zs_usage_t *usage)
1709 return (usage->zsu_system->zss_lwps_max);
1712 static uint64_t
1713 zs_shm_total(zs_usage_t *usage)
1715 return (usage->zsu_system->zss_shm_max);
1718 static uint64_t
1719 zs_shmids_total(zs_usage_t *usage)
1721 return (usage->zsu_system->zss_shmids_max);
1724 static uint64_t
1725 zs_semids_total(zs_usage_t *usage)
1727 return (usage->zsu_system->zss_semids_max);
1730 static uint64_t
1731 zs_msgids_total(zs_usage_t *usage)
1733 return (usage->zsu_system->zss_msgids_max);
1736 static uint64_t
1737 zs_lofi_total(zs_usage_t *usage)
1739 return (usage->zsu_system->zss_lofi_max);
1742 static uint64_t
1743 zs_processes_usage_all(zs_usage_t *usage)
1745 return (usage->zsu_system->zss_processes);
1748 static uint64_t
1749 zs_lwps_usage_all(zs_usage_t *usage)
1751 return (usage->zsu_system->zss_lwps);
1754 static uint64_t
1755 zs_shm_usage_all(zs_usage_t *usage)
1757 return (usage->zsu_system->zss_shm);
1760 static uint64_t
1761 zs_shmids_usage_all(zs_usage_t *usage)
1763 return (usage->zsu_system->zss_shmids);
1766 static uint64_t
1767 zs_semids_usage_all(zs_usage_t *usage)
1769 return (usage->zsu_system->zss_semids);
1772 static uint64_t
1773 zs_msgids_usage_all(zs_usage_t *usage)
1775 return (usage->zsu_system->zss_msgids);
1778 static uint64_t
1779 zs_lofi_usage_all(zs_usage_t *usage)
1781 return (usage->zsu_system->zss_lofi);
1783 static uint64_t
1784 zs_processes_usage_all_pct(zs_usage_t *usage)
1786 zs_system_t *system = usage->zsu_system;
1788 return (zs_uint64_used_pct(system->zss_processes_max,
1789 system->zss_processes, B_TRUE));
1792 static uint_t
1793 zs_lwps_usage_all_pct(zs_usage_t *usage)
1795 zs_system_t *system = usage->zsu_system;
1797 return (zs_uint64_used_pct(system->zss_lwps_max,
1798 system->zss_lwps, B_TRUE));
1801 static uint_t
1802 zs_shm_usage_all_pct(zs_usage_t *usage)
1804 zs_system_t *system = usage->zsu_system;
1806 return (zs_uint64_used_pct(system->zss_shm_max,
1807 system->zss_shm, B_TRUE));
1810 static uint_t
1811 zs_shmids_usage_all_pct(zs_usage_t *usage)
1813 zs_system_t *system = usage->zsu_system;
1815 return (zs_uint64_used_pct(system->zss_shmids_max,
1816 system->zss_shmids, B_TRUE));
1819 static uint64_t
1820 zs_semids_usage_all_pct(zs_usage_t *usage)
1822 zs_system_t *system = usage->zsu_system;
1824 return (zs_uint64_used_pct(system->zss_semids_max,
1825 system->zss_semids, B_TRUE));
1828 static uint64_t
1829 zs_msgids_usage_all_pct(zs_usage_t *usage)
1831 zs_system_t *system = usage->zsu_system;
1833 return (zs_uint64_used_pct(system->zss_msgids_max,
1834 system->zss_msgids, B_TRUE));
1837 static uint64_t
1838 zs_lofi_usage_all_pct(zs_usage_t *usage)
1840 zs_system_t *system = usage->zsu_system;
1842 return (zs_uint64_used_pct(system->zss_lofi_max,
1843 system->zss_lofi, B_TRUE));
1846 static uint64_t
1847 zs_processes_usage_zone(zs_zone_t *zone)
1849 return (zone->zsz_processes);
1852 static uint64_t
1853 zs_lwps_usage_zone(zs_zone_t *zone)
1855 return (zone->zsz_lwps);
1858 static uint64_t
1859 zs_shm_usage_zone(zs_zone_t *zone)
1861 return (zone->zsz_shm);
1864 static uint64_t
1865 zs_shmids_usage_zone(zs_zone_t *zone)
1867 return (zone->zsz_shmids);
1870 static uint64_t
1871 zs_semids_usage_zone(zs_zone_t *zone)
1873 return (zone->zsz_semids);
1876 static uint64_t
1877 zs_msgids_usage_zone(zs_zone_t *zone)
1879 return (zone->zsz_msgids);
1882 static uint64_t
1883 zs_lofi_usage_zone(zs_zone_t *zone)
1885 return (zone->zsz_lofi);
1888 static uint_t
1889 zs_processes_usage_zone_pct(zs_zone_t *zone)
1891 zs_system_t *system = zone->zsz_system;
1893 return (zs_uint64_used_pct(system->zss_processes_max,
1894 zone->zsz_processes, B_TRUE));
1897 static uint_t
1898 zs_lwps_usage_zone_pct(zs_zone_t *zone)
1900 zs_system_t *system = zone->zsz_system;
1902 return (zs_uint64_used_pct(system->zss_lwps_max,
1903 zone->zsz_lwps, B_TRUE));
1906 static uint_t
1907 zs_shm_usage_zone_pct(zs_zone_t *zone)
1909 zs_system_t *system = zone->zsz_system;
1911 return (zs_uint64_used_pct(system->zss_shm_max,
1912 zone->zsz_shm, B_TRUE));
1915 static uint_t
1916 zs_shmids_usage_zone_pct(zs_zone_t *zone)
1918 zs_system_t *system = zone->zsz_system;
1920 return (zs_uint64_used_pct(system->zss_shmids_max,
1921 zone->zsz_shmids, B_TRUE));
1924 static uint_t
1925 zs_semids_usage_zone_pct(zs_zone_t *zone)
1927 zs_system_t *system = zone->zsz_system;
1929 return (zs_uint64_used_pct(system->zss_semids_max,
1930 zone->zsz_semids, B_TRUE));
1933 static uint_t
1934 zs_msgids_usage_zone_pct(zs_zone_t *zone)
1936 zs_system_t *system = zone->zsz_system;
1938 return (zs_uint64_used_pct(system->zss_msgids_max,
1939 zone->zsz_msgids, B_TRUE));
1942 static uint_t
1943 zs_lofi_usage_zone_pct(zs_zone_t *zone)
1945 zs_system_t *system = zone->zsz_system;
1947 return (zs_uint64_used_pct(system->zss_lofi_max,
1948 zone->zsz_lofi, B_TRUE));
1951 static uint_t
1952 zs_processes_zone_cap_pct(zs_zone_t *zone)
1954 if (zone->zsz_processes_cap == ZS_LIMIT_NONE)
1955 return (ZS_PCT_NONE);
1957 if (zone->zsz_processes_cap == 0)
1958 return (0);
1960 return (zs_uint64_used_pct(zone->zsz_processes_cap,
1961 zone->zsz_processes, B_TRUE));
1964 static uint_t
1965 zs_lwps_zone_cap_pct(zs_zone_t *zone)
1967 if (zone->zsz_lwps_cap == ZS_LIMIT_NONE)
1968 return (ZS_PCT_NONE);
1970 if (zone->zsz_lwps_cap == 0)
1971 return (0);
1973 return (zs_uint64_used_pct(zone->zsz_lwps_cap, zone->zsz_lwps, B_TRUE));
1976 static uint_t
1977 zs_shm_zone_cap_pct(zs_zone_t *zone)
1979 if (zone->zsz_shm_cap == ZS_LIMIT_NONE)
1980 return (ZS_PCT_NONE);
1982 if (zone->zsz_shm_cap == 0)
1983 return (0);
1985 return (zs_uint64_used_pct(zone->zsz_shm_cap, zone->zsz_shm, B_TRUE));
1988 static uint_t
1989 zs_shmids_zone_cap_pct(zs_zone_t *zone)
1991 if (zone->zsz_shmids_cap == ZS_LIMIT_NONE)
1992 return (ZS_PCT_NONE);
1994 if (zone->zsz_shmids_cap == 0)
1995 return (0);
1997 return (zs_uint64_used_pct(zone->zsz_shmids_cap, zone->zsz_shmids,
1998 B_TRUE));
2001 static uint_t
2002 zs_semids_zone_cap_pct(zs_zone_t *zone)
2004 if (zone->zsz_semids_cap == ZS_LIMIT_NONE)
2005 return (ZS_PCT_NONE);
2007 if (zone->zsz_semids_cap == 0)
2008 return (0);
2010 return (zs_uint64_used_pct(zone->zsz_semids_cap, zone->zsz_semids,
2011 B_TRUE));
2014 static uint_t
2015 zs_msgids_zone_cap_pct(zs_zone_t *zone)
2017 if (zone->zsz_msgids_cap == ZS_LIMIT_NONE)
2018 return (ZS_PCT_NONE);
2020 if (zone->zsz_msgids_cap == 0)
2021 return (0);
2023 return (zs_uint64_used_pct(zone->zsz_msgids_cap, zone->zsz_msgids,
2024 B_TRUE));
2027 static uint_t
2028 zs_lofi_zone_cap_pct(zs_zone_t *zone)
2030 if (zone->zsz_lofi_cap == ZS_LIMIT_NONE)
2031 return (ZS_PCT_NONE);
2033 if (zone->zsz_lofi_cap == 0)
2034 return (0);
2036 return (zs_uint64_used_pct(zone->zsz_lofi_cap, zone->zsz_lofi,
2037 B_TRUE));
2040 /* All funcs this line should be static */
2042 void
2043 zs_close(zs_ctl_t *ctl)
2045 (void) close(ctl->zsctl_door);
2046 zs_usage_free(ctl->zsctl_start);
2047 free(ctl);
2051 * ERRORS
2053 * EINTR signal received, process forked, or zonestatd exited
2054 * ESRCH zonestatd not responding
2056 static zs_usage_t *
2057 zs_usage_read_internal(zs_ctl_t *ctl, int init)
2059 int fd = -1;
2060 uint_t i, j;
2061 zs_usage_t *usage;
2062 zs_zone_t *zone = NULL;
2063 zs_pset_t *pset = NULL;
2064 zs_pset_zone_t *pz;
2065 char *next;
2066 uint64_t cmd[2];
2067 door_arg_t params;
2069 fd = ctl->zsctl_door;
2070 cmd[0] = ZSD_CMD_READ;
2071 cmd[1] = ctl->zsctl_gen;
2072 params.data_ptr = (char *)cmd;
2073 params.data_size = sizeof (cmd);
2074 params.desc_ptr = NULL;
2075 params.desc_num = 0;
2076 params.rbuf = NULL;
2077 params.rsize = 0;
2079 if (door_call(fd, &params) != 0) {
2080 if (errno != EINTR)
2081 errno = ESRCH;
2082 return (NULL);
2085 if (params.rbuf == NULL) {
2086 errno = ESRCH;
2087 return (NULL);
2089 /* LINTED */
2090 usage = (zs_usage_t *)params.data_ptr;
2091 ctl->zsctl_gen = usage->zsu_gen;
2092 usage->zsu_mmap = B_TRUE;
2093 usage->zsu_intervals = 0;
2095 list_create(&usage->zsu_zone_list, sizeof (zs_zone_t),
2096 offsetof(zs_zone_t, zsz_next));
2097 list_create(&usage->zsu_pset_list, sizeof (zs_pset_t),
2098 offsetof(zs_pset_t, zsp_next));
2100 /* Fix up next pointers inside usage_t */
2101 next = (char *)usage;
2102 next += sizeof (zs_usage_t);
2104 /* LINTED */
2105 usage->zsu_system = (zs_system_t *)next;
2106 next += sizeof (zs_system_t);
2108 for (i = 0; i < usage->zsu_nzones; i++) {
2109 /* LINTED */
2110 zone = (zs_zone_t *)next;
2111 list_insert_tail(&usage->zsu_zone_list, zone);
2112 next += sizeof (zs_zone_t);
2113 zone->zsz_system = usage->zsu_system;
2114 zone->zsz_intervals = 0;
2117 for (i = 0; i < usage->zsu_npsets; i++) {
2118 /* LINTED */
2119 pset = (zs_pset_t *)next;
2120 list_insert_tail(&usage->zsu_pset_list, pset);
2121 next += sizeof (zs_pset_t);
2122 list_create(&pset->zsp_usage_list, sizeof (zs_pset_zone_t),
2123 offsetof(zs_pset_zone_t, zspz_next));
2124 for (j = 0; j < pset->zsp_nusage; j++) {
2125 /* LINTED */
2126 pz = (zs_pset_zone_t *)next;
2127 list_insert_tail(&pset->zsp_usage_list, pz);
2128 next += sizeof (zs_pset_zone_t);
2129 pz->zspz_pset = pset;
2130 pz->zspz_zone =
2131 zs_lookup_zone_byid(usage, pz->zspz_zoneid);
2132 assert(pz->zspz_zone != NULL);
2133 pz->zspz_intervals = 0;
2135 pset->zsp_intervals = 0;
2137 if (init)
2138 return (usage);
2141 * If current usage tracking started after start usage, then
2142 * no need to subtract start usage. This really can't happen,
2143 * as zonestatd should never start over while this client is
2144 * connected.
2146 if (usage->zsu_hrstart > ctl->zsctl_start->zsu_hrtime) {
2147 return (usage);
2151 * Compute usage relative to first open. Usage returned by
2152 * zonestatd starts at an arbitrary point in the past.
2156 (void) zs_usage_compute(usage, ctl->zsctl_start, usage,
2157 ZS_COMPUTE_USAGE_INTERVAL);
2159 return (usage);
2162 zs_usage_t *
2163 zs_usage_read(zs_ctl_t *ctl)
2165 return (zs_usage_read_internal(ctl, B_FALSE));
2169 * Open connection to zonestatd. NULL of failure, with errno set:
2171 * EPERM: Insufficent privilege (no PRIV_PROC_INFO)
2172 * ESRCH: Zones monitoring service not available or responding
2173 * ENOTSUP: Incompatiable zones monitoring service version.
2174 * EINTR: Server exited or client forked.
2175 * ENOMEM: as malloc(3c)
2176 * EAGAIN: asl malloc(3c)
2179 zs_ctl_t *
2180 zs_open()
2182 zs_ctl_t *ctl;
2183 int cmd[2];
2184 int *res;
2185 int fd;
2186 door_arg_t params;
2187 door_desc_t *door;
2188 int errno_save;
2190 ctl = calloc(sizeof (zs_ctl_t), 1);
2191 if (ctl == NULL)
2192 return (NULL);
2194 fd = zs_connect_zonestatd();
2195 if (fd < 0) {
2196 free(ctl);
2197 errno = ESRCH;
2198 return (NULL);
2201 cmd[0] = ZSD_CMD_CONNECT;
2202 cmd[1] = ZS_VERSION;
2203 params.data_ptr = (char *)cmd;
2204 params.data_size = sizeof (cmd);
2205 params.desc_ptr = NULL;
2206 params.desc_num = 0;
2207 params.rbuf = NULL;
2208 params.rsize = 0;
2209 if (door_call(fd, &params) != 0) {
2210 errno_save = errno;
2211 free(ctl);
2212 (void) close(fd);
2213 if (errno_save == EINTR)
2214 errno = EINTR;
2215 else
2216 errno = ESRCH;
2217 return (NULL);
2219 (void) close(fd);
2220 /* LINTED */
2221 res = (int *)params.data_ptr;
2222 if (res[1] == ZSD_STATUS_VERSION_MISMATCH) {
2223 free(ctl);
2224 errno = ENOTSUP;
2225 return (NULL);
2227 if (res[1] == ZSD_STATUS_PERMISSION) {
2228 free(ctl);
2229 errno = EPERM;
2230 return (NULL);
2232 if (res[1] != ZSD_STATUS_OK) {
2233 free(ctl);
2234 errno = ESRCH;
2235 return (NULL);
2238 door = params.desc_ptr;
2239 if (door == NULL) {
2240 free(ctl);
2241 return (NULL);
2243 ctl->zsctl_door = door->d_data.d_desc.d_descriptor;
2245 if (params.data_ptr != (char *)cmd)
2246 (void) munmap(params.data_ptr, params.data_size);
2250 * Get the initial usage from zonestatd. This creates a
2251 * zero-point on which to base future usages returned by
2252 * zs_read().
2254 ctl->zsctl_start = zs_usage_read_internal(ctl, B_TRUE);
2255 if (ctl->zsctl_start == NULL) {
2256 errno_save = errno;
2257 (void) close(ctl->zsctl_door);
2258 free(ctl);
2259 if (errno_save == EINTR)
2260 errno = EINTR;
2261 else
2262 errno = ESRCH;
2263 return (NULL);
2265 return (ctl);
2269 * Return NULL on error.
2271 * ERRORS:
2272 * EINVAL: Invalid function.
2274 zs_usage_t *
2275 zs_usage_compute(zs_usage_t *ures, zs_usage_t *uold, zs_usage_t *unew,
2276 int func)
2278 zs_system_t *sold, *snew, *sres;
2279 boolean_t alloced = B_FALSE;
2281 if (func != ZS_COMPUTE_USAGE_INTERVAL &&
2282 func != ZS_COMPUTE_USAGE_TOTAL &&
2283 func != ZS_COMPUTE_USAGE_AVERAGE &&
2284 func != ZS_COMPUTE_USAGE_HIGH)
2285 assert(0);
2287 if (ures == NULL) {
2288 alloced = B_TRUE;
2289 ures = zs_usage_alloc();
2290 if (ures == NULL)
2291 return (NULL);
2294 sres = ures->zsu_system;
2295 sold = uold->zsu_system;
2296 snew = unew->zsu_system;
2298 switch (func) {
2299 case ZS_COMPUTE_USAGE_INTERVAL:
2300 /* Use system totals from newer interval */
2301 if (sres != snew)
2302 *sres = *snew;
2304 TIMESTRUC_DELTA(sres->zss_cpu_total_time,
2305 snew->zss_cpu_total_time, sold->zss_cpu_total_time);
2306 TIMESTRUC_DELTA(sres->zss_cpu_usage_kern,
2307 snew->zss_cpu_usage_kern, sold->zss_cpu_usage_kern);
2308 TIMESTRUC_DELTA(sres->zss_cpu_usage_zones,
2309 snew->zss_cpu_usage_zones, sold->zss_cpu_usage_zones);
2310 break;
2311 case ZS_COMPUTE_USAGE_HIGH:
2313 /* Find max cpus */
2314 sres->zss_ncpus = MAX(sold->zss_ncpus, snew->zss_ncpus);
2315 sres->zss_ncpus_online = MAX(sold->zss_ncpus_online,
2316 snew->zss_ncpus_online);
2318 /* Find max cpu times */
2319 sres->zss_cpu_total_time = ZS_MAXTS(sold->zss_cpu_total_time,
2320 snew->zss_cpu_total_time);
2321 sres->zss_cpu_usage_kern = ZS_MAXTS(sold->zss_cpu_usage_kern,
2322 snew->zss_cpu_usage_kern);
2323 sres->zss_cpu_usage_zones = ZS_MAXTS(sold->zss_cpu_usage_zones,
2324 snew->zss_cpu_usage_zones);
2326 /* These don't change */
2327 sres->zss_processes_max = snew->zss_processes_max;
2328 sres->zss_lwps_max = snew->zss_lwps_max;
2329 sres->zss_shm_max = snew->zss_shm_max;
2330 sres->zss_shmids_max = snew->zss_shmids_max;
2331 sres->zss_semids_max = snew->zss_semids_max;
2332 sres->zss_msgids_max = snew->zss_msgids_max;
2333 sres->zss_lofi_max = snew->zss_lofi_max;
2335 * Add in memory values and limits. Scale memory to
2336 * avoid overflow.
2338 sres->zss_ram_total = MAX(sold->zss_ram_total,
2339 snew->zss_ram_total);
2340 sres->zss_ram_kern = MAX(sold->zss_ram_kern,
2341 snew->zss_ram_kern);
2342 sres->zss_ram_zones = MAX(sold->zss_ram_zones,
2343 snew->zss_ram_zones);
2344 sres->zss_locked_kern = MAX(sold->zss_locked_kern,
2345 snew->zss_locked_kern);
2346 sres->zss_locked_zones = MAX(sold->zss_locked_zones,
2347 snew->zss_locked_zones);
2348 sres->zss_vm_total = MAX(sold->zss_vm_total,
2349 snew->zss_vm_total);
2350 sres->zss_vm_kern = MAX(sold->zss_vm_kern,
2351 snew->zss_vm_kern);
2352 sres->zss_vm_zones = MAX(sold->zss_vm_zones,
2353 snew->zss_vm_zones);
2354 sres->zss_swap_total = MAX(sold->zss_swap_total,
2355 snew->zss_swap_total);
2356 sres->zss_swap_used = MAX(sold->zss_swap_used,
2357 snew->zss_swap_used);
2359 sres->zss_processes = MAX(sold->zss_processes,
2360 snew->zss_processes);
2361 sres->zss_lwps = MAX(sold->zss_lwps, snew->zss_lwps);
2362 sres->zss_shm = MAX(sold->zss_shm, snew->zss_shm);
2363 sres->zss_shmids = MAX(sold->zss_shmids, snew->zss_shmids);
2364 sres->zss_semids = MAX(sold->zss_semids, snew->zss_semids);
2365 sres->zss_msgids = MAX(sold->zss_msgids, snew->zss_msgids);
2366 sres->zss_lofi = MAX(sold->zss_msgids, snew->zss_lofi);
2367 break;
2368 case ZS_COMPUTE_USAGE_TOTAL:
2369 /* FALLTHROUGH */
2370 case ZS_COMPUTE_USAGE_AVERAGE:
2371 ures->zsu_intervals++;
2374 * Add cpus. The total report will divide this by the
2375 * number of intervals to give the average number of cpus
2376 * over all intervals.
2378 sres->zss_ncpus = sold->zss_ncpus + snew->zss_ncpus;
2379 sres->zss_ncpus_online = sold->zss_ncpus_online +
2380 snew->zss_ncpus_online;
2382 /* Add in cpu times */
2383 sres->zss_cpu_total_time = sold->zss_cpu_total_time;
2384 TIMESTRUC_ADD_TIMESTRUC(sres->zss_cpu_total_time,
2385 snew->zss_cpu_total_time);
2386 sres->zss_cpu_usage_kern = sold->zss_cpu_usage_kern;
2387 TIMESTRUC_ADD_TIMESTRUC(sres->zss_cpu_usage_kern,
2388 snew->zss_cpu_usage_kern);
2389 sres->zss_cpu_usage_zones = sold->zss_cpu_usage_zones;
2390 TIMESTRUC_ADD_TIMESTRUC(sres->zss_cpu_usage_zones,
2391 snew->zss_cpu_usage_zones);
2393 /* These don't change */
2394 sres->zss_processes_max = snew->zss_processes_max;
2395 sres->zss_lwps_max = snew->zss_lwps_max;
2396 sres->zss_shm_max = snew->zss_shm_max;
2397 sres->zss_shmids_max = snew->zss_shmids_max;
2398 sres->zss_semids_max = snew->zss_semids_max;
2399 sres->zss_msgids_max = snew->zss_msgids_max;
2400 sres->zss_lofi_max = snew->zss_lofi_max;
2402 * Add in memory values and limits. Scale memory to
2403 * avoid overflow.
2405 if (sres != sold) {
2406 sres->zss_ram_total = sold->zss_ram_total / 1024;
2407 sres->zss_ram_kern = sold->zss_ram_kern / 1024;
2408 sres->zss_ram_zones = sold->zss_ram_zones / 1024;
2409 sres->zss_locked_kern = sold->zss_locked_kern / 1024;
2410 sres->zss_locked_zones = sold->zss_locked_zones / 1024;
2411 sres->zss_vm_total = sold->zss_vm_total / 1024;
2412 sres->zss_vm_kern = sold->zss_vm_kern / 1024;
2413 sres->zss_vm_zones = sold->zss_vm_zones / 1024;
2414 sres->zss_swap_total = sold->zss_swap_total / 1024;
2415 sres->zss_swap_used = sold->zss_swap_used / 1024;
2417 sres->zss_processes = sold->zss_processes;
2418 sres->zss_lwps = sold->zss_lwps;
2419 sres->zss_shm = sold->zss_shm / 1024;
2420 sres->zss_shmids = sold->zss_shmids;
2421 sres->zss_semids = sold->zss_semids;
2422 sres->zss_msgids = sold->zss_msgids;
2423 sres->zss_lofi = sold->zss_lofi;
2425 /* Add in new values. */
2426 sres->zss_ram_total += (snew->zss_ram_total / 1024);
2427 sres->zss_ram_kern += (snew->zss_ram_kern / 1024);
2428 sres->zss_ram_zones += (snew->zss_ram_zones / 1024);
2429 sres->zss_locked_kern += (snew->zss_locked_kern / 1024);
2430 sres->zss_locked_zones += (snew->zss_locked_zones / 1024);
2431 sres->zss_vm_total += (snew->zss_vm_total / 1024);
2432 sres->zss_vm_kern += (snew->zss_vm_kern / 1024);
2433 sres->zss_vm_zones += (snew->zss_vm_zones / 1024);
2434 sres->zss_swap_total += (snew->zss_swap_total / 1024);
2435 sres->zss_swap_used += (snew->zss_swap_used / 1024);
2436 sres->zss_processes += snew->zss_processes;
2437 sres->zss_lwps += snew->zss_lwps;
2438 sres->zss_shm += (snew->zss_shm / 1024);
2439 sres->zss_shmids += snew->zss_shmids;
2440 sres->zss_semids += snew->zss_semids;
2441 sres->zss_msgids += snew->zss_msgids;
2442 sres->zss_lofi += snew->zss_lofi;
2443 break;
2444 default:
2445 if (alloced)
2446 zs_usage_free(ures);
2447 assert(0);
2449 if (zs_usage_compute_zones(ures, uold, unew, func) != 0)
2450 goto err;
2452 if (zs_usage_compute_psets(ures, uold, unew, func) != 0)
2453 goto err;
2455 return (ures);
2456 err:
2457 if (alloced)
2458 zs_usage_free(ures);
2459 return (NULL);
2462 void
2463 zs_usage_free(zs_usage_t *usage)
2465 zs_zone_t *zone, *ztmp;
2466 zs_pset_t *pset, *ptmp;
2467 zs_pset_zone_t *pz, *pztmp;
2469 if (usage->zsu_mmap) {
2470 (void) munmap((void *)usage, usage->zsu_size);
2471 return;
2473 free(usage->zsu_system);
2474 zone = list_head(&usage->zsu_zone_list);
2475 while (zone != NULL) {
2476 ztmp = zone;
2477 zone = list_next(&usage->zsu_zone_list, zone);
2478 free(ztmp);
2480 pset = list_head(&usage->zsu_pset_list);
2481 while (pset != NULL) {
2482 pz = list_head(&pset->zsp_usage_list);
2483 while (pz != NULL) {
2484 pztmp = pz;
2485 pz = list_next(&pset->zsp_usage_list, pz);
2486 free(pztmp);
2488 ptmp = pset;
2489 pset = list_next(&usage->zsu_pset_list, pset);
2490 free(ptmp);
2492 free(usage);
2495 zs_usage_set_t *
2496 zs_usage_set_alloc()
2498 zs_usage_set_t *set;
2500 set = calloc(sizeof (zs_usage_set_t), 1);
2501 if (set == NULL)
2502 return (NULL);
2504 if ((set->zsus_total = zs_usage_alloc()) == NULL)
2505 goto err;
2506 if ((set->zsus_avg = zs_usage_alloc()) == NULL)
2507 goto err;
2508 if ((set->zsus_high = zs_usage_alloc()) == NULL)
2509 goto err;
2511 return (set);
2513 err:
2514 if (set->zsus_total != NULL)
2515 free(set->zsus_total);
2516 if (set->zsus_avg != NULL)
2517 free(set->zsus_avg);
2518 if (set->zsus_high != NULL)
2519 free(set->zsus_high);
2521 return (NULL);
2524 void
2525 zs_usage_set_free(zs_usage_set_t *set)
2527 zs_usage_free(set->zsus_total);
2528 zs_usage_free(set->zsus_avg);
2529 zs_usage_free(set->zsus_high);
2530 free(set);
2534 zs_usage_set_add(zs_usage_set_t *set, zs_usage_t *usage)
2537 /* Compute ongoing functions for usage set */
2538 (void) zs_usage_compute(set->zsus_high, set->zsus_high, usage,
2539 ZS_COMPUTE_USAGE_HIGH);
2541 (void) zs_usage_compute(set->zsus_total, set->zsus_total, usage,
2542 ZS_COMPUTE_USAGE_TOTAL);
2544 (void) zs_usage_compute(set->zsus_avg, set->zsus_avg, usage,
2545 ZS_COMPUTE_USAGE_AVERAGE);
2547 set->zsus_count++;
2548 zs_usage_free(usage);
2549 return (0);
2553 zs_usage_set_count(zs_usage_set_t *set)
2555 return (set->zsus_count);
2558 zs_usage_t *
2559 zs_usage_set_compute(zs_usage_set_t *set, int func)
2561 zs_usage_t *u;
2562 zs_system_t *s;
2563 zs_zone_t *z;
2564 zs_pset_t *p;
2565 zs_pset_zone_t *pz;
2566 uint_t intervals;
2567 boolean_t average;
2569 switch (func) {
2570 case ZS_COMPUTE_SET_HIGH:
2571 return (set->zsus_high);
2572 case ZS_COMPUTE_SET_TOTAL:
2573 u = set->zsus_total;
2574 average = B_FALSE;
2575 break;
2576 case ZS_COMPUTE_SET_AVERAGE:
2577 u = set->zsus_avg;
2578 average = B_TRUE;
2579 break;
2580 default:
2581 assert(0);
2584 s = u->zsu_system;
2586 s->zss_ram_total /= u->zsu_intervals;
2587 s->zss_ram_total *= 1024;
2588 s->zss_ram_kern /= u->zsu_intervals;
2589 s->zss_ram_kern *= 1024;
2590 s->zss_ram_zones /= u->zsu_intervals;
2591 s->zss_ram_zones *= 1024;
2592 s->zss_locked_kern /= u->zsu_intervals;
2593 s->zss_locked_kern *= 1024;
2594 s->zss_locked_zones /= u->zsu_intervals;
2595 s->zss_locked_zones *= 1024;
2596 s->zss_vm_total /= u->zsu_intervals;
2597 s->zss_vm_total *= 1024;
2598 s->zss_vm_kern /= u->zsu_intervals;
2599 s->zss_vm_kern *= 1024;
2600 s->zss_vm_zones /= u->zsu_intervals;
2601 s->zss_vm_zones *= 1024;
2602 s->zss_swap_total /= u->zsu_intervals;
2603 s->zss_swap_total *= 1024;
2604 s->zss_swap_used /= u->zsu_intervals;
2605 s->zss_swap_used *= 1024;
2606 s->zss_processes /= u->zsu_intervals;
2607 s->zss_lwps /= u->zsu_intervals;
2608 s->zss_shm /= u->zsu_intervals;
2609 s->zss_shm *= 1024;
2610 s->zss_shmids /= u->zsu_intervals;
2611 s->zss_semids /= u->zsu_intervals;
2612 s->zss_msgids /= u->zsu_intervals;
2613 s->zss_lofi /= u->zsu_intervals;
2615 s->zss_ncpus /= u->zsu_intervals;
2616 s->zss_ncpus_online /= u->zsu_intervals;
2618 for (z = list_head(&u->zsu_zone_list); z != NULL;
2619 z = list_next(&u->zsu_zone_list, z)) {
2621 if (average) {
2622 intervals = z->zsz_intervals;
2623 } else {
2624 assert(z->zsz_intervals == 0);
2625 intervals = u->zsu_intervals;
2628 if (z->zsz_cpu_cap != ZS_LIMIT_NONE)
2629 z->zsz_cpu_cap /= z->zsz_intervals;
2630 if (z->zsz_ram_cap != ZS_LIMIT_NONE)
2631 z->zsz_ram_cap /= z->zsz_intervals;
2632 if (z->zsz_vm_cap != ZS_LIMIT_NONE)
2633 z->zsz_vm_cap /= z->zsz_intervals;
2634 if (z->zsz_locked_cap != ZS_LIMIT_NONE)
2635 z->zsz_locked_cap /= z->zsz_intervals;
2636 if (z->zsz_processes_cap != ZS_LIMIT_NONE)
2637 z->zsz_processes_cap /= z->zsz_intervals;
2638 if (z->zsz_lwps_cap != ZS_LIMIT_NONE)
2639 z->zsz_lwps_cap /= z->zsz_intervals;
2640 if (z->zsz_shm_cap != ZS_LIMIT_NONE)
2641 z->zsz_shm_cap /= z->zsz_intervals;
2642 if (z->zsz_shmids_cap != ZS_LIMIT_NONE)
2643 z->zsz_shmids_cap /= z->zsz_intervals;
2644 if (z->zsz_semids_cap != ZS_LIMIT_NONE)
2645 z->zsz_semids_cap /= z->zsz_intervals;
2646 if (z->zsz_msgids_cap != ZS_LIMIT_NONE)
2647 z->zsz_msgids_cap /= z->zsz_intervals;
2648 if (z->zsz_lofi_cap != ZS_LIMIT_NONE)
2649 z->zsz_lofi_cap /= z->zsz_intervals;
2651 z->zsz_usage_ram /= intervals;
2652 z->zsz_usage_locked /= intervals;
2653 z->zsz_usage_vm /= intervals;
2654 z->zsz_processes /= intervals;
2655 z->zsz_lwps /= intervals;
2656 z->zsz_shm /= intervals;
2657 z->zsz_shmids /= intervals;
2658 z->zsz_semids /= intervals;
2659 z->zsz_msgids /= intervals;
2660 z->zsz_lofi /= intervals;
2661 z->zsz_cpus_online /= intervals;
2662 z->zsz_cpu_shares /= intervals;
2664 for (p = list_head(&u->zsu_pset_list); p != NULL;
2665 p = list_next(&u->zsu_pset_list, p)) {
2667 intervals = p->zsp_intervals;
2669 p->zsp_online /= intervals;
2670 p->zsp_size /= intervals;
2671 p->zsp_min /= intervals;
2672 p->zsp_max /= intervals;
2673 p->zsp_importance /= intervals;
2674 p->zsp_cpu_shares /= intervals;
2676 for (pz = list_head(&p->zsp_usage_list); pz != NULL;
2677 pz = list_next(&p->zsp_usage_list, pz)) {
2679 if (average) {
2680 intervals = pz->zspz_intervals;
2681 } else {
2682 assert(pz->zspz_intervals == 0);
2683 intervals = p->zsp_intervals;
2685 pz->zspz_cpu_shares /= intervals;
2688 return (u);
2692 * Returns 0 on success. Trips assert on invalid property.
2694 void
2695 zs_resource_property(zs_usage_t *u, int res, int prop, zs_property_t *p)
2697 switch (res) {
2698 case ZS_RESOURCE_CPU:
2699 switch (prop) {
2700 case ZS_RESOURCE_PROP_CPU_TOTAL:
2701 p->zsp_id = prop;
2702 p->zsp_type = ZS_PROP_TYPE_UINT64;
2703 p->zsp_v.zsv_uint64 = u->zsu_system->zss_ncpus;
2704 break;
2705 case ZS_RESOURCE_PROP_CPU_ONLINE:
2706 p->zsp_id = prop;
2707 p->zsp_type = ZS_PROP_TYPE_UINT64;
2708 p->zsp_v.zsv_uint64 = u->zsu_system->zss_ncpus_online;
2709 break;
2710 default:
2711 assert(0);
2713 break;
2714 case ZS_RESOURCE_RAM_RSS:
2715 case ZS_RESOURCE_RAM_LOCKED:
2716 case ZS_RESOURCE_VM:
2717 case ZS_RESOURCE_DISK_SWAP:
2718 case ZS_RESOURCE_LWPS:
2719 case ZS_RESOURCE_PROCESSES:
2720 case ZS_RESOURCE_SHM_MEMORY:
2721 case ZS_RESOURCE_SHM_IDS:
2722 case ZS_RESOURCE_SEM_IDS:
2723 case ZS_RESOURCE_MSG_IDS:
2724 /* FALLTHROUGH */
2725 default:
2726 assert(0);
2731 * Returns one of ZS_RESOURCE_TYPE_* on success. Asserts on invalid
2732 * resource.
2735 zs_resource_type(int res)
2737 switch (res) {
2738 case ZS_RESOURCE_CPU:
2739 return (ZS_RESOURCE_TYPE_TIME);
2740 break;
2741 case ZS_RESOURCE_RAM_RSS:
2742 case ZS_RESOURCE_RAM_LOCKED:
2743 case ZS_RESOURCE_VM:
2744 case ZS_RESOURCE_DISK_SWAP:
2745 case ZS_RESOURCE_SHM_MEMORY:
2746 return (ZS_RESOURCE_TYPE_BYTES);
2747 break;
2748 case ZS_RESOURCE_LWPS:
2749 case ZS_RESOURCE_PROCESSES:
2750 case ZS_RESOURCE_SHM_IDS:
2751 case ZS_RESOURCE_SEM_IDS:
2752 case ZS_RESOURCE_MSG_IDS:
2753 return (ZS_RESOURCE_TYPE_COUNT);
2754 break;
2755 default:
2756 assert(0);
2757 return (0);
2762 * Get total available resource on system
2764 uint64_t
2765 zs_resource_total_uint64(zs_usage_t *u, int res)
2767 uint64_t v;
2769 switch (res) {
2770 case ZS_RESOURCE_CPU:
2771 v = zs_cpu_total_cpu(u);
2772 break;
2773 case ZS_RESOURCE_RAM_RSS:
2774 v = zs_physical_memory_total(u);
2775 break;
2776 case ZS_RESOURCE_RAM_LOCKED:
2777 v = zs_locked_memory_total(u);
2778 break;
2779 case ZS_RESOURCE_VM:
2780 v = zs_virtual_memory_total(u);
2781 break;
2782 case ZS_RESOURCE_DISK_SWAP:
2783 v = zs_disk_swap_total(u);
2784 break;
2785 case ZS_RESOURCE_LWPS:
2786 v = zs_lwps_total(u);
2787 break;
2788 case ZS_RESOURCE_PROCESSES:
2789 v = zs_processes_total(u);
2790 break;
2791 case ZS_RESOURCE_SHM_MEMORY:
2792 v = zs_shm_total(u);
2793 break;
2794 case ZS_RESOURCE_SHM_IDS:
2795 v = zs_shmids_total(u);
2796 break;
2797 case ZS_RESOURCE_SEM_IDS:
2798 v = zs_semids_total(u);
2799 break;
2800 case ZS_RESOURCE_MSG_IDS:
2801 v = zs_msgids_total(u);
2802 break;
2803 case ZS_RESOURCE_LOFI:
2804 v = zs_lofi_total(u);
2805 break;
2806 default:
2807 assert(0);
2809 return (v);
2813 * Get amount of used resource.
2815 uint64_t
2816 zs_resource_used_uint64(zs_usage_t *u, int res, int user)
2818 uint64_t v;
2820 switch (res) {
2821 case ZS_RESOURCE_CPU:
2822 switch (user) {
2823 case ZS_USER_ALL:
2824 v = zs_cpu_usage_all_cpu(u);
2825 break;
2826 case ZS_USER_KERNEL:
2827 v = zs_cpu_usage_kernel_cpu(u);
2828 break;
2829 case ZS_USER_ZONES:
2830 v = zs_cpu_usage_zones_cpu(u);
2831 break;
2832 case ZS_USER_FREE:
2833 v = zs_cpu_usage_idle_cpu(u);
2834 break;
2835 default:
2836 assert(0);
2838 break;
2839 case ZS_RESOURCE_RAM_RSS:
2840 switch (user) {
2841 case ZS_USER_ALL:
2842 v = zs_physical_memory_usage_all(u);
2843 break;
2844 case ZS_USER_KERNEL:
2845 v = zs_physical_memory_usage_kernel(u);
2846 break;
2847 case ZS_USER_ZONES:
2848 v = zs_physical_memory_usage_zones(u);
2849 break;
2850 case ZS_USER_FREE:
2851 v = zs_physical_memory_usage_free(u);
2852 break;
2853 default:
2854 assert(0);
2856 break;
2857 case ZS_RESOURCE_RAM_LOCKED:
2858 switch (user) {
2859 case ZS_USER_ALL:
2860 v = zs_locked_memory_usage_all(u);
2861 break;
2862 case ZS_USER_KERNEL:
2863 v = zs_locked_memory_usage_kernel(u);
2864 break;
2865 case ZS_USER_ZONES:
2866 v = zs_locked_memory_usage_zones(u);
2867 break;
2868 case ZS_USER_FREE:
2869 v = zs_locked_memory_usage_free(u);
2870 break;
2871 default:
2872 assert(0);
2874 break;
2875 case ZS_RESOURCE_VM:
2876 switch (user) {
2877 case ZS_USER_ALL:
2878 v = zs_virtual_memory_usage_all(u);
2879 break;
2880 case ZS_USER_KERNEL:
2881 v = zs_virtual_memory_usage_kernel(u);
2882 break;
2883 case ZS_USER_ZONES:
2884 v = zs_virtual_memory_usage_zones(u);
2885 break;
2886 case ZS_USER_FREE:
2887 v = zs_virtual_memory_usage_free(u);
2888 break;
2889 default:
2890 assert(0);
2892 break;
2893 case ZS_RESOURCE_DISK_SWAP:
2894 switch (user) {
2895 case ZS_USER_ALL:
2896 v = zs_disk_swap_usage_all(u);
2897 break;
2898 case ZS_USER_FREE:
2899 v = zs_disk_swap_usage_free(u);
2900 break;
2901 case ZS_USER_KERNEL:
2902 case ZS_USER_ZONES:
2903 /* FALLTHROUGH */
2904 default:
2905 assert(0);
2907 break;
2908 case ZS_RESOURCE_LWPS:
2909 switch (user) {
2910 case ZS_USER_ALL:
2911 case ZS_USER_ZONES:
2912 v = zs_lwps_usage_all(u);
2913 break;
2914 case ZS_USER_FREE:
2915 v = zs_lwps_total(u) - zs_lwps_usage_all(u);
2916 break;
2917 case ZS_USER_KERNEL:
2918 v = 0;
2919 break;
2920 default:
2921 assert(0);
2923 break;
2924 case ZS_RESOURCE_PROCESSES:
2925 switch (user) {
2926 case ZS_USER_ALL:
2927 case ZS_USER_ZONES:
2928 v = zs_processes_usage_all(u);
2929 break;
2930 case ZS_USER_FREE:
2931 v = zs_processes_total(u) - zs_processes_usage_all(u);
2932 break;
2933 case ZS_USER_KERNEL:
2934 v = 0;
2935 break;
2936 default:
2937 assert(0);
2939 break;
2940 case ZS_RESOURCE_SHM_MEMORY:
2941 switch (user) {
2942 case ZS_USER_ALL:
2943 case ZS_USER_ZONES:
2944 v = zs_shm_usage_all(u);
2945 break;
2946 case ZS_USER_FREE:
2947 v = zs_shm_total(u) -
2948 zs_shm_usage_all(u);
2949 break;
2950 case ZS_USER_KERNEL:
2951 v = 0;
2952 break;
2953 default:
2954 assert(0);
2956 break;
2957 case ZS_RESOURCE_SHM_IDS:
2958 switch (user) {
2959 case ZS_USER_ALL:
2960 case ZS_USER_ZONES:
2961 v = zs_shmids_usage_all(u);
2962 break;
2963 case ZS_USER_FREE:
2964 v = zs_shmids_total(u) - zs_shmids_usage_all(u);
2965 break;
2966 case ZS_USER_KERNEL:
2967 v = 0;
2968 break;
2969 default:
2970 assert(0);
2972 break;
2973 case ZS_RESOURCE_SEM_IDS:
2974 switch (user) {
2975 case ZS_USER_ALL:
2976 case ZS_USER_ZONES:
2977 v = zs_semids_usage_all(u);
2978 break;
2979 case ZS_USER_FREE:
2980 v = zs_semids_total(u) - zs_semids_usage_all(u);
2981 break;
2982 case ZS_USER_KERNEL:
2983 v = 0;
2984 break;
2985 default:
2986 assert(0);
2988 break;
2989 case ZS_RESOURCE_MSG_IDS:
2990 switch (user) {
2991 case ZS_USER_ALL:
2992 case ZS_USER_ZONES:
2993 v = zs_msgids_usage_all(u);
2994 break;
2995 case ZS_USER_FREE:
2996 v = zs_msgids_total(u) - zs_msgids_usage_all(u);
2997 break;
2998 case ZS_USER_KERNEL:
2999 v = 0;
3000 break;
3001 default:
3002 assert(0);
3004 break;
3005 case ZS_RESOURCE_LOFI:
3006 switch (user) {
3007 case ZS_USER_ALL:
3008 case ZS_USER_ZONES:
3009 v = zs_lofi_usage_all(u);
3010 break;
3011 case ZS_USER_FREE:
3012 v = zs_lofi_total(u) - zs_lofi_usage_all(u);
3013 break;
3014 case ZS_USER_KERNEL:
3015 v = 0;
3016 break;
3017 default:
3018 assert(0);
3020 break;
3022 default:
3023 assert(0);
3025 return (v);
3029 * Get used resource as a percent of total resource.
3031 uint_t
3032 zs_resource_used_pct(zs_usage_t *u, int res, int user)
3034 uint64_t v;
3036 switch (res) {
3037 case ZS_RESOURCE_CPU:
3038 switch (user) {
3039 case ZS_USER_ALL:
3040 v = zs_cpu_usage_all_pct(u);
3041 break;
3042 case ZS_USER_KERNEL:
3043 v = zs_cpu_usage_kernel_pct(u);
3044 break;
3045 case ZS_USER_ZONES:
3046 v = zs_cpu_usage_zones_pct(u);
3047 break;
3048 case ZS_USER_FREE:
3049 v = zs_cpu_usage_idle_pct(u);
3050 break;
3051 default:
3052 assert(0);
3054 break;
3055 case ZS_RESOURCE_RAM_RSS:
3056 switch (user) {
3057 case ZS_USER_ALL:
3058 v = zs_physical_memory_usage_all_pct(u);
3059 break;
3060 case ZS_USER_KERNEL:
3061 v = zs_physical_memory_usage_kernel_pct(u);
3062 break;
3063 case ZS_USER_ZONES:
3064 v = zs_physical_memory_usage_zones_pct(u);
3065 break;
3066 case ZS_USER_FREE:
3067 v = zs_physical_memory_usage_free_pct(u);
3068 break;
3069 default:
3070 assert(0);
3072 break;
3073 case ZS_RESOURCE_RAM_LOCKED:
3074 switch (user) {
3075 case ZS_USER_ALL:
3076 v = zs_locked_memory_usage_all_pct(u);
3077 break;
3078 case ZS_USER_KERNEL:
3079 v = zs_locked_memory_usage_kernel_pct(u);
3080 break;
3081 case ZS_USER_ZONES:
3082 v = zs_locked_memory_usage_zones_pct(u);
3083 break;
3084 case ZS_USER_FREE:
3085 v = zs_locked_memory_usage_free_pct(u);
3086 break;
3087 default:
3088 assert(0);
3090 break;
3091 case ZS_RESOURCE_VM:
3092 switch (user) {
3093 case ZS_USER_ALL:
3094 v = zs_virtual_memory_usage_all_pct(u);
3095 break;
3096 case ZS_USER_KERNEL:
3097 v = zs_virtual_memory_usage_kernel_pct(u);
3098 break;
3099 case ZS_USER_ZONES:
3100 v = zs_virtual_memory_usage_zones_pct(u);
3101 break;
3102 case ZS_USER_FREE:
3103 v = zs_virtual_memory_usage_free_pct(u);
3104 break;
3105 default:
3106 assert(0);
3108 break;
3109 case ZS_RESOURCE_DISK_SWAP:
3110 switch (user) {
3111 case ZS_USER_ALL:
3112 v = zs_disk_swap_usage_all_pct(u);
3113 break;
3114 case ZS_USER_FREE:
3115 v = zs_disk_swap_usage_free_pct(u);
3116 break;
3117 case ZS_USER_KERNEL:
3118 case ZS_USER_ZONES:
3119 /* FALLTHROUGH */
3120 default:
3121 assert(0);
3123 break;
3124 case ZS_RESOURCE_LWPS:
3125 switch (user) {
3126 case ZS_USER_ALL:
3127 case ZS_USER_ZONES:
3128 v = zs_lwps_usage_all_pct(u);
3129 break;
3130 case ZS_USER_FREE:
3131 v = ZSD_PCT_INT - zs_lwps_usage_all_pct(u);
3132 break;
3133 case ZS_USER_KERNEL:
3134 v = 0;
3135 break;
3136 default:
3137 assert(0);
3139 break;
3140 case ZS_RESOURCE_PROCESSES:
3141 switch (user) {
3142 case ZS_USER_ALL:
3143 case ZS_USER_ZONES:
3144 v = zs_processes_usage_all_pct(u);
3145 break;
3146 case ZS_USER_FREE:
3147 v = ZSD_PCT_INT - zs_processes_usage_all_pct(u);
3148 break;
3149 case ZS_USER_KERNEL:
3150 v = 0;
3151 break;
3152 default:
3153 assert(0);
3155 break;
3156 case ZS_RESOURCE_SHM_MEMORY:
3157 switch (user) {
3158 case ZS_USER_ALL:
3159 case ZS_USER_ZONES:
3160 v = zs_shm_usage_all_pct(u);
3161 break;
3162 case ZS_USER_FREE:
3163 v = ZSD_PCT_INT - zs_shm_usage_all_pct(u);
3164 break;
3165 case ZS_USER_KERNEL:
3166 v = 0;
3167 break;
3168 default:
3169 assert(0);
3171 break;
3172 case ZS_RESOURCE_SHM_IDS:
3173 switch (user) {
3174 case ZS_USER_ALL:
3175 case ZS_USER_ZONES:
3176 v = zs_shmids_usage_all_pct(u);
3177 break;
3178 case ZS_USER_FREE:
3179 v = ZSD_PCT_INT - zs_shmids_usage_all_pct(u);
3180 break;
3181 case ZS_USER_KERNEL:
3182 v = 0;
3183 break;
3184 default:
3185 assert(0);
3187 break;
3188 case ZS_RESOURCE_SEM_IDS:
3189 switch (user) {
3190 case ZS_USER_ALL:
3191 case ZS_USER_ZONES:
3192 v = zs_semids_usage_all_pct(u);
3193 break;
3194 case ZS_USER_FREE:
3195 v = ZSD_PCT_INT - zs_semids_usage_all_pct(u);
3196 break;
3197 case ZS_USER_KERNEL:
3198 v = 0;
3199 break;
3200 default:
3201 assert(0);
3203 break;
3204 case ZS_RESOURCE_MSG_IDS:
3205 switch (user) {
3206 case ZS_USER_ALL:
3207 case ZS_USER_ZONES:
3208 v = zs_msgids_usage_all_pct(u);
3209 break;
3210 case ZS_USER_FREE:
3211 v = ZSD_PCT_INT - zs_msgids_usage_all_pct(u);
3212 break;
3213 case ZS_USER_KERNEL:
3214 v = 0;
3215 break;
3216 default:
3217 assert(0);
3219 break;
3220 case ZS_RESOURCE_LOFI:
3221 switch (user) {
3222 case ZS_USER_ALL:
3223 case ZS_USER_ZONES:
3224 v = zs_lofi_usage_all_pct(u);
3225 break;
3226 case ZS_USER_FREE:
3227 v = ZSD_PCT_INT - zs_lofi_usage_all_pct(u);
3228 break;
3229 case ZS_USER_KERNEL:
3230 v = 0;
3231 break;
3232 default:
3233 assert(0);
3235 break;
3236 default:
3237 assert(0);
3240 return (v);
3244 * Get resource used by individual zone.
3246 uint64_t
3247 zs_resource_used_zone_uint64(zs_zone_t *z, int res)
3249 uint64_t v;
3251 switch (res) {
3252 case ZS_RESOURCE_CPU:
3253 v = zs_cpu_usage_zone_cpu(z);
3254 break;
3255 case ZS_RESOURCE_RAM_RSS:
3256 v = zs_physical_memory_usage_zone(z);
3257 break;
3258 case ZS_RESOURCE_RAM_LOCKED:
3259 v = zs_locked_memory_usage_zone(z);
3260 break;
3261 case ZS_RESOURCE_VM:
3262 v = zs_virtual_memory_usage_zone(z);
3263 break;
3264 case ZS_RESOURCE_DISK_SWAP:
3265 assert(0);
3266 break;
3267 case ZS_RESOURCE_LWPS:
3268 v = zs_lwps_usage_zone(z);
3269 break;
3270 case ZS_RESOURCE_PROCESSES:
3271 v = zs_processes_usage_zone(z);
3272 break;
3273 case ZS_RESOURCE_SHM_MEMORY:
3274 v = zs_shm_usage_zone(z);
3275 break;
3276 case ZS_RESOURCE_SHM_IDS:
3277 v = zs_shmids_usage_zone(z);
3278 break;
3279 case ZS_RESOURCE_SEM_IDS:
3280 v = zs_semids_usage_zone(z);
3281 break;
3282 case ZS_RESOURCE_MSG_IDS:
3283 v = zs_msgids_usage_zone(z);
3284 break;
3285 case ZS_RESOURCE_LOFI:
3286 v = zs_lofi_usage_zone(z);
3287 break;
3288 default:
3289 assert(0);
3291 return (v);
3295 * Get resource used by individual zone as percent
3297 uint_t
3298 zs_resource_used_zone_pct(zs_zone_t *z, int res)
3300 uint_t v;
3302 switch (res) {
3303 case ZS_RESOURCE_CPU:
3304 v = zs_cpu_usage_zone_pct(z);
3305 break;
3306 case ZS_RESOURCE_RAM_RSS:
3307 v = zs_physical_memory_usage_zone_pct(z);
3308 break;
3309 case ZS_RESOURCE_RAM_LOCKED:
3310 v = zs_locked_memory_usage_zone_pct(z);
3311 break;
3312 case ZS_RESOURCE_VM:
3313 v = zs_virtual_memory_usage_zone_pct(z);
3314 break;
3315 case ZS_RESOURCE_DISK_SWAP:
3316 assert(0);
3317 break;
3318 case ZS_RESOURCE_LWPS:
3319 v = zs_lwps_usage_zone_pct(z);
3320 break;
3321 case ZS_RESOURCE_PROCESSES:
3322 v = zs_processes_usage_zone_pct(z);
3323 break;
3324 case ZS_RESOURCE_SHM_MEMORY:
3325 v = zs_shm_usage_zone_pct(z);
3326 break;
3327 case ZS_RESOURCE_SHM_IDS:
3328 v = zs_shmids_usage_zone_pct(z);
3329 break;
3330 case ZS_RESOURCE_SEM_IDS:
3331 v = zs_semids_usage_zone_pct(z);
3332 break;
3333 case ZS_RESOURCE_MSG_IDS:
3334 v = zs_msgids_usage_zone_pct(z);
3335 break;
3336 case ZS_RESOURCE_LOFI:
3337 v = zs_lofi_usage_zone_pct(z);
3338 break;
3339 default:
3340 assert(0);
3342 return (v);
3346 * Get total time available for a resource
3348 void
3349 zs_resource_total_time(zs_usage_t *u, int res, timestruc_t *t)
3351 switch (res) {
3352 case ZS_RESOURCE_CPU:
3353 zs_cpu_total_time(u, t);
3354 break;
3355 case ZS_RESOURCE_RAM_RSS:
3356 case ZS_RESOURCE_RAM_LOCKED:
3357 case ZS_RESOURCE_VM:
3358 case ZS_RESOURCE_DISK_SWAP:
3359 case ZS_RESOURCE_LWPS:
3360 case ZS_RESOURCE_PROCESSES:
3361 case ZS_RESOURCE_SHM_MEMORY:
3362 case ZS_RESOURCE_SHM_IDS:
3363 case ZS_RESOURCE_SEM_IDS:
3364 case ZS_RESOURCE_MSG_IDS:
3365 /* FALLTHROUGH */
3366 default:
3367 assert(0);
3372 * Get total time used for a resource
3374 void
3375 zs_resource_used_time(zs_usage_t *u, int res, int user, timestruc_t *t)
3377 switch (res) {
3378 case ZS_RESOURCE_CPU:
3379 switch (user) {
3380 case ZS_USER_ALL:
3381 zs_cpu_usage_all(u, t);
3382 break;
3383 case ZS_USER_KERNEL:
3384 zs_cpu_usage_kernel(u, t);
3385 break;
3386 case ZS_USER_ZONES:
3387 zs_cpu_usage_zones(u, t);
3388 break;
3389 case ZS_USER_FREE:
3390 zs_cpu_usage_idle(u, t);
3391 break;
3392 default:
3393 assert(0);
3395 break;
3396 case ZS_RESOURCE_RAM_RSS:
3397 case ZS_RESOURCE_RAM_LOCKED:
3398 case ZS_RESOURCE_VM:
3399 case ZS_RESOURCE_DISK_SWAP:
3400 case ZS_RESOURCE_LWPS:
3401 case ZS_RESOURCE_PROCESSES:
3402 case ZS_RESOURCE_SHM_MEMORY:
3403 case ZS_RESOURCE_SHM_IDS:
3404 case ZS_RESOURCE_SEM_IDS:
3405 case ZS_RESOURCE_MSG_IDS:
3406 /* FALLTHROUGH */
3407 default:
3408 assert(0);
3413 * Get total resource time used for a particular zone
3415 void
3416 zs_resource_used_zone_time(zs_zone_t *z, int res, timestruc_t *t)
3418 switch (res) {
3419 case ZS_RESOURCE_CPU:
3420 zs_cpu_usage_zone(z, t);
3421 break;
3422 case ZS_RESOURCE_RAM_RSS:
3423 case ZS_RESOURCE_RAM_LOCKED:
3424 case ZS_RESOURCE_VM:
3425 case ZS_RESOURCE_DISK_SWAP:
3426 case ZS_RESOURCE_SHM_MEMORY:
3427 case ZS_RESOURCE_LWPS:
3428 case ZS_RESOURCE_PROCESSES:
3429 case ZS_RESOURCE_SHM_IDS:
3430 case ZS_RESOURCE_SEM_IDS:
3431 case ZS_RESOURCE_MSG_IDS:
3432 /* FALLTHROUGH */
3433 default:
3434 assert(0);
3440 zs_zone_list(zs_usage_t *usage, zs_zone_t **zonelist, int num)
3442 int i = 0;
3443 zs_zone_t *zone, *tmp;
3445 /* copy what fits of the zone list into the buffer */
3446 for (zone = list_head(&usage->zsu_zone_list); zone != NULL;
3447 zone = list_next(&usage->zsu_zone_list, zone)) {
3449 /* put the global zone at the first position */
3450 if (i < num) {
3451 if (zone->zsz_id == GLOBAL_ZONEID) {
3452 tmp = zonelist[0];
3453 zonelist[i] = tmp;
3454 zonelist[0] = zone;
3455 } else {
3456 zonelist[i] = zone;
3459 i++;
3461 return (i);
3464 zs_zone_t *
3465 zs_zone_first(zs_usage_t *usage)
3467 return (list_head(&usage->zsu_zone_list));
3470 zs_zone_t *
3471 zs_zone_next(zs_usage_t *usage, zs_zone_t *zone)
3473 return (list_next(&usage->zsu_zone_list, zone));
3478 * Gets a zone property
3480 void
3481 zs_zone_property(zs_zone_t *zone, int prop, zs_property_t *p)
3483 switch (prop) {
3484 case ZS_ZONE_PROP_NAME:
3485 p->zsp_type = ZS_PROP_TYPE_STRING;
3486 p->zsp_id = prop;
3487 (void) zs_zone_name(zone, p->zsp_v.zsv_string,
3488 sizeof (p->zsp_v.zsv_string));
3489 break;
3490 case ZS_ZONE_PROP_ID:
3491 p->zsp_type = ZS_PROP_TYPE_INT;
3492 p->zsp_id = prop;
3493 p->zsp_v.zsv_int = zs_zone_id(zone);
3494 break;
3495 case ZS_ZONE_PROP_IPTYPE:
3496 p->zsp_type = ZS_PROP_TYPE_UINT;
3497 p->zsp_id = prop;
3498 p->zsp_v.zsv_uint = zs_zone_iptype(zone);
3499 break;
3500 case ZS_ZONE_PROP_CPUTYPE:
3501 p->zsp_type = ZS_PROP_TYPE_UINT;
3502 p->zsp_id = prop;
3503 p->zsp_v.zsv_uint = zs_zone_cputype(zone);
3504 break;
3505 case ZS_ZONE_PROP_SCHEDULERS:
3506 p->zsp_type = ZS_PROP_TYPE_UINT;
3507 p->zsp_id = prop;
3508 p->zsp_v.zsv_uint = zs_zone_schedulers(zone);
3509 break;
3510 case ZS_ZONE_PROP_CPU_SHARES:
3511 p->zsp_type = ZS_PROP_TYPE_UINT64;
3512 p->zsp_id = prop;
3513 p->zsp_v.zsv_uint64 = zs_zone_cpu_shares(zone);
3514 break;
3515 case ZS_ZONE_PROP_POOLNAME:
3516 p->zsp_type = ZS_PROP_TYPE_STRING;
3517 p->zsp_id = prop;
3518 (void) zs_zone_poolname(zone, p->zsp_v.zsv_string,
3519 sizeof (p->zsp_v.zsv_string));
3520 break;
3521 case ZS_ZONE_PROP_PSETNAME:
3522 p->zsp_type = ZS_PROP_TYPE_STRING;
3523 p->zsp_id = prop;
3524 (void) zs_zone_psetname(zone, p->zsp_v.zsv_string,
3525 sizeof (p->zsp_v.zsv_string));
3526 break;
3527 /* Not implemented */
3528 case ZS_ZONE_PROP_DEFAULT_SCHED:
3529 case ZS_ZONE_PROP_UPTIME:
3530 case ZS_ZONE_PROP_BOOTTIME:
3531 /* FALLTHROUGH */
3532 default:
3533 assert(0);
3538 zs_zone_limit_type(int limit)
3540 switch (limit) {
3541 case ZS_LIMIT_CPU:
3542 case ZS_LIMIT_CPU_SHARES:
3543 return (ZS_LIMIT_TYPE_TIME);
3544 case ZS_LIMIT_RAM_RSS:
3545 case ZS_LIMIT_RAM_LOCKED:
3546 case ZS_LIMIT_VM:
3547 case ZS_LIMIT_SHM_MEMORY:
3548 return (ZS_LIMIT_TYPE_BYTES);
3549 case ZS_LIMIT_LWPS:
3550 case ZS_LIMIT_PROCESSES:
3551 case ZS_LIMIT_SHM_IDS:
3552 case ZS_LIMIT_MSG_IDS:
3553 case ZS_LIMIT_SEM_IDS:
3554 return (ZS_LIMIT_TYPE_COUNT);
3555 default:
3556 assert(0);
3557 return (0);
3561 * Gets the zones limit. Returns ZS_LIMIT_NONE if no limit set.
3563 uint64_t
3564 zs_zone_limit_uint64(zs_zone_t *z, int limit)
3566 uint64_t v;
3568 switch (limit) {
3569 case ZS_LIMIT_CPU:
3570 v = zs_zone_cpu_cap(z);
3571 break;
3572 case ZS_LIMIT_CPU_SHARES:
3573 v = zs_zone_cpu_shares(z);
3574 break;
3575 case ZS_LIMIT_RAM_RSS:
3576 v = zs_zone_physical_memory_cap(z);
3577 break;
3578 case ZS_LIMIT_RAM_LOCKED:
3579 v = zs_zone_locked_memory_cap(z);
3580 break;
3581 case ZS_LIMIT_VM:
3582 v = zs_zone_virtual_memory_cap(z);
3583 break;
3584 case ZS_LIMIT_LWPS:
3585 v = z->zsz_lwps_cap;
3586 break;
3587 case ZS_LIMIT_PROCESSES:
3588 v = z->zsz_processes_cap;
3589 break;
3590 case ZS_LIMIT_SHM_MEMORY:
3591 v = z->zsz_shm_cap;
3592 break;
3593 case ZS_LIMIT_SHM_IDS:
3594 v = z->zsz_shmids_cap;
3595 break;
3596 case ZS_LIMIT_SEM_IDS:
3597 v = z->zsz_semids_cap;
3598 break;
3599 case ZS_LIMIT_MSG_IDS:
3600 v = z->zsz_msgids_cap;
3601 break;
3602 case ZS_LIMIT_LOFI:
3603 v = z->zsz_lofi_cap;
3604 break;
3605 default:
3606 assert(0);
3608 return (v);
3612 * Gets the amount of resource used for a limit. Returns ZS_LIMIT_NONE if
3613 * no limit configured.
3615 uint64_t
3616 zs_zone_limit_used_uint64(zs_zone_t *z, int limit)
3618 uint64_t v;
3620 switch (limit) {
3621 case ZS_LIMIT_CPU:
3622 v = zs_zone_cpu_cap_used(z);
3623 break;
3624 case ZS_LIMIT_CPU_SHARES:
3625 v = zs_zone_cpu_shares_used(z);
3626 break;
3627 case ZS_LIMIT_RAM_RSS:
3628 v = zs_zone_physical_memory_cap_used(z);
3629 break;
3630 case ZS_LIMIT_RAM_LOCKED:
3631 v = zs_zone_locked_memory_cap_used(z);
3632 break;
3633 case ZS_LIMIT_VM:
3634 v = zs_zone_virtual_memory_cap_used(z);
3635 break;
3636 case ZS_LIMIT_LWPS:
3637 v = z->zsz_lwps;
3638 break;
3639 case ZS_LIMIT_PROCESSES:
3640 v = z->zsz_processes;
3641 break;
3642 case ZS_LIMIT_SHM_MEMORY:
3643 v = z->zsz_shm;
3644 break;
3645 case ZS_LIMIT_SHM_IDS:
3646 v = z->zsz_shmids;
3647 break;
3648 case ZS_LIMIT_SEM_IDS:
3649 v = z->zsz_semids;
3650 break;
3651 case ZS_LIMIT_MSG_IDS:
3652 v = z->zsz_msgids;
3653 break;
3654 case ZS_LIMIT_LOFI:
3655 v = z->zsz_lofi;
3656 break;
3657 default:
3658 assert(0);
3660 return (v);
3664 * Gets time used under limit. Time is zero if no limit is configured
3666 void
3667 zs_zone_limit_time(zs_zone_t *z, int limit, timestruc_t *v)
3669 switch (limit) {
3670 case ZS_LIMIT_CPU:
3671 if (z->zsz_cpu_cap == ZS_LIMIT_NONE) {
3672 v->tv_sec = 0;
3673 v->tv_nsec = 0;
3674 break;
3676 zs_zone_cpu_cap_time(z, v);
3677 break;
3678 case ZS_LIMIT_CPU_SHARES:
3679 if (z->zsz_cpu_shares == ZS_LIMIT_NONE ||
3680 z->zsz_cpu_shares == ZS_SHARES_UNLIMITED ||
3681 z->zsz_cpu_shares == 0 ||
3682 (z->zsz_scheds & ZS_SCHED_FSS) == 0) {
3683 v->tv_sec = 0;
3684 v->tv_nsec = 0;
3685 break;
3687 zs_zone_cpu_share_time(z, v);
3688 break;
3689 case ZS_LIMIT_RAM_RSS:
3690 case ZS_LIMIT_RAM_LOCKED:
3691 case ZS_LIMIT_VM:
3692 case ZS_LIMIT_SHM_MEMORY:
3693 case ZS_LIMIT_LWPS:
3694 case ZS_LIMIT_PROCESSES:
3695 case ZS_LIMIT_SHM_IDS:
3696 case ZS_LIMIT_MSG_IDS:
3697 case ZS_LIMIT_SEM_IDS:
3698 /* FALLTHROUGH */
3699 default:
3700 assert(0);
3705 * Errno is set on error:
3707 * EINVAL: No such property
3708 * ENOENT: No time value for the specified limit.
3709 * ESRCH: No limit is configured.
3711 * If no limit is configured, the value will be ZS_PCT_NONE
3713 void
3714 zs_zone_limit_used_time(zs_zone_t *z, int limit, timestruc_t *t)
3716 switch (limit) {
3717 case ZS_LIMIT_CPU:
3718 if (z->zsz_cpu_cap == ZS_LIMIT_NONE) {
3719 t->tv_sec = 0;
3720 t->tv_nsec = 0;
3721 break;
3723 zs_zone_cpu_cap_time_used(z, t);
3724 break;
3725 case ZS_LIMIT_CPU_SHARES:
3726 if (z->zsz_cpu_shares == ZS_LIMIT_NONE ||
3727 z->zsz_cpu_shares == ZS_SHARES_UNLIMITED ||
3728 z->zsz_cpu_shares == 0 ||
3729 (z->zsz_scheds & ZS_SCHED_FSS) == 0) {
3730 t->tv_sec = 0;
3731 t->tv_nsec = 0;
3732 break;
3734 zs_zone_cpu_share_time_used(z, t);
3735 break;
3736 case ZS_LIMIT_RAM_RSS:
3737 case ZS_LIMIT_RAM_LOCKED:
3738 case ZS_LIMIT_VM:
3739 case ZS_LIMIT_SHM_MEMORY:
3740 case ZS_LIMIT_LWPS:
3741 case ZS_LIMIT_PROCESSES:
3742 case ZS_LIMIT_SHM_IDS:
3743 case ZS_LIMIT_MSG_IDS:
3744 case ZS_LIMIT_SEM_IDS:
3745 /* FALLTHROUGH */
3746 default:
3747 assert(0);
3752 * Get a zones usage as a percent of the limit. Return ZS_PCT_NONE if
3753 * no limit is configured.
3755 uint_t
3756 zs_zone_limit_used_pct(zs_zone_t *z, int limit)
3758 uint_t v;
3760 switch (limit) {
3761 case ZS_LIMIT_CPU:
3762 v = zs_zone_cpu_cap_pct(z);
3763 break;
3764 case ZS_LIMIT_CPU_SHARES:
3765 v = zs_zone_cpu_shares_pct(z);
3766 break;
3767 case ZS_LIMIT_RAM_RSS:
3768 v = zs_zone_physical_memory_cap_pct(z);
3769 break;
3770 case ZS_LIMIT_RAM_LOCKED:
3771 v = zs_zone_locked_memory_cap_pct(z);
3772 break;
3773 case ZS_LIMIT_VM:
3774 v = zs_zone_virtual_memory_cap_pct(z);
3775 break;
3776 case ZS_LIMIT_LWPS:
3777 v = zs_lwps_zone_cap_pct(z);
3778 break;
3779 case ZS_LIMIT_PROCESSES:
3780 v = zs_processes_zone_cap_pct(z);
3781 break;
3782 case ZS_LIMIT_SHM_MEMORY:
3783 v = zs_shm_zone_cap_pct(z);
3784 break;
3785 case ZS_LIMIT_SHM_IDS:
3786 v = zs_shmids_zone_cap_pct(z);
3787 break;
3788 case ZS_LIMIT_SEM_IDS:
3789 v = zs_semids_zone_cap_pct(z);
3790 break;
3791 case ZS_LIMIT_MSG_IDS:
3792 v = zs_msgids_zone_cap_pct(z);
3793 break;
3794 case ZS_LIMIT_LOFI:
3795 v = zs_lofi_zone_cap_pct(z);
3796 break;
3797 default:
3798 assert(0);
3800 return (v);
3804 zs_pset_list(zs_usage_t *usage, zs_pset_t **psetlist, int num)
3806 int i = 0;
3807 zs_pset_t *pset, *tmp;
3809 /* copy what fits of the pset list into the buffer */
3810 for (pset = list_head(&usage->zsu_pset_list); pset != NULL;
3811 pset = list_next(&usage->zsu_pset_list, pset)) {
3813 /* put the default pset at the first position */
3814 if (i < num) {
3815 if (pset->zsp_id == ZS_PSET_DEFAULT) {
3816 tmp = psetlist[0];
3817 psetlist[i] = tmp;
3818 psetlist[0] = pset;
3819 } else {
3820 psetlist[i] = pset;
3823 i++;
3825 return (i);
3828 zs_pset_t *
3829 zs_pset_first(zs_usage_t *usage)
3831 return (list_head(&usage->zsu_pset_list));
3834 zs_pset_t *
3835 zs_pset_next(zs_usage_t *usage, zs_pset_t *pset)
3837 return (list_next(&usage->zsu_pset_list, pset));
3841 * Get various properties on a pset.
3843 void
3844 zs_pset_property(zs_pset_t *pset, int prop, zs_property_t *p)
3846 switch (prop) {
3848 case ZS_PSET_PROP_NAME:
3849 p->zsp_type = ZS_PROP_TYPE_STRING;
3850 p->zsp_id = prop;
3851 (void) zs_pset_name(pset, p->zsp_v.zsv_string,
3852 sizeof (p->zsp_v.zsv_string));
3853 break;
3854 case ZS_PSET_PROP_ID:
3855 p->zsp_type = ZS_PROP_TYPE_INT;
3856 p->zsp_id = prop;
3857 p->zsp_v.zsv_int = zs_pset_id(pset);
3858 break;
3859 case ZS_PSET_PROP_CPUTYPE:
3860 p->zsp_type = ZS_PROP_TYPE_UINT;
3861 p->zsp_id = prop;
3862 p->zsp_v.zsv_uint = zs_pset_cputype(pset);
3863 break;
3864 case ZS_PSET_PROP_SIZE:
3865 p->zsp_type = ZS_PROP_TYPE_UINT64;
3866 p->zsp_id = prop;
3867 p->zsp_v.zsv_uint64 = zs_pset_size(pset);
3868 break;
3869 case ZS_PSET_PROP_ONLINE:
3870 p->zsp_type = ZS_PROP_TYPE_UINT64;
3871 p->zsp_id = prop;
3872 p->zsp_v.zsv_uint64 = zs_pset_online(pset);
3873 break;
3874 case ZS_PSET_PROP_MIN:
3875 p->zsp_type = ZS_PROP_TYPE_UINT64;
3876 p->zsp_id = prop;
3877 p->zsp_v.zsv_uint64 = zs_pset_min(pset);
3878 break;
3879 case ZS_PSET_PROP_MAX:
3880 p->zsp_type = ZS_PROP_TYPE_UINT64;
3881 p->zsp_id = prop;
3882 p->zsp_v.zsv_uint64 = zs_pset_max(pset);
3883 break;
3884 case ZS_PSET_PROP_CPU_SHARES:
3885 p->zsp_type = ZS_PROP_TYPE_UINT64;
3886 p->zsp_id = prop;
3887 p->zsp_v.zsv_uint64 = zs_pset_cpu_shares(pset);
3888 break;
3889 case ZS_PSET_PROP_SCHEDULERS:
3890 p->zsp_type = ZS_PROP_TYPE_UINT;
3891 p->zsp_id = prop;
3892 p->zsp_v.zsv_uint = zs_pset_schedulers(pset);
3893 break;
3894 /* Not implemented */
3895 case ZS_PSET_PROP_CREATETIME:
3896 case ZS_PSET_PROP_LOAD_1MIN:
3897 case ZS_PSET_PROP_LOAD_5MIN:
3898 case ZS_PSET_PROP_LOAD_15MIN:
3899 /* FALLTHROUGH */
3900 default:
3901 assert(0);
3905 void
3906 zs_pset_total_time(zs_pset_t *pset, timestruc_t *t)
3908 *t = pset->zsp_total_time;
3911 uint64_t
3912 zs_pset_total_cpus(zs_pset_t *pset)
3914 return (pset->zsp_online * ZSD_ONE_CPU);
3918 * Get total time used for pset
3920 void
3921 zs_pset_used_time(zs_pset_t *pset, int user, timestruc_t *t)
3923 switch (user) {
3924 case ZS_USER_ALL:
3925 zs_pset_usage_all(pset, t);
3926 break;
3927 case ZS_USER_KERNEL:
3928 zs_pset_usage_kernel(pset, t);
3929 break;
3930 case ZS_USER_ZONES:
3931 zs_pset_usage_zones(pset, t);
3932 break;
3933 case ZS_USER_FREE:
3934 zs_pset_usage_idle(pset, t);
3935 break;
3936 default:
3937 assert(0);
3942 * Returns 0 on success. -1 on failure.
3944 * ERRORS
3945 * EINVAL: Invalid user.
3948 uint64_t
3949 zs_pset_used_cpus(zs_pset_t *pset, int user)
3951 uint_t v;
3953 switch (user) {
3954 case ZS_USER_ALL:
3955 v = zs_pset_usage_all_cpus(pset);
3956 break;
3957 case ZS_USER_KERNEL:
3958 v = zs_pset_usage_kernel_cpus(pset);
3959 break;
3960 case ZS_USER_ZONES:
3961 v = zs_pset_usage_zones_cpus(pset);
3962 break;
3963 case ZS_USER_FREE:
3964 v = zs_pset_usage_idle_cpus(pset);
3965 break;
3966 default:
3967 assert(0);
3969 return (v);
3972 * Get percent of pset cpu time used
3974 uint_t
3975 zs_pset_used_pct(zs_pset_t *pset, int user)
3977 uint_t v;
3979 switch (user) {
3980 case ZS_USER_ALL:
3981 v = zs_pset_usage_all_pct(pset);
3982 break;
3983 case ZS_USER_KERNEL:
3984 v = zs_pset_usage_kernel_pct(pset);
3985 break;
3986 case ZS_USER_ZONES:
3987 v = zs_pset_usage_zones_pct(pset);
3988 break;
3989 case ZS_USER_FREE:
3990 v = zs_pset_usage_idle_pct(pset);
3991 break;
3992 default:
3993 assert(0);
3995 return (v);
3999 zs_pset_zone_list(zs_pset_t *pset, zs_pset_zone_t **zonelist, int num)
4001 int i = 0;
4002 zs_pset_zone_t *zone, *tmp;
4004 /* copy what fits of the pset's zone list into the buffer */
4005 for (zone = list_head(&pset->zsp_usage_list); zone != NULL;
4006 zone = list_next(&pset->zsp_usage_list, zone)) {
4008 /* put the global zone at the first position */
4009 if (i < num) {
4010 if (zone->zspz_zone->zsz_id == GLOBAL_ZONEID) {
4011 tmp = zonelist[0];
4012 zonelist[i] = tmp;
4013 zonelist[0] = zone;
4014 } else {
4015 zonelist[i] = zone;
4018 i++;
4020 return (i);
4023 zs_pset_zone_t *
4024 zs_pset_zone_first(zs_pset_t *pset)
4026 return (list_head(&pset->zsp_usage_list));
4029 zs_pset_zone_t *
4030 zs_pset_zone_next(zs_pset_t *pset, zs_pset_zone_t *pz)
4032 return (list_next(&pset->zsp_usage_list, pz));
4035 zs_pset_t *
4036 zs_pset_zone_get_pset(zs_pset_zone_t *pz)
4038 return (pz->zspz_pset);
4041 zs_zone_t *
4042 zs_pset_zone_get_zone(zs_pset_zone_t *pz)
4044 return (pz->zspz_zone);
4048 * Get a property describing a zone's usage of a pset
4050 void
4051 zs_pset_zone_property(zs_pset_zone_t *pz, int prop, zs_property_t *p)
4053 switch (prop) {
4055 case ZS_PZ_PROP_CPU_CAP:
4056 p->zsp_type = ZS_PROP_TYPE_UINT64;
4057 p->zsp_id = prop;
4058 p->zsp_v.zsv_uint64 = (int)zs_pset_zone_cpu_cap(pz);
4059 break;
4060 case ZS_PZ_PROP_CPU_SHARES:
4061 p->zsp_type = ZS_PROP_TYPE_UINT64;
4062 p->zsp_id = prop;
4063 p->zsp_v.zsv_uint64 = (int)zs_pset_zone_cpu_shares(pz);
4064 break;
4065 case ZS_PZ_PROP_SCHEDULERS:
4066 p->zsp_type = ZS_PROP_TYPE_UINT;
4067 p->zsp_id = prop;
4068 p->zsp_v.zsv_uint = (int)zs_pset_zone_schedulers(pz);
4069 break;
4070 default:
4071 assert(0);
4075 void
4076 zs_pset_zone_used_time(zs_pset_zone_t *pz, timestruc_t *t)
4078 zs_pset_zone_usage_time(pz, t);
4081 uint64_t
4082 zs_pset_zone_used_cpus(zs_pset_zone_t *pz)
4084 return (zs_pset_zone_usage_cpus(pz));
4088 * Get percent of a psets cpus used by a zone
4090 uint_t
4091 zs_pset_zone_used_pct(zs_pset_zone_t *pz, int type)
4093 uint_t v;
4095 switch (type) {
4096 case ZS_PZ_PCT_PSET:
4097 v = zs_pset_zone_usage_pct_pset(pz);
4098 break;
4099 case ZS_PZ_PCT_CPU_CAP:
4100 v = zs_pset_zone_usage_pct_cpu_cap(pz);
4101 break;
4102 case ZS_PZ_PCT_PSET_SHARES:
4103 v = zs_pset_zone_usage_pct_pset_shares(pz);
4104 break;
4105 case ZS_PZ_PCT_CPU_SHARES:
4106 v = zs_pset_zone_usage_pct_cpu_shares(pz);
4107 break;
4108 default:
4109 assert(0);
4111 return (v);
4115 * returns similar to malloc
4117 zs_property_t *
4118 zs_property_alloc()
4120 return ((zs_property_t *)malloc(sizeof (zs_property_t)));
4123 size_t
4124 zs_property_size()
4126 return (sizeof (zs_property_t));
4129 void
4130 zs_property_free(zs_property_t *p)
4132 free(p);
4136 zs_property_type(zs_property_t *p)
4138 return (p->zsp_type);
4142 zs_property_id(zs_property_t *p)
4144 return (p->zsp_id);
4147 char *
4148 zs_property_string(zs_property_t *p)
4150 assert(p->zsp_type == ZS_PROP_TYPE_STRING);
4151 return (p->zsp_v.zsv_string);
4154 double
4155 zs_property_double(zs_property_t *p)
4157 assert(p->zsp_type == ZS_PROP_TYPE_DOUBLE);
4158 return (p->zsp_v.zsv_double);
4161 void
4162 zs_property_time(zs_property_t *p, timestruc_t *t)
4164 assert(p->zsp_type == ZS_PROP_TYPE_TIME);
4165 *t = p->zsp_v.zsv_ts;
4168 uint64_t
4169 zs_property_uint64(zs_property_t *p)
4171 assert(p->zsp_type == ZS_PROP_TYPE_UINT64);
4172 return (p->zsp_v.zsv_uint64);
4175 int64_t
4176 zs_property_int64(zs_property_t *p)
4178 assert(p->zsp_type == ZS_PROP_TYPE_INT64);
4179 return (p->zsp_v.zsv_int64);
4182 uint_t
4183 zs_property_uint(zs_property_t *p)
4185 assert(p->zsp_type == ZS_PROP_TYPE_UINT);
4186 return (p->zsp_v.zsv_uint);
4190 zs_property_int(zs_property_t *p)
4192 assert(p->zsp_type == ZS_PROP_TYPE_INT);
4193 return (p->zsp_v.zsv_uint);