]> git.proxmox.com Git - mirror_corosync.git/blame - exec/coroparse.c
knet: PMTUd data_mtu already accounts for IP and knet header overheads
[mirror_corosync.git] / exec / coroparse.c
CommitLineData
2f552719 1/*
bc47c583 2 * Copyright (c) 2006-2013 Red Hat, Inc.
2f552719
SD
3 *
4 * All rights reserved.
5 *
6 * Author: Patrick Caulfield (pcaulfie@redhat.com)
8a45e2b1 7 * Jan Friesse (jfriesse@redhat.com)
2f552719
SD
8 *
9 * This software licensed under BSD license, the text of which follows:
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
13 *
14 * - Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 * - Redistributions in binary form must reproduce the above copyright notice,
17 * this list of conditions and the following disclaimer in the documentation
18 * and/or other materials provided with the distribution.
19 * - Neither the name of the MontaVista Software, Inc. nor the names of its
20 * contributors may be used to endorse or promote products derived from this
21 * software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
33 * THE POSSIBILITY OF SUCH DAMAGE.
34 */
031c02f5
FDN
35
36#include <config.h>
37
2f552719
SD
38#include <sys/types.h>
39#include <sys/uio.h>
40#include <sys/socket.h>
1e0d40cd 41#include <sys/stat.h>
2f552719
SD
42#include <sys/un.h>
43#include <netinet/in.h>
44#include <arpa/inet.h>
45#include <unistd.h>
46#include <fcntl.h>
47#include <stdlib.h>
48#include <stdio.h>
49#include <errno.h>
2f552719 50#include <string.h>
ae229831 51#include <dirent.h>
6fd822c4 52#include <limits.h>
2290913d 53#include <stddef.h>
8a45e2b1
JF
54#include <grp.h>
55#include <pwd.h>
2f552719 56
b4c06e52 57#include <qb/qblist.h>
37e17e7a 58#include <qb/qbutil.h>
00434a4f 59#define LOGSYS_UTILS_ONLY 1
8ad583a5 60#include <corosync/logsys.h>
6f5e3293 61#include <corosync/icmap.h>
e1f53138 62
f763d3ba 63#include "main.h"
2f552719
SD
64#include "util.h"
65
8a45e2b1
JF
66enum parser_cb_type {
67 PARSER_CB_START,
68 PARSER_CB_END,
69 PARSER_CB_SECTION_START,
70 PARSER_CB_SECTION_END,
71 PARSER_CB_ITEM,
72};
73
8a45e2b1
JF
74enum main_cp_cb_data_state {
75 MAIN_CP_CB_DATA_STATE_NORMAL,
76 MAIN_CP_CB_DATA_STATE_TOTEM,
77 MAIN_CP_CB_DATA_STATE_INTERFACE,
78 MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS,
79 MAIN_CP_CB_DATA_STATE_UIDGID,
80 MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON,
81 MAIN_CP_CB_DATA_STATE_MEMBER,
82 MAIN_CP_CB_DATA_STATE_QUORUM,
cb5fd775 83 MAIN_CP_CB_DATA_STATE_QDEVICE,
6d0b0b14
JF
84 MAIN_CP_CB_DATA_STATE_NODELIST,
85 MAIN_CP_CB_DATA_STATE_NODELIST_NODE,
3cd4f9a1 86 MAIN_CP_CB_DATA_STATE_PLOAD,
39cd6b3d 87 MAIN_CP_CB_DATA_STATE_QB,
88 MAIN_CP_CB_DATA_STATE_RESOURCES,
89 MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM,
90 MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS,
91 MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_MEMUSED,
92 MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED
8a45e2b1
JF
93};
94
aab55a00
CC
95typedef int (*parser_cb_f)(const char *path,
96 char *key,
97 char *value,
98 enum main_cp_cb_data_state *state,
99 enum parser_cb_type type,
100 const char **error_string,
101 icmap_map_t config_map,
102 void *user_data);
103
8a45e2b1
JF
104struct key_value_list_item {
105 char *key;
106 char *value;
b4c06e52 107 struct qb_list_head list;
8a45e2b1
JF
108};
109
110struct main_cp_cb_data {
268cde6e 111 int linknumber;
8a45e2b1
JF
112 char *bindnetaddr;
113 char *mcastaddr;
114 char *broadcast;
115 int mcastport;
116 int ttl;
268cde6e
CC
117 int knet_link_priority;
118 int knet_ping_interval;
119 int knet_ping_timeout;
120 int knet_ping_precision;
7cec6a13
CC
121 int knet_pong_count;
122 int knet_pmtud_interval;
8a45e2b1 123
b4c06e52 124 struct qb_list_head logger_subsys_items_head;
8a45e2b1
JF
125 char *subsys;
126 char *logging_daemon_name;
b4c06e52 127 struct qb_list_head member_items_head;
6d0b0b14
JF
128
129 int node_number;
130 int ring0_addr_added;
8a45e2b1
JF
131};
132
133static int read_config_file_into_icmap(
bc47c583 134 const char **error_string, icmap_map_t config_map);
2f552719
SD
135static char error_string_response[512];
136
8a45e2b1
JF
137static int uid_determine (const char *req_user)
138{
139 int pw_uid = 0;
140 struct passwd passwd;
141 struct passwd* pwdptr = &passwd;
142 struct passwd* temp_pwd_pt;
143 char *pwdbuffer;
005e7fd3 144 int pwdlinelen, rc;
86b074dc
JF
145 long int id;
146 char *ep;
147
148 id = strtol(req_user, &ep, 10);
149 if (*ep == '\0' && id >= 0 && id <= UINT_MAX) {
150 return (id);
151 }
8a45e2b1
JF
152
153 pwdlinelen = sysconf (_SC_GETPW_R_SIZE_MAX);
154
155 if (pwdlinelen == -1) {
156 pwdlinelen = 256;
157 }
158
159 pwdbuffer = malloc (pwdlinelen);
160
005e7fd3
AB
161 while ((rc = getpwnam_r (req_user, pwdptr, pwdbuffer, pwdlinelen, &temp_pwd_pt)) == ERANGE) {
162 char *n;
163
164 pwdlinelen *= 2;
165 if (pwdlinelen <= 32678) {
166 n = realloc (pwdbuffer, pwdlinelen);
167 if (n != NULL) {
168 pwdbuffer = n;
169 continue;
52f88d04
JF
170 }
171 }
005e7fd3
AB
172 }
173 if (rc != 0) {
174 free (pwdbuffer);
175 sprintf (error_string_response, "getpwnam_r(): %s", strerror(rc));
176 return (-1);
177 }
178 if (temp_pwd_pt == NULL) {
52f88d04 179 free (pwdbuffer);
8a45e2b1
JF
180 sprintf (error_string_response,
181 "The '%s' user is not found in /etc/passwd, please read the documentation.",
182 req_user);
183 return (-1);
184 }
185 pw_uid = passwd.pw_uid;
186 free (pwdbuffer);
187
188 return pw_uid;
189}
190
191static int gid_determine (const char *req_group)
192{
7c8e83ac 193 int corosync_gid = 0;
8a45e2b1
JF
194 struct group group;
195 struct group * grpptr = &group;
196 struct group * temp_grp_pt;
197 char *grpbuffer;
005e7fd3 198 int grplinelen, rc;
86b074dc
JF
199 long int id;
200 char *ep;
201
202 id = strtol(req_group, &ep, 10);
203 if (*ep == '\0' && id >= 0 && id <= UINT_MAX) {
204 return (id);
205 }
8a45e2b1
JF
206
207 grplinelen = sysconf (_SC_GETGR_R_SIZE_MAX);
208
209 if (grplinelen == -1) {
210 grplinelen = 256;
211 }
212
213 grpbuffer = malloc (grplinelen);
214
005e7fd3
AB
215 while ((rc = getgrnam_r (req_group, grpptr, grpbuffer, grplinelen, &temp_grp_pt)) == ERANGE) {
216 char *n;
217
218 grplinelen *= 2;
219 if (grplinelen <= 32678) {
220 n = realloc (grpbuffer, grplinelen);
221 if (n != NULL) {
222 grpbuffer = n;
223 continue;
52f88d04
JF
224 }
225 }
005e7fd3
AB
226 }
227 if (rc != 0) {
228 free (grpbuffer);
229 sprintf (error_string_response, "getgrnam_r(): %s", strerror(rc));
230 return (-1);
231 }
232 if (temp_grp_pt == NULL) {
52f88d04 233 free (grpbuffer);
8a45e2b1
JF
234 sprintf (error_string_response,
235 "The '%s' group is not found in /etc/group, please read the documentation.",
236 req_group);
237 return (-1);
238 }
7c8e83ac 239 corosync_gid = group.gr_gid;
8a45e2b1 240 free (grpbuffer);
2f552719 241
7c8e83ac 242 return corosync_gid;
8a45e2b1 243}
3ffb151a
FDN
244static char *strchr_rs (const char *haystack, int byte)
245{
246 const char *end_address = strchr (haystack, byte);
247 if (end_address) {
248 end_address += 1; /* skip past { or = */
8a45e2b1
JF
249
250 while (*end_address == ' ' || *end_address == '\t')
251 end_address++;
3ffb151a
FDN
252 }
253
254 return ((char *) end_address);
255}
256
bc47c583 257int coroparse_configparse (icmap_map_t config_map, const char **error_string)
2f552719 258{
bc47c583 259 if (read_config_file_into_icmap(error_string, config_map)) {
2f552719
SD
260 return -1;
261 }
262
263 return 0;
264}
265
663489d2 266static char *remove_whitespace(char *string, int remove_colon_and_brace)
2f552719 267{
8a45e2b1
JF
268 char *start;
269 char *end;
2f552719 270
8a45e2b1
JF
271 start = string;
272 while (*start == ' ' || *start == '\t')
273 start++;
274
275 end = start+(strlen(start))-1;
663489d2 276 while ((*end == ' ' || *end == '\t' || (remove_colon_and_brace && (*end == ':' || *end == '{'))) && end > start)
2f552719
SD
277 end--;
278 if (end != start)
279 *(end+1) = '\0';
280
281 return start;
282}
283
ae229831 284
ae229831 285
2f552719 286static int parse_section(FILE *fp,
8a45e2b1 287 char *path,
ae229831 288 const char **error_string,
66172a50 289 int depth,
aab55a00 290 enum main_cp_cb_data_state state,
8a45e2b1 291 parser_cb_f parser_cb,
bc47c583 292 icmap_map_t config_map,
8a45e2b1 293 void *user_data)
2f552719
SD
294{
295 char line[512];
296 int i;
297 char *loc;
99db3567 298 int ignore_line;
8a45e2b1
JF
299 char new_keyname[ICMAP_KEYNAME_MAXLEN];
300
301 if (strcmp(path, "") == 0) {
aab55a00 302 parser_cb("", NULL, NULL, &state, PARSER_CB_START, error_string, config_map, user_data);
8a45e2b1 303 }
2f552719 304
94b64352
JF
305 while (fgets (line, sizeof (line), fp)) {
306 if (strlen(line) > 0) {
307 if (line[strlen(line) - 1] == '\n')
308 line[strlen(line) - 1] = '\0';
309 if (strlen (line) > 0 && line[strlen(line) - 1] == '\r')
310 line[strlen(line) - 1] = '\0';
311 }
2f552719
SD
312 /*
313 * Clear out white space and tabs
314 */
315 for (i = strlen (line) - 1; i > -1; i--) {
316 if (line[i] == '\t' || line[i] == ' ') {
317 line[i] = '\0';
318 } else {
319 break;
320 }
321 }
99db3567
JF
322
323 ignore_line = 1;
324 for (i = 0; i < strlen (line); i++) {
325 if (line[i] != '\t' && line[i] != ' ') {
326 if (line[i] != '#')
327 ignore_line = 0;
328
329 break;
330 }
331 }
2f552719
SD
332 /*
333 * Clear out comments and empty lines
334 */
99db3567 335 if (ignore_line) {
2f552719
SD
336 continue;
337 }
338
339 /* New section ? */
283011c6 340 if ((loc = strchr_rs (line, '{'))) {
663489d2 341 char *section = remove_whitespace(line, 1);
aab55a00 342 enum main_cp_cb_data_state newstate;
2f552719
SD
343
344 loc--;
345 *loc = '\0';
8a45e2b1 346
675da757
JF
347 if (strlen(path) + strlen(section) + 1 >= ICMAP_KEYNAME_MAXLEN) {
348 *error_string = "parser error: Start of section makes total cmap path too long";
349 return -1;
350 }
8a45e2b1
JF
351 strcpy(new_keyname, path);
352 if (strcmp(path, "") != 0) {
353 strcat(new_keyname, ".");
ae229831 354 }
8a45e2b1 355 strcat(new_keyname, section);
ae229831 356
aab55a00
CC
357 /* Only use the new state for items further down the stack */
358 newstate = state;
359 if (!parser_cb(new_keyname, NULL, NULL, &newstate, PARSER_CB_SECTION_START, error_string, config_map, user_data)) {
8a45e2b1
JF
360 return -1;
361 }
362
aab55a00 363 if (parse_section(fp, new_keyname, error_string, depth + 1, newstate, parser_cb, config_map, user_data))
2f552719 364 return -1;
663489d2
JF
365
366 continue ;
2f552719
SD
367 }
368
369 /* New key/value */
283011c6 370 if ((loc = strchr_rs (line, ':'))) {
2f552719
SD
371 char *key;
372 char *value;
373
374 *(loc-1) = '\0';
663489d2
JF
375 key = remove_whitespace(line, 1);
376 value = remove_whitespace(loc, 0);
8a45e2b1 377
675da757
JF
378 if (strlen(path) + strlen(key) + 1 >= ICMAP_KEYNAME_MAXLEN) {
379 *error_string = "parser error: New key makes total cmap path too long";
380 return -1;
381 }
8a45e2b1
JF
382 strcpy(new_keyname, path);
383 if (strcmp(path, "") != 0) {
384 strcat(new_keyname, ".");
385 }
386 strcat(new_keyname, key);
387
aab55a00 388 if (!parser_cb(new_keyname, key, value, &state, PARSER_CB_ITEM, error_string, config_map, user_data)) {
8a45e2b1 389 return -1;
ae229831 390 }
663489d2
JF
391
392 continue ;
2f552719
SD
393 }
394
8236a087 395 if (strchr_rs (line, '}')) {
66172a50
JF
396 if (depth == 0) {
397 *error_string = "parser error: Unexpected closing brace";
398
399 return -1;
400 }
401
aab55a00 402 if (!parser_cb(path, NULL, NULL, &state, PARSER_CB_SECTION_END, error_string, config_map, user_data)) {
8a45e2b1
JF
403 return -1;
404 }
405
2f552719
SD
406 return 0;
407 }
408 }
409
8a45e2b1 410 if (strcmp(path, "") != 0) {
66172a50 411 *error_string = "parser error: Missing closing brace";
2f552719
SD
412 return -1;
413 }
414
8a45e2b1 415 if (strcmp(path, "") == 0) {
aab55a00 416 parser_cb("", NULL, NULL, &state, PARSER_CB_END, error_string, config_map, user_data);
8a45e2b1
JF
417 }
418
2f552719
SD
419 return 0;
420}
421
4e9716ed 422static int safe_atoq_range(icmap_value_types_t value_type, long long int *min_val, long long int *max_val)
0929dcb6 423{
4e9716ed
JF
424 switch (value_type) {
425 case ICMAP_VALUETYPE_INT8: *min_val = INT8_MIN; *max_val = INT8_MAX; break;
426 case ICMAP_VALUETYPE_UINT8: *min_val = 0; *max_val = UINT8_MAX; break;
427 case ICMAP_VALUETYPE_INT16: *min_val = INT16_MIN; *max_val = INT16_MAX; break;
428 case ICMAP_VALUETYPE_UINT16: *min_val = 0; *max_val = UINT16_MAX; break;
429 case ICMAP_VALUETYPE_INT32: *min_val = INT32_MIN; *max_val = INT32_MAX; break;
430 case ICMAP_VALUETYPE_UINT32: *min_val = 0; *max_val = UINT32_MAX; break;
431 default:
432 return (-1);
433 }
434
435 return (0);
436}
437
438/*
439 * Convert string str to long long int res. Type of result is target_type and currently only
440 * ICMAP_VALUETYPE_[U]INT[8|16|32] is supported.
441 * Return 0 on success, -1 on failure.
442 */
443static int safe_atoq(const char *str, long long int *res, icmap_value_types_t target_type)
444{
445 long long int val;
446 long long int min_val, max_val;
0929dcb6
JF
447 char *endptr;
448
449 errno = 0;
450
4e9716ed 451 val = strtoll(str, &endptr, 10);
0929dcb6
JF
452 if (errno == ERANGE) {
453 return (-1);
454 }
455
456 if (endptr == str) {
457 return (-1);
458 }
459
460 if (*endptr != '\0') {
461 return (-1);
462 }
463
4e9716ed
JF
464 if (safe_atoq_range(target_type, &min_val, &max_val) != 0) {
465 return (-1);
466 }
467
468 if (val < min_val || val > max_val) {
469 return (-1);
470 }
471
0929dcb6
JF
472 *res = val;
473 return (0);
474}
475
6825c1d3
JF
476static int str_to_ull(const char *str, unsigned long long int *res)
477{
478 unsigned long long int val;
479 char *endptr;
480
481 errno = 0;
482
483 val = strtoull(str, &endptr, 10);
484 if (errno == ERANGE) {
485 return (-1);
486 }
487
488 if (endptr == str) {
489 return (-1);
490 }
491
492 if (*endptr != '\0') {
493 return (-1);
494 }
495
496 *res = val;
497 return (0);
498}
0929dcb6 499
8a45e2b1
JF
500static int main_config_parser_cb(const char *path,
501 char *key,
502 char *value,
aab55a00 503 enum main_cp_cb_data_state *state,
8a45e2b1
JF
504 enum parser_cb_type type,
505 const char **error_string,
bc47c583 506 icmap_map_t config_map,
8a45e2b1 507 void *user_data)
ae229831 508{
4e9716ed
JF
509 int ii;
510 long long int val;
511 long long int min_val, max_val;
512 icmap_value_types_t val_type = ICMAP_VALUETYPE_BINARY;
6825c1d3 513 unsigned long long int ull;
8a45e2b1
JF
514 int add_as_string;
515 char key_name[ICMAP_KEYNAME_MAXLEN];
0929dcb6 516 static char formated_err[256];
8a45e2b1
JF
517 struct main_cp_cb_data *data = (struct main_cp_cb_data *)user_data;
518 struct key_value_list_item *kv_item;
1f90c31b 519 struct qb_list_head *iter, *tmp_iter;
8a45e2b1
JF
520 int uid, gid;
521
522 switch (type) {
523 case PARSER_CB_START:
524 memset(data, 0, sizeof(struct main_cp_cb_data));
aab55a00 525 *state = MAIN_CP_CB_DATA_STATE_NORMAL;
8a45e2b1
JF
526 break;
527 case PARSER_CB_END:
528 break;
529 case PARSER_CB_ITEM:
530 add_as_string = 1;
531
aab55a00 532 switch (*state) {
8a45e2b1
JF
533 case MAIN_CP_CB_DATA_STATE_NORMAL:
534 break;
eb3d49ef
FDN
535 case MAIN_CP_CB_DATA_STATE_PLOAD:
536 if ((strcmp(path, "pload.count") == 0) ||
537 (strcmp(path, "pload.size") == 0)) {
4e9716ed
JF
538 val_type = ICMAP_VALUETYPE_UINT32;
539 if (safe_atoq(value, &val, val_type) != 0) {
eb3d49ef
FDN
540 goto atoi_error;
541 }
4e9716ed 542 icmap_set_uint32_r(config_map, path, val);
eb3d49ef
FDN
543 add_as_string = 0;
544 }
545 break;
8a45e2b1
JF
546 case MAIN_CP_CB_DATA_STATE_QUORUM:
547 if ((strcmp(path, "quorum.expected_votes") == 0) ||
548 (strcmp(path, "quorum.votes") == 0) ||
10098dba 549 (strcmp(path, "quorum.last_man_standing_window") == 0) ||
8a45e2b1 550 (strcmp(path, "quorum.leaving_timeout") == 0)) {
4e9716ed
JF
551 val_type = ICMAP_VALUETYPE_UINT32;
552 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
553 goto atoi_error;
554 }
4e9716ed 555 icmap_set_uint32_r(config_map, path, val);
8a45e2b1
JF
556 add_as_string = 0;
557 }
558
9589611d 559 if ((strcmp(path, "quorum.two_node") == 0) ||
ff6a43ed 560 (strcmp(path, "quorum.expected_votes_tracking") == 0) ||
2d7a8ab2 561 (strcmp(path, "quorum.allow_downscale") == 0) ||
e8d0af0b 562 (strcmp(path, "quorum.wait_for_all") == 0) ||
b41372c6 563 (strcmp(path, "quorum.auto_tie_breaker") == 0) ||
769fc913 564 (strcmp(path, "quorum.last_man_standing") == 0)) {
4e9716ed
JF
565 val_type = ICMAP_VALUETYPE_UINT8;
566 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
567 goto atoi_error;
568 }
4e9716ed 569 icmap_set_uint8_r(config_map, path, val);
8a45e2b1
JF
570 add_as_string = 0;
571 }
572 break;
cb5fd775
FDN
573 case MAIN_CP_CB_DATA_STATE_QDEVICE:
574 if ((strcmp(path, "quorum.device.timeout") == 0) ||
17488909 575 (strcmp(path, "quorum.device.sync_timeout") == 0) ||
cb5fd775 576 (strcmp(path, "quorum.device.votes") == 0)) {
4e9716ed
JF
577 val_type = ICMAP_VALUETYPE_UINT32;
578 if (safe_atoq(value, &val, val_type) != 0) {
cb5fd775
FDN
579 goto atoi_error;
580 }
4e9716ed 581 icmap_set_uint32_r(config_map, path, val);
cb5fd775
FDN
582 add_as_string = 0;
583 }
86dd11b2 584 if ((strcmp(path, "quorum.device.master_wins") == 0)) {
4e9716ed
JF
585 val_type = ICMAP_VALUETYPE_UINT8;
586 if (safe_atoq(value, &val, val_type) != 0) {
86dd11b2
FDN
587 goto atoi_error;
588 }
4e9716ed 589 icmap_set_uint8_r(config_map, path, val);
86dd11b2
FDN
590 add_as_string = 0;
591 }
ce9c69da 592 break;
8a45e2b1
JF
593 case MAIN_CP_CB_DATA_STATE_TOTEM:
594 if ((strcmp(path, "totem.version") == 0) ||
595 (strcmp(path, "totem.nodeid") == 0) ||
596 (strcmp(path, "totem.threads") == 0) ||
597 (strcmp(path, "totem.token") == 0) ||
58176d67 598 (strcmp(path, "totem.token_coefficient") == 0) ||
8a45e2b1
JF
599 (strcmp(path, "totem.token_retransmit") == 0) ||
600 (strcmp(path, "totem.hold") == 0) ||
601 (strcmp(path, "totem.token_retransmits_before_loss_const") == 0) ||
602 (strcmp(path, "totem.join") == 0) ||
603 (strcmp(path, "totem.send_join") == 0) ||
604 (strcmp(path, "totem.consensus") == 0) ||
605 (strcmp(path, "totem.merge") == 0) ||
606 (strcmp(path, "totem.downcheck") == 0) ||
607 (strcmp(path, "totem.fail_recv_const") == 0) ||
608 (strcmp(path, "totem.seqno_unchanged_const") == 0) ||
609 (strcmp(path, "totem.rrp_token_expired_timeout") == 0) ||
610 (strcmp(path, "totem.rrp_problem_count_timeout") == 0) ||
611 (strcmp(path, "totem.rrp_problem_count_threshold") == 0) ||
612 (strcmp(path, "totem.rrp_problem_count_mcast_threshold") == 0) ||
613 (strcmp(path, "totem.rrp_autorecovery_check_timeout") == 0) ||
614 (strcmp(path, "totem.heartbeat_failures_allowed") == 0) ||
615 (strcmp(path, "totem.max_network_delay") == 0) ||
616 (strcmp(path, "totem.window_size") == 0) ||
617 (strcmp(path, "totem.max_messages") == 0) ||
618 (strcmp(path, "totem.miss_count_const") == 0) ||
7cec6a13 619 (strcmp(path, "totem.knet_pmtud_interval") == 0) ||
8a45e2b1 620 (strcmp(path, "totem.netmtu") == 0)) {
4e9716ed
JF
621 val_type = ICMAP_VALUETYPE_UINT32;
622 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
623 goto atoi_error;
624 }
4e9716ed 625 icmap_set_uint32_r(config_map,path, val);
8a45e2b1
JF
626 add_as_string = 0;
627 }
6825c1d3
JF
628 if (strcmp(path, "totem.config_version") == 0) {
629 if (str_to_ull(value, &ull) != 0) {
630 goto atoi_error;
631 }
bc47c583 632 icmap_set_uint64_r(config_map, path, ull);
6825c1d3
JF
633 add_as_string = 0;
634 }
dd588d00
JF
635 if (strcmp(path, "totem.ip_version") == 0) {
636 if ((strcmp(value, "ipv4") != 0) &&
637 (strcmp(value, "ipv6") != 0)) {
638 *error_string = "Invalid ip_version type";
639
640 return (0);
641 }
642 }
8cdd2fc4
JF
643 if (strcmp(path, "totem.crypto_type") == 0) {
644 if ((strcmp(value, "nss") != 0) &&
20c58715
FDN
645 (strcmp(value, "aes256") != 0) &&
646 (strcmp(value, "aes192") != 0) &&
647 (strcmp(value, "aes128") != 0) &&
648 (strcmp(value, "3des") != 0)) {
8cdd2fc4
JF
649 *error_string = "Invalid crypto type";
650
651 return (0);
652 }
653 }
ab1675f0
JF
654 if (strcmp(path, "totem.crypto_cipher") == 0) {
655 if ((strcmp(value, "none") != 0) &&
20c58715
FDN
656 (strcmp(value, "aes256") != 0) &&
657 (strcmp(value, "aes192") != 0) &&
658 (strcmp(value, "aes128") != 0) &&
659 (strcmp(value, "3des") != 0)) {
ab1675f0
JF
660 *error_string = "Invalid cipher type";
661
662 return (0);
663 }
664 }
665 if (strcmp(path, "totem.crypto_hash") == 0) {
666 if ((strcmp(value, "none") != 0) &&
e57b5b9e 667 (strcmp(value, "md5") != 0) &&
4a2d5036 668 (strcmp(value, "sha1") != 0) &&
4a2d5036
FDN
669 (strcmp(value, "sha256") != 0) &&
670 (strcmp(value, "sha384") != 0) &&
671 (strcmp(value, "sha512") != 0)) {
ab1675f0
JF
672 *error_string = "Invalid hash type";
673
674 return (0);
675 }
676 }
a919908e
SD
677 break;
678
3cd4f9a1
JF
679 case MAIN_CP_CB_DATA_STATE_QB:
680 if (strcmp(path, "qb.ipc_type") == 0) {
681 if ((strcmp(value, "native") != 0) &&
682 (strcmp(value, "shm") != 0) &&
683 (strcmp(value, "socket") != 0)) {
684 *error_string = "Invalid qb ipc_type";
685
686 return (0);
687 }
688 }
689 break;
690
8a45e2b1 691 case MAIN_CP_CB_DATA_STATE_INTERFACE:
268cde6e 692 if (strcmp(path, "totem.interface.linknumber") == 0) {
4e9716ed
JF
693 val_type = ICMAP_VALUETYPE_UINT8;
694 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
695 goto atoi_error;
696 }
697
268cde6e 698 data->linknumber = val;
8a45e2b1
JF
699 add_as_string = 0;
700 }
701 if (strcmp(path, "totem.interface.bindnetaddr") == 0) {
702 data->bindnetaddr = strdup(value);
703 add_as_string = 0;
704 }
705 if (strcmp(path, "totem.interface.mcastaddr") == 0) {
706 data->mcastaddr = strdup(value);
707 add_as_string = 0;
708 }
709 if (strcmp(path, "totem.interface.broadcast") == 0) {
710 data->broadcast = strdup(value);
711 add_as_string = 0;
712 }
713 if (strcmp(path, "totem.interface.mcastport") == 0) {
4e9716ed
JF
714 val_type = ICMAP_VALUETYPE_UINT16;
715 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
716 goto atoi_error;
717 }
4e9716ed 718 data->mcastport = val;
8a45e2b1
JF
719 add_as_string = 0;
720 }
721 if (strcmp(path, "totem.interface.ttl") == 0) {
4e9716ed
JF
722 val_type = ICMAP_VALUETYPE_UINT8;
723 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
724 goto atoi_error;
725 }
4e9716ed 726 data->ttl = val;
8a45e2b1
JF
727 add_as_string = 0;
728 }
268cde6e
CC
729 if (strcmp(path, "totem.interface.knet_link_priority") == 0) {
730 val_type = ICMAP_VALUETYPE_UINT8;
731 if (safe_atoq(value, &val, val_type) != 0) {
732 goto atoi_error;
733 }
734 data->knet_link_priority = val;
735 add_as_string = 0;
736 }
737 if (strcmp(path, "totem.interface.knet_ping_interval") == 0) {
738 val_type = ICMAP_VALUETYPE_UINT32;
739 if (safe_atoq(value, &val, val_type) != 0) {
740 goto atoi_error;
741 }
742 data->knet_ping_interval = val;
743 add_as_string = 0;
744 }
745 if (strcmp(path, "totem.interface.knet_ping_timeout") == 0) {
746 val_type = ICMAP_VALUETYPE_UINT32;
747 if (safe_atoq(value, &val, val_type) != 0) {
748 goto atoi_error;
749 }
750 data->knet_ping_timeout = val;
751 add_as_string = 0;
752 }
753 if (strcmp(path, "totem.interface.knet_ping_precision") == 0) {
754 val_type = ICMAP_VALUETYPE_UINT32;
755 if (safe_atoq(value, &val, val_type) != 0) {
756 goto atoi_error;
757 }
758 data->knet_ping_precision = val;
759 add_as_string = 0;
760 }
7cec6a13
CC
761 if (strcmp(path, "totem.interface.knet_pong_count") == 0) {
762 val_type = ICMAP_VALUETYPE_UINT32;
763 if (safe_atoq(value, &val, val_type) != 0) {
764 goto atoi_error;
765 }
766 data->knet_pong_count = val;
767 add_as_string = 0;
768 }
8a45e2b1
JF
769 break;
770 case MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS:
771 if (strcmp(key, "subsys") == 0) {
772 data->subsys = strdup(value);
773 if (data->subsys == NULL) {
774 *error_string = "Can't alloc memory";
775
776 return (0);
777 }
778 } else {
779 kv_item = malloc(sizeof(*kv_item));
780 if (kv_item == NULL) {
781 *error_string = "Can't alloc memory";
782
783 return (0);
784 }
785 memset(kv_item, 0, sizeof(*kv_item));
786
787 kv_item->key = strdup(key);
788 kv_item->value = strdup(value);
789 if (kv_item->key == NULL || kv_item->value == NULL) {
790 free(kv_item);
791 *error_string = "Can't alloc memory";
792
793 return (0);
794 }
b4c06e52
MJ
795 qb_list_init(&kv_item->list);
796 qb_list_add(&kv_item->list, &data->logger_subsys_items_head);
8a45e2b1
JF
797 }
798 add_as_string = 0;
799 break;
800 case MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON:
801 if (strcmp(key, "subsys") == 0) {
802 data->subsys = strdup(value);
803 if (data->subsys == NULL) {
804 *error_string = "Can't alloc memory";
805
806 return (0);
807 }
808 } else if (strcmp(key, "name") == 0) {
809 data->logging_daemon_name = strdup(value);
810 if (data->logging_daemon_name == NULL) {
811 *error_string = "Can't alloc memory";
812
813 return (0);
814 }
815 } else {
816 kv_item = malloc(sizeof(*kv_item));
817 if (kv_item == NULL) {
818 *error_string = "Can't alloc memory";
819
820 return (0);
821 }
822 memset(kv_item, 0, sizeof(*kv_item));
823
824 kv_item->key = strdup(key);
825 kv_item->value = strdup(value);
826 if (kv_item->key == NULL || kv_item->value == NULL) {
827 free(kv_item);
828 *error_string = "Can't alloc memory";
829
830 return (0);
831 }
b4c06e52
MJ
832 qb_list_init(&kv_item->list);
833 qb_list_add(&kv_item->list, &data->logger_subsys_items_head);
8a45e2b1
JF
834 }
835 add_as_string = 0;
836 break;
837 case MAIN_CP_CB_DATA_STATE_UIDGID:
838 if (strcmp(key, "uid") == 0) {
839 uid = uid_determine(value);
840 if (uid == -1) {
841 *error_string = error_string_response;
842 return (0);
843 }
f837f95d 844 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.uid.%u",
8a45e2b1 845 uid);
bc47c583 846 icmap_set_uint8_r(config_map, key_name, 1);
8a45e2b1
JF
847 add_as_string = 0;
848 } else if (strcmp(key, "gid") == 0) {
849 gid = gid_determine(value);
850 if (gid == -1) {
851 *error_string = error_string_response;
852 return (0);
853 }
f837f95d 854 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.gid.%u",
8a45e2b1 855 gid);
bc47c583 856 icmap_set_uint8_r(config_map, key_name, 1);
8a45e2b1
JF
857 add_as_string = 0;
858 } else {
859 *error_string = "uidgid: Only uid and gid are allowed items";
860 return (0);
861 }
862 break;
863 case MAIN_CP_CB_DATA_STATE_MEMBER:
864 if (strcmp(key, "memberaddr") != 0) {
865 *error_string = "Only memberaddr is allowed in member section";
866
867 return (0);
868 }
869
870 kv_item = malloc(sizeof(*kv_item));
871 if (kv_item == NULL) {
872 *error_string = "Can't alloc memory";
873
874 return (0);
875 }
876 memset(kv_item, 0, sizeof(*kv_item));
877
878 kv_item->key = strdup(key);
879 kv_item->value = strdup(value);
880 if (kv_item->key == NULL || kv_item->value == NULL) {
881 free(kv_item);
882 *error_string = "Can't alloc memory";
883
884 return (0);
885 }
b4c06e52
MJ
886 qb_list_init(&kv_item->list);
887 qb_list_add(&kv_item->list, &data->member_items_head);
8a45e2b1
JF
888 add_as_string = 0;
889 break;
6d0b0b14
JF
890 case MAIN_CP_CB_DATA_STATE_NODELIST:
891 break;
892 case MAIN_CP_CB_DATA_STATE_NODELIST_NODE:
893 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.%s", data->node_number, key);
894 if ((strcmp(key, "nodeid") == 0) ||
895 (strcmp(key, "quorum_votes") == 0)) {
4e9716ed
JF
896 val_type = ICMAP_VALUETYPE_UINT32;
897 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
898 goto atoi_error;
899 }
900
4e9716ed 901 icmap_set_uint32_r(config_map, key_name, val);
6d0b0b14
JF
902 add_as_string = 0;
903 }
904
905 if (strcmp(key, "ring0_addr") == 0) {
906 data->ring0_addr_added = 1;
907 }
908
909 if (add_as_string) {
bc47c583 910 icmap_set_string_r(config_map, key_name, value);
6d0b0b14
JF
911 add_as_string = 0;
912 }
913 break;
39cd6b3d 914 case MAIN_CP_CB_DATA_STATE_RESOURCES:
915 if (strcmp(key, "watchdog_timeout") == 0) {
916 val_type = ICMAP_VALUETYPE_UINT32;
917 if (safe_atoq(value, &val, val_type) != 0) {
918 goto atoi_error;
919 }
920 icmap_set_uint32_r(config_map,path, val);
921 add_as_string = 0;
922 }
923 break;
924 case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM:
39cd6b3d 925 case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_MEMUSED:
926 if (strcmp(key, "poll_period") == 0) {
927 if (str_to_ull(value, &ull) != 0) {
928 goto atoi_error;
929 }
930 icmap_set_uint64_r(config_map,path, ull);
931 add_as_string = 0;
932 }
933 break;
934 case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS:
39cd6b3d 935 case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED:
936 if (strcmp(key, "poll_period") == 0) {
937 if (str_to_ull(value, &ull) != 0) {
938 goto atoi_error;
939 }
940 icmap_set_uint64_r(config_map,path, ull);
941 add_as_string = 0;
942 }
943 break;
ae229831
JF
944 }
945
8a45e2b1 946 if (add_as_string) {
bc47c583 947 icmap_set_string_r(config_map, path, value);
8a45e2b1
JF
948 }
949 break;
950 case PARSER_CB_SECTION_START:
951 if (strcmp(path, "totem.interface") == 0) {
aab55a00 952 *state = MAIN_CP_CB_DATA_STATE_INTERFACE;
268cde6e 953 data->linknumber = 0;
8a45e2b1
JF
954 data->mcastport = -1;
955 data->ttl = -1;
268cde6e
CC
956 data->knet_link_priority = -1;
957 data->knet_ping_interval = -1;
958 data->knet_ping_timeout = -1;
959 data->knet_ping_precision = -1;
7cec6a13 960 data->knet_pong_count = -1;
b4c06e52 961 qb_list_init(&data->member_items_head);
8a45e2b1
JF
962 };
963 if (strcmp(path, "totem") == 0) {
aab55a00 964 *state = MAIN_CP_CB_DATA_STATE_TOTEM;
8a45e2b1 965 };
3cd4f9a1 966 if (strcmp(path, "qb") == 0) {
aab55a00 967 *state = MAIN_CP_CB_DATA_STATE_QB;
3cd4f9a1 968 }
8a45e2b1 969 if (strcmp(path, "logging.logger_subsys") == 0) {
aab55a00 970 *state = MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS;
b4c06e52 971 qb_list_init(&data->logger_subsys_items_head);
8a45e2b1
JF
972 data->subsys = NULL;
973 }
974 if (strcmp(path, "logging.logging_daemon") == 0) {
aab55a00 975 *state = MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON;
b4c06e52 976 qb_list_init(&data->logger_subsys_items_head);
8a45e2b1
JF
977 data->subsys = NULL;
978 data->logging_daemon_name = NULL;
979 }
980 if (strcmp(path, "uidgid") == 0) {
aab55a00 981 *state = MAIN_CP_CB_DATA_STATE_UIDGID;
ae229831 982 }
8a45e2b1 983 if (strcmp(path, "totem.interface.member") == 0) {
aab55a00 984 *state = MAIN_CP_CB_DATA_STATE_MEMBER;
8a45e2b1
JF
985 }
986 if (strcmp(path, "quorum") == 0) {
aab55a00 987 *state = MAIN_CP_CB_DATA_STATE_QUORUM;
8a45e2b1 988 }
cb5fd775 989 if (strcmp(path, "quorum.device") == 0) {
aab55a00 990 *state = MAIN_CP_CB_DATA_STATE_QDEVICE;
cb5fd775 991 }
6d0b0b14 992 if (strcmp(path, "nodelist") == 0) {
aab55a00 993 *state = MAIN_CP_CB_DATA_STATE_NODELIST;
6d0b0b14
JF
994 data->node_number = 0;
995 }
996 if (strcmp(path, "nodelist.node") == 0) {
aab55a00 997 *state = MAIN_CP_CB_DATA_STATE_NODELIST_NODE;
6d0b0b14
JF
998 data->ring0_addr_added = 0;
999 }
39cd6b3d 1000 if (strcmp(path, "resources") == 0) {
1001 *state = MAIN_CP_CB_DATA_STATE_RESOURCES;
1002 }
1003 if (strcmp(path, "resources.system") == 0) {
1004 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM;
1005 }
1006 if (strcmp(path, "resources.system.memory_used") == 0) {
1007 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_MEMUSED;
1008 }
1009 if (strcmp(path, "resources.process") == 0) {
1010 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS;
1011 }
1012 if (strcmp(path, "resources.process.memory_used") == 0) {
1013 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED;
1014 }
8a45e2b1
JF
1015 break;
1016 case PARSER_CB_SECTION_END:
aab55a00 1017 switch (*state) {
8a45e2b1
JF
1018 case MAIN_CP_CB_DATA_STATE_INTERFACE:
1019 /*
1020 * Create new interface section
1021 */
1022 if (data->bindnetaddr != NULL) {
1023 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.bindnetaddr",
268cde6e 1024 data->linknumber);
bc47c583 1025 icmap_set_string_r(config_map, key_name, data->bindnetaddr);
8a45e2b1
JF
1026
1027 free(data->bindnetaddr);
1028 data->bindnetaddr = NULL;
8a45e2b1
JF
1029 }
1030
1031 if (data->mcastaddr != NULL) {
1032 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.mcastaddr",
268cde6e 1033 data->linknumber);
bc47c583 1034 icmap_set_string_r(config_map, key_name, data->mcastaddr);
8a45e2b1
JF
1035
1036 free(data->mcastaddr);
1037 data->mcastaddr = NULL;
1038 }
1039
1040 if (data->broadcast != NULL) {
1041 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.broadcast",
268cde6e 1042 data->linknumber);
bc47c583 1043 icmap_set_string_r(config_map, key_name, data->broadcast);
8a45e2b1
JF
1044
1045 free(data->broadcast);
1046 data->broadcast = NULL;
1047 }
1048
1049 if (data->mcastport > -1) {
1050 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.mcastport",
268cde6e 1051 data->linknumber);
bc47c583 1052 icmap_set_uint16_r(config_map, key_name, data->mcastport);
8a45e2b1
JF
1053 }
1054
1055 if (data->ttl > -1) {
1056 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.ttl",
268cde6e 1057 data->linknumber);
bc47c583 1058 icmap_set_uint8_r(config_map, key_name, data->ttl);
8a45e2b1 1059 }
268cde6e
CC
1060 if (data->knet_link_priority > -1) {
1061 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_link_priority",
1062 data->linknumber);
1063 icmap_set_uint8_r(config_map, key_name, data->knet_link_priority);
1064 }
1065 if (data->knet_ping_interval > -1) {
1066 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_ping_interval",
1067 data->linknumber);
1068 icmap_set_uint32_r(config_map, key_name, data->knet_ping_interval);
1069 }
1070 if (data->knet_ping_timeout > -1) {
1071 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_ping_timeout",
1072 data->linknumber);
1073 icmap_set_uint32_r(config_map, key_name, data->knet_ping_timeout);
1074 }
1075 if (data->knet_ping_precision > -1) {
1076 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_ping_precision",
1077 data->linknumber);
1078 icmap_set_uint32_r(config_map, key_name, data->knet_ping_precision);
1079 }
7cec6a13
CC
1080 if (data->knet_pong_count > -1) {
1081 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_pong_count",
1082 data->linknumber);
1083 icmap_set_uint32_r(config_map, key_name, data->knet_pong_count);
1084 }
8a45e2b1 1085
4e9716ed 1086 ii = 0;
b4c06e52 1087
1f90c31b 1088 qb_list_for_each_safe(iter, tmp_iter, &(data->member_items_head)) {
b4c06e52 1089 kv_item = qb_list_entry(iter, struct key_value_list_item, list);
8a45e2b1
JF
1090
1091 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.member.%u",
268cde6e 1092 data->linknumber, ii);
bc47c583 1093 icmap_set_string_r(config_map, key_name, kv_item->value);
8a45e2b1 1094
8a45e2b1
JF
1095 free(kv_item->value);
1096 free(kv_item->key);
1097 free(kv_item);
4e9716ed 1098 ii++;
8a45e2b1
JF
1099 }
1100
3cd4f9a1 1101 break;
8a45e2b1
JF
1102 case MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS:
1103 if (data->subsys == NULL) {
1104 *error_string = "No subsys key in logger_subsys directive";
1105
1106 return (0);
1107 }
1108
1f90c31b 1109 qb_list_for_each_safe(iter, tmp_iter, &(data->logger_subsys_items_head)) {
b4c06e52 1110 kv_item = qb_list_entry(iter, struct key_value_list_item, list);
8a45e2b1
JF
1111
1112 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logger_subsys.%s.%s",
aab55a00 1113 data->subsys, kv_item->key);
b4c06e52 1114 icmap_set_string_r(config_map, key_name, kv_item->value);
8a45e2b1
JF
1115
1116 free(kv_item->value);
1117 free(kv_item->key);
1118 free(kv_item);
1119 }
1120
1121 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logger_subsys.%s.subsys",
1122 data->subsys);
bc47c583 1123 icmap_set_string_r(config_map, key_name, data->subsys);
8a45e2b1
JF
1124
1125 free(data->subsys);
1126
8a45e2b1
JF
1127 break;
1128 case MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON:
1129 if (data->logging_daemon_name == NULL) {
1130 *error_string = "No name key in logging_daemon directive";
1131
1132 return (0);
1133 }
1134
1f90c31b 1135 qb_list_for_each_safe(iter, tmp_iter, &(data->logger_subsys_items_head)) {
b4c06e52 1136 kv_item = qb_list_entry(iter, struct key_value_list_item, list);
8a45e2b1
JF
1137
1138 if (data->subsys == NULL) {
1139 if (strcmp(data->logging_daemon_name, "corosync") == 0) {
1140 snprintf(key_name, ICMAP_KEYNAME_MAXLEN,
1141 "logging.%s",
1142 kv_item->key);
1143 } else {
1144 snprintf(key_name, ICMAP_KEYNAME_MAXLEN,
1145 "logging.logging_daemon.%s.%s",
1146 data->logging_daemon_name, kv_item->key);
1147 }
1148 } else {
1149 if (strcmp(data->logging_daemon_name, "corosync") == 0) {
1150 snprintf(key_name, ICMAP_KEYNAME_MAXLEN,
1151 "logging.logger_subsys.%s.%s",
1152 data->subsys,
1153 kv_item->key);
1154 } else {
1155 snprintf(key_name, ICMAP_KEYNAME_MAXLEN,
1156 "logging.logging_daemon.%s.%s.%s",
1157 data->logging_daemon_name, data->subsys,
1158 kv_item->key);
1159 }
1160 }
bc47c583 1161 icmap_set_string_r(config_map, key_name, kv_item->value);
8a45e2b1 1162
8a45e2b1
JF
1163 free(kv_item->value);
1164 free(kv_item->key);
1165 free(kv_item);
1166 }
1167
1168 if (data->subsys == NULL) {
1169 if (strcmp(data->logging_daemon_name, "corosync") != 0) {
1170 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logging_daemon.%s.name",
1171 data->logging_daemon_name);
bc47c583 1172 icmap_set_string_r(config_map, key_name, data->logging_daemon_name);
8a45e2b1
JF
1173 }
1174 } else {
1175 if (strcmp(data->logging_daemon_name, "corosync") == 0) {
1176 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logger_subsys.%s.subsys",
1177 data->subsys);
bc47c583 1178 icmap_set_string_r(config_map, key_name, data->subsys);
8a45e2b1
JF
1179
1180 } else {
1181 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logging_daemon.%s.%s.subsys",
1182 data->logging_daemon_name, data->subsys);
bc47c583 1183 icmap_set_string_r(config_map, key_name, data->subsys);
8a45e2b1
JF
1184 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logging_daemon.%s.%s.name",
1185 data->logging_daemon_name, data->subsys);
bc47c583 1186 icmap_set_string_r(config_map, key_name, data->logging_daemon_name);
8a45e2b1
JF
1187 }
1188 }
1189
1190 free(data->subsys);
1191 free(data->logging_daemon_name);
1192
6d0b0b14
JF
1193 break;
1194 case MAIN_CP_CB_DATA_STATE_NODELIST_NODE:
1195 if (!data->ring0_addr_added) {
1196 *error_string = "No ring0_addr specified for node";
1197
1198 return (0);
1199 }
1200 data->node_number++;
aab55a00
CC
1201 break;
1202 case MAIN_CP_CB_DATA_STATE_NORMAL:
1203 case MAIN_CP_CB_DATA_STATE_PLOAD:
1204 case MAIN_CP_CB_DATA_STATE_UIDGID:
1205 case MAIN_CP_CB_DATA_STATE_MEMBER:
1206 case MAIN_CP_CB_DATA_STATE_QUORUM:
1207 case MAIN_CP_CB_DATA_STATE_QDEVICE:
1208 case MAIN_CP_CB_DATA_STATE_NODELIST:
1209 case MAIN_CP_CB_DATA_STATE_TOTEM:
1210 case MAIN_CP_CB_DATA_STATE_QB:
6d0b0b14 1211 break;
39cd6b3d 1212 case MAIN_CP_CB_DATA_STATE_RESOURCES:
1213 *state = MAIN_CP_CB_DATA_STATE_NORMAL;
1214 break;
1215 case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM:
1216 *state = MAIN_CP_CB_DATA_STATE_RESOURCES;
1217 break;
1218 case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_MEMUSED:
1219 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM;
1220 break;
1221 case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS:
1222 *state = MAIN_CP_CB_DATA_STATE_RESOURCES;
1223 break;
1224 case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED:
1225 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS;
1226 break;
8a45e2b1
JF
1227 }
1228 break;
ae229831
JF
1229 }
1230
8a45e2b1 1231 return (1);
0929dcb6
JF
1232
1233atoi_error:
4e9716ed
JF
1234 min_val = max_val = 0;
1235 /*
1236 * This is really assert, because developer ether doesn't set val_type correctly or
1237 * we've got here after some nasty memory overwrite
1238 */
1239 assert(safe_atoq_range(val_type, &min_val, &max_val) == 0);
1240
0929dcb6 1241 snprintf(formated_err, sizeof(formated_err),
4e9716ed
JF
1242 "Value of key \"%s\" is expected to be integer in range (%lld..%lld), but \"%s\" was given",
1243 key, min_val, max_val, value);
0929dcb6
JF
1244 *error_string = formated_err;
1245
1246 return (0);
8a45e2b1
JF
1247}
1248
1249static int uidgid_config_parser_cb(const char *path,
1250 char *key,
1251 char *value,
aab55a00 1252 enum main_cp_cb_data_state *state,
8a45e2b1
JF
1253 enum parser_cb_type type,
1254 const char **error_string,
bc47c583 1255 icmap_map_t config_map,
8a45e2b1
JF
1256 void *user_data)
1257{
1258 char key_name[ICMAP_KEYNAME_MAXLEN];
1259 int uid, gid;
1260
1261 switch (type) {
1262 case PARSER_CB_START:
1263 break;
1264 case PARSER_CB_END:
1265 break;
1266 case PARSER_CB_ITEM:
1267 if (strcmp(path, "uidgid.uid") == 0) {
1268 uid = uid_determine(value);
1269 if (uid == -1) {
1270 *error_string = error_string_response;
1271 return (0);
1272 }
f837f95d 1273 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.uid.%u",
8a45e2b1 1274 uid);
bc47c583 1275 icmap_set_uint8_r(config_map, key_name, 1);
92ead610 1276 } else if (strcmp(path, "uidgid.gid") == 0) {
8a45e2b1
JF
1277 gid = gid_determine(value);
1278 if (gid == -1) {
1279 *error_string = error_string_response;
1280 return (0);
1281 }
f837f95d 1282 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.gid.%u",
8a45e2b1 1283 gid);
bc47c583 1284 icmap_set_uint8_r(config_map, key_name, 1);
8a45e2b1 1285 } else {
ae229831 1286 *error_string = "uidgid: Only uid and gid are allowed items";
8a45e2b1 1287 return (0);
ae229831 1288 }
8a45e2b1
JF
1289 break;
1290 case PARSER_CB_SECTION_START:
1291 if (strcmp(path, "uidgid") != 0) {
3b8365e8 1292 *error_string = "uidgid: Can't add subsection different than uidgid";
8a45e2b1
JF
1293 return (0);
1294 };
1295 break;
1296 case PARSER_CB_SECTION_END:
1297 break;
ae229831 1298 }
2f552719 1299
8a45e2b1 1300 return (1);
ae229831
JF
1301}
1302
8a45e2b1 1303static int read_uidgid_files_into_icmap(
bc47c583
CC
1304 const char **error_string,
1305 icmap_map_t config_map)
ae229831
JF
1306{
1307 FILE *fp;
1308 const char *dirname;
1309 DIR *dp;
1310 struct dirent *dirent;
2290913d 1311 struct dirent *entry;
1bd8aba6 1312 char filename[PATH_MAX + FILENAME_MAX + 1];
ae229831 1313 int res = 0;
2290913d
AS
1314 size_t len;
1315 int return_code;
1e0d40cd 1316 struct stat stat_buf;
aab55a00 1317 enum main_cp_cb_data_state state = MAIN_CP_CB_DATA_STATE_NORMAL;
8a45e2b1 1318 char key_name[ICMAP_KEYNAME_MAXLEN];
ae229831 1319
2135d91c 1320 dirname = COROSYSCONFDIR "/uidgid.d";
ae229831
JF
1321 dp = opendir (dirname);
1322
1323 if (dp == NULL)
1324 return 0;
1325
427fdd45 1326 len = offsetof(struct dirent, d_name) + FILENAME_MAX + 1;
eda1e364 1327
2290913d 1328 entry = malloc(len);
eda1e364 1329 if (entry == NULL) {
c2a39cb8
JF
1330 res = 0;
1331 goto error_exit;
eda1e364 1332 }
2290913d
AS
1333
1334 for (return_code = readdir_r(dp, entry, &dirent);
1335 dirent != NULL && return_code == 0;
1336 return_code = readdir_r(dp, entry, &dirent)) {
1337
1e0d40cd 1338 snprintf(filename, sizeof (filename), "%s/%s", dirname, dirent->d_name);
966f461b
JF
1339 res = stat (filename, &stat_buf);
1340 if (res == 0 && S_ISREG(stat_buf.st_mode)) {
ae229831
JF
1341
1342 fp = fopen (filename, "r");
1343 if (fp == NULL) continue;
1344
8a45e2b1
JF
1345 key_name[0] = 0;
1346
aab55a00 1347 res = parse_section(fp, key_name, error_string, 0, state, uidgid_config_parser_cb, config_map, NULL);
ae229831
JF
1348
1349 fclose (fp);
1350
1351 if (res != 0) {
1352 goto error_exit;
1353 }
1354 }
1355 }
1356
1357error_exit:
2290913d 1358 free (entry);
ae229831
JF
1359 closedir(dp);
1360
1361 return res;
1362}
2f552719 1363
8a45e2b1
JF
1364/* Read config file and load into icmap */
1365static int read_config_file_into_icmap(
bc47c583
CC
1366 const char **error_string,
1367 icmap_map_t config_map)
2f552719
SD
1368{
1369 FILE *fp;
23c64c64 1370 const char *filename;
2f552719
SD
1371 char *error_reason = error_string_response;
1372 int res;
8a45e2b1
JF
1373 char key_name[ICMAP_KEYNAME_MAXLEN];
1374 struct main_cp_cb_data data;
aab55a00 1375 enum main_cp_cb_data_state state = MAIN_CP_CB_DATA_STATE_NORMAL;
2f552719
SD
1376
1377 filename = getenv ("COROSYNC_MAIN_CONFIG_FILE");
1378 if (!filename)
2135d91c 1379 filename = COROSYSCONFDIR "/corosync.conf";
2f552719
SD
1380
1381 fp = fopen (filename, "r");
23c64c64 1382 if (fp == NULL) {
20f3331d 1383 char error_str[100];
37e17e7a 1384 const char *error_ptr = qb_strerror_r(errno, error_str, sizeof(error_str));
870046d0 1385 snprintf (error_reason, sizeof(error_string_response),
3131601c 1386 "Can't read file %s reason = (%s)",
00434a4f 1387 filename, error_ptr);
2f552719
SD
1388 *error_string = error_reason;
1389 return -1;
1390 }
1391
8a45e2b1
JF
1392 key_name[0] = 0;
1393
aab55a00 1394 res = parse_section(fp, key_name, error_string, 0, state, main_config_parser_cb, config_map, &data);
2f552719
SD
1395
1396 fclose(fp);
1397
ae229831 1398 if (res == 0) {
bc47c583 1399 res = read_uidgid_files_into_icmap(error_string, config_map);
ae229831
JF
1400 }
1401
94b64352
JF
1402 if (res == 0) {
1403 snprintf (error_reason, sizeof(error_string_response),
3131601c 1404 "Successfully read main configuration file '%s'.", filename);
94b64352
JF
1405 *error_string = error_reason;
1406 }
2f552719
SD
1407
1408 return res;
1409}