dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / libzonestat / common / libzonestat.c
blob4238a264fa615c159fa156e8e87bf83137560204
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 free(set->zsus_total);
2515 free(set->zsus_avg);
2516 free(set->zsus_high);
2518 return (NULL);
2521 void
2522 zs_usage_set_free(zs_usage_set_t *set)
2524 zs_usage_free(set->zsus_total);
2525 zs_usage_free(set->zsus_avg);
2526 zs_usage_free(set->zsus_high);
2527 free(set);
2531 zs_usage_set_add(zs_usage_set_t *set, zs_usage_t *usage)
2534 /* Compute ongoing functions for usage set */
2535 (void) zs_usage_compute(set->zsus_high, set->zsus_high, usage,
2536 ZS_COMPUTE_USAGE_HIGH);
2538 (void) zs_usage_compute(set->zsus_total, set->zsus_total, usage,
2539 ZS_COMPUTE_USAGE_TOTAL);
2541 (void) zs_usage_compute(set->zsus_avg, set->zsus_avg, usage,
2542 ZS_COMPUTE_USAGE_AVERAGE);
2544 set->zsus_count++;
2545 zs_usage_free(usage);
2546 return (0);
2550 zs_usage_set_count(zs_usage_set_t *set)
2552 return (set->zsus_count);
2555 zs_usage_t *
2556 zs_usage_set_compute(zs_usage_set_t *set, int func)
2558 zs_usage_t *u;
2559 zs_system_t *s;
2560 zs_zone_t *z;
2561 zs_pset_t *p;
2562 zs_pset_zone_t *pz;
2563 uint_t intervals;
2564 boolean_t average;
2566 switch (func) {
2567 case ZS_COMPUTE_SET_HIGH:
2568 return (set->zsus_high);
2569 case ZS_COMPUTE_SET_TOTAL:
2570 u = set->zsus_total;
2571 average = B_FALSE;
2572 break;
2573 case ZS_COMPUTE_SET_AVERAGE:
2574 u = set->zsus_avg;
2575 average = B_TRUE;
2576 break;
2577 default:
2578 assert(0);
2581 s = u->zsu_system;
2583 s->zss_ram_total /= u->zsu_intervals;
2584 s->zss_ram_total *= 1024;
2585 s->zss_ram_kern /= u->zsu_intervals;
2586 s->zss_ram_kern *= 1024;
2587 s->zss_ram_zones /= u->zsu_intervals;
2588 s->zss_ram_zones *= 1024;
2589 s->zss_locked_kern /= u->zsu_intervals;
2590 s->zss_locked_kern *= 1024;
2591 s->zss_locked_zones /= u->zsu_intervals;
2592 s->zss_locked_zones *= 1024;
2593 s->zss_vm_total /= u->zsu_intervals;
2594 s->zss_vm_total *= 1024;
2595 s->zss_vm_kern /= u->zsu_intervals;
2596 s->zss_vm_kern *= 1024;
2597 s->zss_vm_zones /= u->zsu_intervals;
2598 s->zss_vm_zones *= 1024;
2599 s->zss_swap_total /= u->zsu_intervals;
2600 s->zss_swap_total *= 1024;
2601 s->zss_swap_used /= u->zsu_intervals;
2602 s->zss_swap_used *= 1024;
2603 s->zss_processes /= u->zsu_intervals;
2604 s->zss_lwps /= u->zsu_intervals;
2605 s->zss_shm /= u->zsu_intervals;
2606 s->zss_shm *= 1024;
2607 s->zss_shmids /= u->zsu_intervals;
2608 s->zss_semids /= u->zsu_intervals;
2609 s->zss_msgids /= u->zsu_intervals;
2610 s->zss_lofi /= u->zsu_intervals;
2612 s->zss_ncpus /= u->zsu_intervals;
2613 s->zss_ncpus_online /= u->zsu_intervals;
2615 for (z = list_head(&u->zsu_zone_list); z != NULL;
2616 z = list_next(&u->zsu_zone_list, z)) {
2618 if (average) {
2619 intervals = z->zsz_intervals;
2620 } else {
2621 assert(z->zsz_intervals == 0);
2622 intervals = u->zsu_intervals;
2625 if (z->zsz_cpu_cap != ZS_LIMIT_NONE)
2626 z->zsz_cpu_cap /= z->zsz_intervals;
2627 if (z->zsz_ram_cap != ZS_LIMIT_NONE)
2628 z->zsz_ram_cap /= z->zsz_intervals;
2629 if (z->zsz_vm_cap != ZS_LIMIT_NONE)
2630 z->zsz_vm_cap /= z->zsz_intervals;
2631 if (z->zsz_locked_cap != ZS_LIMIT_NONE)
2632 z->zsz_locked_cap /= z->zsz_intervals;
2633 if (z->zsz_processes_cap != ZS_LIMIT_NONE)
2634 z->zsz_processes_cap /= z->zsz_intervals;
2635 if (z->zsz_lwps_cap != ZS_LIMIT_NONE)
2636 z->zsz_lwps_cap /= z->zsz_intervals;
2637 if (z->zsz_shm_cap != ZS_LIMIT_NONE)
2638 z->zsz_shm_cap /= z->zsz_intervals;
2639 if (z->zsz_shmids_cap != ZS_LIMIT_NONE)
2640 z->zsz_shmids_cap /= z->zsz_intervals;
2641 if (z->zsz_semids_cap != ZS_LIMIT_NONE)
2642 z->zsz_semids_cap /= z->zsz_intervals;
2643 if (z->zsz_msgids_cap != ZS_LIMIT_NONE)
2644 z->zsz_msgids_cap /= z->zsz_intervals;
2645 if (z->zsz_lofi_cap != ZS_LIMIT_NONE)
2646 z->zsz_lofi_cap /= z->zsz_intervals;
2648 z->zsz_usage_ram /= intervals;
2649 z->zsz_usage_locked /= intervals;
2650 z->zsz_usage_vm /= intervals;
2651 z->zsz_processes /= intervals;
2652 z->zsz_lwps /= intervals;
2653 z->zsz_shm /= intervals;
2654 z->zsz_shmids /= intervals;
2655 z->zsz_semids /= intervals;
2656 z->zsz_msgids /= intervals;
2657 z->zsz_lofi /= intervals;
2658 z->zsz_cpus_online /= intervals;
2659 z->zsz_cpu_shares /= intervals;
2661 for (p = list_head(&u->zsu_pset_list); p != NULL;
2662 p = list_next(&u->zsu_pset_list, p)) {
2664 intervals = p->zsp_intervals;
2666 p->zsp_online /= intervals;
2667 p->zsp_size /= intervals;
2668 p->zsp_min /= intervals;
2669 p->zsp_max /= intervals;
2670 p->zsp_importance /= intervals;
2671 p->zsp_cpu_shares /= intervals;
2673 for (pz = list_head(&p->zsp_usage_list); pz != NULL;
2674 pz = list_next(&p->zsp_usage_list, pz)) {
2676 if (average) {
2677 intervals = pz->zspz_intervals;
2678 } else {
2679 assert(pz->zspz_intervals == 0);
2680 intervals = p->zsp_intervals;
2682 pz->zspz_cpu_shares /= intervals;
2685 return (u);
2689 * Returns 0 on success. Trips assert on invalid property.
2691 void
2692 zs_resource_property(zs_usage_t *u, int res, int prop, zs_property_t *p)
2694 switch (res) {
2695 case ZS_RESOURCE_CPU:
2696 switch (prop) {
2697 case ZS_RESOURCE_PROP_CPU_TOTAL:
2698 p->zsp_id = prop;
2699 p->zsp_type = ZS_PROP_TYPE_UINT64;
2700 p->zsp_v.zsv_uint64 = u->zsu_system->zss_ncpus;
2701 break;
2702 case ZS_RESOURCE_PROP_CPU_ONLINE:
2703 p->zsp_id = prop;
2704 p->zsp_type = ZS_PROP_TYPE_UINT64;
2705 p->zsp_v.zsv_uint64 = u->zsu_system->zss_ncpus_online;
2706 break;
2707 default:
2708 assert(0);
2710 break;
2711 case ZS_RESOURCE_RAM_RSS:
2712 case ZS_RESOURCE_RAM_LOCKED:
2713 case ZS_RESOURCE_VM:
2714 case ZS_RESOURCE_DISK_SWAP:
2715 case ZS_RESOURCE_LWPS:
2716 case ZS_RESOURCE_PROCESSES:
2717 case ZS_RESOURCE_SHM_MEMORY:
2718 case ZS_RESOURCE_SHM_IDS:
2719 case ZS_RESOURCE_SEM_IDS:
2720 case ZS_RESOURCE_MSG_IDS:
2721 /* FALLTHROUGH */
2722 default:
2723 assert(0);
2728 * Returns one of ZS_RESOURCE_TYPE_* on success. Asserts on invalid
2729 * resource.
2732 zs_resource_type(int res)
2734 switch (res) {
2735 case ZS_RESOURCE_CPU:
2736 return (ZS_RESOURCE_TYPE_TIME);
2737 break;
2738 case ZS_RESOURCE_RAM_RSS:
2739 case ZS_RESOURCE_RAM_LOCKED:
2740 case ZS_RESOURCE_VM:
2741 case ZS_RESOURCE_DISK_SWAP:
2742 case ZS_RESOURCE_SHM_MEMORY:
2743 return (ZS_RESOURCE_TYPE_BYTES);
2744 break;
2745 case ZS_RESOURCE_LWPS:
2746 case ZS_RESOURCE_PROCESSES:
2747 case ZS_RESOURCE_SHM_IDS:
2748 case ZS_RESOURCE_SEM_IDS:
2749 case ZS_RESOURCE_MSG_IDS:
2750 return (ZS_RESOURCE_TYPE_COUNT);
2751 break;
2752 default:
2753 assert(0);
2754 return (0);
2759 * Get total available resource on system
2761 uint64_t
2762 zs_resource_total_uint64(zs_usage_t *u, int res)
2764 uint64_t v;
2766 switch (res) {
2767 case ZS_RESOURCE_CPU:
2768 v = zs_cpu_total_cpu(u);
2769 break;
2770 case ZS_RESOURCE_RAM_RSS:
2771 v = zs_physical_memory_total(u);
2772 break;
2773 case ZS_RESOURCE_RAM_LOCKED:
2774 v = zs_locked_memory_total(u);
2775 break;
2776 case ZS_RESOURCE_VM:
2777 v = zs_virtual_memory_total(u);
2778 break;
2779 case ZS_RESOURCE_DISK_SWAP:
2780 v = zs_disk_swap_total(u);
2781 break;
2782 case ZS_RESOURCE_LWPS:
2783 v = zs_lwps_total(u);
2784 break;
2785 case ZS_RESOURCE_PROCESSES:
2786 v = zs_processes_total(u);
2787 break;
2788 case ZS_RESOURCE_SHM_MEMORY:
2789 v = zs_shm_total(u);
2790 break;
2791 case ZS_RESOURCE_SHM_IDS:
2792 v = zs_shmids_total(u);
2793 break;
2794 case ZS_RESOURCE_SEM_IDS:
2795 v = zs_semids_total(u);
2796 break;
2797 case ZS_RESOURCE_MSG_IDS:
2798 v = zs_msgids_total(u);
2799 break;
2800 case ZS_RESOURCE_LOFI:
2801 v = zs_lofi_total(u);
2802 break;
2803 default:
2804 assert(0);
2806 return (v);
2810 * Get amount of used resource.
2812 uint64_t
2813 zs_resource_used_uint64(zs_usage_t *u, int res, int user)
2815 uint64_t v;
2817 switch (res) {
2818 case ZS_RESOURCE_CPU:
2819 switch (user) {
2820 case ZS_USER_ALL:
2821 v = zs_cpu_usage_all_cpu(u);
2822 break;
2823 case ZS_USER_KERNEL:
2824 v = zs_cpu_usage_kernel_cpu(u);
2825 break;
2826 case ZS_USER_ZONES:
2827 v = zs_cpu_usage_zones_cpu(u);
2828 break;
2829 case ZS_USER_FREE:
2830 v = zs_cpu_usage_idle_cpu(u);
2831 break;
2832 default:
2833 assert(0);
2835 break;
2836 case ZS_RESOURCE_RAM_RSS:
2837 switch (user) {
2838 case ZS_USER_ALL:
2839 v = zs_physical_memory_usage_all(u);
2840 break;
2841 case ZS_USER_KERNEL:
2842 v = zs_physical_memory_usage_kernel(u);
2843 break;
2844 case ZS_USER_ZONES:
2845 v = zs_physical_memory_usage_zones(u);
2846 break;
2847 case ZS_USER_FREE:
2848 v = zs_physical_memory_usage_free(u);
2849 break;
2850 default:
2851 assert(0);
2853 break;
2854 case ZS_RESOURCE_RAM_LOCKED:
2855 switch (user) {
2856 case ZS_USER_ALL:
2857 v = zs_locked_memory_usage_all(u);
2858 break;
2859 case ZS_USER_KERNEL:
2860 v = zs_locked_memory_usage_kernel(u);
2861 break;
2862 case ZS_USER_ZONES:
2863 v = zs_locked_memory_usage_zones(u);
2864 break;
2865 case ZS_USER_FREE:
2866 v = zs_locked_memory_usage_free(u);
2867 break;
2868 default:
2869 assert(0);
2871 break;
2872 case ZS_RESOURCE_VM:
2873 switch (user) {
2874 case ZS_USER_ALL:
2875 v = zs_virtual_memory_usage_all(u);
2876 break;
2877 case ZS_USER_KERNEL:
2878 v = zs_virtual_memory_usage_kernel(u);
2879 break;
2880 case ZS_USER_ZONES:
2881 v = zs_virtual_memory_usage_zones(u);
2882 break;
2883 case ZS_USER_FREE:
2884 v = zs_virtual_memory_usage_free(u);
2885 break;
2886 default:
2887 assert(0);
2889 break;
2890 case ZS_RESOURCE_DISK_SWAP:
2891 switch (user) {
2892 case ZS_USER_ALL:
2893 v = zs_disk_swap_usage_all(u);
2894 break;
2895 case ZS_USER_FREE:
2896 v = zs_disk_swap_usage_free(u);
2897 break;
2898 case ZS_USER_KERNEL:
2899 case ZS_USER_ZONES:
2900 /* FALLTHROUGH */
2901 default:
2902 assert(0);
2904 break;
2905 case ZS_RESOURCE_LWPS:
2906 switch (user) {
2907 case ZS_USER_ALL:
2908 case ZS_USER_ZONES:
2909 v = zs_lwps_usage_all(u);
2910 break;
2911 case ZS_USER_FREE:
2912 v = zs_lwps_total(u) - zs_lwps_usage_all(u);
2913 break;
2914 case ZS_USER_KERNEL:
2915 v = 0;
2916 break;
2917 default:
2918 assert(0);
2920 break;
2921 case ZS_RESOURCE_PROCESSES:
2922 switch (user) {
2923 case ZS_USER_ALL:
2924 case ZS_USER_ZONES:
2925 v = zs_processes_usage_all(u);
2926 break;
2927 case ZS_USER_FREE:
2928 v = zs_processes_total(u) - zs_processes_usage_all(u);
2929 break;
2930 case ZS_USER_KERNEL:
2931 v = 0;
2932 break;
2933 default:
2934 assert(0);
2936 break;
2937 case ZS_RESOURCE_SHM_MEMORY:
2938 switch (user) {
2939 case ZS_USER_ALL:
2940 case ZS_USER_ZONES:
2941 v = zs_shm_usage_all(u);
2942 break;
2943 case ZS_USER_FREE:
2944 v = zs_shm_total(u) -
2945 zs_shm_usage_all(u);
2946 break;
2947 case ZS_USER_KERNEL:
2948 v = 0;
2949 break;
2950 default:
2951 assert(0);
2953 break;
2954 case ZS_RESOURCE_SHM_IDS:
2955 switch (user) {
2956 case ZS_USER_ALL:
2957 case ZS_USER_ZONES:
2958 v = zs_shmids_usage_all(u);
2959 break;
2960 case ZS_USER_FREE:
2961 v = zs_shmids_total(u) - zs_shmids_usage_all(u);
2962 break;
2963 case ZS_USER_KERNEL:
2964 v = 0;
2965 break;
2966 default:
2967 assert(0);
2969 break;
2970 case ZS_RESOURCE_SEM_IDS:
2971 switch (user) {
2972 case ZS_USER_ALL:
2973 case ZS_USER_ZONES:
2974 v = zs_semids_usage_all(u);
2975 break;
2976 case ZS_USER_FREE:
2977 v = zs_semids_total(u) - zs_semids_usage_all(u);
2978 break;
2979 case ZS_USER_KERNEL:
2980 v = 0;
2981 break;
2982 default:
2983 assert(0);
2985 break;
2986 case ZS_RESOURCE_MSG_IDS:
2987 switch (user) {
2988 case ZS_USER_ALL:
2989 case ZS_USER_ZONES:
2990 v = zs_msgids_usage_all(u);
2991 break;
2992 case ZS_USER_FREE:
2993 v = zs_msgids_total(u) - zs_msgids_usage_all(u);
2994 break;
2995 case ZS_USER_KERNEL:
2996 v = 0;
2997 break;
2998 default:
2999 assert(0);
3001 break;
3002 case ZS_RESOURCE_LOFI:
3003 switch (user) {
3004 case ZS_USER_ALL:
3005 case ZS_USER_ZONES:
3006 v = zs_lofi_usage_all(u);
3007 break;
3008 case ZS_USER_FREE:
3009 v = zs_lofi_total(u) - zs_lofi_usage_all(u);
3010 break;
3011 case ZS_USER_KERNEL:
3012 v = 0;
3013 break;
3014 default:
3015 assert(0);
3017 break;
3019 default:
3020 assert(0);
3022 return (v);
3026 * Get used resource as a percent of total resource.
3028 uint_t
3029 zs_resource_used_pct(zs_usage_t *u, int res, int user)
3031 uint64_t v;
3033 switch (res) {
3034 case ZS_RESOURCE_CPU:
3035 switch (user) {
3036 case ZS_USER_ALL:
3037 v = zs_cpu_usage_all_pct(u);
3038 break;
3039 case ZS_USER_KERNEL:
3040 v = zs_cpu_usage_kernel_pct(u);
3041 break;
3042 case ZS_USER_ZONES:
3043 v = zs_cpu_usage_zones_pct(u);
3044 break;
3045 case ZS_USER_FREE:
3046 v = zs_cpu_usage_idle_pct(u);
3047 break;
3048 default:
3049 assert(0);
3051 break;
3052 case ZS_RESOURCE_RAM_RSS:
3053 switch (user) {
3054 case ZS_USER_ALL:
3055 v = zs_physical_memory_usage_all_pct(u);
3056 break;
3057 case ZS_USER_KERNEL:
3058 v = zs_physical_memory_usage_kernel_pct(u);
3059 break;
3060 case ZS_USER_ZONES:
3061 v = zs_physical_memory_usage_zones_pct(u);
3062 break;
3063 case ZS_USER_FREE:
3064 v = zs_physical_memory_usage_free_pct(u);
3065 break;
3066 default:
3067 assert(0);
3069 break;
3070 case ZS_RESOURCE_RAM_LOCKED:
3071 switch (user) {
3072 case ZS_USER_ALL:
3073 v = zs_locked_memory_usage_all_pct(u);
3074 break;
3075 case ZS_USER_KERNEL:
3076 v = zs_locked_memory_usage_kernel_pct(u);
3077 break;
3078 case ZS_USER_ZONES:
3079 v = zs_locked_memory_usage_zones_pct(u);
3080 break;
3081 case ZS_USER_FREE:
3082 v = zs_locked_memory_usage_free_pct(u);
3083 break;
3084 default:
3085 assert(0);
3087 break;
3088 case ZS_RESOURCE_VM:
3089 switch (user) {
3090 case ZS_USER_ALL:
3091 v = zs_virtual_memory_usage_all_pct(u);
3092 break;
3093 case ZS_USER_KERNEL:
3094 v = zs_virtual_memory_usage_kernel_pct(u);
3095 break;
3096 case ZS_USER_ZONES:
3097 v = zs_virtual_memory_usage_zones_pct(u);
3098 break;
3099 case ZS_USER_FREE:
3100 v = zs_virtual_memory_usage_free_pct(u);
3101 break;
3102 default:
3103 assert(0);
3105 break;
3106 case ZS_RESOURCE_DISK_SWAP:
3107 switch (user) {
3108 case ZS_USER_ALL:
3109 v = zs_disk_swap_usage_all_pct(u);
3110 break;
3111 case ZS_USER_FREE:
3112 v = zs_disk_swap_usage_free_pct(u);
3113 break;
3114 case ZS_USER_KERNEL:
3115 case ZS_USER_ZONES:
3116 /* FALLTHROUGH */
3117 default:
3118 assert(0);
3120 break;
3121 case ZS_RESOURCE_LWPS:
3122 switch (user) {
3123 case ZS_USER_ALL:
3124 case ZS_USER_ZONES:
3125 v = zs_lwps_usage_all_pct(u);
3126 break;
3127 case ZS_USER_FREE:
3128 v = ZSD_PCT_INT - zs_lwps_usage_all_pct(u);
3129 break;
3130 case ZS_USER_KERNEL:
3131 v = 0;
3132 break;
3133 default:
3134 assert(0);
3136 break;
3137 case ZS_RESOURCE_PROCESSES:
3138 switch (user) {
3139 case ZS_USER_ALL:
3140 case ZS_USER_ZONES:
3141 v = zs_processes_usage_all_pct(u);
3142 break;
3143 case ZS_USER_FREE:
3144 v = ZSD_PCT_INT - zs_processes_usage_all_pct(u);
3145 break;
3146 case ZS_USER_KERNEL:
3147 v = 0;
3148 break;
3149 default:
3150 assert(0);
3152 break;
3153 case ZS_RESOURCE_SHM_MEMORY:
3154 switch (user) {
3155 case ZS_USER_ALL:
3156 case ZS_USER_ZONES:
3157 v = zs_shm_usage_all_pct(u);
3158 break;
3159 case ZS_USER_FREE:
3160 v = ZSD_PCT_INT - zs_shm_usage_all_pct(u);
3161 break;
3162 case ZS_USER_KERNEL:
3163 v = 0;
3164 break;
3165 default:
3166 assert(0);
3168 break;
3169 case ZS_RESOURCE_SHM_IDS:
3170 switch (user) {
3171 case ZS_USER_ALL:
3172 case ZS_USER_ZONES:
3173 v = zs_shmids_usage_all_pct(u);
3174 break;
3175 case ZS_USER_FREE:
3176 v = ZSD_PCT_INT - zs_shmids_usage_all_pct(u);
3177 break;
3178 case ZS_USER_KERNEL:
3179 v = 0;
3180 break;
3181 default:
3182 assert(0);
3184 break;
3185 case ZS_RESOURCE_SEM_IDS:
3186 switch (user) {
3187 case ZS_USER_ALL:
3188 case ZS_USER_ZONES:
3189 v = zs_semids_usage_all_pct(u);
3190 break;
3191 case ZS_USER_FREE:
3192 v = ZSD_PCT_INT - zs_semids_usage_all_pct(u);
3193 break;
3194 case ZS_USER_KERNEL:
3195 v = 0;
3196 break;
3197 default:
3198 assert(0);
3200 break;
3201 case ZS_RESOURCE_MSG_IDS:
3202 switch (user) {
3203 case ZS_USER_ALL:
3204 case ZS_USER_ZONES:
3205 v = zs_msgids_usage_all_pct(u);
3206 break;
3207 case ZS_USER_FREE:
3208 v = ZSD_PCT_INT - zs_msgids_usage_all_pct(u);
3209 break;
3210 case ZS_USER_KERNEL:
3211 v = 0;
3212 break;
3213 default:
3214 assert(0);
3216 break;
3217 case ZS_RESOURCE_LOFI:
3218 switch (user) {
3219 case ZS_USER_ALL:
3220 case ZS_USER_ZONES:
3221 v = zs_lofi_usage_all_pct(u);
3222 break;
3223 case ZS_USER_FREE:
3224 v = ZSD_PCT_INT - zs_lofi_usage_all_pct(u);
3225 break;
3226 case ZS_USER_KERNEL:
3227 v = 0;
3228 break;
3229 default:
3230 assert(0);
3232 break;
3233 default:
3234 assert(0);
3237 return (v);
3241 * Get resource used by individual zone.
3243 uint64_t
3244 zs_resource_used_zone_uint64(zs_zone_t *z, int res)
3246 uint64_t v;
3248 switch (res) {
3249 case ZS_RESOURCE_CPU:
3250 v = zs_cpu_usage_zone_cpu(z);
3251 break;
3252 case ZS_RESOURCE_RAM_RSS:
3253 v = zs_physical_memory_usage_zone(z);
3254 break;
3255 case ZS_RESOURCE_RAM_LOCKED:
3256 v = zs_locked_memory_usage_zone(z);
3257 break;
3258 case ZS_RESOURCE_VM:
3259 v = zs_virtual_memory_usage_zone(z);
3260 break;
3261 case ZS_RESOURCE_DISK_SWAP:
3262 assert(0);
3263 break;
3264 case ZS_RESOURCE_LWPS:
3265 v = zs_lwps_usage_zone(z);
3266 break;
3267 case ZS_RESOURCE_PROCESSES:
3268 v = zs_processes_usage_zone(z);
3269 break;
3270 case ZS_RESOURCE_SHM_MEMORY:
3271 v = zs_shm_usage_zone(z);
3272 break;
3273 case ZS_RESOURCE_SHM_IDS:
3274 v = zs_shmids_usage_zone(z);
3275 break;
3276 case ZS_RESOURCE_SEM_IDS:
3277 v = zs_semids_usage_zone(z);
3278 break;
3279 case ZS_RESOURCE_MSG_IDS:
3280 v = zs_msgids_usage_zone(z);
3281 break;
3282 case ZS_RESOURCE_LOFI:
3283 v = zs_lofi_usage_zone(z);
3284 break;
3285 default:
3286 assert(0);
3288 return (v);
3292 * Get resource used by individual zone as percent
3294 uint_t
3295 zs_resource_used_zone_pct(zs_zone_t *z, int res)
3297 uint_t v;
3299 switch (res) {
3300 case ZS_RESOURCE_CPU:
3301 v = zs_cpu_usage_zone_pct(z);
3302 break;
3303 case ZS_RESOURCE_RAM_RSS:
3304 v = zs_physical_memory_usage_zone_pct(z);
3305 break;
3306 case ZS_RESOURCE_RAM_LOCKED:
3307 v = zs_locked_memory_usage_zone_pct(z);
3308 break;
3309 case ZS_RESOURCE_VM:
3310 v = zs_virtual_memory_usage_zone_pct(z);
3311 break;
3312 case ZS_RESOURCE_DISK_SWAP:
3313 assert(0);
3314 break;
3315 case ZS_RESOURCE_LWPS:
3316 v = zs_lwps_usage_zone_pct(z);
3317 break;
3318 case ZS_RESOURCE_PROCESSES:
3319 v = zs_processes_usage_zone_pct(z);
3320 break;
3321 case ZS_RESOURCE_SHM_MEMORY:
3322 v = zs_shm_usage_zone_pct(z);
3323 break;
3324 case ZS_RESOURCE_SHM_IDS:
3325 v = zs_shmids_usage_zone_pct(z);
3326 break;
3327 case ZS_RESOURCE_SEM_IDS:
3328 v = zs_semids_usage_zone_pct(z);
3329 break;
3330 case ZS_RESOURCE_MSG_IDS:
3331 v = zs_msgids_usage_zone_pct(z);
3332 break;
3333 case ZS_RESOURCE_LOFI:
3334 v = zs_lofi_usage_zone_pct(z);
3335 break;
3336 default:
3337 assert(0);
3339 return (v);
3343 * Get total time available for a resource
3345 void
3346 zs_resource_total_time(zs_usage_t *u, int res, timestruc_t *t)
3348 switch (res) {
3349 case ZS_RESOURCE_CPU:
3350 zs_cpu_total_time(u, t);
3351 break;
3352 case ZS_RESOURCE_RAM_RSS:
3353 case ZS_RESOURCE_RAM_LOCKED:
3354 case ZS_RESOURCE_VM:
3355 case ZS_RESOURCE_DISK_SWAP:
3356 case ZS_RESOURCE_LWPS:
3357 case ZS_RESOURCE_PROCESSES:
3358 case ZS_RESOURCE_SHM_MEMORY:
3359 case ZS_RESOURCE_SHM_IDS:
3360 case ZS_RESOURCE_SEM_IDS:
3361 case ZS_RESOURCE_MSG_IDS:
3362 /* FALLTHROUGH */
3363 default:
3364 assert(0);
3369 * Get total time used for a resource
3371 void
3372 zs_resource_used_time(zs_usage_t *u, int res, int user, timestruc_t *t)
3374 switch (res) {
3375 case ZS_RESOURCE_CPU:
3376 switch (user) {
3377 case ZS_USER_ALL:
3378 zs_cpu_usage_all(u, t);
3379 break;
3380 case ZS_USER_KERNEL:
3381 zs_cpu_usage_kernel(u, t);
3382 break;
3383 case ZS_USER_ZONES:
3384 zs_cpu_usage_zones(u, t);
3385 break;
3386 case ZS_USER_FREE:
3387 zs_cpu_usage_idle(u, t);
3388 break;
3389 default:
3390 assert(0);
3392 break;
3393 case ZS_RESOURCE_RAM_RSS:
3394 case ZS_RESOURCE_RAM_LOCKED:
3395 case ZS_RESOURCE_VM:
3396 case ZS_RESOURCE_DISK_SWAP:
3397 case ZS_RESOURCE_LWPS:
3398 case ZS_RESOURCE_PROCESSES:
3399 case ZS_RESOURCE_SHM_MEMORY:
3400 case ZS_RESOURCE_SHM_IDS:
3401 case ZS_RESOURCE_SEM_IDS:
3402 case ZS_RESOURCE_MSG_IDS:
3403 /* FALLTHROUGH */
3404 default:
3405 assert(0);
3410 * Get total resource time used for a particular zone
3412 void
3413 zs_resource_used_zone_time(zs_zone_t *z, int res, timestruc_t *t)
3415 switch (res) {
3416 case ZS_RESOURCE_CPU:
3417 zs_cpu_usage_zone(z, t);
3418 break;
3419 case ZS_RESOURCE_RAM_RSS:
3420 case ZS_RESOURCE_RAM_LOCKED:
3421 case ZS_RESOURCE_VM:
3422 case ZS_RESOURCE_DISK_SWAP:
3423 case ZS_RESOURCE_SHM_MEMORY:
3424 case ZS_RESOURCE_LWPS:
3425 case ZS_RESOURCE_PROCESSES:
3426 case ZS_RESOURCE_SHM_IDS:
3427 case ZS_RESOURCE_SEM_IDS:
3428 case ZS_RESOURCE_MSG_IDS:
3429 /* FALLTHROUGH */
3430 default:
3431 assert(0);
3437 zs_zone_list(zs_usage_t *usage, zs_zone_t **zonelist, int num)
3439 int i = 0;
3440 zs_zone_t *zone, *tmp;
3442 /* copy what fits of the zone list into the buffer */
3443 for (zone = list_head(&usage->zsu_zone_list); zone != NULL;
3444 zone = list_next(&usage->zsu_zone_list, zone)) {
3446 /* put the global zone at the first position */
3447 if (i < num) {
3448 if (zone->zsz_id == GLOBAL_ZONEID) {
3449 tmp = zonelist[0];
3450 zonelist[i] = tmp;
3451 zonelist[0] = zone;
3452 } else {
3453 zonelist[i] = zone;
3456 i++;
3458 return (i);
3461 zs_zone_t *
3462 zs_zone_first(zs_usage_t *usage)
3464 return (list_head(&usage->zsu_zone_list));
3467 zs_zone_t *
3468 zs_zone_next(zs_usage_t *usage, zs_zone_t *zone)
3470 return (list_next(&usage->zsu_zone_list, zone));
3475 * Gets a zone property
3477 void
3478 zs_zone_property(zs_zone_t *zone, int prop, zs_property_t *p)
3480 switch (prop) {
3481 case ZS_ZONE_PROP_NAME:
3482 p->zsp_type = ZS_PROP_TYPE_STRING;
3483 p->zsp_id = prop;
3484 (void) zs_zone_name(zone, p->zsp_v.zsv_string,
3485 sizeof (p->zsp_v.zsv_string));
3486 break;
3487 case ZS_ZONE_PROP_ID:
3488 p->zsp_type = ZS_PROP_TYPE_INT;
3489 p->zsp_id = prop;
3490 p->zsp_v.zsv_int = zs_zone_id(zone);
3491 break;
3492 case ZS_ZONE_PROP_IPTYPE:
3493 p->zsp_type = ZS_PROP_TYPE_UINT;
3494 p->zsp_id = prop;
3495 p->zsp_v.zsv_uint = zs_zone_iptype(zone);
3496 break;
3497 case ZS_ZONE_PROP_CPUTYPE:
3498 p->zsp_type = ZS_PROP_TYPE_UINT;
3499 p->zsp_id = prop;
3500 p->zsp_v.zsv_uint = zs_zone_cputype(zone);
3501 break;
3502 case ZS_ZONE_PROP_SCHEDULERS:
3503 p->zsp_type = ZS_PROP_TYPE_UINT;
3504 p->zsp_id = prop;
3505 p->zsp_v.zsv_uint = zs_zone_schedulers(zone);
3506 break;
3507 case ZS_ZONE_PROP_CPU_SHARES:
3508 p->zsp_type = ZS_PROP_TYPE_UINT64;
3509 p->zsp_id = prop;
3510 p->zsp_v.zsv_uint64 = zs_zone_cpu_shares(zone);
3511 break;
3512 case ZS_ZONE_PROP_POOLNAME:
3513 p->zsp_type = ZS_PROP_TYPE_STRING;
3514 p->zsp_id = prop;
3515 (void) zs_zone_poolname(zone, p->zsp_v.zsv_string,
3516 sizeof (p->zsp_v.zsv_string));
3517 break;
3518 case ZS_ZONE_PROP_PSETNAME:
3519 p->zsp_type = ZS_PROP_TYPE_STRING;
3520 p->zsp_id = prop;
3521 (void) zs_zone_psetname(zone, p->zsp_v.zsv_string,
3522 sizeof (p->zsp_v.zsv_string));
3523 break;
3524 /* Not implemented */
3525 case ZS_ZONE_PROP_DEFAULT_SCHED:
3526 case ZS_ZONE_PROP_UPTIME:
3527 case ZS_ZONE_PROP_BOOTTIME:
3528 /* FALLTHROUGH */
3529 default:
3530 assert(0);
3535 zs_zone_limit_type(int limit)
3537 switch (limit) {
3538 case ZS_LIMIT_CPU:
3539 case ZS_LIMIT_CPU_SHARES:
3540 return (ZS_LIMIT_TYPE_TIME);
3541 case ZS_LIMIT_RAM_RSS:
3542 case ZS_LIMIT_RAM_LOCKED:
3543 case ZS_LIMIT_VM:
3544 case ZS_LIMIT_SHM_MEMORY:
3545 return (ZS_LIMIT_TYPE_BYTES);
3546 case ZS_LIMIT_LWPS:
3547 case ZS_LIMIT_PROCESSES:
3548 case ZS_LIMIT_SHM_IDS:
3549 case ZS_LIMIT_MSG_IDS:
3550 case ZS_LIMIT_SEM_IDS:
3551 return (ZS_LIMIT_TYPE_COUNT);
3552 default:
3553 assert(0);
3554 return (0);
3558 * Gets the zones limit. Returns ZS_LIMIT_NONE if no limit set.
3560 uint64_t
3561 zs_zone_limit_uint64(zs_zone_t *z, int limit)
3563 uint64_t v;
3565 switch (limit) {
3566 case ZS_LIMIT_CPU:
3567 v = zs_zone_cpu_cap(z);
3568 break;
3569 case ZS_LIMIT_CPU_SHARES:
3570 v = zs_zone_cpu_shares(z);
3571 break;
3572 case ZS_LIMIT_RAM_RSS:
3573 v = zs_zone_physical_memory_cap(z);
3574 break;
3575 case ZS_LIMIT_RAM_LOCKED:
3576 v = zs_zone_locked_memory_cap(z);
3577 break;
3578 case ZS_LIMIT_VM:
3579 v = zs_zone_virtual_memory_cap(z);
3580 break;
3581 case ZS_LIMIT_LWPS:
3582 v = z->zsz_lwps_cap;
3583 break;
3584 case ZS_LIMIT_PROCESSES:
3585 v = z->zsz_processes_cap;
3586 break;
3587 case ZS_LIMIT_SHM_MEMORY:
3588 v = z->zsz_shm_cap;
3589 break;
3590 case ZS_LIMIT_SHM_IDS:
3591 v = z->zsz_shmids_cap;
3592 break;
3593 case ZS_LIMIT_SEM_IDS:
3594 v = z->zsz_semids_cap;
3595 break;
3596 case ZS_LIMIT_MSG_IDS:
3597 v = z->zsz_msgids_cap;
3598 break;
3599 case ZS_LIMIT_LOFI:
3600 v = z->zsz_lofi_cap;
3601 break;
3602 default:
3603 assert(0);
3605 return (v);
3609 * Gets the amount of resource used for a limit. Returns ZS_LIMIT_NONE if
3610 * no limit configured.
3612 uint64_t
3613 zs_zone_limit_used_uint64(zs_zone_t *z, int limit)
3615 uint64_t v;
3617 switch (limit) {
3618 case ZS_LIMIT_CPU:
3619 v = zs_zone_cpu_cap_used(z);
3620 break;
3621 case ZS_LIMIT_CPU_SHARES:
3622 v = zs_zone_cpu_shares_used(z);
3623 break;
3624 case ZS_LIMIT_RAM_RSS:
3625 v = zs_zone_physical_memory_cap_used(z);
3626 break;
3627 case ZS_LIMIT_RAM_LOCKED:
3628 v = zs_zone_locked_memory_cap_used(z);
3629 break;
3630 case ZS_LIMIT_VM:
3631 v = zs_zone_virtual_memory_cap_used(z);
3632 break;
3633 case ZS_LIMIT_LWPS:
3634 v = z->zsz_lwps;
3635 break;
3636 case ZS_LIMIT_PROCESSES:
3637 v = z->zsz_processes;
3638 break;
3639 case ZS_LIMIT_SHM_MEMORY:
3640 v = z->zsz_shm;
3641 break;
3642 case ZS_LIMIT_SHM_IDS:
3643 v = z->zsz_shmids;
3644 break;
3645 case ZS_LIMIT_SEM_IDS:
3646 v = z->zsz_semids;
3647 break;
3648 case ZS_LIMIT_MSG_IDS:
3649 v = z->zsz_msgids;
3650 break;
3651 case ZS_LIMIT_LOFI:
3652 v = z->zsz_lofi;
3653 break;
3654 default:
3655 assert(0);
3657 return (v);
3661 * Gets time used under limit. Time is zero if no limit is configured
3663 void
3664 zs_zone_limit_time(zs_zone_t *z, int limit, timestruc_t *v)
3666 switch (limit) {
3667 case ZS_LIMIT_CPU:
3668 if (z->zsz_cpu_cap == ZS_LIMIT_NONE) {
3669 v->tv_sec = 0;
3670 v->tv_nsec = 0;
3671 break;
3673 zs_zone_cpu_cap_time(z, v);
3674 break;
3675 case ZS_LIMIT_CPU_SHARES:
3676 if (z->zsz_cpu_shares == ZS_LIMIT_NONE ||
3677 z->zsz_cpu_shares == ZS_SHARES_UNLIMITED ||
3678 z->zsz_cpu_shares == 0 ||
3679 (z->zsz_scheds & ZS_SCHED_FSS) == 0) {
3680 v->tv_sec = 0;
3681 v->tv_nsec = 0;
3682 break;
3684 zs_zone_cpu_share_time(z, v);
3685 break;
3686 case ZS_LIMIT_RAM_RSS:
3687 case ZS_LIMIT_RAM_LOCKED:
3688 case ZS_LIMIT_VM:
3689 case ZS_LIMIT_SHM_MEMORY:
3690 case ZS_LIMIT_LWPS:
3691 case ZS_LIMIT_PROCESSES:
3692 case ZS_LIMIT_SHM_IDS:
3693 case ZS_LIMIT_MSG_IDS:
3694 case ZS_LIMIT_SEM_IDS:
3695 /* FALLTHROUGH */
3696 default:
3697 assert(0);
3702 * Errno is set on error:
3704 * EINVAL: No such property
3705 * ENOENT: No time value for the specified limit.
3706 * ESRCH: No limit is configured.
3708 * If no limit is configured, the value will be ZS_PCT_NONE
3710 void
3711 zs_zone_limit_used_time(zs_zone_t *z, int limit, timestruc_t *t)
3713 switch (limit) {
3714 case ZS_LIMIT_CPU:
3715 if (z->zsz_cpu_cap == ZS_LIMIT_NONE) {
3716 t->tv_sec = 0;
3717 t->tv_nsec = 0;
3718 break;
3720 zs_zone_cpu_cap_time_used(z, t);
3721 break;
3722 case ZS_LIMIT_CPU_SHARES:
3723 if (z->zsz_cpu_shares == ZS_LIMIT_NONE ||
3724 z->zsz_cpu_shares == ZS_SHARES_UNLIMITED ||
3725 z->zsz_cpu_shares == 0 ||
3726 (z->zsz_scheds & ZS_SCHED_FSS) == 0) {
3727 t->tv_sec = 0;
3728 t->tv_nsec = 0;
3729 break;
3731 zs_zone_cpu_share_time_used(z, t);
3732 break;
3733 case ZS_LIMIT_RAM_RSS:
3734 case ZS_LIMIT_RAM_LOCKED:
3735 case ZS_LIMIT_VM:
3736 case ZS_LIMIT_SHM_MEMORY:
3737 case ZS_LIMIT_LWPS:
3738 case ZS_LIMIT_PROCESSES:
3739 case ZS_LIMIT_SHM_IDS:
3740 case ZS_LIMIT_MSG_IDS:
3741 case ZS_LIMIT_SEM_IDS:
3742 /* FALLTHROUGH */
3743 default:
3744 assert(0);
3749 * Get a zones usage as a percent of the limit. Return ZS_PCT_NONE if
3750 * no limit is configured.
3752 uint_t
3753 zs_zone_limit_used_pct(zs_zone_t *z, int limit)
3755 uint_t v;
3757 switch (limit) {
3758 case ZS_LIMIT_CPU:
3759 v = zs_zone_cpu_cap_pct(z);
3760 break;
3761 case ZS_LIMIT_CPU_SHARES:
3762 v = zs_zone_cpu_shares_pct(z);
3763 break;
3764 case ZS_LIMIT_RAM_RSS:
3765 v = zs_zone_physical_memory_cap_pct(z);
3766 break;
3767 case ZS_LIMIT_RAM_LOCKED:
3768 v = zs_zone_locked_memory_cap_pct(z);
3769 break;
3770 case ZS_LIMIT_VM:
3771 v = zs_zone_virtual_memory_cap_pct(z);
3772 break;
3773 case ZS_LIMIT_LWPS:
3774 v = zs_lwps_zone_cap_pct(z);
3775 break;
3776 case ZS_LIMIT_PROCESSES:
3777 v = zs_processes_zone_cap_pct(z);
3778 break;
3779 case ZS_LIMIT_SHM_MEMORY:
3780 v = zs_shm_zone_cap_pct(z);
3781 break;
3782 case ZS_LIMIT_SHM_IDS:
3783 v = zs_shmids_zone_cap_pct(z);
3784 break;
3785 case ZS_LIMIT_SEM_IDS:
3786 v = zs_semids_zone_cap_pct(z);
3787 break;
3788 case ZS_LIMIT_MSG_IDS:
3789 v = zs_msgids_zone_cap_pct(z);
3790 break;
3791 case ZS_LIMIT_LOFI:
3792 v = zs_lofi_zone_cap_pct(z);
3793 break;
3794 default:
3795 assert(0);
3797 return (v);
3801 zs_pset_list(zs_usage_t *usage, zs_pset_t **psetlist, int num)
3803 int i = 0;
3804 zs_pset_t *pset, *tmp;
3806 /* copy what fits of the pset list into the buffer */
3807 for (pset = list_head(&usage->zsu_pset_list); pset != NULL;
3808 pset = list_next(&usage->zsu_pset_list, pset)) {
3810 /* put the default pset at the first position */
3811 if (i < num) {
3812 if (pset->zsp_id == ZS_PSET_DEFAULT) {
3813 tmp = psetlist[0];
3814 psetlist[i] = tmp;
3815 psetlist[0] = pset;
3816 } else {
3817 psetlist[i] = pset;
3820 i++;
3822 return (i);
3825 zs_pset_t *
3826 zs_pset_first(zs_usage_t *usage)
3828 return (list_head(&usage->zsu_pset_list));
3831 zs_pset_t *
3832 zs_pset_next(zs_usage_t *usage, zs_pset_t *pset)
3834 return (list_next(&usage->zsu_pset_list, pset));
3838 * Get various properties on a pset.
3840 void
3841 zs_pset_property(zs_pset_t *pset, int prop, zs_property_t *p)
3843 switch (prop) {
3845 case ZS_PSET_PROP_NAME:
3846 p->zsp_type = ZS_PROP_TYPE_STRING;
3847 p->zsp_id = prop;
3848 (void) zs_pset_name(pset, p->zsp_v.zsv_string,
3849 sizeof (p->zsp_v.zsv_string));
3850 break;
3851 case ZS_PSET_PROP_ID:
3852 p->zsp_type = ZS_PROP_TYPE_INT;
3853 p->zsp_id = prop;
3854 p->zsp_v.zsv_int = zs_pset_id(pset);
3855 break;
3856 case ZS_PSET_PROP_CPUTYPE:
3857 p->zsp_type = ZS_PROP_TYPE_UINT;
3858 p->zsp_id = prop;
3859 p->zsp_v.zsv_uint = zs_pset_cputype(pset);
3860 break;
3861 case ZS_PSET_PROP_SIZE:
3862 p->zsp_type = ZS_PROP_TYPE_UINT64;
3863 p->zsp_id = prop;
3864 p->zsp_v.zsv_uint64 = zs_pset_size(pset);
3865 break;
3866 case ZS_PSET_PROP_ONLINE:
3867 p->zsp_type = ZS_PROP_TYPE_UINT64;
3868 p->zsp_id = prop;
3869 p->zsp_v.zsv_uint64 = zs_pset_online(pset);
3870 break;
3871 case ZS_PSET_PROP_MIN:
3872 p->zsp_type = ZS_PROP_TYPE_UINT64;
3873 p->zsp_id = prop;
3874 p->zsp_v.zsv_uint64 = zs_pset_min(pset);
3875 break;
3876 case ZS_PSET_PROP_MAX:
3877 p->zsp_type = ZS_PROP_TYPE_UINT64;
3878 p->zsp_id = prop;
3879 p->zsp_v.zsv_uint64 = zs_pset_max(pset);
3880 break;
3881 case ZS_PSET_PROP_CPU_SHARES:
3882 p->zsp_type = ZS_PROP_TYPE_UINT64;
3883 p->zsp_id = prop;
3884 p->zsp_v.zsv_uint64 = zs_pset_cpu_shares(pset);
3885 break;
3886 case ZS_PSET_PROP_SCHEDULERS:
3887 p->zsp_type = ZS_PROP_TYPE_UINT;
3888 p->zsp_id = prop;
3889 p->zsp_v.zsv_uint = zs_pset_schedulers(pset);
3890 break;
3891 /* Not implemented */
3892 case ZS_PSET_PROP_CREATETIME:
3893 case ZS_PSET_PROP_LOAD_1MIN:
3894 case ZS_PSET_PROP_LOAD_5MIN:
3895 case ZS_PSET_PROP_LOAD_15MIN:
3896 /* FALLTHROUGH */
3897 default:
3898 assert(0);
3902 void
3903 zs_pset_total_time(zs_pset_t *pset, timestruc_t *t)
3905 *t = pset->zsp_total_time;
3908 uint64_t
3909 zs_pset_total_cpus(zs_pset_t *pset)
3911 return (pset->zsp_online * ZSD_ONE_CPU);
3915 * Get total time used for pset
3917 void
3918 zs_pset_used_time(zs_pset_t *pset, int user, timestruc_t *t)
3920 switch (user) {
3921 case ZS_USER_ALL:
3922 zs_pset_usage_all(pset, t);
3923 break;
3924 case ZS_USER_KERNEL:
3925 zs_pset_usage_kernel(pset, t);
3926 break;
3927 case ZS_USER_ZONES:
3928 zs_pset_usage_zones(pset, t);
3929 break;
3930 case ZS_USER_FREE:
3931 zs_pset_usage_idle(pset, t);
3932 break;
3933 default:
3934 assert(0);
3939 * Returns 0 on success. -1 on failure.
3941 * ERRORS
3942 * EINVAL: Invalid user.
3945 uint64_t
3946 zs_pset_used_cpus(zs_pset_t *pset, int user)
3948 uint_t v;
3950 switch (user) {
3951 case ZS_USER_ALL:
3952 v = zs_pset_usage_all_cpus(pset);
3953 break;
3954 case ZS_USER_KERNEL:
3955 v = zs_pset_usage_kernel_cpus(pset);
3956 break;
3957 case ZS_USER_ZONES:
3958 v = zs_pset_usage_zones_cpus(pset);
3959 break;
3960 case ZS_USER_FREE:
3961 v = zs_pset_usage_idle_cpus(pset);
3962 break;
3963 default:
3964 assert(0);
3966 return (v);
3969 * Get percent of pset cpu time used
3971 uint_t
3972 zs_pset_used_pct(zs_pset_t *pset, int user)
3974 uint_t v;
3976 switch (user) {
3977 case ZS_USER_ALL:
3978 v = zs_pset_usage_all_pct(pset);
3979 break;
3980 case ZS_USER_KERNEL:
3981 v = zs_pset_usage_kernel_pct(pset);
3982 break;
3983 case ZS_USER_ZONES:
3984 v = zs_pset_usage_zones_pct(pset);
3985 break;
3986 case ZS_USER_FREE:
3987 v = zs_pset_usage_idle_pct(pset);
3988 break;
3989 default:
3990 assert(0);
3992 return (v);
3996 zs_pset_zone_list(zs_pset_t *pset, zs_pset_zone_t **zonelist, int num)
3998 int i = 0;
3999 zs_pset_zone_t *zone, *tmp;
4001 /* copy what fits of the pset's zone list into the buffer */
4002 for (zone = list_head(&pset->zsp_usage_list); zone != NULL;
4003 zone = list_next(&pset->zsp_usage_list, zone)) {
4005 /* put the global zone at the first position */
4006 if (i < num) {
4007 if (zone->zspz_zone->zsz_id == GLOBAL_ZONEID) {
4008 tmp = zonelist[0];
4009 zonelist[i] = tmp;
4010 zonelist[0] = zone;
4011 } else {
4012 zonelist[i] = zone;
4015 i++;
4017 return (i);
4020 zs_pset_zone_t *
4021 zs_pset_zone_first(zs_pset_t *pset)
4023 return (list_head(&pset->zsp_usage_list));
4026 zs_pset_zone_t *
4027 zs_pset_zone_next(zs_pset_t *pset, zs_pset_zone_t *pz)
4029 return (list_next(&pset->zsp_usage_list, pz));
4032 zs_pset_t *
4033 zs_pset_zone_get_pset(zs_pset_zone_t *pz)
4035 return (pz->zspz_pset);
4038 zs_zone_t *
4039 zs_pset_zone_get_zone(zs_pset_zone_t *pz)
4041 return (pz->zspz_zone);
4045 * Get a property describing a zone's usage of a pset
4047 void
4048 zs_pset_zone_property(zs_pset_zone_t *pz, int prop, zs_property_t *p)
4050 switch (prop) {
4052 case ZS_PZ_PROP_CPU_CAP:
4053 p->zsp_type = ZS_PROP_TYPE_UINT64;
4054 p->zsp_id = prop;
4055 p->zsp_v.zsv_uint64 = (int)zs_pset_zone_cpu_cap(pz);
4056 break;
4057 case ZS_PZ_PROP_CPU_SHARES:
4058 p->zsp_type = ZS_PROP_TYPE_UINT64;
4059 p->zsp_id = prop;
4060 p->zsp_v.zsv_uint64 = (int)zs_pset_zone_cpu_shares(pz);
4061 break;
4062 case ZS_PZ_PROP_SCHEDULERS:
4063 p->zsp_type = ZS_PROP_TYPE_UINT;
4064 p->zsp_id = prop;
4065 p->zsp_v.zsv_uint = (int)zs_pset_zone_schedulers(pz);
4066 break;
4067 default:
4068 assert(0);
4072 void
4073 zs_pset_zone_used_time(zs_pset_zone_t *pz, timestruc_t *t)
4075 zs_pset_zone_usage_time(pz, t);
4078 uint64_t
4079 zs_pset_zone_used_cpus(zs_pset_zone_t *pz)
4081 return (zs_pset_zone_usage_cpus(pz));
4085 * Get percent of a psets cpus used by a zone
4087 uint_t
4088 zs_pset_zone_used_pct(zs_pset_zone_t *pz, int type)
4090 uint_t v;
4092 switch (type) {
4093 case ZS_PZ_PCT_PSET:
4094 v = zs_pset_zone_usage_pct_pset(pz);
4095 break;
4096 case ZS_PZ_PCT_CPU_CAP:
4097 v = zs_pset_zone_usage_pct_cpu_cap(pz);
4098 break;
4099 case ZS_PZ_PCT_PSET_SHARES:
4100 v = zs_pset_zone_usage_pct_pset_shares(pz);
4101 break;
4102 case ZS_PZ_PCT_CPU_SHARES:
4103 v = zs_pset_zone_usage_pct_cpu_shares(pz);
4104 break;
4105 default:
4106 assert(0);
4108 return (v);
4112 * returns similar to malloc
4114 zs_property_t *
4115 zs_property_alloc()
4117 return ((zs_property_t *)malloc(sizeof (zs_property_t)));
4120 size_t
4121 zs_property_size()
4123 return (sizeof (zs_property_t));
4126 void
4127 zs_property_free(zs_property_t *p)
4129 free(p);
4133 zs_property_type(zs_property_t *p)
4135 return (p->zsp_type);
4139 zs_property_id(zs_property_t *p)
4141 return (p->zsp_id);
4144 char *
4145 zs_property_string(zs_property_t *p)
4147 assert(p->zsp_type == ZS_PROP_TYPE_STRING);
4148 return (p->zsp_v.zsv_string);
4151 double
4152 zs_property_double(zs_property_t *p)
4154 assert(p->zsp_type == ZS_PROP_TYPE_DOUBLE);
4155 return (p->zsp_v.zsv_double);
4158 void
4159 zs_property_time(zs_property_t *p, timestruc_t *t)
4161 assert(p->zsp_type == ZS_PROP_TYPE_TIME);
4162 *t = p->zsp_v.zsv_ts;
4165 uint64_t
4166 zs_property_uint64(zs_property_t *p)
4168 assert(p->zsp_type == ZS_PROP_TYPE_UINT64);
4169 return (p->zsp_v.zsv_uint64);
4172 int64_t
4173 zs_property_int64(zs_property_t *p)
4175 assert(p->zsp_type == ZS_PROP_TYPE_INT64);
4176 return (p->zsp_v.zsv_int64);
4179 uint_t
4180 zs_property_uint(zs_property_t *p)
4182 assert(p->zsp_type == ZS_PROP_TYPE_UINT);
4183 return (p->zsp_v.zsv_uint);
4187 zs_property_int(zs_property_t *p)
4189 assert(p->zsp_type == ZS_PROP_TYPE_INT);
4190 return (p->zsp_v.zsv_uint);