summaryrefslogtreecommitdiffstats
path: root/ctdb/common/conf.h
blob: 6b152c1c3587deced9cea195d782a4cdbeea5735 (plain)
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
/*
   Configuration file handling on top of tini

   Copyright (C) Amitay Isaacs  2017

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __CTDB_CONF_H__
#define __CTDB_CONF_H__

#include <stdio.h>
#include <stdbool.h>
#include <talloc.h>

/**
 * @file conf.h
 *
 * @brief Configuration file handling with sections and key-value pairs
 *
 * CTDB settings can be written in a configuration file ctdb.conf (similar to
 * samba's smb.conf).  Various daemons and tools will consult the configuration
 * file for runtime settings.
 *
 * The configuration will be organized in sections depending on various
 * components. Each section will have various configuration options in the form
 * of key-value pairs.
 *
 * [section1]
 *	key1 = value1
 *	...
 *
 * [section2]
 *	key2 = value2
 *	...
 *
 * ...
 *
 */

/**
 * @brief Abstract data structure holding the configuration options
 */
struct conf_context;

/**
 * @brief configuration option update mode
 *
 * When a value of configuration option is changed, update mode is set
 * appropriately.
 *
 * CONF_MODE_API - value modified using set functions
 * CONF_MODE_LOAD - value modified via conf_load
 * CONF_MODE_RELOAD - value modified via conf_reload
 */
enum conf_update_mode {
	CONF_MODE_API,
	CONF_MODE_LOAD,
	CONF_MODE_RELOAD,
};

/**
 * @brief configuration option type
 */
enum conf_type {
	CONF_STRING,
	CONF_INTEGER,
	CONF_BOOLEAN,
};

/**
 * @brief Configuration section validation function
 *
 * Check if all the configuration options are consistent with each-other
 */
typedef bool (*conf_validate_section_fn)(struct conf_context *conf,
					 const char *section,
					 enum conf_update_mode mode);

/**
 * @brief Configuration option validation function for string
 *
 * Check if a configuration option value is valid
 */
typedef bool (*conf_validate_string_option_fn)(const char *key,
					       const char *old_value,
					       const char *new_value,
					       enum conf_update_mode mode);

/**
 * @brief Configuration option validation function for integer
 *
 * Check if a configuration option value is valid
 */
typedef bool (*conf_validate_integer_option_fn)(const char *key,
						int old_value,
						int new_value,
						enum conf_update_mode mode);

/**
 * @brief Configuration option validation function for boolean
 *
 * Check if a configuration option value is valid
 */
typedef bool (*conf_validate_boolean_option_fn)(const char *key,
						bool old_value,
						bool new_value,
						enum conf_update_mode mode);

/**
 * @brief Initialize configuration option database
 *
 * This return a new configuration options context.  Freeing this context will
 * free up all the memory associated with the configuration options.
 *
 * @param[in] mem_ctx  Talloc memory context
 * @param[in] result  The new configuration options context
 * @return 0 on success, errno on failure
 */
int conf_init(TALLOC_CTX *mem_ctx, struct conf_context **result);

/**
 * @brief Define a section for organizing configuration options
 *
 * This functions creates a section to organize configuration option.  The
 * section names are case-insensitive and are always stored in lower case.
 *
 * @param[in] conf  The configuration options context
 * @param[in] section  The name of the section
 * @param[in] validate  The validation function for configuration options
 */
void conf_define_section(struct conf_context *conf,
			 const char *section,
			 conf_validate_section_fn validate);

/**
 * @brief Define a configuration option which has a string value
 *
 * This functions adds a new configuration option organized under a given
 * section.  Configuration options are case-insensitive and are always stored
 * in lower case.
 *
 * @param[in] conf  The configuration options context
 * @param[in] section  The name of the section
 * @param[in] key  The name of the configuration option
 * @param[in] default_value  The default value for the configuration option
 * @param[in] validate  The validation function for the configuration option
 */
void conf_define_string(struct conf_context *conf,
			const char *section,
			const char *key,
			const char *default_value,
			conf_validate_string_option_fn validate);

/**
 * @brief Define a configuration option which has an integer value
 *
 * This functions adds a new configuration option organized under a given
 * section.  Configuration options are case-insensitive and are always stored
 * in lower case.
 *
 * @param[in] conf  The configuration options context
 * @param[in] section  The name of the section
 * @param[in] key  The name of the configuration option
 * @param[in] default_value  The default value for the configuration option
 * @param[in] validate  The validation function for the configuration option
 */
void conf_define_integer(struct conf_context *conf,
			 const char *section,
			 const char *key,
			 const int default_value,
			 conf_validate_integer_option_fn validate);

/**
 * @brief Define a configuration option which has an boolean value
 *
 * This functions adds a new configuration option organized under a given
 * section.  Configuration options are case-insensitive and are always stored
 * in lower case.
 *
 * @param[in] conf  The configuration options context
 * @param[in] section  The name of the section
 * @param[in] key  The name of the configuration option
 * @param[in] default_value  The default value for the configuration option
 * @param[in] validate  The validation function for the configuration option
 */
void conf_define_boolean(struct conf_context *conf,
			 const char *section,
			 const char *key,
			 const bool default_value,
			 conf_validate_boolean_option_fn validate);

/**
 * @brief Assign user-accessible pointer for string option
 *
 * This pointer can be used for accessing the value of configuration option
 * directly without requiring a function call.
 *
 * @param[in] conf  The configuration options context
 * @param[in] section  The name of the section
 * @param[in] key  The name of the configuration option
 * @param[in] ptr  User-accessible pointer to the value
 */
void conf_assign_string_pointer(struct conf_context *conf,
				const char *section,
				const char *key,
				const char **ptr);

/**
 * @brief Assign user-accessible pointer for integer option
 *
 * This pointer can be used for accessing the value of configuration option
 * directly without requiring a function call.
 *
 * @param[in] conf  The configuration options context
 * @param[in] section  The name of the section
 * @param[in] key  The name of the configuration option
 * @param[in] ptr  User-accessible pointer to the value
 */
void conf_assign_integer_pointer(struct conf_context *conf,
				 const char *section,
				 const char *key,
				 int *ptr);

/**
 * @brief Assign user-accessible pointer for boolean option
 *
 * This pointer can be used for accessing the value of configuration option
 * directly without requiring a function call.
 *
 * @param[in] conf  The configuration options context
 * @param[in] section  The name of the section
 * @param[in] key  The name of the configuration option
 * @param[in] ptr  User-accessible pointer to the value
 * @return true on success, false on failure
 */
void conf_assign_boolean_pointer(struct conf_context *conf,
				 const char *section,
				 const char *key,
				 bool *ptr);

/**
 * @brief Query a configuration option
 *
 * This function checks if a configuration option is defined or not.
 *
 * @param[in] conf  The configuration options context
 * @param[in] section  The name of the section
 * @param[in] key  The name of the configuration option
 * @param[out] type  The type of the configuration option
 * @return true on success, false if section/option is not defined
 */
bool conf_query(struct conf_context *conf,
		const char *section,
		const char *key,
		enum conf_type *type);

/**
 * @brief Check if the defined configuration options are valid
 *
 * This function must be called after creating configuration options
 * to confirm that all the option definitions are valid.
 *
 * @param[in] conf  The configuration options context
 * @return true on success, false on failure
 */
bool conf_valid(struct conf_context *conf);

/**
 * @brief Set the default values for all configuration options
 *
 * This function resets all the configuration options to their default values.
 *
 * @param[in] conf  The connfiguration options context
 */
void conf_set_defaults(struct conf_context *conf);

/**
 * @brief Load the values for configuration option values from a file
 *
 * This function will update the values of the configuration options from those
 * specified in a file.  This function will fail in case it encounters an
 * undefined option.  Any sections which are not defined, will be ignored.
 *
 * This function will call validation function (if specified) before updating
 * the value of a configuration option.  After updating all the values for a
 * section, the validation for section (if specified) will be called.  If any
 * of the validation functions return error, then all the configuration
 * options will be reset to their previous values.
 *
 * @param[in] conf  The configuration options context
 * @param[in] filename  The configuration file
 * @param[in] skip_unknown  Whether unknown config options should be ignored
 * @return 0 on success, errno on failure
 */
int conf_load(struct conf_context *conf,
	      const char *filename,
	      bool ignore_unknown);

/**
 * @brief Reload the values for configuration options
 *
 * This function will re-load the values of the configuration options.  This
 * function can be called only after succesful call to conf_load().
 *
 * @see conf_load
 *
 * @param[in] conf  The configuration options context
 * @return 0 on success, errno on failure.
 */
int conf_reload(struct conf_context *conf);

/**
 * @brief Set the string value of a configuration option
 *
 * This function can be used to update the value of a configuration option.
 * This will call the validation function for that option (if defined) and
 * the section validation function (if defined).
 *
 * If a user-defined storage pointer is provided, then the value of a
 * configuration option should not be changed via that pointer.
 *
 * @param[in] conf  The configuration options context
 * @param[in] section  The name of a section
 * @param[in] key  The name of a configuration option
 * @param[in] str_val  The string value
 * @return 0 on success, errno in case of failure
 */
int conf_set_string(struct conf_context *conf,
		    const char *section,
		    const char *key,
		    const char *str_val);

/**
 * @brief Set the integer value of a configuration option
 *
 * This function can be used to update the value of a configuration option.
 * This will call the validation function for that option (if defined) and
 * the section validation function (if defined).
 *
 * If a user-defined storage pointer is provided, then the value of a
 * configuration option should not be changed via that pointer.
 *
 * @param[in] conf  The configuration options context
 * @param[in] section  The name of a section
 * @param[in] key  The name of a configuration option
 * @param[in] int_val  The integer value
 * @return 0 on success, errno in case of failure
 */
int conf_set_integer(struct conf_context *conf,
		     const char *section,
		     const char *key,
		     int int_val);

/**
 * @brief Set the boolean value of a configuration option
 *
 * This function can be used to update the value of a configuration option.
 * This will call the validation function for that option (if defined) and
 * the section validation function (if defined).
 *
 * If a user-defined storage pointer is provided, then the value of a
 * configuration option should not be changed via that pointer.
 *
 * @param[in] conf  The configuration options context
 * @param[in] section  The name of a section
 * @param[in] key  The name of a configuration option
 * @param[in] bool_val  The boolean value
 * @return 0 on success, errno in case of failure
 */
int conf_set_boolean(struct conf_context *conf,
		     const char *section,
		     const char *key,
		     bool bool_val);

/**
 * @brief Get the string value of a configuration option
 *
 * This function can be used to fetch the current value of a configuration
 * option.
 *
 * If a user-defined storage pointer is provided, then the value of a
 * configuration option can be accessed directly via that pointer.
 *
 * @param[in] conf  The configuration options context
 * @param[in] section  The name of a section
 * @param[in] key  The name of a configuration option
 * @param[out] str_val  The string value of the configuration option
 * @param[out] is_default  True if the value is default value
 * @return 0 on success, errno in case of failure
 */
int conf_get_string(struct conf_context *conf,
		    const char *section,
		    const char *key,
		    const char **str_val,
		    bool *is_default);

/**
 * @brief Get the integer value of a configuration option
 *
 * This function can be used to fetch the current value of a configuration
 * option.
 *
 * If a user-defined storage pointer is provided, then the value of a
 * configuration option can be accessed directly via that pointer.
 *
 * @param[in] conf  The configuration options context
 * @param[in] section  The name of a section
 * @param[in] key  The name of a configuration option
 * @param[out] int_val  The integer value of the configuration option
 * @param[out] is_default  True if the value is default value
 * @return 0 on success, errno in case of failure
 */
int conf_get_integer(struct conf_context *conf,
		     const char *section,
		     const char *key,
		     int *int_val,
		     bool *is_default);

/**
 * @brief Get the boolean value of a configuration option
 *
 * This function can be used to fetch the current value of a configuration
 * option.
 *
 * If a user-defined storage pointer is provided, then the value of a
 * configuration option can be accessed directly via that pointer.
 *
 * @param[in] conf  The configuration options context
 * @param[in] section  The name of a section
 * @param[in] key  The name of a configuration option
 * @param[out] bool_val  The boolean value of the configuration option
 * @param[out] is_default  True if the value is default value
 * @return 0 on success, errno in case of failure
 */
int conf_get_boolean(struct conf_context *conf,
		     const char *section,
		     const char *key,
		     bool *bool_val,
		     bool *is_default);

/**
 * @brief Dump the configuration in a file
 *
 * All the configuration options are dumped with their current values.
 * If an option has a default value, then it is commented.
 *
 * Here is a sample output:
 *
 * [section1]
 *	key1 = value1
 *	key2 = value2
 *	# key3 = default_value3
 * [section2]
 *	key4 = value4
 *
 * @param[in] conf  The configuration options context
 * @param[in] fp  File pointer
 */
void conf_dump(struct conf_context *conf, FILE *fp);

#endif /* __CTDB_CONF_H__ */