1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 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> 42 43 #define ZSD_PCT_INT 10000 44 #define ZSD_PCT_DOUBLE 10000.0 45 46 #define ZSD_ONE_CPU 100 47 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 54 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)) 57 58 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 } \ 67 } 68 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 } \ 77 } 78 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); } 82 83 /* 84 * Functions for reading and manipulating resource usage. 85 */ 86 static int 87 zs_connect_zonestatd() 88 { 89 int fd; 90 91 fd = open(ZS_DOOR_PATH, O_RDONLY); 92 return (fd); 93 } 94 95 static zs_zone_t * 96 zs_lookup_zone_byid(zs_usage_t *u, zoneid_t zid) 97 { 98 zs_zone_t *zone; 99 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); 104 } 105 return (NULL); 106 } 107 108 static zs_zone_t * 109 zs_lookup_zone_byname(zs_usage_t *u, char *name) 110 { 111 zs_zone_t *zone; 112 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); 117 } 118 return (NULL); 119 } 120 121 static zs_usage_t * 122 zs_usage_alloc() 123 { 124 zs_usage_t *u; 125 zs_system_t *s; 126 127 u = (zs_usage_t *)calloc(sizeof (zs_usage_t), 1); 128 if (u == NULL) 129 return (NULL); 130 131 s = (zs_system_t *)calloc(sizeof (zs_system_t), 1); 132 if (s == NULL) { 133 free(u); 134 return (NULL); 135 } 136 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)); 143 144 return (u); 145 } 146 147 static void 148 zs_zone_add_usage(zs_zone_t *old, zs_zone_t *new, int func) 149 { 150 151 if (func == ZS_COMPUTE_USAGE_HIGH) { 152 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); 166 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); 171 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); 179 180 ZS_MAXOF(old->zsz_cpus_online, new->zsz_cpus_online); 181 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; 187 } 188 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); 200 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; 205 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; 213 214 old->zsz_cpus_online += new->zsz_cpus_online; 215 old->zsz_cpu_shares += new->zsz_cpu_shares; 216 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); 221 } 222 223 static int 224 zs_usage_compute_zones(zs_usage_t *ures, zs_usage_t *uold, zs_usage_t *unew, 225 int func) 226 { 227 zs_system_t *sres; 228 zs_zone_t *zold, *znew, *zres; 229 230 sres = ures->zsu_system; 231 /* 232 * Walk zones, assume lists are always sorted the same. Include 233 * all zones that exist in the new usage. 234 */ 235 zold = list_head(&uold->zsu_zone_list); 236 znew = list_head(&unew->zsu_zone_list); 237 238 while (zold != NULL && znew != NULL) { 239 240 int cmp; 241 242 cmp = strcmp(zold->zsz_name, znew->zsz_name); 243 if (cmp > 0) { 244 /* 245 * Old interval does not contain zone in new 246 * interval. Zone is new. Add zone to result. 247 */ 248 if (ures != unew) { 249 zres = (zs_zone_t *)calloc(sizeof (zs_zone_t), 250 1); 251 if (zres == NULL) 252 return (-1); 253 *zres = *znew; 254 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); 264 265 } else { 266 zres = znew; 267 } 268 269 if (func == ZS_COMPUTE_USAGE_AVERAGE) 270 zres->zsz_intervals++; 271 272 znew = list_next(&unew->zsu_zone_list, znew); 273 continue; 274 275 } else if (cmp < 0) { 276 /* 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 280 */ 281 zold = list_next(&uold->zsu_zone_list, zold); 282 continue; 283 } 284 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); 298 } 299 if (func == ZS_COMPUTE_USAGE_AVERAGE) 300 zres->zsz_intervals++; 301 if (func == ZS_COMPUTE_USAGE_INTERVAL) { 302 /* 303 * If zone is in the old interval, but has been 304 * rebooted, don't subtract its old interval usage 305 */ 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; 310 } 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); 321 } 322 znew = list_next(&unew->zsu_zone_list, znew); 323 zold = list_next(&uold->zsu_zone_list, zold); 324 } 325 326 if (ures == unew) 327 return (0); 328 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); 342 343 znew = list_next(&unew->zsu_zone_list, znew); 344 } 345 return (0); 346 } 347 348 static void 349 zs_pset_zone_add_usage(zs_pset_zone_t *old, zs_pset_zone_t *new, int func) 350 { 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; 355 } 356 old->zspz_cpu_shares += new->zspz_cpu_shares; 357 TIMESTRUC_ADD_TIMESTRUC(old->zspz_cpu_usage, new->zspz_cpu_usage); 358 } 359 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) 363 { 364 zs_pset_zone_t *puold, *punew, *pures; 365 366 /* 367 * Walk psets usages, assume lists are always sorted the same. Include 368 * all pset usages that exist in the new pset. 369 */ 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); 375 376 while (puold != NULL && punew != NULL) { 377 378 int cmp; 379 380 cmp = strcmp(puold->zspz_zone->zsz_name, 381 punew->zspz_zone->zsz_name); 382 if (cmp > 0) { 383 /* 384 * Old interval does not contain usage new 385 * interval. Usage is new. 386 */ 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; 393 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; 408 } 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; 418 } 419 420 punew = list_next(&pnew->zsp_usage_list, punew); 421 continue; 422 } else if (cmp < 0) { 423 424 /* 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. 429 * 430 * For total utilization, add pset time to zone that 431 * has run in this pset before. 432 */ 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; 440 } 441 puold = list_next(&pold->zsp_usage_list, puold); 442 continue; 443 } 444 /* 445 * Zone is using pset in both start and end interval. Compute 446 * interval 447 */ 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); 463 } 464 if (func == ZS_COMPUTE_USAGE_AVERAGE) 465 pures->zspz_intervals++; 466 467 if (func == ZS_COMPUTE_USAGE_INTERVAL) { 468 /* 469 * If pset usage has been destroyed and re-created 470 * since start interval, don't subtract the start 471 * interval. 472 */ 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; 477 } 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); 482 } 483 punew = list_next(&pnew->zsp_usage_list, punew); 484 puold = list_next(&pold->zsp_usage_list, puold); 485 } 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); 494 } 495 } 496 497 /* No need to add new pset zone usages if result pset is new pset */ 498 if (pres == pnew) 499 return (0); 500 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); 517 518 punew = list_next(&pnew->zsp_usage_list, punew); 519 } 520 return (0); 521 } 522 523 static void 524 zs_pset_add_usage(zs_pset_t *old, zs_pset_t *new, int func) 525 { 526 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; 538 } 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); 548 } 549 550 static int 551 zs_usage_compute_psets(zs_usage_t *ures, zs_usage_t *uold, zs_usage_t *unew, 552 int func) 553 { 554 zs_pset_t *pold, *pnew, *pres; 555 556 /* 557 * Walk psets, assume lists are always sorted the same. Include 558 * all psets that exist at the end of the interval. 559 */ 560 pold = list_head(&uold->zsu_pset_list); 561 pnew = list_head(&unew->zsu_pset_list); 562 563 while (pold != NULL && pnew != NULL) { 564 565 int cmp; 566 567 cmp = strcmp(pold->zsp_name, pnew->zsp_name); 568 if (cmp > 0) { 569 /* 570 * Old interval does not contain pset in new 571 * interval. Pset is new. 572 */ 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)); 582 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); 589 590 } else { 591 pres = pnew; 592 } 593 if (zs_usage_compute_pset_usage(uold, ures, pres, 594 NULL, pnew, func) != 0) 595 return (-1); 596 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; 602 603 } else if (cmp < 0) { 604 /* 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. 608 */ 609 pold = list_next(&uold->zsu_pset_list, pold); 610 continue; 611 } 612 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); 622 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); 628 } 629 if (func == ZS_COMPUTE_USAGE_AVERAGE || 630 func == ZS_COMPUTE_USAGE_TOTAL) 631 pres->zsp_intervals++; 632 if (func == ZS_COMPUTE_USAGE_INTERVAL) { 633 /* 634 * If pset as been destroyed and re-created since start 635 * interval, don't subtract the start interval. 636 */ 637 if (pnew->zsp_hrstart > uold->zsu_hrtime) { 638 goto usages; 639 } 640 TIMESTRUC_DELTA(pres->zsp_total_time, 641 pnew->zsp_total_time, pold->zsp_total_time); 642 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); 649 } 650 usages: 651 if (zs_usage_compute_pset_usage(uold, ures, pres, pold, 652 pnew, func) != 0) 653 return (-1); 654 655 pnew = list_next(&unew->zsu_pset_list, pnew); 656 pold = list_next(&uold->zsu_pset_list, pold); 657 } 658 659 if (ures == unew) 660 return (0); 661 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); 678 679 if (zs_usage_compute_pset_usage(uold, ures, pres, NULL, 680 pnew, func) != 0) 681 return (-1); 682 683 pnew = list_next(&unew->zsu_pset_list, pnew); 684 } 685 return (0); 686 } 687 688 static int 689 zs_zone_name(zs_zone_t *zone, char *name, size_t len) 690 { 691 return (strlcpy(name, zone->zsz_name, len)); 692 } 693 694 static zoneid_t 695 zs_zone_id(zs_zone_t *zone) 696 { 697 return (zone->zsz_id); 698 } 699 700 static uint_t 701 zs_zone_iptype(zs_zone_t *zone) 702 { 703 return (zone->zsz_iptype); 704 } 705 706 static uint_t 707 zs_zone_cputype(zs_zone_t *zone) 708 { 709 return (zone->zsz_cputype); 710 } 711 712 static int 713 zs_zone_poolname(zs_zone_t *zone, char *name, size_t len) 714 { 715 return (strlcpy(name, zone->zsz_pool, len)); 716 } 717 718 static int 719 zs_zone_psetname(zs_zone_t *zone, char *name, size_t len) 720 { 721 return (strlcpy(name, zone->zsz_pset, len)); 722 } 723 724 static uint_t 725 zs_zone_schedulers(zs_zone_t *zone) 726 { 727 return (zone->zsz_scheds); 728 } 729 730 static uint64_t 731 zs_ts_used_scale(timestruc_t *total, timestruc_t *used, uint64_t scale, 732 boolean_t cap_at_100) 733 { 734 double dtotal, dused, pct, dscale; 735 736 /* If no time yet, treat as zero */ 737 if (total->tv_sec == 0 && total->tv_nsec == 0) 738 return (0); 739 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); 744 745 dscale = (double)scale; 746 pct = dused / dtotal * dscale; 747 if (cap_at_100 && pct > dscale) 748 pct = dscale; 749 750 return ((uint_t)pct); 751 } 752 753 /* 754 * Convert total and used time into percent used. 755 */ 756 static uint_t 757 zs_ts_used_pct(timestruc_t *total, timestruc_t *used, boolean_t cap_at_100) 758 { 759 return ((uint_t)zs_ts_used_scale(total, used, ZSD_PCT_INT, cap_at_100)); 760 } 761 762 /* 763 * Convert total and used time, plus number of cpus, into number of cpus 764 * used, where 100 equals 1 cpu used. 765 */ 766 static uint64_t 767 zs_ts_used_cpus(timestruc_t *total, timestruc_t *used, uint_t ncpus, 768 boolean_t cap_at_100) 769 { 770 return (zs_ts_used_scale(total, used, ncpus * ZSD_ONE_CPU, cap_at_100)); 771 } 772 773 static uint64_t 774 zs_zone_cpu_shares(zs_zone_t *zone) 775 { 776 /* No processes found in FSS */ 777 if ((zone->zsz_scheds & ZS_SCHED_FSS) == 0) 778 return (ZS_LIMIT_NONE); 779 780 return (zone->zsz_cpu_shares); 781 } 782 783 static uint64_t 784 zs_zone_cpu_cap(zs_zone_t *zone) 785 { 786 return (zone->zsz_cpu_cap); 787 } 788 789 static uint64_t 790 zs_zone_cpu_cap_used(zs_zone_t *zone) 791 { 792 if (zone->zsz_cpu_cap == ZS_LIMIT_NONE) 793 return (ZS_LIMIT_NONE); 794 795 return (zs_ts_used_cpus(&zone->zsz_cap_time, &zone->zsz_cpu_usage, 796 zone->zsz_cpus_online, B_TRUE)); 797 } 798 799 static uint64_t 800 zs_zone_cpu_shares_used(zs_zone_t *zone) 801 { 802 if (zone->zsz_cpu_shares == ZS_LIMIT_NONE) 803 return (ZS_LIMIT_NONE); 804 805 if (zone->zsz_cpu_shares == ZS_SHARES_UNLIMITED) 806 return (ZS_LIMIT_NONE); 807 808 if ((zone->zsz_scheds & ZS_SCHED_FSS) == 0) 809 return (ZS_LIMIT_NONE); 810 811 return (zs_ts_used_scale(&zone->zsz_share_time, &zone->zsz_cpu_usage, 812 zone->zsz_cpu_shares, B_FALSE)); 813 } 814 815 static void 816 zs_zone_cpu_cap_time(zs_zone_t *zone, timestruc_t *ts) 817 { 818 *ts = zone->zsz_cap_time; 819 } 820 821 static void 822 zs_zone_cpu_share_time(zs_zone_t *zone, timestruc_t *ts) 823 { 824 *ts = zone->zsz_share_time; 825 } 826 827 static void 828 zs_zone_cpu_cap_time_used(zs_zone_t *zone, timestruc_t *ts) 829 { 830 *ts = zone->zsz_cpu_usage; 831 } 832 833 static void 834 zs_zone_cpu_share_time_used(zs_zone_t *zone, timestruc_t *ts) 835 { 836 *ts = zone->zsz_cpu_usage; 837 } 838 839 840 static uint64_t 841 zs_uint64_used_scale(uint64_t total, uint64_t used, uint64_t scale, 842 boolean_t cap_at_100) 843 { 844 double dtotal, dused, pct, dscale; 845 846 /* If no time yet, treat as zero */ 847 if (total == 0) 848 return (0); 849 850 dtotal = (double)total; 851 dused = (double)used; 852 853 dscale = (double)scale; 854 pct = dused / dtotal * dscale; 855 if (cap_at_100 && pct > dscale) 856 pct = dscale; 857 858 return ((uint64_t)pct); 859 } 860 861 /* 862 * Convert a total and used value into a percent used. 863 */ 864 static uint_t 865 zs_uint64_used_pct(uint64_t total, uint64_t used, boolean_t cap_at_100) 866 { 867 return ((uint_t)zs_uint64_used_scale(total, used, ZSD_PCT_INT, 868 cap_at_100)); 869 } 870 871 static uint_t 872 zs_zone_cpu_cap_pct(zs_zone_t *zone) 873 { 874 if (zone->zsz_cpu_cap == ZS_LIMIT_NONE) 875 return (ZS_PCT_NONE); 876 877 return (zs_ts_used_pct(&zone->zsz_cap_time, &zone->zsz_cpu_usage, 878 B_TRUE)); 879 } 880 881 static uint_t 882 zs_zone_cpu_shares_pct(zs_zone_t *zone) 883 { 884 if (zone->zsz_cpu_shares == ZS_LIMIT_NONE) 885 return (ZS_PCT_NONE); 886 887 if (zone->zsz_cpu_shares == ZS_SHARES_UNLIMITED) 888 return (ZS_PCT_NONE); 889 890 if ((zone->zsz_scheds & ZS_SCHED_FSS) == 0) 891 return (ZS_PCT_NONE); 892 893 return (zs_ts_used_pct(&zone->zsz_share_time, &zone->zsz_cpu_usage, 894 B_FALSE)); 895 } 896 897 static uint64_t 898 zs_zone_physical_memory_cap(zs_zone_t *zone) 899 { 900 return (zone->zsz_ram_cap); 901 } 902 903 static uint64_t 904 zs_zone_virtual_memory_cap(zs_zone_t *zone) 905 { 906 return (zone->zsz_vm_cap); 907 } 908 909 static uint64_t 910 zs_zone_locked_memory_cap(zs_zone_t *zone) 911 { 912 return (zone->zsz_locked_cap); 913 } 914 915 static uint64_t 916 zs_zone_physical_memory_cap_used(zs_zone_t *zone) 917 { 918 if (zone->zsz_ram_cap == ZS_LIMIT_NONE) 919 return (ZS_LIMIT_NONE); 920 921 return (zone->zsz_usage_ram); 922 } 923 924 static uint64_t 925 zs_zone_virtual_memory_cap_used(zs_zone_t *zone) 926 { 927 if (zone->zsz_vm_cap == ZS_LIMIT_NONE) 928 return (ZS_LIMIT_NONE); 929 930 return (zone->zsz_usage_vm); 931 } 932 933 static uint64_t 934 zs_zone_locked_memory_cap_used(zs_zone_t *zone) 935 { 936 if (zone->zsz_locked_cap == ZS_LIMIT_NONE) 937 return (ZS_LIMIT_NONE); 938 939 return (zone->zsz_usage_locked); 940 } 941 942 static int 943 zs_pset_name(zs_pset_t *pset, char *name, size_t len) 944 { 945 return (strlcpy(name, pset->zsp_name, len)); 946 } 947 948 static psetid_t 949 zs_pset_id(zs_pset_t *pset) 950 { 951 return (pset->zsp_id); 952 } 953 954 static uint64_t 955 zs_pset_size(zs_pset_t *pset) 956 { 957 return (pset->zsp_size); 958 } 959 960 static uint64_t 961 zs_pset_online(zs_pset_t *pset) 962 { 963 return (pset->zsp_online); 964 } 965 966 uint64_t 967 zs_pset_min(zs_pset_t *pset) 968 { 969 return (pset->zsp_min); 970 } 971 972 uint64_t 973 zs_pset_max(zs_pset_t *pset) 974 { 975 return (pset->zsp_max); 976 } 977 978 static uint_t 979 zs_pset_schedulers(zs_pset_t *pset) 980 { 981 return (pset->zsp_scheds); 982 } 983 984 static uint_t 985 zs_pset_zone_schedulers(zs_pset_zone_t *pz) 986 { 987 return (pz->zspz_scheds); 988 } 989 990 static uint64_t 991 zs_pset_cpu_shares(zs_pset_t *pset) 992 { 993 if (!(pset->zsp_scheds & ZS_SCHED_FSS)) 994 return (ZS_LIMIT_NONE); 995 996 return (pset->zsp_cpu_shares); 997 } 998 999 static uint64_t 1000 zs_pset_zone_cpu_shares(zs_pset_zone_t *pz) 1001 { 1002 if (!(pz->zspz_scheds & ZS_SCHED_FSS)) 1003 return (ZS_LIMIT_NONE); 1004 1005 return (pz->zspz_cpu_shares); 1006 } 1007 1008 static uint_t 1009 zs_pset_cputype(zs_pset_t *pset) 1010 { 1011 return (pset->zsp_cputype); 1012 } 1013 1014 static void 1015 zs_pset_usage_all(zs_pset_t *pset, timestruc_t *ts) 1016 { 1017 timestruc_t tot; 1018 1019 tot = pset->zsp_usage_kern; 1020 TIMESTRUC_ADD_TIMESTRUC(tot, pset->zsp_usage_zones); 1021 *ts = tot; 1022 } 1023 1024 static void 1025 zs_pset_usage_idle(zs_pset_t *pset, timestruc_t *ts) 1026 { 1027 timestruc_t tot, time, idle; 1028 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; 1034 } 1035 1036 static void 1037 zs_pset_usage_kernel(zs_pset_t *pset, timestruc_t *ts) 1038 { 1039 *ts = pset->zsp_usage_kern; 1040 } 1041 1042 static void 1043 zs_pset_usage_zones(zs_pset_t *pset, timestruc_t *ts) 1044 { 1045 *ts = pset->zsp_usage_zones; 1046 } 1047 1048 static uint_t 1049 zs_pset_usage_all_pct(zs_pset_t *pset) 1050 { 1051 timestruc_t tot; 1052 1053 tot = pset->zsp_usage_kern; 1054 TIMESTRUC_ADD_TIMESTRUC(tot, pset->zsp_usage_zones); 1055 1056 return (zs_ts_used_pct(&pset->zsp_total_time, &tot, B_TRUE)); 1057 } 1058 1059 static uint_t 1060 zs_pset_usage_idle_pct(zs_pset_t *pset) 1061 { 1062 timestruc_t tot, idle; 1063 1064 tot = pset->zsp_usage_kern; 1065 TIMESTRUC_ADD_TIMESTRUC(tot, pset->zsp_usage_zones); 1066 TIMESTRUC_DELTA(idle, pset->zsp_total_time, tot); 1067 1068 return (zs_ts_used_pct(&pset->zsp_total_time, &idle, B_TRUE)); 1069 } 1070 1071 static uint_t 1072 zs_pset_usage_kernel_pct(zs_pset_t *pset) 1073 { 1074 return (zs_ts_used_pct(&pset->zsp_total_time, &pset->zsp_usage_kern, 1075 B_TRUE)); 1076 } 1077 1078 static uint_t 1079 zs_pset_usage_zones_pct(zs_pset_t *pset) 1080 { 1081 return (zs_ts_used_pct(&pset->zsp_total_time, &pset->zsp_usage_zones, 1082 B_TRUE)); 1083 } 1084 1085 static uint_t 1086 zs_pset_usage_all_cpus(zs_pset_t *pset) 1087 { 1088 timestruc_t tot; 1089 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)); 1094 } 1095 1096 static uint_t 1097 zs_pset_usage_idle_cpus(zs_pset_t *pset) 1098 { 1099 timestruc_t tot, idle; 1100 1101 tot = pset->zsp_usage_kern; 1102 TIMESTRUC_ADD_TIMESTRUC(tot, pset->zsp_usage_zones); 1103 TIMESTRUC_DELTA(idle, pset->zsp_total_time, tot); 1104 1105 return (zs_ts_used_cpus(&pset->zsp_total_time, &tot, pset->zsp_online, 1106 B_TRUE)); 1107 } 1108 1109 static uint_t 1110 zs_pset_usage_kernel_cpus(zs_pset_t *pset) 1111 { 1112 return (zs_ts_used_cpus(&pset->zsp_total_time, &pset->zsp_usage_kern, 1113 pset->zsp_online, B_TRUE)); 1114 } 1115 1116 static uint64_t 1117 zs_pset_usage_zones_cpus(zs_pset_t *pset) 1118 { 1119 return (zs_ts_used_cpus(&pset->zsp_total_time, &pset->zsp_usage_zones, 1120 pset->zsp_online, B_TRUE)); 1121 } 1122 1123 static void 1124 zs_pset_zone_usage_time(zs_pset_zone_t *pz, timestruc_t *t) 1125 { 1126 *t = pz->zspz_cpu_usage; 1127 } 1128 1129 static uint_t 1130 zs_pset_zone_usage_cpus(zs_pset_zone_t *pz) 1131 { 1132 return (zs_ts_used_cpus(&pz->zspz_pset->zsp_total_time, 1133 &pz->zspz_cpu_usage, pz->zspz_pset->zsp_online, B_TRUE)); 1134 } 1135 1136 static uint_t 1137 zs_pset_zone_usage_pct_pset(zs_pset_zone_t *pz) 1138 { 1139 return (zs_ts_used_pct(&pz->zspz_pset->zsp_total_time, 1140 &pz->zspz_cpu_usage, B_TRUE)); 1141 } 1142 1143 static uint64_t 1144 zs_pset_zone_cpu_cap(zs_pset_zone_t *pz) 1145 { 1146 return (pz->zspz_zone->zsz_cpu_cap); 1147 } 1148 1149 static uint_t 1150 zs_pset_zone_usage_pct_cpu_cap(zs_pset_zone_t *pz) 1151 { 1152 zs_zone_t *zone = pz->zspz_zone; 1153 1154 if (zone->zsz_cpu_cap == ZS_LIMIT_NONE) { 1155 return (ZS_PCT_NONE); 1156 } 1157 return (zs_ts_used_pct(&zone->zsz_cap_time, 1158 &pz->zspz_cpu_usage, B_TRUE)); 1159 } 1160 1161 /* 1162 * Return the fraction of total shares for a pset allocated to the zone. 1163 */ 1164 static uint_t 1165 zs_pset_zone_usage_pct_pset_shares(zs_pset_zone_t *pz) 1166 { 1167 zs_pset_t *pset = pz->zspz_pset; 1168 1169 if (!(pz->zspz_scheds & ZS_SCHED_FSS)) 1170 return (ZS_PCT_NONE); 1171 1172 if (pz->zspz_cpu_shares == ZS_LIMIT_NONE) 1173 return (ZS_PCT_NONE); 1174 1175 if (pz->zspz_cpu_shares == ZS_SHARES_UNLIMITED) 1176 return (ZS_PCT_NONE); 1177 1178 if (pz->zspz_pset->zsp_cpu_shares == 0) 1179 return (0); 1180 1181 if (pz->zspz_cpu_shares == 0) 1182 return (0); 1183 1184 return (zs_uint64_used_pct(pset->zsp_cpu_shares, pz->zspz_cpu_shares, 1185 B_TRUE)); 1186 } 1187 1188 /* 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. 1192 */ 1193 static uint_t 1194 zs_pset_zone_usage_pct_cpu_shares(zs_pset_zone_t *pz) 1195 { 1196 timestruc_t tot, time; 1197 double sharefactor; 1198 double total; 1199 double used; 1200 double pct; 1201 1202 if (!(pz->zspz_scheds & ZS_SCHED_FSS)) 1203 return (ZS_PCT_NONE); 1204 1205 if (pz->zspz_cpu_shares == ZS_LIMIT_NONE) 1206 return (ZS_PCT_NONE); 1207 1208 if (pz->zspz_cpu_shares == ZS_SHARES_UNLIMITED) 1209 return (ZS_PCT_NONE); 1210 1211 if (pz->zspz_cpu_shares == 0) 1212 return (ZS_PCT_NONE); 1213 1214 sharefactor = (double)zs_pset_zone_usage_pct_pset_shares(pz); 1215 1216 /* Common scaling function won't do sharefactor. */ 1217 time = pz->zspz_pset->zsp_total_time; 1218 tot = pz->zspz_cpu_usage; 1219 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); 1225 1226 pct = used / total * ZSD_PCT_DOUBLE; 1227 /* Allow percent of share used to exceed 100% */ 1228 return ((uint_t)pct); 1229 } 1230 1231 static void 1232 zs_cpu_total_time(zs_usage_t *usage, timestruc_t *ts) 1233 { 1234 *ts = usage->zsu_system->zss_cpu_total_time; 1235 } 1236 1237 static void 1238 zs_cpu_usage_all(zs_usage_t *usage, timestruc_t *ts) 1239 { 1240 timestruc_t tot; 1241 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; 1247 } 1248 1249 static void 1250 zs_cpu_usage_idle(zs_usage_t *usage, timestruc_t *ts) 1251 { 1252 timestruc_t tot, time, idle; 1253 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; 1261 } 1262 1263 static uint_t 1264 zs_cpu_usage_all_pct(zs_usage_t *usage) 1265 { 1266 timestruc_t tot; 1267 1268 tot = usage->zsu_system->zss_cpu_usage_kern; 1269 TIMESTRUC_ADD_TIMESTRUC(tot, usage->zsu_system->zss_cpu_usage_zones); 1270 1271 return (zs_ts_used_pct(&usage->zsu_system->zss_cpu_total_time, 1272 &tot, B_TRUE)); 1273 } 1274 1275 1276 static uint_t 1277 zs_cpu_usage_idle_pct(zs_usage_t *usage) 1278 { 1279 timestruc_t tot, idle; 1280 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); 1284 1285 return (zs_ts_used_pct(&usage->zsu_system->zss_cpu_total_time, 1286 &idle, B_TRUE)); 1287 } 1288 1289 static void 1290 zs_cpu_usage_kernel(zs_usage_t *usage, timestruc_t *ts) 1291 { 1292 *ts = usage->zsu_system->zss_cpu_usage_kern; 1293 } 1294 1295 static uint_t 1296 zs_cpu_usage_kernel_pct(zs_usage_t *usage) 1297 { 1298 return (zs_ts_used_pct(&usage->zsu_system->zss_cpu_total_time, 1299 &usage->zsu_system->zss_cpu_usage_kern, B_TRUE)); 1300 } 1301 1302 static void 1303 zs_cpu_usage_zones(zs_usage_t *usage, timestruc_t *ts) 1304 { 1305 *ts = usage->zsu_system->zss_cpu_usage_zones; 1306 } 1307 1308 1309 static uint_t 1310 zs_cpu_usage_zones_pct(zs_usage_t *usage) 1311 { 1312 return (zs_ts_used_pct(&usage->zsu_system->zss_cpu_total_time, 1313 &usage->zsu_system->zss_cpu_usage_zones, B_TRUE)); 1314 } 1315 1316 1317 static void 1318 zs_cpu_usage_zone(zs_zone_t *zone, timestruc_t *ts) 1319 { 1320 *ts = zone->zsz_cpu_usage; 1321 } 1322 1323 static uint64_t 1324 zs_cpu_total_cpu(zs_usage_t *usage) 1325 { 1326 return (usage->zsu_system->zss_ncpus_online * ZSD_ONE_CPU); 1327 } 1328 1329 static uint64_t 1330 zs_cpu_usage_all_cpu(zs_usage_t *usage) 1331 { 1332 timestruc_t tot; 1333 1334 tot = usage->zsu_system->zss_cpu_usage_kern; 1335 TIMESTRUC_ADD_TIMESTRUC(tot, usage->zsu_system->zss_cpu_usage_zones); 1336 1337 return (zs_ts_used_cpus(&usage->zsu_system->zss_cpu_total_time, 1338 &tot, usage->zsu_system->zss_ncpus_online, B_TRUE)); 1339 } 1340 1341 static uint64_t 1342 zs_cpu_usage_idle_cpu(zs_usage_t *usage) 1343 { 1344 timestruc_t tot, idle; 1345 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); 1349 1350 return (zs_ts_used_cpus(&usage->zsu_system->zss_cpu_total_time, 1351 &idle, usage->zsu_system->zss_ncpus_online, B_TRUE)); 1352 } 1353 1354 static uint64_t 1355 zs_cpu_usage_kernel_cpu(zs_usage_t *usage) 1356 { 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)); 1360 } 1361 1362 static uint64_t 1363 zs_cpu_usage_zones_cpu(zs_usage_t *usage) 1364 { 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)); 1368 } 1369 1370 static uint64_t 1371 zs_cpu_usage_zone_cpu(zs_zone_t *zone) 1372 { 1373 return (zs_ts_used_cpus(&zone->zsz_pset_time, &zone->zsz_cpu_usage, 1374 zone->zsz_cpus_online, B_TRUE)); 1375 } 1376 1377 static uint_t 1378 zs_cpu_usage_zone_pct(zs_zone_t *zone) 1379 { 1380 return (zs_ts_used_pct(&zone->zsz_pset_time, &zone->zsz_cpu_usage, 1381 B_TRUE)); 1382 } 1383 1384 static uint64_t 1385 zs_physical_memory_total(zs_usage_t *usage) 1386 { 1387 return (usage->zsu_system->zss_ram_total); 1388 } 1389 1390 1391 static uint64_t 1392 zs_physical_memory_usage_all(zs_usage_t *usage) 1393 { 1394 return (usage->zsu_system->zss_ram_kern + 1395 usage->zsu_system->zss_ram_zones); 1396 } 1397 1398 static uint_t 1399 zs_physical_memory_usage_all_pct(zs_usage_t *usage) 1400 { 1401 zs_system_t *system = usage->zsu_system; 1402 1403 return (zs_uint64_used_pct(system->zss_ram_total, 1404 (system->zss_ram_kern + system->zss_ram_zones), B_TRUE)); 1405 } 1406 1407 static uint64_t 1408 zs_physical_memory_usage_free(zs_usage_t *usage) 1409 { 1410 return (usage->zsu_system->zss_ram_total - 1411 (usage->zsu_system->zss_ram_kern + 1412 usage->zsu_system->zss_ram_zones)); 1413 } 1414 1415 static uint_t 1416 zs_physical_memory_usage_free_pct(zs_usage_t *usage) 1417 { 1418 return (ZSD_PCT_INT - zs_physical_memory_usage_all_pct(usage)); 1419 } 1420 1421 static uint64_t 1422 zs_physical_memory_usage_kernel(zs_usage_t *usage) 1423 { 1424 return (usage->zsu_system->zss_ram_kern); 1425 } 1426 1427 static uint_t 1428 zs_physical_memory_usage_kernel_pct(zs_usage_t *usage) 1429 { 1430 zs_system_t *system = usage->zsu_system; 1431 1432 return (zs_uint64_used_pct(system->zss_ram_total, 1433 system->zss_ram_kern, B_TRUE)); 1434 } 1435 1436 static uint64_t 1437 zs_physical_memory_usage_zones(zs_usage_t *usage) 1438 { 1439 return (usage->zsu_system->zss_ram_zones); 1440 } 1441 1442 static uint_t 1443 zs_physical_memory_usage_zones_pct(zs_usage_t *usage) 1444 { 1445 zs_system_t *system = usage->zsu_system; 1446 1447 return (zs_uint64_used_pct(system->zss_ram_total, 1448 system->zss_ram_zones, B_TRUE)); 1449 } 1450 1451 static uint64_t 1452 zs_physical_memory_usage_zone(zs_zone_t *zone) 1453 { 1454 return (zone->zsz_usage_ram); 1455 } 1456 1457 static uint_t 1458 zs_physical_memory_usage_zone_pct(zs_zone_t *zone) 1459 { 1460 zs_system_t *system = zone->zsz_system; 1461 1462 return (zs_uint64_used_pct(system->zss_ram_total, 1463 zone->zsz_usage_ram, B_TRUE)); 1464 } 1465 1466 static uint_t 1467 zs_zone_physical_memory_cap_pct(zs_zone_t *zone) 1468 { 1469 if (zone->zsz_ram_cap == ZS_LIMIT_NONE) 1470 return (ZS_PCT_NONE); 1471 1472 if (zone->zsz_ram_cap == 0) { 1473 return (0); 1474 } 1475 1476 /* Allow ram cap to exeed 100% */ 1477 return (zs_uint64_used_pct(zone->zsz_ram_cap, 1478 zone->zsz_usage_ram, B_FALSE)); 1479 } 1480 static uint64_t 1481 zs_virtual_memory_total(zs_usage_t *usage) 1482 { 1483 return (usage->zsu_system->zss_vm_total); 1484 } 1485 1486 static uint64_t 1487 zs_virtual_memory_usage_all(zs_usage_t *usage) 1488 { 1489 return (usage->zsu_system->zss_vm_kern + 1490 usage->zsu_system->zss_vm_zones); 1491 } 1492 static uint64_t 1493 zs_virtual_memory_usage_free(zs_usage_t *usage) 1494 { 1495 return (usage->zsu_system->zss_vm_total - 1496 (usage->zsu_system->zss_vm_kern + 1497 usage->zsu_system->zss_vm_zones)); 1498 } 1499 static uint_t 1500 zs_virtual_memory_usage_all_pct(zs_usage_t *usage) 1501 { 1502 zs_system_t *system = usage->zsu_system; 1503 1504 return (zs_uint64_used_pct(system->zss_vm_total, 1505 (system->zss_vm_kern + system->zss_vm_zones), B_TRUE)); 1506 1507 } 1508 1509 static uint_t 1510 zs_virtual_memory_usage_free_pct(zs_usage_t *usage) 1511 { 1512 return (ZSD_PCT_INT - zs_virtual_memory_usage_all_pct(usage)); 1513 1514 } 1515 static uint64_t 1516 zs_virtual_memory_usage_kernel(zs_usage_t *usage) 1517 { 1518 return (usage->zsu_system->zss_vm_kern); 1519 } 1520 1521 static uint_t 1522 zs_virtual_memory_usage_kernel_pct(zs_usage_t *usage) 1523 { 1524 zs_system_t *system = usage->zsu_system; 1525 1526 return (zs_uint64_used_pct(system->zss_vm_total, 1527 system->zss_vm_kern, B_TRUE)); 1528 } 1529 1530 static uint64_t 1531 zs_virtual_memory_usage_zones(zs_usage_t *usage) 1532 { 1533 return (usage->zsu_system->zss_vm_zones); 1534 } 1535 1536 static uint_t 1537 zs_virtual_memory_usage_zones_pct(zs_usage_t *usage) 1538 { 1539 zs_system_t *system = usage->zsu_system; 1540 1541 return (zs_uint64_used_pct(system->zss_vm_total, 1542 system->zss_vm_zones, B_TRUE)); 1543 } 1544 1545 static uint64_t 1546 zs_virtual_memory_usage_zone(zs_zone_t *zone) 1547 { 1548 return (zone->zsz_usage_vm); 1549 } 1550 1551 static uint_t 1552 zs_virtual_memory_usage_zone_pct(zs_zone_t *zone) 1553 { 1554 zs_system_t *system = zone->zsz_system; 1555 1556 return (zs_uint64_used_pct(system->zss_vm_total, 1557 zone->zsz_usage_vm, B_TRUE)); 1558 1559 } 1560 1561 static uint_t 1562 zs_zone_virtual_memory_cap_pct(zs_zone_t *zone) 1563 { 1564 if (zone->zsz_vm_cap == ZS_LIMIT_NONE) 1565 return (ZS_PCT_NONE); 1566 1567 if (zone->zsz_vm_cap == 0) 1568 return (0); 1569 1570 return (zs_uint64_used_pct(zone->zsz_vm_cap, 1571 zone->zsz_usage_vm, B_TRUE)); 1572 } 1573 1574 static uint64_t 1575 zs_locked_memory_total(zs_usage_t *usage) 1576 { 1577 return (usage->zsu_system->zss_ram_total); 1578 } 1579 1580 static uint64_t 1581 zs_locked_memory_usage_all(zs_usage_t *usage) 1582 { 1583 return (usage->zsu_system->zss_locked_kern + 1584 usage->zsu_system->zss_locked_zones); 1585 } 1586 static uint64_t 1587 zs_locked_memory_usage_free(zs_usage_t *usage) 1588 { 1589 return (usage->zsu_system->zss_ram_total - 1590 (usage->zsu_system->zss_locked_kern + 1591 usage->zsu_system->zss_locked_zones)); 1592 } 1593 1594 static uint_t 1595 zs_locked_memory_usage_all_pct(zs_usage_t *usage) 1596 { 1597 zs_system_t *system = usage->zsu_system; 1598 1599 return (zs_uint64_used_pct(system->zss_ram_total, 1600 (system->zss_locked_kern + system->zss_locked_zones), B_TRUE)); 1601 } 1602 1603 static uint_t 1604 zs_locked_memory_usage_free_pct(zs_usage_t *usage) 1605 { 1606 return (ZSD_PCT_INT - zs_locked_memory_usage_all_pct(usage)); 1607 1608 } 1609 1610 static uint64_t 1611 zs_locked_memory_usage_kernel(zs_usage_t *usage) 1612 { 1613 return (usage->zsu_system->zss_locked_kern); 1614 } 1615 1616 static uint_t 1617 zs_locked_memory_usage_kernel_pct(zs_usage_t *usage) 1618 { 1619 zs_system_t *system = usage->zsu_system; 1620 1621 return (zs_uint64_used_pct(system->zss_ram_total, 1622 system->zss_locked_kern, B_TRUE)); 1623 } 1624 1625 static uint64_t 1626 zs_locked_memory_usage_zones(zs_usage_t *usage) 1627 { 1628 return (usage->zsu_system->zss_locked_zones); 1629 } 1630 1631 static uint_t 1632 zs_locked_memory_usage_zones_pct(zs_usage_t *usage) 1633 { 1634 zs_system_t *system = usage->zsu_system; 1635 1636 return (zs_uint64_used_pct(system->zss_ram_total, 1637 system->zss_locked_zones, B_TRUE)); 1638 } 1639 1640 static uint64_t 1641 zs_locked_memory_usage_zone(zs_zone_t *zone) 1642 { 1643 return (zone->zsz_usage_locked); 1644 } 1645 1646 static uint_t 1647 zs_locked_memory_usage_zone_pct(zs_zone_t *zone) 1648 { 1649 zs_system_t *system = zone->zsz_system; 1650 1651 return (zs_uint64_used_pct(system->zss_ram_total, 1652 zone->zsz_usage_locked, B_TRUE)); 1653 } 1654 1655 static uint_t 1656 zs_zone_locked_memory_cap_pct(zs_zone_t *zone) 1657 { 1658 if (zone->zsz_locked_cap == ZS_LIMIT_NONE) 1659 return (ZS_PCT_NONE); 1660 1661 if (zone->zsz_locked_cap == 0) 1662 return (0); 1663 1664 return (zs_uint64_used_pct(zone->zsz_locked_cap, 1665 zone->zsz_usage_locked, B_TRUE)); 1666 1667 } 1668 static uint64_t 1669 zs_disk_swap_total(zs_usage_t *usage) 1670 { 1671 return (usage->zsu_system->zss_swap_total); 1672 } 1673 1674 static uint64_t 1675 zs_disk_swap_usage_all(zs_usage_t *usage) 1676 { 1677 return (usage->zsu_system->zss_swap_used); 1678 } 1679 1680 static uint_t 1681 zs_disk_swap_usage_all_pct(zs_usage_t *usage) 1682 { 1683 return (zs_uint64_used_pct(usage->zsu_system->zss_swap_total, 1684 usage->zsu_system->zss_swap_used, B_TRUE)); 1685 } 1686 1687 static uint64_t 1688 zs_disk_swap_usage_free(zs_usage_t *usage) 1689 { 1690 return (usage->zsu_system->zss_swap_total - 1691 usage->zsu_system->zss_swap_used); 1692 } 1693 1694 static uint_t 1695 zs_disk_swap_usage_free_pct(zs_usage_t *usage) 1696 { 1697 return (ZSD_PCT_INT - zs_disk_swap_usage_all_pct(usage)); 1698 } 1699 1700 static uint64_t 1701 zs_processes_total(zs_usage_t *usage) 1702 { 1703 return (usage->zsu_system->zss_processes_max); 1704 } 1705 1706 static uint64_t 1707 zs_lwps_total(zs_usage_t *usage) 1708 { 1709 return (usage->zsu_system->zss_lwps_max); 1710 } 1711 1712 static uint64_t 1713 zs_shm_total(zs_usage_t *usage) 1714 { 1715 return (usage->zsu_system->zss_shm_max); 1716 } 1717 1718 static uint64_t 1719 zs_shmids_total(zs_usage_t *usage) 1720 { 1721 return (usage->zsu_system->zss_shmids_max); 1722 } 1723 1724 static uint64_t 1725 zs_semids_total(zs_usage_t *usage) 1726 { 1727 return (usage->zsu_system->zss_semids_max); 1728 } 1729 1730 static uint64_t 1731 zs_msgids_total(zs_usage_t *usage) 1732 { 1733 return (usage->zsu_system->zss_msgids_max); 1734 } 1735 1736 static uint64_t 1737 zs_lofi_total(zs_usage_t *usage) 1738 { 1739 return (usage->zsu_system->zss_lofi_max); 1740 } 1741 1742 static uint64_t 1743 zs_processes_usage_all(zs_usage_t *usage) 1744 { 1745 return (usage->zsu_system->zss_processes); 1746 } 1747 1748 static uint64_t 1749 zs_lwps_usage_all(zs_usage_t *usage) 1750 { 1751 return (usage->zsu_system->zss_lwps); 1752 } 1753 1754 static uint64_t 1755 zs_shm_usage_all(zs_usage_t *usage) 1756 { 1757 return (usage->zsu_system->zss_shm); 1758 } 1759 1760 static uint64_t 1761 zs_shmids_usage_all(zs_usage_t *usage) 1762 { 1763 return (usage->zsu_system->zss_shmids); 1764 } 1765 1766 static uint64_t 1767 zs_semids_usage_all(zs_usage_t *usage) 1768 { 1769 return (usage->zsu_system->zss_semids); 1770 } 1771 1772 static uint64_t 1773 zs_msgids_usage_all(zs_usage_t *usage) 1774 { 1775 return (usage->zsu_system->zss_msgids); 1776 } 1777 1778 static uint64_t 1779 zs_lofi_usage_all(zs_usage_t *usage) 1780 { 1781 return (usage->zsu_system->zss_lofi); 1782 } 1783 static uint64_t 1784 zs_processes_usage_all_pct(zs_usage_t *usage) 1785 { 1786 zs_system_t *system = usage->zsu_system; 1787 1788 return (zs_uint64_used_pct(system->zss_processes_max, 1789 system->zss_processes, B_TRUE)); 1790 } 1791 1792 static uint_t 1793 zs_lwps_usage_all_pct(zs_usage_t *usage) 1794 { 1795 zs_system_t *system = usage->zsu_system; 1796 1797 return (zs_uint64_used_pct(system->zss_lwps_max, 1798 system->zss_lwps, B_TRUE)); 1799 } 1800 1801 static uint_t 1802 zs_shm_usage_all_pct(zs_usage_t *usage) 1803 { 1804 zs_system_t *system = usage->zsu_system; 1805 1806 return (zs_uint64_used_pct(system->zss_shm_max, 1807 system->zss_shm, B_TRUE)); 1808 } 1809 1810 static uint_t 1811 zs_shmids_usage_all_pct(zs_usage_t *usage) 1812 { 1813 zs_system_t *system = usage->zsu_system; 1814 1815 return (zs_uint64_used_pct(system->zss_shmids_max, 1816 system->zss_shmids, B_TRUE)); 1817 } 1818 1819 static uint64_t 1820 zs_semids_usage_all_pct(zs_usage_t *usage) 1821 { 1822 zs_system_t *system = usage->zsu_system; 1823 1824 return (zs_uint64_used_pct(system->zss_semids_max, 1825 system->zss_semids, B_TRUE)); 1826 } 1827 1828 static uint64_t 1829 zs_msgids_usage_all_pct(zs_usage_t *usage) 1830 { 1831 zs_system_t *system = usage->zsu_system; 1832 1833 return (zs_uint64_used_pct(system->zss_msgids_max, 1834 system->zss_msgids, B_TRUE)); 1835 } 1836 1837 static uint64_t 1838 zs_lofi_usage_all_pct(zs_usage_t *usage) 1839 { 1840 zs_system_t *system = usage->zsu_system; 1841 1842 return (zs_uint64_used_pct(system->zss_lofi_max, 1843 system->zss_lofi, B_TRUE)); 1844 } 1845 1846 static uint64_t 1847 zs_processes_usage_zone(zs_zone_t *zone) 1848 { 1849 return (zone->zsz_processes); 1850 } 1851 1852 static uint64_t 1853 zs_lwps_usage_zone(zs_zone_t *zone) 1854 { 1855 return (zone->zsz_lwps); 1856 } 1857 1858 static uint64_t 1859 zs_shm_usage_zone(zs_zone_t *zone) 1860 { 1861 return (zone->zsz_shm); 1862 } 1863 1864 static uint64_t 1865 zs_shmids_usage_zone(zs_zone_t *zone) 1866 { 1867 return (zone->zsz_shmids); 1868 } 1869 1870 static uint64_t 1871 zs_semids_usage_zone(zs_zone_t *zone) 1872 { 1873 return (zone->zsz_semids); 1874 } 1875 1876 static uint64_t 1877 zs_msgids_usage_zone(zs_zone_t *zone) 1878 { 1879 return (zone->zsz_msgids); 1880 } 1881 1882 static uint64_t 1883 zs_lofi_usage_zone(zs_zone_t *zone) 1884 { 1885 return (zone->zsz_lofi); 1886 } 1887 1888 static uint_t 1889 zs_processes_usage_zone_pct(zs_zone_t *zone) 1890 { 1891 zs_system_t *system = zone->zsz_system; 1892 1893 return (zs_uint64_used_pct(system->zss_processes_max, 1894 zone->zsz_processes, B_TRUE)); 1895 } 1896 1897 static uint_t 1898 zs_lwps_usage_zone_pct(zs_zone_t *zone) 1899 { 1900 zs_system_t *system = zone->zsz_system; 1901 1902 return (zs_uint64_used_pct(system->zss_lwps_max, 1903 zone->zsz_lwps, B_TRUE)); 1904 } 1905 1906 static uint_t 1907 zs_shm_usage_zone_pct(zs_zone_t *zone) 1908 { 1909 zs_system_t *system = zone->zsz_system; 1910 1911 return (zs_uint64_used_pct(system->zss_shm_max, 1912 zone->zsz_shm, B_TRUE)); 1913 } 1914 1915 static uint_t 1916 zs_shmids_usage_zone_pct(zs_zone_t *zone) 1917 { 1918 zs_system_t *system = zone->zsz_system; 1919 1920 return (zs_uint64_used_pct(system->zss_shmids_max, 1921 zone->zsz_shmids, B_TRUE)); 1922 } 1923 1924 static uint_t 1925 zs_semids_usage_zone_pct(zs_zone_t *zone) 1926 { 1927 zs_system_t *system = zone->zsz_system; 1928 1929 return (zs_uint64_used_pct(system->zss_semids_max, 1930 zone->zsz_semids, B_TRUE)); 1931 } 1932 1933 static uint_t 1934 zs_msgids_usage_zone_pct(zs_zone_t *zone) 1935 { 1936 zs_system_t *system = zone->zsz_system; 1937 1938 return (zs_uint64_used_pct(system->zss_msgids_max, 1939 zone->zsz_msgids, B_TRUE)); 1940 } 1941 1942 static uint_t 1943 zs_lofi_usage_zone_pct(zs_zone_t *zone) 1944 { 1945 zs_system_t *system = zone->zsz_system; 1946 1947 return (zs_uint64_used_pct(system->zss_lofi_max, 1948 zone->zsz_lofi, B_TRUE)); 1949 } 1950 1951 static uint_t 1952 zs_processes_zone_cap_pct(zs_zone_t *zone) 1953 { 1954 if (zone->zsz_processes_cap == ZS_LIMIT_NONE) 1955 return (ZS_PCT_NONE); 1956 1957 if (zone->zsz_processes_cap == 0) 1958 return (0); 1959 1960 return (zs_uint64_used_pct(zone->zsz_processes_cap, 1961 zone->zsz_processes, B_TRUE)); 1962 } 1963 1964 static uint_t 1965 zs_lwps_zone_cap_pct(zs_zone_t *zone) 1966 { 1967 if (zone->zsz_lwps_cap == ZS_LIMIT_NONE) 1968 return (ZS_PCT_NONE); 1969 1970 if (zone->zsz_lwps_cap == 0) 1971 return (0); 1972 1973 return (zs_uint64_used_pct(zone->zsz_lwps_cap, zone->zsz_lwps, B_TRUE)); 1974 } 1975 1976 static uint_t 1977 zs_shm_zone_cap_pct(zs_zone_t *zone) 1978 { 1979 if (zone->zsz_shm_cap == ZS_LIMIT_NONE) 1980 return (ZS_PCT_NONE); 1981 1982 if (zone->zsz_shm_cap == 0) 1983 return (0); 1984 1985 return (zs_uint64_used_pct(zone->zsz_shm_cap, zone->zsz_shm, B_TRUE)); 1986 } 1987 1988 static uint_t 1989 zs_shmids_zone_cap_pct(zs_zone_t *zone) 1990 { 1991 if (zone->zsz_shmids_cap == ZS_LIMIT_NONE) 1992 return (ZS_PCT_NONE); 1993 1994 if (zone->zsz_shmids_cap == 0) 1995 return (0); 1996 1997 return (zs_uint64_used_pct(zone->zsz_shmids_cap, zone->zsz_shmids, 1998 B_TRUE)); 1999 } 2000 2001 static uint_t 2002 zs_semids_zone_cap_pct(zs_zone_t *zone) 2003 { 2004 if (zone->zsz_semids_cap == ZS_LIMIT_NONE) 2005 return (ZS_PCT_NONE); 2006 2007 if (zone->zsz_semids_cap == 0) 2008 return (0); 2009 2010 return (zs_uint64_used_pct(zone->zsz_semids_cap, zone->zsz_semids, 2011 B_TRUE)); 2012 } 2013 2014 static uint_t 2015 zs_msgids_zone_cap_pct(zs_zone_t *zone) 2016 { 2017 if (zone->zsz_msgids_cap == ZS_LIMIT_NONE) 2018 return (ZS_PCT_NONE); 2019 2020 if (zone->zsz_msgids_cap == 0) 2021 return (0); 2022 2023 return (zs_uint64_used_pct(zone->zsz_msgids_cap, zone->zsz_msgids, 2024 B_TRUE)); 2025 } 2026 2027 static uint_t 2028 zs_lofi_zone_cap_pct(zs_zone_t *zone) 2029 { 2030 if (zone->zsz_lofi_cap == ZS_LIMIT_NONE) 2031 return (ZS_PCT_NONE); 2032 2033 if (zone->zsz_lofi_cap == 0) 2034 return (0); 2035 2036 return (zs_uint64_used_pct(zone->zsz_lofi_cap, zone->zsz_lofi, 2037 B_TRUE)); 2038 } 2039 2040 /* All funcs this line should be static */ 2041 2042 void 2043 zs_close(zs_ctl_t *ctl) 2044 { 2045 (void) close(ctl->zsctl_door); 2046 zs_usage_free(ctl->zsctl_start); 2047 free(ctl); 2048 } 2049 2050 /* 2051 * ERRORS 2052 * 2053 * EINTR signal received, process forked, or zonestatd exited 2054 * ESRCH zonestatd not responding 2055 */ 2056 static zs_usage_t * 2057 zs_usage_read_internal(zs_ctl_t *ctl, int init) 2058 { 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; 2068 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; 2078 2079 if (door_call(fd, ¶ms) != 0) { 2080 if (errno != EINTR) 2081 errno = ESRCH; 2082 return (NULL); 2083 } 2084 2085 if (params.rbuf == NULL) { 2086 errno = ESRCH; 2087 return (NULL); 2088 } 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; 2094 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)); 2099 2100 /* Fix up next pointers inside usage_t */ 2101 next = (char *)usage; 2102 next += sizeof (zs_usage_t); 2103 2104 /* LINTED */ 2105 usage->zsu_system = (zs_system_t *)next; 2106 next += sizeof (zs_system_t); 2107 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; 2115 } 2116 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; 2134 } 2135 pset->zsp_intervals = 0; 2136 } 2137 if (init) 2138 return (usage); 2139 2140 /* 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. 2145 */ 2146 if (usage->zsu_hrstart > ctl->zsctl_start->zsu_hrtime) { 2147 return (usage); 2148 } 2149 2150 /* 2151 * Compute usage relative to first open. Usage returned by 2152 * zonestatd starts at an arbitrary point in the past. 2153 * 2154 */ 2155 2156 (void) zs_usage_compute(usage, ctl->zsctl_start, usage, 2157 ZS_COMPUTE_USAGE_INTERVAL); 2158 2159 return (usage); 2160 } 2161 2162 zs_usage_t * 2163 zs_usage_read(zs_ctl_t *ctl) 2164 { 2165 return (zs_usage_read_internal(ctl, B_FALSE)); 2166 } 2167 2168 /* 2169 * Open connection to zonestatd. NULL of failure, with errno set: 2170 * 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) 2177 * 2178 */ 2179 zs_ctl_t * 2180 zs_open() 2181 { 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; 2189 2190 ctl = calloc(sizeof (zs_ctl_t), 1); 2191 if (ctl == NULL) 2192 return (NULL); 2193 2194 fd = zs_connect_zonestatd(); 2195 if (fd < 0) { 2196 free(ctl); 2197 errno = ESRCH; 2198 return (NULL); 2199 } 2200 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, ¶ms) != 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); 2218 } 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); 2226 } 2227 if (res[1] == ZSD_STATUS_PERMISSION) { 2228 free(ctl); 2229 errno = EPERM; 2230 return (NULL); 2231 } 2232 if (res[1] != ZSD_STATUS_OK) { 2233 free(ctl); 2234 errno = ESRCH; 2235 return (NULL); 2236 } 2237 2238 door = params.desc_ptr; 2239 if (door == NULL) { 2240 free(ctl); 2241 return (NULL); 2242 } 2243 ctl->zsctl_door = door->d_data.d_desc.d_descriptor; 2244 2245 if (params.data_ptr != (char *)cmd) 2246 (void) munmap(params.data_ptr, params.data_size); 2247 2248 2249 /* 2250 * Get the initial usage from zonestatd. This creates a 2251 * zero-point on which to base future usages returned by 2252 * zs_read(). 2253 */ 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); 2264 } 2265 return (ctl); 2266 } 2267 2268 /* 2269 * Return NULL on error. 2270 * 2271 * ERRORS: 2272 * EINVAL: Invalid function. 2273 */ 2274 zs_usage_t * 2275 zs_usage_compute(zs_usage_t *ures, zs_usage_t *uold, zs_usage_t *unew, 2276 int func) 2277 { 2278 zs_system_t *sold, *snew, *sres; 2279 boolean_t alloced = B_FALSE; 2280 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); 2286 2287 if (ures == NULL) { 2288 alloced = B_TRUE; 2289 ures = zs_usage_alloc(); 2290 if (ures == NULL) 2291 return (NULL); 2292 } 2293 2294 sres = ures->zsu_system; 2295 sold = uold->zsu_system; 2296 snew = unew->zsu_system; 2297 2298 switch (func) { 2299 case ZS_COMPUTE_USAGE_INTERVAL: 2300 /* Use system totals from newer interval */ 2301 if (sres != snew) 2302 *sres = *snew; 2303 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: 2312 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); 2317 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); 2325 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; 2334 /* 2335 * Add in memory values and limits. Scale memory to 2336 * avoid overflow. 2337 */ 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); 2358 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++; 2372 2373 /* 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. 2377 */ 2378 sres->zss_ncpus = sold->zss_ncpus + snew->zss_ncpus; 2379 sres->zss_ncpus_online = sold->zss_ncpus_online + 2380 snew->zss_ncpus_online; 2381 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); 2392 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; 2401 /* 2402 * Add in memory values and limits. Scale memory to 2403 * avoid overflow. 2404 */ 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; 2416 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; 2424 } 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); 2448 } 2449 if (zs_usage_compute_zones(ures, uold, unew, func) != 0) 2450 goto err; 2451 2452 if (zs_usage_compute_psets(ures, uold, unew, func) != 0) 2453 goto err; 2454 2455 return (ures); 2456 err: 2457 if (alloced) 2458 zs_usage_free(ures); 2459 return (NULL); 2460 } 2461 2462 void 2463 zs_usage_free(zs_usage_t *usage) 2464 { 2465 zs_zone_t *zone, *ztmp; 2466 zs_pset_t *pset, *ptmp; 2467 zs_pset_zone_t *pz, *pztmp; 2468 2469 if (usage->zsu_mmap) { 2470 (void) munmap((void *)usage, usage->zsu_size); 2471 return; 2472 } 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); 2479 } 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); 2487 } 2488 ptmp = pset; 2489 pset = list_next(&usage->zsu_pset_list, pset); 2490 free(ptmp); 2491 } 2492 free(usage); 2493 } 2494 2495 zs_usage_set_t * 2496 zs_usage_set_alloc() 2497 { 2498 zs_usage_set_t *set; 2499 2500 set = calloc(sizeof (zs_usage_set_t), 1); 2501 if (set == NULL) 2502 return (NULL); 2503 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; 2510 2511 return (set); 2512 2513 err: 2514 if (set->zsus_total != NULL) 2515 free(set->zsus_total); 2516 if (set->zsus_avg != NULL) 2517 free(set->zsus_avg); 2518 if (set->zsus_high != NULL) 2519 free(set->zsus_high); 2520 2521 return (NULL); 2522 } 2523 2524 void 2525 zs_usage_set_free(zs_usage_set_t *set) 2526 { 2527 zs_usage_free(set->zsus_total); 2528 zs_usage_free(set->zsus_avg); 2529 zs_usage_free(set->zsus_high); 2530 free(set); 2531 } 2532 2533 int 2534 zs_usage_set_add(zs_usage_set_t *set, zs_usage_t *usage) 2535 { 2536 2537 /* Compute ongoing functions for usage set */ 2538 (void) zs_usage_compute(set->zsus_high, set->zsus_high, usage, 2539 ZS_COMPUTE_USAGE_HIGH); 2540 2541 (void) zs_usage_compute(set->zsus_total, set->zsus_total, usage, 2542 ZS_COMPUTE_USAGE_TOTAL); 2543 2544 (void) zs_usage_compute(set->zsus_avg, set->zsus_avg, usage, 2545 ZS_COMPUTE_USAGE_AVERAGE); 2546 2547 set->zsus_count++; 2548 zs_usage_free(usage); 2549 return (0); 2550 } 2551 2552 int 2553 zs_usage_set_count(zs_usage_set_t *set) 2554 { 2555 return (set->zsus_count); 2556 } 2557 2558 zs_usage_t * 2559 zs_usage_set_compute(zs_usage_set_t *set, int func) 2560 { 2561 zs_usage_t *u; 2562 zs_system_t *s; 2563 zs_zone_t *z; 2564 zs_pset_t *p; 2565 zs_pset_zone_t *pz; 2566 uint_t intervals; 2567 boolean_t average; 2568 2569 switch (func) { 2570 case ZS_COMPUTE_SET_HIGH: 2571 return (set->zsus_high); 2572 case ZS_COMPUTE_SET_TOTAL: 2573 u = set->zsus_total; 2574 average = B_FALSE; 2575 break; 2576 case ZS_COMPUTE_SET_AVERAGE: 2577 u = set->zsus_avg; 2578 average = B_TRUE; 2579 break; 2580 default: 2581 assert(0); 2582 } 2583 2584 s = u->zsu_system; 2585 2586 s->zss_ram_total /= u->zsu_intervals; 2587 s->zss_ram_total *= 1024; 2588 s->zss_ram_kern /= u->zsu_intervals; 2589 s->zss_ram_kern *= 1024; 2590 s->zss_ram_zones /= u->zsu_intervals; 2591 s->zss_ram_zones *= 1024; 2592 s->zss_locked_kern /= u->zsu_intervals; 2593 s->zss_locked_kern *= 1024; 2594 s->zss_locked_zones /= u->zsu_intervals; 2595 s->zss_locked_zones *= 1024; 2596 s->zss_vm_total /= u->zsu_intervals; 2597 s->zss_vm_total *= 1024; 2598 s->zss_vm_kern /= u->zsu_intervals; 2599 s->zss_vm_kern *= 1024; 2600 s->zss_vm_zones /= u->zsu_intervals; 2601 s->zss_vm_zones *= 1024; 2602 s->zss_swap_total /= u->zsu_intervals; 2603 s->zss_swap_total *= 1024; 2604 s->zss_swap_used /= u->zsu_intervals; 2605 s->zss_swap_used *= 1024; 2606 s->zss_processes /= u->zsu_intervals; 2607 s->zss_lwps /= u->zsu_intervals; 2608 s->zss_shm /= u->zsu_intervals; 2609 s->zss_shm *= 1024; 2610 s->zss_shmids /= u->zsu_intervals; 2611 s->zss_semids /= u->zsu_intervals; 2612 s->zss_msgids /= u->zsu_intervals; 2613 s->zss_lofi /= u->zsu_intervals; 2614 2615 s->zss_ncpus /= u->zsu_intervals; 2616 s->zss_ncpus_online /= u->zsu_intervals; 2617 2618 for (z = list_head(&u->zsu_zone_list); z != NULL; 2619 z = list_next(&u->zsu_zone_list, z)) { 2620 2621 if (average) { 2622 intervals = z->zsz_intervals; 2623 } else { 2624 assert(z->zsz_intervals == 0); 2625 intervals = u->zsu_intervals; 2626 } 2627 2628 if (z->zsz_cpu_cap != ZS_LIMIT_NONE) 2629 z->zsz_cpu_cap /= z->zsz_intervals; 2630 if (z->zsz_ram_cap != ZS_LIMIT_NONE) 2631 z->zsz_ram_cap /= z->zsz_intervals; 2632 if (z->zsz_vm_cap != ZS_LIMIT_NONE) 2633 z->zsz_vm_cap /= z->zsz_intervals; 2634 if (z->zsz_locked_cap != ZS_LIMIT_NONE) 2635 z->zsz_locked_cap /= z->zsz_intervals; 2636 if (z->zsz_processes_cap != ZS_LIMIT_NONE) 2637 z->zsz_processes_cap /= z->zsz_intervals; 2638 if (z->zsz_lwps_cap != ZS_LIMIT_NONE) 2639 z->zsz_lwps_cap /= z->zsz_intervals; 2640 if (z->zsz_shm_cap != ZS_LIMIT_NONE) 2641 z->zsz_shm_cap /= z->zsz_intervals; 2642 if (z->zsz_shmids_cap != ZS_LIMIT_NONE) 2643 z->zsz_shmids_cap /= z->zsz_intervals; 2644 if (z->zsz_semids_cap != ZS_LIMIT_NONE) 2645 z->zsz_semids_cap /= z->zsz_intervals; 2646 if (z->zsz_msgids_cap != ZS_LIMIT_NONE) 2647 z->zsz_msgids_cap /= z->zsz_intervals; 2648 if (z->zsz_lofi_cap != ZS_LIMIT_NONE) 2649 z->zsz_lofi_cap /= z->zsz_intervals; 2650 2651 z->zsz_usage_ram /= intervals; 2652 z->zsz_usage_locked /= intervals; 2653 z->zsz_usage_vm /= intervals; 2654 z->zsz_processes /= intervals; 2655 z->zsz_lwps /= intervals; 2656 z->zsz_shm /= intervals; 2657 z->zsz_shmids /= intervals; 2658 z->zsz_semids /= intervals; 2659 z->zsz_msgids /= intervals; 2660 z->zsz_lofi /= intervals; 2661 z->zsz_cpus_online /= intervals; 2662 z->zsz_cpu_shares /= intervals; 2663 } 2664 for (p = list_head(&u->zsu_pset_list); p != NULL; 2665 p = list_next(&u->zsu_pset_list, p)) { 2666 2667 intervals = p->zsp_intervals; 2668 2669 p->zsp_online /= intervals; 2670 p->zsp_size /= intervals; 2671 p->zsp_min /= intervals; 2672 p->zsp_max /= intervals; 2673 p->zsp_importance /= intervals; 2674 p->zsp_cpu_shares /= intervals; 2675 2676 for (pz = list_head(&p->zsp_usage_list); pz != NULL; 2677 pz = list_next(&p->zsp_usage_list, pz)) { 2678 2679 if (average) { 2680 intervals = pz->zspz_intervals; 2681 } else { 2682 assert(pz->zspz_intervals == 0); 2683 intervals = p->zsp_intervals; 2684 } 2685 pz->zspz_cpu_shares /= intervals; 2686 } 2687 } 2688 return (u); 2689 } 2690 2691 /* 2692 * Returns 0 on success. Trips assert on invalid property. 2693 */ 2694 void 2695 zs_resource_property(zs_usage_t *u, int res, int prop, zs_property_t *p) 2696 { 2697 switch (res) { 2698 case ZS_RESOURCE_CPU: 2699 switch (prop) { 2700 case ZS_RESOURCE_PROP_CPU_TOTAL: 2701 p->zsp_id = prop; 2702 p->zsp_type = ZS_PROP_TYPE_UINT64; 2703 p->zsp_v.zsv_uint64 = u->zsu_system->zss_ncpus; 2704 break; 2705 case ZS_RESOURCE_PROP_CPU_ONLINE: 2706 p->zsp_id = prop; 2707 p->zsp_type = ZS_PROP_TYPE_UINT64; 2708 p->zsp_v.zsv_uint64 = u->zsu_system->zss_ncpus_online; 2709 break; 2710 default: 2711 assert(0); 2712 } 2713 break; 2714 case ZS_RESOURCE_RAM_RSS: 2715 case ZS_RESOURCE_RAM_LOCKED: 2716 case ZS_RESOURCE_VM: 2717 case ZS_RESOURCE_DISK_SWAP: 2718 case ZS_RESOURCE_LWPS: 2719 case ZS_RESOURCE_PROCESSES: 2720 case ZS_RESOURCE_SHM_MEMORY: 2721 case ZS_RESOURCE_SHM_IDS: 2722 case ZS_RESOURCE_SEM_IDS: 2723 case ZS_RESOURCE_MSG_IDS: 2724 /* FALLTHROUGH */ 2725 default: 2726 assert(0); 2727 } 2728 } 2729 2730 /* 2731 * Returns one of ZS_RESOURCE_TYPE_* on success. Asserts on invalid 2732 * resource. 2733 */ 2734 int 2735 zs_resource_type(int res) 2736 { 2737 switch (res) { 2738 case ZS_RESOURCE_CPU: 2739 return (ZS_RESOURCE_TYPE_TIME); 2740 break; 2741 case ZS_RESOURCE_RAM_RSS: 2742 case ZS_RESOURCE_RAM_LOCKED: 2743 case ZS_RESOURCE_VM: 2744 case ZS_RESOURCE_DISK_SWAP: 2745 case ZS_RESOURCE_SHM_MEMORY: 2746 return (ZS_RESOURCE_TYPE_BYTES); 2747 break; 2748 case ZS_RESOURCE_LWPS: 2749 case ZS_RESOURCE_PROCESSES: 2750 case ZS_RESOURCE_SHM_IDS: 2751 case ZS_RESOURCE_SEM_IDS: 2752 case ZS_RESOURCE_MSG_IDS: 2753 return (ZS_RESOURCE_TYPE_COUNT); 2754 break; 2755 default: 2756 assert(0); 2757 return (0); 2758 } 2759 } 2760 2761 /* 2762 * Get total available resource on system 2763 */ 2764 uint64_t 2765 zs_resource_total_uint64(zs_usage_t *u, int res) 2766 { 2767 uint64_t v; 2768 2769 switch (res) { 2770 case ZS_RESOURCE_CPU: 2771 v = zs_cpu_total_cpu(u); 2772 break; 2773 case ZS_RESOURCE_RAM_RSS: 2774 v = zs_physical_memory_total(u); 2775 break; 2776 case ZS_RESOURCE_RAM_LOCKED: 2777 v = zs_locked_memory_total(u); 2778 break; 2779 case ZS_RESOURCE_VM: 2780 v = zs_virtual_memory_total(u); 2781 break; 2782 case ZS_RESOURCE_DISK_SWAP: 2783 v = zs_disk_swap_total(u); 2784 break; 2785 case ZS_RESOURCE_LWPS: 2786 v = zs_lwps_total(u); 2787 break; 2788 case ZS_RESOURCE_PROCESSES: 2789 v = zs_processes_total(u); 2790 break; 2791 case ZS_RESOURCE_SHM_MEMORY: 2792 v = zs_shm_total(u); 2793 break; 2794 case ZS_RESOURCE_SHM_IDS: 2795 v = zs_shmids_total(u); 2796 break; 2797 case ZS_RESOURCE_SEM_IDS: 2798 v = zs_semids_total(u); 2799 break; 2800 case ZS_RESOURCE_MSG_IDS: 2801 v = zs_msgids_total(u); 2802 break; 2803 case ZS_RESOURCE_LOFI: 2804 v = zs_lofi_total(u); 2805 break; 2806 default: 2807 assert(0); 2808 } 2809 return (v); 2810 } 2811 2812 /* 2813 * Get amount of used resource. 2814 */ 2815 uint64_t 2816 zs_resource_used_uint64(zs_usage_t *u, int res, int user) 2817 { 2818 uint64_t v; 2819 2820 switch (res) { 2821 case ZS_RESOURCE_CPU: 2822 switch (user) { 2823 case ZS_USER_ALL: 2824 v = zs_cpu_usage_all_cpu(u); 2825 break; 2826 case ZS_USER_KERNEL: 2827 v = zs_cpu_usage_kernel_cpu(u); 2828 break; 2829 case ZS_USER_ZONES: 2830 v = zs_cpu_usage_zones_cpu(u); 2831 break; 2832 case ZS_USER_FREE: 2833 v = zs_cpu_usage_idle_cpu(u); 2834 break; 2835 default: 2836 assert(0); 2837 } 2838 break; 2839 case ZS_RESOURCE_RAM_RSS: 2840 switch (user) { 2841 case ZS_USER_ALL: 2842 v = zs_physical_memory_usage_all(u); 2843 break; 2844 case ZS_USER_KERNEL: 2845 v = zs_physical_memory_usage_kernel(u); 2846 break; 2847 case ZS_USER_ZONES: 2848 v = zs_physical_memory_usage_zones(u); 2849 break; 2850 case ZS_USER_FREE: 2851 v = zs_physical_memory_usage_free(u); 2852 break; 2853 default: 2854 assert(0); 2855 } 2856 break; 2857 case ZS_RESOURCE_RAM_LOCKED: 2858 switch (user) { 2859 case ZS_USER_ALL: 2860 v = zs_locked_memory_usage_all(u); 2861 break; 2862 case ZS_USER_KERNEL: 2863 v = zs_locked_memory_usage_kernel(u); 2864 break; 2865 case ZS_USER_ZONES: 2866 v = zs_locked_memory_usage_zones(u); 2867 break; 2868 case ZS_USER_FREE: 2869 v = zs_locked_memory_usage_free(u); 2870 break; 2871 default: 2872 assert(0); 2873 } 2874 break; 2875 case ZS_RESOURCE_VM: 2876 switch (user) { 2877 case ZS_USER_ALL: 2878 v = zs_virtual_memory_usage_all(u); 2879 break; 2880 case ZS_USER_KERNEL: 2881 v = zs_virtual_memory_usage_kernel(u); 2882 break; 2883 case ZS_USER_ZONES: 2884 v = zs_virtual_memory_usage_zones(u); 2885 break; 2886 case ZS_USER_FREE: 2887 v = zs_virtual_memory_usage_free(u); 2888 break; 2889 default: 2890 assert(0); 2891 } 2892 break; 2893 case ZS_RESOURCE_DISK_SWAP: 2894 switch (user) { 2895 case ZS_USER_ALL: 2896 v = zs_disk_swap_usage_all(u); 2897 break; 2898 case ZS_USER_FREE: 2899 v = zs_disk_swap_usage_free(u); 2900 break; 2901 case ZS_USER_KERNEL: 2902 case ZS_USER_ZONES: 2903 /* FALLTHROUGH */ 2904 default: 2905 assert(0); 2906 } 2907 break; 2908 case ZS_RESOURCE_LWPS: 2909 switch (user) { 2910 case ZS_USER_ALL: 2911 case ZS_USER_ZONES: 2912 v = zs_lwps_usage_all(u); 2913 break; 2914 case ZS_USER_FREE: 2915 v = zs_lwps_total(u) - zs_lwps_usage_all(u); 2916 break; 2917 case ZS_USER_KERNEL: 2918 v = 0; 2919 break; 2920 default: 2921 assert(0); 2922 } 2923 break; 2924 case ZS_RESOURCE_PROCESSES: 2925 switch (user) { 2926 case ZS_USER_ALL: 2927 case ZS_USER_ZONES: 2928 v = zs_processes_usage_all(u); 2929 break; 2930 case ZS_USER_FREE: 2931 v = zs_processes_total(u) - zs_processes_usage_all(u); 2932 break; 2933 case ZS_USER_KERNEL: 2934 v = 0; 2935 break; 2936 default: 2937 assert(0); 2938 } 2939 break; 2940 case ZS_RESOURCE_SHM_MEMORY: 2941 switch (user) { 2942 case ZS_USER_ALL: 2943 case ZS_USER_ZONES: 2944 v = zs_shm_usage_all(u); 2945 break; 2946 case ZS_USER_FREE: 2947 v = zs_shm_total(u) - 2948 zs_shm_usage_all(u); 2949 break; 2950 case ZS_USER_KERNEL: 2951 v = 0; 2952 break; 2953 default: 2954 assert(0); 2955 } 2956 break; 2957 case ZS_RESOURCE_SHM_IDS: 2958 switch (user) { 2959 case ZS_USER_ALL: 2960 case ZS_USER_ZONES: 2961 v = zs_shmids_usage_all(u); 2962 break; 2963 case ZS_USER_FREE: 2964 v = zs_shmids_total(u) - zs_shmids_usage_all(u); 2965 break; 2966 case ZS_USER_KERNEL: 2967 v = 0; 2968 break; 2969 default: 2970 assert(0); 2971 } 2972 break; 2973 case ZS_RESOURCE_SEM_IDS: 2974 switch (user) { 2975 case ZS_USER_ALL: 2976 case ZS_USER_ZONES: 2977 v = zs_semids_usage_all(u); 2978 break; 2979 case ZS_USER_FREE: 2980 v = zs_semids_total(u) - zs_semids_usage_all(u); 2981 break; 2982 case ZS_USER_KERNEL: 2983 v = 0; 2984 break; 2985 default: 2986 assert(0); 2987 } 2988 break; 2989 case ZS_RESOURCE_MSG_IDS: 2990 switch (user) { 2991 case ZS_USER_ALL: 2992 case ZS_USER_ZONES: 2993 v = zs_msgids_usage_all(u); 2994 break; 2995 case ZS_USER_FREE: 2996 v = zs_msgids_total(u) - zs_msgids_usage_all(u); 2997 break; 2998 case ZS_USER_KERNEL: 2999 v = 0; 3000 break; 3001 default: 3002 assert(0); 3003 } 3004 break; 3005 case ZS_RESOURCE_LOFI: 3006 switch (user) { 3007 case ZS_USER_ALL: 3008 case ZS_USER_ZONES: 3009 v = zs_lofi_usage_all(u); 3010 break; 3011 case ZS_USER_FREE: 3012 v = zs_lofi_total(u) - zs_lofi_usage_all(u); 3013 break; 3014 case ZS_USER_KERNEL: 3015 v = 0; 3016 break; 3017 default: 3018 assert(0); 3019 } 3020 break; 3021 3022 default: 3023 assert(0); 3024 } 3025 return (v); 3026 } 3027 3028 /* 3029 * Get used resource as a percent of total resource. 3030 */ 3031 uint_t 3032 zs_resource_used_pct(zs_usage_t *u, int res, int user) 3033 { 3034 uint64_t v; 3035 3036 switch (res) { 3037 case ZS_RESOURCE_CPU: 3038 switch (user) { 3039 case ZS_USER_ALL: 3040 v = zs_cpu_usage_all_pct(u); 3041 break; 3042 case ZS_USER_KERNEL: 3043 v = zs_cpu_usage_kernel_pct(u); 3044 break; 3045 case ZS_USER_ZONES: 3046 v = zs_cpu_usage_zones_pct(u); 3047 break; 3048 case ZS_USER_FREE: 3049 v = zs_cpu_usage_idle_pct(u); 3050 break; 3051 default: 3052 assert(0); 3053 } 3054 break; 3055 case ZS_RESOURCE_RAM_RSS: 3056 switch (user) { 3057 case ZS_USER_ALL: 3058 v = zs_physical_memory_usage_all_pct(u); 3059 break; 3060 case ZS_USER_KERNEL: 3061 v = zs_physical_memory_usage_kernel_pct(u); 3062 break; 3063 case ZS_USER_ZONES: 3064 v = zs_physical_memory_usage_zones_pct(u); 3065 break; 3066 case ZS_USER_FREE: 3067 v = zs_physical_memory_usage_free_pct(u); 3068 break; 3069 default: 3070 assert(0); 3071 } 3072 break; 3073 case ZS_RESOURCE_RAM_LOCKED: 3074 switch (user) { 3075 case ZS_USER_ALL: 3076 v = zs_locked_memory_usage_all_pct(u); 3077 break; 3078 case ZS_USER_KERNEL: 3079 v = zs_locked_memory_usage_kernel_pct(u); 3080 break; 3081 case ZS_USER_ZONES: 3082 v = zs_locked_memory_usage_zones_pct(u); 3083 break; 3084 case ZS_USER_FREE: 3085 v = zs_locked_memory_usage_free_pct(u); 3086 break; 3087 default: 3088 assert(0); 3089 } 3090 break; 3091 case ZS_RESOURCE_VM: 3092 switch (user) { 3093 case ZS_USER_ALL: 3094 v = zs_virtual_memory_usage_all_pct(u); 3095 break; 3096 case ZS_USER_KERNEL: 3097 v = zs_virtual_memory_usage_kernel_pct(u); 3098 break; 3099 case ZS_USER_ZONES: 3100 v = zs_virtual_memory_usage_zones_pct(u); 3101 break; 3102 case ZS_USER_FREE: 3103 v = zs_virtual_memory_usage_free_pct(u); 3104 break; 3105 default: 3106 assert(0); 3107 } 3108 break; 3109 case ZS_RESOURCE_DISK_SWAP: 3110 switch (user) { 3111 case ZS_USER_ALL: 3112 v = zs_disk_swap_usage_all_pct(u); 3113 break; 3114 case ZS_USER_FREE: 3115 v = zs_disk_swap_usage_free_pct(u); 3116 break; 3117 case ZS_USER_KERNEL: 3118 case ZS_USER_ZONES: 3119 /* FALLTHROUGH */ 3120 default: 3121 assert(0); 3122 } 3123 break; 3124 case ZS_RESOURCE_LWPS: 3125 switch (user) { 3126 case ZS_USER_ALL: 3127 case ZS_USER_ZONES: 3128 v = zs_lwps_usage_all_pct(u); 3129 break; 3130 case ZS_USER_FREE: 3131 v = ZSD_PCT_INT - zs_lwps_usage_all_pct(u); 3132 break; 3133 case ZS_USER_KERNEL: 3134 v = 0; 3135 break; 3136 default: 3137 assert(0); 3138 } 3139 break; 3140 case ZS_RESOURCE_PROCESSES: 3141 switch (user) { 3142 case ZS_USER_ALL: 3143 case ZS_USER_ZONES: 3144 v = zs_processes_usage_all_pct(u); 3145 break; 3146 case ZS_USER_FREE: 3147 v = ZSD_PCT_INT - zs_processes_usage_all_pct(u); 3148 break; 3149 case ZS_USER_KERNEL: 3150 v = 0; 3151 break; 3152 default: 3153 assert(0); 3154 } 3155 break; 3156 case ZS_RESOURCE_SHM_MEMORY: 3157 switch (user) { 3158 case ZS_USER_ALL: 3159 case ZS_USER_ZONES: 3160 v = zs_shm_usage_all_pct(u); 3161 break; 3162 case ZS_USER_FREE: 3163 v = ZSD_PCT_INT - zs_shm_usage_all_pct(u); 3164 break; 3165 case ZS_USER_KERNEL: 3166 v = 0; 3167 break; 3168 default: 3169 assert(0); 3170 } 3171 break; 3172 case ZS_RESOURCE_SHM_IDS: 3173 switch (user) { 3174 case ZS_USER_ALL: 3175 case ZS_USER_ZONES: 3176 v = zs_shmids_usage_all_pct(u); 3177 break; 3178 case ZS_USER_FREE: 3179 v = ZSD_PCT_INT - zs_shmids_usage_all_pct(u); 3180 break; 3181 case ZS_USER_KERNEL: 3182 v = 0; 3183 break; 3184 default: 3185 assert(0); 3186 } 3187 break; 3188 case ZS_RESOURCE_SEM_IDS: 3189 switch (user) { 3190 case ZS_USER_ALL: 3191 case ZS_USER_ZONES: 3192 v = zs_semids_usage_all_pct(u); 3193 break; 3194 case ZS_USER_FREE: 3195 v = ZSD_PCT_INT - zs_semids_usage_all_pct(u); 3196 break; 3197 case ZS_USER_KERNEL: 3198 v = 0; 3199 break; 3200 default: 3201 assert(0); 3202 } 3203 break; 3204 case ZS_RESOURCE_MSG_IDS: 3205 switch (user) { 3206 case ZS_USER_ALL: 3207 case ZS_USER_ZONES: 3208 v = zs_msgids_usage_all_pct(u); 3209 break; 3210 case ZS_USER_FREE: 3211 v = ZSD_PCT_INT - zs_msgids_usage_all_pct(u); 3212 break; 3213 case ZS_USER_KERNEL: 3214 v = 0; 3215 break; 3216 default: 3217 assert(0); 3218 } 3219 break; 3220 case ZS_RESOURCE_LOFI: 3221 switch (user) { 3222 case ZS_USER_ALL: 3223 case ZS_USER_ZONES: 3224 v = zs_lofi_usage_all_pct(u); 3225 break; 3226 case ZS_USER_FREE: 3227 v = ZSD_PCT_INT - zs_lofi_usage_all_pct(u); 3228 break; 3229 case ZS_USER_KERNEL: 3230 v = 0; 3231 break; 3232 default: 3233 assert(0); 3234 } 3235 break; 3236 default: 3237 assert(0); 3238 } 3239 3240 return (v); 3241 } 3242 3243 /* 3244 * Get resource used by individual zone. 3245 */ 3246 uint64_t 3247 zs_resource_used_zone_uint64(zs_zone_t *z, int res) 3248 { 3249 uint64_t v; 3250 3251 switch (res) { 3252 case ZS_RESOURCE_CPU: 3253 v = zs_cpu_usage_zone_cpu(z); 3254 break; 3255 case ZS_RESOURCE_RAM_RSS: 3256 v = zs_physical_memory_usage_zone(z); 3257 break; 3258 case ZS_RESOURCE_RAM_LOCKED: 3259 v = zs_locked_memory_usage_zone(z); 3260 break; 3261 case ZS_RESOURCE_VM: 3262 v = zs_virtual_memory_usage_zone(z); 3263 break; 3264 case ZS_RESOURCE_DISK_SWAP: 3265 assert(0); 3266 break; 3267 case ZS_RESOURCE_LWPS: 3268 v = zs_lwps_usage_zone(z); 3269 break; 3270 case ZS_RESOURCE_PROCESSES: 3271 v = zs_processes_usage_zone(z); 3272 break; 3273 case ZS_RESOURCE_SHM_MEMORY: 3274 v = zs_shm_usage_zone(z); 3275 break; 3276 case ZS_RESOURCE_SHM_IDS: 3277 v = zs_shmids_usage_zone(z); 3278 break; 3279 case ZS_RESOURCE_SEM_IDS: 3280 v = zs_semids_usage_zone(z); 3281 break; 3282 case ZS_RESOURCE_MSG_IDS: 3283 v = zs_msgids_usage_zone(z); 3284 break; 3285 case ZS_RESOURCE_LOFI: 3286 v = zs_lofi_usage_zone(z); 3287 break; 3288 default: 3289 assert(0); 3290 } 3291 return (v); 3292 } 3293 3294 /* 3295 * Get resource used by individual zone as percent 3296 */ 3297 uint_t 3298 zs_resource_used_zone_pct(zs_zone_t *z, int res) 3299 { 3300 uint_t v; 3301 3302 switch (res) { 3303 case ZS_RESOURCE_CPU: 3304 v = zs_cpu_usage_zone_pct(z); 3305 break; 3306 case ZS_RESOURCE_RAM_RSS: 3307 v = zs_physical_memory_usage_zone_pct(z); 3308 break; 3309 case ZS_RESOURCE_RAM_LOCKED: 3310 v = zs_locked_memory_usage_zone_pct(z); 3311 break; 3312 case ZS_RESOURCE_VM: 3313 v = zs_virtual_memory_usage_zone_pct(z); 3314 break; 3315 case ZS_RESOURCE_DISK_SWAP: 3316 assert(0); 3317 break; 3318 case ZS_RESOURCE_LWPS: 3319 v = zs_lwps_usage_zone_pct(z); 3320 break; 3321 case ZS_RESOURCE_PROCESSES: 3322 v = zs_processes_usage_zone_pct(z); 3323 break; 3324 case ZS_RESOURCE_SHM_MEMORY: 3325 v = zs_shm_usage_zone_pct(z); 3326 break; 3327 case ZS_RESOURCE_SHM_IDS: 3328 v = zs_shmids_usage_zone_pct(z); 3329 break; 3330 case ZS_RESOURCE_SEM_IDS: 3331 v = zs_semids_usage_zone_pct(z); 3332 break; 3333 case ZS_RESOURCE_MSG_IDS: 3334 v = zs_msgids_usage_zone_pct(z); 3335 break; 3336 case ZS_RESOURCE_LOFI: 3337 v = zs_lofi_usage_zone_pct(z); 3338 break; 3339 default: 3340 assert(0); 3341 } 3342 return (v); 3343 } 3344 3345 /* 3346 * Get total time available for a resource 3347 */ 3348 void 3349 zs_resource_total_time(zs_usage_t *u, int res, timestruc_t *t) 3350 { 3351 switch (res) { 3352 case ZS_RESOURCE_CPU: 3353 zs_cpu_total_time(u, t); 3354 break; 3355 case ZS_RESOURCE_RAM_RSS: 3356 case ZS_RESOURCE_RAM_LOCKED: 3357 case ZS_RESOURCE_VM: 3358 case ZS_RESOURCE_DISK_SWAP: 3359 case ZS_RESOURCE_LWPS: 3360 case ZS_RESOURCE_PROCESSES: 3361 case ZS_RESOURCE_SHM_MEMORY: 3362 case ZS_RESOURCE_SHM_IDS: 3363 case ZS_RESOURCE_SEM_IDS: 3364 case ZS_RESOURCE_MSG_IDS: 3365 /* FALLTHROUGH */ 3366 default: 3367 assert(0); 3368 } 3369 } 3370 3371 /* 3372 * Get total time used for a resource 3373 */ 3374 void 3375 zs_resource_used_time(zs_usage_t *u, int res, int user, timestruc_t *t) 3376 { 3377 switch (res) { 3378 case ZS_RESOURCE_CPU: 3379 switch (user) { 3380 case ZS_USER_ALL: 3381 zs_cpu_usage_all(u, t); 3382 break; 3383 case ZS_USER_KERNEL: 3384 zs_cpu_usage_kernel(u, t); 3385 break; 3386 case ZS_USER_ZONES: 3387 zs_cpu_usage_zones(u, t); 3388 break; 3389 case ZS_USER_FREE: 3390 zs_cpu_usage_idle(u, t); 3391 break; 3392 default: 3393 assert(0); 3394 } 3395 break; 3396 case ZS_RESOURCE_RAM_RSS: 3397 case ZS_RESOURCE_RAM_LOCKED: 3398 case ZS_RESOURCE_VM: 3399 case ZS_RESOURCE_DISK_SWAP: 3400 case ZS_RESOURCE_LWPS: 3401 case ZS_RESOURCE_PROCESSES: 3402 case ZS_RESOURCE_SHM_MEMORY: 3403 case ZS_RESOURCE_SHM_IDS: 3404 case ZS_RESOURCE_SEM_IDS: 3405 case ZS_RESOURCE_MSG_IDS: 3406 /* FALLTHROUGH */ 3407 default: 3408 assert(0); 3409 } 3410 } 3411 3412 /* 3413 * Get total resource time used for a particular zone 3414 */ 3415 void 3416 zs_resource_used_zone_time(zs_zone_t *z, int res, timestruc_t *t) 3417 { 3418 switch (res) { 3419 case ZS_RESOURCE_CPU: 3420 zs_cpu_usage_zone(z, t); 3421 break; 3422 case ZS_RESOURCE_RAM_RSS: 3423 case ZS_RESOURCE_RAM_LOCKED: 3424 case ZS_RESOURCE_VM: 3425 case ZS_RESOURCE_DISK_SWAP: 3426 case ZS_RESOURCE_SHM_MEMORY: 3427 case ZS_RESOURCE_LWPS: 3428 case ZS_RESOURCE_PROCESSES: 3429 case ZS_RESOURCE_SHM_IDS: 3430 case ZS_RESOURCE_SEM_IDS: 3431 case ZS_RESOURCE_MSG_IDS: 3432 /* FALLTHROUGH */ 3433 default: 3434 assert(0); 3435 } 3436 } 3437 3438 3439 int 3440 zs_zone_list(zs_usage_t *usage, zs_zone_t **zonelist, int num) 3441 { 3442 int i = 0; 3443 zs_zone_t *zone, *tmp; 3444 3445 /* copy what fits of the zone list into the buffer */ 3446 for (zone = list_head(&usage->zsu_zone_list); zone != NULL; 3447 zone = list_next(&usage->zsu_zone_list, zone)) { 3448 3449 /* put the global zone at the first position */ 3450 if (i < num) { 3451 if (zone->zsz_id == GLOBAL_ZONEID) { 3452 tmp = zonelist[0]; 3453 zonelist[i] = tmp; 3454 zonelist[0] = zone; 3455 } else { 3456 zonelist[i] = zone; 3457 } 3458 } 3459 i++; 3460 } 3461 return (i); 3462 } 3463 3464 zs_zone_t * 3465 zs_zone_first(zs_usage_t *usage) 3466 { 3467 return (list_head(&usage->zsu_zone_list)); 3468 } 3469 3470 zs_zone_t * 3471 zs_zone_next(zs_usage_t *usage, zs_zone_t *zone) 3472 { 3473 return (list_next(&usage->zsu_zone_list, zone)); 3474 } 3475 3476 3477 /* 3478 * Gets a zone property 3479 */ 3480 void 3481 zs_zone_property(zs_zone_t *zone, int prop, zs_property_t *p) 3482 { 3483 switch (prop) { 3484 case ZS_ZONE_PROP_NAME: 3485 p->zsp_type = ZS_PROP_TYPE_STRING; 3486 p->zsp_id = prop; 3487 (void) zs_zone_name(zone, p->zsp_v.zsv_string, 3488 sizeof (p->zsp_v.zsv_string)); 3489 break; 3490 case ZS_ZONE_PROP_ID: 3491 p->zsp_type = ZS_PROP_TYPE_INT; 3492 p->zsp_id = prop; 3493 p->zsp_v.zsv_int = zs_zone_id(zone); 3494 break; 3495 case ZS_ZONE_PROP_IPTYPE: 3496 p->zsp_type = ZS_PROP_TYPE_UINT; 3497 p->zsp_id = prop; 3498 p->zsp_v.zsv_uint = zs_zone_iptype(zone); 3499 break; 3500 case ZS_ZONE_PROP_CPUTYPE: 3501 p->zsp_type = ZS_PROP_TYPE_UINT; 3502 p->zsp_id = prop; 3503 p->zsp_v.zsv_uint = zs_zone_cputype(zone); 3504 break; 3505 case ZS_ZONE_PROP_SCHEDULERS: 3506 p->zsp_type = ZS_PROP_TYPE_UINT; 3507 p->zsp_id = prop; 3508 p->zsp_v.zsv_uint = zs_zone_schedulers(zone); 3509 break; 3510 case ZS_ZONE_PROP_CPU_SHARES: 3511 p->zsp_type = ZS_PROP_TYPE_UINT64; 3512 p->zsp_id = prop; 3513 p->zsp_v.zsv_uint64 = zs_zone_cpu_shares(zone); 3514 break; 3515 case ZS_ZONE_PROP_POOLNAME: 3516 p->zsp_type = ZS_PROP_TYPE_STRING; 3517 p->zsp_id = prop; 3518 (void) zs_zone_poolname(zone, p->zsp_v.zsv_string, 3519 sizeof (p->zsp_v.zsv_string)); 3520 break; 3521 case ZS_ZONE_PROP_PSETNAME: 3522 p->zsp_type = ZS_PROP_TYPE_STRING; 3523 p->zsp_id = prop; 3524 (void) zs_zone_psetname(zone, p->zsp_v.zsv_string, 3525 sizeof (p->zsp_v.zsv_string)); 3526 break; 3527 /* Not implemented */ 3528 case ZS_ZONE_PROP_DEFAULT_SCHED: 3529 case ZS_ZONE_PROP_UPTIME: 3530 case ZS_ZONE_PROP_BOOTTIME: 3531 /* FALLTHROUGH */ 3532 default: 3533 assert(0); 3534 } 3535 } 3536 3537 int 3538 zs_zone_limit_type(int limit) 3539 { 3540 switch (limit) { 3541 case ZS_LIMIT_CPU: 3542 case ZS_LIMIT_CPU_SHARES: 3543 return (ZS_LIMIT_TYPE_TIME); 3544 case ZS_LIMIT_RAM_RSS: 3545 case ZS_LIMIT_RAM_LOCKED: 3546 case ZS_LIMIT_VM: 3547 case ZS_LIMIT_SHM_MEMORY: 3548 return (ZS_LIMIT_TYPE_BYTES); 3549 case ZS_LIMIT_LWPS: 3550 case ZS_LIMIT_PROCESSES: 3551 case ZS_LIMIT_SHM_IDS: 3552 case ZS_LIMIT_MSG_IDS: 3553 case ZS_LIMIT_SEM_IDS: 3554 return (ZS_LIMIT_TYPE_COUNT); 3555 default: 3556 assert(0); 3557 return (0); 3558 } 3559 } 3560 /* 3561 * Gets the zones limit. Returns ZS_LIMIT_NONE if no limit set. 3562 */ 3563 uint64_t 3564 zs_zone_limit_uint64(zs_zone_t *z, int limit) 3565 { 3566 uint64_t v; 3567 3568 switch (limit) { 3569 case ZS_LIMIT_CPU: 3570 v = zs_zone_cpu_cap(z); 3571 break; 3572 case ZS_LIMIT_CPU_SHARES: 3573 v = zs_zone_cpu_shares(z); 3574 break; 3575 case ZS_LIMIT_RAM_RSS: 3576 v = zs_zone_physical_memory_cap(z); 3577 break; 3578 case ZS_LIMIT_RAM_LOCKED: 3579 v = zs_zone_locked_memory_cap(z); 3580 break; 3581 case ZS_LIMIT_VM: 3582 v = zs_zone_virtual_memory_cap(z); 3583 break; 3584 case ZS_LIMIT_LWPS: 3585 v = z->zsz_lwps_cap; 3586 break; 3587 case ZS_LIMIT_PROCESSES: 3588 v = z->zsz_processes_cap; 3589 break; 3590 case ZS_LIMIT_SHM_MEMORY: 3591 v = z->zsz_shm_cap; 3592 break; 3593 case ZS_LIMIT_SHM_IDS: 3594 v = z->zsz_shmids_cap; 3595 break; 3596 case ZS_LIMIT_SEM_IDS: 3597 v = z->zsz_semids_cap; 3598 break; 3599 case ZS_LIMIT_MSG_IDS: 3600 v = z->zsz_msgids_cap; 3601 break; 3602 case ZS_LIMIT_LOFI: 3603 v = z->zsz_lofi_cap; 3604 break; 3605 default: 3606 assert(0); 3607 } 3608 return (v); 3609 } 3610 3611 /* 3612 * Gets the amount of resource used for a limit. Returns ZS_LIMIT_NONE if 3613 * no limit configured. 3614 */ 3615 uint64_t 3616 zs_zone_limit_used_uint64(zs_zone_t *z, int limit) 3617 { 3618 uint64_t v; 3619 3620 switch (limit) { 3621 case ZS_LIMIT_CPU: 3622 v = zs_zone_cpu_cap_used(z); 3623 break; 3624 case ZS_LIMIT_CPU_SHARES: 3625 v = zs_zone_cpu_shares_used(z); 3626 break; 3627 case ZS_LIMIT_RAM_RSS: 3628 v = zs_zone_physical_memory_cap_used(z); 3629 break; 3630 case ZS_LIMIT_RAM_LOCKED: 3631 v = zs_zone_locked_memory_cap_used(z); 3632 break; 3633 case ZS_LIMIT_VM: 3634 v = zs_zone_virtual_memory_cap_used(z); 3635 break; 3636 case ZS_LIMIT_LWPS: 3637 v = z->zsz_lwps; 3638 break; 3639 case ZS_LIMIT_PROCESSES: 3640 v = z->zsz_processes; 3641 break; 3642 case ZS_LIMIT_SHM_MEMORY: 3643 v = z->zsz_shm; 3644 break; 3645 case ZS_LIMIT_SHM_IDS: 3646 v = z->zsz_shmids; 3647 break; 3648 case ZS_LIMIT_SEM_IDS: 3649 v = z->zsz_semids; 3650 break; 3651 case ZS_LIMIT_MSG_IDS: 3652 v = z->zsz_msgids; 3653 break; 3654 case ZS_LIMIT_LOFI: 3655 v = z->zsz_lofi; 3656 break; 3657 default: 3658 assert(0); 3659 } 3660 return (v); 3661 } 3662 3663 /* 3664 * Gets time used under limit. Time is zero if no limit is configured 3665 */ 3666 void 3667 zs_zone_limit_time(zs_zone_t *z, int limit, timestruc_t *v) 3668 { 3669 switch (limit) { 3670 case ZS_LIMIT_CPU: 3671 if (z->zsz_cpu_cap == ZS_LIMIT_NONE) { 3672 v->tv_sec = 0; 3673 v->tv_nsec = 0; 3674 break; 3675 } 3676 zs_zone_cpu_cap_time(z, v); 3677 break; 3678 case ZS_LIMIT_CPU_SHARES: 3679 if (z->zsz_cpu_shares == ZS_LIMIT_NONE || 3680 z->zsz_cpu_shares == ZS_SHARES_UNLIMITED || 3681 z->zsz_cpu_shares == 0 || 3682 (z->zsz_scheds & ZS_SCHED_FSS) == 0) { 3683 v->tv_sec = 0; 3684 v->tv_nsec = 0; 3685 break; 3686 } 3687 zs_zone_cpu_share_time(z, v); 3688 break; 3689 case ZS_LIMIT_RAM_RSS: 3690 case ZS_LIMIT_RAM_LOCKED: 3691 case ZS_LIMIT_VM: 3692 case ZS_LIMIT_SHM_MEMORY: 3693 case ZS_LIMIT_LWPS: 3694 case ZS_LIMIT_PROCESSES: 3695 case ZS_LIMIT_SHM_IDS: 3696 case ZS_LIMIT_MSG_IDS: 3697 case ZS_LIMIT_SEM_IDS: 3698 /* FALLTHROUGH */ 3699 default: 3700 assert(0); 3701 } 3702 } 3703 3704 /* 3705 * Errno is set on error: 3706 * 3707 * EINVAL: No such property 3708 * ENOENT: No time value for the specified limit. 3709 * ESRCH: No limit is configured. 3710 * 3711 * If no limit is configured, the value will be ZS_PCT_NONE 3712 */ 3713 void 3714 zs_zone_limit_used_time(zs_zone_t *z, int limit, timestruc_t *t) 3715 { 3716 switch (limit) { 3717 case ZS_LIMIT_CPU: 3718 if (z->zsz_cpu_cap == ZS_LIMIT_NONE) { 3719 t->tv_sec = 0; 3720 t->tv_nsec = 0; 3721 break; 3722 } 3723 zs_zone_cpu_cap_time_used(z, t); 3724 break; 3725 case ZS_LIMIT_CPU_SHARES: 3726 if (z->zsz_cpu_shares == ZS_LIMIT_NONE || 3727 z->zsz_cpu_shares == ZS_SHARES_UNLIMITED || 3728 z->zsz_cpu_shares == 0 || 3729 (z->zsz_scheds & ZS_SCHED_FSS) == 0) { 3730 t->tv_sec = 0; 3731 t->tv_nsec = 0; 3732 break; 3733 } 3734 zs_zone_cpu_share_time_used(z, t); 3735 break; 3736 case ZS_LIMIT_RAM_RSS: 3737 case ZS_LIMIT_RAM_LOCKED: 3738 case ZS_LIMIT_VM: 3739 case ZS_LIMIT_SHM_MEMORY: 3740 case ZS_LIMIT_LWPS: 3741 case ZS_LIMIT_PROCESSES: 3742 case ZS_LIMIT_SHM_IDS: 3743 case ZS_LIMIT_MSG_IDS: 3744 case ZS_LIMIT_SEM_IDS: 3745 /* FALLTHROUGH */ 3746 default: 3747 assert(0); 3748 } 3749 } 3750 3751 /* 3752 * Get a zones usage as a percent of the limit. Return ZS_PCT_NONE if 3753 * no limit is configured. 3754 */ 3755 uint_t 3756 zs_zone_limit_used_pct(zs_zone_t *z, int limit) 3757 { 3758 uint_t v; 3759 3760 switch (limit) { 3761 case ZS_LIMIT_CPU: 3762 v = zs_zone_cpu_cap_pct(z); 3763 break; 3764 case ZS_LIMIT_CPU_SHARES: 3765 v = zs_zone_cpu_shares_pct(z); 3766 break; 3767 case ZS_LIMIT_RAM_RSS: 3768 v = zs_zone_physical_memory_cap_pct(z); 3769 break; 3770 case ZS_LIMIT_RAM_LOCKED: 3771 v = zs_zone_locked_memory_cap_pct(z); 3772 break; 3773 case ZS_LIMIT_VM: 3774 v = zs_zone_virtual_memory_cap_pct(z); 3775 break; 3776 case ZS_LIMIT_LWPS: 3777 v = zs_lwps_zone_cap_pct(z); 3778 break; 3779 case ZS_LIMIT_PROCESSES: 3780 v = zs_processes_zone_cap_pct(z); 3781 break; 3782 case ZS_LIMIT_SHM_MEMORY: 3783 v = zs_shm_zone_cap_pct(z); 3784 break; 3785 case ZS_LIMIT_SHM_IDS: 3786 v = zs_shmids_zone_cap_pct(z); 3787 break; 3788 case ZS_LIMIT_SEM_IDS: 3789 v = zs_semids_zone_cap_pct(z); 3790 break; 3791 case ZS_LIMIT_MSG_IDS: 3792 v = zs_msgids_zone_cap_pct(z); 3793 break; 3794 case ZS_LIMIT_LOFI: 3795 v = zs_lofi_zone_cap_pct(z); 3796 break; 3797 default: 3798 assert(0); 3799 } 3800 return (v); 3801 } 3802 3803 int 3804 zs_pset_list(zs_usage_t *usage, zs_pset_t **psetlist, int num) 3805 { 3806 int i = 0; 3807 zs_pset_t *pset, *tmp; 3808 3809 /* copy what fits of the pset list into the buffer */ 3810 for (pset = list_head(&usage->zsu_pset_list); pset != NULL; 3811 pset = list_next(&usage->zsu_pset_list, pset)) { 3812 3813 /* put the default pset at the first position */ 3814 if (i < num) { 3815 if (pset->zsp_id == ZS_PSET_DEFAULT) { 3816 tmp = psetlist[0]; 3817 psetlist[i] = tmp; 3818 psetlist[0] = pset; 3819 } else { 3820 psetlist[i] = pset; 3821 } 3822 } 3823 i++; 3824 } 3825 return (i); 3826 } 3827 3828 zs_pset_t * 3829 zs_pset_first(zs_usage_t *usage) 3830 { 3831 return (list_head(&usage->zsu_pset_list)); 3832 } 3833 3834 zs_pset_t * 3835 zs_pset_next(zs_usage_t *usage, zs_pset_t *pset) 3836 { 3837 return (list_next(&usage->zsu_pset_list, pset)); 3838 } 3839 3840 /* 3841 * Get various properties on a pset. 3842 */ 3843 void 3844 zs_pset_property(zs_pset_t *pset, int prop, zs_property_t *p) 3845 { 3846 switch (prop) { 3847 3848 case ZS_PSET_PROP_NAME: 3849 p->zsp_type = ZS_PROP_TYPE_STRING; 3850 p->zsp_id = prop; 3851 (void) zs_pset_name(pset, p->zsp_v.zsv_string, 3852 sizeof (p->zsp_v.zsv_string)); 3853 break; 3854 case ZS_PSET_PROP_ID: 3855 p->zsp_type = ZS_PROP_TYPE_INT; 3856 p->zsp_id = prop; 3857 p->zsp_v.zsv_int = zs_pset_id(pset); 3858 break; 3859 case ZS_PSET_PROP_CPUTYPE: 3860 p->zsp_type = ZS_PROP_TYPE_UINT; 3861 p->zsp_id = prop; 3862 p->zsp_v.zsv_uint = zs_pset_cputype(pset); 3863 break; 3864 case ZS_PSET_PROP_SIZE: 3865 p->zsp_type = ZS_PROP_TYPE_UINT64; 3866 p->zsp_id = prop; 3867 p->zsp_v.zsv_uint64 = zs_pset_size(pset); 3868 break; 3869 case ZS_PSET_PROP_ONLINE: 3870 p->zsp_type = ZS_PROP_TYPE_UINT64; 3871 p->zsp_id = prop; 3872 p->zsp_v.zsv_uint64 = zs_pset_online(pset); 3873 break; 3874 case ZS_PSET_PROP_MIN: 3875 p->zsp_type = ZS_PROP_TYPE_UINT64; 3876 p->zsp_id = prop; 3877 p->zsp_v.zsv_uint64 = zs_pset_min(pset); 3878 break; 3879 case ZS_PSET_PROP_MAX: 3880 p->zsp_type = ZS_PROP_TYPE_UINT64; 3881 p->zsp_id = prop; 3882 p->zsp_v.zsv_uint64 = zs_pset_max(pset); 3883 break; 3884 case ZS_PSET_PROP_CPU_SHARES: 3885 p->zsp_type = ZS_PROP_TYPE_UINT64; 3886 p->zsp_id = prop; 3887 p->zsp_v.zsv_uint64 = zs_pset_cpu_shares(pset); 3888 break; 3889 case ZS_PSET_PROP_SCHEDULERS: 3890 p->zsp_type = ZS_PROP_TYPE_UINT; 3891 p->zsp_id = prop; 3892 p->zsp_v.zsv_uint = zs_pset_schedulers(pset); 3893 break; 3894 /* Not implemented */ 3895 case ZS_PSET_PROP_CREATETIME: 3896 case ZS_PSET_PROP_LOAD_1MIN: 3897 case ZS_PSET_PROP_LOAD_5MIN: 3898 case ZS_PSET_PROP_LOAD_15MIN: 3899 /* FALLTHROUGH */ 3900 default: 3901 assert(0); 3902 } 3903 } 3904 3905 void 3906 zs_pset_total_time(zs_pset_t *pset, timestruc_t *t) 3907 { 3908 *t = pset->zsp_total_time; 3909 } 3910 3911 uint64_t 3912 zs_pset_total_cpus(zs_pset_t *pset) 3913 { 3914 return (pset->zsp_online * ZSD_ONE_CPU); 3915 } 3916 3917 /* 3918 * Get total time used for pset 3919 */ 3920 void 3921 zs_pset_used_time(zs_pset_t *pset, int user, timestruc_t *t) 3922 { 3923 switch (user) { 3924 case ZS_USER_ALL: 3925 zs_pset_usage_all(pset, t); 3926 break; 3927 case ZS_USER_KERNEL: 3928 zs_pset_usage_kernel(pset, t); 3929 break; 3930 case ZS_USER_ZONES: 3931 zs_pset_usage_zones(pset, t); 3932 break; 3933 case ZS_USER_FREE: 3934 zs_pset_usage_idle(pset, t); 3935 break; 3936 default: 3937 assert(0); 3938 } 3939 } 3940 3941 /* 3942 * Returns 0 on success. -1 on failure. 3943 * 3944 * ERRORS 3945 * EINVAL: Invalid user. 3946 * 3947 */ 3948 uint64_t 3949 zs_pset_used_cpus(zs_pset_t *pset, int user) 3950 { 3951 uint_t v; 3952 3953 switch (user) { 3954 case ZS_USER_ALL: 3955 v = zs_pset_usage_all_cpus(pset); 3956 break; 3957 case ZS_USER_KERNEL: 3958 v = zs_pset_usage_kernel_cpus(pset); 3959 break; 3960 case ZS_USER_ZONES: 3961 v = zs_pset_usage_zones_cpus(pset); 3962 break; 3963 case ZS_USER_FREE: 3964 v = zs_pset_usage_idle_cpus(pset); 3965 break; 3966 default: 3967 assert(0); 3968 } 3969 return (v); 3970 } 3971 /* 3972 * Get percent of pset cpu time used 3973 */ 3974 uint_t 3975 zs_pset_used_pct(zs_pset_t *pset, int user) 3976 { 3977 uint_t v; 3978 3979 switch (user) { 3980 case ZS_USER_ALL: 3981 v = zs_pset_usage_all_pct(pset); 3982 break; 3983 case ZS_USER_KERNEL: 3984 v = zs_pset_usage_kernel_pct(pset); 3985 break; 3986 case ZS_USER_ZONES: 3987 v = zs_pset_usage_zones_pct(pset); 3988 break; 3989 case ZS_USER_FREE: 3990 v = zs_pset_usage_idle_pct(pset); 3991 break; 3992 default: 3993 assert(0); 3994 } 3995 return (v); 3996 } 3997 3998 int 3999 zs_pset_zone_list(zs_pset_t *pset, zs_pset_zone_t **zonelist, int num) 4000 { 4001 int i = 0; 4002 zs_pset_zone_t *zone, *tmp; 4003 4004 /* copy what fits of the pset's zone list into the buffer */ 4005 for (zone = list_head(&pset->zsp_usage_list); zone != NULL; 4006 zone = list_next(&pset->zsp_usage_list, zone)) { 4007 4008 /* put the global zone at the first position */ 4009 if (i < num) { 4010 if (zone->zspz_zone->zsz_id == GLOBAL_ZONEID) { 4011 tmp = zonelist[0]; 4012 zonelist[i] = tmp; 4013 zonelist[0] = zone; 4014 } else { 4015 zonelist[i] = zone; 4016 } 4017 } 4018 i++; 4019 } 4020 return (i); 4021 } 4022 4023 zs_pset_zone_t * 4024 zs_pset_zone_first(zs_pset_t *pset) 4025 { 4026 return (list_head(&pset->zsp_usage_list)); 4027 } 4028 4029 zs_pset_zone_t * 4030 zs_pset_zone_next(zs_pset_t *pset, zs_pset_zone_t *pz) 4031 { 4032 return (list_next(&pset->zsp_usage_list, pz)); 4033 } 4034 4035 zs_pset_t * 4036 zs_pset_zone_get_pset(zs_pset_zone_t *pz) 4037 { 4038 return (pz->zspz_pset); 4039 } 4040 4041 zs_zone_t * 4042 zs_pset_zone_get_zone(zs_pset_zone_t *pz) 4043 { 4044 return (pz->zspz_zone); 4045 } 4046 4047 /* 4048 * Get a property describing a zone's usage of a pset 4049 */ 4050 void 4051 zs_pset_zone_property(zs_pset_zone_t *pz, int prop, zs_property_t *p) 4052 { 4053 switch (prop) { 4054 4055 case ZS_PZ_PROP_CPU_CAP: 4056 p->zsp_type = ZS_PROP_TYPE_UINT64; 4057 p->zsp_id = prop; 4058 p->zsp_v.zsv_uint64 = (int)zs_pset_zone_cpu_cap(pz); 4059 break; 4060 case ZS_PZ_PROP_CPU_SHARES: 4061 p->zsp_type = ZS_PROP_TYPE_UINT64; 4062 p->zsp_id = prop; 4063 p->zsp_v.zsv_uint64 = (int)zs_pset_zone_cpu_shares(pz); 4064 break; 4065 case ZS_PZ_PROP_SCHEDULERS: 4066 p->zsp_type = ZS_PROP_TYPE_UINT; 4067 p->zsp_id = prop; 4068 p->zsp_v.zsv_uint = (int)zs_pset_zone_schedulers(pz); 4069 break; 4070 default: 4071 assert(0); 4072 } 4073 } 4074 4075 void 4076 zs_pset_zone_used_time(zs_pset_zone_t *pz, timestruc_t *t) 4077 { 4078 zs_pset_zone_usage_time(pz, t); 4079 } 4080 4081 uint64_t 4082 zs_pset_zone_used_cpus(zs_pset_zone_t *pz) 4083 { 4084 return (zs_pset_zone_usage_cpus(pz)); 4085 } 4086 4087 /* 4088 * Get percent of a psets cpus used by a zone 4089 */ 4090 uint_t 4091 zs_pset_zone_used_pct(zs_pset_zone_t *pz, int type) 4092 { 4093 uint_t v; 4094 4095 switch (type) { 4096 case ZS_PZ_PCT_PSET: 4097 v = zs_pset_zone_usage_pct_pset(pz); 4098 break; 4099 case ZS_PZ_PCT_CPU_CAP: 4100 v = zs_pset_zone_usage_pct_cpu_cap(pz); 4101 break; 4102 case ZS_PZ_PCT_PSET_SHARES: 4103 v = zs_pset_zone_usage_pct_pset_shares(pz); 4104 break; 4105 case ZS_PZ_PCT_CPU_SHARES: 4106 v = zs_pset_zone_usage_pct_cpu_shares(pz); 4107 break; 4108 default: 4109 assert(0); 4110 } 4111 return (v); 4112 } 4113 4114 /* 4115 * returns similar to malloc 4116 */ 4117 zs_property_t * 4118 zs_property_alloc() 4119 { 4120 return ((zs_property_t *)malloc(sizeof (zs_property_t))); 4121 } 4122 4123 size_t 4124 zs_property_size() 4125 { 4126 return (sizeof (zs_property_t)); 4127 } 4128 4129 void 4130 zs_property_free(zs_property_t *p) 4131 { 4132 free(p); 4133 } 4134 4135 int 4136 zs_property_type(zs_property_t *p) 4137 { 4138 return (p->zsp_type); 4139 } 4140 4141 int 4142 zs_property_id(zs_property_t *p) 4143 { 4144 return (p->zsp_id); 4145 } 4146 4147 char * 4148 zs_property_string(zs_property_t *p) 4149 { 4150 assert(p->zsp_type == ZS_PROP_TYPE_STRING); 4151 return (p->zsp_v.zsv_string); 4152 } 4153 4154 double 4155 zs_property_double(zs_property_t *p) 4156 { 4157 assert(p->zsp_type == ZS_PROP_TYPE_DOUBLE); 4158 return (p->zsp_v.zsv_double); 4159 } 4160 4161 void 4162 zs_property_time(zs_property_t *p, timestruc_t *t) 4163 { 4164 assert(p->zsp_type == ZS_PROP_TYPE_TIME); 4165 *t = p->zsp_v.zsv_ts; 4166 } 4167 4168 uint64_t 4169 zs_property_uint64(zs_property_t *p) 4170 { 4171 assert(p->zsp_type == ZS_PROP_TYPE_UINT64); 4172 return (p->zsp_v.zsv_uint64); 4173 } 4174 4175 int64_t 4176 zs_property_int64(zs_property_t *p) 4177 { 4178 assert(p->zsp_type == ZS_PROP_TYPE_INT64); 4179 return (p->zsp_v.zsv_int64); 4180 } 4181 4182 uint_t 4183 zs_property_uint(zs_property_t *p) 4184 { 4185 assert(p->zsp_type == ZS_PROP_TYPE_UINT); 4186 return (p->zsp_v.zsv_uint); 4187 } 4188 4189 int 4190 zs_property_int(zs_property_t *p) 4191 { 4192 assert(p->zsp_type == ZS_PROP_TYPE_INT); 4193 return (p->zsp_v.zsv_uint); 4194 } 4195