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>
58 #include <qb/qbutil.h>
84 #define DEFAULT_SHUTDOWN_TIMEOUT 5000
86 static struct qb_list_head trackers_list;
92 static struct cfg_info *shutdown_con;
93 static uint32_t shutdown_flags;
94 static int shutdown_yes;
95 static int shutdown_no;
96 static int shutdown_expected;
100 struct qb_list_head
list;
106 static void cfg_confchg_fn (
108 const unsigned int *member_list,
size_t member_list_entries,
109 const unsigned int *left_list,
size_t left_list_entries,
110 const unsigned int *joined_list,
size_t joined_list_entries,
117 static int cfg_lib_init_fn (
void *conn);
119 static int cfg_lib_exit_fn (
void *conn);
121 static void message_handler_req_exec_cfg_ringreenable (
125 static void message_handler_req_exec_cfg_killnode (
129 static void message_handler_req_exec_cfg_shutdown (
133 static void message_handler_req_exec_cfg_reload_config (
137 static void message_handler_req_exec_cfg_reconfig_crypto (
141 static void exec_cfg_killnode_endian_convert (
void *msg);
143 static void message_handler_req_lib_cfg_ringstatusget (
147 static void message_handler_req_lib_cfg_nodestatusget (
151 static void message_handler_req_lib_cfg_ringreenable (
155 static void message_handler_req_lib_cfg_killnode (
159 static void message_handler_req_lib_cfg_tryshutdown (
163 static void message_handler_req_lib_cfg_replytoshutdown (
167 static void message_handler_req_lib_cfg_trackstart (
171 static void message_handler_req_lib_cfg_trackstop (
175 static void message_handler_req_lib_cfg_get_node_addrs (
179 static void message_handler_req_lib_cfg_local_get (
183 static void message_handler_req_lib_cfg_reload_config (
187 static void message_handler_req_lib_cfg_reopen_log_files (
201 .lib_handler_fn = message_handler_req_lib_cfg_ringreenable,
205 .lib_handler_fn = message_handler_req_lib_cfg_killnode,
209 .lib_handler_fn = message_handler_req_lib_cfg_tryshutdown,
213 .lib_handler_fn = message_handler_req_lib_cfg_replytoshutdown,
217 .lib_handler_fn = message_handler_req_lib_cfg_get_node_addrs,
221 .lib_handler_fn = message_handler_req_lib_cfg_local_get,
225 .lib_handler_fn = message_handler_req_lib_cfg_reload_config,
229 .lib_handler_fn = message_handler_req_lib_cfg_reopen_log_files,
233 .lib_handler_fn = message_handler_req_lib_cfg_nodestatusget,
237 .lib_handler_fn = message_handler_req_lib_cfg_trackstart,
241 .lib_handler_fn = message_handler_req_lib_cfg_trackstop,
253 .exec_handler_fn = message_handler_req_exec_cfg_killnode,
254 .exec_endian_convert_fn = exec_cfg_killnode_endian_convert
257 .exec_handler_fn = message_handler_req_exec_cfg_shutdown,
260 .exec_handler_fn = message_handler_req_exec_cfg_reload_config,
263 .exec_handler_fn = message_handler_req_exec_cfg_reconfig_crypto,
271 .
name =
"corosync configuration service",
274 .private_data_size =
sizeof(
struct cfg_info),
277 .lib_init_fn = cfg_lib_init_fn,
278 .lib_exit_fn = cfg_lib_exit_fn,
279 .lib_engine = cfg_lib_engine,
281 .exec_init_fn = cfg_exec_init_fn,
282 .exec_engine = cfg_exec_engine,
284 .confchg_fn = cfg_confchg_fn
319 static char *cfg_exec_init_fn (
324 qb_list_init(&trackers_list);
328 static void cfg_confchg_fn (
330 const unsigned int *member_list,
size_t member_list_entries,
331 const unsigned int *left_list,
size_t left_list_entries,
332 const unsigned int *joined_list,
size_t joined_list_entries,
340 static int send_shutdown(
void)
360 static void send_test_shutdown(
void *only_conn,
void *exclude_conn,
int status)
363 struct qb_list_head *iter;
372 TRACE1(
"sending testshutdown to only %p", only_conn);
376 qb_list_for_each(iter, &trackers_list) {
379 if (ci->
conn != exclude_conn) {
389 static void check_shutdown_status(
void)
404 if (shutdown_yes + shutdown_no >= shutdown_expected) {
409 if (shutdown_yes >= shutdown_expected ||
411 TRACE1(
"shutdown confirmed");
432 TRACE1(
"shutdown cancelled");
446 shutdown_yes, shutdown_no, shutdown_flags);
455 static void shutdown_timer_fn(
void *arg)
462 shutdown_no = shutdown_expected;
463 check_shutdown_status();
469 static void remove_ci_from_shutdown(
struct cfg_info *ci)
477 if (ci == shutdown_con) {
482 if (!qb_list_empty(&ci->
list)) {
483 qb_list_del(&ci->
list);
484 qb_list_init(&ci->
list);
502 check_shutdown_status();
508 int cfg_lib_exit_fn (
void *conn)
513 remove_ci_from_shutdown(ci);
518 static int cfg_lib_init_fn (
void *
conn)
523 qb_list_init(&ci->
list);
532 static void message_handler_req_exec_cfg_ringreenable (
541 static void exec_cfg_killnode_endian_convert (
void *msg)
552 static void message_handler_req_exec_cfg_killnode (
574 static void message_handler_req_exec_cfg_shutdown (
588 static int nullcheck_strcmp(
const char* left,
const char *right)
598 return strcmp(left, right);
604 static void delete_and_notify_if_changed(
icmap_map_t temp_map,
const char *key_name)
619 static void remove_ro_entries(
icmap_map_t temp_map)
621 #ifndef HAVE_KNET_CRYPTO_RECONF
622 delete_and_notify_if_changed(temp_map,
"totem.secauth");
623 delete_and_notify_if_changed(temp_map,
"totem.crypto_hash");
624 delete_and_notify_if_changed(temp_map,
"totem.crypto_cipher");
625 delete_and_notify_if_changed(temp_map,
"totem.keyfile");
626 delete_and_notify_if_changed(temp_map,
"totem.key");
628 delete_and_notify_if_changed(temp_map,
"totem.version");
629 delete_and_notify_if_changed(temp_map,
"totem.threads");
630 delete_and_notify_if_changed(temp_map,
"totem.ip_version");
631 delete_and_notify_if_changed(temp_map,
"totem.rrp_mode");
632 delete_and_notify_if_changed(temp_map,
"totem.netmtu");
633 delete_and_notify_if_changed(temp_map,
"totem.interface.ringnumber");
634 delete_and_notify_if_changed(temp_map,
"totem.interface.bindnetaddr");
635 delete_and_notify_if_changed(temp_map,
"totem.interface.mcastaddr");
636 delete_and_notify_if_changed(temp_map,
"totem.interface.broadcast");
637 delete_and_notify_if_changed(temp_map,
"totem.interface.mcastport");
638 delete_and_notify_if_changed(temp_map,
"totem.interface.ttl");
639 delete_and_notify_if_changed(temp_map,
"totem.transport");
640 delete_and_notify_if_changed(temp_map,
"totem.cluster_name");
641 delete_and_notify_if_changed(temp_map,
"quorum.provider");
642 delete_and_notify_if_changed(temp_map,
"system.move_to_root_cgroup");
643 delete_and_notify_if_changed(temp_map,
"system.allow_knet_handle_fallback");
644 delete_and_notify_if_changed(temp_map,
"system.sched_rr");
645 delete_and_notify_if_changed(temp_map,
"system.priority");
646 delete_and_notify_if_changed(temp_map,
"system.qb_ipc_type");
647 delete_and_notify_if_changed(temp_map,
"system.state_dir");
657 static void remove_deleted_entries(
icmap_map_t temp_map,
const char *prefix)
661 const char *old_key, *new_key;
670 while (old_key || new_key) {
671 ret = nullcheck_strcmp(old_key, new_key);
672 if ((ret < 0 && old_key) || !new_key) {
682 ret = nullcheck_strcmp(old_key, new_key);
683 }
while (ret < 0 && old_key);
685 else if ((ret > 0 && new_key) || !old_key) {
695 ret = nullcheck_strcmp(old_key, new_key);
696 }
while (ret > 0 && new_key);
710 static void message_handler_req_exec_cfg_reload_config (
718 const char *error_string;
728 memset(&new_config, 0,
sizeof(new_config));
734 goto reload_fini_nomap;
744 goto reload_fini_nofree;
751 remove_deleted_entries(temp_map,
"logging.");
752 remove_deleted_entries(temp_map,
"totem.");
753 remove_deleted_entries(temp_map,
"nodelist.");
754 remove_deleted_entries(temp_map,
"quorum.");
755 remove_deleted_entries(temp_map,
"uidgid.config.");
756 remove_deleted_entries(temp_map,
"nozzle.");
759 remove_ro_entries(temp_map);
762 memset(&new_config, 0,
sizeof(new_config));
764 assert(new_config.orig_interfaces != NULL);
767 new_config.crypto_changed = 0;
770 assert(new_config.interfaces != NULL);
777 memcpy(&new_config.interfaces[0], &new_config.orig_interfaces[0],
806 if (new_config.crypto_changed) {
807 #ifndef HAVE_KNET_CRYPTO_RECONF
808 new_config.crypto_changed = 0;
827 free(new_config.interfaces);
836 free(new_config.orig_interfaces);
847 if (new_config.crypto_changed) {
884 static void message_handler_req_exec_cfg_reconfig_crypto (
902 req_exec_cfg_crypto_reconfig2.header.size =
908 iovec.iov_base = (
char *)&req_exec_cfg_crypto_reconfig2;
920 static void message_handler_req_lib_cfg_ringstatusget (
926 unsigned int iface_count;
928 const char *totem_ip_string;
951 for (i = 0; i < iface_count; i++) {
955 if (!totem_ip_string) {
965 snprintf(ifname,
sizeof(ifname),
"%d %s", iface_ids[i], totem_ip_string);
990 static void message_handler_req_lib_cfg_nodestatusget (
996 void *res_lib_cfg_nodestatusget_ptr = NULL;
997 size_t res_lib_cfg_nodestatusget_size;
1004 memset(&node_status, 0,
sizeof(node_status));
1013 goto ipc_response_send;
1035 for (i=0; i < KNET_MAX_LINK; i++) {
1062 res_lib_cfg_nodestatusget_ptr,
1063 res_lib_cfg_nodestatusget_size);
1068 static void message_handler_req_lib_cfg_trackstart (
1080 if (qb_list_empty(&ci->
list)) {
1081 qb_list_add(&ci->
list, &trackers_list);
1089 shutdown_expected++;
1090 send_test_shutdown(conn, NULL,
CS_OK);
1104 static void message_handler_req_lib_cfg_trackstop (
1111 remove_ci_from_shutdown(ci);
1115 static void message_handler_req_lib_cfg_ringreenable (
1132 static void message_handler_req_lib_cfg_killnode (
1144 const char *iter_key;
1146 char *status_str = NULL;
1147 int match_nodeid_flag = 0;
1155 if (sscanf(iter_key,
"runtime.members.%u.%s", &
nodeid, key_name) != 2) {
1158 if (strcmp(key_name,
"status") != 0) {
1164 match_nodeid_flag = 1;
1170 if (strcmp(status_str,
"joined") != 0) {
1177 if (!match_nodeid_flag) {
1208 static void message_handler_req_lib_cfg_tryshutdown (
1214 struct qb_list_head *iter;
1264 shutdown_expected = 0;
1266 qb_list_for_each(iter, &trackers_list) {
1273 shutdown_expected++;
1280 if (shutdown_expected == 0) {
1309 api->
timer_add_duration((
unsigned long long)shutdown_timeout*QB_TIME_NS_IN_MSEC, NULL,
1310 shutdown_timer_fn, &shutdown_timer);
1315 send_test_shutdown(NULL, conn,
CS_OK);
1326 static void message_handler_req_lib_cfg_replytoshutdown (
1336 if (!shutdown_con) {
1349 check_shutdown_status();
1362 static void message_handler_req_lib_cfg_get_node_addrs (
void *conn,
1369 unsigned int num_interfaces = 0;
1370 struct sockaddr_storage *ss;
1390 if (num_interfaces) {
1393 i < num_interfaces; i++) {
1394 ss = (
struct sockaddr_storage *)&node_ifs[i].
addr;
1395 if (ss->ss_family) {
1408 static void message_handler_req_lib_cfg_local_get (
void *conn,
const void *msg)
1421 static void message_handler_req_lib_cfg_reload_config (
void *conn,
const void *msg)
1443 static void message_handler_req_lib_cfg_reopen_log_files (
void *conn,
const void *msg)