diff --git a/qdevices/qdevice-model-net.c b/qdevices/qdevice-model-net.c index 900cac7e..036ac21e 100644 --- a/qdevices/qdevice-model-net.c +++ b/qdevices/qdevice-model-net.c @@ -1,509 +1,553 @@ /* * Copyright (c) 2015-2016 Red Hat, Inc. * * All rights reserved. * * Author: Jan Friesse (jfriesse@redhat.com) * * This software licensed under BSD license, the text of which follows: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the Red Hat, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "qdevice-model.h" #include "qdevice-model-net.h" #include "qdevice-log.h" #include "qdevice-net-cast-vote-timer.h" #include "qdevice-net-instance.h" #include "qdevice-net-ipc-cmd.h" #include "qdevice-net-algorithm.h" #include "qdevice-net-poll.h" #include "qdevice-net-send.h" #include "qdevice-net-votequorum.h" #include "qnet-config.h" #include "nss-sock.h" int qdevice_model_net_init(struct qdevice_instance *instance) { struct qdevice_net_instance *net_instance; qdevice_log(LOG_DEBUG, "Initializing qdevice_net_instance"); if (qdevice_net_instance_init_from_cmap(instance) != 0) { return (-1); } net_instance = instance->model_data; qdevice_log(LOG_DEBUG, "Registering algorithms"); if (qdevice_net_algorithm_register_all() != 0) { return (-1); } qdevice_log(LOG_DEBUG, "Initializing NSS"); if (nss_sock_init_nss((net_instance->tls_supported != TLV_TLS_UNSUPPORTED ? instance->advanced_settings->net_nss_db_dir : NULL)) != 0) { qdevice_log_nss(LOG_ERR, "Can't init nss"); return (-1); } if (qdevice_net_cast_vote_timer_update(net_instance, TLV_VOTE_ASK_LATER) != 0) { qdevice_log(LOG_ERR, "Can't update cast vote timer"); return (-1); } if (qdevice_net_algorithm_init(net_instance) != 0) { qdevice_log(LOG_ERR, "Algorithm init failed"); return (-1); } return (0); } int qdevice_model_net_destroy(struct qdevice_instance *instance) { struct qdevice_net_instance *net_instance; net_instance = instance->model_data; qdevice_log(LOG_DEBUG, "Destroying algorithm"); qdevice_net_algorithm_destroy(net_instance); qdevice_log(LOG_DEBUG, "Destroying qdevice_net_instance"); qdevice_net_instance_destroy(net_instance); qdevice_log(LOG_DEBUG, "Shutting down NSS"); SSL_ClearSessionCache(); if (NSS_Shutdown() != SECSuccess) { qdevice_log_nss(LOG_WARNING, "Can't shutdown NSS"); } if (PR_Cleanup() != PR_SUCCESS) { qdevice_log_nss(LOG_WARNING, "Can't shutdown NSPR"); } free(net_instance); return (0); } static int qdevice_model_net_timer_connect_timeout(void *data1, void *data2) { struct qdevice_net_instance *instance; instance = (struct qdevice_net_instance *)data1; qdevice_log(LOG_ERR, "Connect timeout"); instance->schedule_disconnect = 1; instance->connect_timer = NULL; instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_CONNECT_TO_THE_SERVER; return (0); } static PRIntn qdevice_model_net_get_af(const struct qdevice_net_instance *instance) { PRIntn af; af = PR_AF_UNSPEC; if (instance->force_ip_version == 4) { af = PR_AF_INET; } if (instance->force_ip_version == 6) { af = PR_AF_INET6; } return (af); } int qdevice_model_net_run(struct qdevice_instance *instance) { struct qdevice_net_instance *net_instance; int try_connect; int res; enum tlv_vote vote; net_instance = instance->model_data; qdevice_log(LOG_DEBUG, "Executing qdevice-net"); try_connect = 1; while (try_connect) { net_instance->state = QDEVICE_NET_INSTANCE_STATE_WAITING_CONNECT; net_instance->socket = NULL; net_instance->connect_timer = timer_list_add(&net_instance->main_timer_list, net_instance->connect_timeout, qdevice_model_net_timer_connect_timeout, (void *)net_instance, NULL); if (net_instance->connect_timer == NULL) { qdevice_log(LOG_CRIT, "Can't schedule connect timer"); try_connect = 0; break; } qdevice_log(LOG_DEBUG, "Trying connect to qnetd server %s:%u (timeout = %ums)", net_instance->host_addr, net_instance->host_port, net_instance->connect_timeout); res = nss_sock_non_blocking_client_init(net_instance->host_addr, net_instance->host_port, qdevice_model_net_get_af(net_instance), &net_instance->non_blocking_client); if (res == -1) { qdevice_log_nss(LOG_ERR, "Can't initialize non blocking client connection"); } res = nss_sock_non_blocking_client_try_next(&net_instance->non_blocking_client); if (res == -1) { qdevice_log_nss(LOG_ERR, "Can't connect to qnetd host"); nss_sock_non_blocking_client_destroy(&net_instance->non_blocking_client); } while (qdevice_net_poll(net_instance) == 0) { }; if (net_instance->connect_timer != NULL) { timer_list_delete(&net_instance->main_timer_list, net_instance->connect_timer); net_instance->connect_timer = NULL; } if (net_instance->echo_request_timer != NULL) { timer_list_delete(&net_instance->main_timer_list, net_instance->echo_request_timer); net_instance->echo_request_timer = NULL; } try_connect = qdevice_net_disconnect_reason_try_reconnect(net_instance->disconnect_reason); vote = TLV_VOTE_NO_CHANGE; if (qdevice_net_algorithm_disconnected(net_instance, net_instance->disconnect_reason, &try_connect, &vote) != 0) { qdevice_log(LOG_ERR, "Algorithm returned error, force exit"); return (-1); } else { - qdevice_log(LOG_ERR, "Algorithm result vote is %s", + qdevice_log(LOG_DEBUG, "Algorithm result vote is %s", tlv_vote_to_str(vote)); } if (qdevice_net_cast_vote_timer_update(net_instance, vote) != 0) { qdevice_log(LOG_ERR, "qdevice_model_net_run fatal error. " " Can't update cast vote timer vote"); } if (qdevice_net_disconnect_reason_force_disconnect(net_instance->disconnect_reason)) { try_connect = 0; } if (net_instance->socket != NULL) { if (PR_Close(net_instance->socket) != PR_SUCCESS) { qdevice_log_nss(LOG_WARNING, "Unable to close connection"); } net_instance->socket = NULL; } if (!net_instance->non_blocking_client.destroyed) { nss_sock_non_blocking_client_destroy(&net_instance->non_blocking_client); } if (net_instance->non_blocking_client.socket != NULL) { if (PR_Close(net_instance->non_blocking_client.socket) != PR_SUCCESS) { qdevice_log_nss(LOG_WARNING, "Unable to close non-blocking client connection"); } net_instance->non_blocking_client.socket = NULL; } qdevice_net_instance_clean(net_instance); if (try_connect) { /* * Give qnetd server a little time before reconnect */ (void)poll(NULL, 0, random() % instance->advanced_settings->net_delay_before_reconnect); } } return (0); } /* * Called when cmap reload (or nodelist) was requested. * * nlist is node list * config_version is valid only if config_version_set != 0 * * Should return 0 if processing should continue or -1 to call exit */ int qdevice_model_net_config_node_list_changed(struct qdevice_instance *instance, const struct node_list *nlist, int config_version_set, uint64_t config_version) { struct qdevice_net_instance *net_instance; int send_node_list; enum tlv_vote vote; net_instance = instance->model_data; if (net_instance->state != QDEVICE_NET_INSTANCE_STATE_WAITING_VOTEQUORUM_CMAP_EVENTS) { /* * Nodelist changed, but connection to qnetd not initiated yet. */ send_node_list = 0; if (net_instance->cast_vote_timer_vote == TLV_VOTE_ACK) { vote = TLV_VOTE_NACK; } else { vote = TLV_VOTE_NO_CHANGE; } } else { send_node_list = 1; vote = TLV_VOTE_NO_CHANGE; } if (qdevice_net_algorithm_config_node_list_changed(net_instance, nlist, config_version_set, config_version, &send_node_list, &vote) != 0) { - qdevice_log(LOG_ERR, "Algorithm returned error, force exit"); - return (-1); + qdevice_log(LOG_ERR, "Algorithm returned error, Disconnecting"); + + net_instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_ALGO_CONFIG_NODE_LIST_CHANGED_ERR; + net_instance->schedule_disconnect = 1; + + return (0); } else { qdevice_log(LOG_DEBUG, "Algorithm decided to %s node list and result vote is %s", (send_node_list ? "send" : "not send"), tlv_vote_to_str(vote)); } if (qdevice_net_cast_vote_timer_update(net_instance, vote) != 0) { qdevice_log(LOG_CRIT, "qdevice_model_net_config_node_list_changed fatal error. " " Can't update cast vote timer vote"); net_instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_SCHEDULE_VOTING_TIMER; net_instance->schedule_disconnect = 1; + + return (0); } if (send_node_list) { if (qdevice_net_send_config_node_list(net_instance, nlist, config_version_set, config_version, 0) != 0) { net_instance->schedule_disconnect = 1; net_instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_ALLOCATE_MSG_BUFFER; + + return (0); } } return (0); } /* * Called when cmap reload (or nodelist) was requested, but it was not possible to * get node list. * * Should return 0 if processing should continue or -1 to call exit */ int qdevice_model_net_get_config_node_list_failed(struct qdevice_instance *instance) { struct qdevice_net_instance *net_instance; net_instance = instance->model_data; net_instance->schedule_disconnect = 1; net_instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_ALLOCATE_MSG_BUFFER; return (0); } int qdevice_model_net_votequorum_quorum_notify(struct qdevice_instance *instance, uint32_t quorate, uint32_t node_list_entries, votequorum_node_t node_list[]) { struct qdevice_net_instance *net_instance; int send_node_list; enum tlv_vote vote; net_instance = instance->model_data; if (net_instance->state != QDEVICE_NET_INSTANCE_STATE_WAITING_VOTEQUORUM_CMAP_EVENTS) { /* * Nodelist changed, but connection to qnetd not initiated yet. */ send_node_list = 0; if (net_instance->cast_vote_timer_vote == TLV_VOTE_ACK) { vote = TLV_VOTE_NACK; } else { vote = TLV_VOTE_NO_CHANGE; } } else { send_node_list = 1; vote = TLV_VOTE_NO_CHANGE; } if (qdevice_net_algorithm_votequorum_quorum_notify(net_instance, quorate, node_list_entries, node_list, &send_node_list, &vote) != 0) { qdevice_log(LOG_DEBUG, "Algorithm returned error. Disconnecting."); net_instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_ALGO_VOTEQUORUM_QUORUM_NOTIFY_ERR; net_instance->schedule_disconnect = 1; + + return (0); } else { qdevice_log(LOG_DEBUG, "Algorithm decided to %s list and result vote is %s", (send_node_list ? "send" : "not send"), tlv_vote_to_str(vote)); } if (qdevice_net_cast_vote_timer_update(net_instance, vote) != 0) { qdevice_log(LOG_CRIT, "qdevice_model_net_votequorum_quorum_notify fatal error. " " Can't update cast vote timer vote"); net_instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_SCHEDULE_VOTING_TIMER; net_instance->schedule_disconnect = 1; + + return (0); } if (send_node_list) { if (qdevice_net_send_quorum_node_list(net_instance, (quorate ? TLV_QUORATE_QUORATE : TLV_QUORATE_INQUORATE), node_list_entries, node_list) != 0) { /* * Fatal error -> schedule disconnect */ net_instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_ALLOCATE_MSG_BUFFER; net_instance->schedule_disconnect = 1; + + return (0); } } return (0); } int qdevice_model_net_votequorum_node_list_notify(struct qdevice_instance *instance, votequorum_ring_id_t votequorum_ring_id, uint32_t node_list_entries, uint32_t node_list[]) { struct qdevice_net_instance *net_instance; struct tlv_ring_id tlv_rid; enum tlv_vote vote; int send_node_list; net_instance = instance->model_data; qdevice_net_votequorum_ring_id_to_tlv(&tlv_rid, &votequorum_ring_id); if (net_instance->state != QDEVICE_NET_INSTANCE_STATE_WAITING_VOTEQUORUM_CMAP_EVENTS) { /* * Nodelist changed, but connection to qnetd not initiated yet. */ send_node_list = 0; if (net_instance->cast_vote_timer_vote == TLV_VOTE_ACK) { vote = TLV_VOTE_NACK; } else { vote = TLV_VOTE_NO_CHANGE; } } else { send_node_list = 1; vote = TLV_VOTE_NO_CHANGE; } if (qdevice_net_algorithm_votequorum_node_list_notify(net_instance, &tlv_rid, node_list_entries, node_list, &send_node_list, &vote) != 0) { qdevice_log(LOG_DEBUG, "Algorithm returned error. Disconnecting."); net_instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_ALGO_VOTEQUORUM_NODE_LIST_NOTIFY_ERR; net_instance->schedule_disconnect = 1; + + return (0); } else { qdevice_log(LOG_DEBUG, "Algorithm decided to %s list and result vote is %s", (send_node_list ? "send" : "not send"), tlv_vote_to_str(vote)); } if (send_node_list) { if (qdevice_net_send_membership_node_list(net_instance, &tlv_rid, node_list_entries, node_list) != 0) { /* * Fatal error -> schedule disconnect */ net_instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_ALLOCATE_MSG_BUFFER; net_instance->schedule_disconnect = 1; + + return (0); } } if (qdevice_net_cast_vote_timer_update(net_instance, vote) != 0) { qdevice_log(LOG_CRIT, "qdevice_model_net_votequorum_node_list_notify fatal error " "Can't update cast vote timer"); net_instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_SCHEDULE_VOTING_TIMER; net_instance->schedule_disconnect = 1; + + return (0); } return (0); } int qdevice_model_net_votequorum_expected_votes_notify(struct qdevice_instance *instance, uint32_t expected_votes) { struct qdevice_net_instance *net_instance; + enum tlv_vote vote; net_instance = instance->model_data; qdevice_log(LOG_DEBUG, "qdevice_model_net_votequorum_expected_votes_notify" " (expected votes old=%"PRIu32" / new=%"PRIu32")", net_instance->qdevice_instance_ptr->vq_expected_votes, expected_votes); + vote = TLV_VOTE_NO_CHANGE; + + if (qdevice_net_algorithm_votequorum_expected_votes_notify(net_instance, expected_votes, + &vote) != 0) { + qdevice_log(LOG_DEBUG, "Algorithm returned error. Disconnecting."); + + net_instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_ALGO_VOTEQUORUM_EXPECTED_VOTES_NOTIFY_ERR; + net_instance->schedule_disconnect = 1; + + return (0); + } else { + qdevice_log(LOG_DEBUG, "Algorithm result vote is %s", tlv_vote_to_str(vote)); + } + + if (qdevice_net_cast_vote_timer_update(net_instance, vote) != 0) { + qdevice_log(LOG_CRIT, "qdevice_model_net_votequorum_expected_votes_notify fatal error. " + " Can't update cast vote timer vote"); + net_instance->disconnect_reason = QDEVICE_NET_DISCONNECT_REASON_CANT_SCHEDULE_VOTING_TIMER; + net_instance->schedule_disconnect = 1; + + return (0); + } + return (0); } int qdevice_model_net_ipc_cmd_status(struct qdevice_instance *instance, struct dynar *outbuf, int verbose) { struct qdevice_net_instance *net_instance; net_instance = instance->model_data; if (!qdevice_net_ipc_cmd_status(net_instance, outbuf, verbose)) { return (-1); } return (0); } static struct qdevice_model qdevice_model_net = { .name = "net", .init = qdevice_model_net_init, .destroy = qdevice_model_net_destroy, .run = qdevice_model_net_run, .get_config_node_list_failed = qdevice_model_net_get_config_node_list_failed, .config_node_list_changed = qdevice_model_net_config_node_list_changed, .votequorum_quorum_notify = qdevice_model_net_votequorum_quorum_notify, .votequorum_node_list_notify = qdevice_model_net_votequorum_node_list_notify, .votequorum_expected_votes_notify = qdevice_model_net_votequorum_expected_votes_notify, .ipc_cmd_status = qdevice_model_net_ipc_cmd_status, }; int qdevice_model_net_register(void) { return (qdevice_model_register(QDEVICE_MODEL_TYPE_NET, &qdevice_model_net)); } diff --git a/qdevices/qdevice-net-algo-2nodelms.c b/qdevices/qdevice-net-algo-2nodelms.c index 44548875..590e9be6 100644 --- a/qdevices/qdevice-net-algo-2nodelms.c +++ b/qdevices/qdevice-net-algo-2nodelms.c @@ -1,177 +1,186 @@ /* * Copyright (c) 2015-2016 Red Hat, Inc. * * All rights reserved. * * Author: Jan Friesse (jfriesse@redhat.com) * * This software licensed under BSD license, the text of which follows: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the Red Hat, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "qdevice-net-algo-2nodelms.h" #include "qdevice-log.h" #include "qdevice-net-send.h" #include "qdevice-net-cast-vote-timer.h" int qdevice_net_algo_2nodelms_init(struct qdevice_net_instance *instance) { return (0); } int qdevice_net_algo_2nodelms_connected(struct qdevice_net_instance *instance, int *send_config_node_list, int *send_membership_node_list, int *send_quorum_node_list, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_2nodelms_config_node_list_changed(struct qdevice_net_instance *instance, const struct node_list *nlist, int config_version_set, uint64_t config_version, int *send_node_list, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_2nodelms_votequorum_node_list_notify(struct qdevice_net_instance *instance, const struct tlv_ring_id *ring_id, uint32_t node_list_entries, uint32_t node_list[], int *send_node_list, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_2nodelms_votequorum_quorum_notify(struct qdevice_net_instance *instance, uint32_t quorate, uint32_t node_list_entries, votequorum_node_t node_list[], int *send_node_list, enum tlv_vote *vote) { return (0); } +int +qdevice_net_algo_2nodelms_votequorum_expected_votes_notify(struct qdevice_net_instance *instance, + uint32_t expected_votes, enum tlv_vote *vote) +{ + + return (0); +} + int qdevice_net_algo_2nodelms_config_node_list_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, int initial, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_2nodelms_membership_node_list_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, const struct tlv_ring_id *ring_id, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_2nodelms_quorum_node_list_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_2nodelms_ask_for_vote_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_2nodelms_vote_info_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_2nodelms_echo_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, int is_expected_seq_number) { return (is_expected_seq_number ? 0 : -1); } int qdevice_net_algo_2nodelms_echo_reply_not_received(struct qdevice_net_instance *instance) { return (-1); } int qdevice_net_algo_2nodelms_disconnected(struct qdevice_net_instance *instance, enum qdevice_net_disconnect_reason disconnect_reason, int *try_reconnect, enum tlv_vote *vote) { return (0); } void qdevice_net_algo_2nodelms_destroy(struct qdevice_net_instance *instance) { } static struct qdevice_net_algorithm qdevice_net_algo_2nodelms = { .init = qdevice_net_algo_2nodelms_init, .connected = qdevice_net_algo_2nodelms_connected, .config_node_list_changed = qdevice_net_algo_2nodelms_config_node_list_changed, .votequorum_node_list_notify = qdevice_net_algo_2nodelms_votequorum_node_list_notify, .votequorum_quorum_notify = qdevice_net_algo_2nodelms_votequorum_quorum_notify, + .votequorum_expected_votes_notify = qdevice_net_algo_2nodelms_votequorum_expected_votes_notify, .config_node_list_reply_received = qdevice_net_algo_2nodelms_config_node_list_reply_received, .membership_node_list_reply_received = qdevice_net_algo_2nodelms_membership_node_list_reply_received, .quorum_node_list_reply_received = qdevice_net_algo_2nodelms_quorum_node_list_reply_received, .ask_for_vote_reply_received = qdevice_net_algo_2nodelms_ask_for_vote_reply_received, .vote_info_received = qdevice_net_algo_2nodelms_vote_info_received, .echo_reply_received = qdevice_net_algo_2nodelms_echo_reply_received, .echo_reply_not_received = qdevice_net_algo_2nodelms_echo_reply_not_received, .disconnected = qdevice_net_algo_2nodelms_disconnected, .destroy = qdevice_net_algo_2nodelms_destroy, }; int qdevice_net_algo_2nodelms_register(void) { return (qdevice_net_algorithm_register(TLV_DECISION_ALGORITHM_TYPE_2NODELMS, &qdevice_net_algo_2nodelms)); } diff --git a/qdevices/qdevice-net-algo-2nodelms.h b/qdevices/qdevice-net-algo-2nodelms.h index 36229cc2..e52cca68 100644 --- a/qdevices/qdevice-net-algo-2nodelms.h +++ b/qdevices/qdevice-net-algo-2nodelms.h @@ -1,97 +1,100 @@ /* * Copyright (c) 2015-2016 Red Hat, Inc. * * All rights reserved. * * Author: Jan Friesse (jfriesse@redhat.com) * * This software licensed under BSD license, the text of which follows: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the Red Hat, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _QDEVICE_NET_ALGO_2NODELMS_H_ #define _QDEVICE_NET_ALGO_2NODELMS_H_ #include "qdevice-net-algorithm.h" #ifdef __cplusplus extern "C" { #endif extern int qdevice_net_algo_2nodelms_init(struct qdevice_net_instance *instance); extern int qdevice_net_algo_2nodelms_connected(struct qdevice_net_instance *instance, int *send_config_node_list, int *send_membership_node_list, int *send_quorum_node_list, enum tlv_vote *vote); extern int qdevice_net_algo_2nodelms_config_node_list_changed( struct qdevice_net_instance *instance, const struct node_list *nlist, int config_version_set, uint64_t config_version, int *send_node_list, enum tlv_vote *vote); extern int qdevice_net_algo_2nodelms_votequorum_node_list_notify( struct qdevice_net_instance *instance, const struct tlv_ring_id *ring_id, uint32_t node_list_entries, uint32_t node_list[], int *send_node_list, enum tlv_vote *vote); extern int qdevice_net_algo_2nodelms_votequorum_quorum_notify( struct qdevice_net_instance *instance, uint32_t quorate, uint32_t node_list_entries, votequorum_node_t node_list[], int *send_node_list, enum tlv_vote *vote); +extern int qdevice_net_algo_2nodelms_votequorum_expected_votes_notify( + struct qdevice_net_instance *instance, uint32_t expected_votes, enum tlv_vote *vote); + extern int qdevice_net_algo_2nodelms_config_node_list_reply_received( struct qdevice_net_instance *instance, uint32_t seq_number, int initial, enum tlv_vote *vote); extern int qdevice_net_algo_2nodelms_membership_node_list_reply_received( struct qdevice_net_instance *instance, uint32_t seq_number, const struct tlv_ring_id *ring_id, enum tlv_vote *vote); extern int qdevice_net_algo_2nodelms_quorum_node_list_reply_received( struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote); extern int qdevice_net_algo_2nodelms_ask_for_vote_reply_received( struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote); extern int qdevice_net_algo_2nodelms_vote_info_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote); extern int qdevice_net_algo_2nodelms_echo_reply_received( struct qdevice_net_instance *instance, uint32_t seq_number, int is_expected_seq_number); extern int qdevice_net_algo_2nodelms_echo_reply_not_received( struct qdevice_net_instance *instance); extern int qdevice_net_algo_2nodelms_disconnected(struct qdevice_net_instance *instance, enum qdevice_net_disconnect_reason disconnect_reason, int *try_reconnect, enum tlv_vote *vote); extern void qdevice_net_algo_2nodelms_destroy(struct qdevice_net_instance *instance); extern int qdevice_net_algo_2nodelms_register(void); #ifdef __cplusplus } #endif #endif /* _QDEVICE_NET_ALGO_2NODELMS_H_ */ diff --git a/qdevices/qdevice-net-algo-ffsplit.c b/qdevices/qdevice-net-algo-ffsplit.c index 4e7daf80..c4126020 100644 --- a/qdevices/qdevice-net-algo-ffsplit.c +++ b/qdevices/qdevice-net-algo-ffsplit.c @@ -1,176 +1,185 @@ /* * Copyright (c) 2015-2016 Red Hat, Inc. * * All rights reserved. * * Author: Jan Friesse (jfriesse@redhat.com) * * This software licensed under BSD license, the text of which follows: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the Red Hat, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "qdevice-net-algo-ffsplit.h" #include "qdevice-log.h" #include "qdevice-net-send.h" #include "qdevice-net-cast-vote-timer.h" int qdevice_net_algo_ffsplit_init(struct qdevice_net_instance *instance) { return (0); } int qdevice_net_algo_ffsplit_connected(struct qdevice_net_instance *instance, int *send_config_node_list, int *send_membership_node_list, int *send_quorum_node_list, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_ffsplit_config_node_list_changed(struct qdevice_net_instance *instance, const struct node_list *nlist, int config_version_set, uint64_t config_version, int *send_node_list, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_ffsplit_votequorum_node_list_notify(struct qdevice_net_instance *instance, const struct tlv_ring_id *ring_id, uint32_t node_list_entries, uint32_t node_list[], int *send_node_list, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_ffsplit_votequorum_quorum_notify(struct qdevice_net_instance *instance, uint32_t quorate, uint32_t node_list_entries, votequorum_node_t node_list[], int *send_node_list, enum tlv_vote *vote) { return (0); } +int +qdevice_net_algo_ffsplit_votequorum_expected_votes_notify(struct qdevice_net_instance *instance, + uint32_t expected_votes, enum tlv_vote *vote) +{ + + return (0); +} + int qdevice_net_algo_ffsplit_config_node_list_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, int initial, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_ffsplit_membership_node_list_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, const struct tlv_ring_id *ring_id, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_ffsplit_quorum_node_list_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_ffsplit_ask_for_vote_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_ffsplit_vote_info_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_ffsplit_echo_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, int is_expected_seq_number) { return (is_expected_seq_number ? 0 : -1); } int qdevice_net_algo_ffsplit_echo_reply_not_received(struct qdevice_net_instance *instance) { return (-1); } int qdevice_net_algo_ffsplit_disconnected(struct qdevice_net_instance *instance, enum qdevice_net_disconnect_reason disconnect_reason, int *try_reconnect, enum tlv_vote *vote) { return (0); } void qdevice_net_algo_ffsplit_destroy(struct qdevice_net_instance *instance) { } static struct qdevice_net_algorithm qdevice_net_algo_ffsplit = { .init = qdevice_net_algo_ffsplit_init, .connected = qdevice_net_algo_ffsplit_connected, .config_node_list_changed = qdevice_net_algo_ffsplit_config_node_list_changed, .votequorum_node_list_notify = qdevice_net_algo_ffsplit_votequorum_node_list_notify, .votequorum_quorum_notify = qdevice_net_algo_ffsplit_votequorum_quorum_notify, + .votequorum_expected_votes_notify = qdevice_net_algo_ffsplit_votequorum_expected_votes_notify, .config_node_list_reply_received = qdevice_net_algo_ffsplit_config_node_list_reply_received, .membership_node_list_reply_received = qdevice_net_algo_ffsplit_membership_node_list_reply_received, .quorum_node_list_reply_received = qdevice_net_algo_ffsplit_quorum_node_list_reply_received, .ask_for_vote_reply_received = qdevice_net_algo_ffsplit_ask_for_vote_reply_received, .vote_info_received = qdevice_net_algo_ffsplit_vote_info_received, .echo_reply_received = qdevice_net_algo_ffsplit_echo_reply_received, .echo_reply_not_received = qdevice_net_algo_ffsplit_echo_reply_not_received, .disconnected = qdevice_net_algo_ffsplit_disconnected, .destroy = qdevice_net_algo_ffsplit_destroy, }; int qdevice_net_algo_ffsplit_register(void) { return (qdevice_net_algorithm_register(TLV_DECISION_ALGORITHM_TYPE_FFSPLIT, &qdevice_net_algo_ffsplit)); } diff --git a/qdevices/qdevice-net-algo-ffsplit.h b/qdevices/qdevice-net-algo-ffsplit.h index a33874de..2100c2e0 100644 --- a/qdevices/qdevice-net-algo-ffsplit.h +++ b/qdevices/qdevice-net-algo-ffsplit.h @@ -1,97 +1,100 @@ /* * Copyright (c) 2015-2016 Red Hat, Inc. * * All rights reserved. * * Author: Jan Friesse (jfriesse@redhat.com) * * This software licensed under BSD license, the text of which follows: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the Red Hat, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _QDEVICE_NET_ALGO_FFSPLIT_H_ #define _QDEVICE_NET_ALGO_FFSPLIT_H_ #include "qdevice-net-algorithm.h" #ifdef __cplusplus extern "C" { #endif extern int qdevice_net_algo_ffsplit_init(struct qdevice_net_instance *instance); extern int qdevice_net_algo_ffsplit_connected(struct qdevice_net_instance *instance, int *send_config_node_list, int *send_membership_node_list, int *send_quorum_node_list, enum tlv_vote *vote); extern int qdevice_net_algo_ffsplit_config_node_list_changed( struct qdevice_net_instance *instance, const struct node_list *nlist, int config_version_set, uint64_t config_version, int *send_node_list, enum tlv_vote *vote); extern int qdevice_net_algo_ffsplit_votequorum_node_list_notify( struct qdevice_net_instance *instance, const struct tlv_ring_id *ring_id, uint32_t node_list_entries, uint32_t node_list[], int *send_node_list, enum tlv_vote *vote); extern int qdevice_net_algo_ffsplit_votequorum_quorum_notify( struct qdevice_net_instance *instance, uint32_t quorate, uint32_t node_list_entries, votequorum_node_t node_list[], int *send_node_list, enum tlv_vote *vote); +extern int qdevice_net_algo_ffsplit_votequorum_expected_votes_notify( + struct qdevice_net_instance *instance, uint32_t expected_votes, enum tlv_vote *vote); + extern int qdevice_net_algo_ffsplit_config_node_list_reply_received( struct qdevice_net_instance *instance, uint32_t seq_number, int initial, enum tlv_vote *vote); extern int qdevice_net_algo_ffsplit_membership_node_list_reply_received( struct qdevice_net_instance *instance, uint32_t seq_number, const struct tlv_ring_id *ring_id, enum tlv_vote *vote); extern int qdevice_net_algo_ffsplit_quorum_node_list_reply_received( struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote); extern int qdevice_net_algo_ffsplit_ask_for_vote_reply_received( struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote); extern int qdevice_net_algo_ffsplit_vote_info_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote); extern int qdevice_net_algo_ffsplit_echo_reply_received( struct qdevice_net_instance *instance, uint32_t seq_number, int is_expected_seq_number); extern int qdevice_net_algo_ffsplit_echo_reply_not_received( struct qdevice_net_instance *instance); extern int qdevice_net_algo_ffsplit_disconnected(struct qdevice_net_instance *instance, enum qdevice_net_disconnect_reason disconnect_reason, int *try_reconnect, enum tlv_vote *vote); extern void qdevice_net_algo_ffsplit_destroy(struct qdevice_net_instance *instance); extern int qdevice_net_algo_ffsplit_register(void); #ifdef __cplusplus } #endif #endif /* _QDEVICE_NET_ALGO_FFSPLIT_H_ */ diff --git a/qdevices/qdevice-net-algo-lms.c b/qdevices/qdevice-net-algo-lms.c index 0ac36fc2..71375b2e 100644 --- a/qdevices/qdevice-net-algo-lms.c +++ b/qdevices/qdevice-net-algo-lms.c @@ -1,219 +1,228 @@ /* * Copyright (c) 2015-2016 Red Hat, Inc. * * All rights reserved. * * Author: Jan Friesse (jfriesse@redhat.com) * * This software licensed under BSD license, the text of which follows: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the Red Hat, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "qdevice-net-algo-lms.h" #include "qdevice-log.h" #include "qdevice-net-send.h" #include "qdevice-net-cast-vote-timer.h" struct algo_lms_instance_data { uint32_t quorate; uint8_t have_wfa; enum tlv_vote vote; }; int qdevice_net_algo_lms_init(struct qdevice_net_instance *instance) { struct algo_lms_instance_data *data; int res; data = malloc(sizeof(struct algo_lms_instance_data)); if (!data) { return (-1); } instance->algorithm_data = data; data->quorate = 0; data->vote = TLV_VOTE_ASK_LATER; res = cmap_get_uint8(instance->qdevice_instance_ptr->cmap_handle, "quorum.wait_for_all", &data->have_wfa); if (res != CS_OK) { qdevice_log(LOG_DEBUG, "algo-lms: Can't get WFA res = %d", res); data->have_wfa = 0; } qdevice_log(LOG_DEBUG, "algo-lms: initialised. WFA = %d", data->have_wfa); return (0); } int qdevice_net_algo_lms_connected(struct qdevice_net_instance *instance, int *send_config_node_list, int *send_membership_node_list, int *send_quorum_node_list, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_lms_config_node_list_changed(struct qdevice_net_instance *instance, const struct node_list *nlist, int config_version_set, uint64_t config_version, int *send_node_list, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_lms_votequorum_node_list_notify(struct qdevice_net_instance *instance, const struct tlv_ring_id *ring_id, uint32_t node_list_entries, uint32_t node_list[], int *send_node_list, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_lms_votequorum_quorum_notify(struct qdevice_net_instance *instance, uint32_t quorate, uint32_t node_list_entries, votequorum_node_t node_list[], int *send_node_list, enum tlv_vote *vote) { struct algo_lms_instance_data *data = instance->algorithm_data; data->quorate = quorate; qdevice_log(LOG_DEBUG, "algo-lms: quorum_notify. quorate = %d", data->quorate); return (0); } int qdevice_net_algo_lms_config_node_list_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, int initial, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_lms_membership_node_list_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, const struct tlv_ring_id *ring_id, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_lms_quorum_node_list_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote) { return (0); } +int +qdevice_net_algo_lms_votequorum_expected_votes_notify(struct qdevice_net_instance *instance, + uint32_t expected_votes, enum tlv_vote *vote) +{ + + return (0); +} + int qdevice_net_algo_lms_ask_for_vote_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_lms_vote_info_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote) { return (0); } int qdevice_net_algo_lms_echo_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, int is_expected_seq_number) { return (is_expected_seq_number ? 0 : -1); } int qdevice_net_algo_lms_echo_reply_not_received(struct qdevice_net_instance *instance) { struct algo_lms_instance_data *data = instance->algorithm_data; qdevice_log(LOG_DEBUG, "algo-lms: echo_not_recvd. quorate = %d, WFA = %d", data->quorate, data->have_wfa); /* qnetd server is disconnected, if we were already quorate AND WFA is enabled then we can continue to provide our vote. Otherwise ... no */ if (data->quorate && data->have_wfa) { return (0); } return (-1); } int qdevice_net_algo_lms_disconnected(struct qdevice_net_instance *instance, enum qdevice_net_disconnect_reason disconnect_reason, int *try_reconnect, enum tlv_vote *vote) { struct algo_lms_instance_data *data = instance->algorithm_data; qdevice_log(LOG_DEBUG, "algo-lms: disconnected. quorate = %d, WFA = %d", data->quorate, data->have_wfa); qdevice_log(LOG_DEBUG, "algo-lms: disconnected. reason = %d, WFA = %d", disconnect_reason, data->have_wfa); if (!data->quorate || !data->have_wfa) { *vote = TLV_VOTE_NACK; } *try_reconnect = 1; return (0); } void qdevice_net_algo_lms_destroy(struct qdevice_net_instance *instance) { free(instance->algorithm_data); } static struct qdevice_net_algorithm qdevice_net_algo_lms = { .init = qdevice_net_algo_lms_init, .connected = qdevice_net_algo_lms_connected, .config_node_list_changed = qdevice_net_algo_lms_config_node_list_changed, .votequorum_node_list_notify = qdevice_net_algo_lms_votequorum_node_list_notify, .votequorum_quorum_notify = qdevice_net_algo_lms_votequorum_quorum_notify, + .votequorum_expected_votes_notify = qdevice_net_algo_lms_votequorum_expected_votes_notify, .config_node_list_reply_received = qdevice_net_algo_lms_config_node_list_reply_received, .membership_node_list_reply_received = qdevice_net_algo_lms_membership_node_list_reply_received, .quorum_node_list_reply_received = qdevice_net_algo_lms_quorum_node_list_reply_received, .ask_for_vote_reply_received = qdevice_net_algo_lms_ask_for_vote_reply_received, .vote_info_received = qdevice_net_algo_lms_vote_info_received, .echo_reply_received = qdevice_net_algo_lms_echo_reply_received, .echo_reply_not_received = qdevice_net_algo_lms_echo_reply_not_received, .disconnected = qdevice_net_algo_lms_disconnected, .destroy = qdevice_net_algo_lms_destroy, }; int qdevice_net_algo_lms_register(void) { return (qdevice_net_algorithm_register(TLV_DECISION_ALGORITHM_TYPE_LMS, &qdevice_net_algo_lms)); } diff --git a/qdevices/qdevice-net-algo-lms.h b/qdevices/qdevice-net-algo-lms.h index b39d3599..fea9c69c 100644 --- a/qdevices/qdevice-net-algo-lms.h +++ b/qdevices/qdevice-net-algo-lms.h @@ -1,97 +1,100 @@ /* * Copyright (c) 2015-2016 Red Hat, Inc. * * All rights reserved. * * Author: Jan Friesse (jfriesse@redhat.com) * * This software licensed under BSD license, the text of which follows: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the Red Hat, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _QDEVICE_NET_ALGO_LMS_H_ #define _QDEVICE_NET_ALGO_LMS_H_ #include "qdevice-net-algorithm.h" #ifdef __cplusplus extern "C" { #endif extern int qdevice_net_algo_lms_init(struct qdevice_net_instance *instance); extern int qdevice_net_algo_lms_connected(struct qdevice_net_instance *instance, int *send_config_node_list, int *send_membership_node_list, int *send_quorum_node_list, enum tlv_vote *vote); extern int qdevice_net_algo_lms_config_node_list_changed( struct qdevice_net_instance *instance, const struct node_list *nlist, int config_version_set, uint64_t config_version, int *send_node_list, enum tlv_vote *vote); extern int qdevice_net_algo_lms_votequorum_node_list_notify( struct qdevice_net_instance *instance, const struct tlv_ring_id *ring_id, uint32_t node_list_entries, uint32_t node_list[], int *send_node_list, enum tlv_vote *vote); extern int qdevice_net_algo_lms_votequorum_quorum_notify( struct qdevice_net_instance *instance, uint32_t quorate, uint32_t node_list_entries, votequorum_node_t node_list[], int *send_node_list, enum tlv_vote *vote); +extern int qdevice_net_algo_lms_votequorum_expected_votes_notify( + struct qdevice_net_instance *instance, uint32_t expected_votes, enum tlv_vote *vote); + extern int qdevice_net_algo_lms_config_node_list_reply_received( struct qdevice_net_instance *instance, uint32_t seq_number, int initial, enum tlv_vote *vote); extern int qdevice_net_algo_lms_membership_node_list_reply_received( struct qdevice_net_instance *instance, uint32_t seq_number, const struct tlv_ring_id *ring_id, enum tlv_vote *vote); extern int qdevice_net_algo_lms_quorum_node_list_reply_received( struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote); extern int qdevice_net_algo_lms_ask_for_vote_reply_received( struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote); extern int qdevice_net_algo_lms_vote_info_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote); extern int qdevice_net_algo_lms_echo_reply_received( struct qdevice_net_instance *instance, uint32_t seq_number, int is_expected_seq_number); extern int qdevice_net_algo_lms_echo_reply_not_received( struct qdevice_net_instance *instance); extern int qdevice_net_algo_lms_disconnected(struct qdevice_net_instance *instance, enum qdevice_net_disconnect_reason disconnect_reason, int *try_reconnect, enum tlv_vote *vote); extern void qdevice_net_algo_lms_destroy(struct qdevice_net_instance *instance); extern int qdevice_net_algo_lms_register(void); #ifdef __cplusplus } #endif #endif /* _QDEVICE_NET_ALGO_LMS_H_ */ diff --git a/qdevices/qdevice-net-algo-test.c b/qdevices/qdevice-net-algo-test.c index 18dd8652..ae426240 100644 --- a/qdevices/qdevice-net-algo-test.c +++ b/qdevices/qdevice-net-algo-test.c @@ -1,322 +1,339 @@ /* * Copyright (c) 2015-2016 Red Hat, Inc. * * All rights reserved. * * Author: Jan Friesse (jfriesse@redhat.com) * * This software licensed under BSD license, the text of which follows: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the Red Hat, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include "qdevice-net-algo-test.h" #include "qdevice-log.h" #include "qdevice-net-send.h" #include "qdevice-net-cast-vote-timer.h" /* * Called after qdevice_net_instance is initialized. Connection to server is not yet * established. Used mainly for allocating instance->algorithm_data. * * Callback should return 0 on success or -1 on failure. */ int qdevice_net_algo_test_init(struct qdevice_net_instance *instance) { instance->algorithm_data = NULL; qdevice_log(LOG_INFO, "algo-test: Initialized"); return (0); } /* * Called after qdevice connected to qnetd. * send_config_node_list, send_membership_node_list and send_quorum_node_list can be set to * nonzero (default) to make qdevice-net send given lists to qnetd * vote (default TLV_VOTE_WAIT_FOR_REPLY) can be set to update voting timer * * Callback should return 0 on success or -1 on failure (-> disconnect client). */ int qdevice_net_algo_test_connected(struct qdevice_net_instance *instance, int *send_config_node_list, int *send_membership_node_list, int *send_quorum_node_list, enum tlv_vote *vote) { qdevice_log(LOG_INFO, "algo-test: Connected"); return (0); } /* * Called after config node list changed. * * Callback can override send_node_list and vote. * Depending on net_instance->state, they are set acordingly: * If net_instance->state != QDEVICE_NET_INSTANCE_STATE_WAITING_VOTEQUORUM_CMAP_EVENTS * send_node_list = 0 * if cast_vote_timer_vote != TLV_VOTE_ACK * vote = TLV_VOTE_NO_CHANGE * if cast_vote_timer_vote = TLV_VOTE_ACK * vote = TLV_VOTE_NACK. * Otherwise send_node_list = 0 and vote = TLV_VOTE_NO_CHANGE * If send_node_list is set to non zero, node list is send to qnetd */ int qdevice_net_algo_test_config_node_list_changed(struct qdevice_net_instance *instance, const struct node_list *nlist, int config_version_set, uint64_t config_version, int *send_node_list, enum tlv_vote *vote) { qdevice_log(LOG_INFO, "algo-test: Config node list changed"); return (0); } /* * Called after votequorum node list notify is dispatched. * * Callback should return 0 on success or -1 on failure (-> disconnect client). * * If net_instance->state != QDEVICE_NET_INSTANCE_STATE_WAITING_VOTEQUORUM_CMAP_EVENTS * send_node_list = 0 * if cast_vote_timer_vote != TLV_VOTE_ACK * vote = TLV_VOTE_NO_CHANGE * if cast_vote_timer_vote = TLV_VOTE_ACK * vote = TLV_VOTE_NACK. * Otherwise send_node_list = 0 and vote = TLV_VOTE_NO_CHANGE * If send_node_list is set to non zero, node list is send to qnetd */ int qdevice_net_algo_test_votequorum_node_list_notify(struct qdevice_net_instance *instance, const struct tlv_ring_id *ring_id, uint32_t node_list_entries, uint32_t node_list[], int *send_node_list, enum tlv_vote *vote) { qdevice_log(LOG_INFO, "algo-test: Votequorum list notify"); return (0); } /* * Called after votequorum quorum notify is dispatched. * * Callback should return 0 on success or -1 on failure (-> disconnect client). * * Callback can override send_node_list and vote. * Depending on net_instance->state, they are set acordingly: * If net_instance->state != QDEVICE_NET_INSTANCE_STATE_WAITING_VOTEQUORUM_CMAP_EVENTS * send_node_list = 0 * if cast_vote_timer_vote != TLV_VOTE_ACK * vote = TLV_VOTE_NO_CHANGE * if cast_vote_timer_vote = TLV_VOTE_ACK * vote = TLV_VOTE_NACK. * Otherwise send_node_list = 0 and vote = TLV_VOTE_NO_CHANGE * * If send_node_list is set to non zero, node list is send to qnetd */ int qdevice_net_algo_test_votequorum_quorum_notify(struct qdevice_net_instance *instance, uint32_t quorate, uint32_t node_list_entries, votequorum_node_t node_list[], int *send_node_list, enum tlv_vote *vote) { qdevice_log(LOG_INFO, "algo-test: Votequorum quorum notify"); return (0); } +/* + * Called after votequorum expected_votes notify is dispatched. + * + * Callback should return 0 on success or -1 on failure (-> disconnect client). + * + * Vote is set to TLV_VOTE_NO_CHANGE + */ +int +qdevice_net_algo_test_votequorum_expected_votes_notify(struct qdevice_net_instance *instance, + uint32_t expected_votes, enum tlv_vote *vote) +{ + + qdevice_log(LOG_INFO, "algo-test: Votequorum expected votes notify"); + + return (0); +} /* * Called when config node list reply is received. Vote is set to value returned by server (and can * be overwriten by algorithm). * * Callback should return 0 on success or -1 on failure (-> disconnect client). */ int qdevice_net_algo_test_config_node_list_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, int initial, enum tlv_vote *vote) { qdevice_log(LOG_INFO, "algo-test: Config node list reply"); return (0); } /* * Called when membership node list reply (reply for votequorum votequorum_nodelist_notify_fn) * is received. Vote is set to value returned by server (and can be overwriten by algorithm). * * Also if server returned TLV_VOTE_ASK_LATER, it's good idea to create timer (call timer_list_add * with instance->main_timer_list parameter) and ask for reply (qdevice_net_send_ask_for_vote). * Another option may be to wait for vote_info message (if server algorithm is configured so). * * Callback should return 0 on success or -1 on failure (-> disconnect client). */ int qdevice_net_algo_test_membership_node_list_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, const struct tlv_ring_id *ring_id, enum tlv_vote *vote) { qdevice_log(LOG_INFO, "algo-test: Membership node list reply"); return (0); } /* * Called when quorum node list reply (reply for votequorum votequorum_quorum_notify_fn) * is received. Vote is set to value returned by server (and can be overwriten by algorithm). * * Callback should return 0 on success or -1 on failure (-> disconnect client). */ int qdevice_net_algo_test_quorum_node_list_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote) { qdevice_log(LOG_INFO, "algo-test: Quorum node list reply"); return (0); } /* * Called when reply for ask for vote message was received. * Vote is set to value returned by server (and can be overwriten by algorithm). * * Callback should return 0 on success or -1 on failure (-> disconnect client). */ int qdevice_net_algo_test_ask_for_vote_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote) { qdevice_log(LOG_INFO, "algo-test: Ask for vote reply received"); return (0); } /* * Called when vote info message from server was received. * Vote is set to value sent by server (and can be overwriten by algorithm). * * Callback should return 0 on success or -1 on failure (-> disconnect client). */ int qdevice_net_algo_test_vote_info_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote) { qdevice_log(LOG_INFO, "algo-test: Vote info received"); return (0); } /* * Called when echo reply message was received. * is_expected_seq_number is set to 1 if received seq_number was equal to last sent echo request. * * Callback should return 0 on success or -1 on failure (-> disconnect client). */ int qdevice_net_algo_test_echo_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, int is_expected_seq_number) { qdevice_log(LOG_INFO, "algo-test: Echo reply received"); return (is_expected_seq_number ? 0 : -1); } /* * Called when client is about to send echo request but echo reply to previous echo request * was not yet received. * * Callback should return 0 if processing should continue (echo request is not send but timer is * scheduled again) otherwise -1 (-> disconnect client). */ int qdevice_net_algo_test_echo_reply_not_received(struct qdevice_net_instance *instance) { qdevice_log(LOG_INFO, "algo-test: Echo reply not received"); return (-1); } /* * Called when client disconnect from server. * * disconnect_reason contains one of QDEVICE_NET_DISCONNECT_REASON_ * try_reconnect can be set to non zero value if reconnect to server should be tried * vote (default TLV_VOTE_NO_CHANGE) can be set to update voting timer * * Callback should return 0 on success, -1 on failure (-> force exit) */ int qdevice_net_algo_test_disconnected(struct qdevice_net_instance *instance, enum qdevice_net_disconnect_reason disconnect_reason, int *try_reconnect, enum tlv_vote *vote) { qdevice_log(LOG_INFO, "algo-test: Disconnected"); return (0); } /* * Called when qdevice-net is going down. */ void qdevice_net_algo_test_destroy(struct qdevice_net_instance *instance) { qdevice_log(LOG_INFO, "algo-test: Destroy"); } static struct qdevice_net_algorithm qdevice_net_algo_test = { .init = qdevice_net_algo_test_init, .connected = qdevice_net_algo_test_connected, .config_node_list_changed = qdevice_net_algo_test_config_node_list_changed, .votequorum_node_list_notify = qdevice_net_algo_test_votequorum_node_list_notify, .votequorum_quorum_notify = qdevice_net_algo_test_votequorum_quorum_notify, + .votequorum_expected_votes_notify = qdevice_net_algo_test_votequorum_expected_votes_notify, .config_node_list_reply_received = qdevice_net_algo_test_config_node_list_reply_received, .membership_node_list_reply_received = qdevice_net_algo_test_membership_node_list_reply_received, .quorum_node_list_reply_received = qdevice_net_algo_test_quorum_node_list_reply_received, .ask_for_vote_reply_received = qdevice_net_algo_test_ask_for_vote_reply_received, .vote_info_received = qdevice_net_algo_test_vote_info_received, .echo_reply_received = qdevice_net_algo_test_echo_reply_received, .echo_reply_not_received = qdevice_net_algo_test_echo_reply_not_received, .disconnected = qdevice_net_algo_test_disconnected, .destroy = qdevice_net_algo_test_destroy, }; int qdevice_net_algo_test_register(void) { return (qdevice_net_algorithm_register(TLV_DECISION_ALGORITHM_TYPE_TEST, &qdevice_net_algo_test)); } diff --git a/qdevices/qdevice-net-algo-test.h b/qdevices/qdevice-net-algo-test.h index cd150b1d..619cae46 100644 --- a/qdevices/qdevice-net-algo-test.h +++ b/qdevices/qdevice-net-algo-test.h @@ -1,98 +1,101 @@ /* * Copyright (c) 2015-2016 Red Hat, Inc. * * All rights reserved. * * Author: Jan Friesse (jfriesse@redhat.com) * * This software licensed under BSD license, the text of which follows: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the Red Hat, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _QDEVICE_NET_ALGO_TEST_H_ #define _QDEVICE_NET_ALGO_TEST_H_ #include "qdevice-net-algorithm.h" #ifdef __cplusplus extern "C" { #endif extern int qdevice_net_algo_test_init(struct qdevice_net_instance *instance); extern int qdevice_net_algo_test_connected(struct qdevice_net_instance *instance, int *send_config_node_list, int *send_membership_node_list, int *send_quorum_node_list, enum tlv_vote *vote); extern int qdevice_net_algo_test_config_node_list_changed( struct qdevice_net_instance *instance, const struct node_list *nlist, int config_version_set, uint64_t config_version, int *send_node_list, enum tlv_vote *vote); extern int qdevice_net_algo_test_votequorum_node_list_notify( struct qdevice_net_instance *instance, const struct tlv_ring_id *ring_id, uint32_t node_list_entries, uint32_t node_list[], int *send_node_list, enum tlv_vote *vote); extern int qdevice_net_algo_test_votequorum_quorum_notify( struct qdevice_net_instance *instance, uint32_t quorate, uint32_t node_list_entries, votequorum_node_t node_list[], int *send_node_list, enum tlv_vote *vote); +extern int qdevice_net_algo_test_votequorum_expected_votes_notify( + struct qdevice_net_instance *instance, uint32_t expected_votes, enum tlv_vote *vote); + extern int qdevice_net_algo_test_config_node_list_reply_received( struct qdevice_net_instance *instance, uint32_t seq_number, int initial, enum tlv_vote *vote); extern int qdevice_net_algo_test_membership_node_list_reply_received( struct qdevice_net_instance *instance, uint32_t seq_number, const struct tlv_ring_id *ring_id, enum tlv_vote *vote); extern int qdevice_net_algo_test_quorum_node_list_reply_received( struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote); extern int qdevice_net_algo_test_ask_for_vote_reply_received( struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote); extern int qdevice_net_algo_test_vote_info_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote); extern int qdevice_net_algo_test_echo_reply_received( struct qdevice_net_instance *instance, uint32_t seq_number, int is_expected_seq_number); extern int qdevice_net_algo_test_echo_reply_not_received( struct qdevice_net_instance *instance); extern int qdevice_net_algo_test_disconnected(struct qdevice_net_instance *instance, enum qdevice_net_disconnect_reason disconnect_reason, int *try_reconnect, enum tlv_vote *vote); extern void qdevice_net_algo_test_destroy(struct qdevice_net_instance *instance); extern int qdevice_net_algo_test_register(void); #ifdef __cplusplus } #endif #endif /* _QDEVICE_NET_ALGO_TEST_H_ */ diff --git a/qdevices/qdevice-net-algorithm.c b/qdevices/qdevice-net-algorithm.c index ee7be160..079771ff 100644 --- a/qdevices/qdevice-net-algorithm.c +++ b/qdevices/qdevice-net-algorithm.c @@ -1,313 +1,329 @@ /* * Copyright (c) 2015-2016 Red Hat, Inc. * * All rights reserved. * * Author: Jan Friesse (jfriesse@redhat.com) * * This software licensed under BSD license, the text of which follows: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the Red Hat, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #include #include "qnet-config.h" #include "qdevice-net-algorithm.h" #include "qdevice-log.h" #include "qdevice-net-algo-test.h" #include "qdevice-net-algo-ffsplit.h" #include "qdevice-net-algo-2nodelms.h" #include "qdevice-net-algo-lms.h" static struct qdevice_net_algorithm *qdevice_net_algorithm_array[QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE]; int qdevice_net_algorithm_init(struct qdevice_net_instance *instance) { if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || qdevice_net_algorithm_array[instance->decision_algorithm] == NULL) { qdevice_log(LOG_CRIT, "qdevice_net_algorithm_init unhandled decision algorithm"); exit(1); } return (qdevice_net_algorithm_array[instance->decision_algorithm]->init(instance)); } int qdevice_net_algorithm_connected(struct qdevice_net_instance *instance, int *send_config_node_list, int *send_membership_node_list, int *send_quorum_node_list, enum tlv_vote *vote) { if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || qdevice_net_algorithm_array[instance->decision_algorithm] == NULL) { qdevice_log(LOG_CRIT, "qdevice_net_algorithm_connected unhandled decision algorithm"); exit(1); } return (qdevice_net_algorithm_array[instance->decision_algorithm]->connected(instance, send_config_node_list, send_membership_node_list, send_quorum_node_list, vote)); } int qdevice_net_algorithm_config_node_list_changed(struct qdevice_net_instance *instance, const struct node_list *nlist, int config_version_set, uint64_t config_version, int *send_node_list, enum tlv_vote *vote) { if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || qdevice_net_algorithm_array[instance->decision_algorithm] == NULL) { qdevice_log(LOG_CRIT, "qdevice_net_algorithm_connected unhandled decision algorithm"); exit(1); } return (qdevice_net_algorithm_array[instance->decision_algorithm]-> config_node_list_changed(instance, nlist, config_version_set, config_version, send_node_list, vote)); } int qdevice_net_algorithm_votequorum_node_list_notify(struct qdevice_net_instance *instance, const struct tlv_ring_id *ring_id, uint32_t node_list_entries, uint32_t node_list[], int *send_node_list, enum tlv_vote *vote) { if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || qdevice_net_algorithm_array[instance->decision_algorithm] == NULL) { qdevice_log(LOG_CRIT, "qdevice_net_algorithm_votequorum_node_list_notify " "unhandled decision algorithm"); exit(1); } return (qdevice_net_algorithm_array[instance->decision_algorithm]->votequorum_node_list_notify( instance, ring_id, node_list_entries, node_list, send_node_list, vote)); } int qdevice_net_algorithm_votequorum_quorum_notify(struct qdevice_net_instance *instance, uint32_t quorate, uint32_t node_list_entries, votequorum_node_t node_list[], int *send_node_list, enum tlv_vote *vote) { if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || qdevice_net_algorithm_array[instance->decision_algorithm] == NULL) { qdevice_log(LOG_CRIT, "qdevice_net_algorithm_votequorum_quorum_notify " "unhandled decision algorithm"); exit(1); } return (qdevice_net_algorithm_array[instance->decision_algorithm]-> votequorum_quorum_notify(instance, quorate, node_list_entries, node_list, send_node_list, vote)); } +int +qdevice_net_algorithm_votequorum_expected_votes_notify(struct qdevice_net_instance *instance, + uint32_t expected_votes, enum tlv_vote *vote) +{ + + if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || + qdevice_net_algorithm_array[instance->decision_algorithm] == NULL) { + qdevice_log(LOG_CRIT, "qdevice_net_algorithm_votequorum_expected_votes_notify " + "unhandled decision algorithm"); + exit(1); + } + + return (qdevice_net_algorithm_array[instance->decision_algorithm]-> + votequorum_expected_votes_notify(instance, expected_votes, vote)); +} + int qdevice_net_algorithm_config_node_list_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, int initial, enum tlv_vote *vote) { if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || qdevice_net_algorithm_array[instance->decision_algorithm] == NULL) { qdevice_log(LOG_CRIT, "qdevice_net_algorithm_config_node_list_reply_received " "unhandled decision algorithm"); exit(1); } return (qdevice_net_algorithm_array[instance->decision_algorithm]-> config_node_list_reply_received(instance, seq_number, initial, vote)); } int qdevice_net_algorithm_membership_node_list_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, const struct tlv_ring_id *ring_id, enum tlv_vote *vote) { if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || qdevice_net_algorithm_array[instance->decision_algorithm] == NULL) { qdevice_log(LOG_CRIT, "qdevice_net_algorithm_membership_node_list_reply_received " "unhandled decision algorithm"); exit(1); } return (qdevice_net_algorithm_array[instance->decision_algorithm]-> membership_node_list_reply_received(instance, seq_number, ring_id, vote)); } int qdevice_net_algorithm_quorum_node_list_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote) { if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || qdevice_net_algorithm_array[instance->decision_algorithm] == NULL) { qdevice_log(LOG_CRIT, "qdevice_net_algorithm_quorum_node_list_reply_received " "unhandled decision algorithm"); exit(1); } return (qdevice_net_algorithm_array[instance->decision_algorithm]-> quorum_node_list_reply_received(instance, seq_number, vote)); } int qdevice_net_algorithm_ask_for_vote_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote) { if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || qdevice_net_algorithm_array[instance->decision_algorithm] == NULL) { qdevice_log(LOG_CRIT, "qdevice_net_algorithm_ask_for_vote_reply_received " "unhandled decision algorithm"); exit(1); } return (qdevice_net_algorithm_array[instance->decision_algorithm]-> ask_for_vote_reply_received(instance, seq_number, vote)); } int qdevice_net_algorithm_vote_info_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote) { if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || qdevice_net_algorithm_array[instance->decision_algorithm] == NULL) { qdevice_log(LOG_CRIT, "qdevice_net_algorithm_vote_info_received " "unhandled decision algorithm"); exit(1); } return (qdevice_net_algorithm_array[instance->decision_algorithm]-> vote_info_received(instance, seq_number, vote)); } int qdevice_net_algorithm_echo_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, int is_expected_seq_number) { if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || qdevice_net_algorithm_array[instance->decision_algorithm] == NULL) { qdevice_log(LOG_CRIT, "qdevice_net_algorithm_echo_reply_received " "unhandled decision algorithm"); exit(1); } return (qdevice_net_algorithm_array[instance->decision_algorithm]-> echo_reply_received(instance, seq_number, is_expected_seq_number)); } int qdevice_net_algorithm_echo_reply_not_received(struct qdevice_net_instance *instance) { if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || qdevice_net_algorithm_array[instance->decision_algorithm] == NULL) { qdevice_log(LOG_CRIT, "qdevice_net_algorithm_echo_reply_not_received " "unhandled decision algorithm"); exit(1); } return (qdevice_net_algorithm_array[instance->decision_algorithm]-> echo_reply_not_received(instance)); } int qdevice_net_algorithm_disconnected(struct qdevice_net_instance *instance, enum qdevice_net_disconnect_reason disconnect_reason, int *try_reconnect, enum tlv_vote *vote) { if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || qdevice_net_algorithm_array[instance->decision_algorithm] == NULL) { qdevice_log(LOG_CRIT, "qdevice_net_algorithm_disconnected " "unhandled decision algorithm"); exit(1); } return (qdevice_net_algorithm_array[instance->decision_algorithm]-> disconnected(instance, disconnect_reason, try_reconnect, vote)); } void qdevice_net_algorithm_destroy(struct qdevice_net_instance *instance) { if (instance->decision_algorithm >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || qdevice_net_algorithm_array[instance->decision_algorithm] == NULL) { qdevice_log(LOG_CRIT, "qdevice_net_algorithm_destroy " "unhandled decision algorithm"); exit(1); } return (qdevice_net_algorithm_array[instance->decision_algorithm]-> destroy(instance)); } int qdevice_net_algorithm_register(enum tlv_decision_algorithm_type algorithm_number, struct qdevice_net_algorithm *algorithm) { if (algorithm_number >= QDEVICE_NET_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE) { return (-1); } if (qdevice_net_algorithm_array[algorithm_number] != NULL) { return (-1); } qdevice_net_algorithm_array[algorithm_number] = algorithm; return (0); } int qdevice_net_algorithm_register_all(void) { if (qdevice_net_algo_test_register() != 0) { qdevice_log(LOG_CRIT, "Failed to register decision algorithm 'test' "); return (-1); } if (qdevice_net_algo_ffsplit_register() != 0) { qdevice_log(LOG_CRIT, "Failed to register decision algorithm 'ffsplit' "); return (-1); } if (qdevice_net_algo_2nodelms_register() != 0) { qdevice_log(LOG_CRIT, "Failed to register decision algorithm '2nodelms' "); return (-1); } if (qdevice_net_algo_lms_register() != 0) { qdevice_log(LOG_CRIT, "Failed to register decision algorithm 'lms' "); return (-1); } return (0); } diff --git a/qdevices/qdevice-net-algorithm.h b/qdevices/qdevice-net-algorithm.h index e105fd43..61e8a8b6 100644 --- a/qdevices/qdevice-net-algorithm.h +++ b/qdevices/qdevice-net-algorithm.h @@ -1,133 +1,138 @@ /* * Copyright (c) 2015-2016 Red Hat, Inc. * * All rights reserved. * * Author: Jan Friesse (jfriesse@redhat.com) * * This software licensed under BSD license, the text of which follows: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the Red Hat, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _QDEVICE_NET_ALGORITHM_H_ #define _QDEVICE_NET_ALGORITHM_H_ #include #include #include "node-list.h" #include "qdevice-net-instance.h" #ifdef __cplusplus extern "C" { #endif extern int qdevice_net_algorithm_init(struct qdevice_net_instance *instance); extern int qdevice_net_algorithm_connected(struct qdevice_net_instance *instance, int *send_config_node_list, int *send_membership_node_list, int *send_quorum_node_list, enum tlv_vote *vote); extern int qdevice_net_algorithm_config_node_list_changed(struct qdevice_net_instance *instance, const struct node_list *nlist, int config_version_set, uint64_t config_version, int *send_node_list, enum tlv_vote *vote); extern int qdevice_net_algorithm_votequorum_node_list_notify(struct qdevice_net_instance *instance, const struct tlv_ring_id *ring_id, uint32_t node_list_entries, uint32_t node_list[], int *send_node_list, enum tlv_vote *vote); extern int qdevice_net_algorithm_votequorum_quorum_notify(struct qdevice_net_instance *instance, uint32_t quorate, uint32_t node_list_entries, votequorum_node_t node_list[], int *send_node_list, enum tlv_vote *vote); +extern int qdevice_net_algorithm_votequorum_expected_votes_notify(struct qdevice_net_instance *instance, + uint32_t expected_votes, enum tlv_vote *vote); + extern int qdevice_net_algorithm_config_node_list_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, int initial, enum tlv_vote *vote); extern int qdevice_net_algorithm_membership_node_list_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, const struct tlv_ring_id *ring_id, enum tlv_vote *vote); extern int qdevice_net_algorithm_quorum_node_list_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote); extern int qdevice_net_algorithm_ask_for_vote_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote); extern int qdevice_net_algorithm_vote_info_received(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote); extern int qdevice_net_algorithm_echo_reply_received(struct qdevice_net_instance *instance, uint32_t seq_number, int is_expected_seq_number); extern int qdevice_net_algorithm_echo_reply_not_received(struct qdevice_net_instance *instance); extern int qdevice_net_algorithm_disconnected(struct qdevice_net_instance *instance, enum qdevice_net_disconnect_reason disconnect_reason, int *try_reconnect, enum tlv_vote *vote); extern void qdevice_net_algorithm_destroy(struct qdevice_net_instance *instance); struct qdevice_net_algorithm { int (*init)(struct qdevice_net_instance *instance); int (*connected)(struct qdevice_net_instance *instance, int *send_config_node_list, int *send_membership_node_list, int *send_quorum_node_list, enum tlv_vote *vote); int (*config_node_list_changed)(struct qdevice_net_instance *instance, const struct node_list *nlist, int config_version_set, uint64_t config_version, int *send_node_list, enum tlv_vote *vote); int (*votequorum_node_list_notify)(struct qdevice_net_instance *instance, const struct tlv_ring_id *ring_id, uint32_t node_list_entries, uint32_t node_list[], int *send_node_list, enum tlv_vote *vote); int (*votequorum_quorum_notify)(struct qdevice_net_instance *instance, uint32_t quorate, uint32_t node_list_entries, votequorum_node_t node_list[], int *send_node_list, enum tlv_vote *vote); + int (*votequorum_expected_votes_notify)(struct qdevice_net_instance *instance, + uint32_t expected_votes, enum tlv_vote *vote); int (*config_node_list_reply_received)(struct qdevice_net_instance *instance, uint32_t seq_number, int initial, enum tlv_vote *vote); int (*membership_node_list_reply_received)(struct qdevice_net_instance *instance, uint32_t seq_number, const struct tlv_ring_id *ring_id, enum tlv_vote *vote); int (*quorum_node_list_reply_received)(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote); int (*ask_for_vote_reply_received)(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote); int (*vote_info_received)(struct qdevice_net_instance *instance, uint32_t seq_number, enum tlv_vote *vote); int (*echo_reply_received)(struct qdevice_net_instance *instance, uint32_t seq_number, int is_expected_seq_number); int (*echo_reply_not_received)(struct qdevice_net_instance *instance); int (*disconnected)(struct qdevice_net_instance *instance, enum qdevice_net_disconnect_reason disconnect_reason, int *try_reconnect, enum tlv_vote *vote); void (*destroy)(struct qdevice_net_instance *instance); }; extern int qdevice_net_algorithm_register( enum tlv_decision_algorithm_type algorithm_number, struct qdevice_net_algorithm *algorithm); extern int qdevice_net_algorithm_register_all(void); #ifdef __cplusplus } #endif #endif /* _QDEVICE_NET_ALGORITHM_H_ */ diff --git a/qdevices/qdevice-net-disconnect-reason.h b/qdevices/qdevice-net-disconnect-reason.h index 5444c5f9..e8420bd5 100644 --- a/qdevices/qdevice-net-disconnect-reason.h +++ b/qdevices/qdevice-net-disconnect-reason.h @@ -1,123 +1,125 @@ /* * Copyright (c) 2015-2016 Red Hat, Inc. * * All rights reserved. * * Author: Jan Friesse (jfriesse@redhat.com) * * This software licensed under BSD license, the text of which follows: * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the Red Hat, Inc. nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _QDEVICE_NET_DISCONNECT_REASON_H_ #define _QDEVICE_NET_DISCONNECT_REASON_H_ #ifdef __cplusplus extern "C" { #endif enum qdevice_net_disconnect_reason { /* Undefined reason. If this error appears, it's error in source code */ QDEVICE_NET_DISCONNECT_REASON_UNDEFINED, /* Received known message, but it was not expected */ QDEVICE_NET_DISCONNECT_REASON_UNEXPECTED_MSG, /* Received unknown message */ QDEVICE_NET_DISCONNECT_REASON_UNSUPPORTED_MSG, /* TLS setting of server and client are incompatible */ QDEVICE_NET_DISCONNECT_REASON_INCOMPATIBLE_TLS, /* MSG setting of server and client are incompatible */ QDEVICE_NET_DISCONNECT_REASON_INCOMPATIBLE_MSG_SIZE, /* Message doesn't contain required option */ QDEVICE_NET_DISCONNECT_REASON_REQUIRED_OPTION_MISSING, /* Can't allocate send list item or message is too long to fit into send buffer */ QDEVICE_NET_DISCONNECT_REASON_CANT_ALLOCATE_MSG_BUFFER, /* Impossible to create or update heartbeat sending timer */ QDEVICE_NET_DISCONNECT_REASON_CANT_SCHEDULE_HB_TIMER, /* Impossible to create or update votequorum poll timer */ QDEVICE_NET_DISCONNECT_REASON_CANT_SCHEDULE_VOTING_TIMER, /* Impossible to register votequorum callback */ QDEVICE_NET_DISCONNECT_REASON_CANT_REGISTER_VOTEQUORUM_CALLBACK, /* Impossible to register cmap callback */ QDEVICE_NET_DISCONNECT_REASON_CANT_REGISTER_CMAP_CALLBACK, /* Impossible to start TLS session */ QDEVICE_NET_DISCONNECT_REASON_CANT_START_TLS, /* Received message with error field set to non TLV_REPLY_ERROR_CODE_NO_ERROR value */ QDEVICE_NET_DISCONNECT_REASON_SERVER_SENT_ERROR, /* Server doesn't support client selected decision algorithm */ QDEVICE_NET_DISCONNECT_REASON_SERVER_DOESNT_SUPPORT_REQUIRED_ALGORITHM, /* Can't decode message sent by server */ QDEVICE_NET_DISCONNECT_REASON_MSG_DECODE_ERROR, /* Server closed connection */ QDEVICE_NET_DISCONNECT_REASON_SERVER_CLOSED_CONNECTION, /* Can't read or store message received from server */ QDEVICE_NET_DISCONNECT_REASON_CANT_READ_MESSAGE, /* Can't send message to server */ QDEVICE_NET_DISCONNECT_REASON_CANT_SEND_MESSAGE, /* Can't dispatch cmap or votequroum. This cannot be overwritten and always means end of qdevice-net */ QDEVICE_NET_DISCONNECT_REASON_COROSYNC_CONNECTION_CLOSED, /* Local socket closed is reasult of sigint */ QDEVICE_NET_DISCONNECT_REASON_LOCAL_SOCKET_CLOSED, /* It was not possible to establish connection with qnetd */ QDEVICE_NET_DISCONNECT_REASON_CANT_CONNECT_TO_THE_SERVER, QDEVICE_NET_DISCONNECT_REASON_ALGO_CONNECTED_ERR, + QDEVICE_NET_DISCONNECT_REASON_ALGO_CONFIG_NODE_LIST_CHANGED_ERR, QDEVICE_NET_DISCONNECT_REASON_ALGO_VOTEQUORUM_QUORUM_NOTIFY_ERR, QDEVICE_NET_DISCONNECT_REASON_ALGO_VOTEQUORUM_NODE_LIST_NOTIFY_ERR, + QDEVICE_NET_DISCONNECT_REASON_ALGO_VOTEQUORUM_EXPECTED_VOTES_NOTIFY_ERR, QDEVICE_NET_DISCONNECT_REASON_ALGO_NODE_LIST_REPLY_ERR, QDEVICE_NET_DISCONNECT_REASON_ALGO_ASK_FOR_VOTE_REPLY_ERR, QDEVICE_NET_DISCONNECT_REASON_ALGO_VOTE_INFO_ERR, QDEVICE_NET_DISCONNECT_REASON_ALGO_ECHO_REPLY_RECEIVED_ERR, QDEVICE_NET_DISCONNECT_REASON_ALGO_ECHO_REPLY_NOT_RECEIVED_ERR, }; #define qdevice_net_disconnect_reason_try_reconnect(reason) ( \ reason == QDEVICE_NET_DISCONNECT_REASON_MSG_DECODE_ERROR || \ reason == QDEVICE_NET_DISCONNECT_REASON_SERVER_CLOSED_CONNECTION || \ reason == QDEVICE_NET_DISCONNECT_REASON_CANT_READ_MESSAGE || \ reason == QDEVICE_NET_DISCONNECT_REASON_CANT_SEND_MESSAGE || \ reason == QDEVICE_NET_DISCONNECT_REASON_CANT_CONNECT_TO_THE_SERVER || \ reason == QDEVICE_NET_DISCONNECT_REASON_ALGO_ECHO_REPLY_NOT_RECEIVED_ERR) #define qdevice_net_disconnect_reason_force_disconnect(reason) ( \ reason == QDEVICE_NET_DISCONNECT_REASON_COROSYNC_CONNECTION_CLOSED || \ reason == QDEVICE_NET_DISCONNECT_REASON_LOCAL_SOCKET_CLOSED || \ reason == QDEVICE_NET_DISCONNECT_REASON_CANT_SCHEDULE_VOTING_TIMER || \ reason == QDEVICE_NET_DISCONNECT_REASON_CANT_REGISTER_VOTEQUORUM_CALLBACK || \ reason == QDEVICE_NET_DISCONNECT_REASON_CANT_REGISTER_CMAP_CALLBACK) #ifdef __cplusplus } #endif #endif /* _QDEVICE_NET_DISCONNECT_REASON_H_ */