Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F5726905
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
159 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/include/corosync/confdb.h b/include/corosync/confdb.h
index ca0d7ba3..6879383d 100644
--- a/include/corosync/confdb.h
+++ b/include/corosync/confdb.h
@@ -1,348 +1,364 @@
/*
- * Copyright (c) 2008-2010 Red Hat, Inc.
+ * Copyright (c) 2008-2012 Red Hat, Inc.
*
* All rights reserved.
*
* Author: Christine Caulfield (ccaulfi@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 COROSYNC_CONFDB_H_DEFINED
#define COROSYNC_CONFDB_H_DEFINED
#include <corosync/corotypes.h>
#include <corosync/hdb.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup confdb_corosync
*
* @{
*/
typedef uint64_t confdb_handle_t;
#define OBJECT_PARENT_HANDLE 0xFFFFFFFF00000000ULL
typedef enum {
CONFDB_VALUETYPE_INT16,
CONFDB_VALUETYPE_UINT16,
CONFDB_VALUETYPE_INT32,
CONFDB_VALUETYPE_UINT32,
CONFDB_VALUETYPE_INT64,
CONFDB_VALUETYPE_UINT64,
CONFDB_VALUETYPE_FLOAT,
CONFDB_VALUETYPE_DOUBLE,
CONFDB_VALUETYPE_STRING,
CONFDB_VALUETYPE_ANY,
} confdb_value_types_t;
typedef enum {
CONFDB_TRACK_DEPTH_ONE,
CONFDB_TRACK_DEPTH_RECURSIVE
} confdb_track_depth_t;
typedef enum {
OBJECT_KEY_CREATED,
OBJECT_KEY_REPLACED,
OBJECT_KEY_DELETED,
} confdb_change_type_t;
typedef enum {
CONFDB_RELOAD_NOTIFY_START,
CONFDB_RELOAD_NOTIFY_END,
CONFDB_RELOAD_NOTIFY_FAILED
} confdb_reload_type_t;
typedef void (*confdb_key_change_notify_fn_t) (
confdb_handle_t handle,
confdb_change_type_t change_type,
hdb_handle_t parent_object_handle,
hdb_handle_t object_handle,
const void *object_name,
size_t object_name_len,
const void *key_name,
size_t key_name_len,
const void *key_value,
size_t key_value_len);
typedef void (*confdb_object_create_notify_fn_t) (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
hdb_handle_t object_handle,
const void *name_pt,
size_t name_len);
typedef void (*confdb_object_delete_notify_fn_t) (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const void *name_pt,
size_t name_len);
typedef void (*confdb_reload_notify_fn_t) (
confdb_handle_t handle,
confdb_reload_type_t type);
typedef struct {
confdb_object_create_notify_fn_t confdb_object_create_change_notify_fn;
confdb_object_delete_notify_fn_t confdb_object_delete_change_notify_fn;
confdb_key_change_notify_fn_t confdb_key_change_notify_fn;
confdb_reload_notify_fn_t confdb_reload_notify_fn;
} confdb_callbacks_t;
/** @} */
/*
* Create a new confdb connection
*/
cs_error_t confdb_initialize (
confdb_handle_t *handle,
confdb_callbacks_t *callbacks);
/*
* Close the confdb handle
*/
cs_error_t confdb_finalize (
confdb_handle_t handle);
/*
* Write back the configuration
*/
cs_error_t confdb_write (
confdb_handle_t handle,
char *error_text,
size_t errbuf_len);
/*
* Reload the configuration
*/
cs_error_t confdb_reload (
confdb_handle_t handle,
int flush,
char *error_text,
size_t errbuf_len);
/*
* Get a file descriptor on which to poll. confdb_handle_t is NOT a
* file descriptor and may not be used directly.
*/
cs_error_t confdb_fd_get (
confdb_handle_t handle,
int *fd);
/*
* Dispatch configuration changes
*/
cs_error_t confdb_dispatch (
confdb_handle_t handle,
cs_dispatch_flags_t dispatch_types);
/*
* Change notification
*/
cs_error_t confdb_track_changes (
confdb_handle_t handle,
hdb_handle_t object_handle,
unsigned int flags);
cs_error_t confdb_stop_track_changes (
confdb_handle_t handle);
/*
* Manipulate objects
*/
cs_error_t confdb_object_create (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const void *object_name,
size_t object_name_len,
hdb_handle_t *object_handle);
cs_error_t confdb_object_destroy (
confdb_handle_t handle,
hdb_handle_t object_handle);
cs_error_t confdb_object_parent_get (
confdb_handle_t handle,
hdb_handle_t object_handle,
hdb_handle_t *parent_object_handle);
cs_error_t confdb_object_name_get (
confdb_handle_t handle,
hdb_handle_t object_handle,
char *object_name,
size_t *object_name_len);
/*
* Manipulate keys
*/
cs_error_t confdb_key_create (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
const void *value,
size_t value_len);
cs_error_t confdb_key_create_typed (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const char *key_name,
const void *value,
size_t value_len,
confdb_value_types_t type);
cs_error_t confdb_key_delete (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
const void *value,
size_t value_len);
/*
* Key queries
*/
cs_error_t confdb_key_get (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
void *value,
size_t *value_len);
cs_error_t confdb_key_get_typed (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const char *key_name,
void *value,
size_t *value_len,
confdb_value_types_t *type);
+cs_error_t confdb_key_get_typed2 (
+ confdb_handle_t handle,
+ hdb_handle_t parent_object_handle,
+ const char *key_name,
+ void **value,
+ size_t *value_len,
+ confdb_value_types_t *type);
+
cs_error_t confdb_key_replace (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
const void *old_value,
size_t old_value_len,
const void *new_value,
size_t new_value_len);
cs_error_t confdb_key_increment (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
unsigned int *value);
cs_error_t confdb_key_decrement (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
unsigned int *value);
/*
* Object queries
* "find" loops through all objects of a given name and is also
* a quick way of finding a specific object,
* "iter" returns each object in sequence.
*/
cs_error_t confdb_object_find_start (
confdb_handle_t handle,
hdb_handle_t parent_object_handle);
cs_error_t confdb_object_find (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const void *object_name,
size_t object_name_len,
hdb_handle_t *object_handle);
cs_error_t confdb_object_find_destroy(
confdb_handle_t handle,
hdb_handle_t parent_object_handle);
cs_error_t confdb_object_iter_start (
confdb_handle_t handle,
hdb_handle_t parent_object_handle);
cs_error_t confdb_object_iter (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
hdb_handle_t *object_handle,
void *object_name,
size_t *object_name_len);
cs_error_t confdb_object_iter_destroy(
confdb_handle_t handle,
hdb_handle_t parent_object_handle);
/*
* Key iterator
*/
cs_error_t confdb_key_iter_start (
confdb_handle_t handle,
hdb_handle_t object_handle);
cs_error_t confdb_key_iter (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
void *key_name,
size_t *key_name_len,
void *value,
size_t *value_len);
cs_error_t confdb_key_iter_typed (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
char *key_name,
void *value,
size_t *value_len,
confdb_value_types_t *type);
+cs_error_t confdb_key_iter_typed2 (
+ confdb_handle_t handle,
+ hdb_handle_t parent_object_handle,
+ char *key_name,
+ void **value,
+ size_t *value_len,
+ confdb_value_types_t *type);
+
/*
* Get/set context variable
*/
cs_error_t confdb_context_get (
confdb_handle_t handle,
const void **context);
cs_error_t confdb_context_set (
confdb_handle_t handle,
const void *context);
#ifdef __cplusplus
}
#endif
#endif /* COROSYNC_CONFDB_H_DEFINED */
diff --git a/include/corosync/ipc_confdb.h b/include/corosync/ipc_confdb.h
index 856c8a67..709c6770 100644
--- a/include/corosync/ipc_confdb.h
+++ b/include/corosync/ipc_confdb.h
@@ -1,278 +1,330 @@
/*
- * Copyright (c) 2008-2010 Red Hat, Inc.
+ * Copyright (c) 2008-2012 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 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 IPC_CONFDB_H_DEFINED
#define IPC_CONFDB_H_DEFINED
#include <netinet/in.h>
#include <corosync/corotypes.h>
#include <corosync/mar_gen.h>
enum req_confdb_types {
MESSAGE_REQ_CONFDB_OBJECT_CREATE = 0,
MESSAGE_REQ_CONFDB_OBJECT_DESTROY = 1,
MESSAGE_REQ_CONFDB_OBJECT_FIND = 2,
MESSAGE_REQ_CONFDB_KEY_CREATE = 3,
MESSAGE_REQ_CONFDB_KEY_GET = 4,
MESSAGE_REQ_CONFDB_KEY_REPLACE = 5,
MESSAGE_REQ_CONFDB_KEY_DELETE = 6,
MESSAGE_REQ_CONFDB_OBJECT_ITER = 7,
MESSAGE_REQ_CONFDB_OBJECT_PARENT_GET = 8,
MESSAGE_REQ_CONFDB_KEY_ITER = 9,
MESSAGE_REQ_CONFDB_TRACK_START = 10,
MESSAGE_REQ_CONFDB_TRACK_STOP = 11,
MESSAGE_REQ_CONFDB_WRITE = 12,
MESSAGE_REQ_CONFDB_RELOAD = 13,
MESSAGE_REQ_CONFDB_OBJECT_FIND_DESTROY = 14,
MESSAGE_REQ_CONFDB_KEY_INCREMENT = 15,
MESSAGE_REQ_CONFDB_KEY_DECREMENT = 16,
MESSAGE_REQ_CONFDB_KEY_CREATE_TYPED = 17,
MESSAGE_REQ_CONFDB_KEY_GET_TYPED = 18,
MESSAGE_REQ_CONFDB_KEY_ITER_TYPED = 19,
MESSAGE_REQ_CONFDB_OBJECT_NAME_GET = 20,
+ MESSAGE_REQ_CONFDB_KEY_ITER_TYPED2 = 21,
+ MESSAGE_REQ_CONFDB_KEY_REPLACE2 = 22,
+ MESSAGE_REQ_CONFDB_KEY_GET_TYPED2 = 23,
+ MESSAGE_REQ_CONFDB_KEY_CREATE_TYPED2 = 24,
};
enum res_confdb_types {
MESSAGE_RES_CONFDB_OBJECT_CREATE = 0,
MESSAGE_RES_CONFDB_OBJECT_DESTROY = 1,
MESSAGE_RES_CONFDB_OBJECT_FIND = 2,
MESSAGE_RES_CONFDB_KEY_CREATE = 3,
MESSAGE_RES_CONFDB_KEY_GET = 4,
MESSAGE_RES_CONFDB_KEY_REPLACE = 5,
MESSAGE_RES_CONFDB_KEY_DELETE = 6,
MESSAGE_RES_CONFDB_OBJECT_ITER = 7,
MESSAGE_RES_CONFDB_OBJECT_PARENT_GET = 8,
MESSAGE_RES_CONFDB_KEY_ITER = 9,
MESSAGE_RES_CONFDB_TRACK_START = 10,
MESSAGE_RES_CONFDB_TRACK_STOP = 11,
MESSAGE_RES_CONFDB_KEY_CHANGE_CALLBACK = 12,
MESSAGE_RES_CONFDB_OBJECT_CREATE_CALLBACK = 13,
MESSAGE_RES_CONFDB_OBJECT_DESTROY_CALLBACK = 14,
MESSAGE_RES_CONFDB_WRITE = 15,
MESSAGE_RES_CONFDB_RELOAD = 16,
MESSAGE_RES_CONFDB_OBJECT_FIND_DESTROY = 17,
MESSAGE_RES_CONFDB_KEY_INCREMENT = 18,
MESSAGE_RES_CONFDB_KEY_DECREMENT = 19,
MESSAGE_RES_CONFDB_KEY_GET_TYPED = 20,
MESSAGE_RES_CONFDB_KEY_ITER_TYPED = 21,
MESSAGE_RES_CONFDB_RELOAD_CALLBACK = 22,
MESSAGE_RES_CONFDB_OBJECT_NAME_GET = 23,
+ MESSAGE_RES_CONFDB_KEY_ITER_TYPED2 = 24,
+ MESSAGE_RES_CONFDB_KEY_GET_TYPED2 = 25,
+ MESSAGE_RES_CONFDB_KEY_CHANGE_CALLBACK2 = 26,
};
struct req_lib_confdb_object_create {
coroipc_request_header_t header __attribute__((aligned(8)));
mar_uint64_t parent_object_handle __attribute__((aligned(8)));
mar_name_t object_name __attribute__((aligned(8)));
};
struct res_lib_confdb_object_create {
coroipc_response_header_t header __attribute__((aligned(8)));
mar_uint64_t object_handle __attribute__((aligned(8)));
};
struct req_lib_confdb_object_destroy {
coroipc_request_header_t header __attribute__((aligned(8)));
mar_uint64_t object_handle __attribute__((aligned(8)));
};
struct req_lib_confdb_object_parent_get {
coroipc_request_header_t header __attribute__((aligned(8)));
mar_uint64_t object_handle __attribute__((aligned(8)));
};
struct res_lib_confdb_object_parent_get {
coroipc_response_header_t header __attribute__((aligned(8)));
mar_uint64_t parent_object_handle __attribute__((aligned(8)));
};
struct req_lib_confdb_object_name_get {
coroipc_request_header_t header __attribute__((aligned(8)));
mar_uint64_t object_handle __attribute__((aligned(8)));
};
struct res_lib_confdb_object_name_get {
coroipc_response_header_t header __attribute__((aligned(8)));
mar_name_t object_name __attribute__((aligned(8)));
};
struct req_lib_confdb_key_create {
coroipc_request_header_t header __attribute__((aligned(8)));
mar_uint64_t object_handle __attribute__((aligned(8)));
mar_name_t key_name __attribute__((aligned(8)));
mar_name_t value __attribute__((aligned(8)));
};
struct req_lib_confdb_key_create_typed {
coroipc_request_header_t header __attribute__((aligned(8)));
mar_uint64_t object_handle __attribute__((aligned(8)));
mar_name_t key_name __attribute__((aligned(8)));
mar_name_t value __attribute__((aligned(8)));
mar_int32_t type __attribute__((aligned(8)));
};
+struct req_lib_confdb_key_create_typed2 {
+ coroipc_request_header_t header __attribute__((aligned(8)));
+ mar_uint64_t object_handle __attribute__((aligned(8)));
+ mar_name_t key_name __attribute__((aligned(8)));
+ mar_int32_t type __attribute__((aligned(8)));
+ mar_int32_t value_length __attribute__((aligned(8)));
+ mar_uint8_t value __attribute__((aligned(8))); /* First byte of value */
+};
+
struct req_lib_confdb_key_delete {
coroipc_request_header_t header __attribute__((aligned(8)));
mar_uint64_t object_handle __attribute__((aligned(8)));
mar_name_t key_name __attribute__((aligned(8)));
mar_name_t value __attribute__((aligned(8)));
};
struct req_lib_confdb_key_replace {
coroipc_request_header_t header __attribute__((aligned(8)));
mar_uint64_t object_handle __attribute__((aligned(8)));
mar_name_t key_name __attribute__((aligned(8)));
mar_name_t old_value __attribute__((aligned(8)));
mar_name_t new_value __attribute__((aligned(8)));
};
struct req_lib_confdb_object_find {
coroipc_request_header_t header __attribute__((aligned(8)));
mar_uint64_t parent_object_handle __attribute__((aligned(8)));
mar_name_t object_name __attribute__((aligned(8)));
mar_uint64_t find_handle __attribute__((aligned(8)));
};
struct res_lib_confdb_object_find {
coroipc_response_header_t header __attribute__((aligned(8)));
mar_uint64_t object_handle __attribute__((aligned(8)));
mar_uint64_t find_handle __attribute__((aligned(8)));
};
struct req_lib_confdb_object_iter {
coroipc_request_header_t header __attribute__((aligned(8)));
mar_uint64_t parent_object_handle __attribute__((aligned(8)));
mar_uint64_t find_handle __attribute__((aligned(8)));
};
struct res_lib_confdb_object_iter {
coroipc_response_header_t header __attribute__((aligned(8)));
mar_name_t object_name __attribute__((aligned(8)));
mar_uint64_t object_handle __attribute__((aligned(8)));
mar_uint64_t find_handle __attribute__((aligned(8)));
};
struct req_lib_confdb_key_iter {
coroipc_request_header_t header __attribute__((aligned(8)));
mar_uint64_t parent_object_handle __attribute__((aligned(8)));
mar_uint64_t next_entry __attribute__((aligned(8)));
};
struct res_lib_confdb_key_iter {
coroipc_response_header_t header __attribute__((aligned(8)));
mar_name_t key_name __attribute__((aligned(8)));
mar_name_t value __attribute__((aligned(8)));
};
struct res_lib_confdb_key_iter_typed {
coroipc_response_header_t header __attribute__((aligned(8)));
mar_name_t key_name __attribute__((aligned(8)));
mar_name_t value __attribute__((aligned(8)));
mar_int32_t type __attribute__((aligned(8)));
};
struct req_lib_confdb_key_get {
coroipc_request_header_t header __attribute__((aligned(8)));
mar_uint64_t parent_object_handle __attribute__((aligned(8)));
mar_name_t key_name __attribute__((aligned(8)));
};
struct req_lib_confdb_object_find_destroy {
coroipc_request_header_t header __attribute__((aligned(8)));
mar_uint64_t find_handle __attribute__((aligned(8)));
};
struct res_lib_confdb_key_get {
coroipc_response_header_t header __attribute__((aligned(8)));
mar_name_t value __attribute__((aligned(8)));
};
struct res_lib_confdb_key_get_typed {
coroipc_response_header_t header __attribute__((aligned(8)));
mar_name_t value __attribute__((aligned(8)));
mar_int32_t type __attribute__((aligned(8)));
};
struct res_lib_confdb_key_incdec {
coroipc_response_header_t header __attribute__((aligned(8)));
mar_uint32_t value __attribute__((aligned(8)));
};
struct res_lib_confdb_write {
coroipc_response_header_t header __attribute__((aligned(8)));
mar_name_t error __attribute__((aligned(8)));
};
struct req_lib_confdb_reload {
coroipc_response_header_t header __attribute__((aligned(8)));
mar_int32_t flush __attribute__((aligned(8)));
};
struct res_lib_confdb_reload {
coroipc_response_header_t header __attribute__((aligned(8)));
mar_name_t error __attribute__((aligned(8)));
};
struct res_lib_confdb_key_change_callback {
coroipc_response_header_t header __attribute__((aligned(8)));
mar_uint64_t change_type __attribute__((aligned(8)));
mar_uint64_t parent_object_handle __attribute__((aligned(8)));
mar_uint64_t object_handle __attribute__((aligned(8)));
mar_name_t object_name __attribute__((aligned(8)));
mar_name_t key_name __attribute__((aligned(8)));
mar_name_t key_value __attribute__((aligned(8)));
};
+struct res_lib_confdb_key_change_callback2 {
+ coroipc_response_header_t header __attribute__((aligned(8)));
+ mar_uint64_t change_type __attribute__((aligned(8)));
+ mar_uint64_t parent_object_handle __attribute__((aligned(8)));
+ mar_uint64_t object_handle __attribute__((aligned(8)));
+ mar_name_t object_name __attribute__((aligned(8)));
+ mar_name_t key_name __attribute__((aligned(8)));
+ mar_uint32_t key_value_length __attribute__((aligned(8)));
+ mar_uint8_t key_value __attribute__((aligned(8))); /* First byte of new value */
+};
+
struct res_lib_confdb_object_create_callback {
coroipc_response_header_t header __attribute__((aligned(8)));
mar_uint64_t parent_object_handle __attribute__((aligned(8)));
mar_uint64_t object_handle __attribute__((aligned(8)));
mar_name_t name __attribute__((aligned(8)));
};
struct res_lib_confdb_object_destroy_callback {
coroipc_response_header_t header __attribute__((aligned(8)));
mar_uint64_t parent_object_handle __attribute__((aligned(8)));
mar_name_t name __attribute__((aligned(8)));
};
struct res_lib_confdb_reload_callback {
coroipc_response_header_t header __attribute__((aligned(8)));
mar_uint32_t type __attribute__((aligned(8)));
};
struct req_lib_confdb_object_track_start {
coroipc_request_header_t header __attribute__((aligned(8)));
mar_uint64_t object_handle __attribute__((aligned(8)));
mar_uint32_t flags __attribute__((aligned(8)));
};
+struct res_lib_confdb_key_get_typed2 {
+ coroipc_response_header_t header __attribute__((aligned(8)));
+ mar_int32_t type __attribute__((aligned(8)));
+ mar_uint32_t value_length __attribute__((aligned(8)));
+ mar_uint8_t value __attribute__((aligned(8)));
+ // Actual value follows this
+};
+
+struct res_lib_confdb_key_iter_typed2 {
+ coroipc_response_header_t header __attribute__((aligned(8)));
+ mar_name_t key_name __attribute__((aligned(8)));
+ mar_int32_t type __attribute__((aligned(8)));
+ mar_int32_t value_length __attribute__((aligned(8)));
+ mar_uint8_t value __attribute__((aligned(8))); /* First byte of value */
+};
+
+struct req_lib_confdb_key_replace2 {
+ coroipc_request_header_t header __attribute__((aligned(8)));
+ mar_uint64_t object_handle __attribute__((aligned(8)));
+ mar_name_t key_name __attribute__((aligned(8)));
+ mar_int32_t new_value_length __attribute__((aligned(8)));
+ mar_uint8_t new_value __attribute__((aligned(8))); /* First byte of new value */
+ /* Oddly objdb doesn't use the old value, so we don't bother sending it */
+};
+
#endif /* IPC_CONFDB_H_DEFINED */
diff --git a/lib/confdb.c b/lib/confdb.c
index 1ea2ed0b..0dbecb96 100644
--- a/lib/confdb.c
+++ b/lib/confdb.c
@@ -1,1814 +1,1994 @@
/*
- * Copyright (c) 2008-2010 Red Hat, Inc.
+ * Copyright (c) 2008-2012 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 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.
*/
/*
* Provides access to data in the corosync object database
*/
#include <config.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <errno.h>
#include <corosync/corotypes.h>
#include <corosync/coroipc_types.h>
#include <corosync/coroipcc.h>
#include <corosync/corodefs.h>
#include <corosync/hdb.h>
#include <corosync/list.h>
#include <corosync/confdb.h>
#include <corosync/ipc_confdb.h>
#include "util.h"
#include "sa-confdb.h"
#undef MIN
#define MIN(x,y) ((x) < (y) ? (x) : (y))
/* Hold the information for iterators so that
callers can do recursive tree traversals.
each object_handle can have its own iterator */
struct iter_context {
struct list_head list;
hdb_handle_t parent_object_handle;
hdb_handle_t find_handle;
hdb_handle_t next_entry;
};
struct confdb_inst {
hdb_handle_t handle;
int finalize;
int standalone;
confdb_callbacks_t callbacks;
const void *context;
struct list_head object_find_head;
struct list_head object_iter_head;
struct list_head key_iter_head;
};
DECLARE_HDB_DATABASE(confdb_handle_t_db,NULL);
static cs_error_t do_find_destroy(struct confdb_inst *confdb_inst, hdb_handle_t find_handle);
/* Safely tidy one iterator context list */
static void free_context_list(struct confdb_inst *confdb_inst, struct list_head *list)
{
struct iter_context *context;
struct list_head *iter, *tmp;
for (iter = list->next, tmp = iter->next;
iter != list; iter = tmp, tmp = iter->next) {
context = list_entry (iter, struct iter_context, list);
(void)do_find_destroy(confdb_inst, context->find_handle);
free(context);
}
}
static struct iter_context *find_iter_context(struct list_head *list, hdb_handle_t object_handle)
{
struct iter_context *context;
struct list_head *iter;
for (iter = list->next;
iter != list; iter = iter->next) {
context = list_entry (iter, struct iter_context, list);
if (context->parent_object_handle == object_handle)
return context;
}
return NULL;
}
/**
* @defgroup confdb_corosync
* @ingroup corosync
*
* @{
*/
cs_error_t confdb_initialize (
confdb_handle_t *handle,
confdb_callbacks_t *callbacks)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
error = hdb_error_to_cs(hdb_handle_create (&confdb_handle_t_db, sizeof (struct confdb_inst), handle));
if (error != CS_OK) {
goto error_no_destroy;
}
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, *handle, (void *)&confdb_inst));
if (error != CS_OK) {
goto error_destroy;
}
if (getenv("COROSYNC_DEFAULT_CONFIG_IFACE")) {
error = confdb_sa_init();
confdb_inst->standalone = 1;
}
else {
error = coroipcc_service_connect (
COROSYNC_SOCKET_NAME,
CONFDB_SERVICE,
IPC_REQUEST_SIZE,
IPC_RESPONSE_SIZE,
IPC_DISPATCH_SIZE,
&confdb_inst->handle);
}
if (error != CS_OK)
goto error_put_destroy;
if (callbacks) {
memcpy (&confdb_inst->callbacks, callbacks, sizeof (confdb_callbacks_t));
}
list_init (&confdb_inst->object_find_head);
list_init (&confdb_inst->object_iter_head);
list_init (&confdb_inst->key_iter_head);
(void)hdb_handle_put (&confdb_handle_t_db, *handle);
return (CS_OK);
error_put_destroy:
(void)hdb_handle_put (&confdb_handle_t_db, *handle);
error_destroy:
(void)hdb_handle_destroy (&confdb_handle_t_db, *handle);
error_no_destroy:
return (error);
}
cs_error_t confdb_finalize (
confdb_handle_t handle)
{
struct confdb_inst *confdb_inst;
cs_error_t error;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
/*
* Another thread has already started finalizing
*/
if (confdb_inst->finalize) {
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (CS_ERR_BAD_HANDLE);
}
confdb_inst->finalize = 1;
/* Free saved context handles */
free_context_list(confdb_inst, &confdb_inst->object_find_head);
free_context_list(confdb_inst, &confdb_inst->object_iter_head);
free_context_list(confdb_inst, &confdb_inst->key_iter_head);
if (!confdb_inst->standalone) {
coroipcc_service_disconnect (confdb_inst->handle);
}
(void)hdb_handle_destroy (&confdb_handle_t_db, handle);
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (CS_OK);
}
cs_error_t confdb_fd_get (
confdb_handle_t handle,
int *fd)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
error = coroipcc_fd_get (confdb_inst->handle, fd);
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (error);
}
cs_error_t confdb_context_get (
confdb_handle_t handle,
const void **context)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
*context = confdb_inst->context;
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (CS_OK);
}
cs_error_t confdb_context_set (
confdb_handle_t handle,
const void *context)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
confdb_inst->context = context;
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (CS_OK);
}
cs_error_t confdb_dispatch (
confdb_handle_t handle,
cs_dispatch_flags_t dispatch_types)
{
int timeout = -1;
cs_error_t error;
int cont = 1; /* always continue do loop except when set to 0 */
struct confdb_inst *confdb_inst;
confdb_callbacks_t callbacks;
struct res_lib_confdb_key_change_callback *res_key_changed_pt;
struct res_lib_confdb_object_create_callback *res_object_created_pt;
struct res_lib_confdb_object_destroy_callback *res_object_destroyed_pt;
struct res_lib_confdb_reload_callback *res_reload_pt;
coroipc_response_header_t *dispatch_data;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
if (confdb_inst->standalone) {
error = CS_ERR_NOT_SUPPORTED;
goto error_put;
}
/*
* Timeout instantly for CS_DISPATCH_ONE or CS_DISPATCH_ALL and
* wait indefinitely for CS_DISPATCH_BLOCKING
*/
if (dispatch_types == CONFDB_DISPATCH_ALL) {
timeout = 0;
}
do {
error = coroipcc_dispatch_get (
confdb_inst->handle,
(void **)&dispatch_data,
timeout);
if (error == CS_ERR_BAD_HANDLE) {
error = CS_OK;
goto error_put;
}
if (error == CS_ERR_TRY_AGAIN) {
error = CS_OK;
if (dispatch_types == CONFDB_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 confdbFinalize has been called.
*/
memcpy (&callbacks, &confdb_inst->callbacks, sizeof (confdb_callbacks_t));
/*
* Dispatch incoming message
*/
switch (dispatch_data->id) {
case MESSAGE_RES_CONFDB_KEY_CHANGE_CALLBACK:
if (callbacks.confdb_key_change_notify_fn == NULL) {
break;
}
res_key_changed_pt = (struct res_lib_confdb_key_change_callback *)dispatch_data;
callbacks.confdb_key_change_notify_fn(handle,
res_key_changed_pt->change_type,
res_key_changed_pt->object_handle,
res_key_changed_pt->parent_object_handle,
res_key_changed_pt->object_name.value,
res_key_changed_pt->object_name.length,
res_key_changed_pt->key_name.value,
res_key_changed_pt->key_name.length,
res_key_changed_pt->key_value.value,
res_key_changed_pt->key_value.length);
break;
+ case MESSAGE_RES_CONFDB_KEY_CHANGE_CALLBACK2:
+ if (callbacks.confdb_key_change_notify_fn == NULL) {
+ break;
+ }
+
+ res_key_changed_pt = (struct res_lib_confdb_key_change_callback *)dispatch_data;
+
+ callbacks.confdb_key_change_notify_fn(handle,
+ res_key_changed_pt->change_type,
+ res_key_changed_pt->object_handle,
+ res_key_changed_pt->parent_object_handle,
+ res_key_changed_pt->object_name.value,
+ res_key_changed_pt->object_name.length,
+ res_key_changed_pt->key_name.value,
+ res_key_changed_pt->key_name.length,
+ &res_key_changed_pt->key_value.value,
+ res_key_changed_pt->key_value.length);
+ break;
+
case MESSAGE_RES_CONFDB_OBJECT_CREATE_CALLBACK:
if (callbacks.confdb_object_create_change_notify_fn == NULL) {
break;
}
res_object_created_pt = (struct res_lib_confdb_object_create_callback *)dispatch_data;
callbacks.confdb_object_create_change_notify_fn(handle,
res_object_created_pt->object_handle,
res_object_created_pt->parent_object_handle,
res_object_created_pt->name.value,
res_object_created_pt->name.length);
break;
case MESSAGE_RES_CONFDB_OBJECT_DESTROY_CALLBACK:
if (callbacks.confdb_object_delete_change_notify_fn == NULL) {
break;
}
res_object_destroyed_pt = (struct res_lib_confdb_object_destroy_callback *)dispatch_data;
callbacks.confdb_object_delete_change_notify_fn(handle,
res_object_destroyed_pt->parent_object_handle,
res_object_destroyed_pt->name.value,
res_object_destroyed_pt->name.length);
break;
case MESSAGE_RES_CONFDB_RELOAD_CALLBACK:
if (callbacks.confdb_reload_notify_fn == NULL) {
continue;
}
res_reload_pt = (struct res_lib_confdb_reload_callback *)dispatch_data;
callbacks.confdb_reload_notify_fn(handle,
res_reload_pt->type);
break;
default:
coroipcc_dispatch_put (confdb_inst->handle);
error = CS_ERR_LIBRARY;
goto error_noput;
break;
}
coroipcc_dispatch_put (confdb_inst->handle);
/*
* Determine if more messages should be processed
*/
if (dispatch_types == CS_DISPATCH_ONE) {
cont = 0;
}
} while (cont);
error_put:
(void)hdb_handle_put (&confdb_handle_t_db, handle);
error_noput:
return (error);
}
cs_error_t confdb_object_create (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const void *object_name,
size_t object_name_len,
hdb_handle_t *object_handle)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
struct iovec iov;
struct req_lib_confdb_object_create req_lib_confdb_object_create;
struct res_lib_confdb_object_create res_lib_confdb_object_create;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
if (confdb_inst->standalone) {
error = CS_OK;
if (confdb_sa_object_create(parent_object_handle,
object_name, object_name_len,
object_handle))
error = CS_ERR_ACCESS;
goto error_exit;
}
req_lib_confdb_object_create.header.size = sizeof (struct req_lib_confdb_object_create);
req_lib_confdb_object_create.header.id = MESSAGE_REQ_CONFDB_OBJECT_CREATE;
req_lib_confdb_object_create.parent_object_handle = parent_object_handle;
memcpy(req_lib_confdb_object_create.object_name.value, object_name, object_name_len);
req_lib_confdb_object_create.object_name.length = object_name_len;
iov.iov_base = (char *)&req_lib_confdb_object_create;
iov.iov_len = sizeof (struct req_lib_confdb_object_create);
error = coroipcc_msg_send_reply_receive (
confdb_inst->handle,
&iov,
1,
&res_lib_confdb_object_create,
sizeof (struct res_lib_confdb_object_create));
if (error != CS_OK) {
goto error_exit;
}
error = res_lib_confdb_object_create.header.error;
*object_handle = res_lib_confdb_object_create.object_handle;
error_exit:
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (error);
}
cs_error_t confdb_object_destroy (
confdb_handle_t handle,
hdb_handle_t object_handle)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
struct iovec iov;
struct req_lib_confdb_object_destroy req_lib_confdb_object_destroy;
coroipc_response_header_t res;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
if (confdb_inst->standalone) {
error = CS_OK;
if (confdb_sa_object_destroy(object_handle))
error = CS_ERR_ACCESS;
goto error_exit;
}
req_lib_confdb_object_destroy.header.size = sizeof (struct req_lib_confdb_object_destroy);
req_lib_confdb_object_destroy.header.id = MESSAGE_REQ_CONFDB_OBJECT_DESTROY;
req_lib_confdb_object_destroy.object_handle = object_handle;
iov.iov_base = (char *)&req_lib_confdb_object_destroy;
iov.iov_len = sizeof (struct req_lib_confdb_object_destroy);
error = coroipcc_msg_send_reply_receive (
confdb_inst->handle,
&iov,
1,
&res,
sizeof (coroipc_response_header_t));
if (error != CS_OK) {
goto error_exit;
}
error = res.error;
error_exit:
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (error);
}
cs_error_t confdb_object_parent_get (
confdb_handle_t handle,
hdb_handle_t object_handle,
hdb_handle_t *parent_object_handle)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
struct iovec iov;
struct req_lib_confdb_object_parent_get req_lib_confdb_object_parent_get;
struct res_lib_confdb_object_parent_get res_lib_confdb_object_parent_get;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
if (confdb_inst->standalone) {
error = CS_OK;
if (confdb_sa_object_parent_get(object_handle, parent_object_handle))
error = CS_ERR_ACCESS;
goto error_exit;
}
req_lib_confdb_object_parent_get.header.size = sizeof (struct req_lib_confdb_object_parent_get);
req_lib_confdb_object_parent_get.header.id = MESSAGE_REQ_CONFDB_OBJECT_PARENT_GET;
req_lib_confdb_object_parent_get.object_handle = object_handle;
iov.iov_base = (char *)&req_lib_confdb_object_parent_get;
iov.iov_len = sizeof (struct req_lib_confdb_object_parent_get);
error = coroipcc_msg_send_reply_receive (
confdb_inst->handle,
&iov,
1,
&res_lib_confdb_object_parent_get,
sizeof (struct res_lib_confdb_object_parent_get));
if (error != CS_OK) {
goto error_exit;
}
error = res_lib_confdb_object_parent_get.header.error;
*parent_object_handle = res_lib_confdb_object_parent_get.parent_object_handle;
error_exit:
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (error);
}
cs_error_t confdb_object_name_get (
confdb_handle_t handle,
hdb_handle_t object_handle,
char *object_name,
size_t *object_name_len)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
struct iovec iov;
struct req_lib_confdb_object_name_get request;
struct res_lib_confdb_object_name_get response;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
if (confdb_inst->standalone) {
error = CS_OK;
if (confdb_sa_object_name_get(object_handle, object_name, object_name_len))
error = CS_ERR_ACCESS;
goto error_exit;
}
request.header.size = sizeof (struct req_lib_confdb_object_name_get);
request.header.id = MESSAGE_REQ_CONFDB_OBJECT_NAME_GET;
request.object_handle = object_handle;
iov.iov_base = (char *)&request;
iov.iov_len = sizeof (struct req_lib_confdb_object_name_get);
error = coroipcc_msg_send_reply_receive (
confdb_inst->handle,
&iov,
1,
&response,
sizeof (struct res_lib_confdb_object_name_get));
if (error != CS_OK) {
goto error_exit;
}
error = response.header.error;
if (error == CS_OK) {
*object_name_len = response.object_name.length;
memcpy(object_name, response.object_name.value, *object_name_len);
}
error_exit:
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (error);
}
static cs_error_t do_find_destroy(
struct confdb_inst *confdb_inst,
hdb_handle_t find_handle)
{
cs_error_t error;
struct iovec iov;
struct req_lib_confdb_object_find_destroy req_lib_confdb_object_find_destroy;
coroipc_response_header_t res;
if (!find_handle)
return CS_OK;
if (confdb_inst->standalone) {
error = CS_OK;
if (confdb_sa_find_destroy(find_handle))
error = CS_ERR_ACCESS;
goto error_exit;
}
req_lib_confdb_object_find_destroy.header.size = sizeof (struct req_lib_confdb_object_find_destroy);
req_lib_confdb_object_find_destroy.header.id = MESSAGE_REQ_CONFDB_OBJECT_FIND_DESTROY;
req_lib_confdb_object_find_destroy.find_handle = find_handle;
iov.iov_base = (char *)&req_lib_confdb_object_find_destroy;
iov.iov_len = sizeof (struct req_lib_confdb_object_find_destroy);
error = coroipcc_msg_send_reply_receive (
confdb_inst->handle,
&iov,
1,
&res,
sizeof (coroipc_response_header_t));
if (error != CS_OK) {
goto error_exit;
}
error = res.error;
error_exit:
return (error);
}
cs_error_t confdb_object_find_destroy(
confdb_handle_t handle,
hdb_handle_t parent_object_handle)
{
struct iter_context *context;
cs_error_t error;
struct confdb_inst *confdb_inst;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
context = find_iter_context(&confdb_inst->object_find_head, parent_object_handle);
error = do_find_destroy(confdb_inst, context->find_handle);
if (error == CS_OK) {
list_del(&context->list);
free(context);
}
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return error;
}
cs_error_t confdb_object_iter_destroy(
confdb_handle_t handle,
hdb_handle_t parent_object_handle)
{
struct iter_context *context;
cs_error_t error;
struct confdb_inst *confdb_inst;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
context = find_iter_context(&confdb_inst->object_iter_head, parent_object_handle);
error = do_find_destroy(confdb_inst, context->find_handle);
if (error == CS_OK) {
list_del(&context->list);
free(context);
}
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return error;
}
cs_error_t confdb_key_create (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
const void *value,
size_t value_len)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
struct iovec iov;
struct req_lib_confdb_key_create req_lib_confdb_key_create;
coroipc_response_header_t res;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
if (confdb_inst->standalone) {
error = CS_OK;
if (confdb_sa_key_create(parent_object_handle,
key_name, key_name_len,
value, value_len))
error = CS_ERR_ACCESS;
goto error_exit;
}
req_lib_confdb_key_create.header.size = sizeof (struct req_lib_confdb_key_create);
req_lib_confdb_key_create.header.id = MESSAGE_REQ_CONFDB_KEY_CREATE;
req_lib_confdb_key_create.object_handle = parent_object_handle;
memcpy(req_lib_confdb_key_create.key_name.value, key_name, key_name_len);
req_lib_confdb_key_create.key_name.length = key_name_len;
memcpy(req_lib_confdb_key_create.value.value, value, value_len);
req_lib_confdb_key_create.value.length = value_len;
iov.iov_base = (char *)&req_lib_confdb_key_create;
iov.iov_len = sizeof (struct req_lib_confdb_key_create);
error = coroipcc_msg_send_reply_receive (
confdb_inst->handle,
&iov,
1,
&res,
sizeof (res));
if (error != CS_OK) {
goto error_exit;
}
error = res.error;
error_exit:
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (error);
}
cs_error_t confdb_key_create_typed (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const char *key_name,
const void *value,
size_t value_len,
confdb_value_types_t type)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
struct iovec iov;
- struct req_lib_confdb_key_create_typed request;
+ struct req_lib_confdb_key_create_typed2 *request;
coroipc_response_header_t res;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
if (confdb_inst->standalone) {
error = CS_OK;
if (confdb_sa_key_create_typed(parent_object_handle,
key_name, value, value_len, type))
error = CS_ERR_ACCESS;
goto error_exit;
}
- request.header.size = sizeof (struct req_lib_confdb_key_create_typed);
- request.header.id = MESSAGE_REQ_CONFDB_KEY_CREATE_TYPED;
- request.object_handle = parent_object_handle;
- request.key_name.length = strlen(key_name)+1;
- memcpy(request.key_name.value, key_name, request.key_name.length);
- memcpy(request.value.value, value, value_len);
- request.value.length = value_len;
- request.type = type;
+ request = malloc(sizeof(struct req_lib_confdb_key_create_typed2)+value_len);
+ if (!request) {
+ error = CS_ERR_NO_MEMORY;
+ goto error_exit;
+ }
- iov.iov_base = (char *)&request;
- iov.iov_len = sizeof (struct req_lib_confdb_key_create_typed);
+ request->header.size = sizeof (struct req_lib_confdb_key_create_typed2) + value_len;
+ request->header.id = MESSAGE_REQ_CONFDB_KEY_CREATE_TYPED2;
+ request->object_handle = parent_object_handle;
+ request->key_name.length = strlen(key_name)+1;
+ memcpy(request->key_name.value, key_name, request->key_name.length);
+ memcpy(&request->value, value, value_len);
+ request->value_length = value_len;
+ request->type = type;
+
+ iov.iov_base = (char *)request;
+ iov.iov_len = request->header.size;
error = coroipcc_msg_send_reply_receive (
confdb_inst->handle,
&iov,
1,
&res,
sizeof (res));
if (error != CS_OK) {
goto error_exit;
}
error = res.error;
error_exit:
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (error);
}
cs_error_t confdb_key_delete (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
const void *value,
size_t value_len)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
struct iovec iov;
struct req_lib_confdb_key_delete req_lib_confdb_key_delete;
coroipc_response_header_t res;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
if (confdb_inst->standalone) {
error = CS_OK;
if (confdb_sa_key_delete(parent_object_handle,
key_name, key_name_len,
value, value_len))
error = CS_ERR_ACCESS;
goto error_exit;
}
req_lib_confdb_key_delete.header.size = sizeof (struct req_lib_confdb_key_delete);
req_lib_confdb_key_delete.header.id = MESSAGE_REQ_CONFDB_KEY_DELETE;
req_lib_confdb_key_delete.object_handle = parent_object_handle;
memcpy(req_lib_confdb_key_delete.key_name.value, key_name, key_name_len);
req_lib_confdb_key_delete.key_name.length = key_name_len;
memcpy(req_lib_confdb_key_delete.value.value, value, value_len);
req_lib_confdb_key_delete.value.length = value_len;
iov.iov_base = (char *)&req_lib_confdb_key_delete;
iov.iov_len = sizeof (struct req_lib_confdb_key_delete);
error = coroipcc_msg_send_reply_receive (
confdb_inst->handle,
&iov,
1,
&res,
sizeof (res));
if (error != CS_OK) {
goto error_exit;
}
error = res.error;
error_exit:
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (error);
}
cs_error_t confdb_key_get (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
void *value,
size_t *value_len)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
struct iovec iov;
struct req_lib_confdb_key_get req_lib_confdb_key_get;
struct res_lib_confdb_key_get res_lib_confdb_key_get;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
if (confdb_inst->standalone) {
error = CS_OK;
if (confdb_sa_key_get(parent_object_handle,
key_name, key_name_len,
value, value_len))
error = CS_ERR_ACCESS;
goto error_exit;
}
req_lib_confdb_key_get.header.size = sizeof (struct req_lib_confdb_key_get);
req_lib_confdb_key_get.header.id = MESSAGE_REQ_CONFDB_KEY_GET;
req_lib_confdb_key_get.parent_object_handle = parent_object_handle;
memcpy(req_lib_confdb_key_get.key_name.value, key_name, key_name_len);
req_lib_confdb_key_get.key_name.length = key_name_len;
iov.iov_base = (char *)&req_lib_confdb_key_get;
iov.iov_len = sizeof (struct req_lib_confdb_key_get);
error = coroipcc_msg_send_reply_receive (
confdb_inst->handle,
&iov,
1,
&res_lib_confdb_key_get,
sizeof (struct res_lib_confdb_key_get));
if (error != CS_OK) {
goto error_exit;
}
error = res_lib_confdb_key_get.header.error;
if (error == CS_OK) {
*value_len = res_lib_confdb_key_get.value.length;
memcpy(value, res_lib_confdb_key_get.value.value, *value_len);
}
error_exit:
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (error);
}
cs_error_t confdb_key_get_typed (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const char *key_name,
void *value,
size_t *value_len,
confdb_value_types_t *type)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
struct iovec iov;
struct req_lib_confdb_key_get req_lib_confdb_key_get;
struct res_lib_confdb_key_get_typed response;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
if (confdb_inst->standalone) {
error = CS_OK;
if (confdb_sa_key_get_typed(parent_object_handle,
- key_name, value, value_len, (int*)type))
+ key_name, &value, value_len, (int*)type))
error = CS_ERR_ACCESS;
goto error_exit;
}
req_lib_confdb_key_get.header.size = sizeof (struct req_lib_confdb_key_get);
req_lib_confdb_key_get.header.id = MESSAGE_REQ_CONFDB_KEY_GET_TYPED;
req_lib_confdb_key_get.parent_object_handle = parent_object_handle;
req_lib_confdb_key_get.key_name.length = strlen(key_name) + 1;
memcpy(req_lib_confdb_key_get.key_name.value, key_name, req_lib_confdb_key_get.key_name.length);
iov.iov_base = (char *)&req_lib_confdb_key_get;
iov.iov_len = sizeof (struct req_lib_confdb_key_get);
error = coroipcc_msg_send_reply_receive (
confdb_inst->handle,
&iov,
1,
&response,
sizeof (struct res_lib_confdb_key_get_typed));
if (error != CS_OK) {
goto error_exit;
}
error = response.header.error;
if (error == CS_OK) {
*value_len = response.value.length;
*type = response.type;
memcpy(value, response.value.value, *value_len);
}
error_exit:
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (error);
}
+cs_error_t confdb_key_get_typed2 (
+ confdb_handle_t handle,
+ hdb_handle_t parent_object_handle,
+ const char *key_name,
+ void **value,
+ size_t *value_len,
+ confdb_value_types_t *type)
+{
+ cs_error_t error;
+ struct confdb_inst *confdb_inst;
+ struct iovec iov;
+ struct req_lib_confdb_key_get req_lib_confdb_key_get;
+ struct res_lib_confdb_key_get_typed2 *response;
+ void *return_address;
+
+ error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ if (confdb_inst->standalone) {
+ error = CS_OK;
+
+ if (confdb_sa_key_get_typed(parent_object_handle,
+ key_name, value, value_len, (int*)type))
+ error = CS_ERR_ACCESS;
+ goto error_exit;
+ }
+
+ req_lib_confdb_key_get.header.size = sizeof (struct req_lib_confdb_key_get);
+ req_lib_confdb_key_get.header.id = MESSAGE_REQ_CONFDB_KEY_GET_TYPED2;
+ req_lib_confdb_key_get.parent_object_handle = parent_object_handle;
+ req_lib_confdb_key_get.key_name.length = strlen(key_name) + 1;
+ memcpy(req_lib_confdb_key_get.key_name.value, key_name, req_lib_confdb_key_get.key_name.length);
+
+ iov.iov_base = (char *)&req_lib_confdb_key_get;
+ iov.iov_len = sizeof (struct req_lib_confdb_key_get);
+
+ error = coroipcc_msg_send_reply_receive_in_buf_get (
+ confdb_inst->handle,
+ &iov,
+ 1,
+ &return_address);
+ response = return_address;
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+ error = response->header.error;
+
+ if (error == CS_OK) {
+ if (!*value) {
+ /* Allow space for naughty callers to put a NUL for printing */
+ *value = malloc(response->value_length+1);
+ if (!*value) {
+ error = CS_ERR_NO_MEMORY;
+ goto error_exit;
+ }
+ }
+ memcpy(*value, &response->value, response->value_length);
+ *value_len = response->value_length;
+ *type = response->type;
+ }
+
+error_exit:
+ (void)hdb_handle_put (&confdb_handle_t_db, handle);
+
+ return (error);
+
+}
+
cs_error_t confdb_key_increment (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
unsigned int *value)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
struct iovec iov;
struct req_lib_confdb_key_get req_lib_confdb_key_get;
struct res_lib_confdb_key_incdec res_lib_confdb_key_incdec;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
if (confdb_inst->standalone) {
error = CS_OK;
if (confdb_sa_key_increment(parent_object_handle,
key_name, key_name_len,
value))
error = CS_ERR_ACCESS;
goto error_exit;
}
req_lib_confdb_key_get.header.size = sizeof (struct req_lib_confdb_key_get);
req_lib_confdb_key_get.header.id = MESSAGE_REQ_CONFDB_KEY_INCREMENT;
req_lib_confdb_key_get.parent_object_handle = parent_object_handle;
memcpy(req_lib_confdb_key_get.key_name.value, key_name, key_name_len);
req_lib_confdb_key_get.key_name.length = key_name_len;
iov.iov_base = (char *)&req_lib_confdb_key_get;
iov.iov_len = sizeof (struct req_lib_confdb_key_get);
error = coroipcc_msg_send_reply_receive (
confdb_inst->handle,
&iov,
1,
&res_lib_confdb_key_incdec,
sizeof (struct res_lib_confdb_key_incdec));
if (error != CS_OK) {
goto error_exit;
}
error = res_lib_confdb_key_incdec.header.error;
if (error == CS_OK) {
*value = res_lib_confdb_key_incdec.value;
}
error_exit:
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (error);
}
cs_error_t confdb_key_decrement (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
unsigned int *value)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
struct iovec iov;
struct req_lib_confdb_key_get req_lib_confdb_key_get;
struct res_lib_confdb_key_incdec res_lib_confdb_key_incdec;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
if (confdb_inst->standalone) {
error = CS_OK;
if (confdb_sa_key_decrement(parent_object_handle,
key_name, key_name_len,
value))
error = CS_ERR_ACCESS;
goto error_exit;
}
req_lib_confdb_key_get.header.size = sizeof (struct req_lib_confdb_key_get);
req_lib_confdb_key_get.header.id = MESSAGE_REQ_CONFDB_KEY_DECREMENT;
req_lib_confdb_key_get.parent_object_handle = parent_object_handle;
memcpy(req_lib_confdb_key_get.key_name.value, key_name, key_name_len);
req_lib_confdb_key_get.key_name.length = key_name_len;
iov.iov_base = (char *)&req_lib_confdb_key_get;
iov.iov_len = sizeof (struct req_lib_confdb_key_get);
error = coroipcc_msg_send_reply_receive (
confdb_inst->handle,
&iov,
1,
&res_lib_confdb_key_incdec,
sizeof (struct res_lib_confdb_key_incdec));
if (error != CS_OK) {
goto error_exit;
}
error = res_lib_confdb_key_incdec.header.error;
if (error == CS_OK) {
*value = res_lib_confdb_key_incdec.value;
}
error_exit:
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (error);
}
cs_error_t confdb_key_replace (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
const void *old_value,
size_t old_value_len,
const void *new_value,
size_t new_value_len)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
struct iovec iov;
- struct req_lib_confdb_key_replace req_lib_confdb_key_replace;
+ struct req_lib_confdb_key_replace2 *req_lib_confdb_key_replace;
coroipc_response_header_t res;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
if (confdb_inst->standalone) {
error = CS_OK;
if (confdb_sa_key_replace(parent_object_handle,
key_name, key_name_len,
old_value, old_value_len,
new_value, new_value_len))
error = CS_ERR_ACCESS;
goto error_exit;
}
- req_lib_confdb_key_replace.header.size = sizeof (struct req_lib_confdb_key_replace);
- req_lib_confdb_key_replace.header.id = MESSAGE_REQ_CONFDB_KEY_REPLACE;
- req_lib_confdb_key_replace.object_handle = parent_object_handle;
- memcpy(req_lib_confdb_key_replace.key_name.value, key_name, key_name_len);
- req_lib_confdb_key_replace.key_name.length = key_name_len;
- memcpy(req_lib_confdb_key_replace.old_value.value, old_value, old_value_len);
- req_lib_confdb_key_replace.old_value.length = old_value_len;
- memcpy(req_lib_confdb_key_replace.new_value.value, new_value, new_value_len);
- req_lib_confdb_key_replace.new_value.length = new_value_len;
- iov.iov_base = (char *)&req_lib_confdb_key_replace;
- iov.iov_len = sizeof (struct req_lib_confdb_key_replace);
+ req_lib_confdb_key_replace = malloc(sizeof(struct req_lib_confdb_key_replace2) + new_value_len);
+
+ req_lib_confdb_key_replace->header.size = sizeof(struct req_lib_confdb_key_replace2) + new_value_len;
+ req_lib_confdb_key_replace->header.id = MESSAGE_REQ_CONFDB_KEY_REPLACE2;
+ req_lib_confdb_key_replace->object_handle = parent_object_handle;
+ memcpy(req_lib_confdb_key_replace->key_name.value, key_name, key_name_len);
+ req_lib_confdb_key_replace->key_name.length = key_name_len;
+ memcpy(&req_lib_confdb_key_replace->new_value, new_value, new_value_len);
+ req_lib_confdb_key_replace->new_value_length = new_value_len;
+ /* Oddly objdb doesn't use the old value, so we don't bother sending it */
+ iov.iov_base = (char *)req_lib_confdb_key_replace;
+ iov.iov_len = sizeof(struct req_lib_confdb_key_replace2) + new_value_len;
error = coroipcc_msg_send_reply_receive (
confdb_inst->handle,
&iov,
1,
&res,
sizeof (res));
if (error != CS_OK) {
goto error_exit;
}
error = res.error;
error_exit:
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (error);
}
cs_error_t confdb_object_iter_start (
confdb_handle_t handle,
hdb_handle_t object_handle)
{
struct confdb_inst *confdb_inst;
cs_error_t error = CS_OK;
struct iter_context *context;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
context = find_iter_context(&confdb_inst->object_iter_head, object_handle);
if (!context) {
context = malloc(sizeof(struct iter_context));
if (!context) {
error = CS_ERR_NO_MEMORY;
goto ret;
}
context->parent_object_handle = object_handle;
context->find_handle = 0;
list_add(&context->list, &confdb_inst->object_iter_head);
}
/* Start a new find context */
if (context->find_handle) {
(void)do_find_destroy(confdb_inst, context->find_handle);
context->find_handle = 0;
}
(void)hdb_handle_put (&confdb_handle_t_db, handle);
ret:
return error;
}
cs_error_t confdb_key_iter_start (
confdb_handle_t handle,
hdb_handle_t object_handle)
{
struct confdb_inst *confdb_inst;
cs_error_t error = CS_OK;
struct iter_context *context;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
context = find_iter_context(&confdb_inst->key_iter_head, object_handle);
if (!context) {
context = malloc(sizeof(struct iter_context));
if (!context) {
error = CS_ERR_NO_MEMORY;
goto ret;
}
context->parent_object_handle = object_handle;
list_add(&context->list, &confdb_inst->key_iter_head);
}
context->find_handle = 0;
context->next_entry = 0;
(void)hdb_handle_put (&confdb_handle_t_db, handle);
ret:
return error;
}
cs_error_t confdb_object_find_start (
confdb_handle_t handle,
hdb_handle_t parent_object_handle)
{
struct confdb_inst *confdb_inst;
cs_error_t error = CS_OK;
struct iter_context *context;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
context = find_iter_context(&confdb_inst->object_find_head, parent_object_handle);
if (!context) {
context = malloc(sizeof(struct iter_context));
if (!context) {
error = CS_ERR_NO_MEMORY;
goto ret;
}
context->find_handle = 0;
context->parent_object_handle = parent_object_handle;
list_add(&context->list, &confdb_inst->object_find_head);
}
/* Start a new find context */
if (context->find_handle) {
(void)do_find_destroy(confdb_inst, context->find_handle);
context->find_handle = 0;
}
(void)hdb_handle_put (&confdb_handle_t_db, handle);
ret:
return error;
}
cs_error_t confdb_object_find (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const void *object_name,
size_t object_name_len,
hdb_handle_t *object_handle)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
struct iovec iov;
struct iter_context *context;
struct req_lib_confdb_object_find req_lib_confdb_object_find;
struct res_lib_confdb_object_find res_lib_confdb_object_find;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
/* You MUST call confdb_object_find_start first */
context = find_iter_context(&confdb_inst->object_find_head, parent_object_handle);
if (!context) {
error = CS_ERR_CONTEXT_NOT_FOUND;
goto error_exit;
}
if (confdb_inst->standalone) {
error = CS_OK;
if (confdb_sa_object_find(parent_object_handle,
&context->find_handle,
object_handle,
object_name, object_name_len))
error = CS_ERR_ACCESS;
goto error_exit;
}
req_lib_confdb_object_find.header.size = sizeof (struct req_lib_confdb_object_find);
req_lib_confdb_object_find.header.id = MESSAGE_REQ_CONFDB_OBJECT_FIND;
req_lib_confdb_object_find.parent_object_handle = parent_object_handle;
req_lib_confdb_object_find.find_handle = context->find_handle;
memcpy(req_lib_confdb_object_find.object_name.value, object_name, object_name_len);
req_lib_confdb_object_find.object_name.length = object_name_len;
iov.iov_base = (char *)&req_lib_confdb_object_find;
iov.iov_len = sizeof (struct req_lib_confdb_object_find);
error = coroipcc_msg_send_reply_receive (
confdb_inst->handle,
&iov,
1,
&res_lib_confdb_object_find,
sizeof (struct res_lib_confdb_object_find));
if (error != CS_OK) {
goto error_exit;
}
error = res_lib_confdb_object_find.header.error;
*object_handle = res_lib_confdb_object_find.object_handle;
context->find_handle = res_lib_confdb_object_find.find_handle;
error_exit:
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (error);
}
cs_error_t confdb_object_iter (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
hdb_handle_t *object_handle,
void *object_name,
size_t *object_name_len)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
struct iovec iov;
struct iter_context *context;
struct req_lib_confdb_object_iter req_lib_confdb_object_iter;
struct res_lib_confdb_object_iter res_lib_confdb_object_iter;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
/* You MUST call confdb_object_iter_start first */
context = find_iter_context(&confdb_inst->object_iter_head, parent_object_handle);
if (!context) {
error = CS_ERR_CONTEXT_NOT_FOUND;
goto error_exit;
}
if (confdb_inst->standalone) {
error = CS_OK;
*object_name_len = 0;
if (confdb_sa_object_iter(parent_object_handle,
&context->find_handle,
object_handle,
NULL, 0,
object_name, object_name_len))
error = CS_ERR_ACCESS;
goto sa_exit;
}
req_lib_confdb_object_iter.header.size = sizeof (struct req_lib_confdb_object_iter);
req_lib_confdb_object_iter.header.id = MESSAGE_REQ_CONFDB_OBJECT_ITER;
req_lib_confdb_object_iter.parent_object_handle = parent_object_handle;
req_lib_confdb_object_iter.find_handle = context->find_handle;
iov.iov_base = (char *)&req_lib_confdb_object_iter;
iov.iov_len = sizeof (struct req_lib_confdb_object_iter);
error = coroipcc_msg_send_reply_receive (
confdb_inst->handle,
&iov,
1,
&res_lib_confdb_object_iter,
sizeof (struct res_lib_confdb_object_iter));
if (error != CS_OK) {
goto error_exit;
}
error = res_lib_confdb_object_iter.header.error;
if (error == CS_OK) {
*object_name_len = res_lib_confdb_object_iter.object_name.length;
memcpy(object_name, res_lib_confdb_object_iter.object_name.value, *object_name_len);
*object_handle = res_lib_confdb_object_iter.object_handle;
context->find_handle = res_lib_confdb_object_iter.find_handle;
}
sa_exit:
error_exit:
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (error);
}
cs_error_t confdb_key_iter (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
void *key_name,
size_t *key_name_len,
void *value,
size_t *value_len)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
struct iovec iov;
struct iter_context *context;
struct req_lib_confdb_key_iter req_lib_confdb_key_iter;
struct res_lib_confdb_key_iter res_lib_confdb_key_iter;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
/* You MUST call confdb_key_iter_start first */
context = find_iter_context(&confdb_inst->key_iter_head, parent_object_handle);
if (!context) {
error = CS_ERR_CONTEXT_NOT_FOUND;
goto error_exit;
}
if (confdb_inst->standalone) {
error = CS_OK;
if (confdb_sa_key_iter(parent_object_handle,
context->next_entry,
key_name, key_name_len,
value, value_len))
error = CS_ERR_ACCESS;
goto sa_exit;
}
req_lib_confdb_key_iter.header.size = sizeof (struct req_lib_confdb_key_iter);
req_lib_confdb_key_iter.header.id = MESSAGE_REQ_CONFDB_KEY_ITER;
req_lib_confdb_key_iter.parent_object_handle = parent_object_handle;
req_lib_confdb_key_iter.next_entry= context->next_entry;
iov.iov_base = (char *)&req_lib_confdb_key_iter;
iov.iov_len = sizeof (struct req_lib_confdb_key_iter);
error = coroipcc_msg_send_reply_receive (
confdb_inst->handle,
&iov,
1,
&res_lib_confdb_key_iter,
sizeof (struct res_lib_confdb_key_iter));
if (error != CS_OK) {
goto error_exit;
}
error = res_lib_confdb_key_iter.header.error;
if (error == CS_OK) {
char* key_name_str = (char*)key_name;
*key_name_len = res_lib_confdb_key_iter.key_name.length;
memcpy(key_name, res_lib_confdb_key_iter.key_name.value, *key_name_len);
key_name_str[res_lib_confdb_key_iter.key_name.length] = '\0';
*value_len = res_lib_confdb_key_iter.value.length;
memcpy(value, res_lib_confdb_key_iter.value.value, *value_len);
}
sa_exit:
context->next_entry++;
error_exit:
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (error);
}
cs_error_t confdb_key_iter_typed (
confdb_handle_t handle,
hdb_handle_t parent_object_handle,
char *key_name,
void *value,
size_t *value_len,
confdb_value_types_t *type)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
struct iovec iov;
struct iter_context *context;
struct req_lib_confdb_key_iter req_lib_confdb_key_iter;
struct res_lib_confdb_key_iter_typed response;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
/* You MUST call confdb_key_iter_start first */
context = find_iter_context(&confdb_inst->key_iter_head, parent_object_handle);
if (!context) {
error = CS_ERR_CONTEXT_NOT_FOUND;
goto error_exit;
}
if (confdb_inst->standalone) {
error = CS_OK;
if (confdb_sa_key_iter_typed(parent_object_handle,
context->next_entry,
key_name,
- value, value_len, (int*)type))
+ &value, value_len, (int*)type))
error = CS_ERR_ACCESS;
goto sa_exit;
}
req_lib_confdb_key_iter.header.size = sizeof (struct req_lib_confdb_key_iter);
req_lib_confdb_key_iter.header.id = MESSAGE_REQ_CONFDB_KEY_ITER_TYPED;
req_lib_confdb_key_iter.parent_object_handle = parent_object_handle;
req_lib_confdb_key_iter.next_entry= context->next_entry;
iov.iov_base = (char *)&req_lib_confdb_key_iter;
iov.iov_len = sizeof (struct req_lib_confdb_key_iter);
error = coroipcc_msg_send_reply_receive (
confdb_inst->handle,
&iov,
1,
&response,
sizeof (struct res_lib_confdb_key_iter_typed));
if (error != CS_OK) {
goto error_exit;
}
error = response.header.error;
if (error == CS_OK) {
memcpy(key_name, response.key_name.value, response.key_name.length);
key_name[response.key_name.length] = '\0';
*value_len = response.value.length;
memcpy(value, response.value.value, *value_len);
*type = response.type;
}
sa_exit:
context->next_entry++;
error_exit:
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (error);
}
+cs_error_t confdb_key_iter_typed2 (
+ confdb_handle_t handle,
+ hdb_handle_t parent_object_handle,
+ char *key_name,
+ void **value,
+ size_t *value_len,
+ confdb_value_types_t *type)
+{
+ cs_error_t error;
+ struct confdb_inst *confdb_inst;
+ struct iovec iov;
+ struct iter_context *context;
+ struct req_lib_confdb_key_iter req_lib_confdb_key_iter;
+ struct res_lib_confdb_key_iter_typed2 *response;
+ void *return_address;
+
+ error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
+ if (error != CS_OK) {
+ return (error);
+ }
+
+ /* You MUST call confdb_key_iter_start first */
+ context = find_iter_context(&confdb_inst->key_iter_head, parent_object_handle);
+ if (!context) {
+ error = CS_ERR_CONTEXT_NOT_FOUND;
+ goto error_exit;
+ }
+
+ if (confdb_inst->standalone) {
+ error = CS_OK;
+ if (confdb_sa_key_iter_typed(parent_object_handle,
+ context->next_entry,
+ key_name,
+ value, value_len, (int*)type))
+ error = CS_ERR_ACCESS;
+ goto sa_exit;
+ }
+
+ req_lib_confdb_key_iter.header.size = sizeof (struct req_lib_confdb_key_iter);
+ req_lib_confdb_key_iter.header.id = MESSAGE_REQ_CONFDB_KEY_ITER_TYPED2;
+ req_lib_confdb_key_iter.parent_object_handle = parent_object_handle;
+ req_lib_confdb_key_iter.next_entry= context->next_entry;
+
+ iov.iov_base = (char *)&req_lib_confdb_key_iter;
+ iov.iov_len = sizeof (struct req_lib_confdb_key_iter);
+
+ error = coroipcc_msg_send_reply_receive_in_buf_get (
+ confdb_inst->handle,
+ &iov,
+ 1,
+ &return_address);
+ response = return_address;
+
+ if (error != CS_OK) {
+ goto error_exit;
+ }
+ error = response->header.error;
+
+ if (error == CS_OK) {
+ if (!*value) {
+ /* Allow space for naughty callers to put a NUL for printing */
+ *value = malloc(response->value_length+1);
+ if (!*value) {
+ error = CS_ERR_NO_MEMORY;
+ goto error_exit;
+ }
+ }
+ memcpy(key_name, response->key_name.value, response->key_name.length);
+ key_name[response->key_name.length] = '\0';
+ memcpy(*value, &response->value, response->value_length);
+ *value_len = response->value_length;
+ *type = response->type;
+ }
+
+sa_exit:
+ context->next_entry++;
+
+error_exit:
+ (void)hdb_handle_put (&confdb_handle_t_db, handle);
+
+ return (error);
+}
+
cs_error_t confdb_write (
confdb_handle_t handle,
char *error_text,
size_t errbuf_len)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
struct iovec iov;
coroipc_request_header_t req;
struct res_lib_confdb_write res_lib_confdb_write;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
/* FIXME: set error_text */
return (error);
}
if (confdb_inst->standalone) {
error = CS_OK;
if (confdb_sa_write(error_text, errbuf_len))
error = CS_ERR_ACCESS;
goto error_exit;
}
req.size = sizeof (coroipc_request_header_t);
req.id = MESSAGE_REQ_CONFDB_WRITE;
iov.iov_base = (char *)&req;
iov.iov_len = sizeof (coroipc_request_header_t);
error = coroipcc_msg_send_reply_receive (
confdb_inst->handle,
&iov,
1,
&res_lib_confdb_write,
sizeof (struct res_lib_confdb_write));
if (error != CS_OK) {
/* FIXME: set error_text */
goto error_exit;
}
error = res_lib_confdb_write.header.error;
if (res_lib_confdb_write.error.length) {
memcpy(error_text, res_lib_confdb_write.error.value,
MIN(res_lib_confdb_write.error.length,errbuf_len));
error_text[errbuf_len-1] = '\0';
}
error_exit:
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (error);
}
cs_error_t confdb_reload (
confdb_handle_t handle,
int flush,
char *error_text,
size_t errbuf_len)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
struct iovec iov;
struct res_lib_confdb_reload res_lib_confdb_reload;
struct req_lib_confdb_reload req_lib_confdb_reload;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
/* FIXME: set error_text */
return (error);
}
if (confdb_inst->standalone) {
error = CS_OK;
if (confdb_sa_reload(flush, error_text, errbuf_len))
error = CS_ERR_ACCESS;
goto error_exit;
}
req_lib_confdb_reload.header.size = sizeof (req_lib_confdb_reload);
req_lib_confdb_reload.header.id = MESSAGE_REQ_CONFDB_RELOAD;
req_lib_confdb_reload.flush = flush;
iov.iov_base = (char *)&req_lib_confdb_reload;
iov.iov_len = sizeof (req_lib_confdb_reload);
error = coroipcc_msg_send_reply_receive (
confdb_inst->handle,
&iov,
1,
&res_lib_confdb_reload,
sizeof (struct res_lib_confdb_reload));
if (error != CS_OK) {
/* FIXME: set error_text */
goto error_exit;
}
error = res_lib_confdb_reload.header.error;
if(res_lib_confdb_reload.error.length) {
memcpy(error_text, res_lib_confdb_reload.error.value,
MIN(res_lib_confdb_reload.error.length,errbuf_len));
error_text[errbuf_len-1] = '\0';
}
error_exit:
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (error);
}
cs_error_t confdb_track_changes (
confdb_handle_t handle,
hdb_handle_t object_handle,
unsigned int flags)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
struct iovec iov;
struct req_lib_confdb_object_track_start req;
coroipc_response_header_t res;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
if (confdb_inst->standalone) {
error = CS_ERR_NOT_SUPPORTED;
goto error_exit;
}
req.header.size = sizeof (struct req_lib_confdb_object_track_start);
req.header.id = MESSAGE_REQ_CONFDB_TRACK_START;
req.object_handle = object_handle;
req.flags = flags;
iov.iov_base = (char *)&req;
iov.iov_len = sizeof (struct req_lib_confdb_object_track_start);
error = coroipcc_msg_send_reply_receive (
confdb_inst->handle,
&iov,
1,
&res,
sizeof (coroipc_response_header_t));
if (error != CS_OK) {
goto error_exit;
}
error = res.error;
error_exit:
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (error);
}
cs_error_t confdb_stop_track_changes (confdb_handle_t handle)
{
cs_error_t error;
struct confdb_inst *confdb_inst;
struct iovec iov;
coroipc_request_header_t req;
coroipc_response_header_t res;
error = hdb_error_to_cs(hdb_handle_get (&confdb_handle_t_db, handle, (void *)&confdb_inst));
if (error != CS_OK) {
return (error);
}
if (confdb_inst->standalone) {
error = CS_ERR_NOT_SUPPORTED;
goto error_exit;
}
req.size = sizeof (coroipc_request_header_t);
req.id = MESSAGE_REQ_CONFDB_TRACK_STOP;
iov.iov_base = (char *)&req;
iov.iov_len = sizeof (coroipc_request_header_t);
error = coroipcc_msg_send_reply_receive (
confdb_inst->handle,
&iov,
1,
&res,
sizeof (coroipc_response_header_t));
if (error != CS_OK) {
goto error_exit;
}
error = res.error;
error_exit:
(void)hdb_handle_put (&confdb_handle_t_db, handle);
return (error);
}
diff --git a/lib/sa-confdb.c b/lib/sa-confdb.c
index 03995e34..9a11418b 100644
--- a/lib/sa-confdb.c
+++ b/lib/sa-confdb.c
@@ -1,449 +1,464 @@
/*
- * Copyright (c) 2008, 2009 Red Hat, Inc.
+ * Copyright (c) 2008, 2012 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 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.
*/
/*
* Provides stand-alone access to data in the corosync object database
* when aisexec is not running.
*/
#include <config.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <corosync/corotypes.h>
#include <corosync/coroipcc.h>
#include <corosync/engine/objdb.h>
#include <corosync/engine/config.h>
#include <corosync/engine/logsys.h>
#include <corosync/lcr/lcr_comp.h>
#include <corosync/lcr/lcr_ifact.h>
#include "sa-confdb.h"
static struct objdb_iface_ver0 *objdb;
static int num_config_modules;
static struct config_iface_ver0 *config_modules[128];
void main_get_config_modules(struct config_iface_ver0 ***modules, int *num);
static int load_objdb(void)
{
hdb_handle_t objdb_handle;
void *objdb_p;
int res;
/*
* Load the object database interface
*/
res = lcr_ifact_reference (
&objdb_handle,
"objdb",
0,
&objdb_p,
(void *)0);
if (res == -1) {
return -1;
}
objdb = (struct objdb_iface_ver0 *)objdb_p;
objdb->objdb_init ();
return CS_OK;
}
static int load_config(void)
{
char *config_iface;
char *iface;
int res;
hdb_handle_t config_handle;
hdb_handle_t config_version = 0;
void *config_p;
struct config_iface_ver0 *config;
const char *error_string;
char *strtok_savept;
/* User's bootstrap config service */
config_iface = getenv("COROSYNC_DEFAULT_CONFIG_IFACE");
if (!config_iface) {
if ((config_iface = strdup("corosync_parser")) == NULL) {
return -1;
}
}
/* Make a copy so we can deface it with strtok */
if ((config_iface = strdup(config_iface)) == NULL) {
return -1;
}
iface = strtok_r (config_iface, ":", &strtok_savept);
while (iface)
{
res = lcr_ifact_reference (
&config_handle,
iface,
config_version,
&config_p,
0);
config = (struct config_iface_ver0 *)config_p;
if (res == -1) {
return -1;
}
res = config->config_readconfig(objdb, &error_string);
if (res == -1) {
return -1;
}
config_modules[num_config_modules++] = config;
iface = strtok_r (NULL, ":", &strtok_savept);
}
free(config_iface);
return CS_OK;
}
/* Needed by objdb when it writes back the configuration */
void main_get_config_modules(struct config_iface_ver0 ***modules, int *num)
{
*modules = config_modules;
*num = num_config_modules;
}
int confdb_sa_init (void)
{
int res;
res = load_objdb();
if (res != CS_OK)
return res;
res = load_config();
return res;
}
int confdb_sa_object_create (
hdb_handle_t parent_object_handle,
const void *object_name,
size_t object_name_len,
hdb_handle_t *object_handle)
{
return objdb->object_create(parent_object_handle,
object_handle,
object_name, object_name_len);
}
int confdb_sa_object_destroy (
hdb_handle_t object_handle)
{
return objdb->object_destroy(object_handle);
}
int confdb_sa_object_parent_get (
hdb_handle_t object_handle,
hdb_handle_t *parent_object_handle)
{
return objdb->object_parent_get(object_handle, parent_object_handle);
}
int confdb_sa_object_name_get(
hdb_handle_t object_handle,
char *object_name,
size_t *object_name_len)
{
return objdb->object_name_get(object_handle, object_name, object_name_len);
}
int confdb_sa_key_create (
hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
const void *value,
size_t value_len)
{
return objdb->object_key_create(parent_object_handle,
key_name, key_name_len,
value, value_len);
}
int confdb_sa_key_create_typed (
hdb_handle_t parent_object_handle,
const char *key_name,
const void *value,
size_t value_len,
int type)
{
return objdb->object_key_create_typed(parent_object_handle,
key_name,
value, value_len, type);
}
int confdb_sa_key_delete (
hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
const void *value,
size_t value_len)
{
return objdb->object_key_delete(parent_object_handle,
key_name, key_name_len);
}
int confdb_sa_key_get (
hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
void *value,
size_t *value_len)
{
int res;
void *kvalue;
res = objdb->object_key_get(parent_object_handle,
key_name, key_name_len,
&kvalue, value_len);
if (!res) {
memcpy(value, kvalue, *value_len);
}
return res;
}
int confdb_sa_key_get_typed (
hdb_handle_t parent_object_handle,
const char *key_name,
- void *value,
+ void **value,
size_t *value_len,
int *type)
{
int res;
void *kvalue;
res = objdb->object_key_get_typed(parent_object_handle,
key_name,
&kvalue, value_len, (objdb_value_types_t*)type);
if (!res) {
- memcpy(value, kvalue, *value_len);
+ if (!*value) {
+ *value = malloc(*value_len);
+ if (!*value) {
+ res = CS_ERR_NO_MEMORY;
+ }
+ }
+ if (*value) {
+ memcpy(*value, kvalue, *value_len);
+ }
}
return res;
}
int confdb_sa_key_increment (
hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
unsigned int *value)
{
int res;
res = objdb->object_key_increment(parent_object_handle,
key_name, key_name_len,
value);
return res;
}
int confdb_sa_key_decrement (
hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
unsigned int *value)
{
int res;
res = objdb->object_key_decrement(parent_object_handle,
key_name, key_name_len,
value);
return res;
}
int confdb_sa_key_replace (
hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
const void *old_value,
size_t old_value_len,
const void *new_value,
size_t new_value_len)
{
return objdb->object_key_replace(parent_object_handle,
key_name, key_name_len,
new_value, new_value_len);
}
int confdb_sa_write (char *error_text, size_t errbuf_len)
{
const char *errtext;
int ret;
ret = objdb->object_write_config(&errtext);
if (!ret) {
strncpy(error_text, errtext, errbuf_len);
if (errbuf_len > 0)
error_text[errbuf_len-1] = '\0';
}
return ret;
}
int confdb_sa_reload (
int flush,
char *error_text,
size_t errbuf_len)
{
char *errtext;
int ret;
ret = objdb->object_reload_config(flush, (const char **) &errtext);
if (!ret) {
strncpy(error_text, errtext, errbuf_len);
if (errbuf_len > 0)
error_text[errbuf_len-1] = '\0';
}
return ret;
}
int confdb_sa_object_find (
hdb_handle_t parent_object_handle,
hdb_handle_t *find_handle,
hdb_handle_t *object_handle,
const void *object_name,
size_t object_name_len)
{
int res;
if (!*find_handle) {
objdb->object_find_create(parent_object_handle,
object_name, object_name_len,
find_handle);
}
res = objdb->object_find_next(*find_handle,
object_handle);
return res;
}
int confdb_sa_object_iter (
hdb_handle_t parent_object_handle,
hdb_handle_t *find_handle,
hdb_handle_t *object_handle,
const void *object_name,
size_t object_name_len,
void *found_object_name,
size_t *found_object_name_len)
{
int res;
if (!*find_handle) {
objdb->object_find_create(parent_object_handle,
object_name, object_name_len,
find_handle);
}
res = objdb->object_find_next(*find_handle,
object_handle);
/* Return object name if we were called as _iter */
if (!res) {
objdb->object_name_get(*object_handle,
found_object_name, found_object_name_len);
}
return res;
}
int confdb_sa_key_iter (
hdb_handle_t parent_object_handle,
hdb_handle_t start_pos,
void *key_name,
size_t *key_name_len,
void *value,
size_t *value_len)
{
int res;
void *kname, *kvalue;
res = objdb->object_key_iter_from(parent_object_handle,
start_pos,
&kname, key_name_len,
&kvalue, value_len);
if (!res) {
memcpy(key_name, kname, *key_name_len);
memcpy(value, kvalue, *value_len);
}
return res;
}
int confdb_sa_key_iter_typed (
hdb_handle_t parent_object_handle,
hdb_handle_t start_pos,
char *key_name,
- void *value,
+ void **value,
size_t *value_len,
int *type)
{
int res;
void *kname;
void *kvalue;
size_t key_name_len;
res = objdb->object_key_iter_from(parent_object_handle,
start_pos,
&kname, &key_name_len,
&kvalue, value_len);
if (!res) {
memcpy(key_name, kname, key_name_len);
key_name[key_name_len] = '\0';
- memcpy(value, kvalue, *value_len);
-
- objdb->object_key_get_typed(parent_object_handle,
- key_name,
- &kvalue, value_len, (objdb_value_types_t*)type);
+ if (!*value) {
+ *value = malloc(*value_len);
+ if (!*value) {
+ res = CS_ERR_NO_MEMORY;
+ }
+ }
+ if (*value) {
+ memcpy(*value, kvalue, *value_len);
+ objdb->object_key_get_typed(parent_object_handle,
+ key_name,
+ &kvalue, value_len, (objdb_value_types_t*)type);
+ }
}
return res;
}
int confdb_sa_find_destroy(hdb_handle_t find_handle)
{
return objdb->object_find_destroy(find_handle);
}
diff --git a/lib/sa-confdb.h b/lib/sa-confdb.h
index 61a0fa75..439c760f 100644
--- a/lib/sa-confdb.h
+++ b/lib/sa-confdb.h
@@ -1,112 +1,112 @@
/*
- * Copyright (c) 2008, 2009 Red Hat, Inc.
+ * Copyright (c) 2008, 2012 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 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.
*/
extern int confdb_sa_init(void);
extern int confdb_sa_object_create(hdb_handle_t parent_object_handle,
const void *object_name,
size_t object_name_len,
hdb_handle_t *object_handle);
extern int confdb_sa_object_destroy(hdb_handle_t object_handle);
extern int confdb_sa_object_parent_get(hdb_handle_t object_handle,
hdb_handle_t *parent_object_handle);
extern int confdb_sa_object_name_get(hdb_handle_t object_handle,
char *object_name,
size_t *object_name_len);
extern int confdb_sa_key_create(hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
const void *value,
size_t value_len);
extern int confdb_sa_key_create_typed (hdb_handle_t parent_object_handle,
const char *key_name,
const void *value,
size_t value_len,
int type);
extern int confdb_sa_key_delete(hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
const void *value,
size_t value_len);
extern int confdb_sa_key_get(hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
void *value,
size_t *value_len);
extern int confdb_sa_key_get_typed(hdb_handle_t parent_object_handle,
const char *key_name,
- void *value,
+ void **value,
size_t *value_len,
int *type);
extern int confdb_sa_key_replace(hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
const void *old_value,
size_t old_value_len,
const void *new_value,
size_t new_value_len);
extern int confdb_sa_object_find(hdb_handle_t parent_object_handle,
hdb_handle_t *find_handle,
hdb_handle_t *object_handle,
const void *object_name,
size_t object_name_len);
extern int confdb_sa_object_iter(hdb_handle_t parent_object_handle,
hdb_handle_t *find_handle,
hdb_handle_t *object_handle,
const void *object_name,
size_t object_name_len,
void *found_object_name,
size_t *found_object_name_len);
extern int confdb_sa_key_iter(hdb_handle_t parent_object_handle,
hdb_handle_t start_pos,
void *key_name,
size_t *key_name_len,
void *value,
size_t *value_len);
extern int confdb_sa_key_iter_typed (hdb_handle_t parent_object_handle,
hdb_handle_t start_pos,
char *key_name,
- void *value,
+ void **value,
size_t *value_len,
int *type);
extern int confdb_sa_key_increment(hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
unsigned int *value);
extern int confdb_sa_key_decrement(hdb_handle_t parent_object_handle,
const void *key_name,
size_t key_name_len,
unsigned int *value);
extern int confdb_sa_find_destroy(hdb_handle_t find_handle);
extern int confdb_sa_write(char *error_text, size_t errbuf_len);
extern int confdb_sa_reload(int flush, char *error_text, size_t errbuf_len);
diff --git a/services/confdb.c b/services/confdb.c
index 39dbd939..1559604a 100644
--- a/services/confdb.c
+++ b/services/confdb.c
@@ -1,1092 +1,1263 @@
/*
- * Copyright (c) 2008-2010 Red Hat, Inc.
+ * Copyright (c) 2008-2012 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);
+ const void *message);
+static void message_handler_req_lib_confdb_key_create_typed2 (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_get_typed2 (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_replace2 (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);
+ 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_iter_typed2 (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_object_name_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 void *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 void *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
},
{ /* 20 */
.lib_handler_fn = message_handler_req_lib_confdb_object_name_get,
.flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
},
+ { /* 21 */
+ .lib_handler_fn = message_handler_req_lib_confdb_key_iter_typed2,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 22 */
+ .lib_handler_fn = message_handler_req_lib_confdb_key_replace2,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 23 */
+ .lib_handler_fn = message_handler_req_lib_confdb_key_get_typed2,
+ .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 24 */
+ .lib_handler_fn = message_handler_req_lib_confdb_key_create_typed2,
+ .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)
{
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 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);
+ if (value_len > CS_MAX_NAME_LENGTH) {
+ ret = CS_ERR_TOO_BIG;
+ } 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);
+ if (value_len > CS_MAX_NAME_LENGTH) {
+ ret = CS_ERR_TOO_BIG;
+ } 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_get_typed2 (void *conn,
+ const void *message)
+{
+ const struct req_lib_confdb_key_get *req_lib_confdb_key_get = message;
+ struct res_lib_confdb_key_get_typed2 res_lib_confdb_key_get;
+ struct res_lib_confdb_key_get_typed2 *res = &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;
+ res->header.size = sizeof(res_lib_confdb_key_get);
+ }
+ else {
+ res = alloca(sizeof(struct res_lib_confdb_key_get_typed2) + value_len);
+
+ memcpy(&res->value, value, value_len);
+ res->value_length = value_len;
+ res->type = type;
+
+ res->header.size = sizeof(struct res_lib_confdb_key_get_typed2)+value_len;
+ res->header.error = ret;
+ }
+ res->header.id = MESSAGE_RES_CONFDB_KEY_GET_TYPED2;
+ res->header.error = ret;
+
+ api->ipc_response_send(conn, res, res->header.size);
+
+}
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_CREATE;
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_object_name_get (void *conn,
const void *message)
{
const struct req_lib_confdb_object_name_get *request = message;
struct res_lib_confdb_object_name_get response;
int ret = CS_OK;
char object_name[CS_MAX_NAME_LENGTH];
size_t object_name_len;
if (api->object_name_get(request->object_handle,
object_name, &object_name_len)) {
ret = CS_ERR_ACCESS;
}
response.object_name.length = object_name_len;
strncpy((char*)response.object_name.value, object_name, CS_MAX_NAME_LENGTH);
response.object_name.value[CS_MAX_NAME_LENGTH-1] = '\0';
response.header.size = sizeof(response);
response.header.id = MESSAGE_RES_CONFDB_OBJECT_NAME_GET;
response.header.error = ret;
api->ipc_response_send(conn, &response, sizeof(response));
}
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);
+ if (value_len > CS_MAX_NAME_LENGTH) {
+ ret = CS_ERR_TOO_BIG;
+ } else {
+ 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);
+ if (value_len > CS_MAX_NAME_LENGTH) {
+ ret = CS_ERR_TOO_BIG;
+ } else {
+ 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_key_iter_typed2 (void *conn,
+ const void *message)
+{
+ const struct req_lib_confdb_key_iter *req_lib_confdb_key_iter = message;
+ struct res_lib_confdb_key_iter_typed2 res_lib_confdb_key_iter;
+ struct res_lib_confdb_key_iter_typed2 *res = &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;
+ res->header.size = sizeof(res_lib_confdb_key_iter);
+ }
+ else {
+ res = alloca(sizeof(struct res_lib_confdb_key_iter_typed2) + value_len);
+
+ memcpy(res->key_name.value, key_name, key_name_len);
+ res->key_name.length = key_name_len;
+ res->key_name.value[key_name_len] = '\0';
+ memcpy(&res->value, value, value_len);
+ res->value_length = value_len;
+
+ api->object_key_get_typed(req_lib_confdb_key_iter->parent_object_handle,
+ (const char*)res->key_name.value,
+ &value,
+ &value_len,
+ &my_type);
+ res->type = my_type;
+
+ res->header.size = sizeof(res_lib_confdb_key_iter)+value_len;
+ }
+ res->header.id = MESSAGE_RES_CONFDB_KEY_ITER_TYPED2;
+ res->header.error = ret;
+
+ api->ipc_response_send(conn, res, res->header.size);
+}
+
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;
+ struct res_lib_confdb_key_change_callback2 *res;
- res.header.size = sizeof(res);
- res.header.id = MESSAGE_RES_CONFDB_KEY_CHANGE_CALLBACK;
- res.header.error = CS_OK;
+ res = alloca(sizeof(struct res_lib_confdb_key_change_callback2) + key_value_len);
+
+ res->header.size = sizeof(struct res_lib_confdb_key_change_callback2) + key_value_len;
+ res->header.id = MESSAGE_RES_CONFDB_KEY_CHANGE_CALLBACK2;
+ res->header.error = CS_OK;
// handle & type
- res.change_type = change_type;
- res.parent_object_handle = parent_object_handle;
- res.object_handle = object_handle;
+ 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;
+ 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;
+ 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;
+ memcpy(&res->key_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));
+ ipc_dispatch_send_from_poll_thread(priv_data_pt, res, res->header.size);
}
static void confdb_notify_lib_of_new_object(hdb_handle_t parent_object_handle,
hdb_handle_t object_handle,
const void *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 void *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));
}
+
+static void message_handler_req_lib_confdb_key_create_typed2 (void *conn,
+ const void *message)
+{
+ const struct req_lib_confdb_key_create_typed2 *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,
+ 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_replace2 (void *conn,
+ const void *message)
+{
+ const struct req_lib_confdb_key_replace2 *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,
+ 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));
+}
diff --git a/tools/corosync-objctl.c b/tools/corosync-objctl.c
index d7909bb2..3e2bd4c8 100644
--- a/tools/corosync-objctl.c
+++ b/tools/corosync-objctl.c
@@ -1,936 +1,945 @@
/*
* Copyright (c) 2008 Allied Telesis Labs NZ
+ * (c) 2012 Red Hat, Inc.
*
* All rights reserved.
*
* Author: Angus Salkeld <angus.salkeld@alliedtelesis.co.nz>
*
* 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 <sys/select.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/un.h>
#include <corosync/corotypes.h>
#include <corosync/confdb.h>
#define SEPERATOR '.'
#define SEPERATOR_STR "."
-#define OBJ_NAME_SIZE 512
+#define OBJ_NAME_SIZE 4096
typedef enum {
ACTION_READ,
ACTION_WRITE,
ACTION_CREATE,
ACTION_CREATE_KEY,
ACTION_DELETE,
ACTION_PRINT_ALL,
ACTION_PRINT_DEFAULT,
ACTION_TRACK,
} action_types_t;
typedef enum {
FIND_OBJECT_ONLY,
FIND_OBJECT_OR_KEY,
FIND_KEY_ONLY
} find_object_of_type_t;
static void tail_key_changed(confdb_handle_t handle,
confdb_change_type_t change_type,
hdb_handle_t parent_object_handle,
hdb_handle_t object_handle,
const void *object_name,
size_t object_name_len,
const void *key_name,
size_t key_name_len,
const void *key_value,
size_t key_value_len);
static void tail_object_created(confdb_handle_t handle,
hdb_handle_t parent_object_handle,
hdb_handle_t object_handle,
const void *name_pt,
size_t name_len);
static void tail_object_deleted(confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const void *name_pt,
size_t name_len);
static void create_object(confdb_handle_t handle, char * name_pt);
static void create_object_key(confdb_handle_t handle, char * name_pt);
static void write_key(confdb_handle_t handle, char * path_pt);
static void get_parent_name(const char * name_pt, char * parent_name);
static confdb_callbacks_t callbacks = {
.confdb_key_change_notify_fn = tail_key_changed,
.confdb_object_create_change_notify_fn = tail_object_created,
.confdb_object_delete_change_notify_fn = tail_object_deleted,
};
static int debug = 0;
static int show_binary = 0;
static int action;
static void print_binary_key (char *value, size_t value_len)
{
size_t i;
char c;
for (i = 0; i < value_len; i++) {
c = value[i];
if (c >= ' ' && c < 0x7f && c != '\\') {
fputc (c, stdout);
} else {
if (c == '\\') {
printf ("\\\\");
} else {
printf ("\\x%02X", c);
}
}
}
printf ("\n");
}
static void print_key (char *key_name, void *value, size_t value_len, confdb_value_types_t type)
{
switch (type) {
case CONFDB_VALUETYPE_INT16:
printf ("%s=%hd\n", key_name,
*(int16_t*)value);
break;
case CONFDB_VALUETYPE_UINT16:
printf ("%s=%hu\n", key_name,
*(uint16_t*)value);
break;
case CONFDB_VALUETYPE_INT32:
printf ("%s=%d\n", key_name,
*(int32_t*)value);
break;
case CONFDB_VALUETYPE_UINT32:
printf ("%s=%u\n", key_name,
*(uint32_t*)value);
break;
case CONFDB_VALUETYPE_INT64:
printf ("%s=%"PRIi64"\n", key_name,
*(int64_t*)value);
break;
case CONFDB_VALUETYPE_UINT64:
printf ("%s=%"PRIu64"\n", key_name,
*(uint64_t*)value);
break;
case CONFDB_VALUETYPE_FLOAT:
printf ("%s=%f\n", key_name,
*(float*)value);
break;
case CONFDB_VALUETYPE_DOUBLE:
printf ("%s=%f\n", key_name,
*(double*)value);
break;
case CONFDB_VALUETYPE_STRING:
printf ("%s=%s\n", key_name, (char*)value);
break;
default:
case CONFDB_VALUETYPE_ANY:
if (!show_binary) {
printf ("%s=**binary**(%d)\n", key_name, type);
} else {
printf ("%s=", key_name);
print_binary_key ((char *)value, value_len);
}
break;
}
}
/* Recursively dump the object tree */
static void print_config_tree(confdb_handle_t handle, hdb_handle_t parent_object_handle, char * parent_name)
{
hdb_handle_t object_handle;
char object_name[OBJ_NAME_SIZE];
size_t object_name_len;
char key_name[OBJ_NAME_SIZE];
- char key_value[OBJ_NAME_SIZE];
+ char output_string[OBJ_NAME_SIZE];
+ char *key_value=NULL;/* Dynamically allocated value */
size_t key_value_len;
cs_error_t res;
int children_printed;
confdb_value_types_t type;
/* Show the keys */
res = confdb_key_iter_start(handle, parent_object_handle);
if (res != CS_OK) {
fprintf(stderr, "error resetting key iterator for object "HDB_X_FORMAT" %d\n", parent_object_handle, res);
exit(EXIT_FAILURE);
}
children_printed = 0;
- while ( (res = confdb_key_iter_typed(handle,
+ while ( (res = confdb_key_iter_typed2(handle,
parent_object_handle,
key_name,
- key_value,
+ (void**)&key_value,
&key_value_len,
&type)) == CS_OK) {
key_value[key_value_len] = '\0';
if (parent_name != NULL)
printf("%s%c", parent_name, SEPERATOR);
print_key(key_name, key_value, key_value_len, type);
+ free(key_value);
+ key_value = NULL;
children_printed++;
}
/* Show sub-objects */
res = confdb_object_iter_start(handle, parent_object_handle);
if (res != CS_OK) {
fprintf(stderr, "error resetting object iterator for object "HDB_X_FORMAT" %d\n", parent_object_handle, res);
exit(EXIT_FAILURE);
}
while ( (res = confdb_object_iter(handle,
parent_object_handle,
&object_handle,
object_name,
&object_name_len)) == CS_OK) {
object_name[object_name_len] = '\0';
if (parent_name != NULL) {
- snprintf(key_value, OBJ_NAME_SIZE, "%s%c%s", parent_name, SEPERATOR, object_name);
+ snprintf(output_string, OBJ_NAME_SIZE, "%s%c%s", parent_name, SEPERATOR, object_name);
} else {
if ((action == ACTION_PRINT_DEFAULT) && strcmp(object_name, "internal_configuration") == 0) continue;
- snprintf(key_value, OBJ_NAME_SIZE, "%s", object_name);
+ snprintf(output_string, OBJ_NAME_SIZE, "%s", object_name);
}
- print_config_tree(handle, object_handle, key_value);
+ print_config_tree(handle, object_handle, output_string);
children_printed++;
}
if (children_printed == 0 && parent_name != NULL) {
printf("%s\n", parent_name);
}
}
static cs_error_t reload_db(confdb_handle_t handle)
{
char error[1024];
cs_error_t ret;
ret = confdb_reload(handle, 0, error, sizeof(error) - 1);
if (ret != CONFDB_OK) {
fprintf (stderr, "Error reloading DB %d\n", ret);
}
return ret;
}
static int read_in_config_file (char * filename)
{
confdb_handle_t handle;
int result;
int ignore;
int c;
FILE* fh;
char buf[1024];
char * line;
char * end;
char parent_name[OBJ_NAME_SIZE];
if (access (filename, R_OK) != 0) {
perror ("Couldn't access file.");
return -1;
}
fh = fopen(filename, "r");
if (fh == NULL) {
perror ("Couldn't open file.");
return -1;
}
result = confdb_initialize (&handle, &callbacks);
if (result != CONFDB_OK) {
fprintf (stderr, "Could not initialize objdb library. Error %d\n", result);
fclose (fh);
return -1;
}
while (fgets (buf, 1024, fh) != NULL) {
/* find the first real character, if it is
* a '#' then ignore this line.
* else process.
* if no real characters then also ignore.
*/
ignore = 1;
for (c = 0; c < 1024; c++) {
if (isblank (buf[c]))
continue;
if (buf[c] == '#' || buf[c] == '\n') {
ignore = 1;
break;
}
ignore = 0;
line = &buf[c];
break;
}
if (ignore == 1)
continue;
/* kill the \n */
end = strchr (line, '\n');
if (end != NULL)
*end = '\0';
if (debug == 2)
printf ("%d: %s\n", __LINE__, line);
/* find the parent object */
get_parent_name(line, parent_name);
if (debug == 2)
printf ("%d: %s\n", __LINE__, parent_name);
/* create the object */
create_object (handle, parent_name);
/* write the attribute */
write_key (handle, line);
}
reload_db(handle);
confdb_finalize (handle);
fclose (fh);
return 0;
}
static int print_all(void)
{
confdb_handle_t handle;
int result;
result = confdb_initialize (&handle, &callbacks);
if (result != CS_OK) {
fprintf (stderr, "Could not initialize objdb library. Error %d\n", result);
return 1;
}
print_config_tree(handle, OBJECT_PARENT_HANDLE, NULL);
result = confdb_finalize (handle);
return 0;
}
static int print_help(void)
{
printf("\n");
printf ("usage: corosync-objctl [-b] object%ckey ... Print an object\n", SEPERATOR);
printf (" corosync-objctl -c object%cchild_obj ... Create Object\n", SEPERATOR);
printf (" corosync-objctl -d object%cchild_obj ... Delete object\n", SEPERATOR);
printf (" corosync-objctl -w object%cchild_obj.key=value ... Create a key\n", SEPERATOR);
printf (" corosync-objctl -n object%cchild_obj.key=value ... Create a new object with the key\n", SEPERATOR);
printf (" corosync-objctl -t object%cchild_obj ... Track changes\n", SEPERATOR);
printf (" corosync-objctl [-b] -a Print all objects\n");
printf (" corosync-objctl -p <filename> Load in config from the specified file.\n");
printf("\n");
return 0;
}
static cs_error_t validate_name(char * obj_name_pt)
{
if ((strchr (obj_name_pt, SEPERATOR) == NULL) &&
(strchr (obj_name_pt, '=') == NULL))
return CS_OK;
else
return CS_ERR_INVALID_PARAM;
}
static void get_parent_name(const char * name_pt, char * parent_name)
{
char * tmp;
strcpy(parent_name, name_pt);
/* first remove the value (it could be a file path */
tmp = strchr(parent_name, '=');
if (tmp != NULL) {
*tmp = '\0';
tmp--;
while (isblank (*tmp)) {
*tmp = '\0';
tmp--;
}
}
/* then truncate the child name */
tmp = strrchr(parent_name, SEPERATOR);
if (tmp != NULL) *tmp = '\0';
}
static void get_key(const char * name_pt, char * key_name, char * key_value)
{
char * tmp = (char*)name_pt;
char str_copy[OBJ_NAME_SIZE];
char * copy_tmp = str_copy;
int equals_seen = 0;
int in_quotes = 0;
/* strip out spaces when not in quotes */
while (*tmp != '\0') {
if (*tmp == '=')
equals_seen = 1;
if (equals_seen && *tmp == '"') {
if (in_quotes)
in_quotes = 0;
else
in_quotes = 1;
}
if (*tmp != ' ' || in_quotes) {
*copy_tmp = *tmp;
copy_tmp++;
}
tmp++;
}
*copy_tmp = '\0';
/* first remove the value (it could have a SEPERATOR in it */
tmp = strchr(str_copy, '=');
if (tmp != NULL && strlen(tmp) > 0) {
strcpy(key_value, tmp+1);
*tmp = '\0';
} else {
key_value[0] = '\0';
}
/* then remove the name */
tmp = strrchr(str_copy, SEPERATOR);
if (tmp == NULL) tmp = str_copy;
strcpy(key_name, tmp+1);
}
static cs_error_t find_object (confdb_handle_t handle,
char * name_pt,
find_object_of_type_t type,
hdb_handle_t * out_handle)
{
char * obj_name_pt;
char * save_pt;
hdb_handle_t obj_handle;
confdb_handle_t parent_object_handle = OBJECT_PARENT_HANDLE;
char tmp_name[OBJ_NAME_SIZE];
cs_error_t res = CS_OK;
strncpy (tmp_name, name_pt, sizeof (tmp_name));
tmp_name[sizeof (tmp_name) - 1] = '\0';
obj_name_pt = strtok_r(tmp_name, SEPERATOR_STR, &save_pt);
while (obj_name_pt != NULL) {
res = confdb_object_find_start(handle, parent_object_handle);
if (res != CS_OK) {
fprintf (stderr, "Could not start object_find %d\n", res);
exit (EXIT_FAILURE);
}
res = confdb_object_find(handle, parent_object_handle,
obj_name_pt, strlen (obj_name_pt), &obj_handle);
if (res != CS_OK) {
return res;
}
parent_object_handle = obj_handle;
obj_name_pt = strtok_r (NULL, SEPERATOR_STR, &save_pt);
}
*out_handle = parent_object_handle;
return res;
}
static void read_object(confdb_handle_t handle, char * name_pt)
{
char parent_name[OBJ_NAME_SIZE];
hdb_handle_t obj_handle;
cs_error_t res;
get_parent_name(name_pt, parent_name);
res = find_object (handle, name_pt, FIND_OBJECT_OR_KEY, &obj_handle);
if (res == CS_OK) {
print_config_tree(handle, obj_handle, parent_name);
}
}
static void write_key(confdb_handle_t handle, char * path_pt)
{
hdb_handle_t obj_handle;
char parent_name[OBJ_NAME_SIZE];
char key_name[OBJ_NAME_SIZE];
char key_value[OBJ_NAME_SIZE];
char old_key_value[OBJ_NAME_SIZE];
+ char *old_key_value_ptr = old_key_value;
size_t old_key_value_len;
cs_error_t res;
confdb_value_types_t type;
/* find the parent object */
get_parent_name(path_pt, parent_name);
get_key(path_pt, key_name, key_value);
if (debug == 1)
printf ("%d: key:\"%s\", value:\"%s\"\n",
__LINE__, key_name, key_value);
if (validate_name(key_name) != CS_OK) {
fprintf(stderr, "Incorrect key name, can not have \"=\" or \"%c\"\n", SEPERATOR);
exit(EXIT_FAILURE);
}
res = find_object (handle, parent_name, FIND_OBJECT_ONLY, &obj_handle);
if (res != CS_OK) {
fprintf(stderr, "Can't find parent object of \"%s\"\n", path_pt);
exit(EXIT_FAILURE);
}
/* get the current key */
- res = confdb_key_get_typed (handle,
+ res = confdb_key_get_typed2 (handle,
obj_handle,
key_name,
- old_key_value,
+ (void**)&old_key_value_ptr,
&old_key_value_len, &type);
+ if (debug == 1 && res==CS_OK)
+ printf ("%d: key:\"%s\", old value:\"%s\"\n",
+ __LINE__, key_name, old_key_value);
+
if (res == CS_OK) {
/* replace the current value */
res = confdb_key_replace (handle,
obj_handle,
key_name,
strlen(key_name),
old_key_value,
old_key_value_len,
key_value,
strlen(key_value)+1);
if (res != CS_OK)
fprintf(stderr, "Failed to replace the key %s=%s. Error %d\n", key_name, key_value, res);
} else {
/* not there, create a new key */
res = confdb_key_create_typed (handle,
obj_handle,
key_name,
key_value,
strlen(key_value)+1,
CONFDB_VALUETYPE_STRING);
if (res != CS_OK)
fprintf(stderr, "Failed to create the key %s=%s. Error %d\n", key_name, key_value, res);
}
}
static void create_object(confdb_handle_t handle, char * name_pt)
{
char * obj_name_pt;
char * save_pt;
hdb_handle_t obj_handle;
hdb_handle_t parent_object_handle = OBJECT_PARENT_HANDLE;
char tmp_name[OBJ_NAME_SIZE];
cs_error_t res;
strncpy (tmp_name, name_pt, sizeof (tmp_name));
tmp_name[sizeof (tmp_name) - 1] = '\0';
obj_name_pt = strtok_r(tmp_name, SEPERATOR_STR, &save_pt);
while (obj_name_pt != NULL) {
res = confdb_object_find_start(handle, parent_object_handle);
if (res != CS_OK) {
fprintf (stderr, "Could not start object_find %d\n", res);
exit (EXIT_FAILURE);
}
res = confdb_object_find(handle, parent_object_handle,
obj_name_pt, strlen (obj_name_pt), &obj_handle);
if (res != CS_OK) {
if (validate_name(obj_name_pt) != CS_OK) {
fprintf(stderr, "Incorrect object name \"%s\", \"=\" not allowed.\n",
obj_name_pt);
exit(EXIT_FAILURE);
}
if (debug)
printf ("%s:%d: %s\n", __func__,__LINE__, obj_name_pt);
res = confdb_object_create (handle,
parent_object_handle,
obj_name_pt,
strlen (obj_name_pt),
&obj_handle);
if (res != CS_OK)
fprintf(stderr, "Failed to create object \"%s\". Error %d.\n",
obj_name_pt, res);
}
parent_object_handle = obj_handle;
obj_name_pt = strtok_r (NULL, SEPERATOR_STR, &save_pt);
}
}
static void create_object_key(confdb_handle_t handle, char *name_pt)
{
char * obj_name_pt;
char * new_obj_name_pt;
char * save_pt;
hdb_handle_t obj_handle;
hdb_handle_t parent_object_handle = OBJECT_PARENT_HANDLE;
char tmp_name[OBJ_NAME_SIZE];
cs_error_t res;
char parent_name[OBJ_NAME_SIZE];
char key_name[OBJ_NAME_SIZE];
char key_value[OBJ_NAME_SIZE];
get_parent_name(name_pt, parent_name);
get_key(name_pt, key_name, key_value);
strncpy (tmp_name, parent_name, sizeof (tmp_name));
tmp_name[sizeof (tmp_name) - 1] = '\0';
obj_name_pt = strtok_r(tmp_name, SEPERATOR_STR, &save_pt);
/*
* Create parent object tree
*/
while (obj_name_pt != NULL) {
res = confdb_object_find_start(handle, parent_object_handle);
if (res != CS_OK) {
fprintf (stderr, "Could not start object_find %d\n", res);
exit (EXIT_FAILURE);
}
new_obj_name_pt = strtok_r (NULL, SEPERATOR_STR, &save_pt);
res = confdb_object_find(handle, parent_object_handle,
obj_name_pt, strlen (obj_name_pt), &obj_handle);
if (res != CS_OK || new_obj_name_pt == NULL) {
if (validate_name(obj_name_pt) != CS_OK) {
fprintf(stderr, "Incorrect object name \"%s\", \"=\" not allowed.\n",
obj_name_pt);
exit(EXIT_FAILURE);
}
if (debug)
printf ("%s:%d: %s\n", __func__,__LINE__, obj_name_pt);
res = confdb_object_create (handle,
parent_object_handle,
obj_name_pt,
strlen (obj_name_pt),
&obj_handle);
if (res != CS_OK) {
fprintf(stderr, "Failed to create object \"%s\". Error %d.\n",
obj_name_pt, res);
}
}
parent_object_handle = obj_handle;
obj_name_pt = new_obj_name_pt;
}
/*
* Create key
*/
res = confdb_key_create_typed (handle,
obj_handle,
key_name,
key_value,
strlen(key_value)+1,
CONFDB_VALUETYPE_STRING);
if (res != CS_OK) {
fprintf(stderr,
"Failed to create the key %s=%s. Error %d\n",
key_name, key_value, res);
}
}
/* Print "?" in place of any non-printable byte of OBJ. */
static void print_name (FILE *fp, const void *obj, size_t obj_len)
{
const char *p = obj;
size_t i;
for (i = 0; i < obj_len; i++) {
int c = *p++;
if (!isprint (c)) {
c = '?';
}
fputc (c, fp);
}
}
static void tail_key_changed(confdb_handle_t handle,
confdb_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)
{
/* printf("key_changed> %.*s.%.*s=%.*s\n", */
fputs("key_changed> ", stdout);
print_name (stdout, object_name_pt, object_name_len);
fputs(".", stdout);
print_name (stdout, key_name_pt, key_name_len);
fputs("=", stdout);
print_name (stdout, key_value_pt, key_value_len);
fputs("\n", stdout);
}
static void tail_object_created(confdb_handle_t handle,
hdb_handle_t parent_object_handle,
hdb_handle_t object_handle,
const void *name_pt,
size_t name_len)
{
fputs("object_created>", stdout);
print_name(stdout, name_pt, name_len);
fputs("\n", stdout);
}
static void tail_object_deleted(confdb_handle_t handle,
hdb_handle_t parent_object_handle,
const void *name_pt,
size_t name_len)
{
fputs("object_deleted>", stdout);
print_name(stdout, name_pt, name_len);
fputs("\n", stdout);
}
static void listen_for_object_changes(confdb_handle_t handle)
{
int result;
fd_set read_fds;
int select_fd;
int quit = CS_FALSE;
FD_ZERO (&read_fds);
if (confdb_fd_get (handle, &select_fd) != CS_OK) {
printf ("can't get the confdb selector object.\n");
return;
}
printf ("Type \"q\" to finish\n");
do {
FD_SET (select_fd, &read_fds);
FD_SET (STDIN_FILENO, &read_fds);
result = select (select_fd + 1, &read_fds, 0, 0, 0);
if (result == -1) {
perror ("select\n");
}
if (FD_ISSET (STDIN_FILENO, &read_fds)) {
char inbuf[3];
if (fgets(inbuf, sizeof(inbuf), stdin) == NULL)
quit = CS_TRUE;
else if (strncmp(inbuf, "q", 1) == 0)
quit = CS_TRUE;
}
if (FD_ISSET (select_fd, &read_fds)) {
if (confdb_dispatch (handle, CONFDB_DISPATCH_ALL) != CS_OK)
exit(1);
}
} while (result && quit == CS_FALSE);
(void)confdb_stop_track_changes(handle);
}
static void track_object(confdb_handle_t handle, char * name_pt)
{
cs_error_t res;
hdb_handle_t obj_handle;
res = find_object (handle, name_pt, FIND_OBJECT_ONLY, &obj_handle);
if (res != CS_OK) {
fprintf (stderr, "Could not find object \"%s\". Error %d\n",
name_pt, res);
return;
}
res = confdb_track_changes (handle, obj_handle, CONFDB_TRACK_DEPTH_RECURSIVE);
if (res != CS_OK) {
fprintf (stderr, "Could not enable tracking on object \"%s\". Error %d\n",
name_pt, res);
return;
}
}
static void stop_tracking(confdb_handle_t handle)
{
cs_error_t res;
res = confdb_stop_track_changes (handle);
if (res != CS_OK) {
fprintf (stderr, "Could not stop tracking. Error %d\n", res);
return;
}
}
static void delete_object(confdb_handle_t handle, char * name_pt)
{
cs_error_t res;
hdb_handle_t obj_handle;
res = find_object (handle, name_pt, FIND_OBJECT_ONLY, &obj_handle);
if (res == CS_OK) {
res = confdb_object_destroy (handle, obj_handle);
if (res != CS_OK)
fprintf(stderr, "Failed to find object \"%s\" to delete. Error %d\n", name_pt, res);
} else {
char parent_name[OBJ_NAME_SIZE];
char key_name[OBJ_NAME_SIZE];
char key_value[OBJ_NAME_SIZE];
/* find the parent object */
get_parent_name(name_pt, parent_name);
get_key(name_pt, key_name, key_value);
res = find_object (handle, parent_name, FIND_OBJECT_ONLY, &obj_handle);
if (res != CS_OK) {
fprintf(stderr, "Failed to find the key's parent object \"%s\". Error %d\n", parent_name, res);
exit (EXIT_FAILURE);
}
res = confdb_key_delete (handle,
obj_handle,
key_name,
strlen(key_name),
key_value,
strlen(key_value));
if (res != CS_OK)
fprintf(stderr, "Failed to delete key \"%s=%s\" from object \"%s\". Error %d\n",
key_name, key_value, parent_name, res);
}
}
int main (int argc, char *argv[]) {
confdb_handle_t handle;
cs_error_t result;
int c;
action = ACTION_READ;
for (;;){
c = getopt (argc,argv,"habwncvdtp:");
if (c==-1) {
break;
}
switch (c) {
case 'v':
debug++;
break;
case 'h':
return print_help();
break;
case 'a':
action = ACTION_PRINT_ALL;
break;
case 'b':
show_binary++;
break;
case 'p':
return read_in_config_file (optarg);
break;
case 'c':
action = ACTION_CREATE;
break;
case 'd':
action = ACTION_DELETE;
break;
case 'w':
action = ACTION_WRITE;
break;
case 'n':
action = ACTION_CREATE_KEY;
break;
case 't':
action = ACTION_TRACK;
break;
default :
action = ACTION_READ;
break;
}
}
if (argc == 1) {
action = ACTION_PRINT_DEFAULT;
return print_all();
} else if (action == ACTION_PRINT_ALL) {
return print_all();
} else if (optind >= argc) {
fprintf(stderr, "Expected an object path after options\n");
exit(EXIT_FAILURE);
}
result = confdb_initialize (&handle, &callbacks);
if (result != CS_OK) {
fprintf (stderr, "Failed to initialize the objdb API. Error %d\n", result);
exit (EXIT_FAILURE);
}
while (optind < argc) {
switch (action) {
case ACTION_READ:
read_object(handle, argv[optind++]);
break;
case ACTION_WRITE:
write_key(handle, argv[optind++]);
break;
case ACTION_CREATE:
create_object(handle, argv[optind++]);
break;
case ACTION_CREATE_KEY:
create_object_key(handle, argv[optind++]);
break;
case ACTION_DELETE:
delete_object(handle, argv[optind++]);
break;
case ACTION_TRACK:
track_object(handle, argv[optind++]);
break;
}
}
if (action == ACTION_TRACK) {
listen_for_object_changes(handle);
stop_tracking(handle);
} else {
reload_db(handle);
}
result = confdb_finalize (handle);
if (result != CS_OK) {
fprintf (stderr, "Error finalizing objdb API. Error %d\n", result);
exit(EXIT_FAILURE);
}
return 0;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Sep 22, 11:00 PM (15 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2403365
Default Alt Text
(159 KB)
Attached To
Mode
rC Corosync
Attached
Detach File
Event Timeline
Log In to Comment