cpu plugin: Add support for OpenBSD.
[collectd.git] / src / cpu.c
index c79c4b6..f842b49 100644 (file)
--- a/src/cpu.c
+++ b/src/cpu.c
 # endif
 #endif /* HAVE_SYSCTLBYNAME */
 
-#if !PROCESSOR_CPU_LOAD_INFO && !KERNEL_LINUX && !HAVE_LIBKSTAT && !HAVE_SYSCTLBYNAME
+#ifdef __OpenBSD__
+# ifdef HAVE_SYS_SYSCTL_H
+#  include <sys/sysctl.h>
+# endif
+
+# ifdef HAVE_SYS_DKSTAT_H
+#  include <sys/dkstat.h>
+# endif
+#endif /* __OpenBSD__ */
+
+#if HAVE_STATGRAB_H
+# include <statgrab.h>
+#endif
+
+#if !PROCESSOR_CPU_LOAD_INFO && !KERNEL_LINUX && !HAVE_LIBKSTAT \
+       && !HAVE_SYSCTLBYNAME && !HAVE_LIBSTATGRAB && !__OpenBSD__
 # error "No applicable input method."
 #endif
 
@@ -96,9 +111,13 @@ static kstat_t *ksp[MAX_NUMCPU];
 static int numcpu;
 /* #endif HAVE_LIBKSTAT */
 
-#elif defined(HAVE_SYSCTLBYNAME)
+#elif defined(HAVE_SYSCTLBYNAME) || __OpenBSD__
 static int numcpu;
-#endif /* HAVE_SYSCTLBYNAME */
+/* #endif HAVE_SYSCTLBYNAME */
+
+#elif defined(HAVE_LIBSTATGRAB)
+/* no variables needed */
+#endif /* HAVE_LIBSTATGRAB */
 
 static int init (void)
 {
@@ -152,7 +171,26 @@ static int init (void)
 
        if (numcpu != 1)
                NOTICE ("cpu: Only one processor supported when using `sysctlbyname' (found %i)", numcpu);
-#endif
+/* #endif HAVE_SYSCTLBYNAME */
+
+#elif defined __OpenBSD__
+       size_t numcpu_size;
+       int mib[2] = {CTL_HW, HW_NCPU};
+
+       numcpu_size = sizeof (numcpu);
+
+       if (sysctl (mib, 2, &numcpu, &numcpu_size, NULL, 0) < 0)
+       {
+               char errbuf[1024];
+               WARNING ("cpu plugin: sysctl: %s",
+                               sstrerror (errno, errbuf, sizeof (errbuf)));
+               return (-1);
+       }
+/* #endif __OpenBSD__ */
+
+#elif defined(HAVE_LIBSTATGRAB)
+       /* nothing to initialize */
+#endif /* HAVE_LIBSTATGRAB */
 
        return (0);
 } /* int init */
@@ -166,15 +204,14 @@ static void submit (int cpu_num, const char *type_instance, counter_t value)
 
        vl.values = values;
        vl.values_len = 1;
-       vl.time = time (NULL);
-       strcpy (vl.host, hostname_g);
-       strcpy (vl.plugin, "cpu");
-       snprintf (vl.plugin_instance, sizeof (vl.type_instance),
+       sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+       sstrncpy (vl.plugin, "cpu", sizeof (vl.plugin));
+       ssnprintf (vl.plugin_instance, sizeof (vl.type_instance),
                        "%i", cpu_num);
-       vl.plugin_instance[DATA_MAX_NAME_LEN - 1] = '\0';
-       strcpy (vl.type_instance, type_instance);
+       sstrncpy (vl.type, "cpu", sizeof (vl.type));
+       sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance));
 
-       plugin_dispatch_values ("cpu", &vl);
+       plugin_dispatch_values (&vl);
 }
 
 static int cpu_read (void)
@@ -364,13 +401,92 @@ static int cpu_read (void)
                return (-1);
        }
 
-       cpuinfo[CP_SYS] += cpuinfo[CP_INTR];
-
        submit (0, "user", cpuinfo[CP_USER]);
        submit (0, "nice", cpuinfo[CP_NICE]);
        submit (0, "system", cpuinfo[CP_SYS]);
        submit (0, "idle", cpuinfo[CP_IDLE]);
-#endif
+       submit (0, "interrupt", cpuinfo[CP_INTR]);
+/* #endif HAVE_SYSCTLBYNAME */
+
+#elif defined __OpenBSD__
+       int64_t **cpuinfo;
+       size_t cpuinfo_size;
+       int i;
+
+       cpuinfo = (int64_t **) calloc (numcpu, sizeof(int64_t *));
+       if(cpuinfo == NULL) {
+               ERROR ("cpu plugin: calloc failed.");
+               return (-1);
+       }
+       for (i = 0; i < numcpu; i++) {
+                cpuinfo[i] = (int64_t *) calloc (CPUSTATES, sizeof(int64_t));
+                if (cpuinfo[i] == NULL) {
+                        ERROR ("cpu plugin: calloc failed.");
+                        return (-1);
+                }
+        }
+
+       if (numcpu > 1) {
+               cpuinfo_size = CPUSTATES * sizeof(int64_t);
+
+                for (i = 0; i < numcpu; i++) {
+                        int mib[] = {CTL_KERN, KERN_CPTIME2, i};
+
+                       if (sysctl(mib, 3, cpuinfo[i], &cpuinfo_size, NULL, 0) < 0) {
+                               char errbuf[1024];
+                               ERROR ("cpu plugin: sysctl failed: %s.",
+                                               sstrerror (errno, errbuf, sizeof (errbuf)));
+                               return (-1);
+                       }
+               }
+       } else {
+               int mib[] = {CTL_KERN, KERN_CPTIME};
+               long cpuinfo_tmp[CPUSTATES];
+
+               cpuinfo_size = sizeof(cpuinfo_tmp);
+
+               if (sysctl(mib, 2, &cpuinfo_tmp, &cpuinfo_size, NULL, 0) < 0)
+               {
+                       char errbuf[1024];
+                       ERROR ("cpu plugin: sysctl failed: %s.",
+                                       sstrerror (errno, errbuf, sizeof (errbuf)));
+                       return (-1);
+               }
+               for(i = 0; i < CPUSTATES; i++) {
+                       cpuinfo[0][i] = cpuinfo_tmp[i];
+               }
+       }
+
+       for (i = 0; i < numcpu; i++) {
+               cpuinfo[i][CP_SYS] += cpuinfo[i][CP_INTR];
+
+               submit (i, "user", cpuinfo[i][CP_USER]);
+               submit (i, "nice", cpuinfo[i][CP_NICE]);
+               submit (i, "system", cpuinfo[i][CP_SYS]);
+               submit (i, "idle", cpuinfo[i][CP_IDLE]);
+
+               free (cpuinfo[i]);
+       }
+       free (cpuinfo);
+/* #endif __OpenBSD__ */
+
+#elif defined(HAVE_LIBSTATGRAB)
+       sg_cpu_stats *cs;
+       cs = sg_get_cpu_stats ();
+
+       if (cs == NULL)
+       {
+              ERROR ("cpu plugin: sg_get_cpu_stats failed.");
+               return (-1);
+       }
+
+       submit (0, "idle",   (counter_t) cs->idle);
+       submit (0, "nice",   (counter_t) cs->nice);
+       submit (0, "swap",   (counter_t) cs->swap);
+       submit (0, "system", (counter_t) cs->kernel);
+       submit (0, "user",   (counter_t) cs->user);
+       submit (0, "wait",   (counter_t) cs->iowait);
+#endif /* HAVE_LIBSTATGRAB */
 
        return (0);
 }