X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Frrd_open.c;h=d2ec549754d62d1a2d4e5b6597884212fb350599;hb=f4abf7d18767b842801a7c38f922e34e0ff3c890;hp=a83031a99cf40694129157fcee55400594e74202;hpb=59525f3de81d5f6a9c5e5fc3a6662fa7e074163f;p=rrdtool.git diff --git a/src/rrd_open.c b/src/rrd_open.c index a83031a..d2ec549 100644 --- a/src/rrd_open.c +++ b/src/rrd_open.c @@ -6,10 +6,34 @@ * $Id$ *****************************************************************************/ +#include +#include +#include +#include + #include "rrd_tool.h" #include "unused.h" #define MEMBLK 8192 +#ifdef WIN32 +# define random() rand() +# define srandom(x) srand(x) +# define getpid() 0 + +#define _LK_UNLCK 0 /* Unlock */ +#define _LK_LOCK 1 /* Lock */ +#define _LK_NBLCK 2 /* Non-blocking lock */ +#define _LK_RLCK 3 /* Lock for read only */ +#define _LK_NBRLCK 4 /* Non-blocking lock for read only */ + + +#define LK_UNLCK _LK_UNLCK +#define LK_LOCK _LK_LOCK +#define LK_NBLCK _LK_NBLCK +#define LK_RLCK _LK_RLCK +#define LK_NBRLCK _LK_NBRLCK +#endif + /* DEBUG 2 prints information obtained via mincore(2) */ #define DEBUG 1 /* do not calculate exact madvise hints but assume 1 page for headers and @@ -34,7 +58,7 @@ #define __rrd_read(dst, dst_t, cnt) { \ size_t wanted = sizeof(dst_t)*(cnt); \ size_t got; \ - if ((dst = malloc(wanted)) == NULL) { \ + if ((dst = (dst_t*)malloc(wanted)) == NULL) { \ rrd_set_error(#dst " malloc"); \ goto out_nullify_head; \ } \ @@ -54,6 +78,10 @@ #endif #endif +long int rra_random_row( + rra_def_t *); + + /* Open a database file, return its header and an open filehandle, * positioned to the first cdp in the first rra. * In the error path of rrd_open, only rrd_free(&rrd) has to be called @@ -69,7 +97,7 @@ rrd_file_t *rrd_open( rrd_t *rrd, unsigned rdwr) { - int i; + unsigned long ui; int flags = 0; int version; @@ -81,8 +109,8 @@ rrd_file_t *rrd_open( struct stat statb; rrd_file_t *rrd_file = NULL; rrd_simple_file_t *rrd_simple_file = NULL; - off_t newfile_size = 0; - off_t header_len, value_cnt, data_len; + size_t newfile_size = 0; + size_t header_len, value_cnt, data_len; /* Are we creating a new file? */ if((rdwr & RRD_CREAT) && (rrd->stat_head != NULL)) @@ -98,15 +126,15 @@ rrd_file_t *rrd_open( sizeof(rra_ptr_t) * rrd->stat_head->rra_cnt; value_cnt = 0; - for (i = 0; i < rrd->stat_head->rra_cnt; i++) - value_cnt += rrd->stat_head->ds_cnt * rrd->rra_def[i].row_cnt; + for (ui = 0; ui < rrd->stat_head->rra_cnt; ui++) + value_cnt += rrd->stat_head->ds_cnt * rrd->rra_def[ui].row_cnt; data_len = sizeof(rrd_value_t) * value_cnt; newfile_size = header_len + data_len; } - rrd_file = malloc(sizeof(rrd_file_t)); + rrd_file = (rrd_file_t*)malloc(sizeof(rrd_file_t)); if (rrd_file == NULL) { rrd_set_error("allocating rrd_file descriptor for '%s'", file_name); return NULL; @@ -146,10 +174,10 @@ rrd_file_t *rrd_open( } else { if (rdwr & RRD_READWRITE) { flags |= O_RDWR; -#ifdef HAVE_MMAP - rrd_simple_file->mm_flags = MAP_SHARED; - rrd_simple_file->mm_prot |= PROT_WRITE; -#endif +#ifdef HAVE_MMAP + rrd_simple_file->mm_flags = MAP_SHARED; + rrd_simple_file->mm_prot |= PROT_WRITE; +#endif } if (rdwr & RRD_CREAT) { flags |= (O_CREAT | O_TRUNC); @@ -172,6 +200,21 @@ rrd_file_t *rrd_open( goto out_free; } +#ifdef HAVE_MMAP +#ifdef HAVE_BROKEN_MS_ASYNC + if (rdwr & RRD_READWRITE) { + /* some unices, the files mtime does not get update + on msync MS_ASYNC, in order to help them, + we update the the timestamp at this point. + The thing happens pretty 'close' to the open + call so the chances of a race should be minimal. + + Maybe ask your vendor to fix your OS ... */ + utime(file_name,NULL); + } +#endif +#endif + /* Better try to avoid seeks as much as possible. stat may be heavy but * many concurrent seeks are even worse. */ if (newfile_size == 0 && ((fstat(rrd_simple_file->fd, &statb)) < 0)) { @@ -309,12 +352,11 @@ rrd_file_t *rrd_open( { unsigned long row_cnt = 0; - unsigned long i; - for (i=0; istat_head->rra_cnt; i++) - row_cnt += rrd->rra_def[i].row_cnt; + for (ui=0; uistat_head->rra_cnt; ui++) + row_cnt += rrd->rra_def[ui].row_cnt; - off_t correct_len = rrd_file->header_len + + size_t correct_len = rrd_file->header_len + sizeof(rrd_value_t) * row_cnt * rrd->stat_head->ds_cnt; if (correct_len > rrd_file->file_len) @@ -334,6 +376,7 @@ rrd_file_t *rrd_open( if (data != MAP_FAILED) munmap(data, rrd_file->file_len); #endif + close(rrd_simple_file->fd); out_free: free(rrd_file->pvt); @@ -353,7 +396,7 @@ void mincore_print( rrd_simple_file = (rrd_simple_file_t *)rrd_file->pvt; #ifdef HAVE_MMAP /* pretty print blocks in core */ - off_t off; + size_t off; unsigned char *vec; ssize_t _page_size = sysconf(_SC_PAGESIZE); @@ -434,9 +477,9 @@ void rrd_dontneed( { rrd_simple_file_t *rrd_simple_file = (rrd_simple_file_t *)rrd_file->pvt; #if defined USE_MADVISE || defined HAVE_POSIX_FADVISE - off_t dontneed_start; - off_t rra_start; - off_t active_block; + size_t dontneed_start; + size_t rra_start; + size_t active_block; unsigned long i; ssize_t _page_size = sysconf(_SC_PAGESIZE); @@ -618,7 +661,7 @@ ssize_t rrd_write( { rrd_simple_file_t *rrd_simple_file = (rrd_simple_file_t *)rrd_file->pvt; #ifdef HAVE_MMAP - int old_size = rrd_file->file_len; + size_t old_size = rrd_file->file_len; if (count == 0) return 0; if (buf == NULL) @@ -647,12 +690,14 @@ ssize_t rrd_write( void rrd_flush( rrd_file_t *rrd_file) { +#ifndef WIN32 rrd_simple_file_t *rrd_simple_file; rrd_simple_file = (rrd_simple_file_t *)rrd_file->pvt; if (fdatasync(rrd_simple_file->fd) != 0) { rrd_set_error("flushing fd %d: %s", rrd_simple_file->fd, rrd_strerror(errno)); } +#endif } @@ -707,3 +752,46 @@ void rrd_freemem( { free(mem); } + +/* + * rra_update informs us about the RRAs being updated + * The low level storage API may use this information for + * aligning RRAs within stripes, or other performance enhancements + */ +void rrd_notify_row( + rrd_file_t *rrd_file __attribute__((unused)), + int rra_idx __attribute__((unused)), + unsigned long rra_row __attribute__((unused)), + time_t rra_time __attribute__((unused))) +{ +} + +/* + * This function is called when creating a new RRD + * The storage implementation can use this opportunity to select + * a sensible starting row within the file. + * The default implementation is random, to ensure that all RRAs + * don't change to a new disk block at the same time + */ +unsigned long rrd_select_initial_row( + rrd_file_t *rrd_file __attribute__((unused)), + int rra_idx __attribute__((unused)), + rra_def_t *rra + ) +{ + return rra_random_row(rra); +} + +static int rand_init = 0; + +long int rra_random_row( + rra_def_t *rra) +{ + if (!rand_init) { + srandom((unsigned int) time(NULL) + (unsigned int) getpid()); + rand_init++; + } + + return random() % rra->row_cnt; +} +