]> arthur.barton.de Git - netdata.git/blob - src/common.c
Merge pull request #912 from sehraf/master
[netdata.git] / src / common.c
1 #include "common.h"
2
3 char *global_host_prefix = "";
4 int enable_ksm = 1;
5
6 volatile sig_atomic_t netdata_exit = 0;
7
8 // ----------------------------------------------------------------------------
9 // memory allocation functions that handle failures
10
11 // although netdata does not use memory allocations too often (netdata tries to
12 // maintain its memory footprint stable during runtime, i.e. all buffers are
13 // allocated during initialization and are adapted to current use throughout
14 // its lifetime), these can be used to override the default system allocation
15 // routines.
16
17 char *strdupz(const char *s) {
18     char *t = strdup(s);
19     if (unlikely(!t)) fatal("Cannot strdup() string '%s'", s);
20     return t;
21 }
22
23 void *mallocz(size_t size) {
24     void *p = malloc(size);
25     if (unlikely(!p)) fatal("Cannot allocate %zu bytes of memory.", size);
26     return p;
27 }
28
29 void *callocz(size_t nmemb, size_t size) {
30     void *p = calloc(nmemb, size);
31     if (unlikely(!p)) fatal("Cannot allocate %zu bytes of memory.", nmemb * size);
32     return p;
33 }
34
35 void *reallocz(void *ptr, size_t size) {
36     void *p = realloc(ptr, size);
37     if (unlikely(!p)) fatal("Cannot re-allocate memory to %zu bytes.", size);
38     return p;
39 }
40
41 void freez(void *ptr) {
42     free(ptr);
43 }
44
45 // ----------------------------------------------------------------------------
46 // time functions
47
48 inline unsigned long long timeval_usec(struct timeval *tv) {
49     return tv->tv_sec * 1000000ULL + tv->tv_usec;
50 }
51
52 // time(NULL) in nanoseconds
53 inline unsigned long long time_usec(void) {
54     struct timeval now;
55     gettimeofday(&now, NULL);
56     return timeval_usec(&now);
57 }
58
59 inline unsigned long long usec_dt(struct timeval *now, struct timeval *old) {
60     unsigned long long tv1 = timeval_usec(now);
61     unsigned long long tv2 = timeval_usec(old);
62     return (tv1 > tv2) ? (tv1 - tv2) : (tv2 - tv1);
63 }
64
65 int sleep_usec(unsigned long long usec) {
66
67 #ifndef NETDATA_WITH_USLEEP
68     // we expect microseconds (1.000.000 per second)
69     // but timespec is nanoseconds (1.000.000.000 per second)
70     struct timespec rem, req = {
71             .tv_sec = (time_t) (usec / 1000000),
72             .tv_nsec = (suseconds_t) ((usec % 1000000) * 1000)
73     };
74
75     while (nanosleep(&req, &rem) == -1) {
76         if (likely(errno == EINTR)) {
77             info("nanosleep() interrupted (while sleeping for %llu microseconds).", usec);
78             req.tv_sec = rem.tv_sec;
79             req.tv_nsec = rem.tv_nsec;
80         } else {
81             error("Cannot nanosleep() for %llu microseconds.", usec);
82             break;
83         }
84     }
85
86     return 0;
87 #else
88     int ret = usleep(usec);
89     if(unlikely(ret == -1 && errno == EINVAL)) {
90         // on certain systems, usec has to be up to 999999
91         if(usec > 999999) {
92             int counter = usec / 999999;
93             while(counter--)
94                 usleep(999999);
95
96             usleep(usec % 999999);
97         }
98         else {
99             error("Cannot usleep() for %llu microseconds.", usec);
100             return ret;
101         }
102     }
103
104     if(ret != 0)
105         error("usleep() failed for %llu microseconds.", usec);
106
107     return ret;
108 #endif
109 }
110
111 unsigned char netdata_map_chart_names[256] = {
112         [0] = '\0', //
113         [1] = '_', //
114         [2] = '_', //
115         [3] = '_', //
116         [4] = '_', //
117         [5] = '_', //
118         [6] = '_', //
119         [7] = '_', //
120         [8] = '_', //
121         [9] = '_', //
122         [10] = '_', //
123         [11] = '_', //
124         [12] = '_', //
125         [13] = '_', //
126         [14] = '_', //
127         [15] = '_', //
128         [16] = '_', //
129         [17] = '_', //
130         [18] = '_', //
131         [19] = '_', //
132         [20] = '_', //
133         [21] = '_', //
134         [22] = '_', //
135         [23] = '_', //
136         [24] = '_', //
137         [25] = '_', //
138         [26] = '_', //
139         [27] = '_', //
140         [28] = '_', //
141         [29] = '_', //
142         [30] = '_', //
143         [31] = '_', //
144         [32] = '_', //
145         [33] = '_', // !
146         [34] = '_', // "
147         [35] = '_', // #
148         [36] = '_', // $
149         [37] = '_', // %
150         [38] = '_', // &
151         [39] = '_', // '
152         [40] = '_', // (
153         [41] = '_', // )
154         [42] = '_', // *
155         [43] = '_', // +
156         [44] = '.', // ,
157         [45] = '-', // -
158         [46] = '.', // .
159         [47] = '/', // /
160         [48] = '0', // 0
161         [49] = '1', // 1
162         [50] = '2', // 2
163         [51] = '3', // 3
164         [52] = '4', // 4
165         [53] = '5', // 5
166         [54] = '6', // 6
167         [55] = '7', // 7
168         [56] = '8', // 8
169         [57] = '9', // 9
170         [58] = '_', // :
171         [59] = '_', // ;
172         [60] = '_', // <
173         [61] = '_', // =
174         [62] = '_', // >
175         [63] = '_', // ?
176         [64] = '_', // @
177         [65] = 'a', // A
178         [66] = 'b', // B
179         [67] = 'c', // C
180         [68] = 'd', // D
181         [69] = 'e', // E
182         [70] = 'f', // F
183         [71] = 'g', // G
184         [72] = 'h', // H
185         [73] = 'i', // I
186         [74] = 'j', // J
187         [75] = 'k', // K
188         [76] = 'l', // L
189         [77] = 'm', // M
190         [78] = 'n', // N
191         [79] = 'o', // O
192         [80] = 'p', // P
193         [81] = 'q', // Q
194         [82] = 'r', // R
195         [83] = 's', // S
196         [84] = 't', // T
197         [85] = 'u', // U
198         [86] = 'v', // V
199         [87] = 'w', // W
200         [88] = 'x', // X
201         [89] = 'y', // Y
202         [90] = 'z', // Z
203         [91] = '_', // [
204         [92] = '/', // backslash
205         [93] = '_', // ]
206         [94] = '_', // ^
207         [95] = '_', // _
208         [96] = '_', // `
209         [97] = 'a', // a
210         [98] = 'b', // b
211         [99] = 'c', // c
212         [100] = 'd', // d
213         [101] = 'e', // e
214         [102] = 'f', // f
215         [103] = 'g', // g
216         [104] = 'h', // h
217         [105] = 'i', // i
218         [106] = 'j', // j
219         [107] = 'k', // k
220         [108] = 'l', // l
221         [109] = 'm', // m
222         [110] = 'n', // n
223         [111] = 'o', // o
224         [112] = 'p', // p
225         [113] = 'q', // q
226         [114] = 'r', // r
227         [115] = 's', // s
228         [116] = 't', // t
229         [117] = 'u', // u
230         [118] = 'v', // v
231         [119] = 'w', // w
232         [120] = 'x', // x
233         [121] = 'y', // y
234         [122] = 'z', // z
235         [123] = '_', // {
236         [124] = '_', // |
237         [125] = '_', // }
238         [126] = '_', // ~
239         [127] = '_', //
240         [128] = '_', //
241         [129] = '_', //
242         [130] = '_', //
243         [131] = '_', //
244         [132] = '_', //
245         [133] = '_', //
246         [134] = '_', //
247         [135] = '_', //
248         [136] = '_', //
249         [137] = '_', //
250         [138] = '_', //
251         [139] = '_', //
252         [140] = '_', //
253         [141] = '_', //
254         [142] = '_', //
255         [143] = '_', //
256         [144] = '_', //
257         [145] = '_', //
258         [146] = '_', //
259         [147] = '_', //
260         [148] = '_', //
261         [149] = '_', //
262         [150] = '_', //
263         [151] = '_', //
264         [152] = '_', //
265         [153] = '_', //
266         [154] = '_', //
267         [155] = '_', //
268         [156] = '_', //
269         [157] = '_', //
270         [158] = '_', //
271         [159] = '_', //
272         [160] = '_', //
273         [161] = '_', //
274         [162] = '_', //
275         [163] = '_', //
276         [164] = '_', //
277         [165] = '_', //
278         [166] = '_', //
279         [167] = '_', //
280         [168] = '_', //
281         [169] = '_', //
282         [170] = '_', //
283         [171] = '_', //
284         [172] = '_', //
285         [173] = '_', //
286         [174] = '_', //
287         [175] = '_', //
288         [176] = '_', //
289         [177] = '_', //
290         [178] = '_', //
291         [179] = '_', //
292         [180] = '_', //
293         [181] = '_', //
294         [182] = '_', //
295         [183] = '_', //
296         [184] = '_', //
297         [185] = '_', //
298         [186] = '_', //
299         [187] = '_', //
300         [188] = '_', //
301         [189] = '_', //
302         [190] = '_', //
303         [191] = '_', //
304         [192] = '_', //
305         [193] = '_', //
306         [194] = '_', //
307         [195] = '_', //
308         [196] = '_', //
309         [197] = '_', //
310         [198] = '_', //
311         [199] = '_', //
312         [200] = '_', //
313         [201] = '_', //
314         [202] = '_', //
315         [203] = '_', //
316         [204] = '_', //
317         [205] = '_', //
318         [206] = '_', //
319         [207] = '_', //
320         [208] = '_', //
321         [209] = '_', //
322         [210] = '_', //
323         [211] = '_', //
324         [212] = '_', //
325         [213] = '_', //
326         [214] = '_', //
327         [215] = '_', //
328         [216] = '_', //
329         [217] = '_', //
330         [218] = '_', //
331         [219] = '_', //
332         [220] = '_', //
333         [221] = '_', //
334         [222] = '_', //
335         [223] = '_', //
336         [224] = '_', //
337         [225] = '_', //
338         [226] = '_', //
339         [227] = '_', //
340         [228] = '_', //
341         [229] = '_', //
342         [230] = '_', //
343         [231] = '_', //
344         [232] = '_', //
345         [233] = '_', //
346         [234] = '_', //
347         [235] = '_', //
348         [236] = '_', //
349         [237] = '_', //
350         [238] = '_', //
351         [239] = '_', //
352         [240] = '_', //
353         [241] = '_', //
354         [242] = '_', //
355         [243] = '_', //
356         [244] = '_', //
357         [245] = '_', //
358         [246] = '_', //
359         [247] = '_', //
360         [248] = '_', //
361         [249] = '_', //
362         [250] = '_', //
363         [251] = '_', //
364         [252] = '_', //
365         [253] = '_', //
366         [254] = '_', //
367         [255] = '_'  //
368 };
369
370 // make sure the supplied string
371 // is good for a netdata chart/dimension ID/NAME
372 void netdata_fix_chart_name(char *s) {
373     while ((*s = netdata_map_chart_names[(unsigned char) *s])) s++;
374 }
375
376 unsigned char netdata_map_chart_ids[256] = {
377         [0] = '\0', //
378         [1] = '_', //
379         [2] = '_', //
380         [3] = '_', //
381         [4] = '_', //
382         [5] = '_', //
383         [6] = '_', //
384         [7] = '_', //
385         [8] = '_', //
386         [9] = '_', //
387         [10] = '_', //
388         [11] = '_', //
389         [12] = '_', //
390         [13] = '_', //
391         [14] = '_', //
392         [15] = '_', //
393         [16] = '_', //
394         [17] = '_', //
395         [18] = '_', //
396         [19] = '_', //
397         [20] = '_', //
398         [21] = '_', //
399         [22] = '_', //
400         [23] = '_', //
401         [24] = '_', //
402         [25] = '_', //
403         [26] = '_', //
404         [27] = '_', //
405         [28] = '_', //
406         [29] = '_', //
407         [30] = '_', //
408         [31] = '_', //
409         [32] = '_', //
410         [33] = '_', // !
411         [34] = '_', // "
412         [35] = '_', // #
413         [36] = '_', // $
414         [37] = '_', // %
415         [38] = '_', // &
416         [39] = '_', // '
417         [40] = '_', // (
418         [41] = '_', // )
419         [42] = '_', // *
420         [43] = '_', // +
421         [44] = '.', // ,
422         [45] = '-', // -
423         [46] = '.', // .
424         [47] = '_', // /
425         [48] = '0', // 0
426         [49] = '1', // 1
427         [50] = '2', // 2
428         [51] = '3', // 3
429         [52] = '4', // 4
430         [53] = '5', // 5
431         [54] = '6', // 6
432         [55] = '7', // 7
433         [56] = '8', // 8
434         [57] = '9', // 9
435         [58] = '_', // :
436         [59] = '_', // ;
437         [60] = '_', // <
438         [61] = '_', // =
439         [62] = '_', // >
440         [63] = '_', // ?
441         [64] = '_', // @
442         [65] = 'a', // A
443         [66] = 'b', // B
444         [67] = 'c', // C
445         [68] = 'd', // D
446         [69] = 'e', // E
447         [70] = 'f', // F
448         [71] = 'g', // G
449         [72] = 'h', // H
450         [73] = 'i', // I
451         [74] = 'j', // J
452         [75] = 'k', // K
453         [76] = 'l', // L
454         [77] = 'm', // M
455         [78] = 'n', // N
456         [79] = 'o', // O
457         [80] = 'p', // P
458         [81] = 'q', // Q
459         [82] = 'r', // R
460         [83] = 's', // S
461         [84] = 't', // T
462         [85] = 'u', // U
463         [86] = 'v', // V
464         [87] = 'w', // W
465         [88] = 'x', // X
466         [89] = 'y', // Y
467         [90] = 'z', // Z
468         [91] = '_', // [
469         [92] = '/', // backslash
470         [93] = '_', // ]
471         [94] = '_', // ^
472         [95] = '_', // _
473         [96] = '_', // `
474         [97] = 'a', // a
475         [98] = 'b', // b
476         [99] = 'c', // c
477         [100] = 'd', // d
478         [101] = 'e', // e
479         [102] = 'f', // f
480         [103] = 'g', // g
481         [104] = 'h', // h
482         [105] = 'i', // i
483         [106] = 'j', // j
484         [107] = 'k', // k
485         [108] = 'l', // l
486         [109] = 'm', // m
487         [110] = 'n', // n
488         [111] = 'o', // o
489         [112] = 'p', // p
490         [113] = 'q', // q
491         [114] = 'r', // r
492         [115] = 's', // s
493         [116] = 't', // t
494         [117] = 'u', // u
495         [118] = 'v', // v
496         [119] = 'w', // w
497         [120] = 'x', // x
498         [121] = 'y', // y
499         [122] = 'z', // z
500         [123] = '_', // {
501         [124] = '_', // |
502         [125] = '_', // }
503         [126] = '_', // ~
504         [127] = '_', //
505         [128] = '_', //
506         [129] = '_', //
507         [130] = '_', //
508         [131] = '_', //
509         [132] = '_', //
510         [133] = '_', //
511         [134] = '_', //
512         [135] = '_', //
513         [136] = '_', //
514         [137] = '_', //
515         [138] = '_', //
516         [139] = '_', //
517         [140] = '_', //
518         [141] = '_', //
519         [142] = '_', //
520         [143] = '_', //
521         [144] = '_', //
522         [145] = '_', //
523         [146] = '_', //
524         [147] = '_', //
525         [148] = '_', //
526         [149] = '_', //
527         [150] = '_', //
528         [151] = '_', //
529         [152] = '_', //
530         [153] = '_', //
531         [154] = '_', //
532         [155] = '_', //
533         [156] = '_', //
534         [157] = '_', //
535         [158] = '_', //
536         [159] = '_', //
537         [160] = '_', //
538         [161] = '_', //
539         [162] = '_', //
540         [163] = '_', //
541         [164] = '_', //
542         [165] = '_', //
543         [166] = '_', //
544         [167] = '_', //
545         [168] = '_', //
546         [169] = '_', //
547         [170] = '_', //
548         [171] = '_', //
549         [172] = '_', //
550         [173] = '_', //
551         [174] = '_', //
552         [175] = '_', //
553         [176] = '_', //
554         [177] = '_', //
555         [178] = '_', //
556         [179] = '_', //
557         [180] = '_', //
558         [181] = '_', //
559         [182] = '_', //
560         [183] = '_', //
561         [184] = '_', //
562         [185] = '_', //
563         [186] = '_', //
564         [187] = '_', //
565         [188] = '_', //
566         [189] = '_', //
567         [190] = '_', //
568         [191] = '_', //
569         [192] = '_', //
570         [193] = '_', //
571         [194] = '_', //
572         [195] = '_', //
573         [196] = '_', //
574         [197] = '_', //
575         [198] = '_', //
576         [199] = '_', //
577         [200] = '_', //
578         [201] = '_', //
579         [202] = '_', //
580         [203] = '_', //
581         [204] = '_', //
582         [205] = '_', //
583         [206] = '_', //
584         [207] = '_', //
585         [208] = '_', //
586         [209] = '_', //
587         [210] = '_', //
588         [211] = '_', //
589         [212] = '_', //
590         [213] = '_', //
591         [214] = '_', //
592         [215] = '_', //
593         [216] = '_', //
594         [217] = '_', //
595         [218] = '_', //
596         [219] = '_', //
597         [220] = '_', //
598         [221] = '_', //
599         [222] = '_', //
600         [223] = '_', //
601         [224] = '_', //
602         [225] = '_', //
603         [226] = '_', //
604         [227] = '_', //
605         [228] = '_', //
606         [229] = '_', //
607         [230] = '_', //
608         [231] = '_', //
609         [232] = '_', //
610         [233] = '_', //
611         [234] = '_', //
612         [235] = '_', //
613         [236] = '_', //
614         [237] = '_', //
615         [238] = '_', //
616         [239] = '_', //
617         [240] = '_', //
618         [241] = '_', //
619         [242] = '_', //
620         [243] = '_', //
621         [244] = '_', //
622         [245] = '_', //
623         [246] = '_', //
624         [247] = '_', //
625         [248] = '_', //
626         [249] = '_', //
627         [250] = '_', //
628         [251] = '_', //
629         [252] = '_', //
630         [253] = '_', //
631         [254] = '_', //
632         [255] = '_'  //
633 };
634
635 // make sure the supplied string
636 // is good for a netdata chart/dimension ID/NAME
637 void netdata_fix_chart_id(char *s) {
638     while ((*s = netdata_map_chart_ids[(unsigned char) *s])) s++;
639 }
640
641 /*
642 // http://stackoverflow.com/questions/7666509/hash-function-for-string
643 uint32_t simple_hash(const char *name)
644 {
645     const char *s = name;
646     uint32_t hash = 5381;
647     int i;
648
649     while((i = *s++)) hash = ((hash << 5) + hash) + i;
650
651     // fprintf(stderr, "HASH: %lu %s\n", hash, name);
652
653     return hash;
654 }
655 */
656
657
658 // http://isthe.com/chongo/tech/comp/fnv/#FNV-1a
659 uint32_t simple_hash(const char *name) {
660     unsigned char *s = (unsigned char *) name;
661     uint32_t hval = 0x811c9dc5;
662
663     // FNV-1a algorithm
664     while (*s) {
665         // multiply by the 32 bit FNV magic prime mod 2^32
666         // NOTE: No need to optimize with left shifts.
667         //       GCC will use imul instruction anyway.
668         //       Tested with 'gcc -O3 -S'
669         //hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24);
670         hval *= 16777619;
671
672         // xor the bottom with the current octet
673         hval ^= (uint32_t) *s++;
674     }
675
676     // fprintf(stderr, "HASH: %u = %s\n", hval, name);
677     return hval;
678 }
679
680 uint32_t simple_uhash(const char *name) {
681     unsigned char *s = (unsigned char *) name;
682     uint32_t hval = 0x811c9dc5, c;
683
684     // FNV-1a algorithm
685     while ((c = *s++)) {
686         if (unlikely(c >= 'A' && c <= 'Z')) c += 'a' - 'A';
687         hval *= 16777619;
688         hval ^= c;
689     }
690     return hval;
691 }
692
693 /*
694 // http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx
695 // one at a time hash
696 uint32_t simple_hash(const char *name) {
697     unsigned char *s = (unsigned char *)name;
698     uint32_t h = 0;
699
700     while(*s) {
701         h += *s++;
702         h += (h << 10);
703         h ^= (h >> 6);
704     }
705
706     h += (h << 3);
707     h ^= (h >> 11);
708     h += (h << 15);
709
710     // fprintf(stderr, "HASH: %u = %s\n", h, name);
711
712     return h;
713 }
714 */
715
716 void strreverse(char *begin, char *end) {
717     char aux;
718
719     while (end > begin) {
720         // clearer code.
721         aux = *end;
722         *end-- = *begin;
723         *begin++ = aux;
724     }
725 }
726
727 char *mystrsep(char **ptr, char *s) {
728     char *p = "";
729     while (p && !p[0] && *ptr) p = strsep(ptr, s);
730     return (p);
731 }
732
733 char *trim(char *s) {
734     // skip leading spaces
735     // and 'comments' as well!?
736     while (*s && isspace(*s)) s++;
737     if (!*s || *s == '#') return NULL;
738
739     // skip tailing spaces
740     // this way is way faster. Writes only one NUL char.
741     ssize_t l = strlen(s);
742     if (--l >= 0) {
743         char *p = s + l;
744         while (p > s && isspace(*p)) p--;
745         *++p = '\0';
746     }
747
748     if (!*s) return NULL;
749
750     return s;
751 }
752
753 void *mymmap(const char *filename, size_t size, int flags, int ksm) {
754     static int log_madvise_1 = 1;
755 #ifdef MADV_MERGEABLE
756     static int log_madvise_2 = 1, log_madvise_3 = 1;
757 #endif
758     int fd;
759     void *mem = NULL;
760
761     errno = 0;
762     fd = open(filename, O_RDWR | O_CREAT | O_NOATIME, 0664);
763     if (fd != -1) {
764         if (lseek(fd, size, SEEK_SET) == (off_t) size) {
765             if (write(fd, "", 1) == 1) {
766                 if (ftruncate(fd, size))
767                     error("Cannot truncate file '%s' to size %zu. Will use the larger file.", filename, size);
768
769 #ifdef MADV_MERGEABLE
770                 if (flags & MAP_SHARED || !enable_ksm || !ksm) {
771 #endif
772                     mem = mmap(NULL, size, PROT_READ | PROT_WRITE, flags, fd, 0);
773                     if (mem != MAP_FAILED) {
774                         int advise = MADV_SEQUENTIAL | MADV_DONTFORK;
775                         if (flags & MAP_SHARED) advise |= MADV_WILLNEED;
776
777                         if (madvise(mem, size, advise) != 0 && log_madvise_1) {
778                             error("Cannot advise the kernel about the memory usage of file '%s'.", filename);
779                             log_madvise_1--;
780                         }
781                     }
782 #ifdef MADV_MERGEABLE
783                 } else {
784 /*
785                     // test - load the file into memory
786                     mem = calloc(1, size);
787                     if(mem) {
788                         if(lseek(fd, 0, SEEK_SET) == 0) {
789                             if(read(fd, mem, size) != (ssize_t)size)
790                                 error("Cannot read from file '%s'", filename);
791                         }
792                         else
793                             error("Cannot seek to beginning of file '%s'.", filename);
794                     }
795 */
796                     mem = mmap(NULL, size, PROT_READ | PROT_WRITE, flags | MAP_ANONYMOUS, -1, 0);
797                     if (mem != MAP_FAILED) {
798                         if (lseek(fd, 0, SEEK_SET) == 0) {
799                             if (read(fd, mem, size) != (ssize_t) size)
800                                 error("Cannot read from file '%s'", filename);
801                         } else
802                             error("Cannot seek to beginning of file '%s'.", filename);
803
804                         // don't use MADV_SEQUENTIAL|MADV_DONTFORK, they disable MADV_MERGEABLE
805                         if (madvise(mem, size, MADV_SEQUENTIAL | MADV_DONTFORK) != 0 && log_madvise_2) {
806                             error("Cannot advise the kernel about the memory usage (MADV_SEQUENTIAL|MADV_DONTFORK) of file '%s'.",
807                                   filename);
808                             log_madvise_2--;
809                         }
810
811                         if (madvise(mem, size, MADV_MERGEABLE) != 0 && log_madvise_3) {
812                             error("Cannot advise the kernel about the memory usage (MADV_MERGEABLE) of file '%s'.",
813                                   filename);
814                             log_madvise_3--;
815                         }
816                     } else
817                         error("Cannot allocate PRIVATE ANONYMOUS memory for KSM for file '%s'.", filename);
818                 }
819 #endif
820             } else
821                 error("Cannot write to file '%s' at position %zu.", filename, size);
822         } else
823             error("Cannot seek file '%s' to size %zu.", filename, size);
824
825         close(fd);
826     } else
827         error("Cannot create/open file '%s'.", filename);
828
829     return mem;
830 }
831
832 int savememory(const char *filename, void *mem, size_t size) {
833     char tmpfilename[FILENAME_MAX + 1];
834
835     snprintfz(tmpfilename, FILENAME_MAX, "%s.%ld.tmp", filename, (long) getpid());
836
837     int fd = open(tmpfilename, O_RDWR | O_CREAT | O_NOATIME, 0664);
838     if (fd < 0) {
839         error("Cannot create/open file '%s'.", filename);
840         return -1;
841     }
842
843     if (write(fd, mem, size) != (ssize_t) size) {
844         error("Cannot write to file '%s' %ld bytes.", filename, (long) size);
845         close(fd);
846         return -1;
847     }
848
849     close(fd);
850
851     if (rename(tmpfilename, filename)) {
852         error("Cannot rename '%s' to '%s'", tmpfilename, filename);
853         return -1;
854     }
855
856     return 0;
857 }
858
859 int fd_is_valid(int fd) {
860     return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
861 }
862
863 pid_t gettid(void) {
864     return (pid_t)syscall(SYS_gettid);
865 }
866
867 char *fgets_trim_len(char *buf, size_t buf_size, FILE *fp, size_t *len) {
868     char *s = fgets(buf, (int)buf_size, fp);
869     if (!s) return NULL;
870
871     char *t = s;
872     if (*t != '\0') {
873         // find the string end
874         while (*++t != '\0');
875
876         // trim trailing spaces/newlines/tabs
877         while (--t > s && *t == '\n')
878             *t = '\0';
879     }
880
881     if (len)
882         *len = t - s + 1;
883
884     return s;
885 }
886
887 char *strncpyz(char *dst, const char *src, size_t n) {
888     char *p = dst;
889
890     while (*src && n--)
891         *dst++ = *src++;
892
893     *dst = '\0';
894
895     return p;
896 }
897
898 int vsnprintfz(char *dst, size_t n, const char *fmt, va_list args) {
899     int size = vsnprintf(dst, n, fmt, args);
900
901     if (unlikely((size_t) size > n)) {
902         // truncated
903         size = (int)n;
904     }
905
906     dst[size] = '\0';
907     return size;
908 }
909
910 int snprintfz(char *dst, size_t n, const char *fmt, ...) {
911     va_list args;
912
913     va_start(args, fmt);
914     int ret = vsnprintfz(dst, n, fmt, args);
915     va_end(args);
916
917     return ret;
918 }
919
920 // ----------------------------------------------------------------------------
921 // system functions
922 // to retrieve settings of the system
923
924 int processors = 1;
925 long get_system_cpus(void) {
926     procfile *ff = NULL;
927
928     processors = 1;
929
930     char filename[FILENAME_MAX + 1];
931     snprintfz(filename, FILENAME_MAX, "%s/proc/stat", global_host_prefix);
932
933     ff = procfile_open(filename, NULL, PROCFILE_FLAG_DEFAULT);
934     if(!ff) {
935         error("Cannot open file '%s'. Assuming system has %d processors.", filename, processors);
936         return processors;
937     }
938
939     ff = procfile_readall(ff);
940     if(!ff) {
941         error("Cannot open file '%s'. Assuming system has %d processors.", filename, processors);
942         return processors;
943     }
944
945     processors = 0;
946     unsigned int i;
947     for(i = 0; i < procfile_lines(ff); i++) {
948         if(!procfile_linewords(ff, i)) continue;
949
950         if(strncmp(procfile_lineword(ff, i, 0), "cpu", 3) == 0) processors++;
951     }
952     processors--;
953     if(processors < 1) processors = 1;
954
955     procfile_close(ff);
956
957     info("System has %d processors.", processors);
958     return processors;
959 }
960
961 pid_t pid_max = 32768;
962 pid_t get_system_pid_max(void) {
963     procfile *ff = NULL;
964
965     char filename[FILENAME_MAX + 1];
966     snprintfz(filename, FILENAME_MAX, "%s/proc/sys/kernel/pid_max", global_host_prefix);
967     ff = procfile_open(filename, NULL, PROCFILE_FLAG_DEFAULT);
968     if(!ff) {
969         error("Cannot open file '%s'. Assuming system supports %d pids.", filename, pid_max);
970         return pid_max;
971     }
972
973     ff = procfile_readall(ff);
974     if(!ff) {
975         error("Cannot read file '%s'. Assuming system supports %d pids.", filename, pid_max);
976         return pid_max;
977     }
978
979     pid_max = (pid_t)atoi(procfile_lineword(ff, 0, 0));
980     if(!pid_max) {
981         procfile_close(ff);
982         pid_max = 32768;
983         error("Cannot parse file '%s'. Assuming system supports %d pids.", filename, pid_max);
984         return pid_max;
985     }
986
987     procfile_close(ff);
988     info("System supports %d pids.", pid_max);
989     return pid_max;
990 }
991
992 unsigned int hz;
993 void get_system_HZ(void) {
994     long ticks;
995
996     if ((ticks = sysconf(_SC_CLK_TCK)) == -1) {
997         perror("sysconf");
998     }
999
1000     hz = (unsigned int) ticks;
1001 }