- int flags = 0;
- mode_t mode = S_IRUSR;
- int version, prot = PROT_READ;
- off_t offset = 0;
- char *data;
- struct stat statb;
- rrd_file_t *rrd_file = malloc(sizeof(rrd_file_t));
- if (rrd_file == NULL) {
- rrd_set_error("allocating rrd_file descriptor for '%s'",
- file_name);
- return NULL;
- }
- memset(rrd_file, 0, sizeof(rrd_file_t));
- rrd_init(rrd);
- if (rdwr == RRD_READWRITE) {
- mode |= S_IWUSR;
- prot |= PROT_WRITE;
- } else if (rdwr == RRD_CREAT) {
- mode |= S_IWUSR;
- prot |= PROT_WRITE;
- flags |= (O_CREAT|O_TRUNC);
- }
-#ifdef O_NONBLOCK
- flags |= O_NONBLOCK;
-#endif
-
- if ((rrd_file->fd = open(file_name, flags, mode)) < 0 ){
- rrd_set_error("opening '%s': %s",file_name, rrd_strerror(errno));
- return NULL;
- }
-
- /* ???: length = lseek(rrd_file->fd, 0, SEEK_END); */
- /* ??? locking the whole area of the file may overdo it a bit, does it? */
- if ((fstat(rrd_file->fd, &statb)) < 0) {
- rrd_set_error("fstat '%s': %s",file_name, rrd_strerror(errno));
- goto out_close;
- }
- rrd_file->file_len = statb.st_size;
+ unsigned long ui;
+ int flags = 0;
+ int version;
+
+#ifdef HAVE_MMAP
+ ssize_t _page_size = sysconf(_SC_PAGESIZE);
+ char *data = MAP_FAILED;
+#endif
+ off_t offset = 0;
+ struct stat statb;
+ rrd_file_t *rrd_file = NULL;
+ rrd_simple_file_t *rrd_simple_file = NULL;
+ 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))
+ {
+ header_len = \
+ sizeof(stat_head_t) + \
+ sizeof(ds_def_t) * rrd->stat_head->ds_cnt + \
+ sizeof(rra_def_t) * rrd->stat_head->rra_cnt + \
+ sizeof(time_t) + \
+ sizeof(live_head_t) + \
+ sizeof(pdp_prep_t) * rrd->stat_head->ds_cnt + \
+ sizeof(cdp_prep_t) * rrd->stat_head->ds_cnt * rrd->stat_head->rra_cnt + \
+ sizeof(rra_ptr_t) * rrd->stat_head->rra_cnt;
+
+ value_cnt = 0;
+ 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 = (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;
+ }
+ memset(rrd_file, 0, sizeof(rrd_file_t));
+
+ rrd_file->pvt = malloc(sizeof(rrd_simple_file_t));
+ if(rrd_file->pvt == NULL) {
+ rrd_set_error("allocating rrd_simple_file for '%s'", file_name);
+ return NULL;
+ }
+ memset(rrd_file->pvt, 0, sizeof(rrd_simple_file_t));
+ rrd_simple_file = (rrd_simple_file_t *)rrd_file->pvt;
+
+#ifdef DEBUG
+ if ((rdwr & (RRD_READONLY | RRD_READWRITE)) ==
+ (RRD_READONLY | RRD_READWRITE)) {
+ /* Both READONLY and READWRITE were given, which is invalid. */
+ rrd_set_error("in read/write request mask");
+ exit(-1);
+ }
+#endif
+
+#ifdef HAVE_MMAP
+ rrd_simple_file->mm_prot = PROT_READ;
+ rrd_simple_file->mm_flags = 0;
+#endif
+
+ if (rdwr & RRD_READONLY) {
+ flags |= O_RDONLY;
+#ifdef HAVE_MMAP
+ rrd_simple_file->mm_flags = MAP_PRIVATE;
+# ifdef MAP_NORESERVE
+ rrd_simple_file->mm_flags |= MAP_NORESERVE; /* readonly, so no swap backing needed */
+# endif
+#endif
+ } 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
+ }
+ if (rdwr & RRD_CREAT) {
+ flags |= (O_CREAT | O_TRUNC);
+ }
+ }
+ if (rdwr & RRD_READAHEAD) {
+#ifdef MAP_POPULATE
+ rrd_simple_file->mm_flags |= MAP_POPULATE; /* populate ptes and data */
+#endif
+#if defined MAP_NONBLOCK
+ rrd_simple_file->mm_flags |= MAP_NONBLOCK; /* just populate ptes */
+#endif
+ }
+#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
+ flags |= O_BINARY;
+#endif
+
+ if ((rrd_simple_file->fd = open(file_name, flags, 0666)) < 0) {
+ rrd_set_error("opening '%s': %s", file_name, rrd_strerror(errno));
+ 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