X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fcommon.c;h=5de7d97b9ef3e9dfb090816aa2c1418567e4f43a;hb=69441903172882014e9ac90df2ae6c813dfdfdf5;hp=6fdb441c95af1ed952267d674e8d7f240f289dc5;hpb=4dc9287f4de0283ae986444377075dcbdada2871;p=collectd.git diff --git a/src/common.c b/src/common.c index 6fdb441c..5de7d97b 100644 --- a/src/common.c +++ b/src/common.c @@ -543,11 +543,12 @@ int check_create_dir (const char *file_orig) } while (42) { - if (stat (dir, &statbuf) == -1) + if ((stat (dir, &statbuf) == -1) + && (lstat (dir, &statbuf) == -1)) { if (errno == ENOENT) { - if (mkdir (dir, 0755) == 0) + if (mkdir (dir, S_IRWXU | S_IRWXG | S_IRWXO) == 0) break; /* this might happen, if a different thread created @@ -635,24 +636,23 @@ long long get_kstat_value (kstat_t *ksp, char *name) kstat_named_t *kn; long long retval = -1LL; -#ifdef assert - assert (ksp != NULL); - assert (ksp->ks_type == KSTAT_TYPE_NAMED); -#else if (ksp == NULL) { - ERROR ("ERROR: %s:%i: ksp == NULL\n", __FILE__, __LINE__); + ERROR ("get_kstat_value (\"%s\"): ksp is NULL.", name); return (-1LL); } else if (ksp->ks_type != KSTAT_TYPE_NAMED) { - ERROR ("ERROR: %s:%i: ksp->ks_type != KSTAT_TYPE_NAMED\n", __FILE__, __LINE__); + ERROR ("get_kstat_value (\"%s\"): ksp->ks_type (%#x) " + "is not KSTAT_TYPE_NAMED (%#x).", + name, + (unsigned int) ksp->ks_type, + (unsigned int) KSTAT_TYPE_NAMED); return (-1LL); } -#endif if ((kn = (kstat_named_t *) kstat_data_lookup (ksp, name)) == NULL) - return (retval); + return (-1LL); if (kn->data_type == KSTAT_DATA_INT32) retval = (long long) kn->value.i32; @@ -664,7 +664,7 @@ long long get_kstat_value (kstat_t *ksp, char *name) retval = (long long) kn->value.ui64; /* XXX: Might overflow! */ else WARNING ("get_kstat_value: Not a numeric value: %s", name); - + return (retval); } #endif /* HAVE_LIBKSTAT */ @@ -771,36 +771,43 @@ int format_name (char *ret, int ret_len, const char *plugin, const char *plugin_instance, const char *type, const char *type_instance) { - int status; + char *buffer; + size_t buffer_size; + + buffer = ret; + buffer_size = (size_t) ret_len; + +#define APPEND(str) do { \ + size_t l = strlen (str); \ + if (l >= buffer_size) \ + return (ENOBUFS); \ + memcpy (buffer, (str), l); \ + buffer += l; buffer_size -= l; \ +} while (0) - assert (plugin != NULL); - assert (type != NULL); + assert (plugin != NULL); + assert (type != NULL); - if ((plugin_instance == NULL) || (strlen (plugin_instance) == 0)) - { - if ((type_instance == NULL) || (strlen (type_instance) == 0)) - status = ssnprintf (ret, ret_len, "%s/%s/%s", - hostname, plugin, type); - else - status = ssnprintf (ret, ret_len, "%s/%s/%s-%s", - hostname, plugin, type, - type_instance); - } - else - { - if ((type_instance == NULL) || (strlen (type_instance) == 0)) - status = ssnprintf (ret, ret_len, "%s/%s-%s/%s", - hostname, plugin, plugin_instance, - type); - else - status = ssnprintf (ret, ret_len, "%s/%s-%s/%s-%s", - hostname, plugin, plugin_instance, - type, type_instance); - } + APPEND (hostname); + APPEND ("/"); + APPEND (plugin); + if ((plugin_instance != NULL) && (plugin_instance[0] != 0)) + { + APPEND ("-"); + APPEND (plugin_instance); + } + APPEND ("/"); + APPEND (type); + if ((type_instance != NULL) && (type_instance[0] != 0)) + { + APPEND ("-"); + APPEND (type_instance); + } + assert (buffer_size > 0); + buffer[0] = 0; - if ((status < 1) || (status >= ret_len)) - return (-1); - return (0); +#undef APPEND + return (0); } /* int format_name */ int format_values (char *ret, size_t ret_len, /* {{{ */ @@ -939,22 +946,38 @@ int parse_identifier_vl (const char *str, value_list_t *vl) /* {{{ */ if (status != 0) return (status); - sstrncpy (vl->host, host, sizeof (host)); - sstrncpy (vl->plugin, plugin, sizeof (plugin)); + sstrncpy (vl->host, host, sizeof (vl->host)); + sstrncpy (vl->plugin, plugin, sizeof (vl->plugin)); sstrncpy (vl->plugin_instance, (plugin_instance != NULL) ? plugin_instance : "", - sizeof (plugin_instance)); - sstrncpy (vl->type, type, sizeof (type)); + sizeof (vl->plugin_instance)); + sstrncpy (vl->type, type, sizeof (vl->type)); sstrncpy (vl->type_instance, (type_instance != NULL) ? type_instance : "", - sizeof (type_instance)); + sizeof (vl->type_instance)); return (0); } /* }}} int parse_identifier_vl */ -int parse_value (const char *value, value_t *ret_value, int ds_type) +int parse_value (const char *value_orig, value_t *ret_value, int ds_type) { + char *value; char *endptr = NULL; + size_t value_len; + + if (value_orig == NULL) + return (EINVAL); + + value = strdup (value_orig); + if (value == NULL) + return (ENOMEM); + value_len = strlen (value); + + while ((value_len > 0) && isspace ((int) value[value_len - 1])) + { + value[value_len - 1] = 0; + value_len--; + } switch (ds_type) { @@ -975,17 +998,23 @@ int parse_value (const char *value, value_t *ret_value, int ds_type) break; default: + sfree (value); ERROR ("parse_value: Invalid data source type: %i.", ds_type); return -1; } if (value == endptr) { - ERROR ("parse_value: Failed to parse string as number: %s.", value); + sfree (value); + ERROR ("parse_value: Failed to parse string as %s: %s.", + DS_TYPE_TO_STRING (ds_type), value); return -1; } else if ((NULL != endptr) && ('\0' != *endptr)) - WARNING ("parse_value: Ignoring trailing garbage after number: %s.", - endptr); + INFO ("parse_value: Ignoring trailing garbage \"%s\" after %s value. " + "Input string was \"%s\".", + endptr, DS_TYPE_TO_STRING (ds_type), value_orig); + + sfree (value); return 0; } /* int parse_value */ @@ -1207,7 +1236,102 @@ counter_t counter_diff (counter_t old_value, counter_t new_value) } return (diff); -} /* counter_t counter_to_gauge */ +} /* counter_t counter_diff */ + +int rate_to_value (value_t *ret_value, gauge_t rate, /* {{{ */ + rate_to_value_state_t *state, + int ds_type, cdtime_t t) +{ + gauge_t delta_gauge; + cdtime_t delta_t; + + if (ds_type == DS_TYPE_GAUGE) + { + state->last_value.gauge = rate; + state->last_time = t; + + *ret_value = state->last_value; + return (0); + } + + /* Counter and absolute can't handle negative rates. Reset "last time" + * to zero, so that the next valid rate will re-initialize the + * structure. */ + if ((rate < 0.0) + && ((ds_type == DS_TYPE_COUNTER) + || (ds_type == DS_TYPE_ABSOLUTE))) + { + memset (state, 0, sizeof (*state)); + return (EINVAL); + } + + /* Another invalid state: The time is not increasing. */ + if (t <= state->last_time) + { + memset (state, 0, sizeof (*state)); + return (EINVAL); + } + + delta_t = t - state->last_time; + delta_gauge = (rate * CDTIME_T_TO_DOUBLE (delta_t)) + state->residual; + + /* Previous value is invalid. */ + if (state->last_time == 0) /* {{{ */ + { + if (ds_type == DS_TYPE_DERIVE) + { + state->last_value.derive = (derive_t) rate; + state->residual = rate - ((gauge_t) state->last_value.derive); + } + else if (ds_type == DS_TYPE_COUNTER) + { + state->last_value.counter = (counter_t) rate; + state->residual = rate - ((gauge_t) state->last_value.counter); + } + else if (ds_type == DS_TYPE_ABSOLUTE) + { + state->last_value.absolute = (absolute_t) rate; + state->residual = rate - ((gauge_t) state->last_value.absolute); + } + else + { + assert (23 == 42); + } + + state->last_time = t; + return (EAGAIN); + } /* }}} */ + + if (ds_type == DS_TYPE_DERIVE) + { + derive_t delta_derive = (derive_t) delta_gauge; + + state->last_value.derive += delta_derive; + state->residual = delta_gauge - ((gauge_t) delta_derive); + } + else if (ds_type == DS_TYPE_COUNTER) + { + counter_t delta_counter = (counter_t) delta_gauge; + + state->last_value.counter += delta_counter; + state->residual = delta_gauge - ((gauge_t) delta_counter); + } + else if (ds_type == DS_TYPE_ABSOLUTE) + { + absolute_t delta_absolute = (absolute_t) delta_gauge; + + state->last_value.absolute = delta_absolute; + state->residual = delta_gauge - ((gauge_t) delta_absolute); + } + else + { + assert (23 == 42); + } + + state->last_time = t; + *ret_value = state->last_value; + return (0); +} /* }}} value_t rate_to_value */ int service_name_to_port_number (const char *service_name) {