X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fswap.c;h=1779f861b9b91b88d86e3fbfef6423a3d5bfbb57;hb=37905c5a2370c8e6edae5011978773eeaa589d09;hp=1cf707797f1057b4fb6124c763a46e057b2753ee;hpb=16d71c37aac266ae89f12bcdbce6111f5e9d0673;p=collectd.git diff --git a/src/swap.c b/src/swap.c index 1cf70779..1779f861 100644 --- a/src/swap.c +++ b/src/swap.c @@ -1,6 +1,6 @@ /** * collectd - src/swap.c - * Copyright (C) 2005-2007 Florian octo Forster + * Copyright (C) 2005-2009 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 @@ -26,16 +26,26 @@ #if HAVE_SYS_SWAP_H # include #endif +#if HAVE_VM_ANON_H +# include +#endif #if HAVE_SYS_PARAM_H # include #endif #if HAVE_SYS_SYSCTL_H # include #endif +#if HAVE_SYS_DKSTAT_H +# include +#endif #if HAVE_KVM_H # include #endif +#if HAVE_STATGRAB_H +# include +#endif + #undef MAX #define MAX(x,y) ((x) > (y) ? (x) : (y)) @@ -48,14 +58,18 @@ static unsigned long long pagesize; static kstat_t *ksp; /* #endif HAVE_LIBKSTAT */ +#elif HAVE_SWAPCTL +/* No global variables */ +/* #endif HAVE_SWAPCTL */ + #elif defined(VM_SWAPUSAGE) /* No global variables */ /* #endif defined(VM_SWAPUSAGE) */ -#elif HAVE_LIBKVM +#elif HAVE_LIBKVM_GETSWAPINFO static kvm_t *kvm_obj = NULL; int kvm_pagesize; -/* #endif HAVE_LIBKVM */ +/* #endif HAVE_LIBKVM_GETSWAPINFO */ #elif HAVE_LIBSTATGRAB /* No global variables */ @@ -78,11 +92,15 @@ static int swap_init (void) ksp = NULL; /* #endif HAVE_LIBKSTAT */ +#elif HAVE_SWAPCTL + /* No init stuff */ +/* #endif HAVE_SWAPCTL */ + #elif defined(VM_SWAPUSAGE) /* No init stuff */ /* #endif defined(VM_SWAPUSAGE) */ -#elif HAVE_LIBKVM +#elif HAVE_LIBKVM_GETSWAPINFO if (kvm_obj != NULL) { kvm_close (kvm_obj); @@ -101,7 +119,7 @@ static int swap_init (void) ERROR ("swap plugin: kvm_open failed."); return (-1); } -/* #endif HAVE_LIBKVM */ +/* #endif HAVE_LIBKVM_GETSWAPINFO */ #elif HAVE_LIBSTATGRAB /* No init stuff */ @@ -119,12 +137,12 @@ static void swap_submit (const char *type_instance, double value) vl.values = values; vl.values_len = 1; - vl.time = time (NULL); - strcpy (vl.host, hostname_g); - strcpy (vl.plugin, "swap"); - strncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); + sstrncpy (vl.host, hostname_g, sizeof (vl.host)); + sstrncpy (vl.plugin, "swap", sizeof (vl.plugin)); + sstrncpy (vl.type, "swap", sizeof (vl.type)); + sstrncpy (vl.type_instance, type_instance, sizeof (vl.type_instance)); - plugin_dispatch_values ("swap", &vl); + plugin_dispatch_values (&vl); } /* void swap_submit */ static int swap_read (void) @@ -235,6 +253,84 @@ static int swap_read (void) swap_submit ("reserved", swap_resv); /* #endif HAVE_LIBKSTAT */ +#elif HAVE_SWAPCTL + struct swapent *swap_entries; + int swap_num; + int status; + int i; + + uint64_t used = 0; + uint64_t total = 0; + + /* + * XXX: This is the syntax for the *BSD `swapctl', which has the + * following prototype: + * swapctl (int cmd, void *arg, int misc); + * + * HP-UX and Solaris (and possibly other UNIXes) provide `swapctl', + * too, but with the following prototype: + * swapctl (int cmd, void *arg); + * + * Solaris is usually handled in the KSTAT case above. For other UNIXes + * a separate case for the other version of `swapctl' may be necessary. + */ + swap_num = swapctl (SWAP_NSWAP, NULL, 0); + if (swap_num < 0) + { + ERROR ("swap plugin: swapctl (SWAP_NSWAP) failed with status %i.", + swap_num); + return (-1); + } + else if (swap_num == 0) + return (0); + + swap_entries = calloc (swap_num, sizeof (*swap_entries)); + if (swap_entries == NULL) + { + ERROR ("swap plugin: calloc failed."); + return (-1); + } + + status = swapctl (SWAP_STATS, swap_entries, swap_num); + if (status != swap_num) + { + ERROR ("swap plugin: swapctl (SWAP_STATS) failed with status %i.", + status); + sfree (swap_entries); + return (-1); + } + +#if defined(DEV_BSIZE) && (DEV_BSIZE > 0) +# define C_SWAP_BLOCK_SIZE ((uint64_t) DEV_BSIZE) +#else +# define C_SWAP_BLOCK_SIZE ((uint64_t) 512) +#endif + + for (i = 0; i < swap_num; i++) + { + if ((swap_entries[i].se_flags & SWF_ENABLE) == 0) + continue; + + used += ((uint64_t) swap_entries[i].se_inuse) + * C_SWAP_BLOCK_SIZE; + total += ((uint64_t) swap_entries[i].se_nblks) + * C_SWAP_BLOCK_SIZE; + } + + if (total < used) + { + ERROR ("swap plugin: Total swap space (%"PRIu64") " + "is less than used swap space (%"PRIu64").", + total, used); + return (-1); + } + + swap_submit ("used", (gauge_t) used); + swap_submit ("free", (gauge_t) (total - used)); + + sfree (swap_entries); +/* #endif HAVE_SWAPCTL */ + #elif defined(VM_SWAPUSAGE) int mib[3]; size_t mib_len; @@ -255,7 +351,7 @@ static int swap_read (void) swap_submit ("free", sw_usage.xsu_avail); /* #endif VM_SWAPUSAGE */ -#elif HAVE_LIBKVM +#elif HAVE_LIBKVM_GETSWAPINFO struct kvm_swap data_s; int status; @@ -281,7 +377,7 @@ static int swap_read (void) swap_submit ("used", used); swap_submit ("free", free); -/* #endif HAVE_LIBKVM */ +/* #endif HAVE_LIBKVM_GETSWAPINFO */ #elif HAVE_LIBSTATGRAB sg_swap_stats *swap;