diff --git a/qdevices/node-list.c b/qdevices/node-list.c index 45db7152..ec0efc43 100644 --- a/qdevices/node-list.c +++ b/qdevices/node-list.c @@ -1,196 +1,211 @@ /* * 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 #include "node-list.h" void node_list_init(struct node_list *list) { TAILQ_INIT(list); } struct node_list_entry * node_list_add(struct node_list *list, uint32_t node_id, uint32_t data_center_id, enum tlv_node_state node_state) { struct node_list_entry *node; node = (struct node_list_entry *)malloc(sizeof(*node)); if (node == NULL) { return (NULL); } memset(node, 0, sizeof(*node)); node->node_id = node_id; node->data_center_id = data_center_id; node->node_state = node_state; TAILQ_INSERT_TAIL(list, node, entries); return (node); } struct node_list_entry * node_list_add_from_node_info(struct node_list *list, const struct tlv_node_info *node_info) { return (node_list_add(list, node_info->node_id, node_info->data_center_id, node_info->node_state)); } int node_list_clone(struct node_list *dst_list, const struct node_list *src_list) { struct node_list_entry *node_entry; node_list_init(dst_list); TAILQ_FOREACH(node_entry, src_list, entries) { if (node_list_add(dst_list, node_entry->node_id, node_entry->data_center_id, node_entry->node_state) == NULL) { node_list_free(dst_list); return (-1); } } return (0); } void node_list_entry_to_tlv_node_info(const struct node_list_entry *node, struct tlv_node_info *node_info) { node_info->node_id = node->node_id; node_info->data_center_id = node->data_center_id; node_info->node_state = node->node_state; } void node_list_free(struct node_list *list) { struct node_list_entry *node; struct node_list_entry *node_next; node = TAILQ_FIRST(list); while (node != NULL) { node_next = TAILQ_NEXT(node, entries); free(node); node = node_next; } TAILQ_INIT(list); } void node_list_del(struct node_list *list, struct node_list_entry *node) { TAILQ_REMOVE(list, node, entries); free(node); } int node_list_is_empty(const struct node_list *list) { return (TAILQ_EMPTY(list)); } struct node_list_entry * node_list_find_node_id(const struct node_list *list, uint32_t node_id) { struct node_list_entry *node_entry; TAILQ_FOREACH(node_entry, list, entries) { if (node_entry->node_id == node_id) { return (node_entry); } } return (NULL); } int node_list_eq(const struct node_list *list1, const struct node_list *list2) { struct node_list_entry *node1_entry; struct node_list_entry *node2_entry; struct node_list tmp_list; int res; res = 1; if (node_list_clone(&tmp_list, list2) != 0) { return (-1); } TAILQ_FOREACH(node1_entry, list1, entries) { node2_entry = node_list_find_node_id(&tmp_list, node1_entry->node_id); if (node2_entry == NULL) { res = 0; goto return_res; } if (node1_entry->node_id != node2_entry->node_id || node1_entry->data_center_id != node2_entry->data_center_id || node1_entry->node_state != node2_entry->node_state) { res = 0; goto return_res; } node_list_del(&tmp_list, node2_entry); } if (!node_list_is_empty(&tmp_list)) { res = 0; goto return_res; } return_res: node_list_free(&tmp_list); return (res); } + +size_t +node_list_size(const struct node_list *nlist) +{ + struct node_list_entry *node_entry; + size_t res; + + res = 0; + + TAILQ_FOREACH(node_entry, nlist, entries) { + res++; + } + + return (res); +} diff --git a/qdevices/node-list.h b/qdevices/node-list.h index 222920a6..b05b62da 100644 --- a/qdevices/node-list.h +++ b/qdevices/node-list.h @@ -1,89 +1,91 @@ /* * 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 _NODE_LIST_H_ #define _NODE_LIST_H_ #include #include #include #include "tlv.h" #ifdef __cplusplus extern "C" { #endif struct node_list_entry { uint32_t node_id; uint32_t data_center_id; enum tlv_node_state node_state; TAILQ_ENTRY(node_list_entry) entries; }; TAILQ_HEAD(node_list, node_list_entry); extern void node_list_init(struct node_list *list); extern struct node_list_entry *node_list_add(struct node_list *list, uint32_t node_id, uint32_t data_center_id, enum tlv_node_state node_state); extern struct node_list_entry *node_list_add_from_node_info( struct node_list *list, const struct tlv_node_info *node_info); extern int node_list_clone(struct node_list *dst_list, const struct node_list *src_list); extern void node_list_free(struct node_list *list); extern void node_list_del(struct node_list *list, struct node_list_entry *node); extern int node_list_is_empty(const struct node_list *list); extern void node_list_entry_to_tlv_node_info( const struct node_list_entry *node, struct tlv_node_info *node_info); extern struct node_list_entry * node_list_find_node_id(const struct node_list *list, uint32_t node_id); extern int node_list_eq(const struct node_list *list1, const struct node_list *list2); +extern size_t node_list_size(const struct node_list *nlist); + #ifdef __cplusplus } #endif #endif /* _NODE_LIST_H_ */ diff --git a/qdevices/qnetd-algo-test.c b/qdevices/qnetd-algo-test.c index 94a3b06c..2ff8e7c4 100644 --- a/qdevices/qnetd-algo-test.c +++ b/qdevices/qnetd-algo-test.c @@ -1,237 +1,262 @@ /* * 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 "qnetd-algo-test.h" #include "qnetd-log.h" #include "qnetd-cluster-list.h" #include "qnetd-client-send.h" #include "qnetd-log-debug.h" #include "qnetd-client-algo-timer.h" #include "utils.h" /* * Called right after client sent init message. This happens after initial accept of client, * tls handshake and sending basic information about cluster/client. * Known information: * - client->cluster_name (client->cluster_name_len) * - client->node_id (client->node_id_set = 1) * - client->decision_algorithm * - client->cluster * - * Callback is designed mainly for allocating client->algorithm_data. + * Callback is designed mainly for allocating client->algorithm_data. It's also already + * part of the cluster, so can access (alloc) client->cluster->algorithm_data. * * client is initialized qnetd_client structure. * * Return TLV_REPLY_ERROR_CODE_NO_ERROR on success, different TLV_REPLY_ERROR_CODE_* * on failure (error is send back to client) */ enum tlv_reply_error_code qnetd_algo_test_client_init(struct qnetd_client *client) { int *algo_data; qnetd_log(LOG_WARNING, "algo-test: Client %s (cluster = '%s', node_id = " UTILS_PRI_NODE_ID") initiated test algorithm. It's not recommended to use test " "algorithm because it can create multiple quorate partitions!", client->addr_str, client->cluster_name, client->node_id); qnetd_log(LOG_INFO, "algo-test: client_init"); client->algorithm_data = malloc(sizeof(int)); if (client->algorithm_data == NULL) { return (-1); } algo_data = client->algorithm_data; *algo_data = 42; + if (qnetd_cluster_size(client->cluster) == 1) { + /* + * First client in the cluster + */ + qnetd_log(LOG_INFO, "algo-test: Initializing cluster->algorithm data"); + + client->cluster->algorithm_data = malloc(sizeof(int)); + if (client->cluster->algorithm_data == NULL) { + return (-1); + } + + algo_data = client->cluster->algorithm_data; + *algo_data = 42; + } + return (TLV_REPLY_ERROR_CODE_NO_ERROR); } /* * Called after client sent configuration node list * All client fields are already set. Nodes is actual node list, initial is used * for distrinquish between initial node list and changed node list. * msg_seq_num is 32-bit number set by client. If client sent config file version, * config_version_set is set to 1 and config_version contains valid config file version. * * Function has to return result_vote. This can be one of ack/nack, ask_later (client * should ask later for a vote) or wait_for_reply (client should wait for reply). * * Return TLV_REPLY_ERROR_CODE_NO_ERROR on success, different TLV_REPLY_ERROR_CODE_* * on failure (error is send back to client) */ enum tlv_reply_error_code qnetd_algo_test_config_node_list_received(struct qnetd_client *client, uint32_t msg_seq_num, int config_version_set, uint64_t config_version, const struct node_list *nodes, int initial, enum tlv_vote *result_vote) { qnetd_log(LOG_INFO, "algo-test: node_list_received"); *result_vote = TLV_VOTE_NO_CHANGE; return (TLV_REPLY_ERROR_CODE_NO_ERROR); } /* * Called after client sent membership node list. * All client fields are already set. Nodes is actual node list. * msg_seq_num is 32-bit number set by client. * ring_id is copied from client votequorum callback. * * Function has to return result_vote. This can be one of ack/nack, ask_later (client * should ask later for a vote) or wait_for_reply (client should wait for reply). * * Return TLV_REPLY_ERROR_CODE_NO_ERROR on success, different TLV_REPLY_ERROR_CODE_* * on failure (error is send back to client) */ enum tlv_reply_error_code qnetd_algo_test_membership_node_list_received(struct qnetd_client *client, uint32_t msg_seq_num, const struct tlv_ring_id *ring_id, const struct node_list *nodes, enum tlv_vote *result_vote) { qnetd_log(LOG_INFO, "algo-test: membership_node_list_received"); *result_vote = TLV_VOTE_ACK; return (TLV_REPLY_ERROR_CODE_NO_ERROR); } /* * Called after client sent quorum node list. * All client fields are already set. Nodes is actual node list. * msg_seq_num is 32-bit number set by client. * quorate is copied from client votequorum callback. * Function is just informative. If client vote is required to change, it's possible * to use qnetd_client_send_vote_info. * * Return TLV_REPLY_ERROR_CODE_NO_ERROR on success, different TLV_REPLY_ERROR_CODE_* * on failure (error is send back to client) */ enum tlv_reply_error_code qnetd_algo_test_quorum_node_list_received(struct qnetd_client *client, uint32_t msg_seq_num, enum tlv_quorate quorate, const struct node_list *nodes, enum tlv_vote *result_vote) { qnetd_log(LOG_INFO, "algo-test: quorum_node_list_received"); *result_vote = TLV_VOTE_NO_CHANGE; return (TLV_REPLY_ERROR_CODE_NO_ERROR); } /* * Called after client disconnect. Client structure is still existing (and it's part * of a client->cluster), but it is destroyed (and removed from cluster) right after * this callback finishes. Callback is used mainly for destroing client->algorithm_data. */ void qnetd_algo_test_client_disconnect(struct qnetd_client *client, int server_going_down) { qnetd_log(LOG_INFO, "algo-test: client_disconnect"); free(client->algorithm_data); + + if (qnetd_cluster_size(client->cluster) == 1) { + /* + * Last client in the cluster + */ + qnetd_log(LOG_INFO, "algo-test: Finalizing cluster->algorithm data"); + + free(client->cluster->algorithm_data); + } } /* * Called after client sent ask for vote message. This is usually happening after server * replied TLV_VOTE_ASK_LATER. */ enum tlv_reply_error_code qnetd_algo_test_ask_for_vote_received(struct qnetd_client *client, uint32_t msg_seq_num, enum tlv_vote *result_vote) { qnetd_log(LOG_INFO, "algo-test: ask_for_vote_received"); *result_vote = TLV_VOTE_ACK; return (TLV_REPLY_ERROR_CODE_NO_ERROR); } enum tlv_reply_error_code qnetd_algo_test_vote_info_reply_received(struct qnetd_client *client, uint32_t msg_seq_num) { qnetd_log(LOG_INFO, "algo-test: vote_info_reply_received"); return (TLV_REPLY_ERROR_CODE_NO_ERROR); } /* * Called as a result of qnetd_client_algo_timer_schedule function call after timeout expires. * * If send_vote is set by callback to non zero value, result_vote must also be set and such vote is * send to client. Result_vote is ignored if send_vote = 0 (default). * * If reschedule timer (default value = 0) is set to non zero value, callback is called again later * with same timeout as originaly created. * * Return TLV_REPLY_ERROR_CODE_NO_ERROR on success, different TLV_REPLY_ERROR_CODE_* * on failure (error is send back to client) */ enum tlv_reply_error_code qnetd_algo_test_timer_callback(struct qnetd_client *client, int *reschedule_timer, int *send_vote, enum tlv_vote *result_vote) { return (TLV_REPLY_ERROR_CODE_NO_ERROR); } static struct qnetd_algorithm qnetd_algo_test = { .init = qnetd_algo_test_client_init, .config_node_list_received = qnetd_algo_test_config_node_list_received, .membership_node_list_received = qnetd_algo_test_membership_node_list_received, .quorum_node_list_received = qnetd_algo_test_quorum_node_list_received, .client_disconnect = qnetd_algo_test_client_disconnect, .ask_for_vote_received = qnetd_algo_test_ask_for_vote_received, .vote_info_reply_received = qnetd_algo_test_vote_info_reply_received, .timer_callback = qnetd_algo_test_timer_callback, }; enum tlv_reply_error_code qnetd_algo_test_register() { return (qnetd_algorithm_register(TLV_DECISION_ALGORITHM_TYPE_TEST, &qnetd_algo_test)); } diff --git a/qdevices/qnetd-cluster-list.c b/qdevices/qnetd-cluster-list.c index 15a5e635..0849d84b 100644 --- a/qdevices/qnetd-cluster-list.c +++ b/qdevices/qnetd-cluster-list.c @@ -1,139 +1,139 @@ /* * 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 #include "qnetd-cluster-list.h" void qnetd_cluster_list_init(struct qnetd_cluster_list *list) { TAILQ_INIT(list); } struct qnetd_cluster * qnetd_cluster_list_find_by_name(struct qnetd_cluster_list *list, const char *cluster_name, size_t cluster_name_len) { struct qnetd_cluster *cluster; TAILQ_FOREACH(cluster, list, entries) { if (cluster->cluster_name_len == cluster_name_len && memcmp(cluster->cluster_name, cluster_name, cluster_name_len) == 0) { return (cluster); } } return (NULL); } struct qnetd_cluster * qnetd_cluster_list_add_client(struct qnetd_cluster_list *list, struct qnetd_client *client) { struct qnetd_cluster *cluster; cluster = qnetd_cluster_list_find_by_name(list, client->cluster_name, client->cluster_name_len); if (cluster == NULL) { cluster = (struct qnetd_cluster *)malloc(sizeof(*cluster)); if (cluster == NULL) { return (NULL); } if (qnetd_cluster_init(cluster, client->cluster_name, client->cluster_name_len) != 0) { free(cluster); return (NULL); } TAILQ_INSERT_TAIL(list, cluster, entries); } TAILQ_INSERT_TAIL(&cluster->client_list, client, cluster_entries); return (cluster); } void qnetd_cluster_list_del_client(struct qnetd_cluster_list *list, struct qnetd_cluster *cluster, struct qnetd_client *client) { TAILQ_REMOVE(&cluster->client_list, client, cluster_entries); if (TAILQ_EMPTY(&cluster->client_list)) { TAILQ_REMOVE(list, cluster, entries); qnetd_cluster_destroy(cluster); free(cluster); } } void qnetd_cluster_list_free(struct qnetd_cluster_list *list) { struct qnetd_cluster *cluster; struct qnetd_cluster *cluster_next; cluster = TAILQ_FIRST(list); while (cluster != NULL) { cluster_next = TAILQ_NEXT(cluster, entries); qnetd_cluster_destroy(cluster); free(cluster); cluster = cluster_next; } TAILQ_INIT(list); } size_t -qnetd_cluster_list_size(struct qnetd_cluster_list *list) +qnetd_cluster_list_size(const struct qnetd_cluster_list *list) { size_t res; struct qnetd_cluster *cluster; res = 0; TAILQ_FOREACH(cluster, list, entries) { res++; } return (res); } diff --git a/qdevices/qnetd-cluster-list.h b/qdevices/qnetd-cluster-list.h index a008a0e7..45f49df4 100644 --- a/qdevices/qnetd-cluster-list.h +++ b/qdevices/qnetd-cluster-list.h @@ -1,72 +1,72 @@ /* * 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 _QNETD_CLUSTER_LIST_H_ #define _QNETD_CLUSTER_LIST_H_ #include #include #include #include "qnetd-client-list.h" #include "qnetd-cluster.h" #ifdef __cplusplus extern "C" { #endif TAILQ_HEAD(qnetd_cluster_list, qnetd_cluster); extern void qnetd_cluster_list_init(struct qnetd_cluster_list *list); extern struct qnetd_cluster *qnetd_cluster_list_find_by_name( struct qnetd_cluster_list *list, const char *cluster_name, size_t cluster_name_len); extern struct qnetd_cluster *qnetd_cluster_list_add_client( struct qnetd_cluster_list *list, struct qnetd_client *client); extern void qnetd_cluster_list_del_client( struct qnetd_cluster_list *list, struct qnetd_cluster *cluster, struct qnetd_client *client); extern void qnetd_cluster_list_free(struct qnetd_cluster_list *list); extern size_t qnetd_cluster_list_size( - struct qnetd_cluster_list *list); + const struct qnetd_cluster_list *list); #ifdef __cplusplus } #endif #endif /* _QNETD_CLUSTER_LIST_H_ */ diff --git a/qdevices/qnetd-cluster.c b/qdevices/qnetd-cluster.c index 5ac78ed9..49d3b076 100644 --- a/qdevices/qnetd-cluster.c +++ b/qdevices/qnetd-cluster.c @@ -1,81 +1,81 @@ /* * 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 #include "qnetd-cluster.h" int qnetd_cluster_init(struct qnetd_cluster *cluster, const char *cluster_name, size_t cluster_name_len) { memset(cluster, 0, sizeof(*cluster)); cluster->cluster_name = malloc(cluster_name_len + 1); if (cluster->cluster_name == NULL) { return (-1); } memset(cluster->cluster_name, 0, cluster_name_len + 1); memcpy(cluster->cluster_name, cluster_name, cluster_name_len); cluster->cluster_name_len = cluster_name_len; TAILQ_INIT(&cluster->client_list); return (0); } void qnetd_cluster_destroy(struct qnetd_cluster *cluster) { free(cluster->cluster_name); cluster->cluster_name = NULL; } size_t -qnetd_cluster_size(struct qnetd_cluster *cluster) +qnetd_cluster_size(const struct qnetd_cluster *cluster) { size_t res; struct qnetd_client *client; res = 0; TAILQ_FOREACH(client, &cluster->client_list, cluster_entries) { res++; } return (res); } diff --git a/qdevices/qnetd-cluster.h b/qdevices/qnetd-cluster.h index dcc9502a..128e675d 100644 --- a/qdevices/qnetd-cluster.h +++ b/qdevices/qnetd-cluster.h @@ -1,69 +1,69 @@ /* * 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 _QNETD_CLUSTER_H_ #define _QNETD_CLUSTER_H_ #include #include #include #include "tlv.h" #include "qnetd-client-list.h" #ifdef __cplusplus extern "C" { #endif struct qnetd_cluster { char *cluster_name; size_t cluster_name_len; void *algorithm_data; struct qnetd_client_list client_list; TAILQ_ENTRY(qnetd_cluster) entries; }; extern int qnetd_cluster_init(struct qnetd_cluster *cluster, const char *cluster_name, size_t cluster_name_len); extern void qnetd_cluster_destroy(struct qnetd_cluster *cluster); -extern size_t qnetd_cluster_size(struct qnetd_cluster *cluster); +extern size_t qnetd_cluster_size(const struct qnetd_cluster *cluster); #ifdef __cplusplus } #endif #endif /* _QNETD_CLUSTER_H_ */