29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * CDDL HEADER START
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * The contents of this file are subject to the terms of the
3dcb12c941df15fc72227698263d7e1b4c33576calanbur * Common Development and Distribution License (the "License").
3dcb12c941df15fc72227698263d7e1b4c33576calanbur * You may not use this file except in compliance with the License.
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
29949e866e40b95795203f3ee46f44a197c946e4stevel * or http://www.opensolaris.org/os/licensing.
29949e866e40b95795203f3ee46f44a197c946e4stevel * See the License for the specific language governing permissions
29949e866e40b95795203f3ee46f44a197c946e4stevel * and limitations under the License.
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * When distributing Covered Code, include this CDDL HEADER in each
29949e866e40b95795203f3ee46f44a197c946e4stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
29949e866e40b95795203f3ee46f44a197c946e4stevel * If applicable, add the following below this CDDL HEADER, with the
29949e866e40b95795203f3ee46f44a197c946e4stevel * fields enclosed by brackets "[]" replaced with your own identifying
29949e866e40b95795203f3ee46f44a197c946e4stevel * information: Portions Copyright [yyyy] [name of copyright owner]
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * CDDL HEADER END
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
44c4f64b9f50f21ae3e51ad48a595c85f53db4bcJohn Levon * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
c9f77c52c0735e65aa2534394c5151cdb963cbefAndy Stormont * Copyright (c) 2014 Racktop Systems.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Kstat.xs is a Perl XS (eXStension module) that makes the Solaris
29949e866e40b95795203f3ee46f44a197c946e4stevel * kstat(3KSTAT) facility available to Perl scripts. Kstat is a general-purpose
29949e866e40b95795203f3ee46f44a197c946e4stevel * mechanism for providing kernel statistics to users. The Solaris API is
29949e866e40b95795203f3ee46f44a197c946e4stevel * function-based (see the manpage for details), but for ease of use in Perl
29949e866e40b95795203f3ee46f44a197c946e4stevel * scripts this module presents the information as a nested hash data structure.
29949e866e40b95795203f3ee46f44a197c946e4stevel * It would be too inefficient to read every kstat in the system, so this module
29949e866e40b95795203f3ee46f44a197c946e4stevel * uses the Perl TIEHASH mechanism to implement a read-on-demand semantic, which
29949e866e40b95795203f3ee46f44a197c946e4stevel * only reads and updates kstats as and when they are actually accessed.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Ignored raw kstats.
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * Some raw kstats are ignored by this module, these are listed below. The
29949e866e40b95795203f3ee46f44a197c946e4stevel * most common reason is that the kstats are stored as arrays and the ks_ndata
29949e866e40b95795203f3ee46f44a197c946e4stevel * and/or ks_data_size fields are invalid. In this case it is impossible to
29949e866e40b95795203f3ee46f44a197c946e4stevel * know how many records are in the array, so they can't be read.
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * unix:*:sfmmu_percpu_stat
29949e866e40b95795203f3ee46f44a197c946e4stevel * This is stored as an array with one entry per cpu. Each element is of type
29949e866e40b95795203f3ee46f44a197c946e4stevel * struct sfmmu_percpu_stat. The ks_ndata and ks_data_size fields are bogus.
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * ufs directio:*:UFS DirectIO Stats
29949e866e40b95795203f3ee46f44a197c946e4stevel * The structure definition used for these kstats (ufs_directio_kstats) is in a
29949e866e40b95795203f3ee46f44a197c946e4stevel * C file (uts/common/fs/ufs/ufs_directio.c) rather than a header file, so it
29949e866e40b95795203f3ee46f44a197c946e4stevel * isn't accessible.
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * qlc:*:statistics
29949e866e40b95795203f3ee46f44a197c946e4stevel * This is a third-party driver for which we don't have source.
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * mm:*:phys_installed
29949e866e40b95795203f3ee46f44a197c946e4stevel * This is stored as an array of uint64_t, with each pair of values being the
29949e866e40b95795203f3ee46f44a197c946e4stevel * (address, size) of a memory segment. The ks_ndata and ks_data_size fields
29949e866e40b95795203f3ee46f44a197c946e4stevel * are both zero.
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * sockfs:*:sock_unix_list
29949e866e40b95795203f3ee46f44a197c946e4stevel * This is stored as an array with one entry per active socket. Each element
29949e866e40b95795203f3ee46f44a197c946e4stevel * is of type struct k_sockinfo. The ks_ndata and ks_data_size fields are both
29949e866e40b95795203f3ee46f44a197c946e4stevel * zero.
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * Note that the ks_ndata and ks_data_size of many non-array raw kstats are
29949e866e40b95795203f3ee46f44a197c946e4stevel * also incorrect. The relevant assertions are therefore commented out in the
29949e866e40b95795203f3ee46f44a197c946e4stevel * appropriate raw kstat read routines.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/* Kstat related includes */
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <libgen.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <kstat.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/var.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/utsname.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/sysinfo.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/flock.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/dnlc.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <nfs/nfs.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <nfs/nfs_clnt.h>
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/* Ultra-specific kstat includes */
29949e866e40b95795203f3ee46f44a197c946e4stevel#ifdef __sparc
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <vm/hat_sfmmu.h> /* from /usr/platform/sun4u/include */
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/simmstat.h> /* from /usr/platform/sun4u/include */
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/sysctrl.h> /* from /usr/platform/sun4u/include */
29949e866e40b95795203f3ee46f44a197c946e4stevel#include <sys/fhc.h> /* from /usr/include */
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Solaris #defines SP, which conflicts with the perl definition of SP
29949e866e40b95795203f3ee46f44a197c946e4stevel * We don't need the Solaris one, so get rid of it to avoid warnings
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel#undef SP
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/* Perl XS includes */
29949e866e40b95795203f3ee46f44a197c946e4stevel#include "EXTERN.h"
29949e866e40b95795203f3ee46f44a197c946e4stevel#include "perl.h"
29949e866e40b95795203f3ee46f44a197c946e4stevel#include "XSUB.h"
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/* Debug macros */
29949e866e40b95795203f3ee46f44a197c946e4stevel#define DEBUG_ID "Sun::Solaris::Kstat"
29949e866e40b95795203f3ee46f44a197c946e4stevel#ifdef KSTAT_DEBUG
29949e866e40b95795203f3ee46f44a197c946e4stevel#define PERL_ASSERT(EXP) \
29949e866e40b95795203f3ee46f44a197c946e4stevel ((void)((EXP) || (croak("%s: assertion failed at %s:%d: %s", \
29949e866e40b95795203f3ee46f44a197c946e4stevel DEBUG_ID, __FILE__, __LINE__, #EXP), 0), 0))
29949e866e40b95795203f3ee46f44a197c946e4stevel#define PERL_ASSERTMSG(EXP, MSG) \
29949e866e40b95795203f3ee46f44a197c946e4stevel ((void)((EXP) || (croak(DEBUG_ID ": " MSG), 0), 0))
29949e866e40b95795203f3ee46f44a197c946e4stevel#else
29949e866e40b95795203f3ee46f44a197c946e4stevel#define PERL_ASSERT(EXP) ((void)0)
29949e866e40b95795203f3ee46f44a197c946e4stevel#define PERL_ASSERTMSG(EXP, MSG) ((void)0)
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/* Macros for saving the contents of KSTAT_RAW structures */
29949e866e40b95795203f3ee46f44a197c946e4stevel#if defined(HAS_QUAD) && defined(USE_64_BIT_INT)
29949e866e40b95795203f3ee46f44a197c946e4stevel#define NEW_IV(V) \
29949e866e40b95795203f3ee46f44a197c946e4stevel (newSViv((IVTYPE) V))
29949e866e40b95795203f3ee46f44a197c946e4stevel#define NEW_UV(V) \
29949e866e40b95795203f3ee46f44a197c946e4stevel (newSVuv((UVTYPE) V))
29949e866e40b95795203f3ee46f44a197c946e4stevel#else
29949e866e40b95795203f3ee46f44a197c946e4stevel#define NEW_IV(V) \
29949e866e40b95795203f3ee46f44a197c946e4stevel (V >= IV_MIN && V <= IV_MAX ? newSViv((IVTYPE) V) : newSVnv((NVTYPE) V))
29949e866e40b95795203f3ee46f44a197c946e4stevel#if defined(UVTYPE)
29949e866e40b95795203f3ee46f44a197c946e4stevel#define NEW_UV(V) \
29949e866e40b95795203f3ee46f44a197c946e4stevel (V <= UV_MAX ? newSVuv((UVTYPE) V) : newSVnv((NVTYPE) V))
29949e866e40b95795203f3ee46f44a197c946e4stevel# else
29949e866e40b95795203f3ee46f44a197c946e4stevel#define NEW_UV(V) \
29949e866e40b95795203f3ee46f44a197c946e4stevel (V <= IV_MAX ? newSViv((IVTYPE) V) : newSVnv((NVTYPE) V))
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif
29949e866e40b95795203f3ee46f44a197c946e4stevel#define NEW_HRTIME(V) \
29949e866e40b95795203f3ee46f44a197c946e4stevel newSVnv((NVTYPE) (V / 1000000000.0))
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#define SAVE_FNP(H, F, K) \
b30a53d02d9bc370d76b8125a98e34311c768b5eRichard Lowe hv_store(H, K, sizeof (K) - 1, newSViv((IVTYPE)(uintptr_t)&F), 0)
29949e866e40b95795203f3ee46f44a197c946e4stevel#define SAVE_STRING(H, S, K, SS) \
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(H, #K, sizeof (#K) - 1, \
29949e866e40b95795203f3ee46f44a197c946e4stevel newSVpvn(S->K, SS ? strlen(S->K) : sizeof(S->K)), 0)
29949e866e40b95795203f3ee46f44a197c946e4stevel#define SAVE_INT32(H, S, K) \
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(H, #K, sizeof (#K) - 1, NEW_IV(S->K), 0)
29949e866e40b95795203f3ee46f44a197c946e4stevel#define SAVE_UINT32(H, S, K) \
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(H, #K, sizeof (#K) - 1, NEW_UV(S->K), 0)
29949e866e40b95795203f3ee46f44a197c946e4stevel#define SAVE_INT64(H, S, K) \
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(H, #K, sizeof (#K) - 1, NEW_IV(S->K), 0)
29949e866e40b95795203f3ee46f44a197c946e4stevel#define SAVE_UINT64(H, S, K) \
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(H, #K, sizeof (#K) - 1, NEW_UV(S->K), 0)
29949e866e40b95795203f3ee46f44a197c946e4stevel#define SAVE_HRTIME(H, S, K) \
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(H, #K, sizeof (#K) - 1, NEW_HRTIME(S->K), 0)
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/* Private structure used for saving kstat info in the tied hashes */
29949e866e40b95795203f3ee46f44a197c946e4steveltypedef struct {
29949e866e40b95795203f3ee46f44a197c946e4stevel char read; /* Kstat block has been read before */
29949e866e40b95795203f3ee46f44a197c946e4stevel char valid; /* Kstat still exists in kstat chain */
29949e866e40b95795203f3ee46f44a197c946e4stevel char strip_str; /* Strip KSTAT_DATA_CHAR fields */
29949e866e40b95795203f3ee46f44a197c946e4stevel kstat_ctl_t *kstat_ctl; /* Handle returned by kstat_open */
29949e866e40b95795203f3ee46f44a197c946e4stevel kstat_t *kstat; /* Handle used by kstat_read */
29949e866e40b95795203f3ee46f44a197c946e4stevel} KstatInfo_t;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/* typedef for apply_to_ties callback functions */
29949e866e40b95795203f3ee46f44a197c946e4steveltypedef int (*ATTCb_t)(HV *, void *);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/* typedef for raw kstat reader functions */
29949e866e40b95795203f3ee46f44a197c946e4steveltypedef void (*kstat_raw_reader_t)(HV *, kstat_t *, int);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/* Hash of "module:name" to KSTAT_RAW read functions */
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic HV *raw_kstat_lookup;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Kstats come in two flavours, named and raw. Raw kstats are just C structs,
29949e866e40b95795203f3ee46f44a197c946e4stevel * so we need a function per raw kstat to convert the C struct into the
29949e866e40b95795203f3ee46f44a197c946e4stevel * corresponding perl hash. All such conversion functions are in the following
29949e866e40b95795203f3ee46f44a197c946e4stevel * section.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Definitions in /usr/include/sys/cpuvar.h and /usr/include/sys/sysinfo.h
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsave_cpu_stat(HV *self, kstat_t *kp, int strip_str)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel cpu_stat_t *statp;
29949e866e40b95795203f3ee46f44a197c946e4stevel cpu_sysinfo_t *sysinfop;
29949e866e40b95795203f3ee46f44a197c946e4stevel cpu_syswait_t *syswaitp;
29949e866e40b95795203f3ee46f44a197c946e4stevel cpu_vminfo_t *vminfop;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* PERL_ASSERT(kp->ks_ndata == 1); */
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERT(kp->ks_data_size == sizeof (cpu_stat_t));
29949e866e40b95795203f3ee46f44a197c946e4stevel statp = (cpu_stat_t *)(kp->ks_data);
29949e866e40b95795203f3ee46f44a197c946e4stevel sysinfop = &statp->cpu_sysinfo;
29949e866e40b95795203f3ee46f44a197c946e4stevel syswaitp = &statp->cpu_syswait;
29949e866e40b95795203f3ee46f44a197c946e4stevel vminfop = &statp->cpu_vminfo;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "idle", 4, NEW_UV(sysinfop->cpu[CPU_IDLE]), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "user", 4, NEW_UV(sysinfop->cpu[CPU_USER]), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "kernel", 6, NEW_UV(sysinfop->cpu[CPU_KERNEL]), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "wait", 4, NEW_UV(sysinfop->cpu[CPU_WAIT]), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "wait_io", 7, NEW_UV(sysinfop->wait[W_IO]), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "wait_swap", 9, NEW_UV(sysinfop->wait[W_SWAP]), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "wait_pio", 8, NEW_UV(sysinfop->wait[W_PIO]), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, bread);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, bwrite);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, lread);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, lwrite);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, phread);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, phwrite);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, pswitch);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, trap);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, intr);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, syscall);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, sysread);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, syswrite);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, sysfork);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, sysvfork);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, sysexec);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, readch);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, writech);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, rcvint);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, xmtint);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, mdmint);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, rawch);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, canch);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, outch);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, msg);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, sema);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, namei);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, ufsiget);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, ufsdirblk);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, ufsipage);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, ufsinopage);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, inodeovf);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, fileovf);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, procovf);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, intrthread);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, intrblk);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, idlethread);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, inv_swtch);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, nthreads);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, cpumigrate);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, xcalls);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, mutex_adenters);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, rw_rdfails);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, rw_wrfails);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, modload);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, modunload);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, bawrite);
29949e866e40b95795203f3ee46f44a197c946e4stevel#ifdef STATISTICS /* see header file */
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, rw_enters);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, win_uo_cnt);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, win_uu_cnt);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, win_so_cnt);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, win_su_cnt);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, win_suo_cnt);
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, syswaitp, iowait);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, syswaitp, swap);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, syswaitp, physio);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, pgrec);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, pgfrec);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, pgin);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, pgpgin);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, pgout);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, pgpgout);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, swapin);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, pgswapin);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, swapout);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, pgswapout);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, zfod);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, dfree);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, scan);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, rev);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, hat_fault);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, as_fault);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, maj_fault);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, cow_fault);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, prot_fault);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, softlock);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, kernel_asflt);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, pgrrun);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, execpgin);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, execpgout);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, execfree);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, anonpgin);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, anonpgout);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, anonfree);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, fspgin);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, fspgout);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, vminfop, fsfree);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Definitions in /usr/include/sys/var.h
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsave_var(HV *self, kstat_t *kp, int strip_str)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel struct var *varp;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* PERL_ASSERT(kp->ks_ndata == 1); */
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERT(kp->ks_data_size == sizeof (struct var));
29949e866e40b95795203f3ee46f44a197c946e4stevel varp = (struct var *)(kp->ks_data);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, varp, v_buf);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, varp, v_call);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, varp, v_proc);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, varp, v_maxupttl);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, varp, v_nglobpris);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, varp, v_maxsyspri);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, varp, v_clist);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, varp, v_maxup);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, varp, v_hbuf);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, varp, v_hmask);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, varp, v_pbuf);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, varp, v_sptmap);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, varp, v_maxpmem);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, varp, v_autoup);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, varp, v_bufhwm);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Definition in /usr/include/sys/dnlc.h
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsave_ncstats(HV *self, kstat_t *kp, int strip_str)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel struct ncstats *ncstatsp;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* PERL_ASSERT(kp->ks_ndata == 1); */
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERT(kp->ks_data_size == sizeof (struct ncstats));
29949e866e40b95795203f3ee46f44a197c946e4stevel ncstatsp = (struct ncstats *)(kp->ks_data);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, ncstatsp, hits);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, ncstatsp, misses);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, ncstatsp, enters);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, ncstatsp, dbl_enters);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, ncstatsp, long_enter);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, ncstatsp, long_look);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, ncstatsp, move_to_front);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, ncstatsp, purges);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Definition in /usr/include/sys/sysinfo.h
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsave_sysinfo(HV *self, kstat_t *kp, int strip_str)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel sysinfo_t *sysinfop;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* PERL_ASSERT(kp->ks_ndata == 1); */
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERT(kp->ks_data_size == sizeof (sysinfo_t));
29949e866e40b95795203f3ee46f44a197c946e4stevel sysinfop = (sysinfo_t *)(kp->ks_data);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, updates);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, runque);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, runocc);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, swpque);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, swpocc);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, sysinfop, waiting);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Definition in /usr/include/sys/sysinfo.h
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsave_vminfo(HV *self, kstat_t *kp, int strip_str)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel vminfo_t *vminfop;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* PERL_ASSERT(kp->ks_ndata == 1); */
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERT(kp->ks_data_size == sizeof (vminfo_t));
29949e866e40b95795203f3ee46f44a197c946e4stevel vminfop = (vminfo_t *)(kp->ks_data);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT64(self, vminfop, freemem);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT64(self, vminfop, swap_resv);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT64(self, vminfop, swap_alloc);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT64(self, vminfop, swap_avail);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT64(self, vminfop, swap_free);
0956b730cfe26e3bfd5e8ed9c1527c0e3111b93cMike Harsch SAVE_UINT64(self, vminfop, updates);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Definition in /usr/include/nfs/nfs_clnt.h
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsave_nfs(HV *self, kstat_t *kp, int strip_str)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel struct mntinfo_kstat *mntinfop;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* PERL_ASSERT(kp->ks_ndata == 1); */
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERT(kp->ks_data_size == sizeof (struct mntinfo_kstat));
29949e866e40b95795203f3ee46f44a197c946e4stevel mntinfop = (struct mntinfo_kstat *)(kp->ks_data);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_STRING(self, mntinfop, mik_proto, strip_str);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, mntinfop, mik_vers);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, mntinfop, mik_flags);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, mntinfop, mik_secmod);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, mntinfop, mik_curread);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, mntinfop, mik_curwrite);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, mntinfop, mik_timeo);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, mntinfop, mik_retrans);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, mntinfop, mik_acregmin);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, mntinfop, mik_acregmax);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, mntinfop, mik_acdirmin);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, mntinfop, mik_acdirmax);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "lookup_srtt", 11,
29949e866e40b95795203f3ee46f44a197c946e4stevel NEW_UV(mntinfop->mik_timers[0].srtt), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "lookup_deviate", 14,
29949e866e40b95795203f3ee46f44a197c946e4stevel NEW_UV(mntinfop->mik_timers[0].deviate), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "lookup_rtxcur", 13,
29949e866e40b95795203f3ee46f44a197c946e4stevel NEW_UV(mntinfop->mik_timers[0].rtxcur), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "read_srtt", 9,
29949e866e40b95795203f3ee46f44a197c946e4stevel NEW_UV(mntinfop->mik_timers[1].srtt), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "read_deviate", 12,
29949e866e40b95795203f3ee46f44a197c946e4stevel NEW_UV(mntinfop->mik_timers[1].deviate), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "read_rtxcur", 11,
29949e866e40b95795203f3ee46f44a197c946e4stevel NEW_UV(mntinfop->mik_timers[1].rtxcur), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "write_srtt", 10,
29949e866e40b95795203f3ee46f44a197c946e4stevel NEW_UV(mntinfop->mik_timers[2].srtt), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "write_deviate", 13,
29949e866e40b95795203f3ee46f44a197c946e4stevel NEW_UV(mntinfop->mik_timers[2].deviate), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "write_rtxcur", 12,
29949e866e40b95795203f3ee46f44a197c946e4stevel NEW_UV(mntinfop->mik_timers[2].rtxcur), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, mntinfop, mik_noresponse);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, mntinfop, mik_failover);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, mntinfop, mik_remap);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_STRING(self, mntinfop, mik_curserver, strip_str);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * The following struct => hash functions are all only present on the sparc
29949e866e40b95795203f3ee46f44a197c946e4stevel * platform, so they are all conditionally compiled depending on __sparc
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Definition in /usr/platform/sun4u/include/vm/hat_sfmmu.h
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#ifdef __sparc
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsave_sfmmu_global_stat(HV *self, kstat_t *kp, int strip_str)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel struct sfmmu_global_stat *sfmmugp;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* PERL_ASSERT(kp->ks_ndata == 1); */
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERT(kp->ks_data_size == sizeof (struct sfmmu_global_stat));
29949e866e40b95795203f3ee46f44a197c946e4stevel sfmmugp = (struct sfmmu_global_stat *)(kp->ks_data);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_tsb_exceptions);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_tsb_raise_exception);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_pagefaults);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_uhash_searches);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_uhash_links);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_khash_searches);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_khash_links);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_swapout);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_tsb_alloc);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_tsb_allocfail);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_tsb_sectsb_create);
05d3dc4b6755c54754109ffbe7e792f4e5b7c7c9paulsan SAVE_INT32(self, sfmmugp, sf_scd_1sttsb_alloc);
05d3dc4b6755c54754109ffbe7e792f4e5b7c7c9paulsan SAVE_INT32(self, sfmmugp, sf_scd_2ndtsb_alloc);
05d3dc4b6755c54754109ffbe7e792f4e5b7c7c9paulsan SAVE_INT32(self, sfmmugp, sf_scd_1sttsb_allocfail);
05d3dc4b6755c54754109ffbe7e792f4e5b7c7c9paulsan SAVE_INT32(self, sfmmugp, sf_scd_2ndtsb_allocfail);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_tteload8k);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_tteload64k);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_tteload512k);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_tteload4m);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_tteload32m);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_tteload256m);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_tsb_load8k);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_tsb_load4m);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_hblk_hit);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_hblk8_ncreate);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_hblk8_nalloc);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_hblk1_ncreate);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_hblk1_nalloc);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_hblk_slab_cnt);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_hblk_reserve_cnt);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_hblk_recurse_cnt);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_hblk_reserve_hit);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_get_free_success);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_get_free_throttle);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_get_free_fail);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_put_free_success);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_put_free_fail);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_pgcolor_conflict);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_uncache_conflict);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_unload_conflict);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_ism_uncache);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_ism_recache);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_recache);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_steal_count);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_pagesync);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_clrwrt);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_pagesync_invalid);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_kernel_xcalls);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_user_xcalls);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_tsb_grow);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_tsb_shrink);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_tsb_resize_failures);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_tsb_reloc);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_user_vtop);
1e2e7a75ddb1eedcefa449ce98fd5862749b72eehuah SAVE_INT32(self, sfmmugp, sf_ctx_inv);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmugp, sf_tlb_reprog_pgsz);
05d3dc4b6755c54754109ffbe7e792f4e5b7c7c9paulsan SAVE_INT32(self, sfmmugp, sf_region_remap_demap);
05d3dc4b6755c54754109ffbe7e792f4e5b7c7c9paulsan SAVE_INT32(self, sfmmugp, sf_create_scd);
05d3dc4b6755c54754109ffbe7e792f4e5b7c7c9paulsan SAVE_INT32(self, sfmmugp, sf_join_scd);
05d3dc4b6755c54754109ffbe7e792f4e5b7c7c9paulsan SAVE_INT32(self, sfmmugp, sf_leave_scd);
05d3dc4b6755c54754109ffbe7e792f4e5b7c7c9paulsan SAVE_INT32(self, sfmmugp, sf_destroy_scd);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Definition in /usr/platform/sun4u/include/vm/hat_sfmmu.h
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#ifdef __sparc
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsave_sfmmu_tsbsize_stat(HV *self, kstat_t *kp, int strip_str)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel struct sfmmu_tsbsize_stat *sfmmutp;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* PERL_ASSERT(kp->ks_ndata == 1); */
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERT(kp->ks_data_size == sizeof (struct sfmmu_tsbsize_stat));
29949e866e40b95795203f3ee46f44a197c946e4stevel sfmmutp = (struct sfmmu_tsbsize_stat *)(kp->ks_data);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmutp, sf_tsbsz_8k);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmutp, sf_tsbsz_16k);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmutp, sf_tsbsz_32k);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmutp, sf_tsbsz_64k);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmutp, sf_tsbsz_128k);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmutp, sf_tsbsz_256k);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmutp, sf_tsbsz_512k);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmutp, sf_tsbsz_1m);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmutp, sf_tsbsz_2m);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, sfmmutp, sf_tsbsz_4m);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Definition in /usr/platform/sun4u/include/sys/simmstat.h
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#ifdef __sparc
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsave_simmstat(HV *self, kstat_t *kp, int strip_str)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel uchar_t *simmstatp;
29949e866e40b95795203f3ee46f44a197c946e4stevel SV *list;
29949e866e40b95795203f3ee46f44a197c946e4stevel int i;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* PERL_ASSERT(kp->ks_ndata == 1); */
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERT(kp->ks_data_size == sizeof (uchar_t) * SIMM_COUNT);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel list = newSVpv("", 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel for (i = 0, simmstatp = (uchar_t *)(kp->ks_data);
29949e866e40b95795203f3ee46f44a197c946e4stevel i < SIMM_COUNT - 1; i++, simmstatp++) {
29949e866e40b95795203f3ee46f44a197c946e4stevel sv_catpvf(list, "%d,", *simmstatp);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel sv_catpvf(list, "%d", *simmstatp);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "status", 6, list, 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Used by save_temperature to make CSV lists from arrays of
29949e866e40b95795203f3ee46f44a197c946e4stevel * short temperature values
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#ifdef __sparc
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic SV *
29949e866e40b95795203f3ee46f44a197c946e4stevelshort_array_to_SV(short *shortp, int len)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel SV *list;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel list = newSVpv("", 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel for (; len > 1; len--, shortp++) {
29949e866e40b95795203f3ee46f44a197c946e4stevel sv_catpvf(list, "%d,", *shortp);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel sv_catpvf(list, "%d", *shortp);
29949e866e40b95795203f3ee46f44a197c946e4stevel return (list);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Definition in /usr/platform/sun4u/include/sys/fhc.h
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsave_temperature(HV *self, kstat_t *kp, int strip_str)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel struct temp_stats *tempsp;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* PERL_ASSERT(kp->ks_ndata == 1); */
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERT(kp->ks_data_size == sizeof (struct temp_stats));
29949e866e40b95795203f3ee46f44a197c946e4stevel tempsp = (struct temp_stats *)(kp->ks_data);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, tempsp, index);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "l1", 2, short_array_to_SV(tempsp->l1, L1_SZ), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "l2", 2, short_array_to_SV(tempsp->l2, L2_SZ), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "l3", 2, short_array_to_SV(tempsp->l3, L3_SZ), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "l4", 2, short_array_to_SV(tempsp->l4, L4_SZ), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "l5", 2, short_array_to_SV(tempsp->l5, L5_SZ), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, tempsp, max);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, tempsp, min);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, tempsp, state);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, tempsp, temp_cnt);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, tempsp, shutdown_cnt);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, tempsp, version);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, tempsp, trend);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_INT32(self, tempsp, override);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Not actually defined anywhere - just a short. Yuck.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#ifdef __sparc
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsave_temp_over(HV *self, kstat_t *kp, int strip_str)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel short *shortp;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* PERL_ASSERT(kp->ks_ndata == 1); */
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERT(kp->ks_data_size == sizeof (short));
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel shortp = (short *)(kp->ks_data);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "override", 8, newSViv(*shortp), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Defined in /usr/platform/sun4u/include/sys/sysctrl.h
29949e866e40b95795203f3ee46f44a197c946e4stevel * (Well, sort of. Actually there's no structure, just a list of #defines
29949e866e40b95795203f3ee46f44a197c946e4stevel * enumerating *some* of the array indexes.)
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#ifdef __sparc
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsave_ps_shadow(HV *self, kstat_t *kp, int strip_str)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel uchar_t *ucharp;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* PERL_ASSERT(kp->ks_ndata == 1); */
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERT(kp->ks_data_size == SYS_PS_COUNT);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel ucharp = (uchar_t *)(kp->ks_data);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "core_0", 6, newSViv(*ucharp++), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "core_1", 6, newSViv(*ucharp++), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "core_2", 6, newSViv(*ucharp++), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "core_3", 6, newSViv(*ucharp++), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "core_4", 6, newSViv(*ucharp++), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "core_5", 6, newSViv(*ucharp++), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "core_6", 6, newSViv(*ucharp++), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "core_7", 6, newSViv(*ucharp++), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "pps_0", 5, newSViv(*ucharp++), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "clk_33", 6, newSViv(*ucharp++), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "clk_50", 6, newSViv(*ucharp++), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "v5_p", 4, newSViv(*ucharp++), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "v12_p", 5, newSViv(*ucharp++), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "v5_aux", 6, newSViv(*ucharp++), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "v5_p_pch", 8, newSViv(*ucharp++), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "v12_p_pch", 9, newSViv(*ucharp++), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "v3_pch", 6, newSViv(*ucharp++), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "v5_pch", 6, newSViv(*ucharp++), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "p_fan", 5, newSViv(*ucharp++), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Definition in /usr/platform/sun4u/include/sys/fhc.h
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel#ifdef __sparc
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsave_fault_list(HV *self, kstat_t *kp, int strip_str)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel struct ft_list *faultp;
29949e866e40b95795203f3ee46f44a197c946e4stevel int i;
29949e866e40b95795203f3ee46f44a197c946e4stevel char name[KSTAT_STRLEN + 7]; /* room for 999999 faults */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* PERL_ASSERT(kp->ks_ndata == 1); */
29949e866e40b95795203f3ee46f44a197c946e4stevel /* PERL_ASSERT(kp->ks_data_size == sizeof (struct ft_list)); */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel for (i = 1, faultp = (struct ft_list *)(kp->ks_data);
29949e866e40b95795203f3ee46f44a197c946e4stevel i <= 999999 && i <= kp->ks_data_size / sizeof (struct ft_list);
29949e866e40b95795203f3ee46f44a197c946e4stevel i++, faultp++) {
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) snprintf(name, sizeof (name), "unit_%d", i);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, name, strlen(name), newSViv(faultp->unit), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) snprintf(name, sizeof (name), "type_%d", i);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, name, strlen(name), newSViv(faultp->type), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) snprintf(name, sizeof (name), "fclass_%d", i);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, name, strlen(name), newSViv(faultp->fclass), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) snprintf(name, sizeof (name), "create_time_%d", i);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, name, strlen(name),
29949e866e40b95795203f3ee46f44a197c946e4stevel NEW_UV(faultp->create_time), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) snprintf(name, sizeof (name), "msg_%d", i);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, name, strlen(name), newSVpv(faultp->msg, 0), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * We need to be able to find the function corresponding to a particular raw
29949e866e40b95795203f3ee46f44a197c946e4stevel * kstat. To do this we ignore the instance and glue the module and name
29949e866e40b95795203f3ee46f44a197c946e4stevel * together to form a composite key. We can then use the data in the kstat
29949e866e40b95795203f3ee46f44a197c946e4stevel * structure to find the appropriate function. We use a perl hash to manage the
29949e866e40b95795203f3ee46f44a197c946e4stevel * lookup, where the key is "module:name" and the value is a pointer to the
29949e866e40b95795203f3ee46f44a197c946e4stevel * appropriate C function.
29949e866e40b95795203f3ee46f44a197c946e4stevel *
29949e866e40b95795203f3ee46f44a197c946e4stevel * Note that some kstats include the instance number as part of the module
29949e866e40b95795203f3ee46f44a197c946e4stevel * and/or name. This could be construed as a bug. However, to work around this
29949e866e40b95795203f3ee46f44a197c946e4stevel * we omit any digits from the module and name as we build the table in
29949e866e40b95795203f3ee46f44a197c946e4stevel * build_raw_kstat_loopup(), and we remove any digits from the module and name
29949e866e40b95795203f3ee46f44a197c946e4stevel * when we look up the functions in lookup_raw_kstat_fn()
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * This function is called when the XS is first dlopen()ed, and builds the
29949e866e40b95795203f3ee46f44a197c946e4stevel * lookup table as described above.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelbuild_raw_kstat_lookup()
29949e866e40b95795203f3ee46f44a197c946e4stevel {
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Create new hash */
29949e866e40b95795203f3ee46f44a197c946e4stevel raw_kstat_lookup = newHV();
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_FNP(raw_kstat_lookup, save_cpu_stat, "cpu_stat:cpu_stat");
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_FNP(raw_kstat_lookup, save_var, "unix:var");
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_FNP(raw_kstat_lookup, save_ncstats, "unix:ncstats");
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_FNP(raw_kstat_lookup, save_sysinfo, "unix:sysinfo");
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_FNP(raw_kstat_lookup, save_vminfo, "unix:vminfo");
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_FNP(raw_kstat_lookup, save_nfs, "nfs:mntinfo");
29949e866e40b95795203f3ee46f44a197c946e4stevel#ifdef __sparc
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_FNP(raw_kstat_lookup, save_sfmmu_global_stat,
29949e866e40b95795203f3ee46f44a197c946e4stevel "unix:sfmmu_global_stat");
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_FNP(raw_kstat_lookup, save_sfmmu_tsbsize_stat,
29949e866e40b95795203f3ee46f44a197c946e4stevel "unix:sfmmu_tsbsize_stat");
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_FNP(raw_kstat_lookup, save_simmstat, "unix:simm-status");
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_FNP(raw_kstat_lookup, save_temperature, "unix:temperature");
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_FNP(raw_kstat_lookup, save_temp_over, "unix:temperature override");
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_FNP(raw_kstat_lookup, save_ps_shadow, "unix:ps_shadow");
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_FNP(raw_kstat_lookup, save_fault_list, "unix:fault_list");
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * This finds and returns the raw kstat reader function corresponding to the
29949e866e40b95795203f3ee46f44a197c946e4stevel * supplied module and name. If no matching function exists, 0 is returned.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic kstat_raw_reader_t lookup_raw_kstat_fn(char *module, char *name)
29949e866e40b95795203f3ee46f44a197c946e4stevel {
29949e866e40b95795203f3ee46f44a197c946e4stevel char key[KSTAT_STRLEN * 2];
29949e866e40b95795203f3ee46f44a197c946e4stevel register char *f, *t;
29949e866e40b95795203f3ee46f44a197c946e4stevel SV **entry;
29949e866e40b95795203f3ee46f44a197c946e4stevel kstat_raw_reader_t fnp;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Copy across module & name, removing any digits - see comment above */
29949e866e40b95795203f3ee46f44a197c946e4stevel for (f = module, t = key; *f != '\0'; f++, t++) {
29949e866e40b95795203f3ee46f44a197c946e4stevel while (*f != '\0' && isdigit(*f)) { f++; }
29949e866e40b95795203f3ee46f44a197c946e4stevel *t = *f;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel *t++ = ':';
29949e866e40b95795203f3ee46f44a197c946e4stevel for (f = name; *f != '\0'; f++, t++) {
29949e866e40b95795203f3ee46f44a197c946e4stevel while (*f != '\0' && isdigit(*f)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel f++;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel *t = *f;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel *t = '\0';
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* look up & return the function, or teturn 0 if not found */
29949e866e40b95795203f3ee46f44a197c946e4stevel if ((entry = hv_fetch(raw_kstat_lookup, key, strlen(key), FALSE)) == 0)
29949e866e40b95795203f3ee46f44a197c946e4stevel {
29949e866e40b95795203f3ee46f44a197c946e4stevel fnp = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel fnp = (kstat_raw_reader_t)(uintptr_t)SvIV(*entry);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel return (fnp);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * This module converts the flat list returned by kstat_read() into a perl hash
29949e866e40b95795203f3ee46f44a197c946e4stevel * tree keyed on module, instance, name and statistic. The following functions
29949e866e40b95795203f3ee46f44a197c946e4stevel * provide code to create the nested hashes, and to iterate over them.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Given module, instance and name keys return a pointer to the hash tied to
29949e866e40b95795203f3ee46f44a197c946e4stevel * the bottommost hash. If the hash already exists, we just return a pointer
29949e866e40b95795203f3ee46f44a197c946e4stevel * to it, otherwise we create the hash and any others also required above it in
29949e866e40b95795203f3ee46f44a197c946e4stevel * the hierarchy. The returned tiehash is blessed into the
29949e866e40b95795203f3ee46f44a197c946e4stevel * Sun::Solaris::Kstat::_Stat class, so that the appropriate TIEHASH methods are
29949e866e40b95795203f3ee46f44a197c946e4stevel * called when the bottommost hash is accessed. If the is_new parameter is
29949e866e40b95795203f3ee46f44a197c946e4stevel * non-null it will be set to TRUE if a new tie has been created, and FALSE if
29949e866e40b95795203f3ee46f44a197c946e4stevel * the tie already existed.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic HV *
29949e866e40b95795203f3ee46f44a197c946e4stevelget_tie(SV *self, char *module, int instance, char *name, int *is_new)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel char str_inst[11]; /* big enough for up to 10^10 instances */
29949e866e40b95795203f3ee46f44a197c946e4stevel char *key[3]; /* 3 part key: module, instance, name */
29949e866e40b95795203f3ee46f44a197c946e4stevel int k;
29949e866e40b95795203f3ee46f44a197c946e4stevel int new;
29949e866e40b95795203f3ee46f44a197c946e4stevel HV *hash;
29949e866e40b95795203f3ee46f44a197c946e4stevel HV *tie;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Create the keys */
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) snprintf(str_inst, sizeof (str_inst), "%d", instance);
29949e866e40b95795203f3ee46f44a197c946e4stevel key[0] = module;
29949e866e40b95795203f3ee46f44a197c946e4stevel key[1] = str_inst;
29949e866e40b95795203f3ee46f44a197c946e4stevel key[2] = name;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Iteratively descend the tree, creating new hashes as required */
29949e866e40b95795203f3ee46f44a197c946e4stevel hash = (HV *)SvRV(self);
29949e866e40b95795203f3ee46f44a197c946e4stevel for (k = 0; k < 3; k++) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SV **entry;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel SvREADONLY_off(hash);
29949e866e40b95795203f3ee46f44a197c946e4stevel entry = hv_fetch(hash, key[k], strlen(key[k]), TRUE);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* If the entry doesn't exist, create it */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (! SvOK(*entry)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel HV *newhash;
29949e866e40b95795203f3ee46f44a197c946e4stevel SV *rv;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel newhash = newHV();
29949e866e40b95795203f3ee46f44a197c946e4stevel rv = newRV_noinc((SV *)newhash);
29949e866e40b95795203f3ee46f44a197c946e4stevel sv_setsv(*entry, rv);
29949e866e40b95795203f3ee46f44a197c946e4stevel SvREFCNT_dec(rv);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (k < 2) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SvREADONLY_on(newhash);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel SvREADONLY_on(*entry);
29949e866e40b95795203f3ee46f44a197c946e4stevel SvREADONLY_on(hash);
29949e866e40b95795203f3ee46f44a197c946e4stevel hash = newhash;
29949e866e40b95795203f3ee46f44a197c946e4stevel new = 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Otherwise it already existed */
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel SvREADONLY_on(hash);
29949e866e40b95795203f3ee46f44a197c946e4stevel hash = (HV *)SvRV(*entry);
29949e866e40b95795203f3ee46f44a197c946e4stevel new = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Create and bless a hash for the tie, if necessary */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (new) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SV *tieref;
29949e866e40b95795203f3ee46f44a197c946e4stevel HV *stash;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel tie = newHV();
29949e866e40b95795203f3ee46f44a197c946e4stevel tieref = newRV_noinc((SV *)tie);
29949e866e40b95795203f3ee46f44a197c946e4stevel stash = gv_stashpv("Sun::Solaris::Kstat::_Stat", TRUE);
29949e866e40b95795203f3ee46f44a197c946e4stevel sv_bless(tieref, stash);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Add TIEHASH magic */
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_magic(hash, (GV *)tieref, 'P');
29949e866e40b95795203f3ee46f44a197c946e4stevel SvREADONLY_on(hash);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Otherwise, just find the existing tied hash */
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel MAGIC *mg;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel mg = mg_find((SV *)hash, 'P');
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERTMSG(mg != 0, "get_tie: lost P magic");
29949e866e40b95795203f3ee46f44a197c946e4stevel tie = (HV *)SvRV(mg->mg_obj);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel if (is_new) {
29949e866e40b95795203f3ee46f44a197c946e4stevel *is_new = new;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel return (tie);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * This is an iterator function used to traverse the hash hierarchy and apply
29949e866e40b95795203f3ee46f44a197c946e4stevel * the passed function to the tied hashes at the bottom of the hierarchy. If
29949e866e40b95795203f3ee46f44a197c946e4stevel * any of the callback functions return 0, 0 is returned, otherwise 1
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int
29949e866e40b95795203f3ee46f44a197c946e4stevelapply_to_ties(SV *self, ATTCb_t cb, void *arg)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel HV *hash1;
29949e866e40b95795203f3ee46f44a197c946e4stevel HE *entry1;
29949e866e40b95795203f3ee46f44a197c946e4stevel int ret;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel hash1 = (HV *)SvRV(self);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_iterinit(hash1);
29949e866e40b95795203f3ee46f44a197c946e4stevel ret = 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Iterate over each module */
c9f77c52c0735e65aa2534394c5151cdb963cbefAndy Stormont while ((entry1 = hv_iternext(hash1))) {
29949e866e40b95795203f3ee46f44a197c946e4stevel HV *hash2;
29949e866e40b95795203f3ee46f44a197c946e4stevel HE *entry2;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel hash2 = (HV *)SvRV(hv_iterval(hash1, entry1));
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_iterinit(hash2);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Iterate over each module:instance */
c9f77c52c0735e65aa2534394c5151cdb963cbefAndy Stormont while ((entry2 = hv_iternext(hash2))) {
29949e866e40b95795203f3ee46f44a197c946e4stevel HV *hash3;
29949e866e40b95795203f3ee46f44a197c946e4stevel HE *entry3;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel hash3 = (HV *)SvRV(hv_iterval(hash2, entry2));
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_iterinit(hash3);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Iterate over each module:instance:name */
c9f77c52c0735e65aa2534394c5151cdb963cbefAndy Stormont while ((entry3 = hv_iternext(hash3))) {
29949e866e40b95795203f3ee46f44a197c946e4stevel HV *hash4;
29949e866e40b95795203f3ee46f44a197c946e4stevel MAGIC *mg;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Get the tie */
29949e866e40b95795203f3ee46f44a197c946e4stevel hash4 = (HV *)SvRV(hv_iterval(hash3, entry3));
29949e866e40b95795203f3ee46f44a197c946e4stevel mg = mg_find((SV *)hash4, 'P');
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERTMSG(mg != 0,
29949e866e40b95795203f3ee46f44a197c946e4stevel "apply_to_ties: lost P magic");
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Apply the callback */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (! cb((HV *)SvRV(mg->mg_obj), arg)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel ret = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel return (ret);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Mark this HV as valid - used by update() when pruning deleted kstat nodes
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int
29949e866e40b95795203f3ee46f44a197c946e4stevelset_valid(HV *self, void *arg)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel MAGIC *mg;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel mg = mg_find((SV *)self, '~');
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERTMSG(mg != 0, "set_valid: lost ~ magic");
81ec5430b8d8c635b14871820f7667e220c3db2cTheo Schlossnagle ((KstatInfo_t *)SvPVX(mg->mg_obj))->valid = (int)(intptr_t)arg;
29949e866e40b95795203f3ee46f44a197c946e4stevel return (1);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Prune invalid kstat nodes. This is called when kstat_chain_update() detects
29949e866e40b95795203f3ee46f44a197c946e4stevel * that the kstat chain has been updated. This removes any hash tree entries
29949e866e40b95795203f3ee46f44a197c946e4stevel * that no longer have a corresponding kstat. If del is non-null it will be
29949e866e40b95795203f3ee46f44a197c946e4stevel * set to the keys of the deleted kstat nodes, if any. If any entries are
29949e866e40b95795203f3ee46f44a197c946e4stevel * deleted 1 will be retured, otherwise 0
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int
29949e866e40b95795203f3ee46f44a197c946e4stevelprune_invalid(SV *self, AV *del)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel HV *hash1;
29949e866e40b95795203f3ee46f44a197c946e4stevel HE *entry1;
29949e866e40b95795203f3ee46f44a197c946e4stevel STRLEN klen;
29949e866e40b95795203f3ee46f44a197c946e4stevel char *module, *instance, *name, *key;
29949e866e40b95795203f3ee46f44a197c946e4stevel int ret;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel hash1 = (HV *)SvRV(self);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_iterinit(hash1);
29949e866e40b95795203f3ee46f44a197c946e4stevel ret = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Iterate over each module */
c9f77c52c0735e65aa2534394c5151cdb963cbefAndy Stormont while ((entry1 = hv_iternext(hash1))) {
29949e866e40b95795203f3ee46f44a197c946e4stevel HV *hash2;
29949e866e40b95795203f3ee46f44a197c946e4stevel HE *entry2;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel module = HePV(entry1, PL_na);
29949e866e40b95795203f3ee46f44a197c946e4stevel hash2 = (HV *)SvRV(hv_iterval(hash1, entry1));
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_iterinit(hash2);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Iterate over each module:instance */
c9f77c52c0735e65aa2534394c5151cdb963cbefAndy Stormont while ((entry2 = hv_iternext(hash2))) {
29949e866e40b95795203f3ee46f44a197c946e4stevel HV *hash3;
29949e866e40b95795203f3ee46f44a197c946e4stevel HE *entry3;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel instance = HePV(entry2, PL_na);
29949e866e40b95795203f3ee46f44a197c946e4stevel hash3 = (HV *)SvRV(hv_iterval(hash2, entry2));
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_iterinit(hash3);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Iterate over each module:instance:name */
c9f77c52c0735e65aa2534394c5151cdb963cbefAndy Stormont while ((entry3 = hv_iternext(hash3))) {
29949e866e40b95795203f3ee46f44a197c946e4stevel HV *hash4;
29949e866e40b95795203f3ee46f44a197c946e4stevel MAGIC *mg;
29949e866e40b95795203f3ee46f44a197c946e4stevel HV *tie;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel name = HePV(entry3, PL_na);
29949e866e40b95795203f3ee46f44a197c946e4stevel hash4 = (HV *)SvRV(hv_iterval(hash3, entry3));
29949e866e40b95795203f3ee46f44a197c946e4stevel mg = mg_find((SV *)hash4, 'P');
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERTMSG(mg != 0,
29949e866e40b95795203f3ee46f44a197c946e4stevel "prune_invalid: lost P magic");
29949e866e40b95795203f3ee46f44a197c946e4stevel tie = (HV *)SvRV(mg->mg_obj);
29949e866e40b95795203f3ee46f44a197c946e4stevel mg = mg_find((SV *)tie, '~');
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERTMSG(mg != 0,
29949e866e40b95795203f3ee46f44a197c946e4stevel "prune_invalid: lost ~ magic");
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* If this is marked as invalid, prune it */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (((KstatInfo_t *)SvPVX(
29949e866e40b95795203f3ee46f44a197c946e4stevel (SV *)mg->mg_obj))->valid == FALSE) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SvREADONLY_off(hash3);
29949e866e40b95795203f3ee46f44a197c946e4stevel key = HePV(entry3, klen);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_delete(hash3, key, klen, G_DISCARD);
29949e866e40b95795203f3ee46f44a197c946e4stevel SvREADONLY_on(hash3);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (del) {
29949e866e40b95795203f3ee46f44a197c946e4stevel av_push(del,
29949e866e40b95795203f3ee46f44a197c946e4stevel newSVpvf("%s:%s:%s",
29949e866e40b95795203f3ee46f44a197c946e4stevel module, instance, name));
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel ret = 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* If the module:instance:name hash is empty prune it */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (HvKEYS(hash3) == 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SvREADONLY_off(hash2);
29949e866e40b95795203f3ee46f44a197c946e4stevel key = HePV(entry2, klen);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_delete(hash2, key, klen, G_DISCARD);
29949e866e40b95795203f3ee46f44a197c946e4stevel SvREADONLY_on(hash2);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel /* If the module:instance hash is empty prune it */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (HvKEYS(hash2) == 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SvREADONLY_off(hash1);
29949e866e40b95795203f3ee46f44a197c946e4stevel key = HePV(entry1, klen);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_delete(hash1, key, klen, G_DISCARD);
29949e866e40b95795203f3ee46f44a197c946e4stevel SvREADONLY_on(hash1);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel return (ret);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Named kstats are returned as a list of key/values. This function converts
29949e866e40b95795203f3ee46f44a197c946e4stevel * such a list into the equivalent perl datatypes, and stores them in the passed
29949e866e40b95795203f3ee46f44a197c946e4stevel * hash.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsave_named(HV *self, kstat_t *kp, int strip_str)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel kstat_named_t *knp;
29949e866e40b95795203f3ee46f44a197c946e4stevel int n;
29949e866e40b95795203f3ee46f44a197c946e4stevel SV* value;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel for (n = kp->ks_ndata, knp = KSTAT_NAMED_PTR(kp); n > 0; n--, knp++) {
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (knp->data_type) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case KSTAT_DATA_CHAR:
29949e866e40b95795203f3ee46f44a197c946e4stevel value = newSVpv(knp->value.c, strip_str ?
29949e866e40b95795203f3ee46f44a197c946e4stevel strlen(knp->value.c) : sizeof (knp->value.c));
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case KSTAT_DATA_INT32:
29949e866e40b95795203f3ee46f44a197c946e4stevel value = newSViv(knp->value.i32);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case KSTAT_DATA_UINT32:
29949e866e40b95795203f3ee46f44a197c946e4stevel value = NEW_UV(knp->value.ui32);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case KSTAT_DATA_INT64:
29949e866e40b95795203f3ee46f44a197c946e4stevel value = NEW_UV(knp->value.i64);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case KSTAT_DATA_UINT64:
29949e866e40b95795203f3ee46f44a197c946e4stevel value = NEW_UV(knp->value.ui64);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case KSTAT_DATA_STRING:
29949e866e40b95795203f3ee46f44a197c946e4stevel if (KSTAT_NAMED_STR_PTR(knp) == NULL)
29949e866e40b95795203f3ee46f44a197c946e4stevel value = newSVpv("null", sizeof ("null") - 1);
29949e866e40b95795203f3ee46f44a197c946e4stevel else
29949e866e40b95795203f3ee46f44a197c946e4stevel value = newSVpv(KSTAT_NAMED_STR_PTR(knp),
29949e866e40b95795203f3ee46f44a197c946e4stevel KSTAT_NAMED_STR_BUFLEN(knp) -1);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERTMSG(0, "kstat_read: invalid data type");
c9f77c52c0735e65aa2534394c5151cdb963cbefAndy Stormont continue;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, knp->name, strlen(knp->name), value, 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Save kstat interrupt statistics
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsave_intr(HV *self, kstat_t *kp, int strip_str)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel kstat_intr_t *kintrp;
29949e866e40b95795203f3ee46f44a197c946e4stevel int i;
29949e866e40b95795203f3ee46f44a197c946e4stevel static char *intr_names[] =
29949e866e40b95795203f3ee46f44a197c946e4stevel { "hard", "soft", "watchdog", "spurious", "multiple_service" };
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERT(kp->ks_ndata == 1);
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERT(kp->ks_data_size == sizeof (kstat_intr_t));
29949e866e40b95795203f3ee46f44a197c946e4stevel kintrp = KSTAT_INTR_PTR(kp);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel for (i = 0; i < KSTAT_NUM_INTRS; i++) {
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, intr_names[i], strlen(intr_names[i]),
29949e866e40b95795203f3ee46f44a197c946e4stevel NEW_UV(kintrp->intrs[i]), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Save IO statistics
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsave_io(HV *self, kstat_t *kp, int strip_str)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel kstat_io_t *kiop;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERT(kp->ks_ndata == 1);
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERT(kp->ks_data_size == sizeof (kstat_io_t));
29949e866e40b95795203f3ee46f44a197c946e4stevel kiop = KSTAT_IO_PTR(kp);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT64(self, kiop, nread);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT64(self, kiop, nwritten);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, kiop, reads);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, kiop, writes);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_HRTIME(self, kiop, wtime);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_HRTIME(self, kiop, wlentime);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_HRTIME(self, kiop, wlastupdate);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_HRTIME(self, kiop, rtime);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_HRTIME(self, kiop, rlentime);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_HRTIME(self, kiop, rlastupdate);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, kiop, wcnt);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT32(self, kiop, rcnt);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Save timer statistics
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic void
29949e866e40b95795203f3ee46f44a197c946e4stevelsave_timer(HV *self, kstat_t *kp, int strip_str)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel kstat_timer_t *ktimerp;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERT(kp->ks_ndata == 1);
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERT(kp->ks_data_size == sizeof (kstat_timer_t));
29949e866e40b95795203f3ee46f44a197c946e4stevel ktimerp = KSTAT_TIMER_PTR(kp);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_STRING(self, ktimerp, name, strip_str);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_UINT64(self, ktimerp, num_events);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_HRTIME(self, ktimerp, elapsed_time);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_HRTIME(self, ktimerp, min_time);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_HRTIME(self, ktimerp, max_time);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_HRTIME(self, ktimerp, start_time);
29949e866e40b95795203f3ee46f44a197c946e4stevel SAVE_HRTIME(self, ktimerp, stop_time);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Read kstats and copy into the supplied perl hash structure. If refresh is
29949e866e40b95795203f3ee46f44a197c946e4stevel * true, this function is being called as part of the update() method. In this
29949e866e40b95795203f3ee46f44a197c946e4stevel * case it is only necessary to read the kstats if they have previously been
29949e866e40b95795203f3ee46f44a197c946e4stevel * accessed (kip->read == TRUE). If refresh is false, this function is being
29949e866e40b95795203f3ee46f44a197c946e4stevel * called prior to returning a value to the caller. In this case, it is only
29949e866e40b95795203f3ee46f44a197c946e4stevel * necessary to read the kstats if they have not previously been read. If the
29949e866e40b95795203f3ee46f44a197c946e4stevel * kstat_read() fails, 0 is returned, otherwise 1
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelstatic int
29949e866e40b95795203f3ee46f44a197c946e4stevelread_kstats(HV *self, int refresh)
29949e866e40b95795203f3ee46f44a197c946e4stevel{
29949e866e40b95795203f3ee46f44a197c946e4stevel MAGIC *mg;
29949e866e40b95795203f3ee46f44a197c946e4stevel KstatInfo_t *kip;
29949e866e40b95795203f3ee46f44a197c946e4stevel kstat_raw_reader_t fnp;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Find the MAGIC KstatInfo_t data structure */
29949e866e40b95795203f3ee46f44a197c946e4stevel mg = mg_find((SV *)self, '~');
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERTMSG(mg != 0, "read_kstats: lost ~ magic");
29949e866e40b95795203f3ee46f44a197c946e4stevel kip = (KstatInfo_t *)SvPVX(mg->mg_obj);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Return early if we don't need to actually read the kstats */
29949e866e40b95795203f3ee46f44a197c946e4stevel if ((refresh && ! kip->read) || (! refresh && kip->read)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel return (1);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Read the kstats and return 0 if this fails */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (kstat_read(kip->kstat_ctl, kip->kstat, NULL) < 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel return (0);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Save the read data */
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(self, "snaptime", 8, NEW_HRTIME(kip->kstat->ks_snaptime), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel switch (kip->kstat->ks_type) {
29949e866e40b95795203f3ee46f44a197c946e4stevel case KSTAT_TYPE_RAW:
29949e866e40b95795203f3ee46f44a197c946e4stevel if ((fnp = lookup_raw_kstat_fn(kip->kstat->ks_module,
29949e866e40b95795203f3ee46f44a197c946e4stevel kip->kstat->ks_name)) != 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel fnp(self, kip->kstat, kip->strip_str);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case KSTAT_TYPE_NAMED:
29949e866e40b95795203f3ee46f44a197c946e4stevel save_named(self, kip->kstat, kip->strip_str);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case KSTAT_TYPE_INTR:
29949e866e40b95795203f3ee46f44a197c946e4stevel save_intr(self, kip->kstat, kip->strip_str);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case KSTAT_TYPE_IO:
29949e866e40b95795203f3ee46f44a197c946e4stevel save_io(self, kip->kstat, kip->strip_str);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel case KSTAT_TYPE_TIMER:
29949e866e40b95795203f3ee46f44a197c946e4stevel save_timer(self, kip->kstat, kip->strip_str);
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel default:
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERTMSG(0, "read_kstats: illegal kstat type");
29949e866e40b95795203f3ee46f44a197c946e4stevel break;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel kip->read = TRUE;
29949e866e40b95795203f3ee46f44a197c946e4stevel return (1);
29949e866e40b95795203f3ee46f44a197c946e4stevel}
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/*
29949e866e40b95795203f3ee46f44a197c946e4stevel * The XS code exported to perl is below here. Note that the XS preprocessor
29949e866e40b95795203f3ee46f44a197c946e4stevel * has its own commenting syntax, so all comments from this point on are in
29949e866e40b95795203f3ee46f44a197c946e4stevel * that form.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel/* The following XS methods are the ABI of the Sun::Solaris::Kstat package */
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelMODULE = Sun::Solaris::Kstat PACKAGE = Sun::Solaris::Kstat
29949e866e40b95795203f3ee46f44a197c946e4stevelPROTOTYPES: ENABLE
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel # Create the raw kstat to store function lookup table on load
29949e866e40b95795203f3ee46f44a197c946e4stevelBOOT:
29949e866e40b95795203f3ee46f44a197c946e4stevel build_raw_kstat_lookup();
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel # The Sun::Solaris::Kstat constructor. This builds the nested
29949e866e40b95795203f3ee46f44a197c946e4stevel # name::instance::module hash structure, but doesn't actually read the
29949e866e40b95795203f3ee46f44a197c946e4stevel # underlying kstats. This is done on demand by the TIEHASH methods in
29949e866e40b95795203f3ee46f44a197c946e4stevel # Sun::Solaris::Kstat::_Stat
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelSV*
29949e866e40b95795203f3ee46f44a197c946e4stevelnew(class, ...)
29949e866e40b95795203f3ee46f44a197c946e4stevel char *class;
29949e866e40b95795203f3ee46f44a197c946e4stevelPREINIT:
29949e866e40b95795203f3ee46f44a197c946e4stevel HV *stash;
29949e866e40b95795203f3ee46f44a197c946e4stevel kstat_ctl_t *kc;
29949e866e40b95795203f3ee46f44a197c946e4stevel SV *kcsv;
29949e866e40b95795203f3ee46f44a197c946e4stevel kstat_t *kp;
29949e866e40b95795203f3ee46f44a197c946e4stevel KstatInfo_t kstatinfo;
29949e866e40b95795203f3ee46f44a197c946e4stevel int sp, strip_str;
29949e866e40b95795203f3ee46f44a197c946e4stevelCODE:
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Check we have an even number of arguments, excluding the class */
29949e866e40b95795203f3ee46f44a197c946e4stevel sp = 1;
29949e866e40b95795203f3ee46f44a197c946e4stevel if (((items - sp) % 2) != 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel croak(DEBUG_ID ": new: invalid number of arguments");
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Process any (name => value) arguments */
29949e866e40b95795203f3ee46f44a197c946e4stevel strip_str = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel while (sp < items) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SV *name, *value;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel name = ST(sp);
29949e866e40b95795203f3ee46f44a197c946e4stevel sp++;
29949e866e40b95795203f3ee46f44a197c946e4stevel value = ST(sp);
29949e866e40b95795203f3ee46f44a197c946e4stevel sp++;
29949e866e40b95795203f3ee46f44a197c946e4stevel if (strcmp(SvPVX(name), "strip_strings") == 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel strip_str = SvTRUE(value);
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel croak(DEBUG_ID ": new: invalid parameter name '%s'",
29949e866e40b95795203f3ee46f44a197c946e4stevel SvPVX(name));
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Open the kstats handle */
29949e866e40b95795203f3ee46f44a197c946e4stevel if ((kc = kstat_open()) == 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel XSRETURN_UNDEF;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Create a blessed hash ref */
29949e866e40b95795203f3ee46f44a197c946e4stevel RETVAL = (SV *)newRV_noinc((SV *)newHV());
29949e866e40b95795203f3ee46f44a197c946e4stevel stash = gv_stashpv(class, TRUE);
29949e866e40b95795203f3ee46f44a197c946e4stevel sv_bless(RETVAL, stash);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Create a place to save the KstatInfo_t structure */
29949e866e40b95795203f3ee46f44a197c946e4stevel kcsv = newSVpv((char *)&kc, sizeof (kc));
29949e866e40b95795203f3ee46f44a197c946e4stevel sv_magic(SvRV(RETVAL), kcsv, '~', 0, 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel SvREFCNT_dec(kcsv);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Initialise the KstatsInfo_t structure */
29949e866e40b95795203f3ee46f44a197c946e4stevel kstatinfo.read = FALSE;
29949e866e40b95795203f3ee46f44a197c946e4stevel kstatinfo.valid = TRUE;
29949e866e40b95795203f3ee46f44a197c946e4stevel kstatinfo.strip_str = strip_str;
29949e866e40b95795203f3ee46f44a197c946e4stevel kstatinfo.kstat_ctl = kc;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Scan the kstat chain, building hash entries for the kstats */
29949e866e40b95795203f3ee46f44a197c946e4stevel for (kp = kc->kc_chain; kp != 0; kp = kp->ks_next) {
29949e866e40b95795203f3ee46f44a197c946e4stevel HV *tie;
29949e866e40b95795203f3ee46f44a197c946e4stevel SV *kstatsv;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Don't bother storing the kstat headers */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (strncmp(kp->ks_name, "kstat_", 6) == 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel continue;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Don't bother storing raw stats we don't understand */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (kp->ks_type == KSTAT_TYPE_RAW &&
29949e866e40b95795203f3ee46f44a197c946e4stevel lookup_raw_kstat_fn(kp->ks_module, kp->ks_name) == 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel#ifdef REPORT_UNKNOWN
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) fprintf(stderr,
29949e866e40b95795203f3ee46f44a197c946e4stevel "Unknown kstat type %s:%d:%s - %d of size %d\n",
29949e866e40b95795203f3ee46f44a197c946e4stevel kp->ks_module, kp->ks_instance, kp->ks_name,
29949e866e40b95795203f3ee46f44a197c946e4stevel kp->ks_ndata, kp->ks_data_size);
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif
29949e866e40b95795203f3ee46f44a197c946e4stevel continue;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Create a 3-layer hash hierarchy - module.instance.name */
29949e866e40b95795203f3ee46f44a197c946e4stevel tie = get_tie(RETVAL, kp->ks_module, kp->ks_instance,
29949e866e40b95795203f3ee46f44a197c946e4stevel kp->ks_name, 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Save the data necessary to read the kstat info on demand */
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(tie, "class", 5, newSVpv(kp->ks_class, 0), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(tie, "crtime", 6, NEW_HRTIME(kp->ks_crtime), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel kstatinfo.kstat = kp;
29949e866e40b95795203f3ee46f44a197c946e4stevel kstatsv = newSVpv((char *)&kstatinfo, sizeof (kstatinfo));
29949e866e40b95795203f3ee46f44a197c946e4stevel sv_magic((SV *)tie, kstatsv, '~', 0, 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel SvREFCNT_dec(kstatsv);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel SvREADONLY_on(SvRV(RETVAL));
29949e866e40b95795203f3ee46f44a197c946e4stevel /* SvREADONLY_on(RETVAL); */
29949e866e40b95795203f3ee46f44a197c946e4stevelOUTPUT:
29949e866e40b95795203f3ee46f44a197c946e4stevel RETVAL
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel # Update the perl hash structure so that it is in line with the kernel kstats
29949e866e40b95795203f3ee46f44a197c946e4stevel # data. Only kstats athat have previously been accessed are read,
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel # Scalar context: true/false
29949e866e40b95795203f3ee46f44a197c946e4stevel # Array context: (\@added, \@deleted)
29949e866e40b95795203f3ee46f44a197c946e4stevelvoid
29949e866e40b95795203f3ee46f44a197c946e4stevelupdate(self)
29949e866e40b95795203f3ee46f44a197c946e4stevel SV* self;
29949e866e40b95795203f3ee46f44a197c946e4stevelPREINIT:
29949e866e40b95795203f3ee46f44a197c946e4stevel MAGIC *mg;
29949e866e40b95795203f3ee46f44a197c946e4stevel kstat_ctl_t *kc;
29949e866e40b95795203f3ee46f44a197c946e4stevel kstat_t *kp;
29949e866e40b95795203f3ee46f44a197c946e4stevel int ret;
29949e866e40b95795203f3ee46f44a197c946e4stevel AV *add, *del;
29949e866e40b95795203f3ee46f44a197c946e4stevelPPCODE:
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Find the hidden KstatInfo_t structure */
29949e866e40b95795203f3ee46f44a197c946e4stevel mg = mg_find(SvRV(self), '~');
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERTMSG(mg != 0, "update: lost ~ magic");
29949e866e40b95795203f3ee46f44a197c946e4stevel kc = *(kstat_ctl_t **)SvPVX(mg->mg_obj);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Update the kstat chain, and return immediately on error. */
29949e866e40b95795203f3ee46f44a197c946e4stevel if ((ret = kstat_chain_update(kc)) == -1) {
29949e866e40b95795203f3ee46f44a197c946e4stevel if (GIMME_V == G_ARRAY) {
29949e866e40b95795203f3ee46f44a197c946e4stevel EXTEND(SP, 2);
29949e866e40b95795203f3ee46f44a197c946e4stevel PUSHs(sv_newmortal());
29949e866e40b95795203f3ee46f44a197c946e4stevel PUSHs(sv_newmortal());
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel EXTEND(SP, 1);
29949e866e40b95795203f3ee46f44a197c946e4stevel PUSHs(sv_2mortal(newSViv(ret)));
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Create the arrays to be returned if in an array context */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (GIMME_V == G_ARRAY) {
29949e866e40b95795203f3ee46f44a197c946e4stevel add = newAV();
29949e866e40b95795203f3ee46f44a197c946e4stevel del = newAV();
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel add = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel del = 0;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * If the kstat chain hasn't changed we can just reread any stats
29949e866e40b95795203f3ee46f44a197c946e4stevel * that have already been read
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (ret == 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel if (! apply_to_ties(self, (ATTCb_t)read_kstats, (void *)TRUE)) {
29949e866e40b95795203f3ee46f44a197c946e4stevel if (GIMME_V == G_ARRAY) {
29949e866e40b95795203f3ee46f44a197c946e4stevel EXTEND(SP, 2);
29949e866e40b95795203f3ee46f44a197c946e4stevel PUSHs(sv_2mortal(newRV_noinc((SV *)add)));
29949e866e40b95795203f3ee46f44a197c946e4stevel PUSHs(sv_2mortal(newRV_noinc((SV *)del)));
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel EXTEND(SP, 1);
29949e866e40b95795203f3ee46f44a197c946e4stevel PUSHs(sv_2mortal(newSViv(-1)));
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Otherwise we have to update the Perl structure so that it is in
29949e866e40b95795203f3ee46f44a197c946e4stevel * agreement with the new kstat chain. We do this in such a way as to
29949e866e40b95795203f3ee46f44a197c946e4stevel * retain all the existing structures, just adding or deleting the
29949e866e40b95795203f3ee46f44a197c946e4stevel * bare minimum.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel KstatInfo_t kstatinfo;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Step 1: set the 'invalid' flag on each entry
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel apply_to_ties(self, &set_valid, (void *)FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Step 2: Set the 'valid' flag on all entries still in the
29949e866e40b95795203f3ee46f44a197c946e4stevel * kernel kstat chain
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel kstatinfo.read = FALSE;
29949e866e40b95795203f3ee46f44a197c946e4stevel kstatinfo.valid = TRUE;
29949e866e40b95795203f3ee46f44a197c946e4stevel kstatinfo.kstat_ctl = kc;
29949e866e40b95795203f3ee46f44a197c946e4stevel for (kp = kc->kc_chain; kp != 0; kp = kp->ks_next) {
29949e866e40b95795203f3ee46f44a197c946e4stevel int new;
29949e866e40b95795203f3ee46f44a197c946e4stevel HV *tie;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Don't bother storing the kstat headers or types */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (strncmp(kp->ks_name, "kstat_", 6) == 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel continue;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Don't bother storing raw stats we don't understand */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (kp->ks_type == KSTAT_TYPE_RAW &&
29949e866e40b95795203f3ee46f44a197c946e4stevel lookup_raw_kstat_fn(kp->ks_module, kp->ks_name)
29949e866e40b95795203f3ee46f44a197c946e4stevel == 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel#ifdef REPORT_UNKNOWN
29949e866e40b95795203f3ee46f44a197c946e4stevel (void) printf("Unknown kstat type %s:%d:%s "
29949e866e40b95795203f3ee46f44a197c946e4stevel "- %d of size %d\n", kp->ks_module,
29949e866e40b95795203f3ee46f44a197c946e4stevel kp->ks_instance, kp->ks_name,
29949e866e40b95795203f3ee46f44a197c946e4stevel kp->ks_ndata, kp->ks_data_size);
29949e866e40b95795203f3ee46f44a197c946e4stevel#endif
29949e866e40b95795203f3ee46f44a197c946e4stevel continue;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Find the tied hash associated with the kstat entry */
29949e866e40b95795203f3ee46f44a197c946e4stevel tie = get_tie(self, kp->ks_module, kp->ks_instance,
29949e866e40b95795203f3ee46f44a197c946e4stevel kp->ks_name, &new);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* If newly created store the associated kstat info */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (new) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SV *kstatsv;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel * Save the data necessary to read the kstat
29949e866e40b95795203f3ee46f44a197c946e4stevel * info on demand
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(tie, "class", 5,
29949e866e40b95795203f3ee46f44a197c946e4stevel newSVpv(kp->ks_class, 0), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store(tie, "crtime", 6,
29949e866e40b95795203f3ee46f44a197c946e4stevel NEW_HRTIME(kp->ks_crtime), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel kstatinfo.kstat = kp;
29949e866e40b95795203f3ee46f44a197c946e4stevel kstatsv = newSVpv((char *)&kstatinfo,
29949e866e40b95795203f3ee46f44a197c946e4stevel sizeof (kstatinfo));
29949e866e40b95795203f3ee46f44a197c946e4stevel sv_magic((SV *)tie, kstatsv, '~', 0, 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel SvREFCNT_dec(kstatsv);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Save the key on the add list, if required */
29949e866e40b95795203f3ee46f44a197c946e4stevel if (GIMME_V == G_ARRAY) {
29949e866e40b95795203f3ee46f44a197c946e4stevel av_push(add, newSVpvf("%s:%d:%s",
29949e866e40b95795203f3ee46f44a197c946e4stevel kp->ks_module, kp->ks_instance,
29949e866e40b95795203f3ee46f44a197c946e4stevel kp->ks_name));
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* If the stats already exist, just update them */
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel MAGIC *mg;
29949e866e40b95795203f3ee46f44a197c946e4stevel KstatInfo_t *kip;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Find the hidden KstatInfo_t */
29949e866e40b95795203f3ee46f44a197c946e4stevel mg = mg_find((SV *)tie, '~');
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERTMSG(mg != 0, "update: lost ~ magic");
29949e866e40b95795203f3ee46f44a197c946e4stevel kip = (KstatInfo_t *)SvPVX(mg->mg_obj);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Mark the tie as valid */
29949e866e40b95795203f3ee46f44a197c946e4stevel kip->valid = TRUE;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Re-save the kstat_t pointer. If the kstat
29949e866e40b95795203f3ee46f44a197c946e4stevel * has been deleted and re-added since the last
29949e866e40b95795203f3ee46f44a197c946e4stevel * update, the address of the kstat structure
29949e866e40b95795203f3ee46f44a197c946e4stevel * will have changed, even though the kstat will
29949e866e40b95795203f3ee46f44a197c946e4stevel * still live at the same place in the perl
29949e866e40b95795203f3ee46f44a197c946e4stevel * hash tree structure.
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel kip->kstat = kp;
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /* Reread the stats, if read previously */
29949e866e40b95795203f3ee46f44a197c946e4stevel read_kstats(tie, TRUE);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel /*
29949e866e40b95795203f3ee46f44a197c946e4stevel *Step 3: Delete any entries still marked as 'invalid'
29949e866e40b95795203f3ee46f44a197c946e4stevel */
29949e866e40b95795203f3ee46f44a197c946e4stevel ret = prune_invalid(self, del);
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel if (GIMME_V == G_ARRAY) {
29949e866e40b95795203f3ee46f44a197c946e4stevel EXTEND(SP, 2);
29949e866e40b95795203f3ee46f44a197c946e4stevel PUSHs(sv_2mortal(newRV_noinc((SV *)add)));
29949e866e40b95795203f3ee46f44a197c946e4stevel PUSHs(sv_2mortal(newRV_noinc((SV *)del)));
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel EXTEND(SP, 1);
29949e866e40b95795203f3ee46f44a197c946e4stevel PUSHs(sv_2mortal(newSViv(ret)));
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel # Destructor. Closes the kstat connection
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelvoid
29949e866e40b95795203f3ee46f44a197c946e4stevelDESTROY(self)
29949e866e40b95795203f3ee46f44a197c946e4stevel SV *self;
29949e866e40b95795203f3ee46f44a197c946e4stevelPREINIT:
29949e866e40b95795203f3ee46f44a197c946e4stevel MAGIC *mg;
29949e866e40b95795203f3ee46f44a197c946e4stevel kstat_ctl_t *kc;
29949e866e40b95795203f3ee46f44a197c946e4stevelCODE:
29949e866e40b95795203f3ee46f44a197c946e4stevel mg = mg_find(SvRV(self), '~');
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERTMSG(mg != 0, "DESTROY: lost ~ magic");
29949e866e40b95795203f3ee46f44a197c946e4stevel kc = *(kstat_ctl_t **)SvPVX(mg->mg_obj);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (kstat_close(kc) != 0) {
29949e866e40b95795203f3ee46f44a197c946e4stevel croak(DEBUG_ID ": kstat_close: failed");
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel # The following XS methods implement the TIEHASH mechanism used to update the
29949e866e40b95795203f3ee46f44a197c946e4stevel # kstats hash structure. These are blessed into a package that isn't
29949e866e40b95795203f3ee46f44a197c946e4stevel # visible to callers of the Sun::Solaris::Kstat module
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelMODULE = Sun::Solaris::Kstat PACKAGE = Sun::Solaris::Kstat::_Stat
29949e866e40b95795203f3ee46f44a197c946e4stevelPROTOTYPES: ENABLE
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel # If a value has already been read, return it. Otherwise read the appropriate
29949e866e40b95795203f3ee46f44a197c946e4stevel # kstat and then return the value
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelSV*
29949e866e40b95795203f3ee46f44a197c946e4stevelFETCH(self, key)
29949e866e40b95795203f3ee46f44a197c946e4stevel SV* self;
29949e866e40b95795203f3ee46f44a197c946e4stevel SV* key;
29949e866e40b95795203f3ee46f44a197c946e4stevelPREINIT:
29949e866e40b95795203f3ee46f44a197c946e4stevel char *k;
29949e866e40b95795203f3ee46f44a197c946e4stevel STRLEN klen;
29949e866e40b95795203f3ee46f44a197c946e4stevel SV **value;
29949e866e40b95795203f3ee46f44a197c946e4stevelCODE:
29949e866e40b95795203f3ee46f44a197c946e4stevel self = SvRV(self);
29949e866e40b95795203f3ee46f44a197c946e4stevel k = SvPV(key, klen);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (strNE(k, "class") && strNE(k, "crtime")) {
29949e866e40b95795203f3ee46f44a197c946e4stevel read_kstats((HV *)self, FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel value = hv_fetch((HV *)self, k, klen, FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (value) {
29949e866e40b95795203f3ee46f44a197c946e4stevel RETVAL = *value; SvREFCNT_inc(RETVAL);
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel RETVAL = &PL_sv_undef;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevelOUTPUT:
29949e866e40b95795203f3ee46f44a197c946e4stevel RETVAL
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel # Save the passed value into the kstat hash. Read the appropriate kstat first,
29949e866e40b95795203f3ee46f44a197c946e4stevel # if necessary. Note that this DOES NOT update the underlying kernel kstat
29949e866e40b95795203f3ee46f44a197c946e4stevel # structure.
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelSV*
29949e866e40b95795203f3ee46f44a197c946e4stevelSTORE(self, key, value)
29949e866e40b95795203f3ee46f44a197c946e4stevel SV* self;
29949e866e40b95795203f3ee46f44a197c946e4stevel SV* key;
29949e866e40b95795203f3ee46f44a197c946e4stevel SV* value;
29949e866e40b95795203f3ee46f44a197c946e4stevelPREINIT:
29949e866e40b95795203f3ee46f44a197c946e4stevel char *k;
29949e866e40b95795203f3ee46f44a197c946e4stevel STRLEN klen;
29949e866e40b95795203f3ee46f44a197c946e4stevelCODE:
29949e866e40b95795203f3ee46f44a197c946e4stevel self = SvRV(self);
29949e866e40b95795203f3ee46f44a197c946e4stevel k = SvPV(key, klen);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (strNE(k, "class") && strNE(k, "crtime")) {
29949e866e40b95795203f3ee46f44a197c946e4stevel read_kstats((HV *)self, FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel SvREFCNT_inc(value);
29949e866e40b95795203f3ee46f44a197c946e4stevel RETVAL = *(hv_store((HV *)self, k, klen, value, 0));
29949e866e40b95795203f3ee46f44a197c946e4stevel SvREFCNT_inc(RETVAL);
29949e866e40b95795203f3ee46f44a197c946e4stevelOUTPUT:
29949e866e40b95795203f3ee46f44a197c946e4stevel RETVAL
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel # Check for the existence of the passed key. Read the kstat first if necessary
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelbool
29949e866e40b95795203f3ee46f44a197c946e4stevelEXISTS(self, key)
29949e866e40b95795203f3ee46f44a197c946e4stevel SV* self;
29949e866e40b95795203f3ee46f44a197c946e4stevel SV* key;
29949e866e40b95795203f3ee46f44a197c946e4stevelPREINIT:
29949e866e40b95795203f3ee46f44a197c946e4stevel char *k;
29949e866e40b95795203f3ee46f44a197c946e4stevelCODE:
29949e866e40b95795203f3ee46f44a197c946e4stevel self = SvRV(self);
29949e866e40b95795203f3ee46f44a197c946e4stevel k = SvPV(key, PL_na);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (strNE(k, "class") && strNE(k, "crtime")) {
29949e866e40b95795203f3ee46f44a197c946e4stevel read_kstats((HV *)self, FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel RETVAL = hv_exists_ent((HV *)self, key, 0);
29949e866e40b95795203f3ee46f44a197c946e4stevelOUTPUT:
29949e866e40b95795203f3ee46f44a197c946e4stevel RETVAL
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel # Hash iterator initialisation. Read the kstats if necessary.
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelSV*
29949e866e40b95795203f3ee46f44a197c946e4stevelFIRSTKEY(self)
29949e866e40b95795203f3ee46f44a197c946e4stevel SV* self;
29949e866e40b95795203f3ee46f44a197c946e4stevelPREINIT:
29949e866e40b95795203f3ee46f44a197c946e4stevel HE *he;
29949e866e40b95795203f3ee46f44a197c946e4stevelPPCODE:
29949e866e40b95795203f3ee46f44a197c946e4stevel self = SvRV(self);
29949e866e40b95795203f3ee46f44a197c946e4stevel read_kstats((HV *)self, FALSE);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_iterinit((HV *)self);
c9f77c52c0735e65aa2534394c5151cdb963cbefAndy Stormont if ((he = hv_iternext((HV *)self))) {
29949e866e40b95795203f3ee46f44a197c946e4stevel EXTEND(SP, 1);
29949e866e40b95795203f3ee46f44a197c946e4stevel PUSHs(hv_iterkeysv(he));
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel # Return hash iterator next value. Read the kstats if necessary.
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelSV*
29949e866e40b95795203f3ee46f44a197c946e4stevelNEXTKEY(self, lastkey)
29949e866e40b95795203f3ee46f44a197c946e4stevel SV* self;
29949e866e40b95795203f3ee46f44a197c946e4stevel SV* lastkey;
29949e866e40b95795203f3ee46f44a197c946e4stevelPREINIT:
29949e866e40b95795203f3ee46f44a197c946e4stevel HE *he;
29949e866e40b95795203f3ee46f44a197c946e4stevelPPCODE:
29949e866e40b95795203f3ee46f44a197c946e4stevel self = SvRV(self);
c9f77c52c0735e65aa2534394c5151cdb963cbefAndy Stormont if ((he = hv_iternext((HV *)self))) {
29949e866e40b95795203f3ee46f44a197c946e4stevel EXTEND(SP, 1);
29949e866e40b95795203f3ee46f44a197c946e4stevel PUSHs(hv_iterkeysv(he));
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel # Delete the specified hash entry.
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelSV*
29949e866e40b95795203f3ee46f44a197c946e4stevelDELETE(self, key)
29949e866e40b95795203f3ee46f44a197c946e4stevel SV *self;
29949e866e40b95795203f3ee46f44a197c946e4stevel SV *key;
29949e866e40b95795203f3ee46f44a197c946e4stevelCODE:
29949e866e40b95795203f3ee46f44a197c946e4stevel self = SvRV(self);
29949e866e40b95795203f3ee46f44a197c946e4stevel RETVAL = hv_delete_ent((HV *)self, key, 0, 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel if (RETVAL) {
29949e866e40b95795203f3ee46f44a197c946e4stevel SvREFCNT_inc(RETVAL);
29949e866e40b95795203f3ee46f44a197c946e4stevel } else {
29949e866e40b95795203f3ee46f44a197c946e4stevel RETVAL = &PL_sv_undef;
29949e866e40b95795203f3ee46f44a197c946e4stevel }
29949e866e40b95795203f3ee46f44a197c946e4stevelOUTPUT:
29949e866e40b95795203f3ee46f44a197c946e4stevel RETVAL
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel # Clear the entire hash. This will stop any update() calls rereading this
29949e866e40b95795203f3ee46f44a197c946e4stevel # kstat until it is accessed again.
29949e866e40b95795203f3ee46f44a197c946e4stevel #
29949e866e40b95795203f3ee46f44a197c946e4stevel
29949e866e40b95795203f3ee46f44a197c946e4stevelvoid
29949e866e40b95795203f3ee46f44a197c946e4stevelCLEAR(self)
29949e866e40b95795203f3ee46f44a197c946e4stevel SV* self;
29949e866e40b95795203f3ee46f44a197c946e4stevelPREINIT:
29949e866e40b95795203f3ee46f44a197c946e4stevel MAGIC *mg;
29949e866e40b95795203f3ee46f44a197c946e4stevel KstatInfo_t *kip;
29949e866e40b95795203f3ee46f44a197c946e4stevelCODE:
29949e866e40b95795203f3ee46f44a197c946e4stevel self = SvRV(self);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_clear((HV *)self);
29949e866e40b95795203f3ee46f44a197c946e4stevel mg = mg_find(self, '~');
29949e866e40b95795203f3ee46f44a197c946e4stevel PERL_ASSERTMSG(mg != 0, "CLEAR: lost ~ magic");
29949e866e40b95795203f3ee46f44a197c946e4stevel kip = (KstatInfo_t *)SvPVX(mg->mg_obj);
29949e866e40b95795203f3ee46f44a197c946e4stevel kip->read = FALSE;
29949e866e40b95795203f3ee46f44a197c946e4stevel kip->valid = TRUE;
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store((HV *)self, "class", 5, newSVpv(kip->kstat->ks_class, 0), 0);
29949e866e40b95795203f3ee46f44a197c946e4stevel hv_store((HV *)self, "crtime", 6, NEW_HRTIME(kip->kstat->ks_crtime), 0);