cdp_prep_t *cdp_prep; /* cdp prep area */
rra_ptr_t *rra_ptr; /* list of rra pointers */
rrd_value_t *rrd_value; /* list of rrd values */
+ void *__mmap_start; /* all __ variables will be used internally */
+ long __mmap_size;
} rrd_t;
/****************************************************************************
rrd_strerror(errno));
goto out_close;
}
+ rrd->__mmap_start = data;
+ rrd->__mmap_size = rrd_file->file_len;
+
rrd_simple_file->file_start = data;
#endif
if (rdwr & RRD_CREAT)
#ifdef HAVE_MMAP
if (data != MAP_FAILED)
munmap(data, rrd_file->file_len);
+ rrd->__mmap_start = NULL;
+ rrd->__mmap_size = 0;
#endif
close(rrd_simple_file->fd);
rrd->pdp_prep = NULL;
rrd->cdp_prep = NULL;
rrd->rrd_value = NULL;
+ rrd->__mmap_start = NULL;
+ rrd->__mmap_size = 0;
}
-/* free RRD header data. */
-
-#ifdef HAVE_MMAP
-void rrd_free(
- rrd_t *rrd)
+/* free RRD data, act correctly, regardless of mmap'ped or malloc'd memory. */
+static void free_rrd_ptr_if_not_mmapped(void *m, const rrd_t *rrd)
{
- if (rrd->legacy_last_up) { /* this gets set for version < 3 only */
- free(rrd->live_head);
+ if (m == NULL) return;
+
+ if (rrd == NULL || rrd->__mmap_start == NULL) {
+ free(m);
+ }
+
+ /* is this ALWAYS correct on all supported platforms ??? */
+ long ofs = (char*)m - (char*)rrd->__mmap_start;
+ if (ofs < rrd->__mmap_size) {
+ // DO NOT FREE, this memory is mmapped!!
+ return;
}
+
+ free(m);
}
-#else
+
void rrd_free(
rrd_t *rrd)
{
- free(rrd->live_head);
- free(rrd->stat_head);
- free(rrd->ds_def);
- free(rrd->rra_def);
- free(rrd->rra_ptr);
- free(rrd->pdp_prep);
- free(rrd->cdp_prep);
- free(rrd->rrd_value);
+ if (rrd == NULL) return;
+
+ free_rrd_ptr_if_not_mmapped(rrd->live_head, rrd);
+ free_rrd_ptr_if_not_mmapped(rrd->stat_head, rrd);
+ free_rrd_ptr_if_not_mmapped(rrd->ds_def, rrd);
+ free_rrd_ptr_if_not_mmapped(rrd->rra_def, rrd);
+ free_rrd_ptr_if_not_mmapped(rrd->rra_ptr, rrd);
+ free_rrd_ptr_if_not_mmapped(rrd->pdp_prep, rrd);
+ free_rrd_ptr_if_not_mmapped(rrd->cdp_prep, rrd);
+ free_rrd_ptr_if_not_mmapped(rrd->rrd_value, rrd);
}
-#endif
-
/* routine used by external libraries to free memory allocated by
* rrd library */