Hello,
Here are updated patches for rrdtool/rrd_client.c and
rrdtool/rrd_daemon.c. We had some discussions in August last year. I
created a branch and the diffs are against latest git. I've run the
code, especially rrd_daemon with valgrind under Linux, but need some
help to check that also rrd_client works OK (maybe rrd_daemon too). Can
you help me with test cases to run the execute the code modified paths.
I know one application using rrdtool, lm-sensors (build-dependency on
librrd2-dev), but am not sure my computers have the sensors to be a good
test case.
Note that the modified functions get_path() and get_abs_path() are
static, so they don't change the API.
Thanks,
Svante Signell
--- a/src/rrd_daemon.c
+++ b/src/rrd_daemon.c
@@ -125,7 +125,7 @@ typedef enum { RESP_ERR = -1, RESP_OK =
struct listen_socket_s
{
int fd;
- char addr[PATH_MAX + 1];
+ char *addr;
int family;
/* state for BATCH processing */
@@ -1159,23 +1159,28 @@ err:
} /* }}} static int check_file_access */
/* when using a base dir, convert relative paths to absolute paths.
- * if necessary, modifies the "filename" pointer to point
- * to the new path created in "tmp". "tmp" is provided
- * by the caller and sizeof(tmp) must be >= PATH_MAX.
+ * if necessary, modify the "filename" pointer to point
+ * to the new path created in "tmp". "tmp" is malloced
+ * and freed by the called function.
*
+ * FIXME: Check this!
* this allows us to optimize for the expected case (absolute path)
* with a no-op.
*/
-static void get_abs_path(char **filename, char *tmp)
+static void get_abs_path(char **filename)
{
- assert(tmp != NULL);
+ char *tmp = NULL;
+ int len = 0;
assert(filename != NULL && *filename != NULL);
if (config_base_dir == NULL || **filename == '/')
return;
- snprintf(tmp, PATH_MAX, "%s/%s", config_base_dir, *filename);
+ len = strlen(config_base_dir) + 1 + strlen(*filename) + 1;
+ tmp = malloc(len);
+ snprintf(tmp, len, "%s/%s", config_base_dir, *filename);
*filename = tmp;
+ free(tmp);
} /* }}} static int get_abs_path */
static int flush_file (const char *filename) /* {{{ */
@@ -1266,7 +1271,7 @@ static int handle_request_stats (HANDLER
static int handle_request_flush (HANDLER_PROTO) /* {{{ */
{
- char *file, file_tmp[PATH_MAX];
+ char *file;
int status;
status = buffer_get_field (&buffer, &buffer_size, &file);
@@ -1280,7 +1285,7 @@ static int handle_request_flush (HANDLER
stats_flush_received++;
pthread_mutex_unlock(&stats_lock);
- get_abs_path(&file, file_tmp);
+ get_abs_path(&file);
if (!check_file_access(file, sock)) return 0;
status = flush_file (file);
@@ -1321,14 +1326,14 @@ static int handle_request_flushall(HANDL
static int handle_request_pending(HANDLER_PROTO) /* {{{ */
{
int status;
- char *file, file_tmp[PATH_MAX];
+ char *file;
cache_item_t *ci;
status = buffer_get_field(&buffer, &buffer_size, &file);
if (status != 0)
return syntax_error(sock,cmd);
- get_abs_path(&file, file_tmp);
+ get_abs_path(&file);
pthread_mutex_lock(&cache_lock);
ci = g_tree_lookup(cache_tree, file);
@@ -1349,13 +1354,13 @@ static int handle_request_forget(HANDLER
{
int status;
gboolean found;
- char *file, file_tmp[PATH_MAX];
+ char *file;
status = buffer_get_field(&buffer, &buffer_size, &file);
if (status != 0)
return syntax_error(sock,cmd);
- get_abs_path(&file, file_tmp);
+ get_abs_path(&file);
if (!check_file_access(file, sock)) return 0;
pthread_mutex_lock(&cache_lock);
@@ -1396,7 +1401,7 @@ static int handle_request_queue (HANDLER
static int handle_request_update (HANDLER_PROTO) /* {{{ */
{
- char *file, file_tmp[PATH_MAX];
+ char *file;
int values_num = 0;
int status;
char orig_buf[RRD_CMD_MAX];
@@ -1415,7 +1420,7 @@ static int handle_request_update (HANDLE
stats_updates_received++;
pthread_mutex_unlock(&stats_lock);
- get_abs_path(&file, file_tmp);
+ get_abs_path(&file);
if (!check_file_access(file, sock)) return 0;
pthread_mutex_lock (&cache_lock);
@@ -1558,7 +1563,7 @@ static int handle_request_update (HANDLE
static int handle_request_fetch (HANDLER_PROTO) /* {{{ */
{
- char *file, file_tmp[PATH_MAX];
+ char *file;
char *cf;
char *start_str;
@@ -1612,7 +1617,7 @@ static int handle_request_fetch (HANDLER
if (status != 0)
return (syntax_error(sock,cmd));
- get_abs_path(&file, file_tmp);
+ get_abs_path(&file);
if (!check_file_access(file, sock)) return 0;
status = flush_file (file);
@@ -1776,7 +1781,7 @@ static int handle_request_wrote (HANDLER
static int handle_request_info (HANDLER_PROTO) /* {{{ */
{
- char *file, file_tmp[PATH_MAX];
+ char *file;
int status;
rrd_info_t *info;
@@ -1785,7 +1790,7 @@ static int handle_request_info (HANDLER_
if (status != 0)
return syntax_error(sock,cmd);
/* get full pathname */
- get_abs_path(&file, file_tmp);
+ get_abs_path(&file);
if (!check_file_access(file, sock)) {
return send_response(sock, RESP_ERR, "Cannot read: %s\n", file);
}
@@ -1825,7 +1830,7 @@ static int handle_request_info (HANDLER_
static int handle_request_first (HANDLER_PROTO) /* {{{ */
{
- char *i, *file, file_tmp[PATH_MAX];
+ char *i, *file;
int status;
int idx;
time_t t;
@@ -1835,7 +1840,7 @@ static int handle_request_first (HANDLER
if (status != 0)
return syntax_error(sock,cmd);
/* get full pathname */
- get_abs_path(&file, file_tmp);
+ get_abs_path(&file);
if (!check_file_access(file, sock)) {
return send_response(sock, RESP_ERR, "Cannot read: %s\n", file);
}
@@ -1860,7 +1865,7 @@ static int handle_request_first (HANDLER
static int handle_request_last (HANDLER_PROTO) /* {{{ */
{
- char *file, file_tmp[PATH_MAX];
+ char *file;
int status;
time_t t, from_file, step;
rrd_file_t * rrd_file;
@@ -1872,7 +1877,7 @@ static int handle_request_last (HANDLER_
if (status != 0)
return syntax_error(sock,cmd);
/* get full pathname */
- get_abs_path(&file, file_tmp);
+ get_abs_path(&file);
if (!check_file_access(file, sock)) {
return send_response(sock, RESP_ERR, "Cannot read: %s\n", file);
}
@@ -1902,8 +1907,8 @@ static int handle_request_last (HANDLER_
static int handle_request_create (HANDLER_PROTO) /* {{{ */
{
- char *file, file_tmp[PATH_MAX];
- char *file_copy, *dir, *dir_tmp[PATH_MAX];
+ char *file;
+ char *file_copy, *dir, *dir_tmp;
struct stat st;
char *tok;
int ac = 0;
@@ -1919,7 +1924,7 @@ static int handle_request_create (HANDLE
if (status != 0)
return syntax_error(sock,cmd);
/* get full pathname */
- get_abs_path(&file, file_tmp);
+ get_abs_path(&file);
file_copy = strdup(file);
if (file_copy == NULL) {
@@ -1932,7 +1937,8 @@ static int handle_request_create (HANDLE
pthread_mutex_lock(&rrdfilecreate_lock);
dir = dirname(file_copy);
- if (realpath(dir, dir_tmp) == NULL && errno == ENOENT) {
+ dir_tmp = realpath(dir, NULL);
+ if (dir_tmp == NULL && errno == ENOENT) {
if (!config_allow_recursive_mkdir) {
return send_response(sock, RESP_ERR,
"No permission to recursively create: %s\nDid you pass -R to the daemon?\n",
@@ -2401,8 +2407,8 @@ static void journal_close(void) /* {{{ *
static void journal_new_file(void) /* {{{ */
{
struct timeval now;
- int new_fd;
- char new_file[PATH_MAX + 1];
+ int new_fd, len;
+ char *new_file = NULL;
assert(journal_dir != NULL);
assert(journal_cur != NULL);
@@ -2411,7 +2417,9 @@ static void journal_new_file(void) /* {{
gettimeofday(&now, NULL);
/* this format assures that the files sort in strcmp() order */
- snprintf(new_file, PATH_MAX, "%s/%s.%010d.%06d",
+ len = strlen(journal_dir) + 1 + strlen(JOURNAL_BASE) + 10 + 6 + 1;
+ new_file = malloc(len);
+ snprintf(new_file, len, "%s/%s.%010d.%06d",
journal_dir, JOURNAL_BASE, (int)now.tv_sec, (int)now.tv_usec);
new_fd = open(new_file, O_WRONLY|O_CREAT|O_APPEND,
@@ -2429,6 +2437,7 @@ static void journal_new_file(void) /* {{
/* record the file in the journal set */
rrd_add_strdup(&journal_cur->files, &journal_cur->files_num, new_file);
+ free(new_file);
return;
error:
@@ -2438,6 +2447,7 @@ error:
RRDD_LOG(LOG_CRIT,
"JOURNALING DISABLED: All values will be flushed at shutdown");
+ free(new_file);
close(new_fd);
config_flush_at_shutdown = 1;
@@ -2500,7 +2510,6 @@ static void journal_done(void) /* {{{ */
journal_set_free(journal_cur);
journal_set_free(journal_old);
- free(journal_dir);
} /* }}} static void journal_done */
@@ -2634,10 +2643,10 @@ static int journal_sort(const void *v1,
static void journal_init(void) /* {{{ */
{
- int had_journal = 0;
+ int had_journal = 0, len = 0;
DIR *dir;
struct dirent *dent;
- char path[PATH_MAX+1];
+ char *path = NULL;
if (journal_dir == NULL) return;
@@ -2656,19 +2665,27 @@ static void journal_init(void) /* {{{ */
* correct sort order. TODO: remove after first release
*/
{
- char old_path[PATH_MAX+1];
- snprintf(old_path, PATH_MAX, "%s/%s", journal_dir, JOURNAL_BASE ".old" );
- snprintf(path, PATH_MAX, "%s/%s", journal_dir, JOURNAL_BASE ".0000");
+ char *old_path = NULL;
+ if (journal_dir != NULL) {
+ len = strlen(journal_dir) + 1 + strlen(JOURNAL_BASE) + 5 + 1;
+ old_path = malloc(len);
+ path = malloc(len);
+ snprintf(old_path, len, "%s/%s", journal_dir, JOURNAL_BASE ".old" );
+ snprintf(path, len, "%s/%s", journal_dir, JOURNAL_BASE ".0000");
rename(old_path, path);
- snprintf(old_path, PATH_MAX, "%s/%s", journal_dir, JOURNAL_BASE );
- snprintf(path, PATH_MAX, "%s/%s", journal_dir, JOURNAL_BASE ".0001");
+ snprintf(old_path, len, "%s/%s", journal_dir, JOURNAL_BASE );
+ snprintf(path, len, "%s/%s", journal_dir, JOURNAL_BASE ".0001");
rename(old_path, path);
+ free(old_path);
+ }
}
+ /* FIXME: Check all free(path) !! */
dir = opendir(journal_dir);
if (!dir) {
RRDD_LOG(LOG_CRIT, "journal_init: opendir(%s) failed\n", journal_dir);
+ free(path);
return;
}
while ((dent = readdir(dir)) != NULL)
@@ -2677,15 +2694,20 @@ static void journal_init(void) /* {{{ */
if (strncmp(dent->d_name, JOURNAL_BASE, strlen(JOURNAL_BASE)))
continue;
- snprintf(path, PATH_MAX, "%s/%s", journal_dir, dent->d_name);
+ len = strlen(journal_dir) + 1 + strlen(dent->d_name) + 1;
+ path = realloc(path, len);
+ snprintf(path, len, "%s/%s", journal_dir, dent->d_name);
if (!rrd_add_strdup(&journal_cur->files, &journal_cur->files_num, path))
{
RRDD_LOG(LOG_CRIT, "journal_init: cannot add journal file %s!",
dent->d_name);
+ free(path);
break;
}
+ free(path);
}
+ free(path);
closedir(dir);
qsort(journal_cur->files, journal_cur->files_num,
@@ -2712,6 +2734,7 @@ static void free_listen_socket(listen_so
free(sock->rbuf); sock->rbuf = NULL;
free(sock->wbuf); sock->wbuf = NULL;
+ free(sock->addr); sock->addr = NULL;
free(sock);
} /* }}} void free_listen_socket */
@@ -2841,6 +2864,8 @@ out_close:
static int open_listen_socket_unix (const listen_socket_t *sock) /* {{{ */
{
+ // FIXME
+ //int fd, len;
int fd;
struct sockaddr_un sa;
listen_socket_t *temp;
@@ -2868,8 +2893,8 @@ static int open_listen_socket_unix (cons
dir, rrd_strerror(errno));
return (-1);
}
-
- free(path_copy);
+ // FIXME
+ //free(path_copy);
temp = (listen_socket_t *) rrd_realloc (listen_fds,
sizeof (listen_fds[0]) * (listen_fds_num + 1));
@@ -2937,8 +2962,11 @@ static int open_listen_socket_unix (cons
listen_fds[listen_fds_num].fd = fd;
listen_fds[listen_fds_num].family = PF_UNIX;
- strncpy(listen_fds[listen_fds_num].addr, path,
- sizeof (listen_fds[listen_fds_num].addr) - 1);
+ // FIXME
+ //len = strlen(path) + 1;
+ //listen_fds[listen_fds_num].addr = malloc(len);
+ strcpy(listen_fds[listen_fds_num].addr, path_copy);
+ free(path_copy);
listen_fds_num++;
return (0);
@@ -3152,9 +3180,9 @@ static void open_listen_sockets_traditio
}
else
{
- strncpy(default_socket.addr, RRDCACHED_DEFAULT_ADDRESS,
- sizeof(default_socket.addr) - 1);
- default_socket.addr[sizeof(default_socket.addr) - 1] = '\0';
+ int len = strlen(RRDCACHED_DEFAULT_ADDRESS) + 1;
+ default_socket.addr = malloc(len);
+ strcpy(default_socket.addr, RRDCACHED_DEFAULT_ADDRESS);
if (default_socket.permissions == 0)
socket_permission_set_all (&default_socket);
@@ -3173,6 +3201,8 @@ static int close_listen_sockets (void) /
if (listen_fds[i].family == PF_UNIX)
unlink(listen_fds[i].addr);
+ // FIXME
+ free (listen_fds[i].addr);
}
free (listen_fds);
@@ -3394,6 +3424,9 @@ static int cleanup (void) /* {{{ */
free(queue_threads);
free(config_base_dir);
+ // FIXME: Put at the right place
+ // see free_listen_sockets(listen_fds):
+ //free(default_socket.addr);
pthread_mutex_lock(&cache_lock);
g_tree_destroy(cache_tree);
@@ -3434,7 +3467,9 @@ static int read_options (int argc, char
case 'l':
{
+ // FIXME: struct member being malloced
listen_socket_t *new;
+ int len;
new = malloc(sizeof(listen_socket_t));
if (new == NULL)
@@ -3444,7 +3479,15 @@ static int read_options (int argc, char
}
memset(new, 0, sizeof(listen_socket_t));
- strncpy(new->addr, optarg, sizeof(new->addr)-1);
+ len = strlen(optarg) + 1;
+ // FIXME: Find out where to free new->addr and new
+ new->addr = malloc(len);
+ if (new->addr == NULL)
+ {
+ fprintf(stderr, "read_options: malloc failed.\n");
+ return(2);
+ }
+ strcpy(new->addr, optarg);
/* Add permissions to the socket {{{ */
if (default_socket.permissions != 0)
@@ -3465,8 +3508,15 @@ static int read_options (int argc, char
&config_listen_address_list_len, new))
{
fprintf(stderr, "read_options: rrd_add_ptr failed.\n");
+ // FIXME
+ //free(new->addr);
+ //free(new);
return (2);
}
+ // FIXME: This removes unix:... in open_listen_socket_unix
+ // FIXME: This makes vagrind unhappy
+ //free(new->addr);
+ //free(new);
}
break;
@@ -3618,7 +3668,7 @@ static int read_options (int argc, char
case 'b':
{
size_t len;
- char base_realpath[PATH_MAX];
+ char *base_realpath = NULL;
if (config_base_dir != NULL)
free (config_base_dir);
@@ -3641,7 +3691,7 @@ static int read_options (int argc, char
* assumptions possible (we don't have to resolve paths
* that start with a "/")
*/
- if (realpath(config_base_dir, base_realpath) == NULL)
+ if ((base_realpath = realpath(config_base_dir, NULL)) == NULL)
{
fprintf (stderr, "Failed to canonicalize the base directory '%s': "
"%s\n", config_base_dir, rrd_strerror(errno));
@@ -3671,15 +3721,17 @@ static int read_options (int argc, char
}
if (strncmp(config_base_dir,
- base_realpath, sizeof(base_realpath)) != 0)
+ base_realpath, len) != 0)
{
fprintf(stderr,
"Base directory (-b) resolved via file system links!\n"
"Please consult rrdcached '-b' documentation!\n"
"Consider specifying the real directory (%s)\n",
base_realpath);
+ free(base_realpath);
return 5;
}
+ free(base_realpath);
}
break;
@@ -3702,8 +3754,7 @@ static int read_options (int argc, char
case 'j':
{
- char journal_dir_actual[PATH_MAX];
- journal_dir = realpath((const char *)optarg, journal_dir_actual);
+ journal_dir = realpath((const char *)optarg, NULL);
if (journal_dir)
{
// if we were able to properly resolve the path, lets have a copy
@@ -3714,17 +3765,20 @@ static int read_options (int argc, char
{
fprintf(stderr, "Failed to create journal directory '%s': %s\n",
journal_dir, rrd_strerror(errno));
+ free(journal_dir);
return 6;
}
if (access(journal_dir, R_OK|W_OK|X_OK) != 0)
{
fprintf(stderr, "Must specify a writable directory with -j! (%s)\n",
errno ? rrd_strerror(errno) : "");
+ free(journal_dir);
return 6;
}
} else {
fprintf(stderr, "Unable to resolve journal path (%s,%s)\n", optarg,
errno ? rrd_strerror(errno) : "");
+ free(journal_dir);
return 6;
}
}
--- a/src/rrd_client.c
+++ b/src/rrd_client.c
@@ -81,12 +81,12 @@ static size_t inbuf_used = 0;
* 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 (const char *path) /* {{{ */
{
const char *ret = path;
int is_unix = 0;
- if ((path == NULL) || (resolved_path == NULL) || (sd_path == NULL))
+ if ((path == NULL) || (sd_path == NULL))
return (NULL);
if ((*sd_path == '/')
@@ -95,7 +95,7 @@ static const char *get_path (const char
if (is_unix)
{
- ret = realpath(path, resolved_path);
+ ret = realpath(path, NULL);
if (ret == NULL)
rrd_set_error("realpath(%s): %s", path, rrd_strerror(errno));
return ret;
@@ -840,7 +840,6 @@ int rrdc_update (const char *filename, i
rrdc_response_t *res;
int status;
int i;
- char file_path[PATH_MAX];
memset (buffer, 0, sizeof (buffer));
buffer_ptr = &buffer[0];
@@ -851,7 +850,7 @@ int rrdc_update (const char *filename, i
return (ENOBUFS);
mutex_lock (&lock);
- filename = get_path (filename, file_path);
+ filename = get_path (filename);
if (filename == NULL)
{
mutex_unlock (&lock);
@@ -902,7 +901,6 @@ static int rrdc_filebased_command (const
size_t buffer_size;
rrdc_response_t *res;
int status;
- char file_path[PATH_MAX];
if (filename == NULL)
return (-1);
@@ -916,7 +914,7 @@ static int rrdc_filebased_command (const
return (ENOBUFS);
mutex_lock (&lock);
- filename = get_path (filename, file_path);
+ filename = get_path (filename);
if (filename == NULL)
{
mutex_unlock (&lock);
@@ -964,7 +962,6 @@ rrd_info_t * rrdc_info (const char *file
size_t buffer_size;
rrdc_response_t *res;
int status;
- char file_path[PATH_MAX];
rrd_info_t *data = NULL, *cd;
rrd_infoval_t info;
unsigned int l;
@@ -987,7 +984,7 @@ rrd_info_t * rrdc_info (const char *file
}
mutex_lock (&lock);
- filename = get_path (filename, file_path);
+ filename = get_path (filename);
if (filename == NULL)
{
mutex_unlock (&lock);
@@ -1064,7 +1061,6 @@ time_t rrdc_last (const char *filename)
size_t buffer_size;
rrdc_response_t *res;
int status;
- char file_path[PATH_MAX];
time_t lastup;
if (filename == NULL) {
@@ -1083,7 +1079,7 @@ time_t rrdc_last (const char *filename)
}
mutex_lock (&lock);
- filename = get_path (filename, file_path);
+ filename = get_path (filename);
if (filename == NULL)
{
mutex_unlock (&lock);
@@ -1125,7 +1121,6 @@ time_t rrdc_first (const char *filename,
size_t buffer_size;
rrdc_response_t *res;
int status;
- char file_path[PATH_MAX];
time_t firstup;
if (filename == NULL) {
@@ -1144,7 +1139,7 @@ time_t rrdc_first (const char *filename,
}
mutex_lock (&lock);
- filename = get_path (filename, file_path);
+ filename = get_path (filename);
if (filename == NULL)
{
mutex_unlock (&lock);
@@ -1198,7 +1193,6 @@ int rrdc_create (const char *filename, /
size_t buffer_size;
rrdc_response_t *res;
int status;
- char file_path[PATH_MAX];
int i;
if (filename == NULL) {
@@ -1217,7 +1211,7 @@ int rrdc_create (const char *filename, /
}
mutex_lock (&lock);
- filename = get_path (filename, file_path);
+ filename = get_path (filename);
if (filename == NULL)
{
mutex_unlock (&lock);
@@ -1282,7 +1276,6 @@ int rrdc_fetch (const char *filename, /*
size_t buffer_free;
size_t buffer_size;
rrdc_response_t *res;
- char path_buffer[PATH_MAX];
const char *path_ptr;
char *str_tmp;
@@ -1315,7 +1308,7 @@ int rrdc_fetch (const char *filename, /*
return (ENOBUFS);
/* change to path for rrdcached */
- path_ptr = get_path (filename, path_buffer);
+ path_ptr = get_path (filename);
if (path_ptr == NULL)
return (EINVAL);
_______________________________________________
rrd-developers mailing list
[email protected]
https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers