# HG changeset patch # User Peter Stamfest <pe...@stamfest.at> # Date 1299524364 -3600 # Node ID 2e1ec35bef337eee041078d583cfe5aaa7068509 # Parent 4fcecd56ec3b1091c9fd649d3d52aa86a679eb02 * Introduce rrdc_connection_t - bundles all the data needed for a rrdcached connection - remove global variables used until now * Use rrdc_connection_t throughout rrdtool - sematic changes: - The last connection to a rrdcached is not kept open, thus multiple requests to the same rrdcached use different connections.
diff --git a/src/rrd_client.c b/src/rrd_client.c --- a/src/rrd_client.c +++ b/src/rrd_client.c @@ -25,6 +25,7 @@ * Sebastian tokkee Harl <sh at tokkee.org> **/ + #include "rrd.h" #include "rrd_tool.h" #include "rrd_client.h" @@ -55,10 +56,6 @@ }; typedef struct rrdc_response_s rrdc_response_t; -static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; -static int sd = -1; -static FILE *sh = NULL; -static char *sd_path = NULL; /* cache the path for sd */ /* get_path: Return a path name appropriate to be sent to the daemon. * @@ -68,16 +65,16 @@ * are not allowed, since path name translation is done by the server. * * One must hold `lock' when calling this function. */ -static const char *get_path (const char *path, char *resolved_path) /* {{{ */ +static const char *get_path (rrdc_connection_t *conn, const char *path, char *resolved_path) /* {{{ */ { const char *ret = path; int is_unix = 0; - if ((path == NULL) || (resolved_path == NULL) || (sd_path == NULL)) + if ((conn == NULL) || (path == NULL) || (resolved_path == NULL) || (conn->sd_path == NULL)) return (NULL); - if ((*sd_path == '/') - || (strncmp ("unix:", sd_path, strlen ("unix:")) == 0)) + if ((*(conn->sd_path) == '/') + || (strncmp ("unix:", conn->sd_path, strlen ("unix:")) == 0)) is_unix = 1; if (is_unix) @@ -232,23 +229,23 @@ } /* }}} int parse_value_array_header */ /* One must hold `lock' when calling `close_connection'. */ -static void close_connection (void) /* {{{ */ +static void close_connection (rrdc_connection_t *conn) /* {{{ */ { - if (sh != NULL) + if (conn->sh != NULL) { - fclose (sh); - sh = NULL; - sd = -1; + fclose (conn->sh); + conn->sh = NULL; + conn->sd = -1; } - else if (sd >= 0) + else if (conn->sd >= 0) { - close (sd); - sd = -1; + close (conn->sd); + conn->sd = -1; } - if (sd_path != NULL) - free (sd_path); - sd_path = NULL; + if (conn->sd_path != NULL) + free (conn->sd_path); + conn->sd_path = NULL; } /* }}} void close_connection */ static int buffer_add_string (const char *str, /* {{{ */ @@ -367,7 +364,7 @@ free (res); } /* }}} void response_free */ -static int response_read (rrdc_response_t **ret_response) /* {{{ */ +static int response_read (rrdc_connection_t *conn, rrdc_response_t **ret_response) /* {{{ */ { rrdc_response_t *ret = NULL; int status = 0; @@ -379,7 +376,7 @@ #define DIE(code) do { status = code; goto err_out; } while(0) - if (sh == NULL) + if (conn == NULL || conn->sh == NULL) DIE(-1); ret = (rrdc_response_t *) malloc (sizeof (rrdc_response_t)); @@ -389,7 +386,7 @@ ret->lines = NULL; ret->lines_num = 0; - buffer_ptr = fgets (buffer, sizeof (buffer), sh); + buffer_ptr = fgets (buffer, sizeof (buffer), conn->sh); if (buffer_ptr == NULL) DIE(-3); @@ -418,7 +415,7 @@ for (i = 0; i < ret->lines_num; i++) { - buffer_ptr = fgets (buffer, sizeof (buffer), sh); + buffer_ptr = fgets (buffer, sizeof (buffer), conn->sh); if (buffer_ptr == NULL) DIE(-6); @@ -431,39 +428,39 @@ out: *ret_response = ret; - fflush(sh); + fflush(conn->sh); return (status); err_out: response_free(ret); - close_connection(); + close_connection(conn); return (status); #undef DIE } /* }}} rrdc_response_t *response_read */ -static int request (const char *buffer, size_t buffer_size, /* {{{ */ +static int request (rrdc_connection_t *conn, const char *buffer, size_t buffer_size, /* {{{ */ rrdc_response_t **ret_response) { int status; rrdc_response_t *res; - if (sh == NULL) + if (conn == NULL || conn->sh == NULL) return (ENOTCONN); - status = (int) fwrite (buffer, buffer_size, /* nmemb = */ 1, sh); + status = (int) fwrite (buffer, buffer_size, /* nmemb = */ 1, conn->sh); if (status != 1) { - close_connection (); + close_connection (conn); rrd_set_error("request: socket error (%d) while talking to rrdcached", status); return (-1); } - fflush (sh); + fflush (conn->sh); res = NULL; - status = response_read (&res); + status = response_read (conn, &res); if (status != 0) { @@ -479,9 +476,9 @@ /* determine whether we are connected to the specified daemon_addr if * NULL, return whether we are connected at all */ -int rrdc_is_connected(const char *daemon_addr) /* {{{ */ +int rrdc_is_connected(rrdc_connection_t *conn, const char *daemon_addr) /* {{{ */ { - if (sd < 0) + if (conn->sd < 0) return 0; else if (daemon_addr == NULL) { @@ -496,23 +493,23 @@ else return 0; } - else if (strcmp(daemon_addr, sd_path) == 0) + else if (strcmp(daemon_addr, conn->sd_path) == 0) return 1; else return 0; } /* }}} int rrdc_is_connected */ -static int rrdc_connect_unix (const char *path) /* {{{ */ +static int rrdc_connect_unix (rrdc_connection_t *conn, const char *path) /* {{{ */ { struct sockaddr_un sa; int status; assert (path != NULL); - assert (sd == -1); + assert (conn->sd == -1); - sd = socket (PF_UNIX, SOCK_STREAM, /* protocol = */ 0); - if (sd < 0) + conn->sd = socket (PF_UNIX, SOCK_STREAM, /* protocol = */ 0); + if (conn->sd < 0) { status = errno; return (status); @@ -522,26 +519,26 @@ sa.sun_family = AF_UNIX; strncpy (sa.sun_path, path, sizeof (sa.sun_path) - 1); - status = connect (sd, (struct sockaddr *) &sa, sizeof (sa)); + status = connect (conn->sd, (struct sockaddr *) &sa, sizeof (sa)); if (status != 0) { status = errno; - close_connection (); + close_connection (conn); return (status); } - sh = fdopen (sd, "r+"); - if (sh == NULL) + conn->sh = fdopen (conn->sd, "r+"); + if (conn->sh == NULL) { status = errno; - close_connection (); + close_connection (conn); return (status); } return (0); } /* }}} int rrdc_connect_unix */ -static int rrdc_connect_network (const char *addr_orig) /* {{{ */ +static int rrdc_connect_network (rrdc_connection_t *conn, const char *addr_orig) /* {{{ */ { struct addrinfo ai_hints; struct addrinfo *ai_res; @@ -550,8 +547,9 @@ char *addr; char *port; + assert (conn != NULL); assert (addr_orig != NULL); - assert (sd == -1); + assert (conn->sd == -1); strncpy(addr_copy, addr_orig, sizeof(addr_copy)); addr_copy[sizeof(addr_copy) - 1] = '\0'; @@ -615,27 +613,27 @@ for (ai_ptr = ai_res; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next) { - sd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); - if (sd < 0) + conn->sd = socket (ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol); + if (conn->sd < 0) { status = errno; - sd = -1; + conn->sd = -1; continue; } - status = connect (sd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); + status = connect (conn->sd, ai_ptr->ai_addr, ai_ptr->ai_addrlen); if (status != 0) { status = errno; - close_connection(); + close_connection(conn); continue; } - sh = fdopen (sd, "r+"); - if (sh == NULL) + conn->sh = fdopen (conn->sd, "r+"); + if (conn->sh == NULL) { status = errno; - close_connection (); + close_connection (conn); continue; } @@ -648,7 +646,7 @@ return (status); } /* }}} int rrdc_connect_network */ -int rrdc_connect (const char *addr) /* {{{ */ +int rrdc_connect (rrdc_connection_t *conn, const char *addr) /* {{{ */ { int status = 0; @@ -658,29 +656,31 @@ if (addr == NULL) return 0; - pthread_mutex_lock(&lock); + assert (conn != NULL); - if (sd >= 0 && sd_path != NULL && strcmp(addr, sd_path) == 0) + pthread_mutex_lock(&conn->lock); + + if (conn->sd >= 0 && conn->sd_path != NULL && strcmp(addr, conn->sd_path) == 0) { /* connection to the same daemon; use cached connection */ - pthread_mutex_unlock (&lock); + pthread_mutex_unlock (&conn->lock); return (0); } else { - close_connection(); + close_connection(conn); } rrd_clear_error (); if (strncmp ("unix:", addr, strlen ("unix:")) == 0) - status = rrdc_connect_unix (addr + strlen ("unix:")); + status = rrdc_connect_unix (conn, addr + strlen ("unix:")); else if (addr[0] == '/') - status = rrdc_connect_unix (addr); + status = rrdc_connect_unix (conn, addr); else - status = rrdc_connect_network(addr); + status = rrdc_connect_network(conn, addr); - if (status == 0 && sd >= 0) - sd_path = strdup(addr); + if (status == 0 && conn->sd >= 0) + conn->sd_path = strdup(addr); else { char *err = rrd_test_error () ? rrd_get_error () : "Internal error"; @@ -695,22 +695,23 @@ free (err); } - pthread_mutex_unlock (&lock); + pthread_mutex_unlock (&conn->lock); return (status); } /* }}} int rrdc_connect */ -int rrdc_disconnect (void) /* {{{ */ +int rrdc_disconnect (rrdc_connection_t *conn) /* {{{ */ { - pthread_mutex_lock (&lock); + pthread_mutex_lock (&conn->lock); - close_connection(); + close_connection(conn); - pthread_mutex_unlock (&lock); + pthread_mutex_unlock (&conn->lock); return (0); } /* }}} int rrdc_disconnect */ -int rrdc_update (const char *filename, int values_num, /* {{{ */ +int rrdc_update (rrdc_connection_t *conn, + const char *filename, int values_num, /* {{{ */ const char * const *values) { char buffer[RRD_CMD_MAX]; @@ -730,18 +731,18 @@ if (status != 0) return (ENOBUFS); - pthread_mutex_lock (&lock); - filename = get_path (filename, file_path); + pthread_mutex_lock (&conn->lock); + filename = get_path (conn, filename, file_path); if (filename == NULL) { - pthread_mutex_unlock (&lock); + pthread_mutex_unlock (&conn->lock); return (-1); } status = buffer_add_string (filename, &buffer_ptr, &buffer_free); if (status != 0) { - pthread_mutex_unlock (&lock); + pthread_mutex_unlock (&conn->lock); return (ENOBUFS); } @@ -750,7 +751,7 @@ status = buffer_add_value (values[i], &buffer_ptr, &buffer_free); if (status != 0) { - pthread_mutex_unlock (&lock); + pthread_mutex_unlock (&conn->lock); return (ENOBUFS); } } @@ -761,8 +762,8 @@ buffer[buffer_size - 1] = '\n'; res = NULL; - status = request (buffer, buffer_size, &res); - pthread_mutex_unlock (&lock); + status = request (conn, buffer, buffer_size, &res); + pthread_mutex_unlock (&conn->lock); if (status != 0) return (status); @@ -773,7 +774,7 @@ return (status); } /* }}} int rrdc_update */ -int rrdc_flush (const char *filename) /* {{{ */ +int rrdc_flush (rrdc_connection_t *conn, const char *filename) /* {{{ */ { char buffer[RRD_CMD_MAX]; char *buffer_ptr; @@ -794,18 +795,18 @@ if (status != 0) return (ENOBUFS); - pthread_mutex_lock (&lock); - filename = get_path (filename, file_path); + pthread_mutex_lock (&conn->lock); + filename = get_path (conn, filename, file_path); if (filename == NULL) { - pthread_mutex_unlock (&lock); + pthread_mutex_unlock (&conn->lock); return (-1); } status = buffer_add_string (filename, &buffer_ptr, &buffer_free); if (status != 0) { - pthread_mutex_unlock (&lock); + pthread_mutex_unlock (&conn->lock); return (ENOBUFS); } @@ -815,8 +816,8 @@ buffer[buffer_size - 1] = '\n'; res = NULL; - status = request (buffer, buffer_size, &res); - pthread_mutex_unlock (&lock); + status = request (conn, buffer, buffer_size, &res); + pthread_mutex_unlock (&conn->lock); if (status != 0) return (status); @@ -827,7 +828,7 @@ return (status); } /* }}} int rrdc_flush */ -rrd_info_t * rrdc_info (const char *filename) /* {{{ */ +rrd_info_t * rrdc_info (rrdc_connection_t *conn, const char *filename) /* {{{ */ { char buffer[RRD_CMD_MAX]; char *buffer_ptr; @@ -857,18 +858,18 @@ return (NULL); } - pthread_mutex_lock (&lock); - filename = get_path (filename, file_path); + pthread_mutex_lock (&conn->lock); + filename = get_path (conn, filename, file_path); if (filename == NULL) { - pthread_mutex_unlock (&lock); + pthread_mutex_unlock (&conn->lock); return (NULL); } status = buffer_add_string (filename, &buffer_ptr, &buffer_free); if (status != 0) { - pthread_mutex_unlock (&lock); + pthread_mutex_unlock (&conn->lock); rrd_set_error ("rrdc_info: out of memory"); return (NULL); } @@ -879,8 +880,8 @@ buffer[buffer_size - 1] = '\n'; res = NULL; - status = request (buffer, buffer_size, &res); - pthread_mutex_unlock (&lock); + status = request (conn, buffer, buffer_size, &res); + pthread_mutex_unlock (&conn->lock); if (status != 0) { rrd_set_error ("rrdcached: %s", res->message); @@ -928,7 +929,7 @@ return (data); } /* }}} int rrdc_info */ -time_t rrdc_last (const char *filename) /* {{{ */ +time_t rrdc_last (rrdc_connection_t *conn, const char *filename) /* {{{ */ { char buffer[RRD_CMD_MAX]; char *buffer_ptr; @@ -954,18 +955,18 @@ return (-1); } - pthread_mutex_lock (&lock); - filename = get_path (filename, file_path); + pthread_mutex_lock (&conn->lock); + filename = get_path (conn, filename, file_path); if (filename == NULL) { - pthread_mutex_unlock (&lock); + pthread_mutex_unlock (&conn->lock); return (-1); } status = buffer_add_string (filename, &buffer_ptr, &buffer_free); if (status != 0) { - pthread_mutex_unlock (&lock); + pthread_mutex_unlock (&conn->lock); rrd_set_error ("rrdc_last: out of memory"); return (-1); } @@ -976,8 +977,8 @@ buffer[buffer_size - 1] = '\n'; res = NULL; - status = request (buffer, buffer_size, &res); - pthread_mutex_unlock (&lock); + status = request (conn, buffer, buffer_size, &res); + pthread_mutex_unlock (&conn->lock); if (status != 0) { rrd_set_error ("rrdcached: %s", res->message); @@ -989,7 +990,7 @@ return (lastup); } /* }}} int rrdc_last */ -time_t rrdc_first (const char *filename, int rraindex) /* {{{ */ +time_t rrdc_first (rrdc_connection_t *conn, const char *filename, int rraindex) /* {{{ */ { char buffer[RRD_CMD_MAX]; char *buffer_ptr; @@ -1015,25 +1016,25 @@ return (-1); } - pthread_mutex_lock (&lock); - filename = get_path (filename, file_path); + pthread_mutex_lock (&conn->lock); + filename = get_path (conn, filename, file_path); if (filename == NULL) { - pthread_mutex_unlock (&lock); + pthread_mutex_unlock (&conn->lock); return (-1); } status = buffer_add_string (filename, &buffer_ptr, &buffer_free); if (status != 0) { - pthread_mutex_unlock (&lock); + pthread_mutex_unlock (&conn->lock); rrd_set_error ("rrdc_first: out of memory"); return (-1); } status = buffer_add_ulong (rraindex, &buffer_ptr, &buffer_free); if (status != 0) { - pthread_mutex_unlock (&lock); + pthread_mutex_unlock (&conn->lock); rrd_set_error ("rrdc_first: out of memory"); return (-1); } @@ -1044,8 +1045,8 @@ buffer[buffer_size - 1] = '\n'; res = NULL; - status = request (buffer, buffer_size, &res); - pthread_mutex_unlock (&lock); + status = request (conn, buffer, buffer_size, &res); + pthread_mutex_unlock (&conn->lock); if (status != 0) { rrd_set_error ("rrdcached: %s", res->message); @@ -1057,7 +1058,7 @@ return (firstup); } /* }}} int rrdc_first */ -int rrdc_create (const char *filename, /* {{{ */ +int rrdc_create (rrdc_connection_t *conn, const char *filename, /* {{{ */ unsigned long pdp_step, time_t last_up, int no_overwrite, @@ -1088,11 +1089,11 @@ return (-1); } - pthread_mutex_lock (&lock); - filename = get_path (filename, file_path); + pthread_mutex_lock (&conn->lock); + filename = get_path (conn, filename, file_path); if (filename == NULL) { - pthread_mutex_unlock (&lock); + pthread_mutex_unlock (&conn->lock); return (-1); } @@ -1106,7 +1107,7 @@ } if (status != 0) { - pthread_mutex_unlock (&lock); + pthread_mutex_unlock (&conn->lock); rrd_set_error ("rrdc_create: out of memory"); return (-1); } @@ -1116,7 +1117,7 @@ status = buffer_add_string (argv[i], &buffer_ptr, &buffer_free); if (status != 0) { - pthread_mutex_unlock (&lock); + pthread_mutex_unlock (&conn->lock); rrd_set_error ("rrdc_create: out of memory"); return (-1); } @@ -1130,8 +1131,8 @@ buffer[buffer_size - 1] = '\n'; res = NULL; - status = request (buffer, buffer_size, &res); - pthread_mutex_unlock (&lock); + status = request (conn, buffer, buffer_size, &res); + pthread_mutex_unlock (&conn->lock); if (status != 0) { rrd_set_error ("rrdcached: %s", res->message); @@ -1141,7 +1142,7 @@ return(0); } /* }}} int rrdc_create */ -int rrdc_fetch (const char *filename, /* {{{ */ +int rrdc_fetch (rrdc_connection_t *conn, const char *filename, /* {{{ */ const char *cf, time_t *ret_start, time_t *ret_end, unsigned long *ret_step, @@ -1187,7 +1188,7 @@ return (ENOBUFS); /* change to path for rrdcached */ - path_ptr = get_path (filename, path_buffer); + path_ptr = get_path (conn, filename, path_buffer); if (path_ptr == NULL) return (EINVAL); @@ -1224,7 +1225,7 @@ buffer[buffer_size - 1] = '\n'; res = NULL; - status = request (buffer, buffer_size, &res); + status = request (conn, buffer, buffer_size, &res); if (status != 0) return (status); @@ -1354,16 +1355,16 @@ /* convenience function; if there is a daemon specified, or if we can * detect one from the environment, then flush the file. Otherwise, no-op */ -int rrdc_flush_if_daemon (const char *opt_daemon, const char *filename) /* {{{ */ +int rrdc_flush_if_daemon (rrdc_connection_t *conn, const char *opt_daemon, const char *filename) /* {{{ */ { int status = 0; - rrdc_connect(opt_daemon); + rrdc_connect(conn, opt_daemon); - if (rrdc_is_connected(opt_daemon)) + if (rrdc_is_connected(conn, opt_daemon)) { rrd_clear_error(); - status = rrdc_flush (filename); + status = rrdc_flush (conn, filename); if (status != 0 && !rrd_test_error()) { @@ -1384,7 +1385,7 @@ } /* }}} int rrdc_flush_if_daemon */ -int rrdc_stats_get (rrdc_stats_t **ret_stats) /* {{{ */ +int rrdc_stats_get (rrdc_connection_t *conn, rrdc_stats_t **ret_stats) /* {{{ */ { rrdc_stats_t *head; rrdc_stats_t *tail; @@ -1405,9 +1406,9 @@ * }}} */ res = NULL; - pthread_mutex_lock (&lock); - status = request ("STATS\n", strlen ("STATS\n"), &res); - pthread_mutex_unlock (&lock); + pthread_mutex_lock (&conn->lock); + status = request (conn, "STATS\n", strlen ("STATS\n"), &res); + pthread_mutex_unlock (&conn->lock); if (status != 0) return (status); @@ -1519,6 +1520,82 @@ } /* while (this != NULL) */ } /* }}} void rrdc_stats_free */ +rrdc_connection_t *new_rrdc_connection(const char *addr) { + rrdc_connection_t *c = malloc(sizeof(rrdc_connection_t)); + if (c == NULL) { + rrd_set_error("out of memory"); + return NULL; + } + + pthread_mutex_init(&c->lock, NULL); + c->sd = -1; + c->sh = NULL; + c->sd_path = NULL; + + if (addr != NULL) { + int status = rrdc_connect(c, addr); + if (status != 0) { + rrd_set_error("Cannot connect to rrdcached '%s'. Please use an " + "appropriate daemon address for the desired operation. " + "This might involve using the --daemon option, setting " + "the environment option '%s' or using a proper " + "rrdfile specification", addr, ENV_RRDCACHED_ADDRESS); + delete_rrdc_connection(c); + return NULL; + } + } + + return c; +} + +void delete_rrdc_connection(rrdc_connection_t *conn) { + if (conn == NULL) return; + rrdc_disconnect(conn); + free(conn); +} + + +const char *want_rrdc_connection(const char *addr) { + if (addr != NULL) return addr; + return getenv(ENV_RRDCACHED_ADDRESS); +} + + +static rrdc_connection_t *global = NULL; + +int setup_global_rrdc_connection(const char *addr) { + if (addr == NULL) { + rrd_set_error("Need proper rrdcached address"); + return -1; + } + + if (global != NULL) { + /* special case: if addr is the same as during the last invocation, reuse + * connection, otherwise close old and create new connection. + */ + if (global->sd >= 0 && global->sd_path != NULL && + strcmp(addr, global->sd_path) == 0) { + return 0; + } + + delete_rrdc_connection(global); + global = NULL; + } + + global = new_rrdc_connection(addr); + if (global == NULL) { + // error already set by new_rrdc_connection + return -1; + } + + return 0; +} + +rrdc_connection_t *get_global_rrdc_connection(void) { + return global; +} + + /* * vim: set sw=2 sts=2 ts=8 et fdm=marker : */ diff --git a/src/rrd_client.h b/src/rrd_client.h --- a/src/rrd_client.h +++ b/src/rrd_client.h @@ -63,17 +63,28 @@ // Windows version has no daemon/client support #ifndef WIN32 -int rrdc_connect (const char *addr); -int rrdc_is_connected(const char *daemon_addr); -int rrdc_disconnect (void); -int rrdc_update (const char *filename, int values_num, +struct rrdc_connection_s { + pthread_mutex_t lock; + int sd; + FILE *sh; + char *sd_path; /* cache the path for sd */ +}; + +typedef struct rrdc_connection_s rrdc_connection_t; + + +int rrdc_connect (rrdc_connection_t *conn, const char *addr); +int rrdc_is_connected(rrdc_connection_t *conn, const char *daemon_addr); +int rrdc_disconnect (rrdc_connection_t *conn); + +int rrdc_update (rrdc_connection_t *conn, const char *filename, int values_num, const char * const *values); -rrd_info_t * rrdc_info (const char *filename); -time_t rrdc_last (const char *filename); -time_t rrdc_first (const char *filename, int rraindex); -int rrdc_create (const char *filename, +rrd_info_t * rrdc_info (rrdc_connection_t *conn, const char *filename); +time_t rrdc_last (rrdc_connection_t *conn, const char *filename); +time_t rrdc_first (rrdc_connection_t *conn, const char *filename, int rraindex); +int rrdc_create (rrdc_connection_t *conn, const char *filename, unsigned long pdp_step, time_t last_up, int no_overwrite, @@ -81,10 +92,10 @@ const char **argv); -int rrdc_flush (const char *filename); -int rrdc_flush_if_daemon (const char *opt_daemon, const char *filename); +int rrdc_flush (rrdc_connection_t *conn, const char *filename); +int rrdc_flush_if_daemon (rrdc_connection_t *conn, const char *opt_daemon, const char *filename); -int rrdc_fetch (const char *filename, +int rrdc_fetch (rrdc_connection_t *conn, const char *filename, const char *cf, time_t *ret_start, time_t *ret_end, unsigned long *ret_step, @@ -92,12 +103,24 @@ char ***ret_ds_names, rrd_value_t **ret_data); + +rrdc_connection_t * new_rrdc_connection(const char *addr); +void delete_rrdc_connection(rrdc_connection_t *conn); + +const char *want_rrdc_connection(const char *addr); + +int setup_global_rrdc_connection(const char *addr); +rrdc_connection_t *get_global_rrdc_connection(void); + #else -# define rrdc_flush_if_daemon(a,b) 0 -# define rrdc_connect(a) 0 +# define rrdc_flush_if_daemon(a,b,c) 0 +# define rrdc_connect(a,b) 0 # define rrdc_is_connected(a) 0 # define rrdc_flush(a) 0 -# define rrdc_update(a,b,c) 0 +# define rrdc_update(a,b,c,d) 0 +# define new_rrdc_connection() 0 +# define delete_rrdc_connection(a) 0 +# define want_rrdc_connection(a) NULL #endif struct rrdc_stats_s @@ -116,7 +139,7 @@ }; typedef struct rrdc_stats_s rrdc_stats_t; -int rrdc_stats_get (rrdc_stats_t **ret_stats); +int rrdc_stats_get (rrdc_connection_t *conn, rrdc_stats_t **ret_stats); void rrdc_stats_free (rrdc_stats_t *ret_stats); #endif /* __RRD_CLIENT_H */ diff --git a/src/rrd_create.c b/src/rrd_create.c --- a/src/rrd_create.c +++ b/src/rrd_create.c @@ -123,17 +123,26 @@ return -1; } - rrdc_connect (opt_daemon); - if (rrdc_is_connected (opt_daemon)) { - rc = rrdc_create (argv[optind], - pdp_step, last_up, opt_no_overwrite, - argc - optind - 1, (const char **) (argv + optind + 1)); - } else { - rc = rrd_create_r2(argv[optind], - pdp_step, last_up, opt_no_overwrite, - argc - optind - 1, (const char **) (argv + optind + 1)); - } + const char *addr = want_rrdc_connection(opt_daemon); + if (addr != NULL) { + rrdc_connection_t *conn = new_rrdc_connection(addr); + if (conn == NULL) { + rc = -1; + goto done; + } + rc = rrdc_create (conn, argv[optind], + pdp_step, last_up, opt_no_overwrite, + argc - optind - 1, (const char **) (argv + optind + 1)); + delete_rrdc_connection(conn); + goto done; + } + + rc = rrd_create_r2(argv[optind], + pdp_step, last_up, opt_no_overwrite, + argc - optind - 1, (const char **) (argv + optind + 1)); +done: + if (opt_daemon != NULL) free(opt_daemon); return rc; } diff --git a/src/rrd_dump.c b/src/rrd_dump.c --- a/src/rrd_dump.c +++ b/src/rrd_dump.c @@ -576,9 +576,15 @@ return (-1); } - rc = rrdc_flush_if_daemon(opt_daemon, argv[optind]); - if (opt_daemon) free(opt_daemon); - if (rc) return (rc); + const char *addr = want_rrdc_connection(opt_daemon); + if (addr != NULL) { + rrdc_connection_t *conn = new_rrdc_connection(addr); + if (conn != NULL) { + rc = rrdc_flush(conn, argv[optind]); + delete_rrdc_connection(conn); + if (rc) goto done; + } + } if ((argc - optind) == 2) { rc = rrd_dump_opt_r(argv[optind], argv[optind + 1], opt_header); @@ -586,5 +592,7 @@ rc = rrd_dump_opt_r(argv[optind], NULL, opt_header); } +done: + if (opt_daemon) free(opt_daemon); return rc; } diff --git a/src/rrd_fetch.c b/src/rrd_fetch.c --- a/src/rrd_fetch.c +++ b/src/rrd_fetch.c @@ -3,7 +3,7 @@ ***************************************************************************** * rrd_fetch.c read date from an rrd to use for further processing ***************************************************************************** - * $Id: rrd_fetch.c 2176 2011-03-03 06:53:05Z oetiker $ + * $Id: rrd_fetch.c 2060 2010-03-29 17:05:33Z oetiker $ * $Log$ * Revision 1.8 2004/05/18 18:53:03 oetiker * big spell checking patch -- s...@bellsouth.net @@ -74,7 +74,7 @@ time_t start_tmp = 0, end_tmp = 0; const char *cf; char *opt_daemon = NULL; - int status; + int status = -1; rrd_time_value_t start_tv, end_tv; char *parsetime_error = NULL; @@ -169,14 +169,22 @@ cf = argv[optind + 1]; - rrdc_connect (opt_daemon); - if (rrdc_is_connected (opt_daemon)) - status = rrdc_fetch (argv[optind], cf, start, end, step, - ds_cnt, ds_namv, data); + const char *addr = want_rrdc_connection(opt_daemon); + if (addr != NULL) { + rrdc_connection_t *conn = new_rrdc_connection(addr); + if (conn != NULL) { + status = rrdc_fetch (conn, argv[optind], cf, start, end, step, + ds_cnt, ds_namv, data); + delete_rrdc_connection(conn); + } + } + else + { + status = rrd_fetch_r(argv[optind], cf, start, end, step, + ds_cnt, ds_namv, data); + } - else - status = rrd_fetch_r(argv[optind], cf, start, end, step, - ds_cnt, ds_namv, data); + if (opt_daemon != NULL) free(opt_daemon); if (status != 0) return (-1); diff --git a/src/rrd_first.c b/src/rrd_first.c --- a/src/rrd_first.c +++ b/src/rrd_first.c @@ -23,6 +23,7 @@ {"daemon", required_argument, 0, 'd'}, {0, 0, 0, 0} }; + time_t result = -1; optind = 0; opterr = 0; /* initialize getopt */ @@ -67,12 +68,19 @@ return -1; } - rrdc_connect (opt_daemon); - if (rrdc_is_connected (opt_daemon)) { - return (rrdc_first (argv[optind], target_rraindex)); - } else { - return (rrd_first_r(argv[optind], target_rraindex)); - } + const char *addr = want_rrdc_connection(opt_daemon); + if (addr != NULL) { + rrdc_connection_t *conn = new_rrdc_connection(addr); + if (conn != NULL) { + result = rrdc_first (conn, argv[optind], target_rraindex); + delete_rrdc_connection(conn); + } + goto done; + } + result = rrd_first_r(argv[optind], target_rraindex); +done: + if (opt_daemon != NULL) free(opt_daemon); + return result; } diff --git a/src/rrd_flushcached.c b/src/rrd_flushcached.c --- a/src/rrd_flushcached.c +++ b/src/rrd_flushcached.c @@ -73,15 +73,8 @@ } /* try to connect to rrdcached */ - status = rrdc_connect(opt_daemon); - if (status != 0) goto out; - - if (! rrdc_is_connected(opt_daemon)) - { - rrd_set_error ("Daemon address unknown. Please use the \"--daemon\" " - "option to set an address on the command line or set the " - "\"%s\" environment variable.", - ENV_RRDCACHED_ADDRESS); + rrdc_connection_t *conn = new_rrdc_connection(opt_daemon); + if (conn == NULL) { status = -1; goto out; } @@ -89,7 +82,7 @@ status = 0; for (i = optind; i < argc; i++) { - status = rrdc_flush(argv[i]); + status = rrdc_flush(conn, argv[i]); if (status) { char *error; @@ -108,6 +101,7 @@ } out: + if (conn != NULL) delete_rrdc_connection(conn); if (opt_daemon) free(opt_daemon); return status; diff --git a/src/rrd_graph.c b/src/rrd_graph.c --- a/src/rrd_graph.c +++ b/src/rrd_graph.c @@ -862,41 +862,40 @@ else rrd_daemon = im->daemon_addr; - /* "daemon" may be NULL. ENV_RRDCACHED_ADDRESS is evaluated in that - * case. If "daemon" holds the same value as in the previous - * iteration, no actual new connection is established - the - * existing connection is re-used. */ - rrdc_connect (rrd_daemon); - - /* If connecting was successfull, use the daemon to query the data. - * If there is no connection, for example because no daemon address - * was specified, (try to) use the local file directly. */ - if (rrdc_is_connected (rrd_daemon)) - { - status = rrdc_fetch (im->gdes[i].rrd, - cf_to_string (im->gdes[i].cf), - &im->gdes[i].start, - &im->gdes[i].end, - &ft_step, - &im->gdes[i].ds_cnt, - &im->gdes[i].ds_namv, - &im->gdes[i].data); - if (status != 0) - return (status); - } - else - { - if ((rrd_fetch_fn(im->gdes[i].rrd, - im->gdes[i].cf, - &im->gdes[i].start, - &im->gdes[i].end, - &ft_step, - &im->gdes[i].ds_cnt, - &im->gdes[i].ds_namv, - &im->gdes[i].data)) == -1) { - return -1; + const char *addr = want_rrdc_connection(rrd_daemon); + if (addr != NULL) { + rrdc_connection_t *conn = new_rrdc_connection(addr); + if (conn != NULL) { + status = rrdc_fetch (conn, im->gdes[i].rrd, + cf_to_string (im->gdes[i].cf), + &im->gdes[i].start, + &im->gdes[i].end, + &ft_step, + &im->gdes[i].ds_cnt, + &im->gdes[i].ds_namv, + &im->gdes[i].data); + + delete_rrdc_connection(conn); + + if (status != 0) + return (status); + + } else { + // try to read data locally } } + + if ((rrd_fetch_fn(im->gdes[i].rrd, + im->gdes[i].cf, + &im->gdes[i].start, + &im->gdes[i].end, + &ft_step, + &im->gdes[i].ds_cnt, + &im->gdes[i].ds_namv, + &im->gdes[i].data)) == -1) { + return -1; + } + im->gdes[i].data_first = 1; if (ft_step < im->gdes[i].step) { diff --git a/src/rrd_info.c b/src/rrd_info.c --- a/src/rrd_info.c +++ b/src/rrd_info.c @@ -141,18 +141,31 @@ return (NULL); } - if( flushfirst ) { - status = rrdc_flush_if_daemon(opt_daemon, argv[optind]); - if (status) return (NULL); + const char *addr = want_rrdc_connection(opt_daemon); + rrdc_connection_t *conn = NULL; + + if (addr != NULL) { + conn = new_rrdc_connection(addr); + if (conn == NULL) { + return NULL; + } } - rrdc_connect (opt_daemon); - if (rrdc_is_connected (opt_daemon)) - info = rrdc_info (argv[optind]); + if( flushfirst && conn != NULL) { + status = rrdc_flush(conn, argv[optind]); + if (status) return (NULL); + } + + if (conn != NULL) { + info = rrdc_info (conn, argv[optind]); + } else - info = rrd_info_r(argv[optind]); + info = rrd_info_r(argv[optind]); if (opt_daemon) free(opt_daemon); + if (conn != NULL) { + delete_rrdc_connection(conn); + } return (info); } /* rrd_info_t *rrd_info */ diff --git a/src/rrd_last.c b/src/rrd_last.c --- a/src/rrd_last.c +++ b/src/rrd_last.c @@ -14,7 +14,7 @@ char **argv) { char *opt_daemon = NULL; - time_t lastupdate; + time_t lastupdate = -1; optind = 0; opterr = 0; /* initialize getopt */ @@ -58,10 +58,14 @@ return (-1); } - rrdc_connect (opt_daemon); - if (rrdc_is_connected (opt_daemon)) - lastupdate = rrdc_last (argv[optind]); - + const char *addr = want_rrdc_connection(opt_daemon); + if (addr != NULL) { + rrdc_connection_t *conn = new_rrdc_connection(addr); + if (conn != NULL) { + lastupdate = rrdc_last (conn, argv[optind]); + delete_rrdc_connection(conn); + } + } else lastupdate = rrd_last_r(argv[optind]); diff --git a/src/rrd_lastupdate.c b/src/rrd_lastupdate.c --- a/src/rrd_lastupdate.c +++ b/src/rrd_lastupdate.c @@ -16,7 +16,7 @@ char **ds_names; char **last_ds; unsigned long ds_count, i; - int status; + int status = 0; char *opt_daemon = NULL; @@ -62,7 +62,14 @@ return (-1); } - status = rrdc_flush_if_daemon(opt_daemon, argv[optind]); + const char *addr = want_rrdc_connection(opt_daemon); + if (addr != NULL) { + rrdc_connection_t *conn = new_rrdc_connection(addr); + if (conn != NULL) { + status = rrdc_flush (conn, argv[optind]); + delete_rrdc_connection(conn); + } + } if (opt_daemon) free (opt_daemon); if (status) return (-1); diff --git a/src/rrd_update.c b/src/rrd_update.c --- a/src/rrd_update.c +++ b/src/rrd_update.c @@ -389,6 +389,8 @@ char *tmplt = NULL; int rc = -1; char *opt_daemon = NULL; + rrdc_connection_t *conn = NULL; + const char *addr = NULL; optind = 0; opterr = 0; /* initialize getopt */ @@ -427,29 +429,32 @@ goto out; } - { /* try to connect to rrdcached */ - int status = rrdc_connect(opt_daemon); - if (status != 0) { - rc = status; - goto out; - } + + addr = want_rrdc_connection(opt_daemon); + + if (addr != NULL) { + conn = new_rrdc_connection(addr); + if (conn == NULL) { + rc = -1; + goto out; + } } - if ((tmplt != NULL) && rrdc_is_connected(opt_daemon)) + if ((tmplt != NULL) && conn != NULL) { rrd_set_error("The caching daemon cannot be used together with " "templates yet."); goto out; } - if (! rrdc_is_connected(opt_daemon)) + if (conn == NULL) { rc = rrd_update_r(argv[optind], tmplt, argc - optind - 1, (const char **) (argv + optind + 1)); } else /* we are connected */ { - rc = rrdc_update (argv[optind], /* file */ + rc = rrdc_update (conn, argv[optind], /* file */ argc - optind - 1, /* values_num */ (const char *const *) (argv + optind + 1)); /* values */ if (rc > 0) @@ -468,6 +473,10 @@ free (opt_daemon); opt_daemon = NULL; } + if (conn != NULL) { + delete_rrdc_connection(conn); + conn = NULL; + } return rc; } diff --git a/src/rrd_xport.c b/src/rrd_xport.c --- a/src/rrd_xport.c +++ b/src/rrd_xport.c @@ -167,9 +167,12 @@ return (-1); } - { /* try to connect to rrdcached */ - int status = rrdc_connect(im.daemon_addr); - if (status != 0) return status; + const char *addr = want_rrdc_connection(im.daemon_addr); + if (addr != NULL) { /* try to connect to rrdcached */ + rrdc_connection_t *conn = new_rrdc_connection(addr); + if (conn == NULL) { + return -1; + } } if (rrd_xport_fn(&im, start, end, step, col_cnt, legend_v, data) == -1) { _______________________________________________ rrd-developers mailing list rrd-developers@lists.oetiker.ch https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers