X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fuptime.c;h=dd33ab38dd1467d57f7c046fd4bb6a835164b845;hb=d4f53887527777296b0982af60f4c0fecdb2f0d9;hp=4edfa8409c5034aa0ec889c9aa45889e50f4d3d1;hpb=b423bd090e6a1af51446ad6967d5016045bd6ea5;p=collectd.git diff --git a/src/uptime.c b/src/uptime.c index 4edfa840..dd33ab38 100644 --- a/src/uptime.c +++ b/src/uptime.c @@ -20,199 +20,184 @@ **/ #include "collectd.h" -#include "common.h" + #include "plugin.h" +#include "utils/common/common.h" #if KERNEL_LINUX -# define UPTIME_FILE "/proc/uptime" -/* No need for includes, using /proc filesystem, Linux only. */ +#include /* #endif KERNEL_LINUX */ #elif HAVE_LIBKSTAT -/* Using kstats chain to retrieve the boot time, this applies to: - * - Solaris / OpenSolaris +/* Using kstats chain to retrieve the boot time on Solaris / OpenSolaris systems */ /* #endif HAVE_LIBKSTAT */ #elif HAVE_SYS_SYSCTL_H -# include -/* Using sysctl interface to retrieve the boot time, this applies to: - * - *BSD - * - Darwin / OS X - */ +#include +/* Using sysctl interface to retrieve the boot time on *BSD / Darwin / OS X + * systems */ /* #endif HAVE_SYS_SYSCTL_H */ +#elif HAVE_PERFSTAT +#include +#include +/* Using perfstat_cpu_total to retrive the boot time in AIX */ +/* #endif HAVE_PERFSTAT */ + #else -# error "No applicable input method." +#error "No applicable input method." #endif -/* +/* * Global variables */ -#if KERNEL_LINUX -/* global variables not needed */ -/* #endif KERNEL_LINUX */ - -#elif HAVE_LIBKSTAT -static time_t boottime; -extern kstat_ctl_t *kc; -/* #endif HAVE_LIBKSTAT */ -#elif HAVE_SYS_SYSCTL_H -static time_t boottime; +#if HAVE_KSTAT_H +#include #endif -static void uptime_submit (gauge_t uptime) -{ - value_t values[1]; - value_list_t vl = VALUE_LIST_INIT; +#if HAVE_LIBKSTAT +extern kstat_ctl_t *kc; +#endif /* #endif HAVE_LIBKSTAT */ - values[0].gauge = uptime; +static void uptime_submit(gauge_t value) { + value_list_t vl = VALUE_LIST_INIT; - vl.values = values; - vl.values_len = 1; + vl.values = &(value_t){.gauge = value}; + vl.values_len = 1; - sstrncpy (vl.host, hostname_g, sizeof (vl.host)); - sstrncpy (vl.plugin, "uptime", sizeof (vl.plugin)); - sstrncpy (vl.type, "uptime", sizeof (vl.type)); + sstrncpy(vl.plugin, "uptime", sizeof(vl.plugin)); + sstrncpy(vl.type, "uptime", sizeof(vl.type)); - plugin_dispatch_values (&vl); + plugin_dispatch_values(&vl); } -#if !defined(KERNEL_LINUX) || !KERNEL_LINUX -static int uptime_init (void) -{ -/* NOTE - - On unix systems other than Linux there is no /proc filesystem which - calculates the uptime every time we call a read for the /proc/uptime - file, the only information available is the boot time (in unix time, - since epoch). Hence there is no need to read, every time the - plugin_read is called, a value that won't change: this is a right - task for the uptime_init function. However, since uptime_init is run - only once, if the function fails in retrieving the boot time, the - plugin is unregistered and there is no chance to try again later. - Nevertheless, this is very unlikely to happen. +/* + * On most unix systems the uptime is calculated by looking at the boot + * time (stored in unix time, since epoch) and the current one. We are + * going to do the same, reading the boot time value while executing + * the uptime_init function (there is no need to read, every time the + * plugin_read is called, a value that won't change). However, since + * uptime_init is run only once, if the function fails in retrieving + * the boot time, the plugin is unregistered and there is no chance to + * try again later. Nevertheless, this is very unlikely to happen. */ +static time_t uptime_get_sys(void) { /* {{{ */ + time_t result; +#if KERNEL_LINUX + struct sysinfo info; + int status; -# if HAVE_LIBKSTAT - kstat_t *ksp; - kstat_named_t *knp; - - ksp = NULL; - knp = NULL; - - /* kstats chain already opened by update_kstat (using *kc), let's verify everything went fine. */ - if (kc == NULL) - { - ERROR ("uptime plugin: kstat chain control structure not available."); - return (-1); - } - - ksp = kstat_lookup (kc, "unix", 0, "system_misc"); - if (ksp == NULL) - { - ERROR ("uptime plugin: Cannot find unix:0:system_misc kstat."); - return (-1); - } - - if (kstat_read (kc, ksp, NULL) < 0) - { - ERROR ("uptime plugin: kstat_read failed."); - return (-1); - } - - knp = (kstat_named_t *) kstat_data_lookup (ksp, "boot_time"); - if (knp == NULL) - { - ERROR ("uptime plugin: kstat_data_lookup (boot_time) failed."); - return (-1); - } - - boottime = (time_t) knp->value.ui32; + status = sysinfo(&info); + if (status != 0) { + ERROR("uptime plugin: Error calling sysinfo: %s", STRERRNO); + return -1; + } + + result = (time_t)info.uptime; +/* #endif KERNEL_LINUX */ + +#elif HAVE_LIBKSTAT + kstat_t *ksp; + kstat_named_t *knp; + + ksp = NULL; + knp = NULL; + + /* kstats chain already opened by update_kstat (using *kc), verify everything + * went fine. */ + if (kc == NULL) { + ERROR("uptime plugin: kstat chain control structure not available."); + return -1; + } + + ksp = kstat_lookup(kc, "unix", 0, "system_misc"); + if (ksp == NULL) { + ERROR("uptime plugin: Cannot find unix:0:system_misc kstat."); + return -1; + } + + if (kstat_read(kc, ksp, NULL) < 0) { + ERROR("uptime plugin: kstat_read failed."); + return -1; + } + + knp = (kstat_named_t *)kstat_data_lookup(ksp, "boot_time"); + if (knp == NULL) { + ERROR("uptime plugin: kstat_data_lookup (boot_time) failed."); + return -1; + } + + if (knp->value.ui32 == 0) { + ERROR("uptime plugin: kstat_data_lookup returned success, " + "but `boottime' is zero!"); + return -1; + } + + result = time(NULL) - (time_t)knp->value.ui32; /* #endif HAVE_LIBKSTAT */ -# elif HAVE_SYS_SYSCTL_H - struct timeval boottv; - size_t boottv_len; - int status; +#elif HAVE_SYS_SYSCTL_H + struct timeval boottv = {0}; + size_t boottv_len; + int status; - int mib[2]; + int mib[] = {CTL_KERN, KERN_BOOTTIME}; - mib[0] = CTL_KERN; - mib[1] = KERN_BOOTTIME; + boottv_len = sizeof(boottv); - memset (&boottv, 0, sizeof (boottv)); - boottv_len = sizeof (boottv); + status = sysctl(mib, STATIC_ARRAY_SIZE(mib), &boottv, &boottv_len, + /* new_value = */ NULL, /* new_length = */ 0); + if (status != 0) { + ERROR("uptime plugin: No value read from sysctl interface: %s", STRERRNO); + return -1; + } - status = sysctl (mib, STATIC_ARRAY_SIZE (mib), &boottv, &boottv_len, - /* new_value = */ NULL, /* new_length = */ 0); - if (status != 0) - { - char errbuf[1024]; - ERROR ("uptime plugin: No value read from sysctl interface: %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } + if (boottv.tv_sec == 0) { + ERROR("uptime plugin: sysctl(3) returned success, " + "but `boottime' is zero!"); + return -1; + } - boottime = boottv.tv_sec; - if (boottime == 0) - { - ERROR ("uptime plugin: sysctl(3) returned success, " - "but `boottime' is zero!"); - return (-1); - } -#endif /* HAVE_SYS_SYSCTL_H */ + result = time(NULL) - boottv.tv_sec; +/* #endif HAVE_SYS_SYSCTL_H */ - return (0); +#elif HAVE_PERFSTAT + int status; + perfstat_cpu_total_t cputotal; + int hertz; -} -#endif /* !KERNEL_LINUX */ + status = perfstat_cpu_total(NULL, &cputotal, sizeof(perfstat_cpu_total_t), 1); + if (status < 0) { + ERROR("uptime plugin: perfstat_cpu_total: %s", STRERRNO); + return -1; + } -static int uptime_read (void) -{ - gauge_t uptime; + hertz = sysconf(_SC_CLK_TCK); + if (hertz <= 0) + hertz = HZ; -#if KERNEL_LINUX - FILE *fh; - - fh = fopen (UPTIME_FILE, "r"); - - if (fh == NULL) - { - char errbuf[1024]; - ERROR ("uptime plugin: Cannot open "UPTIME_FILE": %s", - sstrerror (errno, errbuf, sizeof (errbuf))); - return (-1); - } - - if ( fscanf (fh, "%lf", &uptime) < 1 ) - { - WARNING ("uptime plugin: No value read from "UPTIME_FILE); - fclose (fh); - return (-1); - } - - fclose (fh); -/* #endif KERNEL_LINUX */ + result = cputotal.lbolt / hertz; +#endif /* HAVE_PERFSTAT */ -#elif HAVE_LIBKSTAT || HAVE_SYS_SYSCTL_H - time_t elapsed; + return result; +} /* }}} int uptime_get_sys */ - elapsed = time (NULL) - boottime; +static int uptime_read(void) { + gauge_t uptime; + time_t elapsed; - uptime = (gauge_t) elapsed; -#endif /* HAVE_LIBKSTAT || HAVE_SYS_SYSCTL_H */ + /* calculate the amount of time elapsed since boot, AKA uptime */ + elapsed = uptime_get_sys(); - uptime_submit (uptime); + uptime = (gauge_t)elapsed; - return (0); + uptime_submit(uptime); + + return 0; } -void module_register (void) -{ -#if !defined(KERNEL_LINUX) || !KERNEL_LINUX - plugin_register_init ("uptime", uptime_init); -#endif - plugin_register_read ("uptime", uptime_read); +void module_register(void) { + plugin_register_read("uptime", uptime_read); } /* void module_register */