38 #include <sys/types.h>
40 #include <sys/socket.h>
43 #include <netinet/in.h>
44 #include <arpa/inet.h>
58 #include <qb/qbutil.h>
59 #define LOGSYS_UTILS_ONLY 1
78 const char **error_string,
123 static int read_config_file_into_icmap(
124 const char **error_string,
icmap_map_t config_map);
125 static char error_string_response[512];
127 static int uid_determine (
const char *req_user)
130 struct passwd passwd;
131 struct passwd* pwdptr = &passwd;
132 struct passwd* temp_pwd_pt;
138 id = strtol(req_user, &ep, 10);
139 if (*ep ==
'\0' &&
id >= 0 &&
id <= UINT_MAX) {
143 pwdlinelen = sysconf (_SC_GETPW_R_SIZE_MAX);
145 if (pwdlinelen == -1) {
149 pwdbuffer = malloc (pwdlinelen);
151 while ((rc = getpwnam_r (req_user, pwdptr, pwdbuffer, pwdlinelen, &temp_pwd_pt)) == ERANGE) {
155 if (pwdlinelen <= 32678) {
156 n = realloc (pwdbuffer, pwdlinelen);
165 sprintf (error_string_response,
"getpwnam_r(): %s", strerror(rc));
168 if (temp_pwd_pt == NULL) {
170 sprintf (error_string_response,
171 "The '%s' user is not found in /etc/passwd, please read the documentation.",
175 pw_uid = passwd.pw_uid;
181 static int gid_determine (
const char *req_group)
183 int corosync_gid = 0;
185 struct group * grpptr = &group;
186 struct group * temp_grp_pt;
192 id = strtol(req_group, &ep, 10);
193 if (*ep ==
'\0' &&
id >= 0 &&
id <= UINT_MAX) {
197 grplinelen = sysconf (_SC_GETGR_R_SIZE_MAX);
199 if (grplinelen == -1) {
203 grpbuffer = malloc (grplinelen);
205 while ((rc = getgrnam_r (req_group, grpptr, grpbuffer, grplinelen, &temp_grp_pt)) == ERANGE) {
209 if (grplinelen <= 32678) {
210 n = realloc (grpbuffer, grplinelen);
219 sprintf (error_string_response,
"getgrnam_r(): %s", strerror(rc));
222 if (temp_grp_pt == NULL) {
224 sprintf (error_string_response,
225 "The '%s' group is not found in /etc/group, please read the documentation.",
229 corosync_gid = group.gr_gid;
234 static char *strchr_rs (
const char *haystack,
int byte)
236 const char *end_address = strchr (haystack, byte);
240 while (*end_address ==
' ' || *end_address ==
'\t')
244 return ((
char *) end_address);
249 if (read_config_file_into_icmap(error_string, config_map)) {
256 static char *remove_whitespace(
char *
string,
int remove_colon_and_brace)
262 while (*start ==
' ' || *start ==
'\t')
265 end = start+(strlen(start))-1;
266 while ((*end ==
' ' || *end ==
'\t' || (remove_colon_and_brace && (*end ==
':' || *end ==
'{'))) && end > start)
276 static int parse_section(FILE *fp,
278 const char **error_string,
290 if (strcmp(path,
"") == 0) {
291 parser_cb(
"", NULL, NULL,
PARSER_CB_START, error_string, config_map, user_data);
294 while (fgets (line,
sizeof (line), fp)) {
295 if (strlen(line) > 0) {
296 if (line[strlen(line) - 1] ==
'\n')
297 line[strlen(line) - 1] =
'\0';
298 if (strlen (line) > 0 && line[strlen(line) - 1] ==
'\r')
299 line[strlen(line) - 1] =
'\0';
304 for (i = strlen (line) - 1; i > -1; i--) {
305 if (line[i] ==
'\t' || line[i] ==
' ') {
313 for (i = 0; i < strlen (line); i++) {
314 if (line[i] !=
'\t' && line[i] !=
' ') {
329 if ((loc = strchr_rs (line,
'{'))) {
330 char *section = remove_whitespace(line, 1);
336 *error_string =
"parser error: Start of section makes total cmap path too long";
339 strcpy(new_keyname, path);
340 if (strcmp(path,
"") != 0) {
341 strcat(new_keyname,
".");
343 strcat(new_keyname, section);
349 if (parse_section(fp, new_keyname, error_string, depth + 1, parser_cb, config_map, user_data))
356 if ((loc = strchr_rs (line,
':'))) {
361 key = remove_whitespace(line, 1);
362 value = remove_whitespace(loc, 0);
365 *error_string =
"parser error: New key makes total cmap path too long";
368 strcpy(new_keyname, path);
369 if (strcmp(path,
"") != 0) {
370 strcat(new_keyname,
".");
372 strcat(new_keyname, key);
374 if (!parser_cb(new_keyname, key, value,
PARSER_CB_ITEM, error_string, config_map, user_data)) {
381 if (strchr_rs (line,
'}')) {
383 *error_string =
"parser error: Unexpected closing brace";
396 if (strcmp(path,
"") != 0) {
397 *error_string =
"parser error: Missing closing brace";
401 if (strcmp(path,
"") == 0) {
402 parser_cb(
"", NULL, NULL,
PARSER_CB_END, error_string, config_map, user_data);
408 static int safe_atoi(
const char *str,
int *res)
415 val = strtol(str, &endptr, 10);
416 if (errno == ERANGE) {
424 if (*endptr !=
'\0') {
432 static int str_to_ull(
const char *str,
unsigned long long int *res)
434 unsigned long long int val;
439 val = strtoull(str, &endptr, 10);
440 if (errno == ERANGE) {
448 if (*endptr !=
'\0') {
456 static int main_config_parser_cb(
const char *path,
460 const char **error_string,
465 unsigned long long int ull;
468 static char formated_err[256];
484 switch (data->
state) {
488 if ((strcmp(path,
"pload.count") == 0) ||
489 (strcmp(path,
"pload.size") == 0)) {
490 if (safe_atoi(value, &i) != 0) {
498 if ((strcmp(path,
"quorum.expected_votes") == 0) ||
499 (strcmp(path,
"quorum.votes") == 0) ||
500 (strcmp(path,
"quorum.last_man_standing_window") == 0) ||
501 (strcmp(path,
"quorum.leaving_timeout") == 0)) {
502 if (safe_atoi(value, &i) != 0) {
509 if ((strcmp(path,
"quorum.two_node") == 0) ||
510 (strcmp(path,
"quorum.allow_downscale") == 0) ||
511 (strcmp(path,
"quorum.wait_for_all") == 0) ||
512 (strcmp(path,
"quorum.auto_tie_breaker") == 0) ||
513 (strcmp(path,
"quorum.last_man_standing") == 0)) {
514 if (safe_atoi(value, &i) != 0) {
522 if ((strcmp(path,
"quorum.device.timeout") == 0) ||
523 (strcmp(path,
"quorum.device.votes") == 0)) {
524 if (safe_atoi(value, &i) != 0) {
530 if ((strcmp(path,
"quorum.device.master_wins") == 0)) {
531 if (safe_atoi(value, &i) != 0) {
539 if ((strcmp(path,
"totem.version") == 0) ||
540 (strcmp(path,
"totem.nodeid") == 0) ||
541 (strcmp(path,
"totem.threads") == 0) ||
542 (strcmp(path,
"totem.token") == 0) ||
543 (strcmp(path,
"totem.token_retransmit") == 0) ||
544 (strcmp(path,
"totem.hold") == 0) ||
545 (strcmp(path,
"totem.token_retransmits_before_loss_const") == 0) ||
546 (strcmp(path,
"totem.join") == 0) ||
547 (strcmp(path,
"totem.send_join") == 0) ||
548 (strcmp(path,
"totem.consensus") == 0) ||
549 (strcmp(path,
"totem.merge") == 0) ||
550 (strcmp(path,
"totem.downcheck") == 0) ||
551 (strcmp(path,
"totem.fail_recv_const") == 0) ||
552 (strcmp(path,
"totem.seqno_unchanged_const") == 0) ||
553 (strcmp(path,
"totem.rrp_token_expired_timeout") == 0) ||
554 (strcmp(path,
"totem.rrp_problem_count_timeout") == 0) ||
555 (strcmp(path,
"totem.rrp_problem_count_threshold") == 0) ||
556 (strcmp(path,
"totem.rrp_problem_count_mcast_threshold") == 0) ||
557 (strcmp(path,
"totem.rrp_autorecovery_check_timeout") == 0) ||
558 (strcmp(path,
"totem.heartbeat_failures_allowed") == 0) ||
559 (strcmp(path,
"totem.max_network_delay") == 0) ||
560 (strcmp(path,
"totem.window_size") == 0) ||
561 (strcmp(path,
"totem.max_messages") == 0) ||
562 (strcmp(path,
"totem.miss_count_const") == 0) ||
563 (strcmp(path,
"totem.netmtu") == 0)) {
564 if (safe_atoi(value, &i) != 0) {
570 if (strcmp(path,
"totem.config_version") == 0) {
571 if (str_to_ull(value, &ull) != 0) {
577 if (strcmp(path,
"totem.ip_version") == 0) {
578 if ((strcmp(value,
"ipv4") != 0) &&
579 (strcmp(value,
"ipv6") != 0)) {
580 *error_string =
"Invalid ip_version type";
585 if (strcmp(path,
"totem.crypto_type") == 0) {
586 if ((strcmp(value,
"nss") != 0) &&
587 (strcmp(value,
"aes256") != 0) &&
588 (strcmp(value,
"aes192") != 0) &&
589 (strcmp(value,
"aes128") != 0) &&
590 (strcmp(value,
"3des") != 0)) {
591 *error_string =
"Invalid crypto type";
596 if (strcmp(path,
"totem.crypto_cipher") == 0) {
597 if ((strcmp(value,
"none") != 0) &&
598 (strcmp(value,
"aes256") != 0) &&
599 (strcmp(value,
"aes192") != 0) &&
600 (strcmp(value,
"aes128") != 0) &&
601 (strcmp(value,
"3des") != 0)) {
602 *error_string =
"Invalid cipher type";
607 if (strcmp(path,
"totem.crypto_hash") == 0) {
608 if ((strcmp(value,
"none") != 0) &&
609 (strcmp(value,
"md5") != 0) &&
610 (strcmp(value,
"sha1") != 0) &&
611 (strcmp(value,
"sha256") != 0) &&
612 (strcmp(value,
"sha384") != 0) &&
613 (strcmp(value,
"sha512") != 0)) {
614 *error_string =
"Invalid hash type";
622 if (strcmp(path,
"qb.ipc_type") == 0) {
623 if ((strcmp(value,
"native") != 0) &&
624 (strcmp(value,
"shm") != 0) &&
625 (strcmp(value,
"socket") != 0)) {
626 *error_string =
"Invalid qb ipc_type";
634 if (strcmp(path,
"totem.interface.ringnumber") == 0) {
635 if (safe_atoi(value, &i) != 0) {
642 if (strcmp(path,
"totem.interface.bindnetaddr") == 0) {
646 if (strcmp(path,
"totem.interface.mcastaddr") == 0) {
650 if (strcmp(path,
"totem.interface.broadcast") == 0) {
654 if (strcmp(path,
"totem.interface.mcastport") == 0) {
655 if (safe_atoi(value, &i) != 0) {
660 *error_string =
"Invalid multicast port (should be 0..65535)";
666 if (strcmp(path,
"totem.interface.ttl") == 0) {
667 if (safe_atoi(value, &i) != 0) {
671 if (data->
ttl < 0 || data->
ttl > 255) {
672 *error_string =
"Invalid TTL (should be 0..255)";
680 if (strcmp(key,
"subsys") == 0) {
681 data->
subsys = strdup(value);
682 if (data->
subsys == NULL) {
683 *error_string =
"Can't alloc memory";
688 kv_item = malloc(
sizeof(*kv_item));
689 if (kv_item == NULL) {
690 *error_string =
"Can't alloc memory";
694 memset(kv_item, 0,
sizeof(*kv_item));
696 kv_item->
key = strdup(key);
697 kv_item->
value = strdup(value);
698 if (kv_item->
key == NULL || kv_item->
value == NULL) {
700 *error_string =
"Can't alloc memory";
704 list_init(&kv_item->
list);
710 if (strcmp(key,
"subsys") == 0) {
711 data->
subsys = strdup(value);
712 if (data->
subsys == NULL) {
713 *error_string =
"Can't alloc memory";
717 }
else if (strcmp(key,
"name") == 0) {
720 *error_string =
"Can't alloc memory";
725 kv_item = malloc(
sizeof(*kv_item));
726 if (kv_item == NULL) {
727 *error_string =
"Can't alloc memory";
731 memset(kv_item, 0,
sizeof(*kv_item));
733 kv_item->
key = strdup(key);
734 kv_item->
value = strdup(value);
735 if (kv_item->
key == NULL || kv_item->
value == NULL) {
737 *error_string =
"Can't alloc memory";
741 list_init(&kv_item->
list);
747 if (strcmp(key,
"uid") == 0) {
748 uid = uid_determine(value);
750 *error_string = error_string_response;
757 }
else if (strcmp(key,
"gid") == 0) {
758 gid = gid_determine(value);
760 *error_string = error_string_response;
768 *error_string =
"uidgid: Only uid and gid are allowed items";
773 if (strcmp(key,
"memberaddr") != 0) {
774 *error_string =
"Only memberaddr is allowed in member section";
779 kv_item = malloc(
sizeof(*kv_item));
780 if (kv_item == NULL) {
781 *error_string =
"Can't alloc memory";
785 memset(kv_item, 0,
sizeof(*kv_item));
787 kv_item->
key = strdup(key);
788 kv_item->
value = strdup(value);
789 if (kv_item->
key == NULL || kv_item->
value == NULL) {
791 *error_string =
"Can't alloc memory";
795 list_init(&kv_item->
list);
803 if ((strcmp(key,
"nodeid") == 0) ||
804 (strcmp(key,
"quorum_votes") == 0)) {
805 if (safe_atoi(value, &i) != 0) {
813 if (strcmp(key,
"ring0_addr") == 0) {
829 if (strcmp(path,
"totem.interface") == 0) {
836 if (strcmp(path,
"totem") == 0) {
839 if (strcmp(path,
"qb") == 0) {
842 if (strcmp(path,
"logging.logger_subsys") == 0) {
847 if (strcmp(path,
"logging.logging_daemon") == 0) {
853 if (strcmp(path,
"uidgid") == 0) {
856 if (strcmp(path,
"totem.interface.member") == 0) {
859 if (strcmp(path,
"quorum") == 0) {
862 if (strcmp(path,
"quorum.device") == 0) {
865 if (strcmp(path,
"nodelist") == 0) {
869 if (strcmp(path,
"nodelist.node") == 0) {
875 switch (data->
state) {
918 if (data->
ttl > -1) {
933 iter_next = iter->
next;
935 free(kv_item->
value);
950 if (data->
subsys == NULL) {
951 *error_string =
"No subsys key in logger_subsys directive";
964 iter_next = iter->
next;
966 free(kv_item->
value);
981 *error_string =
"No name key in logging_daemon directive";
990 if (data->
subsys == NULL) {
997 "logging.logging_daemon.%s.%s",
1003 "logging.logger_subsys.%s.%s",
1008 "logging.logging_daemon.%s.%s.%s",
1015 iter_next = iter->
next;
1017 free(kv_item->
value);
1022 if (data->
subsys == NULL) {
1066 *error_string =
"No ring0_addr specified for node";
1080 snprintf(formated_err,
sizeof(formated_err),
1081 "Value of key \"%s\" must be integer, but \"%s\" was given", key, value);
1082 *error_string = formated_err;
1087 static int uidgid_config_parser_cb(
const char *path,
1091 const char **error_string,
1104 if (strcmp(path,
"uidgid.uid") == 0) {
1105 uid = uid_determine(value);
1107 *error_string = error_string_response;
1113 }
else if (strcmp(path,
"uidgid.gid") == 0) {
1114 gid = gid_determine(value);
1116 *error_string = error_string_response;
1123 *error_string =
"uidgid: Only uid and gid are allowed items";
1128 if (strcmp(path,
"uidgid") != 0) {
1129 *error_string =
"uidgid: Can't add subsection different then uidgid";
1140 static int read_uidgid_files_into_icmap(
1141 const char **error_string,
1145 const char *dirname;
1147 struct dirent *dirent;
1148 struct dirent *entry;
1149 char filename[PATH_MAX + FILENAME_MAX + 1];
1153 struct stat stat_buf;
1157 dp = opendir (dirname);
1162 len = offsetof(
struct dirent, d_name) + FILENAME_MAX + 1;
1164 entry = malloc(len);
1165 if (entry == NULL) {
1170 for (return_code = readdir_r(dp, entry, &dirent);
1171 dirent != NULL && return_code == 0;
1172 return_code = readdir_r(dp, entry, &dirent)) {
1174 snprintf(filename,
sizeof (filename),
"%s/%s", dirname, dirent->d_name);
1175 res = stat (filename, &stat_buf);
1176 if (res == 0 && S_ISREG(stat_buf.st_mode)) {
1178 fp = fopen (filename,
"r");
1179 if (fp == NULL)
continue;
1183 res = parse_section(fp, key_name, error_string, 0, uidgid_config_parser_cb, config_map, NULL);
1201 static int read_config_file_into_icmap(
1202 const char **error_string,
1206 const char *filename;
1207 char *error_reason = error_string_response;
1212 filename = getenv (
"COROSYNC_MAIN_CONFIG_FILE");
1216 fp = fopen (filename,
"r");
1218 char error_str[100];
1219 const char *error_ptr = qb_strerror_r(errno, error_str,
sizeof(error_str));
1220 snprintf (error_reason,
sizeof(error_string_response),
1221 "Can't read file %s reason = (%s)",
1222 filename, error_ptr);
1223 *error_string = error_reason;
1229 res = parse_section(fp, key_name, error_string, 0, main_config_parser_cb, config_map, &data);
1234 res = read_uidgid_files_into_icmap(error_string, config_map);
1238 snprintf (error_reason,
sizeof(error_string_response),
1239 "Successfully read main configuration file '%s'.", filename);
1240 *error_string = error_reason;
char * logging_daemon_name
int(* parser_cb_f)(const char *path, char *key, char *value, enum parser_cb_type type, const char **error_string, icmap_map_t config_map, void *user_data)
struct list_head logger_subsys_items_head
struct list_head member_items_head
int coroparse_configparse(icmap_map_t config_map, const char **error_string)
cs_error_t icmap_set_uint64_r(const icmap_map_t map, const char *key_name, uint64_t value)
enum main_cp_cb_data_state state
cs_error_t icmap_set_string_r(const icmap_map_t map, const char *key_name, const char *value)
#define ICMAP_KEYNAME_MAXLEN
cs_error_t icmap_set_uint8_r(const icmap_map_t map, const char *key_name, uint8_t value)
cs_error_t icmap_set_uint32_r(const icmap_map_t map, const char *key_name, uint32_t value)
cs_error_t icmap_set_uint16_r(const icmap_map_t map, const char *key_name, uint16_t value)
#define list_entry(ptr, type, member)