libnetdata.c 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051
  1. // SPDX-License-Identifier: GPL-3.0-or-later
  2. #include "libnetdata.h"
  3. #ifdef __APPLE__
  4. #define INHERIT_NONE 0
  5. #endif /* __APPLE__ */
  6. #if defined(__FreeBSD__) || defined(__APPLE__)
  7. # define O_NOATIME 0
  8. # define MADV_DONTFORK INHERIT_NONE
  9. #endif /* __FreeBSD__ || __APPLE__*/
  10. struct rlimit rlimit_nofile = { .rlim_cur = 1024, .rlim_max = 1024 };
  11. #ifdef MADV_MERGEABLE
  12. int enable_ksm = 1;
  13. #else
  14. int enable_ksm = 0;
  15. #endif
  16. volatile sig_atomic_t netdata_exit = 0;
  17. const char *program_version = VERSION;
  18. #define MAX_JUDY_SIZE_TO_ARAL 24
  19. static bool judy_sizes_config[MAX_JUDY_SIZE_TO_ARAL + 1] = {
  20. [3] = true,
  21. [4] = true,
  22. [5] = true,
  23. [6] = true,
  24. [7] = true,
  25. [8] = true,
  26. [10] = true,
  27. [11] = true,
  28. [15] = true,
  29. [23] = true,
  30. };
  31. static ARAL *judy_sizes_aral[MAX_JUDY_SIZE_TO_ARAL + 1] = {};
  32. struct aral_statistics judy_sizes_aral_statistics = {};
  33. void aral_judy_init(void) {
  34. for(size_t Words = 0; Words <= MAX_JUDY_SIZE_TO_ARAL; Words++)
  35. if(judy_sizes_config[Words]) {
  36. char buf[30+1];
  37. snprintfz(buf, sizeof(buf) - 1, "judy-%zu", Words * sizeof(Word_t));
  38. judy_sizes_aral[Words] = aral_create(
  39. buf,
  40. Words * sizeof(Word_t),
  41. 0,
  42. 65536,
  43. &judy_sizes_aral_statistics,
  44. NULL, NULL, false, false);
  45. }
  46. }
  47. size_t judy_aral_overhead(void) {
  48. return aral_overhead_from_stats(&judy_sizes_aral_statistics);
  49. }
  50. size_t judy_aral_structures(void) {
  51. return aral_structures_from_stats(&judy_sizes_aral_statistics);
  52. }
  53. static ARAL *judy_size_aral(Word_t Words) {
  54. if(Words <= MAX_JUDY_SIZE_TO_ARAL && judy_sizes_aral[Words])
  55. return judy_sizes_aral[Words];
  56. return NULL;
  57. }
  58. inline Word_t JudyMalloc(Word_t Words) {
  59. Word_t Addr;
  60. ARAL *ar = judy_size_aral(Words);
  61. if(ar)
  62. Addr = (Word_t) aral_mallocz(ar);
  63. else
  64. Addr = (Word_t) mallocz(Words * sizeof(Word_t));
  65. return(Addr);
  66. }
  67. inline void JudyFree(void * PWord, Word_t Words) {
  68. ARAL *ar = judy_size_aral(Words);
  69. if(ar)
  70. aral_freez(ar, PWord);
  71. else
  72. freez(PWord);
  73. }
  74. Word_t JudyMallocVirtual(Word_t Words) {
  75. return JudyMalloc(Words);
  76. }
  77. void JudyFreeVirtual(void * PWord, Word_t Words) {
  78. JudyFree(PWord, Words);
  79. }
  80. // ----------------------------------------------------------------------------
  81. // memory allocation functions that handle failures
  82. // although netdata does not use memory allocations too often (netdata tries to
  83. // maintain its memory footprint stable during runtime, i.e. all buffers are
  84. // allocated during initialization and are adapted to current use throughout
  85. // its lifetime), these can be used to override the default system allocation
  86. // routines.
  87. #ifdef NETDATA_TRACE_ALLOCATIONS
  88. #warning NETDATA_TRACE_ALLOCATIONS ENABLED
  89. #include "Judy.h"
  90. #if defined(HAVE_DLSYM) && defined(ENABLE_DLSYM)
  91. #include <dlfcn.h>
  92. typedef void (*libc_function_t)(void);
  93. static void *malloc_first_run(size_t size);
  94. static void *(*libc_malloc)(size_t) = malloc_first_run;
  95. static void *calloc_first_run(size_t n, size_t size);
  96. static void *(*libc_calloc)(size_t, size_t) = calloc_first_run;
  97. static void *realloc_first_run(void *ptr, size_t size);
  98. static void *(*libc_realloc)(void *, size_t) = realloc_first_run;
  99. static void free_first_run(void *ptr);
  100. static void (*libc_free)(void *) = free_first_run;
  101. static char *strdup_first_run(const char *s);
  102. static char *(*libc_strdup)(const char *) = strdup_first_run;
  103. static char *strndup_first_run(const char *s, size_t len);
  104. static char *(*libc_strndup)(const char *, size_t) = strndup_first_run;
  105. static size_t malloc_usable_size_first_run(void *ptr);
  106. #ifdef HAVE_MALLOC_USABLE_SIZE
  107. static size_t (*libc_malloc_usable_size)(void *) = malloc_usable_size_first_run;
  108. #else
  109. static size_t (*libc_malloc_usable_size)(void *) = NULL;
  110. #endif
  111. static void link_system_library_function(libc_function_t *func_pptr, const char *name, bool required) {
  112. *func_pptr = dlsym(RTLD_NEXT, name);
  113. if(!*func_pptr && required) {
  114. fprintf(stderr, "FATAL: Cannot find system's %s() function.\n", name);
  115. abort();
  116. }
  117. }
  118. static void *malloc_first_run(size_t size) {
  119. link_system_library_function((libc_function_t *) &libc_malloc, "malloc", true);
  120. return libc_malloc(size);
  121. }
  122. static void *calloc_first_run(size_t n, size_t size) {
  123. link_system_library_function((libc_function_t *) &libc_calloc, "calloc", true);
  124. return libc_calloc(n, size);
  125. }
  126. static void *realloc_first_run(void *ptr, size_t size) {
  127. link_system_library_function((libc_function_t *) &libc_realloc, "realloc", true);
  128. return libc_realloc(ptr, size);
  129. }
  130. static void free_first_run(void *ptr) {
  131. link_system_library_function((libc_function_t *) &libc_free, "free", true);
  132. libc_free(ptr);
  133. }
  134. static char *strdup_first_run(const char *s) {
  135. link_system_library_function((libc_function_t *) &libc_strdup, "strdup", true);
  136. return libc_strdup(s);
  137. }
  138. static char *strndup_first_run(const char *s, size_t len) {
  139. link_system_library_function((libc_function_t *) &libc_strndup, "strndup", true);
  140. return libc_strndup(s, len);
  141. }
  142. static size_t malloc_usable_size_first_run(void *ptr) {
  143. link_system_library_function((libc_function_t *) &libc_malloc_usable_size, "malloc_usable_size", false);
  144. if(libc_malloc_usable_size)
  145. return libc_malloc_usable_size(ptr);
  146. else
  147. return 0;
  148. }
  149. void *malloc(size_t size) {
  150. return mallocz(size);
  151. }
  152. void *calloc(size_t n, size_t size) {
  153. return callocz(n, size);
  154. }
  155. void *realloc(void *ptr, size_t size) {
  156. return reallocz(ptr, size);
  157. }
  158. void *reallocarray(void *ptr, size_t n, size_t size) {
  159. return reallocz(ptr, n * size);
  160. }
  161. void free(void *ptr) {
  162. freez(ptr);
  163. }
  164. char *strdup(const char *s) {
  165. return strdupz(s);
  166. }
  167. char *strndup(const char *s, size_t len) {
  168. return strndupz(s, len);
  169. }
  170. size_t malloc_usable_size(void *ptr) {
  171. return mallocz_usable_size(ptr);
  172. }
  173. #else // !HAVE_DLSYM
  174. static void *(*libc_malloc)(size_t) = malloc;
  175. static void *(*libc_calloc)(size_t, size_t) = calloc;
  176. static void *(*libc_realloc)(void *, size_t) = realloc;
  177. static void (*libc_free)(void *) = free;
  178. #ifdef HAVE_MALLOC_USABLE_SIZE
  179. static size_t (*libc_malloc_usable_size)(void *) = malloc_usable_size;
  180. #else
  181. static size_t (*libc_malloc_usable_size)(void *) = NULL;
  182. #endif
  183. #endif // HAVE_DLSYM
  184. void posix_memfree(void *ptr) {
  185. libc_free(ptr);
  186. }
  187. struct malloc_header_signature {
  188. uint32_t magic;
  189. uint32_t size;
  190. struct malloc_trace *trace;
  191. };
  192. struct malloc_header {
  193. struct malloc_header_signature signature;
  194. uint8_t padding[(sizeof(struct malloc_header_signature) % MALLOC_ALIGNMENT) ? MALLOC_ALIGNMENT - (sizeof(struct malloc_header_signature) % MALLOC_ALIGNMENT) : 0];
  195. uint8_t data[];
  196. };
  197. static size_t malloc_header_size = sizeof(struct malloc_header);
  198. int malloc_trace_compare(void *A, void *B) {
  199. struct malloc_trace *a = A;
  200. struct malloc_trace *b = B;
  201. return strcmp(a->function, b->function);
  202. }
  203. static avl_tree_lock malloc_trace_index = {
  204. .avl_tree = {
  205. .root = NULL,
  206. .compar = malloc_trace_compare},
  207. .rwlock = AVL_LOCK_INITIALIZER
  208. };
  209. int malloc_trace_walkthrough(int (*callback)(void *item, void *data), void *data) {
  210. return avl_traverse_lock(&malloc_trace_index, callback, data);
  211. }
  212. NEVERNULL WARNUNUSED
  213. static struct malloc_trace *malloc_trace_find_or_create(const char *file, const char *function, size_t line) {
  214. struct malloc_trace tmp = {
  215. .line = line,
  216. .function = function,
  217. .file = file,
  218. };
  219. struct malloc_trace *t = (struct malloc_trace *)avl_search_lock(&malloc_trace_index, (avl_t *)&tmp);
  220. if(!t) {
  221. t = libc_calloc(1, sizeof(struct malloc_trace));
  222. if(!t) fatal("No memory");
  223. t->line = line;
  224. t->function = function;
  225. t->file = file;
  226. struct malloc_trace *t2 = (struct malloc_trace *)avl_insert_lock(&malloc_trace_index, (avl_t *)t);
  227. if(t2 != t)
  228. free(t);
  229. t = t2;
  230. }
  231. if(!t)
  232. fatal("Cannot insert to AVL");
  233. return t;
  234. }
  235. void malloc_trace_mmap(size_t size) {
  236. struct malloc_trace *p = malloc_trace_find_or_create("unknown", "netdata_mmap", 1);
  237. size_t_atomic_count(add, p->mmap_calls, 1);
  238. size_t_atomic_count(add, p->allocations, 1);
  239. size_t_atomic_bytes(add, p->bytes, size);
  240. }
  241. void malloc_trace_munmap(size_t size) {
  242. struct malloc_trace *p = malloc_trace_find_or_create("unknown", "netdata_mmap", 1);
  243. size_t_atomic_count(add, p->munmap_calls, 1);
  244. size_t_atomic_count(sub, p->allocations, 1);
  245. size_t_atomic_bytes(sub, p->bytes, size);
  246. }
  247. void *mallocz_int(size_t size, const char *file, const char *function, size_t line) {
  248. struct malloc_trace *p = malloc_trace_find_or_create(file, function, line);
  249. size_t_atomic_count(add, p->malloc_calls, 1);
  250. size_t_atomic_count(add, p->allocations, 1);
  251. size_t_atomic_bytes(add, p->bytes, size);
  252. struct malloc_header *t = (struct malloc_header *)libc_malloc(malloc_header_size + size);
  253. if (unlikely(!t)) fatal("mallocz() cannot allocate %zu bytes of memory (%zu with header).", size, malloc_header_size + size);
  254. t->signature.magic = 0x0BADCAFE;
  255. t->signature.trace = p;
  256. t->signature.size = size;
  257. #ifdef NETDATA_INTERNAL_CHECKS
  258. for(ssize_t i = 0; i < (ssize_t)sizeof(t->padding) ;i++) // signed to avoid compiler warning when zero-padded
  259. t->padding[i] = 0xFF;
  260. #endif
  261. return (void *)&t->data;
  262. }
  263. void *callocz_int(size_t nmemb, size_t size, const char *file, const char *function, size_t line) {
  264. struct malloc_trace *p = malloc_trace_find_or_create(file, function, line);
  265. size = nmemb * size;
  266. size_t_atomic_count(add, p->calloc_calls, 1);
  267. size_t_atomic_count(add, p->allocations, 1);
  268. size_t_atomic_bytes(add, p->bytes, size);
  269. struct malloc_header *t = (struct malloc_header *)libc_calloc(1, malloc_header_size + size);
  270. if (unlikely(!t)) fatal("mallocz() cannot allocate %zu bytes of memory (%zu with header).", size, malloc_header_size + size);
  271. t->signature.magic = 0x0BADCAFE;
  272. t->signature.trace = p;
  273. t->signature.size = size;
  274. #ifdef NETDATA_INTERNAL_CHECKS
  275. for(ssize_t i = 0; i < (ssize_t)sizeof(t->padding) ;i++) // signed to avoid compiler warning when zero-padded
  276. t->padding[i] = 0xFF;
  277. #endif
  278. return &t->data;
  279. }
  280. char *strdupz_int(const char *s, const char *file, const char *function, size_t line) {
  281. struct malloc_trace *p = malloc_trace_find_or_create(file, function, line);
  282. size_t size = strlen(s) + 1;
  283. size_t_atomic_count(add, p->strdup_calls, 1);
  284. size_t_atomic_count(add, p->allocations, 1);
  285. size_t_atomic_bytes(add, p->bytes, size);
  286. struct malloc_header *t = (struct malloc_header *)libc_malloc(malloc_header_size + size);
  287. if (unlikely(!t)) fatal("strdupz() cannot allocate %zu bytes of memory (%zu with header).", size, malloc_header_size + size);
  288. t->signature.magic = 0x0BADCAFE;
  289. t->signature.trace = p;
  290. t->signature.size = size;
  291. #ifdef NETDATA_INTERNAL_CHECKS
  292. for(ssize_t i = 0; i < (ssize_t)sizeof(t->padding) ;i++) // signed to avoid compiler warning when zero-padded
  293. t->padding[i] = 0xFF;
  294. #endif
  295. memcpy(&t->data, s, size);
  296. return (char *)&t->data;
  297. }
  298. char *strndupz_int(const char *s, size_t len, const char *file, const char *function, size_t line) {
  299. struct malloc_trace *p = malloc_trace_find_or_create(file, function, line);
  300. size_t size = len + 1;
  301. size_t_atomic_count(add, p->strdup_calls, 1);
  302. size_t_atomic_count(add, p->allocations, 1);
  303. size_t_atomic_bytes(add, p->bytes, size);
  304. struct malloc_header *t = (struct malloc_header *)libc_malloc(malloc_header_size + size);
  305. if (unlikely(!t)) fatal("strndupz() cannot allocate %zu bytes of memory (%zu with header).", size, malloc_header_size + size);
  306. t->signature.magic = 0x0BADCAFE;
  307. t->signature.trace = p;
  308. t->signature.size = size;
  309. #ifdef NETDATA_INTERNAL_CHECKS
  310. for(ssize_t i = 0; i < (ssize_t)sizeof(t->padding) ;i++) // signed to avoid compiler warning when zero-padded
  311. t->padding[i] = 0xFF;
  312. #endif
  313. memcpy(&t->data, s, size);
  314. t->data[len] = '\0';
  315. return (char *)&t->data;
  316. }
  317. static struct malloc_header *malloc_get_header(void *ptr, const char *caller, const char *file, const char *function, size_t line) {
  318. uint8_t *ret = (uint8_t *)ptr - malloc_header_size;
  319. struct malloc_header *t = (struct malloc_header *)ret;
  320. if(t->signature.magic != 0x0BADCAFE) {
  321. netdata_log_error("pointer %p is not our pointer (called %s() from %zu@%s, %s()).", ptr, caller, line, file, function);
  322. return NULL;
  323. }
  324. return t;
  325. }
  326. void *reallocz_int(void *ptr, size_t size, const char *file, const char *function, size_t line) {
  327. if(!ptr) return mallocz_int(size, file, function, line);
  328. struct malloc_header *t = malloc_get_header(ptr, __FUNCTION__, file, function, line);
  329. if(!t)
  330. return libc_realloc(ptr, size);
  331. if(t->signature.size == size) return ptr;
  332. size_t_atomic_count(add, t->signature.trace->free_calls, 1);
  333. size_t_atomic_count(sub, t->signature.trace->allocations, 1);
  334. size_t_atomic_bytes(sub, t->signature.trace->bytes, t->signature.size);
  335. struct malloc_trace *p = malloc_trace_find_or_create(file, function, line);
  336. size_t_atomic_count(add, p->realloc_calls, 1);
  337. size_t_atomic_count(add, p->allocations, 1);
  338. size_t_atomic_bytes(add, p->bytes, size);
  339. t = (struct malloc_header *)libc_realloc(t, malloc_header_size + size);
  340. if (unlikely(!t)) fatal("reallocz() cannot allocate %zu bytes of memory (%zu with header).", size, malloc_header_size + size);
  341. t->signature.magic = 0x0BADCAFE;
  342. t->signature.trace = p;
  343. t->signature.size = size;
  344. #ifdef NETDATA_INTERNAL_CHECKS
  345. for(ssize_t i = 0; i < (ssize_t)sizeof(t->padding) ;i++) // signed to avoid compiler warning when zero-padded
  346. t->padding[i] = 0xFF;
  347. #endif
  348. return (void *)&t->data;
  349. }
  350. size_t mallocz_usable_size_int(void *ptr, const char *file, const char *function, size_t line) {
  351. if(unlikely(!ptr)) return 0;
  352. struct malloc_header *t = malloc_get_header(ptr, __FUNCTION__, file, function, line);
  353. if(!t) {
  354. if(libc_malloc_usable_size)
  355. return libc_malloc_usable_size(ptr);
  356. else
  357. return 0;
  358. }
  359. return t->signature.size;
  360. }
  361. void freez_int(void *ptr, const char *file, const char *function, size_t line) {
  362. if(unlikely(!ptr)) return;
  363. struct malloc_header *t = malloc_get_header(ptr, __FUNCTION__, file, function, line);
  364. if(!t) {
  365. libc_free(ptr);
  366. return;
  367. }
  368. size_t_atomic_count(add, t->signature.trace->free_calls, 1);
  369. size_t_atomic_count(sub, t->signature.trace->allocations, 1);
  370. size_t_atomic_bytes(sub, t->signature.trace->bytes, t->signature.size);
  371. #ifdef NETDATA_INTERNAL_CHECKS
  372. // it should crash if it is used after freeing it
  373. memset(t, 0, malloc_header_size + t->signature.size);
  374. #endif
  375. libc_free(t);
  376. }
  377. #else
  378. char *strdupz(const char *s) {
  379. char *t = strdup(s);
  380. if (unlikely(!t)) fatal("Cannot strdup() string '%s'", s);
  381. return t;
  382. }
  383. char *strndupz(const char *s, size_t len) {
  384. char *t = strndup(s, len);
  385. if (unlikely(!t)) fatal("Cannot strndup() string '%s' of len %zu", s, len);
  386. return t;
  387. }
  388. // If ptr is NULL, no operation is performed.
  389. void freez(void *ptr) {
  390. free(ptr);
  391. }
  392. void *mallocz(size_t size) {
  393. void *p = malloc(size);
  394. if (unlikely(!p)) fatal("Cannot allocate %zu bytes of memory.", size);
  395. return p;
  396. }
  397. void *callocz(size_t nmemb, size_t size) {
  398. void *p = calloc(nmemb, size);
  399. if (unlikely(!p)) fatal("Cannot allocate %zu bytes of memory.", nmemb * size);
  400. return p;
  401. }
  402. void *reallocz(void *ptr, size_t size) {
  403. void *p = realloc(ptr, size);
  404. if (unlikely(!p)) fatal("Cannot re-allocate memory to %zu bytes.", size);
  405. return p;
  406. }
  407. void posix_memfree(void *ptr) {
  408. free(ptr);
  409. }
  410. #endif
  411. // --------------------------------------------------------------------------------------------------------------------
  412. void json_escape_string(char *dst, const char *src, size_t size) {
  413. const char *t;
  414. char *d = dst, *e = &dst[size - 1];
  415. for(t = src; *t && d < e ;t++) {
  416. if(unlikely(*t == '\\' || *t == '"')) {
  417. if(unlikely(d + 1 >= e)) break;
  418. *d++ = '\\';
  419. }
  420. *d++ = *t;
  421. }
  422. *d = '\0';
  423. }
  424. void json_fix_string(char *s) {
  425. unsigned char c;
  426. while((c = (unsigned char)*s)) {
  427. if(unlikely(c == '\\'))
  428. *s++ = '/';
  429. else if(unlikely(c == '"'))
  430. *s++ = '\'';
  431. else if(unlikely(isspace(c) || iscntrl(c)))
  432. *s++ = ' ';
  433. else if(unlikely(!isprint(c) || c > 127))
  434. *s++ = '_';
  435. else
  436. s++;
  437. }
  438. }
  439. unsigned char netdata_map_chart_names[256] = {
  440. [0] = '\0', //
  441. [1] = '_', //
  442. [2] = '_', //
  443. [3] = '_', //
  444. [4] = '_', //
  445. [5] = '_', //
  446. [6] = '_', //
  447. [7] = '_', //
  448. [8] = '_', //
  449. [9] = '_', //
  450. [10] = '_', //
  451. [11] = '_', //
  452. [12] = '_', //
  453. [13] = '_', //
  454. [14] = '_', //
  455. [15] = '_', //
  456. [16] = '_', //
  457. [17] = '_', //
  458. [18] = '_', //
  459. [19] = '_', //
  460. [20] = '_', //
  461. [21] = '_', //
  462. [22] = '_', //
  463. [23] = '_', //
  464. [24] = '_', //
  465. [25] = '_', //
  466. [26] = '_', //
  467. [27] = '_', //
  468. [28] = '_', //
  469. [29] = '_', //
  470. [30] = '_', //
  471. [31] = '_', //
  472. [32] = '_', //
  473. [33] = '_', // !
  474. [34] = '_', // "
  475. [35] = '_', // #
  476. [36] = '_', // $
  477. [37] = '_', // %
  478. [38] = '_', // &
  479. [39] = '_', // '
  480. [40] = '_', // (
  481. [41] = '_', // )
  482. [42] = '_', // *
  483. [43] = '_', // +
  484. [44] = '.', // ,
  485. [45] = '-', // -
  486. [46] = '.', // .
  487. [47] = '/', // /
  488. [48] = '0', // 0
  489. [49] = '1', // 1
  490. [50] = '2', // 2
  491. [51] = '3', // 3
  492. [52] = '4', // 4
  493. [53] = '5', // 5
  494. [54] = '6', // 6
  495. [55] = '7', // 7
  496. [56] = '8', // 8
  497. [57] = '9', // 9
  498. [58] = '_', // :
  499. [59] = '_', // ;
  500. [60] = '_', // <
  501. [61] = '_', // =
  502. [62] = '_', // >
  503. [63] = '_', // ?
  504. [64] = '_', // @
  505. [65] = 'a', // A
  506. [66] = 'b', // B
  507. [67] = 'c', // C
  508. [68] = 'd', // D
  509. [69] = 'e', // E
  510. [70] = 'f', // F
  511. [71] = 'g', // G
  512. [72] = 'h', // H
  513. [73] = 'i', // I
  514. [74] = 'j', // J
  515. [75] = 'k', // K
  516. [76] = 'l', // L
  517. [77] = 'm', // M
  518. [78] = 'n', // N
  519. [79] = 'o', // O
  520. [80] = 'p', // P
  521. [81] = 'q', // Q
  522. [82] = 'r', // R
  523. [83] = 's', // S
  524. [84] = 't', // T
  525. [85] = 'u', // U
  526. [86] = 'v', // V
  527. [87] = 'w', // W
  528. [88] = 'x', // X
  529. [89] = 'y', // Y
  530. [90] = 'z', // Z
  531. [91] = '_', // [
  532. [92] = '/', // backslash
  533. [93] = '_', // ]
  534. [94] = '_', // ^
  535. [95] = '_', // _
  536. [96] = '_', // `
  537. [97] = 'a', // a
  538. [98] = 'b', // b
  539. [99] = 'c', // c
  540. [100] = 'd', // d
  541. [101] = 'e', // e
  542. [102] = 'f', // f
  543. [103] = 'g', // g
  544. [104] = 'h', // h
  545. [105] = 'i', // i
  546. [106] = 'j', // j
  547. [107] = 'k', // k
  548. [108] = 'l', // l
  549. [109] = 'm', // m
  550. [110] = 'n', // n
  551. [111] = 'o', // o
  552. [112] = 'p', // p
  553. [113] = 'q', // q
  554. [114] = 'r', // r
  555. [115] = 's', // s
  556. [116] = 't', // t
  557. [117] = 'u', // u
  558. [118] = 'v', // v
  559. [119] = 'w', // w
  560. [120] = 'x', // x
  561. [121] = 'y', // y
  562. [122] = 'z', // z
  563. [123] = '_', // {
  564. [124] = '_', // |
  565. [125] = '_', // }
  566. [126] = '_', // ~
  567. [127] = '_', //
  568. [128] = '_', //
  569. [129] = '_', //
  570. [130] = '_', //
  571. [131] = '_', //
  572. [132] = '_', //
  573. [133] = '_', //
  574. [134] = '_', //
  575. [135] = '_', //
  576. [136] = '_', //
  577. [137] = '_', //
  578. [138] = '_', //
  579. [139] = '_', //
  580. [140] = '_', //
  581. [141] = '_', //
  582. [142] = '_', //
  583. [143] = '_', //
  584. [144] = '_', //
  585. [145] = '_', //
  586. [146] = '_', //
  587. [147] = '_', //
  588. [148] = '_', //
  589. [149] = '_', //
  590. [150] = '_', //
  591. [151] = '_', //
  592. [152] = '_', //
  593. [153] = '_', //
  594. [154] = '_', //
  595. [155] = '_', //
  596. [156] = '_', //
  597. [157] = '_', //
  598. [158] = '_', //
  599. [159] = '_', //
  600. [160] = '_', //
  601. [161] = '_', //
  602. [162] = '_', //
  603. [163] = '_', //
  604. [164] = '_', //
  605. [165] = '_', //
  606. [166] = '_', //
  607. [167] = '_', //
  608. [168] = '_', //
  609. [169] = '_', //
  610. [170] = '_', //
  611. [171] = '_', //
  612. [172] = '_', //
  613. [173] = '_', //
  614. [174] = '_', //
  615. [175] = '_', //
  616. [176] = '_', //
  617. [177] = '_', //
  618. [178] = '_', //
  619. [179] = '_', //
  620. [180] = '_', //
  621. [181] = '_', //
  622. [182] = '_', //
  623. [183] = '_', //
  624. [184] = '_', //
  625. [185] = '_', //
  626. [186] = '_', //
  627. [187] = '_', //
  628. [188] = '_', //
  629. [189] = '_', //
  630. [190] = '_', //
  631. [191] = '_', //
  632. [192] = '_', //
  633. [193] = '_', //
  634. [194] = '_', //
  635. [195] = '_', //
  636. [196] = '_', //
  637. [197] = '_', //
  638. [198] = '_', //
  639. [199] = '_', //
  640. [200] = '_', //
  641. [201] = '_', //
  642. [202] = '_', //
  643. [203] = '_', //
  644. [204] = '_', //
  645. [205] = '_', //
  646. [206] = '_', //
  647. [207] = '_', //
  648. [208] = '_', //
  649. [209] = '_', //
  650. [210] = '_', //
  651. [211] = '_', //
  652. [212] = '_', //
  653. [213] = '_', //
  654. [214] = '_', //
  655. [215] = '_', //
  656. [216] = '_', //
  657. [217] = '_', //
  658. [218] = '_', //
  659. [219] = '_', //
  660. [220] = '_', //
  661. [221] = '_', //
  662. [222] = '_', //
  663. [223] = '_', //
  664. [224] = '_', //
  665. [225] = '_', //
  666. [226] = '_', //
  667. [227] = '_', //
  668. [228] = '_', //
  669. [229] = '_', //
  670. [230] = '_', //
  671. [231] = '_', //
  672. [232] = '_', //
  673. [233] = '_', //
  674. [234] = '_', //
  675. [235] = '_', //
  676. [236] = '_', //
  677. [237] = '_', //
  678. [238] = '_', //
  679. [239] = '_', //
  680. [240] = '_', //
  681. [241] = '_', //
  682. [242] = '_', //
  683. [243] = '_', //
  684. [244] = '_', //
  685. [245] = '_', //
  686. [246] = '_', //
  687. [247] = '_', //
  688. [248] = '_', //
  689. [249] = '_', //
  690. [250] = '_', //
  691. [251] = '_', //
  692. [252] = '_', //
  693. [253] = '_', //
  694. [254] = '_', //
  695. [255] = '_' //
  696. };
  697. // make sure the supplied string
  698. // is good for a netdata chart/dimension ID/NAME
  699. void netdata_fix_chart_name(char *s) {
  700. while ((*s = netdata_map_chart_names[(unsigned char) *s])) s++;
  701. }
  702. unsigned char netdata_map_chart_ids[256] = {
  703. [0] = '\0', //
  704. [1] = '_', //
  705. [2] = '_', //
  706. [3] = '_', //
  707. [4] = '_', //
  708. [5] = '_', //
  709. [6] = '_', //
  710. [7] = '_', //
  711. [8] = '_', //
  712. [9] = '_', //
  713. [10] = '_', //
  714. [11] = '_', //
  715. [12] = '_', //
  716. [13] = '_', //
  717. [14] = '_', //
  718. [15] = '_', //
  719. [16] = '_', //
  720. [17] = '_', //
  721. [18] = '_', //
  722. [19] = '_', //
  723. [20] = '_', //
  724. [21] = '_', //
  725. [22] = '_', //
  726. [23] = '_', //
  727. [24] = '_', //
  728. [25] = '_', //
  729. [26] = '_', //
  730. [27] = '_', //
  731. [28] = '_', //
  732. [29] = '_', //
  733. [30] = '_', //
  734. [31] = '_', //
  735. [32] = '_', //
  736. [33] = '_', // !
  737. [34] = '_', // "
  738. [35] = '_', // #
  739. [36] = '_', // $
  740. [37] = '_', // %
  741. [38] = '_', // &
  742. [39] = '_', // '
  743. [40] = '_', // (
  744. [41] = '_', // )
  745. [42] = '_', // *
  746. [43] = '_', // +
  747. [44] = '.', // ,
  748. [45] = '-', // -
  749. [46] = '.', // .
  750. [47] = '_', // /
  751. [48] = '0', // 0
  752. [49] = '1', // 1
  753. [50] = '2', // 2
  754. [51] = '3', // 3
  755. [52] = '4', // 4
  756. [53] = '5', // 5
  757. [54] = '6', // 6
  758. [55] = '7', // 7
  759. [56] = '8', // 8
  760. [57] = '9', // 9
  761. [58] = '_', // :
  762. [59] = '_', // ;
  763. [60] = '_', // <
  764. [61] = '_', // =
  765. [62] = '_', // >
  766. [63] = '_', // ?
  767. [64] = '_', // @
  768. [65] = 'a', // A
  769. [66] = 'b', // B
  770. [67] = 'c', // C
  771. [68] = 'd', // D
  772. [69] = 'e', // E
  773. [70] = 'f', // F
  774. [71] = 'g', // G
  775. [72] = 'h', // H
  776. [73] = 'i', // I
  777. [74] = 'j', // J
  778. [75] = 'k', // K
  779. [76] = 'l', // L
  780. [77] = 'm', // M
  781. [78] = 'n', // N
  782. [79] = 'o', // O
  783. [80] = 'p', // P
  784. [81] = 'q', // Q
  785. [82] = 'r', // R
  786. [83] = 's', // S
  787. [84] = 't', // T
  788. [85] = 'u', // U
  789. [86] = 'v', // V
  790. [87] = 'w', // W
  791. [88] = 'x', // X
  792. [89] = 'y', // Y
  793. [90] = 'z', // Z
  794. [91] = '_', // [
  795. [92] = '_', // backslash
  796. [93] = '_', // ]
  797. [94] = '_', // ^
  798. [95] = '_', // _
  799. [96] = '_', // `
  800. [97] = 'a', // a
  801. [98] = 'b', // b
  802. [99] = 'c', // c
  803. [100] = 'd', // d
  804. [101] = 'e', // e
  805. [102] = 'f', // f
  806. [103] = 'g', // g
  807. [104] = 'h', // h
  808. [105] = 'i', // i
  809. [106] = 'j', // j
  810. [107] = 'k', // k
  811. [108] = 'l', // l
  812. [109] = 'm', // m
  813. [110] = 'n', // n
  814. [111] = 'o', // o
  815. [112] = 'p', // p
  816. [113] = 'q', // q
  817. [114] = 'r', // r
  818. [115] = 's', // s
  819. [116] = 't', // t
  820. [117] = 'u', // u
  821. [118] = 'v', // v
  822. [119] = 'w', // w
  823. [120] = 'x', // x
  824. [121] = 'y', // y
  825. [122] = 'z', // z
  826. [123] = '_', // {
  827. [124] = '_', // |
  828. [125] = '_', // }
  829. [126] = '_', // ~
  830. [127] = '_', //
  831. [128] = '_', //
  832. [129] = '_', //
  833. [130] = '_', //
  834. [131] = '_', //
  835. [132] = '_', //
  836. [133] = '_', //
  837. [134] = '_', //
  838. [135] = '_', //
  839. [136] = '_', //
  840. [137] = '_', //
  841. [138] = '_', //
  842. [139] = '_', //
  843. [140] = '_', //
  844. [141] = '_', //
  845. [142] = '_', //
  846. [143] = '_', //
  847. [144] = '_', //
  848. [145] = '_', //
  849. [146] = '_', //
  850. [147] = '_', //
  851. [148] = '_', //
  852. [149] = '_', //
  853. [150] = '_', //
  854. [151] = '_', //
  855. [152] = '_', //
  856. [153] = '_', //
  857. [154] = '_', //
  858. [155] = '_', //
  859. [156] = '_', //
  860. [157] = '_', //
  861. [158] = '_', //
  862. [159] = '_', //
  863. [160] = '_', //
  864. [161] = '_', //
  865. [162] = '_', //
  866. [163] = '_', //
  867. [164] = '_', //
  868. [165] = '_', //
  869. [166] = '_', //
  870. [167] = '_', //
  871. [168] = '_', //
  872. [169] = '_', //
  873. [170] = '_', //
  874. [171] = '_', //
  875. [172] = '_', //
  876. [173] = '_', //
  877. [174] = '_', //
  878. [175] = '_', //
  879. [176] = '_', //
  880. [177] = '_', //
  881. [178] = '_', //
  882. [179] = '_', //
  883. [180] = '_', //
  884. [181] = '_', //
  885. [182] = '_', //
  886. [183] = '_', //
  887. [184] = '_', //
  888. [185] = '_', //
  889. [186] = '_', //
  890. [187] = '_', //
  891. [188] = '_', //
  892. [189] = '_', //
  893. [190] = '_', //
  894. [191] = '_', //
  895. [192] = '_', //
  896. [193] = '_', //
  897. [194] = '_', //
  898. [195] = '_', //
  899. [196] = '_', //
  900. [197] = '_', //
  901. [198] = '_', //
  902. [199] = '_', //
  903. [200] = '_', //
  904. [201] = '_', //
  905. [202] = '_', //
  906. [203] = '_', //
  907. [204] = '_', //
  908. [205] = '_', //
  909. [206] = '_', //
  910. [207] = '_', //
  911. [208] = '_', //
  912. [209] = '_', //
  913. [210] = '_', //
  914. [211] = '_', //
  915. [212] = '_', //
  916. [213] = '_', //
  917. [214] = '_', //
  918. [215] = '_', //
  919. [216] = '_', //
  920. [217] = '_', //
  921. [218] = '_', //
  922. [219] = '_', //
  923. [220] = '_', //
  924. [221] = '_', //
  925. [222] = '_', //
  926. [223] = '_', //
  927. [224] = '_', //
  928. [225] = '_', //
  929. [226] = '_', //
  930. [227] = '_', //
  931. [228] = '_', //
  932. [229] = '_', //
  933. [230] = '_', //
  934. [231] = '_', //
  935. [232] = '_', //
  936. [233] = '_', //
  937. [234] = '_', //
  938. [235] = '_', //
  939. [236] = '_', //
  940. [237] = '_', //
  941. [238] = '_', //
  942. [239] = '_', //
  943. [240] = '_', //
  944. [241] = '_', //
  945. [242] = '_', //
  946. [243] = '_', //
  947. [244] = '_', //
  948. [245] = '_', //
  949. [246] = '_', //
  950. [247] = '_', //
  951. [248] = '_', //
  952. [249] = '_', //
  953. [250] = '_', //
  954. [251] = '_', //
  955. [252] = '_', //
  956. [253] = '_', //
  957. [254] = '_', //
  958. [255] = '_' //
  959. };
  960. // make sure the supplied string
  961. // is good for a netdata chart/dimension ID/NAME
  962. void netdata_fix_chart_id(char *s) {
  963. while ((*s = netdata_map_chart_ids[(unsigned char) *s])) s++;
  964. }
  965. static int memory_file_open(const char *filename, size_t size) {
  966. // netdata_log_info("memory_file_open('%s', %zu", filename, size);
  967. int fd = open(filename, O_RDWR | O_CREAT | O_NOATIME, 0664);
  968. if (fd != -1) {
  969. if (lseek(fd, size, SEEK_SET) == (off_t) size) {
  970. if (write(fd, "", 1) == 1) {
  971. if (ftruncate(fd, size))
  972. netdata_log_error("Cannot truncate file '%s' to size %zu. Will use the larger file.", filename, size);
  973. }
  974. else
  975. netdata_log_error("Cannot write to file '%s' at position %zu.", filename, size);
  976. }
  977. else
  978. netdata_log_error("Cannot seek file '%s' to size %zu.", filename, size);
  979. }
  980. else
  981. netdata_log_error("Cannot create/open file '%s'.", filename);
  982. return fd;
  983. }
  984. inline int madvise_sequential(void *mem, size_t len) {
  985. static int logger = 1;
  986. int ret = madvise(mem, len, MADV_SEQUENTIAL);
  987. if (ret != 0 && logger-- > 0)
  988. netdata_log_error("madvise(MADV_SEQUENTIAL) failed.");
  989. return ret;
  990. }
  991. inline int madvise_random(void *mem, size_t len) {
  992. static int logger = 1;
  993. int ret = madvise(mem, len, MADV_RANDOM);
  994. if (ret != 0 && logger-- > 0)
  995. netdata_log_error("madvise(MADV_RANDOM) failed.");
  996. return ret;
  997. }
  998. inline int madvise_dontfork(void *mem, size_t len) {
  999. static int logger = 1;
  1000. int ret = madvise(mem, len, MADV_DONTFORK);
  1001. if (ret != 0 && logger-- > 0)
  1002. netdata_log_error("madvise(MADV_DONTFORK) failed.");
  1003. return ret;
  1004. }
  1005. inline int madvise_willneed(void *mem, size_t len) {
  1006. static int logger = 1;
  1007. int ret = madvise(mem, len, MADV_WILLNEED);
  1008. if (ret != 0 && logger-- > 0)
  1009. netdata_log_error("madvise(MADV_WILLNEED) failed.");
  1010. return ret;
  1011. }
  1012. inline int madvise_dontneed(void *mem, size_t len) {
  1013. static int logger = 1;
  1014. int ret = madvise(mem, len, MADV_DONTNEED);
  1015. if (ret != 0 && logger-- > 0)
  1016. netdata_log_error("madvise(MADV_DONTNEED) failed.");
  1017. return ret;
  1018. }
  1019. inline int madvise_dontdump(void *mem __maybe_unused, size_t len __maybe_unused) {
  1020. #if __linux__
  1021. static int logger = 1;
  1022. int ret = madvise(mem, len, MADV_DONTDUMP);
  1023. if (ret != 0 && logger-- > 0)
  1024. netdata_log_error("madvise(MADV_DONTDUMP) failed.");
  1025. return ret;
  1026. #else
  1027. return 0;
  1028. #endif
  1029. }
  1030. inline int madvise_mergeable(void *mem __maybe_unused, size_t len __maybe_unused) {
  1031. #ifdef MADV_MERGEABLE
  1032. static int logger = 1;
  1033. int ret = madvise(mem, len, MADV_MERGEABLE);
  1034. if (ret != 0 && logger-- > 0)
  1035. netdata_log_error("madvise(MADV_MERGEABLE) failed.");
  1036. return ret;
  1037. #else
  1038. return 0;
  1039. #endif
  1040. }
  1041. void *netdata_mmap(const char *filename, size_t size, int flags, int ksm, bool read_only, int *open_fd)
  1042. {
  1043. // netdata_log_info("netdata_mmap('%s', %zu", filename, size);
  1044. // MAP_SHARED is used in memory mode map
  1045. // MAP_PRIVATE is used in memory mode ram and save
  1046. if(unlikely(!(flags & MAP_SHARED) && !(flags & MAP_PRIVATE)))
  1047. fatal("Neither MAP_SHARED or MAP_PRIVATE were given to netdata_mmap()");
  1048. if(unlikely((flags & MAP_SHARED) && (flags & MAP_PRIVATE)))
  1049. fatal("Both MAP_SHARED and MAP_PRIVATE were given to netdata_mmap()");
  1050. if(unlikely((flags & MAP_SHARED) && (!filename || !*filename)))
  1051. fatal("MAP_SHARED requested, without a filename to netdata_mmap()");
  1052. // don't enable ksm is the global setting is disabled
  1053. if(unlikely(!enable_ksm)) ksm = 0;
  1054. // KSM only merges anonymous (private) pages, never pagecache (file) pages
  1055. // but MAP_PRIVATE without MAP_ANONYMOUS it fails too, so we need it always
  1056. if((flags & MAP_PRIVATE)) flags |= MAP_ANONYMOUS;
  1057. int fd = -1;
  1058. void *mem = MAP_FAILED;
  1059. if(filename && *filename) {
  1060. // open/create the file to be used
  1061. fd = memory_file_open(filename, size);
  1062. if(fd == -1) goto cleanup;
  1063. }
  1064. int fd_for_mmap = fd;
  1065. if(fd != -1 && (flags & MAP_PRIVATE)) {
  1066. // this is MAP_PRIVATE allocation
  1067. // no need for mmap() to use our fd
  1068. // we will copy the file into the memory allocated
  1069. fd_for_mmap = -1;
  1070. }
  1071. mem = mmap(NULL, size, read_only ? PROT_READ : PROT_READ | PROT_WRITE, flags, fd_for_mmap, 0);
  1072. if (mem != MAP_FAILED) {
  1073. #ifdef NETDATA_TRACE_ALLOCATIONS
  1074. malloc_trace_mmap(size);
  1075. #endif
  1076. // if we have a file open, but we didn't give it to mmap(),
  1077. // we have to read the file into the memory block we allocated
  1078. if(fd != -1 && fd_for_mmap == -1) {
  1079. if (lseek(fd, 0, SEEK_SET) == 0) {
  1080. if (read(fd, mem, size) != (ssize_t) size)
  1081. netdata_log_info("Cannot read from file '%s'", filename);
  1082. }
  1083. else netdata_log_info("Cannot seek to beginning of file '%s'.", filename);
  1084. }
  1085. // madvise_sequential(mem, size);
  1086. madvise_dontfork(mem, size);
  1087. madvise_dontdump(mem, size);
  1088. // if(flags & MAP_SHARED) madvise_willneed(mem, size);
  1089. if(ksm) madvise_mergeable(mem, size);
  1090. }
  1091. cleanup:
  1092. if(fd != -1) {
  1093. if (open_fd)
  1094. *open_fd = fd;
  1095. else
  1096. close(fd);
  1097. }
  1098. if(mem == MAP_FAILED) return NULL;
  1099. errno = 0;
  1100. return mem;
  1101. }
  1102. int netdata_munmap(void *ptr, size_t size) {
  1103. #ifdef NETDATA_TRACE_ALLOCATIONS
  1104. malloc_trace_munmap(size);
  1105. #endif
  1106. return munmap(ptr, size);
  1107. }
  1108. char *fgets_trim_len(char *buf, size_t buf_size, FILE *fp, size_t *len) {
  1109. char *s = fgets(buf, (int)buf_size, fp);
  1110. if (!s) return NULL;
  1111. char *t = s;
  1112. if (*t != '\0') {
  1113. // find the string end
  1114. while (*++t != '\0');
  1115. // trim trailing spaces/newlines/tabs
  1116. while (--t > s && *t == '\n')
  1117. *t = '\0';
  1118. }
  1119. if (len)
  1120. *len = t - s + 1;
  1121. return s;
  1122. }
  1123. // vsnprintfz() returns the number of bytes actually written - after possible truncation
  1124. int vsnprintfz(char *dst, size_t n, const char *fmt, va_list args) {
  1125. if(unlikely(!n)) return 0;
  1126. int size = vsnprintf(dst, n, fmt, args);
  1127. dst[n - 1] = '\0';
  1128. if (unlikely((size_t) size >= n)) size = (int)(n - 1);
  1129. return size;
  1130. }
  1131. // snprintfz() returns the number of bytes actually written - after possible truncation
  1132. int snprintfz(char *dst, size_t n, const char *fmt, ...) {
  1133. va_list args;
  1134. va_start(args, fmt);
  1135. int ret = vsnprintfz(dst, n, fmt, args);
  1136. va_end(args);
  1137. return ret;
  1138. }
  1139. static int is_virtual_filesystem(const char *path, char **reason) {
  1140. #if defined(__APPLE__) || defined(__FreeBSD__)
  1141. (void)path;
  1142. (void)reason;
  1143. #else
  1144. struct statfs stat;
  1145. // stat.f_fsid.__val[0] is a file system id
  1146. // stat.f_fsid.__val[1] is the inode
  1147. // so their combination uniquely identifies the file/dir
  1148. if (statfs(path, &stat) == -1) {
  1149. if(reason) *reason = "failed to statfs()";
  1150. return -1;
  1151. }
  1152. if(stat.f_fsid.__val[0] != 0 || stat.f_fsid.__val[1] != 0) {
  1153. errno = EINVAL;
  1154. if(reason) *reason = "is not a virtual file system";
  1155. return -1;
  1156. }
  1157. #endif
  1158. return 0;
  1159. }
  1160. int verify_netdata_host_prefix() {
  1161. if(!netdata_configured_host_prefix)
  1162. netdata_configured_host_prefix = "";
  1163. if(!*netdata_configured_host_prefix)
  1164. return 0;
  1165. char buffer[FILENAME_MAX + 1];
  1166. char *path = netdata_configured_host_prefix;
  1167. char *reason = "unknown reason";
  1168. errno = 0;
  1169. struct stat sb;
  1170. if (stat(path, &sb) == -1) {
  1171. reason = "failed to stat()";
  1172. goto failed;
  1173. }
  1174. if((sb.st_mode & S_IFMT) != S_IFDIR) {
  1175. errno = EINVAL;
  1176. reason = "is not a directory";
  1177. goto failed;
  1178. }
  1179. path = buffer;
  1180. snprintfz(path, FILENAME_MAX, "%s/proc", netdata_configured_host_prefix);
  1181. if(is_virtual_filesystem(path, &reason) == -1)
  1182. goto failed;
  1183. snprintfz(path, FILENAME_MAX, "%s/sys", netdata_configured_host_prefix);
  1184. if(is_virtual_filesystem(path, &reason) == -1)
  1185. goto failed;
  1186. if(netdata_configured_host_prefix && *netdata_configured_host_prefix)
  1187. netdata_log_info("Using host prefix directory '%s'", netdata_configured_host_prefix);
  1188. return 0;
  1189. failed:
  1190. netdata_log_error("Ignoring host prefix '%s': path '%s' %s", netdata_configured_host_prefix, path, reason);
  1191. netdata_configured_host_prefix = "";
  1192. return -1;
  1193. }
  1194. char *strdupz_path_subpath(const char *path, const char *subpath) {
  1195. if(unlikely(!path || !*path)) path = ".";
  1196. if(unlikely(!subpath)) subpath = "";
  1197. // skip trailing slashes in path
  1198. size_t len = strlen(path);
  1199. while(len > 0 && path[len - 1] == '/') len--;
  1200. // skip leading slashes in subpath
  1201. while(subpath[0] == '/') subpath++;
  1202. // if the last character in path is / and (there is a subpath or path is now empty)
  1203. // keep the trailing slash in path and remove the additional slash
  1204. char *slash = "/";
  1205. if(path[len] == '/' && (*subpath || len == 0)) {
  1206. slash = "";
  1207. len++;
  1208. }
  1209. else if(!*subpath) {
  1210. // there is no subpath
  1211. // no need for trailing slash
  1212. slash = "";
  1213. }
  1214. char buffer[FILENAME_MAX + 1];
  1215. snprintfz(buffer, FILENAME_MAX, "%.*s%s%s", (int)len, path, slash, subpath);
  1216. return strdupz(buffer);
  1217. }
  1218. int path_is_dir(const char *path, const char *subpath) {
  1219. char *s = strdupz_path_subpath(path, subpath);
  1220. size_t max_links = 100;
  1221. int is_dir = 0;
  1222. struct stat statbuf;
  1223. while(max_links-- && stat(s, &statbuf) == 0) {
  1224. if((statbuf.st_mode & S_IFMT) == S_IFDIR) {
  1225. is_dir = 1;
  1226. break;
  1227. }
  1228. else if((statbuf.st_mode & S_IFMT) == S_IFLNK) {
  1229. char buffer[FILENAME_MAX + 1];
  1230. ssize_t l = readlink(s, buffer, FILENAME_MAX);
  1231. if(l > 0) {
  1232. buffer[l] = '\0';
  1233. freez(s);
  1234. s = strdupz(buffer);
  1235. continue;
  1236. }
  1237. else {
  1238. is_dir = 0;
  1239. break;
  1240. }
  1241. }
  1242. else {
  1243. is_dir = 0;
  1244. break;
  1245. }
  1246. }
  1247. freez(s);
  1248. return is_dir;
  1249. }
  1250. int path_is_file(const char *path, const char *subpath) {
  1251. char *s = strdupz_path_subpath(path, subpath);
  1252. size_t max_links = 100;
  1253. int is_file = 0;
  1254. struct stat statbuf;
  1255. while(max_links-- && stat(s, &statbuf) == 0) {
  1256. if((statbuf.st_mode & S_IFMT) == S_IFREG) {
  1257. is_file = 1;
  1258. break;
  1259. }
  1260. else if((statbuf.st_mode & S_IFMT) == S_IFLNK) {
  1261. char buffer[FILENAME_MAX + 1];
  1262. ssize_t l = readlink(s, buffer, FILENAME_MAX);
  1263. if(l > 0) {
  1264. buffer[l] = '\0';
  1265. freez(s);
  1266. s = strdupz(buffer);
  1267. continue;
  1268. }
  1269. else {
  1270. is_file = 0;
  1271. break;
  1272. }
  1273. }
  1274. else {
  1275. is_file = 0;
  1276. break;
  1277. }
  1278. }
  1279. freez(s);
  1280. return is_file;
  1281. }
  1282. void recursive_config_double_dir_load(const char *user_path, const char *stock_path, const char *subpath, int (*callback)(const char *filename, void *data), void *data, size_t depth) {
  1283. if(depth > 3) {
  1284. netdata_log_error("CONFIG: Max directory depth reached while reading user path '%s', stock path '%s', subpath '%s'", user_path, stock_path, subpath);
  1285. return;
  1286. }
  1287. char *udir = strdupz_path_subpath(user_path, subpath);
  1288. char *sdir = strdupz_path_subpath(stock_path, subpath);
  1289. netdata_log_debug(D_HEALTH, "CONFIG traversing user-config directory '%s', stock config directory '%s'", udir, sdir);
  1290. DIR *dir = opendir(udir);
  1291. if (!dir) {
  1292. netdata_log_error("CONFIG cannot open user-config directory '%s'.", udir);
  1293. }
  1294. else {
  1295. struct dirent *de = NULL;
  1296. while((de = readdir(dir))) {
  1297. if(de->d_type == DT_DIR || de->d_type == DT_LNK) {
  1298. if( !de->d_name[0] ||
  1299. (de->d_name[0] == '.' && de->d_name[1] == '\0') ||
  1300. (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')
  1301. ) {
  1302. netdata_log_debug(D_HEALTH, "CONFIG ignoring user-config directory '%s/%s'", udir, de->d_name);
  1303. continue;
  1304. }
  1305. if(path_is_dir(udir, de->d_name)) {
  1306. recursive_config_double_dir_load(udir, sdir, de->d_name, callback, data, depth + 1);
  1307. continue;
  1308. }
  1309. }
  1310. if(de->d_type == DT_UNKNOWN || de->d_type == DT_REG || de->d_type == DT_LNK) {
  1311. size_t len = strlen(de->d_name);
  1312. if(path_is_file(udir, de->d_name) &&
  1313. len > 5 && !strcmp(&de->d_name[len - 5], ".conf")) {
  1314. char *filename = strdupz_path_subpath(udir, de->d_name);
  1315. netdata_log_debug(D_HEALTH, "CONFIG calling callback for user file '%s'", filename);
  1316. callback(filename, data);
  1317. freez(filename);
  1318. continue;
  1319. }
  1320. }
  1321. netdata_log_debug(D_HEALTH, "CONFIG ignoring user-config file '%s/%s' of type %d", udir, de->d_name, (int)de->d_type);
  1322. }
  1323. closedir(dir);
  1324. }
  1325. netdata_log_debug(D_HEALTH, "CONFIG traversing stock config directory '%s', user config directory '%s'", sdir, udir);
  1326. dir = opendir(sdir);
  1327. if (!dir) {
  1328. netdata_log_error("CONFIG cannot open stock config directory '%s'.", sdir);
  1329. }
  1330. else {
  1331. if (strcmp(udir, sdir)) {
  1332. struct dirent *de = NULL;
  1333. while((de = readdir(dir))) {
  1334. if(de->d_type == DT_DIR || de->d_type == DT_LNK) {
  1335. if( !de->d_name[0] ||
  1336. (de->d_name[0] == '.' && de->d_name[1] == '\0') ||
  1337. (de->d_name[0] == '.' && de->d_name[1] == '.' && de->d_name[2] == '\0')
  1338. ) {
  1339. netdata_log_debug(D_HEALTH, "CONFIG ignoring stock config directory '%s/%s'", sdir, de->d_name);
  1340. continue;
  1341. }
  1342. if(path_is_dir(sdir, de->d_name)) {
  1343. // we recurse in stock subdirectory, only when there is no corresponding
  1344. // user subdirectory - to avoid reading the files twice
  1345. if(!path_is_dir(udir, de->d_name))
  1346. recursive_config_double_dir_load(udir, sdir, de->d_name, callback, data, depth + 1);
  1347. continue;
  1348. }
  1349. }
  1350. if(de->d_type == DT_UNKNOWN || de->d_type == DT_REG || de->d_type == DT_LNK) {
  1351. size_t len = strlen(de->d_name);
  1352. if(path_is_file(sdir, de->d_name) && !path_is_file(udir, de->d_name) &&
  1353. len > 5 && !strcmp(&de->d_name[len - 5], ".conf")) {
  1354. char *filename = strdupz_path_subpath(sdir, de->d_name);
  1355. netdata_log_debug(D_HEALTH, "CONFIG calling callback for stock file '%s'", filename);
  1356. callback(filename, data);
  1357. freez(filename);
  1358. continue;
  1359. }
  1360. }
  1361. netdata_log_debug(D_HEALTH, "CONFIG ignoring stock-config file '%s/%s' of type %d", udir, de->d_name, (int)de->d_type);
  1362. }
  1363. }
  1364. closedir(dir);
  1365. }
  1366. netdata_log_debug(D_HEALTH, "CONFIG done traversing user-config directory '%s', stock config directory '%s'", udir, sdir);
  1367. freez(udir);
  1368. freez(sdir);
  1369. }
  1370. // Returns the number of bytes read from the file if file_size is not NULL.
  1371. // The actual buffer has an extra byte set to zero (not included in the count).
  1372. char *read_by_filename(const char *filename, long *file_size)
  1373. {
  1374. FILE *f = fopen(filename, "r");
  1375. if (!f)
  1376. return NULL;
  1377. if (fseek(f, 0, SEEK_END) < 0) {
  1378. fclose(f);
  1379. return NULL;
  1380. }
  1381. long size = ftell(f);
  1382. if (size <= 0 || fseek(f, 0, SEEK_END) < 0) {
  1383. fclose(f);
  1384. return NULL;
  1385. }
  1386. char *contents = callocz(size + 1, 1);
  1387. if (!contents) {
  1388. fclose(f);
  1389. return NULL;
  1390. }
  1391. if (fseek(f, 0, SEEK_SET) < 0) {
  1392. fclose(f);
  1393. freez(contents);
  1394. return NULL;
  1395. }
  1396. size_t res = fread(contents, 1, size, f);
  1397. if ( res != (size_t)size) {
  1398. freez(contents);
  1399. fclose(f);
  1400. return NULL;
  1401. }
  1402. fclose(f);
  1403. if (file_size)
  1404. *file_size = size;
  1405. return contents;
  1406. }
  1407. char *find_and_replace(const char *src, const char *find, const char *replace, const char *where)
  1408. {
  1409. size_t size = strlen(src) + 1;
  1410. size_t find_len = strlen(find);
  1411. size_t repl_len = strlen(replace);
  1412. char *value, *dst;
  1413. if (likely(where))
  1414. size += (repl_len - find_len);
  1415. value = mallocz(size);
  1416. dst = value;
  1417. if (likely(where)) {
  1418. size_t count = where - src;
  1419. memmove(dst, src, count);
  1420. src += count;
  1421. dst += count;
  1422. memmove(dst, replace, repl_len);
  1423. src += find_len;
  1424. dst += repl_len;
  1425. }
  1426. strcpy(dst, src);
  1427. return value;
  1428. }
  1429. BUFFER *run_command_and_get_output_to_buffer(const char *command, int max_line_length) {
  1430. BUFFER *wb = buffer_create(0, NULL);
  1431. pid_t pid;
  1432. FILE *fp = netdata_popen(command, &pid, NULL);
  1433. if(fp) {
  1434. char buffer[max_line_length + 1];
  1435. while (fgets(buffer, max_line_length, fp)) {
  1436. buffer[max_line_length] = '\0';
  1437. buffer_strcat(wb, buffer);
  1438. }
  1439. }
  1440. else {
  1441. buffer_free(wb);
  1442. netdata_log_error("Failed to execute command '%s'.", command);
  1443. return NULL;
  1444. }
  1445. netdata_pclose(NULL, fp, pid);
  1446. return wb;
  1447. }
  1448. bool run_command_and_copy_output_to_stdout(const char *command, int max_line_length) {
  1449. pid_t pid;
  1450. FILE *fp = netdata_popen(command, &pid, NULL);
  1451. if(fp) {
  1452. char buffer[max_line_length + 1];
  1453. while (fgets(buffer, max_line_length, fp))
  1454. fprintf(stdout, "%s", buffer);
  1455. }
  1456. else {
  1457. netdata_log_error("Failed to execute command '%s'.", command);
  1458. return false;
  1459. }
  1460. netdata_pclose(NULL, fp, pid);
  1461. return true;
  1462. }
  1463. static int fd_is_valid(int fd) {
  1464. return fcntl(fd, F_GETFD) != -1 || errno != EBADF;
  1465. }
  1466. void for_each_open_fd(OPEN_FD_ACTION action, OPEN_FD_EXCLUDE excluded_fds){
  1467. int fd;
  1468. switch(action){
  1469. case OPEN_FD_ACTION_CLOSE:
  1470. if(!(excluded_fds & OPEN_FD_EXCLUDE_STDIN)) (void)close(STDIN_FILENO);
  1471. if(!(excluded_fds & OPEN_FD_EXCLUDE_STDOUT)) (void)close(STDOUT_FILENO);
  1472. if(!(excluded_fds & OPEN_FD_EXCLUDE_STDERR)) (void)close(STDERR_FILENO);
  1473. #if defined(HAVE_CLOSE_RANGE)
  1474. if(close_range(STDERR_FILENO + 1, ~0U, 0) == 0) return;
  1475. netdata_log_error("close_range() failed, will try to close fds one by one");
  1476. #endif
  1477. break;
  1478. case OPEN_FD_ACTION_FD_CLOEXEC:
  1479. if(!(excluded_fds & OPEN_FD_EXCLUDE_STDIN)) (void)fcntl(STDIN_FILENO, F_SETFD, FD_CLOEXEC);
  1480. if(!(excluded_fds & OPEN_FD_EXCLUDE_STDOUT)) (void)fcntl(STDOUT_FILENO, F_SETFD, FD_CLOEXEC);
  1481. if(!(excluded_fds & OPEN_FD_EXCLUDE_STDERR)) (void)fcntl(STDERR_FILENO, F_SETFD, FD_CLOEXEC);
  1482. #if defined(HAVE_CLOSE_RANGE) && defined(CLOSE_RANGE_CLOEXEC) // Linux >= 5.11, FreeBSD >= 13.1
  1483. if(close_range(STDERR_FILENO + 1, ~0U, CLOSE_RANGE_CLOEXEC) == 0) return;
  1484. netdata_log_error("close_range() failed, will try to mark fds for closing one by one");
  1485. #endif
  1486. break;
  1487. default:
  1488. break; // do nothing
  1489. }
  1490. DIR *dir = opendir("/proc/self/fd");
  1491. if (dir == NULL) {
  1492. struct rlimit rl;
  1493. int open_max = -1;
  1494. if(getrlimit(RLIMIT_NOFILE, &rl) == 0 && rl.rlim_max != RLIM_INFINITY) open_max = rl.rlim_max;
  1495. #ifdef _SC_OPEN_MAX
  1496. else open_max = sysconf(_SC_OPEN_MAX);
  1497. #endif
  1498. if (open_max == -1) open_max = 65535; // 65535 arbitrary default if everything else fails
  1499. for (fd = STDERR_FILENO + 1; fd < open_max; fd++) {
  1500. switch(action){
  1501. case OPEN_FD_ACTION_CLOSE:
  1502. if(fd_is_valid(fd)) (void)close(fd);
  1503. break;
  1504. case OPEN_FD_ACTION_FD_CLOEXEC:
  1505. (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
  1506. break;
  1507. default:
  1508. break; // do nothing
  1509. }
  1510. }
  1511. } else {
  1512. struct dirent *entry;
  1513. while ((entry = readdir(dir)) != NULL) {
  1514. fd = str2i(entry->d_name);
  1515. if(unlikely((fd == STDIN_FILENO ) || (fd == STDOUT_FILENO) || (fd == STDERR_FILENO) )) continue;
  1516. switch(action){
  1517. case OPEN_FD_ACTION_CLOSE:
  1518. if(fd_is_valid(fd)) (void)close(fd);
  1519. break;
  1520. case OPEN_FD_ACTION_FD_CLOEXEC:
  1521. (void)fcntl(fd, F_SETFD, FD_CLOEXEC);
  1522. break;
  1523. default:
  1524. break; // do nothing
  1525. }
  1526. }
  1527. closedir(dir);
  1528. }
  1529. }
  1530. struct timing_steps {
  1531. const char *name;
  1532. usec_t time;
  1533. size_t count;
  1534. } timing_steps[TIMING_STEP_MAX + 1] = {
  1535. [TIMING_STEP_INTERNAL] = { .name = "internal", .time = 0, },
  1536. [TIMING_STEP_BEGIN2_PREPARE] = { .name = "BEGIN2 prepare", .time = 0, },
  1537. [TIMING_STEP_BEGIN2_FIND_CHART] = { .name = "BEGIN2 find chart", .time = 0, },
  1538. [TIMING_STEP_BEGIN2_PARSE] = { .name = "BEGIN2 parse", .time = 0, },
  1539. [TIMING_STEP_BEGIN2_ML] = { .name = "BEGIN2 ml", .time = 0, },
  1540. [TIMING_STEP_BEGIN2_PROPAGATE] = { .name = "BEGIN2 propagate", .time = 0, },
  1541. [TIMING_STEP_BEGIN2_STORE] = { .name = "BEGIN2 store", .time = 0, },
  1542. [TIMING_STEP_SET2_PREPARE] = { .name = "SET2 prepare", .time = 0, },
  1543. [TIMING_STEP_SET2_LOOKUP_DIMENSION] = { .name = "SET2 find dimension", .time = 0, },
  1544. [TIMING_STEP_SET2_PARSE] = { .name = "SET2 parse", .time = 0, },
  1545. [TIMING_STEP_SET2_ML] = { .name = "SET2 ml", .time = 0, },
  1546. [TIMING_STEP_SET2_PROPAGATE] = { .name = "SET2 propagate", .time = 0, },
  1547. [TIMING_STEP_RRDSET_STORE_METRIC] = { .name = "SET2 rrdset store", .time = 0, },
  1548. [TIMING_STEP_DBENGINE_FIRST_CHECK] = { .name = "db 1st check", .time = 0, },
  1549. [TIMING_STEP_DBENGINE_CHECK_DATA] = { .name = "db check data", .time = 0, },
  1550. [TIMING_STEP_DBENGINE_PACK] = { .name = "db pack", .time = 0, },
  1551. [TIMING_STEP_DBENGINE_PAGE_FIN] = { .name = "db page fin", .time = 0, },
  1552. [TIMING_STEP_DBENGINE_MRG_UPDATE] = { .name = "db mrg update", .time = 0, },
  1553. [TIMING_STEP_DBENGINE_PAGE_ALLOC] = { .name = "db page alloc", .time = 0, },
  1554. [TIMING_STEP_DBENGINE_CREATE_NEW_PAGE] = { .name = "db new page", .time = 0, },
  1555. [TIMING_STEP_DBENGINE_FLUSH_PAGE] = { .name = "db page flush", .time = 0, },
  1556. [TIMING_STEP_SET2_STORE] = { .name = "SET2 store", .time = 0, },
  1557. [TIMING_STEP_END2_PREPARE] = { .name = "END2 prepare", .time = 0, },
  1558. [TIMING_STEP_END2_PUSH_V1] = { .name = "END2 push v1", .time = 0, },
  1559. [TIMING_STEP_END2_ML] = { .name = "END2 ml", .time = 0, },
  1560. [TIMING_STEP_END2_RRDSET] = { .name = "END2 rrdset", .time = 0, },
  1561. [TIMING_STEP_END2_PROPAGATE] = { .name = "END2 propagate", .time = 0, },
  1562. [TIMING_STEP_END2_STORE] = { .name = "END2 store", .time = 0, },
  1563. // terminator
  1564. [TIMING_STEP_MAX] = { .name = NULL, .time = 0, },
  1565. };
  1566. void timing_action(TIMING_ACTION action, TIMING_STEP step) {
  1567. static __thread usec_t last_action_time = 0;
  1568. static struct timing_steps timings2[TIMING_STEP_MAX + 1] = {};
  1569. switch(action) {
  1570. case TIMING_ACTION_INIT:
  1571. last_action_time = now_monotonic_usec();
  1572. break;
  1573. case TIMING_ACTION_STEP: {
  1574. if(!last_action_time)
  1575. return;
  1576. usec_t now = now_monotonic_usec();
  1577. __atomic_add_fetch(&timing_steps[step].time, now - last_action_time, __ATOMIC_RELAXED);
  1578. __atomic_add_fetch(&timing_steps[step].count, 1, __ATOMIC_RELAXED);
  1579. last_action_time = now;
  1580. break;
  1581. }
  1582. case TIMING_ACTION_FINISH: {
  1583. if(!last_action_time)
  1584. return;
  1585. usec_t expected = __atomic_load_n(&timing_steps[TIMING_STEP_INTERNAL].time, __ATOMIC_RELAXED);
  1586. if(last_action_time - expected < 10 * USEC_PER_SEC) {
  1587. last_action_time = 0;
  1588. return;
  1589. }
  1590. if(!__atomic_compare_exchange_n(&timing_steps[TIMING_STEP_INTERNAL].time, &expected, last_action_time, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
  1591. last_action_time = 0;
  1592. return;
  1593. }
  1594. struct timing_steps timings3[TIMING_STEP_MAX + 1];
  1595. memcpy(timings3, timing_steps, sizeof(timings3));
  1596. size_t total_reqs = 0;
  1597. usec_t total_usec = 0;
  1598. for(size_t t = 1; t < TIMING_STEP_MAX ; t++) {
  1599. total_usec += timings3[t].time - timings2[t].time;
  1600. total_reqs += timings3[t].count - timings2[t].count;
  1601. }
  1602. BUFFER *wb = buffer_create(1024, NULL);
  1603. for(size_t t = 1; t < TIMING_STEP_MAX ; t++) {
  1604. size_t requests = timings3[t].count - timings2[t].count;
  1605. if(!requests) continue;
  1606. buffer_sprintf(wb, "TIMINGS REPORT: [%3zu. %-20s]: # %10zu, t %11.2f ms (%6.2f %%), avg %6.2f usec/run\n",
  1607. t,
  1608. timing_steps[t].name ? timing_steps[t].name : "x",
  1609. requests,
  1610. (double) (timings3[t].time - timings2[t].time) / (double)USEC_PER_MS,
  1611. (double) (timings3[t].time - timings2[t].time) * 100.0 / (double) total_usec,
  1612. (double) (timings3[t].time - timings2[t].time) / (double)requests
  1613. );
  1614. }
  1615. netdata_log_info("TIMINGS REPORT:\n%sTIMINGS REPORT: total # %10zu, t %11.2f ms",
  1616. buffer_tostring(wb), total_reqs, (double)total_usec / USEC_PER_MS);
  1617. memcpy(timings2, timings3, sizeof(timings2));
  1618. last_action_time = 0;
  1619. buffer_free(wb);
  1620. }
  1621. }
  1622. }
  1623. #ifdef ENABLE_HTTPS
  1624. int hash256_string(const unsigned char *string, size_t size, char *hash) {
  1625. EVP_MD_CTX *ctx;
  1626. ctx = EVP_MD_CTX_create();
  1627. if (!ctx)
  1628. return 0;
  1629. if (!EVP_DigestInit(ctx, EVP_sha256())) {
  1630. EVP_MD_CTX_destroy(ctx);
  1631. return 0;
  1632. }
  1633. if (!EVP_DigestUpdate(ctx, string, size)) {
  1634. EVP_MD_CTX_destroy(ctx);
  1635. return 0;
  1636. }
  1637. if (!EVP_DigestFinal(ctx, (unsigned char *)hash, NULL)) {
  1638. EVP_MD_CTX_destroy(ctx);
  1639. return 0;
  1640. }
  1641. EVP_MD_CTX_destroy(ctx);
  1642. return 1;
  1643. }
  1644. #endif
  1645. bool rrdr_relative_window_to_absolute(time_t *after, time_t *before, time_t now) {
  1646. if(!now) now = now_realtime_sec();
  1647. int absolute_period_requested = -1;
  1648. time_t before_requested = *before;
  1649. time_t after_requested = *after;
  1650. // allow relative for before (smaller than API_RELATIVE_TIME_MAX)
  1651. if(ABS(before_requested) <= API_RELATIVE_TIME_MAX) {
  1652. // if the user asked for a positive relative time,
  1653. // flip it to a negative
  1654. if(before_requested > 0)
  1655. before_requested = -before_requested;
  1656. before_requested = now + before_requested;
  1657. absolute_period_requested = 0;
  1658. }
  1659. // allow relative for after (smaller than API_RELATIVE_TIME_MAX)
  1660. if(ABS(after_requested) <= API_RELATIVE_TIME_MAX) {
  1661. if(after_requested > 0)
  1662. after_requested = -after_requested;
  1663. // if the user didn't give an after, use the number of points
  1664. // to give a sane default
  1665. if(after_requested == 0)
  1666. after_requested = -600;
  1667. // since the query engine now returns inclusive timestamps
  1668. // it is awkward to return 6 points when after=-5 is given
  1669. // so for relative queries we add 1 second, to give
  1670. // more predictable results to users.
  1671. after_requested = before_requested + after_requested + 1;
  1672. absolute_period_requested = 0;
  1673. }
  1674. if(absolute_period_requested == -1)
  1675. absolute_period_requested = 1;
  1676. // check if the parameters are flipped
  1677. if(after_requested > before_requested) {
  1678. long long t = before_requested;
  1679. before_requested = after_requested;
  1680. after_requested = t;
  1681. }
  1682. // if the query requests future data
  1683. // shift the query back to be in the present time
  1684. // (this may also happen because of the rules above)
  1685. if(before_requested > now) {
  1686. time_t delta = before_requested - now;
  1687. before_requested -= delta;
  1688. after_requested -= delta;
  1689. }
  1690. *before = before_requested;
  1691. *after = after_requested;
  1692. return (absolute_period_requested != 1);
  1693. }
  1694. // Returns 1 if an absolute period was requested or 0 if it was a relative period
  1695. bool rrdr_relative_window_to_absolute_query(time_t *after, time_t *before, time_t *now_ptr, bool unittest_running) {
  1696. time_t now = now_realtime_sec() - 1;
  1697. if(now_ptr)
  1698. *now_ptr = now;
  1699. time_t before_requested = *before;
  1700. time_t after_requested = *after;
  1701. int absolute_period_requested = rrdr_relative_window_to_absolute(&after_requested, &before_requested, now);
  1702. time_t absolute_minimum_time = now - (10 * 365 * 86400);
  1703. time_t absolute_maximum_time = now + (1 * 365 * 86400);
  1704. if (after_requested < absolute_minimum_time && !unittest_running)
  1705. after_requested = absolute_minimum_time;
  1706. if (after_requested > absolute_maximum_time && !unittest_running)
  1707. after_requested = absolute_maximum_time;
  1708. if (before_requested < absolute_minimum_time && !unittest_running)
  1709. before_requested = absolute_minimum_time;
  1710. if (before_requested > absolute_maximum_time && !unittest_running)
  1711. before_requested = absolute_maximum_time;
  1712. *before = before_requested;
  1713. *after = after_requested;
  1714. return (absolute_period_requested != 1);
  1715. }
  1716. int netdata_base64_decode(const char *encoded, char *decoded, size_t decoded_size) {
  1717. static const unsigned char base64_table[256] = {
  1718. ['A'] = 0, ['B'] = 1, ['C'] = 2, ['D'] = 3, ['E'] = 4, ['F'] = 5, ['G'] = 6, ['H'] = 7,
  1719. ['I'] = 8, ['J'] = 9, ['K'] = 10, ['L'] = 11, ['M'] = 12, ['N'] = 13, ['O'] = 14, ['P'] = 15,
  1720. ['Q'] = 16, ['R'] = 17, ['S'] = 18, ['T'] = 19, ['U'] = 20, ['V'] = 21, ['W'] = 22, ['X'] = 23,
  1721. ['Y'] = 24, ['Z'] = 25, ['a'] = 26, ['b'] = 27, ['c'] = 28, ['d'] = 29, ['e'] = 30, ['f'] = 31,
  1722. ['g'] = 32, ['h'] = 33, ['i'] = 34, ['j'] = 35, ['k'] = 36, ['l'] = 37, ['m'] = 38, ['n'] = 39,
  1723. ['o'] = 40, ['p'] = 41, ['q'] = 42, ['r'] = 43, ['s'] = 44, ['t'] = 45, ['u'] = 46, ['v'] = 47,
  1724. ['w'] = 48, ['x'] = 49, ['y'] = 50, ['z'] = 51, ['0'] = 52, ['1'] = 53, ['2'] = 54, ['3'] = 55,
  1725. ['4'] = 56, ['5'] = 57, ['6'] = 58, ['7'] = 59, ['8'] = 60, ['9'] = 61, ['+'] = 62, ['/'] = 63,
  1726. [0 ... '+' - 1] = 255,
  1727. ['+' + 1 ... '/' - 1] = 255,
  1728. ['9' + 1 ... 'A' - 1] = 255,
  1729. ['Z' + 1 ... 'a' - 1] = 255,
  1730. ['z' + 1 ... 255] = 255
  1731. };
  1732. size_t count = 0;
  1733. unsigned int tmp = 0;
  1734. int i, bit;
  1735. if (decoded_size < 1)
  1736. return 0; // Buffer size must be at least 1 for null termination
  1737. for (i = 0, bit = 0; encoded[i]; i++) {
  1738. unsigned char value = base64_table[(unsigned char)encoded[i]];
  1739. if (value > 63)
  1740. return -1; // Invalid character in input
  1741. tmp = tmp << 6 | value;
  1742. if (++bit == 4) {
  1743. if (count + 3 >= decoded_size) break; // Stop decoding if buffer is full
  1744. decoded[count++] = (tmp >> 16) & 0xFF;
  1745. decoded[count++] = (tmp >> 8) & 0xFF;
  1746. decoded[count++] = tmp & 0xFF;
  1747. tmp = 0;
  1748. bit = 0;
  1749. }
  1750. }
  1751. if (bit > 0 && count + 1 < decoded_size) {
  1752. tmp <<= 6 * (4 - bit);
  1753. if (bit > 2 && count + 1 < decoded_size) decoded[count++] = (tmp >> 16) & 0xFF;
  1754. if (bit > 3 && count + 1 < decoded_size) decoded[count++] = (tmp >> 8) & 0xFF;
  1755. }
  1756. decoded[count] = '\0'; // Null terminate the output string
  1757. return count;
  1758. }