38 #include <sys/types.h>
40 #include <sys/socket.h>
42 #include <netinet/in.h>
43 #include <arpa/inet.h>
55 #include <qb/qbipc_common.h>
57 #include <qb/qblist.h>
81 #define DEFAULT_SHUTDOWN_TIMEOUT 5
83 static struct qb_list_head trackers_list;
89 static struct cfg_info *shutdown_con;
90 static uint32_t shutdown_flags;
91 static int shutdown_yes;
92 static int shutdown_no;
93 static int shutdown_expected;
97 struct qb_list_head
list;
103 static void cfg_confchg_fn (
105 const unsigned int *member_list,
size_t member_list_entries,
106 const unsigned int *left_list,
size_t left_list_entries,
107 const unsigned int *joined_list,
size_t joined_list_entries,
114 static int cfg_lib_init_fn (
void *conn);
116 static int cfg_lib_exit_fn (
void *conn);
118 static void message_handler_req_exec_cfg_ringreenable (
122 static void message_handler_req_exec_cfg_killnode (
126 static void message_handler_req_exec_cfg_shutdown (
130 static void message_handler_req_exec_cfg_reload_config (
134 static void message_handler_req_exec_cfg_reconfig_crypto (
138 static void exec_cfg_killnode_endian_convert (
void *msg);
140 static void message_handler_req_lib_cfg_ringstatusget (
144 static void message_handler_req_lib_cfg_ringreenable (
148 static void message_handler_req_lib_cfg_killnode (
152 static void message_handler_req_lib_cfg_tryshutdown (
156 static void message_handler_req_lib_cfg_replytoshutdown (
160 static void message_handler_req_lib_cfg_get_node_addrs (
164 static void message_handler_req_lib_cfg_local_get (
168 static void message_handler_req_lib_cfg_reload_config (
172 static void message_handler_req_lib_cfg_reopen_log_files (
186 .lib_handler_fn = message_handler_req_lib_cfg_ringreenable,
190 .lib_handler_fn = message_handler_req_lib_cfg_killnode,
194 .lib_handler_fn = message_handler_req_lib_cfg_tryshutdown,
198 .lib_handler_fn = message_handler_req_lib_cfg_replytoshutdown,
202 .lib_handler_fn = message_handler_req_lib_cfg_get_node_addrs,
206 .lib_handler_fn = message_handler_req_lib_cfg_local_get,
210 .lib_handler_fn = message_handler_req_lib_cfg_reload_config,
214 .lib_handler_fn = message_handler_req_lib_cfg_reopen_log_files,
225 .exec_handler_fn = message_handler_req_exec_cfg_killnode,
226 .exec_endian_convert_fn = exec_cfg_killnode_endian_convert
229 .exec_handler_fn = message_handler_req_exec_cfg_shutdown,
232 .exec_handler_fn = message_handler_req_exec_cfg_reload_config,
235 .exec_handler_fn = message_handler_req_exec_cfg_reconfig_crypto,
243 .
name =
"corosync configuration service",
246 .private_data_size =
sizeof(
struct cfg_info),
249 .lib_init_fn = cfg_lib_init_fn,
250 .lib_exit_fn = cfg_lib_exit_fn,
251 .lib_engine = cfg_lib_engine,
253 .exec_init_fn = cfg_exec_init_fn,
254 .exec_engine = cfg_exec_engine,
256 .confchg_fn = cfg_confchg_fn
291 static char *cfg_exec_init_fn (
296 qb_list_init(&trackers_list);
300 static void cfg_confchg_fn (
302 const unsigned int *member_list,
size_t member_list_entries,
303 const unsigned int *left_list,
size_t left_list_entries,
304 const unsigned int *joined_list,
size_t joined_list_entries,
312 static int send_shutdown(
void)
332 static void send_test_shutdown(
void *only_conn,
void *exclude_conn,
int status)
335 struct qb_list_head *iter;
344 TRACE1(
"sending testshutdown to only %p", only_conn);
348 qb_list_for_each(iter, &trackers_list) {
351 if (ci->
conn != exclude_conn) {
361 static void check_shutdown_status(
void)
376 if (shutdown_yes + shutdown_no >= shutdown_expected) {
381 if (shutdown_yes >= shutdown_expected ||
383 TRACE1(
"shutdown confirmed");
404 TRACE1(
"shutdown cancelled");
418 shutdown_yes, shutdown_no, shutdown_flags);
427 static void shutdown_timer_fn(
void *arg)
434 shutdown_no = shutdown_expected;
435 check_shutdown_status();
441 static void remove_ci_from_shutdown(
struct cfg_info *ci)
449 if (ci == shutdown_con) {
454 if (!qb_list_empty(&ci->
list)) {
455 qb_list_del(&ci->
list);
456 qb_list_init(&ci->
list);
474 check_shutdown_status();
480 int cfg_lib_exit_fn (
void *conn)
485 remove_ci_from_shutdown(ci);
490 static int cfg_lib_init_fn (
void *
conn)
495 qb_list_init(&ci->
list);
504 static void message_handler_req_exec_cfg_ringreenable (
513 static void exec_cfg_killnode_endian_convert (
void *msg)
524 static void message_handler_req_exec_cfg_killnode (
546 static void message_handler_req_exec_cfg_shutdown (
560 static int nullcheck_strcmp(
const char* left,
const char *right)
570 return strcmp(left, right);
576 static void delete_and_notify_if_changed(
icmap_map_t temp_map,
const char *key_name)
591 static void remove_ro_entries(
icmap_map_t temp_map)
593 #ifndef HAVE_KNET_CRYPTO_RECONF
594 delete_and_notify_if_changed(temp_map,
"totem.secauth");
595 delete_and_notify_if_changed(temp_map,
"totem.crypto_hash");
596 delete_and_notify_if_changed(temp_map,
"totem.crypto_cipher");
597 delete_and_notify_if_changed(temp_map,
"totem.keyfile");
598 delete_and_notify_if_changed(temp_map,
"totem.key");
600 delete_and_notify_if_changed(temp_map,
"totem.version");
601 delete_and_notify_if_changed(temp_map,
"totem.threads");
602 delete_and_notify_if_changed(temp_map,
"totem.ip_version");
603 delete_and_notify_if_changed(temp_map,
"totem.rrp_mode");
604 delete_and_notify_if_changed(temp_map,
"totem.netmtu");
605 delete_and_notify_if_changed(temp_map,
"totem.interface.ringnumber");
606 delete_and_notify_if_changed(temp_map,
"totem.interface.bindnetaddr");
607 delete_and_notify_if_changed(temp_map,
"totem.interface.mcastaddr");
608 delete_and_notify_if_changed(temp_map,
"totem.interface.broadcast");
609 delete_and_notify_if_changed(temp_map,
"totem.interface.mcastport");
610 delete_and_notify_if_changed(temp_map,
"totem.interface.ttl");
611 delete_and_notify_if_changed(temp_map,
"totem.transport");
612 delete_and_notify_if_changed(temp_map,
"totem.cluster_name");
613 delete_and_notify_if_changed(temp_map,
"quorum.provider");
614 delete_and_notify_if_changed(temp_map,
"system.move_to_root_cgroup");
615 delete_and_notify_if_changed(temp_map,
"system.sched_rr");
616 delete_and_notify_if_changed(temp_map,
"system.priority");
617 delete_and_notify_if_changed(temp_map,
"system.qb_ipc_type");
618 delete_and_notify_if_changed(temp_map,
"system.state_dir");
628 static void remove_deleted_entries(
icmap_map_t temp_map,
const char *prefix)
632 const char *old_key, *new_key;
641 while (old_key || new_key) {
642 ret = nullcheck_strcmp(old_key, new_key);
643 if ((ret < 0 && old_key) || !new_key) {
653 ret = nullcheck_strcmp(old_key, new_key);
654 }
while (ret < 0 && old_key);
656 else if ((ret > 0 && new_key) || !old_key) {
666 ret = nullcheck_strcmp(old_key, new_key);
667 }
while (ret > 0 && new_key);
681 static void message_handler_req_exec_cfg_reload_config (
689 const char *error_string;
699 memset(&new_config, 0,
sizeof(new_config));
705 goto reload_fini_nomap;
715 goto reload_fini_nofree;
722 remove_deleted_entries(temp_map,
"logging.");
723 remove_deleted_entries(temp_map,
"totem.");
724 remove_deleted_entries(temp_map,
"nodelist.");
725 remove_deleted_entries(temp_map,
"quorum.");
726 remove_deleted_entries(temp_map,
"uidgid.config.");
727 remove_deleted_entries(temp_map,
"nozzle.");
730 remove_ro_entries(temp_map);
733 memset(&new_config, 0,
sizeof(new_config));
735 assert(new_config.orig_interfaces != NULL);
738 new_config.crypto_changed = 0;
741 assert(new_config.interfaces != NULL);
748 memcpy(&new_config.interfaces[0], &new_config.orig_interfaces[0],
777 if (new_config.crypto_changed) {
778 #ifndef HAVE_KNET_CRYPTO_RECONF
779 new_config.crypto_changed = 0;
798 free(new_config.interfaces);
807 free(new_config.orig_interfaces);
818 if (new_config.crypto_changed) {
855 static void message_handler_req_exec_cfg_reconfig_crypto (
873 req_exec_cfg_crypto_reconfig2.header.size =
879 iovec.iov_base = (
char *)&req_exec_cfg_crypto_reconfig2;
891 static void message_handler_req_lib_cfg_ringstatusget (
897 unsigned int iface_count;
899 const char *totem_ip_string;
922 for (i = 0; i < iface_count; i++) {
926 if (!totem_ip_string) {
936 snprintf(ifname,
sizeof(ifname),
"%d %s", iface_ids[i], totem_ip_string);
960 static void message_handler_req_lib_cfg_ringreenable (
977 static void message_handler_req_lib_cfg_killnode (
989 const char *iter_key;
991 char *status_str = NULL;
992 int match_nodeid_flag = 0;
1000 if (sscanf(iter_key,
"runtime.members.%u.%s", &
nodeid, key_name) != 2) {
1003 if (strcmp(key_name,
"status") != 0) {
1009 match_nodeid_flag = 1;
1015 if (strcmp(status_str,
"joined") != 0) {
1022 if (!match_nodeid_flag) {
1053 static void message_handler_req_lib_cfg_tryshutdown (
1059 struct qb_list_head *iter;
1109 shutdown_expected = 0;
1111 qb_list_for_each(iter, &trackers_list) {
1118 shutdown_expected++;
1125 if (shutdown_expected == 0) {
1155 shutdown_timer_fn, &shutdown_timer);
1160 send_test_shutdown(NULL, conn,
CS_OK);
1171 static void message_handler_req_lib_cfg_replytoshutdown (
1181 if (!shutdown_con) {
1194 check_shutdown_status();
1207 static void message_handler_req_lib_cfg_get_node_addrs (
void *conn,
1214 unsigned int num_interfaces = 0;
1215 struct sockaddr_storage *ss;
1235 if (num_interfaces) {
1238 i < num_interfaces; i++) {
1239 ss = (
struct sockaddr_storage *)&node_ifs[i].
addr;
1240 if (ss->ss_family) {
1253 static void message_handler_req_lib_cfg_local_get (
void *conn,
const void *msg)
1266 static void message_handler_req_lib_cfg_reload_config (
void *conn,
const void *msg)
1288 static void message_handler_req_lib_cfg_reopen_log_files (
void *conn,
const void *msg)