X-Git-Url: https://arthur.barton.de/gitweb/?a=blobdiff_plain;f=src%2Fcommon.c;h=ea94ecc33baead4af53305c687ee01749dc96e45;hb=9dc4407074b37a1f0712dbbf8b34a0e5284fd018;hp=46cb182e4b0676691de4c956cc1e726f7b7f8b6a;hpb=67af57710d1fef400f48313bdff325f56e41778e;p=netdata.git diff --git a/src/common.c b/src/common.c old mode 100755 new mode 100644 index 46cb182e..ea94ecc3 --- a/src/common.c +++ b/src/common.c @@ -1,6 +1,7 @@ -// enable O_NOATIME -#define _GNU_SOURCE - +#ifdef HAVE_CONFIG_H +#include +#endif +#include #include #include #include @@ -13,6 +14,548 @@ #include "log.h" #include "common.h" +#include "appconfig.h" +#include "../config.h" + +char *global_host_prefix = ""; +int enable_ksm = 1; + +// time(NULL) in milliseconds +unsigned long long timems(void) { + struct timeval now; + gettimeofday(&now, NULL); + return now.tv_sec * 1000000ULL + now.tv_usec; +} + +unsigned char netdata_map_chart_names[256] = { + [0] = '\0', // + [1] = '_', // + [2] = '_', // + [3] = '_', // + [4] = '_', // + [5] = '_', // + [6] = '_', // + [7] = '_', // + [8] = '_', // + [9] = '_', // + [10] = '_', // + [11] = '_', // + [12] = '_', // + [13] = '_', // + [14] = '_', // + [15] = '_', // + [16] = '_', // + [17] = '_', // + [18] = '_', // + [19] = '_', // + [20] = '_', // + [21] = '_', // + [22] = '_', // + [23] = '_', // + [24] = '_', // + [25] = '_', // + [26] = '_', // + [27] = '_', // + [28] = '_', // + [29] = '_', // + [30] = '_', // + [31] = '_', // + [32] = '_', // + [33] = '_', // ! + [34] = '_', // " + [35] = '_', // # + [36] = '_', // $ + [37] = '_', // % + [38] = '_', // & + [39] = '_', // ' + [40] = '_', // ( + [41] = '_', // ) + [42] = '_', // * + [43] = '_', // + + [44] = '.', // , + [45] = '-', // - + [46] = '.', // . + [47] = '/', // / + [48] = '0', // 0 + [49] = '1', // 1 + [50] = '2', // 2 + [51] = '3', // 3 + [52] = '4', // 4 + [53] = '5', // 5 + [54] = '6', // 6 + [55] = '7', // 7 + [56] = '8', // 8 + [57] = '9', // 9 + [58] = '_', // : + [59] = '_', // ; + [60] = '_', // < + [61] = '_', // = + [62] = '_', // > + [63] = '_', // ? + [64] = '_', // @ + [65] = 'a', // A + [66] = 'b', // B + [67] = 'c', // C + [68] = 'd', // D + [69] = 'e', // E + [70] = 'f', // F + [71] = 'g', // G + [72] = 'h', // H + [73] = 'i', // I + [74] = 'j', // J + [75] = 'k', // K + [76] = 'l', // L + [77] = 'm', // M + [78] = 'n', // N + [79] = 'o', // O + [80] = 'p', // P + [81] = 'q', // Q + [82] = 'r', // R + [83] = 's', // S + [84] = 't', // T + [85] = 'u', // U + [86] = 'v', // V + [87] = 'w', // W + [88] = 'x', // X + [89] = 'y', // Y + [90] = 'z', // Z + [91] = '_', // [ + [92] = '/', // backslash + [93] = '_', // ] + [94] = '_', // ^ + [95] = '_', // _ + [96] = '_', // ` + [97] = 'a', // a + [98] = 'b', // b + [99] = 'c', // c + [100] = 'd', // d + [101] = 'e', // e + [102] = 'f', // f + [103] = 'g', // g + [104] = 'h', // h + [105] = 'i', // i + [106] = 'j', // j + [107] = 'k', // k + [108] = 'l', // l + [109] = 'm', // m + [110] = 'n', // n + [111] = 'o', // o + [112] = 'p', // p + [113] = 'q', // q + [114] = 'r', // r + [115] = 's', // s + [116] = 't', // t + [117] = 'u', // u + [118] = 'v', // v + [119] = 'w', // w + [120] = 'x', // x + [121] = 'y', // y + [122] = 'z', // z + [123] = '_', // { + [124] = '_', // | + [125] = '_', // } + [126] = '_', // ~ + [127] = '_', // + [128] = '_', // + [129] = '_', // + [130] = '_', // + [131] = '_', // + [132] = '_', // + [133] = '_', // + [134] = '_', // + [135] = '_', // + [136] = '_', // + [137] = '_', // + [138] = '_', // + [139] = '_', // + [140] = '_', // + [141] = '_', // + [142] = '_', // + [143] = '_', // + [144] = '_', // + [145] = '_', // + [146] = '_', // + [147] = '_', // + [148] = '_', // + [149] = '_', // + [150] = '_', // + [151] = '_', // + [152] = '_', // + [153] = '_', // + [154] = '_', // + [155] = '_', // + [156] = '_', // + [157] = '_', // + [158] = '_', // + [159] = '_', // + [160] = '_', // + [161] = '_', // + [162] = '_', // + [163] = '_', // + [164] = '_', // + [165] = '_', // + [166] = '_', // + [167] = '_', // + [168] = '_', // + [169] = '_', // + [170] = '_', // + [171] = '_', // + [172] = '_', // + [173] = '_', // + [174] = '_', // + [175] = '_', // + [176] = '_', // + [177] = '_', // + [178] = '_', // + [179] = '_', // + [180] = '_', // + [181] = '_', // + [182] = '_', // + [183] = '_', // + [184] = '_', // + [185] = '_', // + [186] = '_', // + [187] = '_', // + [188] = '_', // + [189] = '_', // + [190] = '_', // + [191] = '_', // + [192] = '_', // + [193] = '_', // + [194] = '_', // + [195] = '_', // + [196] = '_', // + [197] = '_', // + [198] = '_', // + [199] = '_', // + [200] = '_', // + [201] = '_', // + [202] = '_', // + [203] = '_', // + [204] = '_', // + [205] = '_', // + [206] = '_', // + [207] = '_', // + [208] = '_', // + [209] = '_', // + [210] = '_', // + [211] = '_', // + [212] = '_', // + [213] = '_', // + [214] = '_', // + [215] = '_', // + [216] = '_', // + [217] = '_', // + [218] = '_', // + [219] = '_', // + [220] = '_', // + [221] = '_', // + [222] = '_', // + [223] = '_', // + [224] = '_', // + [225] = '_', // + [226] = '_', // + [227] = '_', // + [228] = '_', // + [229] = '_', // + [230] = '_', // + [231] = '_', // + [232] = '_', // + [233] = '_', // + [234] = '_', // + [235] = '_', // + [236] = '_', // + [237] = '_', // + [238] = '_', // + [239] = '_', // + [240] = '_', // + [241] = '_', // + [242] = '_', // + [243] = '_', // + [244] = '_', // + [245] = '_', // + [246] = '_', // + [247] = '_', // + [248] = '_', // + [249] = '_', // + [250] = '_', // + [251] = '_', // + [252] = '_', // + [253] = '_', // + [254] = '_', // + [255] = '_' // +}; + +// make sure the supplied string +// is good for a netdata chart/dimension ID/NAME +void netdata_fix_chart_name(char *s) { + while((*s = netdata_map_chart_names[(unsigned char)*s])) s++; +} + +unsigned char netdata_map_chart_ids[256] = { + [0] = '\0', // + [1] = '_', // + [2] = '_', // + [3] = '_', // + [4] = '_', // + [5] = '_', // + [6] = '_', // + [7] = '_', // + [8] = '_', // + [9] = '_', // + [10] = '_', // + [11] = '_', // + [12] = '_', // + [13] = '_', // + [14] = '_', // + [15] = '_', // + [16] = '_', // + [17] = '_', // + [18] = '_', // + [19] = '_', // + [20] = '_', // + [21] = '_', // + [22] = '_', // + [23] = '_', // + [24] = '_', // + [25] = '_', // + [26] = '_', // + [27] = '_', // + [28] = '_', // + [29] = '_', // + [30] = '_', // + [31] = '_', // + [32] = '_', // + [33] = '_', // ! + [34] = '_', // " + [35] = '_', // # + [36] = '_', // $ + [37] = '_', // % + [38] = '_', // & + [39] = '_', // ' + [40] = '_', // ( + [41] = '_', // ) + [42] = '_', // * + [43] = '_', // + + [44] = '.', // , + [45] = '-', // - + [46] = '.', // . + [47] = '_', // / + [48] = '0', // 0 + [49] = '1', // 1 + [50] = '2', // 2 + [51] = '3', // 3 + [52] = '4', // 4 + [53] = '5', // 5 + [54] = '6', // 6 + [55] = '7', // 7 + [56] = '8', // 8 + [57] = '9', // 9 + [58] = '_', // : + [59] = '_', // ; + [60] = '_', // < + [61] = '_', // = + [62] = '_', // > + [63] = '_', // ? + [64] = '_', // @ + [65] = 'a', // A + [66] = 'b', // B + [67] = 'c', // C + [68] = 'd', // D + [69] = 'e', // E + [70] = 'f', // F + [71] = 'g', // G + [72] = 'h', // H + [73] = 'i', // I + [74] = 'j', // J + [75] = 'k', // K + [76] = 'l', // L + [77] = 'm', // M + [78] = 'n', // N + [79] = 'o', // O + [80] = 'p', // P + [81] = 'q', // Q + [82] = 'r', // R + [83] = 's', // S + [84] = 't', // T + [85] = 'u', // U + [86] = 'v', // V + [87] = 'w', // W + [88] = 'x', // X + [89] = 'y', // Y + [90] = 'z', // Z + [91] = '_', // [ + [92] = '/', // backslash + [93] = '_', // ] + [94] = '_', // ^ + [95] = '_', // _ + [96] = '_', // ` + [97] = 'a', // a + [98] = 'b', // b + [99] = 'c', // c + [100] = 'd', // d + [101] = 'e', // e + [102] = 'f', // f + [103] = 'g', // g + [104] = 'h', // h + [105] = 'i', // i + [106] = 'j', // j + [107] = 'k', // k + [108] = 'l', // l + [109] = 'm', // m + [110] = 'n', // n + [111] = 'o', // o + [112] = 'p', // p + [113] = 'q', // q + [114] = 'r', // r + [115] = 's', // s + [116] = 't', // t + [117] = 'u', // u + [118] = 'v', // v + [119] = 'w', // w + [120] = 'x', // x + [121] = 'y', // y + [122] = 'z', // z + [123] = '_', // { + [124] = '_', // | + [125] = '_', // } + [126] = '_', // ~ + [127] = '_', // + [128] = '_', // + [129] = '_', // + [130] = '_', // + [131] = '_', // + [132] = '_', // + [133] = '_', // + [134] = '_', // + [135] = '_', // + [136] = '_', // + [137] = '_', // + [138] = '_', // + [139] = '_', // + [140] = '_', // + [141] = '_', // + [142] = '_', // + [143] = '_', // + [144] = '_', // + [145] = '_', // + [146] = '_', // + [147] = '_', // + [148] = '_', // + [149] = '_', // + [150] = '_', // + [151] = '_', // + [152] = '_', // + [153] = '_', // + [154] = '_', // + [155] = '_', // + [156] = '_', // + [157] = '_', // + [158] = '_', // + [159] = '_', // + [160] = '_', // + [161] = '_', // + [162] = '_', // + [163] = '_', // + [164] = '_', // + [165] = '_', // + [166] = '_', // + [167] = '_', // + [168] = '_', // + [169] = '_', // + [170] = '_', // + [171] = '_', // + [172] = '_', // + [173] = '_', // + [174] = '_', // + [175] = '_', // + [176] = '_', // + [177] = '_', // + [178] = '_', // + [179] = '_', // + [180] = '_', // + [181] = '_', // + [182] = '_', // + [183] = '_', // + [184] = '_', // + [185] = '_', // + [186] = '_', // + [187] = '_', // + [188] = '_', // + [189] = '_', // + [190] = '_', // + [191] = '_', // + [192] = '_', // + [193] = '_', // + [194] = '_', // + [195] = '_', // + [196] = '_', // + [197] = '_', // + [198] = '_', // + [199] = '_', // + [200] = '_', // + [201] = '_', // + [202] = '_', // + [203] = '_', // + [204] = '_', // + [205] = '_', // + [206] = '_', // + [207] = '_', // + [208] = '_', // + [209] = '_', // + [210] = '_', // + [211] = '_', // + [212] = '_', // + [213] = '_', // + [214] = '_', // + [215] = '_', // + [216] = '_', // + [217] = '_', // + [218] = '_', // + [219] = '_', // + [220] = '_', // + [221] = '_', // + [222] = '_', // + [223] = '_', // + [224] = '_', // + [225] = '_', // + [226] = '_', // + [227] = '_', // + [228] = '_', // + [229] = '_', // + [230] = '_', // + [231] = '_', // + [232] = '_', // + [233] = '_', // + [234] = '_', // + [235] = '_', // + [236] = '_', // + [237] = '_', // + [238] = '_', // + [239] = '_', // + [240] = '_', // + [241] = '_', // + [242] = '_', // + [243] = '_', // + [244] = '_', // + [245] = '_', // + [246] = '_', // + [247] = '_', // + [248] = '_', // + [249] = '_', // + [250] = '_', // + [251] = '_', // + [252] = '_', // + [253] = '_', // + [254] = '_', // + [255] = '_' // +}; + +// make sure the supplied string +// is good for a netdata chart/dimension ID/NAME +void netdata_fix_chart_id(char *s) { + while((*s = netdata_map_chart_ids[(unsigned char)*s])) s++; +} /* // http://stackoverflow.com/questions/7666509/hash-function-for-string @@ -30,7 +573,7 @@ uint32_t simple_hash(const char *name) } */ -/* + // http://isthe.com/chongo/tech/comp/fnv/#FNV-1a uint32_t simple_hash(const char *name) { unsigned char *s = (unsigned char *)name; @@ -39,8 +582,11 @@ uint32_t simple_hash(const char *name) { // FNV-1a algorithm while (*s) { // multiply by the 32 bit FNV magic prime mod 2^32 - // gcc optimized - hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); + // NOTE: No need to optimize with left shifts. + // GCC will use imul instruction anyway. + // Tested with 'gcc -O3 -S' + //hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24); + hval *= 16777619; // xor the bottom with the current octet hval ^= (uint32_t)*s++; @@ -49,8 +595,8 @@ uint32_t simple_hash(const char *name) { // fprintf(stderr, "HASH: %u = %s\n", hval, name); return hval; } -*/ +/* // http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx // one at a time hash uint32_t simple_hash(const char *name) { @@ -71,12 +617,19 @@ uint32_t simple_hash(const char *name) { return h; } +*/ void strreverse(char* begin, char* end) { - char aux; - while (end > begin) - aux = *end, *end-- = *begin, *begin++ = aux; + char aux; + + while (end > begin) + { + // clearer code. + aux = *end; + *end-- = *begin; + *begin++ = aux; + } } char *mystrsep(char **ptr, char *s) @@ -86,62 +639,29 @@ char *mystrsep(char **ptr, char *s) return(p); } -// like strsep() but: -// it trims spaces before and after each value -// it accepts quoted values in single or double quotes -char *qstrsep(char **ptr) -{ - if(!*ptr || !**ptr) return NULL; - - char *s, *p = *ptr; - - // skip leading spaces - while(isspace(*p)) p++; - - // if the first char is a quote, assume quoted - if(*p == '"' || *p == '\'') { - char q = *p; - s = ++p; - while(*p && *p != q) p++; - - if(*p == q) { - *p = '\0'; - p++; - } - - *ptr = p; - return s; - } - - s = p; - while(*p && !isspace(*p)) p++; - if(!*p) *ptr = NULL; - else { - *p = '\0'; - *ptr = ++p; - } - - return s; -} - char *trim(char *s) { // skip leading spaces + // and 'comments' as well!? while(*s && isspace(*s)) s++; if(!*s || *s == '#') return NULL; // skip tailing spaces - int c = strlen(s) - 1; - while(c >= 0 && isspace(s[c])) { - s[c] = '\0'; - c--; + // this way is way faster. Writes only one NUL char. + ssize_t l = strlen(s); + if (--l >= 0) + { + char *p = s + l; + while (p > s && isspace(*p)) p--; + *++p = '\0'; } - if(c < 0) return NULL; + if(!*s) return NULL; + return s; } -void *mymmap(const char *filename, unsigned long size, int flags) +void *mymmap(const char *filename, size_t size, int flags, int ksm) { int fd; void *mem = NULL; @@ -151,15 +671,43 @@ void *mymmap(const char *filename, unsigned long size, int flags) if(fd != -1) { if(lseek(fd, size, SEEK_SET) == (long)size) { if(write(fd, "", 1) == 1) { - if(ftruncate(fd, size)) error("Cannot truncate file '%s' to size %ld. Will use the larger file.", filename, size); - mem = mmap(NULL, size, PROT_READ|PROT_WRITE, flags, fd, 0); - if(mem) { - if(madvise(mem, size, MADV_SEQUENTIAL|MADV_DONTFORK|MADV_WILLNEED) != 0) - error("Cannot advise the kernel about the memory usage of file '%s'.", filename); +#ifdef MADV_MERGEABLE + if(flags & MAP_SHARED || !enable_ksm || !ksm) { +#endif + mem = mmap(NULL, size, PROT_READ|PROT_WRITE, flags, fd, 0); + if(mem) { + int advise = MADV_SEQUENTIAL|MADV_DONTFORK; + if(flags & MAP_SHARED) advise |= MADV_WILLNEED; + + if(madvise(mem, size, advise) != 0) + error("Cannot advise the kernel about the memory usage of file '%s'.", filename); + } +#ifdef MADV_MERGEABLE + } + else { + mem = mmap(NULL, size, PROT_READ|PROT_WRITE, flags|MAP_ANONYMOUS, -1, 0); + if(mem) { + if(lseek(fd, 0, SEEK_SET) == 0) { + if(read(fd, mem, size) != (ssize_t)size) + error("Cannot read from file '%s'", filename); + } + else + error("Cannot seek to beginning of file '%s'.", filename); + + // don't use MADV_SEQUENTIAL|MADV_DONTFORK, they disable MADV_MERGEABLE + if(madvise(mem, size, MADV_SEQUENTIAL|MADV_DONTFORK) != 0) + error("Cannot advise the kernel about the memory usage (MADV_SEQUENTIAL|MADV_DONTFORK) of file '%s'.", filename); + + if(madvise(mem, size, MADV_MERGEABLE) != 0) + error("Cannot advise the kernel about the memory usage (MADV_MERGEABLE) of file '%s'.", filename); + } + else + error("Cannot allocate PRIVATE ANONYMOUS memory for KSM for file '%s'.", filename); } +#endif } else error("Cannot write to file '%s' at position %ld.", filename, size); } @@ -176,7 +724,7 @@ int savememory(const char *filename, void *mem, unsigned long size) { char tmpfilename[FILENAME_MAX + 1]; - snprintf(tmpfilename, FILENAME_MAX, "%s.%ld.tmp", filename, (long)getpid()); + snprintfz(tmpfilename, FILENAME_MAX, "%s.%ld.tmp", filename, (long)getpid()); int fd = open(tmpfilename, O_RDWR|O_CREAT|O_NOATIME, 0664); if(fd < 0) { @@ -205,3 +753,74 @@ int fd_is_valid(int fd) { return fcntl(fd, F_GETFD) != -1 || errno != EBADF; } +/* + *************************************************************************** + * Get number of clock ticks per second. + *************************************************************************** + */ +unsigned int hz; + +void get_HZ(void) +{ + long ticks; + + if ((ticks = sysconf(_SC_CLK_TCK)) == -1) { + perror("sysconf"); + } + + hz = (unsigned int) ticks; +} + +pid_t gettid(void) +{ + return syscall(SYS_gettid); +} + +char *fgets_trim_len(char *buf, size_t buf_size, FILE *fp, size_t *len) { + char *s = fgets(buf, buf_size, fp); + if(!s) return NULL; + + char *t = s; + if(*t != '\0') { + // find the string end + while (*++t != '\0'); + + // trim trailing spaces/newlines/tabs + while (--t > s && *t == '\n') + *t = '\0'; + } + + if(len) + *len = t - s + 1; + + return s; +} + +char *strncpyz(char *dest, const char *src, size_t n) +{ + char *p = dest; + + while (*src && n--) + *dest++ = *src++; + *dest = '\0'; + + return p; +} + +int vsnprintfz(char *sout, size_t n, const char *fmt, va_list args) +{ + int size; + + size = vsnprintf(sout, n, fmt, args); + sout[size] = '\0'; + return size; +} + +int snprintfz(char *sout, size_t n, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + return vsnprintfz(sout, n, fmt, args); + // args will vanish! +}