]>
Commit | Line | Data |
---|---|---|
9a1955a7 JF |
1 | /* |
2 | * Copyright (c) 2015-2017 Red Hat, Inc. | |
3 | * | |
4 | * All rights reserved. | |
5 | * | |
6 | * Author: Jan Friesse (jfriesse@redhat.com) | |
7 | * | |
8 | * This software licensed under BSD license, the text of which follows: | |
9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions are met: | |
12 | * | |
13 | * - Redistributions of source code must retain the above copyright notice, | |
14 | * this list of conditions and the following disclaimer. | |
15 | * - Redistributions in binary form must reproduce the above copyright notice, | |
16 | * this list of conditions and the following disclaimer in the documentation | |
17 | * and/or other materials provided with the distribution. | |
18 | * - Neither the name of the Red Hat, Inc. nor the names of its | |
19 | * contributors may be used to endorse or promote products derived from this | |
20 | * software without specific prior written permission. | |
21 | * | |
22 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
23 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
24 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
25 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | |
26 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
29 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
30 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
31 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | |
32 | * THE POSSIBILITY OF SUCH DAMAGE. | |
33 | */ | |
34 | ||
35 | #include <sys/types.h> | |
36 | ||
37 | #include "qnet-config.h" | |
38 | #include "qnetd-algorithm.h" | |
39 | #include "qnetd-algo-test.h" | |
40 | #include "qnetd-algo-ffsplit.h" | |
41 | #include "qnetd-algo-2nodelms.h" | |
42 | #include "qnetd-algo-lms.h" | |
43 | #include "qnetd-log.h" | |
44 | ||
45 | static struct qnetd_algorithm *qnetd_algorithm_array[QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE]; | |
46 | ||
47 | enum tlv_reply_error_code | |
48 | qnetd_algorithm_client_init(struct qnetd_client *client) | |
49 | { | |
50 | if (client->decision_algorithm >= QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || | |
51 | qnetd_algorithm_array[client->decision_algorithm] == NULL) { | |
52 | qnetd_log(LOG_CRIT, "qnetd_algorithm_client_init unhandled decision algorithm"); | |
53 | ||
54 | return (TLV_REPLY_ERROR_CODE_INTERNAL_ERROR); | |
55 | } | |
56 | ||
57 | return (qnetd_algorithm_array[client->decision_algorithm]->init(client)); | |
58 | } | |
59 | ||
60 | enum tlv_reply_error_code | |
61 | qnetd_algorithm_config_node_list_received(struct qnetd_client *client, | |
62 | uint32_t msg_seq_num, int config_version_set, uint64_t config_version, | |
63 | const struct node_list *nodes, int initial, enum tlv_vote *result_vote) | |
64 | { | |
65 | if (client->decision_algorithm >= QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || | |
66 | qnetd_algorithm_array[client->decision_algorithm] == NULL) { | |
67 | qnetd_log(LOG_CRIT, "qnetd_algorithm_config_node_list_received unhandled " | |
68 | "decision algorithm"); | |
69 | return (TLV_REPLY_ERROR_CODE_INTERNAL_ERROR); | |
70 | } | |
71 | ||
72 | return (qnetd_algorithm_array[client->decision_algorithm]->config_node_list_received( | |
73 | client, msg_seq_num, | |
74 | config_version_set, config_version, nodes, initial, result_vote)); | |
75 | } | |
76 | ||
77 | enum tlv_reply_error_code | |
78 | qnetd_algorithm_membership_node_list_received(struct qnetd_client *client, | |
79 | uint32_t msg_seq_num, const struct tlv_ring_id *ring_id, | |
80 | const struct node_list *nodes, enum tlv_heuristics heuristics, enum tlv_vote *result_vote) | |
81 | { | |
82 | ||
83 | if (client->decision_algorithm >= QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || | |
84 | qnetd_algorithm_array[client->decision_algorithm] == NULL) { | |
85 | qnetd_log(LOG_CRIT, "qnetd_algorithm_membership_node_list_received unhandled " | |
86 | "decision algorithm"); | |
87 | return (TLV_REPLY_ERROR_CODE_INTERNAL_ERROR); | |
88 | } | |
89 | ||
90 | return (qnetd_algorithm_array[client->decision_algorithm]->membership_node_list_received( | |
91 | client, msg_seq_num, | |
92 | ring_id, nodes, heuristics, result_vote)); | |
93 | } | |
94 | ||
95 | enum tlv_reply_error_code | |
96 | qnetd_algorithm_quorum_node_list_received(struct qnetd_client *client, | |
97 | uint32_t msg_seq_num, enum tlv_quorate quorate, | |
98 | const struct node_list *nodes, enum tlv_vote *result_vote) | |
99 | { | |
100 | ||
101 | if (client->decision_algorithm >= QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || | |
102 | qnetd_algorithm_array[client->decision_algorithm] == NULL) { | |
103 | qnetd_log(LOG_CRIT, "algorithm_quorum_node_list_received unhandled " | |
104 | "decision algorithm"); | |
105 | return (TLV_REPLY_ERROR_CODE_INTERNAL_ERROR); | |
106 | } | |
107 | ||
108 | return (qnetd_algorithm_array[client->decision_algorithm]->quorum_node_list_received( | |
109 | client, msg_seq_num, quorate, nodes, result_vote)); | |
110 | } | |
111 | ||
112 | void | |
113 | qnetd_algorithm_client_disconnect(struct qnetd_client *client, int server_going_down) | |
114 | { | |
115 | ||
116 | if (client->decision_algorithm >= QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || | |
117 | qnetd_algorithm_array[client->decision_algorithm] == NULL) { | |
118 | qnetd_log(LOG_CRIT, "qnetd_algorithm_client_disconnect unhandled decision " | |
119 | "algorithm"); | |
120 | return; | |
121 | } | |
122 | ||
123 | qnetd_algorithm_array[client->decision_algorithm]->client_disconnect(client, server_going_down); | |
124 | } | |
125 | ||
126 | enum tlv_reply_error_code | |
127 | qnetd_algorithm_ask_for_vote_received(struct qnetd_client *client, uint32_t msg_seq_num, | |
128 | enum tlv_vote *result_vote) | |
129 | { | |
130 | ||
131 | if (client->decision_algorithm >= QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || | |
132 | qnetd_algorithm_array[client->decision_algorithm] == NULL) { | |
133 | qnetd_log(LOG_CRIT, "qnetd_algorithm_ask_for_vote_received unhandled " | |
134 | "decision algorithm"); | |
135 | return (TLV_REPLY_ERROR_CODE_INTERNAL_ERROR); | |
136 | } | |
137 | ||
138 | return (qnetd_algorithm_array[client->decision_algorithm]->ask_for_vote_received( | |
139 | client, msg_seq_num, result_vote)); | |
140 | } | |
141 | ||
142 | enum tlv_reply_error_code | |
143 | qnetd_algorithm_vote_info_reply_received(struct qnetd_client *client, uint32_t msg_seq_num) | |
144 | { | |
145 | ||
146 | if (client->decision_algorithm >= QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || | |
147 | qnetd_algorithm_array[client->decision_algorithm] == NULL) { | |
148 | qnetd_log(LOG_CRIT, "qnetd_algorithm_vote_info_reply_received unhandled decision algorithm"); | |
149 | return (TLV_REPLY_ERROR_CODE_INTERNAL_ERROR); | |
150 | } | |
151 | ||
152 | return (qnetd_algorithm_array[client->decision_algorithm]->vote_info_reply_received( | |
153 | client, msg_seq_num)); | |
154 | ||
155 | } | |
156 | ||
157 | enum tlv_reply_error_code | |
158 | qnetd_algorithm_heuristics_change_received(struct qnetd_client *client, uint32_t msg_seq_num, | |
159 | enum tlv_heuristics heuristics, enum tlv_vote *result_vote) | |
160 | { | |
161 | ||
162 | if (client->decision_algorithm >= QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || | |
163 | qnetd_algorithm_array[client->decision_algorithm] == NULL) { | |
164 | qnetd_log(LOG_CRIT, "qnetd_algorithm_ask_for_vote_received unhandled " | |
165 | "decision algorithm"); | |
166 | return (TLV_REPLY_ERROR_CODE_INTERNAL_ERROR); | |
167 | } | |
168 | ||
169 | return (qnetd_algorithm_array[client->decision_algorithm]->heuristics_change_received( | |
170 | client, msg_seq_num, heuristics, result_vote)); | |
171 | } | |
172 | ||
173 | enum tlv_reply_error_code | |
174 | qnetd_algorithm_timer_callback(struct qnetd_client *client, int *reschedule_timer, | |
175 | int *send_vote, enum tlv_vote *result_vote) | |
176 | { | |
177 | ||
178 | if (client->decision_algorithm >= QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE || | |
179 | qnetd_algorithm_array[client->decision_algorithm] == NULL) { | |
180 | qnetd_log(LOG_CRIT, "qnetd_algorithm_timer_callback unhandled decision algorithm"); | |
181 | return (TLV_REPLY_ERROR_CODE_INTERNAL_ERROR); | |
182 | } | |
183 | ||
184 | return (qnetd_algorithm_array[client->decision_algorithm]->timer_callback( | |
185 | client, reschedule_timer, send_vote, result_vote)); | |
186 | } | |
187 | ||
188 | int | |
189 | qnetd_algorithm_register(enum tlv_decision_algorithm_type algorithm_number, | |
190 | struct qnetd_algorithm *algorithm) | |
191 | { | |
192 | ||
193 | if (algorithm_number >= QNETD_STATIC_SUPPORTED_DECISION_ALGORITHMS_SIZE) { | |
194 | qnetd_log(LOG_CRIT, "Failed to register unsupported decision algorithm %u", | |
195 | algorithm_number); | |
196 | return (-1); | |
197 | } | |
198 | ||
199 | if (qnetd_algorithm_array[algorithm_number] != NULL) { | |
200 | qnetd_log(LOG_CRIT, "Failed to register decision algorithm %u, " | |
201 | "it's already registered.", algorithm_number); | |
202 | return (-1); | |
203 | } | |
204 | ||
205 | qnetd_algorithm_array[algorithm_number] = algorithm; | |
206 | ||
207 | return (0); | |
208 | } | |
209 | ||
210 | int | |
211 | qnetd_algorithm_register_all(void) | |
212 | { | |
213 | ||
214 | if (qnetd_algo_test_register() != 0) { | |
215 | qnetd_log(LOG_CRIT, "Failed to register decision algorithm 'test'"); | |
216 | return (-1); | |
217 | } | |
218 | if (qnetd_algo_ffsplit_register() != 0) { | |
219 | qnetd_log(LOG_CRIT, "Failed to register decision algorithm 'ffsplit'"); | |
220 | return (-1); | |
221 | } | |
222 | if (qnetd_algo_2nodelms_register() != 0) { | |
223 | qnetd_log(LOG_CRIT, "Failed to register decision algorithm '2nodelms'"); | |
224 | return (-1); | |
225 | } | |
226 | if (qnetd_algo_lms_register() != 0) { | |
227 | qnetd_log(LOG_CRIT, "Failed to register decision algorithm 'lms'"); | |
228 | return (-1); | |
229 | } | |
230 | ||
231 | return (0); | |
232 | } |