]> git.proxmox.com Git - mirror_corosync.git/blame - exec/coroparse.c
corosync-notifyd: Rename global local_nodeid
[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;
c0f1d576 123 char *knet_transport;
8a45e2b1 124
b4c06e52 125 struct qb_list_head logger_subsys_items_head;
8a45e2b1
JF
126 char *subsys;
127 char *logging_daemon_name;
b4c06e52 128 struct qb_list_head member_items_head;
6d0b0b14
JF
129
130 int node_number;
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);
f05d1c92 149 if (*req_user != '\0' && *ep == '\0' && id >= 0 && id <= UINT_MAX) {
86b074dc
JF
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);
f05d1c92 203 if (*req_group != '\0' && *ep == '\0' && id >= 0 && id <= UINT_MAX) {
86b074dc
JF
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) ||
16f616b6 620 (strcmp(path, "totem.knet_compression_threshold") == 0) ||
8a45e2b1 621 (strcmp(path, "totem.netmtu") == 0)) {
4e9716ed
JF
622 val_type = ICMAP_VALUETYPE_UINT32;
623 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
624 goto atoi_error;
625 }
4e9716ed 626 icmap_set_uint32_r(config_map,path, val);
8a45e2b1
JF
627 add_as_string = 0;
628 }
16f616b6
CC
629 if (strcmp(path, "totem.knet_compression_level") == 0) {
630 val_type = ICMAP_VALUETYPE_INT32;
631 if (safe_atoq(value, &val, val_type) != 0) {
632 goto atoi_error;
633 }
634 icmap_set_int32_r(config_map, path, val);
635 add_as_string = 0;
636 }
6825c1d3
JF
637 if (strcmp(path, "totem.config_version") == 0) {
638 if (str_to_ull(value, &ull) != 0) {
639 goto atoi_error;
640 }
bc47c583 641 icmap_set_uint64_r(config_map, path, ull);
6825c1d3
JF
642 add_as_string = 0;
643 }
dd588d00
JF
644 if (strcmp(path, "totem.ip_version") == 0) {
645 if ((strcmp(value, "ipv4") != 0) &&
646 (strcmp(value, "ipv6") != 0)) {
647 *error_string = "Invalid ip_version type";
648
649 return (0);
650 }
651 }
8cdd2fc4
JF
652 if (strcmp(path, "totem.crypto_type") == 0) {
653 if ((strcmp(value, "nss") != 0) &&
20c58715
FDN
654 (strcmp(value, "aes256") != 0) &&
655 (strcmp(value, "aes192") != 0) &&
656 (strcmp(value, "aes128") != 0) &&
657 (strcmp(value, "3des") != 0)) {
8cdd2fc4
JF
658 *error_string = "Invalid crypto type";
659
660 return (0);
661 }
662 }
ab1675f0
JF
663 if (strcmp(path, "totem.crypto_cipher") == 0) {
664 if ((strcmp(value, "none") != 0) &&
20c58715
FDN
665 (strcmp(value, "aes256") != 0) &&
666 (strcmp(value, "aes192") != 0) &&
667 (strcmp(value, "aes128") != 0) &&
668 (strcmp(value, "3des") != 0)) {
ab1675f0
JF
669 *error_string = "Invalid cipher type";
670
671 return (0);
672 }
673 }
674 if (strcmp(path, "totem.crypto_hash") == 0) {
675 if ((strcmp(value, "none") != 0) &&
e57b5b9e 676 (strcmp(value, "md5") != 0) &&
4a2d5036 677 (strcmp(value, "sha1") != 0) &&
4a2d5036
FDN
678 (strcmp(value, "sha256") != 0) &&
679 (strcmp(value, "sha384") != 0) &&
680 (strcmp(value, "sha512") != 0)) {
ab1675f0
JF
681 *error_string = "Invalid hash type";
682
683 return (0);
684 }
685 }
a919908e
SD
686 break;
687
3cd4f9a1
JF
688 case MAIN_CP_CB_DATA_STATE_QB:
689 if (strcmp(path, "qb.ipc_type") == 0) {
690 if ((strcmp(value, "native") != 0) &&
691 (strcmp(value, "shm") != 0) &&
692 (strcmp(value, "socket") != 0)) {
693 *error_string = "Invalid qb ipc_type";
694
695 return (0);
696 }
697 }
698 break;
699
8a45e2b1 700 case MAIN_CP_CB_DATA_STATE_INTERFACE:
268cde6e 701 if (strcmp(path, "totem.interface.linknumber") == 0) {
4e9716ed
JF
702 val_type = ICMAP_VALUETYPE_UINT8;
703 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
704 goto atoi_error;
705 }
706
268cde6e 707 data->linknumber = val;
8a45e2b1
JF
708 add_as_string = 0;
709 }
710 if (strcmp(path, "totem.interface.bindnetaddr") == 0) {
711 data->bindnetaddr = strdup(value);
712 add_as_string = 0;
713 }
714 if (strcmp(path, "totem.interface.mcastaddr") == 0) {
715 data->mcastaddr = strdup(value);
716 add_as_string = 0;
717 }
718 if (strcmp(path, "totem.interface.broadcast") == 0) {
719 data->broadcast = strdup(value);
720 add_as_string = 0;
721 }
722 if (strcmp(path, "totem.interface.mcastport") == 0) {
4e9716ed
JF
723 val_type = ICMAP_VALUETYPE_UINT16;
724 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
725 goto atoi_error;
726 }
4e9716ed 727 data->mcastport = val;
8a45e2b1
JF
728 add_as_string = 0;
729 }
730 if (strcmp(path, "totem.interface.ttl") == 0) {
4e9716ed
JF
731 val_type = ICMAP_VALUETYPE_UINT8;
732 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
733 goto atoi_error;
734 }
4e9716ed 735 data->ttl = val;
8a45e2b1
JF
736 add_as_string = 0;
737 }
268cde6e
CC
738 if (strcmp(path, "totem.interface.knet_link_priority") == 0) {
739 val_type = ICMAP_VALUETYPE_UINT8;
740 if (safe_atoq(value, &val, val_type) != 0) {
741 goto atoi_error;
742 }
743 data->knet_link_priority = val;
744 add_as_string = 0;
745 }
746 if (strcmp(path, "totem.interface.knet_ping_interval") == 0) {
747 val_type = ICMAP_VALUETYPE_UINT32;
748 if (safe_atoq(value, &val, val_type) != 0) {
749 goto atoi_error;
750 }
751 data->knet_ping_interval = val;
752 add_as_string = 0;
753 }
754 if (strcmp(path, "totem.interface.knet_ping_timeout") == 0) {
755 val_type = ICMAP_VALUETYPE_UINT32;
756 if (safe_atoq(value, &val, val_type) != 0) {
757 goto atoi_error;
758 }
759 data->knet_ping_timeout = val;
760 add_as_string = 0;
761 }
762 if (strcmp(path, "totem.interface.knet_ping_precision") == 0) {
763 val_type = ICMAP_VALUETYPE_UINT32;
764 if (safe_atoq(value, &val, val_type) != 0) {
765 goto atoi_error;
766 }
767 data->knet_ping_precision = val;
768 add_as_string = 0;
769 }
7cec6a13
CC
770 if (strcmp(path, "totem.interface.knet_pong_count") == 0) {
771 val_type = ICMAP_VALUETYPE_UINT32;
772 if (safe_atoq(value, &val, val_type) != 0) {
773 goto atoi_error;
774 }
775 data->knet_pong_count = val;
776 add_as_string = 0;
777 }
c0f1d576
CC
778 if (strcmp(path, "totem.interface.knet_transport") == 0) {
779 val_type = ICMAP_VALUETYPE_STRING;
780 data->knet_transport = strdup(value);
781 add_as_string = 0;
782 }
8a45e2b1
JF
783 break;
784 case MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS:
785 if (strcmp(key, "subsys") == 0) {
786 data->subsys = strdup(value);
787 if (data->subsys == NULL) {
788 *error_string = "Can't alloc memory";
789
790 return (0);
791 }
792 } else {
793 kv_item = malloc(sizeof(*kv_item));
794 if (kv_item == NULL) {
795 *error_string = "Can't alloc memory";
796
797 return (0);
798 }
799 memset(kv_item, 0, sizeof(*kv_item));
800
801 kv_item->key = strdup(key);
802 kv_item->value = strdup(value);
803 if (kv_item->key == NULL || kv_item->value == NULL) {
804 free(kv_item);
805 *error_string = "Can't alloc memory";
806
807 return (0);
808 }
b4c06e52
MJ
809 qb_list_init(&kv_item->list);
810 qb_list_add(&kv_item->list, &data->logger_subsys_items_head);
8a45e2b1
JF
811 }
812 add_as_string = 0;
813 break;
814 case MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON:
815 if (strcmp(key, "subsys") == 0) {
816 data->subsys = strdup(value);
817 if (data->subsys == NULL) {
818 *error_string = "Can't alloc memory";
819
820 return (0);
821 }
822 } else if (strcmp(key, "name") == 0) {
823 data->logging_daemon_name = strdup(value);
824 if (data->logging_daemon_name == NULL) {
825 *error_string = "Can't alloc memory";
826
827 return (0);
828 }
829 } else {
830 kv_item = malloc(sizeof(*kv_item));
831 if (kv_item == NULL) {
832 *error_string = "Can't alloc memory";
833
834 return (0);
835 }
836 memset(kv_item, 0, sizeof(*kv_item));
837
838 kv_item->key = strdup(key);
839 kv_item->value = strdup(value);
840 if (kv_item->key == NULL || kv_item->value == NULL) {
841 free(kv_item);
842 *error_string = "Can't alloc memory";
843
844 return (0);
845 }
b4c06e52
MJ
846 qb_list_init(&kv_item->list);
847 qb_list_add(&kv_item->list, &data->logger_subsys_items_head);
8a45e2b1
JF
848 }
849 add_as_string = 0;
850 break;
851 case MAIN_CP_CB_DATA_STATE_UIDGID:
852 if (strcmp(key, "uid") == 0) {
853 uid = uid_determine(value);
854 if (uid == -1) {
855 *error_string = error_string_response;
856 return (0);
857 }
f837f95d 858 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.uid.%u",
8a45e2b1 859 uid);
bc47c583 860 icmap_set_uint8_r(config_map, key_name, 1);
8a45e2b1
JF
861 add_as_string = 0;
862 } else if (strcmp(key, "gid") == 0) {
863 gid = gid_determine(value);
864 if (gid == -1) {
865 *error_string = error_string_response;
866 return (0);
867 }
f837f95d 868 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.gid.%u",
8a45e2b1 869 gid);
bc47c583 870 icmap_set_uint8_r(config_map, key_name, 1);
8a45e2b1
JF
871 add_as_string = 0;
872 } else {
873 *error_string = "uidgid: Only uid and gid are allowed items";
874 return (0);
875 }
876 break;
877 case MAIN_CP_CB_DATA_STATE_MEMBER:
878 if (strcmp(key, "memberaddr") != 0) {
879 *error_string = "Only memberaddr is allowed in member section";
880
881 return (0);
882 }
883
884 kv_item = malloc(sizeof(*kv_item));
885 if (kv_item == NULL) {
886 *error_string = "Can't alloc memory";
887
888 return (0);
889 }
890 memset(kv_item, 0, sizeof(*kv_item));
891
892 kv_item->key = strdup(key);
893 kv_item->value = strdup(value);
894 if (kv_item->key == NULL || kv_item->value == NULL) {
895 free(kv_item);
896 *error_string = "Can't alloc memory";
897
898 return (0);
899 }
b4c06e52
MJ
900 qb_list_init(&kv_item->list);
901 qb_list_add(&kv_item->list, &data->member_items_head);
8a45e2b1
JF
902 add_as_string = 0;
903 break;
6d0b0b14
JF
904 case MAIN_CP_CB_DATA_STATE_NODELIST:
905 break;
906 case MAIN_CP_CB_DATA_STATE_NODELIST_NODE:
907 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "nodelist.node.%u.%s", data->node_number, key);
908 if ((strcmp(key, "nodeid") == 0) ||
909 (strcmp(key, "quorum_votes") == 0)) {
4e9716ed
JF
910 val_type = ICMAP_VALUETYPE_UINT32;
911 if (safe_atoq(value, &val, val_type) != 0) {
0929dcb6
JF
912 goto atoi_error;
913 }
914
4e9716ed 915 icmap_set_uint32_r(config_map, key_name, val);
6d0b0b14
JF
916 add_as_string = 0;
917 }
918
6d0b0b14 919 if (add_as_string) {
bc47c583 920 icmap_set_string_r(config_map, key_name, value);
6d0b0b14
JF
921 add_as_string = 0;
922 }
923 break;
39cd6b3d 924 case MAIN_CP_CB_DATA_STATE_RESOURCES:
925 if (strcmp(key, "watchdog_timeout") == 0) {
926 val_type = ICMAP_VALUETYPE_UINT32;
927 if (safe_atoq(value, &val, val_type) != 0) {
928 goto atoi_error;
929 }
930 icmap_set_uint32_r(config_map,path, val);
931 add_as_string = 0;
932 }
933 break;
934 case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM:
39cd6b3d 935 case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_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;
944 case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS:
39cd6b3d 945 case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED:
946 if (strcmp(key, "poll_period") == 0) {
947 if (str_to_ull(value, &ull) != 0) {
948 goto atoi_error;
949 }
950 icmap_set_uint64_r(config_map,path, ull);
951 add_as_string = 0;
952 }
953 break;
ae229831
JF
954 }
955
8a45e2b1 956 if (add_as_string) {
bc47c583 957 icmap_set_string_r(config_map, path, value);
8a45e2b1
JF
958 }
959 break;
960 case PARSER_CB_SECTION_START:
961 if (strcmp(path, "totem.interface") == 0) {
aab55a00 962 *state = MAIN_CP_CB_DATA_STATE_INTERFACE;
268cde6e 963 data->linknumber = 0;
8a45e2b1
JF
964 data->mcastport = -1;
965 data->ttl = -1;
268cde6e
CC
966 data->knet_link_priority = -1;
967 data->knet_ping_interval = -1;
968 data->knet_ping_timeout = -1;
969 data->knet_ping_precision = -1;
7cec6a13 970 data->knet_pong_count = -1;
c0f1d576 971 data->knet_transport = NULL;
b4c06e52 972 qb_list_init(&data->member_items_head);
8a45e2b1
JF
973 };
974 if (strcmp(path, "totem") == 0) {
aab55a00 975 *state = MAIN_CP_CB_DATA_STATE_TOTEM;
8a45e2b1 976 };
3cd4f9a1 977 if (strcmp(path, "qb") == 0) {
aab55a00 978 *state = MAIN_CP_CB_DATA_STATE_QB;
3cd4f9a1 979 }
8a45e2b1 980 if (strcmp(path, "logging.logger_subsys") == 0) {
aab55a00 981 *state = MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS;
b4c06e52 982 qb_list_init(&data->logger_subsys_items_head);
8a45e2b1
JF
983 data->subsys = NULL;
984 }
985 if (strcmp(path, "logging.logging_daemon") == 0) {
aab55a00 986 *state = MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON;
b4c06e52 987 qb_list_init(&data->logger_subsys_items_head);
8a45e2b1
JF
988 data->subsys = NULL;
989 data->logging_daemon_name = NULL;
990 }
991 if (strcmp(path, "uidgid") == 0) {
aab55a00 992 *state = MAIN_CP_CB_DATA_STATE_UIDGID;
ae229831 993 }
8a45e2b1 994 if (strcmp(path, "totem.interface.member") == 0) {
aab55a00 995 *state = MAIN_CP_CB_DATA_STATE_MEMBER;
8a45e2b1
JF
996 }
997 if (strcmp(path, "quorum") == 0) {
aab55a00 998 *state = MAIN_CP_CB_DATA_STATE_QUORUM;
8a45e2b1 999 }
cb5fd775 1000 if (strcmp(path, "quorum.device") == 0) {
aab55a00 1001 *state = MAIN_CP_CB_DATA_STATE_QDEVICE;
cb5fd775 1002 }
6d0b0b14 1003 if (strcmp(path, "nodelist") == 0) {
aab55a00 1004 *state = MAIN_CP_CB_DATA_STATE_NODELIST;
6d0b0b14
JF
1005 data->node_number = 0;
1006 }
1007 if (strcmp(path, "nodelist.node") == 0) {
aab55a00 1008 *state = MAIN_CP_CB_DATA_STATE_NODELIST_NODE;
6d0b0b14 1009 }
39cd6b3d 1010 if (strcmp(path, "resources") == 0) {
1011 *state = MAIN_CP_CB_DATA_STATE_RESOURCES;
1012 }
1013 if (strcmp(path, "resources.system") == 0) {
1014 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM;
1015 }
1016 if (strcmp(path, "resources.system.memory_used") == 0) {
1017 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_MEMUSED;
1018 }
1019 if (strcmp(path, "resources.process") == 0) {
1020 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS;
1021 }
1022 if (strcmp(path, "resources.process.memory_used") == 0) {
1023 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED;
1024 }
8a45e2b1
JF
1025 break;
1026 case PARSER_CB_SECTION_END:
aab55a00 1027 switch (*state) {
8a45e2b1
JF
1028 case MAIN_CP_CB_DATA_STATE_INTERFACE:
1029 /*
1030 * Create new interface section
1031 */
1032 if (data->bindnetaddr != NULL) {
1033 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.bindnetaddr",
268cde6e 1034 data->linknumber);
bc47c583 1035 icmap_set_string_r(config_map, key_name, data->bindnetaddr);
8a45e2b1
JF
1036
1037 free(data->bindnetaddr);
1038 data->bindnetaddr = NULL;
8a45e2b1
JF
1039 }
1040
1041 if (data->mcastaddr != NULL) {
1042 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.mcastaddr",
268cde6e 1043 data->linknumber);
bc47c583 1044 icmap_set_string_r(config_map, key_name, data->mcastaddr);
8a45e2b1
JF
1045
1046 free(data->mcastaddr);
1047 data->mcastaddr = NULL;
1048 }
1049
1050 if (data->broadcast != NULL) {
1051 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.broadcast",
268cde6e 1052 data->linknumber);
bc47c583 1053 icmap_set_string_r(config_map, key_name, data->broadcast);
8a45e2b1
JF
1054
1055 free(data->broadcast);
1056 data->broadcast = NULL;
1057 }
1058
1059 if (data->mcastport > -1) {
1060 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.mcastport",
268cde6e 1061 data->linknumber);
bc47c583 1062 icmap_set_uint16_r(config_map, key_name, data->mcastport);
8a45e2b1
JF
1063 }
1064
1065 if (data->ttl > -1) {
1066 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.ttl",
268cde6e 1067 data->linknumber);
bc47c583 1068 icmap_set_uint8_r(config_map, key_name, data->ttl);
8a45e2b1 1069 }
268cde6e
CC
1070 if (data->knet_link_priority > -1) {
1071 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_link_priority",
1072 data->linknumber);
1073 icmap_set_uint8_r(config_map, key_name, data->knet_link_priority);
1074 }
1075 if (data->knet_ping_interval > -1) {
1076 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_ping_interval",
1077 data->linknumber);
1078 icmap_set_uint32_r(config_map, key_name, data->knet_ping_interval);
1079 }
1080 if (data->knet_ping_timeout > -1) {
1081 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_ping_timeout",
1082 data->linknumber);
1083 icmap_set_uint32_r(config_map, key_name, data->knet_ping_timeout);
1084 }
1085 if (data->knet_ping_precision > -1) {
1086 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_ping_precision",
1087 data->linknumber);
1088 icmap_set_uint32_r(config_map, key_name, data->knet_ping_precision);
1089 }
7cec6a13
CC
1090 if (data->knet_pong_count > -1) {
1091 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_pong_count",
1092 data->linknumber);
1093 icmap_set_uint32_r(config_map, key_name, data->knet_pong_count);
1094 }
c0f1d576
CC
1095 if (data->knet_transport) {
1096 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.knet_transport",
1097 data->linknumber);
1098 icmap_set_string_r(config_map, key_name, data->knet_transport);
1099 free(data->knet_transport);
1100 }
8a45e2b1 1101
4e9716ed 1102 ii = 0;
b4c06e52 1103
1f90c31b 1104 qb_list_for_each_safe(iter, tmp_iter, &(data->member_items_head)) {
b4c06e52 1105 kv_item = qb_list_entry(iter, struct key_value_list_item, list);
8a45e2b1
JF
1106
1107 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "totem.interface.%u.member.%u",
268cde6e 1108 data->linknumber, ii);
bc47c583 1109 icmap_set_string_r(config_map, key_name, kv_item->value);
8a45e2b1 1110
8a45e2b1
JF
1111 free(kv_item->value);
1112 free(kv_item->key);
1113 free(kv_item);
4e9716ed 1114 ii++;
8a45e2b1
JF
1115 }
1116
3cd4f9a1 1117 break;
8a45e2b1
JF
1118 case MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS:
1119 if (data->subsys == NULL) {
1120 *error_string = "No subsys key in logger_subsys directive";
1121
1122 return (0);
1123 }
1124
1f90c31b 1125 qb_list_for_each_safe(iter, tmp_iter, &(data->logger_subsys_items_head)) {
b4c06e52 1126 kv_item = qb_list_entry(iter, struct key_value_list_item, list);
8a45e2b1
JF
1127
1128 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logger_subsys.%s.%s",
aab55a00 1129 data->subsys, kv_item->key);
b4c06e52 1130 icmap_set_string_r(config_map, key_name, kv_item->value);
8a45e2b1
JF
1131
1132 free(kv_item->value);
1133 free(kv_item->key);
1134 free(kv_item);
1135 }
1136
1137 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logger_subsys.%s.subsys",
1138 data->subsys);
bc47c583 1139 icmap_set_string_r(config_map, key_name, data->subsys);
8a45e2b1
JF
1140
1141 free(data->subsys);
1142
8a45e2b1
JF
1143 break;
1144 case MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON:
1145 if (data->logging_daemon_name == NULL) {
1146 *error_string = "No name key in logging_daemon directive";
1147
1148 return (0);
1149 }
1150
1f90c31b 1151 qb_list_for_each_safe(iter, tmp_iter, &(data->logger_subsys_items_head)) {
b4c06e52 1152 kv_item = qb_list_entry(iter, struct key_value_list_item, list);
8a45e2b1
JF
1153
1154 if (data->subsys == NULL) {
1155 if (strcmp(data->logging_daemon_name, "corosync") == 0) {
1156 snprintf(key_name, ICMAP_KEYNAME_MAXLEN,
1157 "logging.%s",
1158 kv_item->key);
1159 } else {
1160 snprintf(key_name, ICMAP_KEYNAME_MAXLEN,
1161 "logging.logging_daemon.%s.%s",
1162 data->logging_daemon_name, kv_item->key);
1163 }
1164 } else {
1165 if (strcmp(data->logging_daemon_name, "corosync") == 0) {
1166 snprintf(key_name, ICMAP_KEYNAME_MAXLEN,
1167 "logging.logger_subsys.%s.%s",
1168 data->subsys,
1169 kv_item->key);
1170 } else {
1171 snprintf(key_name, ICMAP_KEYNAME_MAXLEN,
1172 "logging.logging_daemon.%s.%s.%s",
1173 data->logging_daemon_name, data->subsys,
1174 kv_item->key);
1175 }
1176 }
bc47c583 1177 icmap_set_string_r(config_map, key_name, kv_item->value);
8a45e2b1 1178
8a45e2b1
JF
1179 free(kv_item->value);
1180 free(kv_item->key);
1181 free(kv_item);
1182 }
1183
1184 if (data->subsys == NULL) {
1185 if (strcmp(data->logging_daemon_name, "corosync") != 0) {
1186 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logging_daemon.%s.name",
1187 data->logging_daemon_name);
bc47c583 1188 icmap_set_string_r(config_map, key_name, data->logging_daemon_name);
8a45e2b1
JF
1189 }
1190 } else {
1191 if (strcmp(data->logging_daemon_name, "corosync") == 0) {
1192 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logger_subsys.%s.subsys",
1193 data->subsys);
bc47c583 1194 icmap_set_string_r(config_map, key_name, data->subsys);
8a45e2b1
JF
1195
1196 } else {
1197 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logging_daemon.%s.%s.subsys",
1198 data->logging_daemon_name, data->subsys);
bc47c583 1199 icmap_set_string_r(config_map, key_name, data->subsys);
8a45e2b1
JF
1200 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "logging.logging_daemon.%s.%s.name",
1201 data->logging_daemon_name, data->subsys);
bc47c583 1202 icmap_set_string_r(config_map, key_name, data->logging_daemon_name);
8a45e2b1
JF
1203 }
1204 }
1205
1206 free(data->subsys);
1207 free(data->logging_daemon_name);
1208
6d0b0b14
JF
1209 break;
1210 case MAIN_CP_CB_DATA_STATE_NODELIST_NODE:
6d0b0b14 1211 data->node_number++;
aab55a00
CC
1212 break;
1213 case MAIN_CP_CB_DATA_STATE_NORMAL:
1214 case MAIN_CP_CB_DATA_STATE_PLOAD:
1215 case MAIN_CP_CB_DATA_STATE_UIDGID:
1216 case MAIN_CP_CB_DATA_STATE_MEMBER:
1217 case MAIN_CP_CB_DATA_STATE_QUORUM:
1218 case MAIN_CP_CB_DATA_STATE_QDEVICE:
1219 case MAIN_CP_CB_DATA_STATE_NODELIST:
1220 case MAIN_CP_CB_DATA_STATE_TOTEM:
1221 case MAIN_CP_CB_DATA_STATE_QB:
6d0b0b14 1222 break;
39cd6b3d 1223 case MAIN_CP_CB_DATA_STATE_RESOURCES:
1224 *state = MAIN_CP_CB_DATA_STATE_NORMAL;
1225 break;
1226 case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM:
1227 *state = MAIN_CP_CB_DATA_STATE_RESOURCES;
1228 break;
1229 case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_MEMUSED:
1230 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM;
1231 break;
1232 case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS:
1233 *state = MAIN_CP_CB_DATA_STATE_RESOURCES;
1234 break;
1235 case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED:
1236 *state = MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS;
1237 break;
8a45e2b1
JF
1238 }
1239 break;
ae229831
JF
1240 }
1241
8a45e2b1 1242 return (1);
0929dcb6
JF
1243
1244atoi_error:
4e9716ed
JF
1245 min_val = max_val = 0;
1246 /*
1247 * This is really assert, because developer ether doesn't set val_type correctly or
1248 * we've got here after some nasty memory overwrite
1249 */
1250 assert(safe_atoq_range(val_type, &min_val, &max_val) == 0);
1251
0929dcb6 1252 snprintf(formated_err, sizeof(formated_err),
4e9716ed
JF
1253 "Value of key \"%s\" is expected to be integer in range (%lld..%lld), but \"%s\" was given",
1254 key, min_val, max_val, value);
0929dcb6
JF
1255 *error_string = formated_err;
1256
1257 return (0);
8a45e2b1
JF
1258}
1259
1260static int uidgid_config_parser_cb(const char *path,
1261 char *key,
1262 char *value,
aab55a00 1263 enum main_cp_cb_data_state *state,
8a45e2b1
JF
1264 enum parser_cb_type type,
1265 const char **error_string,
bc47c583 1266 icmap_map_t config_map,
8a45e2b1
JF
1267 void *user_data)
1268{
1269 char key_name[ICMAP_KEYNAME_MAXLEN];
1270 int uid, gid;
1271
1272 switch (type) {
1273 case PARSER_CB_START:
1274 break;
1275 case PARSER_CB_END:
1276 break;
1277 case PARSER_CB_ITEM:
1278 if (strcmp(path, "uidgid.uid") == 0) {
1279 uid = uid_determine(value);
1280 if (uid == -1) {
1281 *error_string = error_string_response;
1282 return (0);
1283 }
f837f95d 1284 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.uid.%u",
8a45e2b1 1285 uid);
bc47c583 1286 icmap_set_uint8_r(config_map, key_name, 1);
92ead610 1287 } else if (strcmp(path, "uidgid.gid") == 0) {
8a45e2b1
JF
1288 gid = gid_determine(value);
1289 if (gid == -1) {
1290 *error_string = error_string_response;
1291 return (0);
1292 }
f837f95d 1293 snprintf(key_name, ICMAP_KEYNAME_MAXLEN, "uidgid.config.gid.%u",
8a45e2b1 1294 gid);
bc47c583 1295 icmap_set_uint8_r(config_map, key_name, 1);
8a45e2b1 1296 } else {
ae229831 1297 *error_string = "uidgid: Only uid and gid are allowed items";
8a45e2b1 1298 return (0);
ae229831 1299 }
8a45e2b1
JF
1300 break;
1301 case PARSER_CB_SECTION_START:
1302 if (strcmp(path, "uidgid") != 0) {
3b8365e8 1303 *error_string = "uidgid: Can't add subsection different than uidgid";
8a45e2b1
JF
1304 return (0);
1305 };
1306 break;
1307 case PARSER_CB_SECTION_END:
1308 break;
ae229831 1309 }
2f552719 1310
8a45e2b1 1311 return (1);
ae229831
JF
1312}
1313
8a45e2b1 1314static int read_uidgid_files_into_icmap(
bc47c583
CC
1315 const char **error_string,
1316 icmap_map_t config_map)
ae229831
JF
1317{
1318 FILE *fp;
1319 const char *dirname;
1320 DIR *dp;
1321 struct dirent *dirent;
1bd8aba6 1322 char filename[PATH_MAX + FILENAME_MAX + 1];
ae229831 1323 int res = 0;
1e0d40cd 1324 struct stat stat_buf;
aab55a00 1325 enum main_cp_cb_data_state state = MAIN_CP_CB_DATA_STATE_NORMAL;
8a45e2b1 1326 char key_name[ICMAP_KEYNAME_MAXLEN];
ae229831 1327
2135d91c 1328 dirname = COROSYSCONFDIR "/uidgid.d";
ae229831
JF
1329 dp = opendir (dirname);
1330
1331 if (dp == NULL)
1332 return 0;
1333
c83e6c7e
BL
1334 for (dirent = readdir(dp);
1335 dirent != NULL;
1336 dirent = readdir(dp)) {
2290913d 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:
1358 closedir(dp);
1359
1360 return res;
1361}
2f552719 1362
8a45e2b1
JF
1363/* Read config file and load into icmap */
1364static int read_config_file_into_icmap(
bc47c583
CC
1365 const char **error_string,
1366 icmap_map_t config_map)
2f552719
SD
1367{
1368 FILE *fp;
23c64c64 1369 const char *filename;
2f552719
SD
1370 char *error_reason = error_string_response;
1371 int res;
8a45e2b1
JF
1372 char key_name[ICMAP_KEYNAME_MAXLEN];
1373 struct main_cp_cb_data data;
aab55a00 1374 enum main_cp_cb_data_state state = MAIN_CP_CB_DATA_STATE_NORMAL;
2f552719
SD
1375
1376 filename = getenv ("COROSYNC_MAIN_CONFIG_FILE");
1377 if (!filename)
2135d91c 1378 filename = COROSYSCONFDIR "/corosync.conf";
2f552719
SD
1379
1380 fp = fopen (filename, "r");
23c64c64 1381 if (fp == NULL) {
20f3331d 1382 char error_str[100];
37e17e7a 1383 const char *error_ptr = qb_strerror_r(errno, error_str, sizeof(error_str));
870046d0 1384 snprintf (error_reason, sizeof(error_string_response),
3131601c 1385 "Can't read file %s reason = (%s)",
00434a4f 1386 filename, error_ptr);
2f552719
SD
1387 *error_string = error_reason;
1388 return -1;
1389 }
1390
8a45e2b1
JF
1391 key_name[0] = 0;
1392
aab55a00 1393 res = parse_section(fp, key_name, error_string, 0, state, main_config_parser_cb, config_map, &data);
2f552719
SD
1394
1395 fclose(fp);
1396
ae229831 1397 if (res == 0) {
bc47c583 1398 res = read_uidgid_files_into_icmap(error_string, config_map);
ae229831
JF
1399 }
1400
94b64352
JF
1401 if (res == 0) {
1402 snprintf (error_reason, sizeof(error_string_response),
3131601c 1403 "Successfully read main configuration file '%s'.", filename);
94b64352
JF
1404 *error_string = error_reason;
1405 }
2f552719
SD
1406
1407 return res;
1408}