summaryrefslogtreecommitdiff
path: root/src/pmdas/darwin
diff options
context:
space:
mode:
Diffstat (limited to 'src/pmdas/darwin')
-rw-r--r--src/pmdas/darwin/GNUmakefile69
-rw-r--r--src/pmdas/darwin/disk.c261
-rw-r--r--src/pmdas/darwin/disk.h55
-rw-r--r--src/pmdas/darwin/help199
-rw-r--r--src/pmdas/darwin/kernel.c195
-rw-r--r--src/pmdas/darwin/network.c185
-rw-r--r--src/pmdas/darwin/network.h57
-rw-r--r--src/pmdas/darwin/pmda.c1268
-rw-r--r--src/pmdas/darwin/pmns258
-rw-r--r--src/pmdas/darwin/root15
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"