[rrd-developers] [PATCH 1 of 7] * Introduce rrdc_connection_t
Peter Stamfest
peter at stamfest.at
Mon Mar 7 20:28:03 CET 2011
# HG changeset patch
# User Peter Stamfest <peter at 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 -- slif at 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) {
More information about the rrd-developers
mailing list