master
c 171 lines 5.81 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include "netdata-conf-global.h"
4 #include "daemon/common.h"
5
6 size_t netdata_conf_cpus(void) {
7 static size_t processors = 0;
8
9 if(processors)
10 return processors;
11
12 SPINLOCK spinlock = SPINLOCK_INITIALIZER;
13 spinlock_lock(&spinlock);
14 size_t p = 0;
15
16 if(processors)
17 goto skip;
18
19 #if defined(OS_LINUX)
20 p = os_read_cpuset_cpus("/sys/fs/cgroup/cpuset.cpus", p);
21 if(!p)
22 p = os_read_cpuset_cpus("/sys/fs/cgroup/cpuset/cpuset.cpus", p);
23 #endif
24
25 if(!p)
26 p = os_get_system_cpus_uncached();
27
28 p = inicfg_get_number(&netdata_config, CONFIG_SECTION_GLOBAL, "cpu cores", p);
29 if(p < 1)
30 p = 1;
31
32 processors = p;
33
34 char buf[24];
35 snprintfz(buf, sizeof(buf), "%zu", processors);
36 nd_setenv("NETDATA_CONF_CPUS", buf, 1);
37
38 skip:
39 spinlock_unlock(&spinlock);
40 return processors;
41 }
42
43 void netdata_conf_glibc_malloc_initialize(size_t wanted_arenas, size_t trim_threshold __maybe_unused) {
44 wanted_arenas = inicfg_get_number(&netdata_config, CONFIG_SECTION_GLOBAL, "glibc malloc arena max for plugins", wanted_arenas);
45 if(wanted_arenas < 1 || wanted_arenas > os_get_system_cpus_cached(true)) {
46 if(wanted_arenas < 1) wanted_arenas = 1;
47 else wanted_arenas = os_get_system_cpus_cached(true);
48 inicfg_set_number(&netdata_config, CONFIG_SECTION_GLOBAL, "glibc malloc arena max for plugins", wanted_arenas);
49 nd_log(NDLS_DAEMON, NDLP_NOTICE,
50 "malloc arenas can be from 1 to %zu. Setting it to %zu",
51 os_get_system_cpus_cached(true), wanted_arenas);
52 }
53
54 char buf[32];
55 snprintfz(buf, sizeof(buf), "%zu", wanted_arenas);
56 setenv("MALLOC_ARENA_MAX", buf, true);
57
58 #if defined(HAVE_C_MALLOPT)
59 wanted_arenas = inicfg_get_number(&netdata_config, CONFIG_SECTION_GLOBAL, "glibc malloc arena max for netdata", wanted_arenas);
60 if(wanted_arenas < 1 || wanted_arenas > os_get_system_cpus_cached(true)) {
61 if(wanted_arenas < 1) wanted_arenas = 1;
62 else wanted_arenas = os_get_system_cpus_cached(true);
63 inicfg_set_number(&netdata_config, CONFIG_SECTION_GLOBAL, "glibc malloc arena max for netdata", wanted_arenas);
64 nd_log(NDLS_DAEMON, NDLP_NOTICE,
65 "malloc arenas can be from 1 to %zu. Setting it to %zu",
66 os_get_system_cpus_cached(true), wanted_arenas);
67 }
68 mallopt(M_ARENA_MAX, (int)wanted_arenas);
69 mallopt(M_TRIM_THRESHOLD, (int)trim_threshold);
70
71 #ifdef NETDATA_INTERNAL_CHECKS
72 mallopt(M_PERTURB, 0x5A);
73 // mallopt(M_MXFAST, 0);
74 #endif
75 #endif
76 }
77
78 static size_t default_stacksize = 8ULL * 1024 * 1024; // default is 8MiB
79
80 static void netdata_conf_stack_size(void) {
81 FUNCTION_RUN_ONCE();
82
83 // initialize thread - this is required before the first nd_thread_create()
84 default_stacksize = netdata_threads_init();
85
86 // musl default thread stack size is 128k, let's set it to a higher value to avoid random crashes
87 if (default_stacksize < 1 * 1024 * 1024)
88 default_stacksize = 1 * 1024 * 1024;
89
90 // Let the user override the default stack size
91 default_stacksize = inicfg_get_size_bytes(&netdata_config, CONFIG_SECTION_GLOBAL, "pthread stack size", default_stacksize);
92
93 netdata_threads_set_stack_size(default_stacksize);
94
95 }
96
97 void netdata_conf_reset_stack_size(void) {
98 netdata_threads_set_stack_size(default_stacksize);
99 }
100
101 void libuv_initialize(void) {
102 netdata_conf_stack_size();
103
104 // libuv worker threads need to limited by the amount of memory the system has,
105 // otherwise the system may refuse to create that many threads.
106
107 // our original target
108 libuv_worker_threads = (int)netdata_conf_cpus() * 6;
109
110 OS_SYSTEM_MEMORY mem = os_system_memory(true);
111 if(OS_SYSTEM_MEMORY_OK(mem)) {
112 // we have memory information
113 uint64_t mem_for_threads1 = mem.ram_total_bytes / 20;
114 uint64_t mem_for_threads2 = mem.ram_available_bytes / 10;
115 uint64_t mem_for_threads = MIN(mem_for_threads1, mem_for_threads2);
116
117 int max_allowed_threads = (int)HOWMANY(mem_for_threads, default_stacksize);
118 if(max_allowed_threads < MIN_LIBUV_WORKER_THREADS)
119 max_allowed_threads = MIN_LIBUV_WORKER_THREADS;
120
121 if(libuv_worker_threads > max_allowed_threads)
122 libuv_worker_threads = max_allowed_threads;
123 }
124
125 libuv_worker_threads = MIN(MAX_LIBUV_WORKER_THREADS, MAX(MIN_LIBUV_WORKER_THREADS, libuv_worker_threads));
126
127 libuv_worker_threads = (int)inicfg_get_number_range(
128 &netdata_config, CONFIG_SECTION_GLOBAL, "libuv worker threads",
129 libuv_worker_threads, MIN_LIBUV_WORKER_THREADS, MAX_LIBUV_WORKER_THREADS);
130
131 char buf[20 + 1];
132 snprintfz(buf, sizeof(buf) - 1, "%d", libuv_worker_threads);
133 setenv("UV_THREADPOOL_SIZE", buf, 1);
134 }
135
136 void netdata_conf_section_global_hostname(void) {
137 FUNCTION_RUN_ONCE();
138
139 nd_runtime_paths_load_hostname_from_inicfg();
140 }
141
142 void netdata_conf_section_global(void) {
143 FUNCTION_RUN_ONCE();
144
145 netdata_conf_section_directories();
146 netdata_conf_section_global_hostname();
147
148 nd_profile_setup(); // required for configuring the database
149 netdata_conf_section_db();
150
151 // --------------------------------------------------------------------
152 // get various system parameters
153
154 os_get_system_cpus_uncached();
155 os_get_system_pid_max();
156 }
157
158 void netdata_conf_section_global_run_as_user(const char **user) {
159 // --------------------------------------------------------------------
160 // get the user we should run
161
162 // IMPORTANT: this is required before web_files_uid()
163 if(getuid() == 0) {
164 *user = inicfg_get(&netdata_config, CONFIG_SECTION_GLOBAL, "run as user", NETDATA_USER);
165 }
166 else {
167 struct passwd *passwd = getpwuid(getuid());
168 *user = inicfg_get(&netdata_config, CONFIG_SECTION_GLOBAL, "run as user", (passwd && passwd->pw_name)?passwd->pw_name:"");
169 }
170 }
171