diff options
Diffstat (limited to 'src/pmdas/darwin')
-rw-r--r-- | src/pmdas/darwin/GNUmakefile | 69 | ||||
-rw-r--r-- | src/pmdas/darwin/disk.c | 261 | ||||
-rw-r--r-- | src/pmdas/darwin/disk.h | 55 | ||||
-rw-r--r-- | src/pmdas/darwin/help | 199 | ||||
-rw-r--r-- | src/pmdas/darwin/kernel.c | 195 | ||||
-rw-r--r-- | src/pmdas/darwin/network.c | 185 | ||||
-rw-r--r-- | src/pmdas/darwin/network.h | 57 | ||||
-rw-r--r-- | src/pmdas/darwin/pmda.c | 1268 | ||||
-rw-r--r-- | src/pmdas/darwin/pmns | 258 | ||||
-rw-r--r-- | src/pmdas/darwin/root | 15 |
10 files changed, 2562 insertions, 0 deletions
diff --git a/src/pmdas/darwin/GNUmakefile b/src/pmdas/darwin/GNUmakefile new file mode 100644 index 0000000..a2fd3a7 --- /dev/null +++ b/src/pmdas/darwin/GNUmakefile @@ -0,0 +1,69 @@ +# +# Copyright (c) 2004 Silicon Graphics, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# + +TOPDIR = ../../.. +include $(TOPDIR)/src/include/builddefs + +IAM = darwin +DOMAIN = DARWIN +CMDTARGET = pmdadarwin +LIBTARGET = pmda_darwin.dylib +PMDADIR = $(PCP_PMDAS_DIR)/$(IAM) +CONF_LINE = "darwin 78 dso darwin_init $(PMDADIR)/$(LIBTARGET)" + +CFILES = pmda.c kernel.c disk.c network.c +HFILES = disk.h network.h + +LSRCFILES = help root pmns + +FRAMEWORKS = -framework CoreFoundation -framework IOKit +LLDLIBS = $(PCP_PMDALIB) $(FRAMEWORKS) + +LDIRT = *.log *.dir *.pag root_darwin domain.h + +default: build-me + +include $(BUILDRULES) + +ifeq "$(TARGET_OS)" "darwin" +build-me: root_darwin domain.h $(LIBTARGET) $(CMDTARGET) help.dir help.pag + @if [ `grep -c $(CONF_LINE) ../pmcd.conf` -eq 0 ]; then \ + echo $(CONF_LINE) >> ../pmcd.conf ; \ + fi + +install: build-me + $(INSTALL) -m 755 -d $(PMDADIR) + $(INSTALL) -m 644 domain.h help.dir help.pag $(PMDADIR) + $(INSTALL) -m 755 $(LIBTARGET) $(CMDTARGET) $(PMDADIR) + $(INSTALL) -m 644 root_darwin $(PCP_VAR_DIR)/pmns/root_darwin +else +build-me: +install: +endif + +default_pcp : default + +install_pcp : install + +help.dir help.pag: help root_darwin + $(RUN_IN_BUILD_ENV) $(TOPDIR)/src/newhelp/newhelp -n root_darwin -v 2 -o help < help + +root_darwin: ../../pmns/stdpmid root pmns + rm -f root_darwin + sed -e 's;<stdpmid>;"../../pmns/stdpmid";' <root \ + | $(RUN_IN_BUILD_ENV) $(TOPDIR)/src/pmcpp/pmcpp \ + | sed -e '/^#/d' -e '/^$$/d' >root_darwin + +domain.h: ../../pmns/stdpmid + $(DOMAIN_MAKERULE) diff --git a/src/pmdas/darwin/disk.c b/src/pmdas/darwin/disk.c new file mode 100644 index 0000000..5d175b3 --- /dev/null +++ b/src/pmdas/darwin/disk.c @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2004 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include <mach/mach.h> +#define IOKIT 1 +#include <device/device_types.h> +#include <CoreFoundation/CoreFoundation.h> +#include <IOKit/IOKitLib.h> +#include <IOKit/storage/IOBlockStorageDriver.h> +#include <IOKit/storage/IOMedia.h> +#include <IOKit/IOBSD.h> + +#include "pmapi.h" +#include "impl.h" +#include "pmda.h" + +#include "disk.h" + +/* + * Ensure we have space for the next device in our pre-allocated + * device pool. If not, make some or pass on the error. + */ +static int +check_stats_size(struct diskstats *stats, int count) +{ + if (count > stats->highwater) { + stats->highwater++; + stats->disks = realloc(stats->disks, + stats->highwater * sizeof(struct diskstat)); + if (!stats->disks) { + stats->highwater = 0; + return -ENOMEM; + } + } + return 0; +} + +/* + * Insert all disks into the global disk instance domain. + */ +static int +update_disk_indom(struct diskstats *all, int count, pmdaIndom *indom) +{ + int i; + + if (count > 0 && count != indom->it_numinst) { + i = sizeof(pmdaInstid) * count; + if ((indom->it_set = realloc(indom->it_set, i)) == NULL) { + indom->it_numinst = 0; + return -ENOMEM; + } + } + for (i = 0; i < count; i++) { + indom->it_set[i].i_name = all->disks[i].name; + indom->it_set[i].i_inst = i; + } + indom->it_numinst = count; + return 0; +} + +/* + * Update the global counters with values from one disk. + */ +static void +update_disk_totals(struct diskstats *all, struct diskstat *disk) +{ + all->read += disk->read; + all->write += disk->write; + all->read_bytes += disk->read_bytes; + all->write_bytes += disk->write_bytes; + all->blkread += disk->read_bytes / disk->blocksize; + all->blkwrite += disk->write_bytes / disk->blocksize; + all->read_time += disk->read_time; + all->write_time += disk->write_time; +} + +static void +clear_disk_totals(struct diskstats *all) +{ + all->read = 0; + all->write = 0; + all->read_bytes = 0; + all->write_bytes = 0; + all->blkread = 0; + all->blkwrite = 0; + all->read_time = 0; + all->write_time = 0; +} + +/* + * Update the counters associated with a single disk. + */ +static void +update_disk_stats(struct diskstat *disk, + CFDictionaryRef pproperties, CFDictionaryRef properties) +{ + CFDictionaryRef statistics; + CFStringRef name; + CFNumberRef number; + + memset(disk, 0, sizeof(struct diskstat)); + + /* Get name from the drive properties */ + name = (CFStringRef) CFDictionaryGetValue(pproperties, + CFSTR(kIOBSDNameKey)); + if(name == NULL) + return; /* Not much we can do with no name */ + + CFStringGetCString(name, disk->name, DEVNAMEMAX, + CFStringGetSystemEncoding()); + + /* Get the blocksize from the drive properties */ + number = (CFNumberRef) CFDictionaryGetValue(pproperties, + CFSTR(kIOMediaPreferredBlockSizeKey)); + if(number == NULL) + return; /* Not much we can do with no number */ + CFNumberGetValue(number, kCFNumberSInt64Type, &disk->blocksize); + + /* Get the statistics from the device properties. */ + statistics = (CFDictionaryRef) CFDictionaryGetValue(properties, + CFSTR(kIOBlockStorageDriverStatisticsKey)); + if (statistics) { + number = (CFNumberRef) CFDictionaryGetValue(statistics, + CFSTR(kIOBlockStorageDriverStatisticsReadsKey)); + if (number) + CFNumberGetValue(number, kCFNumberSInt64Type, + &disk->read); + number = (CFNumberRef) CFDictionaryGetValue(statistics, + CFSTR(kIOBlockStorageDriverStatisticsWritesKey)); + if (number) + CFNumberGetValue(number, kCFNumberSInt64Type, + &disk->write); + number = (CFNumberRef) CFDictionaryGetValue(statistics, + CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey)); + if (number) + CFNumberGetValue(number, kCFNumberSInt64Type, + &disk->read_bytes); + number = (CFNumberRef) CFDictionaryGetValue(statistics, + CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey)); + if (number) + CFNumberGetValue(number, kCFNumberSInt64Type, + &disk->write_bytes); + number = (CFNumberRef) CFDictionaryGetValue(statistics, + CFSTR(kIOBlockStorageDriverStatisticsLatentReadTimeKey)); + if (number) + CFNumberGetValue(number, kCFNumberSInt64Type, + &disk->read_time); + number = (CFNumberRef) CFDictionaryGetValue(statistics, + CFSTR(kIOBlockStorageDriverStatisticsLatentWriteTimeKey)); + if (number) + CFNumberGetValue(number, kCFNumberSInt64Type, + &disk->write_time); + } +} + +static int +update_disk(diskstats_t *stats, io_registry_entry_t drive, int index) +{ + io_registry_entry_t device; + CFDictionaryRef pproperties, properties; + int status; + + /* Get the drives parent, from which we get statistics. */ + status = IORegistryEntryGetParentEntry(drive, kIOServicePlane, &device); + if (status != KERN_SUCCESS) + return -oserror(); + + if (!IOObjectConformsTo(device, "IOBlockStorageDriver")) { + IOObjectRelease(device); + return 0; + } + + /* Obtain the drive properties. */ + pproperties = 0; + status = IORegistryEntryCreateCFProperties(drive, + (CFMutableDictionaryRef *)&pproperties, + kCFAllocatorDefault, kNilOptions); + if (status != KERN_SUCCESS) { + IOObjectRelease(device); + return -oserror(); + } + + /* Obtain the device properties. */ + properties = 0; + status = IORegistryEntryCreateCFProperties(device, + (CFMutableDictionaryRef *)&properties, + kCFAllocatorDefault, kNilOptions); + if (status != KERN_SUCCESS) { + IOObjectRelease(device); + return -oserror(); + } + + /* Make space to store the actual values, then go get them. */ + status = check_stats_size(stats, index + 1); + if (status < 0) { + IOObjectRelease(device); + } else { + update_disk_stats(&stats->disks[index], pproperties, properties); + update_disk_totals(stats, &stats->disks[index]); + } + CFRelease(pproperties); + CFRelease(properties); + return status; +} + +int +refresh_disks(struct diskstats *stats, pmdaIndom *indom) +{ + io_registry_entry_t drive; + CFMutableDictionaryRef match; + int i, status; + static int inited = 0; + static mach_port_t mach_master_port; + static io_iterator_t mach_device_list; + + if (!inited) { + /* Get ports and services for device statistics. */ + if (IOMasterPort(bootstrap_port, &mach_master_port)) { + fprintf(stderr, "%s: IOMasterPort error\n", __FUNCTION__); + return -oserror(); + } + memset(stats, 0, sizeof(struct diskstats)); + inited = 1; + } + + /* Get an interator for IOMedia objects (drives). */ + match = IOServiceMatching("IOMedia"); + CFDictionaryAddValue(match, CFSTR(kIOMediaWholeKey), kCFBooleanTrue); + status = IOServiceGetMatchingServices(mach_master_port, + match, &mach_device_list); + if (status != KERN_SUCCESS) { + fprintf(stderr, "%s: IOServiceGetMatchingServices error\n", + __FUNCTION__); + return -oserror(); + } + + indom->it_numinst = 0; + clear_disk_totals(stats); + for (i = 0; (drive = IOIteratorNext(mach_device_list)) != 0; i++) { + status = update_disk(stats, drive, i); + if (status) + break; + IOObjectRelease(drive); + } + IOIteratorReset(mach_device_list); + + if (!status) + status = update_disk_indom(stats, i, indom); + return status; +} diff --git a/src/pmdas/darwin/disk.h b/src/pmdas/darwin/disk.h new file mode 100644 index 0000000..c3579ff --- /dev/null +++ b/src/pmdas/darwin/disk.h @@ -0,0 +1,55 @@ +/* + * Disk statistics types + * Copyright (c) 2004 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define DEVNAMEMAX 255 /* largest device name we allow */ + +/* + * Per-device statistics + */ +typedef struct diskstat { + __uint64_t read; + __uint64_t write; + __uint64_t read_bytes; + __uint64_t write_bytes; + __uint64_t read_time; + __uint64_t write_time; + __uint64_t blocksize; + char name[DEVNAMEMAX + 1]; +} diskstat_t; + +/* + * Global statistics. + * + * We avoid continually realloc'ing memory by keeping track + * of the maximum number of devices we've allocated space for + * so far, and only realloc new space if we go beyond that. + */ +typedef struct diskstats { + __uint64_t read; + __uint64_t write; + __uint64_t read_bytes; + __uint64_t write_bytes; + __uint64_t blkread; + __uint64_t blkwrite; + __uint64_t read_time; + __uint64_t write_time; + int highwater; /* largest number of devices seen so far */ + diskstat_t *disks; /* space for highwater number of devices */ +} diskstats_t; + diff --git a/src/pmdas/darwin/help b/src/pmdas/darwin/help new file mode 100644 index 0000000..ef8deee --- /dev/null +++ b/src/pmdas/darwin/help @@ -0,0 +1,199 @@ +# +# Copyright (c) 2004 Silicon Graphics, Inc. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +# MacOS X PMDA help file in the ASCII format +# +# lines beginning with a # are ignored +# lines beginning @ introduce a new entry of the form +# @ metric_name oneline-text +# help test goes +# here over multiple lines +# ... +# +# the metric_name is decoded against the default PMNS -- as a special case, +# a name of the form NNN.MM (for numeric NNN and MM) is interpreted as an +# instance domain identification, and the text describes the instance domain +# +# blank lines before the @ line are ignored +# +@ kernel.uname.release release level of the running kernel +@ kernel.uname.version version level (build number) and build date of the running kernel +@ kernel.uname.sysname name of the implementation of the operating system +@ kernel.uname.machine name of the hardware type the system is running on +@ kernel.uname.nodename host name of this node on the network + +@ kernel.all.cpu.user total user time for all processors +@ kernel.all.cpu.nice total nice time for all processors +@ kernel.all.cpu.sys total system time for all processors +@ kernel.all.cpu.idle total idle time for all processors +@ kernel.all.load 1, 5 and 15 minute load average +@ kernel.all.uptime time the current kernel has been running +@ kernel.all.hz value of HZ (jiffies/second) for the currently running kernel +@ hinv.ncpu number of processors +@ kernel.percpu.cpu.user percpu user processor time metric +@ kernel.percpu.cpu.nice percpu nice user processor time metric +@ kernel.percpu.cpu.sys percpu system processor time metric +@ kernel.percpu.cpu.idle percpu idle processor time metric + +@ hinv.physmem total system memory +@ hinv.pagesize system memory page size +@ mem.physmem total system memory metric +@ mem.freemem total pages free in the system +@ mem.active the total pages currently in use and pageable +@ mem.inactive the total pages on the inactive list +@ mem.pages.freemem total number of free pages in the system +@ mem.pages.active the number of pages currently in use and pageable +@ mem.pages.inactive the number of pages on the inactive list +@ mem.pages.reactivated the number of pages that have been moved from inactive to active list +@ mem.pages.wired the total number of pages wired down (cannot be paged out) +@ mem.pages.faults the number of times the "vm_fault" routine has been called +@ mem.pages.cow_faults the number of faults that caused a page to be copied +@ mem.pages.zero_filled the number of pages that have been zero-filled on demand +@ mem.pageins the number of requests for pages from a pager +@ mem.pageouts the number of pages that have been paged out +@ mem.cache_hits the number of object cache hits +@ mem.cache_lookups the number of object cache lookups +@ mem.util.wired wired memory +@ mem.util.active active memory +@ mem.util.inactive inactive memory +@ mem.util.free free memory + +@ hinv.nfilesys number of file systems currently mounted +@ filesys.capacity total capacity of mounted filesystem (Kbytes) +@ filesys.used total space used on mounted filesystem (Kbytes) +@ filesys.free total space free on mounted filesystem (Kbytes) +@ filesys.usedfiles number of inodes allocated on mounted filesystem +@ filesys.freefiles number of unallocated inodes on mounted filesystem +@ filesys.mountdir file system mount point +@ filesys.full percentage of filesystem in use +@ filesys.blocksize size of each block on mounted filesystem (Bytes) +@ filesys.avail total space free to non-superusers on mounted filesystem (Kbytes) +@ filesys.type filesystem type name for each mounted filesystem + +@ hinv.ndisk number of disks in the system +@ disk.dev.read per-disk read operations +Cumulative number of disk read operations since system boot time (subject +to counter wrap). + +@ disk.dev.write per-disk write operations +Cumulative number of disk write operations since system boot time (subject +to counter wrap). + +@ disk.dev.total per-disk total (read+write) operations +Cumulative number of disk read and write operations since system boot +time (subject to counter wrap). + +@ disk.dev.read_bytes per-disk count of bytes read +@ disk.dev.write_bytes per-disk count of bytes written +@ disk.dev.total_bytes per-disk count bytes read and written +@ disk.dev.blkread per-disk block read operations +Cumulative number of disk block read operations since system boot time +(subject to counter wrap). + +@ disk.dev.blkwrite per-disk block write operations +Cumulative number of disk block write operations since system boot time +(subject to counter wrap). + +@ disk.dev.blktotal per-disk total (read+write) block operations +Cumulative number of disk block read and write operations since system +boot time (subject to counter wrap). + +@ disk.dev.read_time i dunno either +@ disk.dev.write_time i dunno either +@ disk.dev.total_time i dunno either +@ disk.all.read_time i dunno either +@ disk.all.write_time i dunno either +@ disk.all.total_time i dunno either + +@ disk.all.read total read operations, summed for all disks +Cumulative number of disk read operations since system boot time +(subject to counter wrap), summed over all disk devices. + +@ disk.all.write total write operations, summed for all disks +Cumulative number of disk read operations since system boot time +(subject to counter wrap), summed over all disk devices. + +@ disk.all.total total read and write operations, summed for all disks +Cumulative number of disk read and write operations since system boot +time (subject to counter wrap), summed over all disk devices. + +@ disk.all.blkread block read operations, summed for all disks +Cumulative number of disk block read operations since system boot time +(subject to counter wrap), summed over all disk devices. + +@ disk.all.blkwrite block write operations, summed for all disks +Cumulative number of disk block write operations since system boot time +(subject to counter wrap), summed over all disk devices. + +@ disk.all.blktotal total (read+write) block operations, summed for all disks +Cumulative number of disk block read and write operations since system +boot time (subject to counter wrap), summed over all disk devices. + +@ disk.all.read_bytes count of bytes read for all disk devices +@ disk.all.write_bytes count of bytes written for all disk devices +@ disk.all.total_bytes count of bytes read and written for all disk devices + +@ network.interface.in.bytes network receive read bytes +@ network.interface.in.packets network receive read packets +@ network.interface.in.errors network receive read errors +@ network.interface.in.drops connections dropped on input +@ network.interface.in.mcasts network receive multicasts +@ network.interface.out.bytes network send write bytes +@ network.interface.out.packets network send write packets +@ network.interface.out.errors network send write errors +@ network.interface.out.mcasts network send multicasts +@ network.interface.collisions network send collisions for CDMA interfaces +@ network.interface.mtu maximum transmission size for network interfaces +@ network.interface.baudrate line speed for network interfaces +@ network.interface.total.bytes total network bytes received and sent +@ network.interface.total.packets total network packets received and sent +@ network.interface.total.errors total network errors on receive and send +@ network.interface.total.drops total network connections dropped +@ network.interface.total.mcasts total network multicasts + +@ nfs3.client.calls +@ nfs3.client.reqs +@ nfs3.server.calls +@ nfs3.server.reqs +@ rpc.client.rpccnt +@ rpc.client.rpcretrans +@ rpc.client.rpctimeouts +@ rpc.client.rpcinvalid +@ rpc.client.rpcunexpected +@ rpc.client.attrcache.hits +@ rpc.client.attrcache.misses +@ rpc.client.lookupcache.hits +@ rpc.client.lookupcache.misses +@ rpc.client.biocache.read.hits +@ rpc.client.biocache.read.misses +@ rpc.client.biocache.write.hits +@ rpc.client.biocache.write.misses +@ rpc.client.biocache.readlink.hits +@ rpc.client.biocache.readlink.misses +@ rpc.client.biocache.readdir.hits +@ rpc.client.biocache.readdir.misses +@ rpc.client.direofcache.hits +@ rpc.client.direofcache.misses +@ rpc.server.retfailed +@ rpc.server.faults +@ rpc.server.cache.inprog +@ rpc.server.cache.nonidem +@ rpc.server.cache.idem +@ rpc.server.cache.misses +@ rpc.server.vopwrites +@ rpc.server.pageins +@ rpc.server.pageouts diff --git a/src/pmdas/darwin/kernel.c b/src/pmdas/darwin/kernel.c new file mode 100644 index 0000000..57921c9 --- /dev/null +++ b/src/pmdas/darwin/kernel.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2004 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ +#include <sys/time.h> +#include <sys/types.h> +#include <sys/resource.h> +#include <sys/utsname.h> +#include <sys/sysctl.h> +#include <sys/mount.h> +#include <mach/mach.h> +#include "pmapi.h" +#include "impl.h" +#include "pmda.h" + +extern mach_port_t mach_host; +extern int mach_hertz; + +int +refresh_vmstat(struct vm_statistics *vmstat) +{ + int error, info = HOST_VM_INFO; + natural_t count = HOST_VM_INFO_COUNT; + + error = host_statistics(mach_host, info, (host_info_t)vmstat, &count); + return (error != KERN_SUCCESS) ? -oserror() : 0; +} + +int +refresh_cpuload(struct host_cpu_load_info *cpuload) +{ + int error, info = HOST_CPU_LOAD_INFO; + natural_t count = HOST_CPU_LOAD_INFO_COUNT; + + error = host_statistics(mach_host, info, (host_info_t)cpuload, &count); + return (error != KERN_SUCCESS) ? -oserror() : 0; +} + +int +refresh_uname(struct utsname *utsname) +{ + return (uname(utsname) == -1) ? -oserror() : 0; +} + +int +refresh_hertz(unsigned int *hertz) +{ + int mib[2] = { CTL_KERN, KERN_CLOCKRATE }; + size_t size = sizeof(struct clockinfo); + struct clockinfo clockrate; + + if (sysctl(mib, 2, &clockrate, &size, NULL, 0) == -1) + return -oserror(); + *hertz = clockrate.hz; + return 0; +} + +int +refresh_loadavg(float *loadavg) +{ + int mib[2] = { CTL_VM, VM_LOADAVG }; + size_t size = sizeof(struct loadavg); + struct loadavg loadavgs; + + if (sysctl(mib, 2, &loadavgs, &size, NULL, 0) == -1) + return -oserror(); + loadavg[0] = (float)loadavgs.ldavg[0] / (float)loadavgs.fscale; + loadavg[1] = (float)loadavgs.ldavg[1] / (float)loadavgs.fscale; + loadavg[2] = (float)loadavgs.ldavg[2] / (float)loadavgs.fscale; + return 0; +} + +int +refresh_uptime(unsigned int *uptime) +{ + static struct timeval boottime; + struct timeval timediff; + + if (!boottime.tv_sec) { + int mib[2] = { CTL_KERN, KERN_BOOTTIME }; + size_t size = sizeof(struct timeval); + + if (sysctl(mib, 2, &boottime, &size, NULL, 0) == -1) + return -oserror(); + } + + __pmtimevalNow(&timediff); + timediff.tv_usec -= boottime.tv_usec; + if (timediff.tv_usec < 0) { + timediff.tv_usec += 1000000; + timediff.tv_sec--; + } + timediff.tv_sec -= boottime.tv_sec; + + *uptime = timediff.tv_sec; + return 0; +} + +int +refresh_cpus(struct processor_cpu_load_info **cpuload, pmdaIndom *indom) +{ + natural_t ncpu, icount; + processor_info_array_t iarray; + struct processor_cpu_load_info *cpuinfo; + int error, i, info = PROCESSOR_CPU_LOAD_INFO; + + error = host_processor_info(mach_host, info, &ncpu, &iarray, &icount); + if (error != KERN_SUCCESS) + return -oserror(); + + cpuinfo = (struct processor_cpu_load_info *)iarray; + if (ncpu != indom->it_numinst) { + char name[16]; /* 8 is real max atm, but be conservative */ + + error = -ENOMEM; + i = sizeof(unsigned long) * CPU_STATE_MAX * ncpu; + if ((*cpuload = realloc(*cpuload, i)) == NULL) + goto vmdealloc; + + i = sizeof(pmdaInstid) * ncpu; + if ((indom->it_set = realloc(indom->it_set, i)) == NULL) { + free(*cpuload); + *cpuload = NULL; + indom->it_numinst = 0; + goto vmdealloc; + } + + for (i = 0; i < ncpu; i++) { + snprintf(name, sizeof(name), "cpu%d", i); + indom->it_set[i].i_name = strdup(name); + indom->it_set[i].i_inst = i; + } + indom->it_numinst = ncpu; + } + + error = 0; + for (i = 0; i < ncpu; i++) + memcpy(&(*cpuload)[i], &cpuinfo[i], + sizeof(unsigned long) * CPU_STATE_MAX); + +vmdealloc: + vm_deallocate(mach_host, (vm_address_t)iarray, icount); + return error; +} + +int +refresh_filesys(struct statfs **filesys, pmdaIndom *indom) +{ + int i, count = getmntinfo(filesys, MNT_NOWAIT); + + if (count < 0) { + indom->it_numinst = 0; + indom->it_set = NULL; + return -oserror(); + } + if (count > 0 && count != indom->it_numinst) { + i = sizeof(pmdaInstid) * count; + if ((indom->it_set = realloc(indom->it_set, i)) == NULL) { + indom->it_numinst = 0; + return -ENOMEM; + } + } + for (i = 0; i < count; i++) { + indom->it_set[i].i_name = (*filesys)[i].f_mntfromname; + indom->it_set[i].i_inst = i; + } + indom->it_numinst = count; + return 0; +} + +#if 0 +int +refresh_hinv() +{ +sysctl... +hw.machine = Power Macintosh +hw.model = PowerMac4,2 +hw.busfrequency = 99837332 +hw.cpufrequency = 700000000 +hw.cachelinesize = 32 +hw.l1icachesize = 32768 +hw.l1dcachesize = 32768 +hw.l2settings = 2147483648 +hw.l2cachesize = 262144 +} +#endif diff --git a/src/pmdas/darwin/network.c b/src/pmdas/darwin/network.c new file mode 100644 index 0000000..bc134c6 --- /dev/null +++ b/src/pmdas/darwin/network.c @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2004,2006 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ +#include <fcntl.h> +#include <limits.h> +#include <sys/socket.h> +#include <sys/sysctl.h> +#include <net/if.h> +#include <net/if_var.h> +#include <net/if_dl.h> +#include <net/route.h> +#include <mach/mach.h> +#include "pmapi.h" +#include "impl.h" +#include "pmda.h" +#include "network.h" + +extern char *pmProgname; +extern mach_port_t mach_master_port; + +void +init_network(void) +{ + +} + +/* + * Ensure we have space for the next interface in our pre-allocated + * interface stats pool. If not, make some or pass on the error. + */ +static int +check_stats_size(struct netstats *stats, int count) +{ + if (count > stats->highwater) { + stats->highwater++; + stats->interfaces = realloc(stats->interfaces, + stats->highwater * sizeof(struct ifacestat)); + if (!stats->interfaces) { + stats->highwater = 0; + return -ENOMEM; + } + } + return 0; +} + +/* + * Insert all interfaces into the global network instance domain. + */ +static int +update_network_indom(struct netstats *all, int count, pmdaIndom *indom) +{ + int i; + + if (count > 0 && count != indom->it_numinst) { + i = sizeof(pmdaInstid) * count; + if ((indom->it_set = realloc(indom->it_set, i)) == NULL) { + indom->it_numinst = 0; + return -ENOMEM; + } + } + for (i = 0; i < count; i++) { + indom->it_set[i].i_name = all->interfaces[i].name; + indom->it_set[i].i_inst = i; + } + indom->it_numinst = count; + return 0; +} + +int +refresh_network(struct netstats *stats, pmdaIndom *indom) +{ + int i = 0, status = 0; + + size_t n; + char *new_buf, *next, *end; + struct sockaddr_dl *sdl; + + static char *buf=NULL; + static size_t buf_len=0; + +#ifdef RTM_IFINFO2 + struct if_msghdr2 *ifm; + int mib[6] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST2, 0}; +#else + struct if_msghdr *ifm; + int mib[6] = {CTL_NET, PF_ROUTE, 0, 0, NET_RT_IFLIST, 0}; +#endif + + if( sysctl( mib, 6, NULL, &n, NULL, 0 ) < 0 ) { + /* unable to query buffer size */ + fprintf( stderr, "%s: get net mib buf len failed\n", pmProgname ); + return -ENXIO; + } + if( n > buf_len ) { + if( (new_buf = malloc(n)) == NULL ) { + /* unable to malloc buf */ + fprintf( stderr, "%s: net mib buf malloc failed\n", pmProgname ); + return -ENXIO; + } else { + if( buf != NULL ) free( buf ); + buf = new_buf; + buf_len = n; + } + } + if( sysctl( mib, 6, buf, &n, NULL, 0 ) < 0 ) { + /* unable to copy-in buffer */ + fprintf( stderr, "%s: net mib buf read failed\n", pmProgname ); + return -ENXIO; + } + + for( next = buf, i=0, end = buf + n; next < end; ) { + +#ifdef RTM_IFINFO2 + ifm = (struct if_msghdr2 *)next; + next += ifm->ifm_msglen; + if( ifm->ifm_type == RTM_IFINFO2 ) { +#else + ifm = (struct if_msghdr *)next; + next += ifm->ifm_msglen; + if( ifm->ifm_type == RTM_IFINFO ) { +#endif + + status = check_stats_size(stats, i + 1); + if (status < 0) break; + + sdl = (struct sockaddr_dl *)(ifm + 1); + n = sdl->sdl_nlen < IFNAMEMAX ? sdl->sdl_nlen : IFNAMEMAX; + strncpy( stats->interfaces[i].name, sdl->sdl_data, n ); + stats->interfaces[i].name[n] = 0; + + stats->interfaces[i].mtu = ifm->ifm_data.ifi_mtu; + stats->interfaces[i].baudrate = ifm->ifm_data.ifi_baudrate; + stats->interfaces[i].ipackets = ifm->ifm_data.ifi_ipackets; + stats->interfaces[i].ierrors = ifm->ifm_data.ifi_ierrors; + stats->interfaces[i].opackets = ifm->ifm_data.ifi_opackets; + stats->interfaces[i].oerrors = ifm->ifm_data.ifi_oerrors; + stats->interfaces[i].collisions = ifm->ifm_data.ifi_collisions; + stats->interfaces[i].ibytes = ifm->ifm_data.ifi_ibytes; + stats->interfaces[i].obytes = ifm->ifm_data.ifi_obytes; + stats->interfaces[i].imcasts = ifm->ifm_data.ifi_imcasts; + stats->interfaces[i].omcasts = ifm->ifm_data.ifi_omcasts; + stats->interfaces[i].iqdrops = ifm->ifm_data.ifi_iqdrops; + i++; + } + } + if (!status) update_network_indom(stats, i, indom); + return status; +} + +int +refresh_nfs(struct nfsstats *stats) +{ + int name[3]; + size_t length = sizeof(struct nfsstats); + static int nfstype = -1; + + if (nfstype == -1) { + struct vfsconf vfsconf; + + if (getvfsbyname("nfs", &vfsconf) == -1) + return -oserror(); + nfstype = vfsconf.vfc_typenum; + } + + name[0] = CTL_VFS; + name[1] = nfstype; + name[0] = NFS_NFSSTATS; + if (sysctl(name, 3, stats, &length, NULL, 0) == -1) + return -oserror(); + stats->biocache_reads -= stats->read_bios; + stats->biocache_writes -= stats->write_bios; + stats->biocache_readlinks -= stats->readlink_bios; + stats->biocache_readdirs -= stats->readdir_bios; + return 0; +} diff --git a/src/pmdas/darwin/network.h b/src/pmdas/darwin/network.h new file mode 100644 index 0000000..985ec9a --- /dev/null +++ b/src/pmdas/darwin/network.h @@ -0,0 +1,57 @@ +/* + * Network interface statistics types + * Copyright (c) 2004 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <sys/mount.h> +#include <nfs/rpcv2.h> +#include <nfs/nfsproto.h> +#include <nfs/nfs.h> + +#define IFNAMEMAX 16 /* largest interface name we allow */ + +/* + * Per-interface statistics + */ +typedef struct ifacestat { + __uint64_t mtu; /* maximum transmission unit */ + __uint64_t baudrate; /* linespeed */ + __uint64_t ipackets; /* packets received on interface */ + __uint64_t ierrors; /* input errors on interface */ + __uint64_t opackets; /* packets sent on interface */ + __uint64_t oerrors; /* output errors on interface */ + __uint64_t collisions; /* collisions on csma interfaces */ + __uint64_t ibytes; /* total number of octets received */ + __uint64_t obytes; /* total number of octets sent */ + __uint64_t imcasts; /* packets received via multicast */ + __uint64_t omcasts; /* packets sent via multicast */ + __uint64_t iqdrops; /* dropped on input, this interface */ + char name[IFNAMEMAX + 1]; +} ifacestat_t; + +/* + * Global statistics. + * + * We avoid continually realloc'ing memory by keeping track + * of the maximum number of interfaces we've allocated space + * for so far, and only realloc new space if we go beyond that. + */ +typedef struct netstats { + int highwater; /* largest number of interfaces seen so far */ + ifacestat_t *interfaces; /* space for highwater number of interfaces */ +} netstats_t; + diff --git a/src/pmdas/darwin/pmda.c b/src/pmdas/darwin/pmda.c new file mode 100644 index 0000000..e000b11 --- /dev/null +++ b/src/pmdas/darwin/pmda.c @@ -0,0 +1,1268 @@ +/* + * MacOS X kernel PMDA + * "darwin" is easier to type than "macosx", especially for Aussies. ;-) + * + * Copyright (c) 2012 Red Hat. + * Copyright (c) 2004 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <syslog.h> +#include <unistd.h> +#include <sys/mount.h> +#include <sys/utsname.h> +#include <mach/mach.h> +#include "pmapi.h" +#include "impl.h" +#include "pmda.h" +#include "domain.h" + +#include "disk.h" +#include "network.h" + + +#define page_count_to_kb(x) (((__uint64_t)(x) << mach_page_shift) >> 10) +#define page_count_to_mb(x) (((__uint64_t)(x) << mach_page_shift) >> 20) + +static pmdaInterface dispatch; +static int _isDSO = 1; /* =0 I am a daemon */ +static char *username; + +mach_port_t mach_host = 0; +vm_size_t mach_page_size = 0; +unsigned int mach_page_shift = 0; + +unsigned int mach_hertz = 0; +extern int refresh_hertz(unsigned int *); + +int mach_uname_error = 0; +struct utsname mach_uname = { { 0 } }; +extern int refresh_uname(struct utsname *); + +int mach_loadavg_error = 0; +float mach_loadavg[3] = { 0,0,0 }; +extern int refresh_loadavg(float *); + +int mach_cpuload_error = 0; +struct host_cpu_load_info mach_cpuload = { { 0 } }; +extern int refresh_cpuload(struct host_cpu_load_info *); + +int mach_vmstat_error = 0; +struct vm_statistics mach_vmstat = { 0 }; +extern int refresh_vmstat(struct vm_statistics *); + +int mach_fs_error = 0; +struct statfs *mach_fs = NULL; +extern int refresh_filesys(struct statfs **, pmdaIndom *); + +int mach_disk_error = 0; +struct diskstats mach_disk = { 0 }; +extern int refresh_disks(struct diskstats *, pmdaIndom *); + +int mach_cpu_error = 0; +struct processor_cpu_load_info *mach_cpu = NULL; +extern int refresh_cpus(struct processor_cpu_load_info **, pmdaIndom *); + +int mach_uptime_error = 0; +unsigned int mach_uptime = 0; +extern int refresh_uptime(unsigned int *); + +int mach_net_error = 0; +struct netstats mach_net = { 0 }; +extern int refresh_network(struct netstats *, pmdaIndom *); +extern void init_network(void); + +int mach_nfs_error = 0; +struct nfsstats mach_nfs = { 0 }; +extern int refresh_nfs(struct nfsstats *); + +/* + * Metric Instance Domains (statically initialized ones only) + */ +static pmdaInstid loadavg_indom_id[] = { + { 1, "1 minute" }, { 5, "5 minute" }, { 15, "15 minute" } +}; +#define LOADAVG_COUNT (sizeof(loadavg_indom_id)/sizeof(pmdaInstid)) + +static pmdaInstid nfs3_indom_id[] = { + { 0, "null" }, { 1, "getattr" }, { 2, "setattr" }, + { 3, "lookup" }, { 4, "access" }, { 5, "readlink" }, + { 6, "read" }, { 7, "write" }, { 8, "create" }, + { 9, "mkdir" }, { 10, "symlink" }, { 11, "mknod" }, + { 12, "remove" }, { 13, "rmdir" }, { 14, "rename" }, + { 15, "link" }, { 16, "readdir" }, { 17, "readdir+" }, + { 18, "statfs" }, { 19, "fsinfo" }, { 20, "pathconf" }, + { 21, "commit" }, { 22, "getlease" }, { 23, "vacate" }, + { 24, "evict" } +}; +#define NFS3_RPC_COUNT (sizeof(nfs3_indom_id)/sizeof(pmdaInstid)) + +/* + * Metric Instance Domain table + */ +enum { + LOADAVG_INDOM, /* 0 - 1, 5, 15 minute run queue averages */ + FILESYS_INDOM, /* 1 - set of all mounted filesystems */ + DISK_INDOM, /* 2 - set of all disk devices */ + CPU_INDOM, /* 3 - set of all processors */ + NETWORK_INDOM, /* 4 - set of all network interfaces */ + NFS3_INDOM, /* 6 - nfs v3 operations */ + NUM_INDOMS /* total number of instance domains */ +}; + +static pmdaIndom indomtab[] = { + { LOADAVG_INDOM, 3, loadavg_indom_id }, + { FILESYS_INDOM, 0, NULL }, + { DISK_INDOM, 0, NULL }, + { CPU_INDOM, 0, NULL }, + { NETWORK_INDOM, 0, NULL }, + { NFS3_INDOM, NFS3_RPC_COUNT, nfs3_indom_id }, +}; + +/* + * Fetch clusters and metric table + */ +enum { + CLUSTER_INIT = 0, /* 0 = values we know at startup */ + CLUSTER_VMSTAT, /* 1 = mach memory statistics */ + CLUSTER_KERNEL_UNAME, /* 2 = utsname information */ + CLUSTER_LOADAVG, /* 3 = run queue averages */ + CLUSTER_HINV, /* 4 = hardware inventory */ + CLUSTER_FILESYS, /* 5 = mounted filesystems */ + CLUSTER_CPULOAD, /* 6 = number of ticks in state */ + CLUSTER_DISK, /* 7 = disk device statistics */ + CLUSTER_CPU, /* 8 = per-cpu statistics */ + CLUSTER_UPTIME, /* 9 = system uptime in seconds */ + CLUSTER_NETWORK, /* 10 = networking statistics */ + CLUSTER_NFS, /* 11 = nfs filesystem statistics */ + NUM_CLUSTERS /* total number of clusters */ +}; + +static pmdaMetric metrictab[] = { + +/* hinv.pagesize */ + { &mach_page_size, + { PMDA_PMID(CLUSTER_INIT,0), PM_TYPE_U64, PM_INDOM_NULL, + PM_SEM_DISCRETE, PMDA_PMUNITS(1,0,0,PM_SPACE_BYTE,0,0) }, }, +/* kernel.all.hz */ + { &mach_hertz, + { PMDA_PMID(CLUSTER_INIT,1), PM_TYPE_U32, PM_INDOM_NULL, + PM_SEM_DISCRETE, PMDA_PMUNITS(0,-1,1,0,PM_TIME_SEC,PM_COUNT_ONE) }, }, + +/* hinv.physmem */ + { NULL, + { PMDA_PMID(CLUSTER_VMSTAT,2), PM_TYPE_U32, PM_INDOM_NULL, + PM_SEM_DISCRETE, PMDA_PMUNITS(1,0,0,PM_SPACE_MBYTE,0,0) }, }, +/* mem.physmem */ + { NULL, + { PMDA_PMID(CLUSTER_VMSTAT,3), PM_TYPE_U64, PM_INDOM_NULL, + PM_SEM_DISCRETE, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, }, +/* mem.freemem */ + { NULL, + { PMDA_PMID(CLUSTER_VMSTAT,4), PM_TYPE_U64, PM_INDOM_NULL, + PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, }, +/* mem.active */ + { NULL, + { PMDA_PMID(CLUSTER_VMSTAT,5), PM_TYPE_U64, PM_INDOM_NULL, + PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, }, +/* mem.inactive */ + { NULL, + { PMDA_PMID(CLUSTER_VMSTAT,6), PM_TYPE_U64, PM_INDOM_NULL, + PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, }, +/* mem.pages.free */ + { &mach_vmstat.free_count, + { PMDA_PMID(CLUSTER_VMSTAT,7), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_INSTANT, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* mem.pages.active */ + { &mach_vmstat.active_count, + { PMDA_PMID(CLUSTER_VMSTAT,8), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_INSTANT, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* mem.pages.inactive */ + { &mach_vmstat.inactive_count, + { PMDA_PMID(CLUSTER_VMSTAT,9), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_INSTANT, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* mem.pages.reactivated */ + { &mach_vmstat.reactivations, + { PMDA_PMID(CLUSTER_VMSTAT,10), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* mem.pages.wired */ + { &mach_vmstat.wire_count, + { PMDA_PMID(CLUSTER_VMSTAT,11), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_INSTANT, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* mem.pages.faults */ + { &mach_vmstat.faults, + { PMDA_PMID(CLUSTER_VMSTAT,12), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* mem.pages.cow_faults */ + { &mach_vmstat.cow_faults, + { PMDA_PMID(CLUSTER_VMSTAT,13), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* mem.pages.zero_filled */ + { &mach_vmstat.zero_fill_count, + { PMDA_PMID(CLUSTER_VMSTAT,14), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* mem.pageins */ + { &mach_vmstat.pageins, + { PMDA_PMID(CLUSTER_VMSTAT,15), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* mem.pageouts */ + { &mach_vmstat.pageouts, + { PMDA_PMID(CLUSTER_VMSTAT,16), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* mem.cache_hits */ + { &mach_vmstat.hits, + { PMDA_PMID(CLUSTER_VMSTAT,17), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* mem.cache_lookups */ + { &mach_vmstat.lookups, + { PMDA_PMID(CLUSTER_VMSTAT,18), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* mem.util.wired */ + { NULL, + { PMDA_PMID(CLUSTER_VMSTAT,19), PM_TYPE_U64, PM_INDOM_NULL, + PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, }, +/* mem.util.active */ + { NULL, + { PMDA_PMID(CLUSTER_VMSTAT,20), PM_TYPE_U64, PM_INDOM_NULL, + PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, }, +/* mem.util.inactive */ + { NULL, + { PMDA_PMID(CLUSTER_VMSTAT,21), PM_TYPE_U64, PM_INDOM_NULL, + PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, }, +/* mem.util.free */ + { NULL, + { PMDA_PMID(CLUSTER_VMSTAT,22), PM_TYPE_U64, PM_INDOM_NULL, + PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, }, + +/* kernel.uname.release */ + { mach_uname.release, + { PMDA_PMID(CLUSTER_KERNEL_UNAME, 23), PM_TYPE_STRING, PM_INDOM_NULL, + PM_SEM_INSTANT, PMDA_PMUNITS(0,0,0,0,0,0) }, }, +/* kernel.uname.version */ + { mach_uname.version, + { PMDA_PMID(CLUSTER_KERNEL_UNAME, 24), PM_TYPE_STRING, PM_INDOM_NULL, + PM_SEM_INSTANT, PMDA_PMUNITS(0,0,0,0,0,0) }, }, +/* kernel.uname.sysname */ + { mach_uname.sysname, + { PMDA_PMID(CLUSTER_KERNEL_UNAME, 25), PM_TYPE_STRING, PM_INDOM_NULL, + PM_SEM_INSTANT, PMDA_PMUNITS(0,0,0,0,0,0) }, }, +/* kernel.uname.machine */ + { mach_uname.machine, + { PMDA_PMID(CLUSTER_KERNEL_UNAME, 26), PM_TYPE_STRING, PM_INDOM_NULL, + PM_SEM_INSTANT, PMDA_PMUNITS(0,0,0,0,0,0) }, }, +/* kernel.uname.nodename */ + { mach_uname.nodename, + { PMDA_PMID(CLUSTER_KERNEL_UNAME, 27), PM_TYPE_STRING, PM_INDOM_NULL, + PM_SEM_INSTANT, PMDA_PMUNITS(0,0,0,0,0,0) }, }, +/* pmda.uname */ + { NULL, + { PMDA_PMID(CLUSTER_KERNEL_UNAME, 28), PM_TYPE_STRING, PM_INDOM_NULL, + PM_SEM_INSTANT, PMDA_PMUNITS(0,0,0,0,0,0) }, }, +/* pmda.version */ + { NULL, + { PMDA_PMID(CLUSTER_KERNEL_UNAME, 29), PM_TYPE_STRING, PM_INDOM_NULL, + PM_SEM_INSTANT, PMDA_PMUNITS(0,0,0,0,0,0) }, }, + +/* kernel.all.load */ + { NULL, + { PMDA_PMID(CLUSTER_LOADAVG,30), PM_TYPE_FLOAT, LOADAVG_INDOM, + PM_SEM_INSTANT, PMDA_PMUNITS(0,0,0,0,0,0) }, }, + +/* hinv.nfilesys */ + { NULL, + { PMDA_PMID(CLUSTER_FILESYS,31), PM_TYPE_U32, PM_INDOM_NULL, + PM_SEM_DISCRETE, PMDA_PMUNITS(0,0,0,0,0,0) }, }, +/* filesys.capacity */ + { NULL, + { PMDA_PMID(CLUSTER_FILESYS,32), PM_TYPE_U64, FILESYS_INDOM, + PM_SEM_DISCRETE, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, }, +/* filesys.used */ + { NULL, + { PMDA_PMID(CLUSTER_FILESYS,33), PM_TYPE_U64, FILESYS_INDOM, + PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, }, +/* filesys.free */ + { NULL, + { PMDA_PMID(CLUSTER_FILESYS,34), PM_TYPE_U64, FILESYS_INDOM, + PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, }, +/* filesys.usedfiles */ + { NULL, + { PMDA_PMID(CLUSTER_FILESYS,35), PM_TYPE_U32, FILESYS_INDOM, + PM_SEM_INSTANT, PMDA_PMUNITS(0,0,0,0,0,0) }, }, +/* filesys.freefiles */ + { NULL, + { PMDA_PMID(CLUSTER_FILESYS,36), PM_TYPE_U32, FILESYS_INDOM, + PM_SEM_INSTANT, PMDA_PMUNITS(0,0,0,0,0,0) }, }, +/* filesys.mountdir */ + { NULL, + { PMDA_PMID(CLUSTER_FILESYS,37), PM_TYPE_STRING, FILESYS_INDOM, + PM_SEM_DISCRETE, PMDA_PMUNITS(0,0,0,0,0,0) }, }, +/* filesys.full */ + { NULL, + { PMDA_PMID(CLUSTER_FILESYS,38), PM_TYPE_DOUBLE, FILESYS_INDOM, + PM_SEM_DISCRETE, PMDA_PMUNITS(0,0,0,0,0,0) }, }, +/* filesys.blocksize */ + { NULL, + { PMDA_PMID(CLUSTER_FILESYS,39), PM_TYPE_U32, FILESYS_INDOM, + PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_BYTE,0,0) }, }, +/* filesys.avail */ + { NULL, + { PMDA_PMID(CLUSTER_FILESYS,40), PM_TYPE_U64, FILESYS_INDOM, + PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, }, +/* filesys.type */ + { NULL, + { PMDA_PMID(CLUSTER_FILESYS,41), PM_TYPE_STRING, FILESYS_INDOM, + PM_SEM_DISCRETE, PMDA_PMUNITS(0,0,0,0,0,0) }, }, + +/* kernel.all.cpu.user */ + { NULL, + { PMDA_PMID(CLUSTER_CPULOAD,42), PM_TYPE_U64, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, }, +/* kernel.all.cpu.nice */ + { NULL, + { PMDA_PMID(CLUSTER_CPULOAD,43), PM_TYPE_U64, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, }, +/* kernel.all.cpu.sys */ + { NULL, + { PMDA_PMID(CLUSTER_CPULOAD,44), PM_TYPE_U64, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, }, +/* kernel.all.cpu.idle */ + { NULL, + { PMDA_PMID(CLUSTER_CPULOAD,45), PM_TYPE_U64, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, }, + +/* hinv.ndisk */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,46), PM_TYPE_U32, PM_INDOM_NULL, + PM_SEM_DISCRETE, PMDA_PMUNITS(0,0,0,0,0,0) }, }, +/* disk.dev.read */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,47), PM_TYPE_U64, DISK_INDOM, PM_SEM_COUNTER, + PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* disk.dev.write */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,48), PM_TYPE_U64, DISK_INDOM, PM_SEM_COUNTER, + PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* disk.dev.total */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,49), PM_TYPE_U64, DISK_INDOM, PM_SEM_COUNTER, + PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* disk.dev.read_bytes */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,50), PM_TYPE_U64, DISK_INDOM, PM_SEM_COUNTER, + PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, }, +/* disk.dev.write_bytes */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,51), PM_TYPE_U64, DISK_INDOM, PM_SEM_COUNTER, + PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, }, +/* disk.dev.total_bytes */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,52), PM_TYPE_U64, DISK_INDOM, PM_SEM_COUNTER, + PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, }, +/* disk.dev.blkread */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,53), PM_TYPE_U64, DISK_INDOM, PM_SEM_COUNTER, + PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* disk.dev.blkwrite */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,54), PM_TYPE_U64, DISK_INDOM, PM_SEM_COUNTER, + PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* disk.dev.blktotal */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,55), PM_TYPE_U64, DISK_INDOM, PM_SEM_COUNTER, + PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* disk.dev.read_time */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,56), PM_TYPE_U64, DISK_INDOM, PM_SEM_COUNTER, + PMDA_PMUNITS(0,1,0,0,PM_TIME_NSEC,0) }, }, +/* disk.dev.write_time */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,57), PM_TYPE_U64, DISK_INDOM, PM_SEM_COUNTER, + PMDA_PMUNITS(0,1,0,0,PM_TIME_NSEC,0) }, }, +/* disk.dev.total_time */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,58), PM_TYPE_U64, DISK_INDOM, PM_SEM_COUNTER, + PMDA_PMUNITS(0,1,0,0,PM_TIME_NSEC,0) }, }, +/* disk.all.read */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,59), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER, + PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* disk.all.write */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,60), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER, + PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* disk.all.total */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,61), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER, + PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* disk.all.read_bytes */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,62), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER, + PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, }, +/* disk.all.write_bytes */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,63), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER, + PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, }, +/* disk.all.total_bytes */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,64), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER, + PMDA_PMUNITS(1,0,0,PM_SPACE_KBYTE,0,0) }, }, +/* disk.all.blkread */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,65), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER, + PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* disk.all.blkwrite */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,66), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER, + PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* disk.all.blktotal */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,67), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER, + PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* disk.all.read_time */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,68), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER, + PMDA_PMUNITS(0,1,0,0,PM_TIME_NSEC,0) }, }, +/* disk.all.write_time */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,69), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER, + PMDA_PMUNITS(0,1,0,0,PM_TIME_NSEC,0) }, }, +/* disk.all.total_time */ + { NULL, + { PMDA_PMID(CLUSTER_DISK,70), PM_TYPE_U64, PM_INDOM_NULL, PM_SEM_COUNTER, + PMDA_PMUNITS(0,1,0,0,PM_TIME_NSEC,0) }, }, + +/* hinv.ncpu */ + { NULL, + { PMDA_PMID(CLUSTER_CPU,71), PM_TYPE_U32, PM_INDOM_NULL, + PM_SEM_DISCRETE, PMDA_PMUNITS(0,0,0,0,0,0) }, }, +/* kernel.percpu.cpu.user */ + { NULL, + { PMDA_PMID(CLUSTER_CPU,72), PM_TYPE_U64, CPU_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, }, +/* kernel.percpu.cpu.nice */ + { NULL, + { PMDA_PMID(CLUSTER_CPU,73), PM_TYPE_U64, CPU_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, }, +/* kernel.percpu.cpu.sys */ + { NULL, + { PMDA_PMID(CLUSTER_CPU,74), PM_TYPE_U64, CPU_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, }, +/* kernel.percpu.cpu.idle */ + { NULL, + { PMDA_PMID(CLUSTER_CPU,75), PM_TYPE_U64, CPU_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,1,0,0,PM_TIME_MSEC,0) }, }, + +/* kernel.all.uptime */ + { &mach_uptime, + { PMDA_PMID(CLUSTER_UPTIME,76), PM_TYPE_U32, PM_INDOM_NULL, + PM_SEM_INSTANT, PMDA_PMUNITS(0,1,1,0,PM_TIME_SEC,PM_COUNT_ONE) }, }, + +/* network.interface.in.bytes */ + { NULL, + { PMDA_PMID(CLUSTER_NETWORK,77), PM_TYPE_U64, NETWORK_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,PM_SPACE_BYTE,0,0) }, }, +/* network.interface.in.packets */ + { NULL, + { PMDA_PMID(CLUSTER_NETWORK,78), PM_TYPE_U64, NETWORK_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* network.interface.in.errors */ + { NULL, + { PMDA_PMID(CLUSTER_NETWORK,79), PM_TYPE_U64, NETWORK_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* network.interface.in.drops */ + { NULL, + { PMDA_PMID(CLUSTER_NETWORK,80), PM_TYPE_U64, NETWORK_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* network.interface.in.mcasts */ + { NULL, + { PMDA_PMID(CLUSTER_NETWORK,81), PM_TYPE_U64, NETWORK_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* network.interface.out.bytes */ + { NULL, + { PMDA_PMID(CLUSTER_NETWORK,82), PM_TYPE_U64, NETWORK_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,0,PM_SPACE_BYTE,0) }, }, +/* network.interface.out.packets */ + { NULL, + { PMDA_PMID(CLUSTER_NETWORK,83), PM_TYPE_U64, NETWORK_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* network.interface.out.errors */ + { NULL, + { PMDA_PMID(CLUSTER_NETWORK,84), PM_TYPE_U64, NETWORK_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* network.interface.out.mcasts */ + { NULL, + { PMDA_PMID(CLUSTER_NETWORK,85), PM_TYPE_U64, NETWORK_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* network.interface.collisions */ + { NULL, + { PMDA_PMID(CLUSTER_NETWORK,86), PM_TYPE_U64, NETWORK_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* network.interface.mtu */ + { NULL, + { PMDA_PMID(CLUSTER_NETWORK,87), PM_TYPE_U64, NETWORK_INDOM, + PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,0,PM_SPACE_BYTE,0) }, }, +/* network.interface.baudrate */ + { NULL, + { PMDA_PMID(CLUSTER_NETWORK,88), PM_TYPE_U64, NETWORK_INDOM, + PM_SEM_INSTANT, PMDA_PMUNITS(1,0,0,0,PM_SPACE_BYTE,0) }, }, +/* network.interface.total.bytes */ + { NULL, + { PMDA_PMID(CLUSTER_NETWORK,89), PM_TYPE_U64, NETWORK_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(1,0,0,0,PM_SPACE_BYTE,0) }, }, +/* network.interface.total.packets */ + { NULL, + { PMDA_PMID(CLUSTER_NETWORK,90), PM_TYPE_U64, NETWORK_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* network.interface.total.errors */ + { NULL, + { PMDA_PMID(CLUSTER_NETWORK,91), PM_TYPE_U64, NETWORK_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* network.interface.total.drops */ + { NULL, + { PMDA_PMID(CLUSTER_NETWORK,92), PM_TYPE_U64, NETWORK_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* network.interface.total.mcasts */ + { NULL, + { PMDA_PMID(CLUSTER_NETWORK,93), PM_TYPE_U64, NETWORK_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, + +/* nfs3.client.calls */ + { NULL, + { PMDA_PMID(CLUSTER_NFS,94), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* nfs3.client.reqs */ + { NULL, + { PMDA_PMID(CLUSTER_NFS,95), PM_TYPE_32, NFS3_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* nfs3.server.calls */ + { NULL, + { PMDA_PMID(CLUSTER_NFS,96), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* nfs3.server.reqs */ + { NULL, + { PMDA_PMID(CLUSTER_NFS,97), PM_TYPE_32, NFS3_INDOM, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.client.rpccnt */ + { &mach_nfs.rpcrequests, + { PMDA_PMID(CLUSTER_NFS,98), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.client.rpcretrans */ + { &mach_nfs.rpcretries, + { PMDA_PMID(CLUSTER_NFS,99), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.client.rpctimeouts */ + { &mach_nfs.rpctimeouts, + { PMDA_PMID(CLUSTER_NFS,100), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.client.rpcinvalid */ + { &mach_nfs.rpcinvalid, + { PMDA_PMID(CLUSTER_NFS,101), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.client.rpcunexpected */ + { &mach_nfs.rpcunexpected, + { PMDA_PMID(CLUSTER_NFS,102), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.client.attrcache.hits */ + { &mach_nfs.attrcache_hits, + { PMDA_PMID(CLUSTER_NFS,103), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.client.attrcache.misses */ + { &mach_nfs.attrcache_misses, + { PMDA_PMID(CLUSTER_NFS,104), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.client.lookupcache.hits */ + { &mach_nfs.lookupcache_hits, + { PMDA_PMID(CLUSTER_NFS,105), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.client.lookupcache.misses */ + { &mach_nfs.lookupcache_misses, + { PMDA_PMID(CLUSTER_NFS,106), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.client.biocache.read.hits */ + { &mach_nfs.read_bios, + { PMDA_PMID(CLUSTER_NFS,107), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.client.biocache.read.misses */ + { &mach_nfs.biocache_reads, + { PMDA_PMID(CLUSTER_NFS,108), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.client.biocache.write.hits */ + { &mach_nfs.write_bios, + { PMDA_PMID(CLUSTER_NFS,109), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.client.biocache.write.misses */ + { &mach_nfs.biocache_writes, + { PMDA_PMID(CLUSTER_NFS,110), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.client.biocache.readlink.hits */ + { &mach_nfs.readlink_bios, + { PMDA_PMID(CLUSTER_NFS,111), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.client.biocache.readlink.misses */ + { &mach_nfs.biocache_readlinks, + { PMDA_PMID(CLUSTER_NFS,112), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.client.biocache.readdir.hits */ + { &mach_nfs.readdir_bios, + { PMDA_PMID(CLUSTER_NFS,113), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.client.biocache.readdir.misses */ + { &mach_nfs.biocache_readdirs, + { PMDA_PMID(CLUSTER_NFS,114), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.client.direofcache.hits */ + { &mach_nfs.direofcache_hits, + { PMDA_PMID(CLUSTER_NFS,115), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.client.direofcache.misses */ + { &mach_nfs.direofcache_misses, + { PMDA_PMID(CLUSTER_NFS,116), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.server.retfailed */ + { &mach_nfs.srvrpc_errs, + { PMDA_PMID(CLUSTER_NFS,117), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.server.faults */ + { &mach_nfs.srvrpc_errs, + { PMDA_PMID(CLUSTER_NFS,118), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.server.cache.inprog */ + { &mach_nfs.srvcache_inproghits, + { PMDA_PMID(CLUSTER_NFS,119), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.server.cache.nonidem */ + { &mach_nfs.srvcache_nonidemdonehits, + { PMDA_PMID(CLUSTER_NFS,120), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.server.cache.idem */ + { &mach_nfs.srvcache_idemdonehits, + { PMDA_PMID(CLUSTER_NFS,121), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.server.cache.misses */ + { &mach_nfs.srvcache_misses, + { PMDA_PMID(CLUSTER_NFS,122), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.server.nqnfs.leases -- deprecated */ + { NULL, + { PMDA_PMID(CLUSTER_NFS,123), PM_TYPE_NOSUPPORT, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.server.nqnfs.maxleases -- deprecated */ + { NULL, + { PMDA_PMID(CLUSTER_NFS,124), PM_TYPE_NOSUPPORT, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.server.nqnfs.getleases -- deprecated */ + { NULL, + { PMDA_PMID(CLUSTER_NFS,125), PM_TYPE_NOSUPPORT, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.server.vopwrites */ + { &mach_nfs.srvvop_writes, + { PMDA_PMID(CLUSTER_NFS,126), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.server.pageins */ + { &mach_nfs.pageins, + { PMDA_PMID(CLUSTER_NFS,127), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, +/* rpc.server.pageouts */ + { &mach_nfs.pageouts, + { PMDA_PMID(CLUSTER_NFS,128), PM_TYPE_32, PM_INDOM_NULL, + PM_SEM_COUNTER, PMDA_PMUNITS(0,0,1,0,0,PM_COUNT_ONE) }, }, + +/* filesys.maxfiles */ + { NULL, + { PMDA_PMID(CLUSTER_FILESYS,129), PM_TYPE_U32, FILESYS_INDOM, + PM_SEM_INSTANT, PMDA_PMUNITS(0,0,0,0,0,0) }, }, + +}; + +static void +darwin_refresh(int *need_refresh) +{ + if (need_refresh[CLUSTER_LOADAVG]) + mach_loadavg_error = refresh_loadavg(mach_loadavg); + if (need_refresh[CLUSTER_CPULOAD]) + mach_cpuload_error = refresh_cpuload(&mach_cpuload); + if (need_refresh[CLUSTER_VMSTAT]) + mach_vmstat_error = refresh_vmstat(&mach_vmstat); + if (need_refresh[CLUSTER_KERNEL_UNAME]) + mach_uname_error = refresh_uname(&mach_uname); + if (need_refresh[CLUSTER_FILESYS]) + mach_fs_error = refresh_filesys(&mach_fs, &indomtab[FILESYS_INDOM]); + if (need_refresh[CLUSTER_DISK]) + mach_disk_error = refresh_disks(&mach_disk, &indomtab[DISK_INDOM]); + if (need_refresh[CLUSTER_CPU]) + mach_cpu_error = refresh_cpus(&mach_cpu, &indomtab[CPU_INDOM]); + if (need_refresh[CLUSTER_UPTIME]) + mach_uptime_error = refresh_uptime(&mach_uptime); + if (need_refresh[CLUSTER_NETWORK]) + mach_net_error = refresh_network(&mach_net, &indomtab[NETWORK_INDOM]); + if (need_refresh[CLUSTER_NFS]) + mach_nfs_error = refresh_nfs(&mach_nfs); +} + +static inline int +fetch_loadavg(unsigned int item, unsigned int inst, pmAtomValue *atom) +{ + if (mach_loadavg_error) + return mach_loadavg_error; + switch (item) { + case 30: /* kernel.all.load */ + if (inst == 1) + atom->f = mach_loadavg[0]; + else if (inst == 5) + atom->f = mach_loadavg[1]; + else if (inst == 15) + atom->f = mach_loadavg[2]; + else + return PM_ERR_INST; + return 1; + } + return PM_ERR_PMID; +} + +static inline int +fetch_cpuload(unsigned int item, pmAtomValue *atom) +{ + if (mach_cpuload_error) + return mach_cpuload_error; + switch (item) { + case 42: /* kernel.all.cpu.user */ + atom->ull = LOAD_SCALE * (double) + mach_cpuload.cpu_ticks[CPU_STATE_USER] / mach_hertz; + return 1; + case 43: /* kernel.all.cpu.nice */ + atom->ull = LOAD_SCALE * (double) + mach_cpuload.cpu_ticks[CPU_STATE_NICE] / mach_hertz; + return 1; + case 44: /* kernel.all.cpu.sys */ + atom->ull = LOAD_SCALE * (double) + mach_cpuload.cpu_ticks[CPU_STATE_SYSTEM] / mach_hertz; + return 1; + case 45: /* kernel.all.cpu.idle */ + atom->ull = LOAD_SCALE * (double) + mach_cpuload.cpu_ticks[CPU_STATE_IDLE] / mach_hertz; + return 1; + } + return PM_ERR_PMID; +} + +static inline int +fetch_vmstat(unsigned int item, unsigned int inst, pmAtomValue *atom) +{ + if (mach_vmstat_error) + return mach_vmstat_error; + switch (item) { + case 2: /* hinv.physmem */ + atom->ul = (__uint32_t)page_count_to_mb( + mach_vmstat.free_count + mach_vmstat.wire_count + + mach_vmstat.active_count + mach_vmstat.inactive_count); + return 1; + case 3: /* mem.physmem */ + atom->ull = page_count_to_kb( + mach_vmstat.free_count + mach_vmstat.wire_count + + mach_vmstat.active_count + mach_vmstat.inactive_count); + return 1; + case 4: /* mem.freemem */ + atom->ull = page_count_to_kb(mach_vmstat.free_count); + return 1; + case 5: /* mem.active */ + atom->ull = page_count_to_kb(mach_vmstat.active_count); + return 1; + case 6: /* mem.inactive */ + atom->ull = page_count_to_kb(mach_vmstat.inactive_count); + return 1; + case 19: /* mem.util.wired */ + atom->ull = page_count_to_kb(mach_vmstat.wire_count); + return 1; + case 20: /* mem.util.active */ + atom->ull = page_count_to_kb(mach_vmstat.active_count); + return 1; + case 21: /* mem.util.inactive */ + atom->ull = page_count_to_kb(mach_vmstat.inactive_count); + return 1; + case 22: /* mem.util.free */ + atom->ull = page_count_to_kb(mach_vmstat.free_count); + return 1; + } + return PM_ERR_PMID; +} + +static inline int +fetch_uname(unsigned int item, pmAtomValue *atom) +{ + static char mach_uname_all[(_SYS_NAMELEN*5)+8]; + + if (mach_uname_error) + return mach_uname_error; + switch (item) { + case 28: /* pmda.uname */ + snprintf(mach_uname_all, sizeof(mach_uname_all), "%s %s %s %s %s", + mach_uname.sysname, mach_uname.nodename, + mach_uname.release, mach_uname.version, + mach_uname.machine); + atom->cp = mach_uname_all; + return 1; + case 29: /* pmda.version */ + atom->cp = pmGetConfig("PCP_VERSION"); + return 1; + } + return PM_ERR_PMID; +} + +static inline int +fetch_filesys(unsigned int item, unsigned int inst, pmAtomValue *atom) +{ + __uint64_t ull, used; + + if (mach_fs_error) + return mach_fs_error; + if (item == 31) { /* hinv.nfilesys */ + atom->ul = indomtab[FILESYS_INDOM].it_numinst; + return 1; + } + if (indomtab[FILESYS_INDOM].it_numinst == 0) + return 0; /* no values available */ + if (inst < 0 || inst >= indomtab[FILESYS_INDOM].it_numinst) + return PM_ERR_INST; + switch (item) { + case 32: /* filesys.capacity */ + ull = (__uint64_t)mach_fs[inst].f_blocks; + atom->ull = ull * mach_fs[inst].f_bsize >> 10; + return 1; + case 33: /* filesys.used */ + used = (__uint64_t)(mach_fs[inst].f_blocks - mach_fs[inst].f_bfree); + atom->ull = used * mach_fs[inst].f_bsize >> 10; + return 1; + case 34: /* filesys.free */ + ull = (__uint64_t)mach_fs[inst].f_bfree; + atom->ull = ull * mach_fs[inst].f_bsize >> 10; + return 1; + case 129: /* filesys.maxfiles */ + atom->ul = mach_fs[inst].f_files; + return 1; + case 35: /* filesys.usedfiles */ + atom->ul = mach_fs[inst].f_files - mach_fs[inst].f_ffree; + return 1; + case 36: /* filesys.freefiles */ + atom->ul = mach_fs[inst].f_ffree; + return 1; + case 37: /* filesys.mountdir */ + atom->cp = mach_fs[inst].f_mntonname; + return 1; + case 38: /* filesys.full */ + used = (__uint64_t)(mach_fs[inst].f_blocks - mach_fs[inst].f_bfree); + ull = used + (__uint64_t)mach_fs[inst].f_bavail; + atom->d = (100.0 * (double)used) / (double)ull; + return 1; + case 39: /* filesys.blocksize */ + atom->ul = mach_fs[inst].f_bsize; + return 1; + case 40: /* filesys.avail */ + ull = (__uint64_t)mach_fs[inst].f_bavail; + atom->ull = ull * mach_fs[inst].f_bsize >> 10; + return 1; + case 41: /* filesys.type */ + atom->cp = mach_fs[inst].f_fstypename; + return 1; + } + return PM_ERR_PMID; +} + +static inline int +fetch_disk(unsigned int item, unsigned int inst, pmAtomValue *atom) +{ + if (mach_disk_error) + return mach_disk_error; + if (item == 46) { /* hinv.ndisk */ + atom->ul = indomtab[DISK_INDOM].it_numinst; + return 1; + } + if (indomtab[DISK_INDOM].it_numinst == 0) + return 0; /* no values available */ + if (item < 59 && (inst < 0 || inst >= indomtab[DISK_INDOM].it_numinst)) + return PM_ERR_INST; + switch (item) { + case 47: /* disk.dev.read */ + atom->ull = mach_disk.disks[inst].read; + return 1; + case 48: /* disk.dev.write */ + atom->ull = mach_disk.disks[inst].write; + return 1; + case 49: /* disk.dev.total */ + atom->ull = mach_disk.disks[inst].read + mach_disk.disks[inst].write; + return 1; + case 50: /* disk.dev.read_bytes */ + atom->ull = mach_disk.disks[inst].read_bytes >> 10; + return 1; + case 51: /* disk.dev.write_bytes */ + atom->ull = mach_disk.disks[inst].write_bytes >> 10; + return 1; + case 52: /* disk.dev.total_bytes */ + atom->ull = (mach_disk.disks[inst].read_bytes + + mach_disk.disks[inst].write_bytes) >> 10; + return 1; + case 53: /* disk.dev.blkread */ + atom->ull = mach_disk.disks[inst].read_bytes / + mach_disk.disks[inst].blocksize; + return 1; + case 54: /* disk.dev.blkwrite */ + atom->ull = mach_disk.disks[inst].write_bytes / + mach_disk.disks[inst].blocksize; + return 1; + case 55: /* disk.dev.blktotal */ + atom->ull = (mach_disk.disks[inst].read_bytes + + mach_disk.disks[inst].write_bytes) / + mach_disk.disks[inst].blocksize; + return 1; + case 56: /* disk.dev.read_time */ + atom->ull = mach_disk.disks[inst].read_time; + return 1; + case 57: /* disk.dev.write_time */ + atom->ull = mach_disk.disks[inst].write_time; + return 1; + case 58: /* disk.dev.total_time */ + atom->ull = mach_disk.disks[inst].read_time + + mach_disk.disks[inst].write_time; + return 1; + case 59: /* disk.all.read */ + atom->ull = mach_disk.read; + return 1; + case 60: /* disk.all.write */ + atom->ull = mach_disk.write; + return 1; + case 61: /* disk.all.total */ + atom->ull = mach_disk.read + mach_disk.write; + return 1; + case 62: /* disk.all.read_bytes */ + atom->ull = mach_disk.read_bytes >> 10; + return 1; + case 63: /* disk.all.write_bytes */ + atom->ull = mach_disk.write_bytes >> 10; + return 1; + case 64: /* disk.all.total_bytes */ + atom->ull = (mach_disk.read_bytes + mach_disk.write_bytes) >> 10; + return 1; + case 65: /* disk.all.blkread */ + atom->ull = mach_disk.blkread; + return 1; + case 66: /* disk.all.blkwrite */ + atom->ull = mach_disk.blkwrite; + return 1; + case 67: /* disk.all.blktotal */ + atom->ull = mach_disk.blkread + mach_disk.blkwrite; + return 1; + case 68: /* disk.all.read_time */ + atom->ull = mach_disk.read_time; + return 1; + case 69: /* disk.all.write_time */ + atom->ull = mach_disk.write_time; + return 1; + case 70: /* disk.all.total_time */ + atom->ull = mach_disk.read_time + mach_disk.write_time; + return 1; + } + return PM_ERR_PMID; +} + +static inline int +fetch_cpu(unsigned int item, unsigned int inst, pmAtomValue *atom) +{ + if (mach_cpu_error) + return mach_cpu_error; + if (item == 71) { /* hinv.ncpu */ + atom->ul = indomtab[CPU_INDOM].it_numinst; + return 1; + } + if (indomtab[CPU_INDOM].it_numinst == 0) /* uh-huh. */ + return 0; /* no values available */ + if (inst < 0 || inst >= indomtab[CPU_INDOM].it_numinst) + return PM_ERR_INST; + switch (item) { + case 72: /* kernel.percpu.cpu.user */ + atom->ull = LOAD_SCALE * (double) + mach_cpu[inst].cpu_ticks[CPU_STATE_USER] / mach_hertz; + return 1; + case 73: /* kernel.percpu.cpu.nice */ + atom->ull = LOAD_SCALE * (double) + mach_cpu[inst].cpu_ticks[CPU_STATE_NICE] / mach_hertz; + return 1; + case 74: /* kernel.percpu.cpu.sys */ + atom->ull = LOAD_SCALE * (double) + mach_cpu[inst].cpu_ticks[CPU_STATE_SYSTEM] / mach_hertz; + return 1; + case 75: /* kernel.percpu.cpu.idle */ + atom->ull = LOAD_SCALE * (double) + mach_cpu[inst].cpu_ticks[CPU_STATE_IDLE] / mach_hertz; + return 1; + } + return PM_ERR_PMID; +} + +static inline int +fetch_network(unsigned int item, unsigned int inst, pmAtomValue *atom) +{ + if (mach_net_error) + return mach_net_error; + if (indomtab[NETWORK_INDOM].it_numinst == 0) + return 0; /* no values available */ + if (inst < 0 || inst >= indomtab[NETWORK_INDOM].it_numinst) + return PM_ERR_INST; + switch (item) { + case 77: /* network.interface.in.bytes */ + atom->ull = mach_net.interfaces[inst].ibytes; + return 1; + case 78: /* network.interface.in.packets */ + atom->ull = mach_net.interfaces[inst].ipackets; + return 1; + case 79: /* network.interface.in.errors */ + atom->ull = mach_net.interfaces[inst].ierrors; + return 1; + case 80: /* network.interface.in.drops */ + atom->ull = mach_net.interfaces[inst].iqdrops; + return 1; + case 81: /* network.interface.in.mcasts */ + atom->ull = mach_net.interfaces[inst].imcasts; + return 1; + case 82: /* network.interface.out.bytes */ + atom->ull = mach_net.interfaces[inst].obytes; + return 1; + case 83: /* network.interface.out.packets */ + atom->ull = mach_net.interfaces[inst].opackets; + return 1; + case 84: /* network.interface.out.errors */ + atom->ull = mach_net.interfaces[inst].oerrors; + return 1; + case 85: /* network.interface.out.mcasts */ + atom->ull = mach_net.interfaces[inst].omcasts; + return 1; + case 86: /* network.interface.collisions */ + atom->ull = mach_net.interfaces[inst].collisions; + return 1; + case 87: /* network.interface.mtu */ + atom->ull = mach_net.interfaces[inst].mtu; + return 1; + case 88: /* network.interface.baudrate */ + atom->ull = mach_net.interfaces[inst].baudrate; + return 1; + case 89: /* network.interface.total.bytes */ + atom->ull = mach_net.interfaces[inst].ibytes + + mach_net.interfaces[inst].obytes; + return 1; + case 90: /* network.interface.total.packets */ + atom->ull = mach_net.interfaces[inst].ipackets + + mach_net.interfaces[inst].opackets; + return 1; + case 91: /* network.interface.total.errors */ + atom->ull = mach_net.interfaces[inst].ierrors + + mach_net.interfaces[inst].oerrors; + return 1; + case 92: /* network.interface.total.drops */ + atom->ull = mach_net.interfaces[inst].iqdrops; + return 1; + case 93: /* network.interface.total.mcasts */ + atom->ull = mach_net.interfaces[inst].imcasts + + mach_net.interfaces[inst].omcasts; + return 1; + } + return PM_ERR_PMID; +} + +static inline int +fetch_nfs(unsigned int item, unsigned int inst, pmAtomValue *atom) +{ + if (mach_net_error) + return mach_net_error; + switch (item) { + case 94: /* nfs3.client.calls */ + for (atom->l = 0, inst = 0; inst < NFS3_RPC_COUNT; inst++) + atom->l += mach_nfs.rpccnt[inst]; + return 1; + case 95: /* nfs3.client.reqs */ + if (inst < 0 || inst >= NFS3_RPC_COUNT) + return PM_ERR_INST; + atom->l = mach_nfs.rpccnt[inst]; + return 1; + case 96: /* nfs3.server.calls */ + for (atom->l = 0, inst = 0; inst < NFS3_RPC_COUNT; inst++) + atom->l += mach_nfs.srvrpccnt[inst]; + return 1; + case 97: /* nfs3.server.reqs */ + if (inst < 0 || inst >= NFS3_RPC_COUNT) + return PM_ERR_INST; + atom->l = mach_nfs.srvrpccnt[inst]; + return 1; + case 123: /* rpc.server.nqnfs.leases -- deprecated */ + case 124: /* rpc.server.nqnfs.maxleases -- deprecated */ + case 125: /* rpc.server.nqnfs.getleases -- deprecated */ + return PM_ERR_APPVERSION; + } + return PM_ERR_PMID; +} + + +static int +darwin_fetchCallBack(pmdaMetric *mdesc, unsigned int inst, pmAtomValue *atom) +{ + __pmID_int *idp = (__pmID_int *)&(mdesc->m_desc.pmid); + + if (mdesc->m_user) { + /* + * The metric value is extracted directly via the address specified + * in metrictab. Note: not all metrics support this - those that + * don't have NULL for the m_user field in their respective + * metrictab slot. + */ + switch (mdesc->m_desc.type) { + case PM_TYPE_32: atom->l = *(__int32_t *)mdesc->m_user; break; + case PM_TYPE_U32: atom->ul = *(__uint32_t *)mdesc->m_user; break; + case PM_TYPE_64: atom->ll = *(__int64_t *)mdesc->m_user; break; + case PM_TYPE_U64: atom->ull = *(__uint64_t *)mdesc->m_user; break; + case PM_TYPE_FLOAT: atom->f = *(float *)mdesc->m_user; break; + case PM_TYPE_DOUBLE: atom->d = *(double *)mdesc->m_user; break; + case PM_TYPE_STRING: atom->cp = (char *)mdesc->m_user; break; + case PM_TYPE_NOSUPPORT: return 0; + default: fprintf(stderr, + "Error in fetchCallBack: unsupported metric type %s\n", + pmTypeStr(mdesc->m_desc.type)); + return 0; + } + return 1; + } + + switch (idp->cluster) { + case CLUSTER_LOADAVG: return fetch_loadavg(idp->item, inst, atom); + case CLUSTER_CPULOAD: return fetch_cpuload(idp->item, atom); + case CLUSTER_VMSTAT: return fetch_vmstat(idp->item, inst, atom); + case CLUSTER_KERNEL_UNAME: return fetch_uname(idp->item, atom); + case CLUSTER_FILESYS: return fetch_filesys(idp->item, inst, atom); + case CLUSTER_DISK: return fetch_disk(idp->item, inst, atom); + case CLUSTER_CPU: return fetch_cpu(idp->item, inst, atom); + case CLUSTER_NETWORK: return fetch_network(idp->item, inst, atom); + case CLUSTER_NFS: return fetch_nfs(idp->item, inst, atom); + } + return 0; +} + +static int +darwin_instance(pmInDom indom, int inst, char *name, __pmInResult **result, pmdaExt *pmda) +{ + __pmInDom_int *indomp = (__pmInDom_int *)&indom; + int need_refresh[NUM_CLUSTERS] = { 0 }; + + switch (indomp->serial) { + case FILESYS_INDOM: need_refresh[CLUSTER_FILESYS]++; break; + case DISK_INDOM: need_refresh[CLUSTER_DISK]++; break; + case CPU_INDOM: need_refresh[CLUSTER_CPU]++; break; + case NETWORK_INDOM: need_refresh[CLUSTER_NETWORK]++; break; + } + darwin_refresh(need_refresh); + return pmdaInstance(indom, inst, name, result, pmda); +} + +static int +darwin_fetch(int numpmid, pmID pmidlist[], pmResult **resp, pmdaExt *pmda) +{ + int i, need_refresh[NUM_CLUSTERS] = { 0 }; + + for (i = 0; i < numpmid; i++) { + __pmID_int *idp = (__pmID_int *)&(pmidlist[i]); + if (idp->cluster >= 0 && idp->cluster < NUM_CLUSTERS) + need_refresh[idp->cluster]++; + } + darwin_refresh(need_refresh); + return pmdaFetch(numpmid, pmidlist, resp, pmda); +} + +void +darwin_init(pmdaInterface *dp) +{ + if (_isDSO) { + int sep = __pmPathSeparator(); + char helppath[MAXPATHLEN]; + sprintf(helppath, "%s%c" "darwin" "%c" "help", + pmGetConfig("PCP_PMDAS_DIR"), sep, sep); + pmdaDSO(dp, PMDA_INTERFACE_3, "darwin DSO", helppath); + } else { + __pmSetProcessIdentity(username); + } + + if (dp->status != 0) + return; + + dp->version.two.instance = darwin_instance; + dp->version.two.fetch = darwin_fetch; + pmdaSetFetchCallBack(dp, darwin_fetchCallBack); + + pmdaSetFlags(dp, PMDA_EXT_FLAG_DIRECT); + pmdaInit(dp, indomtab, sizeof(indomtab)/sizeof(indomtab[0]), + metrictab, sizeof(metrictab)/sizeof(metrictab[0])); + + mach_host = mach_host_self(); + host_page_size(mach_host, &mach_page_size); + mach_page_shift = ffs(mach_page_size) - 1; + if (refresh_hertz(&mach_hertz) != 0) + mach_hertz = 100; + init_network(); +} + +static void +usage(void) +{ + fprintf(stderr, "Usage: %s [options]\n\n", pmProgname); + fputs("Options:\n" +" -d domain use domain (numeric) for metrics domain of PMDA\n" +" -l logfile write log into logfile rather than using default log name\n" +" -U username user account to run under (default \"pcp\")\n" +"\nExactly one of the following options may appear:\n" +" -i port expect PMCD to connect on given inet port (number or name)\n" +" -p expect PMCD to supply stdin/stdout (pipe)\n" +" -u socket expect PMCD to connect on given unix domain socket\n" +" -6 port expect PMCD to connect on given ipv6 port (number or name)\n", + stderr); + exit(1); +} + +int +main(int argc, char **argv) +{ + int c, sep = __pmPathSeparator(); + int errflag = 0; + char helppath[MAXPATHLEN]; + + _isDSO = 0; + __pmSetProgname(argv[0]); + __pmGetUsername(&username); + + sprintf(helppath, "%s%c" "darwin" "%c" "help", + pmGetConfig("PCP_PMDAS_DIR"), sep, sep); + pmdaDaemon(&dispatch, PMDA_INTERFACE_3, pmProgname, DARWIN, "darwin.log", + helppath); + + while ((c = pmdaGetOpt(argc, argv, "D:d:i:l:pu:U:6:?", &dispatch, &errflag)) != EOF) { + switch(c) { + case 'U': + username = optarg; + break; + default: + errflag++; + } + } + if (errflag) + usage(); + + pmdaOpenLog(&dispatch); + darwin_init(&dispatch); + pmdaConnect(&dispatch); + pmdaMain(&dispatch); + exit(0); +} diff --git a/src/pmdas/darwin/pmns b/src/pmdas/darwin/pmns new file mode 100644 index 0000000..da82370 --- /dev/null +++ b/src/pmdas/darwin/pmns @@ -0,0 +1,258 @@ + +hinv { + physmem DARWIN:1:2 + pagesize DARWIN:0:0 + ncpu DARWIN:8:71 + nfilesys DARWIN:5:31 + ndisk DARWIN:7:46 +} + +pmda { + uname DARWIN:2:28 + version DARWIN:2:29 +} + +kernel { + uname + all + percpu +} + +kernel.uname { + release DARWIN:2:23 + version DARWIN:2:24 + sysname DARWIN:2:25 + machine DARWIN:2:26 + nodename DARWIN:2:27 +} + +kernel.all { + cpu + load DARWIN:3:30 + uptime DARWIN:9:76 + hz DARWIN:0:1 +} + +kernel.all.cpu { + user DARWIN:6:42 + nice DARWIN:6:43 + sys DARWIN:6:44 + idle DARWIN:6:45 +} + +kernel.percpu { + cpu +} + +kernel.percpu.cpu { + user DARWIN:8:72 + nice DARWIN:8:73 + sys DARWIN:8:74 + idle DARWIN:8:75 +} + +mem { + physmem DARWIN:1:3 + freemem DARWIN:1:4 + active DARWIN:1:5 + inactive DARWIN:1:6 + pages + pageins DARWIN:1:15 + pageouts DARWIN:1:16 + cache_hits DARWIN:1:17 + cache_lookups DARWIN:1:18 + util +} + +mem.pages { + freemem DARWIN:1:7 + active DARWIN:1:8 + inactive DARWIN:1:9 + reactivated DARWIN:1:10 + wired DARWIN:1:11 + faults DARWIN:1:12 + cow_faults DARWIN:1:13 + zero_filled DARWIN:1:14 +} + +mem.util { + wired DARWIN:1:19 + active DARWIN:1:20 + inactive DARWIN:1:21 + free DARWIN:1:22 +} + +filesys { + capacity DARWIN:5:32 + used DARWIN:5:33 + free DARWIN:5:34 + maxfiles DARWIN:5:129 + usedfiles DARWIN:5:35 + freefiles DARWIN:5:36 + mountdir DARWIN:5:37 + full DARWIN:5:38 + blocksize DARWIN:5:39 + avail DARWIN:5:40 + type DARWIN:5:41 +} + +disk { + dev + all +} + +disk.dev { + read DARWIN:7:47 + write DARWIN:7:48 + total DARWIN:7:49 + read_bytes DARWIN:7:50 + write_bytes DARWIN:7:51 + total_bytes DARWIN:7:52 + blkread DARWIN:7:53 + blkwrite DARWIN:7:54 + blktotal DARWIN:7:55 + read_time DARWIN:7:56 + write_time DARWIN:7:57 + total_time DARWIN:7:58 +} + +disk.all { + read DARWIN:7:59 + write DARWIN:7:60 + total DARWIN:7:61 + read_bytes DARWIN:7:62 + write_bytes DARWIN:7:63 + total_bytes DARWIN:7:64 + blkread DARWIN:7:65 + blkwrite DARWIN:7:66 + blktotal DARWIN:7:67 + read_time DARWIN:7:68 + write_time DARWIN:7:69 + total_time DARWIN:7:70 +} + +network { + interface +} + +network.interface { + in + out + collisions DARWIN:10:86 + mtu DARWIN:10:87 + baudrate DARWIN:10:88 + total +} + +network.interface.in { + bytes DARWIN:10:77 + packets DARWIN:10:78 + errors DARWIN:10:79 + drops DARWIN:10:80 + mcasts DARWIN:10:81 +} + +network.interface.out { + bytes DARWIN:10:82 + packets DARWIN:10:83 + errors DARWIN:10:84 + mcasts DARWIN:10:85 +} + +network.interface.total { + bytes DARWIN:10:89 + packets DARWIN:10:90 + errors DARWIN:10:91 + drops DARWIN:10:92 + mcasts DARWIN:10:93 +} + +nfs3 { + client + server +} + +nfs3.client { + calls DARWIN:11:94 + reqs DARWIN:11:95 +} + +nfs3.server { + calls DARWIN:11:96 + reqs DARWIN:11:97 +} + +rpc { + client + server +} + +rpc.client { + rpccnt DARWIN:11:98 + rpcretrans DARWIN:11:99 + rpctimeouts DARWIN:11:100 + rpcinvalid DARWIN:11:101 + rpcunexpected DARWIN:11:102 + attrcache + lookupcache + biocache + direofcache +} + +rpc.client.attrcache { + hits DARWIN:11:103 + misses DARWIN:11:104 +} + +rpc.client.lookupcache { + hits DARWIN:11:105 + misses DARWIN:11:106 +} + +rpc.client.biocache { + read + write + readlink + readdir +} + +rpc.client.biocache.read { + hits DARWIN:11:107 + misses DARWIN:11:108 +} + +rpc.client.biocache.write { + hits DARWIN:11:109 + misses DARWIN:11:110 +} + +rpc.client.biocache.readlink { + hits DARWIN:11:111 + misses DARWIN:11:112 +} + +rpc.client.biocache.readdir { + hits DARWIN:11:113 + misses DARWIN:11:114 +} + +rpc.client.direofcache { + hits DARWIN:11:115 + misses DARWIN:11:116 +} + +rpc.server { + retfailed DARWIN:11:117 + faults DARWIN:11:118 + cache + vopwrites DARWIN:11:126 + pageins DARWIN:11:127 + pageouts DARWIN:11:128 +} + +rpc.server.cache { + inprog DARWIN:11:119 + nonidem DARWIN:11:120 + idem DARWIN:11:121 + misses DARWIN:11:122 +} diff --git a/src/pmdas/darwin/root b/src/pmdas/darwin/root new file mode 100644 index 0000000..4a4ad71 --- /dev/null +++ b/src/pmdas/darwin/root @@ -0,0 +1,15 @@ +#include <stdpmid> + +root { + kernel + pmda + mem + hinv + filesys + disk + network + nfs3 + rpc +} + +#include "pmns" |