Merge branch 'collectd-5.5'
[collectd.git] / src / memory.c
index 0e6d49b..3d8a867 100644 (file)
@@ -30,6 +30,9 @@
 #ifdef HAVE_SYS_SYSCTL_H
 # include <sys/sysctl.h>
 #endif
+#ifdef HAVE_SYS_VMMETER_H
+# include <sys/vmmeter.h>
+#endif
 
 #ifdef HAVE_MACH_KERN_RETURN_H
 # include <mach/kern_return.h>
@@ -73,6 +76,7 @@ static vm_size_t pagesize;
 #elif HAVE_LIBKSTAT
 static int pagesize;
 static kstat_t *ksp;
+static kstat_t *ksz;
 /* #endif HAVE_LIBKSTAT */
 
 #elif HAVE_SYSCTL
@@ -134,6 +138,12 @@ static int memory_init (void)
                ksp = NULL;
                return (-1);
        }
+       if (get_kstat (&ksz, "zfs", 0, "arcstats") != 0)
+       {
+               ksz = NULL;
+               return (-1);
+       }
+
 /* #endif HAVE_LIBKSTAT */
 
 #elif HAVE_SYSCTL
@@ -157,9 +167,9 @@ static int memory_init (void)
 
 #define MEMORY_SUBMIT(...) do { \
        if (values_absolute) \
-               plugin_dispatch_multivalue (vl, 0, __VA_ARGS__, NULL); \
+               plugin_dispatch_multivalue (vl, 0, DS_TYPE_GAUGE, __VA_ARGS__, NULL); \
        if (values_percentage) \
-               plugin_dispatch_multivalue (vl, 1, __VA_ARGS__, NULL); \
+               plugin_dispatch_multivalue (vl, 1, DS_TYPE_GAUGE, __VA_ARGS__, NULL); \
 } while (0)
 
 static int memory_read_internal (value_list_t *vl)
@@ -227,7 +237,7 @@ static int memory_read_internal (value_list_t *vl)
         * vm.stats.vm.v_inactive_count: 113730
         * vm.stats.vm.v_cache_count: 10809
         */
-       char *sysctl_keys[8] =
+       const char *sysctl_keys[8] =
        {
                "vm.stats.vm.v_page_size",
                "vm.stats.vm.v_page_count",
@@ -278,11 +288,14 @@ static int memory_read_internal (value_list_t *vl)
        char *fields[8];
        int numfields;
 
+       _Bool detailed_slab_info = 0;
+
        gauge_t mem_total = 0;
        gauge_t mem_used = 0;
        gauge_t mem_buffered = 0;
        gauge_t mem_cached = 0;
        gauge_t mem_free = 0;
+       gauge_t mem_slab_total = 0;
        gauge_t mem_slab_reclaimable = 0;
        gauge_t mem_slab_unreclaimable = 0;
 
@@ -306,10 +319,16 @@ static int memory_read_internal (value_list_t *vl)
                        val = &mem_buffered;
                else if (strncasecmp (buffer, "Cached:", 7) == 0)
                        val = &mem_cached;
-               else if (strncasecmp (buffer, "SReclaimable:", 13) == 0)
+               else if (strncasecmp (buffer, "Slab:", 5) == 0)
+                       val = &mem_slab_total;
+               else if (strncasecmp (buffer, "SReclaimable:", 13) == 0) {
                        val = &mem_slab_reclaimable;
-               else if (strncasecmp (buffer, "SUnreclaim:", 11) == 0)
+                       detailed_slab_info = 1;
+               }
+               else if (strncasecmp (buffer, "SUnreclaim:", 11) == 0) {
                        val = &mem_slab_unreclaimable;
+                       detailed_slab_info = 1;
+               }
                else
                        continue;
 
@@ -327,16 +346,28 @@ static int memory_read_internal (value_list_t *vl)
                                sstrerror (errno, errbuf, sizeof (errbuf)));
        }
 
-       if (mem_total < (mem_free + mem_buffered + mem_cached + mem_slab_unreclaimable + mem_slab_reclaimable))
+       if (mem_total < (mem_free + mem_buffered + mem_cached + mem_slab_total))
                return (-1);
 
-       mem_used = mem_total - (mem_free + mem_buffered + mem_cached + mem_slab_unreclaimable + mem_slab_reclaimable);
-       MEMORY_SUBMIT ("used",        mem_used,
-                      "buffered",    mem_buffered,
-                      "cached",      mem_cached,
-                      "free",        mem_free,
-                      "slab_unrecl", mem_slab_unreclaimable,
-                      "slab_recl",   mem_slab_reclaimable);
+       mem_used = mem_total - (mem_free + mem_buffered + mem_cached + mem_slab_total);
+
+       /* SReclaimable and SUnreclaim were introduced in kernel 2.6.19
+        * They sum up to the value of Slab, which is available on older & newer
+        * kernels. So SReclaimable/SUnreclaim are submitted if available, and Slab
+        * if not. */
+       if (detailed_slab_info)
+               MEMORY_SUBMIT ("used",        mem_used,
+                              "buffered",    mem_buffered,
+                              "cached",      mem_cached,
+                              "free",        mem_free,
+                              "slab_unrecl", mem_slab_unreclaimable,
+                              "slab_recl",   mem_slab_reclaimable);
+       else
+               MEMORY_SUBMIT ("used",     mem_used,
+                              "buffered", mem_buffered,
+                              "cached",   mem_cached,
+                              "free",     mem_free,
+                              "slab",     mem_slab_total);
 /* #endif KERNEL_LINUX */
 
 #elif HAVE_LIBKSTAT
@@ -347,6 +378,8 @@ static int memory_read_internal (value_list_t *vl)
        long long mem_lock;
        long long mem_kern;
        long long mem_unus;
+       long long arcsize;
+
 
        long long pp_kernel;
        long long physmem;
@@ -354,17 +387,20 @@ static int memory_read_internal (value_list_t *vl)
 
        if (ksp == NULL)
                return (-1);
+       if (ksz == NULL)
+               return (-1);
 
        mem_used = get_kstat_value (ksp, "pagestotal");
        mem_free = get_kstat_value (ksp, "pagesfree");
        mem_lock = get_kstat_value (ksp, "pageslocked");
-       mem_kern = 0;
-       mem_unus = 0;
-
+       arcsize = get_kstat_value (ksz, "size");
        pp_kernel = get_kstat_value (ksp, "pp_kernel");
        physmem = get_kstat_value (ksp, "physmem");
        availrmem = get_kstat_value (ksp, "availrmem");
 
+       mem_kern = 0;
+       mem_unus = 0;
+
        if ((mem_used < 0LL) || (mem_free < 0LL) || (mem_lock < 0LL))
        {
                WARNING ("memory plugin: one of used, free or locked is negative.");
@@ -407,11 +443,14 @@ static int memory_read_internal (value_list_t *vl)
        mem_lock *= pagesize; /* some? ;) */
        mem_kern *= pagesize; /* it's 2011 RAM is cheap */
        mem_unus *= pagesize;
+       mem_kern -= arcsize;
+
 
        MEMORY_SUBMIT ("used",     (gauge_t) mem_used,
                       "free",     (gauge_t) mem_free,
                       "locked",   (gauge_t) mem_lock,
                       "kernel",   (gauge_t) mem_kern,
+                      "arc",      (gauge_t) arcsize,
                       "unusable", (gauge_t) mem_unus);
 /* #endif HAVE_LIBKSTAT */