master
h 229 lines 11.1 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #ifndef LIBNETDATA_INICFG_H
4 #define LIBNETDATA_INICFG_H
5
6 /*
7 * This section manages ini config files, like netdata.conf and stream.conf
8 *
9 * It is organized like this:
10 *
11 * struct config (i.e. netdata.conf or stream.conf)
12 * .sections = a linked list of struct section
13 * .mutex = a mutex to protect the above linked list due to multi-threading
14 * .index = an AVL tree of struct section
15 *
16 * struct section (i.e. [global] or [health] of netdata.conf)
17 * .value = a linked list of struct config_option
18 * .mutex = a mutex to protect the above linked list due to multi-threading
19 * .value_index = an AVL tree of struct config_option
20 *
21 * struct config_option (ie. a name-value pair for each ini file option)
22 *
23 * The following operations on name-value options are supported:
24 * SET to set the value of an option
25 * SET DEFAULT to set the value and the default value of an option
26 * GET to get the value of an option
27 * EXISTS to check if an option exists
28 * MOVE to move an option from a section to another section, and/or rename it
29 *
30 * GET and SET operations are provided for the following data types:
31 * STRING
32 * NUMBER (long long)
33 * FLOAT (long double)
34 * BOOLEAN (false, true)
35 * BOOLEAN ONDEMAND (false, true, auto)
36 *
37 * GET and SET operations create struct config_option, if it is not already present.
38 * This allows netdata to run even without netdata.conf and stream.conf. The internal
39 * defaults are used to create the structure that should exist in the ini file and the config
40 * file can be downloaded from the server.
41 *
42 * Also 2 operations are supported for the whole config file:
43 *
44 * LOAD To load the ini file from disk
45 * GENERATE To generate the ini file (this is used to download the ini file from the server)
46 *
47 * For each option (name-value pair), the system maintains 4 flags:
48 * LOADED to indicate that the value has been loaded from the file
49 * USED to indicate that netdata used the value
50 * CHANGED to indicate that the value has been changed from the loaded value or the internal default value
51 * CHECKED is used internally for optimization (to avoid an strcmp() every time GET is called).
52 *
53 * TODO:
54 * 1. The linked lists and the mutexes can be removed and the AVL trees can become DICTIONARY.
55 * This part of the code was written before we add traversal to AVL.
56 *
57 * 2. High level data types could be supported, to simplify the rest of the code:
58 * MULTIPLE CHOICE to let the user select one of the supported keywords
59 * this would allow users see in comments the available options
60 *
61 * SIMPLE PATTERN to let the user define netdata SIMPLE PATTERNS
62 *
63 * 3. Sorting of options should be supported.
64 * Today, when the ini file is downloaded from the server, the options are shown in the order
65 * they appear in the linked list (the order they were added, listing changed options first).
66 * If we remove the linked list, the order they appear in the AVL tree will be used (which is
67 * random due to simple_hash()).
68 * Ideally, we support sorting of options when generating the ini file.
69 *
70 * 4. There is no free() operation. So, memory is freed on netdata exit.
71 *
72 * 5. Avoid memory fragmentation
73 * Since entries are created from multiple threads and a lot of allocations are required
74 * for each config_option, fragmentation can be a problem for IoT.
75 *
76 * 6. Although this way of managing options is quite flexible and dynamic, it wastes memory
77 * for the names of the options. Since most of the option names are static, we could provide
78 * a method to allocate only the dynamic option names.
79 */
80
81 #include "../libnetdata.h"
82
83 #define CONFIG_FILENAME "netdata.conf"
84
85 #define CONFIG_SECTION_GLOBAL "global"
86 #define CONFIG_SECTION_DIRECTORIES "directories"
87 #define CONFIG_SECTION_LOGS "logs"
88 #define CONFIG_SECTION_ENV_VARS "environment variables"
89 #define CONFIG_SECTION_SQLITE "sqlite"
90 #define CONFIG_SECTION_WEB "web"
91 #define CONFIG_SECTION_WEBRTC "webrtc"
92 #define CONFIG_SECTION_STATSD "statsd"
93 #define CONFIG_SECTION_PLUGINS "plugins"
94 #define CONFIG_SECTION_CLOUD "cloud"
95 #define CONFIG_SECTION_REGISTRY "registry"
96 #define CONFIG_SECTION_HEALTH "health"
97 #define CONFIG_SECTION_STREAM "stream"
98 #define CONFIG_SECTION_ML "ml"
99 #define CONFIG_SECTION_EXPORTING "exporting:global"
100 #define CONFIG_SECTION_PROMETHEUS "prometheus:exporter"
101 #define CONFIG_SECTION_HOST_LABEL "host labels"
102 #define EXPORTING_CONF "exporting.conf"
103 #define CONFIG_SECTION_PULSE "pulse"
104 #define CONFIG_SECTION_DB "db"
105
106 // these are used to limit the configuration names and values lengths
107 // they are not enforced by config.c functions (they will strdup() all strings, no matter of their length)
108 #define CONFIG_MAX_NAME 1024
109 #define CONFIG_MAX_VALUE 2048
110
111 // ----------------------------------------------------------------------------
112 // Config definitions
113 #define CONFIG_FILE_LINE_MAX ((CONFIG_MAX_NAME + CONFIG_MAX_VALUE + 1024) * 2)
114
115 struct config_section;
116
117 struct config {
118 struct config_section *sections;
119 SPINLOCK spinlock;
120 avl_tree_lock index;
121 };
122
123 #define APPCONFIG_INITIALIZER (struct config) { \
124 .sections = NULL, \
125 .spinlock = SPINLOCK_INITIALIZER, \
126 .index = { \
127 .avl_tree = { \
128 .root = NULL, \
129 .compar = inicfg_section_compare, \
130 }, \
131 .rwlock = AVL_LOCK_INITIALIZER, \
132 }, \
133 }
134
135 int inicfg_load(struct config *root, char *filename, int overwrite_used, const char *section_name);
136
137 typedef bool (*inicfg_foreach_value_cb_t)(void *data, const char *name, const char *value);
138 size_t inicfg_foreach_value_in_section(struct config *root, const char *section, inicfg_foreach_value_cb_t cb, void *data);
139
140 // sets a raw value, only if it is not loaded from the config
141 void inicfg_set_default_raw_value(struct config *root, const char *section, const char *name, const char *value);
142
143 int inicfg_exists(struct config *root, const char *section, const char *name);
144 int inicfg_move(struct config *root, const char *section_old, const char *name_old, const char *section_new, const char *name_new);
145 int inicfg_move_everywhere(struct config *root, const char *name_old, const char *name_new);
146
147 void inicfg_generate(struct config *root, BUFFER *wb, int only_changed, bool netdata_conf);
148
149 int inicfg_section_compare(void *a, void *b);
150
151 bool inicfg_test_boolean_value(const char *s);
152
153 struct connector_instance {
154 char instance_name[CONFIG_MAX_NAME + 1];
155 char connector_name[CONFIG_MAX_NAME + 1];
156 };
157
158 typedef struct _connector_instance {
159 struct config_section *connector; // actual connector
160 struct config_section *instance; // This instance
161 char instance_name[CONFIG_MAX_NAME + 1];
162 char connector_name[CONFIG_MAX_NAME + 1];
163 struct _connector_instance *next; // Next instance
164 } _CONNECTOR_INSTANCE;
165
166 _CONNECTOR_INSTANCE *add_connector_instance(struct config_section *connector, struct config_section *instance);
167
168 // ----------------------------------------------------------------------------
169 // shortcuts for the default netdata configuration
170
171 extern struct config netdata_config;
172
173 bool stream_conf_needs_dbengine(struct config *root);
174 bool stream_conf_has_api_enabled(struct config *root);
175
176 /**
177 * Free all configuration resources
178 *
179 * This function frees all memory associated with a configuration,
180 * including all sections and options.
181 *
182 * @param root The config structure to free
183 */
184 void inicfg_free(struct config *root);
185
186 const char *inicfg_get(struct config *root, const char *section, const char *name, const char *default_value);
187 const char *inicfg_set(struct config *root, const char *section, const char *name, const char *value);
188 const char *inicfg_get_filename(struct config *root, const char *section, const char *name, const char *default_value);
189 const char *inicfg_get_path(struct config *root, const char *section, const char *name, const char *default_value);
190 const char *inicfg_get_path_list(struct config *root, const char *section, const char *name, const char *default_value);
191 const char *inicfg_get_quoted_path_list(struct config *root, const char *section, const char *name, const char *default_value);
192 const char *inicfg_get_log_path_setting(struct config *root, const char *section, const char *name, const char *default_value);
193 const char *inicfg_log_path_setting_for_display(const char *value, char *dst, size_t dst_size);
194
195 long long inicfg_get_number(struct config *root, const char *section, const char *name, long long value);
196 long long inicfg_get_number_range(struct config *root, const char *section, const char *name, long long value, long long min, long long max);
197
198 long long inicfg_set_number(struct config *root, const char *section, const char *name, long long value);
199 NETDATA_DOUBLE inicfg_get_double(struct config *root, const char *section, const char *name, NETDATA_DOUBLE value);
200 NETDATA_DOUBLE inicfg_set_double(struct config *root, const char *section, const char *name, NETDATA_DOUBLE value);
201
202 // disabled
203 #define CONFIG_BOOLEAN_NO 0
204 // enabled
205 #define CONFIG_BOOLEAN_YES 1
206 // enabled if it has useful info when enabled
207 #define CONFIG_BOOLEAN_AUTO 2
208 // an invalid value to check for validity (used as default initialization when needed)
209 #define CONFIG_BOOLEAN_INVALID 100
210
211 int inicfg_get_boolean(struct config *root, const char *section, const char *name, int value);
212 int inicfg_get_boolean_ondemand(struct config *root, const char *section, const char *name, int value);
213 int inicfg_set_boolean(struct config *root, const char *section, const char *name, int value);
214
215 uint64_t inicfg_get_size_bytes(struct config *root, const char *section, const char *name, uint64_t default_value);
216 uint64_t inicfg_set_size_bytes(struct config *root, const char *section, const char *name, uint64_t value);
217
218 uint64_t inicfg_get_size_mb(struct config *root, const char *section, const char *name, uint64_t default_value);
219 uint64_t inicfg_set_size_mb(struct config *root, const char *section, const char *name, uint64_t value);
220
221 msec_t inicfg_get_duration_ms(struct config *root, const char *section, const char *name, msec_t default_value);
222 msec_t inicfg_set_duration_ms(struct config *root, const char *section, const char *name, msec_t value);
223
224 time_t inicfg_get_duration_seconds(struct config *root, const char *section, const char *name, time_t default_value);
225 time_t inicfg_set_duration_seconds(struct config *root, const char *section, const char *name, time_t value);
226
227 time_t inicfg_get_duration_days_to_seconds(struct config *root, const char *section, const char *name, unsigned default_value_seconds);
228
229 #endif // LIBNETDATA_INICFG_H