X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fcommon.c;h=cf2a63989f357600d3dc7aa011b551c90abf59f4;hb=fd909f8965b2b6714dc1da328c77f3681c04af5e;hp=3c416fc2f1e0c62fdda895503b1d67c472cbd98a;hpb=cc0d31accbf4f5543693ec7001088d887fb732d2;p=collectd.git diff --git a/src/common.c b/src/common.c index 3c416fc2..cf2a6398 100644 --- a/src/common.c +++ b/src/common.c @@ -1,6 +1,6 @@ /** * collectd - src/common.c - * Copyright (C) 2005 Florian octo Forster + * Copyright (C) 2005,2006 Florian octo Forster * * This program is free software; you can redistribute it and/ * or modify it under the terms of the GNU General Public Li- @@ -29,50 +29,17 @@ # include #endif +/* for ntohl and htonl */ +#if HAVE_ARPA_INET_H +# include +#endif + +extern int operating_mode; + #ifdef HAVE_LIBKSTAT extern kstat_ctl_t *kc; #endif -#ifdef HAVE_LIBRRD -static char *rra_def[] = -{ - "RRA:AVERAGE:0.0:1:1500", - "RRA:AVERAGE:0.2:6:1500", - "RRA:AVERAGE:0.1:180:1680", - "RRA:AVERAGE:0.1:2160:1520", - "RRA:MIN:0.0:1:1500", - "RRA:MIN:0.2:6:1500", - "RRA:MIN:0.1:180:1680", - "RRA:MIN:0.1:2160:1520", - "RRA:MAX:0.0:1:1500", - "RRA:MAX:0.2:6:1500", - "RRA:MAX:0.1:180:1680", - "RRA:MAX:0.1:2160:1520", - NULL -}; -static int rra_num = 12; - -static int rra_timespans[] = -{ - 3600, - 86400, - 604800, - 2678400, - 31622400, - 0 -}; -static int rra_timespans_num = 5; - -static char *rra_types[] = -{ - "AVERAGE", - "MIN", - "MAX", - NULL -}; -static int rra_types_num = 3; -#endif /* HAVE_LIBRRD */ - void sstrncpy (char *d, const char *s, int len) { strncpy (d, s, len); @@ -121,6 +88,70 @@ void sfree (void **ptr) } #endif +ssize_t sread (int fd, void *buf, size_t count) +{ + char *ptr; + size_t nleft; + ssize_t status; + + ptr = (char *) buf; + nleft = count; + + while (nleft > 0) + { + status = read (fd, (void *) ptr, nleft); + + if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) + continue; + + if (status < 0) + return (status); + + if (status == 0) + { + DBG ("Received EOF from fd %i. " + "Closing fd and returning error.", + fd); + close (fd); + return (-1); + } + + assert (nleft >= status); + + nleft = nleft - status; + ptr = ptr + status; + } + + return (0); +} + + +ssize_t swrite (int fd, const void *buf, size_t count) +{ + const char *ptr; + size_t nleft; + ssize_t status; + + ptr = (const char *) buf; + nleft = count; + + while (nleft > 0) + { + status = write (fd, (const void *) ptr, nleft); + + if ((status < 0) && ((errno == EAGAIN) || (errno == EINTR))) + continue; + + if (status < 0) + return (status); + + nleft = nleft - status; + ptr = ptr + status; + } + + return (0); +} + int strsplit (char *string, char **fields, size_t size) { size_t i; @@ -180,6 +211,27 @@ int strjoin (char *dst, size_t dst_len, return (strlen (dst)); } +int strsubstitute (char *str, char c_from, char c_to) +{ + int ret; + + if (str == NULL) + return (-1); + + ret = 0; + while (*str != '\0') + { + if (*str == c_from) + { + *str = c_to; + ret++; + } + str++; + } + + return (ret); +} + int escape_slashes (char *buf, int buf_len) { int i; @@ -208,7 +260,29 @@ int escape_slashes (char *buf, int buf_len) return (0); } -#ifdef HAVE_LIBRRD +int timeval_sub_timespec (struct timeval *tv0, struct timeval *tv1, struct timespec *ret) +{ + if ((tv0 == NULL) || (tv1 == NULL) || (ret == NULL)) + return (-2); + + if ((tv0->tv_sec < tv1->tv_sec) + || ((tv0->tv_sec == tv1->tv_sec) && (tv0->tv_usec < tv1->tv_usec))) + return (-1); + + ret->tv_sec = tv0->tv_sec - tv1->tv_sec; + ret->tv_nsec = 1000 * ((long) (tv0->tv_usec - tv1->tv_usec)); + + if (ret->tv_nsec < 0) + { + assert (ret->tv_sec > 0); + + ret->tv_nsec += 1000000000; + ret->tv_sec -= 1; + } + + return (0); +} + int check_create_dir (const char *file_orig) { struct stat statbuf; @@ -313,140 +387,69 @@ int check_create_dir (const char *file_orig) return (0); } -/* * * * * - * Magic * - * * * * */ -int rra_get (char ***ret) +static int log_create_file (char *filename, char **ds_def, int ds_num) { - static char **rra_def = NULL; - static int rra_num = 0; - - int rra_max = rra_timespans_num * rra_types_num; - - int step; - int rows; - int span; - - int cdp_num; - int cdp_len; - int i, j; - - char buffer[64]; - - if ((rra_num != 0) && (rra_def != NULL)) - { - *ret = rra_def; - return (rra_num); - } + FILE *log; + int i; - if ((rra_def = (char **) malloc ((rra_max + 1) * sizeof (char *))) == NULL) + if (check_create_dir (filename)) return (-1); - memset (rra_def, '\0', (rra_max + 1) * sizeof (char *)); - - step = atoi (COLLECTD_STEP); - rows = atoi (COLLECTD_ROWS); - if ((step <= 0) || (rows <= 0)) + log = fopen (filename, "w"); + if (log == NULL) { - *ret = NULL; + syslog (LOG_WARNING, "Failed to create %s: %s", filename, + strerror(errno)); return (-1); } - cdp_len = 0; - for (i = 0; i < rra_timespans_num; i++) + fprintf (log, "epoch"); + for (i = 0; i < ds_num; i++) { - span = rra_timespans[i]; - - if ((span / step) < rows) - continue; - - if (cdp_len == 0) - cdp_len = 1; - else - cdp_len = (int) floor (((double) span) / ((double) (rows * step))); - - cdp_num = (int) ceil (((double) span) / ((double) (cdp_len * step))); + char *name; + char *tmp; - for (j = 0; j < rra_types_num; j++) + name = strchr (ds_def[i], ':'); + if (name == NULL) { - if (rra_num >= rra_max) - break; - - if (snprintf (buffer, sizeof(buffer), "RRA:%s:%3.1f:%u:%u", - rra_types[j], COLLECTD_XFF, - cdp_len, cdp_num) >= sizeof (buffer)) - { - syslog (LOG_ERR, "rra_get: Buffer would have been truncated."); - continue; - } - - rra_def[rra_num++] = sstrdup (buffer); + syslog (LOG_WARNING, "Invalid DS definition '%s' for %s", + ds_def[i], filename); + fclose(log); + remove(filename); + return (-1); } - } - -#if COLLECT_DEBUG - DBG ("rra_num = %i", rra_num); - for (i = 0; i < rra_num; i++) - DBG (" %s", rra_def[i]); -#endif - - *ret = rra_def; - return (rra_num); -} - -int rrd_create_file (char *filename, char **ds_def, int ds_num) -{ - char **argv; - int argc; - int i, j; - int status = 0; - - if (check_create_dir (filename)) - return (-1); - - rra_get (&argv); /* FIXME */ - - argc = ds_num + rra_num + 4; - - if ((argv = (char **) malloc (sizeof (char *) * (argc + 1))) == NULL) - { - syslog (LOG_ERR, "rrd_create failed: %s", strerror (errno)); - return (-1); - } - argv[0] = "create"; - argv[1] = filename; - argv[2] = "-s"; - argv[3] = COLLECTD_STEP; + name += 1; + tmp = strchr (name, ':'); + if (tmp == NULL) + { + syslog (LOG_WARNING, "Invalid DS definition '%s' for %s", + ds_def[i], filename); + fclose(log); + remove(filename); + return (-1); + } - j = 4; - for (i = 0; i < ds_num; i++) - argv[j++] = ds_def[i]; - for (i = 0; i < rra_num; i++) - argv[j++] = rra_def[i]; - argv[j] = NULL; - - optind = 0; /* bug in librrd? */ - rrd_clear_error (); - if (rrd_create (argc, argv) == -1) - { - syslog (LOG_ERR, "rrd_create failed: %s: %s", filename, rrd_get_error ()); - status = -1; + /* The `%.*s' is needed because there is no null-byte behind + * the name. */ + fprintf(log, ",%.*s", (int) (tmp - name), name); } + fprintf(log, "\n"); + fclose(log); - free (argv); - - return (status); + return 0; } -#endif /* HAVE_LIBRRD */ -int rrd_update_file (char *host, char *file, char *values, +int log_update_file (char *host, char *file, char *values, char **ds_def, int ds_num) { -#ifdef HAVE_LIBRRD + char *tmp; + FILE *fp; struct stat statbuf; char full_file[1024]; - char *argv[4] = { "update", full_file, values, NULL }; + + /* Cook the values a bit: Substitute colons with commas */ + strsubstitute (values, ':', ','); /* host == NULL => local mode */ if (host != NULL) @@ -460,11 +463,35 @@ int rrd_update_file (char *host, char *file, char *values, return (-1); } + strncpy (full_file, file, 1024); + + tmp = full_file + strlen (full_file) - 4; + assert ((tmp != NULL) && (tmp > full_file)); + + /* Change the filename for logfiles. */ + if (strncmp (tmp, ".rrd", 4) == 0) + { + time_t now; + struct tm *tm; + + /* TODO: Find a way to minimize the calls to `localtime', since + * they are pretty expensive.. */ + now = time (NULL); + tm = localtime (&now); + + strftime (tmp, 1024 - (tmp - full_file), "-%Y-%m-%d", tm); + + /* `localtime(3)' returns a pointer to static data, + * therefore the pointer may not be free'd. */ + } + else + DBG ("The filename ends with `%s' which is unexpected.", tmp); + if (stat (full_file, &statbuf) == -1) { if (errno == ENOENT) { - if (rrd_create_file (full_file, ds_def, ds_num)) + if (log_create_file (full_file, ds_def, ds_num)) return (-1); } else @@ -479,17 +506,20 @@ int rrd_update_file (char *host, char *file, char *values, return (-1); } - optind = 0; /* bug in librrd? */ - rrd_clear_error (); - if (rrd_update (3, argv) == -1) + + fp = fopen (full_file, "a"); + if (fp == NULL) { - syslog (LOG_WARNING, "rrd_update failed: %s: %s", full_file, rrd_get_error ()); + syslog (LOG_WARNING, "Failed to append to %s: %s", full_file, + strerror(errno)); return (-1); } -#endif /* HAVE_LIBRRD */ + fprintf(fp, "%s\n", values); + fclose(fp); return (0); -} +} /* int log_update_file */ + #ifdef HAVE_LIBKSTAT int get_kstat (kstat_t **ksp_ptr, char *module, int instance, char *name) @@ -576,3 +606,21 @@ long long get_kstat_value (kstat_t *ksp, char *name) return (retval); } #endif /* HAVE_LIBKSTAT */ + +unsigned long long ntohll (unsigned long long n) +{ +#if __BYTE_ORDER == __BIG_ENDIAN + return (n); +#else + return (((unsigned long long) ntohl (n)) << 32) + ntohl (n >> 32); +#endif +} + +unsigned long long htonll (unsigned long long n) +{ +#if __BYTE_ORDER == __BIG_ENDIAN + return (n); +#else + return (((unsigned long long) htonl (n)) << 32) + htonl (n >> 32); +#endif +}