44#include <sys/socket.h>
46#include <netinet/in.h>
59#include <qb/qbipc_common.h>
88#define DEFAULT_SHUTDOWN_TIMEOUT 5000
90static struct qb_list_head trackers_list;
97static uint32_t shutdown_flags;
98static int shutdown_yes;
99static int shutdown_no;
100static int shutdown_expected;
110static void cfg_confchg_fn (
112 const unsigned int *member_list,
size_t member_list_entries,
113 const unsigned int *left_list,
size_t left_list_entries,
114 const unsigned int *joined_list,
size_t joined_list_entries,
121static int cfg_lib_init_fn (
void *conn);
123static int cfg_lib_exit_fn (
void *conn);
125static void message_handler_req_exec_cfg_ringreenable (
129static void message_handler_req_exec_cfg_killnode (
133static void message_handler_req_exec_cfg_shutdown (
137static void message_handler_req_exec_cfg_reload_config (
141static void message_handler_req_exec_cfg_reconfig_crypto (
145static void exec_cfg_killnode_endian_convert (
void *msg);
147static void message_handler_req_lib_cfg_ringstatusget (
151static void message_handler_req_lib_cfg_nodestatusget (
155static void message_handler_req_lib_cfg_ringreenable (
159static void message_handler_req_lib_cfg_killnode (
163static void message_handler_req_lib_cfg_tryshutdown (
167static void message_handler_req_lib_cfg_replytoshutdown (
171static void message_handler_req_lib_cfg_trackstart (
175static void message_handler_req_lib_cfg_trackstop (
179static void message_handler_req_lib_cfg_get_node_addrs (
183static void message_handler_req_lib_cfg_local_get (
187static void message_handler_req_lib_cfg_reload_config (
191static void message_handler_req_lib_cfg_reopen_log_files (
201 .lib_handler_fn = message_handler_req_lib_cfg_ringstatusget,
205 .lib_handler_fn = message_handler_req_lib_cfg_ringreenable,
209 .lib_handler_fn = message_handler_req_lib_cfg_killnode,
213 .lib_handler_fn = message_handler_req_lib_cfg_tryshutdown,
217 .lib_handler_fn = message_handler_req_lib_cfg_replytoshutdown,
221 .lib_handler_fn = message_handler_req_lib_cfg_get_node_addrs,
225 .lib_handler_fn = message_handler_req_lib_cfg_local_get,
229 .lib_handler_fn = message_handler_req_lib_cfg_reload_config,
233 .lib_handler_fn = message_handler_req_lib_cfg_reopen_log_files,
237 .lib_handler_fn = message_handler_req_lib_cfg_nodestatusget,
241 .lib_handler_fn = message_handler_req_lib_cfg_trackstart,
245 .lib_handler_fn = message_handler_req_lib_cfg_trackstop,
254 .exec_handler_fn = message_handler_req_exec_cfg_ringreenable,
257 .exec_handler_fn = message_handler_req_exec_cfg_killnode,
258 .exec_endian_convert_fn = exec_cfg_killnode_endian_convert
261 .exec_handler_fn = message_handler_req_exec_cfg_shutdown,
264 .exec_handler_fn = message_handler_req_exec_cfg_reload_config,
267 .exec_handler_fn = message_handler_req_exec_cfg_reconfig_crypto,
275 .name =
"corosync configuration service",
278 .private_data_size =
sizeof(
struct cfg_info),
281 .lib_init_fn = cfg_lib_init_fn,
282 .lib_exit_fn = cfg_lib_exit_fn,
283 .lib_engine = cfg_lib_engine,
285 .exec_init_fn = cfg_exec_init_fn,
286 .exec_engine = cfg_exec_engine,
288 .confchg_fn = cfg_confchg_fn
323static char *cfg_exec_init_fn (
328 qb_list_init(&trackers_list);
332static void cfg_confchg_fn (
334 const unsigned int *member_list,
size_t member_list_entries,
335 const unsigned int *left_list,
size_t left_list_entries,
336 const unsigned int *joined_list,
size_t joined_list_entries,
344static int send_shutdown(
void)
358 assert (api->totem_mcast (&iovec, 1,
TOTEM_SAFE) == 0);
364static void send_test_shutdown(
void *only_conn,
void *exclude_conn,
int status)
367 struct qb_list_head *iter;
376 TRACE1(
"sending testshutdown to only %p", only_conn);
380 qb_list_for_each(iter, &trackers_list) {
383 if (ci->
conn != exclude_conn) {
393static void check_shutdown_status(
void)
408 if (shutdown_yes + shutdown_no >= shutdown_expected) {
411 api->timer_delete(shutdown_timer);
413 if (shutdown_yes >= shutdown_expected ||
415 TRACE1(
"shutdown confirmed");
436 TRACE1(
"shutdown cancelled");
450 shutdown_yes, shutdown_no, shutdown_flags);
459static void shutdown_timer_fn(
void *arg)
466 shutdown_no = shutdown_expected;
467 check_shutdown_status();
473static void remove_ci_from_shutdown(
struct cfg_info *ci)
481 if (ci == shutdown_con) {
483 api->timer_delete(shutdown_timer);
486 if (!qb_list_empty(&ci->
list)) {
487 qb_list_del(&ci->
list);
488 qb_list_init(&ci->
list);
506 check_shutdown_status();
512int cfg_lib_exit_fn (
void *conn)
517 remove_ci_from_shutdown(ci);
522static int cfg_lib_init_fn (
void *
conn)
527 qb_list_init(&ci->
list);
536static void message_handler_req_exec_cfg_ringreenable (
545static void exec_cfg_killnode_endian_convert (
void *msg)
556static void message_handler_req_exec_cfg_killnode (
578static void message_handler_req_exec_cfg_shutdown (
585 if (
nodeid == api->totem_nodeid_get()) {
586 api->shutdown_request();
592static int nullcheck_strcmp(
const char* left,
const char *right)
602 return strcmp(left, right);
608static void delete_and_notify_if_changed(
icmap_map_t temp_map,
const char *key_name)
625#ifndef HAVE_KNET_CRYPTO_RECONF
626 delete_and_notify_if_changed(temp_map,
"totem.secauth");
627 delete_and_notify_if_changed(temp_map,
"totem.crypto_hash");
628 delete_and_notify_if_changed(temp_map,
"totem.crypto_cipher");
629 delete_and_notify_if_changed(temp_map,
"totem.keyfile");
630 delete_and_notify_if_changed(temp_map,
"totem.key");
632 delete_and_notify_if_changed(temp_map,
"totem.version");
633 delete_and_notify_if_changed(temp_map,
"totem.threads");
634 delete_and_notify_if_changed(temp_map,
"totem.ip_version");
635 delete_and_notify_if_changed(temp_map,
"totem.ip_dscp");
636 delete_and_notify_if_changed(temp_map,
"totem.netmtu");
637 delete_and_notify_if_changed(temp_map,
"totem.interface.bindnetaddr");
638 delete_and_notify_if_changed(temp_map,
"totem.interface.mcastaddr");
639 delete_and_notify_if_changed(temp_map,
"totem.interface.broadcast");
640 delete_and_notify_if_changed(temp_map,
"totem.interface.mcastport");
641 delete_and_notify_if_changed(temp_map,
"totem.interface.ttl");
642 delete_and_notify_if_changed(temp_map,
"totem.transport");
643 delete_and_notify_if_changed(temp_map,
"totem.cluster_name");
644 delete_and_notify_if_changed(temp_map,
"quorum.provider");
645 delete_and_notify_if_changed(temp_map,
"system.move_to_root_cgroup");
646 delete_and_notify_if_changed(temp_map,
"system.allow_knet_handle_fallback");
647 delete_and_notify_if_changed(temp_map,
"system.sched_rr");
648 delete_and_notify_if_changed(temp_map,
"system.priority");
649 delete_and_notify_if_changed(temp_map,
"system.qb_ipc_type");
650 delete_and_notify_if_changed(temp_map,
"system.state_dir");
660static void remove_deleted_entries(
icmap_map_t temp_map,
const char *prefix)
664 const char *old_key, *new_key;
673 while (old_key || new_key) {
674 ret = nullcheck_strcmp(old_key, new_key);
675 if ((ret < 0 && old_key) || !new_key) {
685 ret = nullcheck_strcmp(old_key, new_key);
686 }
while (ret < 0 && old_key);
688 else if ((ret > 0 && new_key) || !old_key) {
698 ret = nullcheck_strcmp(old_key, new_key);
699 }
while (ret > 0 && new_key);
713static void message_handler_req_exec_cfg_reload_config (
721 const char *error_string;
734 memset(&new_config, 0,
sizeof(new_config));
740 goto reload_fini_nomap;
750 goto reload_fini_nofree;
757 remove_deleted_entries(temp_map,
"logging.");
758 remove_deleted_entries(temp_map,
"totem.");
759 remove_deleted_entries(temp_map,
"nodelist.");
760 remove_deleted_entries(temp_map,
"quorum.");
761 remove_deleted_entries(temp_map,
"uidgid.config.");
762 remove_deleted_entries(temp_map,
"nozzle.");
765 remove_ro_entries(temp_map);
768 memset(&new_config, 0,
sizeof(new_config));
770 assert(new_config.orig_interfaces != NULL);
773 new_config.crypto_changed = 0;
776 assert(new_config.interfaces != NULL);
783 memcpy(&new_config.interfaces[0], &new_config.orig_interfaces[0],
812 if (new_config.crypto_changed) {
813#ifndef HAVE_KNET_CRYPTO_RECONF
814 new_config.crypto_changed = 0;
841 free(new_config.interfaces);
842 free(new_config.orig_interfaces);
853 if (new_config.crypto_changed) {
866 assert (api->totem_mcast (&iovec, 1,
TOTEM_SAFE) == 0);
870 if (
nodeid == api->totem_nodeid_get()) {
890static void message_handler_req_exec_cfg_reconfig_crypto (
897 if (
nodeid == api->totem_nodeid_get()) {
908 req_exec_cfg_crypto_reconfig2.header.size =
914 iovec.iov_base = (
char *)&req_exec_cfg_crypto_reconfig2;
917 assert (api->totem_mcast (&iovec, 1,
TOTEM_SAFE) == 0);
926static void message_handler_req_lib_cfg_ringstatusget (
932 unsigned int iface_count;
934 const char *totem_ip_string;
945 api->totem_ifaces_get (
946 api->totem_nodeid_get(),
957 for (i = 0; i < iface_count; i++) {
959 = (
const char *)api->totem_ip_print (&interfaces[i]);
961 if (!totem_ip_string) {
971 snprintf(ifname,
sizeof(ifname),
"%d %s", iface_ids[i], totem_ip_string);
987 api->ipc_response_send (
996static void message_handler_req_lib_cfg_nodestatusget (
1002 void *res_lib_cfg_nodestatusget_ptr = NULL;
1003 size_t res_lib_cfg_nodestatusget_size;
1010 memset(&node_status, 0,
sizeof(node_status));
1019 goto ipc_response_send;
1041 for (i=0; i < KNET_MAX_LINK; i++) {
1066 api->ipc_response_send (
1068 res_lib_cfg_nodestatusget_ptr,
1069 res_lib_cfg_nodestatusget_size);
1074static void message_handler_req_lib_cfg_trackstart (
1086 if (qb_list_empty(&ci->
list)) {
1087 qb_list_add(&ci->
list, &trackers_list);
1095 shutdown_expected++;
1096 send_test_shutdown(conn, NULL,
CS_OK);
1110static void message_handler_req_lib_cfg_trackstop (
1118 remove_ci_from_shutdown(ci);
1129static void message_handler_req_lib_cfg_ringreenable (
1139 api->ipc_response_send (
1146static void message_handler_req_lib_cfg_killnode (
1158 const char *iter_key;
1160 char *status_str = NULL;
1161 int match_nodeid_flag = 0;
1169 if (sscanf(iter_key,
"runtime.members.%u.%s", &
nodeid, key_name) != 2) {
1172 if (strcmp(key_name,
"status") != 0) {
1178 match_nodeid_flag = 1;
1184 if (strcmp(status_str,
"joined") != 0) {
1191 if (!match_nodeid_flag) {
1206 (void)api->totem_mcast (&iovec, 1,
TOTEM_SAFE);
1222static void message_handler_req_lib_cfg_tryshutdown (
1228 struct qb_list_head *iter;
1270 shutdown_con = (
struct cfg_info *)api->ipc_private_data_get (
conn);
1278 shutdown_expected = 0;
1280 qb_list_for_each(iter, &trackers_list) {
1287 shutdown_expected++;
1294 if (shutdown_expected == 0) {
1323 api->timer_add_duration((
unsigned long long)shutdown_timeout*QB_TIME_NS_IN_MSEC, NULL,
1324 shutdown_timer_fn, &shutdown_timer);
1329 send_test_shutdown(NULL, conn,
CS_OK);
1340static void message_handler_req_lib_cfg_replytoshutdown (
1350 if (!shutdown_con) {
1363 check_shutdown_status();
1376static void message_handler_req_lib_cfg_get_node_addrs (
void *conn,
1382 unsigned int num_interfaces = 0;
1388 size_t res_lib_cfg_get_node_addrs_size;
1393 nodeid = api->totem_nodeid_get();
1395 if (api->totem_ifaces_get(
nodeid, iface_ids, node_ifs,
INTERFACE_MAX, &status, &num_interfaces)) {
1407 if (num_interfaces) {
1410 i < num_interfaces; i++) {
1411 if (node_ifs[i].
family) {
1424static void message_handler_req_lib_cfg_local_get (
void *conn,
const void *msg)
1437static void message_handler_req_lib_cfg_reload_config (
void *conn,
const void *msg)
1449 api->ipc_refcnt_inc(conn);
1454 assert (api->totem_mcast (&iovec, 1,
TOTEM_SAFE) == 0);
1459static void message_handler_req_lib_cfg_reopen_log_files (
void *conn,
const void *msg)
1473 api->ipc_response_send(conn,
#define SERVICE_ID_MAKE(a, b)
totem_configuration_type
The totem_configuration_type enum.
qb_loop_timer_handle corosync_timer_handle_t
corosync_timer_handle_t
#define corosync_fatal_error(err)
unsigned char addr[TOTEMIP_ADDRLEN]
@ CS_LIB_FLOW_CONTROL_REQUIRED
@ CS_LIB_FLOW_CONTROL_NOT_REQUIRED
@ COROSYNC_FATAL_ERROR_EXIT
int coroparse_configparse(icmap_map_t config_map, const char **error_string)
cs_error_t
The cs_error_t enum.
@ CS_ERR_FAILED_OPERATION
struct corosync_service_engine cfg_service_engine
@ MESSAGE_REQ_EXEC_CFG_RELOAD_CONFIG
@ MESSAGE_REQ_EXEC_CFG_SHUTDOWN
@ MESSAGE_REQ_EXEC_CFG_RINGREENABLE
@ MESSAGE_REQ_EXEC_CFG_KILLNODE
@ MESSAGE_REQ_EXEC_CFG_CRYPTO_RECONFIG
#define DEFAULT_SHUTDOWN_TIMEOUT
struct corosync_service_engine * cfg_get_service_engine_ver0(void)
icmap_iter_t icmap_iter_init_r(const icmap_map_t map, const char *prefix)
icmap_iter_init_r
cs_error_t icmap_get_string_r(const icmap_map_t map, const char *key_name, char **str)
cs_error_t icmap_get_uint32(const char *key_name, uint32_t *u32)
cs_error_t icmap_set_uint8(const char *key_name, uint8_t value)
cs_error_t icmap_delete(const char *key_name)
Delete key from map.
struct icmap_map * icmap_map_t
icmap type.
cs_error_t icmap_set_int32(const char *key_name, int32_t value)
cs_error_t icmap_delete_r(const icmap_map_t map, const char *key_name)
icmap_delete_r
int icmap_key_value_eq(const icmap_map_t map1, const char *key_name1, const icmap_map_t map2, const char *key_name2)
Compare value of key with name key_name1 in map1 with key with name key_name2 in map2.
icmap_iter_t icmap_iter_init(const char *prefix)
Initialize iterator with given prefix.
cs_error_t icmap_copy_map(icmap_map_t dst_map, const icmap_map_t src_map)
Copy content of src_map icmap to dst_map icmap.
cs_error_t icmap_init_r(icmap_map_t *result)
Initialize additional (local, reentrant) icmap_map.
const char * icmap_iter_next(icmap_iter_t iter, size_t *value_len, icmap_value_types_t *type)
Return next item in iterator iter.
icmap_map_t icmap_get_global_map(void)
Return global icmap.
qb_map_iter_t * icmap_iter_t
Itterator type.
void icmap_iter_finalize(icmap_iter_t iter)
Finalize iterator.
void icmap_fini_r(const icmap_map_t map)
Finalize local, reentrant icmap.
#define ICMAP_KEYNAME_MAXLEN
Maximum length of key in icmap.
@ CFG_SHUTDOWN_FLAG_REGARDLESS
@ CFG_SHUTDOWN_FLAG_IMMEDIATE
#define CFG_INTERFACE_STATUS_MAX_LEN
#define CFG_INTERFACE_NAME_MAX_LEN
@ MESSAGE_RES_CFG_STATETRACKSTOP
@ MESSAGE_RES_CFG_LOCAL_GET
@ MESSAGE_RES_CFG_RELOAD_CONFIG
@ MESSAGE_RES_CFG_RINGSTATUSGET
@ MESSAGE_RES_CFG_TRYSHUTDOWN
@ MESSAGE_RES_CFG_NODESTATUSGET
@ MESSAGE_RES_CFG_GET_NODE_ADDRS
@ MESSAGE_RES_CFG_REOPEN_LOG_FILES
@ MESSAGE_RES_CFG_TESTSHUTDOWN
@ MESSAGE_RES_CFG_STATETRACKSTART
@ MESSAGE_RES_CFG_KILLNODE
@ MESSAGE_RES_CFG_REPLYTOSHUTDOWN
@ MESSAGE_RES_CFG_RINGREENABLE
#define CFG_MAX_INTERFACES
#define LOGSYS_LEVEL_ERROR
#define log_printf(level, format, args...)
#define LOGSYS_LEVEL_NOTICE
#define TRACE1(format, args...)
#define LOGSYS_DECLARE_SUBSYS(subsys)
The LOGSYS_DECLARE_SUBSYS macro.
cs_error_t logsys_reopen_log_files(void)
#define LOGSYS_LEVEL_DEBUG
enum cfg_info::@326077157174355020027351322202300337371176060125 shutdown_reply
The corosync_api_v1 struct.
The corosync_exec_handler struct.
The corosync_lib_handler struct.
The corosync_service_engine struct.
uint8_t value[CS_MAX_NAME_LENGTH]
The mar_message_source_t struct.
struct qb_ipc_request_header header __attribute__((aligned(8)))
mar_uint32_t phase __attribute__((aligned(8)))
mar_uint32_t nodeid __attribute__((aligned(8)))
mar_name_t reason __attribute__((aligned(8)))
struct qb_ipc_request_header header __attribute__((aligned(8)))
mar_message_source_t source __attribute__((aligned(8)))
struct qb_ipc_request_header header __attribute__((aligned(8)))
mar_message_source_t source __attribute__((aligned(8)))
struct qb_ipc_request_header header __attribute__((aligned(8)))
struct qb_ipc_request_header header __attribute__((aligned(8)))
The req_lib_cfg_get_node_addrs struct.
The req_lib_cfg_killnode struct.
The req_lib_cfg_nodestatusget struct.
The req_lib_cfg_replytoshutdown struct.
The req_lib_cfg_tryshutdown struct.
The res_lib_cfg_get_node_addrs struct.
The res_lib_cfg_killnode struct.
The res_lib_cfg_local_get struct.
The res_lib_cfg_nodestatusget struct.
The res_lib_cfg_reload_config struct.
The res_lib_cfg_reopen_log_files struct.
The res_lib_cfg_replytoshutdown struct.
The res_lib_cfg_ringreenable struct.
The res_lib_cfg_ringstatusget struct.
The res_lib_cfg_testshutdown struct.
struct qb_ipc_response_header header
struct qb_ipc_response_header header
The res_lib_cfg_tryshutdown struct.
The totem_ip_address struct.
@ CRYPTO_RECONFIG_PHASE_CLEANUP
@ CRYPTO_RECONFIG_PHASE_ACTIVATE
void totem_volatile_config_read(struct totem_config *totem_config, icmap_map_t temp_map, const char *deleted_key)
int totemconfig_commit_new_params(struct totem_config *totem_config, icmap_map_t map)
int totem_volatile_config_validate(struct totem_config *totem_config, icmap_map_t temp_map, const char **error_string)
int totem_reread_crypto_config(struct totem_config *totem_config, icmap_map_t map, const char **error_string)
int totemconfig_configure_new_params(struct totem_config *totem_config, icmap_map_t map, const char **error_string)
void totempg_get_config(struct totem_config *config)
int totempg_nodestatus_get(unsigned int nodeid, struct totem_node_status *node_status)
void totempg_put_config(struct totem_config *config)
int totempg_crypto_reconfigure_phase(cfg_message_crypto_reconfig_phase_t phase)
struct memb_ring_id ring_id
struct totem_message_header header