From 672a5d8877e055d90272210497302afb26e28c8f Mon Sep 17 00:00:00 2001 From: oetiker Date: Tue, 14 Oct 2008 11:33:37 +0000 Subject: [PATCH] Some observations I made while implementing this: - In rrd_open(), the call to rrd_init() clobbers values already populated in rrd_create.c - The logic for newfile_size in rrd_open() wasn't really able to cope with the logic for a file starting with size 0 I've tried to deal with these issues, but maybe there is a more elegant solution. -- Daniel Pocock git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk/program@1601 a5681a0c-68f1-0310-ab6d-d61299d08faa --- src/rrd_create.c | 50 +++++++++++++++++++++++++------------------------- src/rrd_open.c | 37 +++++++++++++++++++++++++++++++++++-- src/rrd_resize.c | 2 +- src/rrd_tool.h | 1 + 4 files changed, 62 insertions(+), 28 deletions(-) diff --git a/src/rrd_create.c b/src/rrd_create.c index 9ee6896..ffc1892 100644 --- a/src/rrd_create.c +++ b/src/rrd_create.c @@ -671,36 +671,31 @@ int rrd_create_fn( rrd_t *rrd) { unsigned long i, ii; - int rrd_file; rrd_value_t *unknown; int unkn_cnt; rrd_file_t *rrd_file_dn; rrd_t rrd_dn; - unsigned flags = O_WRONLY | O_CREAT | O_TRUNC; + unsigned rrd_flags = RRD_READWRITE | RRD_CREAT; -#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__) - flags |= O_BINARY; -#endif - - if ((rrd_file = open(file_name, flags, 0666)) < 0) { + if ((rrd_file_dn = rrd_open(file_name, rrd, rrd_flags)) == NULL) { rrd_set_error("creating '%s': %s", file_name, rrd_strerror(errno)); rrd_free2(rrd); return (-1); } - write(rrd_file, rrd->stat_head, sizeof(stat_head_t)); + rrd_write(rrd_file_dn, rrd->stat_head, sizeof(stat_head_t)); - write(rrd_file, rrd->ds_def, sizeof(ds_def_t) * rrd->stat_head->ds_cnt); + rrd_write(rrd_file_dn, rrd->ds_def, sizeof(ds_def_t) * rrd->stat_head->ds_cnt); - write(rrd_file, rrd->rra_def, + rrd_write(rrd_file_dn, rrd->rra_def, sizeof(rra_def_t) * rrd->stat_head->rra_cnt); - write(rrd_file, rrd->live_head, sizeof(live_head_t)); + rrd_write(rrd_file_dn, rrd->live_head, sizeof(live_head_t)); if ((rrd->pdp_prep = calloc(1, sizeof(pdp_prep_t))) == NULL) { rrd_set_error("allocating pdp_prep"); rrd_free2(rrd); - close(rrd_file); + rrd_close(rrd_file_dn); return (-1); } @@ -711,12 +706,12 @@ int rrd_create_fn( rrd->live_head->last_up % rrd->stat_head->pdp_step; for (i = 0; i < rrd->stat_head->ds_cnt; i++) - write(rrd_file, rrd->pdp_prep, sizeof(pdp_prep_t)); + rrd_write(rrd_file_dn, rrd->pdp_prep, sizeof(pdp_prep_t)); if ((rrd->cdp_prep = calloc(1, sizeof(cdp_prep_t))) == NULL) { rrd_set_error("allocating cdp_prep"); rrd_free2(rrd); - close(rrd_file); + rrd_close(rrd_file_dn); return (-1); } @@ -753,7 +748,7 @@ int rrd_create_fn( } for (ii = 0; ii < rrd->stat_head->ds_cnt; ii++) { - write(rrd_file, rrd->cdp_prep, sizeof(cdp_prep_t)); + rrd_write(rrd_file_dn, rrd->cdp_prep, sizeof(cdp_prep_t)); } } @@ -763,7 +758,7 @@ int rrd_create_fn( if ((rrd->rra_ptr = calloc(1, sizeof(rra_ptr_t))) == NULL) { rrd_set_error("allocating rra_ptr"); rrd_free2(rrd); - close(rrd_file); + rrd_close(rrd_file_dn); return (-1); } @@ -773,14 +768,14 @@ int rrd_create_fn( * the pointer a priori. */ for (i = 0; i < rrd->stat_head->rra_cnt; i++) { rrd->rra_ptr->cur_row = rra_random_row(&rrd->rra_def[i]); - write(rrd_file, rrd->rra_ptr, sizeof(rra_ptr_t)); + rrd_write(rrd_file_dn, rrd->rra_ptr, sizeof(rra_ptr_t)); } /* write the empty data area */ if ((unknown = (rrd_value_t *) malloc(512 * sizeof(rrd_value_t))) == NULL) { rrd_set_error("allocating unknown"); rrd_free2(rrd); - close(rrd_file); + rrd_close(rrd_file_dn); return (-1); } for (i = 0; i < 512; ++i) @@ -791,22 +786,27 @@ int rrd_create_fn( unkn_cnt += rrd->stat_head->ds_cnt * rrd->rra_def[i].row_cnt; while (unkn_cnt > 0) { - write(rrd_file, unknown, sizeof(rrd_value_t) * min(unkn_cnt, 512)); + if(rrd_write(rrd_file_dn, unknown, sizeof(rrd_value_t) * min(unkn_cnt, 512)) < 0) + { + rrd_set_error("creating rrd: %s", rrd_strerror(errno)); + return -1; + } unkn_cnt -= 512; } free(unknown); - fdatasync(rrd_file); rrd_free2(rrd); - if (close(rrd_file) == -1) { + if (rrd_close(rrd_file_dn) == -1) { rrd_set_error("creating rrd: %s", rrd_strerror(errno)); return -1; } /* flush all we don't need out of the cache */ - rrd_file_dn = rrd_open(file_name, &rrd_dn, RRD_READONLY); - rrd_dontneed(rrd_file_dn, &rrd_dn); - rrd_free(&rrd_dn); - rrd_close(rrd_file_dn); + if((rrd_file_dn = rrd_open(file_name, &rrd_dn, RRD_READONLY)) != NULL) + { + rrd_dontneed(rrd_file_dn, &rrd_dn); + /* rrd_free(&rrd_dn); */ + rrd_close(rrd_file_dn); + } return (0); } diff --git a/src/rrd_open.c b/src/rrd_open.c index f262413..86d608c 100644 --- a/src/rrd_open.c +++ b/src/rrd_open.c @@ -79,13 +79,14 @@ rrd_file_t *rrd_open( rrd_file_t *rrd_file = NULL; off_t newfile_size = 0; - if (rdwr & RRD_CREAT) { + if ((rdwr & RRD_CREAT) && (rdwr & RRD_CREAT_SETSIZE)) { /* yes bad inline signaling alert, we are using the floatcookie to pass the size in ... only used in resize */ newfile_size = (off_t) rrd->stat_head->float_cookie; free(rrd->stat_head); } - rrd_init(rrd); + if(!(rdwr & RRD_CREAT)) + rrd_init(rrd); rrd_file = malloc(sizeof(rrd_file_t)); if (rrd_file == NULL) { rrd_set_error("allocating rrd_file descriptor for '%s'", file_name); @@ -170,7 +171,13 @@ rrd_file_t *rrd_open( } } */ + #ifdef HAVE_MMAP + if(rrd_file->file_len == 0 && (rdwr & RRD_CREAT)) + { + rrd_file->file_start = NULL; + goto out_done; + } data = mmap(0, rrd_file->file_len, mm_prot, mm_flags, rrd_file->fd, offset); @@ -535,10 +542,36 @@ ssize_t rrd_write( size_t count) { #ifdef HAVE_MMAP + /* These flags are used if creating a new RRD */ + int mm_prot = PROT_READ | PROT_WRITE, mm_flags = MAP_SHARED; + int old_size = rrd_file->file_len; + int new_size = rrd_file->file_len; if (count == 0) return 0; if (buf == NULL) return -1; /* EINVAL */ + + if((rrd_file->pos + count) > old_size) + { + new_size = rrd_file->pos + count; + rrd_file->file_len = new_size; + lseek(rrd_file->fd, new_size - 1, SEEK_SET); + write(rrd_file->fd, "\0", 1); /* poke */ + lseek(rrd_file->fd, 0, SEEK_SET); + if(rrd_file->file_start == NULL) + { + rrd_file->file_start = mmap(0, new_size, mm_prot, mm_flags, + rrd_file->fd, 0); + } + else + rrd_file->file_start = mremap(rrd_file->file_start, old_size, new_size, MREMAP_MAYMOVE); + + if (rrd_file->file_start == MAP_FAILED) { + rrd_set_error("m(re)maping file : %s", + rrd_strerror(errno)); + return -1; + } + } memcpy(rrd_file->file_start + rrd_file->pos, buf, count); rrd_file->pos += count; return count; /* mimmic write() semantics */ diff --git a/src/rrd_resize.c b/src/rrd_resize.c index 57adbf0..66d02af 100644 --- a/src/rrd_resize.c +++ b/src/rrd_resize.c @@ -93,7 +93,7 @@ int rrd_resize( } rrdnew.stat_head->float_cookie = rrd_file->file_len + (rrdold.stat_head->ds_cnt * sizeof(rrd_value_t) * modify); - rrd_out_file = rrd_open(outfilename, &rrdnew, RRD_READWRITE | RRD_CREAT); + rrd_out_file = rrd_open(outfilename, &rrdnew, RRD_READWRITE | RRD_CREAT | RRD_CREAT_SETSIZE); if (rrd_out_file == NULL) { rrd_set_error("Can't create '%s': %s", outfilename, rrd_strerror(errno)); diff --git a/src/rrd_tool.h b/src/rrd_tool.h index 43781da..c281979 100644 --- a/src/rrd_tool.h +++ b/src/rrd_tool.h @@ -97,6 +97,7 @@ extern "C" { #define RRD_CREAT (1<<2) #define RRD_READAHEAD (1<<3) #define RRD_COPY (1<<4) +#define RRD_CREAT_SETSIZE (1<<5) enum cf_en cf_conv( const char *string); -- 2.11.0