rm -rf $(builddir)doc/api
AIS_LIBS = ais SaAmf SaClm SaCkpt SaEvt SaLck SaMsg evs cpg \
- cfg aisutil
+ cfg aisutil confdb
AIS_HEADERS = saAis.h saAmf.h saClm.h saCkpt.h saEvt.h saEvt.h saLck.h \
saMsg.h cpg.h cfg.h evs.h ipc_gen.h mar_gen.h swab.h \
- ais_util.h
+ ais_util.h confdb.h
EXEC_LIBS = totem_pg logsys
# Copyright (c) 2002-2006 MontaVista Software, Inc.
# Copyright (c) 2006 Sun Microsystems, Inc.
-# Copyright (c) 2006-2007 Red Hat, Inc.
+# Copyright (c) 2006-2008 Red Hat, Inc.
#
# All rights reserved.
#
AMF_OBJS = amf.o amfutil.o amfnode.o amfcluster.o amfapp.o amfsg.o amfsu.o amfcomp.o amfsi.o
# LCR objects
-LCR_SRC = evs.c clm.c ckpt.c evt.c lck.c msg.c cfg.c cpg.c aisparser.c vsf_ykd.c objdb.c $(AMF_SRC)
-LCR_OBJS = evs.o clm.o ckpt.o evt.o lck.o msg.o cfg.o cpg.o aisparser.o vsf_ykd.o objdb.o $(AMF_OBJS)
+LCR_SRC = evs.c clm.c ckpt.c evt.c lck.c msg.c cfg.c cpg.c aisparser.c vsf_ykd.c objdb.c confdb.c $(AMF_SRC)
+LCR_OBJS = evs.o clm.o ckpt.o evt.o lck.o msg.o cfg.o cpg.o aisparser.o vsf_ykd.o objdb.o confdb.o $(AMF_OBJS)
# main executive objects
MAIN_SRC = main.c mempool.c util.c sync.c service.c ipc.c flow.c timer.c \
service_evs.lcrso service_clm.lcrso service_amf.lcrso \
service_ckpt.lcrso service_evt.lcrso service_lck.lcrso \
service_msg.lcrso service_cfg.lcrso service_cpg.lcrso \
+ service_confdb.lcrso \
objdb.lcrso aisparser.lcrso vsf_ykd.lcrso keygen openais-instantiate
else
EXEC_OBJS = $(MAIN_OBJS) $(LCR_OBJS)
service_cfg.lcrso: cfg.o
$(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ./aisexec -bind_at_load cfg.o -o $@
+service_confdb.lcrso: confdb.o
+ $(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ./aisexec -bind_at_load confdb.o -o $@
+
service_cpg.lcrso: cpg.o
$(CC) $(LDFLAGS) -bundle $(LDFLAGS) -bundle_loader ./aisexec -bind_at_load cpg.o -o $@
service_cfg.lcrso: cfg.o
$(CC) -shared -Wl,-soname,service_cfg.lcrso cfg.o -o $@
+service_confdb.lcrso: confdb.o
+ $(CC) -shared -Wl,-soname,service_confdb.lcrso confdb.o -o $@
+
service_cpg.lcrso: cpg.o
$(CC) -shared -Wl,-soname,service_cpg.lcrso cpg.o -o $@
cfg.o: cfg.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
+confdb.o: confdb.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
+
aisparser.o: aisparser.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<
--- /dev/null
+/*
+ * Copyright (c) 2008 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 <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include "../include/saAis.h"
+#include "../include/ipc_gen.h"
+#include "../include/ipc_confdb.h"
+#include "../include/mar_gen.h"
+#include "../lcr/lcr_comp.h"
+#include "main.h"
+#include "flow.h"
+#include "ipc.h"
+#include "objdb.h"
+#include "service.h"
+#include "ipc.h"
+#include "logsys.h"
+
+LOGSYS_DECLARE_SUBSYS ("CONFDB", LOG_INFO);
+
+static struct objdb_iface_ver0 *global_objdb;
+
+static int confdb_exec_init_fn (struct objdb_iface_ver0 *objdb);
+
+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, void *message);
+static void message_handler_req_lib_confdb_object_destroy (void *conn, void *message);
+
+static void message_handler_req_lib_confdb_key_create (void *conn, void *message);
+static void message_handler_req_lib_confdb_key_get (void *conn, void *message);
+static void message_handler_req_lib_confdb_key_replace (void *conn, void *message);
+static void message_handler_req_lib_confdb_key_delete (void *conn, void *message);
+static void message_handler_req_lib_confdb_key_iter (void *conn, void *message);
+
+static void message_handler_req_lib_confdb_object_iter (void *conn, void *message);
+static void message_handler_req_lib_confdb_object_find (void *conn, void *message);
+
+static void message_handler_req_lib_confdb_object_parent_get (void *conn, void *message);
+
+static void message_handler_req_lib_confdb_track_start (void *conn, void *message);
+static void message_handler_req_lib_confdb_track_stop (void *conn, void *message);
+
+
+/*
+ * Library Handler Definition
+ */
+static struct openais_lib_handler confdb_lib_service[] =
+{
+ { /* 0 */
+ .lib_handler_fn = message_handler_req_lib_confdb_object_create,
+ .response_size = sizeof (mar_res_header_t),
+ .response_id = MESSAGE_RES_CONFDB_OBJECT_CREATE,
+ .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 1 */
+ .lib_handler_fn = message_handler_req_lib_confdb_object_destroy,
+ .response_size = sizeof (mar_res_header_t),
+ .response_id = MESSAGE_RES_CONFDB_OBJECT_DESTROY,
+ .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 2 */
+ .lib_handler_fn = message_handler_req_lib_confdb_object_find,
+ .response_size = sizeof (struct res_lib_confdb_object_find),
+ .response_id = MESSAGE_RES_CONFDB_OBJECT_FIND,
+ .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 3 */
+ .lib_handler_fn = message_handler_req_lib_confdb_key_create,
+ .response_size = sizeof (mar_res_header_t),
+ .response_id = MESSAGE_RES_CONFDB_KEY_CREATE,
+ .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 4 */
+ .lib_handler_fn = message_handler_req_lib_confdb_key_get,
+ .response_size = sizeof (struct res_lib_confdb_key_get),
+ .response_id = MESSAGE_RES_CONFDB_KEY_GET,
+ .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 5 */
+ .lib_handler_fn = message_handler_req_lib_confdb_key_replace,
+ .response_size = sizeof (mar_res_header_t),
+ .response_id = MESSAGE_RES_CONFDB_KEY_REPLACE,
+ .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 6 */
+ .lib_handler_fn = message_handler_req_lib_confdb_key_delete,
+ .response_size = sizeof (mar_res_header_t),
+ .response_id = MESSAGE_RES_CONFDB_KEY_DELETE,
+ .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 7 */
+ .lib_handler_fn = message_handler_req_lib_confdb_object_iter,
+ .response_size = sizeof (struct res_lib_confdb_object_iter),
+ .response_id = MESSAGE_RES_CONFDB_OBJECT_ITER,
+ .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 8 */
+ .lib_handler_fn = message_handler_req_lib_confdb_object_parent_get,
+ .response_size = sizeof (struct res_lib_confdb_object_parent_get),
+ .response_id = MESSAGE_RES_CONFDB_OBJECT_PARENT_GET,
+ .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 9 */
+ .lib_handler_fn = message_handler_req_lib_confdb_key_iter,
+ .response_size = sizeof (struct res_lib_confdb_key_iter),
+ .response_id = MESSAGE_RES_CONFDB_KEY_ITER,
+ .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 10 */
+ .lib_handler_fn = message_handler_req_lib_confdb_track_start,
+ .response_size = sizeof (mar_res_header_t),
+ .response_id = MESSAGE_RES_CONFDB_TRACK_START,
+ .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
+ },
+ { /* 11 */
+ .lib_handler_fn = message_handler_req_lib_confdb_track_stop,
+ .response_size = sizeof (mar_res_header_t),
+ .response_id = MESSAGE_RES_CONFDB_TRACK_START,
+ .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED
+ },
+};
+
+
+struct openais_service_handler confdb_service_handler = {
+ .name = "openais cluster config database access v1.01",
+ .id = CONFDB_SERVICE,
+ .private_data_size = 0,
+ .flow_control = OPENAIS_FLOW_CONTROL_NOT_REQUIRED,
+ .lib_init_fn = confdb_lib_init_fn,
+ .lib_exit_fn = confdb_lib_exit_fn,
+ .lib_service = confdb_lib_service,
+ .lib_service_count = sizeof (confdb_lib_service) / sizeof (struct openais_lib_handler),
+ .exec_init_fn = confdb_exec_init_fn,
+};
+
+/*
+ * Dynamic loader definition
+ */
+static struct openais_service_handler *confdb_get_service_handler_ver0 (void);
+
+static struct openais_service_handler_iface_ver0 confdb_service_handler_iface = {
+ .openais_get_service_handler_ver0 = confdb_get_service_handler_ver0
+};
+
+static struct lcr_iface openais_confdb_ver0[1] = {
+ {
+ .name = "openais_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 = openais_confdb_ver0
+};
+
+
+static struct openais_service_handler *confdb_get_service_handler_ver0 (void)
+{
+ return (&confdb_service_handler);
+}
+
+__attribute__ ((constructor)) static void confdb_comp_register (void) {
+ lcr_interfaces_set (&openais_confdb_ver0[0], &confdb_service_handler_iface);
+
+ lcr_component_register (&confdb_comp_ver0);
+}
+
+static int confdb_exec_init_fn (struct objdb_iface_ver0 *objdb)
+{
+ global_objdb = objdb;
+ return 0;
+}
+
+static int confdb_lib_init_fn (void *conn)
+{
+ log_printf(LOG_LEVEL_DEBUG, "lib_init_fn: conn=%p\n", conn);
+ return (0);
+}
+
+static int confdb_lib_exit_fn (void *conn)
+{
+
+ log_printf(LOG_LEVEL_DEBUG, "exit_fn for conn=%p\n", conn);
+ return (0);
+}
+
+static void message_handler_req_lib_confdb_object_create (void *conn, void *message)
+{
+ struct req_lib_confdb_object_create *req_lib_confdb_object_create = (struct req_lib_confdb_object_create *)message;
+ struct res_lib_confdb_object_create res_lib_confdb_object_create;
+ unsigned int object_handle;
+ int ret = SA_AIS_OK;
+
+ if (global_objdb->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 = SA_AIS_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;
+ openais_conn_send_response(conn, &res_lib_confdb_object_create, sizeof(res_lib_confdb_object_create));
+}
+
+static void message_handler_req_lib_confdb_object_destroy (void *conn, void *message)
+{
+ struct req_lib_confdb_object_destroy *req_lib_confdb_object_destroy = (struct req_lib_confdb_object_destroy *)message;
+ mar_res_header_t res;
+ int ret = SA_AIS_OK;
+
+ if (global_objdb->object_destroy(req_lib_confdb_object_destroy->object_handle))
+ ret = SA_AIS_ERR_ACCESS;
+
+ res.size = sizeof(res);
+ res.id = MESSAGE_RES_CONFDB_OBJECT_CREATE;
+ res.error = ret;
+ openais_conn_send_response(conn, &res, sizeof(res));
+}
+
+
+static void message_handler_req_lib_confdb_key_create (void *conn, void *message)
+{
+ struct req_lib_confdb_key_create *req_lib_confdb_key_create = (struct req_lib_confdb_key_create *)message;
+ mar_res_header_t res;
+ int ret = SA_AIS_OK;
+
+ if (global_objdb->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 = SA_AIS_ERR_ACCESS;
+
+ res.size = sizeof(res);
+ res.id = MESSAGE_RES_CONFDB_KEY_CREATE;
+ res.error = ret;
+ openais_conn_send_response(conn, &res, sizeof(res));
+}
+
+static void message_handler_req_lib_confdb_key_get (void *conn, void *message)
+{
+ struct req_lib_confdb_key_get *req_lib_confdb_key_get = (struct req_lib_confdb_key_get *)message;
+ struct res_lib_confdb_key_get res_lib_confdb_key_get;
+ int value_len;
+ void *value;
+ int ret = SA_AIS_OK;
+
+ if (global_objdb->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 = SA_AIS_ERR_ACCESS;
+ else {
+ memcpy(res_lib_confdb_key_get.value.value, value, value_len);
+ res_lib_confdb_key_get.value.length = value_len;
+
+ }
+ res_lib_confdb_key_get.header.size = sizeof(res_lib_confdb_key_get);
+ res_lib_confdb_key_get.header.id = MESSAGE_RES_CONFDB_KEY_GET;
+ res_lib_confdb_key_get.header.error = ret;
+ openais_conn_send_response(conn, &res_lib_confdb_key_get, sizeof(res_lib_confdb_key_get));
+}
+
+static void message_handler_req_lib_confdb_key_replace (void *conn, void *message)
+{
+ struct req_lib_confdb_key_replace *req_lib_confdb_key_replace = (struct req_lib_confdb_key_replace *)message;
+ mar_res_header_t res;
+ int ret = SA_AIS_OK;
+
+ if (global_objdb->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->old_value.value,
+ req_lib_confdb_key_replace->old_value.length,
+ req_lib_confdb_key_replace->new_value.value,
+ req_lib_confdb_key_replace->new_value.length))
+ ret = SA_AIS_ERR_ACCESS;
+
+ res.size = sizeof(res);
+ res.id = MESSAGE_RES_CONFDB_KEY_REPLACE;
+ res.error = ret;
+ openais_conn_send_response(conn, &res, sizeof(res));
+}
+
+static void message_handler_req_lib_confdb_key_delete (void *conn, void *message)
+{
+ struct req_lib_confdb_key_delete *req_lib_confdb_key_delete = (struct req_lib_confdb_key_delete *)message;
+ mar_res_header_t res;
+ int ret = SA_AIS_OK;
+
+ if (global_objdb->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,
+ req_lib_confdb_key_delete->value.value,
+ req_lib_confdb_key_delete->value.length))
+ ret = SA_AIS_ERR_ACCESS;
+
+ res.size = sizeof(res);
+ res.id = MESSAGE_RES_CONFDB_KEY_DELETE;
+ res.error = ret;
+ openais_conn_send_response(conn, &res, sizeof(res));
+}
+
+static void message_handler_req_lib_confdb_object_parent_get (void *conn, void *message)
+{
+ struct req_lib_confdb_object_parent_get *req_lib_confdb_object_parent_get = (struct req_lib_confdb_object_parent_get *)message;
+ struct res_lib_confdb_object_parent_get res_lib_confdb_object_parent_get;
+ unsigned int object_handle;
+ int ret = SA_AIS_OK;
+
+ if (global_objdb->object_parent_get(req_lib_confdb_object_parent_get->object_handle,
+ &object_handle))
+ ret = SA_AIS_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;
+ openais_conn_send_response(conn, &res_lib_confdb_object_parent_get, sizeof(res_lib_confdb_object_parent_get));
+}
+
+
+static void message_handler_req_lib_confdb_key_iter (void *conn, void *message)
+{
+ struct req_lib_confdb_key_iter *req_lib_confdb_key_iter = (struct req_lib_confdb_key_iter *)message;
+ struct res_lib_confdb_key_iter res_lib_confdb_key_iter;
+ void *key_name;
+ int key_name_len;
+ void *value;
+ int value_len;
+ int ret = SA_AIS_OK;
+
+ if (global_objdb->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 = SA_AIS_ERR_ACCESS;
+ else {
+ memcpy(res_lib_confdb_key_iter.key_name.value, key_name, key_name_len);
+ memcpy(res_lib_confdb_key_iter.value.value, value, value_len);
+ res_lib_confdb_key_iter.key_name.length = key_name_len;
+ res_lib_confdb_key_iter.value.length = value_len;
+ }
+ res_lib_confdb_key_iter.header.size = sizeof(res_lib_confdb_key_iter);
+ res_lib_confdb_key_iter.header.id = MESSAGE_RES_CONFDB_KEY_ITER;
+ res_lib_confdb_key_iter.header.error = ret;
+
+ openais_conn_send_response(conn, &res_lib_confdb_key_iter, sizeof(res_lib_confdb_key_iter));
+}
+
+static void message_handler_req_lib_confdb_object_iter (void *conn, void *message)
+{
+ struct req_lib_confdb_object_iter *req_lib_confdb_object_iter = (struct req_lib_confdb_object_iter *)message;
+ struct res_lib_confdb_object_iter res_lib_confdb_object_iter;
+ void *object_name;
+ int object_name_len;
+ int ret = SA_AIS_OK;
+
+ if (global_objdb->object_iter_from(req_lib_confdb_object_iter->parent_object_handle,
+ req_lib_confdb_object_iter->next_entry,
+ &object_name,
+ &object_name_len,
+ &res_lib_confdb_object_iter.object_handle))
+ ret = SA_AIS_ERR_ACCESS;
+ else {
+ res_lib_confdb_object_iter.object_name.length = object_name_len;
+ memcpy(res_lib_confdb_object_iter.object_name.value, object_name, object_name_len);
+ }
+ 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;
+
+ openais_conn_send_response(conn, &res_lib_confdb_object_iter, sizeof(res_lib_confdb_object_iter));
+}
+
+static void message_handler_req_lib_confdb_object_find (void *conn, void *message)
+{
+ struct req_lib_confdb_object_find *req_lib_confdb_object_find = (struct req_lib_confdb_object_find *)message;
+ struct res_lib_confdb_object_find res_lib_confdb_object_find;
+ int ret = SA_AIS_OK;
+
+ if (global_objdb->object_find_from(req_lib_confdb_object_find->parent_object_handle,
+ req_lib_confdb_object_find->next_entry,
+ req_lib_confdb_object_find->object_name.value,
+ req_lib_confdb_object_find->object_name.length,
+ &res_lib_confdb_object_find.object_handle,
+ &res_lib_confdb_object_find.next_entry))
+ ret = SA_AIS_ERR_ACCESS;
+
+ 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;
+
+ openais_conn_send_response(conn, &res_lib_confdb_object_find, sizeof(res_lib_confdb_object_find));
+}
+
+/* TODO: when we have notification in the objdb. */
+static void message_handler_req_lib_confdb_track_start (void *conn, void *message)
+{
+ mar_res_header_t res;
+
+ res.size = sizeof(res);
+ res.id = MESSAGE_RES_CONFDB_TRACK_START;
+ res.error = SA_AIS_ERR_NOT_SUPPORTED;
+ openais_conn_send_response(conn, &res, sizeof(res));
+}
+
+static void message_handler_req_lib_confdb_track_stop (void *conn, void *message)
+{
+ mar_res_header_t res;
+
+ res.size = sizeof(res);
+ res.id = MESSAGE_RES_CONFDB_TRACK_STOP;
+ res.error = SA_AIS_ERR_NOT_SUPPORTED;
+ openais_conn_send_response(conn, &res, sizeof(res));
+}
+
/*
* Copyright (c) 2006 MontaVista Software, Inc.
+ * Copyright (c) 2008 Red Hat, Inc.
*
* All rights reserved.
*
* Author: Steven Dake (sdake@mvista.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:
*
void **value,
int *value_len)
{
- unsigned int res;
+ unsigned int res = 0;
struct object_instance *instance;
struct object_key *object_key = NULL;
struct list_head *list;
*value_len = object_key->value_len;
}
}
+ else {
+ res = -1;
+ }
hdb_handle_put (&object_instance_database, object_handle);
- return (0);
+ return (res);
error_exit:
return (-1);
}
+static int object_find_from(unsigned int parent_object_handle,
+ unsigned int start_pos,
+ void *object_name,
+ int object_name_len,
+ unsigned int *object_handle,
+ unsigned int *next_pos)
+{
+ unsigned int res;
+ unsigned int pos = 0;
+ struct object_instance *instance;
+ struct object_instance *find_instance = NULL;
+ struct list_head *list;
+ unsigned int found = 0;
+
+ res = hdb_handle_get (&object_instance_database,
+ parent_object_handle, (void *)&instance);
+ if (res != 0) {
+ goto error_exit;
+ }
+ res = -ENOENT;
+ for (list = instance->child_head.next;
+ list != &instance->child_head; list = list->next) {
+
+ find_instance = list_entry (list, struct object_instance,
+ child_list);
+
+ if ((find_instance->object_name_len == object_name_len) &&
+ (memcmp (find_instance->object_name, object_name,
+ object_name_len) == 0)) {
+ if (pos++ == start_pos) {
+ found = 1;
+ break;
+ }
+ }
+ }
+
+ hdb_handle_put (&object_instance_database, parent_object_handle);
+ if (found) {
+ *object_handle = find_instance->object_handle;
+ res = 0;
+ }
+ *next_pos = pos;
+ return (res);
+
+error_exit:
+ return (-1);
+}
+
+static int object_iter_from(unsigned int parent_object_handle,
+ unsigned int start_pos,
+ void **object_name,
+ int *name_len,
+ unsigned int *object_handle)
+{
+ unsigned int res;
+ unsigned int pos = 0;
+ struct object_instance *instance;
+ struct object_instance *find_instance = NULL;
+ struct list_head *list;
+ unsigned int found = 0;
+
+ res = hdb_handle_get (&object_instance_database,
+ parent_object_handle, (void *)&instance);
+ if (res != 0) {
+ goto error_exit;
+ }
+ res = -ENOENT;
+
+ for (list = instance->child_head.next;
+ list != &instance->child_head; list = list->next) {
+
+ find_instance = list_entry (list, struct object_instance,
+ child_list);
+ if (pos++ == start_pos) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ *object_handle = find_instance->object_handle;
+ *object_name = find_instance->object_name;
+ *name_len = find_instance->object_name_len;
+ res = 0;
+ }
+ else {
+ res = -1;
+ }
+
+ return (res);
+
+error_exit:
+ return (-1);
+}
+
+static int object_key_iter_from(unsigned int parent_object_handle,
+ unsigned int start_pos,
+ void **key_name,
+ int *key_len,
+ void **value,
+ int *value_len)
+{
+ unsigned int pos = 0;
+ unsigned int res;
+ struct object_instance *instance;
+ struct object_key *find_key = NULL;
+ struct list_head *list;
+ unsigned int found = 0;
+
+ res = hdb_handle_get (&object_instance_database,
+ parent_object_handle, (void *)&instance);
+ if (res != 0) {
+ goto error_exit;
+ }
+ res = -ENOENT;
+
+ for (list = instance->key_head.next;
+ list != &instance->key_head; list = list->next) {
+
+ find_key = list_entry (list, struct object_key, list);
+
+ if (pos++ == start_pos) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ *key_name = find_key->key_name;
+ if (key_len)
+ *key_len = find_key->key_len;
+ *value = find_key->value;
+ if (value_len)
+ *value_len = find_key->value_len;
+ res = 0;
+ }
+ else {
+ res = -1;
+ }
+
+ hdb_handle_put (&object_instance_database, parent_object_handle);
+ return (res);
+
+error_exit:
+ return (-1);
+}
+
+
+
+
static int object_parent_get(unsigned int object_handle,
unsigned int *parent_handle)
{
.object_key_valid_set = object_key_valid_set,
.object_find_reset = object_find_reset,
.object_find = object_find,
+ .object_find_from = object_find_from,
.object_key_get = object_key_get,
.object_key_iter = object_key_iter,
.object_key_iter_reset = object_key_iter_reset,
+ .object_key_iter_from = object_key_iter_from,
.object_iter = object_iter,
.object_iter_reset = object_iter_reset,
+ .object_iter_from = object_iter_from,
.object_priv_get = object_priv_get,
.object_parent_get = object_parent_get,
.object_dump = object_dump
int (*object_dump) (
unsigned int object_handle,
FILE *file);
+
+ int (*object_find_from) (
+ unsigned int parent_object_handle,
+ unsigned int start_pos,
+ void *object_name,
+ int object_name_len,
+ unsigned int *object_handle,
+ unsigned int *next_pos);
+
+ int (*object_iter_from) (
+ unsigned int parent_object_handle,
+ unsigned int start_pos,
+ void **object_name,
+ int *name_len,
+ unsigned int *object_handle);
+
+ int (*object_key_iter_from) (
+ unsigned int parent_object_handle,
+ unsigned int start_pos,
+ void **key_name,
+ int *key_len,
+ void **value,
+ int *value_len);
};
#endif /* OBJDB_H_DEFINED */
{
.name = "openais_cpg",
.ver = 0,
+ },
+ {
+ .name = "openais_confdb",
+ .ver = 0,
}
};
--- /dev/null
+/*
+ * Copyright (c) 2008 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 OPENAIS_CONFDB_H_DEFINED
+#define OPENAIS_CONFDB_H_DEFINED
+
+/**
+ * @addtogroup confdb_openais
+ *
+ * @{
+ */
+typedef uint64_t confdb_handle_t;
+
+#define OBJECT_PARENT_HANDLE 0
+
+typedef enum {
+ CONFDB_DISPATCH_ONE,
+ CONFDB_DISPATCH_ALL,
+ CONFDB_DISPATCH_BLOCKING
+} confdb_dispatch_t;
+
+typedef enum {
+ CONFDB_OK = 1,
+ CONFDB_ERR_LIBRARY = 2,
+ CONFDB_ERR_TIMEOUT = 5,
+ CONFDB_ERR_TRY_AGAIN = 6,
+ CONFDB_ERR_INVALID_PARAM = 7,
+ CONFDB_ERR_NO_MEMORY = 8,
+ CONFDB_ERR_BAD_HANDLE = 9,
+ CONFDB_ERR_ACCESS = 11,
+ CONFDB_ERR_NOT_EXIST = 12,
+ CONFDB_ERR_EXIST = 14,
+ CONFDB_ERR_CONTEXT_NOT_FOUND = 17,
+ CONFDB_ERR_NOT_SUPPORTED = 20,
+ CONFDB_ERR_SECURITY = 29,
+} confdb_error_t;
+
+
+typedef void (*confdb_change_notify_fn_t) (
+ confdb_handle_t handle,
+ unsigned int parent_object_handle,
+ unsigned int object_handle,
+ void *object_name,
+ int object_name_len,
+ void *key_name,
+ int key_name_len,
+ void *key_value,
+ int key_value_len);
+
+typedef struct {
+ confdb_change_notify_fn_t confdb_change_notify_fn;
+} confdb_callbacks_t;
+
+/** @} */
+
+/*
+ * Create a new confdb connection
+ */
+confdb_error_t confdb_initialize (
+ confdb_handle_t *handle,
+ confdb_callbacks_t *callbacks);
+
+/*
+ * Close the confdb handle
+ */
+confdb_error_t confdb_finalize (
+ confdb_handle_t handle);
+
+/*
+ * Get a file descriptor on which to poll. confdb_handle_t is NOT a
+ * file descriptor and may not be used directly.
+ */
+confdb_error_t confdb_fd_get (
+ confdb_handle_t handle,
+ int *fd);
+
+/*
+ * Dispatch configuration changes
+ */
+confdb_error_t confdb_dispatch (
+ confdb_handle_t handle,
+ confdb_dispatch_t dispatch_types);
+
+
+/*
+ * Change notification
+ */
+confdb_error_t confdb_track_changes (
+ confdb_handle_t handle,
+ unsigned int object_handle,
+ unsigned int flags);
+
+confdb_error_t confdb_stop_track_changes (
+ confdb_handle_t handle);
+
+/*
+ * Manipulate objects
+ */
+confdb_error_t confdb_object_create (
+ confdb_handle_t handle,
+ unsigned int parent_object_handle,
+ void *object_name,
+ int object_name_len,
+ unsigned int *object_handle);
+
+confdb_error_t confdb_object_destroy (
+ confdb_handle_t handle,
+ unsigned int object_handle);
+
+confdb_error_t confdb_object_parent_get (
+ confdb_handle_t handle,
+ unsigned int object_handle,
+ unsigned int *parent_object_handle);
+
+/*
+ * Manipulate keys
+ */
+confdb_error_t confdb_key_create (
+ confdb_handle_t handle,
+ unsigned int parent_object_handle,
+ void *key_name,
+ int key_name_len,
+ void *value,
+ int value_len);
+
+confdb_error_t confdb_key_delete (
+ confdb_handle_t handle,
+ unsigned int parent_object_handle,
+ void *key_name,
+ int key_name_len,
+ void *value,
+ int value_len);
+
+/*
+ * Key queries
+ */
+confdb_error_t confdb_key_get (
+ confdb_handle_t handle,
+ unsigned int parent_object_handle,
+ void *key_name,
+ int key_name_len,
+ void *value,
+ int *value_len);
+
+confdb_error_t confdb_key_replace (
+ confdb_handle_t handle,
+ unsigned int parent_object_handle,
+ void *key_name,
+ int key_name_len,
+ void *old_value,
+ int old_value_len,
+ void *new_value,
+ int new_value_len);
+
+/*
+ * Object queries
+ * "find" loops through all objects of a given name and is also
+ * a quick way of finding a specific object,
+ * "iter" returns ech object in sequence.
+ */
+confdb_error_t confdb_object_find_start (
+ confdb_handle_t handle,
+ unsigned int parent_object_handle);
+
+confdb_error_t confdb_object_find (
+ confdb_handle_t handle,
+ unsigned int parent_object_handle,
+ void *object_name,
+ int object_name_len,
+ unsigned int *object_handle);
+
+confdb_error_t confdb_object_iter_start (
+ confdb_handle_t handle,
+ unsigned int parent_object_handle);
+
+confdb_error_t confdb_object_iter (
+ confdb_handle_t handle,
+ unsigned int parent_object_handle,
+ unsigned int *object_handle,
+ void *object_name,
+ int *object_name_len);
+
+/*
+ * Key iterator
+ */
+confdb_error_t confdb_key_iter_start (
+ confdb_handle_t handle,
+ unsigned int object_handle);
+
+confdb_error_t confdb_key_iter (
+ confdb_handle_t handle,
+ unsigned int parent_object_handle,
+ void *key_name,
+ int *key_name_len,
+ void *value,
+ int *value_len);
+
+
+#endif /* OPENAIS_CONFDB_H_DEFINED */
--- /dev/null
+/*
+ * Copyright (c) 2008 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 "saAis.h"
+#include "ipc_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
+};
+
+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_CHANGE_CALLBACK = 12
+};
+
+
+struct req_lib_confdb_object_create {
+ mar_req_header_t header __attribute__((aligned(8)));
+ mar_uint32_t parent_object_handle __attribute__((aligned(8)));
+ mar_name_t object_name __attribute__((aligned(8)));
+};
+
+struct res_lib_confdb_object_create {
+ mar_res_header_t header __attribute__((aligned(8)));
+ mar_uint32_t object_handle __attribute__((aligned(8)));
+};
+
+struct req_lib_confdb_object_destroy {
+ mar_req_header_t header __attribute__((aligned(8)));
+ mar_uint32_t object_handle __attribute__((aligned(8)));
+};
+
+struct req_lib_confdb_object_parent_get {
+ mar_req_header_t header __attribute__((aligned(8)));
+ mar_uint32_t object_handle __attribute__((aligned(8)));
+};
+
+struct res_lib_confdb_object_parent_get {
+ mar_res_header_t header __attribute__((aligned(8)));
+ mar_uint32_t parent_object_handle __attribute__((aligned(8)));
+};
+
+
+struct req_lib_confdb_key_create {
+ mar_req_header_t header __attribute__((aligned(8)));
+ mar_uint32_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_delete {
+ mar_req_header_t header __attribute__((aligned(8)));
+ mar_uint32_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 {
+ mar_req_header_t header __attribute__((aligned(8)));
+ mar_uint32_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 {
+ mar_req_header_t header __attribute__((aligned(8)));
+ mar_uint32_t parent_object_handle __attribute__((aligned(8)));
+ mar_name_t object_name __attribute__((aligned(8)));
+ mar_uint32_t next_entry __attribute__((aligned(8)));
+};
+
+struct res_lib_confdb_object_find {
+ mar_res_header_t header __attribute__((aligned(8)));
+ mar_uint32_t object_handle __attribute__((aligned(8)));
+ mar_uint32_t next_entry __attribute__((aligned(8)));
+};
+
+struct req_lib_confdb_object_iter {
+ mar_req_header_t header __attribute__((aligned(8)));
+ mar_uint32_t parent_object_handle __attribute__((aligned(8)));
+ mar_uint32_t next_entry __attribute__((aligned(8)));
+};
+
+struct res_lib_confdb_object_iter {
+ mar_res_header_t header __attribute__((aligned(8)));
+ mar_name_t object_name __attribute__((aligned(8)));
+ mar_uint32_t object_handle __attribute__((aligned(8)));
+};
+
+struct req_lib_confdb_key_iter {
+ mar_req_header_t header __attribute__((aligned(8)));
+ mar_uint32_t parent_object_handle __attribute__((aligned(8)));
+ mar_uint32_t next_entry __attribute__((aligned(8)));
+};
+
+struct res_lib_confdb_key_iter {
+ mar_res_header_t header __attribute__((aligned(8)));
+ mar_name_t key_name __attribute__((aligned(8)));
+ mar_name_t value __attribute__((aligned(8)));
+};
+
+struct req_lib_confdb_key_get {
+ mar_req_header_t header __attribute__((aligned(8)));
+ mar_uint32_t parent_object_handle __attribute__((aligned(8)));
+ mar_name_t key_name __attribute__((aligned(8)));
+};
+
+struct res_lib_confdb_key_get {
+ mar_res_header_t header __attribute__((aligned(8)));
+ mar_name_t value __attribute__((aligned(8)));
+};
+
+struct res_lib_confdb_change_callback {
+ mar_res_header_t header __attribute__((aligned(8)));
+ mar_uint32_t parent_object_handle __attribute__((aligned(8)));
+ mar_uint32_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)));
+};
+
+
+#endif /* IPC_CONFDB_H_DEFINED */
LCK_SERVICE = 5,
MSG_SERVICE = 6,
CFG_SERVICE = 7,
- CPG_SERVICE = 8
+ CPG_SERVICE = 8,
+ CONFDB_SERVICE = 10
};
enum req_init_types {
libSaLck.a libSaLck.so.2.0.0 \
libSaMsg.a libSaMsg.so.2.0.0 \
libcpg.a libcpg.so.2.0.0 \
+ libconfdb.a libconfdb.so.2.0.0 \
libais.a libais.so.2.0.0 \
libevs.a libevs.so.2.0.0 \
libcfg.a libcfg.so.2.0.0 \
libcpg.so.2.0.0: util.o cpg.o
$(CC) -bundle -bind_at_load util.o cpg.o -o $@
+libconfdb.so.2.0.0: util.o confdb.o
+ $(CC) -bundle -bind_at_load util.o confdb.o -o $@
+
libcfg.so.2.0.0: util.o cfg.o
$(CC) -bundle -bind_at_load util.o cfg.o -o $@
libcpg.so.2.0.0: util.o cpg.o
$(CC) -shared -Wl,-soname,libcpg.so.2,-version-script=$(srcdir)$(subdir)libcpg.versions util.o cpg.o -o $@
+libconfdb.so.2.0.0: util.o confdb.o
+ $(CC) -shared -Wl,-soname,libconfdb.so.2,-version-script=$(srcdir)$(subdir)libconfdb.versions util.o confdb.o -o $@
+
libcfg.so.2.0.0: util.o cfg.o
$(CC) -shared -Wl,-soname,libcfg.so.2,-version-script=$(srcdir)$(subdir)libcfg.versions util.o cfg.o -o $@
libcpg.a: util.o cpg.o
$(AR) -rc libcpg.a util.o cpg.o
+libconfdb.a: util.o confdb.o
+ $(AR) -rc libconfdb.a util.o confdb.o
+
libcfg.a: util.o cfg.o
$(AR) -rc libcfg.a util.o cfg.o
rm -f *.o libais.so* libais.a libSaClm.so* libSaClm.a* libSaAmf.so* libSaAmf.a \
libSaCkpt.so* libSaCkpt.a* libSaEvt.so* libSaEvt.a libSaLck.so* libSaLck.a \
libSaMsg.so* libSaMsg.a libcfg.so* libOpenaisCfg.a libaisutil.so* libaisutil.a \
- libevs.so* libevs.a libcpg.so* libcpg.a libcfg.a *.da *.bb *.bbg
+ libevs.so* libevs.a libcpg.so* libcpg.a libcfg.a libconfdb.so* libconfdb.a libconfdb.a \
+ *.da *.bb *.bbg
# -fPIC rules required for all libraries
%.o: %.c
--- /dev/null
+/*
+ * Copyright (c) 2008 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 openais object database
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <errno.h>
+
+#include <saAis.h>
+#include <confdb.h>
+#include <ipc_confdb.h>
+#include <mar_gen.h>
+#include <ais_util.h>
+#include <list.h>
+
+/* 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;
+ uint32_t parent_object_handle;
+ uint32_t context;
+};
+
+struct confdb_inst {
+ int response_fd;
+ int dispatch_fd;
+ int finalize;
+ confdb_callbacks_t callbacks;
+ void *context;
+ pthread_mutex_t response_mutex;
+ pthread_mutex_t dispatch_mutex;
+
+ struct list_head object_find_head;
+ struct list_head object_iter_head;
+ struct list_head key_iter_head;
+};
+
+static void confdb_instance_destructor (void *instance);
+
+static struct saHandleDatabase confdb_handle_t_db = {
+ .handleCount = 0,
+ .handles = 0,
+ .mutex = PTHREAD_MUTEX_INITIALIZER,
+ .handleInstanceDestructor = confdb_instance_destructor
+};
+
+/* Safely tidy one iterator context list */
+static void free_context_list(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);
+ free(context);
+ }
+}
+
+/*
+ * Clean up function for a confdb instance (confdb_initialize) handle
+ */
+static void confdb_instance_destructor (void *instance)
+{
+ struct confdb_inst *confdb_inst = instance;
+
+ pthread_mutex_destroy (&confdb_inst->response_mutex);
+ pthread_mutex_destroy (&confdb_inst->dispatch_mutex);
+}
+
+static struct iter_context *find_iter_context(struct list_head *list, unsigned int 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_openais
+ * @ingroup openais
+ *
+ * @{
+ */
+
+confdb_error_t confdb_initialize (
+ confdb_handle_t *handle,
+ confdb_callbacks_t *callbacks)
+{
+ SaAisErrorT error;
+ struct confdb_inst *confdb_inst;
+
+ error = saHandleCreate (&confdb_handle_t_db, sizeof (struct confdb_inst), handle);
+ if (error != SA_AIS_OK) {
+ goto error_no_destroy;
+ }
+
+ error = saHandleInstanceGet (&confdb_handle_t_db, *handle, (void *)&confdb_inst);
+ if (error != SA_AIS_OK) {
+ goto error_destroy;
+ }
+
+ error = saServiceConnect (&confdb_inst->dispatch_fd,
+ &confdb_inst->response_fd,
+ CONFDB_SERVICE);
+ if (error != SA_AIS_OK) {
+ goto error_put_destroy;
+ }
+
+ memcpy (&confdb_inst->callbacks, callbacks, sizeof (confdb_callbacks_t));
+
+ pthread_mutex_init (&confdb_inst->response_mutex, NULL);
+ pthread_mutex_init (&confdb_inst->dispatch_mutex, NULL);
+
+ list_init (&confdb_inst->object_find_head);
+ list_init (&confdb_inst->object_iter_head);
+ list_init (&confdb_inst->key_iter_head);
+
+ saHandleInstancePut (&confdb_handle_t_db, *handle);
+
+ return (SA_AIS_OK);
+
+error_put_destroy:
+ saHandleInstancePut (&confdb_handle_t_db, *handle);
+error_destroy:
+ saHandleDestroy (&confdb_handle_t_db, *handle);
+error_no_destroy:
+ return (error);
+}
+
+confdb_error_t confdb_finalize (
+ confdb_handle_t handle)
+{
+ struct confdb_inst *confdb_inst;
+ SaAisErrorT error;
+
+ error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
+ if (error != SA_AIS_OK) {
+ return (error);
+ }
+
+ pthread_mutex_lock (&confdb_inst->response_mutex);
+
+ /*
+ * Another thread has already started finalizing
+ */
+ if (confdb_inst->finalize) {
+ pthread_mutex_unlock (&confdb_inst->response_mutex);
+ saHandleInstancePut (&confdb_handle_t_db, handle);
+ return (CONFDB_ERR_BAD_HANDLE);
+ }
+
+ confdb_inst->finalize = 1;
+
+ pthread_mutex_unlock (&confdb_inst->response_mutex);
+
+ saHandleDestroy (&confdb_handle_t_db, handle);
+
+ /* Free saved context handles */
+ free_context_list(&confdb_inst->object_find_head);
+ free_context_list(&confdb_inst->object_iter_head);
+ free_context_list(&confdb_inst->key_iter_head);
+
+ /*
+ * Disconnect from the server
+ */
+ if (confdb_inst->response_fd != -1) {
+ shutdown(confdb_inst->response_fd, 0);
+ close(confdb_inst->response_fd);
+ }
+ if (confdb_inst->dispatch_fd != -1) {
+ shutdown(confdb_inst->dispatch_fd, 0);
+ close(confdb_inst->dispatch_fd);
+ }
+ saHandleInstancePut (&confdb_handle_t_db, handle);
+
+ return (CONFDB_OK);
+}
+
+confdb_error_t confdb_fd_get (
+ confdb_handle_t handle,
+ int *fd)
+{
+ SaAisErrorT error;
+ struct confdb_inst *confdb_inst;
+
+ error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
+ if (error != SA_AIS_OK) {
+ return (error);
+ }
+
+ *fd = confdb_inst->dispatch_fd;
+
+ saHandleInstancePut (&confdb_handle_t_db, handle);
+
+ return (SA_AIS_OK);
+}
+
+confdb_error_t confdb_context_get (
+ confdb_handle_t handle,
+ void **context)
+{
+ SaAisErrorT error;
+ struct confdb_inst *confdb_inst;
+
+ error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
+ if (error != SA_AIS_OK) {
+ return (error);
+ }
+
+ *context = confdb_inst->context;
+
+ saHandleInstancePut (&confdb_handle_t_db, handle);
+
+ return (SA_AIS_OK);
+}
+
+confdb_error_t confdb_context_set (
+ confdb_handle_t handle,
+ void *context)
+{
+ SaAisErrorT error;
+ struct confdb_inst *confdb_inst;
+
+ error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
+ if (error != SA_AIS_OK) {
+ return (error);
+ }
+
+ confdb_inst->context = context;
+
+ saHandleInstancePut (&confdb_handle_t_db, handle);
+
+ return (SA_AIS_OK);
+}
+
+struct res_overlay {
+ mar_res_header_t header __attribute__((aligned(8)));
+ char data[512000];
+};
+
+confdb_error_t confdb_dispatch (
+ confdb_handle_t handle,
+ confdb_dispatch_t dispatch_types)
+{
+ struct pollfd ufds;
+ int timeout = -1;
+ SaAisErrorT error;
+ int cont = 1; /* always continue do loop except when set to 0 */
+ int dispatch_avail;
+ struct confdb_inst *confdb_inst;
+ struct res_lib_confdb_change_callback *res_confdb_change_callback;
+ confdb_callbacks_t callbacks;
+ struct res_overlay dispatch_data;
+ int ignore_dispatch = 0;
+
+ error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
+ if (error != SA_AIS_OK) {
+ return (error);
+ }
+
+ /*
+ * Timeout instantly for SA_DISPATCH_ONE or SA_DISPATCH_ALL and
+ * wait indefinately for SA_DISPATCH_BLOCKING
+ */
+ if (dispatch_types == CONFDB_DISPATCH_ALL) {
+ timeout = 0;
+ }
+
+ do {
+ ufds.fd = confdb_inst->dispatch_fd;
+ ufds.events = POLLIN;
+ ufds.revents = 0;
+
+ error = saPollRetry (&ufds, 1, timeout);
+ if (error != SA_AIS_OK) {
+ goto error_nounlock;
+ }
+
+ pthread_mutex_lock (&confdb_inst->dispatch_mutex);
+
+ /*
+ * Regather poll data in case ufds has changed since taking lock
+ */
+ error = saPollRetry (&ufds, 1, timeout);
+ if (error != SA_AIS_OK) {
+ goto error_nounlock;
+ }
+
+ /*
+ * Handle has been finalized in another thread
+ */
+ if (confdb_inst->finalize == 1) {
+ error = CONFDB_OK;
+ pthread_mutex_unlock (&confdb_inst->dispatch_mutex);
+ goto error_unlock;
+ }
+
+ dispatch_avail = ufds.revents & POLLIN;
+ if (dispatch_avail == 0 && dispatch_types == CONFDB_DISPATCH_ALL) {
+ pthread_mutex_unlock (&confdb_inst->dispatch_mutex);
+ break; /* exit do while cont is 1 loop */
+ } else
+ if (dispatch_avail == 0) {
+ pthread_mutex_unlock (&confdb_inst->dispatch_mutex);
+ continue; /* next poll */
+ }
+
+ if (ufds.revents & POLLIN) {
+ /*
+ * Queue empty, read response from socket
+ */
+ error = saRecvRetry (confdb_inst->dispatch_fd, &dispatch_data.header,
+ sizeof (mar_res_header_t));
+ if (error != SA_AIS_OK) {
+ goto error_unlock;
+ }
+ if (dispatch_data.header.size > sizeof (mar_res_header_t)) {
+ error = saRecvRetry (confdb_inst->dispatch_fd, &dispatch_data.data,
+ dispatch_data.header.size - sizeof (mar_res_header_t));
+
+ if (error != SA_AIS_OK) {
+ goto error_unlock;
+ }
+ }
+ } else {
+ pthread_mutex_unlock (&confdb_inst->dispatch_mutex);
+ continue;
+ }
+
+ /*
+ * 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));
+
+ pthread_mutex_unlock (&confdb_inst->dispatch_mutex);
+ /*
+ * Dispatch incoming message
+ */
+ switch (dispatch_data.header.id) {
+ case MESSAGE_RES_CONFDB_CHANGE_CALLBACK:
+ res_confdb_change_callback = (struct res_lib_confdb_change_callback *)&dispatch_data;
+
+ callbacks.confdb_change_notify_fn (handle,
+ res_confdb_change_callback->parent_object_handle,
+ res_confdb_change_callback->object_handle,
+ res_confdb_change_callback->object_name.value,
+ res_confdb_change_callback->object_name.length,
+ res_confdb_change_callback->key_name.value,
+ res_confdb_change_callback->key_name.length,
+ res_confdb_change_callback->key_value.value,
+ res_confdb_change_callback->key_value.length);
+ break;
+
+ default:
+ error = SA_AIS_ERR_LIBRARY;
+ goto error_nounlock;
+ break;
+ }
+
+ /*
+ * Determine if more messages should be processed
+ * */
+ switch (dispatch_types) {
+ case CONFDB_DISPATCH_ONE:
+ if (ignore_dispatch) {
+ ignore_dispatch = 0;
+ } else {
+ cont = 0;
+ }
+ break;
+ case CONFDB_DISPATCH_ALL:
+ if (ignore_dispatch) {
+ ignore_dispatch = 0;
+ }
+ break;
+ case CONFDB_DISPATCH_BLOCKING:
+ break;
+ }
+ } while (cont);
+
+error_unlock:
+ saHandleInstancePut (&confdb_handle_t_db, handle);
+error_nounlock:
+ return (error);
+}
+
+confdb_error_t confdb_object_create (
+ confdb_handle_t handle,
+ unsigned int parent_object_handle,
+ void *object_name,
+ int object_name_len,
+ unsigned int *object_handle)
+{
+ confdb_error_t error;
+ struct confdb_inst *confdb_inst;
+ struct iovec iov[2];
+ struct req_lib_confdb_object_create req_lib_confdb_object_create;
+ struct res_lib_confdb_object_create res_lib_confdb_object_create;
+
+ error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
+ if (error != SA_AIS_OK) {
+ return (error);
+ }
+
+ 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[0].iov_base = (char *)&req_lib_confdb_object_create;
+ iov[0].iov_len = sizeof (struct req_lib_confdb_object_create);
+
+ pthread_mutex_lock (&confdb_inst->response_mutex);
+
+ error = saSendMsgReceiveReply (confdb_inst->response_fd, iov, 1,
+ &res_lib_confdb_object_create, sizeof (struct res_lib_confdb_object_create));
+
+ pthread_mutex_unlock (&confdb_inst->response_mutex);
+ if (error != SA_AIS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_confdb_object_create.header.error;
+ *object_handle = res_lib_confdb_object_create.object_handle;
+
+error_exit:
+ saHandleInstancePut (&confdb_handle_t_db, handle);
+
+ return (error);
+}
+
+confdb_error_t confdb_object_destroy (
+ confdb_handle_t handle,
+ unsigned int object_handle)
+{
+ confdb_error_t error;
+ struct confdb_inst *confdb_inst;
+ struct iovec iov[2];
+ struct req_lib_confdb_object_destroy req_lib_confdb_object_destroy;
+ mar_res_header_t res;
+
+ error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
+ if (error != SA_AIS_OK) {
+ return (error);
+ }
+
+ 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[0].iov_base = (char *)&req_lib_confdb_object_destroy;
+ iov[0].iov_len = sizeof (struct req_lib_confdb_object_destroy);
+
+ pthread_mutex_lock (&confdb_inst->response_mutex);
+
+ error = saSendMsgReceiveReply (confdb_inst->response_fd, iov, 1,
+ &res, sizeof ( mar_res_header_t));
+
+ pthread_mutex_unlock (&confdb_inst->response_mutex);
+ if (error != SA_AIS_OK) {
+ goto error_exit;
+ }
+
+ error = res.error;
+
+error_exit:
+ saHandleInstancePut (&confdb_handle_t_db, handle);
+
+ return (error);
+}
+
+confdb_error_t confdb_object_parent_get (
+ confdb_handle_t handle,
+ unsigned int object_handle,
+ unsigned int *parent_object_handle)
+{
+ confdb_error_t error;
+ struct confdb_inst *confdb_inst;
+ struct iovec iov[2];
+ 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 = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
+ if (error != SA_AIS_OK) {
+ return (error);
+ }
+
+ 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[0].iov_base = (char *)&req_lib_confdb_object_parent_get;
+ iov[0].iov_len = sizeof (struct req_lib_confdb_object_parent_get);
+
+ pthread_mutex_lock (&confdb_inst->response_mutex);
+
+ error = saSendMsgReceiveReply (confdb_inst->response_fd, iov, 1,
+ &res_lib_confdb_object_parent_get, sizeof (struct res_lib_confdb_object_parent_get));
+
+ pthread_mutex_unlock (&confdb_inst->response_mutex);
+ if (error != SA_AIS_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:
+ saHandleInstancePut (&confdb_handle_t_db, handle);
+
+ return (error);
+}
+
+confdb_error_t confdb_key_create (
+ confdb_handle_t handle,
+ unsigned int parent_object_handle,
+ void *key_name,
+ int key_name_len,
+ void *value,
+ int value_len)
+{
+ confdb_error_t error;
+ struct confdb_inst *confdb_inst;
+ struct iovec iov[2];
+ struct req_lib_confdb_key_create req_lib_confdb_key_create;
+ mar_res_header_t res;
+
+ error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
+ if (error != SA_AIS_OK) {
+ return (error);
+ }
+
+ 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[0].iov_base = (char *)&req_lib_confdb_key_create;
+ iov[0].iov_len = sizeof (struct req_lib_confdb_key_create);
+
+ pthread_mutex_lock (&confdb_inst->response_mutex);
+
+ error = saSendMsgReceiveReply (confdb_inst->response_fd, iov, 1,
+ &res, sizeof (res));
+
+ pthread_mutex_unlock (&confdb_inst->response_mutex);
+ if (error != SA_AIS_OK) {
+ goto error_exit;
+ }
+
+ error = res.error;
+
+error_exit:
+ saHandleInstancePut (&confdb_handle_t_db, handle);
+
+ return (error);
+}
+
+confdb_error_t confdb_key_get (
+ confdb_handle_t handle,
+ unsigned int parent_object_handle,
+ void *key_name,
+ int key_name_len,
+ void *value,
+ int *value_len)
+{
+ confdb_error_t error;
+ struct confdb_inst *confdb_inst;
+ struct iovec iov[2];
+ struct req_lib_confdb_key_get req_lib_confdb_key_get;
+ struct res_lib_confdb_key_get res_lib_confdb_key_get;
+
+ error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
+ if (error != SA_AIS_OK) {
+ return (error);
+ }
+
+ 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[0].iov_base = (char *)&req_lib_confdb_key_get;
+ iov[0].iov_len = sizeof (struct req_lib_confdb_key_get);
+
+ pthread_mutex_lock (&confdb_inst->response_mutex);
+
+ error = saSendMsgReceiveReply (confdb_inst->response_fd, iov, 1,
+ &res_lib_confdb_key_get, sizeof (struct res_lib_confdb_key_get));
+
+ pthread_mutex_unlock (&confdb_inst->response_mutex);
+ if (error != SA_AIS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_confdb_key_get.header.error;
+ if (error == SA_AIS_OK) {
+ *value_len = res_lib_confdb_key_get.value.length;
+ memcpy(value, res_lib_confdb_key_get.value.value, *value_len);
+ }
+
+error_exit:
+ saHandleInstancePut (&confdb_handle_t_db, handle);
+
+ return (error);
+}
+
+
+confdb_error_t confdb_key_replace (
+ confdb_handle_t handle,
+ unsigned int parent_object_handle,
+ void *key_name,
+ int key_name_len,
+ void *old_value,
+ int old_value_len,
+ void *new_value,
+ int new_value_len)
+{
+ confdb_error_t error;
+ struct confdb_inst *confdb_inst;
+ struct iovec iov[2];
+ struct req_lib_confdb_key_replace req_lib_confdb_key_replace;
+ mar_res_header_t res;
+
+ error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
+ if (error != SA_AIS_OK) {
+ return (error);
+ }
+
+ 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[0].iov_base = (char *)&req_lib_confdb_key_replace;
+ iov[0].iov_len = sizeof (struct req_lib_confdb_key_replace);
+
+ pthread_mutex_lock (&confdb_inst->response_mutex);
+
+ error = saSendMsgReceiveReply (confdb_inst->response_fd, iov, 1,
+ &res, sizeof (res));
+
+ pthread_mutex_unlock (&confdb_inst->response_mutex);
+ if (error != SA_AIS_OK) {
+ goto error_exit;
+ }
+
+ error = res.error;
+
+error_exit:
+ saHandleInstancePut (&confdb_handle_t_db, handle);
+
+ return (error);
+}
+
+confdb_error_t confdb_object_iter_start (
+ confdb_handle_t handle,
+ unsigned int object_handle)
+{
+ struct confdb_inst *confdb_inst;
+ confdb_error_t error = SA_AIS_OK;
+ struct iter_context *context;
+
+ error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
+ if (error != SA_AIS_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 = CONFDB_ERR_NO_MEMORY;
+ goto ret;
+ }
+ context->parent_object_handle = object_handle;
+ list_add(&context->list, &confdb_inst->object_iter_head);
+ }
+
+ context->context = 0;
+
+ saHandleInstancePut (&confdb_handle_t_db, handle);
+
+ret:
+ return error;
+}
+
+confdb_error_t confdb_key_iter_start (
+ confdb_handle_t handle,
+ unsigned int object_handle)
+{
+ struct confdb_inst *confdb_inst;
+ confdb_error_t error = SA_AIS_OK;
+ struct iter_context *context;
+
+ error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
+ if (error != SA_AIS_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 = CONFDB_ERR_NO_MEMORY;
+ goto ret;
+ }
+ context->parent_object_handle = object_handle;
+ list_add(&context->list, &confdb_inst->key_iter_head);
+ }
+
+ context->context = 0;
+
+ saHandleInstancePut (&confdb_handle_t_db, handle);
+
+ret:
+ return error;
+}
+
+confdb_error_t confdb_object_find_start (
+ confdb_handle_t handle,
+ unsigned int parent_object_handle)
+{
+ struct confdb_inst *confdb_inst;
+ confdb_error_t error = SA_AIS_OK;
+ struct iter_context *context;
+
+ error = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
+ if (error != SA_AIS_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 = CONFDB_ERR_NO_MEMORY;
+ goto ret;
+ }
+ context->parent_object_handle = parent_object_handle;
+ list_add(&context->list, &confdb_inst->object_find_head);
+ }
+
+ context->context = 0;
+
+ saHandleInstancePut (&confdb_handle_t_db, handle);
+
+ret:
+ return error;
+}
+
+confdb_error_t confdb_object_find (
+ confdb_handle_t handle,
+ unsigned int parent_object_handle,
+ void *object_name,
+ int object_name_len,
+ unsigned int *object_handle)
+{
+ confdb_error_t error;
+ struct confdb_inst *confdb_inst;
+ struct iovec iov[2];
+ 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 = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
+ if (error != SA_AIS_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 = CONFDB_ERR_CONTEXT_NOT_FOUND;
+ 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.next_entry = context->context;
+ 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[0].iov_base = (char *)&req_lib_confdb_object_find;
+ iov[0].iov_len = sizeof (struct req_lib_confdb_object_find);
+
+ pthread_mutex_lock (&confdb_inst->response_mutex);
+
+ error = saSendMsgReceiveReply (confdb_inst->response_fd, iov, 1,
+ &res_lib_confdb_object_find, sizeof (struct res_lib_confdb_object_find));
+
+ pthread_mutex_unlock (&confdb_inst->response_mutex);
+ if (error != SA_AIS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_confdb_object_find.header.error;
+ *object_handle = res_lib_confdb_object_find.object_handle;
+ context->context = res_lib_confdb_object_find.next_entry;
+
+error_exit:
+ saHandleInstancePut (&confdb_handle_t_db, handle);
+
+ return (error);
+}
+
+
+confdb_error_t confdb_object_iter (
+ confdb_handle_t handle,
+ unsigned int parent_object_handle,
+ unsigned int *object_handle,
+ void *object_name,
+ int *object_name_len)
+{
+ confdb_error_t error;
+ struct confdb_inst *confdb_inst;
+ struct iovec iov[2];
+ 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 = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
+ if (error != SA_AIS_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 = CONFDB_ERR_CONTEXT_NOT_FOUND;
+ goto error_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.next_entry = context->context;
+
+ iov[0].iov_base = (char *)&req_lib_confdb_object_iter;
+ iov[0].iov_len = sizeof (struct req_lib_confdb_object_iter);
+
+ pthread_mutex_lock (&confdb_inst->response_mutex);
+
+ error = saSendMsgReceiveReply (confdb_inst->response_fd, iov, 1,
+ &res_lib_confdb_object_iter, sizeof (struct res_lib_confdb_object_iter));
+
+ pthread_mutex_unlock (&confdb_inst->response_mutex);
+ if (error != SA_AIS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_confdb_object_iter.header.error;
+ if (error == SA_AIS_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->context++;
+
+error_exit:
+ saHandleInstancePut (&confdb_handle_t_db, handle);
+
+ return (error);
+}
+
+confdb_error_t confdb_key_iter (
+ confdb_handle_t handle,
+ unsigned int parent_object_handle,
+ void *key_name,
+ int *key_name_len,
+ void *value,
+ int *value_len)
+{
+ confdb_error_t error;
+ struct confdb_inst *confdb_inst;
+ struct iovec iov[2];
+ 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 = saHandleInstanceGet (&confdb_handle_t_db, handle, (void *)&confdb_inst);
+ if (error != SA_AIS_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 = CONFDB_ERR_CONTEXT_NOT_FOUND;
+ goto error_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->context;
+
+ iov[0].iov_base = (char *)&req_lib_confdb_key_iter;
+ iov[0].iov_len = sizeof (struct req_lib_confdb_key_iter);
+
+ pthread_mutex_lock (&confdb_inst->response_mutex);
+
+ error = saSendMsgReceiveReply (confdb_inst->response_fd, iov, 1,
+ &res_lib_confdb_key_iter, sizeof (struct res_lib_confdb_key_iter));
+
+ pthread_mutex_unlock (&confdb_inst->response_mutex);
+ if (error != SA_AIS_OK) {
+ goto error_exit;
+ }
+
+ error = res_lib_confdb_key_iter.header.error;
+ if (error == SA_AIS_OK) {
+ *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);
+ *value_len = res_lib_confdb_key_iter.value.length;
+ memcpy(value, res_lib_confdb_key_iter.value.value, *value_len);
+ }
+
+ context->context++;
+
+error_exit:
+ saHandleInstancePut (&confdb_handle_t_db, handle);
+
+ return (error);
+}
--- /dev/null
+# Version and symbol export for libconfdb.so
+
+OPENAIS_CONFDB_1.0 {
+ global:
+ confdb_initialize;
+ confdb_finalize;
+ confdb_fd_get;
+ confdb_dispatch;
+ confdb_track_changes;
+ confdb_stop_track_changes;
+ confdb_object_create;
+ confdb_object_destroy;
+ confdb_object_parent_get;
+ confdb_key_create;
+ confdb_key_delete;
+ confdb_key_get;
+ confdb_key_replace;
+ confdb_object_find_start;
+ confdb_object_find;
+ confdb_object_iter_start;
+ confdb_object_iter;
+ confdb_key_iter_start;
+ confdb_key_iter;
+
+ local:
+ saHandleCreate;
+ saHandleDestroy;
+ saHandleInstanceGet;
+ saHandleInstancePut;
+ saRecvRetry;
+ saSelectRetry;
+ saSendMsgReceiveReply;
+ saSendMsgRetry;
+ saSendReceiveReply;
+ saSendRetry;
+ saServiceConnect;
+ saVersionVerify;
+};
# Copyright (c) 2002-2004 MontaVista Software, Inc.
-# Copyright (c) 2006-2007 Red Hat, Inc.
+# Copyright (c) 2006-2008 Red Hat, Inc.
# Copyright (c) 2006 Sun Microsystems, Inc.
#
# All rights reserved.
override LDFLAGS += -lnsl -lsocket -lrt
endif
-LIBRARIES= ../lib/libSaClm.a ../lib/libSaAmf.a ../lib/libSaCkpt.a ../lib/libSaEvt.a ../lib/libSaLck.a ../lib/libSaMsg.a ../lib/libevs.a ../lib/libcpg.a ../lib/libcfg.a
+LIBRARIES= ../lib/libSaClm.a ../lib/libSaAmf.a ../lib/libSaCkpt.a ../lib/libSaEvt.a ../lib/libSaLck.a ../lib/libSaMsg.a ../lib/libevs.a ../lib/libcpg.a ../lib/libcfg.a ../lib/libconfdb.a
LIBS = $(LIBRARIES)
BINARIES=testclm testamf1 \
testckpt ckptstress ckptbench \
ckptbenchth ckpt-rd ckpt-wr testevt testevs \
evsbench subscription publish evtbench unlink testclm2 testlck \
- testmsg testcpg testcpg2 cpgbench openais-cfgtool \
+ testmsg testcpg testcpg2 cpgbench testconfdb openais-cfgtool \
logsys_s logsys_t1 logsys_t2
override CFLAGS += -I../include
cpgbench: cpgbench.o $(LIBRARIES)
$(CC) $(LDFLAGS) -o cpgbench cpgbench.o $(LIBS)
+testconfdb: testconfdb.o $(LIBRARIES)
+ $(CC) $(LDFLAGS) -o testconfdb testconfdb.o $(LIBS)
+
openais-cfgtool: openais-cfgtool.o $(LIBRARIES)
$(CC) $(LDFLAGS) -o openais-cfgtool openais-cfgtool.o $(LIBS)
--- /dev/null
+/*
+ * Copyright (c) 2008 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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <signal.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/un.h>
+
+#include "saAis.h"
+#include "confdb.h"
+
+
+/* Callbacks are not supported yet */
+confdb_callbacks_t callbacks = {
+ .confdb_change_notify_fn = NULL,
+};
+
+/* Recursively dump the object tree */
+static void print_config_tree(confdb_handle_t handle, unsigned int parent_object_handle, int depth)
+{
+ unsigned int object_handle;
+ char object_name[1024];
+ int object_name_len;
+ char key_name[1024];
+ int key_name_len;
+ char key_value[1024];
+ int key_value_len;
+ int res;
+ int i;
+
+ /* Show the keys */
+ res = confdb_key_iter_start(handle, parent_object_handle);
+ if (res != SA_AIS_OK) {
+ printf( "error resetting key iterator for object %d: %d\n", parent_object_handle, res);
+ return;
+ }
+
+ while ( (res = confdb_key_iter(handle, parent_object_handle, key_name, &key_name_len,
+ key_value, &key_value_len)) == SA_AIS_OK) {
+ key_name[key_name_len] = '\0';
+ key_value[key_value_len] = '\0';
+ for (i=0; i<depth; i++) printf(" ");
+ printf(" KEY %s=%s\n", key_name, key_value);
+ }
+
+ /* Show sub-objects */
+ res = confdb_object_iter_start(handle, parent_object_handle);
+ if (res != SA_AIS_OK) {
+ printf( "error resetting object iterator for object %d: %d\n", parent_object_handle, res);
+ return;
+ }
+
+ while ( (res = confdb_object_iter(handle, parent_object_handle, &object_handle, object_name, &object_name_len)) == SA_AIS_OK) {
+ unsigned int parent;
+
+ res = confdb_object_parent_get(handle, object_handle, &parent);
+ if (res != SA_AIS_OK) {
+ printf( "error getting parent for object %d: %d\n", object_handle, res);
+ return;
+ }
+
+ for (i=0; i<depth; i++) printf(" ");
+
+ object_name[object_name_len] = '\0';
+ printf("OBJECT: %s (%u, parent: %u)\n", object_name, object_handle, parent);
+
+ /* Down we go ... */
+ print_config_tree(handle, object_handle, depth+1);
+ }
+}
+
+static void do_write_tests(confdb_handle_t handle)
+{
+ int res;
+ unsigned int object_handle;
+
+ /* Add a scratch object and put some keys into it */
+ res = confdb_object_create(handle, OBJECT_PARENT_HANDLE, (void *)"testconfdb", strlen("testconfdb"), &object_handle);
+ if (res != SA_AIS_OK) {
+ printf( "error creating 'testconfdb' object: %d\n", res);
+ return;
+ }
+
+ res = confdb_key_create(handle, object_handle, "testkey", strlen("testkey"), "one", strlen("one"));
+ if (res != SA_AIS_OK) {
+ printf( "error creating 'testconfdb' key 1: %d\n", res);
+ return;
+ }
+
+ res = confdb_key_create(handle, object_handle, "testkey", strlen("testkey"), "two", strlen("two"));
+ if (res != SA_AIS_OK) {
+ printf( "error creating 'testconfdb' key 2: %d\n", res);
+ return;
+ }
+
+ res = confdb_key_create(handle, object_handle, "grot", strlen("grot"), "perrins", strlen("perrins"));
+ if (res != SA_AIS_OK) {
+ printf( "error creating 'testconfdb' key 3: %d\n", res);
+ return;
+ }
+
+ res = confdb_key_replace(handle, object_handle, "testkey", strlen("testkey"), "two", strlen("two"),
+ "newtwo", strlen("newtwo"));
+
+ if (res != SA_AIS_OK) {
+ printf( "error replace 'testconfdb' key 2: %d\n", res);
+ return;
+ }
+
+ /* Print it for verification */
+ print_config_tree(handle, object_handle, 0);
+ printf("-------------------------\n");
+
+ /* Remove it.
+ Check that it doesn't exist when the full tree dump runs next */
+ res = confdb_object_destroy(handle, object_handle);
+ if (res != SA_AIS_OK) {
+ printf( "error destroying 'testconfdb' object: %d\n", res);
+ return;
+ }
+}
+
+
+int main (int argc, char *argv[]) {
+ confdb_handle_t handle;
+ int result;
+ unsigned int totem_handle;
+ char key_value[256];
+ int value_len;
+
+ result = confdb_initialize (&handle, &callbacks);
+ if (result != SA_AIS_OK) {
+ printf ("Could not initialize Cluster Configuration Database API instance error %d\n", result);
+ exit (1);
+ }
+
+ if (argv[1] && strcmp(argv[1], "write")==0)
+ do_write_tests(handle);
+
+ /* Test iterators */
+ print_config_tree(handle, OBJECT_PARENT_HANDLE, 0);
+
+ /* Find "totem" and dump bits of it again, to test the direct APIs */
+ result = confdb_object_find_start(handle, OBJECT_PARENT_HANDLE);
+ if (result != SA_AIS_OK) {
+ printf ("Could not start object_find %d\n", result);
+ exit (1);
+ }
+
+ result = confdb_object_find(handle, OBJECT_PARENT_HANDLE, "totem", strlen("totem"), &totem_handle);
+ if (result != SA_AIS_OK) {
+ printf ("Could not object_find \"totem\": %d\n", result);
+ exit (1);
+ }
+
+ result = confdb_key_get(handle, totem_handle, "version", strlen("version"), key_value, &value_len);
+ if (result != SA_AIS_OK) {
+ printf ("Could not get \"version\" key: %d\n", result);
+ exit (1);
+ }
+ key_value[value_len] = '\0';
+ printf("totem/version = '%s'\n", key_value);
+
+ result = confdb_key_get(handle, totem_handle, "secauth", strlen("secauth"), key_value, &value_len);
+ if (result != SA_AIS_OK) {
+ printf ("Could not get \"secauth\" key: %d\n", result);
+ exit (1);
+ }
+ key_value[value_len] = '\0';
+ printf("totem/secauth = '%s'\n", key_value);
+
+ /* Try a call that fails */
+ result = confdb_key_get(handle, totem_handle, "grot", strlen("grot"), key_value, &value_len);
+ printf ("Get \"grot\" key returned: %d (should fail)\n", result);
+
+ result = confdb_finalize (handle);
+ printf ("Finalize result is %d (should be 1)\n", result);
+ return (0);
+}