X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fmemory.c;h=16b8e09fbac720d6c32f7a919bf2f46cc793713e;hb=4d370741101aeb037ae52f3529a4a0869e0dc08a;hp=c503821ba0ce095b2241dc10689a3d60c7c11c7d;hpb=061c3c091d725d58dfe1e7525a8d72a1ea389a8a;p=collectd.git diff --git a/src/memory.c b/src/memory.c index c503821b..16b8e09f 100644 --- a/src/memory.c +++ b/src/memory.c @@ -24,12 +24,16 @@ **/ #include "collectd.h" + #include "common.h" #include "plugin.h" #ifdef HAVE_SYS_SYSCTL_H # include #endif +#ifdef HAVE_SYS_VMMETER_H +# include +#endif #ifdef HAVE_MACH_KERN_RETURN_H # include @@ -73,6 +77,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 @@ -94,9 +99,7 @@ static _Bool values_percentage = 0; static int memory_config (oconfig_item_t *ci) /* {{{ */ { - int i; - - for (i = 0; i < ci->children_num; i++) + for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; if (strcasecmp ("ValuesAbsolute", child->key) == 0) @@ -134,6 +137,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 +166,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 +236,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", @@ -240,9 +249,7 @@ static int memory_read_internal (value_list_t *vl) }; double sysctl_vals[8]; - int i; - - for (i = 0; sysctl_keys[i] != NULL; i++) + for (int i = 0; sysctl_keys[i] != NULL; i++) { int value; size_t value_len = sizeof (value); @@ -260,7 +267,7 @@ static int memory_read_internal (value_list_t *vl) } /* for (sysctl_keys) */ /* multiply all all page counts with the pagesize */ - for (i = 1; sysctl_keys[i] != NULL; i++) + for (int i = 1; sysctl_keys[i] != NULL; i++) if (!isnan (sysctl_vals[i])) sysctl_vals[i] *= sysctl_vals[0]; @@ -278,11 +285,16 @@ 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; if ((fh = fopen ("/proc/meminfo", "r")) == NULL) { @@ -304,6 +316,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, "Slab:", 5) == 0) + val = &mem_slab_total; + else if (strncasecmp (buffer, "SReclaimable:", 13) == 0) { + val = &mem_slab_reclaimable; + detailed_slab_info = 1; + } + else if (strncasecmp (buffer, "SUnreclaim:", 11) == 0) { + val = &mem_slab_unreclaimable; + detailed_slab_info = 1; + } else continue; @@ -321,14 +343,28 @@ static int memory_read_internal (value_list_t *vl) sstrerror (errno, errbuf, sizeof (errbuf))); } - if (mem_total < (mem_free + mem_buffered + mem_cached)) + if (mem_total < (mem_free + mem_buffered + mem_cached + mem_slab_total)) return (-1); - mem_used = mem_total - (mem_free + mem_buffered + mem_cached); - MEMORY_SUBMIT ("used", mem_used, - "buffered", mem_buffered, - "cached", mem_cached, - "free", mem_free); + 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 @@ -339,6 +375,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; @@ -346,17 +384,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."); @@ -399,23 +440,25 @@ 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 */ #elif HAVE_SYSCTL int mib[] = {CTL_VM, VM_METER}; - struct vmtotal vmtotal; + struct vmtotal vmtotal = { 0 }; gauge_t mem_active; gauge_t mem_inactive; gauge_t mem_free; size_t size; - memset (&vmtotal, 0, sizeof (vmtotal)); size = sizeof (vmtotal); if (sysctl (mib, 2, &vmtotal, &size, NULL, 0) < 0) { @@ -448,9 +491,8 @@ static int memory_read_internal (value_list_t *vl) /* #endif HAVE_LIBSTATGRAB */ #elif HAVE_PERFSTAT - perfstat_memory_total_t pmemory; + perfstat_memory_total_t pmemory = { 0 }; - memset (&pmemory, 0, sizeof (pmemory)); if (perfstat_memory_total(NULL, &pmemory, sizeof(pmemory), 1) < 0) { char errbuf[1024];