efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * CDDL HEADER START
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * The contents of this file are subject to the terms of the
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Common Development and Distribution License (the "License").
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * You may not use this file except in compliance with the License.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * or http://www.opensolaris.org/os/licensing.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * See the License for the specific language governing permissions
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * and limitations under the License.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * When distributing Covered Code, include this CDDL HEADER in each
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * If applicable, add the following below this CDDL HEADER, with the
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * fields enclosed by brackets "[]" replaced with your own identifying
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * information: Portions Copyright [yyyy] [name of copyright owner]
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * CDDL HEADER END
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence#define MAX_PSET_NAME 1024 /* Taken from PV_NAME_MAX_LEN */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence#define ZONESTAT_EXACCT_FILE "/var/adm/exacct/zonestat-process"
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * zonestatd implements gathering cpu and memory utilization data for
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * running zones. It has these components:
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * zsd_server:
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Door server to respond to client connections. Each client
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * will connect using libzonestat.so, which will open and
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * call /var/tmp/.zonestat_door. Each connecting client is given
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * a file descriptor to the stat server.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * The zsd_server also responds to zoneadmd, which reports when a
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * new zone is booted. This is used to fattach the zsd_server door
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * into the new zone.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * zsd_stat_server:
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Receives client requests for the current utilization data. Each
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * client request will cause zonestatd to update the current utilization
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * data by kicking the stat_thread.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * If the client is in a non-global zone, the utilization data will
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * be filtered to only show the given zone. The usage by all other zones
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * will be added to the system utilization.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * stat_thread:
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * The stat thread implements querying the system to determine the
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * current utilization data for each running zone. This includes
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * inspecting the system's processor set configuration, as well as details
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * of each zone, such as their configured limits, and which processor
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * sets they are running in.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * The stat_thread will only update memory utilization data as often as
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * the configured config/sample_interval on the zones-monitoring service.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * The private vmusage structure unfortunately uses size_t types, and assumes
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * the caller's bitness matches the kernel's bitness. Since the getvmusage()
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * system call is contracted, and zonestatd is 32 bit, the following structures
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * are used to interact with a 32bit or 64 bit kernel.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * An amd64 kernel will align the following uint64_t members, but a
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * 32bit i386 process will not without help.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Used to store a zone's usage of a pset */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence boolean_t zsu_found; /* zone bound at end of interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence boolean_t zsu_active; /* zone was bound during interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence boolean_t zsu_new; /* zone newly bound in this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence boolean_t zsu_deleted; /* zone was unbound in this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence boolean_t zsu_empty; /* no procs in pset in this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence time_t zsu_start; /* time when zone was found in pset */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence hrtime_t zsu_hrstart; /* time when zone was found in pset */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint_t zsu_scheds; /* schedulers found in this pass */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence timestruc_t zsu_cpu_usage; /* cpu time used */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Used to store a pset's utilization */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint_t zsp_cputype; /* default, dedicated or shared */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence boolean_t zsp_found; /* pset found at end of interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence boolean_t zsp_new; /* pset new in this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence boolean_t zsp_deleted; /* pset deleted in this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence boolean_t zsp_active; /* pset existed during interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence boolean_t zsp_empty; /* no processes in pset */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint64_t zsp_online; /* online cpus in interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint64_t zsp_size; /* size in this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint64_t zsp_min; /* configured min in this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint64_t zsp_max; /* configured max in this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence int64_t zsp_importance; /* configured max in this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint_t zsp_scheds; /* scheds of processes found in pset */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint64_t zsp_cpu_shares; /* total shares in this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Individual zone usages of pset */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Summed kstat values from individual cpus in pset */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Used to track an individual cpu's utilization as reported by kstats */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence boolean_t zsc_found; /* cpu online in this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence boolean_t zsc_onlined; /* cpu onlined during this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence boolean_t zsc_offlined; /* cpu offlined during this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence boolean_t zsc_active; /* cpu online during this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence boolean_t zsc_allocated; /* True if cpu has ever been found */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* kstats this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* kstats in most recent interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Total kstat increases since zonestatd started reading kstats */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Used to describe an individual zone and its utilization */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* These are deduced by inspecting processes */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence boolean_t zsz_new; /* zone booted during this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence boolean_t zsz_deleted; /* halted during this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence boolean_t zsz_active; /* running in this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence boolean_t zsz_empty; /* no processes in this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence boolean_t zsz_gone; /* not installed in this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence boolean_t zsz_found; /* Running at end of this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence timestruc_t zsz_cpu_usage; /* cpu time of cpu cap */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence timestruc_t zsz_cap_time; /* cpu time of cpu cap */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence timestruc_t zsz_share_time; /* cpu time of share of cpu */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence timestruc_t zsz_pset_time; /* time of all psets zone is bound to */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Used to track the cpu usage of an individual processes.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * zonestatd sweeps /proc each interval and charges the cpu usage of processes.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * to their zone. As processes exit, their extended accounting records are
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * read and the difference of their total and known usage is charged to their
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * If a process is never seen in /proc, the total usage on its extended
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * accounting record will be charged to its zone.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Used to track the overall resource usage of the system */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * A dumping ground for various information and structures used to compute
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * utilization.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * This structure is used to track the system while clients are connected.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * When The first client connects, a zsd_ctl is allocated and configured by
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * zsd_open(). When all clients disconnect, the zsd_ctl is closed.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* To track extended accounting */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence int zsctl_proc_fd; /* Log currently being used */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence int zsctl_proc_fd_next; /* Log file to use next */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* pool configuration handle */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* The above usage tacking structures */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Various system info */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Used to track time available under a cpu cap. */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Caches for arrays allocated for use by various system calls */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Info about procfs for scanning /proc */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Counts on tracked entities */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrenceint g_hasclient; /* True if any clients are connected */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * The usage cache is updated by the stat_thread, and copied to clients by
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * the zsd_stat_server. Mutex and cond are to synchronize between the
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * stat_thread and the stat_server.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* fds of door servers */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Starting and current time. Used to throttle memory calculation, and to
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * mark new zones and psets with their boot and creation time.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * main() thread.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* PRINTFLIKE1 */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) fprintf(stderr, gettext("zonestat: Warning: "));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* PRINTFLIKE1 */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) fprintf(stderr, gettext("zonestat: Error: "));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Turns on extended accounting if not configured externally */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Start a new accounting file if accounting not configured
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * externally.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (acctctl(AC_PROC | AC_RES_SET, res, sizeof (res)) != 0) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to set accounting resources"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Only set accounting file if none is configured */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ret = acctctl(AC_PROC | AC_FILE_GET, oldfile, sizeof (oldfile));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (acctctl(AC_PROC | AC_FILE_SET, path, strlen(path) + 1)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to set accounting file"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (acctctl(AC_PROC | AC_STATE_SET, &state, sizeof (state)) == -1) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to enable accounting"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Turns off extended accounting if not configured externally */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* If accounting file is externally configured, leave it alone */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ret = acctctl(AC_PROC | AC_FILE_GET, oldfile, sizeof (oldfile));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (acctctl(AC_PROC | AC_RES_SET, res, sizeof (res)) != 0) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to clear accounting resources"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (acctctl(AC_PROC | AC_FILE_SET, NULL, 0) == -1) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to clear accounting file"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (acctctl(AC_PROC | AC_STATE_SET, &state, sizeof (state)) == -1) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to diable accounting"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * If not configured externally, deletes the current extended accounting file
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * and starts a new one.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Since the stat_thread holds an open handle to the accounting file, it will
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * read all remaining entries from the old file before switching to
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * read the new one.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* If accounting file is externally configured, leave it alone */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ret = acctctl(AC_PROC | AC_FILE_GET, oldfile, sizeof (oldfile));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Roll it next time */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (acctctl(AC_PROC | AC_FILE_SET, path, strlen(path) + 1) == -1) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to set accounting file"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Contract stuff for zone_enter() */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence fd = open64(CTFS_ROOT "/process/template", O_RDWR);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * For now, zoneadmd doesn't do anything with the contract.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Deliver no events, don't inherit, and allow it to be orphaned.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence err |= ct_pr_tmpl_set_fatal(fd, CT_PR_EV_HWERR);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence err |= ct_pr_tmpl_set_param(fd, CT_PR_PGRPONLY | CT_PR_REGENT);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Contract stuff for zone_enter()
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if ((cfd = open64(CTFS_ROOT "/process/latest", O_RDONLY)) == -1)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if ((r = ct_status_read(cfd, CTD_COMMON, &st)) != 0) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if ((flags != -1) && (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) != -1))
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencecontract_open(ctid_t ctid, const char *type, const char *file, int oflag)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence n = snprintf(path, PATH_MAX, CTFS_ROOT "/%s/%ld/%s", type, ctid, file);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (n >= sizeof (path)) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence fd = contract_open(ctid, "all", "ctl", O_WRONLY);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Attach the zsd_server to a zone. Called for each zone when zonestatd
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * starts, and for each newly booted zone when zoneadmd contacts the zsd_server
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Zone_enter is used to avoid reaching into zone to fattach door.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_fattach_zone(zoneid_t zid, int door, boolean_t detach_only)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence "Unable to fork to add zonestat to zoneid %d\n"), zid);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (WIFEXITED(stat) && WEXITSTATUS(stat) == 0)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to attach door to zoneid: %d"), zid);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to create door file: %s"), path);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to fattach file: %s"), path);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Internal error entering zone: %d"), zid);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Zone lookup and allocation functions to manage list of currently running
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_lookup_zone(zsd_ctl_t *ctl, char *zonename, zoneid_t zoneid)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (zone = list_head(&ctl->zsctl_zones); zone != NULL;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_lookup_zone_byid(zsd_ctl_t *ctl, zoneid_t zoneid)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (zone = list_head(&ctl->zsctl_zones); zone != NULL;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_allocate_zone(zsd_ctl_t *ctl, char *zonename, zoneid_t zoneid)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if ((zone = (zsd_zone_t *)calloc(1, sizeof (zsd_zone_t))) == NULL)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) strlcpy(zone->zsz_name, zonename, sizeof (zone->zsz_name));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Allocate as deleted so if not found in first pass, zone is deleted
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * from list. This can happen if zone is returned by zone_list, but
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * exits before first attempt to fetch zone details.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_lookup_insert_zone(zsd_ctl_t *ctl, char *zonename, zoneid_t zoneid)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if ((zone = zsd_lookup_zone(ctl, zonename, zoneid)) != NULL)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if ((zone = zsd_allocate_zone(ctl, zonename, zoneid)) == NULL)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Insert sorted by zonename */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence while (tmp != NULL && strcmp(zonename, tmp->zsz_name) > 0)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence list_insert_before(&ctl->zsctl_zones, tmp, zone);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Mark all zones as not existing. As zones are found, they will
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * be marked as existing. If a zone is not found, then it must have
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (zone = list_head(&ctl->zsctl_zones); zone != NULL;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Mark each zone as not using pset. If processes are found using the
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * pset, the zone will remain bound to the pset. If none of a zones
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * processes are bound to the pset, the zone's usage of the pset will
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * be deleted.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (usage = list_head(&pset->zsp_usage_list);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence usage = list_next(&pset->zsp_usage_list, usage)) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Mark each pset as not existing. If a pset is found, it will be marked
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * as existing. If a pset is not found, it wil be deleted.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (pset = list_head(&ctl->zsctl_psets); pset != NULL;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * A pset was found. Update its information
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_mark_pset_found(zsd_pset_t *pset, uint_t type, uint64_t online,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint64_t size, uint64_t min, uint64_t max, int64_t importance)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* update pset flags */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* pset not seen on previous interval. It is new. */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * A zone's process was found using a pset. Charge the process to the pset and
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * the per-zone data for the pset.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_mark_pset_usage_found(zsd_pset_usage_t *usage, uint_t sched)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Nothing to do if already found */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* update usage flags */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Detect zone's pset id, and if it is bound to multiple psets */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Record if FSS is co-habitating with conflicting scheduler */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Add cpu time for a process to a pset, zone, and system totals */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_add_usage(zsd_ctl_t *ctl, zsd_pset_usage_t *usage, timestruc_t *delta)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence TIMESTRUC_ADD_TIMESTRUC(usage->zsu_cpu_usage, *delta);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence TIMESTRUC_ADD_TIMESTRUC(pset->zsp_usage_zones, *delta);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence TIMESTRUC_ADD_TIMESTRUC(zone->zsz_cpu_usage, *delta);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence TIMESTRUC_ADD_TIMESTRUC(system->zss_cpu_usage_zones, *delta);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Determine which processor sets have been deleted */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Mark pset as not exists, and deleted if it existed
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * previous interval.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Pset vanished during this interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Determine which zones are no longer bound to processor sets */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Mark pset as not exists, and deleted if it existed previous
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (pset = list_head(&ctl->zsctl_psets); pset != NULL;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Mark pset as not exists, and deleted if it existed
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * previous interval.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Add cpu shares for usages that are in FSS */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zone->zsz_cpu_shares != ZS_SHARES_UNLIMITED &&
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence usage->zsu_cpu_shares = zone->zsz_cpu_shares;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pset->zsp_cpu_shares += zone->zsz_cpu_shares;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* A zone has been found. Update its information */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_mark_zone_found(zsd_ctl_t *ctl, zsd_zone_t *zone, uint64_t cpu_shares,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint64_t cpu_cap, uint64_t ram_cap, uint64_t locked_cap,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint64_t vm_cap, uint64_t processes_cap, uint64_t processes,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint64_t lwps_cap, uint64_t lwps, uint64_t shm_cap, uint64_t shm,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint64_t shmids_cap, uint64_t shmids, uint64_t semids_cap,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint64_t semids, uint64_t msgids_cap, uint64_t msgids, uint64_t lofi_cap,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint64_t lofi, char *poolname, char *psetname, uint_t sched, uint_t cputype,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Mark zone as exists, and new if it did not exist in previous
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Zone is new. Assume zone's properties are the same over entire
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) strlcpy(zone->zsz_pool, poolname, sizeof (zone->zsz_pool));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) strlcpy(zone->zsz_pset, psetname, sizeof (zone->zsz_pset));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Schedulers updated later as processes are found */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Cpus updated later as psets bound are identified */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Determine which zones have halted */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Mark zone as not existing, or delete if it did not exist in
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * previous interval.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Zone deleted in prior interval,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * so it no longer exists.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Mark cpus as not existing. If a cpu is found, it will be updated. If
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * a cpu is not found, then it must have gone offline, so it will be
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * The kstat tracking data is rolled so that the usage since the previous
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * interval can be determined.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_mark_cpus_start(zsd_ctl_t *ctl, boolean_t roll)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Mark all cpus as not existing. As cpus are found, they will
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * be marked as existing.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (cpu = list_head(&ctl->zsctl_cpus); cpu != NULL;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence cpu->zsc_nsec_idle_prev = cpu->zsc_nsec_idle;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence cpu->zsc_nsec_intr_prev = cpu->zsc_nsec_intr;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence cpu->zsc_nsec_kern_prev = cpu->zsc_nsec_kern;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence cpu->zsc_nsec_user_prev = cpu->zsc_nsec_user;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * An array the size of the maximum number of cpus is kept. Within this array
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * a list of the online cpus is maintained.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_lookup_insert_cpu(zsd_ctl_t *ctl, processorid_t cpuid)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* A cpu has been found. Update its information */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_mark_cpu_found(zsd_cpu_t *cpu, zsd_pset_t *pset, psetid_t psetid)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * legacy processor sets, the cpu may move while zonestatd is
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * inspecting, causing it to be found twice. In this case, just
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * leave cpu in the first processor set in which it was found.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Mark cpu as online */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * cpu is newly online.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Cpu is newly online.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * cpu online during previous interval. Save properties at
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * start of interval
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Remove all offlined cpus from the list of tracked cpus */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Mark cpu as online or offline */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * cpu offlined in prior interval. It is gone.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Clear structure for future use */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * cpu online at start of interval. Treat
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * as still online, since it was online for
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * some portion of the interval.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Some utility functions for managing the list of processor sets */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_lookup_pset_byid(zsd_ctl_t *ctl, psetid_t psetid)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (pset = list_head(&ctl->zsctl_psets); pset != NULL;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_lookup_pset(zsd_ctl_t *ctl, char *psetname, psetid_t psetid)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (pset = list_head(&ctl->zsctl_psets); pset != NULL;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_allocate_pset(zsd_ctl_t *ctl, char *psetname, psetid_t psetid)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if ((pset = (zsd_pset_t *)calloc(1, sizeof (zsd_pset_t))) == NULL)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) strlcpy(pset->zsp_name, psetname, sizeof (pset->zsp_name));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Allocate as deleted so if not found in first pass, pset is deleted
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * from list. This can happen if pset is returned by pset_list, but
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * is destroyed before first attempt to fetch pset details.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence list_create(&pset->zsp_usage_list, sizeof (zsd_pset_usage_t),
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_lookup_insert_pset(zsd_ctl_t *ctl, char *psetname, psetid_t psetid)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if ((pset = zsd_lookup_pset(ctl, psetname, psetid)) != NULL)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if ((pset = zsd_allocate_pset(ctl, psetname, psetid)) == NULL)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Insert sorted by psetname */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence while (tmp != NULL && strcmp(psetname, tmp->zsp_name) > 0)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence list_insert_before(&ctl->zsctl_psets, tmp, pset);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Some utility functions for managing the list of zones using each pset */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_lookup_usage(zsd_pset_t *pset, zsd_zone_t *zone)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (usage = list_head(&pset->zsp_usage_list); usage != NULL;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence usage = list_next(&pset->zsp_usage_list, usage))
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_allocate_pset_usage(zsd_ctl_t *ctl, zsd_pset_t *pset, zsd_zone_t *zone)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if ((usage = (zsd_pset_usage_t *)calloc(1, sizeof (zsd_pset_usage_t)))
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Allocate as not deleted. If a process is found in a pset for
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * a zone, the usage will not be deleted until at least the next
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_lookup_insert_usage(zsd_ctl_t *ctl, zsd_pset_t *pset, zsd_zone_t *zone)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if ((usage = zsd_allocate_pset_usage(ctl, pset, zone)) == NULL)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence while (tmp != NULL && strcmp(zone->zsz_name, tmp->zsu_zone->zsz_name)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence list_insert_before(&pset->zsp_usage_list, tmp, usage);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Re-count these values each interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Reads each cpu's kstats, and adds the usage to the cpu's pset */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_update_cpu_stats(zsd_ctl_t *ctl, zsd_cpu_t *cpu)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Get the cpu time totals for this cpu */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence kstat = kstat_lookup(ctl->zsctl_kstat_ctl, "cpu", cpuid, "sys");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence kid = kstat_read(ctl->zsctl_kstat_ctl, kstat, NULL);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence knp = kstat_data_lookup(kstat, "cpu_nsec_idle");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (knp == NULL || knp->data_type != KSTAT_DATA_UINT64)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence knp = kstat_data_lookup(kstat, "cpu_nsec_kernel");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (knp == NULL || knp->data_type != KSTAT_DATA_UINT64)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence knp = kstat_data_lookup(kstat, "cpu_nsec_user");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (knp == NULL || knp->data_type != KSTAT_DATA_UINT64)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Tracking intr time per cpu just exists for future enhancements.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * The value is presently always zero.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * cpu is newly online. There is no reference value,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * so just record its current stats for comparison
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * on next stat read.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence cpu->zsc_nsec_idle_prev = cpu->zsc_nsec_idle;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence cpu->zsc_nsec_intr_prev = cpu->zsc_nsec_intr;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence cpu->zsc_nsec_kern_prev = cpu->zsc_nsec_kern;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence cpu->zsc_nsec_user_prev = cpu->zsc_nsec_user;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Calculate relative time since previous refresh.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Paranoia. Don't let time go backwards.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (cpu->zsc_nsec_idle > cpu->zsc_nsec_idle_prev)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence idle = cpu->zsc_nsec_idle - cpu->zsc_nsec_idle_prev;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (cpu->zsc_nsec_intr > cpu->zsc_nsec_intr_prev)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence intr = cpu->zsc_nsec_intr - cpu->zsc_nsec_intr_prev;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (cpu->zsc_nsec_kern > cpu->zsc_nsec_kern_prev)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence kern = cpu->zsc_nsec_kern - cpu->zsc_nsec_kern_prev;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (cpu->zsc_nsec_user > cpu->zsc_nsec_user_prev)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence user = cpu->zsc_nsec_user - cpu->zsc_nsec_user_prev;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Update totals for cpu usage */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Add cpu's stats to its pset if it is known to be in
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * the pset since previous read.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (cpu->zsc_psetid == cpu->zsc_psetid_prev ||
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Last pset was different than current pset.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Best guess is to split usage between the two.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence TIMESTRUC_ADD_NANOSEC(pset_prev->zsp_idle, idle / 2);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence TIMESTRUC_ADD_NANOSEC(pset_prev->zsp_intr, intr / 2);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence TIMESTRUC_ADD_NANOSEC(pset_prev->zsp_kern, kern / 2);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence TIMESTRUC_ADD_NANOSEC(pset_prev->zsp_user, user / 2);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Determine the details of a processor set by pset_id */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_get_pool_pset(zsd_ctl_t *ctl, psetid_t psetid, char *psetname,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence size_t namelen, uint_t *cputype, uint64_t *online, uint64_t *size,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint64_t *min, uint64_t *max, int64_t *importance)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (ctl->zsctl_pool_status == POOL_DISABLED) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Inspect legacy psets
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* pset is gone. Tell caller to retry */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Success */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Could not allocate to get new cpu list.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence "Could not allocate for cpu list"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Old school pset. Just make min and max equal
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * to its size
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) strlcpy(psetname, "pset_default", namelen);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Just treat legacy pset as a simple pool pset
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Look up the pool pset using the pset id */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (pool_value_set_name(vals[1], "pset.sys_id")
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (pool_value_set_name(vals[0], "type") != PO_SUCCESS)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (pool_value_set_string(vals[0], "pset") != PO_SUCCESS)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if ((res_list = pool_query_resources(conf, &num, vals)) == NULL)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (pool_get_property(conf, pool_resource_to_elem(conf, pset),
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pool_value_get_string(vals[0], &string) != PO_SUCCESS)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (strncmp(psetname, "SUNWtmp", strlen("SUNWtmp")) == 0)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Get size, min, max, and importance */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (pool_get_property(conf, pool_resource_to_elem(conf,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pool_value_get_uint64(vals[0], &uint64) == PO_SUCCESS)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Get size, min, max, and importance */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (pool_get_property(conf, pool_resource_to_elem(conf,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pool_value_get_uint64(vals[0], &uint64) == PO_SUCCESS)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (pool_get_property(conf, pool_resource_to_elem(conf,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pool_value_get_uint64(vals[0], &uint64) == PO_SUCCESS)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (pool_get_property(conf, pool_resource_to_elem(conf,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pset), "pset.importance", vals[0]) == POC_INT &&
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pool_value_get_int64(vals[0], &int64) == PO_SUCCESS)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* get cpus */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence cpus = pool_query_resource_components(conf, pset, &num, NULL);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Make sure there is space for cpu id list */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Could not allocate to get new cpu list.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence "Could not allocate for cpu list"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* count the online cpus */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (i = 0; i < num; i++) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (pool_get_property(conf, pool_component_to_elem(
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence conf, cpus[i]), "cpu.status", vals[0]) != POC_STRING ||
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pool_value_get_string(vals[0], &string) != PO_SUCCESS)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (pool_get_property(conf, pool_component_to_elem(
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence conf, cpus[i]), "cpu.sys_id", vals[0]) != POC_INT ||
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pool_value_get_int64(vals[0], &int64) != PO_SUCCESS)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * The pools operations should succeed since the conf is a consistent
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * snapshot. Tell caller there is no need to retry.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Update the current list of processor sets.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * This also updates the list of online cpus, and each cpu's pset membership.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Zero cpu counters to recount them */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (ctl->zsctl_pool_status == POOL_DISABLED) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Pools must have become disabled */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) pool_conf_close(ctl->zsctl_pool_conf);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence "Unable to update pool configuration"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Not able to get pool info. Don't update. */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Get the list of psets using libpool */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (pool_value_set_name(vals[0], "type") != PO_SUCCESS)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (pool_value_set_string(vals[0], "pset") != PO_SUCCESS)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if ((res_list = pool_query_resources(conf, &num, vals))
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if ((cache = (psetid_t *)realloc(ctl->zsctl_pset_cache,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Save the pset id of each pset */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (i = 0; i < num; i++) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (pool_get_property(conf, pool_resource_to_elem(conf,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (ctl->zsctl_pool_status == POOL_ENABLED) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) pool_conf_close(ctl->zsctl_pool_conf);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Get the pset list using legacy psets */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) pset_list(ctl->zsctl_pset_cache, &num);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if ((cache = (psetid_t *)realloc(ctl->zsctl_pset_cache,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Could not allocate to get new pset list.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Add the default pset to list */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ctl->zsctl_pset_cache[num] = ctl->zsctl_pset_cache[0];
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Refresh cpu membership of all psets */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (i = 0; i < num; i++) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Get pool pset information */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (zsd_get_pool_pset(ctl, sys_id, psetname, sizeof (psetname),
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence &cputype, &online, &size, &min, &max, &importance)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Failed to get info for pset %d"),
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* update pset info */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_mark_pset_found(pset, cputype, online, size, min,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* update each cpu in pset */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Fetch the current pool and pset name for the given zone.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_get_zone_pool_pset(zsd_ctl_t *ctl, zsd_zone_t *zone,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence char *pool, int poollen, char *pset, int psetlen, uint_t *cputype)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ret = zone_getattr(zone->zsz_id, ZONE_ATTR_POOLID,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Default values if lookup fails */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) strlcpy(poolname, "pool_default", sizeof (poolname));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) strlcpy(psetname, "pset_default", sizeof (poolname));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* no dedicated cpu if pools are disabled */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Get the pool name using the id */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (pool_value_set_name(vals[0], "pool.sys_id") != PO_SUCCESS)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if ((pools = pool_query_pools(conf, &num, vals)) == NULL)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (pool_get_property(conf, pool_to_elem(conf, pools[0]),
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pool_value_get_string(vals[0], &string) != PO_SUCCESS)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) strlcpy(poolname, (char *)string, sizeof (poolname));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Get the name of the pset for the pool */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (pool_value_set_name(vals[0], "type") != PO_SUCCESS)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (pool_value_set_string(vals[0], "pset") != PO_SUCCESS)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if ((res_list = pool_query_pool_resources(conf, pools[0], &num, vals))
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (pool_get_property(conf, pool_resource_to_elem(conf,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence res_list[0]), "pset.sys_id", vals[0]) != POC_INT ||
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pool_value_get_int64(vals[0], &int64) != PO_SUCCESS)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (pool_get_property(conf, pool_resource_to_elem(conf,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence res_list[0]), "pset.name", vals[0]) != POC_STRING ||
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pool_value_get_string(vals[0], &string) != PO_SUCCESS)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) strlcpy(psetname, (char *)string, sizeof (psetname));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (strncmp(psetname, "SUNWtmp_", strlen("SUNWtmp_")) == 0)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (strncmp(psetname, "SUNW_legacy_", strlen("SUNW_legacy_")) == 0)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Convert scheduler names to ZS_* scheduler flags */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Fetch the limit information for a zone. This uses zone_enter() as the
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * getrctl(2) system call only returns rctl information for the zone of
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * the caller.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_get_zone_caps(zsd_ctl_t *ctl, zsd_zone_t *zone, uint64_t *cpu_shares,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint64_t *cpu_cap, uint64_t *ram_cap, uint64_t *locked_cap,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint64_t *vm_cap, uint64_t *processes_cap, uint64_t *processes,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint64_t *lwps_cap, uint64_t *lwps, uint64_t *shm_cap, uint64_t *shm,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint64_t *shmids_cap, uint64_t *shmids, uint64_t *semids_cap,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint64_t *semids, uint64_t *msgids_cap, uint64_t *msgids,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint64_t *lofi_cap, uint64_t *lofi, uint_t *sched)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Treat all caps as no cap on error */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Get the ram cap first since it is a zone attr */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ret = zone_getattr(zone->zsz_id, ZONE_ATTR_PHYS_MCAP,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Get the zone's default scheduling class */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ret = zone_getattr(zone->zsz_id, ZONE_ATTR_SCHED_CLASS,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* rctl caps must be fetched from within the zone */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) close(p[0]);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) close(p[0]);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) close(p[0]);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Get caps for zone, and write them to zonestatd parent. */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence vals[i++] = zsd_get_zone_rctl_limit("zone.cpu-shares");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence vals[i++] = zsd_get_zone_rctl_limit("zone.cpu-cap");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence vals[i++] = zsd_get_zone_rctl_limit("zone.max-locked-memory");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence vals[i++] = zsd_get_zone_rctl_limit("zone.max-swap");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence vals[i++] = zsd_get_zone_rctl_limit("zone.max-processes");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence vals[i++] = zsd_get_zone_rctl_usage("zone.max-processes");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence vals[i++] = zsd_get_zone_rctl_limit("zone.max-lwps");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence vals[i++] = zsd_get_zone_rctl_usage("zone.max-lwps");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence vals[i++] = zsd_get_zone_rctl_limit("zone.max-shm-memory");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence vals[i++] = zsd_get_zone_rctl_usage("zone.max-shm-memory");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence vals[i++] = zsd_get_zone_rctl_limit("zone.max-shm-ids");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence vals[i++] = zsd_get_zone_rctl_usage("zone.max-shm-ids");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence vals[i++] = zsd_get_zone_rctl_limit("zone.max-sem-ids");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence vals[i++] = zsd_get_zone_rctl_usage("zone.max-sem-ids");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence vals[i++] = zsd_get_zone_rctl_limit("zone.max-msg-ids");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence vals[i++] = zsd_get_zone_rctl_usage("zone.max-msg-ids");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence vals[i++] = zsd_get_zone_rctl_limit("zone.max-lofi");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence vals[i++] = zsd_get_zone_rctl_usage("zone.max-lofi");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (write(p[1], vals, ZSD_NUM_RCTL_VALS * sizeof (uint64_t)) !=
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Read cap from child in zone */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (read(p[0], vals, ZSD_NUM_RCTL_VALS * sizeof (uint64_t)) !=
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Interpret maximum values as no cap */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (*processes_cap == sys->zss_processes_max)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) close(p[0]);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Update the current list of running zones */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Get the current list of running zones */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) zone_list(ctl->zsctl_zone_cache, &num);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if ((cache = (zoneid_t *)realloc(ctl->zsctl_zone_cache,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Could not allocate to get new zone list. Give up */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (i = 0; i < num; i++) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ret = getzonenamebyid(ctl->zsctl_zone_cache[i],
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ret = zone_getattr(ctl->zsctl_zone_cache[i], ZONE_ATTR_FLAGS,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_get_zone_pool_pset(ctl, zone, poolname, sizeof (poolname),
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (zsd_get_zone_caps(ctl, zone, &cpu_shares, &cpu_cap,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence &ram_cap, &locked_cap, &vm_cap, &processes_cap, &processes,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence &lwps_cap, &lwps, &shm_cap, &shm, &shmids_cap, &shmids,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence &semids_cap, &semids, &msgids_cap, &msgids, &lofi_cap,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_mark_zone_found(ctl, zone, cpu_shares, cpu_cap, ram_cap,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence locked_cap, vm_cap, processes_cap, processes, lwps_cap,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence lwps, shm_cap, shm, shmids_cap, shmids, semids_cap,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence semids, msgids_cap, msgids, lofi_cap, lofi, poolname,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Fetch the details of a process from its psinfo_t */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_get_proc_info(zsd_ctl_t *ctl, psinfo_t *psinfo, psetid_t *psetid,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence psetid_t *prev_psetid, zoneid_t *zoneid, zoneid_t *prev_zoneid,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Get cached data for proc */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence proc = &(ctl->zsctl_proc_array[psinfo->pr_pid]);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence TIMESTRUC_DELTA(d, psinfo->pr_time, proc->zspr_usage);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence *sched = zsd_schedname2int(psinfo->pr_lwp.pr_clname,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Update cached data for proc */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence proc->zspr_psetid = psinfo->pr_lwp.pr_bindpset;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence proc->zspr_usage.tv_sec = psinfo->pr_time.tv_sec;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence proc->zspr_usage.tv_nsec = psinfo->pr_time.tv_nsec;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Reset the known cpu usage of a process. This is done after a process
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * exits so that if the pid is recycled, data from its previous life is
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Open the current extended accounting file. On initialization, open the
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * file as the current file to be used. Otherwise, open the file as the
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * next file to use of the current file reaches EOF.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_open_exacct(zsd_ctl_t *ctl, boolean_t init)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * The accounting file is first opened at the tail. Following
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * opens to new accounting files are opened at the head.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* open accounting files for cpu consumption */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ret = acctctl(AC_STATE_GET | AC_PROC, &state, sizeof (state));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to get process accounting state"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence "Unable to enable process accounting"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ret = acctctl(AC_FILE_GET | AC_PROC, path, sizeof (path));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to get process accounting file"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if ((*fd = open64(path, O_RDONLY, 0)) >= 0 &&
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (oret = ea_fdopen(eaf, *fd, NULL, flags, O_RDONLY)) == 0)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * It is possible the accounting file is momentarily unavailable
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * because it is being rolled. Try for up to half a second.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * If failure to open accounting file persists, give up.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence else if (*fd >= 0)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence "Unable to open process accounting file"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* wait one millisecond */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Walk /proc and charge each process to its zone and processor set.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Then read exacct data for exited processes, and charge them as well.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_refresh_procs(zsd_ctl_t *ctl, boolean_t init)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Get the current accounting file. The current accounting file
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * may be different than the file in use, as the accounting file
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * may have been rolled, or manually changed by an admin.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to track process accounting"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Mark the current time as the interval end time. Don't track
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * processes that exit after this time.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) memset(dent, 0, ctl->zsctl_procfs_dent_size);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Walk all processes and compute each zone's usage on each pset. */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) snprintf(path, sizeof (path), "/proc/%s/psinfo",
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (read(fd, &psinfo, sizeof (psinfo)) != sizeof (psinfo)) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_get_proc_info(ctl, &psinfo, &psetid, &prev_psetid,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence d2.tv_sec = (delta.tv_sec / 2) + (delta.tv_sec % 2);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence d2.tv_nsec = (delta.tv_nsec / 2) + (delta.tv_nsec % 2);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Get the zone and pset this process is running in */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence usage = zsd_lookup_insert_usage(ctl, pset, zone);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Get the usage of the previous zone and pset if they were
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence prev_zone = zsd_lookup_zone_byid(ctl, prev_zoneid);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence prev_pset = zsd_lookup_pset_byid(ctl, prev_psetid);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (prev_zone != NULL || prev_pset != NULL) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence prev_usage = zsd_lookup_insert_usage(ctl, prev_pset,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Update the usage with the processes info */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_mark_pset_usage_found(prev_usage, sched);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * First time around is just to get a starting point. All
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * usages will be zero.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * No need to collect exited proc data on initialization. Just
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * caching the usage of the known processes to get a zero starting
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Add accounting records to account for processes which have
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ret = ea_get_object(&ctl->zsctl_proc_eaf, &object);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * See if the next accounting file is the
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * same as the current accounting file.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * End of current accounting file is
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * reached, so finished. Clear EOF
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * bit for next time around.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Accounting file has changed. Move
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * to current accounting file.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Other accounting error. Give up on
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * accounting.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Skip if not a process group */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if ((object.eo_catalog & EXT_TYPE_MASK) != EXT_GROUP ||
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (object.eo_catalog & EXD_DATA_MASK) != EXD_GROUP_PROC) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* The process group entry should be complete */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence "unable to get process accounting data");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Next entries should be process data */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence "process data of wrong type");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence switch (pobject.eo_catalog & EXD_DATA_MASK) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * This process should not be currently in
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * the list of processes to process.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence "Malformed process accounting entry found"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence finish.tv_nsec > (interval_end.tv_usec * 1000)))
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Try to identify the zone and pset to which this
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * exited process belongs.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Save proc info */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * The following tries to deduce the processes pset.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * First choose pset and sched using cached value from the
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * most recent time the process has been seen.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * pset and sched can change across zone_enter, so make sure
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * most recent sighting of this process was in the same
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * zone before using most recent known value.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * If there is no known value, use value of processes
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * parent. If parent is unknown, walk parents until a known
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * parent is found.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * If no parent in the zone is found, use the zone's default
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * pset and scheduling class.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pset = zsd_lookup_pset_byid(ctl, prev_psetid);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence } else if (pproc->zspr_zoneid == zone->zsz_id &&
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pset = zsd_lookup_pset_byid(ctl, prev_psetid);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Process or processes parent has never been seen.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Save to deduce a known parent later.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Add the zone's usage to the pset */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence usage = zsd_lookup_insert_usage(ctl, pset, zone);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* compute the usage to add for the exited proc */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * close next accounting file.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* For the remaining processes, use pset and sched of a known parent */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (next->zspr_ppid == 0 || next->zspr_ppid == -1) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Kernel process, or parent is unknown, skip
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * process, remove from process list.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pproc = &(ctl->zsctl_proc_array[next->zspr_ppid]);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (pproc->zspr_zoneid != proc->zspr_zoneid) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Parent in different zone. Save process and
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * use zone's default pset and sched below
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Parent has unknown pset, Search parent's parent */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Found parent with known pset. Use its info */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Add the zone's usage to the pset */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence usage = zsd_lookup_insert_usage(ctl, pset, zone);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_mark_pset_usage_found(usage, proc->zspr_sched);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_add_usage(ctl, usage, &proc->zspr_usage);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Process has never been seen. Using zone info to
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * determine pset and scheduling class.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zone = zsd_lookup_zone_byid(ctl, proc->zspr_zoneid);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pset = zsd_lookup_pset_byid(ctl, prev_psetid);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pset = zsd_lookup_pset(ctl, zone->zsz_pset, -1);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Ignore FX high scheduling class if it is not the
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * only scheduling class in the zone.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * If more than one scheduling class has been found
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * in the zone, use zone's default scheduling class for
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * this process.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Add the zone's usage to the pset */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence usage = zsd_lookup_insert_usage(ctl, pset, zone);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_add_usage(ctl, usage, &proc->zspr_usage);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Close the next accounting file if we have not transitioned to it
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * getvmusage(2) uses size_t's in the passwd data structure, which differ
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * in size for 32bit and 64 bit kernels. Since this is a contracted interface,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * and zonestatd does not necessarily match the kernel's bitness, marshal
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * results appropriately.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_getvmusage(zsd_ctl_t *ctl, uint_t flags, time_t age, zsd_vmusage64_t *buf,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ret = syscall(SYS_rusagesys, _RUSAGESYS_GETVMUSAGE,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence flags, age, (uintptr_t)buf, (uintptr_t)&nres32);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * An array of vmusage32_t's has been returned.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Convert it to an array of vmusage64_t's.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence vmu64[i].vmu_swap_all = vmu32[i].vmu_swap_all;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * kernel is 64 bit, so use 64 bit structures as zonestat
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence return (syscall(SYS_rusagesys, _RUSAGESYS_GETVMUSAGE,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence flags, age, (uintptr_t)buf, (uintptr_t)nres));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Update the current physical, virtual, and locked memory usage of the
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * running zones.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_refresh_memory(zsd_ctl_t *ctl, boolean_t init)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence uint64_t disk_swap_used; /* disk swap with contents */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* interrogate swap devices to find the amount of disk swap */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence num_swap_devices = swapctl(SC_GETNSWP, NULL);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* No disk swap */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* see if swap table needs to be larger */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (num_swap_devices > ctl->zsctl_swap_cache_num) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence swt_size = sizeof (int) +
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (num_swap_devices * sizeof (struct swapent)) +
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Could not allocate to get list of swap devices.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Just use data from the most recent read, which will
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * be zero if this is the first read.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to allocate to determine "
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence "virtual memory"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (i = 0; i < num_swap_devices; i++, swent++) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ctl->zsctl_swap_cache_num = num_swap_devices;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence num_swap_devices = swapctl(SC_LIST, ctl->zsctl_swap_cache);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* More swap devices have arrived */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to determine disk swap devices"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Unexpected error. Use existing data */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* add up the disk swap */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (i = 0; i < num_swap_devices; i++, swent++) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence disk_swap_used += (swent->ste_pages - swent->ste_free);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* get system pages kstat */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence kstat = kstat_lookup(ctl->zsctl_kstat_ctl, "unix", 0, "system_pages");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to lookup system pages kstat"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence kid = kstat_read(ctl->zsctl_kstat_ctl, kstat, NULL);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to read system pages kstat"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence else if (knp->data_type == KSTAT_DATA_UINT32)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to read pp_kernel"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence else if (knp->data_type == KSTAT_DATA_UINT32)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* get the zfs arc size if available */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence kstat = kstat_lookup(ctl->zsctl_kstat_ctl, "zfs", 0, "arcstats");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence kid = kstat_read(ctl->zsctl_kstat_ctl, kstat, NULL);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Try to get swap information */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to get swap info"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* getvmusage to get physical memory usage */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ret = zsd_getvmusage(ctl, VMUSAGE_SYSTEM | VMUSAGE_ALL_ZONES, 0,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Unexpected error. Use existing data */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence "Unable to read physical memory usage"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* vmusage results cache too small */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (num_vmusage > ctl->zsctl_vmusage_cache_num) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence size_t size = sizeof (zsd_vmusage64_t) * num_vmusage;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to alloc to determine "
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence "physical memory usage"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (i = 0; i < num_vmusage; i++) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* total pages backing user process mappings */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence phys_zones_overcount += vmusage[i].vmu_rss_all;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zone = zsd_lookup_zone_byid(ctl, vmusage[i].vmu_id);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zone->zsz_usage_ram = vmusage[i].vmu_rss_all;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Figure how much memory was double counted due to text sharing
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * between zones. Credit this back so that the sum of the zones
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * equals the total zone ram usage;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence phys_zones_extra = phys_zones_overcount - phys_zones;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence phys_zones_credit = phys_zones_extra / vmu_nzones;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* walk the zones to get swap and locked kstats. Fetch ram cap. */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (zone = list_head(&ctl->zsctl_zones); zone != NULL;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* If zone halted during interval, show memory usage as none */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (zone->zsz_usage_ram > phys_zones_credit) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Get zone's swap usage. Since zone could have halted,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * treats as zero if cannot read
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) snprintf(kstat_name, sizeof (kstat_name),
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence kstat = kstat_lookup(ctl->zsctl_kstat_ctl, "caps",
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence kid = kstat_read(ctl->zsctl_kstat_ctl, kstat, NULL);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Get zone's locked usage. Since zone could have halted,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * treats as zero if cannot read
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) snprintf(kstat_name, sizeof (kstat_name),
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence kstat = kstat_lookup(ctl->zsctl_kstat_ctl, "caps",
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence kid = kstat_read(ctl->zsctl_kstat_ctl, kstat, NULL);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Since locked memory accounting for zones
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * can double count ddi locked memory, cap each
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * zone's locked usage at its ram usage.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence sysconf(_SC_PHYS_PAGES) * ctl->zsctl_pagesize;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence phys_used = (sysconf(_SC_PHYS_PAGES) - sysconf(_SC_AVPHYS_PAGES))
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Compute remaining statistics */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence sys->zss_ram_kern = phys_used - phys_zones - arc_size;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * The total for kernel locked memory should include
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * segkp locked pages, but oh well. The arc size is subtracted,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * as that physical memory is reclaimable.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Add memory used by kernel startup and obp to kernel locked */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence sys->zss_locked_kern += phys_total - physmem;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Add in the portion of (RAM+DISK) that is not available as swap,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * and consider it swap used by the kernel.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence sys->zss_vm_total = phys_total + disk_swap_total;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence vm_free = (ani.ani_max - ani.ani_resv) * ctl->zsctl_pagesize;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence sys->zss_vm_kern = vm_used - sys->zss_vm_zones - arc_size;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Charge each cpu's usage to its processor sets. Also add the cpu's total
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * time to each zone using the processor set. This tracks the maximum
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * amount of cpu time that a zone could have used.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_refresh_cpu_stats(zsd_ctl_t *ctl, boolean_t init)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Update the per-cpu kstat data */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Update the elapsed real time */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* first time around, store hrtime for future comparision */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Compute increase in hrtime since the most recent read */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if ((hrtime = hrtime - ctl->zsctl_hrtime_prev) > 0)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence TIMESTRUC_ADD_NANOSEC(ctl->zsctl_hrtime_total, hrtime);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* On initialization, all psets have zero time */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (pset = list_head(&ctl->zsctl_psets); pset != NULL;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Internal error,inactive pset found"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* sum total used time for pset */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* kernel time in pset is total time minus zone time */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Total pset elapsed time is used time plus idle time */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence TIMESTRUC_DELTA(delta, ts, pset->zsp_total_time);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (usage = list_head(&pset->zsp_usage_list); usage != NULL;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence usage = list_next(&pset->zsp_usage_list, usage)) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (usage->zsu_cpu_shares != ZS_LIMIT_NONE &&
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence usage->zsu_cpu_shares != ZS_SHARES_UNLIMITED &&
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Figure out how many nanoseconds of share time
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * to give to the zone
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Add pset time to each zone using pset */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence TIMESTRUC_ADD_TIMESTRUC(zone->zsz_pset_time, delta);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (zone = list_head(&ctl->zsctl_zones); zone != NULL;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* update cpu cap tracking if the zone has a cpu cap */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence elapsed = ctl->zsctl_hrtime - ctl->zsctl_hrtime_prev;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence TIMESTRUC_ADD_NANOSEC(zone->zsz_cap_time, elapsed);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* kernel time in pset is total time minus zone time */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Total pset elapsed time is used time plus idle time */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Saves current usage data to a cache that is read by libzonestat when
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * calling zs_usage_read().
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * All pointers in the cached data structure are set to NULL. When
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * libzonestat reads the cached data, it will set the pointers relative to
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * its address space.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence sizeof (zs_pset_zone_t) * ctl->zsctl_npset_usages;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to allocate usage cache\n"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence cache->zsuc_size = size - sizeof (zs_usage_cache_t);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence usage = cache->zsuc_usage = (zs_usage_t *)next;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence sys->zss_locked_kern = dsys->zss_locked_kern;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence sys->zss_locked_zones = dsys->zss_locked_zones;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence sys->zss_ncpus_online = dsys->zss_ncpus_online;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence sys->zss_cpu_total_time = dsys->zss_cpu_total_time;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence sys->zss_cpu_usage_zones = dsys->zss_cpu_usage_zones;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence sys->zss_cpu_usage_kern = dsys->zss_cpu_usage_kern;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (i = 0, dzone = list_head(&ctl->zsctl_zones);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence i++, dzone = list_next(&ctl->zsctl_zones, dzone)) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) strlcpy(zone->zsz_name, dzone->zsz_name,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) strlcpy(zone->zsz_pool, dzone->zsz_pool,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) strlcpy(zone->zsz_pset, dzone->zsz_pset,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zone->zsz_cpu_shares = dzone->zsz_cpu_shares;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zone->zsz_locked_cap = dzone->zsz_locked_cap;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zone->zsz_cpus_online = dzone->zsz_cpus_online;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zone->zsz_share_time = dzone->zsz_share_time;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zone->zsz_usage_locked = dzone->zsz_usage_locked;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zone->zsz_processes_cap = dzone->zsz_processes_cap;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zone->zsz_shmids_cap = dzone->zsz_shmids_cap;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zone->zsz_semids_cap = dzone->zsz_semids_cap;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zone->zsz_msgids_cap = dzone->zsz_msgids_cap;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (i = 0, dpset = list_head(&ctl->zsctl_psets);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence i++, dpset = list_next(&ctl->zsctl_psets, dpset)) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) strlcpy(pset->zsp_name, dpset->zsp_name,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pset->zsp_importance = dpset->zsp_importance;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pset->zsp_cpu_shares = dpset->zsp_cpu_shares;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pset->zsp_total_time = dpset->zsp_total_time;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pset->zsp_usage_kern = dpset->zsp_usage_kern;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pset->zsp_usage_zones = dpset->zsp_usage_zones;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Add pset usages for pset */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (j = 0, dpusage = list_head(&dpset->zsp_usage_list);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence j++, dpusage = list_next(&dpset->zsp_usage_list, dpusage)) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* pointers are computed by client */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pusage->zspz_zoneid = dpusage->zsu_zone->zsz_id;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pusage->zspz_cpu_shares = dpusage->zsu_cpu_shares;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence pusage->zspz_cpu_usage = dpusage->zsu_cpu_usage;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Update the current cache pointer */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Wake up any clients that are waiting for this calculation */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Close the handles held by zsd_open() */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) pool_conf_close(ctl->zsctl_pool_conf);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence while ((zone = list_head(&ctl->zsctl_zones)) != NULL) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence while ((pset = list_head(&ctl->zsctl_psets)) != NULL) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence while ((usage = list_head(&pset->zsp_usage_list))
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Release all cpus being tracked */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Update the utilization data for all zones and processor sets.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_read(zsd_ctl_t *ctl, boolean_t init, boolean_t do_memory)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) kstat_chain_update(ctl->zsctl_kstat_ctl);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) gettimeofday(&(ctl->zsctl_timeofday), NULL);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Memory calculation is expensive. Only update it on sample
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Delete objects that no longer exist.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Pset usages must be deleted first as they point to zone and
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * pset objects.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Save results for clients.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Roll process accounting file.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Get the system rctl, which is the upper most limit
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence rblk_last = (rctlblk_t *)alloca(rctlblk_size());
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (getrctl(name, NULL, rblk_last, RCTL_FIRST) != 0)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence while (getrctl(name, rblk_last, rblk, RCTL_NEXT) == 0)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) bcopy(rblk, rblk_last, rctlblk_size());
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Open any necessary subsystems for collecting utilization data,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * allocate and initialize data structures, and get initial utilization.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * ENOMEM out of memory
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * EINVAL other error
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (ctl == NULL && (ctl = (zsd_ctl_t *)calloc(1,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* open kstats */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (ctl->zsctl_kstat_ctl = kstat_open()) == NULL) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * These are set when the accounting file is opened by
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * zsd_update_procs()
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Create structures to track usage */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (ctl->zsctl_system == NULL && (ctl->zsctl_system = (zsd_system_t *)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* get the kernel bitness to know structure layout for getvmusage */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ret = sysinfo(SI_ARCHITECTURE_64, path, sizeof (path));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (ctl->zsctl_cpu_array == NULL && (ctl->zsctl_cpu_array =
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (zsd_cpu_t *)calloc(size + 1, sizeof (zsd_cpu_t))) == NULL) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ctl->zsctl_cpu_array[i].zsc_allocated = B_FALSE;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ctl->zsctl_cpu_array[i].zsc_psetid = ZS_PSET_ERROR;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ctl->zsctl_cpu_array[i].zsc_psetid_prev = ZS_PSET_ERROR;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("/proc not a procfs filesystem"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (ctl->zsctl_proc_array = (zsd_proc_t *)calloc(size,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence list_link_init(&(ctl->zsctl_proc_array[i].zspr_next));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ctl->zsctl_proc_array[i].zspr_psetid = ZS_PSET_ERROR;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ctl->zsctl_proc_array[i].zspr_usage.tv_sec = 0;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ctl->zsctl_proc_array[i].zspr_usage.tv_nsec = 0;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence list_create(&ctl->zsctl_zones, sizeof (zsd_zone_t),
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence list_create(&ctl->zsctl_psets, sizeof (zsd_pset_t),
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence list_create(&ctl->zsctl_cpus, sizeof (zsd_cpu_t),
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to determine max path of /proc"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (ctl->zsctl_procfs_dent = (struct dirent *)calloc(1, size))
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (ctl->zsctl_pool_conf = pool_conf_alloc()) == NULL) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (ctl->zsctl_pool_vals[0] = pool_value_alloc()) == NULL) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (ctl->zsctl_pool_vals[1] = pool_value_alloc()) == NULL) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * get system limits
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence system->zss_maxpid = size = sysconf(_SC_MAXPID);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence system->zss_processes_max = zsd_get_system_rctl("zone.max-processes");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence system->zss_lwps_max = zsd_get_system_rctl("zone.max-lwps");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence system->zss_shm_max = zsd_get_system_rctl("zone.max-shm-memory");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence system->zss_shmids_max = zsd_get_system_rctl("zone.max-shm-ids");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence system->zss_semids_max = zsd_get_system_rctl("zone.max-sem-ids");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence system->zss_msgids_max = zsd_get_system_rctl("zone.max-msg-ids");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence system->zss_lofi_max = zsd_get_system_rctl("zone.max-lofi");
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Reading zone statistics failed"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* Copy utilization data to buffer, filtering data if non-global zone. */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_usage_filter(zoneid_t zid, zs_usage_cache_t *cache, zs_usage_t *usage,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Privileged users in the global zone get everything */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) bcopy(cusage, usage, cusage->zsu_size);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Zones just get their own usage */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Save system limits but not usage */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Find the matching zone */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence sys->zss_ram_kern += (sys->zss_ram_zones - zone->zsz_usage_ram);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence sys->zss_vm_kern += (sys->zss_vm_zones - zone->zsz_usage_vm);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence sys->zss_locked_kern += (sys->zss_locked_zones -
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence sys->zss_locked_zones = zone->zsz_usage_locked;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence TIMESTRUC_DELTA(delta, sys->zss_cpu_usage_zones, zone->zsz_cpu_usage);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence TIMESTRUC_ADD_TIMESTRUC(sys->zss_cpu_usage_kern, delta);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence sys->zss_cpu_usage_zones = zone->zsz_cpu_usage;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence TIMESTRUC_DELTA(delta, pset->zsp_usage_zones,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence TIMESTRUC_ADD_TIMESTRUC(pset->zsp_usage_kern, delta);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Respond to new connections from libzonestat.so. Also respond to zoneadmd,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * which reports new zones.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* ARGSUSED */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_server(void *cookie, char *argp, size_t arg_size,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* If connection, return door to stat server */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Verify client compilation version */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) door_return(argp, sizeof (cmd) * 2, NULL, 0);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Verify client permission */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) door_return(argp, sizeof (cmd) * 2, NULL, 0);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence eset = ucred_getprivset(ucred, PRIV_EFFECTIVE);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) door_return(argp, sizeof (cmd) * 2, NULL, 0);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) door_return(argp, sizeof (cmd) * 2, NULL, 0);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Return stat server door */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence door.d_data.d_desc.d_descriptor = g_stat_door;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) door_return(argp, sizeof (cmd) * 2, &door, 1);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Respond to zoneadmd informing zonestatd of a new zone */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_fattach_zone(args[1], g_server_door, B_FALSE);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) door_return(argp, sizeof (cmd) * 2, NULL, 0);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Respond to libzonestat.so clients with the current utlilzation data.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* ARGSUSED */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrencezsd_stat_server(void *cookie, char *argp, size_t arg_size,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Tell stat thread there are no more clients */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence eset = ucred_getprivset(ucred, PRIV_EFFECTIVE);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Force a new cpu calculation for client. This will force a
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * new memory calculation if the memory data is older than the
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * sample period.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ret = cond_wait(&g_usage_cache_wait, &g_usage_cache_lock);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence "Interrupted before writing usage size to client\n"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Copy current usage data to stack to send to client */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence usage = (zs_usage_t *)alloca(cache->zsuc_size);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Filter out results if caller is non-global zone */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_usage_filter(zoneid, cache, usage, is_gz);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* ARGSUSED */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * The stat thread generates new utilization data when clients request
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * it. It also manages opening and closing the subsystems used to gather
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * data depending on if clients exist.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* ARGSUSED */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("Unable to fetch current time"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * These are used to decide if the most recent memory
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * calculation was within a sample interval,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * and weather or not the usage collection needs to
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * be opened or closed.
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * If all clients have gone, close usage collecting
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * Wait for a usage data request
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence "Unable to fetch current time"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence "Unable to open zone statistics"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (zsd_read(g_ctl, B_FALSE, do_memory) != 0) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence "Unable to read zone statistics"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (!g_hasclient && g_open == B_TRUE && g_ctl) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) strlcpy(pcinfo.pc_clname, "FX", sizeof (pcinfo.pc_clname));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (priocntl(0, 0, PC_GETCID, (caddr_t)&pcinfo) == -1) {
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("cannot get FX class parameters"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ((fxparms_t *)pcparms.pc_clparms)->fx_upri = 60;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ((fxparms_t *)pcparms.pc_clparms)->fx_uprilim = 60;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ((fxparms_t *)pcparms.pc_clparms)->fx_tqsecs = 0;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence ((fxparms_t *)pcparms.pc_clparms)->fx_tqnsecs = FX_NOCHANGE;
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (priocntl(P_PID, getpid(), PC_SETPARMS, (caddr_t)&pcparms) == -1)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("cannot enter the FX class"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * wake the parent with a clue
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) sigaction(SIGPIPE, &act, NULL); /* ignore SIGPIPE */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* forward ready code via exit status */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* daemon process exited before becoming ready */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* assume daemon process printed useful message */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_warn(gettext("daemon process killed or died"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence * generic Unix setup
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) umask(0000);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zids = (zoneid_t *)malloc(sizeof (zoneid_t) * nzids_last);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence for (i = 0; i < nzids; i++)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_fattach_zone(zids[i], g_server_door, detach_only);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) signal(SIGTERM, zonestat_quithandler);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence/* (void) sigignore(SIGCHLD); */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_error(gettext("Must be run from global zone only"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Get the configured sample interval */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence prop = scf_simple_prop_get(NULL, "svc:/system/zones-monitoring:default",
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_error(gettext("Unable to fetch SMF property "
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (scf_simple_prop_type(prop) != SCF_TYPE_COUNT)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence "\"config/sample_interval\". Must be of type \"count\""));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence intervalp = scf_simple_prop_next_count(prop);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence "\"config/sample_interval\". Must be greater than zero"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_error(gettext("Unable to start daemon\n"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Run at high priority */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) mutex_init(&g_usage_cache_lock, USYNC_THREAD, NULL);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) cond_init(&g_usage_cache_kick, USYNC_THREAD, NULL);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence (void) cond_init(&g_usage_cache_wait, USYNC_THREAD, NULL);
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence g_server_door = door_create(zsd_server, NULL,
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_error(gettext("Unable to create server door\n"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence g_stat_door = door_create(zsd_stat_server, NULL, DOOR_UNREF_MULTI |
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_error(gettext("Unable to create statistics door\n"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence if (thr_create(NULL, 0, stat_thread, NULL, 0, &tid) != 0)
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence zsd_error(gettext("Unable to create statistics thread\n"));
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* Wait for signal to quit */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* detach doors */
efd4c9b63ad77503c101fc6c2ed8ba96c9d52964Steve Lawrence /* kick stat thread and wait for it to close the statistics */