Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/exec/apidef.c b/exec/apidef.c
index b22b17f1..72bfc620 100644
--- a/exec/apidef.c
+++ b/exec/apidef.c
@@ -1,185 +1,187 @@
/*
* Copyright (c) 2008, 2009 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 <stdlib.h>
#include <string.h>
#include <corosync/corotypes.h>
#include <corosync/coroipc_types.h>
#include <corosync/lcr/lcr_ifact.h>
#include <corosync/totem/totempg.h>
#include <corosync/totem/totemip.h>
#include <corosync/totem/totem.h>
#include <corosync/engine/logsys.h>
#include <corosync/coroipcs.h>
#include "util.h"
#include "timer.h"
#include "sync.h"
#include "quorum.h"
#include "schedwrk.h"
#include "main.h"
#include "apidef.h"
#include <corosync/engine/coroapi.h>
#include "service.h"
LOGSYS_DECLARE_SUBSYS ("APIDEF");
/*
* Remove compile warnings about type name changes in corosync_tpg_group
*/
typedef int (*typedef_tpg_join) (
hdb_handle_t,
const struct corosync_tpg_group *,
size_t);
typedef int (*typedef_tpg_leave) (hdb_handle_t,
const struct corosync_tpg_group *,
size_t);
typedef int (*typedef_tpg_groups_mcast_groups) (
hdb_handle_t, int,
const struct corosync_tpg_group *,
size_t groups_cnt,
const struct iovec *,
unsigned int);
typedef int (*typedef_tpg_groups_send_ok) (
hdb_handle_t,
const struct corosync_tpg_group *,
size_t groups_cnt,
struct iovec *,
int);
static inline void _corosync_public_exit_error (cs_fatal_error_t err,
const char *file,
unsigned int line)
__attribute__((noreturn));
static inline void _corosync_public_exit_error (
cs_fatal_error_t err, const char *file, unsigned int line)
{
_corosync_exit_error (err, file, line);
}
static struct corosync_api_v1 apidef_corosync_api_v1 = {
.timer_add_duration = corosync_timer_add_duration,
.timer_add_absolute = corosync_timer_add_absolute,
.timer_delete = corosync_timer_delete,
.timer_time_get = corosync_timer_time_get,
.timer_expire_time_get = corosync_timer_expire_time_get,
.ipc_source_set = message_source_set,
.ipc_source_is_local = message_source_is_local,
.ipc_private_data_get = coroipcs_private_data_get,
.ipc_response_iov_send = coroipcs_response_iov_send,
.ipc_response_send = coroipcs_response_send,
.ipc_dispatch_send = coroipcs_dispatch_send,
.ipc_dispatch_iov_send = coroipcs_dispatch_iov_send,
.ipc_refcnt_inc = coroipcs_refcount_inc,
.ipc_refcnt_dec = coroipcs_refcount_dec,
.totem_nodeid_get = totempg_my_nodeid_get,
.totem_family_get = totempg_my_family_get,
.totem_ring_reenable = totempg_ring_reenable,
.totem_mcast = main_mcast,
.totem_ifaces_get = totempg_ifaces_get,
.totem_ifaces_print = totempg_ifaces_print,
.totem_ip_print = totemip_print,
.totem_crypto_set = totempg_crypto_set,
.totem_callback_token_create = totempg_callback_token_create,
.totem_get_stats = totempg_get_stats,
.tpg_init = totempg_groups_initialize,
.tpg_exit = NULL, /* missing from totempg api */
.tpg_join = (typedef_tpg_join)totempg_groups_join,
.tpg_leave = (typedef_tpg_leave)totempg_groups_leave,
.tpg_joined_mcast = totempg_groups_mcast_joined,
.tpg_joined_reserve = totempg_groups_joined_reserve,
.tpg_joined_release = totempg_groups_joined_release,
.tpg_groups_mcast = (typedef_tpg_groups_mcast_groups)totempg_groups_mcast_groups,
.tpg_groups_reserve = NULL,
.tpg_groups_release = NULL,
.schedwrk_create = schedwrk_create,
.schedwrk_create_nolock = schedwrk_create_nolock,
.schedwrk_destroy = schedwrk_destroy,
.sync_request = NULL, //sync_request,
.quorum_is_quorate = corosync_quorum_is_quorate,
.quorum_register_callback = corosync_quorum_register_callback,
.quorum_unregister_callback = corosync_quorum_unregister_callback,
.quorum_initialize = corosync_quorum_initialize,
.service_link_and_init = corosync_service_link_and_init,
.service_unlink_and_exit = corosync_service_unlink_and_exit,
.plugin_interface_reference = lcr_ifact_reference,
.plugin_interface_release = lcr_ifact_release,
.error_memory_failure = _corosync_out_of_memory_error,
.fatal_error = _corosync_public_exit_error,
.shutdown_request = corosync_shutdown_request,
.state_dump = corosync_state_dump,
- .poll_handle_get = corosync_poll_handle_get
+ .poll_handle_get = corosync_poll_handle_get,
+ .poll_dispatch_add = poll_dispatch_add,
+ .poll_dispatch_delete = poll_dispatch_delete
};
void apidef_init (struct objdb_iface_ver0 *objdb) {
apidef_corosync_api_v1.object_create = objdb->object_create;
apidef_corosync_api_v1.object_priv_set = objdb->object_priv_set;
apidef_corosync_api_v1.object_key_create = objdb->object_key_create;
apidef_corosync_api_v1.object_destroy = objdb->object_destroy;
apidef_corosync_api_v1.object_valid_set = objdb->object_valid_set;
apidef_corosync_api_v1.object_key_valid_set = objdb->object_key_valid_set;
apidef_corosync_api_v1.object_find_create = objdb->object_find_create;
apidef_corosync_api_v1.object_find_next = objdb->object_find_next;
apidef_corosync_api_v1.object_find_destroy = objdb->object_find_destroy;
apidef_corosync_api_v1.object_key_get = objdb->object_key_get;
apidef_corosync_api_v1.object_priv_get = objdb->object_priv_get;
apidef_corosync_api_v1.object_key_replace = objdb->object_key_replace;
apidef_corosync_api_v1.object_key_delete = objdb->object_key_delete;
apidef_corosync_api_v1.object_iter_reset = objdb->object_iter_reset;
apidef_corosync_api_v1.object_iter = objdb->object_iter;
apidef_corosync_api_v1.object_key_iter = objdb->object_key_iter;
apidef_corosync_api_v1.object_parent_get = objdb->object_parent_get;
apidef_corosync_api_v1.object_name_get = objdb->object_name_get;
apidef_corosync_api_v1.object_dump = objdb->object_dump;
apidef_corosync_api_v1.object_key_iter_from = objdb->object_key_iter_from;
apidef_corosync_api_v1.object_track_start = objdb->object_track_start;
apidef_corosync_api_v1.object_track_stop = objdb->object_track_stop;
apidef_corosync_api_v1.object_write_config = objdb->object_write_config;
apidef_corosync_api_v1.object_reload_config = objdb->object_reload_config;
apidef_corosync_api_v1.object_key_increment = objdb->object_key_increment;
apidef_corosync_api_v1.object_key_decrement = objdb->object_key_decrement;
apidef_corosync_api_v1.object_key_create_typed = objdb->object_key_create_typed;
apidef_corosync_api_v1.object_key_get_typed = objdb->object_key_get_typed;
apidef_corosync_api_v1.object_key_iter_typed = objdb->object_key_iter_typed;
}
struct corosync_api_v1 *apidef_get (void)
{
return (&apidef_corosync_api_v1);
}
diff --git a/include/corosync/engine/coroapi.h b/include/corosync/engine/coroapi.h
index c3c812ff..2e27f989 100644
--- a/include/corosync/engine/coroapi.h
+++ b/include/corosync/engine/coroapi.h
@@ -1,696 +1,711 @@
/*
* Copyright (c) 2008, 2009 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.
*/
#ifndef COROAPI_H_DEFINED
#define COROAPI_H_DEFINED
#include <stdio.h>
#ifdef COROSYNC_BSD
#include <sys/uio.h>
#endif
#include <corosync/hdb.h>
#include <corosync/swab.h>
typedef struct {
uint32_t nodeid __attribute__((aligned(8)));
void *conn __attribute__((aligned(8)));
} mar_message_source_t __attribute__((aligned(8)));
static inline void swab_mar_message_source_t (mar_message_source_t *to_swab)
{
swab32 (to_swab->nodeid);
/*
* if it is from a byteswapped machine, then we can safely
* ignore its conn info data structure since this is only
* local to the machine
*/
to_swab->conn = NULL;
}
typedef void * corosync_timer_handle_t;
struct corosync_tpg_group {
const void *group;
size_t group_len;
};
#define TOTEMIP_ADDRLEN (sizeof(struct in6_addr))
#define INTERFACE_MAX 2
#ifdef HAVE_SMALL_MEMORY_FOOTPRINT
#define PROCESSOR_COUNT_MAX 16
#define MESSAGE_SIZE_MAX 1024*64
#define MESSAGE_QUEUE_MAX 512
#else
#define PROCESSOR_COUNT_MAX 384
#define MESSAGE_SIZE_MAX 1024*1024 /* (1MB) */
#define MESSAGE_QUEUE_MAX MESSAGE_SIZE_MAX / totem_config->net_mtu
#endif /* HAVE_SMALL_MEMORY_FOOTPRINT */
#define TOTEM_AGREED 0
#define TOTEM_SAFE 1
#define MILLI_2_NANO_SECONDS 1000000ULL
#if !defined(TOTEM_IP_ADDRESS)
struct totem_ip_address {
unsigned int nodeid;
unsigned short family;
unsigned char addr[TOTEMIP_ADDRLEN];
} __attribute__((packed));
#endif
#if !defined(MEMB_RING_ID)
struct memb_ring_id {
struct totem_ip_address rep;
unsigned long long seq;
} __attribute__((packed));
#endif
#if !defined(TOTEM_CONFIGURATION_TYPE)
enum totem_configuration_type {
TOTEM_CONFIGURATION_REGULAR,
TOTEM_CONFIGURATION_TRANSITIONAL
};
#endif
#if !defined(TOTEM_CALLBACK_TOKEN_TYPE)
enum totem_callback_token_type {
TOTEM_CALLBACK_TOKEN_RECEIVED = 1,
TOTEM_CALLBACK_TOKEN_SENT = 2
};
#endif
enum cs_lib_flow_control {
CS_LIB_FLOW_CONTROL_REQUIRED = 1,
CS_LIB_FLOW_CONTROL_NOT_REQUIRED = 2
};
#define corosync_lib_flow_control cs_lib_flow_control
#define COROSYNC_LIB_FLOW_CONTROL_REQUIRED CS_LIB_FLOW_CONTROL_REQUIRED
#define COROSYNC_LIB_FLOW_CONTROL_NOT_REQUIRED CS_LIB_FLOW_CONTROL_NOT_REQUIRED
enum cs_lib_allow_inquorate {
CS_LIB_DISALLOW_INQUORATE = 0, /* default */
CS_LIB_ALLOW_INQUORATE = 1
};
#if !defined (COROSYNC_FLOW_CONTROL_STATE)
enum cs_flow_control_state {
CS_FLOW_CONTROL_STATE_DISABLED,
CS_FLOW_CONTROL_STATE_ENABLED
};
#define corosync_flow_control_state cs_flow_control_state
#define CS_FLOW_CONTROL_STATE_DISABLED CS_FLOW_CONTROL_STATE_DISABLED
#define CS_FLOW_CONTROL_STATE_ENABLED CS_FLOW_CONTROL_STATE_ENABLED
#endif /* COROSYNC_FLOW_CONTROL_STATE */
enum cs_sync_mode {
CS_SYNC_V1 = 0,
CS_SYNC_V2 = 1,
CS_SYNC_V1_APIV2 = 2
};
typedef enum {
COROSYNC_FATAL_ERROR_EXIT = -1,
COROSYNC_LIBAIS_SOCKET = -6,
COROSYNC_LIBAIS_BIND = -7,
COROSYNC_READKEY = -8,
COROSYNC_INVALID_CONFIG = -9,
COROSYNC_DYNAMICLOAD = -12,
COROSYNC_OUT_OF_MEMORY = -15,
COROSYNC_FATAL_ERR = -16
} cs_fatal_error_t;
#define corosync_fatal_error_t cs_fatal_error_t;
#ifndef OBJECT_PARENT_HANDLE
#define OBJECT_PARENT_HANDLE 0xffffffff00000000ULL
struct object_valid {
char *object_name;
size_t object_len;
};
struct object_key_valid {
char *key_name;
size_t key_len;
int (*validate_callback) (const void *key, size_t key_len,
const void *value, size_t value_len);
};
/* deprecated */
typedef enum {
OBJDB_VALUETYPE_INT16,
OBJDB_VALUETYPE_UINT16,
OBJDB_VALUETYPE_INT32,
OBJDB_VALUETYPE_UINT32,
OBJDB_VALUETYPE_INT64,
OBJDB_VALUETYPE_UINT64,
OBJDB_VALUETYPE_FLOAT,
OBJDB_VALUETYPE_DOUBLE,
OBJDB_VALUETYPE_STRING,
OBJDB_VALUETYPE_ANY,
} objdb_value_types_t;
typedef enum {
OBJECT_TRACK_DEPTH_ONE,
OBJECT_TRACK_DEPTH_RECURSIVE
} object_track_depth_t;
typedef enum {
OBJECT_KEY_CREATED,
OBJECT_KEY_REPLACED,
OBJECT_KEY_DELETED
} object_change_type_t;
typedef enum {
OBJDB_RELOAD_NOTIFY_START,
OBJDB_RELOAD_NOTIFY_END,
OBJDB_RELOAD_NOTIFY_FAILED
} objdb_reload_notify_type_t;
typedef void (*object_key_change_notify_fn_t)(
object_change_type_t change_type,
hdb_handle_t parent_object_handle,
hdb_handle_t object_handle,
const void *object_name_pt, size_t object_name_len,
const void *key_name_pt, size_t key_len,
const void *key_value_pt, size_t key_value_len,
void *priv_data_pt);
typedef void (*object_create_notify_fn_t) (
hdb_handle_t parent_object_handle,
hdb_handle_t object_handle,
const uint8_t *name_pt, size_t name_len,
void *priv_data_pt);
typedef void (*object_destroy_notify_fn_t) (
hdb_handle_t parent_object_handle,
const uint8_t *name_pt, size_t name_len,
void *priv_data_pt);
typedef void (*object_notify_callback_fn_t)(
hdb_handle_t object_handle,
const void *key_name, size_t key_len,
const void *value, size_t value_len,
object_change_type_t type,
const void * priv_data_pt);
typedef void (*object_reload_notify_fn_t) (
objdb_reload_notify_type_t,
int flush,
void *priv_data_pt);
#endif /* OBJECT_PARENT_HANDLE_DEFINED */
#ifndef QUORUM_H_DEFINED
typedef void (*quorum_callback_fn_t) (int quorate, void *context);
struct quorum_callin_functions
{
int (*quorate) (void);
int (*register_callback) (quorum_callback_fn_t callback_fn, void *context);
int (*unregister_callback) (quorum_callback_fn_t callback_fn, void *context);
};
typedef void (*sync_callback_fn_t) (
const unsigned int *view_list,
size_t view_list_entries,
int primary_designated,
struct memb_ring_id *ring_id);
#endif /* QUORUM_H_DEFINED */
struct corosync_api_v1 {
/*
* Object and configuration APIs
*/
int (*object_create) (
hdb_handle_t parent_object_handle,
hdb_handle_t *object_handle,
const void *object_name,
size_t object_name_len);
int (*object_priv_set) (
hdb_handle_t object_handle,
void *priv);
int (*object_key_create) (
hdb_handle_t object_handle,
const void *key_name,
size_t key_len,
const void *value,
size_t value_len);
int (*object_destroy) (
hdb_handle_t object_handle);
int (*object_valid_set) (
hdb_handle_t object_handle,
struct object_valid *object_valid_list,
size_t object_valid_list_entries);
int (*object_key_valid_set) (
hdb_handle_t object_handle,
struct object_key_valid *object_key_valid_list,
size_t object_key_valid_list_entries);
int (*object_find_create) (
hdb_handle_t parent_object_handle,
const void *object_name,
size_t object_name_len,
hdb_handle_t *object_find_handle);
int (*object_find_next) (
hdb_handle_t object_find_handle,
hdb_handle_t *object_handle);
int (*object_find_destroy) (
hdb_handle_t object_find_handle);
int (*object_key_get) (
hdb_handle_t object_handle,
const void *key_name,
size_t key_len,
void **value,
size_t *value_len);
int (*object_priv_get) (
hdb_handle_t jobject_handle,
void **priv);
int (*object_key_replace) (
hdb_handle_t object_handle,
const void *key_name,
size_t key_len,
const void *new_value,
size_t new_value_len);
int (*object_key_delete) (
hdb_handle_t object_handle,
const void *key_name,
size_t key_len);
int (*object_iter_reset) (
hdb_handle_t parent_object_handle);
int (*object_iter) (
hdb_handle_t parent_object_handle,
void **object_name,
size_t *name_len,
hdb_handle_t *object_handle);
int (*object_key_iter_reset) (
hdb_handle_t object_handle);
int (*object_key_iter) (
hdb_handle_t parent_object_handle,
void **key_name,
size_t *key_len,
void **value,
size_t *value_len);
int (*object_parent_get) (
hdb_handle_t object_handle,
hdb_handle_t *parent_handle);
int (*object_name_get) (
hdb_handle_t object_handle,
char *object_name,
size_t *object_name_len);
int (*object_dump) (
hdb_handle_t object_handle,
FILE *file);
int (*object_key_iter_from) (
hdb_handle_t parent_object_handle,
hdb_handle_t start_pos,
void **key_name,
size_t *key_len,
void **value,
size_t *value_len);
int (*object_track_start) (
hdb_handle_t object_handle,
object_track_depth_t depth,
object_key_change_notify_fn_t key_change_notify_fn,
object_create_notify_fn_t object_create_notify_fn,
object_destroy_notify_fn_t object_destroy_notify_fn,
object_reload_notify_fn_t object_reload_notify_fn,
void * priv_data_pt);
void (*object_track_stop) (
object_key_change_notify_fn_t key_change_notify_fn,
object_create_notify_fn_t object_create_notify_fn,
object_destroy_notify_fn_t object_destroy_notify_fn,
object_reload_notify_fn_t object_reload_notify_fn,
void * priv_data_pt);
int (*object_write_config) (const char **error_string);
int (*object_reload_config) (int flush,
const char **error_string);
int (*object_key_increment) (
hdb_handle_t object_handle,
const void *key_name,
size_t key_len,
unsigned int *value);
int (*object_key_decrement) (
hdb_handle_t object_handle,
const void *key_name,
size_t key_len,
unsigned int *value);
/*
* Time and timer APIs
*/
int (*timer_add_duration) (
unsigned long long nanoseconds_in_future,
void *data,
void (*timer_nf) (void *data),
corosync_timer_handle_t *handle);
int (*timer_add_absolute) (
unsigned long long nanoseconds_from_epoch,
void *data,
void (*timer_fn) (void *data),
corosync_timer_handle_t *handle);
void (*timer_delete) (
corosync_timer_handle_t timer_handle);
unsigned long long (*timer_time_get) (void);
unsigned long long (*timer_expire_time_get) (
corosync_timer_handle_t timer_handle);
/*
* IPC APIs
*/
void (*ipc_source_set) (mar_message_source_t *source, void *conn);
int (*ipc_source_is_local) (const mar_message_source_t *source);
void *(*ipc_private_data_get) (void *conn);
int (*ipc_response_send) (void *conn, const void *msg, size_t mlen);
int (*ipc_response_iov_send) (void *conn,
const struct iovec *iov, unsigned int iov_len);
int (*ipc_dispatch_send) (void *conn, const void *msg, size_t mlen);
int (*ipc_dispatch_iov_send) (void *conn,
const struct iovec *iov, unsigned int iov_len);
void (*ipc_refcnt_inc) (void *conn);
void (*ipc_refcnt_dec) (void *conn);
/*
* Totem APIs
*/
unsigned int (*totem_nodeid_get) (void);
int (*totem_family_get) (void);
int (*totem_ring_reenable) (void);
int (*totem_mcast) (const struct iovec *iovec,
unsigned int iov_len, unsigned int guarantee);
int (*totem_ifaces_get) (
unsigned int nodeid,
struct totem_ip_address *interfaces,
char ***status,
unsigned int *iface_count);
const char *(*totem_ifaces_print) (unsigned int nodeid);
const char *(*totem_ip_print) (const struct totem_ip_address *addr);
int (*totem_crypto_set) (unsigned int type);
int (*totem_callback_token_create) (
void **handle_out,
enum totem_callback_token_type type,
int delete,
int (*callback_fn) (enum totem_callback_token_type type,
const void *),
const void *data);
/*
* Totem open process groups API for those service engines
* wanting their own groups
*/
int (*tpg_init) (
hdb_handle_t *handle,
void (*deliver_fn) (
unsigned int nodeid,
const void *msg,
unsigned int msg_len,
int endian_conversion_required),
void (*confchg_fn) (
enum totem_configuration_type configuration_type,
const unsigned int *member_list,
size_t member_list_entries,
const unsigned int *left_list,
size_t left_list_entries,
const unsigned int *joined_list,
size_t joined_list_entries,
const struct memb_ring_id *ring_id));
int (*tpg_exit) (
hdb_handle_t handle);
int (*tpg_join) (
hdb_handle_t handle,
const struct corosync_tpg_group *groups,
size_t group_cnt);
int (*tpg_leave) (
hdb_handle_t handle,
const struct corosync_tpg_group *groups,
size_t group_cnt);
int (*tpg_joined_mcast) (
hdb_handle_t handle,
const struct iovec *iovec,
unsigned int iov_len,
int guarantee);
int (*tpg_joined_reserve) (
hdb_handle_t handle,
const struct iovec *iovec,
unsigned int iov_len);
int (*tpg_joined_release) (
int reserved_msgs);
int (*tpg_groups_mcast) (
hdb_handle_t handle,
int guarantee,
const struct corosync_tpg_group *groups,
size_t groups_cnt,
const struct iovec *iovec,
unsigned int iov_len);
int (*tpg_groups_reserve) (
hdb_handle_t handle,
const struct corosync_tpg_group *groups,
size_t groups_cnt,
const struct iovec *iovec,
unsigned int iov_len);
int (*tpg_groups_release) (
int reserved_msgs);
int (*schedwrk_create) (
hdb_handle_t *handle,
int (schedwrk_fn) (const void *),
const void *context);
void (*schedwrk_destroy) (hdb_handle_t handle);
int (*sync_request) (
const char *service_name);
/*
* User plugin-callable functions for quorum
*/
int (*quorum_is_quorate) (void);
int (*quorum_register_callback) (quorum_callback_fn_t callback_fn, void *context);
int (*quorum_unregister_callback) (quorum_callback_fn_t callback_fn, void *context);
/*
* This one is for the quorum management plugin's use
*/
int (*quorum_initialize)(struct quorum_callin_functions *fns);
/*
* Plugin loading and unloading
*/
int (*plugin_interface_reference) (
hdb_handle_t *handle,
const char *iface_name,
int version,
void **interface,
void *context);
int (*plugin_interface_release) (hdb_handle_t handle);
/*
* Service loading and unloading APIs
*/
unsigned int (*service_link_and_init) (
struct corosync_api_v1 *corosync_api_v1,
const char *service_name,
unsigned int service_ver);
unsigned int (*service_unlink_and_exit) (
struct corosync_api_v1 *corosync_api_v1,
const char *service_name,
unsigned int service_ver);
/*
* Error handling APIs
*/
void (*error_memory_failure) (void) __attribute__ ((noreturn));
#define corosync_fatal_error(err) api->fatal_error ((err), __FILE__, __LINE__)
void (*fatal_error) (cs_fatal_error_t err,
const char *file,
unsigned int line) __attribute__ ((noreturn));
void (*shutdown_request) (void);
void (*state_dump) (void);
/*
* The use of this interface is highly discouraged.
* Please avoid using any of coropoll apis in your service engines.
*/
hdb_handle_t (*poll_handle_get) (void);
-
int (*object_key_create_typed) (
hdb_handle_t object_handle,
const char *key_name,
const void *value,
size_t value_len,
objdb_value_types_t type);
int (*object_key_get_typed) (
hdb_handle_t object_handle,
const char *key_name,
void **value,
size_t *value_len,
objdb_value_types_t *type);
int (*object_key_iter_typed) (
hdb_handle_t parent_object_handle,
char **key_name,
void **value,
size_t *value_len,
objdb_value_types_t *type);
void *(*totem_get_stats)(void);
int (*schedwrk_create_nolock) (
hdb_handle_t *handle,
int (schedwrk_fn) (const void *),
const void *context);
+
+ int (*poll_dispatch_add) (hdb_handle_t handle,
+ int fd,
+ int events,
+ void *data,
+
+ int (*dispatch_fn) (hdb_handle_t handle,
+ int fd,
+ int revents,
+ void *data));
+
+
+ int (*poll_dispatch_delete) (
+ hdb_handle_t handle,
+ int fd);
+
};
#define SERVICE_ID_MAKE(a,b) ( ((a)<<16) | (b) )
#define SERVICE_HANDLER_MAXIMUM_COUNT 64
struct corosync_lib_handler {
void (*lib_handler_fn) (void *conn, const void *msg);
enum cs_lib_flow_control flow_control;
};
struct corosync_exec_handler {
void (*exec_handler_fn) (const void *msg, unsigned int nodeid);
void (*exec_endian_convert_fn) (void *msg);
};
struct corosync_service_engine_iface_ver0 {
struct corosync_service_engine *(*corosync_get_service_engine_ver0) (void);
};
typedef void (*sync_init_v1_fn_t) (
const unsigned int *member_list,
size_t member_list_entries,
const struct memb_ring_id *ring_id) ;
struct corosync_service_engine {
const char *name;
unsigned short id;
unsigned short priority; /* Lower priority are loaded first, unloaded last.
* 0 is a special case which always loaded _and_ unloaded last
*/
unsigned int private_data_size;
enum cs_lib_flow_control flow_control;
enum cs_lib_allow_inquorate allow_inquorate;
int (*exec_init_fn) (struct corosync_api_v1 *);
int (*exec_exit_fn) (void);
void (*exec_dump_fn) (void);
int (*lib_init_fn) (void *conn);
int (*lib_exit_fn) (void *conn);
struct corosync_lib_handler *lib_engine;
int lib_engine_count;
struct corosync_exec_handler *exec_engine;
int exec_engine_count;
int (*config_init_fn) (struct corosync_api_v1 *);
void (*confchg_fn) (
enum totem_configuration_type configuration_type,
const unsigned int *member_list, size_t member_list_entries,
const unsigned int *left_list, size_t left_list_entries,
const unsigned int *joined_list, size_t joined_list_entries,
const struct memb_ring_id *ring_id);
enum cs_sync_mode sync_mode;
sync_init_v1_fn_t sync_init;
int (*sync_process) (void);
void (*sync_activate) (void);
void (*sync_abort) (void);
};
#endif /* COROAPI_H_DEFINED */
diff --git a/services/confdb.c b/services/confdb.c
index 56250d4d..27d53f6a 100644
--- a/services/confdb.c
+++ b/services/confdb.c
@@ -1,1064 +1,1064 @@
/*
* Copyright (c) 2008-2010 Red Hat, Inc.
*
* All rights reserved.
*
* Author: Christine Caulfield (ccaulfie@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 CONTIBUTORS "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 <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <poll.h>
#include <corosync/corotypes.h>
#include <corosync/coroipc_types.h>
#include <corosync/corodefs.h>
#include <corosync/cfg.h>
#include <corosync/list.h>
#include <corosync/mar_gen.h>
#include <corosync/ipc_confdb.h>
#include <corosync/lcr/lcr_comp.h>
#include <corosync/engine/logsys.h>
#include <corosync/engine/coroapi.h>
#include <corosync/totem/coropoll.h>
LOGSYS_DECLARE_SUBSYS ("CONFDB");
static hdb_handle_t *
m2h (mar_uint64_t *m)
{
/* FIXME enable the following when/if we use gnulib:
(it's a compile-time assertion; i.e., zero run-time cost)
verify (sizeof (*m) == sizeof (hdb_handle_t)); */
return (void *) m;
}
static struct corosync_api_v1 *api;
static int notify_pipe[2];
struct confdb_ipc_message_holder {
void *conn;
size_t mlen;
struct list_head list;
char msg[];
};
DECLARE_LIST_INIT(confdb_ipc_message_holder_list_head);
pthread_mutex_t confdb_ipc_message_holder_list_mutex =
PTHREAD_MUTEX_INITIALIZER;
static int confdb_exec_init_fn (
struct corosync_api_v1 *corosync_api);
static int confdb_exec_exit_fn(void);
static int fd_set_nonblocking(int fd);
static int objdb_notify_dispatch(hdb_handle_t handle,
int fd, int revents, void *data);
static int confdb_lib_init_fn (void *conn);
static int confdb_lib_exit_fn (void *conn);
static void message_handler_req_lib_confdb_object_create (void *conn,
const void *message);
static void message_handler_req_lib_confdb_object_destroy (void *conn,
const void *message);
static void message_handler_req_lib_confdb_object_find_destroy (void *conn,
const void *message);
static void message_handler_req_lib_confdb_key_create (void *conn,
const void *message);
static void message_handler_req_lib_confdb_key_create_typed (void *conn,
const void *message);
static void message_handler_req_lib_confdb_key_get (void *conn,
const void *message);
static void message_handler_req_lib_confdb_key_get_typed (void *conn,
const void *message);
static void message_handler_req_lib_confdb_key_replace (void *conn,
const void *message);
static void message_handler_req_lib_confdb_key_delete (void *conn,
const void *message);
static void message_handler_req_lib_confdb_key_iter (void *conn,
const void *message);
static void message_handler_req_lib_confdb_key_iter_typed (void *conn,
const void *message);
static void message_handler_req_lib_confdb_key_increment (void *conn,
const void *message);
static void message_handler_req_lib_confdb_key_decrement (void *conn,
const void *message);
static void message_handler_req_lib_confdb_object_iter (void *conn,
const void *message);
static void message_handler_req_lib_confdb_object_find (void *conn,
const void *message);
static void message_handler_req_lib_confdb_object_parent_get (void *conn,
const void *message);
static void message_handler_req_lib_confdb_write (void *conn,
const void *message);
static void message_handler_req_lib_confdb_reload (void *conn,
const void *message);
static void message_handler_req_lib_confdb_track_start (void *conn,
const void *message);
static void message_handler_req_lib_confdb_track_stop (void *conn,
const void *message);
static void confdb_notify_lib_of_key_change(
object_change_type_t change_type,
hdb_handle_t parent_object_handle,
hdb_handle_t object_handle,
const void *object_name_pt, size_t object_name_len,
const void *key_name_pt, size_t key_name_len,
const void *key_value_pt, size_t key_value_len,
void *priv_data_pt);
static void confdb_notify_lib_of_new_object(
hdb_handle_t parent_object_handle,
hdb_handle_t object_handle,
const uint8_t *name_pt, size_t name_len,
void *priv_data_pt);
static void confdb_notify_lib_of_destroyed_object(
hdb_handle_t parent_object_handle,
const uint8_t *name_pt, size_t name_len,
void *priv_data_pt);
static void confdb_notify_lib_of_reload(
objdb_reload_notify_type_t notify_type,
int flush,
void *priv_data_pt);
/*
* Library Handler Definition
*/
static struct corosync_lib_handler confdb_lib_engine[] =
{
{ /* 0 */
.lib_handler_fn = message_handler_req_lib_confdb_object_create,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
},
{ /* 1 */
.lib_handler_fn = message_handler_req_lib_confdb_object_destroy,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
},
{ /* 2 */
.lib_handler_fn = message_handler_req_lib_confdb_object_find,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
},
{ /* 3 */
.lib_handler_fn = message_handler_req_lib_confdb_key_create,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
},
{ /* 4 */
.lib_handler_fn = message_handler_req_lib_confdb_key_get,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
},
{ /* 5 */
.lib_handler_fn = message_handler_req_lib_confdb_key_replace,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
},
{ /* 6 */
.lib_handler_fn = message_handler_req_lib_confdb_key_delete,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
},
{ /* 7 */
.lib_handler_fn = message_handler_req_lib_confdb_object_iter,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
},
{ /* 8 */
.lib_handler_fn = message_handler_req_lib_confdb_object_parent_get,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
},
{ /* 9 */
.lib_handler_fn = message_handler_req_lib_confdb_key_iter,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
},
{ /* 10 */
.lib_handler_fn = message_handler_req_lib_confdb_track_start,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
},
{ /* 11 */
.lib_handler_fn = message_handler_req_lib_confdb_track_stop,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
},
{ /* 12 */
.lib_handler_fn = message_handler_req_lib_confdb_write,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
},
{ /* 13 */
.lib_handler_fn = message_handler_req_lib_confdb_reload,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
},
{ /* 14 */
.lib_handler_fn = message_handler_req_lib_confdb_object_find_destroy,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
},
{ /* 15 */
.lib_handler_fn = message_handler_req_lib_confdb_key_increment,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
},
{ /* 16 */
.lib_handler_fn = message_handler_req_lib_confdb_key_decrement,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
},
{ /* 17 */
.lib_handler_fn = message_handler_req_lib_confdb_key_create_typed,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
},
{ /* 18 */
.lib_handler_fn = message_handler_req_lib_confdb_key_get_typed,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
},
{ /* 19 */
.lib_handler_fn = message_handler_req_lib_confdb_key_iter_typed,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
},
};
struct corosync_service_engine confdb_service_engine = {
.name = "corosync cluster config database access v1.01",
.id = CONFDB_SERVICE,
.priority = 1,
.private_data_size = 0,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED,
.allow_inquorate = CS_LIB_ALLOW_INQUORATE,
.lib_init_fn = confdb_lib_init_fn,
.lib_exit_fn = confdb_lib_exit_fn,
.lib_engine = confdb_lib_engine,
.lib_engine_count = sizeof (confdb_lib_engine) / sizeof (struct corosync_lib_handler),
.exec_init_fn = confdb_exec_init_fn,
.exec_exit_fn = confdb_exec_exit_fn,
};
/*
* Dynamic loader definition
*/
static struct corosync_service_engine *confdb_get_service_engine_ver0 (void);
static struct corosync_service_engine_iface_ver0 confdb_service_engine_iface = {
.corosync_get_service_engine_ver0 = confdb_get_service_engine_ver0
};
static struct lcr_iface corosync_confdb_ver0[1] = {
{
.name = "corosync_confdb",
.version = 0,
.versions_replace = 0,
.versions_replace_count = 0,
.dependencies = 0,
.dependency_count = 0,
.constructor = NULL,
.destructor = NULL,
.interfaces = NULL
}
};
static struct lcr_comp confdb_comp_ver0 = {
.iface_count = 1,
.ifaces = corosync_confdb_ver0
};
static struct corosync_service_engine *confdb_get_service_engine_ver0 (void)
{
return (&confdb_service_engine);
}
#ifdef COROSYNC_SOLARIS
void corosync_lcr_component_register (void);
void corosync_lcr_component_register (void) {
#else
__attribute__ ((constructor)) static void corosync_lcr_component_register (void) {
#endif
lcr_interfaces_set (&corosync_confdb_ver0[0], &confdb_service_engine_iface);
lcr_component_register (&confdb_comp_ver0);
}
static int confdb_exec_exit_fn(void)
{
- poll_dispatch_delete(api->poll_handle_get(), notify_pipe[0]);
+ api->poll_dispatch_delete(api->poll_handle_get(), notify_pipe[0]);
close(notify_pipe[0]);
close(notify_pipe[1]);
return 0;
}
static int confdb_exec_init_fn (
struct corosync_api_v1 *corosync_api)
{
int i;
#ifdef COROSYNC_SOLARIS
logsys_subsys_init();
#endif
api = corosync_api;
if (pipe(notify_pipe) != 0) {
return -1;
}
for (i = 0; i < 2; i++) {
if (fd_set_nonblocking (notify_pipe[i]) == -1) {
return -1;
}
}
- return poll_dispatch_add(api->poll_handle_get(), notify_pipe[0],
+ return api->poll_dispatch_add(api->poll_handle_get(), notify_pipe[0],
POLLIN, NULL, objdb_notify_dispatch);
}
static int confdb_lib_init_fn (void *conn)
{
log_printf(LOGSYS_LEVEL_DEBUG, "lib_init_fn: conn=%p\n", conn);
return (0);
}
static int confdb_lib_exit_fn (void *conn)
{
log_printf(LOGSYS_LEVEL_DEBUG, "exit_fn for conn=%p\n", conn);
/* cleanup the object trackers for this client. */
api->object_track_stop(confdb_notify_lib_of_key_change,
confdb_notify_lib_of_new_object,
confdb_notify_lib_of_destroyed_object,
confdb_notify_lib_of_reload,
conn);
return (0);
}
static int fd_set_nonblocking(int fd)
{
int flags;
int res;
flags = fcntl (fd, F_GETFL);
if (flags == -1) {
return -1;
}
flags |= O_NONBLOCK;
res = fcntl (fd, F_SETFL, flags);
return res;
}
static void message_handler_req_lib_confdb_object_create (void *conn,
const void *message)
{
const struct req_lib_confdb_object_create *req_lib_confdb_object_create
= message;
struct res_lib_confdb_object_create res_lib_confdb_object_create;
hdb_handle_t object_handle;
int ret = CS_OK;
if (api->object_create(req_lib_confdb_object_create->parent_object_handle,
&object_handle,
req_lib_confdb_object_create->object_name.value,
req_lib_confdb_object_create->object_name.length))
ret = CS_ERR_ACCESS;
res_lib_confdb_object_create.object_handle = object_handle;
res_lib_confdb_object_create.header.size = sizeof(res_lib_confdb_object_create);
res_lib_confdb_object_create.header.id = MESSAGE_RES_CONFDB_OBJECT_CREATE;
res_lib_confdb_object_create.header.error = ret;
api->ipc_response_send(conn, &res_lib_confdb_object_create, sizeof(res_lib_confdb_object_create));
}
static void message_handler_req_lib_confdb_object_destroy (void *conn,
const void *message)
{
const struct req_lib_confdb_object_destroy *req_lib_confdb_object_destroy
= message;
coroipc_response_header_t res;
int ret = CS_OK;
if (api->object_destroy(req_lib_confdb_object_destroy->object_handle))
ret = CS_ERR_ACCESS;
res.size = sizeof(res);
res.id = MESSAGE_RES_CONFDB_OBJECT_DESTROY;
res.error = ret;
api->ipc_response_send(conn, &res, sizeof(res));
}
static void message_handler_req_lib_confdb_object_find_destroy (void *conn,
const void *message)
{
const struct req_lib_confdb_object_find_destroy
*req_lib_confdb_object_find_destroy = message;
coroipc_response_header_t res;
int ret = CS_OK;
if (api->object_find_destroy(req_lib_confdb_object_find_destroy->find_handle))
ret = CS_ERR_ACCESS;
res.size = sizeof(res);
res.id = MESSAGE_RES_CONFDB_OBJECT_FIND_DESTROY;
res.error = ret;
api->ipc_response_send(conn, &res, sizeof(res));
}
static void message_handler_req_lib_confdb_key_create (void *conn,
const void *message)
{
const struct req_lib_confdb_key_create *req_lib_confdb_key_create
= message;
coroipc_response_header_t res;
int ret = CS_OK;
if (api->object_key_create(req_lib_confdb_key_create->object_handle,
req_lib_confdb_key_create->key_name.value,
req_lib_confdb_key_create->key_name.length,
req_lib_confdb_key_create->value.value,
req_lib_confdb_key_create->value.length))
ret = CS_ERR_ACCESS;
res.size = sizeof(res);
res.id = MESSAGE_RES_CONFDB_KEY_CREATE;
res.error = ret;
api->ipc_response_send(conn, &res, sizeof(res));
}
static void message_handler_req_lib_confdb_key_create_typed (void *conn,
const void *message)
{
const struct req_lib_confdb_key_create_typed *req_lib_confdb_key_create
= message;
coroipc_response_header_t res;
int ret = CS_OK;
if (api->object_key_create_typed(req_lib_confdb_key_create->object_handle,
(char*)req_lib_confdb_key_create->key_name.value,
req_lib_confdb_key_create->value.value,
req_lib_confdb_key_create->value.length,
req_lib_confdb_key_create->type))
ret = CS_ERR_ACCESS;
res.size = sizeof(res);
res.id = MESSAGE_RES_CONFDB_KEY_CREATE;
res.error = ret;
api->ipc_response_send(conn, &res, sizeof(res));
}
static void message_handler_req_lib_confdb_key_get (void *conn,
const void *message)
{
const struct req_lib_confdb_key_get *req_lib_confdb_key_get = message;
struct res_lib_confdb_key_get res_lib_confdb_key_get;
size_t value_len;
void *value;
int ret = CS_OK;
if (api->object_key_get(req_lib_confdb_key_get->parent_object_handle,
req_lib_confdb_key_get->key_name.value,
req_lib_confdb_key_get->key_name.length,
&value,
&value_len))
ret = CS_ERR_ACCESS;
else {
memcpy(res_lib_confdb_key_get.value.value, value, value_len);
res_lib_confdb_key_get.value.length = value_len;
}
res_lib_confdb_key_get.header.size = sizeof(res_lib_confdb_key_get);
res_lib_confdb_key_get.header.id = MESSAGE_RES_CONFDB_KEY_GET;
res_lib_confdb_key_get.header.error = ret;
api->ipc_response_send(conn, &res_lib_confdb_key_get, sizeof(res_lib_confdb_key_get));
}
static void message_handler_req_lib_confdb_key_get_typed (void *conn,
const void *message)
{
const struct req_lib_confdb_key_get *req_lib_confdb_key_get = message;
struct res_lib_confdb_key_get_typed res_lib_confdb_key_get;
size_t value_len;
void *value;
int ret = CS_OK;
objdb_value_types_t type;
char * key_name = (char*)req_lib_confdb_key_get->key_name.value;
key_name[req_lib_confdb_key_get->key_name.length] = '\0';
if (api->object_key_get_typed(req_lib_confdb_key_get->parent_object_handle,
key_name,
&value,
&value_len, &type))
ret = CS_ERR_ACCESS;
else {
memcpy(res_lib_confdb_key_get.value.value, value, value_len);
res_lib_confdb_key_get.value.length = value_len;
res_lib_confdb_key_get.type = type;
}
res_lib_confdb_key_get.header.size = sizeof(res_lib_confdb_key_get);
res_lib_confdb_key_get.header.id = MESSAGE_RES_CONFDB_KEY_GET_TYPED;
res_lib_confdb_key_get.header.error = ret;
api->ipc_response_send(conn, &res_lib_confdb_key_get, sizeof(res_lib_confdb_key_get));
}
static void message_handler_req_lib_confdb_key_increment (void *conn,
const void *message)
{
const struct req_lib_confdb_key_get *req_lib_confdb_key_get = message;
struct res_lib_confdb_key_incdec res_lib_confdb_key_incdec;
int ret = CS_OK;
if (api->object_key_increment(req_lib_confdb_key_get->parent_object_handle,
req_lib_confdb_key_get->key_name.value,
req_lib_confdb_key_get->key_name.length,
&res_lib_confdb_key_incdec.value))
ret = CS_ERR_ACCESS;
res_lib_confdb_key_incdec.header.size = sizeof(res_lib_confdb_key_incdec);
res_lib_confdb_key_incdec.header.id = MESSAGE_RES_CONFDB_KEY_INCREMENT;
res_lib_confdb_key_incdec.header.error = ret;
api->ipc_response_send(conn, &res_lib_confdb_key_incdec, sizeof(res_lib_confdb_key_incdec));
}
static void message_handler_req_lib_confdb_key_decrement (void *conn,
const void *message)
{
const struct req_lib_confdb_key_get *req_lib_confdb_key_get = message;
struct res_lib_confdb_key_incdec res_lib_confdb_key_incdec;
int ret = CS_OK;
if (api->object_key_decrement(req_lib_confdb_key_get->parent_object_handle,
req_lib_confdb_key_get->key_name.value,
req_lib_confdb_key_get->key_name.length,
&res_lib_confdb_key_incdec.value))
ret = CS_ERR_ACCESS;
res_lib_confdb_key_incdec.header.size = sizeof(res_lib_confdb_key_incdec);
res_lib_confdb_key_incdec.header.id = MESSAGE_RES_CONFDB_KEY_DECREMENT;
res_lib_confdb_key_incdec.header.error = ret;
api->ipc_response_send(conn, &res_lib_confdb_key_incdec, sizeof(res_lib_confdb_key_incdec));
}
static void message_handler_req_lib_confdb_key_replace (void *conn,
const void *message)
{
const struct req_lib_confdb_key_replace *req_lib_confdb_key_replace
= message;
coroipc_response_header_t res;
int ret = CS_OK;
if (api->object_key_replace(req_lib_confdb_key_replace->object_handle,
req_lib_confdb_key_replace->key_name.value,
req_lib_confdb_key_replace->key_name.length,
req_lib_confdb_key_replace->new_value.value,
req_lib_confdb_key_replace->new_value.length))
ret = CS_ERR_ACCESS;
res.size = sizeof(res);
res.id = MESSAGE_RES_CONFDB_KEY_REPLACE;
res.error = ret;
api->ipc_response_send(conn, &res, sizeof(res));
}
static void message_handler_req_lib_confdb_key_delete (void *conn,
const void *message)
{
const struct req_lib_confdb_key_delete *req_lib_confdb_key_delete
= message;
coroipc_response_header_t res;
int ret = CS_OK;
if (api->object_key_delete(req_lib_confdb_key_delete->object_handle,
req_lib_confdb_key_delete->key_name.value,
req_lib_confdb_key_delete->key_name.length))
ret = CS_ERR_ACCESS;
res.size = sizeof(res);
res.id = MESSAGE_RES_CONFDB_KEY_DELETE;
res.error = ret;
api->ipc_response_send(conn, &res, sizeof(res));
}
static void message_handler_req_lib_confdb_object_parent_get (void *conn,
const void *message)
{
const struct req_lib_confdb_object_parent_get
*req_lib_confdb_object_parent_get = message;
struct res_lib_confdb_object_parent_get res_lib_confdb_object_parent_get;
hdb_handle_t object_handle;
int ret = CS_OK;
if (api->object_parent_get(req_lib_confdb_object_parent_get->object_handle,
&object_handle))
ret = CS_ERR_ACCESS;
res_lib_confdb_object_parent_get.parent_object_handle = object_handle;
res_lib_confdb_object_parent_get.header.size = sizeof(res_lib_confdb_object_parent_get);
res_lib_confdb_object_parent_get.header.id = MESSAGE_RES_CONFDB_OBJECT_PARENT_GET;
res_lib_confdb_object_parent_get.header.error = ret;
api->ipc_response_send(conn, &res_lib_confdb_object_parent_get, sizeof(res_lib_confdb_object_parent_get));
}
static void message_handler_req_lib_confdb_key_iter (void *conn,
const void *message)
{
const struct req_lib_confdb_key_iter *req_lib_confdb_key_iter = message;
struct res_lib_confdb_key_iter res_lib_confdb_key_iter;
void *key_name;
size_t key_name_len;
void *value;
size_t value_len;
int ret = CS_OK;
if (api->object_key_iter_from(req_lib_confdb_key_iter->parent_object_handle,
req_lib_confdb_key_iter->next_entry,
&key_name,
&key_name_len,
&value,
&value_len))
ret = CS_ERR_ACCESS;
else {
memcpy(res_lib_confdb_key_iter.key_name.value, key_name, key_name_len);
memcpy(res_lib_confdb_key_iter.value.value, value, value_len);
res_lib_confdb_key_iter.key_name.length = key_name_len;
res_lib_confdb_key_iter.value.length = value_len;
}
res_lib_confdb_key_iter.header.size = sizeof(res_lib_confdb_key_iter);
res_lib_confdb_key_iter.header.id = MESSAGE_RES_CONFDB_KEY_ITER;
res_lib_confdb_key_iter.header.error = ret;
api->ipc_response_send(conn, &res_lib_confdb_key_iter, sizeof(res_lib_confdb_key_iter));
}
static void message_handler_req_lib_confdb_key_iter_typed (void *conn,
const void *message)
{
const struct req_lib_confdb_key_iter *req_lib_confdb_key_iter = message;
struct res_lib_confdb_key_iter_typed res_lib_confdb_key_iter;
void *key_name;
size_t key_name_len;
void *value;
size_t value_len;
int ret = CS_OK;
objdb_value_types_t my_type;
if (api->object_key_iter_from(req_lib_confdb_key_iter->parent_object_handle,
req_lib_confdb_key_iter->next_entry,
&key_name,
&key_name_len,
&value,
&value_len))
ret = CS_ERR_ACCESS;
else {
memcpy(res_lib_confdb_key_iter.key_name.value, key_name, key_name_len);
memcpy(res_lib_confdb_key_iter.value.value, value, value_len);
res_lib_confdb_key_iter.key_name.length = key_name_len;
res_lib_confdb_key_iter.key_name.value[key_name_len] = '\0';
res_lib_confdb_key_iter.value.length = value_len;
api->object_key_get_typed(req_lib_confdb_key_iter->parent_object_handle,
(const char*)res_lib_confdb_key_iter.key_name.value,
&value,
&value_len,
&my_type);
res_lib_confdb_key_iter.type = my_type;
}
res_lib_confdb_key_iter.header.size = sizeof(res_lib_confdb_key_iter);
res_lib_confdb_key_iter.header.id = MESSAGE_RES_CONFDB_KEY_ITER_TYPED;
res_lib_confdb_key_iter.header.error = ret;
api->ipc_response_send(conn, &res_lib_confdb_key_iter, sizeof(res_lib_confdb_key_iter));
}
static void message_handler_req_lib_confdb_object_iter (void *conn,
const void *message)
{
const struct req_lib_confdb_object_iter *req_lib_confdb_object_iter
= message;
struct res_lib_confdb_object_iter res_lib_confdb_object_iter;
size_t object_name_len;
int ret = CS_OK;
if (!req_lib_confdb_object_iter->find_handle) {
if (api->object_find_create(req_lib_confdb_object_iter->parent_object_handle,
NULL, 0,
m2h(&res_lib_confdb_object_iter.find_handle)) == -1) {
ret = CS_ERR_ACCESS;
goto response_send;
}
}
else
res_lib_confdb_object_iter.find_handle = req_lib_confdb_object_iter->find_handle;
if (api->object_find_next(res_lib_confdb_object_iter.find_handle,
m2h(&res_lib_confdb_object_iter.object_handle))) {
ret = CS_ERR_ACCESS;
api->object_find_destroy(res_lib_confdb_object_iter.find_handle);
}
else {
if (api->object_name_get(res_lib_confdb_object_iter.object_handle,
(char *)res_lib_confdb_object_iter.object_name.value,
&object_name_len) == -1) {
ret = CS_ERR_ACCESS;
goto response_send;
} else {
res_lib_confdb_object_iter.object_name.length = object_name_len;
}
}
response_send:
res_lib_confdb_object_iter.header.size = sizeof(res_lib_confdb_object_iter);
res_lib_confdb_object_iter.header.id = MESSAGE_RES_CONFDB_OBJECT_ITER;
res_lib_confdb_object_iter.header.error = ret;
api->ipc_response_send(conn, &res_lib_confdb_object_iter, sizeof(res_lib_confdb_object_iter));
}
static void message_handler_req_lib_confdb_object_find (void *conn,
const void *message)
{
const struct req_lib_confdb_object_find *req_lib_confdb_object_find
= message;
struct res_lib_confdb_object_find res_lib_confdb_object_find;
int ret = CS_OK;
if (!req_lib_confdb_object_find->find_handle) {
if (api->object_find_create(req_lib_confdb_object_find->parent_object_handle,
req_lib_confdb_object_find->object_name.value,
req_lib_confdb_object_find->object_name.length,
m2h(&res_lib_confdb_object_find.find_handle)) == -1) {
ret = CS_ERR_ACCESS;
goto response_send;
}
}
else
res_lib_confdb_object_find.find_handle = req_lib_confdb_object_find->find_handle;
if (api->object_find_next(res_lib_confdb_object_find.find_handle,
m2h(&res_lib_confdb_object_find.object_handle))) {
ret = CS_ERR_ACCESS;
api->object_find_destroy(res_lib_confdb_object_find.find_handle);
}
response_send:
res_lib_confdb_object_find.header.size = sizeof(res_lib_confdb_object_find);
res_lib_confdb_object_find.header.id = MESSAGE_RES_CONFDB_OBJECT_FIND;
res_lib_confdb_object_find.header.error = ret;
api->ipc_response_send(conn, &res_lib_confdb_object_find, sizeof(res_lib_confdb_object_find));
}
static void message_handler_req_lib_confdb_write (void *conn,
const void *message)
{
struct res_lib_confdb_write res_lib_confdb_write;
int ret = CS_OK;
const char *error_string = NULL;
if (api->object_write_config(&error_string))
ret = CS_ERR_ACCESS;
res_lib_confdb_write.header.size = sizeof(res_lib_confdb_write);
res_lib_confdb_write.header.id = MESSAGE_RES_CONFDB_WRITE;
res_lib_confdb_write.header.error = ret;
if (error_string) {
strcpy((char *)res_lib_confdb_write.error.value, error_string);
res_lib_confdb_write.error.length = strlen(error_string) + 1;
} else
res_lib_confdb_write.error.length = 0;
api->ipc_response_send(conn, &res_lib_confdb_write, sizeof(res_lib_confdb_write));
}
static void message_handler_req_lib_confdb_reload (void *conn,
const void *message)
{
const struct req_lib_confdb_reload *req_lib_confdb_reload = message;
struct res_lib_confdb_reload res_lib_confdb_reload;
int ret = CS_OK;
const char *error_string = NULL;
if (api->object_reload_config(req_lib_confdb_reload->flush, &error_string))
ret = CS_ERR_ACCESS;
res_lib_confdb_reload.header.size = sizeof(res_lib_confdb_reload);
res_lib_confdb_reload.header.id = MESSAGE_RES_CONFDB_RELOAD;
res_lib_confdb_reload.header.error = ret;
if(error_string) {
strcpy((char *)res_lib_confdb_reload.error.value, error_string);
res_lib_confdb_reload.error.length = strlen(error_string) + 1;
} else
res_lib_confdb_reload.error.length = 0;
api->ipc_response_send(conn, &res_lib_confdb_reload, sizeof(res_lib_confdb_reload));
}
static int objdb_notify_dispatch(hdb_handle_t handle,
int fd, int revents, void *data)
{
struct confdb_ipc_message_holder *holder;
ssize_t rc;
char pipe_cmd;
if (revents & POLLHUP) {
return -1;
}
pthread_mutex_lock (&confdb_ipc_message_holder_list_mutex);
retry_read:
rc = read(fd, &pipe_cmd, sizeof(pipe_cmd));
if (rc == sizeof(pipe_cmd)) {
goto retry_read; /* Flush whole buffer */
}
if (rc == -1) {
if (errno == EINTR) {
goto retry_read;
}
if (errno != EAGAIN && errno != EWOULDBLOCK) {
goto unlock_exit;
}
} else {
goto unlock_exit; /* rc != -1 && rc != 1 -> end of file */
}
while (!list_empty (&confdb_ipc_message_holder_list_head)) {
holder = list_entry (confdb_ipc_message_holder_list_head.next,
struct confdb_ipc_message_holder, list);
list_del (&holder->list);
/*
* All list operations are done now, so unlock list mutex to
* prevent deadlock in IPC.
*/
pthread_mutex_unlock (&confdb_ipc_message_holder_list_mutex);
api->ipc_dispatch_send(holder->conn, holder->msg, holder->mlen);
api->ipc_refcnt_dec(holder->conn);
free(holder);
/*
* Next operation is again list one, so lock list again.
*/
pthread_mutex_lock (&confdb_ipc_message_holder_list_mutex);
}
unlock_exit:
pthread_mutex_unlock (&confdb_ipc_message_holder_list_mutex);
return 0;
}
static int32_t ipc_dispatch_send_from_poll_thread(void *conn, const void *msg, size_t mlen)
{
struct confdb_ipc_message_holder *holder;
ssize_t written;
size_t holder_size;
char pipe_cmd;
api->ipc_refcnt_inc(conn);
holder_size = sizeof (*holder) + mlen;
holder = malloc (holder_size);
if (holder == NULL) {
api->ipc_refcnt_dec(conn);
return -1;
}
memset(holder, 0, holder_size);
holder->conn = conn;
holder->mlen = mlen;
memcpy(holder->msg, msg, mlen);
list_init(&holder->list);
pthread_mutex_lock (&confdb_ipc_message_holder_list_mutex);
list_add_tail (&holder->list, &confdb_ipc_message_holder_list_head);
pipe_cmd = 'M'; /* Message */
retry_write:
written = write(notify_pipe[1], &pipe_cmd, sizeof(pipe_cmd));
if (written == -1) {
if (errno == EINTR) {
goto retry_write;
}
if (errno != EAGAIN && errno != EWOULDBLOCK) {
/*
* Different error then EINTR or BLOCK -> exit with error
*/
goto refcnt_del_unlock_exit;
}
} else if (written != sizeof (pipe_cmd)) {
goto refcnt_del_unlock_exit;
}
pthread_mutex_unlock (&confdb_ipc_message_holder_list_mutex);
return 0;
refcnt_del_unlock_exit:
list_del (&holder->list);
free(holder);
api->ipc_refcnt_dec(conn);
pthread_mutex_unlock (&confdb_ipc_message_holder_list_mutex);
return -1;
}
static void confdb_notify_lib_of_key_change(object_change_type_t change_type,
hdb_handle_t parent_object_handle,
hdb_handle_t object_handle,
const void *object_name_pt, size_t object_name_len,
const void *key_name_pt, size_t key_name_len,
const void *key_value_pt, size_t key_value_len,
void *priv_data_pt)
{
struct res_lib_confdb_key_change_callback res;
res.header.size = sizeof(res);
res.header.id = MESSAGE_RES_CONFDB_KEY_CHANGE_CALLBACK;
res.header.error = CS_OK;
// handle & type
res.change_type = change_type;
res.parent_object_handle = parent_object_handle;
res.object_handle = object_handle;
//object
memcpy(res.object_name.value, object_name_pt, object_name_len);
res.object_name.length = object_name_len;
//key name
memcpy(res.key_name.value, key_name_pt, key_name_len);
res.key_name.length = key_name_len;
//key value
memcpy(res.key_value.value, key_value_pt, key_value_len);
res.key_value.length = key_value_len;
ipc_dispatch_send_from_poll_thread(priv_data_pt, &res, sizeof(res));
}
static void confdb_notify_lib_of_new_object(hdb_handle_t parent_object_handle,
hdb_handle_t object_handle,
const uint8_t *name_pt, size_t name_len,
void *priv_data_pt)
{
struct res_lib_confdb_object_create_callback res;
res.header.size = sizeof(res);
res.header.id = MESSAGE_RES_CONFDB_OBJECT_CREATE_CALLBACK;
res.header.error = CS_OK;
res.parent_object_handle = parent_object_handle;
res.object_handle = object_handle;
memcpy(res.name.value, name_pt, name_len);
res.name.length = name_len;
ipc_dispatch_send_from_poll_thread(priv_data_pt, &res, sizeof(res));
}
static void confdb_notify_lib_of_destroyed_object(
hdb_handle_t parent_object_handle,
const uint8_t *name_pt, size_t name_len,
void *priv_data_pt)
{
struct res_lib_confdb_object_destroy_callback res;
res.header.size = sizeof(res);
res.header.id = MESSAGE_RES_CONFDB_OBJECT_DESTROY_CALLBACK;
res.header.error = CS_OK;
res.parent_object_handle = parent_object_handle;
memcpy(res.name.value, name_pt, name_len);
res.name.length = name_len;
ipc_dispatch_send_from_poll_thread(priv_data_pt, &res, sizeof(res));
}
static void confdb_notify_lib_of_reload(objdb_reload_notify_type_t notify_type,
int flush,
void *priv_data_pt)
{
struct res_lib_confdb_reload_callback res;
res.header.size = sizeof(res);
res.header.id = MESSAGE_RES_CONFDB_RELOAD_CALLBACK;
res.header.error = CS_OK;
res.type = notify_type;
ipc_dispatch_send_from_poll_thread(priv_data_pt, &res, sizeof(res));
}
static void message_handler_req_lib_confdb_track_start (void *conn,
const void *message)
{
const struct req_lib_confdb_object_track_start *req = message;
coroipc_response_header_t res;
api->object_track_start(req->object_handle,
req->flags,
confdb_notify_lib_of_key_change,
confdb_notify_lib_of_new_object,
confdb_notify_lib_of_destroyed_object,
confdb_notify_lib_of_reload,
conn);
res.size = sizeof(res);
res.id = MESSAGE_RES_CONFDB_TRACK_START;
res.error = CS_OK;
api->ipc_response_send(conn, &res, sizeof(res));
}
static void message_handler_req_lib_confdb_track_stop (void *conn,
const void *message)
{
coroipc_response_header_t res;
api->object_track_stop(confdb_notify_lib_of_key_change,
confdb_notify_lib_of_new_object,
confdb_notify_lib_of_destroyed_object,
confdb_notify_lib_of_reload,
conn);
res.size = sizeof(res);
res.id = MESSAGE_RES_CONFDB_TRACK_STOP;
res.error = CS_OK;
api->ipc_response_send(conn, &res, sizeof(res));
}

File Metadata

Mime Type
text/x-diff
Expires
Sat, Nov 23, 8:18 AM (1 d, 4 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1018490
Default Alt Text
(61 KB)

Event Timeline