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 100 const char **error_string,
127 static int read_config_file_into_icmap(
128 const char **error_string,
icmap_map_t config_map);
129 static char error_string_response[512];
131 static int uid_determine (
const char *req_user)
134 struct passwd passwd;
135 struct passwd* pwdptr = &passwd;
136 struct passwd* temp_pwd_pt;
142 id = strtol(req_user, &ep, 10);
143 if (*ep ==
'\0' &&
id >= 0 &&
id <= UINT_MAX) {
147 pwdlinelen = sysconf (_SC_GETPW_R_SIZE_MAX);
149 if (pwdlinelen == -1) {
153 pwdbuffer = malloc (pwdlinelen);
155 while ((rc = getpwnam_r (req_user, pwdptr, pwdbuffer, pwdlinelen, &temp_pwd_pt)) == ERANGE) {
159 if (pwdlinelen <= 32678) {
160 n = realloc (pwdbuffer, pwdlinelen);
169 sprintf (error_string_response,
"getpwnam_r(): %s", strerror(rc));
172 if (temp_pwd_pt == NULL) {
174 sprintf (error_string_response,
175 "The '%s' user is not found in /etc/passwd, please read the documentation.",
179 pw_uid = passwd.pw_uid;
185 static int gid_determine (
const char *req_group)
187 int corosync_gid = 0;
189 struct group * grpptr = &group;
190 struct group * temp_grp_pt;
196 id = strtol(req_group, &ep, 10);
197 if (*ep ==
'\0' &&
id >= 0 &&
id <= UINT_MAX) {
201 grplinelen = sysconf (_SC_GETGR_R_SIZE_MAX);
203 if (grplinelen == -1) {
207 grpbuffer = malloc (grplinelen);
209 while ((rc = getgrnam_r (req_group, grpptr, grpbuffer, grplinelen, &temp_grp_pt)) == ERANGE) {
213 if (grplinelen <= 32678) {
214 n = realloc (grpbuffer, grplinelen);
223 sprintf (error_string_response,
"getgrnam_r(): %s", strerror(rc));
226 if (temp_grp_pt == NULL) {
228 sprintf (error_string_response,
229 "The '%s' group is not found in /etc/group, please read the documentation.",
233 corosync_gid = group.gr_gid;
238 static char *strchr_rs (
const char *haystack,
int byte)
240 const char *end_address = strchr (haystack, byte);
244 while (*end_address ==
' ' || *end_address ==
'\t')
248 return ((
char *) end_address);
253 if (read_config_file_into_icmap(error_string, config_map)) {
260 static char *remove_whitespace(
char *
string,
int remove_colon_and_brace)
266 while (*start ==
' ' || *start ==
'\t')
269 end = start+(strlen(start))-1;
270 while ((*end ==
' ' || *end ==
'\t' || (remove_colon_and_brace && (*end ==
':' || *end ==
'{'))) && end > start)
280 static int parse_section(FILE *fp,
282 const char **error_string,
295 if (strcmp(path,
"") == 0) {
296 parser_cb(
"", NULL, NULL, &state,
PARSER_CB_START, error_string, config_map, user_data);
299 while (fgets (line,
sizeof (line), fp)) {
300 if (strlen(line) > 0) {
301 if (line[strlen(line) - 1] ==
'\n')
302 line[strlen(line) - 1] =
'\0';
303 if (strlen (line) > 0 && line[strlen(line) - 1] ==
'\r')
304 line[strlen(line) - 1] =
'\0';
309 for (i = strlen (line) - 1; i > -1; i--) {
310 if (line[i] ==
'\t' || line[i] ==
' ') {
318 for (i = 0; i < strlen (line); i++) {
319 if (line[i] !=
'\t' && line[i] !=
' ') {
334 if ((loc = strchr_rs (line,
'{'))) {
335 char *section = remove_whitespace(line, 1);
342 *error_string =
"parser error: Start of section makes total cmap path too long";
345 strcpy(new_keyname, path);
346 if (strcmp(path,
"") != 0) {
347 strcat(new_keyname,
".");
349 strcat(new_keyname, section);
353 if (!parser_cb(new_keyname, NULL, NULL, &newstate,
PARSER_CB_SECTION_START, error_string, config_map, user_data)) {
357 if (parse_section(fp, new_keyname, error_string, depth + 1, newstate, parser_cb, config_map, user_data))
364 if ((loc = strchr_rs (line,
':'))) {
369 key = remove_whitespace(line, 1);
370 value = remove_whitespace(loc, 0);
373 *error_string =
"parser error: New key makes total cmap path too long";
376 strcpy(new_keyname, path);
377 if (strcmp(path,
"") != 0) {
378 strcat(new_keyname,
".");
380 strcat(new_keyname, key);
382 if (!parser_cb(new_keyname, key, value, &state,
PARSER_CB_ITEM, error_string, config_map, user_data)) {
389 if (strchr_rs (line,
'}')) {
391 *error_string =
"parser error: Unexpected closing brace";
396 if (!parser_cb(path, NULL, NULL, &state,
PARSER_CB_SECTION_END, error_string, config_map, user_data)) {
404 if (strcmp(path,
"") != 0) {
405 *error_string =
"parser error: Missing closing brace";
409 if (strcmp(path,
"") == 0) {
410 parser_cb(
"", NULL, NULL, &state,
PARSER_CB_END, error_string, config_map, user_data);
416 static int safe_atoq_range(
icmap_value_types_t value_type,
long long int *min_val,
long long int *max_val)
418 switch (value_type) {
440 long long int min_val, max_val;
445 val = strtoll(str, &endptr, 10);
446 if (errno == ERANGE) {
454 if (*endptr !=
'\0') {
458 if (safe_atoq_range(target_type, &min_val, &max_val) != 0) {
462 if (val < min_val || val > max_val) {
470 static int str_to_ull(
const char *str,
unsigned long long int *res)
472 unsigned long long int val;
477 val = strtoull(str, &endptr, 10);
478 if (errno == ERANGE) {
486 if (*endptr !=
'\0') {
494 static int main_config_parser_cb(
const char *path,
499 const char **error_string,
505 long long int min_val, max_val;
507 unsigned long long int ull;
510 static char formated_err[256];
530 if ((strcmp(path,
"pload.count") == 0) ||
531 (strcmp(path,
"pload.size") == 0)) {
533 if (safe_atoq(value, &val, val_type) != 0) {
541 if ((strcmp(path,
"quorum.expected_votes") == 0) ||
542 (strcmp(path,
"quorum.votes") == 0) ||
543 (strcmp(path,
"quorum.last_man_standing_window") == 0) ||
544 (strcmp(path,
"quorum.leaving_timeout") == 0)) {
546 if (safe_atoq(value, &val, val_type) != 0) {
553 if ((strcmp(path,
"quorum.two_node") == 0) ||
554 (strcmp(path,
"quorum.expected_votes_tracking") == 0) ||
555 (strcmp(path,
"quorum.allow_downscale") == 0) ||
556 (strcmp(path,
"quorum.wait_for_all") == 0) ||
557 (strcmp(path,
"quorum.auto_tie_breaker") == 0) ||
558 (strcmp(path,
"quorum.last_man_standing") == 0)) {
560 if (safe_atoq(value, &val, val_type) != 0) {
568 if ((strcmp(path,
"quorum.device.timeout") == 0) ||
569 (strcmp(path,
"quorum.device.sync_timeout") == 0) ||
570 (strcmp(path,
"quorum.device.votes") == 0)) {
572 if (safe_atoq(value, &val, val_type) != 0) {
578 if ((strcmp(path,
"quorum.device.master_wins") == 0)) {
580 if (safe_atoq(value, &val, val_type) != 0) {
588 if ((strcmp(path,
"totem.version") == 0) ||
589 (strcmp(path,
"totem.nodeid") == 0) ||
590 (strcmp(path,
"totem.threads") == 0) ||
591 (strcmp(path,
"totem.token") == 0) ||
592 (strcmp(path,
"totem.token_coefficient") == 0) ||
593 (strcmp(path,
"totem.token_retransmit") == 0) ||
594 (strcmp(path,
"totem.hold") == 0) ||
595 (strcmp(path,
"totem.token_retransmits_before_loss_const") == 0) ||
596 (strcmp(path,
"totem.join") == 0) ||
597 (strcmp(path,
"totem.send_join") == 0) ||
598 (strcmp(path,
"totem.consensus") == 0) ||
599 (strcmp(path,
"totem.merge") == 0) ||
600 (strcmp(path,
"totem.downcheck") == 0) ||
601 (strcmp(path,
"totem.fail_recv_const") == 0) ||
602 (strcmp(path,
"totem.seqno_unchanged_const") == 0) ||
603 (strcmp(path,
"totem.rrp_token_expired_timeout") == 0) ||
604 (strcmp(path,
"totem.rrp_problem_count_timeout") == 0) ||
605 (strcmp(path,
"totem.rrp_problem_count_threshold") == 0) ||
606 (strcmp(path,
"totem.rrp_problem_count_mcast_threshold") == 0) ||
607 (strcmp(path,
"totem.rrp_autorecovery_check_timeout") == 0) ||
608 (strcmp(path,
"totem.heartbeat_failures_allowed") == 0) ||
609 (strcmp(path,
"totem.max_network_delay") == 0) ||
610 (strcmp(path,
"totem.window_size") == 0) ||
611 (strcmp(path,
"totem.max_messages") == 0) ||
612 (strcmp(path,
"totem.miss_count_const") == 0) ||
613 (strcmp(path,
"totem.netmtu") == 0)) {
615 if (safe_atoq(value, &val, val_type) != 0) {
621 if (strcmp(path,
"totem.config_version") == 0) {
622 if (str_to_ull(value, &ull) != 0) {
628 if (strcmp(path,
"totem.ip_version") == 0) {
629 if ((strcmp(value,
"ipv4") != 0) &&
630 (strcmp(value,
"ipv6") != 0)) {
631 *error_string =
"Invalid ip_version type";
636 if (strcmp(path,
"totem.crypto_type") == 0) {
637 if ((strcmp(value,
"nss") != 0) &&
638 (strcmp(value,
"aes256") != 0) &&
639 (strcmp(value,
"aes192") != 0) &&
640 (strcmp(value,
"aes128") != 0) &&
641 (strcmp(value,
"3des") != 0)) {
642 *error_string =
"Invalid crypto type";
647 if (strcmp(path,
"totem.crypto_cipher") == 0) {
648 if ((strcmp(value,
"none") != 0) &&
649 (strcmp(value,
"aes256") != 0) &&
650 (strcmp(value,
"aes192") != 0) &&
651 (strcmp(value,
"aes128") != 0) &&
652 (strcmp(value,
"3des") != 0)) {
653 *error_string =
"Invalid cipher type";
658 if (strcmp(path,
"totem.crypto_hash") == 0) {
659 if ((strcmp(value,
"none") != 0) &&
660 (strcmp(value,
"md5") != 0) &&
661 (strcmp(value,
"sha1") != 0) &&
662 (strcmp(value,
"sha256") != 0) &&
663 (strcmp(value,
"sha384") != 0) &&
664 (strcmp(value,
"sha512") != 0)) {
665 *error_string =
"Invalid hash type";
673 if (strcmp(path,
"qb.ipc_type") == 0) {
674 if ((strcmp(value,
"native") != 0) &&
675 (strcmp(value,
"shm") != 0) &&
676 (strcmp(value,
"socket") != 0)) {
677 *error_string =
"Invalid qb ipc_type";
685 if (strcmp(path,
"totem.interface.ringnumber") == 0) {
687 if (safe_atoq(value, &val, val_type) != 0) {
694 if (strcmp(path,
"totem.interface.bindnetaddr") == 0) {
698 if (strcmp(path,
"totem.interface.mcastaddr") == 0) {
702 if (strcmp(path,
"totem.interface.broadcast") == 0) {
706 if (strcmp(path,
"totem.interface.mcastport") == 0) {
708 if (safe_atoq(value, &val, val_type) != 0) {
714 if (strcmp(path,
"totem.interface.ttl") == 0) {
716 if (safe_atoq(value, &val, val_type) != 0) {
724 if (strcmp(key,
"subsys") == 0) {
725 data->
subsys = strdup(value);
726 if (data->
subsys == NULL) {
727 *error_string =
"Can't alloc memory";
732 kv_item = malloc(
sizeof(*kv_item));
733 if (kv_item == NULL) {
734 *error_string =
"Can't alloc memory";
738 memset(kv_item, 0,
sizeof(*kv_item));
740 kv_item->
key = strdup(key);
741 kv_item->
value = strdup(value);
742 if (kv_item->
key == NULL || kv_item->
value == NULL) {
744 *error_string =
"Can't alloc memory";
748 list_init(&kv_item->
list);
754 if (strcmp(key,
"subsys") == 0) {
755 data->
subsys = strdup(value);
756 if (data->
subsys == NULL) {
757 *error_string =
"Can't alloc memory";
761 }
else if (strcmp(key,
"name") == 0) {
764 *error_string =
"Can't alloc memory";
769 kv_item = malloc(
sizeof(*kv_item));
770 if (kv_item == NULL) {
771 *error_string =
"Can't alloc memory";
775 memset(kv_item, 0,
sizeof(*kv_item));
777 kv_item->
key = strdup(key);
778 kv_item->
value = strdup(value);
779 if (kv_item->
key == NULL || kv_item->
value == NULL) {
781 *error_string =
"Can't alloc memory";
785 list_init(&kv_item->
list);
791 if (strcmp(key,
"uid") == 0) {
792 uid = uid_determine(value);
794 *error_string = error_string_response;
801 }
else if (strcmp(key,
"gid") == 0) {
802 gid = gid_determine(value);
804 *error_string = error_string_response;
812 *error_string =
"uidgid: Only uid and gid are allowed items";
817 if (strcmp(key,
"memberaddr") != 0) {
818 *error_string =
"Only memberaddr is allowed in member section";
823 kv_item = malloc(
sizeof(*kv_item));
824 if (kv_item == NULL) {
825 *error_string =
"Can't alloc memory";
829 memset(kv_item, 0,
sizeof(*kv_item));
831 kv_item->
key = strdup(key);
832 kv_item->
value = strdup(value);
833 if (kv_item->
key == NULL || kv_item->
value == NULL) {
835 *error_string =
"Can't alloc memory";
839 list_init(&kv_item->
list);
847 if ((strcmp(key,
"nodeid") == 0) ||
848 (strcmp(key,
"quorum_votes") == 0)) {
850 if (safe_atoq(value, &val, val_type) != 0) {
858 if (strcmp(key,
"ring0_addr") == 0) {
868 if (strcmp(key,
"watchdog_timeout") == 0) {
870 if (safe_atoq(value, &val, val_type) != 0) {
880 if (strcmp(key,
"poll_period") == 0) {
881 if (str_to_ull(value, &ull) != 0) {
891 if (strcmp(key,
"poll_period") == 0) {
892 if (str_to_ull(value, &ull) != 0) {
906 if (strcmp(path,
"totem.interface") == 0) {
913 if (strcmp(path,
"totem") == 0) {
916 if (strcmp(path,
"qb") == 0) {
919 if (strcmp(path,
"logging.logger_subsys") == 0) {
924 if (strcmp(path,
"logging.logging_daemon") == 0) {
930 if (strcmp(path,
"uidgid") == 0) {
933 if (strcmp(path,
"totem.interface.member") == 0) {
936 if (strcmp(path,
"quorum") == 0) {
939 if (strcmp(path,
"quorum.device") == 0) {
942 if (strcmp(path,
"nodelist") == 0) {
946 if (strcmp(path,
"nodelist.node") == 0) {
950 if (strcmp(path,
"resources") == 0) {
953 if (strcmp(path,
"resources.system") == 0) {
956 if (strcmp(path,
"resources.system.memory_used") == 0) {
959 if (strcmp(path,
"resources.process") == 0) {
962 if (strcmp(path,
"resources.process.memory_used") == 0) {
1005 if (data->
ttl > -1) {
1020 iter_next = iter->
next;
1022 free(kv_item->
value);
1030 if (data->
subsys == NULL) {
1031 *error_string =
"No subsys key in logger_subsys directive";
1044 iter_next = iter->
next;
1046 free(kv_item->
value);
1060 *error_string =
"No name key in logging_daemon directive";
1069 if (data->
subsys == NULL) {
1076 "logging.logging_daemon.%s.%s",
1082 "logging.logger_subsys.%s.%s",
1087 "logging.logging_daemon.%s.%s.%s",
1094 iter_next = iter->
next;
1096 free(kv_item->
value);
1101 if (data->
subsys == NULL) {
1129 *error_string =
"No ring0_addr specified for node";
1167 min_val = max_val = 0;
1172 assert(safe_atoq_range(val_type, &min_val, &max_val) == 0);
1174 snprintf(formated_err,
sizeof(formated_err),
1175 "Value of key \"%s\" is expected to be integer in range (%lld..%lld), but \"%s\" was given",
1176 key, min_val, max_val, value);
1177 *error_string = formated_err;
1182 static int uidgid_config_parser_cb(
const char *path,
1187 const char **error_string,
1200 if (strcmp(path,
"uidgid.uid") == 0) {
1201 uid = uid_determine(value);
1203 *error_string = error_string_response;
1209 }
else if (strcmp(path,
"uidgid.gid") == 0) {
1210 gid = gid_determine(value);
1212 *error_string = error_string_response;
1219 *error_string =
"uidgid: Only uid and gid are allowed items";
1224 if (strcmp(path,
"uidgid") != 0) {
1225 *error_string =
"uidgid: Can't add subsection different than uidgid";
1236 static int read_uidgid_files_into_icmap(
1237 const char **error_string,
1241 const char *dirname;
1243 struct dirent *dirent;
1244 struct dirent *entry;
1245 char filename[PATH_MAX + FILENAME_MAX + 1];
1249 struct stat stat_buf;
1254 dp = opendir (dirname);
1259 len = offsetof(
struct dirent, d_name) + FILENAME_MAX + 1;
1261 entry = malloc(len);
1262 if (entry == NULL) {
1267 for (return_code = readdir_r(dp, entry, &dirent);
1268 dirent != NULL && return_code == 0;
1269 return_code = readdir_r(dp, entry, &dirent)) {
1271 snprintf(filename,
sizeof (filename),
"%s/%s", dirname, dirent->d_name);
1272 res = stat (filename, &stat_buf);
1273 if (res == 0 && S_ISREG(stat_buf.st_mode)) {
1275 fp = fopen (filename,
"r");
1276 if (fp == NULL)
continue;
1280 res = parse_section(fp, key_name, error_string, 0, state, uidgid_config_parser_cb, config_map, NULL);
1298 static int read_config_file_into_icmap(
1299 const char **error_string,
1303 const char *filename;
1304 char *error_reason = error_string_response;
1310 filename = getenv (
"COROSYNC_MAIN_CONFIG_FILE");
1314 fp = fopen (filename,
"r");
1316 char error_str[100];
1317 const char *error_ptr = qb_strerror_r(errno, error_str,
sizeof(error_str));
1318 snprintf (error_reason,
sizeof(error_string_response),
1319 "Can't read file %s reason = (%s)",
1320 filename, error_ptr);
1321 *error_string = error_reason;
1327 res = parse_section(fp, key_name, error_string, 0, state, main_config_parser_cb, config_map, &data);
1332 res = read_uidgid_files_into_icmap(error_string, config_map);
1336 snprintf (error_reason,
sizeof(error_string_response),
1337 "Successfully read main configuration file '%s'.", filename);
1338 *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
Maximum length of key in icmap.
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)
icmap_value_types_t
Possible types of value.