added memory mode "alloc" to be used when mmap() is not available or fails
Costa Tsaousis (ktsaou) committed
Jun 7, 2017 at 22:01 UTC
533aafde37bce702c876d62fa05f69ded13e9d79
5 files changed
+97
-75
src/rrd.c
+10
-1
@@ -31,19 +31,28 @@ inline const char *rrd_memory_mode_name(RRD_MEMORY_MODE id) {
31
return RRD_MEMORY_MODE_NONE_NAME;
32
33
case RRD_MEMORY_MODE_SAVE:
34
- default:
34
return RRD_MEMORY_MODE_SAVE_NAME;
35
+
36
+ case RRD_MEMORY_MODE_ALLOC:
37
+ return RRD_MEMORY_MODE_ALLOC_NAME;
38
}
39
+
40
+ return RRD_MEMORY_MODE_SAVE_NAME;
41
}
42
43
RRD_MEMORY_MODE rrd_memory_mode_id(const char *name) {
44
if(unlikely(!strcmp(name, RRD_MEMORY_MODE_RAM_NAME)))
45
return RRD_MEMORY_MODE_RAM;
46
+
47
else if(unlikely(!strcmp(name, RRD_MEMORY_MODE_MAP_NAME)))
48
return RRD_MEMORY_MODE_MAP;
49
+
50
else if(unlikely(!strcmp(name, RRD_MEMORY_MODE_NONE_NAME)))
51
return RRD_MEMORY_MODE_NONE;
52
53
+ else if(unlikely(!strcmp(name, RRD_MEMORY_MODE_ALLOC_NAME)))
54
+ return RRD_MEMORY_MODE_ALLOC;
55
+
56
return RRD_MEMORY_MODE_SAVE;
57
}
58
src/rrd.h
+3
-1
@@ -42,13 +42,15 @@ typedef enum rrd_memory_mode {
42
RRD_MEMORY_MODE_NONE = 0,
43
RRD_MEMORY_MODE_RAM = 1,
44
RRD_MEMORY_MODE_MAP = 2,
45
- RRD_MEMORY_MODE_SAVE = 3
45
+ RRD_MEMORY_MODE_SAVE = 3,
46
+ RRD_MEMORY_MODE_ALLOC = 4
47
} RRD_MEMORY_MODE;
48
49
#define RRD_MEMORY_MODE_NONE_NAME "none"
50
#define RRD_MEMORY_MODE_RAM_NAME "ram"
51
#define RRD_MEMORY_MODE_MAP_NAME "map"
52
#define RRD_MEMORY_MODE_SAVE_NAME "save"
53
+#define RRD_MEMORY_MODE_ALLOC_NAME "alloc"
54
55
extern RRD_MEMORY_MODE default_rrd_memory_mode;
56
src/rrddim.c
+39
-33
@@ -130,41 +130,46 @@ RRDDIM *rrddim_add_custom(RRDSET *st, const char *id, const char *name, collecte
130
struct timeval now;
131
now_realtime_timeval(&now);
132
133
- if(strcmp(rd->magic, RRDDIMENSION_MAGIC) != 0) {
134
- errno = 0;
135
- info("Initializing file %s.", fullfilename);
133
+ if(memory_mode == RRD_MEMORY_MODE_RAM) {
134
memset(rd, 0, size);
135
}
138
- else if(rd->memsize != size) {
139
- errno = 0;
140
- error("File %s does not have the desired size. Clearing it.", fullfilename);
141
- memset(rd, 0, size);
142
- }
143
- else if(rd->multiplier != multiplier) {
144
- errno = 0;
145
- error("File %s does not have the same multiplier. Clearing it.", fullfilename);
146
- memset(rd, 0, size);
147
- }
148
- else if(rd->divisor != divisor) {
149
- errno = 0;
150
- error("File %s does not have the same divisor. Clearing it.", fullfilename);
151
- memset(rd, 0, size);
136
+ else {
137
+ if(strcmp(rd->magic, RRDDIMENSION_MAGIC) != 0) {
138
+ errno = 0;
139
+ info("Initializing file %s.", fullfilename);
140
+ memset(rd, 0, size);
141
+ }
142
+ else if(rd->memsize != size) {
143
+ errno = 0;
144
+ error("File %s does not have the desired size. Clearing it.", fullfilename);
145
+ memset(rd, 0, size);
146
+ }
147
+ else if(rd->multiplier != multiplier) {
148
+ errno = 0;
149
+ error("File %s does not have the same multiplier. Clearing it.", fullfilename);
150
+ memset(rd, 0, size);
151
+ }
152
+ else if(rd->divisor != divisor) {
153
+ errno = 0;
154
+ error("File %s does not have the same divisor. Clearing it.", fullfilename);
155
+ memset(rd, 0, size);
156
+ }
157
+ else if(rd->update_every != st->update_every) {
158
+ errno = 0;
159
+ error("File %s does not have the same refresh frequency. Clearing it.", fullfilename);
160
+ memset(rd, 0, size);
161
+ }
162
+ else if(dt_usec(&now, &rd->last_collected_time) > (rd->entries * rd->update_every * USEC_PER_SEC)) {
163
+ errno = 0;
164
+ error("File %s is too old. Clearing it.", fullfilename);
165
+ memset(rd, 0, size);
166
+ }
167
+
168
+ if(rd->algorithm && rd->algorithm != algorithm)
169
+ error("File %s does not have the expected algorithm (expected %u '%s', found %u '%s'). Previous values may be wrong."
170
+ , fullfilename, algorithm, rrd_algorithm_name(algorithm), rd->algorithm, rrd_algorithm_name(
171
+ rd->algorithm));
172
}
153
- else if(rd->update_every != st->update_every) {
154
- errno = 0;
155
- error("File %s does not have the same refresh frequency. Clearing it.", fullfilename);
156
- memset(rd, 0, size);
157
- }
158
- else if(dt_usec(&now, &rd->last_collected_time) > (rd->entries * rd->update_every * USEC_PER_SEC)) {
159
- errno = 0;
160
- error("File %s is too old. Clearing it.", fullfilename);
161
- memset(rd, 0, size);
162
- }
163
-
164
- if(rd->algorithm && rd->algorithm != algorithm)
165
- error("File %s does not have the expected algorithm (expected %u '%s', found %u '%s'). Previous values may be wrong."
166
- , fullfilename, algorithm, rrd_algorithm_name(algorithm), rd->algorithm,
167
- rrd_algorithm_name(rd->algorithm));
173
174
// make sure we have the right memory mode
175
// even if we cleared the memory
@@ -175,7 +180,7 @@ RRDDIM *rrddim_add_custom(RRDSET *st, const char *id, const char *name, collecte
180
if(unlikely(!rd)) {
181
// if we didn't manage to get a mmap'd dimension, just create one
182
rd = callocz(1, size);
178
- rd->rrd_memory_mode = (memory_mode == RRD_MEMORY_MODE_NONE) ? RRD_MEMORY_MODE_NONE : RRD_MEMORY_MODE_RAM;
183
+ rd->rrd_memory_mode = (memory_mode == RRD_MEMORY_MODE_NONE) ? RRD_MEMORY_MODE_NONE : RRD_MEMORY_MODE_ALLOC;
184
}
185
186
rd->memsize = size;
@@ -283,6 +288,7 @@ void rrddim_free(RRDSET *st, RRDDIM *rd)
288
munmap(rd, rd->memsize);
289
break;
290
291
+ case RRD_MEMORY_MODE_ALLOC:
292
case RRD_MEMORY_MODE_NONE:
293
debug(D_RRD_CALLS, "Removing dimension '%s'.", rd->name);
294
freez((void *)rd->id);
src/rrdset.c
+43
-38
@@ -199,7 +199,7 @@ inline long align_entries_to_pagesize(RRD_MEMORY_MODE mode, long entries) {
199
if(unlikely(entries < 5)) entries = 5;
200
if(unlikely(entries > RRD_HISTORY_ENTRIES_MAX)) entries = RRD_HISTORY_ENTRIES_MAX;
201
202
- if(unlikely(mode == RRD_MEMORY_MODE_NONE || mode == RRD_MEMORY_MODE_RAM))
202
+ if(unlikely(mode == RRD_MEMORY_MODE_NONE || mode == RRD_MEMORY_MODE_ALLOC))
203
return entries;
204
205
long page = (size_t)sysconf(_SC_PAGESIZE);
@@ -287,6 +287,7 @@ void rrdset_free(RRDSET *st) {
287
munmap(st, st->memsize);
288
break;
289
290
+ case RRD_MEMORY_MODE_ALLOC:
291
case RRD_MEMORY_MODE_NONE:
292
freez(st);
293
break;
@@ -319,14 +320,14 @@ void rrdset_delete(RRDSET *st) {
320
321
info("Deleting chart '%s' ('%s') from disk...", st->id, st->name);
322
322
- if(st->rrd_memory_mode != RRD_MEMORY_MODE_RAM) {
323
+ if(st->rrd_memory_mode == RRD_MEMORY_MODE_SAVE || st->rrd_memory_mode == RRD_MEMORY_MODE_MAP) {
324
info("Deleting chart header file '%s'.", st->cache_filename);
325
if(unlikely(unlink(st->cache_filename) == -1))
326
error("Cannot delete chart header file '%s'", st->cache_filename);
327
}
328
329
rrddim_foreach_read(rd, st) {
329
- if(likely(rd->rrd_memory_mode != RRD_MEMORY_MODE_RAM)) {
330
+ if(likely(rd->rrd_memory_mode == RRD_MEMORY_MODE_SAVE || rd->rrd_memory_mode == RRD_MEMORY_MODE_MAP)) {
331
info("Deleting dimension file '%s'.", rd->cache_filename);
332
if(unlikely(unlink(rd->cache_filename) == -1))
333
error("Cannot delete dimension file '%s'", rd->cache_filename);
@@ -454,43 +455,47 @@ RRDSET *rrdset_create_custom(
455
st->alarms = NULL;
456
st->flags = 0x00000000;
457
457
- if(strcmp(st->magic, RRDSET_MAGIC) != 0) {
458
- errno = 0;
459
- info("Initializing file %s.", fullfilename);
458
+ if(memory_mode == RRD_MEMORY_MODE_RAM) {
459
memset(st, 0, size);
460
}
462
- else if(strcmp(st->id, fullid) != 0) {
463
- errno = 0;
464
- error("File %s contents are not for chart %s. Clearing it.", fullfilename, fullid);
465
- // munmap(st, size);
466
- // st = NULL;
467
- memset(st, 0, size);
468
- }
469
- else if(st->memsize != size || st->entries != entries) {
470
- errno = 0;
471
- error("File %s does not have the desired size. Clearing it.", fullfilename);
472
- memset(st, 0, size);
473
- }
474
- else if(st->update_every != update_every) {
475
- errno = 0;
476
- error("File %s does not have the desired update frequency. Clearing it.", fullfilename);
477
- memset(st, 0, size);
478
- }
479
- else if((now - st->last_updated.tv_sec) > update_every * entries) {
480
- errno = 0;
481
- error("File %s is too old. Clearing it.", fullfilename);
482
- memset(st, 0, size);
483
- }
484
- else if(st->last_updated.tv_sec > now + update_every) {
485
- errno = 0;
486
- error("File %s refers to the future. Clearing it.", fullfilename);
487
- memset(st, 0, size);
488
- }
489
-
490
- // make sure the database is aligned
491
- if(st->last_updated.tv_sec)
492
- last_updated_time_align(&st->last_updated, update_every);
461
+ else {
462
+ if(strcmp(st->magic, RRDSET_MAGIC) != 0) {
463
+ errno = 0;
464
+ info("Initializing file %s.", fullfilename);
465
+ memset(st, 0, size);
466
+ }
467
+ else if(strcmp(st->id, fullid) != 0) {
468
+ errno = 0;
469
+ error("File %s contents are not for chart %s. Clearing it.", fullfilename, fullid);
470
+ // munmap(st, size);
471
+ // st = NULL;
472
+ memset(st, 0, size);
473
+ }
474
+ else if(st->memsize != size || st->entries != entries) {
475
+ errno = 0;
476
+ error("File %s does not have the desired size. Clearing it.", fullfilename);
477
+ memset(st, 0, size);
478
+ }
479
+ else if(st->update_every != update_every) {
480
+ errno = 0;
481
+ error("File %s does not have the desired update frequency. Clearing it.", fullfilename);
482
+ memset(st, 0, size);
483
+ }
484
+ else if((now - st->last_updated.tv_sec) > update_every * entries) {
485
+ errno = 0;
486
+ error("File %s is too old. Clearing it.", fullfilename);
487
+ memset(st, 0, size);
488
+ }
489
+ else if(st->last_updated.tv_sec > now + update_every) {
490
+ errno = 0;
491
+ error("File %s refers to the future. Clearing it.", fullfilename);
492
+ memset(st, 0, size);
493
+ }
494
495
+ // make sure the database is aligned
496
+ if(st->last_updated.tv_sec)
497
+ last_updated_time_align(&st->last_updated, update_every);
498
+ }
499
500
// make sure we have the right memory mode
501
// even if we cleared the memory
@@ -500,7 +505,7 @@ RRDSET *rrdset_create_custom(
505
506
if(unlikely(!st)) {
507
st = callocz(1, size);
503
- st->rrd_memory_mode = (memory_mode == RRD_MEMORY_MODE_NONE) ? RRD_MEMORY_MODE_NONE : RRD_MEMORY_MODE_RAM;
508
+ st->rrd_memory_mode = (memory_mode == RRD_MEMORY_MODE_NONE) ? RRD_MEMORY_MODE_NONE : RRD_MEMORY_MODE_ALLOC;
509
}
510
511
st->config_section = strdup(config_section);
src/unit_test.c
+2
-2
@@ -923,7 +923,7 @@ int run_test(struct test *test)
923
{
924
fprintf(stderr, "\nRunning test '%s':\n%s\n", test->name, test->description);
925
926
- default_rrd_memory_mode = RRD_MEMORY_MODE_RAM;
926
+ default_rrd_memory_mode = RRD_MEMORY_MODE_ALLOC;
927
default_rrd_update_every = test->update_every;
928
929
char name[101];
@@ -1132,7 +1132,7 @@ int unit_test(long delay, long shift)
1132
snprintfz(name, 100, "unittest-%d-%ld-%ld", repeat, delay, shift);
1133
1134
//debug_flags = 0xffffffff;
1135
- default_rrd_memory_mode = RRD_MEMORY_MODE_RAM;
1135
+ default_rrd_memory_mode = RRD_MEMORY_MODE_ALLOC;
1136
default_rrd_update_every = 1;
1137
1138
int do_abs = 1;