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 95 const char **error_string,
122 static int read_config_file_into_icmap(
123 const char **error_string,
icmap_map_t config_map);
124 static char error_string_response[512];
126 static int uid_determine (
const char *req_user)
129 struct passwd passwd;
130 struct passwd* pwdptr = &passwd;
131 struct passwd* temp_pwd_pt;
137 id = strtol(req_user, &ep, 10);
138 if (*ep ==
'\0' &&
id >= 0 &&
id <= UINT_MAX) {
142 pwdlinelen = sysconf (_SC_GETPW_R_SIZE_MAX);
144 if (pwdlinelen == -1) {
148 pwdbuffer = malloc (pwdlinelen);
150 while ((rc = getpwnam_r (req_user, pwdptr, pwdbuffer, pwdlinelen, &temp_pwd_pt)) == ERANGE) {
154 if (pwdlinelen <= 32678) {
155 n = realloc (pwdbuffer, pwdlinelen);
164 sprintf (error_string_response,
"getpwnam_r(): %s", strerror(rc));
167 if (temp_pwd_pt == NULL) {
169 sprintf (error_string_response,
170 "The '%s' user is not found in /etc/passwd, please read the documentation.",
174 pw_uid = passwd.pw_uid;
180 static int gid_determine (
const char *req_group)
182 int corosync_gid = 0;
184 struct group * grpptr = &group;
185 struct group * temp_grp_pt;
191 id = strtol(req_group, &ep, 10);
192 if (*ep ==
'\0' &&
id >= 0 &&
id <= UINT_MAX) {
196 grplinelen = sysconf (_SC_GETGR_R_SIZE_MAX);
198 if (grplinelen == -1) {
202 grpbuffer = malloc (grplinelen);
204 while ((rc = getgrnam_r (req_group, grpptr, grpbuffer, grplinelen, &temp_grp_pt)) == ERANGE) {
208 if (grplinelen <= 32678) {
209 n = realloc (grpbuffer, grplinelen);
218 sprintf (error_string_response,
"getgrnam_r(): %s", strerror(rc));
221 if (temp_grp_pt == NULL) {
223 sprintf (error_string_response,
224 "The '%s' group is not found in /etc/group, please read the documentation.",
228 corosync_gid = group.gr_gid;
233 static char *strchr_rs (
const char *haystack,
int byte)
235 const char *end_address = strchr (haystack, byte);
239 while (*end_address ==
' ' || *end_address ==
'\t')
243 return ((
char *) end_address);
248 if (read_config_file_into_icmap(error_string, config_map)) {
255 static char *remove_whitespace(
char *
string,
int remove_colon_and_brace)
261 while (*start ==
' ' || *start ==
'\t')
264 end = start+(strlen(start))-1;
265 while ((*end ==
' ' || *end ==
'\t' || (remove_colon_and_brace && (*end ==
':' || *end ==
'{'))) && end > start)
275 static int parse_section(FILE *fp,
277 const char **error_string,
290 if (strcmp(path,
"") == 0) {
291 parser_cb(
"", NULL, NULL, &state,
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);
337 *error_string =
"parser error: Start of section makes total cmap path too long";
340 strcpy(new_keyname, path);
341 if (strcmp(path,
"") != 0) {
342 strcat(new_keyname,
".");
344 strcat(new_keyname, section);
348 if (!parser_cb(new_keyname, NULL, NULL, &newstate,
PARSER_CB_SECTION_START, error_string, config_map, user_data)) {
352 if (parse_section(fp, new_keyname, error_string, depth + 1, newstate, parser_cb, config_map, user_data))
359 if ((loc = strchr_rs (line,
':'))) {
364 key = remove_whitespace(line, 1);
365 value = remove_whitespace(loc, 0);
368 *error_string =
"parser error: New key makes total cmap path too long";
371 strcpy(new_keyname, path);
372 if (strcmp(path,
"") != 0) {
373 strcat(new_keyname,
".");
375 strcat(new_keyname, key);
377 if (!parser_cb(new_keyname, key, value, &state,
PARSER_CB_ITEM, error_string, config_map, user_data)) {
384 if (strchr_rs (line,
'}')) {
386 *error_string =
"parser error: Unexpected closing brace";
391 if (!parser_cb(path, NULL, NULL, &state,
PARSER_CB_SECTION_END, error_string, config_map, user_data)) {
399 if (strcmp(path,
"") != 0) {
400 *error_string =
"parser error: Missing closing brace";
404 if (strcmp(path,
"") == 0) {
405 parser_cb(
"", NULL, NULL, &state,
PARSER_CB_END, error_string, config_map, user_data);
411 static int safe_atoq_range(
icmap_value_types_t value_type,
long long int *min_val,
long long int *max_val)
413 switch (value_type) {
435 long long int min_val, max_val;
440 val = strtoll(str, &endptr, 10);
441 if (errno == ERANGE) {
449 if (*endptr !=
'\0') {
453 if (safe_atoq_range(target_type, &min_val, &max_val) != 0) {
457 if (val < min_val || val > max_val) {
465 static int str_to_ull(
const char *str,
unsigned long long int *res)
467 unsigned long long int val;
472 val = strtoull(str, &endptr, 10);
473 if (errno == ERANGE) {
481 if (*endptr !=
'\0') {
489 static int main_config_parser_cb(
const char *path,
494 const char **error_string,
500 long long int min_val, max_val;
502 unsigned long long int ull;
505 static char formated_err[256];
525 if ((strcmp(path,
"pload.count") == 0) ||
526 (strcmp(path,
"pload.size") == 0)) {
528 if (safe_atoq(value, &val, val_type) != 0) {
536 if ((strcmp(path,
"quorum.expected_votes") == 0) ||
537 (strcmp(path,
"quorum.votes") == 0) ||
538 (strcmp(path,
"quorum.last_man_standing_window") == 0) ||
539 (strcmp(path,
"quorum.leaving_timeout") == 0)) {
541 if (safe_atoq(value, &val, val_type) != 0) {
548 if ((strcmp(path,
"quorum.two_node") == 0) ||
549 (strcmp(path,
"quorum.expected_votes_tracking") == 0) ||
550 (strcmp(path,
"quorum.allow_downscale") == 0) ||
551 (strcmp(path,
"quorum.wait_for_all") == 0) ||
552 (strcmp(path,
"quorum.auto_tie_breaker") == 0) ||
553 (strcmp(path,
"quorum.last_man_standing") == 0)) {
555 if (safe_atoq(value, &val, val_type) != 0) {
563 if ((strcmp(path,
"quorum.device.timeout") == 0) ||
564 (strcmp(path,
"quorum.device.sync_timeout") == 0) ||
565 (strcmp(path,
"quorum.device.votes") == 0)) {
567 if (safe_atoq(value, &val, val_type) != 0) {
573 if ((strcmp(path,
"quorum.device.master_wins") == 0)) {
575 if (safe_atoq(value, &val, val_type) != 0) {
583 if ((strcmp(path,
"totem.version") == 0) ||
584 (strcmp(path,
"totem.nodeid") == 0) ||
585 (strcmp(path,
"totem.threads") == 0) ||
586 (strcmp(path,
"totem.token") == 0) ||
587 (strcmp(path,
"totem.token_coefficient") == 0) ||
588 (strcmp(path,
"totem.token_retransmit") == 0) ||
589 (strcmp(path,
"totem.hold") == 0) ||
590 (strcmp(path,
"totem.token_retransmits_before_loss_const") == 0) ||
591 (strcmp(path,
"totem.join") == 0) ||
592 (strcmp(path,
"totem.send_join") == 0) ||
593 (strcmp(path,
"totem.consensus") == 0) ||
594 (strcmp(path,
"totem.merge") == 0) ||
595 (strcmp(path,
"totem.downcheck") == 0) ||
596 (strcmp(path,
"totem.fail_recv_const") == 0) ||
597 (strcmp(path,
"totem.seqno_unchanged_const") == 0) ||
598 (strcmp(path,
"totem.rrp_token_expired_timeout") == 0) ||
599 (strcmp(path,
"totem.rrp_problem_count_timeout") == 0) ||
600 (strcmp(path,
"totem.rrp_problem_count_threshold") == 0) ||
601 (strcmp(path,
"totem.rrp_problem_count_mcast_threshold") == 0) ||
602 (strcmp(path,
"totem.rrp_autorecovery_check_timeout") == 0) ||
603 (strcmp(path,
"totem.heartbeat_failures_allowed") == 0) ||
604 (strcmp(path,
"totem.max_network_delay") == 0) ||
605 (strcmp(path,
"totem.window_size") == 0) ||
606 (strcmp(path,
"totem.max_messages") == 0) ||
607 (strcmp(path,
"totem.miss_count_const") == 0) ||
608 (strcmp(path,
"totem.netmtu") == 0)) {
610 if (safe_atoq(value, &val, val_type) != 0) {
616 if (strcmp(path,
"totem.config_version") == 0) {
617 if (str_to_ull(value, &ull) != 0) {
623 if (strcmp(path,
"totem.ip_version") == 0) {
624 if ((strcmp(value,
"ipv4") != 0) &&
625 (strcmp(value,
"ipv6") != 0)) {
626 *error_string =
"Invalid ip_version type";
631 if (strcmp(path,
"totem.crypto_type") == 0) {
632 if ((strcmp(value,
"nss") != 0) &&
633 (strcmp(value,
"aes256") != 0) &&
634 (strcmp(value,
"aes192") != 0) &&
635 (strcmp(value,
"aes128") != 0) &&
636 (strcmp(value,
"3des") != 0)) {
637 *error_string =
"Invalid crypto type";
642 if (strcmp(path,
"totem.crypto_cipher") == 0) {
643 if ((strcmp(value,
"none") != 0) &&
644 (strcmp(value,
"aes256") != 0) &&
645 (strcmp(value,
"aes192") != 0) &&
646 (strcmp(value,
"aes128") != 0) &&
647 (strcmp(value,
"3des") != 0)) {
648 *error_string =
"Invalid cipher type";
653 if (strcmp(path,
"totem.crypto_hash") == 0) {
654 if ((strcmp(value,
"none") != 0) &&
655 (strcmp(value,
"md5") != 0) &&
656 (strcmp(value,
"sha1") != 0) &&
657 (strcmp(value,
"sha256") != 0) &&
658 (strcmp(value,
"sha384") != 0) &&
659 (strcmp(value,
"sha512") != 0)) {
660 *error_string =
"Invalid hash type";
668 if (strcmp(path,
"qb.ipc_type") == 0) {
669 if ((strcmp(value,
"native") != 0) &&
670 (strcmp(value,
"shm") != 0) &&
671 (strcmp(value,
"socket") != 0)) {
672 *error_string =
"Invalid qb ipc_type";
680 if (strcmp(path,
"totem.interface.ringnumber") == 0) {
682 if (safe_atoq(value, &val, val_type) != 0) {
689 if (strcmp(path,
"totem.interface.bindnetaddr") == 0) {
693 if (strcmp(path,
"totem.interface.mcastaddr") == 0) {
697 if (strcmp(path,
"totem.interface.broadcast") == 0) {
701 if (strcmp(path,
"totem.interface.mcastport") == 0) {
703 if (safe_atoq(value, &val, val_type) != 0) {
709 if (strcmp(path,
"totem.interface.ttl") == 0) {
711 if (safe_atoq(value, &val, val_type) != 0) {
719 if (strcmp(key,
"subsys") == 0) {
720 data->
subsys = strdup(value);
721 if (data->
subsys == NULL) {
722 *error_string =
"Can't alloc memory";
727 kv_item = malloc(
sizeof(*kv_item));
728 if (kv_item == NULL) {
729 *error_string =
"Can't alloc memory";
733 memset(kv_item, 0,
sizeof(*kv_item));
735 kv_item->
key = strdup(key);
736 kv_item->
value = strdup(value);
737 if (kv_item->
key == NULL || kv_item->
value == NULL) {
739 *error_string =
"Can't alloc memory";
743 list_init(&kv_item->
list);
749 if (strcmp(key,
"subsys") == 0) {
750 data->
subsys = strdup(value);
751 if (data->
subsys == NULL) {
752 *error_string =
"Can't alloc memory";
756 }
else if (strcmp(key,
"name") == 0) {
759 *error_string =
"Can't alloc memory";
764 kv_item = malloc(
sizeof(*kv_item));
765 if (kv_item == NULL) {
766 *error_string =
"Can't alloc memory";
770 memset(kv_item, 0,
sizeof(*kv_item));
772 kv_item->
key = strdup(key);
773 kv_item->
value = strdup(value);
774 if (kv_item->
key == NULL || kv_item->
value == NULL) {
776 *error_string =
"Can't alloc memory";
780 list_init(&kv_item->
list);
786 if (strcmp(key,
"uid") == 0) {
787 uid = uid_determine(value);
789 *error_string = error_string_response;
796 }
else if (strcmp(key,
"gid") == 0) {
797 gid = gid_determine(value);
799 *error_string = error_string_response;
807 *error_string =
"uidgid: Only uid and gid are allowed items";
812 if (strcmp(key,
"memberaddr") != 0) {
813 *error_string =
"Only memberaddr is allowed in member section";
818 kv_item = malloc(
sizeof(*kv_item));
819 if (kv_item == NULL) {
820 *error_string =
"Can't alloc memory";
824 memset(kv_item, 0,
sizeof(*kv_item));
826 kv_item->
key = strdup(key);
827 kv_item->
value = strdup(value);
828 if (kv_item->
key == NULL || kv_item->
value == NULL) {
830 *error_string =
"Can't alloc memory";
834 list_init(&kv_item->
list);
842 if ((strcmp(key,
"nodeid") == 0) ||
843 (strcmp(key,
"quorum_votes") == 0)) {
845 if (safe_atoq(value, &val, val_type) != 0) {
853 if (strcmp(key,
"ring0_addr") == 0) {
869 if (strcmp(path,
"totem.interface") == 0) {
876 if (strcmp(path,
"totem") == 0) {
879 if (strcmp(path,
"qb") == 0) {
882 if (strcmp(path,
"logging.logger_subsys") == 0) {
887 if (strcmp(path,
"logging.logging_daemon") == 0) {
893 if (strcmp(path,
"uidgid") == 0) {
896 if (strcmp(path,
"totem.interface.member") == 0) {
899 if (strcmp(path,
"quorum") == 0) {
902 if (strcmp(path,
"quorum.device") == 0) {
905 if (strcmp(path,
"nodelist") == 0) {
909 if (strcmp(path,
"nodelist.node") == 0) {
953 if (data->
ttl > -1) {
968 iter_next = iter->
next;
970 free(kv_item->
value);
978 if (data->
subsys == NULL) {
979 *error_string =
"No subsys key in logger_subsys directive";
992 iter_next = iter->
next;
994 free(kv_item->
value);
1008 *error_string =
"No name key in logging_daemon directive";
1017 if (data->
subsys == NULL) {
1024 "logging.logging_daemon.%s.%s",
1030 "logging.logger_subsys.%s.%s",
1035 "logging.logging_daemon.%s.%s.%s",
1042 iter_next = iter->
next;
1044 free(kv_item->
value);
1049 if (data->
subsys == NULL) {
1077 *error_string =
"No ring0_addr specified for node";
1100 min_val = max_val = 0;
1105 assert(safe_atoq_range(val_type, &min_val, &max_val) == 0);
1107 snprintf(formated_err,
sizeof(formated_err),
1108 "Value of key \"%s\" is expected to be integer in range (%lld..%lld), but \"%s\" was given",
1109 key, min_val, max_val, value);
1110 *error_string = formated_err;
1115 static int uidgid_config_parser_cb(
const char *path,
1120 const char **error_string,
1133 if (strcmp(path,
"uidgid.uid") == 0) {
1134 uid = uid_determine(value);
1136 *error_string = error_string_response;
1142 }
else if (strcmp(path,
"uidgid.gid") == 0) {
1143 gid = gid_determine(value);
1145 *error_string = error_string_response;
1152 *error_string =
"uidgid: Only uid and gid are allowed items";
1157 if (strcmp(path,
"uidgid") != 0) {
1158 *error_string =
"uidgid: Can't add subsection different than uidgid";
1169 static int read_uidgid_files_into_icmap(
1170 const char **error_string,
1174 const char *dirname;
1176 struct dirent *dirent;
1177 struct dirent *entry;
1178 char filename[PATH_MAX + FILENAME_MAX + 1];
1182 struct stat stat_buf;
1187 dp = opendir (dirname);
1192 len = offsetof(
struct dirent, d_name) + FILENAME_MAX + 1;
1194 entry = malloc(len);
1195 if (entry == NULL) {
1200 for (return_code = readdir_r(dp, entry, &dirent);
1201 dirent != NULL && return_code == 0;
1202 return_code = readdir_r(dp, entry, &dirent)) {
1204 snprintf(filename,
sizeof (filename),
"%s/%s", dirname, dirent->d_name);
1205 res = stat (filename, &stat_buf);
1206 if (res == 0 && S_ISREG(stat_buf.st_mode)) {
1208 fp = fopen (filename,
"r");
1209 if (fp == NULL)
continue;
1213 res = parse_section(fp, key_name, error_string, 0, state, uidgid_config_parser_cb, config_map, NULL);
1231 static int read_config_file_into_icmap(
1232 const char **error_string,
1236 const char *filename;
1237 char *error_reason = error_string_response;
1243 filename = getenv (
"COROSYNC_MAIN_CONFIG_FILE");
1247 fp = fopen (filename,
"r");
1249 char error_str[100];
1250 const char *error_ptr = qb_strerror_r(errno, error_str,
sizeof(error_str));
1251 snprintf (error_reason,
sizeof(error_string_response),
1252 "Can't read file %s reason = (%s)",
1253 filename, error_ptr);
1254 *error_string = error_reason;
1260 res = parse_section(fp, key_name, error_string, 0, state, main_config_parser_cb, config_map, &data);
1265 res = read_uidgid_files_into_icmap(error_string, config_map);
1269 snprintf (error_reason,
sizeof(error_string_response),
1270 "Successfully read main configuration file '%s'.", filename);
1271 *error_string = error_reason;
char * logging_daemon_name
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)
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)
int(* parser_cb_f)(const char *path, char *key, char *value, enum main_cp_cb_data_state *state, enum parser_cb_type type, const char **error_string, icmap_map_t config_map, void *user_data)