summaryrefslogtreecommitdiffstats
path: root/collectors/freebsd.plugin/freebsd_sysctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'collectors/freebsd.plugin/freebsd_sysctl.c')
-rw-r--r--collectors/freebsd.plugin/freebsd_sysctl.c3174
1 files changed, 3174 insertions, 0 deletions
diff --git a/collectors/freebsd.plugin/freebsd_sysctl.c b/collectors/freebsd.plugin/freebsd_sysctl.c
new file mode 100644
index 0000000000..89e6379851
--- /dev/null
+++ b/collectors/freebsd.plugin/freebsd_sysctl.c
@@ -0,0 +1,3174 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#include "plugin_freebsd.h"
+
+#include <sys/vmmeter.h>
+#include <vm/vm_param.h>
+
+#define _KERNEL
+#include <sys/sem.h>
+#include <sys/shm.h>
+#include <sys/msg.h>
+#undef _KERNEL
+
+#include <net/netisr.h>
+
+#include <netinet/ip.h>
+#include <netinet/ip_var.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/icmp_var.h>
+#include <netinet6/ip6_var.h>
+#include <netinet/icmp6.h>
+#include <netinet/tcp_var.h>
+#include <netinet/tcp_fsm.h>
+#include <netinet/udp.h>
+#include <netinet/udp_var.h>
+
+// --------------------------------------------------------------------------------------------------------------------
+// common definitions and variables
+
+int system_pagesize = PAGE_SIZE;
+int number_of_cpus = 1;
+#if __FreeBSD_version >= 1200029
+struct __vmmeter {
+ uint64_t v_swtch;
+ uint64_t v_trap;
+ uint64_t v_syscall;
+ uint64_t v_intr;
+ uint64_t v_soft;
+ uint64_t v_vm_faults;
+ uint64_t v_io_faults;
+ uint64_t v_cow_faults;
+ uint64_t v_cow_optim;
+ uint64_t v_zfod;
+ uint64_t v_ozfod;
+ uint64_t v_swapin;
+ uint64_t v_swapout;
+ uint64_t v_swappgsin;
+ uint64_t v_swappgsout;
+ uint64_t v_vnodein;
+ uint64_t v_vnodeout;
+ uint64_t v_vnodepgsin;
+ uint64_t v_vnodepgsout;
+ uint64_t v_intrans;
+ uint64_t v_reactivated;
+ uint64_t v_pdwakeups;
+ uint64_t v_pdpages;
+ uint64_t v_pdshortfalls;
+ uint64_t v_dfree;
+ uint64_t v_pfree;
+ uint64_t v_tfree;
+ uint64_t v_forks;
+ uint64_t v_vforks;
+ uint64_t v_rforks;
+ uint64_t v_kthreads;
+ uint64_t v_forkpages;
+ uint64_t v_vforkpages;
+ uint64_t v_rforkpages;
+ uint64_t v_kthreadpages;
+ u_int v_page_size;
+ u_int v_page_count;
+ u_int v_free_reserved;
+ u_int v_free_target;
+ u_int v_free_min;
+ u_int v_free_count;
+ u_int v_wire_count;
+ u_int v_active_count;
+ u_int v_inactive_target;
+ u_int v_inactive_count;
+ u_int v_laundry_count;
+ u_int v_pageout_free_min;
+ u_int v_interrupt_free_min;
+ u_int v_free_severe;
+};
+typedef struct __vmmeter vmmeter_t;
+#else
+typedef struct vmmeter vmmeter_t;
+#endif
+
+// --------------------------------------------------------------------------------------------------------------------
+// FreeBSD plugin initialization
+
+int freebsd_plugin_init()
+{
+ system_pagesize = getpagesize();
+ if (system_pagesize <= 0) {
+ error("FREEBSD: can't get system page size");
+ return 1;
+ }
+
+ if (unlikely(GETSYSCTL_BY_NAME("kern.smp.cpus", number_of_cpus))) {
+ error("FREEBSD: can't get number of cpus");
+ return 1;
+ }
+
+ if (unlikely(!number_of_cpus)) {
+ error("FREEBSD: wrong number of cpus");
+ return 1;
+ }
+
+ return 0;
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+// vm.loadavg
+
+// FreeBSD calculates load averages once every 5 seconds
+#define MIN_LOADAVG_UPDATE_EVERY 5
+
+int do_vm_loadavg(int update_every, usec_t dt){
+ static usec_t next_loadavg_dt = 0;
+
+ if (next_loadavg_dt <= dt) {
+ static int mib[2] = {0, 0};
+ struct loadavg sysload;
+
+ if (unlikely(GETSYSCTL_SIMPLE("vm.loadavg", mib, sysload))) {
+ error("DISABLED: system.load chart");
+ error("DISABLED: vm.loadavg module");
+ return 1;
+ } else {
+
+ // --------------------------------------------------------------------
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_load1 = NULL, *rd_load2 = NULL, *rd_load3 = NULL;
+
+ if (unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "system",
+ "load",
+ NULL,
+ "load",
+ NULL,
+ "System Load Average",
+ "load",
+ "freebsd.plugin",
+ "vm.loadavg",
+ NETDATA_CHART_PRIO_SYSTEM_LOAD,
+ (update_every < MIN_LOADAVG_UPDATE_EVERY) ?
+ MIN_LOADAVG_UPDATE_EVERY : update_every, RRDSET_TYPE_LINE
+ );
+ rd_load1 = rrddim_add(st, "load1", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
+ rd_load2 = rrddim_add(st, "load5", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
+ rd_load3 = rrddim_add(st, "load15", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
+ } else
+ rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd_load1, (collected_number) ((double) sysload.ldavg[0] / sysload.fscale * 1000));
+ rrddim_set_by_pointer(st, rd_load2, (collected_number) ((double) sysload.ldavg[1] / sysload.fscale * 1000));
+ rrddim_set_by_pointer(st, rd_load3, (collected_number) ((double) sysload.ldavg[2] / sysload.fscale * 1000));
+ rrdset_done(st);
+
+ next_loadavg_dt = st->update_every * USEC_PER_SEC;
+ }
+ }
+ else
+ next_loadavg_dt -= dt;
+
+ return 0;
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+// vm.vmtotal
+
+int do_vm_vmtotal(int update_every, usec_t dt) {
+ (void)dt;
+ static int do_all_processes = -1, do_processes = -1, do_committed = -1;
+
+ if (unlikely(do_all_processes == -1)) {
+ do_all_processes = config_get_boolean("plugin:freebsd:vm.vmtotal", "enable total processes", 1);
+ do_processes = config_get_boolean("plugin:freebsd:vm.vmtotal", "processes running", 1);
+ do_committed = config_get_boolean("plugin:freebsd:vm.vmtotal", "committed memory", 1);
+ }
+
+ if (likely(do_all_processes | do_processes | do_committed)) {
+ static int mib[2] = {0, 0};
+ struct vmtotal vmtotal_data;
+
+ if (unlikely(GETSYSCTL_SIMPLE("vm.vmtotal", mib, vmtotal_data))) {
+ do_all_processes = 0;
+ error("DISABLED: system.active_processes chart");
+ do_processes = 0;
+ error("DISABLED: system.processes chart");
+ do_committed = 0;
+ error("DISABLED: mem.committed chart");
+ error("DISABLED: vm.vmtotal module");
+ return 1;
+ } else {
+
+ // --------------------------------------------------------------------
+
+ if (likely(do_all_processes)) {
+ static RRDSET *st = NULL;
+ static RRDDIM *rd = NULL;
+
+ if (unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "system",
+ "active_processes",
+ NULL,
+ "processes",
+ NULL,
+ "System Active Processes",
+ "processes",
+ "freebsd.plugin",
+ "vm.vmtotal",
+ NETDATA_CHART_PRIO_SYSTEM_ACTIVE_PROCESSES,
+ update_every,
+ RRDSET_TYPE_LINE
+ );
+ rd = rrddim_add(st, "active", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd, (vmtotal_data.t_rq + vmtotal_data.t_dw + vmtotal_data.t_pw + vmtotal_data.t_sl + vmtotal_data.t_sw));
+ rrdset_done(st);
+ }
+
+ // --------------------------------------------------------------------
+
+ if (likely(do_processes)) {
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_running = NULL, *rd_blocked = NULL;
+
+ if (unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "system",
+ "processes",
+ NULL,
+ "processes",
+ NULL,
+ "System Processes",
+ "processes",
+ "freebsd.plugin",
+ "vm.vmtotal",
+ NETDATA_CHART_PRIO_SYSTEM_PROCESSES,
+ update_every,
+ RRDSET_TYPE_LINE
+ );
+
+ rd_running = rrddim_add(st, "running", NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ rd_blocked = rrddim_add(st, "blocked", NULL, -1, 1, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd_running, vmtotal_data.t_rq);
+ rrddim_set_by_pointer(st, rd_blocked, (vmtotal_data.t_dw + vmtotal_data.t_pw));
+ rrdset_done(st);
+ }
+
+ // --------------------------------------------------------------------
+
+ if (likely(do_committed)) {
+ static RRDSET *st = NULL;
+ static RRDDIM *rd = NULL;
+
+ if (unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "mem",
+ "committed",
+ NULL,
+ "system",
+ NULL,
+ "Committed (Allocated) Memory",
+ "MB",
+ "freebsd.plugin",
+ "vm.vmtotal",
+ NETDATA_CHART_PRIO_MEM_SYSTEM_COMMITTED,
+ update_every,
+ RRDSET_TYPE_AREA
+ );
+ rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
+
+ rd = rrddim_add(st, "Committed_AS", NULL, system_pagesize, MEGA_FACTOR, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd, vmtotal_data.t_rm);
+ rrdset_done(st);
+ }
+ }
+ } else {
+ error("DISABLED: vm.vmtotal module");
+ return 1;
+ }
+
+ return 0;
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+// kern.cp_time
+
+int do_kern_cp_time(int update_every, usec_t dt) {
+ (void)dt;
+
+ if (unlikely(CPUSTATES != 5)) {
+ error("FREEBSD: There are %d CPU states (5 was expected)", CPUSTATES);
+ error("DISABLED: system.cpu chart");
+ error("DISABLED: kern.cp_time module");
+ return 1;
+ } else {
+ static int mib[2] = {0, 0};
+ long cp_time[CPUSTATES];
+
+ if (unlikely(GETSYSCTL_SIMPLE("kern.cp_time", mib, cp_time))) {
+ error("DISABLED: system.cpu chart");
+ error("DISABLED: kern.cp_time module");
+ return 1;
+ } else {
+
+ // --------------------------------------------------------------------
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_nice = NULL, *rd_system = NULL, *rd_user = NULL, *rd_interrupt = NULL, *rd_idle = NULL;
+
+ if (unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "system",
+ "cpu",
+ NULL,
+ "cpu",
+ "system.cpu",
+ "Total CPU utilization",
+ "percentage",
+ "freebsd.plugin",
+ "kern.cp_time",
+ NETDATA_CHART_PRIO_SYSTEM_CPU,
+ update_every,
+ RRDSET_TYPE_STACKED
+ );
+
+ rd_nice = rrddim_add(st, "nice", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
+ rd_system = rrddim_add(st, "system", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
+ rd_user = rrddim_add(st, "user", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
+ rd_interrupt = rrddim_add(st, "interrupt", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
+ rd_idle = rrddim_add(st, "idle", NULL, 1, 1, RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
+ rrddim_hide(st, "idle");
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd_nice, cp_time[1]);
+ rrddim_set_by_pointer(st, rd_system, cp_time[2]);
+ rrddim_set_by_pointer(st, rd_user, cp_time[0]);
+ rrddim_set_by_pointer(st, rd_interrupt, cp_time[3]);
+ rrddim_set_by_pointer(st, rd_idle, cp_time[4]);
+ rrdset_done(st);
+ }
+ }
+
+ return 0;
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+// kern.cp_times
+
+int do_kern_cp_times(int update_every, usec_t dt) {
+ (void)dt;
+
+ if (unlikely(CPUSTATES != 5)) {
+ error("FREEBSD: There are %d CPU states (5 was expected)", CPUSTATES);
+ error("DISABLED: cpu.cpuXX charts");
+ error("DISABLED: kern.cp_times module");
+ return 1;
+ } else {
+ static int mib[2] = {0, 0};
+ long cp_time[CPUSTATES];
+ static long *pcpu_cp_time = NULL;
+ static int old_number_of_cpus = 0;
+
+ if(unlikely(number_of_cpus != old_number_of_cpus))
+ pcpu_cp_time = reallocz(pcpu_cp_time, sizeof(cp_time) * number_of_cpus);
+ if (unlikely(GETSYSCTL_WSIZE("kern.cp_times", mib, pcpu_cp_time, sizeof(cp_time) * number_of_cpus))) {
+ error("DISABLED: cpu.cpuXX charts");
+ error("DISABLED: kern.cp_times module");
+ return 1;
+ } else {
+
+ // --------------------------------------------------------------------
+
+ int i;
+ static struct cpu_chart {
+ char cpuid[MAX_INT_DIGITS + 4];
+ RRDSET *st;
+ RRDDIM *rd_user;
+ RRDDIM *rd_nice;
+ RRDDIM *rd_system;
+ RRDDIM *rd_interrupt;
+ RRDDIM *rd_idle;
+ } *all_cpu_charts = NULL;
+
+ if(unlikely(number_of_cpus > old_number_of_cpus)) {
+ all_cpu_charts = reallocz(all_cpu_charts, sizeof(struct cpu_chart) * number_of_cpus);
+ memset(&all_cpu_charts[old_number_of_cpus], 0, sizeof(struct cpu_chart) * (number_of_cpus - old_number_of_cpus));
+ }
+
+ for (i = 0; i < number_of_cpus; i++) {
+ if (unlikely(!all_cpu_charts[i].st)) {
+ snprintfz(all_cpu_charts[i].cpuid, MAX_INT_DIGITS, "cpu%d", i);
+ all_cpu_charts[i].st = rrdset_create_localhost(
+ "cpu",
+ all_cpu_charts[i].cpuid,
+ NULL,
+ "utilization",
+ "cpu.cpu",
+ "Core utilization",
+ "percentage",
+ "freebsd.plugin",
+ "kern.cp_times",
+ NETDATA_CHART_PRIO_CPU_PER_CORE,
+ update_every,
+ RRDSET_TYPE_STACKED
+ );
+
+ all_cpu_charts[i].rd_nice = rrddim_add(all_cpu_charts[i].st, "nice", NULL, 1, 1,
+ RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
+ all_cpu_charts[i].rd_system = rrddim_add(all_cpu_charts[i].st, "system", NULL, 1, 1,
+ RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
+ all_cpu_charts[i].rd_user = rrddim_add(all_cpu_charts[i].st, "user", NULL, 1, 1,
+ RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
+ all_cpu_charts[i].rd_interrupt = rrddim_add(all_cpu_charts[i].st, "interrupt", NULL, 1, 1,
+ RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
+ all_cpu_charts[i].rd_idle = rrddim_add(all_cpu_charts[i].st, "idle", NULL, 1, 1,
+ RRD_ALGORITHM_PCENT_OVER_DIFF_TOTAL);
+ rrddim_hide(all_cpu_charts[i].st, "idle");
+ } else rrdset_next(all_cpu_charts[i].st);
+
+ rrddim_set_by_pointer(all_cpu_charts[i].st, all_cpu_charts[i].rd_nice, pcpu_cp_time[i * 5 + 1]);
+ rrddim_set_by_pointer(all_cpu_charts[i].st, all_cpu_charts[i].rd_system, pcpu_cp_time[i * 5 + 2]);
+ rrddim_set_by_pointer(all_cpu_charts[i].st, all_cpu_charts[i].rd_user, pcpu_cp_time[i * 5 + 0]);
+ rrddim_set_by_pointer(all_cpu_charts[i].st, all_cpu_charts[i].rd_interrupt, pcpu_cp_time[i * 5 + 3]);
+ rrddim_set_by_pointer(all_cpu_charts[i].st, all_cpu_charts[i].rd_idle, pcpu_cp_time[i * 5 + 4]);
+ rrdset_done(all_cpu_charts[i].st);
+ }
+ }
+
+ old_number_of_cpus = number_of_cpus;
+ }
+
+ return 0;
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+// dev.cpu.temperature
+
+int do_dev_cpu_temperature(int update_every, usec_t dt) {
+ (void)dt;
+
+ int i;
+ static int *mib = NULL;
+ static int *pcpu_temperature = NULL;
+ static int old_number_of_cpus = 0;
+ char char_mib[MAX_INT_DIGITS + 21];
+ char char_rd[MAX_INT_DIGITS + 9];
+
+ if (unlikely(number_of_cpus != old_number_of_cpus)) {
+ pcpu_temperature = reallocz(pcpu_temperature, sizeof(int) * number_of_cpus);
+ mib = reallocz(mib, sizeof(int) * number_of_cpus * 4);
+ if (unlikely(number_of_cpus > old_number_of_cpus))
+ memset(&mib[old_number_of_cpus * 4], 0, sizeof(RRDDIM) * (number_of_cpus - old_number_of_cpus));
+ }
+ for (i = 0; i < number_of_cpus; i++) {
+ if (unlikely(!(mib[i * 4])))
+ sprintf(char_mib, "dev.cpu.%d.temperature", i);
+ if (unlikely(getsysctl_simple(char_mib, &mib[i * 4], 4, &pcpu_temperature[i], sizeof(int)))) {
+ error("DISABLED: cpu.temperature chart");
+ error("DISABLED: dev.cpu.temperature module");
+ return 1;
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ static RRDSET *st;
+ static RRDDIM **rd_pcpu_temperature;
+
+ if (unlikely(number_of_cpus != old_number_of_cpus)) {
+ rd_pcpu_temperature = reallocz(rd_pcpu_temperature, sizeof(RRDDIM) * number_of_cpus);
+ if (unlikely(number_of_cpus > old_number_of_cpus))
+ memset(&rd_pcpu_temperature[old_number_of_cpus], 0, sizeof(RRDDIM) * (number_of_cpus - old_number_of_cpus));
+ }
+
+ if (unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "cpu",
+ "temperature",
+ NULL,
+ "temperature",
+ "cpu.temperatute",
+ "Core temperature",
+ "Celsius",
+ "freebsd.plugin",
+ "dev.cpu.temperature",
+ NETDATA_CHART_PRIO_CPU_TEMPERATURE,
+ update_every,
+ RRDSET_TYPE_LINE
+ );
+ }
+ else rrdset_next(st);
+
+ for (i = 0; i < number_of_cpus; i++) {
+ if (unlikely(!rd_pcpu_temperature[i])) {
+ sprintf(char_rd, "cpu%d.temp", i);
+ rd_pcpu_temperature[i] = rrddim_add(st, char_rd, NULL, 1, 1, RRD_ALGORITHM_ABSOLUTE);
+ }
+
+ rrddim_set_by_pointer(st, rd_pcpu_temperature[i], (collected_number) ((double)pcpu_temperature[i] / 10 - 273.15));
+ }
+
+ rrdset_done(st);
+
+ old_number_of_cpus = number_of_cpus;
+
+ return 0;
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+// dev.cpu.0.freq
+
+int do_dev_cpu_0_freq(int update_every, usec_t dt) {
+ (void)dt;
+ static int mib[4] = {0, 0, 0, 0};
+ int cpufreq;
+
+ if (unlikely(GETSYSCTL_SIMPLE("dev.cpu.0.freq", mib, cpufreq))) {
+ error("DISABLED: cpu.scaling_cur_freq chart");
+ error("DISABLED: dev.cpu.0.freq module");
+ return 1;
+ } else {
+
+ // --------------------------------------------------------------------
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd = NULL;
+
+ if (unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "cpu",
+ "scaling_cur_freq",
+ NULL,
+ "cpufreq",
+ NULL,
+ "Current CPU Scaling Frequency",
+ "MHz",
+ "freebsd.plugin",
+ "dev.cpu.0.freq",
+ NETDATA_CHART_PRIO_CPUFREQ_SCALING_CUR_FREQ,
+ update_every,
+ RRDSET_TYPE_LINE
+ );
+
+ rd = rrddim_add(st, "frequency", NULL, 1, 1000, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd, cpufreq);
+ rrdset_done(st);
+ }
+
+ return 0;
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+// hw.intrcnt
+
+int do_hw_intcnt(int update_every, usec_t dt) {
+ (void)dt;
+ static int mib_hw_intrcnt[2] = {0, 0};
+ size_t intrcnt_size = 0;
+ unsigned long i;
+
+ if (unlikely(GETSYSCTL_SIZE("hw.intrcnt", mib_hw_intrcnt, intrcnt_size))) {
+ error("DISABLED: system.intr chart");
+ error("DISABLED: system.interrupts chart");
+ error("DISABLED: hw.intrcnt module");
+ return 1;
+ } else {
+ unsigned long nintr = 0;
+ static unsigned long old_nintr = 0;
+ static unsigned long *intrcnt = NULL;
+ unsigned long long totalintr = 0;
+
+ nintr = intrcnt_size / sizeof(u_long);
+ if (unlikely(nintr != old_nintr))
+ intrcnt = reallocz(intrcnt, nintr * sizeof(u_long));
+ if (unlikely(GETSYSCTL_WSIZE("hw.intrcnt", mib_hw_intrcnt, intrcnt, nintr * sizeof(u_long)))) {
+ error("DISABLED: system.intr chart");
+ error("DISABLED: system.interrupts chart");
+ error("DISABLED: hw.intrcnt module");
+ return 1;
+ } else {
+ for (i = 0; i < nintr; i++)
+ totalintr += intrcnt[i];
+
+ // --------------------------------------------------------------------
+
+ static RRDSET *st_intr = NULL;
+ static RRDDIM *rd_intr = NULL;
+
+ if (unlikely(!st_intr)) {
+ st_intr = rrdset_create_localhost(
+ "system",
+ "intr",
+ NULL,
+ "interrupts",
+ NULL,
+ "Total Hardware Interrupts",
+ "interrupts/s",
+ "freebsd.plugin",
+ "hw.intrcnt",
+ NETDATA_CHART_PRIO_SYSTEM_INTR,
+ update_every,
+ RRDSET_TYPE_LINE
+ );
+ rrdset_flag_set(st_intr, RRDSET_FLAG_DETAIL);
+
+ rd_intr = rrddim_add(st_intr, "interrupts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ } else
+ rrdset_next(st_intr);
+
+ rrddim_set_by_pointer(st_intr, rd_intr, totalintr);
+ rrdset_done(st_intr);
+
+ // --------------------------------------------------------------------
+
+ size_t size;
+ static int mib_hw_intrnames[2] = {0, 0};
+ static char *intrnames = NULL;
+
+ size = nintr * (MAXCOMLEN + 1);
+ if (unlikely(nintr != old_nintr))
+ intrnames = reallocz(intrnames, size);
+ if (unlikely(GETSYSCTL_WSIZE("hw.intrnames", mib_hw_intrnames, intrnames, size))) {
+ error("DISABLED: system.intr chart");
+ error("DISABLED: system.interrupts chart");
+ error("DISABLED: hw.intrcnt module");
+ return 1;
+ } else {
+
+ // --------------------------------------------------------------------
+
+ static RRDSET *st_interrupts = NULL;
+ void *p;
+
+ if (unlikely(!st_interrupts))
+ st_interrupts = rrdset_create_localhost(
+ "system",
+ "interrupts",
+ NULL,
+ "interrupts",
+ NULL,
+ "System interrupts",
+ "interrupts/s",
+ "freebsd.plugin",
+ "hw.intrcnt",
+ NETDATA_CHART_PRIO_SYSTEM_INTERRUPTS,
+ update_every,
+ RRDSET_TYPE_STACKED
+ );
+ else
+ rrdset_next(st_interrupts);
+
+ for (i = 0; i < nintr; i++) {
+ p = intrnames + i * (MAXCOMLEN + 1);
+ if (unlikely((intrcnt[i] != 0) && (*(char *) p != 0))) {
+ RRDDIM *rd_interrupts = rrddim_find(st_interrupts, p);
+
+ if (unlikely(!rd_interrupts))
+ rd_interrupts = rrddim_add(st_interrupts, p, NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+
+ rrddim_set_by_pointer(st_interrupts, rd_interrupts, intrcnt[i]);
+ }
+ }
+ rrdset_done(st_interrupts);
+ }
+ }
+
+ old_nintr = nintr;
+ }
+
+ return 0;
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+// vm.stats.sys.v_intr
+
+int do_vm_stats_sys_v_intr(int update_every, usec_t dt) {
+ (void)dt;
+ static int mib[4] = {0, 0, 0, 0};
+ u_int int_number;
+
+ if (unlikely(GETSYSCTL_SIMPLE("vm.stats.sys.v_intr", mib, int_number))) {
+ error("DISABLED: system.dev_intr chart");
+ error("DISABLED: vm.stats.sys.v_intr module");
+ return 1;
+ } else {
+
+ // --------------------------------------------------------------------
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd = NULL;
+
+ if (unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "system",
+ "dev_intr",
+ NULL,
+ "interrupts",
+ NULL,
+ "Device Interrupts",
+ "interrupts/s",
+ "freebsd.plugin",
+ "vm.stats.sys.v_intr",
+ NETDATA_CHART_PRIO_SYSTEM_DEV_INTR,
+ update_every,
+ RRDSET_TYPE_LINE
+ );
+
+ rd = rrddim_add(st, "interrupts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd, int_number);
+ rrdset_done(st);
+ }
+
+ return 0;
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+// vm.stats.sys.v_soft
+
+int do_vm_stats_sys_v_soft(int update_every, usec_t dt) {
+ (void)dt;
+ static int mib[4] = {0, 0, 0, 0};
+ u_int soft_intr_number;
+
+ if (unlikely(GETSYSCTL_SIMPLE("vm.stats.sys.v_soft", mib, soft_intr_number))) {
+ error("DISABLED: system.dev_intr chart");
+ error("DISABLED: vm.stats.sys.v_soft module");
+ return 1;
+ } else {
+
+ // --------------------------------------------------------------------
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd = NULL;
+
+ if (unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "system",
+ "soft_intr",
+ NULL,
+ "interrupts",
+ NULL,
+ "Software Interrupts",
+ "interrupts/s",
+ "freebsd.plugin",
+ "vm.stats.sys.v_soft",
+ NETDATA_CHART_PRIO_SYSTEM_SOFT_INTR,
+ update_every,
+ RRDSET_TYPE_LINE
+ );
+
+ rd = rrddim_add(st, "interrupts", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd, soft_intr_number);
+ rrdset_done(st);
+ }
+
+ return 0;
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+// vm.stats.sys.v_swtch
+
+int do_vm_stats_sys_v_swtch(int update_every, usec_t dt) {
+ (void)dt;
+ static int mib[4] = {0, 0, 0, 0};
+ u_int ctxt_number;
+
+ if (unlikely(GETSYSCTL_SIMPLE("vm.stats.sys.v_swtch", mib, ctxt_number))) {
+ error("DISABLED: system.ctxt chart");
+ error("DISABLED: vm.stats.sys.v_swtch module");
+ return 1;
+ } else {
+
+ // --------------------------------------------------------------------
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd = NULL;
+
+ if (unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "system",
+ "ctxt",
+ NULL,
+ "processes",
+ NULL,
+ "CPU Context Switches",
+ "context switches/s",
+ "freebsd.plugin",
+ "vm.stats.sys.v_swtch",
+ NETDATA_CHART_PRIO_SYSTEM_CTXT,
+ update_every,
+ RRDSET_TYPE_LINE
+ );
+
+ rd = rrddim_add(st, "switches", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd, ctxt_number);
+ rrdset_done(st);
+ }
+
+ return 0;
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+// vm.stats.vm.v_forks
+
+int do_vm_stats_sys_v_forks(int update_every, usec_t dt) {
+ (void)dt;
+ static int mib[4] = {0, 0, 0, 0};
+ u_int forks_number;
+
+ if (unlikely(GETSYSCTL_SIMPLE("vm.stats.vm.v_forks", mib, forks_number))) {
+ error("DISABLED: system.forks chart");
+ error("DISABLED: vm.stats.sys.v_swtch module");
+ return 1;
+ } else {
+
+ // --------------------------------------------------------------------
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd = NULL;
+
+ if (unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "system",
+ "forks",
+ NULL,
+ "processes",
+ NULL,
+ "Started Processes",
+ "processes/s",
+ "freebsd.plugin",
+ "vm.stats.sys.v_swtch",
+ NETDATA_CHART_PRIO_SYSTEM_FORKS,
+ update_every,
+ RRDSET_TYPE_LINE
+ );
+
+ rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
+
+ rd = rrddim_add(st, "started", NULL, 1, 1, RRD_ALGORITHM_INCREMENTAL);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd, forks_number);
+ rrdset_done(st);
+ }
+
+ return 0;
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+// vm.swap_info
+
+int do_vm_swap_info(int update_every, usec_t dt) {
+ (void)dt;
+ static int mib[3] = {0, 0, 0};
+
+ if (unlikely(getsysctl_mib("vm.swap_info", mib, 2))) {
+ error("DISABLED: system.swap chart");
+ error("DISABLED: vm.swap_info module");
+ return 1;
+ } else {
+ int i;
+ struct xswdev xsw;
+ struct total_xsw {
+ collected_number bytes_used;
+ collected_number bytes_total;
+ } total_xsw = {0, 0};
+
+ for (i = 0; ; i++) {
+ size_t size;
+
+ mib[2] = i;
+ size = sizeof(xsw);
+ if (unlikely(sysctl(mib, 3, &xsw, &size, NULL, 0) == -1 )) {
+ if (unlikely(errno != ENOENT)) {
+ error("FREEBSD: sysctl(%s...) failed: %s", "vm.swap_info", strerror(errno));
+ error("DISABLED: system.swap chart");
+ error("DISABLED: vm.swap_info module");
+ return 1;
+ } else {
+ if (unlikely(size != sizeof(xsw))) {
+ error("FREEBSD: sysctl(%s...) expected %lu, got %lu", "vm.swap_info", (unsigned long)sizeof(xsw), (unsigned long)size);
+ error("DISABLED: system.swap chart");
+ error("DISABLED: vm.swap_info module");
+ return 1;
+ } else break;
+ }
+ }
+ total_xsw.bytes_used += xsw.xsw_used;
+ total_xsw.bytes_total += xsw.xsw_nblks;
+ }
+
+ // --------------------------------------------------------------------
+
+ static RRDSET *st = NULL;
+ static RRDDIM *rd_free = NULL, *rd_used = NULL;
+
+ if (unlikely(!st)) {
+ st = rrdset_create_localhost(
+ "system",
+ "swap",
+ NULL,
+ "swap",
+ NULL,
+ "System Swap",
+ "MB",
+ "freebsd.plugin",
+ "vm.swap_info",
+ NETDATA_CHART_PRIO_SYSTEM_SWAP,
+ update_every,
+ RRDSET_TYPE_STACKED
+ );
+
+ rrdset_flag_set(st, RRDSET_FLAG_DETAIL);
+
+ rd_free = rrddim_add(st, "free", NULL, system_pagesize, MEGA_FACTOR, RRD_ALGORITHM_ABSOLUTE);
+ rd_used = rrddim_add(st, "used", NULL, system_pagesize, MEGA_FACTOR, RRD_ALGORITHM_ABSOLUTE);
+ }
+ else rrdset_next(st);
+
+ rrddim_set_by_pointer(st, rd_free, total_xsw.bytes_total - total_xsw.bytes_used);
+ rrddim_set_by_pointer(st, rd_used, total_xsw.bytes_used);
+ rrdset_done(st);
+ }
+
+ return 0;
+}
+
+// --------------------------------------------------------------------------------------------------------------------
+// system.ram
+
+int do_system_ram(int updat