1 /*****************************************************************************
2 * RRDtool 1.2.23 Copyright by Tobi Oetiker, 1997-2007
3 *****************************************************************************
4 * rrd_create.c creates new rrds
5 *****************************************************************************/
8 #include "rrd_rpncalc.h"
11 #include "rrd_is_thread_safe.h"
13 unsigned long FnvHash(const char *str);
14 int create_hw_contingent_rras(rrd_t *rrd, unsigned short period, unsigned long hashed_name);
15 void parseGENERIC_DS(const char *def,rrd_t *rrd, int ds_idx);
18 rrd_create(int argc, char **argv)
20 time_t last_up = time(NULL)-10;
21 unsigned long pdp_step = 300;
22 struct rrd_time_value last_up_tv;
23 char *parsetime_error = NULL;
26 optind = 0; opterr = 0; /* initialize getopt */
29 static struct option long_options[] =
31 {"start", required_argument, 0, 'b'},
32 {"step", required_argument,0,'s'},
37 opt = getopt_long(argc, argv, "b:s:",
38 long_options, &option_index);
45 if ((parsetime_error = parsetime(optarg, &last_up_tv))) {
46 rrd_set_error("start time: %s", parsetime_error );
49 if (last_up_tv.type == RELATIVE_TO_END_TIME ||
50 last_up_tv.type == RELATIVE_TO_START_TIME) {
51 rrd_set_error("specifying time relative to the 'start' "
52 "or 'end' makes no sense here");
56 last_up = mktime(&last_up_tv.tm) + last_up_tv.offset;
58 if (last_up < 3600*24*365*10){
59 rrd_set_error("the first entry to the RRD should be after 1980");
65 long_tmp = atol(optarg);
67 rrd_set_error("step size should be no less than one second");
75 rrd_set_error("unknown option '%c'", optopt);
77 rrd_set_error("unknown option '%s'",argv[optind-1]);
82 rrd_set_error("what is the name of the rrd file you want to create?");
85 rc = rrd_create_r(argv[optind],
87 argc - optind - 1, (const char **)(argv + optind + 1));
94 rrd_create_r(const char *filename,
95 unsigned long pdp_step, time_t last_up,
96 int argc, const char **argv)
102 char dummychar1[2], dummychar2[2];
103 unsigned short token_idx, error_flag, period=0;
104 unsigned long hashed_name;
109 if((rrd.stat_head = calloc(1,sizeof(stat_head_t)))==NULL){
110 rrd_set_error("allocating rrd.stat_head");
116 if((rrd.live_head = calloc(1,sizeof(live_head_t)))==NULL){
117 rrd_set_error("allocating rrd.live_head");
122 /* set some defaults */
123 strcpy(rrd.stat_head->cookie,RRD_COOKIE);
124 strcpy(rrd.stat_head->version,RRD_VERSION);
125 rrd.stat_head->float_cookie = FLOAT_COOKIE;
126 rrd.stat_head->ds_cnt = 0; /* this will be adjusted later */
127 rrd.stat_head->rra_cnt = 0; /* ditto */
128 rrd.stat_head->pdp_step = pdp_step; /* 5 minute default */
130 /* a default value */
134 rrd.live_head->last_up = last_up;
136 /* optind points to the first non-option command line arg,
137 * in this case, the file name. */
138 /* Compute the FNV hash value (used by SEASONAL and DEVSEASONAL
140 hashed_name = FnvHash(filename);
143 if (strncmp(argv[i],"DS:",3)==0){
144 size_t old_size = sizeof(ds_def_t)*(rrd.stat_head->ds_cnt);
145 if((rrd.ds_def = rrd_realloc(rrd.ds_def,
146 old_size+sizeof(ds_def_t)))==NULL){
147 rrd_set_error("allocating rrd.ds_def");
151 memset(&rrd.ds_def[rrd.stat_head->ds_cnt], 0, sizeof(ds_def_t));
152 /* extract the name and type */
153 switch (sscanf(&argv[i][3],
154 DS_NAM_FMT "%1[:]" DST_FMT "%1[:]%n",
155 rrd.ds_def[rrd.stat_head->ds_cnt].ds_nam,
157 rrd.ds_def[rrd.stat_head->ds_cnt].dst,
161 case 1: rrd_set_error("Invalid DS name"); break;
163 case 3: rrd_set_error("Invalid DS type"); break;
164 case 4: /* (%n may or may not be counted) */
165 case 5: /* check for duplicate datasource names */
166 for (ii=0;ii<rrd.stat_head->ds_cnt;ii++)
167 if(strcmp(rrd.ds_def[rrd.stat_head->ds_cnt].ds_nam,
168 rrd.ds_def[ii].ds_nam) == 0)
169 rrd_set_error("Duplicate DS name: %s",
170 rrd.ds_def[ii].ds_nam);
171 /* DS_type may be valid or not. Checked later */
173 default: rrd_set_error("invalid DS format");
175 if (rrd_test_error()) {
180 /* parse the remainder of the arguments */
181 switch(dst_conv(rrd.ds_def[rrd.stat_head->ds_cnt].dst))
187 parseGENERIC_DS(&argv[i][offset+3],&rrd, rrd.stat_head->ds_cnt);
190 parseCDEF_DS(&argv[i][offset+3],&rrd, rrd.stat_head->ds_cnt);
193 rrd_set_error("invalid DS type specified");
197 if (rrd_test_error()) {
201 rrd.stat_head -> ds_cnt++;
202 } else if (strncmp(argv[i],"RRA:",4)==0){
205 size_t old_size = sizeof(rra_def_t)*(rrd.stat_head->rra_cnt);
206 if((rrd.rra_def = rrd_realloc(rrd.rra_def,
207 old_size+sizeof(rra_def_t)))==NULL)
209 rrd_set_error("allocating rrd.rra_def");
213 memset(&rrd.rra_def[rrd.stat_head->rra_cnt], 0, sizeof(rra_def_t));
215 argvcopy = strdup(argv[i]);
216 token = strtok_r(&argvcopy[4],":", &tokptr);
217 token_idx = error_flag = 0;
218 while (token != NULL)
223 if (sscanf(token,CF_NAM_FMT,
224 rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam) != 1)
225 rrd_set_error("Failed to parse CF name");
226 switch(cf_conv(rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam))
229 /* initialize some parameters */
230 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_hw_alpha].u_val = 0.1;
231 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_hw_beta].u_val = 1.0/288;
232 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_dependent_rra_idx].u_cnt =
233 rrd.stat_head -> rra_cnt;
237 /* initialize some parameters */
238 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_seasonal_gamma].u_val = 0.1;
241 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_dependent_rra_idx].u_cnt = -1;
244 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_delta_pos].u_val = 2.0;
245 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_delta_neg].u_val = 2.0;
246 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_window_len].u_cnt = 3;
247 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_failure_threshold].u_cnt = 2;
248 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_dependent_rra_idx].u_cnt = -1;
250 /* invalid consolidation function */
252 rrd_set_error("Unrecognized consolidation function %s",
253 rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam);
257 /* default: 1 pdp per cdp */
258 rrd.rra_def[rrd.stat_head->rra_cnt].pdp_cnt = 1;
261 switch(cf_conv(rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam))
268 rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt = atoi(token);
271 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_cdp_xff_val].u_val = atof(token);
272 if (rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_cdp_xff_val].u_val<0.0 ||
273 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_cdp_xff_val].u_val>=1.0)
274 rrd_set_error("Invalid xff: must be between 0 and 1");
279 switch(cf_conv(rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam))
282 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_hw_alpha].u_val = atof(token);
283 if (atof(token) <= 0.0 || atof(token) >= 1.0)
284 rrd_set_error("Invalid alpha: must be between 0 and 1");
288 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_seasonal_gamma].u_val =
290 if (atof(token) <= 0.0 || atof(token) >= 1.0)
291 rrd_set_error("Invalid gamma: must be between 0 and 1");
292 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_seasonal_smooth_idx].u_cnt
293 = hashed_name % rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt;
296 /* specifies the # of violations that constitutes the failure threshold */
297 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_failure_threshold].u_cnt =
299 if (atoi(token) < 1 || atoi(token) > MAX_FAILURES_WINDOW_LEN)
300 rrd_set_error("Failure threshold is out of range %d, %d",1,
301 MAX_FAILURES_WINDOW_LEN);
304 /* specifies the index (1-based) of CF_DEVSEASONAL array
305 * associated with this CF_DEVPREDICT array. */
306 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_dependent_rra_idx].u_cnt =
310 rrd.rra_def[rrd.stat_head->rra_cnt].pdp_cnt = atoi(token);
315 switch(cf_conv(rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam))
318 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_hw_beta].u_val = atof(token);
319 if (atof(token) < 0.0 || atof(token) > 1.0)
320 rrd_set_error("Invalid beta: must be between 0 and 1");
324 /* specifies the index (1-based) of CF_HWPREDICT array
325 * associated with this CF_DEVSEASONAL or CF_SEASONAL array.
327 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_dependent_rra_idx].u_cnt =
331 /* specifies the window length */
332 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_window_len].u_cnt =
334 if (atoi(token) < 1 || atoi(token) > MAX_FAILURES_WINDOW_LEN)
335 rrd_set_error("Window length is out of range %d, %d",1,
336 MAX_FAILURES_WINDOW_LEN);
337 /* verify that window length exceeds the failure threshold */
338 if (rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_window_len].u_cnt <
339 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_failure_threshold].u_cnt)
340 rrd_set_error("Window length is shorter than the failure threshold");
343 /* shouldn't be any more arguments */
344 rrd_set_error("Unexpected extra argument for consolidation function DEVPREDICT");
347 rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt = atoi(token);
352 switch(cf_conv(rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam))
355 /* specifies the index (1-based) of CF_DEVSEASONAL array
356 * associated with this CF_DEVFAILURES array. */
357 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_dependent_rra_idx].u_cnt =
361 /* length of the associated CF_SEASONAL and CF_DEVSEASONAL arrays. */
362 period = atoi(token);
363 if (period > rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt)
364 rrd_set_error("Length of seasonal cycle exceeds length of HW prediction array");
367 /* shouldn't be any more arguments */
368 rrd_set_error("Unexpected extra argument for consolidation function %s",
369 rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam);
374 /* If we are here, this must be a CF_HWPREDICT RRA.
375 * Specifies the index (1-based) of CF_SEASONAL array
376 * associated with this CF_HWPREDICT array. If this argument
377 * is missing, then the CF_SEASONAL, CF_DEVSEASONAL, CF_DEVPREDICT,
379 * arrays are created automatically. */
380 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_dependent_rra_idx].u_cnt =
384 /* should never get here */
385 rrd_set_error("Unknown error");
388 if (rrd_test_error())
390 /* all errors are unrecoverable */
395 token = strtok_r(NULL,":", &tokptr);
400 fprintf(stderr,"Creating RRA CF: %s, dep idx %lu, current idx %lu\n",
401 rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam,
402 rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_dependent_rra_idx].u_cnt,
403 rrd.stat_head -> rra_cnt);
405 /* should we create CF_SEASONAL, CF_DEVSEASONAL, and CF_DEVPREDICT? */
406 if (cf_conv(rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam) == CF_HWPREDICT
407 && rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_dependent_rra_idx].u_cnt
408 == rrd.stat_head -> rra_cnt)
411 fprintf(stderr,"Creating HW contingent RRAs\n");
413 if (create_hw_contingent_rras(&rrd,period,hashed_name) == -1) {
414 rrd_set_error("creating contingent RRA");
419 rrd.stat_head->rra_cnt++;
421 rrd_set_error("can't parse argument '%s'",argv[i]);
428 if (rrd.stat_head->rra_cnt < 1){
429 rrd_set_error("you must define at least one Round Robin Archive");
434 if (rrd.stat_head->ds_cnt < 1){
435 rrd_set_error("you must define at least one Data Source");
439 return rrd_create_fn(filename, &rrd);
442 void parseGENERIC_DS(const char *def,rrd_t *rrd, int ds_idx)
444 char minstr[DS_NAM_SIZE], maxstr[DS_NAM_SIZE];
448 temp = sscanf(def,"%lu:%18[^:]:%18[^:]",
449 &(rrd -> ds_def[ds_idx].par[DS_mrhb_cnt].u_cnt),
452 if (sscanf(def,"%lu:%18[^:]:%18[^:]",
453 &(rrd -> ds_def[ds_idx].par[DS_mrhb_cnt].u_cnt),
456 if (minstr[0] == 'U' && minstr[1] == 0)
457 rrd -> ds_def[ds_idx].par[DS_min_val].u_val = DNAN;
459 rrd -> ds_def[ds_idx].par[DS_min_val].u_val = atof(minstr);
461 if (maxstr[0] == 'U' && maxstr[1] == 0)
462 rrd -> ds_def[ds_idx].par[DS_max_val].u_val = DNAN;
464 rrd -> ds_def[ds_idx].par[DS_max_val].u_val = atof(maxstr);
466 if (! isnan(rrd -> ds_def[ds_idx].par[DS_min_val].u_val) &&
467 ! isnan(rrd -> ds_def[ds_idx].par[DS_max_val].u_val) &&
468 rrd -> ds_def[ds_idx].par[DS_min_val].u_val
469 >= rrd -> ds_def[ds_idx].par[DS_max_val].u_val ) {
470 rrd_set_error("min must be less than max in DS definition");
474 rrd_set_error("failed to parse data source %s", def);
478 /* Create the CF_DEVPREDICT, CF_DEVSEASONAL, CF_SEASONAL, and CF_FAILURES RRAs
479 * associated with a CF_HWPREDICT RRA. */
481 create_hw_contingent_rras(rrd_t *rrd, unsigned short period, unsigned long hashed_name)
484 rra_def_t* current_rra;
486 /* save index to CF_HWPREDICT */
487 unsigned long hw_index = rrd -> stat_head -> rra_cnt;
488 /* advance the pointer */
489 (rrd -> stat_head -> rra_cnt)++;
490 /* allocate the memory for the 4 contingent RRAs */
491 old_size = sizeof(rra_def_t)*(rrd -> stat_head->rra_cnt);
492 if ((rrd -> rra_def = rrd_realloc(rrd -> rra_def,
493 old_size+4*sizeof(rra_def_t)))==NULL)
495 rrd_set_error("allocating rrd.rra_def");
499 memset(&(rrd -> rra_def[rrd -> stat_head->rra_cnt]), 0, 4*sizeof(rra_def_t));
501 /* create the CF_SEASONAL RRA */
502 current_rra = &(rrd -> rra_def[rrd -> stat_head -> rra_cnt]);
503 strcpy(current_rra -> cf_nam,"SEASONAL");
504 current_rra -> row_cnt = period;
505 current_rra -> par[RRA_seasonal_smooth_idx].u_cnt = hashed_name % period;
506 current_rra -> pdp_cnt = 1;
507 current_rra -> par[RRA_seasonal_gamma].u_val =
508 rrd -> rra_def[hw_index].par[RRA_hw_alpha].u_val;
509 current_rra -> par[RRA_dependent_rra_idx].u_cnt = hw_index;
510 rrd -> rra_def[hw_index].par[RRA_dependent_rra_idx].u_cnt = rrd -> stat_head -> rra_cnt;
512 /* create the CF_DEVSEASONAL RRA */
513 (rrd -> stat_head -> rra_cnt)++;
514 current_rra = &(rrd -> rra_def[rrd -> stat_head -> rra_cnt]);
515 strcpy(current_rra -> cf_nam,"DEVSEASONAL");
516 current_rra -> row_cnt = period;
517 current_rra -> par[RRA_seasonal_smooth_idx].u_cnt = hashed_name % period;
518 current_rra -> pdp_cnt = 1;
519 current_rra -> par[RRA_seasonal_gamma].u_val =
520 rrd -> rra_def[hw_index].par[RRA_hw_alpha].u_val;
521 current_rra -> par[RRA_dependent_rra_idx].u_cnt = hw_index;
523 /* create the CF_DEVPREDICT RRA */
524 (rrd -> stat_head -> rra_cnt)++;
525 current_rra = &(rrd -> rra_def[rrd -> stat_head -> rra_cnt]);
526 strcpy(current_rra -> cf_nam,"DEVPREDICT");
527 current_rra -> row_cnt = (rrd -> rra_def[hw_index]).row_cnt;
528 current_rra -> pdp_cnt = 1;
529 current_rra -> par[RRA_dependent_rra_idx].u_cnt
530 = hw_index + 2; /* DEVSEASONAL */
532 /* create the CF_FAILURES RRA */
533 (rrd -> stat_head -> rra_cnt)++;
534 current_rra = &(rrd -> rra_def[rrd -> stat_head -> rra_cnt]);
535 strcpy(current_rra -> cf_nam,"FAILURES");
536 current_rra -> row_cnt = period;
537 current_rra -> pdp_cnt = 1;
538 current_rra -> par[RRA_delta_pos].u_val = 2.0;
539 current_rra -> par[RRA_delta_neg].u_val = 2.0;
540 current_rra -> par[RRA_failure_threshold].u_cnt = 7;
541 current_rra -> par[RRA_window_len].u_cnt = 9;
542 current_rra -> par[RRA_dependent_rra_idx].u_cnt =
543 hw_index + 2; /* DEVSEASONAL */
547 /* create and empty rrd file according to the specs given */
550 rrd_create_fn(const char *file_name, rrd_t *rrd)
554 rrd_value_t *unknown;
559 if ((rrd_file = fopen(file_name,"wb")) == NULL ) {
560 rrd_set_error("creating '%s': %s",file_name, rrd_strerror(errno));
561 free(rrd->stat_head);
562 rrd->stat_head = NULL;
570 fwrite(rrd->stat_head,
571 sizeof(stat_head_t), 1, rrd_file);
574 sizeof(ds_def_t), rrd->stat_head->ds_cnt, rrd_file);
577 sizeof(rra_def_t), rrd->stat_head->rra_cnt, rrd_file);
579 fwrite(rrd->live_head,
580 sizeof(live_head_t),1, rrd_file);
582 if((rrd->pdp_prep = calloc(1,sizeof(pdp_prep_t))) == NULL){
583 rrd_set_error("allocating pdp_prep");
589 strcpy(rrd->pdp_prep->last_ds,"UNKN");
591 rrd->pdp_prep->scratch[PDP_val].u_val = 0.0;
592 rrd->pdp_prep->scratch[PDP_unkn_sec_cnt].u_cnt =
593 rrd->live_head->last_up % rrd->stat_head->pdp_step;
595 for(i=0; i < rrd->stat_head->ds_cnt; i++)
596 fwrite( rrd->pdp_prep,sizeof(pdp_prep_t),1,rrd_file);
598 if((rrd->cdp_prep = calloc(1,sizeof(cdp_prep_t))) == NULL){
599 rrd_set_error("allocating cdp_prep");
606 for(i=0; i < rrd->stat_head->rra_cnt; i++) {
607 switch (cf_conv(rrd->rra_def[i].cf_nam))
610 init_hwpredict_cdp(rrd->cdp_prep);
614 init_seasonal_cdp(rrd->cdp_prep);
617 /* initialize violation history to 0 */
618 for (ii = 0; ii < MAX_CDP_PAR_EN; ii++)
620 /* We can zero everything out, by setting u_val to the
621 * NULL address. Each array entry in scratch is 8 bytes
622 * (a double), but u_cnt only accessed 4 bytes (long) */
623 rrd->cdp_prep->scratch[ii].u_val = 0.0;
627 /* can not be zero because we don't know anything ... */
628 rrd->cdp_prep->scratch[CDP_val].u_val = DNAN;
629 /* startup missing pdp count */
630 rrd->cdp_prep->scratch[CDP_unkn_pdp_cnt].u_cnt =
631 ((rrd->live_head->last_up -
632 rrd->pdp_prep->scratch[PDP_unkn_sec_cnt].u_cnt)
633 % (rrd->stat_head->pdp_step
634 * rrd->rra_def[i].pdp_cnt)) / rrd->stat_head->pdp_step;
638 for(ii=0; ii < rrd->stat_head->ds_cnt; ii++)
640 fwrite( rrd->cdp_prep,sizeof(cdp_prep_t),1,rrd_file);
644 /* now, we must make sure that the rest of the rrd
645 struct is properly initialized */
647 if((rrd->rra_ptr = calloc(1,sizeof(rra_ptr_t))) == NULL) {
648 rrd_set_error("allocating rra_ptr");
654 /* changed this initialization to be consistent with
655 * rrd_restore. With the old value (0), the first update
656 * would occur for cur_row = 1 because rrd_update increments
657 * the pointer a priori. */
658 for (i=0; i < rrd->stat_head->rra_cnt; i++)
660 rrd->rra_ptr->cur_row = rrd->rra_def[i].row_cnt - 1;
661 fwrite( rrd->rra_ptr, sizeof(rra_ptr_t),1,rrd_file);
663 rrd_head_size = ftell(rrd_file);
665 /* write the empty data area */
666 if ((unknown = (rrd_value_t *)malloc(512 * sizeof(rrd_value_t))) == NULL) {
667 rrd_set_error("allocating unknown");
672 for (i = 0; i < 512; ++i)
676 for (i = 0; i < rrd->stat_head->rra_cnt; i++)
677 unkn_cnt += rrd->stat_head->ds_cnt * rrd->rra_def[i].row_cnt;
679 while (unkn_cnt > 0) {
680 fwrite(unknown, sizeof(rrd_value_t), min(unkn_cnt, 512), rrd_file);
685 /* lets see if we had an error */
686 if(ferror(rrd_file)){
687 rrd_set_error("a file error occurred while creating '%s'",file_name);
693 #ifdef HAVE_POSIX_FADVISE
694 /* this file is not going to be read again any time
695 soon, so we drop everything except the header portion from
696 the buffer cache. for this to work, we have to fdsync the file
697 first though. This will not be all that fast, but 'good' data
698 like other rrdfiles headers will stay in cache. Now this only works if creating
699 a single rrd file is not too large, but I assume this should not be the case
700 in general. Otherwhise we would have to sync and release while writing all
703 fdatasync(fileno(rrd_file));
704 if (0 != posix_fadvise(fileno(rrd_file), rrd_head_size, 0, POSIX_FADV_DONTNEED)) {
705 rrd_set_error("setting POSIX_FADV_DONTNEED on '%s': %s",file_name, rrd_strerror(errno));