X-Git-Url: https://git.octo.it/?a=blobdiff_plain;ds=inline;f=src%2Frrd_daemon.c;h=1a20974d2e46c848da9d12580110b7c6dac00627;hb=154355b6ff56aefb6a1062134aadfa2aaab3a38c;hp=bfcf6a3ce4f7ed1d8da75695264e248a4e075cbc;hpb=e5b05bec82bbff5db8add4e58dd6f0fcf2670291;p=rrdtool.git diff --git a/src/rrd_daemon.c b/src/rrd_daemon.c index bfcf6a3..1a20974 100644 --- a/src/rrd_daemon.c +++ b/src/rrd_daemon.c @@ -71,7 +71,7 @@ #endif #endif -#include "rrd.h" +#include "rrd_tool.h" #include "rrd_client.h" #include "unused.h" @@ -109,6 +109,10 @@ #include #include +#ifdef HAVE_LIBWRAP +#include +#endif /* HAVE_LIBWRAP */ + #include /* }}} */ @@ -275,7 +279,7 @@ static uint64_t stats_journal_bytes = 0; static uint64_t stats_journal_rotate = 0; static pthread_mutex_t stats_lock = PTHREAD_MUTEX_INITIALIZER; -static int opt_no_overwrite = 0; +static int opt_no_overwrite = 0; /* default for the daemon */ /* Journaled updates */ #define JOURNAL_REPLAY(s) ((s) == NULL) @@ -1701,7 +1705,7 @@ static int handle_request_info (HANDLER_PROTO) /* {{{ */ { char *file, file_tmp[PATH_MAX]; int status; - rrd_info_t *data; + rrd_info_t *info; /* obtain filename */ status = buffer_get_field(&buffer, &buffer_size, &file); @@ -1714,11 +1718,11 @@ static int handle_request_info (HANDLER_PROTO) /* {{{ */ } /* get data */ rrd_clear_error (); - data = rrd_info_r(file); - if(!data) { + info = rrd_info_r(file); + if(!info) { return send_response(sock, RESP_ERR, "RRD Error: %s\n", rrd_get_error()); } - while (data) { + for (rrd_info_t *data = info; data != NULL; data = data->next) { switch (data->type) { case RD_I_VAL: if (isnan(data->value.u_val)) @@ -1739,8 +1743,10 @@ static int handle_request_info (HANDLER_PROTO) /* {{{ */ add_response_info(sock,"%s %d %lu\n", data->key, data->type, data->value.u_blo.size); break; } - data = data->next; } + + rrd_info_free(info); + return send_response(sock, RESP_OK, "Info for %s follows\n",file); } /* }}} static int handle_request_info */ @@ -1776,13 +1782,17 @@ static int handle_request_first (HANDLER_PROTO) /* {{{ */ return send_response(sock, RESP_ERR, "RRD Error: %s\n", rrd_get_error()); } return send_response(sock, RESP_OK, "%lu\n",(unsigned)t); -} /* }}} static int handle_request_last */ +} /* }}} static int handle_request_first */ + static int handle_request_last (HANDLER_PROTO) /* {{{ */ { char *file, file_tmp[PATH_MAX]; int status; - time_t t; + time_t t, from_file, step; + rrd_file_t * rrd_file; + cache_item_t * ci; + rrd_t rrd; /* obtain filename */ status = buffer_get_field(&buffer, &buffer_size, &file); @@ -1793,12 +1803,27 @@ static int handle_request_last (HANDLER_PROTO) /* {{{ */ if (!check_file_access(file, sock)) { return send_response(sock, RESP_ERR, "Cannot read: %s\n", file); } - /* get data */ - rrd_clear_error (); - t = rrd_last_r(file); - if(t<1) { + rrd_clear_error(); + rrd_init(&rrd); + rrd_file = rrd_open(file,&rrd,RRD_READONLY); + if(!rrd_file) { return send_response(sock, RESP_ERR, "RRD Error: %s\n", rrd_get_error()); } + from_file = rrd.live_head->last_up; + step = rrd.stat_head->pdp_step; + rrd_close(rrd_file); + pthread_mutex_lock(&cache_lock); + ci = g_tree_lookup(cache_tree, file); + if (ci) + t = ci->last_update_stamp; + else + t = from_file; + pthread_mutex_unlock(&cache_lock); + t -= t % step; + rrd_free(&rrd); + if(t<1) { + return send_response(sock, RESP_ERR, "Error: rrdcached: Invalid timestamp returned\n"); + } return send_response(sock, RESP_OK, "%lu\n",(unsigned)t); } /* }}} static int handle_request_last */ @@ -1809,10 +1834,8 @@ static int handle_request_create (HANDLER_PROTO) /* {{{ */ int ac = 0; char *av[128]; int status; - ulong step = 300; + unsigned long step = 300; time_t last_up = time(NULL)-10; - rrd_time_value_t last_up_tv; - char *parsetime_error = NULL; int no_overwrite = opt_no_overwrite; @@ -1827,19 +1850,11 @@ static int handle_request_create (HANDLER_PROTO) /* {{{ */ } RRDD_LOG(LOG_INFO, "rrdcreate request for %s",file); - status = buffer_get_field(&buffer, &buffer_size, &tok ); - for(;(tok && !status);status = buffer_get_field(&buffer, &buffer_size, &tok )) { + while ((status = buffer_get_field(&buffer, &buffer_size, &tok)) == 0 && tok) { if( ! strncmp(tok,"-b",2) ) { status = buffer_get_field(&buffer, &buffer_size, &tok ); if (status != 0) return syntax_error(sock,cmd); - if ((parsetime_error = rrd_parsetime(tok, &last_up_tv))) - return send_response(sock, RESP_ERR, "start time: %s\n", parsetime_error); - if (last_up_tv.type == RELATIVE_TO_END_TIME || - last_up_tv.type == RELATIVE_TO_START_TIME) { - return send_response(sock, RESP_ERR, "Cannot specify time relative to start or end here.\n"); - } - last_up = mktime(&last_up_tv.tm) +last_up_tv.offset; - + last_up = (time_t) atol(tok); continue; } if( ! strncmp(tok,"-s",2) ) { @@ -1863,9 +1878,8 @@ static int handle_request_create (HANDLER_PROTO) /* {{{ */ return send_response(sock, RESP_ERR, "The first entry must be after 1980.\n"); } - rrd_create_set_no_overwrite(no_overwrite); rrd_clear_error (); - status = rrd_create_r(file,step,last_up,ac,(const char **)av); + status = rrd_create_r2(file,step,last_up,no_overwrite,ac,(const char **)av); if(!status) { return send_response(sock, RESP_OK, "RRD created OK\n"); @@ -2062,6 +2076,8 @@ static command_t list_of_commands[] = { /* {{{ */ "CREATE [-b start] [-s step] [-O] \n", "The CREATE command will create an RRD file, overwriting any existing file\n" "unless the -O option is given or rrdcached was started with the -O option.\n" + "The start parameter needs to be in seconds since 1/1/70 (AT-style syntax is\n" + "not acceptable) and the step is in seconds (default is 300).\n" "The DS and RRA definitions are as for the 'rrdtool create' command.\n" }, { @@ -2152,6 +2168,15 @@ static void socket_permission_copy (listen_socket_t *dest, /* {{{ */ dest->permissions = src->permissions; } /* }}} socket_permission_copy */ +static void socket_permission_set_all (listen_socket_t *sock) /* {{{ */ +{ + size_t i; + + sock->permissions = 0; + for (i = 0; i < list_of_commands_len; i++) + sock->permissions |= (1 << i); +} /* }}} void socket_permission_set_all */ + /* check whether commands are received in the expected context */ static int command_check_context(listen_socket_t *sock, command_t *cmd) { @@ -2624,6 +2649,21 @@ static void *connection_thread_main (void *args) /* {{{ */ } pthread_mutex_lock (&connection_threads_lock); +#ifdef HAVE_LIBWRAP + /* LIBWRAP does not support multiple threads! By putting this code + inside pthread_mutex_lock we do not have to worry about request_info + getting overwritten by another thread. + */ + struct request_info req; + request_init(&req, RQ_DAEMON, "rrdcache\0", RQ_FILE, fd, NULL ); + fromhost(&req); + if(!hosts_access(&req)) { + RRDD_LOG(LOG_INFO, "refused connection from %s", eval_client(&req)); + pthread_mutex_unlock (&connection_threads_lock); + close_connection(sock); + return NULL; + } +#endif /* HAVE_LIBWRAP */ connection_threads_num++; pthread_mutex_unlock (&connection_threads_lock); @@ -3100,6 +3140,10 @@ static int daemonize (void) /* {{{ */ strncpy(default_socket.addr, RRDCACHED_DEFAULT_ADDRESS, sizeof(default_socket.addr) - 1); default_socket.addr[sizeof(default_socket.addr) - 1] = '\0'; + + if (default_socket.permissions == 0) + socket_permission_set_all (&default_socket); + open_listen_socket (&default_socket); } @@ -3244,18 +3288,7 @@ static int read_options (int argc, char **argv) /* {{{ */ else /* if (default_socket.permissions == 0) */ { /* Add permission for ALL commands to the socket. */ - size_t i; - for (i = 0; i < list_of_commands_len; i++) - { - status = socket_permission_add (new, list_of_commands[i].cmd); - if (status != 0) - { - fprintf (stderr, "read_options: Adding permission \"%s\" to " - "socket failed. This should never happen, ever! Sorry.\n", - list_of_commands[i].cmd); - status = 4; - } - } + socket_permission_set_all (new); } /* }}} Done adding permissions. */ @@ -3542,6 +3575,7 @@ static int read_options (int argc, char **argv) /* {{{ */ "\n" "Valid options are:\n" " -l
Socket address to listen to.\n" + " Default: "RRDCACHED_DEFAULT_ADDRESS"\n" " -P Sets the permissions to assign to all following " "sockets\n" " -w Interval in which to write data.\n"