2 * Copyright (c) 2006-2018 Red Hat, Inc.
6 * Author: Patrick Caulfield (pcaulfie@redhat.com)
7 * Jan Friesse (jfriesse@redhat.com)
9 * This software licensed under BSD license, the text of which follows:
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
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.
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.
38 #include <sys/types.h>
40 #include <sys/socket.h>
43 #include <netinet/in.h>
44 #include <arpa/inet.h>
58 #include <qb/qblist.h>
59 #include <qb/qbutil.h>
60 #define LOGSYS_UTILS_ONLY 1
61 #include <corosync/logsys.h>
62 #include <corosync/icmap.h>
70 PARSER_CB_SECTION_START
,
71 PARSER_CB_SECTION_END
,
75 enum main_cp_cb_data_state
{
76 MAIN_CP_CB_DATA_STATE_NORMAL
,
77 MAIN_CP_CB_DATA_STATE_TOTEM
,
78 MAIN_CP_CB_DATA_STATE_INTERFACE
,
79 MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS
,
80 MAIN_CP_CB_DATA_STATE_UIDGID
,
81 MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON
,
82 MAIN_CP_CB_DATA_STATE_MEMBER
,
83 MAIN_CP_CB_DATA_STATE_QUORUM
,
84 MAIN_CP_CB_DATA_STATE_QDEVICE
,
85 MAIN_CP_CB_DATA_STATE_NODELIST
,
86 MAIN_CP_CB_DATA_STATE_NODELIST_NODE
,
87 MAIN_CP_CB_DATA_STATE_PLOAD
,
88 MAIN_CP_CB_DATA_STATE_SYSTEM
,
89 MAIN_CP_CB_DATA_STATE_RESOURCES
,
90 MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM
,
91 MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS
,
92 MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_MEMUSED
,
93 MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED
96 typedef int (*parser_cb_f
)(const char *path
,
99 enum main_cp_cb_data_state
*state
,
100 enum parser_cb_type type
,
101 const char **error_string
,
102 icmap_map_t config_map
,
105 struct key_value_list_item
{
108 struct qb_list_head list
;
111 struct main_cp_cb_data
{
118 int knet_link_priority
;
119 int knet_ping_interval
;
120 int knet_ping_timeout
;
121 int knet_ping_precision
;
123 int knet_pmtud_interval
;
124 char *knet_transport
;
126 struct qb_list_head logger_subsys_items_head
;
128 char *logging_daemon_name
;
129 struct qb_list_head member_items_head
;
134 static int read_config_file_into_icmap(
135 const char **error_string
, icmap_map_t config_map
);
136 static char error_string_response
[512];
138 static int uid_determine (const char *req_user
)
141 struct passwd passwd
;
142 struct passwd
* pwdptr
= &passwd
;
143 struct passwd
* temp_pwd_pt
;
149 id
= strtol(req_user
, &ep
, 10);
150 if (*req_user
!= '\0' && *ep
== '\0' && id
>= 0 && id
<= UINT_MAX
) {
154 pwdlinelen
= sysconf (_SC_GETPW_R_SIZE_MAX
);
156 if (pwdlinelen
== -1) {
160 pwdbuffer
= malloc (pwdlinelen
);
162 while ((rc
= getpwnam_r (req_user
, pwdptr
, pwdbuffer
, pwdlinelen
, &temp_pwd_pt
)) == ERANGE
) {
166 if (pwdlinelen
<= 32678) {
167 n
= realloc (pwdbuffer
, pwdlinelen
);
176 sprintf (error_string_response
, "getpwnam_r(): %s", strerror(rc
));
179 if (temp_pwd_pt
== NULL
) {
181 sprintf (error_string_response
,
182 "The '%s' user is not found in /etc/passwd, please read the documentation.",
186 pw_uid
= passwd
.pw_uid
;
192 static int gid_determine (const char *req_group
)
194 int corosync_gid
= 0;
196 struct group
* grpptr
= &group
;
197 struct group
* temp_grp_pt
;
203 id
= strtol(req_group
, &ep
, 10);
204 if (*req_group
!= '\0' && *ep
== '\0' && id
>= 0 && id
<= UINT_MAX
) {
208 grplinelen
= sysconf (_SC_GETGR_R_SIZE_MAX
);
210 if (grplinelen
== -1) {
214 grpbuffer
= malloc (grplinelen
);
216 while ((rc
= getgrnam_r (req_group
, grpptr
, grpbuffer
, grplinelen
, &temp_grp_pt
)) == ERANGE
) {
220 if (grplinelen
<= 32678) {
221 n
= realloc (grpbuffer
, grplinelen
);
230 sprintf (error_string_response
, "getgrnam_r(): %s", strerror(rc
));
233 if (temp_grp_pt
== NULL
) {
235 sprintf (error_string_response
,
236 "The '%s' group is not found in /etc/group, please read the documentation.",
240 corosync_gid
= group
.gr_gid
;
245 static char *strchr_rs (const char *haystack
, int byte
)
247 const char *end_address
= strchr (haystack
, byte
);
249 end_address
+= 1; /* skip past { or = */
251 while (*end_address
== ' ' || *end_address
== '\t')
255 return ((char *) end_address
);
258 int coroparse_configparse (icmap_map_t config_map
, const char **error_string
)
260 if (read_config_file_into_icmap(error_string
, config_map
)) {
267 static char *remove_whitespace(char *string
, int remove_colon_and_brace
)
273 while (*start
== ' ' || *start
== '\t')
276 end
= start
+(strlen(start
))-1;
277 while ((*end
== ' ' || *end
== '\t' || (remove_colon_and_brace
&& (*end
== ':' || *end
== '{'))) && end
> start
)
287 static int parse_section(FILE *fp
,
291 const char **error_string
,
293 enum main_cp_cb_data_state state
,
294 parser_cb_f parser_cb
,
295 icmap_map_t config_map
,
302 char new_keyname
[ICMAP_KEYNAME_MAXLEN
];
303 static char formated_err
[384];
304 const char *tmp_error_string
;
306 if (strcmp(path
, "") == 0) {
307 parser_cb("", NULL
, NULL
, &state
, PARSER_CB_START
, error_string
, config_map
, user_data
);
310 tmp_error_string
= NULL
;
312 while (fgets (line
, sizeof (line
), fp
)) {
315 if (strlen(line
) > 0) {
317 * Check if complete line was read. Use feof to handle files
318 * without ending \n at the end of the file
320 if ((line
[strlen(line
) - 1] != '\n') && !feof(fp
)) {
321 tmp_error_string
= "Line too long";
325 if (line
[strlen(line
) - 1] == '\n')
326 line
[strlen(line
) - 1] = '\0';
327 if (strlen (line
) > 0 && line
[strlen(line
) - 1] == '\r')
328 line
[strlen(line
) - 1] = '\0';
331 * Clear out white space and tabs
333 for (i
= strlen (line
) - 1; i
> -1; i
--) {
334 if (line
[i
] == '\t' || line
[i
] == ' ') {
342 for (i
= 0; i
< strlen (line
); i
++) {
343 if (line
[i
] != '\t' && line
[i
] != ' ') {
351 * Clear out comments and empty lines
358 if ((loc
= strchr_rs (line
, '{'))) {
361 enum main_cp_cb_data_state newstate
;
364 section
= remove_whitespace(line
, 1);
365 after_section
= remove_whitespace(loc
, 0);
367 if (strcmp(section
, "") == 0) {
368 tmp_error_string
= "Missing section name before opening bracket '{'";
372 if (strcmp(after_section
, "") != 0) {
373 tmp_error_string
= "Extra characters after opening bracket '{'";
377 if (strlen(path
) + strlen(section
) + 1 >= ICMAP_KEYNAME_MAXLEN
) {
378 tmp_error_string
= "Start of section makes total cmap path too long";
381 strcpy(new_keyname
, path
);
382 if (strcmp(path
, "") != 0) {
383 strcat(new_keyname
, ".");
385 strcat(new_keyname
, section
);
387 /* Only use the new state for items further down the stack */
389 if (!parser_cb(new_keyname
, NULL
, NULL
, &newstate
, PARSER_CB_SECTION_START
,
390 &tmp_error_string
, config_map
, user_data
)) {
394 if (parse_section(fp
, fname
, line_no
, new_keyname
, error_string
, depth
+ 1, newstate
,
395 parser_cb
, config_map
, user_data
))
402 if ((loc
= strchr_rs (line
, ':'))) {
407 key
= remove_whitespace(line
, 1);
408 value
= remove_whitespace(loc
, 0);
410 if (strlen(path
) + strlen(key
) + 1 >= ICMAP_KEYNAME_MAXLEN
) {
411 tmp_error_string
= "New key makes total cmap path too long";
414 strcpy(new_keyname
, path
);
415 if (strcmp(path
, "") != 0) {
416 strcat(new_keyname
, ".");
418 strcat(new_keyname
, key
);
420 if (!parser_cb(new_keyname
, key
, value
, &state
, PARSER_CB_ITEM
, &tmp_error_string
,
421 config_map
, user_data
)) {
428 if (strchr_rs (line
, '}')) {
430 trimmed_line
= remove_whitespace(line
, 0);
432 if (strcmp(trimmed_line
, "}") != 0) {
433 tmp_error_string
= "Extra characters before or after closing bracket '}'";
438 tmp_error_string
= "Unexpected closing brace";
443 if (!parser_cb(path
, NULL
, NULL
, &state
, PARSER_CB_SECTION_END
, &tmp_error_string
,
444 config_map
, user_data
)) {
452 * Line is not opening section, ending section or value -> error
454 tmp_error_string
= "Line is not opening or closing section or key value";
458 if (strcmp(path
, "") != 0) {
459 tmp_error_string
= "Missing closing brace";
463 if (strcmp(path
, "") == 0) {
464 parser_cb("", NULL
, NULL
, &state
, PARSER_CB_END
, error_string
, config_map
, user_data
);
470 if (snprintf(formated_err
, sizeof(formated_err
), "parser error: %s:%u: %s", fname
, *line_no
,
471 tmp_error_string
) >= sizeof(formated_err
)) {
472 *error_string
= "Can't format parser error message";
474 *error_string
= formated_err
;
480 static int safe_atoq_range(icmap_value_types_t value_type
, long long int *min_val
, long long int *max_val
)
482 switch (value_type
) {
483 case ICMAP_VALUETYPE_INT8
: *min_val
= INT8_MIN
; *max_val
= INT8_MAX
; break;
484 case ICMAP_VALUETYPE_UINT8
: *min_val
= 0; *max_val
= UINT8_MAX
; break;
485 case ICMAP_VALUETYPE_INT16
: *min_val
= INT16_MIN
; *max_val
= INT16_MAX
; break;
486 case ICMAP_VALUETYPE_UINT16
: *min_val
= 0; *max_val
= UINT16_MAX
; break;
487 case ICMAP_VALUETYPE_INT32
: *min_val
= INT32_MIN
; *max_val
= INT32_MAX
; break;
488 case ICMAP_VALUETYPE_UINT32
: *min_val
= 0; *max_val
= UINT32_MAX
; break;
497 * Convert string str to long long int res. Type of result is target_type and currently only
498 * ICMAP_VALUETYPE_[U]INT[8|16|32] is supported.
499 * Return 0 on success, -1 on failure.
501 static int safe_atoq(const char *str
, long long int *res
, icmap_value_types_t target_type
)
504 long long int min_val
, max_val
;
509 val
= strtoll(str
, &endptr
, 10);
510 if (errno
== ERANGE
) {
518 if (*endptr
!= '\0') {
522 if (safe_atoq_range(target_type
, &min_val
, &max_val
) != 0) {
526 if (val
< min_val
|| val
> max_val
) {
534 static int str_to_ull(const char *str
, unsigned long long int *res
)
536 unsigned long long int val
;
541 val
= strtoull(str
, &endptr
, 10);
542 if (errno
== ERANGE
) {
550 if (*endptr
!= '\0') {
558 static int main_config_parser_cb(const char *path
,
561 enum main_cp_cb_data_state
*state
,
562 enum parser_cb_type type
,
563 const char **error_string
,
564 icmap_map_t config_map
,
569 long long int min_val
, max_val
;
570 icmap_value_types_t val_type
= ICMAP_VALUETYPE_BINARY
;
571 unsigned long long int ull
;
573 char key_name
[ICMAP_KEYNAME_MAXLEN
+ 1];
574 static char formated_err
[256];
575 struct main_cp_cb_data
*data
= (struct main_cp_cb_data
*)user_data
;
576 struct key_value_list_item
*kv_item
;
577 struct qb_list_head
*iter
, *tmp_iter
;
584 * Formally this check is not needed because length is checked by parse_section
586 if (strlen(path
) >= sizeof(key_name
)) {
587 if (snprintf(formated_err
, sizeof(formated_err
),
588 "Can't store path \"%s\" into key_name", path
) >= sizeof(formated_err
)) {
589 *error_string
= "Can't format path into key_name error message";
591 *error_string
= formated_err
;
596 * Key_name is used in atoi_error/icmap_set_error, but many of icmap_set*
597 * are using path, so initialize key_name to valid value
599 strncpy(key_name
, path
, sizeof(key_name
));
602 case PARSER_CB_START
:
603 memset(data
, 0, sizeof(struct main_cp_cb_data
));
604 *state
= MAIN_CP_CB_DATA_STATE_NORMAL
;
612 case MAIN_CP_CB_DATA_STATE_NORMAL
:
614 case MAIN_CP_CB_DATA_STATE_PLOAD
:
615 if ((strcmp(path
, "pload.count") == 0) ||
616 (strcmp(path
, "pload.size") == 0)) {
617 val_type
= ICMAP_VALUETYPE_UINT32
;
618 if (safe_atoq(value
, &val
, val_type
) != 0) {
621 if ((cs_err
= icmap_set_uint32_r(config_map
, path
, val
)) != CS_OK
) {
622 goto icmap_set_error
;
627 case MAIN_CP_CB_DATA_STATE_QUORUM
:
628 if ((strcmp(path
, "quorum.expected_votes") == 0) ||
629 (strcmp(path
, "quorum.votes") == 0) ||
630 (strcmp(path
, "quorum.last_man_standing_window") == 0) ||
631 (strcmp(path
, "quorum.leaving_timeout") == 0)) {
632 val_type
= ICMAP_VALUETYPE_UINT32
;
633 if (safe_atoq(value
, &val
, val_type
) != 0) {
636 if ((cs_err
= icmap_set_uint32_r(config_map
, path
, val
)) != CS_OK
) {
637 goto icmap_set_error
;
642 if ((strcmp(path
, "quorum.two_node") == 0) ||
643 (strcmp(path
, "quorum.expected_votes_tracking") == 0) ||
644 (strcmp(path
, "quorum.allow_downscale") == 0) ||
645 (strcmp(path
, "quorum.wait_for_all") == 0) ||
646 (strcmp(path
, "quorum.auto_tie_breaker") == 0) ||
647 (strcmp(path
, "quorum.last_man_standing") == 0)) {
648 val_type
= ICMAP_VALUETYPE_UINT8
;
649 if (safe_atoq(value
, &val
, val_type
) != 0) {
652 if ((cs_err
= icmap_set_uint8_r(config_map
, path
, val
)) != CS_OK
) {
653 goto icmap_set_error
;
658 case MAIN_CP_CB_DATA_STATE_QDEVICE
:
659 if ((strcmp(path
, "quorum.device.timeout") == 0) ||
660 (strcmp(path
, "quorum.device.sync_timeout") == 0) ||
661 (strcmp(path
, "quorum.device.votes") == 0)) {
662 val_type
= ICMAP_VALUETYPE_UINT32
;
663 if (safe_atoq(value
, &val
, val_type
) != 0) {
666 if ((cs_err
= icmap_set_uint32_r(config_map
, path
, val
)) != CS_OK
) {
667 goto icmap_set_error
;
671 if ((strcmp(path
, "quorum.device.master_wins") == 0)) {
672 val_type
= ICMAP_VALUETYPE_UINT8
;
673 if (safe_atoq(value
, &val
, val_type
) != 0) {
676 if ((cs_err
= icmap_set_uint8_r(config_map
, path
, val
)) != CS_OK
) {
677 goto icmap_set_error
;
682 case MAIN_CP_CB_DATA_STATE_TOTEM
:
683 if ((strcmp(path
, "totem.version") == 0) ||
684 (strcmp(path
, "totem.nodeid") == 0) ||
685 (strcmp(path
, "totem.threads") == 0) ||
686 (strcmp(path
, "totem.token") == 0) ||
687 (strcmp(path
, "totem.token_coefficient") == 0) ||
688 (strcmp(path
, "totem.token_retransmit") == 0) ||
689 (strcmp(path
, "totem.token_warning") == 0) ||
690 (strcmp(path
, "totem.hold") == 0) ||
691 (strcmp(path
, "totem.token_retransmits_before_loss_const") == 0) ||
692 (strcmp(path
, "totem.join") == 0) ||
693 (strcmp(path
, "totem.send_join") == 0) ||
694 (strcmp(path
, "totem.consensus") == 0) ||
695 (strcmp(path
, "totem.merge") == 0) ||
696 (strcmp(path
, "totem.downcheck") == 0) ||
697 (strcmp(path
, "totem.fail_recv_const") == 0) ||
698 (strcmp(path
, "totem.seqno_unchanged_const") == 0) ||
699 (strcmp(path
, "totem.rrp_token_expired_timeout") == 0) ||
700 (strcmp(path
, "totem.rrp_problem_count_timeout") == 0) ||
701 (strcmp(path
, "totem.rrp_problem_count_threshold") == 0) ||
702 (strcmp(path
, "totem.rrp_problem_count_mcast_threshold") == 0) ||
703 (strcmp(path
, "totem.rrp_autorecovery_check_timeout") == 0) ||
704 (strcmp(path
, "totem.heartbeat_failures_allowed") == 0) ||
705 (strcmp(path
, "totem.max_network_delay") == 0) ||
706 (strcmp(path
, "totem.window_size") == 0) ||
707 (strcmp(path
, "totem.max_messages") == 0) ||
708 (strcmp(path
, "totem.miss_count_const") == 0) ||
709 (strcmp(path
, "totem.knet_pmtud_interval") == 0) ||
710 (strcmp(path
, "totem.knet_compression_threshold") == 0) ||
711 (strcmp(path
, "totem.netmtu") == 0)) {
712 val_type
= ICMAP_VALUETYPE_UINT32
;
713 if (safe_atoq(value
, &val
, val_type
) != 0) {
716 if ((cs_err
= icmap_set_uint32_r(config_map
,path
, val
)) != CS_OK
) {
717 goto icmap_set_error
;
721 if (strcmp(path
, "totem.knet_compression_level") == 0) {
722 val_type
= ICMAP_VALUETYPE_INT32
;
723 if (safe_atoq(value
, &val
, val_type
) != 0) {
726 if ((cs_err
= icmap_set_int32_r(config_map
, path
, val
)) != CS_OK
) {
727 goto icmap_set_error
;
731 if (strcmp(path
, "totem.config_version") == 0) {
732 if (str_to_ull(value
, &ull
) != 0) {
735 if ((cs_err
= icmap_set_uint64_r(config_map
, path
, ull
)) != CS_OK
) {
736 goto icmap_set_error
;
740 if (strcmp(path
, "totem.ip_version") == 0) {
741 if ((strcmp(value
, "ipv4") != 0) &&
742 (strcmp(value
, "ipv6") != 0)) {
743 *error_string
= "Invalid ip_version type";
748 if (strcmp(path
, "totem.crypto_type") == 0) {
749 if ((strcmp(value
, "nss") != 0) &&
750 (strcmp(value
, "aes256") != 0) &&
751 (strcmp(value
, "aes192") != 0) &&
752 (strcmp(value
, "aes128") != 0) &&
753 (strcmp(value
, "3des") != 0)) {
754 *error_string
= "Invalid crypto type";
759 if (strcmp(path
, "totem.crypto_cipher") == 0) {
760 if ((strcmp(value
, "none") != 0) &&
761 (strcmp(value
, "aes256") != 0) &&
762 (strcmp(value
, "aes192") != 0) &&
763 (strcmp(value
, "aes128") != 0) &&
764 (strcmp(value
, "3des") != 0)) {
765 *error_string
= "Invalid cipher type";
770 if (strcmp(path
, "totem.crypto_hash") == 0) {
771 if ((strcmp(value
, "none") != 0) &&
772 (strcmp(value
, "md5") != 0) &&
773 (strcmp(value
, "sha1") != 0) &&
774 (strcmp(value
, "sha256") != 0) &&
775 (strcmp(value
, "sha384") != 0) &&
776 (strcmp(value
, "sha512") != 0)) {
777 *error_string
= "Invalid hash type";
784 case MAIN_CP_CB_DATA_STATE_SYSTEM
:
785 if (strcmp(path
, "system.qb_ipc_type") == 0) {
786 if ((strcmp(value
, "native") != 0) &&
787 (strcmp(value
, "shm") != 0) &&
788 (strcmp(value
, "socket") != 0)) {
789 *error_string
= "Invalid system.qb_ipc_type";
794 if (strcmp(path
, "system.sched_rr") == 0) {
795 if ((strcmp(value
, "yes") != 0) &&
796 (strcmp(value
, "no") != 0)) {
797 *error_string
= "Invalid system.sched_rr value";
802 if (strcmp(path
, "system.move_to_root_cgroup") == 0) {
803 if ((strcmp(value
, "yes") != 0) &&
804 (strcmp(value
, "no") != 0)) {
805 *error_string
= "Invalid system.move_to_root_cgroup";
812 case MAIN_CP_CB_DATA_STATE_INTERFACE
:
813 if (strcmp(path
, "totem.interface.linknumber") == 0) {
814 val_type
= ICMAP_VALUETYPE_UINT8
;
815 if (safe_atoq(value
, &val
, val_type
) != 0) {
819 data
->linknumber
= val
;
822 if (strcmp(path
, "totem.interface.bindnetaddr") == 0) {
823 data
->bindnetaddr
= strdup(value
);
826 if (strcmp(path
, "totem.interface.mcastaddr") == 0) {
827 data
->mcastaddr
= strdup(value
);
830 if (strcmp(path
, "totem.interface.broadcast") == 0) {
831 data
->broadcast
= strdup(value
);
834 if (strcmp(path
, "totem.interface.mcastport") == 0) {
835 val_type
= ICMAP_VALUETYPE_UINT16
;
836 if (safe_atoq(value
, &val
, val_type
) != 0) {
839 data
->mcastport
= val
;
842 if (strcmp(path
, "totem.interface.ttl") == 0) {
843 val_type
= ICMAP_VALUETYPE_UINT8
;
844 if (safe_atoq(value
, &val
, val_type
) != 0) {
850 if (strcmp(path
, "totem.interface.knet_link_priority") == 0) {
851 val_type
= ICMAP_VALUETYPE_UINT8
;
852 if (safe_atoq(value
, &val
, val_type
) != 0) {
855 data
->knet_link_priority
= val
;
858 if (strcmp(path
, "totem.interface.knet_ping_interval") == 0) {
859 val_type
= ICMAP_VALUETYPE_UINT32
;
860 if (safe_atoq(value
, &val
, val_type
) != 0) {
863 data
->knet_ping_interval
= val
;
866 if (strcmp(path
, "totem.interface.knet_ping_timeout") == 0) {
867 val_type
= ICMAP_VALUETYPE_UINT32
;
868 if (safe_atoq(value
, &val
, val_type
) != 0) {
871 data
->knet_ping_timeout
= val
;
874 if (strcmp(path
, "totem.interface.knet_ping_precision") == 0) {
875 val_type
= ICMAP_VALUETYPE_UINT32
;
876 if (safe_atoq(value
, &val
, val_type
) != 0) {
879 data
->knet_ping_precision
= val
;
882 if (strcmp(path
, "totem.interface.knet_pong_count") == 0) {
883 val_type
= ICMAP_VALUETYPE_UINT32
;
884 if (safe_atoq(value
, &val
, val_type
) != 0) {
887 data
->knet_pong_count
= val
;
890 if (strcmp(path
, "totem.interface.knet_transport") == 0) {
891 val_type
= ICMAP_VALUETYPE_STRING
;
892 data
->knet_transport
= strdup(value
);
896 case MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS
:
897 if (strcmp(key
, "subsys") == 0) {
898 data
->subsys
= strdup(value
);
899 if (data
->subsys
== NULL
) {
900 *error_string
= "Can't alloc memory";
905 kv_item
= malloc(sizeof(*kv_item
));
906 if (kv_item
== NULL
) {
907 *error_string
= "Can't alloc memory";
911 memset(kv_item
, 0, sizeof(*kv_item
));
913 kv_item
->key
= strdup(key
);
914 kv_item
->value
= strdup(value
);
915 if (kv_item
->key
== NULL
|| kv_item
->value
== NULL
) {
917 *error_string
= "Can't alloc memory";
921 qb_list_init(&kv_item
->list
);
922 qb_list_add(&kv_item
->list
, &data
->logger_subsys_items_head
);
926 case MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON
:
927 if (strcmp(key
, "subsys") == 0) {
928 data
->subsys
= strdup(value
);
929 if (data
->subsys
== NULL
) {
930 *error_string
= "Can't alloc memory";
934 } else if (strcmp(key
, "name") == 0) {
935 data
->logging_daemon_name
= strdup(value
);
936 if (data
->logging_daemon_name
== NULL
) {
937 *error_string
= "Can't alloc memory";
942 kv_item
= malloc(sizeof(*kv_item
));
943 if (kv_item
== NULL
) {
944 *error_string
= "Can't alloc memory";
948 memset(kv_item
, 0, sizeof(*kv_item
));
950 kv_item
->key
= strdup(key
);
951 kv_item
->value
= strdup(value
);
952 if (kv_item
->key
== NULL
|| kv_item
->value
== NULL
) {
954 *error_string
= "Can't alloc memory";
958 qb_list_init(&kv_item
->list
);
959 qb_list_add(&kv_item
->list
, &data
->logger_subsys_items_head
);
963 case MAIN_CP_CB_DATA_STATE_UIDGID
:
964 if (strcmp(key
, "uid") == 0) {
965 uid
= uid_determine(value
);
967 *error_string
= error_string_response
;
970 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "uidgid.config.uid.%u",
972 if ((cs_err
= icmap_set_uint8_r(config_map
, key_name
, 1)) != CS_OK
) {
973 goto icmap_set_error
;
976 } else if (strcmp(key
, "gid") == 0) {
977 gid
= gid_determine(value
);
979 *error_string
= error_string_response
;
982 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "uidgid.config.gid.%u",
984 if ((cs_err
= icmap_set_uint8_r(config_map
, key_name
, 1)) != CS_OK
) {
985 goto icmap_set_error
;
989 *error_string
= "uidgid: Only uid and gid are allowed items";
993 case MAIN_CP_CB_DATA_STATE_MEMBER
:
994 if (strcmp(key
, "memberaddr") != 0) {
995 *error_string
= "Only memberaddr is allowed in member section";
1000 kv_item
= malloc(sizeof(*kv_item
));
1001 if (kv_item
== NULL
) {
1002 *error_string
= "Can't alloc memory";
1006 memset(kv_item
, 0, sizeof(*kv_item
));
1008 kv_item
->key
= strdup(key
);
1009 kv_item
->value
= strdup(value
);
1010 if (kv_item
->key
== NULL
|| kv_item
->value
== NULL
) {
1012 *error_string
= "Can't alloc memory";
1016 qb_list_init(&kv_item
->list
);
1017 qb_list_add(&kv_item
->list
, &data
->member_items_head
);
1020 case MAIN_CP_CB_DATA_STATE_NODELIST
:
1022 case MAIN_CP_CB_DATA_STATE_NODELIST_NODE
:
1023 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "nodelist.node.%u.%s", data
->node_number
, key
);
1024 if ((strcmp(key
, "nodeid") == 0) ||
1025 (strcmp(key
, "quorum_votes") == 0)) {
1026 val_type
= ICMAP_VALUETYPE_UINT32
;
1027 if (safe_atoq(value
, &val
, val_type
) != 0) {
1031 if ((cs_err
= icmap_set_uint32_r(config_map
, key_name
, val
)) != CS_OK
) {
1032 goto icmap_set_error
;
1037 if (add_as_string
) {
1038 if ((cs_err
= icmap_set_string_r(config_map
, key_name
, value
)) != CS_OK
) {
1039 goto icmap_set_error
;
1044 case MAIN_CP_CB_DATA_STATE_RESOURCES
:
1045 if (strcmp(key
, "watchdog_timeout") == 0) {
1046 val_type
= ICMAP_VALUETYPE_UINT32
;
1047 if (safe_atoq(value
, &val
, val_type
) != 0) {
1050 if ((cs_err
= icmap_set_uint32_r(config_map
,path
, val
)) != CS_OK
) {
1051 goto icmap_set_error
;
1056 case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM
:
1057 case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_MEMUSED
:
1058 if (strcmp(key
, "poll_period") == 0) {
1059 if (str_to_ull(value
, &ull
) != 0) {
1062 if ((cs_err
= icmap_set_uint64_r(config_map
,path
, ull
)) != CS_OK
) {
1063 goto icmap_set_error
;
1068 case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS
:
1069 case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED
:
1070 if (strcmp(key
, "poll_period") == 0) {
1071 if (str_to_ull(value
, &ull
) != 0) {
1074 if ((cs_err
= icmap_set_uint64_r(config_map
,path
, ull
)) != CS_OK
) {
1075 goto icmap_set_error
;
1082 if (add_as_string
) {
1083 if ((cs_err
= icmap_set_string_r(config_map
, path
, value
)) != CS_OK
) {
1084 goto icmap_set_error
;
1088 case PARSER_CB_SECTION_START
:
1089 if (strcmp(path
, "totem.interface") == 0) {
1090 *state
= MAIN_CP_CB_DATA_STATE_INTERFACE
;
1091 data
->linknumber
= 0;
1092 data
->mcastport
= -1;
1094 data
->knet_link_priority
= -1;
1095 data
->knet_ping_interval
= -1;
1096 data
->knet_ping_timeout
= -1;
1097 data
->knet_ping_precision
= -1;
1098 data
->knet_pong_count
= -1;
1099 data
->knet_transport
= NULL
;
1100 qb_list_init(&data
->member_items_head
);
1102 if (strcmp(path
, "totem") == 0) {
1103 *state
= MAIN_CP_CB_DATA_STATE_TOTEM
;
1105 if (strcmp(path
, "system") == 0) {
1106 *state
= MAIN_CP_CB_DATA_STATE_SYSTEM
;
1108 if (strcmp(path
, "logging.logger_subsys") == 0) {
1109 *state
= MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS
;
1110 qb_list_init(&data
->logger_subsys_items_head
);
1111 data
->subsys
= NULL
;
1113 if (strcmp(path
, "logging.logging_daemon") == 0) {
1114 *state
= MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON
;
1115 qb_list_init(&data
->logger_subsys_items_head
);
1116 data
->subsys
= NULL
;
1117 data
->logging_daemon_name
= NULL
;
1119 if (strcmp(path
, "uidgid") == 0) {
1120 *state
= MAIN_CP_CB_DATA_STATE_UIDGID
;
1122 if (strcmp(path
, "totem.interface.member") == 0) {
1123 *state
= MAIN_CP_CB_DATA_STATE_MEMBER
;
1125 if (strcmp(path
, "quorum") == 0) {
1126 *state
= MAIN_CP_CB_DATA_STATE_QUORUM
;
1128 if (strcmp(path
, "quorum.device") == 0) {
1129 *state
= MAIN_CP_CB_DATA_STATE_QDEVICE
;
1131 if (strcmp(path
, "nodelist") == 0) {
1132 *state
= MAIN_CP_CB_DATA_STATE_NODELIST
;
1133 data
->node_number
= 0;
1135 if (strcmp(path
, "nodelist.node") == 0) {
1136 *state
= MAIN_CP_CB_DATA_STATE_NODELIST_NODE
;
1138 if (strcmp(path
, "resources") == 0) {
1139 *state
= MAIN_CP_CB_DATA_STATE_RESOURCES
;
1141 if (strcmp(path
, "resources.system") == 0) {
1142 *state
= MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM
;
1144 if (strcmp(path
, "resources.system.memory_used") == 0) {
1145 *state
= MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_MEMUSED
;
1147 if (strcmp(path
, "resources.process") == 0) {
1148 *state
= MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS
;
1150 if (strcmp(path
, "resources.process.memory_used") == 0) {
1151 *state
= MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED
;
1154 case PARSER_CB_SECTION_END
:
1156 case MAIN_CP_CB_DATA_STATE_INTERFACE
:
1158 * Create new interface section
1160 if (data
->bindnetaddr
!= NULL
) {
1161 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "totem.interface.%u.bindnetaddr",
1163 cs_err
= icmap_set_string_r(config_map
, key_name
, data
->bindnetaddr
);
1165 free(data
->bindnetaddr
);
1166 data
->bindnetaddr
= NULL
;
1168 if (cs_err
!= CS_OK
) {
1169 goto icmap_set_error
;
1173 if (data
->mcastaddr
!= NULL
) {
1174 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "totem.interface.%u.mcastaddr",
1176 cs_err
= icmap_set_string_r(config_map
, key_name
, data
->mcastaddr
);
1178 free(data
->mcastaddr
);
1179 data
->mcastaddr
= NULL
;
1181 if (cs_err
!= CS_OK
) {
1182 goto icmap_set_error
;
1186 if (data
->broadcast
!= NULL
) {
1187 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "totem.interface.%u.broadcast",
1189 cs_err
= icmap_set_string_r(config_map
, key_name
, data
->broadcast
);
1191 free(data
->broadcast
);
1192 data
->broadcast
= NULL
;
1194 if (cs_err
!= CS_OK
) {
1195 goto icmap_set_error
;
1199 if (data
->mcastport
> -1) {
1200 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "totem.interface.%u.mcastport",
1202 if ((cs_err
= icmap_set_uint16_r(config_map
, key_name
,
1203 data
->mcastport
)) != CS_OK
) {
1204 goto icmap_set_error
;
1208 if (data
->ttl
> -1) {
1209 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "totem.interface.%u.ttl",
1211 if ((cs_err
= icmap_set_uint8_r(config_map
, key_name
, data
->ttl
)) != CS_OK
) {
1212 goto icmap_set_error
;
1215 if (data
->knet_link_priority
> -1) {
1216 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "totem.interface.%u.knet_link_priority",
1218 if ((cs_err
= icmap_set_uint8_r(config_map
, key_name
,
1219 data
->knet_link_priority
)) != CS_OK
) {
1220 goto icmap_set_error
;
1223 if (data
->knet_ping_interval
> -1) {
1224 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "totem.interface.%u.knet_ping_interval",
1226 if ((cs_err
= icmap_set_uint32_r(config_map
, key_name
,
1227 data
->knet_ping_interval
)) != CS_OK
) {
1228 goto icmap_set_error
;
1231 if (data
->knet_ping_timeout
> -1) {
1232 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "totem.interface.%u.knet_ping_timeout",
1234 if ((cs_err
= icmap_set_uint32_r(config_map
, key_name
,
1235 data
->knet_ping_timeout
)) != CS_OK
) {
1236 goto icmap_set_error
;
1239 if (data
->knet_ping_precision
> -1) {
1240 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "totem.interface.%u.knet_ping_precision",
1242 if ((cs_err
= icmap_set_uint32_r(config_map
, key_name
,
1243 data
->knet_ping_precision
)) != CS_OK
) {
1244 goto icmap_set_error
;
1247 if (data
->knet_pong_count
> -1) {
1248 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "totem.interface.%u.knet_pong_count",
1250 if ((cs_err
= icmap_set_uint32_r(config_map
, key_name
,
1251 data
->knet_pong_count
)) != CS_OK
) {
1252 goto icmap_set_error
;
1255 if (data
->knet_transport
) {
1256 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "totem.interface.%u.knet_transport",
1258 cs_err
= icmap_set_string_r(config_map
, key_name
, data
->knet_transport
);
1259 free(data
->knet_transport
);
1261 if (cs_err
!= CS_OK
) {
1262 goto icmap_set_error
;
1268 qb_list_for_each_safe(iter
, tmp_iter
, &(data
->member_items_head
)) {
1269 kv_item
= qb_list_entry(iter
, struct key_value_list_item
, list
);
1271 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "totem.interface.%u.member.%u",
1272 data
->linknumber
, ii
);
1273 cs_err
= icmap_set_string_r(config_map
, key_name
, kv_item
->value
);
1275 free(kv_item
->value
);
1280 if (cs_err
!= CS_OK
) {
1281 goto icmap_set_error
;
1286 case MAIN_CP_CB_DATA_STATE_LOGGER_SUBSYS
:
1287 if (data
->subsys
== NULL
) {
1288 *error_string
= "No subsys key in logger_subsys directive";
1293 qb_list_for_each_safe(iter
, tmp_iter
, &(data
->logger_subsys_items_head
)) {
1294 kv_item
= qb_list_entry(iter
, struct key_value_list_item
, list
);
1296 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "logging.logger_subsys.%s.%s",
1297 data
->subsys
, kv_item
->key
);
1298 cs_err
= icmap_set_string_r(config_map
, key_name
, kv_item
->value
);
1300 free(kv_item
->value
);
1304 if (cs_err
!= CS_OK
) {
1305 goto icmap_set_error
;
1309 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "logging.logger_subsys.%s.subsys",
1311 cs_err
= icmap_set_string_r(config_map
, key_name
, data
->subsys
);
1315 if (cs_err
!= CS_OK
) {
1316 goto icmap_set_error
;
1319 case MAIN_CP_CB_DATA_STATE_LOGGING_DAEMON
:
1320 if (data
->logging_daemon_name
== NULL
) {
1321 *error_string
= "No name key in logging_daemon directive";
1326 qb_list_for_each_safe(iter
, tmp_iter
, &(data
->logger_subsys_items_head
)) {
1327 kv_item
= qb_list_entry(iter
, struct key_value_list_item
, list
);
1329 if (data
->subsys
== NULL
) {
1330 if (strcmp(data
->logging_daemon_name
, "corosync") == 0) {
1331 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
,
1335 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
,
1336 "logging.logging_daemon.%s.%s",
1337 data
->logging_daemon_name
, kv_item
->key
);
1340 if (strcmp(data
->logging_daemon_name
, "corosync") == 0) {
1341 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
,
1342 "logging.logger_subsys.%s.%s",
1346 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
,
1347 "logging.logging_daemon.%s.%s.%s",
1348 data
->logging_daemon_name
, data
->subsys
,
1352 cs_err
= icmap_set_string_r(config_map
, key_name
, kv_item
->value
);
1354 free(kv_item
->value
);
1358 if (cs_err
!= CS_OK
) {
1359 goto icmap_set_error
;
1363 if (data
->subsys
== NULL
) {
1364 if (strcmp(data
->logging_daemon_name
, "corosync") != 0) {
1365 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "logging.logging_daemon.%s.name",
1366 data
->logging_daemon_name
);
1367 cs_err
= icmap_set_string_r(config_map
, key_name
, data
->logging_daemon_name
);
1370 if (strcmp(data
->logging_daemon_name
, "corosync") == 0) {
1371 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "logging.logger_subsys.%s.subsys",
1373 cs_err
= icmap_set_string_r(config_map
, key_name
, data
->subsys
);
1376 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "logging.logging_daemon.%s.%s.subsys",
1377 data
->logging_daemon_name
, data
->subsys
);
1378 cs_err
= icmap_set_string_r(config_map
, key_name
, data
->subsys
);
1380 if (cs_err
!= CS_OK
) {
1382 free(data
->logging_daemon_name
);
1384 goto icmap_set_error
;
1386 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "logging.logging_daemon.%s.%s.name",
1387 data
->logging_daemon_name
, data
->subsys
);
1388 cs_err
= icmap_set_string_r(config_map
, key_name
, data
->logging_daemon_name
);
1393 free(data
->logging_daemon_name
);
1395 if (cs_err
!= CS_OK
) {
1396 goto icmap_set_error
;
1399 case MAIN_CP_CB_DATA_STATE_NODELIST_NODE
:
1400 data
->node_number
++;
1402 case MAIN_CP_CB_DATA_STATE_NORMAL
:
1403 case MAIN_CP_CB_DATA_STATE_PLOAD
:
1404 case MAIN_CP_CB_DATA_STATE_UIDGID
:
1405 case MAIN_CP_CB_DATA_STATE_MEMBER
:
1406 case MAIN_CP_CB_DATA_STATE_QUORUM
:
1407 case MAIN_CP_CB_DATA_STATE_QDEVICE
:
1408 case MAIN_CP_CB_DATA_STATE_NODELIST
:
1409 case MAIN_CP_CB_DATA_STATE_TOTEM
:
1410 case MAIN_CP_CB_DATA_STATE_SYSTEM
:
1412 case MAIN_CP_CB_DATA_STATE_RESOURCES
:
1413 *state
= MAIN_CP_CB_DATA_STATE_NORMAL
;
1415 case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM
:
1416 *state
= MAIN_CP_CB_DATA_STATE_RESOURCES
;
1418 case MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM_MEMUSED
:
1419 *state
= MAIN_CP_CB_DATA_STATE_RESOURCES_SYSTEM
;
1421 case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS
:
1422 *state
= MAIN_CP_CB_DATA_STATE_RESOURCES
;
1424 case MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS_MEMUSED
:
1425 *state
= MAIN_CP_CB_DATA_STATE_RESOURCES_PROCESS
;
1434 min_val
= max_val
= 0;
1436 * This is really assert, because developer ether doesn't set val_type correctly or
1437 * we've got here after some nasty memory overwrite
1439 assert(safe_atoq_range(val_type
, &min_val
, &max_val
) == 0);
1441 if (snprintf(formated_err
, sizeof(formated_err
),
1442 "Value of key \"%s\" is expected to be integer in range (%lld..%lld), but \"%s\" was given",
1443 key_name
, min_val
, max_val
, value
) >= sizeof(formated_err
)) {
1444 *error_string
= "Can't format parser error message";
1446 *error_string
= formated_err
;
1452 if (snprintf(formated_err
, sizeof(formated_err
),
1453 "Can't store key \"%s\" into icmap, returned error is %s",
1454 key_name
, cs_strerror(cs_err
)) >= sizeof(formated_err
)) {
1455 *error_string
= "Can't format parser error message";
1457 *error_string
= formated_err
;
1463 static int uidgid_config_parser_cb(const char *path
,
1466 enum main_cp_cb_data_state
*state
,
1467 enum parser_cb_type type
,
1468 const char **error_string
,
1469 icmap_map_t config_map
,
1472 char key_name
[ICMAP_KEYNAME_MAXLEN
];
1474 static char formated_err
[256];
1480 case PARSER_CB_START
:
1484 case PARSER_CB_ITEM
:
1485 if (strcmp(path
, "uidgid.uid") == 0) {
1486 uid
= uid_determine(value
);
1488 *error_string
= error_string_response
;
1491 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "uidgid.config.uid.%u",
1493 if ((cs_err
= icmap_set_uint8_r(config_map
, key_name
, 1)) != CS_OK
) {
1494 goto icmap_set_error
;
1496 } else if (strcmp(path
, "uidgid.gid") == 0) {
1497 gid
= gid_determine(value
);
1499 *error_string
= error_string_response
;
1502 snprintf(key_name
, ICMAP_KEYNAME_MAXLEN
, "uidgid.config.gid.%u",
1504 if ((cs_err
= icmap_set_uint8_r(config_map
, key_name
, 1)) != CS_OK
) {
1505 goto icmap_set_error
;
1508 *error_string
= "uidgid: Only uid and gid are allowed items";
1512 case PARSER_CB_SECTION_START
:
1513 if (strcmp(path
, "uidgid") != 0) {
1514 *error_string
= "uidgid: Can't add subsection different than uidgid";
1518 case PARSER_CB_SECTION_END
:
1525 if (snprintf(formated_err
, sizeof(formated_err
),
1526 "Can't store key \"%s\" into icmap, returned error is %s",
1527 key_name
, cs_strerror(cs_err
)) >= sizeof(formated_err
)) {
1528 *error_string
= "Can't format parser error message";
1530 *error_string
= formated_err
;
1536 static int read_uidgid_files_into_icmap(
1537 const char **error_string
,
1538 icmap_map_t config_map
)
1543 struct dirent
*dirent
;
1544 char filename
[PATH_MAX
+ FILENAME_MAX
+ 1];
1545 char uidgid_dirname
[PATH_MAX
+ FILENAME_MAX
+ 1];
1547 struct stat stat_buf
;
1548 enum main_cp_cb_data_state state
= MAIN_CP_CB_DATA_STATE_NORMAL
;
1549 char key_name
[ICMAP_KEYNAME_MAXLEN
];
1553 * Build uidgid directory based on corosync.conf file location
1555 res
= snprintf(filename
, sizeof(filename
), "%s",
1556 corosync_get_config_file());
1557 if (res
>= sizeof(filename
)) {
1558 *error_string
= "uidgid.d path too long";
1563 dirname_res
= dirname(filename
);
1565 res
= snprintf(uidgid_dirname
, sizeof(uidgid_dirname
), "%s/%s",
1566 dirname_res
, "uidgid.d");
1567 if (res
>= sizeof(uidgid_dirname
)) {
1568 *error_string
= "uidgid.d path too long";
1573 dp
= opendir (uidgid_dirname
);
1578 for (dirent
= readdir(dp
);
1580 dirent
= readdir(dp
)) {
1582 res
= snprintf(filename
, sizeof (filename
), "%s/%s", uidgid_dirname
, dirent
->d_name
);
1583 if (res
>= sizeof(filename
)) {
1585 *error_string
= "uidgid.d dirname path too long";
1589 res
= stat (filename
, &stat_buf
);
1590 if (res
== 0 && S_ISREG(stat_buf
.st_mode
)) {
1592 fp
= fopen (filename
, "r");
1593 if (fp
== NULL
) continue;
1598 res
= parse_section(fp
, filename
, &line_no
, key_name
, error_string
, 0, state
,
1599 uidgid_config_parser_cb
, config_map
, NULL
);
1615 /* Read config file and load into icmap */
1616 static int read_config_file_into_icmap(
1617 const char **error_string
,
1618 icmap_map_t config_map
)
1621 const char *filename
;
1622 char *error_reason
= error_string_response
;
1624 char key_name
[ICMAP_KEYNAME_MAXLEN
];
1625 struct main_cp_cb_data data
;
1626 enum main_cp_cb_data_state state
= MAIN_CP_CB_DATA_STATE_NORMAL
;
1629 filename
= corosync_get_config_file();
1631 fp
= fopen (filename
, "r");
1633 char error_str
[100];
1634 const char *error_ptr
= qb_strerror_r(errno
, error_str
, sizeof(error_str
));
1635 snprintf (error_reason
, sizeof(error_string_response
),
1636 "Can't read file %s reason = (%s)",
1637 filename
, error_ptr
);
1638 *error_string
= error_reason
;
1645 res
= parse_section(fp
, filename
, &line_no
, key_name
, error_string
, 0, state
,
1646 main_config_parser_cb
, config_map
, &data
);
1651 res
= read_uidgid_files_into_icmap(error_string
, config_map
);
1655 snprintf (error_reason
, sizeof(error_string_response
),
1656 "Successfully read main configuration file '%s'.", filename
);
1657 *error_string
= error_reason
;