X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fcontextswitch.c;h=c207318f9d62425fbfb18e7e86727bce62b65bcb;hb=7947c0d3d8e4cae18dc55108465eb6fa3b88b5f0;hp=0db727c78373a524ee15b3c5856f72e2c3f8f53a;hpb=11c3445e8931bbcefcb5b665a28fdae7691ebc6a;p=collectd.git diff --git a/src/contextswitch.c b/src/contextswitch.c index 0db727c7..c207318f 100644 --- a/src/contextswitch.c +++ b/src/contextswitch.c @@ -1,6 +1,7 @@ /** * collectd - src/contextswitch.c * Copyright (C) 2009 Patrik Weiskircher + * Copyright (C) 2010 Kimo Rosenbaum * * 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 @@ -17,22 +18,35 @@ * * Authors: * Patrik Weiskircher + * Kimo Rosenbaum **/ #include "collectd.h" #include "common.h" #include "plugin.h" -#if !KERNEL_LINUX +#ifdef HAVE_SYS_SYSCTL_H +# include +#endif + +#if HAVE_SYSCTLBYNAME +/* no global variables */ +/* #endif HAVE_SYSCTLBYNAME */ + +#elif KERNEL_LINUX +/* no global variables */ +/* #endif KERNEL_LINUX */ + +#else # error "No applicable input method." #endif -static void cs_submit (unsigned long context_switches) +static void cs_submit (derive_t context_switches) { value_t values[1]; value_list_t vl = VALUE_LIST_INIT; - values[0].derive = context_switches; + values[0].derive = (derive_t) context_switches; vl.values = values; vl.values_len = 1; @@ -45,11 +59,31 @@ static void cs_submit (unsigned long context_switches) static int cs_read (void) { +#if HAVE_SYSCTLBYNAME + int value = 0; + size_t value_len = sizeof (value); + int status; + + status = sysctlbyname ("vm.stats.sys.v_swtch", + &value, &value_len, + /* new pointer = */ NULL, /* new length = */ 0); + if (status != 0) + { + ERROR("contextswitch plugin: sysctlbyname " + "(vm.stats.sys.v_swtch) failed"); + return (-1); + } + + cs_submit (value); +/* #endif HAVE_SYSCTLBYNAME */ + +#elif KERNEL_LINUX FILE *fh; char buffer[64]; int numfields; - char *fields[2]; - unsigned long result = 0; + char *fields[3]; + derive_t result = 0; + int status = -2; fh = fopen ("/proc/stat", "r"); if (fh == NULL) { @@ -58,35 +92,38 @@ static int cs_read (void) return (-1); } - while (fgets(buffer, sizeof(buffer), fh)) + while (fgets(buffer, sizeof(buffer), fh) != NULL) { - if (strncmp(buffer, "ctxt", 4)) + char *endptr; + + numfields = strsplit(buffer, fields, STATIC_ARRAY_SIZE (fields)); + if (numfields != 2) continue; - numfields = strsplit(buffer, fields, 2); - if (numfields != 2) { - ERROR ("contextswitch plugin: ctxt in /proc/stat contains more than 2 fields."); - break; - } + if (strcmp("ctxt", fields[0]) != 0) + continue; - result = strtoul(fields[1], NULL, 10); - if (errno == ERANGE && result == ULONG_MAX) { - ERROR ("contextswitch plugin: ctxt value in /proc/stat overflows."); + errno = 0; + endptr = NULL; + result = (derive_t) strtoll (fields[1], &endptr, /* base = */ 10); + if ((endptr == fields[1]) || (errno != 0)) { + ERROR ("contextswitch plugin: Cannot parse ctxt value: %s", + fields[1]); + status = -1; break; } + cs_submit(result); + status = 0; break; } fclose(fh); - if (result == 0) { - ERROR ("contextswitch plugin: unable to find context switch value."); - return -1; - } - - cs_submit(result); + if (status == -2) + ERROR ("contextswitch plugin: Unable to find context switch value."); +#endif /* KERNEL_LINUX */ - return 0; + return status; } void module_register (void)