From ae7d60290f450707b2533cbc7c3e0ee632d2a7cf Mon Sep 17 00:00:00 2001 From: Jan Friesse Date: Thu, 20 Aug 2020 17:33:53 +0200 Subject: [PATCH] heuristics: Remove qdevice instance pointer Heuristics is designed to be component of its own, which doesn't depend on qdevice_instance. Removing qdevice_instance pointer was easy as soon as exec notifier got two user data pointers. Signed-off-by: Jan Friesse --- qdevices/corosync-qdevice.c | 3 +- qdevices/qdevice-heuristics-instance.h | 4 +- qdevices/qdevice-heuristics-result-notifier.c | 9 +- qdevices/qdevice-heuristics-result-notifier.h | 11 +- qdevices/qdevice-heuristics.c | 153 ----------------- qdevices/qdevice-heuristics.h | 5 +- qdevices/qdevice-instance.c | 156 ++++++++++++++++++ qdevices/qdevice-instance.h | 2 + qdevices/qdevice-net-heuristics.c | 22 +-- qdevices/qdevice-votequorum.c | 12 +- 10 files changed, 190 insertions(+), 187 deletions(-) diff --git a/qdevices/corosync-qdevice.c b/qdevices/corosync-qdevice.c index b322c93..54eddcf 100644 --- a/qdevices/corosync-qdevice.c +++ b/qdevices/corosync-qdevice.c @@ -196,7 +196,6 @@ main(int argc, char * const argv[]) qdevice_instance_init(&instance, &advanced_settings); qdevice_heuristics_init(&instance.heuristics_instance, &advanced_settings); - instance.heuristics_instance.qdevice_instance_ptr = &instance; qdevice_cmap_init(&instance); if (qdevice_log_init(&instance, foreground, force_debug, bump_log_priority) == -1) { @@ -264,7 +263,7 @@ main(int argc, char * const argv[]) } log(LOG_DEBUG, "Waiting for initial heuristics exec result"); - if (qdevice_heuristics_wait_for_initial_exec_result(&instance.heuristics_instance) != 0) { + if (qdevice_instance_wait_for_initial_heuristics_exec_result(&instance) != 0) { return (EXIT_FAILURE); } diff --git a/qdevices/qdevice-heuristics-instance.h b/qdevices/qdevice-heuristics-instance.h index 51e7ea1..6bc23bb 100644 --- a/qdevices/qdevice-heuristics-instance.h +++ b/qdevices/qdevice-heuristics-instance.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017 Red Hat, Inc. + * Copyright (c) 2015-2020 Red Hat, Inc. * * All rights reserved. * @@ -66,8 +66,6 @@ struct qdevice_heuristics_instance { struct qdevice_heuristics_exec_list exec_list; - struct qdevice_instance *qdevice_instance_ptr; - struct qdevice_heuristics_result_notifier_list exec_result_notifier_list; }; diff --git a/qdevices/qdevice-heuristics-result-notifier.c b/qdevices/qdevice-heuristics-result-notifier.c index a7adf1e..fa1a802 100644 --- a/qdevices/qdevice-heuristics-result-notifier.c +++ b/qdevices/qdevice-heuristics-result-notifier.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017 Red Hat, Inc. + * Copyright (c) 2015-2020 Red Hat, Inc. * * All rights reserved. * @@ -61,7 +61,8 @@ qdevice_heuristics_result_notifier_list_get(struct qdevice_heuristics_result_not struct qdevice_heuristics_result_notifier_item * qdevice_heuristics_result_notifier_list_add(struct qdevice_heuristics_result_notifier_list *notifier_list, - qdevice_heuristics_result_notifier_callback callback) + qdevice_heuristics_result_notifier_callback callback, + void *user_data1, void *user_data2) { struct qdevice_heuristics_result_notifier_item *item; @@ -77,6 +78,8 @@ qdevice_heuristics_result_notifier_list_add(struct qdevice_heuristics_result_not memset(item, 0, sizeof(*item)); item->callback = callback; item->active = 0; + item->user_data1 = user_data1; + item->user_data2 = user_data2; TAILQ_INSERT_TAIL(notifier_list, item, entries); @@ -125,7 +128,7 @@ qdevice_heuristics_result_notifier_notify(struct qdevice_heuristics_result_notif continue ; } - if (item->callback(heuristics_instance, seq_number, exec_result) != 0) { + if (item->callback(seq_number, exec_result, item->user_data1, item->user_data2) != 0) { return (-1); } } diff --git a/qdevices/qdevice-heuristics-result-notifier.h b/qdevices/qdevice-heuristics-result-notifier.h index d32d787..aae34a3 100644 --- a/qdevices/qdevice-heuristics-result-notifier.h +++ b/qdevices/qdevice-heuristics-result-notifier.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017 Red Hat, Inc. + * Copyright (c) 2015-2020 Red Hat, Inc. * * All rights reserved. * @@ -46,12 +46,14 @@ extern "C" { #endif -typedef int (*qdevice_heuristics_result_notifier_callback)(void *heuristics_instance, uint32_t seq_number, - enum qdevice_heuristics_exec_result exec_result); +typedef int (*qdevice_heuristics_result_notifier_callback)(uint32_t seq_number, + enum qdevice_heuristics_exec_result exec_result, void *user_data1, void *user_data2); struct qdevice_heuristics_result_notifier_item { qdevice_heuristics_result_notifier_callback callback; int active; + void *user_data1; + void *user_data2; TAILQ_ENTRY(qdevice_heuristics_result_notifier_item) entries; }; @@ -62,7 +64,8 @@ extern void qdevice_heuristics_result_notifier_list_init( extern struct qdevice_heuristics_result_notifier_item *qdevice_heuristics_result_notifier_list_add( struct qdevice_heuristics_result_notifier_list *notifier_list, - qdevice_heuristics_result_notifier_callback callback); + qdevice_heuristics_result_notifier_callback callback, + void *user_data, void *user_data2); extern struct qdevice_heuristics_result_notifier_item *qdevice_heuristics_result_notifier_list_get( struct qdevice_heuristics_result_notifier_list *notifier_list, diff --git a/qdevices/qdevice-heuristics.c b/qdevices/qdevice-heuristics.c index 4820f9e..8529a53 100644 --- a/qdevices/qdevice-heuristics.c +++ b/qdevices/qdevice-heuristics.c @@ -49,8 +49,6 @@ #include "qdevice-votequorum.h" #include "utils.h" -#define QDEVICE_HEURISTICS_WAIT_FOR_INITIAL_EXEC_RESULT_MAX_PFDS 5 - void qdevice_heuristics_init(struct qdevice_heuristics_instance *instance, struct qdevice_advanced_settings *advanced_settings) @@ -228,154 +226,3 @@ qdevice_heuristics_change_exec_list(struct qdevice_heuristics_instance *instance return (0); } - - -int -qdevice_heuristics_wait_for_initial_exec_result(struct qdevice_heuristics_instance *instance) -{ - struct pollfd pfds[QDEVICE_HEURISTICS_WAIT_FOR_INITIAL_EXEC_RESULT_MAX_PFDS]; - int no_pfds; - int poll_res; - int timeout; - int i; - int case_processed; - int res; - - while (!instance->qdevice_instance_ptr->vq_node_list_initial_heuristics_finished) { - no_pfds = 0; - - assert(no_pfds < QDEVICE_HEURISTICS_WAIT_FOR_INITIAL_EXEC_RESULT_MAX_PFDS); - pfds[no_pfds].fd = instance->pipe_log_recv; - pfds[no_pfds].events = POLLIN; - pfds[no_pfds].revents = 0; - no_pfds++; - - assert(no_pfds < QDEVICE_HEURISTICS_WAIT_FOR_INITIAL_EXEC_RESULT_MAX_PFDS); - pfds[no_pfds].fd = instance->pipe_cmd_recv; - pfds[no_pfds].events = POLLIN; - pfds[no_pfds].revents = 0; - no_pfds++; - - assert(no_pfds < QDEVICE_HEURISTICS_WAIT_FOR_INITIAL_EXEC_RESULT_MAX_PFDS); - pfds[no_pfds].fd = instance->qdevice_instance_ptr->votequorum_poll_fd; - pfds[no_pfds].events = POLLIN; - pfds[no_pfds].revents = 0; - no_pfds++; - - if (!send_buffer_list_empty(&instance->cmd_out_buffer_list)) { - assert(no_pfds < QDEVICE_HEURISTICS_WAIT_FOR_INITIAL_EXEC_RESULT_MAX_PFDS); - pfds[no_pfds].fd = instance->pipe_cmd_send; - pfds[no_pfds].events = POLLOUT; - pfds[no_pfds].revents = 0; - no_pfds++; - } - - /* - * We know this is never larger than QDEVICE_DEFAULT_HEURISTICS_MAX_TIMEOUT * 2 - */ - timeout = (int)instance->sync_timeout * 2; - - poll_res = poll(pfds, no_pfds, timeout); - if (poll_res > 0) { - for (i = 0; i < no_pfds; i++) { - if (pfds[i].revents & POLLIN) { - case_processed = 0; - switch (i) { - case 0: - case_processed = 1; - - res = qdevice_heuristics_log_read_from_pipe(instance); - if (res == -1) { - return (-1); - } - break; - case 1: - case_processed = 1; - res = qdevice_heuristics_cmd_read_from_pipe(instance); - if (res == -1) { - return (-1); - } - break; - case 2: - case_processed = 1; - res = qdevice_votequorum_dispatch(instance->qdevice_instance_ptr); - if (res == -1) { - return (-1); - } - case 3: - /* - * Read on heuristics cmd send fs shouldn't happen - */ - break; - } - - if (!case_processed) { - log(LOG_CRIT, "Unhandled read on poll descriptor %u", i); - exit(EXIT_FAILURE); - } - } - - if (pfds[i].revents & POLLOUT) { - case_processed = 0; - switch (i) { - case 0: - case 1: - case 2: - /* - * Write on heuristics log, cmd recv or vq shouldn't happen - */ - break; - case 3: - case_processed = 1; - res = qdevice_heuristics_cmd_write(instance); - if (res == -1) { - return (-1); - } - break; - } - - if (!case_processed) { - log(LOG_CRIT, "Unhandled write on poll descriptor %u", i); - exit(EXIT_FAILURE); - } - } - - if ((pfds[i].revents & (POLLERR|POLLHUP|POLLNVAL)) && - !(pfds[i].revents & (POLLIN|POLLOUT))) { - switch (i) { - case 0: - case 1: - case 3: - /* - * Closed pipe doesn't mean return of POLLIN. To display - * better log message, we call read log as if POLLIN would - * be set. - */ - res = qdevice_heuristics_log_read_from_pipe(instance); - if (res == -1) { - return (-1); - } - - log(LOG_ERR, "POLLERR (%u) on heuristics pipe. Exiting", - pfds[i].revents); - return (-1); - break; - case 2: - log(LOG_ERR, "POLLERR (%u) on corosync socket. Exiting", - pfds[i].revents); - return (-1); - break; - } - } - } - } else if (poll_res == 0) { - log(LOG_ERR, "Timeout waiting for initial heuristics exec result"); - return (-1); - } else { - log_err(LOG_ERR, "Initial heuristics exec result poll failed"); - return (-1); - } - } - - return (0); -} diff --git a/qdevices/qdevice-heuristics.h b/qdevices/qdevice-heuristics.h index a5d2880..3d9ca61 100644 --- a/qdevices/qdevice-heuristics.h +++ b/qdevices/qdevice-heuristics.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017 Red Hat, Inc. + * Copyright (c) 2015-2020 Red Hat, Inc. * * All rights reserved. * @@ -61,9 +61,6 @@ extern int qdevice_heuristics_change_exec_list( struct qdevice_heuristics_instance *instance, const struct qdevice_heuristics_exec_list *new_exec_list, int sync_in_progress); -extern int qdevice_heuristics_wait_for_initial_exec_result( - struct qdevice_heuristics_instance *instance); - #ifdef __cplusplus } #endif diff --git a/qdevices/qdevice-instance.c b/qdevices/qdevice-instance.c index 7d75032..f50e273 100644 --- a/qdevices/qdevice-instance.c +++ b/qdevices/qdevice-instance.c @@ -39,6 +39,10 @@ #include "qdevice-config.h" #include "qdevice-instance.h" #include "qdevice-heuristics-exec-list.h" +/*TODO Remove this 3 line includes when porting on pr-poll-loop */ +#include "qdevice-heuristics.h" +#include "qdevice-heuristics-cmd.h" +#include "qdevice-votequorum.h" #include "qdevice-model.h" #include "utils.h" @@ -294,3 +298,155 @@ qdevice_instance_configure_from_cmap(struct qdevice_instance *instance) return (0); } + +#define QDEVICE_HEURISTICS_WAIT_FOR_INITIAL_EXEC_RESULT_MAX_PFDS 5 + +int +qdevice_instance_wait_for_initial_heuristics_exec_result(struct qdevice_instance *instance) +{ + struct pollfd pfds[QDEVICE_HEURISTICS_WAIT_FOR_INITIAL_EXEC_RESULT_MAX_PFDS]; + int no_pfds; + int poll_res; + int timeout; + int i; + int case_processed; + int res; + + while (!instance->vq_node_list_initial_heuristics_finished) { + no_pfds = 0; + + assert(no_pfds < QDEVICE_HEURISTICS_WAIT_FOR_INITIAL_EXEC_RESULT_MAX_PFDS); + pfds[no_pfds].fd = instance->heuristics_instance.pipe_log_recv; + pfds[no_pfds].events = POLLIN; + pfds[no_pfds].revents = 0; + no_pfds++; + + assert(no_pfds < QDEVICE_HEURISTICS_WAIT_FOR_INITIAL_EXEC_RESULT_MAX_PFDS); + pfds[no_pfds].fd = instance->heuristics_instance.pipe_cmd_recv; + pfds[no_pfds].events = POLLIN; + pfds[no_pfds].revents = 0; + no_pfds++; + + assert(no_pfds < QDEVICE_HEURISTICS_WAIT_FOR_INITIAL_EXEC_RESULT_MAX_PFDS); + pfds[no_pfds].fd = instance->votequorum_poll_fd; + pfds[no_pfds].events = POLLIN; + pfds[no_pfds].revents = 0; + no_pfds++; + + if (!send_buffer_list_empty(&instance->heuristics_instance.cmd_out_buffer_list)) { + assert(no_pfds < QDEVICE_HEURISTICS_WAIT_FOR_INITIAL_EXEC_RESULT_MAX_PFDS); + pfds[no_pfds].fd = instance->heuristics_instance.pipe_cmd_send; + pfds[no_pfds].events = POLLOUT; + pfds[no_pfds].revents = 0; + no_pfds++; + } + + /* + * We know this is never larger than QDEVICE_DEFAULT_HEURISTICS_MAX_TIMEOUT * 2 + */ + timeout = (int)instance->heuristics_instance.sync_timeout * 2; + + poll_res = poll(pfds, no_pfds, timeout); + if (poll_res > 0) { + for (i = 0; i < no_pfds; i++) { + if (pfds[i].revents & POLLIN) { + case_processed = 0; + switch (i) { + case 0: + case_processed = 1; + + res = qdevice_heuristics_log_read_from_pipe(&instance->heuristics_instance); + if (res == -1) { + return (-1); + } + break; + case 1: + case_processed = 1; + res = qdevice_heuristics_cmd_read_from_pipe(&instance->heuristics_instance); + if (res == -1) { + return (-1); + } + break; + case 2: + case_processed = 1; + res = qdevice_votequorum_dispatch(instance); + if (res == -1) { + return (-1); + } + case 3: + /* + * Read on heuristics cmd send fs shouldn't happen + */ + break; + } + + if (!case_processed) { + log(LOG_CRIT, "Unhandled read on poll descriptor %u", i); + exit(EXIT_FAILURE); + } + } + + if (pfds[i].revents & POLLOUT) { + case_processed = 0; + switch (i) { + case 0: + case 1: + case 2: + /* + * Write on heuristics log, cmd recv or vq shouldn't happen + */ + break; + case 3: + case_processed = 1; + res = qdevice_heuristics_cmd_write(&instance->heuristics_instance); + if (res == -1) { + return (-1); + } + break; + } + + if (!case_processed) { + log(LOG_CRIT, "Unhandled write on poll descriptor %u", i); + exit(EXIT_FAILURE); + } + } + + if ((pfds[i].revents & (POLLERR|POLLHUP|POLLNVAL)) && + !(pfds[i].revents & (POLLIN|POLLOUT))) { + switch (i) { + case 0: + case 1: + case 3: + /* + * Closed pipe doesn't mean return of POLLIN. To display + * better log message, we call read log as if POLLIN would + * be set. + */ + res = qdevice_heuristics_log_read_from_pipe(&instance->heuristics_instance); + if (res == -1) { + return (-1); + } + + log(LOG_ERR, "POLLERR (%u) on heuristics pipe. Exiting", + pfds[i].revents); + return (-1); + break; + case 2: + log(LOG_ERR, "POLLERR (%u) on corosync socket. Exiting", + pfds[i].revents); + return (-1); + break; + } + } + } + } else if (poll_res == 0) { + log(LOG_ERR, "Timeout waiting for initial heuristics exec result"); + return (-1); + } else { + log_err(LOG_ERR, "Initial heuristics exec result poll failed"); + return (-1); + } + } + + return (0); +} diff --git a/qdevices/qdevice-instance.h b/qdevices/qdevice-instance.h index d137e52..129ed58 100644 --- a/qdevices/qdevice-instance.h +++ b/qdevices/qdevice-instance.h @@ -129,6 +129,8 @@ extern int qdevice_instance_configure_from_cmap(struct qdevice_instance *instanc extern int qdevice_instance_configure_from_cmap_heuristics(struct qdevice_instance *instance); +extern int qdevice_instance_wait_for_initial_heuristics_exec_result(struct qdevice_instance *instance); + #ifdef __cplusplus } #endif diff --git a/qdevices/qdevice-net-heuristics.c b/qdevices/qdevice-net-heuristics.c index f95e118..5757fab 100644 --- a/qdevices/qdevice-net-heuristics.c +++ b/qdevices/qdevice-net-heuristics.c @@ -60,8 +60,8 @@ qdevice_net_heuristics_exec_result_to_tlv(enum qdevice_heuristics_exec_result ex } static int -qdevice_net_regular_heuristics_exec_result_callback(void *heuristics_instance_ptr, - uint32_t seq_number, enum qdevice_heuristics_exec_result exec_result) +qdevice_net_regular_heuristics_exec_result_callback(uint32_t seq_number, + enum qdevice_heuristics_exec_result exec_result, void *user_data1, void *user_data2) { struct qdevice_heuristics_instance *heuristics_instance; struct qdevice_instance *instance; @@ -70,8 +70,8 @@ qdevice_net_regular_heuristics_exec_result_callback(void *heuristics_instance_pt enum tlv_vote vote; enum tlv_heuristics heuristics; - heuristics_instance = (struct qdevice_heuristics_instance *)heuristics_instance_ptr; - instance = heuristics_instance->qdevice_instance_ptr; + instance = (struct qdevice_instance *)user_data1; + heuristics_instance = &instance->heuristics_instance; net_instance = instance->model_data; if (qdevice_heuristics_result_notifier_list_set_active(&heuristics_instance->exec_result_notifier_list, @@ -179,8 +179,8 @@ qdevice_net_regular_heuristics_exec_result_callback(void *heuristics_instance_pt } static int -qdevice_net_connect_heuristics_exec_result_callback(void *heuristics_instance_ptr, - uint32_t seq_number, enum qdevice_heuristics_exec_result exec_result) +qdevice_net_connect_heuristics_exec_result_callback(uint32_t seq_number, + enum qdevice_heuristics_exec_result exec_result, void *user_data1, void *user_data2) { struct qdevice_heuristics_instance *heuristics_instance; struct qdevice_instance *instance; @@ -193,8 +193,8 @@ qdevice_net_connect_heuristics_exec_result_callback(void *heuristics_instance_pt struct tlv_ring_id tlv_rid; enum tlv_quorate quorate; - heuristics_instance = (struct qdevice_heuristics_instance *)heuristics_instance_ptr; - instance = heuristics_instance->qdevice_instance_ptr; + instance = (struct qdevice_instance *)user_data1; + heuristics_instance = &instance->heuristics_instance; net_instance = instance->model_data; if (qdevice_heuristics_result_notifier_list_set_active(&heuristics_instance->exec_result_notifier_list, @@ -417,7 +417,8 @@ qdevice_net_heuristics_init(struct qdevice_net_instance *net_instance) if (qdevice_heuristics_result_notifier_list_add( &net_instance->qdevice_instance_ptr->heuristics_instance.exec_result_notifier_list, - qdevice_net_regular_heuristics_exec_result_callback) == NULL) { + qdevice_net_regular_heuristics_exec_result_callback, + net_instance->qdevice_instance_ptr, NULL) == NULL) { log(LOG_ERR, "Can't add net regular heuristics exec callback into notifier"); return (-1); @@ -425,7 +426,8 @@ qdevice_net_heuristics_init(struct qdevice_net_instance *net_instance) if (qdevice_heuristics_result_notifier_list_add( &net_instance->qdevice_instance_ptr->heuristics_instance.exec_result_notifier_list, - qdevice_net_connect_heuristics_exec_result_callback) == NULL) { + qdevice_net_connect_heuristics_exec_result_callback, + net_instance->qdevice_instance_ptr, NULL) == NULL) { log(LOG_ERR, "Can't add net connect heuristics exec callback into notifier"); return (-1); diff --git a/qdevices/qdevice-votequorum.c b/qdevices/qdevice-votequorum.c index bd3eee5..c3750a3 100644 --- a/qdevices/qdevice-votequorum.c +++ b/qdevices/qdevice-votequorum.c @@ -84,14 +84,10 @@ qdevice_votequorum_quorum_notify_callback(votequorum_handle_t votequorum_handle, static int qdevice_votequorum_heuristics_exec_result_callback( - void *heuristics_instance_ptr, - uint32_t seq_number, enum qdevice_heuristics_exec_result exec_result) + uint32_t seq_number, enum qdevice_heuristics_exec_result exec_result, + void *user_data1, void *user_data2) { - struct qdevice_heuristics_instance *heuristics_instance; - struct qdevice_instance *instance; - - heuristics_instance = (struct qdevice_heuristics_instance *)heuristics_instance_ptr; - instance = heuristics_instance->qdevice_instance_ptr; + struct qdevice_instance *instance = (struct qdevice_instance *)user_data1; if (qdevice_heuristics_result_notifier_list_set_active( &instance->heuristics_instance.exec_result_notifier_list, @@ -257,7 +253,7 @@ qdevice_votequorum_init(struct qdevice_instance *instance) } if (qdevice_heuristics_result_notifier_list_add(&instance->heuristics_instance.exec_result_notifier_list, - qdevice_votequorum_heuristics_exec_result_callback) == NULL) { + qdevice_votequorum_heuristics_exec_result_callback, instance, NULL) == NULL) { log(LOG_CRIT, "Can't add votequrorum heuristics exec callback into notifier"); exit(EXIT_FAILURE); }