38 #include <sys/types.h> 40 #include <sys/socket.h> 42 #include <netinet/in.h> 43 #include <arpa/inet.h> 54 #include <qb/qbipc_common.h> 78 #define DEFAULT_SHUTDOWN_TIMEOUT 5 86 static struct cfg_info *shutdown_con;
87 static uint32_t shutdown_flags;
88 static int shutdown_yes;
89 static int shutdown_no;
90 static int shutdown_expected;
100 static void cfg_confchg_fn (
102 const unsigned int *member_list,
size_t member_list_entries,
103 const unsigned int *left_list,
size_t left_list_entries,
104 const unsigned int *joined_list,
size_t joined_list_entries,
109 static struct corosync_api_v1 *api;
111 static int cfg_lib_init_fn (
void *
conn);
113 static int cfg_lib_exit_fn (
void *
conn);
115 static void message_handler_req_exec_cfg_ringreenable (
119 static void message_handler_req_exec_cfg_killnode (
123 static void message_handler_req_exec_cfg_shutdown (
127 static void message_handler_req_exec_cfg_reload_config (
131 static void exec_cfg_killnode_endian_convert (
void *msg);
133 static void message_handler_req_lib_cfg_ringstatusget (
137 static void message_handler_req_lib_cfg_ringreenable (
141 static void message_handler_req_lib_cfg_killnode (
145 static void message_handler_req_lib_cfg_tryshutdown (
149 static void message_handler_req_lib_cfg_replytoshutdown (
153 static void message_handler_req_lib_cfg_get_node_addrs (
157 static void message_handler_req_lib_cfg_local_get (
161 static void message_handler_req_lib_cfg_reload_config (
175 .lib_handler_fn = message_handler_req_lib_cfg_ringreenable,
179 .lib_handler_fn = message_handler_req_lib_cfg_killnode,
183 .lib_handler_fn = message_handler_req_lib_cfg_tryshutdown,
187 .lib_handler_fn = message_handler_req_lib_cfg_replytoshutdown,
191 .lib_handler_fn = message_handler_req_lib_cfg_get_node_addrs,
195 .lib_handler_fn = message_handler_req_lib_cfg_local_get,
199 .lib_handler_fn = message_handler_req_lib_cfg_reload_config,
210 .exec_handler_fn = message_handler_req_exec_cfg_killnode,
211 .exec_endian_convert_fn = exec_cfg_killnode_endian_convert
214 .exec_handler_fn = message_handler_req_exec_cfg_shutdown,
217 .exec_handler_fn = message_handler_req_exec_cfg_reload_config,
225 .
name =
"corosync configuration service",
228 .private_data_size =
sizeof(
struct cfg_info),
231 .lib_init_fn = cfg_lib_init_fn,
232 .lib_exit_fn = cfg_lib_exit_fn,
233 .lib_engine = cfg_lib_engine,
235 .exec_init_fn = cfg_exec_init_fn,
236 .exec_engine = cfg_exec_engine,
238 .confchg_fn = cfg_confchg_fn
243 return (&cfg_service_engine);
247 struct qb_ipc_request_header header __attribute__((aligned(8)));
252 struct qb_ipc_request_header header __attribute__((aligned(8)));
257 struct qb_ipc_request_header header __attribute__((aligned(8)));
263 struct qb_ipc_request_header header __attribute__((aligned(8)));
268 static char *cfg_exec_init_fn (
269 struct corosync_api_v1 *corosync_api_v1)
271 api = corosync_api_v1;
273 list_init(&trackers_list);
277 static void cfg_confchg_fn (
279 const unsigned int *member_list,
size_t member_list_entries,
280 const unsigned int *left_list,
size_t left_list_entries,
281 const unsigned int *joined_list,
size_t joined_list_entries,
289 static int send_shutdown(
void)
295 req_exec_cfg_shutdown.header.size =
296 sizeof (
struct req_exec_cfg_shutdown);
300 iovec.iov_base = (
char *)&req_exec_cfg_shutdown;
301 iovec.iov_len =
sizeof (
struct req_exec_cfg_shutdown);
309 static void send_test_shutdown(
void *only_conn,
void *exclude_conn,
int status)
315 res_lib_cfg_testshutdown.header.size =
sizeof(
struct res_lib_cfg_testshutdown);
317 res_lib_cfg_testshutdown.header.error = status;
318 res_lib_cfg_testshutdown.
flags = shutdown_flags;
321 TRACE1(
"sending testshutdown to only %p", only_conn);
323 sizeof(res_lib_cfg_testshutdown));
325 for (iter = trackers_list.
next; iter != &trackers_list; iter = iter->
next) {
328 if (ci->
conn != exclude_conn) {
331 sizeof(res_lib_cfg_testshutdown));
338 static void check_shutdown_status(
void)
353 if (shutdown_yes + shutdown_no >= shutdown_expected) {
358 if (shutdown_yes >= shutdown_expected ||
360 TRACE1(
"shutdown confirmed");
362 res_lib_cfg_tryshutdown.header.size =
sizeof(
struct res_lib_cfg_tryshutdown);
364 res_lib_cfg_tryshutdown.header.error =
CS_OK;
370 sizeof(res_lib_cfg_tryshutdown));
381 TRACE1(
"shutdown cancelled");
382 res_lib_cfg_tryshutdown.header.size =
sizeof(
struct res_lib_cfg_tryshutdown);
384 res_lib_cfg_tryshutdown.header.error =
CS_ERR_BUSY;
390 sizeof(res_lib_cfg_tryshutdown));
395 shutdown_yes, shutdown_no, shutdown_flags);
404 static void shutdown_timer_fn(
void *arg)
411 shutdown_no = shutdown_expected;
412 check_shutdown_status();
418 static void remove_ci_from_shutdown(
struct cfg_info *ci)
426 if (ci == shutdown_con) {
431 if (!list_empty(&ci->
list)) {
433 list_init(&ci->
list);
451 check_shutdown_status();
457 int cfg_lib_exit_fn (
void *
conn)
462 remove_ci_from_shutdown(ci);
467 static int cfg_lib_init_fn (
void *
conn)
472 list_init(&ci->
list);
481 static void message_handler_req_exec_cfg_ringreenable (
493 res_lib_cfg_ringreenable.header.size =
sizeof (
struct res_lib_cfg_ringreenable);
494 res_lib_cfg_ringreenable.header.error =
CS_OK;
496 req_exec_cfg_ringreenable->source.conn,
497 &res_lib_cfg_ringreenable,
498 sizeof (
struct res_lib_cfg_ringreenable));
505 static void exec_cfg_killnode_endian_convert (
void *msg)
508 (
struct req_exec_cfg_killnode *)msg;
511 swab_mar_name_t(&req_exec_cfg_killnode->reason);
516 static void message_handler_req_exec_cfg_killnode (
527 marshall_from_mar_name_t(&reason, &req_exec_cfg_killnode->reason);
529 nodeid, reason.
value);
538 static void message_handler_req_exec_cfg_shutdown (
552 static int nullcheck_strcmp(
const char* left,
const char *right)
562 return strcmp(left, right);
568 static void delete_and_notify_if_changed(
icmap_map_t temp_map,
const char *key_name)
583 static void remove_ro_entries(
icmap_map_t temp_map)
585 delete_and_notify_if_changed(temp_map,
"totem.secauth");
586 delete_and_notify_if_changed(temp_map,
"totem.crypto_hash");
587 delete_and_notify_if_changed(temp_map,
"totem.crypto_cipher");
588 delete_and_notify_if_changed(temp_map,
"totem.version");
589 delete_and_notify_if_changed(temp_map,
"totem.threads");
590 delete_and_notify_if_changed(temp_map,
"totem.ip_version");
591 delete_and_notify_if_changed(temp_map,
"totem.rrp_mode");
592 delete_and_notify_if_changed(temp_map,
"totem.netmtu");
593 delete_and_notify_if_changed(temp_map,
"totem.interface.ringnumber");
594 delete_and_notify_if_changed(temp_map,
"totem.interface.bindnetaddr");
595 delete_and_notify_if_changed(temp_map,
"totem.interface.mcastaddr");
596 delete_and_notify_if_changed(temp_map,
"totem.interface.broadcast");
597 delete_and_notify_if_changed(temp_map,
"totem.interface.mcastport");
598 delete_and_notify_if_changed(temp_map,
"totem.interface.ttl");
599 delete_and_notify_if_changed(temp_map,
"totem.vsftype");
600 delete_and_notify_if_changed(temp_map,
"totem.transport");
601 delete_and_notify_if_changed(temp_map,
"totem.cluster_name");
602 delete_and_notify_if_changed(temp_map,
"quorum.provider");
603 delete_and_notify_if_changed(temp_map,
"qb.ipc_type");
613 static void remove_deleted_entries(
icmap_map_t temp_map,
const char *prefix)
617 const char *old_key, *new_key;
626 while (old_key || new_key) {
627 ret = nullcheck_strcmp(old_key, new_key);
628 if ((ret < 0 && old_key) || !new_key) {
638 ret = nullcheck_strcmp(old_key, new_key);
639 }
while (ret < 0 && old_key);
641 else if ((ret > 0 && new_key) || !old_key) {
651 ret = nullcheck_strcmp(old_key, new_key);
652 }
while (ret > 0 && new_key);
666 static void message_handler_req_exec_cfg_reload_config (
673 const char *error_string;
702 remove_deleted_entries(temp_map,
"logging.");
703 remove_deleted_entries(temp_map,
"totem.");
704 remove_deleted_entries(temp_map,
"nodelist.");
705 remove_deleted_entries(temp_map,
"quorum.");
708 remove_ro_entries(temp_map);
729 res_lib_cfg_reload_config.header.size =
sizeof(res_lib_cfg_reload_config);
731 res_lib_cfg_reload_config.header.error = res;
733 &res_lib_cfg_reload_config,
734 sizeof(res_lib_cfg_reload_config));
744 static void message_handler_req_lib_cfg_ringstatusget (
750 unsigned int iface_count;
752 const char *totem_ip_string;
759 res_lib_cfg_ringstatusget.header.size =
sizeof (
struct res_lib_cfg_ringstatusget);
770 res_lib_cfg_ringstatusget.interface_count = iface_count;
772 for (i = 0; i < iface_count; i++) {
788 strcpy ((
char *)&res_lib_cfg_ringstatusget.interface_status[i],
790 strcpy ((
char *)&res_lib_cfg_ringstatusget.interface_name[i],
795 res_lib_cfg_ringstatusget.header.error = res;
798 &res_lib_cfg_ringstatusget,
799 sizeof (
struct res_lib_cfg_ringstatusget));
804 static void message_handler_req_lib_cfg_ringreenable (
812 req_exec_cfg_ringreenable.header.size =
813 sizeof (
struct req_exec_cfg_ringreenable);
819 iovec.iov_base = (
char *)&req_exec_cfg_ringreenable;
820 iovec.iov_len =
sizeof (
struct req_exec_cfg_ringreenable);
827 static void message_handler_req_lib_cfg_killnode (
837 req_exec_cfg_killnode.header.size =
838 sizeof (
struct req_exec_cfg_killnode);
841 req_exec_cfg_killnode.nodeid = req_lib_cfg_killnode->nodeid;
842 marshall_to_mar_name_t(&req_exec_cfg_killnode.reason, &req_lib_cfg_killnode->reason);
844 iovec.iov_base = (
char *)&req_exec_cfg_killnode;
845 iovec.iov_len =
sizeof (
struct req_exec_cfg_killnode);
849 res_lib_cfg_killnode.header.size =
sizeof(
struct res_lib_cfg_killnode);
851 res_lib_cfg_killnode.header.error =
CS_OK;
854 sizeof(res_lib_cfg_killnode));
860 static void message_handler_req_lib_cfg_tryshutdown (
878 res_lib_cfg_tryshutdown.header.size =
sizeof(
struct res_lib_cfg_tryshutdown);
880 res_lib_cfg_tryshutdown.header.error =
CS_OK;
882 sizeof(res_lib_cfg_tryshutdown));
894 res_lib_cfg_tryshutdown.header.size =
sizeof(
struct res_lib_cfg_tryshutdown);
899 sizeof(res_lib_cfg_tryshutdown));
909 shutdown_flags = req_lib_cfg_tryshutdown->
flags;
916 shutdown_expected = 0;
918 for (iter = trackers_list.
next; iter != &trackers_list; iter = iter->
next) {
932 if (shutdown_expected == 0) {
935 res_lib_cfg_tryshutdown.header.size =
sizeof(
struct res_lib_cfg_tryshutdown);
937 res_lib_cfg_tryshutdown.header.error =
CS_OK;
943 sizeof(res_lib_cfg_tryshutdown));
962 shutdown_timer_fn, &shutdown_timer);
978 static void message_handler_req_lib_cfg_replytoshutdown (
993 if (req_lib_cfg_replytoshutdown->
response) {
1001 check_shutdown_status();
1004 res_lib_cfg_replytoshutdown.header.error = status;
1006 res_lib_cfg_replytoshutdown.header.size =
sizeof(res_lib_cfg_replytoshutdown);
1009 sizeof(res_lib_cfg_replytoshutdown));
1014 static void message_handler_req_lib_cfg_get_node_addrs (
void *
conn,
1020 unsigned int num_interfaces = 0;
1025 unsigned int nodeid = req_lib_cfg_get_node_addrs->
nodeid;
1031 api->
totem_ifaces_get(nodeid, node_ifs, INTERFACE_MAX, &status, &num_interfaces);
1033 res_lib_cfg_get_node_addrs->header.size =
sizeof(
struct res_lib_cfg_get_node_addrs) + (num_interfaces *
TOTEMIP_ADDRLEN);
1035 res_lib_cfg_get_node_addrs->header.error = ret;
1036 res_lib_cfg_get_node_addrs->
num_addrs = num_interfaces;
1037 if (num_interfaces) {
1038 res_lib_cfg_get_node_addrs->
family = node_ifs[0].
family;
1039 for (i = 0, addr_buf = (
char *)res_lib_cfg_get_node_addrs->
addrs;
1049 static void message_handler_req_lib_cfg_local_get (
void *
conn,
const void *msg)
1053 res_lib_cfg_local_get.header.size =
sizeof(res_lib_cfg_local_get);
1055 res_lib_cfg_local_get.header.error =
CS_OK;
1059 sizeof(res_lib_cfg_local_get));
1062 static void message_handler_req_lib_cfg_reload_config (
void *
conn,
const void *msg)
1069 req_exec_cfg_reload_config.header.size =
1070 sizeof (
struct req_exec_cfg_reload_config);
1076 iovec.iov_base = (
char *)&req_exec_cfg_reload_config;
1077 iovec.iov_len =
sizeof (
struct req_exec_cfg_reload_config);
void *(* ipc_private_data_get)(void *conn)
void(* timer_delete)(corosync_timer_handle_t timer_handle)
int(* timer_add_duration)(unsigned long long nanoseconds_in_future, void *data, void(*timer_nf)(void *data), corosync_timer_handle_t *handle)
const char * icmap_iter_next(icmap_iter_t iter, size_t *value_len, icmap_value_types_t *type)
#define CFG_INTERFACE_STATUS_MAX_LEN
cs_error_t icmap_copy_map(icmap_map_t dst_map, const icmap_map_t src_map)
void icmap_iter_finalize(icmap_iter_t iter)
void(* shutdown_request)(void)
uint8_t value[CS_MAX_NAME_LENGTH]
int coroparse_configparse(icmap_map_t config_map, const char **error_string)
#define corosync_fatal_error(err)
int(* ipc_response_send)(void *conn, const void *msg, size_t mlen)
LOGSYS_DECLARE_SUBSYS("CFG")
int icmap_key_value_eq(const icmap_map_t map1, const char *key_name1, const icmap_map_t map2, const char *key_name2)
int(* totem_ifaces_get)(unsigned int nodeid, struct totem_ip_address *interfaces, unsigned int interfaces_size, char ***status, unsigned int *iface_count)
unsigned char addr[TOTEMIP_ADDRLEN]
void icmap_fini_r(const icmap_map_t map)
icmap_map_t icmap_get_global_map(void)
int(* totem_mcast)(const struct iovec *iovec, unsigned int iov_len, unsigned int guarantee)
#define log_printf(level, format, args...)
void(* exec_handler_fn)(const void *msg, unsigned int nodeid)
#define SERVICE_ID_MAKE(a, b)
int(* ipc_source_is_local)(const mar_message_source_t *source)
unsigned int(* totem_nodeid_get)(void)
void(* ipc_refcnt_dec)(void *conn)
#define LOGSYS_LEVEL_ERROR
#define TRACE1(format, args...)
#define CFG_INTERFACE_NAME_MAX_LEN
cs_error_t icmap_delete(const char *key_name)
#define LOGSYS_LEVEL_DEBUG
enum cfg_info::@5 shutdown_reply
cs_error_t icmap_get_uint32(const char *key_name, uint32_t *u32)
#define DEFAULT_SHUTDOWN_TIMEOUT
#define CFG_MAX_INTERFACES
const char *(* totem_ip_print)(const struct totem_ip_address *addr)
cs_error_t icmap_delete_r(const icmap_map_t map, const char *key_name)
cs_error_t icmap_init_r(icmap_map_t *result)
qb_loop_timer_handle corosync_timer_handle_t
struct corosync_service_engine cfg_service_engine
#define list_entry(ptr, type, member)
int(* totem_ring_reenable)(void)
#define LOGSYS_LEVEL_NOTICE
cs_error_t icmap_set_uint8(const char *key_name, uint8_t value)
void(* lib_handler_fn)(void *conn, const void *msg)
struct corosync_service_engine * cfg_get_service_engine_ver0(void)
int(* ipc_dispatch_send)(void *conn, const void *msg, size_t mlen)
icmap_iter_t icmap_iter_init_r(const icmap_map_t map, const char *prefix)
icmap_iter_t icmap_iter_init(const char *prefix)
struct memb_ring_id ring_id
void(* ipc_source_set)(mar_message_source_t *source, void *conn)
qb_map_iter_t * icmap_iter_t
void(* ipc_refcnt_inc)(void *conn)