diff options
Diffstat (limited to 'lib/cfg.c')
-rw-r--r-- | lib/cfg.c | 835 |
1 files changed, 835 insertions, 0 deletions
diff --git a/lib/cfg.c b/lib/cfg.c new file mode 100644 index 0000000..f0a3e9a --- /dev/null +++ b/lib/cfg.c @@ -0,0 +1,835 @@ +/* + * Copyright (c) 2002-2005 MontaVista Software, Inc. + * Copyright (c) 2006-2020 Red Hat, Inc. + * + * All rights reserved. + * + * Author: Steven Dake (sdake@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 MontaVista Software, 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 <config.h> + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <pthread.h> +#include <limits.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/select.h> +#include <sys/un.h> +#include <sys/uio.h> + +#include <qb/qbipcc.h> + +#include <corosync/corotypes.h> +#include <corosync/corodefs.h> +#include <corosync/hdb.h> + +#include <corosync/cfg.h> +#include <corosync/ipc_cfg.h> + +#include "util.h" + +/* + * Data structure for instance data + */ +struct cfg_inst { + qb_ipcc_connection_t *c; + corosync_cfg_callbacks_t callbacks; + cs_name_t comp_name; + int comp_registered; + int finalize; +}; + +/* + * All instances in one database + */ +static void cfg_inst_free (void *inst); + +DECLARE_HDB_DATABASE (cfg_hdb, cfg_inst_free); + +/* + * Implementation + */ + +cs_error_t +corosync_cfg_initialize ( + corosync_cfg_handle_t *cfg_handle, + const corosync_cfg_callbacks_t *cfg_callbacks) +{ + struct cfg_inst *cfg_inst; + cs_error_t error = CS_OK; + + error = hdb_error_to_cs (hdb_handle_create (&cfg_hdb, sizeof (struct cfg_inst), cfg_handle)); + if (error != CS_OK) { + goto error_no_destroy; + } + + error = hdb_error_to_cs (hdb_handle_get (&cfg_hdb, *cfg_handle, (void *)&cfg_inst)); + if (error != CS_OK) { + goto error_destroy; + } + + cfg_inst->finalize = 0; + cfg_inst->c = qb_ipcc_connect ("cfg", IPC_REQUEST_SIZE); + if (cfg_inst->c == NULL) { + error = qb_to_cs_error(-errno); + goto error_put_destroy; + } + + if (cfg_callbacks) { + memcpy (&cfg_inst->callbacks, cfg_callbacks, sizeof (corosync_cfg_callbacks_t)); + } + + (void)hdb_handle_put (&cfg_hdb, *cfg_handle); + + return (CS_OK); + +error_put_destroy: + (void)hdb_handle_put (&cfg_hdb, *cfg_handle); +error_destroy: + (void)hdb_handle_destroy (&cfg_hdb, *cfg_handle); +error_no_destroy: + return (error); +} + +cs_error_t +corosync_cfg_fd_get ( + corosync_cfg_handle_t cfg_handle, + int32_t *selection_fd) +{ + struct cfg_inst *cfg_inst; + cs_error_t error; + + error = hdb_error_to_cs (hdb_handle_get (&cfg_hdb, cfg_handle, (void *)&cfg_inst)); + if (error != CS_OK) { + return (error); + } + + error = qb_to_cs_error (qb_ipcc_fd_get (cfg_inst->c, selection_fd)); + + (void)hdb_handle_put (&cfg_hdb, cfg_handle); + return (error); +} + +cs_error_t +corosync_cfg_dispatch ( + corosync_cfg_handle_t cfg_handle, + cs_dispatch_flags_t dispatch_flags) +{ + int timeout = -1; + cs_error_t error; + int cont = 1; /* always continue do loop except when set to 0 */ + struct cfg_inst *cfg_inst; + struct res_lib_cfg_testshutdown *res_lib_cfg_testshutdown; + corosync_cfg_callbacks_t callbacks; + struct qb_ipc_response_header *dispatch_data; + char dispatch_buf[IPC_DISPATCH_SIZE]; + + error = hdb_error_to_cs (hdb_handle_get (&cfg_hdb, cfg_handle, + (void *)&cfg_inst)); + if (error != CS_OK) { + return (error); + } + + /* + * Timeout instantly for CS_DISPATCH_ONE_NONBLOCKING or CS_DISPATCH_ALL and + * wait indefinately for CS_DISPATCH_ONE or CS_DISPATCH_BLOCKING + */ + if (dispatch_flags == CS_DISPATCH_ALL || dispatch_flags == CS_DISPATCH_ONE_NONBLOCKING) { + timeout = 0; + } + + dispatch_data = (struct qb_ipc_response_header *)dispatch_buf; + do { + error = qb_to_cs_error (qb_ipcc_event_recv ( + cfg_inst->c, + dispatch_buf, + IPC_DISPATCH_SIZE, + timeout)); + if (error == CS_ERR_BAD_HANDLE) { + error = CS_OK; + goto error_put; + } + if (error == CS_ERR_TRY_AGAIN) { + if (dispatch_flags == CS_DISPATCH_ONE_NONBLOCKING) { + /* + * Don't mask error + */ + goto error_put; + } + error = CS_OK; + if (dispatch_flags == CS_DISPATCH_ALL) { + break; /* exit do while cont is 1 loop */ + } else { + continue; /* next poll */ + } + } + if (error != CS_OK) { + goto error_put; + } + + /* + * Make copy of callbacks, message data, unlock instance, and call callback + * A risk of this dispatch method is that the callback routines may + * operate at the same time that cfgFinalize has been called in another thread. + */ + memcpy (&callbacks, &cfg_inst->callbacks, sizeof (corosync_cfg_callbacks_t)); + + /* + * Dispatch incoming response + */ + switch (dispatch_data->id) { + case MESSAGE_RES_CFG_TESTSHUTDOWN: + if (callbacks.corosync_cfg_shutdown_callback == NULL) { + break; + } + + res_lib_cfg_testshutdown = (struct res_lib_cfg_testshutdown *)dispatch_data; + callbacks.corosync_cfg_shutdown_callback(cfg_handle, res_lib_cfg_testshutdown->flags); + break; + default: + error = CS_ERR_LIBRARY; + goto error_nounlock; + break; + } + if (cfg_inst->finalize) { + /* + * If the finalize has been called then get out of the dispatch. + */ + error = CS_ERR_BAD_HANDLE; + goto error_put; + } + + /* + * Determine if more messages should be processed + */ + if (dispatch_flags == CS_DISPATCH_ONE || dispatch_flags == CS_DISPATCH_ONE_NONBLOCKING) { + cont = 0; + } + } while (cont); + +error_put: + (void)hdb_handle_put (&cfg_hdb, cfg_handle); +error_nounlock: + return (error); +} + +static void cfg_inst_free (void *inst) +{ + struct cfg_inst *cfg_inst = (struct cfg_inst *)inst; + qb_ipcc_disconnect(cfg_inst->c); +} + +cs_error_t +corosync_cfg_finalize ( + corosync_cfg_handle_t cfg_handle) +{ + struct cfg_inst *cfg_inst; + cs_error_t error; + + error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle, (void *)&cfg_inst)); + if (error != CS_OK) { + return (error); + } + + /* + * Another thread has already started finalizing + */ + if (cfg_inst->finalize) { + (void)hdb_handle_put (&cfg_hdb, cfg_handle); + return (CS_ERR_BAD_HANDLE); + } + + cfg_inst->finalize = 1; + + (void)hdb_handle_destroy (&cfg_hdb, cfg_handle); + + (void)hdb_handle_put (&cfg_hdb, cfg_handle); + + return (error); +} + +cs_error_t +corosync_cfg_ring_status_get ( + corosync_cfg_handle_t cfg_handle, + char ***interface_names, + char ***status, + unsigned int *interface_count) +{ + struct cfg_inst *cfg_inst; + struct req_lib_cfg_ringstatusget req_lib_cfg_ringstatusget; + struct res_lib_cfg_ringstatusget res_lib_cfg_ringstatusget; + unsigned int i, j; + cs_error_t error; + struct iovec iov; + + error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle, (void *)&cfg_inst)); + if (error != CS_OK) { + return (error); + } + + req_lib_cfg_ringstatusget.header.size = sizeof (struct req_lib_cfg_ringstatusget); + req_lib_cfg_ringstatusget.header.id = MESSAGE_REQ_CFG_RINGSTATUSGET; + + iov.iov_base = (void *)&req_lib_cfg_ringstatusget, + iov.iov_len = sizeof (struct req_lib_cfg_ringstatusget), + + error = qb_to_cs_error (qb_ipcc_sendv_recv(cfg_inst->c, + &iov, + 1, + &res_lib_cfg_ringstatusget, + sizeof (struct res_lib_cfg_ringstatusget), CS_IPC_TIMEOUT_MS)); + + if (error != CS_OK) { + goto exit_handle_put; + } + + *interface_count = res_lib_cfg_ringstatusget.interface_count; + *interface_names = malloc (sizeof (char *) * *interface_count); + if (*interface_names == NULL) { + return (CS_ERR_NO_MEMORY); + } + memset (*interface_names, 0, sizeof (char *) * *interface_count); + + *status = malloc (sizeof (char *) * *interface_count); + if (*status == NULL) { + error = CS_ERR_NO_MEMORY; + goto error_free_interface_names_array; + } + memset (*status, 0, sizeof (char *) * *interface_count); + + for (i = 0; i < res_lib_cfg_ringstatusget.interface_count; i++) { + (*(interface_names))[i] = strdup (res_lib_cfg_ringstatusget.interface_name[i]); + if ((*(interface_names))[i] == NULL) { + error = CS_ERR_NO_MEMORY; + goto error_free_interface_names; + } + } + + for (i = 0; i < res_lib_cfg_ringstatusget.interface_count; i++) { + (*(status))[i] = strdup (res_lib_cfg_ringstatusget.interface_status[i]); + if ((*(status))[i] == NULL) { + error = CS_ERR_NO_MEMORY; + goto error_free_status; + } + } + goto exit_handle_put; + +error_free_status: + for (j = 0; j < i; j++) { + free ((*(status))[j]); + } + i = *interface_count; + +error_free_interface_names: + for (j = 0; j < i; j++) { + free ((*(interface_names))[j]); + } + + free (*status); + +error_free_interface_names_array: + free (*interface_names); + +exit_handle_put: + (void)hdb_handle_put (&cfg_hdb, cfg_handle); + + return (error); +} + +cs_error_t +corosync_cfg_node_status_get ( + corosync_cfg_handle_t cfg_handle, + unsigned int nodeid, + corosync_cfg_node_status_version_t version, + void *node_status) +{ + struct cfg_inst *cfg_inst; + struct req_lib_cfg_nodestatusget req_lib_cfg_nodestatusget; + cs_error_t error; + struct iovec iov; + size_t cfg_node_status_size; + void *res_lib_cfg_nodestatuget_ptr; + struct res_lib_cfg_nodestatusget_v1 res_lib_cfg_nodestatusget_v1; + struct res_lib_cfg_nodestatusget_version *res_lib_cfg_nodestatusget_version; + + if (!node_status) { + return (CS_ERR_INVALID_PARAM); + } + + switch (version) { + case CFG_NODE_STATUS_V1: + cfg_node_status_size = sizeof(struct res_lib_cfg_nodestatusget_v1); + res_lib_cfg_nodestatuget_ptr = &res_lib_cfg_nodestatusget_v1; + + break; + default: + return (CS_ERR_INVALID_PARAM); + break; + } + + error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle, (void *)&cfg_inst)); + if (error != CS_OK) { + return (error); + } + + req_lib_cfg_nodestatusget.header.size = sizeof (struct req_lib_cfg_nodestatusget); + req_lib_cfg_nodestatusget.header.id = MESSAGE_REQ_CFG_NODESTATUSGET; + req_lib_cfg_nodestatusget.nodeid = nodeid; + req_lib_cfg_nodestatusget.version = version; + + iov.iov_base = (void *)&req_lib_cfg_nodestatusget, + iov.iov_len = sizeof (struct req_lib_cfg_nodestatusget), + + error = qb_to_cs_error (qb_ipcc_sendv_recv(cfg_inst->c, + &iov, + 1, + res_lib_cfg_nodestatuget_ptr, + cfg_node_status_size, CS_IPC_TIMEOUT_MS)); + if (error != CS_OK) { + goto error_put; + } + + res_lib_cfg_nodestatusget_version = res_lib_cfg_nodestatuget_ptr; + error = res_lib_cfg_nodestatusget_version->header.error; + if (error != CS_OK) { + goto error_put; + } + + if (res_lib_cfg_nodestatusget_version->version != version) { + /* + * corosync sent us something we don't really understand. + */ + error = CS_ERR_NOT_SUPPORTED; + goto error_put; + } + + switch (version) { + case CFG_NODE_STATUS_V1: + memcpy(node_status, &res_lib_cfg_nodestatusget_v1.node_status, + sizeof(struct corosync_cfg_node_status_v1)); + break; + } + +error_put: + (void)hdb_handle_put (&cfg_hdb, cfg_handle); + + return (error); +} + + +cs_error_t +corosync_cfg_trackstart ( + corosync_cfg_handle_t cfg_handle, + uint8_t track_flags) +{ + struct cfg_inst *cfg_inst; + struct req_lib_cfg_trackstart req_lib_cfg_trackstart; + struct res_lib_cfg_trackstart res_lib_cfg_trackstart; + cs_error_t error; + struct iovec iov; + + req_lib_cfg_trackstart.header.size = sizeof (struct req_lib_cfg_trackstart); + req_lib_cfg_trackstart.header.id = MESSAGE_REQ_CFG_TRACKSTART; + req_lib_cfg_trackstart.track_flags = track_flags; + + error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle, + (void *)&cfg_inst)); + if (error != CS_OK) { + return (error); + } + + iov.iov_base = (void *)&req_lib_cfg_trackstart, + iov.iov_len = sizeof (struct req_lib_cfg_trackstart), + + error = qb_to_cs_error (qb_ipcc_sendv_recv (cfg_inst->c, + &iov, + 1, + &res_lib_cfg_trackstart, + sizeof (struct res_lib_cfg_trackstart), CS_IPC_TIMEOUT_MS)); + + (void)hdb_handle_put (&cfg_hdb, cfg_handle); + + return (error == CS_OK ? res_lib_cfg_trackstart.header.error : error); +} + +cs_error_t +corosync_cfg_trackstop ( + corosync_cfg_handle_t cfg_handle) +{ + struct cfg_inst *cfg_inst; + struct req_lib_cfg_trackstop req_lib_cfg_trackstop; + struct res_lib_cfg_trackstop res_lib_cfg_trackstop; + cs_error_t error; + struct iovec iov; + + error = hdb_error_to_cs (hdb_handle_get (&cfg_hdb, cfg_handle, + (void *)&cfg_inst)); + if (error != CS_OK) { + return (error); + } + + req_lib_cfg_trackstop.header.size = sizeof (struct req_lib_cfg_trackstop); + req_lib_cfg_trackstop.header.id = MESSAGE_REQ_CFG_TRACKSTOP; + + iov.iov_base = (void *)&req_lib_cfg_trackstop, + iov.iov_len = sizeof (struct req_lib_cfg_trackstop), + + error = qb_to_cs_error (qb_ipcc_sendv_recv (cfg_inst->c, + &iov, + 1, + &res_lib_cfg_trackstop, + sizeof (struct res_lib_cfg_trackstop), CS_IPC_TIMEOUT_MS)); + + (void)hdb_handle_put (&cfg_hdb, cfg_handle); + + return (error == CS_OK ? res_lib_cfg_trackstop.header.error : error); +} + +cs_error_t +corosync_cfg_kill_node ( + corosync_cfg_handle_t cfg_handle, + unsigned int nodeid, + const char *reason) +{ + struct cfg_inst *cfg_inst; + struct req_lib_cfg_killnode req_lib_cfg_killnode; + struct res_lib_cfg_killnode res_lib_cfg_killnode; + cs_error_t error; + struct iovec iov; + + if (strlen(reason) >= CS_MAX_NAME_LENGTH) + return CS_ERR_NAME_TOO_LONG; + + error = hdb_error_to_cs (hdb_handle_get (&cfg_hdb, cfg_handle, + (void *)&cfg_inst)); + if (error != CS_OK) { + return (error); + } + + req_lib_cfg_killnode.header.id = MESSAGE_REQ_CFG_KILLNODE; + req_lib_cfg_killnode.header.size = sizeof (struct req_lib_cfg_killnode); + req_lib_cfg_killnode.nodeid = nodeid; + strcpy((char *)req_lib_cfg_killnode.reason.value, reason); + req_lib_cfg_killnode.reason.length = strlen(reason)+1; + + iov.iov_base = (void *)&req_lib_cfg_killnode; + iov.iov_len = sizeof (struct req_lib_cfg_killnode); + + error = qb_to_cs_error (qb_ipcc_sendv_recv (cfg_inst->c, + &iov, + 1, + &res_lib_cfg_killnode, + sizeof (struct res_lib_cfg_killnode), CS_IPC_TIMEOUT_MS)); + + error = res_lib_cfg_killnode.header.error; + + (void)hdb_handle_put (&cfg_hdb, cfg_handle); + + return (error == CS_OK ? res_lib_cfg_killnode.header.error : error); +} + +cs_error_t +corosync_cfg_try_shutdown ( + corosync_cfg_handle_t cfg_handle, + corosync_cfg_shutdown_flags_t flags) +{ + struct cfg_inst *cfg_inst; + struct req_lib_cfg_tryshutdown req_lib_cfg_tryshutdown; + struct res_lib_cfg_tryshutdown res_lib_cfg_tryshutdown; + cs_error_t error; + struct iovec iov; + + error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle, + (void *)&cfg_inst)); + if (error != CS_OK) { + return (error); + } + + req_lib_cfg_tryshutdown.header.id = MESSAGE_REQ_CFG_TRYSHUTDOWN; + req_lib_cfg_tryshutdown.header.size = sizeof (struct req_lib_cfg_tryshutdown); + req_lib_cfg_tryshutdown.flags = flags; + + iov.iov_base = (void *)&req_lib_cfg_tryshutdown; + iov.iov_len = sizeof (req_lib_cfg_tryshutdown); + + error = qb_to_cs_error (qb_ipcc_sendv_recv (cfg_inst->c, + &iov, + 1, + &res_lib_cfg_tryshutdown, + sizeof (struct res_lib_cfg_tryshutdown), CS_IPC_TIMEOUT_MS)); + + (void)hdb_handle_put (&cfg_hdb, cfg_handle); + + return (error == CS_OK ? res_lib_cfg_tryshutdown.header.error : error); +} + +cs_error_t +corosync_cfg_replyto_shutdown ( + corosync_cfg_handle_t cfg_handle, + corosync_cfg_shutdown_reply_flags_t response) +{ + struct cfg_inst *cfg_inst; + struct req_lib_cfg_replytoshutdown req_lib_cfg_replytoshutdown; + struct res_lib_cfg_replytoshutdown res_lib_cfg_replytoshutdown; + struct iovec iov; + cs_error_t error; + + error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle, + (void *)&cfg_inst)); + if (error != CS_OK) { + return (error); + } + + req_lib_cfg_replytoshutdown.header.id = MESSAGE_REQ_CFG_REPLYTOSHUTDOWN; + req_lib_cfg_replytoshutdown.header.size = sizeof (struct req_lib_cfg_replytoshutdown); + req_lib_cfg_replytoshutdown.response = response; + + iov.iov_base = (void *)&req_lib_cfg_replytoshutdown; + iov.iov_len = sizeof (struct req_lib_cfg_replytoshutdown); + + error = qb_to_cs_error (qb_ipcc_sendv_recv (cfg_inst->c, + &iov, + 1, + &res_lib_cfg_replytoshutdown, + sizeof (struct res_lib_cfg_replytoshutdown), CS_IPC_TIMEOUT_MS)); + + return (error); +} + +cs_error_t corosync_cfg_get_node_addrs ( + corosync_cfg_handle_t cfg_handle, + unsigned int nodeid, + size_t max_addrs, + int *num_addrs, + corosync_cfg_node_address_t *addrs) +{ + cs_error_t error; + struct req_lib_cfg_get_node_addrs req_lib_cfg_get_node_addrs; + struct res_lib_cfg_get_node_addrs *res_lib_cfg_get_node_addrs; + struct cfg_inst *cfg_inst; + int addrlen = 0; + int i; + struct iovec iov; + const char *addr_buf; + char response_buf[IPC_RESPONSE_SIZE]; + char zeroes[sizeof(struct sockaddr_storage)]; + + error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, cfg_handle, + (void *)&cfg_inst)); + if (error != CS_OK) { + return (error); + } + memset(zeroes, 0, sizeof(zeroes)); + + req_lib_cfg_get_node_addrs.header.size = sizeof (req_lib_cfg_get_node_addrs); + req_lib_cfg_get_node_addrs.header.id = MESSAGE_REQ_CFG_GET_NODE_ADDRS; + req_lib_cfg_get_node_addrs.nodeid = nodeid; + + iov.iov_base = (char *)&req_lib_cfg_get_node_addrs; + iov.iov_len = sizeof (req_lib_cfg_get_node_addrs); + + error = qb_to_cs_error (qb_ipcc_sendv_recv ( + cfg_inst->c, + &iov, 1, + response_buf, IPC_RESPONSE_SIZE, CS_IPC_TIMEOUT_MS)); + res_lib_cfg_get_node_addrs = (struct res_lib_cfg_get_node_addrs *)response_buf; + + if (error != CS_OK) { + goto error_put; + } + + if (res_lib_cfg_get_node_addrs->family == AF_INET) + addrlen = sizeof(struct sockaddr_in); + if (res_lib_cfg_get_node_addrs->family == AF_INET6) + addrlen = sizeof(struct sockaddr_in6); + + for (i = 0, addr_buf = (char *)res_lib_cfg_get_node_addrs->addrs; + i < max_addrs && i<res_lib_cfg_get_node_addrs->num_addrs; + i++, addr_buf += TOTEMIP_ADDRLEN) { + struct sockaddr_in *in; + struct sockaddr_in6 *in6; + + addrs[i].address_length = addrlen; + + if (res_lib_cfg_get_node_addrs->family == AF_INET) { + in = (struct sockaddr_in *)addrs[i].address; + if (memcmp(addr_buf, zeroes, addrlen) == 0) { + in->sin_family = 0; + } else { + in->sin_family = AF_INET; + } + memcpy(&in->sin_addr, addr_buf, sizeof(struct in_addr)); + } + if (res_lib_cfg_get_node_addrs->family == AF_INET6) { + in6 = (struct sockaddr_in6 *)addrs[i].address; + + if (memcmp(addr_buf, zeroes, addrlen) == 0) { + in6->sin6_family = 0; + } else { + in6->sin6_family = AF_INET6; + } + memcpy(&in6->sin6_addr, addr_buf, sizeof(struct in6_addr)); + } + + /* Mark it as unused */ + + } + *num_addrs = res_lib_cfg_get_node_addrs->num_addrs; + errno = error = res_lib_cfg_get_node_addrs->header.error; + +error_put: + hdb_handle_put (&cfg_hdb, cfg_handle); + + return (error); +} + +cs_error_t corosync_cfg_local_get ( + corosync_cfg_handle_t handle, + unsigned int *local_nodeid) +{ + cs_error_t error; + struct cfg_inst *cfg_inst; + struct iovec iov; + struct req_lib_cfg_local_get req_lib_cfg_local_get; + struct res_lib_cfg_local_get res_lib_cfg_local_get; + + error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, handle, (void *)&cfg_inst)); + if (error != CS_OK) { + return (error); + } + + req_lib_cfg_local_get.header.size = sizeof (struct qb_ipc_request_header); + req_lib_cfg_local_get.header.id = MESSAGE_REQ_CFG_LOCAL_GET; + + iov.iov_base = (void *)&req_lib_cfg_local_get; + iov.iov_len = sizeof (struct req_lib_cfg_local_get); + + error = qb_to_cs_error (qb_ipcc_sendv_recv ( + cfg_inst->c, + &iov, + 1, + &res_lib_cfg_local_get, + sizeof (struct res_lib_cfg_local_get), CS_IPC_TIMEOUT_MS)); + + if (error != CS_OK) { + goto error_exit; + } + + error = res_lib_cfg_local_get.header.error; + + *local_nodeid = res_lib_cfg_local_get.local_nodeid; + +error_exit: + (void)hdb_handle_put (&cfg_hdb, handle); + + return (error); +} + +cs_error_t corosync_cfg_reload_config ( + corosync_cfg_handle_t handle) +{ + cs_error_t error; + struct cfg_inst *cfg_inst; + struct iovec iov; + struct req_lib_cfg_reload_config req_lib_cfg_reload_config; + struct res_lib_cfg_reload_config res_lib_cfg_reload_config; + + error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, handle, (void *)&cfg_inst)); + if (error != CS_OK) { + return (error); + } + + req_lib_cfg_reload_config.header.size = sizeof (struct qb_ipc_request_header); + req_lib_cfg_reload_config.header.id = MESSAGE_REQ_CFG_RELOAD_CONFIG; + + iov.iov_base = (void *)&req_lib_cfg_reload_config; + iov.iov_len = sizeof (struct req_lib_cfg_reload_config); + + error = qb_to_cs_error (qb_ipcc_sendv_recv ( + cfg_inst->c, + &iov, + 1, + &res_lib_cfg_reload_config, + sizeof (struct res_lib_cfg_reload_config), CS_IPC_TIMEOUT_MS)); + + if (error != CS_OK) { + goto error_exit; + } + + error = res_lib_cfg_reload_config.header.error; + +error_exit: + (void)hdb_handle_put (&cfg_hdb, handle); + + return (error); +} + +cs_error_t corosync_cfg_reopen_log_files ( + corosync_cfg_handle_t handle) +{ + cs_error_t error; + struct cfg_inst *cfg_inst; + struct iovec iov; + struct req_lib_cfg_reopen_log_files req_lib_cfg_reopen_log_files; + struct res_lib_cfg_reopen_log_files res_lib_cfg_reopen_log_files; + + error = hdb_error_to_cs(hdb_handle_get (&cfg_hdb, handle, (void *)&cfg_inst)); + if (error != CS_OK) { + return (error); + } + + req_lib_cfg_reopen_log_files.header.size = sizeof (struct qb_ipc_request_header); + req_lib_cfg_reopen_log_files.header.id = MESSAGE_REQ_CFG_REOPEN_LOG_FILES; + + iov.iov_base = (void *)&req_lib_cfg_reopen_log_files; + iov.iov_len = sizeof (struct req_lib_cfg_reopen_log_files); + + error = qb_to_cs_error (qb_ipcc_sendv_recv ( + cfg_inst->c, + &iov, + 1, + &res_lib_cfg_reopen_log_files, + sizeof (struct res_lib_cfg_reopen_log_files), CS_IPC_TIMEOUT_MS)); + + if (error != CS_OK) { + goto error_exit; + } + + error = res_lib_cfg_reopen_log_files.header.error; + +error_exit: + (void)hdb_handle_put (&cfg_hdb, handle); + + return (error); +} |