A first version of the iokit-plugin. In need of a better name.
authorocto <octo>
Tue, 11 Apr 2006 17:22:25 +0000 (17:22 +0000)
committerocto <octo>
Tue, 11 Apr 2006 17:22:25 +0000 (17:22 +0000)
configure.in
src/Makefile.am
src/iokit.c [new file with mode: 0644]

index 77f3c83..5b62025 100644 (file)
@@ -157,6 +157,11 @@ AC_CHECK_HEADERS(mach/kern_return.h)
 # For hddtemp module
 AC_CHECK_HEADERS(linux/major.h)
 
+# For the iokit module
+AC_CHECK_HEADERS(CoreFoundation/CoreFoundation.h)
+AC_CHECK_HEADERS(IOKit/IOKitLib.h)
+AC_CHECK_HEADERS(IOKit/IOTypes.h)
+
 # For load module
 AC_CHECK_HEADERS(sys/loadavg.h)
 
@@ -546,6 +551,20 @@ AC_DEFINE_UNQUOTED(HAVE_LIBCURL, [$with_libcurl_numeric], [Define to 1 if you ha
 AM_CONDITIONAL(BUILD_WITH_LIBCURL, test "x$with_libcurl" = "xyes")
 ### END of check for libcurl ###
 
+with_libiokit="no"
+collectd_libiokit=0
+AC_CHECK_LIB(IOKit, IOServiceGetMatchingServices,
+[
+       with_libiokit="yes"
+       collectd_libiokit=1
+], 
+[
+       with_libiokit="no"
+       collectd_libiokit=0
+])
+AC_DEFINE_UNQUOTED(COLLECT_LIBIOKIT, [$collect_libiokit], [Wether or not to use the IOKit library])
+AM_CONDITIONAL(BUILD_WITH_LIBIOKIT, test "x$with_libiokit" = "xyes")
+
 AC_ARG_WITH(libstatgrab, [AS_HELP_STRING([--with-libstatgrab@<:@=PREFIX@:>@], [Path to libstatgrab.])],
 [
        if test "x$withval" != "xno" -a "x$withval" != "xyes"
@@ -777,6 +796,7 @@ AC_COLLECTD([disk],      [disable], [module], [disk/partition statistics])
 AC_COLLECTD([df],        [disable], [module], [df statistics])
 AC_COLLECTD([quota],     [enable],  [module], [quota statistics (experimental)])
 AC_COLLECTD([hddtemp],   [disable], [module], [hdd temperature statistics])
+AC_COLLECTD([iokit],     [disable], [module], [Apple's iokit hardware sensors])
 AC_COLLECTD([load],      [disable], [module], [system load statistics])
 AC_COLLECTD([memory],    [disable], [module], [memory statistics])
 AC_COLLECTD([mysql],     [disable], [module], [mysql statistics])
@@ -1015,6 +1035,7 @@ cat <<EOF;
 Configuration:
   Libraries:
     libcurl . . . . . . $with_libcurl
+    libiokit  . . . . . $with_libiokit
     librrd  . . . . . . $with_rrdtool
     lm_sensors  . . . . $with_lm_sensors
     libstatgrab . . . . $with_libstatgrab
@@ -1034,6 +1055,7 @@ Configuration:
     df  . . . . . . . . $enable_df
     disk  . . . . . . . $enable_disk
     hddtemp . . . . . . $enable_hddtemp
+    iokit . . . . . . . $enable_iokit
     load  . . . . . . . $enable_load
     memory  . . . . . . $enable_memory
     mysql . . . . . . . $enable_mysql
index 671ce58..c13e950 100644 (file)
@@ -114,6 +114,17 @@ collectd_LDADD += "-dlopen" hddtemp.la
 collectd_DEPENDENCIES += hddtemp.la
 endif
 
+if BUILD_MODULE_IOKIT
+pkglib_LTLIBRARIES += iokit.la
+iokit_la_SOURCES = iokit.c
+iokit_la_LDFLAGS = -module -avoid-version
+if BUILD_WITH_LIBIOKIT
+iokit_la_LDFLAGS += -lIOKit
+endif
+collectd_LDADD += "-dlopen" iokit.la
+collectd_DEPENDENCIES += iokit.la
+endif
+
 if BUILD_MODULE_LOAD
 pkglib_LTLIBRARIES += load.la
 load_la_SOURCES = load.c
diff --git a/src/iokit.c b/src/iokit.c
new file mode 100644 (file)
index 0000000..637c808
--- /dev/null
@@ -0,0 +1,209 @@
+/**
+ * collectd - src/iokit.c
+ * Copyright (C) 2006  Florian octo Forster
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ **/
+
+#include "collectd.h"
+#include "common.h"
+#include "plugin.h"
+#include "utils_debug.h"
+
+#define MODULE_NAME "iokit"
+
+#if HAVE_MACH_MACH_TYPES_H
+#  include <mach/mach_types.h>
+#endif
+#if HAVE_MACH_MACH_INIT_H
+#  include <mach/mach_init.h>
+#endif
+#if HAVE_MACH_MACH_ERROR_H
+#  include <mach/mach_error.h>
+#endif
+#if HAVE_COREFOUNDATION_COREFOUNDATION_H
+#  include <CoreFoundation/CoreFoundation.h>
+#endif
+#if HAVE_IOKIT_IOKITLIB_H
+#  include <IOKit/IOKitLib.h>
+#endif
+#if HAVE_IOKIT_IOTYPES_H
+#  include <IOKit/IOTypes.h>
+#endif
+
+#if HAVE_IOKIT_IOKITLIB_H
+# define IOKIT_HAVE_READ 1
+#else
+# define IOKIT_HAVE_READ 0
+#endif
+
+#if IOKIT_HAVE_READ
+static mach_port_t io_master_port;
+#endif
+
+static char *temperature_file = "temperature-%s.rrd";
+
+static char *ds_def[] =
+{
+       "DS:value:GAUGE:"COLLECTD_HEARTBEAT":U:U",
+       NULL
+};
+static int ds_num = 1;
+
+static void iokit_init (void)
+{
+#if IOKIT_HAVE_READ
+       kern_return_t status;
+       
+       /* FIXME: de-allocate port if it's defined */
+
+       status = IOMasterPort (MACH_PORT_NULL, &io_master_port);
+       if (status != kIOReturnSuccess)
+       {
+               syslog (LOG_ERR, "IOMasterPort failed: %s",
+                               mach_error_string (status));
+               io_master_port = MACH_PORT_NULL;
+               return;
+       }
+#endif
+
+       return;
+}
+
+static void temperature_write (char *host, char *inst, char *val)
+{
+       rrd_update_file (host, temperature_file, val, ds_def, ds_num);
+}
+
+#if IOKIT_HAVE_READ
+static void iokit_submit (char *type, char *inst, int value)
+{
+       char buf[128];
+
+       if (snprintf (buf, 1024, "%u:%i", (unsigned int) curtime,
+                               value) >= 128)
+               return;
+
+       plugin_submit (type, inst, buf);
+}
+
+static void iokit_read (void)
+{
+       kern_return_t   status;
+       io_iterator_t   iterator;
+       io_object_t     io_obj;
+       CFMutableDictionaryRef prop_dict;
+       CFTypeRef       property;
+
+       char type[128];
+       char inst[128];
+       int   value;
+
+       if (!io_master_port || (io_master_port == MACH_PORT_NULL))
+               return;
+
+       status = IOServiceGetMatchingServices (io_master_port,
+                       IOServiceNameMatching("IOHWSensor"),
+                       &iterator);
+       if (status != kIOReturnSuccess)
+               {
+               syslog (LOG_ERR, "IOServiceGetMatchingServices failed: %s",
+                               mach_error_string (status));
+               return;
+       }
+
+       while ((io_obj = IOIteratorNext (iterator)))
+       {
+               prop_dict = NULL;
+               status = IORegistryEntryCreateCFProperties (io_obj,
+                               &prop_dict,
+                               kCFAllocatorDefault,
+                               kNilOptions);
+               if (status != kIOReturnSuccess)
+               {
+                       DBG ("IORegistryEntryCreateCFProperties failed: %s",
+                                       mach_error_string (status));
+                       continue;
+               }
+
+               /* Copy the sensor type. */
+               property = NULL;
+               if (!CFDictionaryGetValueIfPresent (prop_dict,
+                                       CFSTR ("type"),
+                                       &property))
+                       continue;
+               if (CFGetTypeID (property) != CFStringGetTypeID ())
+                       continue;
+               if (!CFStringGetCString (property,
+                                       type, 128,
+                                       kCFStringEncodingASCII))
+                       continue;
+               type[127] = '\0';
+
+               /* Copy the sensor location. This will be used as `instance'. */
+               property = NULL;
+               if (!CFDictionaryGetValueIfPresent (prop_dict,
+                                       CFSTR ("location"),
+                                       &property))
+                       continue;
+               if (CFGetTypeID (property) != CFStringGetTypeID ())
+                       continue;
+               if (!CFStringGetCString (property,
+                                       inst, 128,
+                                       kCFStringEncodingASCII))
+                       continue;
+               inst[127] = '\0';
+
+               /* Get the actual value. Some computation, based on the `type'
+                * is neccessary. */
+               property = NULL;
+               if (!CFDictionaryGetValueIfPresent (prop_dict,
+                                       CFSTR ("current-value"),
+                                       &property))
+                       continue;
+               if (CFGetTypeID (property) != CFNumberGetTypeID ())
+                       continue;
+               if (!CFNumberGetValue (property,
+                                       kCFNumberIntType,
+                                       &value))
+                       continue;
+
+               /* Do stuff */
+               DBG ("type = %s, inst = %s, value = %i",
+                               type, inst, value);
+               iokit_submit (type, inst, value);
+
+               CFRelease (prop_dict);
+               IOObjectRelease (io_obj);
+       } /* while (iterator) */
+
+       IOObjectRelease (iterator);
+}
+#else
+# define iokit_read NULL
+#endif /* IOKIT_HAVE_READ */
+
+void module_register (void)
+{
+       DBG ("IOKIT_HAVE_READ = %i", IOKIT_HAVE_READ);
+
+       plugin_register (MODULE_NAME, iokit_init, iokit_read, NULL);
+       plugin_register ("iokit-temperature", NULL, NULL, temperature_write);
+}
+
+#undef MODULE_NAME